diff --git a/dde-file-manager-5.5.3/.clang-format b/dde-file-manager-5.5.3/.clang-format new file mode 100644 index 0000000..25fe584 --- /dev/null +++ b/dde-file-manager-5.5.3/.clang-format @@ -0,0 +1,140 @@ +# 基于那个配置文件 https://clang.llvm.org/docs/ClangFormatStyleOptions.html +BasedOnStyle: WebKit +# 访问说明符的偏移(public private) +AccessModifierOffset: -4 +# 括号之后,水平对齐参数: Align DontAlign AlwaysBreak。 +AlignAfterOpenBracket: Align +#AlignConsecutiveBitFields: false +# 连续的赋值时,对齐所有的等号 +AlignConsecutiveAssignments: false +# 连续声明时,对齐所有声明的变量名 +AlignConsecutiveDeclarations: false +#AlignConsecutiveMacros: false +AlignEscapedNewlines: DontAlign +# 水平对齐二元和三元表达式的操作数 +AlignOperands: true +# 对齐连续的尾随的注释 +AlignTrailingComments: false +#AllowAllArgumentsOnNextLine: false +#AllowAllConstructorInitializersOnNextLine: false +# 允许函数声明的所有参数在放在下一行 +AllowAllParametersOfDeclarationOnNextLine: false +# 允许短的块放在同一行 +AllowShortBlocksOnASingleLine: true +# 允许短的case标签放在同一行 +AllowShortCaseLabelsOnASingleLine: false +#AllowShortEnumsOnASingleLine: false +# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All +AllowShortFunctionsOnASingleLine: InlineOnly +# 是否允许短if单行 If true, if (a) return; 可以放到同一行 +AllowShortIfStatementsOnASingleLine: false +#AllowShortLambdasOnASingleLine: Inline +# 允许短的循环保持在同一行 +AllowShortLoopsOnASingleLine: false +# 总是在定义返回类型后换行(deprecated) +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BreakBeforeBraces: Custom +BraceWrapping: +# AfterCaseLabel: false + AfterClass: true + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false +# BeforeLambdaBody: false +# BeforeWhile: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true + +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeTernaryOperators: true +#在构造函数初始化时按逗号断行,并以冒号对齐 +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeComma +BreakStringLiterals: false +# 每行字符的限制,0表示没有限制 +ColumnLimit: 0 +# 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变 +# CommentPragmas: '^ IWYU pragma:' +# 语言: None Cpp Java Objc Protp +CompactNamespaces: false +Cpp11BracedListStyle: true +#DeriveLineEnding: \n +DerivePointerAlignment: false +FixNamespaceComments: true +ForEachMacros: ["foreach", "Q_FOREACH"] +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^"' + Priority: 1 + - Regex: '^["<]D' + Priority: 2 + - Regex: '^$' + Priority: 5 + - Regex: '^"moc_' + Priority: 99 + - Regex: '\.moc"' + Priority: 99 + +# 缩进case 标签 +IndentCaseLabels: false +#IndentExternBlock: NoIndent +#IndentCaseBlocks: false +#IndentGotoLabels: false +IndentPPDirectives: None +#缩进宽度 +IndentWidth: 4 +IndentWrappedFunctionNames: false +#InsertTrailingCommas: None +#在block从空行开始 +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp +# 连续的空行保留几行 +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +#指针的*的挨着哪边 +PointerAlignment: Right +# 允许排序#include, 造成编译错误 +SortIncludes: false +SortUsingDeclarations: false +#括号后添加空格 +SpaceAfterCStyleCast: false +#SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +#等号两边的空格 +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +#SpaceBeforeSquareBrackets: false +#SpaceInEmptyBlock: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +#SpacesInConditionalStatement: false +# 容器类的空格 例如 OC的字典 +SpacesInContainerLiterals: false +# 小括号两边添加空格 +SpacesInParentheses: false +# 中括号两边空格 [] +SpacesInSquareBrackets: false +#StatementMacros: ["Q_UNUSED"] +#tab键盘的宽度 +TabWidth: 4 +UseTab: Never diff --git a/dde-file-manager-5.5.3/.clog.toml b/dde-file-manager-5.5.3/.clog.toml new file mode 100644 index 0000000..e84ad83 --- /dev/null +++ b/dde-file-manager-5.5.3/.clog.toml @@ -0,0 +1,4 @@ +[clog] +repository = "https://github.com/linuxdeepin/dde-file-manager" +changelog = "CHANGELOG.md" +from-latest-tag = true diff --git a/dde-file-manager-5.5.3/.gitignore b/dde-file-manager-5.5.3/.gitignore new file mode 100644 index 0000000..91ae1e6 --- /dev/null +++ b/dde-file-manager-5.5.3/.gitignore @@ -0,0 +1,65 @@ +# Compiled Object files +*.slo +*.lo +*.o +*.obj +.qmake.stash + +# Compiled Dynamic libraries +*.so +*.dylib + +# Compiled Static libraries +*.lai +*.la +*.a + +# Executables +*.exe +*.out +*.app +Makefile +Makefile.* +*.Debug +*.Release +*.rc +*.zip + +debug +release +build* + +*.pro.user +*.pro.user* +*.qm +*.autosave + +vendor/include/* +vendor/lib/* + +dde-sharefiles/lib/* +dde-sharefiles/tmp/* +dde-sharefiles/log/* + +NUL + +# Documents +doc/html/* + +tools + +dde-file-manager-lib/test_shutil/fileutils/fileutil_t1.txt + +dde-file-manager-lib/test_shutil/fileutils/fileutil_t2.txt + +dde-file-manager-lib/test_shutil/fileutils/jsonArry.json + +dde-file-manager-lib/test_shutil/fileutils/jsonObj.json + +dde-file-manager-lib/test_shutil/fileutils/sub/fileutil_file_new1.txt + +dde-file-manager-lib/test_shutil/new1.txt + +dde-file-manager-lib/test_shutil/new2.txt + +dde-file-manager-lib/test_shutil/property/oneProperty.pro diff --git a/dde-file-manager-5.5.3/.gitlab-ci.yml b/dde-file-manager-5.5.3/.gitlab-ci.yml new file mode 100644 index 0000000..3473c26 --- /dev/null +++ b/dde-file-manager-5.5.3/.gitlab-ci.yml @@ -0,0 +1,6 @@ +include: + - remote: 'https://gitlab.deepin.io/dev-tools/letmeci/raw/master/gitlab-ci/dde.yml' + +variables: + CPPCHECK: "true" + CODESPELL: "true" diff --git a/dde-file-manager-5.5.3/.pc/.quilt_patches b/dde-file-manager-5.5.3/.pc/.quilt_patches new file mode 100644 index 0000000..6857a8d --- /dev/null +++ b/dde-file-manager-5.5.3/.pc/.quilt_patches @@ -0,0 +1 @@ +debian/patches diff --git a/dde-file-manager-5.5.3/.pc/.quilt_series b/dde-file-manager-5.5.3/.pc/.quilt_series new file mode 100644 index 0000000..c206706 --- /dev/null +++ b/dde-file-manager-5.5.3/.pc/.quilt_series @@ -0,0 +1 @@ +series diff --git a/dde-file-manager-5.5.3/.pc/.version b/dde-file-manager-5.5.3/.pc/.version new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/dde-file-manager-5.5.3/.pc/.version @@ -0,0 +1 @@ +2 diff --git a/dde-file-manager-5.5.3/.pc/applied-patches b/dde-file-manager-5.5.3/.pc/applied-patches new file mode 100644 index 0000000..e69de29 diff --git a/dde-file-manager-5.5.3/.project.json b/dde-file-manager-5.5.3/.project.json new file mode 100644 index 0000000..a298e5d --- /dev/null +++ b/dde-file-manager-5.5.3/.project.json @@ -0,0 +1,6 @@ +{ + "type": "homebrew", + "3rdparty": [], + "ignore": ["debian", "translations", "*.lai", "*.la", "*.a", "*.theme", "*.json", "*.pri", "*.desktop", "*.out", "*.app", "Makefile", "Makefile.*", "*.Debug", "*.Release", "*.rc", "*.qrc", "*.zip", "*.qm", "*.user", ".vscode", "*.png", "*.svg", "*.ts", "*.xml", "*.service", "dde-file-manager-pkexec", "*.policy", "file-manager-daemon auto", "*.mimetype", "*.sh", "*.conf", "*.js", ".readme", "*.doc", "*.xls", "*.ppt", "*.txt", "*.qss", "*.ui", "*.mov", "*.qdocconf", "*.eot", "*.ttf", "*.woff", "*.css", "*.qdoc", "*.qdocinc", "*.md", "*.toml", "*.gitignore", "*.yml", "LICENCE"], + "license": ["GPLv3"] +} diff --git a/dde-file-manager-5.5.3/.qmake.conf b/dde-file-manager-5.5.3/.qmake.conf new file mode 100644 index 0000000..b59186b --- /dev/null +++ b/dde-file-manager-5.5.3/.qmake.conf @@ -0,0 +1,4 @@ +top_srcdir=$$PWD +top_builddir=$$shadowed($$PWD) + +ARCH = $$QMAKE_HOST.arch diff --git a/dde-file-manager-5.5.3/.tx/config b/dde-file-manager-5.5.3/.tx/config new file mode 100644 index 0000000..7f92782 --- /dev/null +++ b/dde-file-manager-5.5.3/.tx/config @@ -0,0 +1,56 @@ +[main] +host = https://www.transifex.com +minimum_perc = 80 +mode = developer + +[deepin-file-manager.dde-file-manager] +file_filter = src/dde-file-manager/translations/dde-file-manager-app_.ts +source_file = src/dde-file-manager/translations/dde-file-manager-app.ts +source_lang = en +type = QT + +[deepin-file-manager.dde-file-manager-lib] +file_filter = src/dde-file-manager-lib/translations/dde-file-manager_.ts +source_file = src/dde-file-manager-lib/translations/dde-file-manager.ts +source_lang = en +type = QT + +[deepin-file-manager.dde-disk-mount-plugin] +file_filter = src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_.ts +source_file = src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin.ts +source_lang = en +type = QT + +[deepin-file-manager.dde-desktop] +file_filter = src/dde-desktop/translations/dde-desktop_.ts +source_file = src/dde-desktop/translations/dde-desktop.ts +source_lang = en +type = QT + +[deepin-file-manager.dde-file-manager-desktop] +file_filter = src/dde-file-manager/translations/dde-file-manager-desktop/desktop_.ts +source_file = src/dde-file-manager/translations/dde-file-manager-desktop/desktop.ts +preTranslate_file = src/dde-file-manager/dde-file-manager.desktop +source_lang = en +type = QT + +[deepin-file-manager.dde-computer-desktop] +file_filter = src/dde-desktop/translations/dde-computer-desktop/desktop_.ts +source_file = src/dde-desktop/translations/dde-computer-desktop/desktop.ts +preTranslate_file = src/dde-desktop/data/applications/dde-computer.desktop +source_lang = en +type = QT + +[deepin-file-manager.dde-trash-desktop] +file_filter = src/dde-desktop/translations/dde-trash-desktop/desktop_.ts +source_file = src/dde-desktop/translations/dde-trash-desktop/desktop.ts +preTranslate_file = src/dde-desktop/data/applications/dde-trash.desktop +source_lang = en +type = QT + +[deepin-file-manager.dde-home-desktop] +file_filter = src/dde-desktop/translations/dde-home-desktop/desktop_.ts +source_file = src/dde-desktop/translations/dde-home-desktop/desktop.ts +preTranslate_file = src/dde-desktop/data/applications/dde-home.desktop +source_lang = en +type = QT diff --git a/dde-file-manager-5.5.3/3rdparty/accessibility/accessibility-suite.pri b/dde-file-manager-5.5.3/3rdparty/accessibility/accessibility-suite.pri new file mode 100644 index 0000000..b6c7063 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/accessibility/accessibility-suite.pri @@ -0,0 +1,14 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-06-24T09:14:17 +# +#------------------------------------------------- + +INCLUDEPATH += $$PWD + + +HEADERS += \ + $$PWD/acframefunctions.h \ + +SOURCES += \ + diff --git a/dde-file-manager-5.5.3/3rdparty/accessibility/acframefunctions.h b/dde-file-manager-5.5.3/3rdparty/accessibility/acframefunctions.h new file mode 100644 index 0000000..f33f595 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/accessibility/acframefunctions.h @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef ACCESSIBLE_FUNCTIONS_H +#define ACCESSIBLE_FUNCTIONS_H + +// 为了方便使用,把相关定义独立出来,如有需要,直接包含这个头文件,然后使用SET_*的宏去设置,USE_*宏开启即可 +/* 宏参数说明 +* classname:类名,例如DLineEdit +* accessiblename:accessible唯一标识,需保证唯一性[getAccessibleName函数处理],优先使用QObject::setAccessibleName值 +* accessibletype:即QAccessible::Role,表示标识控件的类型 +* classobj:QObject指针 +* accessdescription:accessible描述内容,考虑到暂时用不到,目前都默认为空,有需要可自行设计接口 +* +* 部分创建宏说明 +* FUNC_CREATE:创建构造函数 +* FUNC_PRESS:创建Press接口 +* FUNC_SHOWMENU:创建右键菜单接口 +* FUNC_PRESS_SHOWMENU:上两者的综合 +* FUNC_RECT:实现rect接口 +* FUNC_TEXT:实现text接口 +* USE_ACCESSIBLE:对传入的类型设置其accessible功能 +* USE_ACCESSIBLE_BY_OBJECTNAME:同上,[指定objectname]---适用同一个类,但objectname不同的情况 +* +* 设置为指定类型的Accessible控件宏 +* SET_BUTTON_ACCESSIBLE_PRESS_SHOWMENU:button类型,添加press和showmenu功能 +* SET_BUTTON_ACCESSIBLE_SHOWMENU:button类型,添加showmenu功能 +* SET_BUTTON_ACCESSIBLE:button类型,添加press功能 +* SET_LABEL_ACCESSIBLE:label类型,用于标签控件 +* SET_FORM_ACCESSIBLE:form类型,用于widget控件 +* SET_SLIDER_ACCESSIBLE:slider类型,用于滑块控件 +* SET_SEPARATOR_ACCESSIBLE:separator类型,用于分隔符控件 +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEPARATOR "_" + +inline QString getObjPrefix(QAccessible::Role r) +{ + // 按照类型添加固定前缀 + QMetaEnum metaEnum = QMetaEnum::fromType(); + QByteArray prefix = metaEnum.valueToKeys(r); + switch (r) { + case QAccessible::Button: prefix = "Btn"; break; + case QAccessible::StaticText: prefix = "Label"; break; + default: break; + } + return QString::fromLatin1(prefix); +} + +inline QString getIntelAccessibleName(QWidget *w, QAccessible::Role r, QString fallback) +{ + // 避免重复生成 + static QMap< QObject *, QString > objnameMap; + if (!objnameMap[w].isEmpty()) + return objnameMap[w]; + + static QMap< QAccessible::Role, QList< QString > > accessibleMap; + QString oldAccessName = w->accessibleName(); + oldAccessName.replace(SEPARATOR, ""); + + // 再加上标识 + QString accessibleName = "";//getObjPrefix(r) + SEPARATOR; + accessibleName += oldAccessName.isEmpty() ? fallback : oldAccessName; + // 检查名称是否唯一 + if (accessibleMap[r].contains(accessibleName)) { + if (objnameMap.key(accessibleName)) { + objnameMap.remove(objnameMap.key(accessibleName)); + objnameMap.insert(w, accessibleName); + return accessibleName; + } + // 获取编号,然后+1 + int pos = accessibleName.indexOf(SEPARATOR); + int id = accessibleName.mid(pos + 1).toInt(); + + QString newAccessibleName; + do { + // 一直找到一个不重复的名字 + newAccessibleName = accessibleName + SEPARATOR + QString::number(++id); + } while (accessibleMap[r].contains(newAccessibleName)); + + accessibleMap[r].append(newAccessibleName); + objnameMap.insert(w, newAccessibleName); + + return newAccessibleName; + } else { + accessibleMap[r].append(accessibleName); + objnameMap.insert(w, accessibleName); + + return accessibleName; + } +} + +inline QString getAccessibleName(QWidget *w, QAccessible::Role r, QString fallback) +{ + QString accessibleName = getIntelAccessibleName(w, r, fallback); + if(accessibleName.isEmpty()) + { + return getObjPrefix(r) + SEPARATOR; + } + + return accessibleName; +} + +#define FUNC_CREATE(classname,accessibletype,accessdescription) Accessible##classname(classname *w) \ + : QAccessibleWidget(w,accessibletype,#classname)\ + , m_w(w)\ + , m_description(accessdescription)\ +{}\ + private:\ + classname *m_w;\ + QString m_description;\ + +#define FUNC_PRESS(classobj) QStringList actionNames() const override{\ + if(!classobj->isEnabled())\ + return QStringList();\ + return QStringList() << pressAction();}\ + void doAction(const QString &actionName) override{\ + if(actionName == pressAction())\ +{\ + QPointF localPos = classobj->geometry().center();\ + QMouseEvent event(QEvent::MouseButtonPress,localPos,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);\ + QMouseEvent event2(QEvent::MouseButtonRelease,localPos,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);\ + qApp->sendEvent(classobj,&event);\ + qApp->sendEvent(classobj,&event2);\ + }\ + }\ + +#define FUNC_SHOWMENU(classobj) QStringList actionNames() const override{\ + if(!classobj->isEnabled())\ + return QStringList();\ + return QStringList() << showMenuAction();}\ + void doAction(const QString &actionName) override{\ + if(actionName == showMenuAction())\ +{\ + QPointF localPos = classobj->geometry().center();\ + QMouseEvent event(QEvent::MouseButtonPress,localPos,Qt::RightButton,Qt::RightButton,Qt::NoModifier);\ + QMouseEvent event2(QEvent::MouseButtonRelease,localPos,Qt::RightButton,Qt::RightButton,Qt::NoModifier);\ + qApp->sendEvent(classobj,&event);\ + qApp->sendEvent(classobj,&event2);\ + }\ + }\ + +#define FUNC_PRESS_SHOWMENU(classobj) QStringList actionNames() const override{\ + if(!classobj->isEnabled())\ + return QStringList();\ + return QStringList() << pressAction() << showMenuAction();}\ + void doAction(const QString &actionName) override{\ + if(actionName == pressAction())\ +{\ + QPointF localPos = classobj->geometry().center();\ + QMouseEvent event(QEvent::MouseButtonPress,localPos,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);\ + QMouseEvent event2(QEvent::MouseButtonRelease,localPos,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);\ + qApp->sendEvent(classobj,&event);\ + qApp->sendEvent(classobj,&event2);\ + }\ + else if(actionName == showMenuAction())\ +{\ + QPointF localPos = classobj->geometry().center();\ + QMouseEvent event(QEvent::MouseButtonPress,localPos,Qt::RightButton,Qt::RightButton,Qt::NoModifier);\ + QMouseEvent event2(QEvent::MouseButtonRelease,localPos,Qt::RightButton,Qt::RightButton,Qt::NoModifier);\ + qApp->sendEvent(classobj,&event);\ + qApp->sendEvent(classobj,&event2);\ + }\ + }\ + +#define FUNC_RECT(classobj) QRect rect() const override{\ + if (!classobj->isVisible())\ + return QRect();\ + return classobj->geometry();\ + }\ + +#define FUNC_TEXT(classname,accessiblename) QString Accessible##classname::text(QAccessible::Text t) const{\ + switch (t) {\ + case QAccessible::Name:\ + return getAccessibleName(m_w, this->role(), accessiblename);\ + case QAccessible::Description:\ + return m_description;\ + default:\ + return QString();\ + }\ + }\ + +#define USE_ACCESSIBLE(classnamestring,classname) if (classnamestring == QLatin1String(#classname) && object && object->isWidgetType())\ +{\ + interface = new Accessible##classname(static_cast(object));\ + }\ + +// [指定objectname]---适用同一个类,但objectname不同的情况 +#define USE_ACCESSIBLE_BY_OBJECTNAME(classnamestring,classname,objectname) if (classnamestring == QLatin1String(#classname) && object && (object->objectName() == objectname) && object->isWidgetType())\ +{\ + interface = new Accessible##classname(static_cast(object));\ + }\ + +#define SET_BUTTON_ACCESSIBLE_PRESS_DESCRIPTION(classname,accessiblename,accessdescription) class Accessible##classname : public QAccessibleWidget\ +{\ + public:\ + FUNC_CREATE(classname,QAccessible::Button,accessdescription)\ + QString text(QAccessible::Text t) const override;\ + FUNC_PRESS(m_w)\ + };\ + +#define SET_BUTTON_ACCESSIBLE_SHOWMENU_DESCRIPTION(classname,accessiblename,accessdescription) class Accessible##classname : public QAccessibleWidget\ +{\ + public:\ + FUNC_CREATE(classname,QAccessible::Button,accessdescription)\ + QString text(QAccessible::Text t) const override;\ + FUNC_SHOWMENU(m_w)\ + };\ + +#define SET_BUTTON_ACCESSIBLE_PRESS_SHOEMENU_DESCRIPTION(classname,accessiblename,accessdescription) class Accessible##classname : public QAccessibleWidget\ +{\ + public:\ + FUNC_CREATE(classname,QAccessible::Button,accessdescription)\ + QString text(QAccessible::Text t) const override;\ + FUNC_PRESS_SHOWMENU(m_w)\ + };\ + +#define SET_LABEL_ACCESSIBLE_WITH_DESCRIPTION(classname,aaccessibletype,accessiblename,accessdescription) class Accessible##classname : public QAccessibleWidget\ +{\ + public:\ + FUNC_CREATE(classname,aaccessibletype,accessdescription)\ + QString text(QAccessible::Text t) const override;\ + FUNC_RECT(m_w)\ + };\ + +// /*******************************************简化使用*******************************************/ +#define SET_BUTTON_ACCESSIBLE_PRESS_SHOWMENU(classname,accessiblename) SET_BUTTON_ACCESSIBLE_PRESS_SHOEMENU_DESCRIPTION(classname,accessiblename,"")\ + FUNC_TEXT(classname,accessiblename) + +#define SET_BUTTON_ACCESSIBLE_SHOWMENU(classname,accessiblename) SET_BUTTON_ACCESSIBLE_SHOWMENU_DESCRIPTION(classname,accessiblename,"")\ + FUNC_TEXT(classname,accessiblename) + +#define SET_BUTTON_ACCESSIBLE(classname,accessiblename) SET_BUTTON_ACCESSIBLE_PRESS_DESCRIPTION(classname,accessiblename,"")\ + FUNC_TEXT(classname,accessiblename) + +#define SET_LABEL_ACCESSIBLE(classname,accessiblename) SET_LABEL_ACCESSIBLE_WITH_DESCRIPTION(classname,QAccessible::StaticText,accessiblename,"")\ + FUNC_TEXT(classname,accessiblename) + +#define SET_FORM_ACCESSIBLE(classname,accessiblename) SET_LABEL_ACCESSIBLE_WITH_DESCRIPTION(classname,QAccessible::Form,accessiblename,"");\ + FUNC_TEXT(classname,accessiblename) + +#define SET_SLIDER_ACCESSIBLE(classname,accessiblename) SET_LABEL_ACCESSIBLE_WITH_DESCRIPTION(classname,QAccessible::Slider,accessiblename,"")\ + FUNC_TEXT(classname,accessiblename) + +#define SET_SEPARATOR_ACCESSIBLE(classname,accessiblename) SET_LABEL_ACCESSIBLE_WITH_DESCRIPTION(classname,QAccessible::Separator,accessiblename,"")\ + FUNC_TEXT(classname,accessiblename) +/************************************************************************************************/ + +#endif // ACCESSIBLE_FUNCTIONS_H diff --git a/dde-file-manager-5.5.3/3rdparty/cpp-stub/addr_any.h b/dde-file-manager-5.5.3/3rdparty/cpp-stub/addr_any.h new file mode 100644 index 0000000..a153f34 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/cpp-stub/addr_any.h @@ -0,0 +1,280 @@ +#ifndef __ADDR_ANY_H__ +#define __ADDR_ANY_H__ + + +//linux +#include +#include +//c +#include +#include +#include + +//c++ +#include +#include +//project +#include "elfio.hpp" + + + +class AddrAny +{ +public: + AddrAny() + { + m_init = get_exe_pathname(m_fullname); + m_baseaddr = 0; + } + AddrAny(std::string libname) + { + m_init = get_lib_pathname_and_baseaddr(libname, m_fullname, m_baseaddr); + } + + int get_local_func_addr_symtab(std::string func_name_regex_str, std::map& result) + { + return get_func_addr(SHT_SYMTAB, STB_LOCAL, func_name_regex_str, result); + } + int get_global_func_addr_symtab(std::string func_name_regex_str, std::map& result) + { + return get_func_addr(SHT_SYMTAB, STB_GLOBAL, func_name_regex_str, result); + } + int get_weak_func_addr_symtab(std::string func_name_regex_str, std::map& result) + { + return get_func_addr(SHT_SYMTAB, STB_WEAK, func_name_regex_str, result); + } + + int get_global_func_addr_dynsym( std::string func_name_regex_str, std::map& result) + { + return get_func_addr(SHT_DYNSYM, STB_GLOBAL, func_name_regex_str, result); + } + int get_weak_func_addr_dynsym(std::string func_name_regex_str, std::map& result) + { + return get_func_addr(SHT_DYNSYM, STB_WEAK, func_name_regex_str, result); + } + +private: + bool demangle(std::string& s, std::string& name) { + int status; + char* pname = abi::__cxa_demangle(s.c_str(), 0, 0, &status); + if (status != 0) + { + switch(status) + { + case -1: name = "memory allocation error"; break; + case -2: name = "invalid name given"; break; + case -3: name = "internal error: __cxa_demangle: invalid argument"; break; + default: name = "unknown error occured"; break; + } + return false; + } + name = pname; + free(pname); + return true; + } + bool get_exe_pathname( std::string& name) + { + char line[512]; + FILE *fp; + uintptr_t base_addr; + char perm[5]; + unsigned long offset; + int pathname_pos; + char *pathname; + size_t pathname_len; + int match = 0; + + if(NULL == (fp = fopen("/proc/self/maps", "r"))) + { + return false; + } + + while(fgets(line, sizeof(line), fp)) + { + if(sscanf(line, "%" PRIxPTR "-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue; + + if(0 != offset) continue; + + //get pathname + while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1)) + pathname_pos += 1; + if(pathname_pos >= (int)(sizeof(line) - 1)) continue; + pathname = line + pathname_pos; + pathname_len = strlen(pathname); + if(0 == pathname_len) continue; + if(pathname[pathname_len - 1] == '\n') + { + pathname[pathname_len - 1] = '\0'; + pathname_len -= 1; + } + if(0 == pathname_len) continue; + if('[' == pathname[0]) continue; + + name = pathname; + match = 1; + break; + + } + fclose(fp); + + if(0 == match) + { + return false; + } + else + { + return true; + } + + } + + bool get_lib_pathname_and_baseaddr(std::string pathname_regex_str, std::string& name, unsigned long& addr) + { + char line[512]; + FILE *fp; + uintptr_t base_addr; + char perm[5]; + unsigned long offset; + int pathname_pos; + char *pathname; + size_t pathname_len; + int match; + regex_t pathname_regex; + + regcomp(&pathname_regex, pathname_regex_str.c_str(), 0); + + if(NULL == (fp = fopen("/proc/self/maps", "r"))) + { + return false; + } + + while(fgets(line, sizeof(line), fp)) + { + if(sscanf(line, "%" PRIxPTR "-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue; + + //check permission + if(perm[0] != 'r') continue; + if(perm[3] != 'p') continue; //do not touch the shared memory + + //check offset + // + //We are trying to find ELF header in memory. + //It can only be found at the beginning of a mapped memory regions + //whose offset is 0. + if(0 != offset) continue; + + //get pathname + while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1)) + pathname_pos += 1; + if(pathname_pos >= (int)(sizeof(line) - 1)) continue; + pathname = line + pathname_pos; + pathname_len = strlen(pathname); + if(0 == pathname_len) continue; + if(pathname[pathname_len - 1] == '\n') + { + pathname[pathname_len - 1] = '\0'; + pathname_len -= 1; + } + if(0 == pathname_len) continue; + if('[' == pathname[0]) continue; + + //check pathname + //if we need to hook this elf? + match = 0; + if(0 == regexec(&pathname_regex, pathname, 0, NULL, 0)) + { + match = 1; + name = pathname; + addr = (unsigned long)base_addr; + break; + } + if(0 == match) continue; + + } + fclose(fp); + if(0 == match) + { + return false; + } + else + { + return true; + } + + } + + int get_func_addr(unsigned int ttype, unsigned int stype, std::string& func_name_regex_str, std::map& result) + { + // Create an elfio reader + ELFIO::elfio reader; + int count = 0; + regex_t pathname_regex; + + if(!m_init) + { + return -1; + } + + regcomp(&pathname_regex, func_name_regex_str.c_str(), 0); + // Load ELF data + if(!reader.load(m_fullname.c_str())) + { + return -1; + } + + ELFIO::Elf_Half sec_num = reader.sections.size(); + for(int i = 0; i < sec_num; ++i) + { + ELFIO::section* psec = reader.sections[i]; + // Check section type + if(psec->get_type() == ttype) + { + const ELFIO::symbol_section_accessor symbols( reader, psec ); + for ( unsigned int j = 0; j < symbols.get_symbols_num(); ++j ) + { + std::string name; + std::string name_mangle; + ELFIO::Elf64_Addr value; + ELFIO::Elf_Xword size; + unsigned char bind; + unsigned char type; + ELFIO::Elf_Half section_index; + unsigned char other; + + // Read symbol properties + symbols.get_symbol( j, name, value, size, bind, type, section_index, other ); + if(type == STT_FUNC && bind == stype) + { + bool ret = demangle(name,name_mangle); + if(ret == true) + { + if (0 == regexec(&pathname_regex, name_mangle.c_str(), 0, NULL, 0)) + { + result.insert ( std::pair(name_mangle,(void*)(value + m_baseaddr))); + count++; + } + } + else + { + if (0 == regexec(&pathname_regex, name.c_str(), 0, NULL, 0)) + { + result.insert ( std::pair(name,(void*)(value + m_baseaddr))); + count++; + } + } + } + } + break; + } + } + + return count; + } +private: + bool m_init; + std::string m_name; + std::string m_fullname; + unsigned long m_baseaddr; + +}; +#endif diff --git a/dde-file-manager-5.5.3/3rdparty/cpp-stub/addr_pri.h b/dde-file-manager-5.5.3/3rdparty/cpp-stub/addr_pri.h new file mode 100644 index 0000000..9174bb0 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/cpp-stub/addr_pri.h @@ -0,0 +1,177 @@ +#ifndef __ADDR_PRI_H__ +#define __ADDR_PRI_H__ + + +#include +#include + + + +//base on C++11 + +/********************************************************** + access private function +**********************************************************/ + + +namespace std { + template + using enable_if_t = typename enable_if::type; + template + using remove_reference_t = typename remove_reference::type; +} // std + +// Unnamed namespace is used to avoid duplicate symbols if the macros are used +namespace { + namespace private_access_detail { + + // @tparam TagType, used to declare different "get" funciton overloads for + // different members/statics + template + struct private_access { + // Normal lookup cannot find in-class defined (inline) friend functions. + friend PtrType get(TagType) { return PtrValue; } + }; + + } // namespace private_access_detail +} // namespace + +// Used macro naming conventions: +// The "namespace" of this macro library is PRIVATE_ACCESS, i.e. all +// macro here has this prefix. +// All implementation macro, which are not meant to be used directly have the +// PRIVATE_ACCESS_DETAIL prefix. +// Some macros have the ABCD_IMPL form, which means they contain the +// implementation details for the specific ABCD macro. + +#define PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y) x##y +#define PRIVATE_ACCESS_DETAIL_CONCATENATE(x, y) \ + PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y) + +// @param PtrTypeKind E.g if we have "class A", then it can be "A::*" in case of +// members, or it can be "*" in case of statics. +#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, \ + PtrTypeKind) \ + namespace { \ + namespace private_access_detail { \ + /* Tag type, used to declare different get funcitons for different \ + * members \ + */ \ + struct Tag {}; \ + /* Explicit instantiation */ \ + template struct private_access; \ + /* We can build the PtrType only with two aliases */ \ + /* E.g. using PtrType = int(int) *; would be illformed */ \ + using PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) = Type; \ + using PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) = \ + PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) PtrTypeKind; \ + /* Declare the friend function, now it is visible in namespace scope. \ + * Note, \ + * we could declare it inside the Tag type too, in that case ADL would \ + * find \ + * the declaration. By choosing to declare it here, the Tag type remains \ + * a \ + * simple tag type, it has no other responsibilities. */ \ + PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) get(Tag); \ + } \ + } + +#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(Tag, Class, Type, Name) \ + PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*) \ + namespace { \ + namespace access_private_field { \ + Type &Class##Name(Class &&t) { return t.*get(private_access_detail::Tag{}); } \ + Type &Class##Name(Class &t) { return t.*get(private_access_detail::Tag{}); } \ + /* The following usings are here to avoid duplicate const qualifier \ + * warnings \ + */ \ + using PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag) = Type; \ + using PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) = \ + const PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag); \ + PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) & Class##Name(const Class &t) {\ + return t.*get(private_access_detail::Tag{}); \ + } \ + } \ + } + +#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(Tag, Class, Type, Name) \ + PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*) \ + namespace { \ + namespace call_private_fun { \ + /* We do perfect forwarding, but we want to restrict the overload set \ + * only for objects which have the type Class. */ \ + template , \ + Class>::value> * = nullptr, \ + typename... Args> \ + auto Class##Name(Obj &&o, Args &&... args) -> decltype( \ + (std::forward(o).* \ + get(private_access_detail::Tag{}))(std::forward(args)...)) { \ + return (std::forward(o).*get(private_access_detail::Tag{}))( \ + std::forward(args)...); \ + } \ + } \ + namespace get_private_fun { \ + auto Class##Name() -> decltype( \ + get(private_access_detail::Tag{})) { \ + return (get(private_access_detail::Tag{})); \ + } \ + } \ + } + +#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD(Tag, Class, Type, \ + Name) \ + PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *) \ + namespace { \ + namespace access_private_static_field { \ + namespace Class { \ + Type &Class##Name() { return *get(private_access_detail::Tag{}); } \ + } \ + } \ + } + +#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN(Tag, Class, Type, \ + Name) \ + PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *) \ + namespace { \ + namespace call_private_static_fun { \ + namespace Class { \ + template \ + auto Class##Name(Args &&... args) -> decltype( \ + get(private_access_detail::Tag{})(std::forward(args)...)) { \ + return get(private_access_detail::Tag{})( \ + std::forward(args)...); \ + } \ + } \ + } \ + namespace get_private_static_fun { \ + namespace Class { \ + auto Class##Name() -> decltype(get(private_access_detail::Tag{})) { \ + return get(private_access_detail::Tag{}); \ + } \ + } \ + } \ + } + +#define PRIVATE_ACCESS_DETAIL_UNIQUE_TAG \ + PRIVATE_ACCESS_DETAIL_CONCATENATE(PrivateAccessTag, __COUNTER__) + +#define ACCESS_PRIVATE_FIELD(Class, Type, Name) \ + PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \ + Class, Type, Name) + +#define ACCESS_PRIVATE_FUN(Class, Type, Name) \ + PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \ + Class, Type, Name) + +#define ACCESS_PRIVATE_STATIC_FIELD(Class, Type, Name) \ + Type Class::Name; \ + PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD( \ + PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name) + +#define ACCESS_PRIVATE_STATIC_FUN(Class, Type, Name) \ + PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN( \ + PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name) + +#endif diff --git a/dde-file-manager-5.5.3/3rdparty/cpp-stub/elfio.hpp b/dde-file-manager-5.5.3/3rdparty/cpp-stub/elfio.hpp new file mode 100644 index 0000000..dd5c9ae --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/cpp-stub/elfio.hpp @@ -0,0 +1,4888 @@ + +/*** Start of inlined file: elfio_dump.hpp ***/ +#ifndef ELFIO_DUMP_HPP +#define ELFIO_DUMP_HPP + +#include +#include +#include +#include +#include + +/*** Start of inlined file: elfio.hpp ***/ +#ifndef ELFIO_HPP +#define ELFIO_HPP + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4996 ) +#pragma warning( disable : 4355 ) +#pragma warning( disable : 4244 ) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + + +/*** Start of inlined file: elf_types.hpp ***/ +#ifndef ELFTYPES_H +#define ELFTYPES_H + +#ifndef ELFIO_NO_OWN_TYPES +#if !defined( ELFIO_NO_CSTDINT ) && !defined( ELFIO_NO_INTTYPES ) +#include +#else +typedef unsigned char uint8_t; +typedef signed char int8_t; +typedef unsigned short uint16_t; +typedef signed short int16_t; +#ifdef _MSC_VER +typedef unsigned __int32 uint32_t; +typedef signed __int32 int32_t; +typedef unsigned __int64 uint64_t; +typedef signed __int64 int64_t; +#else +typedef unsigned int uint32_t; +typedef signed int int32_t; +typedef unsigned long long uint64_t; +typedef signed long long int64_t; +#endif // _MSC_VER +#endif // ELFIO_NO_CSTDINT +#endif // ELFIO_NO_OWN_TYPES + +namespace ELFIO { + +// Attention! Platform depended definitions. +typedef uint16_t Elf_Half; +typedef uint32_t Elf_Word; +typedef int32_t Elf_Sword; +typedef uint64_t Elf_Xword; +typedef int64_t Elf_Sxword; + +typedef uint32_t Elf32_Addr; +typedef uint32_t Elf32_Off; +typedef uint64_t Elf64_Addr; +typedef uint64_t Elf64_Off; + +#define Elf32_Half Elf_Half +#define Elf64_Half Elf_Half +#define Elf32_Word Elf_Word +#define Elf64_Word Elf_Word +#define Elf32_Sword Elf_Sword +#define Elf64_Sword Elf_Sword + +/////////////////////// +// ELF Header Constants + +// File type +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define ET_LOOS 0xFE00 +#define ET_HIOS 0xFEFF +#define ET_LOPROC 0xFF00 +#define ET_HIPROC 0xFFFF + +#define EM_NONE 0 // No machine +#define EM_M32 1 // AT&T WE 32100 +#define EM_SPARC 2 // SUN SPARC +#define EM_386 3 // Intel 80386 +#define EM_68K 4 // Motorola m68k family +#define EM_88K 5 // Motorola m88k family +#define EM_486 6 // Intel 80486// Reserved for future use +#define EM_860 7 // Intel 80860 +#define EM_MIPS 8 // MIPS R3000 (officially, big-endian only) +#define EM_S370 9 // IBM System/370 +#define EM_MIPS_RS3_LE \ + 10 // MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated +#define EM_res011 11 // Reserved +#define EM_res012 12 // Reserved +#define EM_res013 13 // Reserved +#define EM_res014 14 // Reserved +#define EM_PARISC 15 // HPPA +#define EM_res016 16 // Reserved +#define EM_VPP550 17 // Fujitsu VPP500 +#define EM_SPARC32PLUS 18 // Sun's "v8plus" +#define EM_960 19 // Intel 80960 +#define EM_PPC 20 // PowerPC +#define EM_PPC64 21 // 64-bit PowerPC +#define EM_S390 22 // IBM S/390 +#define EM_SPU 23 // Sony/Toshiba/IBM SPU +#define EM_res024 24 // Reserved +#define EM_res025 25 // Reserved +#define EM_res026 26 // Reserved +#define EM_res027 27 // Reserved +#define EM_res028 28 // Reserved +#define EM_res029 29 // Reserved +#define EM_res030 30 // Reserved +#define EM_res031 31 // Reserved +#define EM_res032 32 // Reserved +#define EM_res033 33 // Reserved +#define EM_res034 34 // Reserved +#define EM_res035 35 // Reserved +#define EM_V800 36 // NEC V800 series +#define EM_FR20 37 // Fujitsu FR20 +#define EM_RH32 38 // TRW RH32 +#define EM_MCORE 39 // Motorola M*Core // May also be taken by Fujitsu MMA +#define EM_RCE 39 // Old name for MCore +#define EM_ARM 40 // ARM +#define EM_OLD_ALPHA 41 // Digital Alpha +#define EM_SH 42 // Renesas (formerly Hitachi) / SuperH SH +#define EM_SPARCV9 43 // SPARC v9 64-bit +#define EM_TRICORE 44 // Siemens Tricore embedded processor +#define EM_ARC 45 // ARC Cores +#define EM_H8_300 46 // Renesas (formerly Hitachi) H8/300 +#define EM_H8_300H 47 // Renesas (formerly Hitachi) H8/300H +#define EM_H8S 48 // Renesas (formerly Hitachi) H8S +#define EM_H8_500 49 // Renesas (formerly Hitachi) H8/500 +#define EM_IA_64 50 // Intel IA-64 Processor +#define EM_MIPS_X 51 // Stanford MIPS-X +#define EM_COLDFIRE 52 // Motorola Coldfire +#define EM_68HC12 53 // Motorola M68HC12 +#define EM_MMA 54 // Fujitsu Multimedia Accelerator +#define EM_PCP 55 // Siemens PCP +#define EM_NCPU 56 // Sony nCPU embedded RISC processor +#define EM_NDR1 57 // Denso NDR1 microprocesspr +#define EM_STARCORE 58 // Motorola Star*Core processor +#define EM_ME16 59 // Toyota ME16 processor +#define EM_ST100 60 // STMicroelectronics ST100 processor +#define EM_TINYJ 61 // Advanced Logic Corp. TinyJ embedded processor +#define EM_X86_64 62 // Advanced Micro Devices X86-64 processor +#define EM_PDSP 63 // Sony DSP Processor +#define EM_PDP10 64 // Digital Equipment Corp. PDP-10 +#define EM_PDP11 65 // Digital Equipment Corp. PDP-11 +#define EM_FX66 66 // Siemens FX66 microcontroller +#define EM_ST9PLUS 67 // STMicroelectronics ST9+ 8/16 bit microcontroller +#define EM_ST7 68 // STMicroelectronics ST7 8-bit microcontroller +#define EM_68HC16 69 // Motorola MC68HC16 Microcontroller +#define EM_68HC11 70 // Motorola MC68HC11 Microcontroller +#define EM_68HC08 71 // Motorola MC68HC08 Microcontroller +#define EM_68HC05 72 // Motorola MC68HC05 Microcontroller +#define EM_SVX 73 // Silicon Graphics SVx +#define EM_ST19 74 // STMicroelectronics ST19 8-bit cpu +#define EM_VAX 75 // Digital VAX +#define EM_CRIS 76 // Axis Communications 32-bit embedded processor +#define EM_JAVELIN 77 // Infineon Technologies 32-bit embedded cpu +#define EM_FIREPATH 78 // Element 14 64-bit DSP processor +#define EM_ZSP 79 // LSI Logic's 16-bit DSP processor +#define EM_MMIX 80 // Donald Knuth's educational 64-bit processor +#define EM_HUANY 81 // Harvard's machine-independent format +#define EM_PRISM 82 // SiTera Prism +#define EM_AVR 83 // Atmel AVR 8-bit microcontroller +#define EM_FR30 84 // Fujitsu FR30 +#define EM_D10V 85 // Mitsubishi D10V +#define EM_D30V 86 // Mitsubishi D30V +#define EM_V850 87 // NEC v850 +#define EM_M32R 88 // Renesas M32R (formerly Mitsubishi M32R) +#define EM_MN10300 89 // Matsushita MN10300 +#define EM_MN10200 90 // Matsushita MN10200 +#define EM_PJ 91 // picoJava +#define EM_OPENRISC 92 // OpenRISC 32-bit embedded processor +#define EM_ARC_A5 93 // ARC Cores Tangent-A5 +#define EM_XTENSA 94 // Tensilica Xtensa Architecture +#define EM_VIDEOCORE 95 // Alphamosaic VideoCore processor +#define EM_TMM_GPP 96 // Thompson Multimedia General Purpose Processor +#define EM_NS32K 97 // National Semiconductor 32000 series +#define EM_TPC 98 // Tenor Network TPC processor +#define EM_SNP1K 99 // Trebia SNP 1000 processor +#define EM_ST200 100 // STMicroelectronics ST200 microcontroller +#define EM_IP2K 101 // Ubicom IP2022 micro controller +#define EM_MAX 102 // MAX Processor +#define EM_CR 103 // National Semiconductor CompactRISC +#define EM_F2MC16 104 // Fujitsu F2MC16 +#define EM_MSP430 105 // TI msp430 micro controller +#define EM_BLACKFIN 106 // ADI Blackfin +#define EM_SE_C33 107 // S1C33 Family of Seiko Epson processors +#define EM_SEP 108 // Sharp embedded microprocessor +#define EM_ARCA 109 // Arca RISC Microprocessor +#define EM_UNICORE \ + 110 // Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University +#define EM_EXCESS 111 // eXcess: 16/32/64-bit configurable embedded CPU +#define EM_DXP 112 // Icera Semiconductor Inc. Deep Execution Processor +#define EM_ALTERA_NIOS2 113 // Altera Nios II soft-core processor +#define EM_CRX 114 // National Semiconductor CRX +#define EM_XGATE 115 // Motorola XGATE embedded processor +#define EM_C166 116 // Infineon C16x/XC16x processor +#define EM_M16C 117 // Renesas M16C series microprocessors +#define EM_DSPIC30F \ + 118 // Microchip Technology dsPIC30F Digital Signal Controller +#define EM_CE 119 // Freescale Communication Engine RISC core +#define EM_M32C 120 // Renesas M32C series microprocessors +#define EM_res121 121 // Reserved +#define EM_res122 122 // Reserved +#define EM_res123 123 // Reserved +#define EM_res124 124 // Reserved +#define EM_res125 125 // Reserved +#define EM_res126 126 // Reserved +#define EM_res127 127 // Reserved +#define EM_res128 128 // Reserved +#define EM_res129 129 // Reserved +#define EM_res130 130 // Reserved +#define EM_TSK3000 131 // Altium TSK3000 core +#define EM_RS08 132 // Freescale RS08 embedded processor +#define EM_res133 133 // Reserved +#define EM_ECOG2 134 // Cyan Technology eCOG2 microprocessor +#define EM_SCORE 135 // Sunplus Score +#define EM_SCORE7 135 // Sunplus S+core7 RISC processor +#define EM_DSP24 136 // New Japan Radio (NJR) 24-bit DSP Processor +#define EM_VIDEOCORE3 137 // Broadcom VideoCore III processor +#define EM_LATTICEMICO32 138 // RISC processor for Lattice FPGA architecture +#define EM_SE_C17 139 // Seiko Epson C17 family +#define EM_TI_C6000 140 // Texas Instruments TMS320C6000 DSP family +#define EM_TI_C2000 141 // Texas Instruments TMS320C2000 DSP family +#define EM_TI_C5500 142 // Texas Instruments TMS320C55x DSP family +#define EM_res143 143 // Reserved +#define EM_res144 144 // Reserved +#define EM_res145 145 // Reserved +#define EM_res146 146 // Reserved +#define EM_res147 147 // Reserved +#define EM_res148 148 // Reserved +#define EM_res149 149 // Reserved +#define EM_res150 150 // Reserved +#define EM_res151 151 // Reserved +#define EM_res152 152 // Reserved +#define EM_res153 153 // Reserved +#define EM_res154 154 // Reserved +#define EM_res155 155 // Reserved +#define EM_res156 156 // Reserved +#define EM_res157 157 // Reserved +#define EM_res158 158 // Reserved +#define EM_res159 159 // Reserved +#define EM_MMDSP_PLUS 160 // STMicroelectronics 64bit VLIW Data Signal Processor +#define EM_CYPRESS_M8C 161 // Cypress M8C microprocessor +#define EM_R32C 162 // Renesas R32C series microprocessors +#define EM_TRIMEDIA 163 // NXP Semiconductors TriMedia architecture family +#define EM_QDSP6 164 // QUALCOMM DSP6 Processor +#define EM_8051 165 // Intel 8051 and variants +#define EM_STXP7X 166 // STMicroelectronics STxP7x family +#define EM_NDS32 \ + 167 // Andes Technology compact code size embedded RISC processor family +#define EM_ECOG1 168 // Cyan Technology eCOG1X family +#define EM_ECOG1X 168 // Cyan Technology eCOG1X family +#define EM_MAXQ30 169 // Dallas Semiconductor MAXQ30 Core Micro-controllers +#define EM_XIMO16 170 // New Japan Radio (NJR) 16-bit DSP Processor +#define EM_MANIK 171 // M2000 Reconfigurable RISC Microprocessor +#define EM_CRAYNV2 172 // Cray Inc. NV2 vector architecture +#define EM_RX 173 // Renesas RX family +#define EM_METAG 174 // Imagination Technologies META processor architecture +#define EM_MCST_ELBRUS 175 // MCST Elbrus general purpose hardware architecture +#define EM_ECOG16 176 // Cyan Technology eCOG16 family +#define EM_CR16 177 // National Semiconductor CompactRISC 16-bit processor +#define EM_ETPU 178 // Freescale Extended Time Processing Unit +#define EM_SLE9X 179 // Infineon Technologies SLE9X core +#define EM_L1OM 180 // Intel L1OM +#define EM_INTEL181 181 // Reserved by Intel +#define EM_INTEL182 182 // Reserved by Intel +#define EM_res183 183 // Reserved by ARM +#define EM_res184 184 // Reserved by ARM +#define EM_AVR32 185 // Atmel Corporation 32-bit microprocessor family +#define EM_STM8 186 // STMicroeletronics STM8 8-bit microcontroller +#define EM_TILE64 187 // Tilera TILE64 multicore architecture family +#define EM_TILEPRO 188 // Tilera TILEPro multicore architecture family +#define EM_MICROBLAZE 189 // Xilinx MicroBlaze 32-bit RISC soft processor core +#define EM_CUDA 190 // NVIDIA CUDA architecture +#define EM_TILEGX 191 // Tilera TILE-Gx multicore architecture family +#define EM_CLOUDSHIELD 192 // CloudShield architecture family +#define EM_COREA_1ST 193 // KIPO-KAIST Core-A 1st generation processor family +#define EM_COREA_2ND 194 // KIPO-KAIST Core-A 2nd generation processor family +#define EM_ARC_COMPACT2 195 // Synopsys ARCompact V2 +#define EM_OPEN8 196 // Open8 8-bit RISC soft processor core +#define EM_RL78 197 // Renesas RL78 family +#define EM_VIDEOCORE5 198 // Broadcom VideoCore V processor +#define EM_78KOR 199 // Renesas 78KOR family +#define EM_56800EX 200 // Freescale 56800EX Digital Signal Controller (DSC) +#define EM_BA1 201 // Beyond BA1 CPU architecture +#define EM_BA2 202 // Beyond BA2 CPU architecture +#define EM_XCORE 203 // XMOS xCORE processor family +#define EM_MCHP_PIC 204 // Microchip 8-bit PIC(r) family +#define EM_INTEL205 205 // Reserved by Intel +#define EM_INTEL206 206 // Reserved by Intel +#define EM_INTEL207 207 // Reserved by Intel +#define EM_INTEL208 208 // Reserved by Intel +#define EM_INTEL209 209 // Reserved by Intel +#define EM_KM32 210 // KM211 KM32 32-bit processor +#define EM_KMX32 211 // KM211 KMX32 32-bit processor +#define EM_KMX16 212 // KM211 KMX16 16-bit processor +#define EM_KMX8 213 // KM211 KMX8 8-bit processor +#define EM_KVARC 214 // KM211 KVARC processor +#define EM_CDP 215 // Paneve CDP architecture family +#define EM_COGE 216 // Cognitive Smart Memory Processor +#define EM_COOL 217 // iCelero CoolEngine +#define EM_NORC 218 // Nanoradio Optimized RISC +#define EM_CSR_KALIMBA 219 // CSR Kalimba architecture family +#define EM_Z80 220 // Zilog Z80 +#define EM_VISIUM 221 // Controls and Data Services VISIUMcore processor +#define EM_FT32 222 // FTDI Chip FT32 high performance 32-bit RISC architecture +#define EM_MOXIE 223 // Moxie processor family +#define EM_AMDGPU 224 // AMD GPU architecture +#define EM_RISCV 243 // RISC-V +#define EM_LANAI 244 // Lanai processor +#define EM_CEVA 245 // CEVA Processor Architecture Family +#define EM_CEVA_X2 246 // CEVA X2 Processor Family +#define EM_BPF 247 // Linux BPF – in-kernel virtual machine +#define EM_GRAPHCORE_IPU 248 // Graphcore Intelligent Processing Unit +#define EM_IMG1 249 // Imagination Technologies +#define EM_NFP 250 // Netronome Flow Processor (P) +#define EM_CSKY 252 // C-SKY processor family + +// File version +#define EV_NONE 0 +#define EV_CURRENT 1 + +// Identification index +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_ABIVERSION 8 +#define EI_PAD 9 +#define EI_NIDENT 16 + +// Magic number +#define ELFMAG0 0x7F +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' + +// File class +#define ELFCLASSNONE 0 +#define ELFCLASS32 1 +#define ELFCLASS64 2 + +// Encoding +#define ELFDATANONE 0 +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +// OS extensions +#define ELFOSABI_NONE 0 // No extensions or unspecified +#define ELFOSABI_HPUX 1 // Hewlett-Packard HP-UX +#define ELFOSABI_NETBSD 2 // NetBSD +#define ELFOSABI_LINUX 3 // Linux +#define ELFOSABI_SOLARIS 6 // Sun Solaris +#define ELFOSABI_AIX 7 // AIX +#define ELFOSABI_IRIX 8 // IRIX +#define ELFOSABI_FREEBSD 9 // FreeBSD +#define ELFOSABI_TRU64 10 // Compaq TRU64 UNIX +#define ELFOSABI_MODESTO 11 // Novell Modesto +#define ELFOSABI_OPENBSD 12 // Open BSD +#define ELFOSABI_OPENVMS 13 // Open VMS +#define ELFOSABI_NSK 14 // Hewlett-Packard Non-Stop Kernel +#define ELFOSABI_AROS 15 // Amiga Research OS +#define ELFOSABI_FENIXOS 16 // The FenixOS highly scalable multi-core OS +// 64-255 Architecture-specific value range +#define ELFOSABI_AMDGPU_HSA \ + 64 // AMDGPU OS for HSA compatible compute // kernels. +#define ELFOSABI_AMDGPU_PAL \ + 65 // AMDGPU OS for AMD PAL compatible graphics // shaders and compute kernels. +#define ELFOSABI_AMDGPU_MESA3D \ + 66 // AMDGPU OS for Mesa3D compatible graphics // shaders and compute kernels. + +// AMDGPU specific e_flags +#define EF_AMDGPU_MACH 0x0ff // AMDGPU processor selection mask. +#define EF_AMDGPU_XNACK \ + 0x100 // Indicates if the XNACK target feature is // enabled for all code contained in the ELF. +// AMDGPU processors +#define EF_AMDGPU_MACH_NONE 0x000 // Unspecified processor. +#define EF_AMDGPU_MACH_R600_R600 0x001 +#define EF_AMDGPU_MACH_R600_R630 0x002 +#define EF_AMDGPU_MACH_R600_RS880 0x003 +#define EF_AMDGPU_MACH_R600_RV670 0x004 +#define EF_AMDGPU_MACH_R600_RV710 0x005 +#define EF_AMDGPU_MACH_R600_RV730 0x006 +#define EF_AMDGPU_MACH_R600_RV770 0x007 +#define EF_AMDGPU_MACH_R600_CEDAR 0x008 +#define EF_AMDGPU_MACH_R600_CYPRESS 0x009 +#define EF_AMDGPU_MACH_R600_JUNIPER 0x00a +#define EF_AMDGPU_MACH_R600_REDWOOD 0x00b +#define EF_AMDGPU_MACH_R600_SUMO 0x00c +#define EF_AMDGPU_MACH_R600_BARTS 0x00d +#define EF_AMDGPU_MACH_R600_CAICOS 0x00e +#define EF_AMDGPU_MACH_R600_CAYMAN 0x00f +#define EF_AMDGPU_MACH_R600_TURKS 0x010 +#define EF_AMDGPU_MACH_R600_RESERVED_FIRST 0x011 +#define EF_AMDGPU_MACH_R600_RESERVED_LAST 0x01f +#define EF_AMDGPU_MACH_R600_FIRST EF_AMDGPU_MACH_R600_R600 +#define EF_AMDGPU_MACH_R600_LAST EF_AMDGPU_MACH_R600_TURKS +#define EF_AMDGPU_MACH_AMDGCN_GFX600 0x020 +#define EF_AMDGPU_MACH_AMDGCN_GFX601 0x021 +#define EF_AMDGPU_MACH_AMDGCN_GFX700 0x022 +#define EF_AMDGPU_MACH_AMDGCN_GFX701 0x023 +#define EF_AMDGPU_MACH_AMDGCN_GFX702 0x024 +#define EF_AMDGPU_MACH_AMDGCN_GFX703 0x025 +#define EF_AMDGPU_MACH_AMDGCN_GFX704 0x026 +#define EF_AMDGPU_MACH_AMDGCN_GFX801 0x028 +#define EF_AMDGPU_MACH_AMDGCN_GFX802 0x029 +#define EF_AMDGPU_MACH_AMDGCN_GFX803 0x02a +#define EF_AMDGPU_MACH_AMDGCN_GFX810 0x02b +#define EF_AMDGPU_MACH_AMDGCN_GFX900 0x02c +#define EF_AMDGPU_MACH_AMDGCN_GFX902 0x02d +#define EF_AMDGPU_MACH_AMDGCN_GFX904 0x02e +#define EF_AMDGPU_MACH_AMDGCN_GFX906 0x02f +#define EF_AMDGPU_MACH_AMDGCN_RESERVED0 0x027 +#define EF_AMDGPU_MACH_AMDGCN_RESERVED1 0x030 +#define EF_AMDGPU_MACH_AMDGCN_FIRST EF_AMDGPU_MACH_AMDGCN_GFX600 +#define EF_AMDGPU_MACH_AMDGCN_LAST EF_AMDGPU_MACH_AMDGCN_GFX906 + +///////////////////// +// Sections constants + +// Section indexes +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xFF00 +#define SHN_LOPROC 0xFF00 +#define SHN_HIPROC 0xFF1F +#define SHN_LOOS 0xFF20 +#define SHN_HIOS 0xFF3F +#define SHN_ABS 0xFFF1 +#define SHN_COMMON 0xFFF2 +#define SHN_XINDEX 0xFFFF +#define SHN_HIRESERVE 0xFFFF + +// Section types +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_INIT_ARRAY 14 +#define SHT_FINI_ARRAY 15 +#define SHT_PREINIT_ARRAY 16 +#define SHT_GROUP 17 +#define SHT_SYMTAB_SHNDX 18 +#define SHT_LOOS 0x60000000 +#define SHT_HIOS 0x6fffffff +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7FFFFFFF +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xFFFFFFFF + +// Section attribute flags +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_MERGE 0x10 +#define SHF_STRINGS 0x20 +#define SHF_INFO_LINK 0x40 +#define SHF_LINK_ORDER 0x80 +#define SHF_OS_NONCONFORMING 0x100 +#define SHF_GROUP 0x200 +#define SHF_TLS 0x400 +#define SHF_MASKOS 0x0ff00000 +#define SHF_MASKPROC 0xF0000000 + +// Section group flags +#define GRP_COMDAT 0x1 +#define GRP_MASKOS 0x0ff00000 +#define GRP_MASKPROC 0xf0000000 + +// Symbol binding +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 +#define STB_LOOS 10 +#define STB_HIOS 12 +#define STB_MULTIDEF 13 +#define STB_LOPROC 13 +#define STB_HIPROC 15 + +// Note types +#define NT_AMDGPU_METADATA 1 +#define NT_AMD_AMDGPU_HSA_METADATA 10 +#define NT_AMD_AMDGPU_ISA 11 +#define NT_AMD_AMDGPU_PAL_METADATA 12 + +// Symbol types +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 +#define STT_COMMON 5 +#define STT_TLS 6 +#define STT_LOOS 10 +#define STT_AMDGPU_HSA_KERNEL 10 +#define STT_HIOS 12 +#define STT_LOPROC 13 +#define STT_HIPROC 15 + +// Symbol visibility +#define STV_DEFAULT 0 +#define STV_INTERNAL 1 +#define STV_HIDDEN 2 +#define STV_PROTECTED 3 + +// Undefined name +#define STN_UNDEF 0 + +// Relocation types +#define R_386_NONE 0 +#define R_X86_64_NONE 0 +#define R_AMDGPU_NONE 0 +#define R_386_32 1 +#define R_X86_64_64 1 +#define R_AMDGPU_ABS32_LO 1 +#define R_386_PC32 2 +#define R_X86_64_PC32 2 +#define R_AMDGPU_ABS32_HI 2 +#define R_386_GOT32 3 +#define R_X86_64_GOT32 3 +#define R_AMDGPU_ABS64 3 +#define R_386_PLT32 4 +#define R_X86_64_PLT32 4 +#define R_AMDGPU_REL32 4 +#define R_386_COPY 5 +#define R_X86_64_COPY 5 +#define R_AMDGPU_REL64 5 +#define R_386_GLOB_DAT 6 +#define R_X86_64_GLOB_DAT 6 +#define R_AMDGPU_ABS32 6 +#define R_386_JMP_SLOT 7 +#define R_X86_64_JUMP_SLOT 7 +#define R_AMDGPU_GOTPCREL 7 +#define R_386_RELATIVE 8 +#define R_X86_64_RELATIVE 8 +#define R_AMDGPU_GOTPCREL32_LO 8 +#define R_386_GOTOFF 9 +#define R_X86_64_GOTPCREL 9 +#define R_AMDGPU_GOTPCREL32_HI 9 +#define R_386_GOTPC 10 +#define R_X86_64_32 10 +#define R_AMDGPU_REL32_LO 10 +#define R_386_32PLT 11 +#define R_X86_64_32S 11 +#define R_AMDGPU_REL32_HI 11 +#define R_X86_64_16 12 +#define R_X86_64_PC16 13 +#define R_AMDGPU_RELATIVE64 13 +#define R_386_TLS_TPOFF 14 +#define R_X86_64_8 14 +#define R_386_TLS_IE 15 +#define R_X86_64_PC8 15 +#define R_386_TLS_GOTIE 16 +#define R_X86_64_DTPMOD64 16 +#define R_386_TLS_LE 17 +#define R_X86_64_DTPOFF64 17 +#define R_386_TLS_GD 18 +#define R_X86_64_TPOFF64 18 +#define R_386_TLS_LDM 19 +#define R_X86_64_TLSGD 19 +#define R_386_16 20 +#define R_X86_64_TLSLD 20 +#define R_386_PC16 21 +#define R_X86_64_DTPOFF32 21 +#define R_386_8 22 +#define R_X86_64_GOTTPOFF 22 +#define R_386_PC8 23 +#define R_X86_64_TPOFF32 23 +#define R_386_TLS_GD_32 24 +#define R_X86_64_PC64 24 +#define R_386_TLS_GD_PUSH 25 +#define R_X86_64_GOTOFF64 25 +#define R_386_TLS_GD_CALL 26 +#define R_X86_64_GOTPC32 26 +#define R_386_TLS_GD_POP 27 +#define R_X86_64_GOT64 27 +#define R_386_TLS_LDM_32 28 +#define R_X86_64_GOTPCREL64 28 +#define R_386_TLS_LDM_PUSH 29 +#define R_X86_64_GOTPC64 29 +#define R_386_TLS_LDM_CALL 30 +#define R_X86_64_GOTPLT64 30 +#define R_386_TLS_LDM_POP 31 +#define R_X86_64_PLTOFF64 31 +#define R_386_TLS_LDO_32 32 +#define R_386_TLS_IE_32 33 +#define R_386_TLS_LE_32 34 +#define R_X86_64_GOTPC32_TLSDESC 34 +#define R_386_TLS_DTPMOD32 35 +#define R_X86_64_TLSDESC_CALL 35 +#define R_386_TLS_DTPOFF32 36 +#define R_X86_64_TLSDESC 36 +#define R_386_TLS_TPOFF32 37 +#define R_X86_64_IRELATIVE 37 +#define R_386_SIZE32 38 +#define R_386_TLS_GOTDESC 39 +#define R_386_TLS_DESC_CALL 40 +#define R_386_TLS_DESC 41 +#define R_386_IRELATIVE 42 +#define R_386_GOT32X 43 +#define R_X86_64_GNU_VTINHERIT 250 +#define R_X86_64_GNU_VTENTRY 251 + +// Segment types +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_TLS 7 +#define PT_LOOS 0x60000000 +#define PT_HIOS 0x6fffffff +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7FFFFFFF + +// Segment flags +#define PF_X 1 // Execute +#define PF_W 2 // Write +#define PF_R 4 // Read +#define PF_MASKOS 0x0ff00000 // Unspecified +#define PF_MASKPROC 0xf0000000 // Unspecified + +// Dynamic Array Tags +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_SONAME 14 +#define DT_RPATH 15 +#define DT_SYMBOLIC 16 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_DEBUG 21 +#define DT_TEXTREL 22 +#define DT_JMPREL 23 +#define DT_BIND_NOW 24 +#define DT_INIT_ARRAY 25 +#define DT_FINI_ARRAY 26 +#define DT_INIT_ARRAYSZ 27 +#define DT_FINI_ARRAYSZ 28 +#define DT_RUNPATH 29 +#define DT_FLAGS 30 +#define DT_ENCODING 32 +#define DT_PREINIT_ARRAY 32 +#define DT_PREINIT_ARRAYSZ 33 +#define DT_MAXPOSTAGS 34 +#define DT_LOOS 0x6000000D +#define DT_HIOS 0x6ffff000 +#define DT_LOPROC 0x70000000 +#define DT_HIPROC 0x7FFFFFFF + +// DT_FLAGS values +#define DF_ORIGIN 0x1 +#define DF_SYMBOLIC 0x2 +#define DF_TEXTREL 0x4 +#define DF_BIND_NOW 0x8 +#define DF_STATIC_TLS 0x10 + +// ELF file header +struct Elf32_Ehdr +{ + unsigned char e_ident[EI_NIDENT]; + Elf_Half e_type; + Elf_Half e_machine; + Elf_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf_Word e_flags; + Elf_Half e_ehsize; + Elf_Half e_phentsize; + Elf_Half e_phnum; + Elf_Half e_shentsize; + Elf_Half e_shnum; + Elf_Half e_shstrndx; +}; + +struct Elf64_Ehdr +{ + unsigned char e_ident[EI_NIDENT]; + Elf_Half e_type; + Elf_Half e_machine; + Elf_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf_Word e_flags; + Elf_Half e_ehsize; + Elf_Half e_phentsize; + Elf_Half e_phnum; + Elf_Half e_shentsize; + Elf_Half e_shnum; + Elf_Half e_shstrndx; +}; + +// Section header +struct Elf32_Shdr +{ + Elf_Word sh_name; + Elf_Word sh_type; + Elf_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf_Word sh_size; + Elf_Word sh_link; + Elf_Word sh_info; + Elf_Word sh_addralign; + Elf_Word sh_entsize; +}; + +struct Elf64_Shdr +{ + Elf_Word sh_name; + Elf_Word sh_type; + Elf_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf_Xword sh_size; + Elf_Word sh_link; + Elf_Word sh_info; + Elf_Xword sh_addralign; + Elf_Xword sh_entsize; +}; + +// Segment header +struct Elf32_Phdr +{ + Elf_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf_Word p_filesz; + Elf_Word p_memsz; + Elf_Word p_flags; + Elf_Word p_align; +}; + +struct Elf64_Phdr +{ + Elf_Word p_type; + Elf_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + Elf_Xword p_filesz; + Elf_Xword p_memsz; + Elf_Xword p_align; +}; + +// Symbol table entry +struct Elf32_Sym +{ + Elf_Word st_name; + Elf32_Addr st_value; + Elf_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf_Half st_shndx; +}; + +struct Elf64_Sym +{ + Elf_Word st_name; + unsigned char st_info; + unsigned char st_other; + Elf_Half st_shndx; + Elf64_Addr st_value; + Elf_Xword st_size; +}; + +#define ELF_ST_BIND( i ) ( ( i ) >> 4 ) +#define ELF_ST_TYPE( i ) ( (i)&0xf ) +#define ELF_ST_INFO( b, t ) ( ( ( b ) << 4 ) + ( (t)&0xf ) ) + +#define ELF_ST_VISIBILITY( o ) ( (o)&0x3 ) + +// Relocation entries +struct Elf32_Rel +{ + Elf32_Addr r_offset; + Elf_Word r_info; +}; + +struct Elf32_Rela +{ + Elf32_Addr r_offset; + Elf_Word r_info; + Elf_Sword r_addend; +}; + +struct Elf64_Rel +{ + Elf64_Addr r_offset; + Elf_Xword r_info; +}; + +struct Elf64_Rela +{ + Elf64_Addr r_offset; + Elf_Xword r_info; + Elf_Sxword r_addend; +}; + +#define ELF32_R_SYM( i ) ( ( i ) >> 8 ) +#define ELF32_R_TYPE( i ) ( (unsigned char)( i ) ) +#define ELF32_R_INFO( s, t ) ( ( ( s ) << 8 ) + (unsigned char)( t ) ) + +#define ELF64_R_SYM( i ) ( ( i ) >> 32 ) +#define ELF64_R_TYPE( i ) ( (i)&0xffffffffL ) +#define ELF64_R_INFO( s, t ) \ + ( ( ( ( int64_t )( s ) ) << 32 ) + ( (t)&0xffffffffL ) ) + +// Dynamic structure +struct Elf32_Dyn +{ + Elf_Sword d_tag; + union { + Elf_Word d_val; + Elf32_Addr d_ptr; + } d_un; +}; + +struct Elf64_Dyn +{ + Elf_Sxword d_tag; + union { + Elf_Xword d_val; + Elf64_Addr d_ptr; + } d_un; +}; + +} // namespace ELFIO + +#endif // ELFTYPES_H + +/*** End of inlined file: elf_types.hpp ***/ + + +/*** Start of inlined file: elfio_version.hpp ***/ +#define ELFIO_VERSION "3.8" + +/*** End of inlined file: elfio_version.hpp ***/ + + +/*** Start of inlined file: elfio_utils.hpp ***/ +#ifndef ELFIO_UTILS_HPP +#define ELFIO_UTILS_HPP + +#define ELFIO_GET_ACCESS( TYPE, NAME, FIELD ) \ + TYPE get_##NAME() const { return ( *convertor )( FIELD ); } +#define ELFIO_SET_ACCESS( TYPE, NAME, FIELD ) \ + void set_##NAME( TYPE value ) \ + { \ + FIELD = value; \ + FIELD = ( *convertor )( FIELD ); \ + } +#define ELFIO_GET_SET_ACCESS( TYPE, NAME, FIELD ) \ + TYPE get_##NAME() const { return ( *convertor )( FIELD ); } \ + void set_##NAME( TYPE value ) \ + { \ + FIELD = value; \ + FIELD = ( *convertor )( FIELD ); \ + } + +#define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) virtual TYPE get_##NAME() const = 0 + +#define ELFIO_SET_ACCESS_DECL( TYPE, NAME ) \ + virtual void set_##NAME( TYPE value ) = 0 + +#define ELFIO_GET_SET_ACCESS_DECL( TYPE, NAME ) \ + virtual TYPE get_##NAME() const = 0; \ + virtual void set_##NAME( TYPE value ) = 0 + +namespace ELFIO { + +//------------------------------------------------------------------------------ +class endianess_convertor +{ + public: + //------------------------------------------------------------------------------ + endianess_convertor() { need_conversion = false; } + + //------------------------------------------------------------------------------ + void setup( unsigned char elf_file_encoding ) + { + need_conversion = ( elf_file_encoding != get_host_encoding() ); + } + + //------------------------------------------------------------------------------ + uint64_t operator()( uint64_t value ) const + { + if ( !need_conversion ) { + return value; + } + value = ( ( value & 0x00000000000000FFull ) << 56 ) | + ( ( value & 0x000000000000FF00ull ) << 40 ) | + ( ( value & 0x0000000000FF0000ull ) << 24 ) | + ( ( value & 0x00000000FF000000ull ) << 8 ) | + ( ( value & 0x000000FF00000000ull ) >> 8 ) | + ( ( value & 0x0000FF0000000000ull ) >> 24 ) | + ( ( value & 0x00FF000000000000ull ) >> 40 ) | + ( ( value & 0xFF00000000000000ull ) >> 56 ); + + return value; + } + + //------------------------------------------------------------------------------ + int64_t operator()( int64_t value ) const + { + if ( !need_conversion ) { + return value; + } + return ( int64_t )( *this )( (uint64_t)value ); + } + + //------------------------------------------------------------------------------ + uint32_t operator()( uint32_t value ) const + { + if ( !need_conversion ) { + return value; + } + value = + ( ( value & 0x000000FF ) << 24 ) | ( ( value & 0x0000FF00 ) << 8 ) | + ( ( value & 0x00FF0000 ) >> 8 ) | ( ( value & 0xFF000000 ) >> 24 ); + + return value; + } + + //------------------------------------------------------------------------------ + int32_t operator()( int32_t value ) const + { + if ( !need_conversion ) { + return value; + } + return ( int32_t )( *this )( (uint32_t)value ); + } + + //------------------------------------------------------------------------------ + uint16_t operator()( uint16_t value ) const + { + if ( !need_conversion ) { + return value; + } + value = ( ( value & 0x00FF ) << 8 ) | ( ( value & 0xFF00 ) >> 8 ); + + return value; + } + + //------------------------------------------------------------------------------ + int16_t operator()( int16_t value ) const + { + if ( !need_conversion ) { + return value; + } + return ( int16_t )( *this )( (uint16_t)value ); + } + + //------------------------------------------------------------------------------ + int8_t operator()( int8_t value ) const { return value; } + + //------------------------------------------------------------------------------ + uint8_t operator()( uint8_t value ) const { return value; } + + //------------------------------------------------------------------------------ + private: + //------------------------------------------------------------------------------ + unsigned char get_host_encoding() const + { + static const int tmp = 1; + if ( 1 == *(const char*)&tmp ) { + return ELFDATA2LSB; + } + else { + return ELFDATA2MSB; + } + } + + //------------------------------------------------------------------------------ + private: + bool need_conversion; +}; + +//------------------------------------------------------------------------------ +inline uint32_t elf_hash( const unsigned char* name ) +{ + uint32_t h = 0, g; + while ( *name ) { + h = ( h << 4 ) + *name++; + g = h & 0xf0000000; + if ( g != 0 ) + h ^= g >> 24; + h &= ~g; + } + return h; +} + +} // namespace ELFIO + +#endif // ELFIO_UTILS_HPP + +/*** End of inlined file: elfio_utils.hpp ***/ + + +/*** Start of inlined file: elfio_header.hpp ***/ +#ifndef ELF_HEADER_HPP +#define ELF_HEADER_HPP + +#include + +namespace ELFIO { + +class elf_header +{ + public: + virtual ~elf_header(){}; + virtual bool load( std::istream& stream ) = 0; + virtual bool save( std::ostream& stream ) const = 0; + + // ELF header functions + ELFIO_GET_ACCESS_DECL( unsigned char, class ); + ELFIO_GET_ACCESS_DECL( unsigned char, elf_version ); + ELFIO_GET_ACCESS_DECL( unsigned char, encoding ); + ELFIO_GET_ACCESS_DECL( Elf_Half, header_size ); + ELFIO_GET_ACCESS_DECL( Elf_Half, section_entry_size ); + ELFIO_GET_ACCESS_DECL( Elf_Half, segment_entry_size ); + + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, version ); + ELFIO_GET_SET_ACCESS_DECL( unsigned char, os_abi ); + ELFIO_GET_SET_ACCESS_DECL( unsigned char, abi_version ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Half, type ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Half, machine ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); + ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, entry ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Half, sections_num ); + ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, sections_offset ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Half, segments_num ); + ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, segments_offset ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Half, section_name_str_index ); +}; + +template struct elf_header_impl_types; +template <> struct elf_header_impl_types +{ + typedef Elf32_Phdr Phdr_type; + typedef Elf32_Shdr Shdr_type; + static const unsigned char file_class = ELFCLASS32; +}; +template <> struct elf_header_impl_types +{ + typedef Elf64_Phdr Phdr_type; + typedef Elf64_Shdr Shdr_type; + static const unsigned char file_class = ELFCLASS64; +}; + +template class elf_header_impl : public elf_header +{ + public: + //------------------------------------------------------------------------------ + elf_header_impl( endianess_convertor* convertor_, unsigned char encoding ) + { + convertor = convertor_; + + std::fill_n( reinterpret_cast( &header ), sizeof( header ), + '\0' ); + + header.e_ident[EI_MAG0] = ELFMAG0; + header.e_ident[EI_MAG1] = ELFMAG1; + header.e_ident[EI_MAG2] = ELFMAG2; + header.e_ident[EI_MAG3] = ELFMAG3; + header.e_ident[EI_CLASS] = elf_header_impl_types::file_class; + header.e_ident[EI_DATA] = encoding; + header.e_ident[EI_VERSION] = EV_CURRENT; + header.e_version = ( *convertor )( (Elf_Word)EV_CURRENT ); + header.e_ehsize = ( sizeof( header ) ); + header.e_ehsize = ( *convertor )( header.e_ehsize ); + header.e_shstrndx = ( *convertor )( (Elf_Half)1 ); + header.e_phentsize = + sizeof( typename elf_header_impl_types::Phdr_type ); + header.e_shentsize = + sizeof( typename elf_header_impl_types::Shdr_type ); + header.e_phentsize = ( *convertor )( header.e_phentsize ); + header.e_shentsize = ( *convertor )( header.e_shentsize ); + } + + //------------------------------------------------------------------------------ + bool load( std::istream& stream ) + { + stream.seekg( 0 ); + stream.read( reinterpret_cast( &header ), sizeof( header ) ); + + return ( stream.gcount() == sizeof( header ) ); + } + + //------------------------------------------------------------------------------ + bool save( std::ostream& stream ) const + { + stream.seekp( 0 ); + stream.write( reinterpret_cast( &header ), + sizeof( header ) ); + + return stream.good(); + } + + //------------------------------------------------------------------------------ + // ELF header functions + ELFIO_GET_ACCESS( unsigned char, class, header.e_ident[EI_CLASS] ); + ELFIO_GET_ACCESS( unsigned char, elf_version, header.e_ident[EI_VERSION] ); + ELFIO_GET_ACCESS( unsigned char, encoding, header.e_ident[EI_DATA] ); + ELFIO_GET_ACCESS( Elf_Half, header_size, header.e_ehsize ); + ELFIO_GET_ACCESS( Elf_Half, section_entry_size, header.e_shentsize ); + ELFIO_GET_ACCESS( Elf_Half, segment_entry_size, header.e_phentsize ); + + ELFIO_GET_SET_ACCESS( Elf_Word, version, header.e_version ); + ELFIO_GET_SET_ACCESS( unsigned char, os_abi, header.e_ident[EI_OSABI] ); + ELFIO_GET_SET_ACCESS( unsigned char, + abi_version, + header.e_ident[EI_ABIVERSION] ); + ELFIO_GET_SET_ACCESS( Elf_Half, type, header.e_type ); + ELFIO_GET_SET_ACCESS( Elf_Half, machine, header.e_machine ); + ELFIO_GET_SET_ACCESS( Elf_Word, flags, header.e_flags ); + ELFIO_GET_SET_ACCESS( Elf_Half, section_name_str_index, header.e_shstrndx ); + ELFIO_GET_SET_ACCESS( Elf64_Addr, entry, header.e_entry ); + ELFIO_GET_SET_ACCESS( Elf_Half, sections_num, header.e_shnum ); + ELFIO_GET_SET_ACCESS( Elf64_Off, sections_offset, header.e_shoff ); + ELFIO_GET_SET_ACCESS( Elf_Half, segments_num, header.e_phnum ); + ELFIO_GET_SET_ACCESS( Elf64_Off, segments_offset, header.e_phoff ); + + private: + T header; + endianess_convertor* convertor; +}; + +} // namespace ELFIO + +#endif // ELF_HEADER_HPP + +/*** End of inlined file: elfio_header.hpp ***/ + + +/*** Start of inlined file: elfio_section.hpp ***/ +#ifndef ELFIO_SECTION_HPP +#define ELFIO_SECTION_HPP + +#include +#include +#include + +namespace ELFIO { + +class section +{ + friend class elfio; + + public: + virtual ~section(){}; + + ELFIO_GET_ACCESS_DECL( Elf_Half, index ); + ELFIO_GET_SET_ACCESS_DECL( std::string, name ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, flags ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, info ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, link ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, addr_align ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, entry_size ); + ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, address ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, size ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, name_string_offset ); + ELFIO_GET_ACCESS_DECL( Elf64_Off, offset ); + + virtual const char* get_data() const = 0; + virtual void set_data( const char* pData, Elf_Word size ) = 0; + virtual void set_data( const std::string& data ) = 0; + virtual void append_data( const char* pData, Elf_Word size ) = 0; + virtual void append_data( const std::string& data ) = 0; + virtual size_t get_stream_size() const = 0; + virtual void set_stream_size( size_t value ) = 0; + + protected: + ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); + ELFIO_SET_ACCESS_DECL( Elf_Half, index ); + + virtual void load( std::istream& stream, std::streampos header_offset ) = 0; + virtual void save( std::ostream& stream, + std::streampos header_offset, + std::streampos data_offset ) = 0; + virtual bool is_address_initialized() const = 0; +}; + +template class section_impl : public section +{ + public: + //------------------------------------------------------------------------------ + section_impl( const endianess_convertor* convertor_ ) + : convertor( convertor_ ) + { + std::fill_n( reinterpret_cast( &header ), sizeof( header ), + '\0' ); + is_address_set = false; + data = 0; + data_size = 0; + index = 0; + stream_size = 0; + } + + //------------------------------------------------------------------------------ + ~section_impl() { delete[] data; } + + //------------------------------------------------------------------------------ + // Section info functions + ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type ); + ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags ); + ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size ); + ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link ); + ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info ); + ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign ); + ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize ); + ELFIO_GET_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name ); + ELFIO_GET_ACCESS( Elf64_Addr, address, header.sh_addr ); + + //------------------------------------------------------------------------------ + Elf_Half get_index() const { return index; } + + //------------------------------------------------------------------------------ + std::string get_name() const { return name; } + + //------------------------------------------------------------------------------ + void set_name( std::string name_ ) { name = name_; } + + //------------------------------------------------------------------------------ + void set_address( Elf64_Addr value ) + { + header.sh_addr = value; + header.sh_addr = ( *convertor )( header.sh_addr ); + is_address_set = true; + } + + //------------------------------------------------------------------------------ + bool is_address_initialized() const { return is_address_set; } + + //------------------------------------------------------------------------------ + const char* get_data() const { return data; } + + //------------------------------------------------------------------------------ + void set_data( const char* raw_data, Elf_Word size ) + { + if ( get_type() != SHT_NOBITS ) { + delete[] data; + data = new ( std::nothrow ) char[size]; + if ( 0 != data && 0 != raw_data ) { + data_size = size; + std::copy( raw_data, raw_data + size, data ); + } + else { + data_size = 0; + } + } + + set_size( data_size ); + } + + //------------------------------------------------------------------------------ + void set_data( const std::string& str_data ) + { + return set_data( str_data.c_str(), (Elf_Word)str_data.size() ); + } + + //------------------------------------------------------------------------------ + void append_data( const char* raw_data, Elf_Word size ) + { + if ( get_type() != SHT_NOBITS ) { + if ( get_size() + size < data_size ) { + std::copy( raw_data, raw_data + size, data + get_size() ); + } + else { + data_size = 2 * ( data_size + size ); + char* new_data = new ( std::nothrow ) char[data_size]; + + if ( 0 != new_data ) { + std::copy( data, data + get_size(), new_data ); + std::copy( raw_data, raw_data + size, + new_data + get_size() ); + delete[] data; + data = new_data; + } + else { + size = 0; + } + } + set_size( get_size() + size ); + } + } + + //------------------------------------------------------------------------------ + void append_data( const std::string& str_data ) + { + return append_data( str_data.c_str(), (Elf_Word)str_data.size() ); + } + + //------------------------------------------------------------------------------ + protected: + //------------------------------------------------------------------------------ + ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset ); + + //------------------------------------------------------------------------------ + void set_index( Elf_Half value ) { index = value; } + + //------------------------------------------------------------------------------ + void load( std::istream& stream, std::streampos header_offset ) + { + std::fill_n( reinterpret_cast( &header ), sizeof( header ), + '\0' ); + + stream.seekg( 0, stream.end ); + set_stream_size( stream.tellg() ); + + stream.seekg( header_offset ); + stream.read( reinterpret_cast( &header ), sizeof( header ) ); + + Elf_Xword size = get_size(); + if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() && + size < get_stream_size() ) { + data = new ( std::nothrow ) char[size + 1]; + + if ( ( 0 != size ) && ( 0 != data ) ) { + stream.seekg( ( *convertor )( header.sh_offset ) ); + stream.read( data, size ); + data[size] = 0; // Ensure data is ended with 0 to avoid oob read + data_size = size; + } + else { + data_size = 0; + } + } + } + + //------------------------------------------------------------------------------ + void save( std::ostream& stream, + std::streampos header_offset, + std::streampos data_offset ) + { + if ( 0 != get_index() ) { + header.sh_offset = data_offset; + header.sh_offset = ( *convertor )( header.sh_offset ); + } + + save_header( stream, header_offset ); + if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL && + get_size() != 0 && data != 0 ) { + save_data( stream, data_offset ); + } + } + + //------------------------------------------------------------------------------ + private: + //------------------------------------------------------------------------------ + void save_header( std::ostream& stream, std::streampos header_offset ) const + { + stream.seekp( header_offset ); + stream.write( reinterpret_cast( &header ), + sizeof( header ) ); + } + + //------------------------------------------------------------------------------ + void save_data( std::ostream& stream, std::streampos data_offset ) const + { + stream.seekp( data_offset ); + stream.write( get_data(), get_size() ); + } + + //------------------------------------------------------------------------------ + size_t get_stream_size() const { return stream_size; } + + //------------------------------------------------------------------------------ + void set_stream_size( size_t value ) { stream_size = value; } + + //------------------------------------------------------------------------------ + private: + T header; + Elf_Half index; + std::string name; + char* data; + Elf_Word data_size; + const endianess_convertor* convertor; + bool is_address_set; + size_t stream_size; +}; + +} // namespace ELFIO + +#endif // ELFIO_SECTION_HPP + +/*** End of inlined file: elfio_section.hpp ***/ + + +/*** Start of inlined file: elfio_segment.hpp ***/ +#ifndef ELFIO_SEGMENT_HPP +#define ELFIO_SEGMENT_HPP + +#include +#include +#include + +namespace ELFIO { + +class segment +{ + friend class elfio; + + public: + virtual ~segment(){}; + + ELFIO_GET_ACCESS_DECL( Elf_Half, index ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, align ); + ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address ); + ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, file_size ); + ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, memory_size ); + ELFIO_GET_ACCESS_DECL( Elf64_Off, offset ); + + virtual const char* get_data() const = 0; + + virtual Elf_Half add_section_index( Elf_Half index, + Elf_Xword addr_align ) = 0; + virtual Elf_Half get_sections_num() const = 0; + virtual Elf_Half get_section_index_at( Elf_Half num ) const = 0; + virtual bool is_offset_initialized() const = 0; + + protected: + ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); + ELFIO_SET_ACCESS_DECL( Elf_Half, index ); + + virtual const std::vector& get_sections() const = 0; + virtual void load( std::istream& stream, std::streampos header_offset ) = 0; + virtual void save( std::ostream& stream, + std::streampos header_offset, + std::streampos data_offset ) = 0; +}; + +//------------------------------------------------------------------------------ +template class segment_impl : public segment +{ + public: + //------------------------------------------------------------------------------ + segment_impl( endianess_convertor* convertor_ ) + : stream_size( 0 ), index( 0 ), data( 0 ), convertor( convertor_ ) + { + is_offset_set = false; + std::fill_n( reinterpret_cast( &ph ), sizeof( ph ), '\0' ); + } + + //------------------------------------------------------------------------------ + virtual ~segment_impl() { delete[] data; } + + //------------------------------------------------------------------------------ + // Section info functions + ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type ); + ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags ); + ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align ); + ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr ); + ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr ); + ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz ); + ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz ); + ELFIO_GET_ACCESS( Elf64_Off, offset, ph.p_offset ); + size_t stream_size; + + //------------------------------------------------------------------------------ + size_t get_stream_size() const { return stream_size; } + + //------------------------------------------------------------------------------ + void set_stream_size( size_t value ) { stream_size = value; } + + //------------------------------------------------------------------------------ + Elf_Half get_index() const { return index; } + + //------------------------------------------------------------------------------ + const char* get_data() const { return data; } + + //------------------------------------------------------------------------------ + Elf_Half add_section_index( Elf_Half sec_index, Elf_Xword addr_align ) + { + sections.push_back( sec_index ); + if ( addr_align > get_align() ) { + set_align( addr_align ); + } + + return (Elf_Half)sections.size(); + } + + //------------------------------------------------------------------------------ + Elf_Half get_sections_num() const { return (Elf_Half)sections.size(); } + + //------------------------------------------------------------------------------ + Elf_Half get_section_index_at( Elf_Half num ) const + { + if ( num < sections.size() ) { + return sections[num]; + } + + return Elf_Half( -1 ); + } + + //------------------------------------------------------------------------------ + protected: + //------------------------------------------------------------------------------ + + //------------------------------------------------------------------------------ + void set_offset( Elf64_Off value ) + { + ph.p_offset = value; + ph.p_offset = ( *convertor )( ph.p_offset ); + is_offset_set = true; + } + + //------------------------------------------------------------------------------ + bool is_offset_initialized() const { return is_offset_set; } + + //------------------------------------------------------------------------------ + const std::vector& get_sections() const { return sections; } + + //------------------------------------------------------------------------------ + void set_index( Elf_Half value ) { index = value; } + + //------------------------------------------------------------------------------ + void load( std::istream& stream, std::streampos header_offset ) + { + + stream.seekg( 0, stream.end ); + set_stream_size( stream.tellg() ); + + stream.seekg( header_offset ); + stream.read( reinterpret_cast( &ph ), sizeof( ph ) ); + is_offset_set = true; + + if ( PT_NULL != get_type() && 0 != get_file_size() ) { + stream.seekg( ( *convertor )( ph.p_offset ) ); + Elf_Xword size = get_file_size(); + + if ( size > get_stream_size() ) { + data = 0; + } + else { + data = new (std::nothrow) char[size + 1]; + + if ( 0 != data ) { + stream.read( data, size ); + data[size] = 0; + } + } + } + } + + //------------------------------------------------------------------------------ + void save( std::ostream& stream, + std::streampos header_offset, + std::streampos data_offset ) + { + ph.p_offset = data_offset; + ph.p_offset = ( *convertor )( ph.p_offset ); + stream.seekp( header_offset ); + stream.write( reinterpret_cast( &ph ), sizeof( ph ) ); + } + + //------------------------------------------------------------------------------ + private: + T ph; + Elf_Half index; + char* data; + std::vector sections; + endianess_convertor* convertor; + bool is_offset_set; +}; + +} // namespace ELFIO + +#endif // ELFIO_SEGMENT_HPP + +/*** End of inlined file: elfio_segment.hpp ***/ + + +/*** Start of inlined file: elfio_strings.hpp ***/ +#ifndef ELFIO_STRINGS_HPP +#define ELFIO_STRINGS_HPP + +#include +#include +#include + +namespace ELFIO { + +//------------------------------------------------------------------------------ +template class string_section_accessor_template +{ + public: + //------------------------------------------------------------------------------ + string_section_accessor_template( S* section_ ) : string_section( section_ ) + { + } + + //------------------------------------------------------------------------------ + const char* get_string( Elf_Word index ) const + { + if ( string_section ) { + if ( index < string_section->get_size() ) { + const char* data = string_section->get_data(); + if ( 0 != data ) { + return data + index; + } + } + } + + return 0; + } + + //------------------------------------------------------------------------------ + Elf_Word add_string( const char* str ) + { + Elf_Word current_position = 0; + + if ( string_section ) { + // Strings are addeded to the end of the current section data + current_position = (Elf_Word)string_section->get_size(); + + if ( current_position == 0 ) { + char empty_string = '\0'; + string_section->append_data( &empty_string, 1 ); + current_position++; + } + string_section->append_data( str, + (Elf_Word)std::strlen( str ) + 1 ); + } + + return current_position; + } + + //------------------------------------------------------------------------------ + Elf_Word add_string( const std::string& str ) + { + return add_string( str.c_str() ); + } + + //------------------------------------------------------------------------------ + private: + S* string_section; +}; + +using string_section_accessor = string_section_accessor_template
; +using const_string_section_accessor = + string_section_accessor_template; + +} // namespace ELFIO + +#endif // ELFIO_STRINGS_HPP + +/*** End of inlined file: elfio_strings.hpp ***/ + +#define ELFIO_HEADER_ACCESS_GET( TYPE, FNAME ) \ + TYPE get_##FNAME() const { return header ? ( header->get_##FNAME() ) : 0; } + +#define ELFIO_HEADER_ACCESS_GET_SET( TYPE, FNAME ) \ + TYPE get_##FNAME() const \ + { \ + return header ? ( header->get_##FNAME() ) : 0; \ + } \ + void set_##FNAME( TYPE val ) \ + { \ + if ( header ) { \ + header->set_##FNAME( val ); \ + } \ + } + +namespace ELFIO { + +//------------------------------------------------------------------------------ +class elfio +{ + public: + //------------------------------------------------------------------------------ + elfio() : sections( this ), segments( this ) + { + header = 0; + current_file_pos = 0; + create( ELFCLASS32, ELFDATA2LSB ); + } + + //------------------------------------------------------------------------------ + ~elfio() { clean(); } + + //------------------------------------------------------------------------------ + void create( unsigned char file_class, unsigned char encoding ) + { + clean(); + convertor.setup( encoding ); + header = create_header( file_class, encoding ); + create_mandatory_sections(); + } + + //------------------------------------------------------------------------------ + bool load( const std::string& file_name ) + { + std::ifstream stream; + stream.open( file_name.c_str(), std::ios::in | std::ios::binary ); + if ( !stream ) { + return false; + } + + return load( stream ); + } + + //------------------------------------------------------------------------------ + bool load( std::istream& stream ) + { + clean(); + + unsigned char e_ident[EI_NIDENT]; + // Read ELF file signature + stream.read( reinterpret_cast( &e_ident ), sizeof( e_ident ) ); + + // Is it ELF file? + if ( stream.gcount() != sizeof( e_ident ) || + e_ident[EI_MAG0] != ELFMAG0 || e_ident[EI_MAG1] != ELFMAG1 || + e_ident[EI_MAG2] != ELFMAG2 || e_ident[EI_MAG3] != ELFMAG3 ) { + return false; + } + + if ( ( e_ident[EI_CLASS] != ELFCLASS64 ) && + ( e_ident[EI_CLASS] != ELFCLASS32 ) ) { + return false; + } + + convertor.setup( e_ident[EI_DATA] ); + header = create_header( e_ident[EI_CLASS], e_ident[EI_DATA] ); + if ( 0 == header ) { + return false; + } + if ( !header->load( stream ) ) { + return false; + } + + load_sections( stream ); + bool is_still_good = load_segments( stream ); + return is_still_good; + } + + //------------------------------------------------------------------------------ + bool save( const std::string& file_name ) + { + std::ofstream stream; + stream.open( file_name.c_str(), std::ios::out | std::ios::binary ); + if ( !stream ) { + return false; + } + + return save( stream ); + } + + //------------------------------------------------------------------------------ + bool save( std::ostream& stream ) + { + if ( !stream || !header ) { + return false; + } + + bool is_still_good = true; + // Define layout specific header fields + // The position of the segment table is fixed after the header. + // The position of the section table is variable and needs to be fixed + // before saving. + header->set_segments_num( segments.size() ); + header->set_segments_offset( segments.size() ? header->get_header_size() + : 0 ); + header->set_sections_num( sections.size() ); + header->set_sections_offset( 0 ); + + // Layout the first section right after the segment table + current_file_pos = header->get_header_size() + + header->get_segment_entry_size() * + (Elf_Xword)header->get_segments_num(); + + calc_segment_alignment(); + + is_still_good = layout_segments_and_their_sections(); + is_still_good = is_still_good && layout_sections_without_segments(); + is_still_good = is_still_good && layout_section_table(); + + is_still_good = is_still_good && save_header( stream ); + is_still_good = is_still_good && save_sections( stream ); + is_still_good = is_still_good && save_segments( stream ); + + return is_still_good; + } + + //------------------------------------------------------------------------------ + // ELF header access functions + ELFIO_HEADER_ACCESS_GET( unsigned char, class ); + ELFIO_HEADER_ACCESS_GET( unsigned char, elf_version ); + ELFIO_HEADER_ACCESS_GET( unsigned char, encoding ); + ELFIO_HEADER_ACCESS_GET( Elf_Word, version ); + ELFIO_HEADER_ACCESS_GET( Elf_Half, header_size ); + ELFIO_HEADER_ACCESS_GET( Elf_Half, section_entry_size ); + ELFIO_HEADER_ACCESS_GET( Elf_Half, segment_entry_size ); + + ELFIO_HEADER_ACCESS_GET_SET( unsigned char, os_abi ); + ELFIO_HEADER_ACCESS_GET_SET( unsigned char, abi_version ); + ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, type ); + ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, machine ); + ELFIO_HEADER_ACCESS_GET_SET( Elf_Word, flags ); + ELFIO_HEADER_ACCESS_GET_SET( Elf64_Addr, entry ); + ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, sections_offset ); + ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, segments_offset ); + ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, section_name_str_index ); + + //------------------------------------------------------------------------------ + const endianess_convertor& get_convertor() const { return convertor; } + + //------------------------------------------------------------------------------ + Elf_Xword get_default_entry_size( Elf_Word section_type ) const + { + switch ( section_type ) { + case SHT_RELA: + if ( header->get_class() == ELFCLASS64 ) { + return sizeof( Elf64_Rela ); + } + else { + return sizeof( Elf32_Rela ); + } + case SHT_REL: + if ( header->get_class() == ELFCLASS64 ) { + return sizeof( Elf64_Rel ); + } + else { + return sizeof( Elf32_Rel ); + } + case SHT_SYMTAB: + if ( header->get_class() == ELFCLASS64 ) { + return sizeof( Elf64_Sym ); + } + else { + return sizeof( Elf32_Sym ); + } + case SHT_DYNAMIC: + if ( header->get_class() == ELFCLASS64 ) { + return sizeof( Elf64_Dyn ); + } + else { + return sizeof( Elf32_Dyn ); + } + default: + return 0; + } + } + + //------------------------------------------------------------------------------ + private: + bool is_offset_in_section( Elf64_Off offset, const section* sec ) const + { + return ( offset >= sec->get_offset() ) && + ( offset < ( sec->get_offset() + sec->get_size() ) ); + } + + //------------------------------------------------------------------------------ + public: + //! returns an empty string if no problems are detected, + //! or a string containing an error message if problems are found + std::string validate() const + { + + // check for overlapping sections in the file + for ( int i = 0; i < sections.size(); ++i ) { + for ( int j = i + 1; j < sections.size(); ++j ) { + const section* a = sections[i]; + const section* b = sections[j]; + if ( !( a->get_type() & SHT_NOBITS ) && + !( b->get_type() & SHT_NOBITS ) && ( a->get_size() > 0 ) && + ( b->get_size() > 0 ) && ( a->get_offset() > 0 ) && + ( b->get_offset() > 0 ) ) { + if ( is_offset_in_section( a->get_offset(), b ) || + is_offset_in_section( + a->get_offset() + a->get_size() - 1, b ) || + is_offset_in_section( b->get_offset(), a ) || + is_offset_in_section( + b->get_offset() + b->get_size() - 1, a ) ) { + return "Sections " + a->get_name() + " and " + + b->get_name() + " overlap in file"; + } + } + } + } + + // more checks to be added here... + + return ""; + } + + //------------------------------------------------------------------------------ + private: + //------------------------------------------------------------------------------ + void clean() + { + delete header; + header = 0; + + std::vector::const_iterator it; + for ( it = sections_.begin(); it != sections_.end(); ++it ) { + delete *it; + } + sections_.clear(); + + std::vector::const_iterator it1; + for ( it1 = segments_.begin(); it1 != segments_.end(); ++it1 ) { + delete *it1; + } + segments_.clear(); + } + + //------------------------------------------------------------------------------ + elf_header* create_header( unsigned char file_class, + unsigned char encoding ) + { + elf_header* new_header = 0; + + if ( file_class == ELFCLASS64 ) { + new_header = + new elf_header_impl( &convertor, encoding ); + } + else if ( file_class == ELFCLASS32 ) { + new_header = + new elf_header_impl( &convertor, encoding ); + } + else { + return 0; + } + + return new_header; + } + + //------------------------------------------------------------------------------ + section* create_section() + { + section* new_section; + unsigned char file_class = get_class(); + + if ( file_class == ELFCLASS64 ) { + new_section = new section_impl( &convertor ); + } + else if ( file_class == ELFCLASS32 ) { + new_section = new section_impl( &convertor ); + } + else { + return 0; + } + + new_section->set_index( (Elf_Half)sections_.size() ); + sections_.push_back( new_section ); + + return new_section; + } + + //------------------------------------------------------------------------------ + segment* create_segment() + { + segment* new_segment; + unsigned char file_class = header->get_class(); + + if ( file_class == ELFCLASS64 ) { + new_segment = new segment_impl( &convertor ); + } + else if ( file_class == ELFCLASS32 ) { + new_segment = new segment_impl( &convertor ); + } + else { + return 0; + } + + new_segment->set_index( (Elf_Half)segments_.size() ); + segments_.push_back( new_segment ); + + return new_segment; + } + + //------------------------------------------------------------------------------ + void create_mandatory_sections() + { + // Create null section without calling to 'add_section' as no string + // section containing section names exists yet + section* sec0 = create_section(); + sec0->set_index( 0 ); + sec0->set_name( "" ); + sec0->set_name_string_offset( 0 ); + + set_section_name_str_index( 1 ); + section* shstrtab = sections.add( ".shstrtab" ); + shstrtab->set_type( SHT_STRTAB ); + shstrtab->set_addr_align( 1 ); + } + + //------------------------------------------------------------------------------ + Elf_Half load_sections( std::istream& stream ) + { + Elf_Half entry_size = header->get_section_entry_size(); + Elf_Half num = header->get_sections_num(); + Elf64_Off offset = header->get_sections_offset(); + + for ( Elf_Half i = 0; i < num; ++i ) { + section* sec = create_section(); + sec->load( stream, (std::streamoff)offset + + (std::streampos)i * entry_size ); + sec->set_index( i ); + // To mark that the section is not permitted to reassign address + // during layout calculation + sec->set_address( sec->get_address() ); + } + + Elf_Half shstrndx = get_section_name_str_index(); + + if ( SHN_UNDEF != shstrndx ) { + string_section_accessor str_reader( sections[shstrndx] ); + for ( Elf_Half i = 0; i < num; ++i ) { + Elf_Word section_offset = sections[i]->get_name_string_offset(); + const char* p = str_reader.get_string( section_offset ); + if ( p != 0 ) { + sections[i]->set_name( p ); + } + } + } + + return num; + } + + //------------------------------------------------------------------------------ + //! Checks whether the addresses of the section entirely fall within the given segment. + //! It doesn't matter if the addresses are memory addresses, or file offsets, + //! they just need to be in the same address space + bool is_sect_in_seg( Elf64_Off sect_begin, + Elf_Xword sect_size, + Elf64_Off seg_begin, + Elf64_Off seg_end ) + { + return ( seg_begin <= sect_begin ) && + ( sect_begin + sect_size <= seg_end ) && + ( sect_begin < + seg_end ); // this is important criteria when sect_size == 0 + // Example: seg_begin=10, seg_end=12 (-> covering the bytes 10 and 11) + // sect_begin=12, sect_size=0 -> shall return false! + } + + //------------------------------------------------------------------------------ + bool load_segments( std::istream& stream ) + { + Elf_Half entry_size = header->get_segment_entry_size(); + Elf_Half num = header->get_segments_num(); + Elf64_Off offset = header->get_segments_offset(); + + for ( Elf_Half i = 0; i < num; ++i ) { + segment* seg; + unsigned char file_class = header->get_class(); + + if ( file_class == ELFCLASS64 ) { + seg = new segment_impl( &convertor ); + } + else if ( file_class == ELFCLASS32 ) { + seg = new segment_impl( &convertor ); + } + else { + return false; + } + + seg->load( stream, (std::streamoff)offset + + (std::streampos)i * entry_size ); + seg->set_index( i ); + + // Add sections to the segments (similar to readelfs algorithm) + Elf64_Off segBaseOffset = seg->get_offset(); + Elf64_Off segEndOffset = segBaseOffset + seg->get_file_size(); + Elf64_Off segVBaseAddr = seg->get_virtual_address(); + Elf64_Off segVEndAddr = segVBaseAddr + seg->get_memory_size(); + for ( Elf_Half j = 0; j < sections.size(); ++j ) { + const section* psec = sections[j]; + + // SHF_ALLOC sections are matched based on the virtual address + // otherwise the file offset is matched + if ( ( psec->get_flags() & SHF_ALLOC ) + ? is_sect_in_seg( psec->get_address(), + psec->get_size(), segVBaseAddr, + segVEndAddr ) + : is_sect_in_seg( psec->get_offset(), psec->get_size(), + segBaseOffset, segEndOffset ) ) { + // Alignment of segment shall not be updated, to preserve original value + // It will be re-calculated on saving. + seg->add_section_index( psec->get_index(), 0 ); + } + } + + // Add section into the segments' container + segments_.push_back( seg ); + } + + return true; + } + + //------------------------------------------------------------------------------ + bool save_header( std::ostream& stream ) { return header->save( stream ); } + + //------------------------------------------------------------------------------ + bool save_sections( std::ostream& stream ) + { + for ( unsigned int i = 0; i < sections_.size(); ++i ) { + section* sec = sections_.at( i ); + + std::streampos headerPosition = + (std::streamoff)header->get_sections_offset() + + (std::streampos)header->get_section_entry_size() * + sec->get_index(); + + sec->save( stream, headerPosition, sec->get_offset() ); + } + return true; + } + + //------------------------------------------------------------------------------ + bool save_segments( std::ostream& stream ) + { + for ( unsigned int i = 0; i < segments_.size(); ++i ) { + segment* seg = segments_.at( i ); + + std::streampos headerPosition = + header->get_segments_offset() + + (std::streampos)header->get_segment_entry_size() * + seg->get_index(); + + seg->save( stream, headerPosition, seg->get_offset() ); + } + return true; + } + + //------------------------------------------------------------------------------ + bool is_section_without_segment( unsigned int section_index ) + { + bool found = false; + + for ( unsigned int j = 0; !found && ( j < segments.size() ); ++j ) { + for ( unsigned int k = 0; + !found && ( k < segments[j]->get_sections_num() ); ++k ) { + found = segments[j]->get_section_index_at( k ) == section_index; + } + } + + return !found; + } + + //------------------------------------------------------------------------------ + bool is_subsequence_of( segment* seg1, segment* seg2 ) + { + // Return 'true' if sections of seg1 are a subset of sections in seg2 + const std::vector& sections1 = seg1->get_sections(); + const std::vector& sections2 = seg2->get_sections(); + + bool found = false; + if ( sections1.size() < sections2.size() ) { + found = std::includes( sections2.begin(), sections2.end(), + sections1.begin(), sections1.end() ); + } + + return found; + } + + //------------------------------------------------------------------------------ + std::vector get_ordered_segments() + { + std::vector res; + std::deque worklist; + + res.reserve( segments.size() ); + std::copy( segments_.begin(), segments_.end(), + std::back_inserter( worklist ) ); + + // Bring the segments which start at address 0 to the front + size_t nextSlot = 0; + for ( size_t i = 0; i < worklist.size(); ++i ) { + if ( i != nextSlot && worklist[i]->is_offset_initialized() && + worklist[i]->get_offset() == 0 ) { + if ( worklist[nextSlot]->get_offset() == 0 ) { + ++nextSlot; + } + std::swap( worklist[i], worklist[nextSlot] ); + ++nextSlot; + } + } + + while ( !worklist.empty() ) { + segment* seg = worklist.front(); + worklist.pop_front(); + + size_t i = 0; + for ( ; i < worklist.size(); ++i ) { + if ( is_subsequence_of( seg, worklist[i] ) ) { + break; + } + } + + if ( i < worklist.size() ) + worklist.push_back( seg ); + else + res.push_back( seg ); + } + + return res; + } + + //------------------------------------------------------------------------------ + bool layout_sections_without_segments() + { + for ( unsigned int i = 0; i < sections_.size(); ++i ) { + if ( is_section_without_segment( i ) ) { + section* sec = sections_[i]; + + Elf_Xword section_align = sec->get_addr_align(); + if ( section_align > 1 && + current_file_pos % section_align != 0 ) { + current_file_pos += + section_align - current_file_pos % section_align; + } + + if ( 0 != sec->get_index() ) + sec->set_offset( current_file_pos ); + + if ( SHT_NOBITS != sec->get_type() && + SHT_NULL != sec->get_type() ) { + current_file_pos += sec->get_size(); + } + } + } + + return true; + } + + //------------------------------------------------------------------------------ + void calc_segment_alignment() + { + for ( std::vector::iterator s = segments_.begin(); + s != segments_.end(); ++s ) { + segment* seg = *s; + for ( int i = 0; i < seg->get_sections_num(); ++i ) { + section* sect = sections_[seg->get_section_index_at( i )]; + if ( sect->get_addr_align() > seg->get_align() ) { + seg->set_align( sect->get_addr_align() ); + } + } + } + } + + //------------------------------------------------------------------------------ + bool layout_segments_and_their_sections() + { + std::vector worklist; + std::vector section_generated( sections.size(), false ); + + // Get segments in a order in where segments which contain a + // sub sequence of other segments are located at the end + worklist = get_ordered_segments(); + + for ( unsigned int i = 0; i < worklist.size(); ++i ) { + Elf_Xword segment_memory = 0; + Elf_Xword segment_filesize = 0; + Elf_Xword seg_start_pos = current_file_pos; + segment* seg = worklist[i]; + + // Special case: PHDR segment + // This segment contains the program headers but no sections + if ( seg->get_type() == PT_PHDR && seg->get_sections_num() == 0 ) { + seg_start_pos = header->get_segments_offset(); + segment_memory = segment_filesize = + header->get_segment_entry_size() * + (Elf_Xword)header->get_segments_num(); + } + // Special case: + else if ( seg->is_offset_initialized() && seg->get_offset() == 0 ) { + seg_start_pos = 0; + if ( seg->get_sections_num() ) { + segment_memory = segment_filesize = current_file_pos; + } + } + // New segments with not generated sections + // have to be aligned + else if ( seg->get_sections_num() && + !section_generated[seg->get_section_index_at( 0 )] ) { + Elf_Xword align = seg->get_align() > 0 ? seg->get_align() : 1; + Elf64_Off cur_page_alignment = current_file_pos % align; + Elf64_Off req_page_alignment = + seg->get_virtual_address() % align; + Elf64_Off error = req_page_alignment - cur_page_alignment; + + current_file_pos += ( seg->get_align() + error ) % align; + seg_start_pos = current_file_pos; + } + else if ( seg->get_sections_num() ) { + seg_start_pos = + sections[seg->get_section_index_at( 0 )]->get_offset(); + } + + // Write segment's data + for ( unsigned int j = 0; j < seg->get_sections_num(); ++j ) { + Elf_Half index = seg->get_section_index_at( j ); + + section* sec = sections[index]; + + // The NULL section is always generated + if ( SHT_NULL == sec->get_type() ) { + section_generated[index] = true; + continue; + } + + Elf_Xword secAlign = 0; + // Fix up the alignment + if ( !section_generated[index] && + sec->is_address_initialized() && + SHT_NOBITS != sec->get_type() && + SHT_NULL != sec->get_type() && 0 != sec->get_size() ) { + // Align the sections based on the virtual addresses + // when possible (this is what matters for execution) + Elf64_Off req_offset = + sec->get_address() - seg->get_virtual_address(); + Elf64_Off cur_offset = current_file_pos - seg_start_pos; + if ( req_offset < cur_offset ) { + // something has gone awfully wrong, abort! + // secAlign would turn out negative, seeking backwards and overwriting previous data + return false; + } + secAlign = req_offset - cur_offset; + } + else if ( !section_generated[index] && + !sec->is_address_initialized() ) { + // If no address has been specified then only the section + // alignment constraint has to be matched + Elf_Xword align = sec->get_addr_align(); + if ( align == 0 ) { + align = 1; + } + Elf64_Off error = current_file_pos % align; + secAlign = ( align - error ) % align; + } + else if ( section_generated[index] ) { + // Alignment for already generated sections + secAlign = + sec->get_offset() - seg_start_pos - segment_filesize; + } + + // Determine the segment file and memory sizes + // Special case .tbss section (NOBITS) in non TLS segment + if ( ( sec->get_flags() & SHF_ALLOC ) && + !( ( sec->get_flags() & SHF_TLS ) && + ( seg->get_type() != PT_TLS ) && + ( SHT_NOBITS == sec->get_type() ) ) ) + segment_memory += sec->get_size() + secAlign; + + if ( SHT_NOBITS != sec->get_type() ) + segment_filesize += sec->get_size() + secAlign; + + // Nothing to be done when generating nested segments + if ( section_generated[index] ) { + continue; + } + + current_file_pos += secAlign; + + // Set the section addresses when missing + if ( !sec->is_address_initialized() ) + sec->set_address( seg->get_virtual_address() + + current_file_pos - seg_start_pos ); + + if ( 0 != sec->get_index() ) + sec->set_offset( current_file_pos ); + + if ( SHT_NOBITS != sec->get_type() ) + current_file_pos += sec->get_size(); + + section_generated[index] = true; + } + + seg->set_file_size( segment_filesize ); + + // If we already have a memory size from loading an elf file (value > 0), + // it must not shrink! + // Memory size may be bigger than file size and it is the loader's job to do something + // with the surplus bytes in memory, like initializing them with a defined value. + if ( seg->get_memory_size() < segment_memory ) { + seg->set_memory_size( segment_memory ); + } + + seg->set_offset( seg_start_pos ); + } + + return true; + } + + //------------------------------------------------------------------------------ + bool layout_section_table() + { + // Simply place the section table at the end for now + Elf64_Off alignmentError = current_file_pos % 4; + current_file_pos += ( 4 - alignmentError ) % 4; + header->set_sections_offset( current_file_pos ); + return true; + } + + //------------------------------------------------------------------------------ + public: + friend class Sections; + class Sections + { + public: + //------------------------------------------------------------------------------ + Sections( elfio* parent_ ) : parent( parent_ ) {} + + //------------------------------------------------------------------------------ + Elf_Half size() const { return (Elf_Half)parent->sections_.size(); } + + //------------------------------------------------------------------------------ + section* operator[]( unsigned int index ) const + { + section* sec = 0; + + if ( index < parent->sections_.size() ) { + sec = parent->sections_[index]; + } + + return sec; + } + + //------------------------------------------------------------------------------ + section* operator[]( const std::string& name ) const + { + section* sec = 0; + + std::vector::const_iterator it; + for ( it = parent->sections_.begin(); it != parent->sections_.end(); + ++it ) { + if ( ( *it )->get_name() == name ) { + sec = *it; + break; + } + } + + return sec; + } + + //------------------------------------------------------------------------------ + section* add( const std::string& name ) + { + section* new_section = parent->create_section(); + new_section->set_name( name ); + + Elf_Half str_index = parent->get_section_name_str_index(); + section* string_table( parent->sections_[str_index] ); + string_section_accessor str_writer( string_table ); + Elf_Word pos = str_writer.add_string( name ); + new_section->set_name_string_offset( pos ); + + return new_section; + } + + //------------------------------------------------------------------------------ + std::vector::iterator begin() + { + return parent->sections_.begin(); + } + + //------------------------------------------------------------------------------ + std::vector::iterator end() + { + return parent->sections_.end(); + } + + //------------------------------------------------------------------------------ + std::vector::const_iterator begin() const + { + return parent->sections_.cbegin(); + } + + //------------------------------------------------------------------------------ + std::vector::const_iterator end() const + { + return parent->sections_.cend(); + } + + //------------------------------------------------------------------------------ + private: + elfio* parent; + } sections; + + //------------------------------------------------------------------------------ + public: + friend class Segments; + class Segments + { + public: + //------------------------------------------------------------------------------ + Segments( elfio* parent_ ) : parent( parent_ ) {} + + //------------------------------------------------------------------------------ + Elf_Half size() const { return (Elf_Half)parent->segments_.size(); } + + //------------------------------------------------------------------------------ + segment* operator[]( unsigned int index ) const + { + return parent->segments_[index]; + } + + //------------------------------------------------------------------------------ + segment* add() { return parent->create_segment(); } + + //------------------------------------------------------------------------------ + std::vector::iterator begin() + { + return parent->segments_.begin(); + } + + //------------------------------------------------------------------------------ + std::vector::iterator end() + { + return parent->segments_.end(); + } + + //------------------------------------------------------------------------------ + std::vector::const_iterator begin() const + { + return parent->segments_.cbegin(); + } + + //------------------------------------------------------------------------------ + std::vector::const_iterator end() const + { + return parent->segments_.cend(); + } + + //------------------------------------------------------------------------------ + private: + elfio* parent; + } segments; + + //------------------------------------------------------------------------------ + private: + elf_header* header; + std::vector sections_; + std::vector segments_; + endianess_convertor convertor; + + Elf_Xword current_file_pos; +}; + +} // namespace ELFIO + + +/*** Start of inlined file: elfio_symbols.hpp ***/ +#ifndef ELFIO_SYMBOLS_HPP +#define ELFIO_SYMBOLS_HPP + +namespace ELFIO { + +//------------------------------------------------------------------------------ +template class symbol_section_accessor_template +{ + public: + //------------------------------------------------------------------------------ + symbol_section_accessor_template( const elfio& elf_file_, + S* symbol_section_ ) + : elf_file( elf_file_ ), symbol_section( symbol_section_ ) + { + find_hash_section(); + } + + //------------------------------------------------------------------------------ + Elf_Xword get_symbols_num() const + { + Elf_Xword nRet = 0; + if ( 0 != symbol_section->get_entry_size() ) { + nRet = + symbol_section->get_size() / symbol_section->get_entry_size(); + } + + return nRet; + } + + //------------------------------------------------------------------------------ + bool get_symbol( Elf_Xword index, + std::string& name, + Elf64_Addr& value, + Elf_Xword& size, + unsigned char& bind, + unsigned char& type, + Elf_Half& section_index, + unsigned char& other ) const + { + bool ret = false; + + if ( elf_file.get_class() == ELFCLASS32 ) { + ret = generic_get_symbol( index, name, value, size, bind, + type, section_index, other ); + } + else { + ret = generic_get_symbol( index, name, value, size, bind, + type, section_index, other ); + } + + return ret; + } + + //------------------------------------------------------------------------------ + bool get_symbol( const std::string& name, + Elf64_Addr& value, + Elf_Xword& size, + unsigned char& bind, + unsigned char& type, + Elf_Half& section_index, + unsigned char& other ) const + { + bool ret = false; + + if ( 0 != get_hash_table_index() ) { + Elf_Word nbucket = *(const Elf_Word*)hash_section->get_data(); + Elf_Word nchain = *(const Elf_Word*)( hash_section->get_data() + + sizeof( Elf_Word ) ); + Elf_Word val = elf_hash( (const unsigned char*)name.c_str() ); + Elf_Word y = *(const Elf_Word*)( hash_section->get_data() + + ( 2 + val % nbucket ) * + sizeof( Elf_Word ) ); + std::string str; + get_symbol( y, str, value, size, bind, type, section_index, other ); + while ( str != name && STN_UNDEF != y && y < nchain ) { + y = *(const Elf_Word*)( hash_section->get_data() + + ( 2 + nbucket + y ) * + sizeof( Elf_Word ) ); + get_symbol( y, str, value, size, bind, type, section_index, + other ); + } + if ( str == name ) { + ret = true; + } + } + else { + for ( Elf_Xword i = 0; i < get_symbols_num() && !ret; i++ ) { + std::string symbol_name; + if ( get_symbol( i, symbol_name, value, size, bind, type, + section_index, other ) ) { + if ( symbol_name == name ) { + ret = true; + } + } + } + } + + return ret; + } + + //------------------------------------------------------------------------------ + bool get_symbol( const Elf64_Addr& value, + std::string& name, + Elf_Xword& size, + unsigned char& bind, + unsigned char& type, + Elf_Half& section_index, + unsigned char& other ) const + { + + const endianess_convertor& convertor = elf_file.get_convertor(); + + Elf_Xword idx = 0; + bool match = false; + Elf64_Addr v = 0; + + if ( elf_file.get_class() == ELFCLASS32 ) { + match = generic_search_symbols( + [&]( const Elf32_Sym* sym ) { + return convertor( sym->st_value ) == value; + }, + idx ); + } + else { + match = generic_search_symbols( + [&]( const Elf64_Sym* sym ) { + return convertor( sym->st_value ) == value; + }, + idx ); + } + + if ( match ) { + return get_symbol( idx, name, v, size, bind, type, section_index, + other ); + } + + return false; + } + + //------------------------------------------------------------------------------ + Elf_Word add_symbol( Elf_Word name, + Elf64_Addr value, + Elf_Xword size, + unsigned char info, + unsigned char other, + Elf_Half shndx ) + { + Elf_Word nRet; + + if ( symbol_section->get_size() == 0 ) { + if ( elf_file.get_class() == ELFCLASS32 ) { + nRet = generic_add_symbol( 0, 0, 0, 0, 0, 0 ); + } + else { + nRet = generic_add_symbol( 0, 0, 0, 0, 0, 0 ); + } + } + + if ( elf_file.get_class() == ELFCLASS32 ) { + nRet = generic_add_symbol( name, value, size, info, + other, shndx ); + } + else { + nRet = generic_add_symbol( name, value, size, info, + other, shndx ); + } + + return nRet; + } + + //------------------------------------------------------------------------------ + Elf_Word add_symbol( Elf_Word name, + Elf64_Addr value, + Elf_Xword size, + unsigned char bind, + unsigned char type, + unsigned char other, + Elf_Half shndx ) + { + return add_symbol( name, value, size, ELF_ST_INFO( bind, type ), other, + shndx ); + } + + //------------------------------------------------------------------------------ + Elf_Word add_symbol( string_section_accessor& pStrWriter, + const char* str, + Elf64_Addr value, + Elf_Xword size, + unsigned char info, + unsigned char other, + Elf_Half shndx ) + { + Elf_Word index = pStrWriter.add_string( str ); + return add_symbol( index, value, size, info, other, shndx ); + } + + //------------------------------------------------------------------------------ + Elf_Word add_symbol( string_section_accessor& pStrWriter, + const char* str, + Elf64_Addr value, + Elf_Xword size, + unsigned char bind, + unsigned char type, + unsigned char other, + Elf_Half shndx ) + { + return add_symbol( pStrWriter, str, value, size, + ELF_ST_INFO( bind, type ), other, shndx ); + } + + //------------------------------------------------------------------------------ + Elf_Xword arrange_local_symbols( + std::function func = + nullptr ) + { + int nRet = 0; + + if ( elf_file.get_class() == ELFCLASS32 ) { + nRet = generic_arrange_local_symbols( func ); + } + else { + nRet = generic_arrange_local_symbols( func ); + } + + return nRet; + } + + //------------------------------------------------------------------------------ + private: + //------------------------------------------------------------------------------ + void find_hash_section() + { + hash_section = 0; + hash_section_index = 0; + Elf_Half nSecNo = elf_file.sections.size(); + for ( Elf_Half i = 0; i < nSecNo && 0 == hash_section_index; ++i ) { + const section* sec = elf_file.sections[i]; + if ( sec->get_link() == symbol_section->get_index() ) { + hash_section = sec; + hash_section_index = i; + } + } + } + + //------------------------------------------------------------------------------ + Elf_Half get_string_table_index() const + { + return (Elf_Half)symbol_section->get_link(); + } + + //------------------------------------------------------------------------------ + Elf_Half get_hash_table_index() const { return hash_section_index; } + + //------------------------------------------------------------------------------ + template const T* generic_get_symbol_ptr( Elf_Xword index ) const + { + if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) { + const T* pSym = reinterpret_cast( + symbol_section->get_data() + + index * symbol_section->get_entry_size() ); + + return pSym; + } + + return nullptr; + } + + //------------------------------------------------------------------------------ + template + bool generic_search_symbols( std::function match, + Elf_Xword& idx ) const + { + for ( Elf_Xword i = 0; i < get_symbols_num(); i++ ) { + const T* symPtr = generic_get_symbol_ptr( i ); + + if ( symPtr == nullptr ) + return false; + + if ( match( symPtr ) ) { + idx = i; + return true; + } + } + + return false; + } + + //------------------------------------------------------------------------------ + template + bool generic_get_symbol( Elf_Xword index, + std::string& name, + Elf64_Addr& value, + Elf_Xword& size, + unsigned char& bind, + unsigned char& type, + Elf_Half& section_index, + unsigned char& other ) const + { + bool ret = false; + + if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) { + const T* pSym = reinterpret_cast( + symbol_section->get_data() + + index * symbol_section->get_entry_size() ); + + const endianess_convertor& convertor = elf_file.get_convertor(); + + section* string_section = + elf_file.sections[get_string_table_index()]; + string_section_accessor str_reader( string_section ); + const char* pStr = + str_reader.get_string( convertor( pSym->st_name ) ); + if ( 0 != pStr ) { + name = pStr; + } + value = convertor( pSym->st_value ); + size = convertor( pSym->st_size ); + bind = ELF_ST_BIND( pSym->st_info ); + type = ELF_ST_TYPE( pSym->st_info ); + section_index = convertor( pSym->st_shndx ); + other = pSym->st_other; + + ret = true; + } + + return ret; + } + + //------------------------------------------------------------------------------ + template + Elf_Word generic_add_symbol( Elf_Word name, + Elf64_Addr value, + Elf_Xword size, + unsigned char info, + unsigned char other, + Elf_Half shndx ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + T entry; + entry.st_name = convertor( name ); + entry.st_value = value; + entry.st_value = convertor( entry.st_value ); + entry.st_size = size; + entry.st_size = convertor( entry.st_size ); + entry.st_info = convertor( info ); + entry.st_other = convertor( other ); + entry.st_shndx = convertor( shndx ); + + symbol_section->append_data( reinterpret_cast( &entry ), + sizeof( entry ) ); + + Elf_Word nRet = symbol_section->get_size() / sizeof( entry ) - 1; + + return nRet; + } + + //------------------------------------------------------------------------------ + template + Elf_Xword generic_arrange_local_symbols( + std::function func ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + const Elf_Xword size = symbol_section->get_entry_size(); + + Elf_Xword first_not_local = + 1; // Skip the first entry. It is always NOTYPE + Elf_Xword current = 0; + Elf_Xword count = get_symbols_num(); + + while ( true ) { + T* p1 = nullptr; + T* p2 = nullptr; + + while ( first_not_local < count ) { + p1 = const_cast( + generic_get_symbol_ptr( first_not_local ) ); + if ( ELF_ST_BIND( convertor( p1->st_info ) ) != STB_LOCAL ) + break; + ++first_not_local; + } + + current = first_not_local + 1; + while ( current < count ) { + p2 = const_cast( generic_get_symbol_ptr( current ) ); + if ( ELF_ST_BIND( convertor( p2->st_info ) ) == STB_LOCAL ) + break; + ++current; + } + + if ( first_not_local < count && current < count ) { + if ( func ) + func( first_not_local, current ); + + // Swap the symbols + T tmp; + std::copy( p1, p1 + 1, &tmp ); + std::copy( p2, p2 + 1, p1 ); + std::copy( &tmp, &tmp + 1, p2 ); + } + else { + // Update 'info' field of the section + symbol_section->set_info( first_not_local ); + break; + } + } + + // Elf_Word nRet = symbol_section->get_size() / sizeof(entry) - 1; + + return first_not_local; + } + + //------------------------------------------------------------------------------ + private: + const elfio& elf_file; + S* symbol_section; + Elf_Half hash_section_index; + const section* hash_section; +}; + +using symbol_section_accessor = symbol_section_accessor_template
; +using const_symbol_section_accessor = + symbol_section_accessor_template; + +} // namespace ELFIO + +#endif // ELFIO_SYMBOLS_HPP + +/*** End of inlined file: elfio_symbols.hpp ***/ + + +/*** Start of inlined file: elfio_note.hpp ***/ +#ifndef ELFIO_NOTE_HPP +#define ELFIO_NOTE_HPP + +namespace ELFIO { + +//------------------------------------------------------------------------------ +// There are discrepancies in documentations. SCO documentation +// (http://www.sco.com/developers/gabi/latest/ch5.pheader.html#note_section) +// requires 8 byte entries alignment for 64-bit ELF file, +// but Oracle's definition uses the same structure +// for 32-bit and 64-bit formats. +// (https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html) +// +// It looks like EM_X86_64 Linux implementation is similar to Oracle's +// definition. Therefore, the same alignment works for both formats +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +template class note_section_accessor_template +{ + public: + //------------------------------------------------------------------------------ + note_section_accessor_template( const elfio& elf_file_, S* section_ ) + : elf_file( elf_file_ ), note_section( section_ ) + { + process_section(); + } + + //------------------------------------------------------------------------------ + Elf_Word get_notes_num() const + { + return (Elf_Word)note_start_positions.size(); + } + + //------------------------------------------------------------------------------ + bool get_note( Elf_Word index, + Elf_Word& type, + std::string& name, + void*& desc, + Elf_Word& descSize ) const + { + if ( index >= note_section->get_size() ) { + return false; + } + + const char* pData = + note_section->get_data() + note_start_positions[index]; + int align = sizeof( Elf_Word ); + + const endianess_convertor& convertor = elf_file.get_convertor(); + type = convertor( *(const Elf_Word*)( pData + 2 * align ) ); + Elf_Word namesz = convertor( *(const Elf_Word*)( pData ) ); + descSize = convertor( *(const Elf_Word*)( pData + sizeof( namesz ) ) ); + + Elf_Xword max_name_size = + note_section->get_size() - note_start_positions[index]; + if ( namesz < 1 || namesz > max_name_size || + (Elf_Xword)namesz + descSize > max_name_size ) { + return false; + } + name.assign( pData + 3 * align, namesz - 1 ); + if ( 0 == descSize ) { + desc = 0; + } + else { + desc = + const_cast( pData + 3 * align + + ( ( namesz + align - 1 ) / align ) * align ); + } + + return true; + } + + //------------------------------------------------------------------------------ + void add_note( Elf_Word type, + const std::string& name, + const void* desc, + Elf_Word descSize ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + int align = sizeof( Elf_Word ); + Elf_Word nameLen = (Elf_Word)name.size() + 1; + Elf_Word nameLenConv = convertor( nameLen ); + std::string buffer( reinterpret_cast( &nameLenConv ), align ); + Elf_Word descSizeConv = convertor( descSize ); + + buffer.append( reinterpret_cast( &descSizeConv ), align ); + type = convertor( type ); + buffer.append( reinterpret_cast( &type ), align ); + buffer.append( name ); + buffer.append( 1, '\x00' ); + const char pad[] = { '\0', '\0', '\0', '\0' }; + if ( nameLen % align != 0 ) { + buffer.append( pad, align - nameLen % align ); + } + if ( desc != 0 && descSize != 0 ) { + buffer.append( reinterpret_cast( desc ), descSize ); + if ( descSize % align != 0 ) { + buffer.append( pad, align - descSize % align ); + } + } + + note_start_positions.push_back( note_section->get_size() ); + note_section->append_data( buffer ); + } + + private: + //------------------------------------------------------------------------------ + void process_section() + { + const endianess_convertor& convertor = elf_file.get_convertor(); + const char* data = note_section->get_data(); + Elf_Xword size = note_section->get_size(); + Elf_Xword current = 0; + + note_start_positions.clear(); + + // Is it empty? + if ( 0 == data || 0 == size ) { + return; + } + + Elf_Word align = sizeof( Elf_Word ); + while ( current + (Elf_Xword)3 * align <= size ) { + note_start_positions.push_back( current ); + Elf_Word namesz = convertor( *(const Elf_Word*)( data + current ) ); + Elf_Word descsz = convertor( + *(const Elf_Word*)( data + current + sizeof( namesz ) ) ); + + current += (Elf_Xword)3 * sizeof( Elf_Word ) + + ( ( namesz + align - 1 ) / align ) * (Elf_Xword)align + + ( ( descsz + align - 1 ) / align ) * (Elf_Xword)align; + } + } + + //------------------------------------------------------------------------------ + private: + const elfio& elf_file; + S* note_section; + std::vector note_start_positions; +}; + +using note_section_accessor = note_section_accessor_template
; +using const_note_section_accessor = + note_section_accessor_template; + +} // namespace ELFIO + +#endif // ELFIO_NOTE_HPP + +/*** End of inlined file: elfio_note.hpp ***/ + + +/*** Start of inlined file: elfio_relocation.hpp ***/ +#ifndef ELFIO_RELOCATION_HPP +#define ELFIO_RELOCATION_HPP + +namespace ELFIO { + +template struct get_sym_and_type; +template <> struct get_sym_and_type +{ + static int get_r_sym( Elf_Xword info ) + { + return ELF32_R_SYM( (Elf_Word)info ); + } + static int get_r_type( Elf_Xword info ) + { + return ELF32_R_TYPE( (Elf_Word)info ); + } +}; +template <> struct get_sym_and_type +{ + static int get_r_sym( Elf_Xword info ) + { + return ELF32_R_SYM( (Elf_Word)info ); + } + static int get_r_type( Elf_Xword info ) + { + return ELF32_R_TYPE( (Elf_Word)info ); + } +}; +template <> struct get_sym_and_type +{ + static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); } + static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); } +}; +template <> struct get_sym_and_type +{ + static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); } + static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); } +}; + +//------------------------------------------------------------------------------ +template class relocation_section_accessor_template +{ + public: + //------------------------------------------------------------------------------ + relocation_section_accessor_template( const elfio& elf_file_, S* section_ ) + : elf_file( elf_file_ ), relocation_section( section_ ) + { + } + + //------------------------------------------------------------------------------ + Elf_Xword get_entries_num() const + { + Elf_Xword nRet = 0; + + if ( 0 != relocation_section->get_entry_size() ) { + nRet = relocation_section->get_size() / + relocation_section->get_entry_size(); + } + + return nRet; + } + + //------------------------------------------------------------------------------ + bool get_entry( Elf_Xword index, + Elf64_Addr& offset, + Elf_Word& symbol, + Elf_Word& type, + Elf_Sxword& addend ) const + { + if ( index >= get_entries_num() ) { // Is index valid + return false; + } + + if ( elf_file.get_class() == ELFCLASS32 ) { + if ( SHT_REL == relocation_section->get_type() ) { + generic_get_entry_rel( index, offset, symbol, type, + addend ); + } + else if ( SHT_RELA == relocation_section->get_type() ) { + generic_get_entry_rela( index, offset, symbol, type, + addend ); + } + } + else { + if ( SHT_REL == relocation_section->get_type() ) { + generic_get_entry_rel( index, offset, symbol, type, + addend ); + } + else if ( SHT_RELA == relocation_section->get_type() ) { + generic_get_entry_rela( index, offset, symbol, type, + addend ); + } + } + + return true; + } + + //------------------------------------------------------------------------------ + bool get_entry( Elf_Xword index, + Elf64_Addr& offset, + Elf64_Addr& symbolValue, + std::string& symbolName, + Elf_Word& type, + Elf_Sxword& addend, + Elf_Sxword& calcValue ) const + { + // Do regular job + Elf_Word symbol; + bool ret = get_entry( index, offset, symbol, type, addend ); + + // Find the symbol + Elf_Xword size; + unsigned char bind; + unsigned char symbolType; + Elf_Half section; + unsigned char other; + + symbol_section_accessor symbols( + elf_file, elf_file.sections[get_symbol_table_index()] ); + ret = ret && symbols.get_symbol( symbol, symbolName, symbolValue, size, + bind, symbolType, section, other ); + + if ( ret ) { // Was it successful? + switch ( type ) { + case R_386_NONE: // none + calcValue = 0; + break; + case R_386_32: // S + A + calcValue = symbolValue + addend; + break; + case R_386_PC32: // S + A - P + calcValue = symbolValue + addend - offset; + break; + case R_386_GOT32: // G + A - P + calcValue = 0; + break; + case R_386_PLT32: // L + A - P + calcValue = 0; + break; + case R_386_COPY: // none + calcValue = 0; + break; + case R_386_GLOB_DAT: // S + case R_386_JMP_SLOT: // S + calcValue = symbolValue; + break; + case R_386_RELATIVE: // B + A + calcValue = addend; + break; + case R_386_GOTOFF: // S + A - GOT + calcValue = 0; + break; + case R_386_GOTPC: // GOT + A - P + calcValue = 0; + break; + default: // Not recognized symbol! + calcValue = 0; + break; + } + } + + return ret; + } + + //------------------------------------------------------------------------------ + bool set_entry( Elf_Xword index, + Elf64_Addr offset, + Elf_Word symbol, + Elf_Word type, + Elf_Sxword addend ) + { + if ( index >= get_entries_num() ) { // Is index valid + return false; + } + + if ( elf_file.get_class() == ELFCLASS32 ) { + if ( SHT_REL == relocation_section->get_type() ) { + generic_set_entry_rel( index, offset, symbol, type, + addend ); + } + else if ( SHT_RELA == relocation_section->get_type() ) { + generic_set_entry_rela( index, offset, symbol, type, + addend ); + } + } + else { + if ( SHT_REL == relocation_section->get_type() ) { + generic_set_entry_rel( index, offset, symbol, type, + addend ); + } + else if ( SHT_RELA == relocation_section->get_type() ) { + generic_set_entry_rela( index, offset, symbol, type, + addend ); + } + } + + return true; + } + + //------------------------------------------------------------------------------ + void add_entry( Elf64_Addr offset, Elf_Xword info ) + { + if ( elf_file.get_class() == ELFCLASS32 ) { + generic_add_entry( offset, info ); + } + else { + generic_add_entry( offset, info ); + } + } + + //------------------------------------------------------------------------------ + void add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type ) + { + Elf_Xword info; + if ( elf_file.get_class() == ELFCLASS32 ) { + info = ELF32_R_INFO( (Elf_Xword)symbol, type ); + } + else { + info = ELF64_R_INFO( (Elf_Xword)symbol, type ); + } + + add_entry( offset, info ); + } + + //------------------------------------------------------------------------------ + void add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) + { + if ( elf_file.get_class() == ELFCLASS32 ) { + generic_add_entry( offset, info, addend ); + } + else { + generic_add_entry( offset, info, addend ); + } + } + + //------------------------------------------------------------------------------ + void add_entry( Elf64_Addr offset, + Elf_Word symbol, + unsigned char type, + Elf_Sxword addend ) + { + Elf_Xword info; + if ( elf_file.get_class() == ELFCLASS32 ) { + info = ELF32_R_INFO( (Elf_Xword)symbol, type ); + } + else { + info = ELF64_R_INFO( (Elf_Xword)symbol, type ); + } + + add_entry( offset, info, addend ); + } + + //------------------------------------------------------------------------------ + void add_entry( string_section_accessor str_writer, + const char* str, + symbol_section_accessor sym_writer, + Elf64_Addr value, + Elf_Word size, + unsigned char sym_info, + unsigned char other, + Elf_Half shndx, + Elf64_Addr offset, + unsigned char type ) + { + Elf_Word str_index = str_writer.add_string( str ); + Elf_Word sym_index = sym_writer.add_symbol( str_index, value, size, + sym_info, other, shndx ); + add_entry( offset, sym_index, type ); + } + + //------------------------------------------------------------------------------ + void swap_symbols( Elf_Xword first, Elf_Xword second ) + { + Elf64_Addr offset; + Elf_Word symbol; + Elf_Word rtype; + Elf_Sxword addend; + for ( Elf_Word i = 0; i < get_entries_num(); i++ ) { + get_entry( i, offset, symbol, rtype, addend ); + if ( symbol == first ) { + set_entry( i, offset, (Elf_Word)second, rtype, addend ); + } + if ( symbol == second ) { + set_entry( i, offset, (Elf_Word)first, rtype, addend ); + } + } + } + + //------------------------------------------------------------------------------ + private: + //------------------------------------------------------------------------------ + Elf_Half get_symbol_table_index() const + { + return (Elf_Half)relocation_section->get_link(); + } + + //------------------------------------------------------------------------------ + template + void generic_get_entry_rel( Elf_Xword index, + Elf64_Addr& offset, + Elf_Word& symbol, + Elf_Word& type, + Elf_Sxword& addend ) const + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + const T* pEntry = reinterpret_cast( + relocation_section->get_data() + + index * relocation_section->get_entry_size() ); + offset = convertor( pEntry->r_offset ); + Elf_Xword tmp = convertor( pEntry->r_info ); + symbol = get_sym_and_type::get_r_sym( tmp ); + type = get_sym_and_type::get_r_type( tmp ); + addend = 0; + } + + //------------------------------------------------------------------------------ + template + void generic_get_entry_rela( Elf_Xword index, + Elf64_Addr& offset, + Elf_Word& symbol, + Elf_Word& type, + Elf_Sxword& addend ) const + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + const T* pEntry = reinterpret_cast( + relocation_section->get_data() + + index * relocation_section->get_entry_size() ); + offset = convertor( pEntry->r_offset ); + Elf_Xword tmp = convertor( pEntry->r_info ); + symbol = get_sym_and_type::get_r_sym( tmp ); + type = get_sym_and_type::get_r_type( tmp ); + addend = convertor( pEntry->r_addend ); + } + + //------------------------------------------------------------------------------ + template + void generic_set_entry_rel( Elf_Xword index, + Elf64_Addr offset, + Elf_Word symbol, + Elf_Word type, + Elf_Sxword ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + T* pEntry = const_cast( reinterpret_cast( + relocation_section->get_data() + + index * relocation_section->get_entry_size() ) ); + + if ( elf_file.get_class() == ELFCLASS32 ) { + pEntry->r_info = ELF32_R_INFO( (Elf_Xword)symbol, type ); + } + else { + pEntry->r_info = ELF64_R_INFO( (Elf_Xword)symbol, type ); + } + pEntry->r_offset = offset; + pEntry->r_offset = convertor( pEntry->r_offset ); + pEntry->r_info = convertor( pEntry->r_info ); + } + + //------------------------------------------------------------------------------ + template + void generic_set_entry_rela( Elf_Xword index, + Elf64_Addr offset, + Elf_Word symbol, + Elf_Word type, + Elf_Sxword addend ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + T* pEntry = const_cast( reinterpret_cast( + relocation_section->get_data() + + index * relocation_section->get_entry_size() ) ); + + if ( elf_file.get_class() == ELFCLASS32 ) { + pEntry->r_info = ELF32_R_INFO( (Elf_Xword)symbol, type ); + } + else { + pEntry->r_info = ELF64_R_INFO( (Elf_Xword)symbol, type ); + } + pEntry->r_offset = offset; + pEntry->r_addend = addend; + pEntry->r_offset = convertor( pEntry->r_offset ); + pEntry->r_info = convertor( pEntry->r_info ); + pEntry->r_addend = convertor( pEntry->r_addend ); + } + + //------------------------------------------------------------------------------ + template + void generic_add_entry( Elf64_Addr offset, Elf_Xword info ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + T entry; + entry.r_offset = offset; + entry.r_info = info; + entry.r_offset = convertor( entry.r_offset ); + entry.r_info = convertor( entry.r_info ); + + relocation_section->append_data( reinterpret_cast( &entry ), + sizeof( entry ) ); + } + + //------------------------------------------------------------------------------ + template + void + generic_add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + T entry; + entry.r_offset = offset; + entry.r_info = info; + entry.r_addend = addend; + entry.r_offset = convertor( entry.r_offset ); + entry.r_info = convertor( entry.r_info ); + entry.r_addend = convertor( entry.r_addend ); + + relocation_section->append_data( reinterpret_cast( &entry ), + sizeof( entry ) ); + } + + //------------------------------------------------------------------------------ + private: + const elfio& elf_file; + S* relocation_section; +}; + +using relocation_section_accessor = + relocation_section_accessor_template
; +using const_relocation_section_accessor = + relocation_section_accessor_template; + +} // namespace ELFIO + +#endif // ELFIO_RELOCATION_HPP + +/*** End of inlined file: elfio_relocation.hpp ***/ + + +/*** Start of inlined file: elfio_dynamic.hpp ***/ +#ifndef ELFIO_DYNAMIC_HPP +#define ELFIO_DYNAMIC_HPP + +namespace ELFIO { + +//------------------------------------------------------------------------------ +template class dynamic_section_accessor_template +{ + public: + //------------------------------------------------------------------------------ + dynamic_section_accessor_template( const elfio& elf_file_, S* section_ ) + : elf_file( elf_file_ ), dynamic_section( section_ ) + { + } + + //------------------------------------------------------------------------------ + Elf_Xword get_entries_num() const + { + Elf_Xword nRet = 0; + + if ( 0 != dynamic_section->get_entry_size() ) { + nRet = + dynamic_section->get_size() / dynamic_section->get_entry_size(); + } + + return nRet; + } + + //------------------------------------------------------------------------------ + bool get_entry( Elf_Xword index, + Elf_Xword& tag, + Elf_Xword& value, + std::string& str ) const + { + if ( index >= get_entries_num() ) { // Is index valid + return false; + } + + if ( elf_file.get_class() == ELFCLASS32 ) { + generic_get_entry_dyn( index, tag, value ); + } + else { + generic_get_entry_dyn( index, tag, value ); + } + + // If the tag may have a string table reference, prepare the string + if ( tag == DT_NEEDED || tag == DT_SONAME || tag == DT_RPATH || + tag == DT_RUNPATH ) { + string_section_accessor strsec = + elf_file.sections[get_string_table_index()]; + const char* result = strsec.get_string( value ); + if ( 0 == result ) { + str.clear(); + return false; + } + str = result; + } + else { + str.clear(); + } + + return true; + } + + //------------------------------------------------------------------------------ + void add_entry( Elf_Xword tag, Elf_Xword value ) + { + if ( elf_file.get_class() == ELFCLASS32 ) { + generic_add_entry( tag, value ); + } + else { + generic_add_entry( tag, value ); + } + } + + //------------------------------------------------------------------------------ + void add_entry( Elf_Xword tag, const std::string& str ) + { + string_section_accessor strsec = + elf_file.sections[get_string_table_index()]; + Elf_Xword value = strsec.add_string( str ); + add_entry( tag, value ); + } + + //------------------------------------------------------------------------------ + private: + //------------------------------------------------------------------------------ + Elf_Half get_string_table_index() const + { + return (Elf_Half)dynamic_section->get_link(); + } + + //------------------------------------------------------------------------------ + template + void generic_get_entry_dyn( Elf_Xword index, + Elf_Xword& tag, + Elf_Xword& value ) const + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + // Check unusual case when dynamic section has no data + if ( dynamic_section->get_data() == 0 || + ( index + 1 ) * dynamic_section->get_entry_size() > + dynamic_section->get_size() ) { + tag = DT_NULL; + value = 0; + return; + } + + const T* pEntry = reinterpret_cast( + dynamic_section->get_data() + + index * dynamic_section->get_entry_size() ); + tag = convertor( pEntry->d_tag ); + switch ( tag ) { + case DT_NULL: + case DT_SYMBOLIC: + case DT_TEXTREL: + case DT_BIND_NOW: + value = 0; + break; + case DT_NEEDED: + case DT_PLTRELSZ: + case DT_RELASZ: + case DT_RELAENT: + case DT_STRSZ: + case DT_SYMENT: + case DT_SONAME: + case DT_RPATH: + case DT_RELSZ: + case DT_RELENT: + case DT_PLTREL: + case DT_INIT_ARRAYSZ: + case DT_FINI_ARRAYSZ: + case DT_RUNPATH: + case DT_FLAGS: + case DT_PREINIT_ARRAYSZ: + value = convertor( pEntry->d_un.d_val ); + break; + case DT_PLTGOT: + case DT_HASH: + case DT_STRTAB: + case DT_SYMTAB: + case DT_RELA: + case DT_INIT: + case DT_FINI: + case DT_REL: + case DT_DEBUG: + case DT_JMPREL: + case DT_INIT_ARRAY: + case DT_FINI_ARRAY: + case DT_PREINIT_ARRAY: + default: + value = convertor( pEntry->d_un.d_ptr ); + break; + } + } + + //------------------------------------------------------------------------------ + template void generic_add_entry( Elf_Xword tag, Elf_Xword value ) + { + const endianess_convertor& convertor = elf_file.get_convertor(); + + T entry; + + switch ( tag ) { + case DT_NULL: + case DT_SYMBOLIC: + case DT_TEXTREL: + case DT_BIND_NOW: + value = 0; + case DT_NEEDED: + case DT_PLTRELSZ: + case DT_RELASZ: + case DT_RELAENT: + case DT_STRSZ: + case DT_SYMENT: + case DT_SONAME: + case DT_RPATH: + case DT_RELSZ: + case DT_RELENT: + case DT_PLTREL: + case DT_INIT_ARRAYSZ: + case DT_FINI_ARRAYSZ: + case DT_RUNPATH: + case DT_FLAGS: + case DT_PREINIT_ARRAYSZ: + entry.d_un.d_val = convertor( value ); + break; + case DT_PLTGOT: + case DT_HASH: + case DT_STRTAB: + case DT_SYMTAB: + case DT_RELA: + case DT_INIT: + case DT_FINI: + case DT_REL: + case DT_DEBUG: + case DT_JMPREL: + case DT_INIT_ARRAY: + case DT_FINI_ARRAY: + case DT_PREINIT_ARRAY: + default: + entry.d_un.d_ptr = convertor( value ); + break; + } + + entry.d_tag = convertor( tag ); + + dynamic_section->append_data( reinterpret_cast( &entry ), + sizeof( entry ) ); + } + + //------------------------------------------------------------------------------ + private: + const elfio& elf_file; + S* dynamic_section; +}; + +using dynamic_section_accessor = dynamic_section_accessor_template
; +using const_dynamic_section_accessor = + dynamic_section_accessor_template; + +} // namespace ELFIO + +#endif // ELFIO_DYNAMIC_HPP + +/*** End of inlined file: elfio_dynamic.hpp ***/ + + +/*** Start of inlined file: elfio_modinfo.hpp ***/ +#ifndef ELFIO_MODINFO_HPP +#define ELFIO_MODINFO_HPP + +#include +#include + +namespace ELFIO { + +//------------------------------------------------------------------------------ +template class modinfo_section_accessor_template +{ + public: + //------------------------------------------------------------------------------ + modinfo_section_accessor_template( S* section_ ) + : modinfo_section( section_ ) + { + process_section(); + } + + //------------------------------------------------------------------------------ + Elf_Word get_attribute_num() const { return (Elf_Word)content.size(); } + + //------------------------------------------------------------------------------ + bool + get_attribute( Elf_Word no, std::string& field, std::string& value ) const + { + if ( no < content.size() ) { + field = content[no].first; + value = content[no].second; + return true; + } + + return false; + } + + //------------------------------------------------------------------------------ + bool get_attribute( std::string field_name, std::string& value ) const + { + for ( auto i = content.begin(); i != content.end(); i++ ) { + if ( field_name == i->first ) { + value = i->second; + return true; + } + } + + return false; + } + + //------------------------------------------------------------------------------ + Elf_Word add_attribute( std::string field, std::string value ) + { + Elf_Word current_position = 0; + + if ( modinfo_section ) { + // Strings are addeded to the end of the current section data + current_position = (Elf_Word)modinfo_section->get_size(); + + std::string attribute = field + "=" + value; + + modinfo_section->append_data( attribute + '\0' ); + content.push_back( + std::pair( field, value ) ); + } + + return current_position; + } + + //------------------------------------------------------------------------------ + private: + void process_section() + { + const char* pdata = modinfo_section->get_data(); + if ( pdata ) { + ELFIO::Elf_Xword i = 0; + while ( i < modinfo_section->get_size() ) { + while ( i < modinfo_section->get_size() && !pdata[i] ) + i++; + if ( i < modinfo_section->get_size() ) { + std::string info = pdata + i; + size_t loc = info.find( '=' ); + std::pair attribute( + info.substr( 0, loc ), info.substr( loc + 1 ) ); + + content.push_back( attribute ); + + i += info.length(); + } + } + } + } + + //------------------------------------------------------------------------------ + private: + S* modinfo_section; + std::vector> content; +}; + +using modinfo_section_accessor = modinfo_section_accessor_template
; +using const_modinfo_section_accessor = + modinfo_section_accessor_template; + +} // namespace ELFIO + +#endif // ELFIO_MODINFO_HPP + +/*** End of inlined file: elfio_modinfo.hpp ***/ + +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + +#endif // ELFIO_HPP + +/*** End of inlined file: elfio.hpp ***/ + + +namespace ELFIO { + +static struct class_table_t +{ + const char key; + const char* str; +} class_table[] = { + { ELFCLASS32, "ELF32" }, + { ELFCLASS64, "ELF64" }, +}; + +static struct endian_table_t +{ + const char key; + const char* str; +} endian_table[] = { + { ELFDATANONE, "None" }, + { ELFDATA2LSB, "Little endian" }, + { ELFDATA2MSB, "Big endian" }, +}; + +static struct version_table_t +{ + const Elf64_Word key; + const char* str; +} version_table[] = { + { EV_NONE, "None" }, + { EV_CURRENT, "Current" }, +}; + +static struct type_table_t +{ + const Elf32_Half key; + const char* str; +} type_table[] = { + { ET_NONE, "No file type" }, { ET_REL, "Relocatable file" }, + { ET_EXEC, "Executable file" }, { ET_DYN, "Shared object file" }, + { ET_CORE, "Core file" }, +}; + +static struct machine_table_t +{ + const Elf64_Half key; + const char* str; +} machine_table[] = { + { EM_NONE, "No machine" }, + { EM_M32, "AT&T WE 32100" }, + { EM_SPARC, "SUN SPARC" }, + { EM_386, "Intel 80386" }, + { EM_68K, "Motorola m68k family" }, + { EM_88K, "Motorola m88k family" }, + { EM_486, "Intel 80486// Reserved for future use" }, + { EM_860, "Intel 80860" }, + { EM_MIPS, "MIPS R3000 (officially, big-endian only)" }, + { EM_S370, "IBM System/370" }, + { EM_MIPS_RS3_LE, + "MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated" }, + { EM_res011, "Reserved" }, + { EM_res012, "Reserved" }, + { EM_res013, "Reserved" }, + { EM_res014, "Reserved" }, + { EM_PARISC, "HPPA" }, + { EM_res016, "Reserved" }, + { EM_VPP550, "Fujitsu VPP500" }, + { EM_SPARC32PLUS, "Sun's v8plus" }, + { EM_960, "Intel 80960" }, + { EM_PPC, "PowerPC" }, + { EM_PPC64, "64-bit PowerPC" }, + { EM_S390, "IBM S/390" }, + { EM_SPU, "Sony/Toshiba/IBM SPU" }, + { EM_res024, "Reserved" }, + { EM_res025, "Reserved" }, + { EM_res026, "Reserved" }, + { EM_res027, "Reserved" }, + { EM_res028, "Reserved" }, + { EM_res029, "Reserved" }, + { EM_res030, "Reserved" }, + { EM_res031, "Reserved" }, + { EM_res032, "Reserved" }, + { EM_res033, "Reserved" }, + { EM_res034, "Reserved" }, + { EM_res035, "Reserved" }, + { EM_V800, "NEC V800 series" }, + { EM_FR20, "Fujitsu FR20" }, + { EM_RH32, "TRW RH32" }, + { EM_MCORE, "Motorola M*Core // May also be taken by Fujitsu MMA" }, + { EM_RCE, "Old name for MCore" }, + { EM_ARM, "ARM" }, + { EM_OLD_ALPHA, "Digital Alpha" }, + { EM_SH, "Renesas (formerly Hitachi) / SuperH SH" }, + { EM_SPARCV9, "SPARC v9 64-bit" }, + { EM_TRICORE, "Siemens Tricore embedded processor" }, + { EM_ARC, "ARC Cores" }, + { EM_H8_300, "Renesas (formerly Hitachi) H8/300" }, + { EM_H8_300H, "Renesas (formerly Hitachi) H8/300H" }, + { EM_H8S, "Renesas (formerly Hitachi) H8S" }, + { EM_H8_500, "Renesas (formerly Hitachi) H8/500" }, + { EM_IA_64, "Intel IA-64 Processor" }, + { EM_MIPS_X, "Stanford MIPS-X" }, + { EM_COLDFIRE, "Motorola Coldfire" }, + { EM_68HC12, "Motorola M68HC12" }, + { EM_MMA, "Fujitsu Multimedia Accelerator" }, + { EM_PCP, "Siemens PCP" }, + { EM_NCPU, "Sony nCPU embedded RISC processor" }, + { EM_NDR1, "Denso NDR1 microprocesspr" }, + { EM_STARCORE, "Motorola Star*Core processor" }, + { EM_ME16, "Toyota ME16 processor" }, + { EM_ST100, "STMicroelectronics ST100 processor" }, + { EM_TINYJ, "Advanced Logic Corp. TinyJ embedded processor" }, + { EM_X86_64, "Advanced Micro Devices X86-64 processor" }, + { EM_PDSP, "Sony DSP Processor" }, + { EM_PDP10, "Digital Equipment Corp. PDP-10" }, + { EM_PDP11, "Digital Equipment Corp. PDP-11" }, + { EM_FX66, "Siemens FX66 microcontroller" }, + { EM_ST9PLUS, "STMicroelectronics ST9+ 8/16 bit microcontroller" }, + { EM_ST7, "STMicroelectronics ST7 8-bit microcontroller" }, + { EM_68HC16, "Motorola MC68HC16 Microcontroller" }, + { EM_68HC11, "Motorola MC68HC11 Microcontroller" }, + { EM_68HC08, "Motorola MC68HC08 Microcontroller" }, + { EM_68HC05, "Motorola MC68HC05 Microcontroller" }, + { EM_SVX, "Silicon Graphics SVx" }, + { EM_ST19, "STMicroelectronics ST19 8-bit cpu" }, + { EM_VAX, "Digital VAX" }, + { EM_CRIS, "Axis Communications 32-bit embedded processor" }, + { EM_JAVELIN, "Infineon Technologies 32-bit embedded cpu" }, + { EM_FIREPATH, "Element 14 64-bit DSP processor" }, + { EM_ZSP, "LSI Logic's 16-bit DSP processor" }, + { EM_MMIX, "Donald Knuth's educational 64-bit processor" }, + { EM_HUANY, "Harvard's machine-independent format" }, + { EM_PRISM, "SiTera Prism" }, + { EM_AVR, "Atmel AVR 8-bit microcontroller" }, + { EM_FR30, "Fujitsu FR30" }, + { EM_D10V, "Mitsubishi D10V" }, + { EM_D30V, "Mitsubishi D30V" }, + { EM_V850, "NEC v850" }, + { EM_M32R, "Renesas M32R (formerly Mitsubishi M32R)" }, + { EM_MN10300, "Matsushita MN10300" }, + { EM_MN10200, "Matsushita MN10200" }, + { EM_PJ, "picoJava" }, + { EM_OPENRISC, "OpenRISC 32-bit embedded processor" }, + { EM_ARC_A5, "ARC Cores Tangent-A5" }, + { EM_XTENSA, "Tensilica Xtensa Architecture" }, + { EM_VIDEOCORE, "Alphamosaic VideoCore processor" }, + { EM_TMM_GPP, "Thompson Multimedia General Purpose Processor" }, + { EM_NS32K, "National Semiconductor 32000 series" }, + { EM_TPC, "Tenor Network TPC processor" }, + { EM_SNP1K, "Trebia SNP 1000 processor" }, + { EM_ST200, "STMicroelectronics ST200 microcontroller" }, + { EM_IP2K, "Ubicom IP2022 micro controller" }, + { EM_MAX, "MAX Processor" }, + { EM_CR, "National Semiconductor CompactRISC" }, + { EM_F2MC16, "Fujitsu F2MC16" }, + { EM_MSP430, "TI msp430 micro controller" }, + { EM_BLACKFIN, "ADI Blackfin" }, + { EM_SE_C33, "S1C33 Family of Seiko Epson processors" }, + { EM_SEP, "Sharp embedded microprocessor" }, + { EM_ARCA, "Arca RISC Microprocessor" }, + { EM_UNICORE, "Microprocessor series from PKU-Unity Ltd. and MPRC of " + "Peking University" }, + { EM_EXCESS, "eXcess: 16/32/64-bit configurable embedded CPU" }, + { EM_DXP, "Icera Semiconductor Inc. Deep Execution Processor" }, + { EM_ALTERA_NIOS2, "Altera Nios II soft-core processor" }, + { EM_CRX, "National Semiconductor CRX" }, + { EM_XGATE, "Motorola XGATE embedded processor" }, + { EM_C166, "Infineon C16x/XC16x processor" }, + { EM_M16C, "Renesas M16C series microprocessors" }, + { EM_DSPIC30F, "Microchip Technology dsPIC30F Digital Signal Controller" }, + { EM_CE, "Freescale Communication Engine RISC core" }, + { EM_M32C, "Renesas M32C series microprocessors" }, + { EM_res121, "Reserved" }, + { EM_res122, "Reserved" }, + { EM_res123, "Reserved" }, + { EM_res124, "Reserved" }, + { EM_res125, "Reserved" }, + { EM_res126, "Reserved" }, + { EM_res127, "Reserved" }, + { EM_res128, "Reserved" }, + { EM_res129, "Reserved" }, + { EM_res130, "Reserved" }, + { EM_TSK3000, "Altium TSK3000 core" }, + { EM_RS08, "Freescale RS08 embedded processor" }, + { EM_res133, "Reserved" }, + { EM_ECOG2, "Cyan Technology eCOG2 microprocessor" }, + { EM_SCORE, "Sunplus Score" }, + { EM_SCORE7, "Sunplus S+core7 RISC processor" }, + { EM_DSP24, "New Japan Radio (NJR) 24-bit DSP Processor" }, + { EM_VIDEOCORE3, "Broadcom VideoCore III processor" }, + { EM_LATTICEMICO32, "RISC processor for Lattice FPGA architecture" }, + { EM_SE_C17, "Seiko Epson C17 family" }, + { EM_TI_C6000, "Texas Instruments TMS320C6000 DSP family" }, + { EM_TI_C2000, "Texas Instruments TMS320C2000 DSP family" }, + { EM_TI_C5500, "Texas Instruments TMS320C55x DSP family" }, + { EM_res143, "Reserved" }, + { EM_res144, "Reserved" }, + { EM_res145, "Reserved" }, + { EM_res146, "Reserved" }, + { EM_res147, "Reserved" }, + { EM_res148, "Reserved" }, + { EM_res149, "Reserved" }, + { EM_res150, "Reserved" }, + { EM_res151, "Reserved" }, + { EM_res152, "Reserved" }, + { EM_res153, "Reserved" }, + { EM_res154, "Reserved" }, + { EM_res155, "Reserved" }, + { EM_res156, "Reserved" }, + { EM_res157, "Reserved" }, + { EM_res158, "Reserved" }, + { EM_res159, "Reserved" }, + { EM_MMDSP_PLUS, "STMicroelectronics 64bit VLIW Data Signal Processor" }, + { EM_CYPRESS_M8C, "Cypress M8C microprocessor" }, + { EM_R32C, "Renesas R32C series microprocessors" }, + { EM_TRIMEDIA, "NXP Semiconductors TriMedia architecture family" }, + { EM_QDSP6, "QUALCOMM DSP6 Processor" }, + { EM_8051, "Intel 8051 and variants" }, + { EM_STXP7X, "STMicroelectronics STxP7x family" }, + { EM_NDS32, + "Andes Technology compact code size embedded RISC processor family" }, + { EM_ECOG1, "Cyan Technology eCOG1X family" }, + { EM_ECOG1X, "Cyan Technology eCOG1X family" }, + { EM_MAXQ30, "Dallas Semiconductor MAXQ30 Core Micro-controllers" }, + { EM_XIMO16, "New Japan Radio (NJR) 16-bit DSP Processor" }, + { EM_MANIK, "M2000 Reconfigurable RISC Microprocessor" }, + { EM_CRAYNV2, "Cray Inc. NV2 vector architecture" }, + { EM_RX, "Renesas RX family" }, + { EM_METAG, "Imagination Technologies META processor architecture" }, + { EM_MCST_ELBRUS, "MCST Elbrus general purpose hardware architecture" }, + { EM_ECOG16, "Cyan Technology eCOG16 family" }, + { EM_CR16, "National Semiconductor CompactRISC 16-bit processor" }, + { EM_ETPU, "Freescale Extended Time Processing Unit" }, + { EM_SLE9X, "Infineon Technologies SLE9X core" }, + { EM_L1OM, "Intel L1OM" }, + { EM_INTEL181, "Reserved by Intel" }, + { EM_INTEL182, "Reserved by Intel" }, + { EM_res183, "Reserved by ARM" }, + { EM_res184, "Reserved by ARM" }, + { EM_AVR32, "Atmel Corporation 32-bit microprocessor family" }, + { EM_STM8, "STMicroeletronics STM8 8-bit microcontroller" }, + { EM_TILE64, "Tilera TILE64 multicore architecture family" }, + { EM_TILEPRO, "Tilera TILEPro multicore architecture family" }, + { EM_MICROBLAZE, "Xilinx MicroBlaze 32-bit RISC soft processor core" }, + { EM_CUDA, "NVIDIA CUDA architecture " }, +}; + +static struct section_type_table_t +{ + const Elf64_Half key; + const char* str; +} section_type_table[] = { + { SHT_NULL, "NULL" }, + { SHT_PROGBITS, "PROGBITS" }, + { SHT_SYMTAB, "SYMTAB" }, + { SHT_STRTAB, "STRTAB" }, + { SHT_RELA, "RELA" }, + { SHT_HASH, "HASH" }, + { SHT_DYNAMIC, "DYNAMIC" }, + { SHT_NOTE, "NOTE" }, + { SHT_NOBITS, "NOBITS" }, + { SHT_REL, "REL" }, + { SHT_SHLIB, "SHLIB" }, + { SHT_DYNSYM, "DYNSYM" }, + { SHT_INIT_ARRAY, "INIT_ARRAY" }, + { SHT_FINI_ARRAY, "FINI_ARRAY" }, + { SHT_PREINIT_ARRAY, "PREINIT_ARRAY" }, + { SHT_GROUP, "GROUP" }, + { SHT_SYMTAB_SHNDX, "SYMTAB_SHNDX " }, +}; + +static struct segment_type_table_t +{ + const Elf_Word key; + const char* str; +} segment_type_table[] = { + { PT_NULL, "NULL" }, { PT_LOAD, "LOAD" }, { PT_DYNAMIC, "DYNAMIC" }, + { PT_INTERP, "INTERP" }, { PT_NOTE, "NOTE" }, { PT_SHLIB, "SHLIB" }, + { PT_PHDR, "PHDR" }, { PT_TLS, "TLS" }, +}; + +static struct segment_flag_table_t +{ + const Elf_Word key; + const char* str; +} segment_flag_table[] = { + { 0, "" }, { 1, "X" }, { 2, "W" }, { 3, "WX" }, + { 4, "R" }, { 5, "RX" }, { 6, "RW" }, { 7, "RWX" }, +}; + +static struct symbol_bind_t +{ + const Elf_Word key; + const char* str; +} symbol_bind_table[] = { + { STB_LOCAL, "LOCAL" }, { STB_GLOBAL, "GLOBAL" }, + { STB_WEAK, "WEAK" }, { STB_LOOS, "LOOS" }, + { STB_HIOS, "HIOS" }, { STB_MULTIDEF, "MULTIDEF" }, + { STB_LOPROC, "LOPROC" }, { STB_HIPROC, "HIPROC" }, +}; + +static struct symbol_type_t +{ + const Elf_Word key; + const char* str; +} symbol_type_table[] = { + { STT_NOTYPE, "NOTYPE" }, { STT_OBJECT, "OBJECT" }, + { STT_FUNC, "FUNC" }, { STT_SECTION, "SECTION" }, + { STT_FILE, "FILE" }, { STT_COMMON, "COMMON" }, + { STT_TLS, "TLS" }, { STT_LOOS, "LOOS" }, + { STT_HIOS, "HIOS" }, { STT_LOPROC, "LOPROC" }, + { STT_HIPROC, "HIPROC" }, +}; + +static struct dynamic_tag_t +{ + const Elf_Word key; + const char* str; +} dynamic_tag_table[] = { + { DT_NULL, "NULL" }, + { DT_NEEDED, "NEEDED" }, + { DT_PLTRELSZ, "PLTRELSZ" }, + { DT_PLTGOT, "PLTGOT" }, + { DT_HASH, "HASH" }, + { DT_STRTAB, "STRTAB" }, + { DT_SYMTAB, "SYMTAB" }, + { DT_RELA, "RELA" }, + { DT_RELASZ, "RELASZ" }, + { DT_RELAENT, "RELAENT" }, + { DT_STRSZ, "STRSZ" }, + { DT_SYMENT, "SYMENT" }, + { DT_INIT, "INIT" }, + { DT_FINI, "FINI" }, + { DT_SONAME, "SONAME" }, + { DT_RPATH, "RPATH" }, + { DT_SYMBOLIC, "SYMBOLIC" }, + { DT_REL, "REL" }, + { DT_RELSZ, "RELSZ" }, + { DT_RELENT, "RELENT" }, + { DT_PLTREL, "PLTREL" }, + { DT_DEBUG, "DEBUG" }, + { DT_TEXTREL, "TEXTREL" }, + { DT_JMPREL, "JMPREL" }, + { DT_BIND_NOW, "BIND_NOW" }, + { DT_INIT_ARRAY, "INIT_ARRAY" }, + { DT_FINI_ARRAY, "FINI_ARRAY" }, + { DT_INIT_ARRAYSZ, "INIT_ARRAYSZ" }, + { DT_FINI_ARRAYSZ, "FINI_ARRAYSZ" }, + { DT_RUNPATH, "RUNPATH" }, + { DT_FLAGS, "FLAGS" }, + { DT_ENCODING, "ENCODING" }, + { DT_PREINIT_ARRAY, "PREINIT_ARRAY" }, + { DT_PREINIT_ARRAYSZ, "PREINIT_ARRAYSZ" }, + { DT_MAXPOSTAGS, "MAXPOSTAGS" }, +}; + +static const ELFIO::Elf_Xword MAX_DATA_ENTRIES = 64; + +//------------------------------------------------------------------------------ +class dump +{ +#define DUMP_DEC_FORMAT( width ) \ + std::setw( width ) << std::setfill( ' ' ) << std::dec << std::right +#define DUMP_HEX_FORMAT( width ) \ + std::setw( width ) << std::setfill( '0' ) << std::hex << std::right +#define DUMP_STR_FORMAT( width ) \ + std::setw( width ) << std::setfill( ' ' ) << std::hex << std::left + + public: + //------------------------------------------------------------------------------ + static void header( std::ostream& out, const elfio& reader ) + { + if ( !reader.get_header_size() ) { + return; + } + out << "ELF Header" << std::endl + << std::endl + << " Class: " << str_class( reader.get_class() ) << std::endl + << " Encoding: " << str_endian( reader.get_encoding() ) + << std::endl + << " ELFVersion: " << str_version( reader.get_elf_version() ) + << std::endl + << " Type: " << str_type( reader.get_type() ) << std::endl + << " Machine: " << str_machine( reader.get_machine() ) + << std::endl + << " Version: " << str_version( reader.get_version() ) + << std::endl + << " Entry: " + << "0x" << std::hex << reader.get_entry() << std::endl + << " Flags: " + << "0x" << std::hex << reader.get_flags() << std::endl + << std::endl; + } + + //------------------------------------------------------------------------------ + static void section_headers( std::ostream& out, const elfio& reader ) + { + Elf_Half n = reader.sections.size(); + + if ( n == 0 ) { + return; + } + + out << "Section Headers:" << std::endl; + if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit + out << "[ Nr ] Type Addr Size ES Flg Lk Inf " + "Al Name" + << std::endl; + } + else { // Output for 64-bit + out << "[ Nr ] Type Addr Size " + " ES Flg" + << std::endl + << " Lk Inf Al Name" << std::endl; + } + + for ( Elf_Half i = 0; i < n; ++i ) { // For all sections + section* sec = reader.sections[i]; + section_header( out, i, sec, reader.get_class() ); + } + + out << "Key to Flags: W (write), A (alloc), X (execute)\n\n" + << std::endl; + } + + //------------------------------------------------------------------------------ + static void section_header( std::ostream& out, + Elf_Half no, + const section* sec, + unsigned char elf_class ) + { + std::ios_base::fmtflags original_flags = out.flags(); + + if ( elf_class == ELFCLASS32 ) { // Output for 32-bit + out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " + << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) + << " " << DUMP_HEX_FORMAT( 8 ) << sec->get_address() << " " + << DUMP_HEX_FORMAT( 8 ) << sec->get_size() << " " + << DUMP_HEX_FORMAT( 2 ) << sec->get_entry_size() << " " + << DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) + << " " << DUMP_HEX_FORMAT( 2 ) << sec->get_link() << " " + << DUMP_HEX_FORMAT( 3 ) << sec->get_info() << " " + << DUMP_HEX_FORMAT( 2 ) << sec->get_addr_align() << " " + << DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " << std::endl; + } + else { // Output for 64-bit + out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " + << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) + << " " << DUMP_HEX_FORMAT( 16 ) << sec->get_address() << " " + << DUMP_HEX_FORMAT( 16 ) << sec->get_size() << " " + << DUMP_HEX_FORMAT( 4 ) << sec->get_entry_size() << " " + << DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) + << " " << std::endl + << " " << DUMP_HEX_FORMAT( 4 ) << sec->get_link() << " " + << DUMP_HEX_FORMAT( 4 ) << sec->get_info() << " " + << DUMP_HEX_FORMAT( 4 ) << sec->get_addr_align() << " " + << DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " << std::endl; + } + + out.flags( original_flags ); + + return; + } + + //------------------------------------------------------------------------------ + static void segment_headers( std::ostream& out, const elfio& reader ) + { + Elf_Half n = reader.segments.size(); + if ( n == 0 ) { + return; + } + + out << "Segment headers:" << std::endl; + if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit + out << "[ Nr ] Type VirtAddr PhysAddr FileSize Mem.Size " + "Flags Align" + << std::endl; + } + else { // Output for 64-bit + out << "[ Nr ] Type VirtAddr PhysAddr " + "Flags" + << std::endl + << " FileSize Mem.Size " + "Align" + << std::endl; + } + + for ( Elf_Half i = 0; i < n; ++i ) { + segment* seg = reader.segments[i]; + segment_header( out, i, seg, reader.get_class() ); + } + + out << std::endl; + } + + //------------------------------------------------------------------------------ + static void segment_header( std::ostream& out, + Elf_Half no, + const segment* seg, + unsigned int elf_class ) + { + std::ios_base::fmtflags original_flags = out.flags(); + + if ( elf_class == ELFCLASS32 ) { // Output for 32-bit + out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " + << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) + << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_virtual_address() + << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_physical_address() + << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_file_size() << " " + << DUMP_HEX_FORMAT( 8 ) << seg->get_memory_size() << " " + << DUMP_STR_FORMAT( 8 ) << str_segment_flag( seg->get_flags() ) + << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_align() << " " + << std::endl; + } + else { // Output for 64-bit + out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " + << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) + << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_virtual_address() + << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_physical_address() + << " " << DUMP_STR_FORMAT( 16 ) + << str_segment_flag( seg->get_flags() ) << " " << std::endl + << " " << DUMP_HEX_FORMAT( 16 ) + << seg->get_file_size() << " " << DUMP_HEX_FORMAT( 16 ) + << seg->get_memory_size() << " " << DUMP_HEX_FORMAT( 16 ) + << seg->get_align() << " " << std::endl; + } + + out.flags( original_flags ); + } + + //------------------------------------------------------------------------------ + static void symbol_tables( std::ostream& out, const elfio& reader ) + { + Elf_Half n = reader.sections.size(); + for ( Elf_Half i = 0; i < n; ++i ) { // For all sections + section* sec = reader.sections[i]; + if ( SHT_SYMTAB == sec->get_type() || + SHT_DYNSYM == sec->get_type() ) { + symbol_section_accessor symbols( reader, sec ); + + Elf_Xword sym_no = symbols.get_symbols_num(); + if ( sym_no > 0 ) { + out << "Symbol table (" << sec->get_name() << ")" + << std::endl; + if ( reader.get_class() == + ELFCLASS32 ) { // Output for 32-bit + out << "[ Nr ] Value Size Type Bind " + "Sect Name" + << std::endl; + } + else { // Output for 64-bit + out << "[ Nr ] Value Size Type " + " Bind Sect" + << std::endl + << " Name" << std::endl; + } + for ( Elf_Xword i = 0; i < sym_no; ++i ) { + std::string name; + Elf64_Addr value = 0; + Elf_Xword size = 0; + unsigned char bind = 0; + unsigned char type = 0; + Elf_Half section = 0; + unsigned char other = 0; + symbols.get_symbol( i, name, value, size, bind, type, + section, other ); + symbol_table( out, i, name, value, size, bind, type, + section, reader.get_class() ); + } + + out << std::endl; + } + } + } + } + + //------------------------------------------------------------------------------ + static void symbol_table( std::ostream& out, + Elf_Xword no, + std::string& name, + Elf64_Addr value, + Elf_Xword size, + unsigned char bind, + unsigned char type, + Elf_Half section, + unsigned int elf_class ) + { + std::ios_base::fmtflags original_flags = out.flags(); + + if ( elf_class == ELFCLASS32 ) { // Output for 32-bit + out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " + << DUMP_HEX_FORMAT( 8 ) << value << " " << DUMP_HEX_FORMAT( 8 ) + << size << " " << DUMP_STR_FORMAT( 7 ) + << str_symbol_type( type ) << " " << DUMP_STR_FORMAT( 8 ) + << str_symbol_bind( bind ) << " " << DUMP_DEC_FORMAT( 5 ) + << section << " " << DUMP_STR_FORMAT( 1 ) << name << " " + << std::endl; + } + else { // Output for 64-bit + out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " + << DUMP_HEX_FORMAT( 16 ) << value << " " + << DUMP_HEX_FORMAT( 16 ) << size << " " << DUMP_STR_FORMAT( 7 ) + << str_symbol_type( type ) << " " << DUMP_STR_FORMAT( 8 ) + << str_symbol_bind( bind ) << " " << DUMP_DEC_FORMAT( 5 ) + << section << " " << std::endl + << " " << DUMP_STR_FORMAT( 1 ) << name << " " + << std::endl; + } + + out.flags( original_flags ); + } + + //------------------------------------------------------------------------------ + static void notes( std::ostream& out, const elfio& reader ) + { + Elf_Half no = reader.sections.size(); + for ( Elf_Half i = 0; i < no; ++i ) { // For all sections + section* sec = reader.sections[i]; + if ( SHT_NOTE == sec->get_type() ) { // Look at notes + note_section_accessor notes( reader, sec ); + Elf_Word no_notes = notes.get_notes_num(); + if ( no > 0 ) { + out << "Note section (" << sec->get_name() << ")" + << std::endl + << " No Type Name" << std::endl; + for ( Elf_Word j = 0; j < no_notes; ++j ) { // For all notes + Elf_Word type; + std::string name; + void* desc; + Elf_Word descsz; + + if ( notes.get_note( j, type, name, desc, descsz ) ) { + // 'name' usually contains \0 at the end. Try to fix it + name = name.c_str(); + note( out, j, type, name ); + } + } + + out << std::endl; + } + } + } + } + + //------------------------------------------------------------------------------ + static void modinfo( std::ostream& out, const elfio& reader ) + { + Elf_Half no = reader.sections.size(); + for ( Elf_Half i = 0; i < no; ++i ) { // For all sections + section* sec = reader.sections[i]; + if ( ".modinfo" == sec->get_name() ) { // Look for the section + out << "Section .modinfo" << std::endl; + + const_modinfo_section_accessor modinfo( sec ); + for ( Elf_Word i = 0; i < modinfo.get_attribute_num(); i++ ) { + std::string field; + std::string value; + if ( modinfo.get_attribute( i, field, value ) ) { + out << " " << std::setw( 20 ) << field + << std::setw( 0 ) << " = " << value << std::endl; + } + } + + out << std::endl; + break; + } + } + } + + //------------------------------------------------------------------------------ + static void + note( std::ostream& out, int no, Elf_Word type, const std::string& name ) + { + out << " [" << DUMP_DEC_FORMAT( 2 ) << no << "] " + << DUMP_HEX_FORMAT( 8 ) << type << " " << DUMP_STR_FORMAT( 1 ) + << name << std::endl; + } + + //------------------------------------------------------------------------------ + static void dynamic_tags( std::ostream& out, const elfio& reader ) + { + Elf_Half n = reader.sections.size(); + for ( Elf_Half i = 0; i < n; ++i ) { // For all sections + section* sec = reader.sections[i]; + if ( SHT_DYNAMIC == sec->get_type() ) { + dynamic_section_accessor dynamic( reader, sec ); + + Elf_Xword dyn_no = dynamic.get_entries_num(); + if ( dyn_no > 0 ) { + out << "Dynamic section (" << sec->get_name() << ")" + << std::endl; + out << "[ Nr ] Tag Name/Value" << std::endl; + for ( Elf_Xword i = 0; i < dyn_no; ++i ) { + Elf_Xword tag = 0; + Elf_Xword value = 0; + std::string str; + dynamic.get_entry( i, tag, value, str ); + dynamic_tag( out, i, tag, value, str, + reader.get_class() ); + if ( DT_NULL == tag ) { + break; + } + } + + out << std::endl; + } + } + } + } + + //------------------------------------------------------------------------------ + static void dynamic_tag( std::ostream& out, + Elf_Xword no, + Elf_Xword tag, + Elf_Xword value, + std::string str, + unsigned int /*elf_class*/ ) + { + out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " + << DUMP_STR_FORMAT( 16 ) << str_dynamic_tag( tag ) << " "; + if ( str.empty() ) { + out << DUMP_HEX_FORMAT( 16 ) << value << " "; + } + else { + out << DUMP_STR_FORMAT( 32 ) << str << " "; + } + out << std::endl; + } + + //------------------------------------------------------------------------------ + static void section_data( std::ostream& out, const section* sec ) + { + std::ios_base::fmtflags original_flags = out.flags(); + + out << sec->get_name() << std::endl; + const char* pdata = sec->get_data(); + if ( pdata ) { + ELFIO::Elf_Xword i; + for ( i = 0; i < std::min( sec->get_size(), MAX_DATA_ENTRIES ); + ++i ) { + if ( i % 16 == 0 ) { + out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]"; + } + + out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF ); + + if ( i % 16 == 15 ) { + out << std::endl; + } + } + if ( i % 16 != 0 ) { + out << std::endl; + } + + out.flags( original_flags ); + } + + return; + } + + //------------------------------------------------------------------------------ + static void section_datas( std::ostream& out, const elfio& reader ) + { + Elf_Half n = reader.sections.size(); + + if ( n == 0 ) { + return; + } + + out << "Section Data:" << std::endl; + + for ( Elf_Half i = 1; i < n; ++i ) { // For all sections + section* sec = reader.sections[i]; + if ( sec->get_type() == SHT_NOBITS ) { + continue; + } + section_data( out, sec ); + } + + out << std::endl; + } + + //------------------------------------------------------------------------------ + static void + segment_data( std::ostream& out, Elf_Half no, const segment* seg ) + { + std::ios_base::fmtflags original_flags = out.flags(); + + out << "Segment # " << no << std::endl; + const char* pdata = seg->get_data(); + if ( pdata ) { + ELFIO::Elf_Xword i; + for ( i = 0; i < std::min( seg->get_file_size(), MAX_DATA_ENTRIES ); + ++i ) { + if ( i % 16 == 0 ) { + out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]"; + } + + out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF ); + + if ( i % 16 == 15 ) { + out << std::endl; + } + } + if ( i % 16 != 0 ) { + out << std::endl; + } + + out.flags( original_flags ); + } + + return; + } + + //------------------------------------------------------------------------------ + static void segment_datas( std::ostream& out, const elfio& reader ) + { + Elf_Half n = reader.segments.size(); + + if ( n == 0 ) { + return; + } + + out << "Segment Data:" << std::endl; + + for ( Elf_Half i = 0; i < n; ++i ) { // For all sections + segment* seg = reader.segments[i]; + segment_data( out, i, seg ); + } + + out << std::endl; + } + + private: + //------------------------------------------------------------------------------ + template + std::string static find_value_in_table( const T& table, const K& key ) + { + std::string res = "?"; + for ( unsigned int i = 0; i < sizeof( table ) / sizeof( table[0] ); + ++i ) { + if ( table[i].key == key ) { + res = table[i].str; + break; + } + } + + return res; + } + + //------------------------------------------------------------------------------ + template + static std::string format_assoc( const T& table, const K& key ) + { + std::string str = find_value_in_table( table, key ); + if ( str == "?" ) { + std::ostringstream oss; + oss << str << " (0x" << std::hex << key << ")"; + str = oss.str(); + } + + return str; + } + + //------------------------------------------------------------------------------ + template + static std::string format_assoc( const T& table, const char key ) + { + return format_assoc( table, (const int)key ); + } + + //------------------------------------------------------------------------------ + static std::string section_flags( Elf_Xword flags ) + { + std::string ret = ""; + if ( flags & SHF_WRITE ) { + ret += "W"; + } + if ( flags & SHF_ALLOC ) { + ret += "A"; + } + if ( flags & SHF_EXECINSTR ) { + ret += "X"; + } + + return ret; + } + +//------------------------------------------------------------------------------ +#define STR_FUNC_TABLE( name ) \ + template static std::string str_##name( const T key ) \ + { \ + return format_assoc( name##_table, key ); \ + } + + STR_FUNC_TABLE( class ) + STR_FUNC_TABLE( endian ) + STR_FUNC_TABLE( version ) + STR_FUNC_TABLE( type ) + STR_FUNC_TABLE( machine ) + STR_FUNC_TABLE( section_type ) + STR_FUNC_TABLE( segment_type ) + STR_FUNC_TABLE( segment_flag ) + STR_FUNC_TABLE( symbol_bind ) + STR_FUNC_TABLE( symbol_type ) + STR_FUNC_TABLE( dynamic_tag ) + +#undef STR_FUNC_TABLE +#undef DUMP_DEC_FORMAT +#undef DUMP_HEX_FORMAT +#undef DUMP_STR_FORMAT +}; // class dump + +}; // namespace ELFIO + +#endif // ELFIO_DUMP_HPP + +/*** End of inlined file: elfio_dump.hpp ***/ + diff --git a/dde-file-manager-5.5.3/3rdparty/cpp-stub/stub.h b/dde-file-manager-5.5.3/3rdparty/cpp-stub/stub.h new file mode 100644 index 0000000..dd232f8 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/cpp-stub/stub.h @@ -0,0 +1,359 @@ +#ifndef __STUB_H__ +#define __STUB_H__ + +#ifdef _WIN32 +//windows +#include +#include +#else +//linux +#include +#include +#endif +//c +#include +#include +//c++ +#include + + +#define ADDR(CLASS_NAME,MEMBER_NAME) (&CLASS_NAME::MEMBER_NAME) + +/********************************************************** + replace function +**********************************************************/ +#ifdef _WIN32 +#define CACHEFLUSH(addr, size) FlushInstructionCache(GetCurrentProcess(), addr, size) +#else +#define CACHEFLUSH(addr, size) __builtin___clear_cache(addr, addr + size) +#endif + +#if defined(__aarch64__) || defined(_M_ARM64) + #define CODESIZE 16U + #define CODESIZE_MIN 16U + #define CODESIZE_MAX CODESIZE + // ldr x9, +8 + // br x9 + // addr + #define REPLACE_FAR(t, fn, fn_stub)\ + ((uint32_t*)fn)[0] = 0x58000040 | 9;\ + ((uint32_t*)fn)[1] = 0xd61f0120 | (9 << 5);\ + *(long long *)(fn + 8) = (long long )fn_stub;\ + CACHEFLUSH((char *)fn, CODESIZE); + #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) +#elif defined(__arm__) || defined(_M_ARM) + #define CODESIZE 8U + #define CODESIZE_MIN 8U + #define CODESIZE_MAX CODESIZE + // ldr pc, [pc, #-4] + #define REPLACE_FAR(t, fn, fn_stub)\ + ((uint32_t*)fn)[0] = 0xe51ff004;\ + ((uint32_t*)fn)[1] = (uint32_t)fn_stub;\ + CACHEFLUSH((char *)fn, CODESIZE); + #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) +#elif defined(__mips64) + #define CACHEFLUSH(addr, size) __builtin___clear_cache(addr, addr + size) + #define CODESIZE 80U + #define CODESIZE_MIN 80U + #define CODESIZE_MAX CODESIZE + //mips没有PC指针,所以需要手动入栈出栈 + //120000ce0: 67bdffe0 daddiu sp, sp, -32 //入栈 + //120000ce4: ffbf0018 sd ra, 24(sp) + //120000ce8: ffbe0010 sd s8, 16(sp) + //120000cec: ffbc0008 sd gp, 8(sp) + //120000cf0: 03a0f025 move s8, sp + + //120000d2c: 03c0e825 move sp, s8 //出栈 + //120000d30: dfbf0018 ld ra, 24(sp) + //120000d34: dfbe0010 ld s8, 16(sp) + //120000d38: dfbc0008 ld gp, 8(sp) + //120000d3c: 67bd0020 daddiu sp, sp, 32 + //120000d40: 03e00008 jr ra + + #define REPLACE_FAR(t, fn, fn_stub)\ + ((uint32_t *)fn)[0] = 0x67bdffe0;\ + ((uint32_t *)fn)[1] = 0xffbf0018;\ + ((uint32_t *)fn)[2] = 0xffbe0010;\ + ((uint32_t *)fn)[3] = 0xffbc0008;\ + ((uint32_t *)fn)[4] = 0x03a0f025;\ + *(uint16_t *)(fn + 20) = (long long)fn_stub >> 32;\ + *(fn + 22) = 0x19;\ + *(fn + 23) = 0x24;\ + ((uint32_t *)fn)[6] = 0x0019cc38;\ + *(uint16_t *)(fn + 28) = (long long)fn_stub >> 16;\ + *(fn + 30) = 0x39;\ + *(fn + 31) = 0x37;\ + ((uint32_t *)fn)[8] = 0x0019cc38;\ + *(uint16_t *)(fn + 36) = (long long)fn_stub;\ + *(fn + 38) = 0x39;\ + *(fn + 39) = 0x37;\ + ((uint32_t *)fn)[10] = 0x0320f809;\ + ((uint32_t *)fn)[11] = 0x00000000;\ + ((uint32_t *)fn)[12] = 0x00000000;\ + ((uint32_t *)fn)[13] = 0x03c0e825;\ + ((uint32_t *)fn)[14] = 0xdfbf0018;\ + ((uint32_t *)fn)[15] = 0xdfbe0010;\ + ((uint32_t *)fn)[16] = 0xdfbc0008;\ + ((uint32_t *)fn)[17] = 0x67bd0020;\ + ((uint32_t *)fn)[18] = 0x03e00008;\ + ((uint32_t *)fn)[19] = 0x00000000;\ + CACHEFLUSH((char *)fn, CODESIZE); + #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) +#elif defined(__thumb__) || defined(_M_THUMB) + #error "Thumb is not supported" +#else //__i386__ _x86_64__ + #define CODESIZE 13U + #define CODESIZE_MIN 5U + #define CODESIZE_MAX CODESIZE + //13 byte(jmp m16:64) + //movabs $0x102030405060708,%r11 + //jmpq *%r11 + static void REPLACE_FAR(void *t, char *fn, char *fn_stub) + { + *fn = 0x49; + *(fn + 1) = 0xbb; + *(long long *)(fn + 2) = (long long)fn_stub; + *(fn + 10) = 0x41; + *(fn + 11) = 0xff; + *(fn + 12) = 0xe3; + CACHEFLUSH((char *)fn, CODESIZE); + } + //5 byte(jmp rel32) + #define REPLACE_NEAR(t, fn, fn_stub)\ + *fn = 0xE9;\ + *(int *)(fn + 1) = (int)(fn_stub - fn - CODESIZE_MIN);\ + CACHEFLUSH((char *)fn, CODESIZE); +#endif + +struct func_stub +{ + char *fn; + unsigned char code_buf[CODESIZE]; + bool far_jmp; +}; + +class Stub +{ +public: + Stub() + { +#ifdef _WIN32 + SYSTEM_INFO sys_info; + GetSystemInfo(&sys_info); + m_pagesize = sys_info.dwPageSize; +#else + m_pagesize = sysconf(_SC_PAGE_SIZE); +#endif + + if (m_pagesize < 0) + { + m_pagesize = 4096; + } + } + ~Stub() + { + clear(); + } + + virtual void clear() + { + std::map::iterator iter; + struct func_stub *pstub; + for(iter=m_result.begin(); iter != m_result.end(); iter++) + { + pstub = iter->second; +#ifdef _WIN32 + DWORD lpflOldProtect; + if(0 != VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) +#else + if (0 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC)) +#endif + { + + if(pstub->far_jmp) + { + std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MAX); + } + else + { + std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MIN); + } + +#ifdef _WIN32 + VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect); +#else + CACHEFLUSH(pstub->fn,CODESIZE); + mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC); +#endif + } + + iter->second = NULL; + delete pstub; + } + + m_result.clear(); + return; + } + template + bool set(T addr, S addr_stub) + { + char * fn; + char * fn_stub; + fn = addrof(addr); + fn_stub = addrof(addr_stub); + struct func_stub *pstub; + std::map::iterator iter = m_result.find(fn); + + if (iter == m_result.end()) + { + pstub = new func_stub; + //start + pstub->fn = fn; + + if(distanceof(fn, fn_stub)) + { + pstub->far_jmp = true; + std::memcpy(pstub->code_buf, fn, CODESIZE_MAX); + } + else + { + pstub->far_jmp = false; + std::memcpy(pstub->code_buf, fn, CODESIZE_MIN); + } + } + else { + pstub = iter->second; + pstub->far_jmp = distanceof(fn, fn_stub); + } + + + +#ifdef _WIN32 + DWORD lpflOldProtect; + if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) +#else + if (-1 == mprotect(pageof(pstub->fn), static_cast(m_pagesize * 2), PROT_READ | PROT_WRITE | PROT_EXEC)) +#endif + { + throw("stub set memory protect to w+r+x faild"); + return false; + } + + if(pstub->far_jmp) + { + REPLACE_FAR(this, fn, fn_stub); + } + else + { + REPLACE_NEAR(this, fn, fn_stub); + } + + +#ifdef _WIN32 + if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect)) +#else + if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC)) +#endif + { + throw("stub set memory protect to r+x failed"); + return false; + } + m_result.insert(std::pair(fn,pstub)); + return true; + } + + template + bool reset(T addr) + { + char * fn; + fn = addrof(addr); + + std::map::iterator iter = m_result.find(fn); + + if (iter == m_result.end()) + { + return true; + } + struct func_stub *pstub; + pstub = iter->second; + +#ifdef _WIN32 + DWORD lpflOldProtect; + if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) +#else + if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC)) +#endif + { + throw("stub reset memory protect to w+r+x faild"); + return false; + } + + if(pstub->far_jmp) + { + std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MAX); + } + else + { + std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MIN); + } + +#ifdef _WIN32 + if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect)) +#else + CACHEFLUSH(pstub->fn,CODESIZE); + if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC)) +#endif + { + throw("stub reset memory protect to r+x failed"); + return false; + } + + m_result.erase(iter); + delete pstub; + + return true; + } +protected: + char *pageof(char* addr) + { +#ifdef _WIN32 + return (char *)((unsigned long long)addr & ~(m_pagesize - 1)); +#else + return (char *)((unsigned long)addr & ~(m_pagesize - 1)); +#endif + } + + template + char* addrof(T addr) + { + union + { + T _s; + char* _d; + }ut; + ut._s = addr; + return ut._d; + } + + bool distanceof(char* addr, char* addr_stub) + { + std::ptrdiff_t diff = addr_stub >= addr ? addr_stub - addr : addr - addr_stub; + if((sizeof(addr) > 4) && (((diff >> 31) - 1) > 0)) + { + return true; + } + return false; + } + +protected: +#ifdef _WIN32 + //LLP64 + long long m_pagesize; +#else + //LP64 + long m_pagesize; +#endif + std::map m_result; +}; + +#endif diff --git a/dde-file-manager-5.5.3/3rdparty/cpp-stub/stub.pri b/dde-file-manager-5.5.3/3rdparty/cpp-stub/stub.pri new file mode 100644 index 0000000..35741a2 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/cpp-stub/stub.pri @@ -0,0 +1,35 @@ +INCLUDEPATH += $$PWD + +#isEmpty(GOOGLETEST_DIR):GOOGLETEST_DIR=$$(GOOGLETEST_DIR) + +#isEmpty(GOOGLETEST_DIR) { +# warning("Using googletest src dir specified at Qt Creator wizard") +# message("set GOOGLETEST_DIR as environment variable or qmake variable to get rid of this message") +# GOOGLETEST_DIR = $$PWD +#} + +#!isEmpty(GOOGLETEST_DIR): { +# GTEST_SRCDIR = $$GOOGLETEST_DIR/googletest +# GMOCK_SRCDIR = $$GOOGLETEST_DIR/googlemock +#} + +#requires(exists($$GTEST_SRCDIR):exists($$GMOCK_SRCDIR)) + +#!exists($$GOOGLETEST_DIR):message("No googletest src dir found - set GOOGLETEST_DIR to enable.") + + +#INCLUDEPATH *= \ +# $$GTEST_SRCDIR \ +# $$GTEST_SRCDIR/include \ +# $$GMOCK_SRCDIR \ +# $$GMOCK_SRCDIR/include + +INCLUDEPATH += $$PWD/../stub-ext +SOURCES += $$PWD/elfio.hpp \ + $$PWD/../stub-ext/stub-shadow.cpp + +HEADERS += $$PWD/addr_any.h \ + $$PWD/addr_pri.h \ + $$PWD/stub.h \ + $$PWD/../stub-ext/stubext.h \ + $$PWD/../stub-ext/stub-shadow.h diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/array.c b/dde-file-manager-5.5.3/3rdparty/fsearch/array.c new file mode 100644 index 0000000..09cb7eb --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/array.c @@ -0,0 +1,171 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#include +#include +#include +#include "array.h" + +struct _DynamicArray { + // number of items in array + uint32_t num_items; + // total size of array + uint32_t max_items; + // data + void **data; +}; + +void +darray_clear (DynamicArray *array) +{ + assert (array != NULL); + if (array->num_items > 0) { + for (uint32_t i = 0; i < array->max_items; i++) { + if(*(array->data) != NULL) + array->data[i] = NULL; + else { + break; + } + } + } +} + +void +darray_free (DynamicArray *array) +{ + if (array == NULL) { + return; + } + + darray_clear (array); + if (array->data) { + free (array->data); + array->data = NULL; + } + free (array); + array = NULL; +} + +DynamicArray * +darray_new (size_t num_items) +{ + DynamicArray *new = calloc (1, sizeof (DynamicArray)); + assert (new != NULL); + + new->max_items = num_items; + new->num_items = 0; + + new->data = calloc (num_items, sizeof (void *)); + assert (new->data != NULL); + + return new; +} + +static void +darray_expand (DynamicArray *array, size_t min) +{ + assert (array != NULL); + assert (array->data != NULL); + + size_t old_max_items = array->max_items; + size_t expand_rate = MAX (array->max_items/2, min - old_max_items); + array->max_items += expand_rate; + + void *new_data = realloc (array->data, array->max_items * sizeof (void *)); + assert (new_data != NULL); + array->data = new_data; + memset (array->data + old_max_items, 0, expand_rate + 1); +} + +void +darray_set_item (DynamicArray *array, void *data, uint32_t idx) +{ + assert (array != NULL); + assert (array->data != NULL); + + if (idx >= array->max_items) { + darray_expand (array, idx + 1); + } + + array->data[idx] = data; + if (data != NULL) { + array->num_items++; + } +} + +void +darray_remove_item (DynamicArray *array, uint32_t idx) +{ + assert (array != NULL); + assert (array->data != NULL); + + if (idx >= array->max_items) { + return; + } + + array->data[idx] = NULL; + array->num_items--; +} + +void * +darray_get_item (DynamicArray *array, uint32_t idx) +{ +// assert (array != NULL); +// assert (array->data != NULL); + if(array==NULL) + { + return NULL; + } + if(array->data==NULL) + { + return NULL; + } + if (idx >= array->max_items) { + return NULL; + } + + return array->data[idx]; +} + +uint32_t +darray_get_num_items (DynamicArray *array) +{ + assert (array != NULL); + assert (array->data != NULL); + + return array->num_items; +} + +uint32_t +darray_get_size (DynamicArray *array) +{ + assert (array != NULL); + assert (array->data != NULL); + + return array->max_items; +} + +void +darray_sort (DynamicArray *array, int (*comp_func)(const void *, const void *)) +{ + assert (array != NULL); + assert (array->data != NULL); + assert (comp_func != NULL); + + qsort (array->data, array->num_items, sizeof (void *), comp_func); +} diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/array.h b/dde-file-manager-5.5.3/3rdparty/fsearch/array.h new file mode 100644 index 0000000..7345548 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/array.h @@ -0,0 +1,51 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#pragma once + +#include +#include + +typedef struct _DynamicArray DynamicArray; + +void +darray_sort(DynamicArray *array, int (*comp_func)(const void *, const void *)); + +uint32_t +darray_get_size(DynamicArray *array); + +uint32_t +darray_get_num_items(DynamicArray *array); + +void * +darray_get_item(DynamicArray *array, uint32_t idx); + +void +darray_remove_item(DynamicArray *array, uint32_t idx); + +void +darray_set_item(DynamicArray *array, void *data, uint32_t idx); + +DynamicArray * +darray_new(size_t num_items); + +void +darray_free(DynamicArray *array); + +void +darray_clear(DynamicArray *array); diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/btree.c b/dde-file-manager-5.5.3/3rdparty/fsearch/btree.c new file mode 100644 index 0000000..da9caba --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/btree.c @@ -0,0 +1,331 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include "btree.h" +#include "string_utils.h" + +BTreeNode * +btree_node_new (const char *name, + time_t mtime, + off_t size, + uint32_t pos, + bool is_dir) +{ + BTreeNode *new = calloc (1, sizeof (BTreeNode)); + assert (new); + + new->parent = NULL; + new->children = NULL; + new->next = NULL; + + // data + new->name = strdup (name); + new->mtime = mtime; + new->size = size; + new->pos = pos; + new->is_dir = is_dir; + + return new; +} + +static void +btree_node_data_free (BTreeNode *node) +{ + if (!node) { + return; + } + if (node->name) { + free (node->name); + node->name = NULL; + } + free (node); + node = NULL; +} + +static void +btree_nodes_free (BTreeNode *node) +{ + while (node) { + if (node->children) { + btree_nodes_free (node->children); + } + BTreeNode *next = node->next; + btree_node_data_free (node); + node = next; + } +} + +void +btree_node_unlink (BTreeNode *node) +{ + assert (node); + if (!node->parent) { + return; + } + BTreeNode *parent = node->parent; + if (parent->children == node) { + parent->children = node->next; + } + else { + BTreeNode *sibling = parent->children; + while (sibling->next != node) { + sibling = sibling->next; + } + sibling->next = node->next; + } + + node->parent = NULL; + node->next = NULL; +} + +void +btree_node_free (BTreeNode *node) +{ + if (!node) { + return; + } + if (node->parent) { + btree_node_unlink (node); + } + if (node->children) { + btree_nodes_free (node->children); + } + btree_node_data_free (node); +} + +BTreeNode * +btree_node_append (BTreeNode *parent, BTreeNode *node) +{ + assert (parent); + assert (node); + node->parent = parent; + node->next = NULL; + + if (!parent->children) { + parent->children = node; + return node; + } + BTreeNode *child = parent->children; + while (child->next) { + child = child->next; + } + child->next = node; + return node; +} + +BTreeNode * +btree_node_prepend (BTreeNode *parent, BTreeNode *node) +{ + assert (parent); + assert (node); + node->parent = parent; + node->next = parent->children; + parent->children = node; + return node; +} + +void +btree_node_remove (BTreeNode *node) +{ + btree_node_free (node); +} + +BTreeNode * +btree_node_get_root (BTreeNode *node) +{ + assert (node); + BTreeNode *root = node; + while (root->parent) { + root = root->parent; + } + return root; +} + +bool +btree_node_is_root (BTreeNode *node) +{ + return node->parent ? false : true; +} + +uint32_t +btree_node_depth (BTreeNode *node) +{ + uint32_t depth = 0; + BTreeNode *temp = node; + while (temp) { + depth++; + temp = temp->parent; + } + return depth; +} + +uint32_t +btree_node_n_children (BTreeNode *node) +{ + assert (node); + if (!node->children) { + return 0; + } + uint32_t num_children = 0; + BTreeNode *child = node->children; + while (child) { + child = child->next; + num_children++; + } + return num_children; +} + +bool +btree_node_has_children (BTreeNode *node) +{ + assert (node); + return node->children ? true : false; +} + +void +btree_node_children_foreach (BTreeNode *node, + void (*func)(BTreeNode *, void *), + void *data) +{ + if (!node) { + return; + } + BTreeNode *child = node->children; + while (child) { + func (child, data); + child = child->next; + } +} + +void +btree_node_count_nodes (BTreeNode *node, uint32_t *num_nodes) +{ + (*num_nodes)++; + if (node->children) { + BTreeNode *child = node->children; + while (child) { + btree_node_count_nodes (child, num_nodes); + child = child->next; + } + } +} + +uint32_t +btree_node_n_nodes (BTreeNode *node) +{ + if (!node) { + return 0; + } + uint32_t num_nodes = 0; + btree_node_count_nodes (node, &num_nodes); + return num_nodes; +} + +void +btree_node_traverse_cb (BTreeNode *node, + bool (*func)(BTreeNode *, void *), + void *data) +{ + func (node, data); + if (node->children) { + BTreeNode *child = node->children; + while (child) { + btree_node_traverse_cb (child, func, data); + child = child->next; + } + } +} + + +void +btree_node_traverse (BTreeNode *node, + bool (*func)(BTreeNode *, void *), + void *data) +{ + if (!node) { + return; + } + btree_node_traverse_cb (node, func, data); +} + +static bool +btree_node_build_path (BTreeNode *node, char *path, size_t path_len) +{ + if (!node) { + // empty node + return false; + } + if (btree_node_is_root (node)) { + if (strlen (node->name) == 0) { + strncpy (path, "/", path_len); + } + else { + strncpy (path, node->name, path_len); + } + return true; + } + + const int32_t depth = btree_node_depth (node); + char *parents[depth + 1]; + parents[depth] = NULL; + + BTreeNode *temp = node; + for (int32_t i = depth - 1; i >= 0 && temp; i--) { + parents[i] = temp->name; + temp = temp->parent; + } + + char *ptr = path; + char *end = &path[path_len - 1]; + + uint32_t counter = 0; + ptr = fs_str_copy (ptr, end, parents[counter++]); + + char *item = parents[counter++]; + while (item && ptr != end) { + ptr = fs_str_copy (ptr, end, "/"); + ptr = fs_str_copy (ptr, end, item); + item = parents[counter++]; + } + return true; +} + +bool +btree_node_get_path (BTreeNode *node, char *path, size_t path_len) +{ + if (!node) { + // empty node + return false; + } + return btree_node_build_path (node->parent, path, path_len); +} + +bool +btree_node_get_path_full (BTreeNode *node, char *path, size_t path_len) +{ + if (!node) { + // empty node + return false; + } + return btree_node_build_path (node, path, path_len); +} diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/btree.h b/dde-file-manager-5.5.3/3rdparty/fsearch/btree.h new file mode 100644 index 0000000..9dbcb87 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/btree.h @@ -0,0 +1,93 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#pragma once + +#include +#include +#include + +typedef struct _BTreeNode BTreeNode; + +struct _BTreeNode { + BTreeNode *next; + BTreeNode *parent; + BTreeNode *children; + + // data + char *name; + + time_t mtime; + off_t size; + uint32_t pos; + bool is_dir; +}; + +BTreeNode * +btree_node_new(const char *name, + time_t mtime, + off_t size, + uint32_t pos, + bool is_dir); + +void +btree_node_free(BTreeNode *node); + +void +btree_node_unlink(BTreeNode *node); + +BTreeNode * +btree_node_append(BTreeNode *parent, BTreeNode *node); + +BTreeNode * +btree_node_prepend(BTreeNode *parent, BTreeNode *node); + +void +btree_node_remove(BTreeNode *node); + +BTreeNode * +btree_node_get_root(BTreeNode *node); + +bool +btree_node_is_root(BTreeNode *node); + +uint32_t +btree_node_n_nodes(BTreeNode *node); + +uint32_t +btree_node_depth(BTreeNode *node); + +uint32_t +btree_node_n_children(BTreeNode *node); + +bool +btree_node_has_children(BTreeNode *node); + +void +btree_node_children_foreach(BTreeNode *node, + void (*func)(BTreeNode *, void *), + void *data); +void +btree_node_traverse(BTreeNode *node, + bool (*func)(BTreeNode *, void *), + void *data); +bool +btree_node_get_path(BTreeNode *node, char *path, size_t path_len); + +bool +btree_node_get_path_full(BTreeNode *node, char *path, size_t path_len); diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/database.c b/dde-file-manager-5.5.3/3rdparty/fsearch/database.c new file mode 100644 index 0000000..13c86c8 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/database.c @@ -0,0 +1,1018 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "database.h" +#include "fsearch_config.h" +#include "fsearch.h" +//#include "debug.h" + +//#define WS_FOLLOWLINK (1 << 1) /* follow symlinks */ +#define WS_DOTFILES (1 << 2) /* per unix convention, .file is hidden */ + +struct _Database +{ + GList *locations; + GList *searches; + DynamicArray *entries; + uint32_t num_entries; + + time_t timestamp; + + GMutex mutex; +}; + +struct _DatabaseLocation +{ + // B+ tree of entry nodes + BTreeNode *entries; + uint32_t num_items; +}; + +enum { + WALK_OK = 0, + WALK_BADPATTERN, + WALK_NAMETOOLONG, + WALK_BADIO, +}; + +// Forward declarations +static void +db_entries_clear (Database *db); + +static DatabaseLocation * +db_location_get_for_path (Database *db, const char *path); + +static DatabaseLocation * +db_location_build_tree (const char *dname, FsearchConfig *cfg, bool *state, void (*callback)(const char *)); + +static DatabaseLocation * +db_location_new (void); + +static void +db_list_add_location (Database *db, DatabaseLocation *location); + +// Implemenation + +static void +db_update_timestamp (Database *db) +{ + assert (db != NULL); + db->timestamp = time(NULL); +} + +DatabaseLocation * +db_location_load_from_file (const char *fname) +{ + assert (fname != NULL); + + FILE *fp = fopen (fname, "rb"); + if (!fp) { + return NULL; + } + + BTreeNode *root = NULL; + + char magic[4]; + if (fread (magic, 1, 4, fp) != 4) { + printf ("failed to read magic\n"); + goto load_fail; + } + if (strncmp (magic, "FSDB", 4)) { + printf ("bad signature\n"); + goto load_fail; + } + + uint8_t majorver = 0; + if (fread (&majorver, 1, 1, fp) != 1) { + goto load_fail; + } + if (majorver != 0) { + printf ("bad majorver=%d\n", majorver); + goto load_fail; + } + + uint8_t minorver = 0; + if (fread (&minorver, 1, 1, fp) != 1) { + goto load_fail; + } + if (minorver != 1) { + printf ("bad minorver=%d\n", minorver); + goto load_fail; + } + printf ("database version=%d.%d\n", majorver, minorver); + + uint32_t num_items = 0; + if (fread (&num_items, 1, 4, fp) != 4) { + goto load_fail; + } + + uint32_t num_items_read = 0; + BTreeNode *prev = NULL; + while (true) { + uint16_t name_len = 0; + if (fread (&name_len, 1, 2, fp) != 2) { + printf("failed to read name length\n"); + goto load_fail; + } + + if (name_len == 0) { + // reached end of child marker + if (!prev) { + goto load_fail; + } + prev = prev->parent; + if (!prev) { + // prev was root node, we're done + printf("reached root node. done\n"); + break; + } + continue; + } + + // read name + char name[name_len + 1]; + if (fread (&name, 1, name_len, fp) != name_len) { + printf("failed to read name\n"); + goto load_fail; + } + name[name_len] = '\0'; + + // read is_dir + uint8_t is_dir = 0; + if (fread (&is_dir, 1, 1, fp) != 1) { + printf("failed to read is_dir\n"); + goto load_fail; + } + + // read size + uint64_t size = 0; + if (fread (&size, 1, 8, fp) != 8) { + printf("failed to read size\n"); + goto load_fail; + } + + // read mtime + uint64_t mtime = 0; + if (fread (&mtime, 1, 8, fp) != 8) { + printf("failed to read mtime\n"); + goto load_fail; + } + + // read mtime + uint32_t pos = 0; + if (fread (&pos, 1, 4, fp) != 4) { + printf("failed to read sort position\n"); + goto load_fail; + } + + int is_root = !strcmp (name, "/"); + BTreeNode *new = btree_node_new (is_root ? "" : name, + mtime, + size, + pos, + is_dir); + if (!prev) { + prev = new; + root = new; + continue; + } + prev = btree_node_prepend (prev, new); + num_items_read++; + } +// trace ("read database: %d/%d\n", num_items_read, num_items); + + DatabaseLocation *location = db_location_new (); + location->num_items = num_items_read; + location->entries = root; + + fclose (fp); + + return location; + +load_fail: + fprintf (stderr, "database load fail (%s)!\n", fname); + if (fp) { + fclose (fp); + } + if (root) { + btree_node_free (root); + } + return NULL; +} + +bool +db_location_write_to_file (DatabaseLocation *location, const char *path) +{ + assert (path != NULL); + assert (location != NULL); + + if (!location->entries) { + return false; + } + g_mkdir_with_parents (path, 0700); + + gchar tempfile[PATH_MAX] = ""; + snprintf (tempfile, sizeof (tempfile), "%s/database.db", path); + + FILE *fp = fopen (tempfile, "w+b"); + if (!fp) { + return false; + } + + const char magic[] = "FSDB"; + if (fwrite (magic, 1, 4, fp) != 4 ) { + goto save_fail; + } + + const uint8_t majorver = 0; + if (fwrite (&majorver, 1, 1, fp) != 1) { + goto save_fail; + } + + const uint8_t minorver = 1; + if (fwrite (&minorver, 1, 1, fp) != 1) { + goto save_fail; + } + + uint32_t num_items = btree_node_n_nodes (location->entries); + if (fwrite (&num_items, 1, 4, fp) != 4) { + goto save_fail; + } + + const uint16_t del = 0; + + BTreeNode *root = location->entries; + BTreeNode *node = root; + uint32_t is_root = !strcmp (root->name, ""); + + while (node) { + const char *name = is_root ? "/" : node->name; + is_root = 0; + uint16_t len = strlen (name); + if (len) { + // write length of node name + if (fwrite (&len, 1, 2, fp) != 2) { + goto save_fail; + } + // write node name + if (fwrite (name, 1, len, fp) != len) { + goto save_fail; + } + // write node name + uint8_t is_dir = node->is_dir; + if (fwrite (&is_dir, 1, 1, fp) != 1) { + goto save_fail; + } + + // write node name + uint64_t size = node->size; + if (fwrite (&size, 1, 8, fp) != 8) { + goto save_fail; + } + + // write node name + uint64_t mtime = node->mtime; + if (fwrite (&mtime, 1, 8, fp) != 8) { + goto save_fail; + } + + // write node name + uint32_t pos = node->pos; + if (fwrite (&pos, 1, 4, fp) != 4) { + goto save_fail; + } + + BTreeNode *temp = node->children; + if (!temp) { + // reached end of children, write delimiter + if (fwrite (&del, 1, 2, fp) != 2) { + goto save_fail; + } + BTreeNode *current = node; + while (true) { + temp = current->next; + if (temp) { + // found next, sibling add that + node = temp; + break; + } + + if (fwrite (&del, 1, 2, fp) != 2) { + goto save_fail; + } + temp = current->parent; + if (!temp) { + // reached last node, abort + node = NULL; + break; + } + else { + current = temp; + } + } + } + else { + node = temp; + } + } + else { + goto save_fail; + } + + } + + fclose (fp); + return true; + +save_fail: + + fclose (fp); + unlink (tempfile); + return false; +} + +static bool +file_is_excluded (const char *name, char **exclude_files) +{ + if (exclude_files) { + for (int i = 0; exclude_files[i]; ++i) { + if (!fnmatch (exclude_files[i], name, 0)) { + return true; + } + } + } + return false; +} + +static bool +directory_is_excluded (const char *name, GList *excludes) +{ + while (excludes) { + if (!strcmp (name, excludes->data)) { + return true; + } + excludes = excludes->next; + } + return false; +} + +static int +db_location_walk_tree_recursive (DatabaseLocation *location, + GList *excludes, + char **exclude_files, + const char *dname, + GTimer *timer, + void (*callback)(const char *), + BTreeNode *parent, + int spec, + bool *state, + bool is_data_prefix) +{ + if (!(*state)) + return WALK_OK; + + if (!db_support(dname, is_data_prefix)) { + return WALK_BADPATTERN; + } + + int len = strlen (dname); + if (len >= FILENAME_MAX - 1) { + //trace ("filename too long: %s\n", dname); + return WALK_NAMETOOLONG; + } + + char fn[FILENAME_MAX] = ""; + strcpy (fn, dname); + if (strcmp (dname, "/")) { + // TODO: use a more performant fix to handle root directory + fn[len++] = '/'; + } + + DIR *dir = NULL; + if (!(dir = opendir (dname))) { + //trace ("can't open: %s\n", dname); + return WALK_BADIO; + } + gulong duration = 0; + g_timer_elapsed (timer, &duration); + + if (duration > 100000) { + if (callback) { + callback (dname); + } + g_timer_reset (timer); + } + + struct dirent *dent = NULL; + while ((*state) && (dent = readdir (dir))) { + if (!strcmp (dent->d_name, ".") || !strcmp (dent->d_name, "..") || dent->d_name[0] == '.') { + continue; + } + if (file_is_excluded (dent->d_name, exclude_files)) { + //trace ("excluded file: %s\n", dent->d_name); + continue; + } + + struct stat st; + strncpy (fn + len, dent->d_name, FILENAME_MAX - len); + + if (lstat (fn, &st) == -1) { + //warn("Can't stat %s", fn); + continue; + } + + if (directory_is_excluded (fn, excludes)) { +// trace ("excluded directory: %s\n", fn); + continue; + } + + const bool is_dir = S_ISDIR (st.st_mode); + BTreeNode *node = btree_node_new (dent->d_name, + st.st_mtime, + st.st_size, + 0, + is_dir); + btree_node_prepend (parent, node); + location->num_items++; + if (is_dir) { + db_location_walk_tree_recursive (location, + excludes, + exclude_files, + fn, + timer, + callback, + node, + spec, + state, + is_data_prefix); + + } + } + + if (dir) { + closedir (dir); + } + return WALK_OK; +} + +static DatabaseLocation * +db_location_build_tree (const char *dname, FsearchConfig *cfg, bool *state, void (*callback)(const char *)) +{ + const char *root_name = NULL; + if (!strcmp (dname, "/")) { + root_name = ""; + } + else { + root_name = dname; + } + BTreeNode *root = btree_node_new (root_name, 0, 0, 0, true); + DatabaseLocation *location = db_location_new (); + location->entries = root; + FsearchConfig *config = cfg; + + int spec = 0; + if (!config->exclude_hidden_items) { + spec |= WS_DOTFILES; + } + GTimer *timer = g_timer_new (); + g_timer_start (timer); + bool is_data_prefix = strncmp("/data", dname, strlen("/data")) == 0; + uint32_t res = db_location_walk_tree_recursive (location, + config->exclude_locations, + config->exclude_files, + dname, + timer, + callback, + root, + spec, + state, + is_data_prefix); + g_timer_destroy (timer); + if (res == WALK_OK) { + return location; + } + else { +// trace ("walk error: %d", res); + db_location_free (location); + } + return NULL; +} + +static DatabaseLocation * +db_location_new (void) +{ + DatabaseLocation *location = g_new0 (DatabaseLocation, 1); + return location; +} + +bool +db_list_insert_node (BTreeNode *node, void *data) +{ + Database *db = data; + darray_set_item (db->entries, node, node->pos); + db->num_entries++; + return true; +} + +static void +db_traverse_tree_insert (BTreeNode *node, void *data) +{ + btree_node_traverse (node, db_list_insert_node, data); +} + +static uint32_t temp_index = 0; + +bool +db_list_add_node (BTreeNode *node, void *data) +{ + Database *db = data; + darray_set_item (db->entries, node, temp_index++); + db->num_entries++; + return true; +} + +static void +db_traverse_tree_add (BTreeNode *node, void *data) +{ + btree_node_traverse (node, db_list_add_node, data); +} + +static void +db_list_insert_location (Database *db, DatabaseLocation *location) +{ + assert (db != NULL); + assert (location != NULL); + assert (location->entries != NULL); + + btree_node_children_foreach (location->entries, db_traverse_tree_insert, db); +} + + +static void +db_list_add_location (Database *db, DatabaseLocation *location) +{ + assert (db != NULL); + assert (location != NULL); + assert (location->entries != NULL); + + btree_node_children_foreach (location->entries, db_traverse_tree_add, db); +} + +static DatabaseLocation * +db_location_get_for_path (Database *db, const char *path) +{ + assert (db != NULL); + assert (path != NULL); + + GList *locations = db->locations; + for (GList *l = locations; l != NULL; l = l->next) { + DatabaseLocation *location = (DatabaseLocation *)l->data; + BTreeNode *root = btree_node_get_root (location->entries); + const char *location_path = root->name; + if (!strcmp (location_path, path)) { + return location; + } + } + return NULL; +} + +void +db_location_free (DatabaseLocation *location) +{ + assert (location != NULL); + + if (location->entries) { + btree_node_free (location->entries); + location->entries = NULL; + } + g_free (location); + location = NULL; +} + +bool +db_location_remove (Database *db, const char *path) +{ + assert (db != NULL); + assert (path != NULL); + + DatabaseLocation *location = db_location_get_for_path (db, path); + if (location) { + db->locations = g_list_remove (db->locations, location); + db_location_free (location); + db_sort (db); + } + + return true; +} + +static void +location_build_path (char *path, size_t path_len, const char *location_name) +{ + assert (path != NULL); + assert (location_name != NULL); + + const char *location = !strcmp (location_name, "") ? "/" : location_name; + + gchar *path_checksum = g_compute_checksum_for_string (G_CHECKSUM_SHA256, + location, + -1); + + assert (path_checksum != NULL); + + gchar config_dir[PATH_MAX] = ""; + config_build_dir (config_dir, sizeof (config_dir)); + + assert (0 <= snprintf (path, path_len, "%s/database/%s", config_dir, path_checksum)); + g_free (path_checksum); + return; +} + +void +db_location_delete (DatabaseLocation *location, const char *location_name) +{ + assert (location != NULL); + assert (location_name != NULL); + + gchar database_path[PATH_MAX] = ""; + location_build_path (database_path, + sizeof (database_path), + location_name); + + gchar database_file_path[PATH_MAX] = ""; + assert (0 <= snprintf (database_file_path, sizeof (database_file_path), "%s/%s", database_path, "database.db")); + + g_remove (database_file_path); + g_remove (database_path); +} + +bool +db_save_location (Database *db, const char *location_name) +{ + assert (db != NULL); + + gchar database_path[PATH_MAX] = ""; + location_build_path (database_path, + sizeof (database_path), + location_name); +// trace ("%s\n", database_path); + + gchar database_fname[PATH_MAX] = ""; + assert (0 <= snprintf (database_fname, sizeof (database_fname), "%s/database.db", database_path)); + DatabaseLocation *location = db_location_get_for_path (db, location_name); + if (location) { + db_location_write_to_file (location, database_path); + } + + return true; +} + +bool +db_save_locations (Database *db) +{ + assert (db != NULL); + g_return_val_if_fail (db->locations != NULL, false); + + //db_update_sort_index (db); + GList *locations = db->locations; + for (GList *l = locations; l != NULL; l = l->next) { + DatabaseLocation *location = (DatabaseLocation *)l->data; + BTreeNode *root = btree_node_get_root (location->entries); + const char *location_path = root->name; + db_save_location (db, location_path); + } + return true; +} + +static gchar * +db_location_get_path (const char *location_name) +{ + gchar database_path[PATH_MAX] = ""; + location_build_path (database_path, + sizeof (database_path), + location_name); +// trace ("%s\n", database_path); + + gchar database_fname[PATH_MAX] = ""; + assert (0 <= snprintf (database_fname, sizeof (database_fname), "%s/database.db", database_path)); + + return g_strdup (database_fname); +} + +bool +db_location_load (Database *db, const char *location_name) +{ + db_lock (db); + gchar *load_path = db_location_get_path (location_name); + if (!load_path) { + db_unlock (db); + return false; + } + DatabaseLocation *location = db_location_load_from_file (load_path); + g_free (load_path); + load_path = NULL; + + if (location) { + location->num_items = btree_node_n_nodes (location->entries); +// trace ("number of nodes: %d\n", location->num_items); + db->locations = g_list_append (db->locations, location); + db->num_entries += location->num_items; + db_update_timestamp (db); + db_unlock (db); + return true; + } + db_update_timestamp (db); + db_unlock (db); + return false; +} + +bool +db_location_add (Database *db, + const char *location_name, + FsearchConfig *config, + bool *state, + void (*callback)(const char *)) +{ + assert (db != NULL); + db_lock (db); +// trace ("load location: %s\n", location_name); + + DatabaseLocation *location = db_location_build_tree (location_name, config, state, callback); + + if (location) { +// trace ("location num entries: %d\n", location->num_items); + db->locations = g_list_append (db->locations, location); + db->num_entries += location->num_items; + db_update_timestamp (db); + db_unlock (db); + return true; + } + + db_update_timestamp (db); + db_unlock (db); + return false; +} + +void +db_update_sort_index (Database *db) +{ + assert (db != NULL); + assert (db->entries != NULL); + + for (uint32_t i = 0; i < db->num_entries; ++i) { + BTreeNode *node = darray_get_item (db->entries, i); + if (node) { + node->pos = i; + } + } +} + +static uint32_t +db_locations_get_num_entries (Database *db) +{ + assert (db != NULL); + assert (db->locations != NULL); + + uint32_t num_entries = 0; + GList *locations = db->locations; + for (GList *l = locations; l != NULL; l = l->next) { + DatabaseLocation *location = l->data; + num_entries += location->num_items; + } + return num_entries; +} + +void +db_build_initial_entries_list (Database *db) +{ + assert (db != NULL); + assert (db->num_entries >= 0); + + db_lock (db); + db_entries_clear (db); + uint32_t num_entries = db_locations_get_num_entries (db); +// trace ("update list: %d\n", num_entries); + db->entries = darray_new (num_entries); + + GList *locations = db->locations; + temp_index = 0; + for (GList *l = locations; l != NULL; l = l->next) { + db_list_add_location (db, l->data); + } + db_sort (db); + db_update_sort_index (db); + db_unlock (db); +} + +void +db_update_entries_list (Database *db) +{ + assert (db != NULL); + assert (db->num_entries >= 0); + + db_lock (db); + db_entries_clear (db); + uint32_t num_entries = db_locations_get_num_entries (db); +// trace ("update list: %d\n", num_entries); + db->entries = darray_new (num_entries); + + GList *locations = db->locations; + for (GList *l = locations; l != NULL; l = l->next) { + db_list_insert_location (db, l->data); + } + db_unlock (db); +} + +BTreeNode * +db_location_get_entries (DatabaseLocation *location) +{ + assert (location != NULL); + return location->entries; +} + +Database * +db_new () +{ + Database *db = g_new0 (Database, 1); + g_mutex_init (&db->mutex); + return db; +} + +static void +db_entries_clear (Database *db) +{ + // free entries + assert (db != NULL); + + if (db->entries) { + darray_free (db->entries); + db->entries = NULL; + } + db->num_entries = 0; +} + +void +db_free (Database *db) +{ + assert (db != NULL); + + db_entries_clear (db); + g_mutex_clear (&db->mutex); + g_free (db); + db = NULL; + return; +} + +time_t +db_get_timestamp (Database *db) +{ + assert (db != NULL); + return db->timestamp; +} + +uint32_t +db_get_num_entries (Database *db) +{ + assert (db != NULL); + return db->num_entries; +} + +void +db_unlock (Database *db) +{ + assert (db != NULL); + g_mutex_unlock (&db->mutex); +} + +void +db_lock (Database *db) +{ + assert (db != NULL); + g_mutex_lock (&db->mutex); +} + +bool +db_try_lock (Database *db) +{ + assert (db != NULL); + return g_mutex_trylock (&db->mutex); +} + +DynamicArray * +db_get_entries (Database *db) +{ + assert (db != NULL); + return db->entries; +} + +static int +sort_by_name (const void *a, const void *b) +{ + BTreeNode *node_a = *(BTreeNode **)a; + BTreeNode *node_b = *(BTreeNode **)b; + + if(!node_a) { + return -1; + } + if (!node_b) { + return 1; + } + + const bool is_dir_a = node_a->is_dir; + const bool is_dir_b = node_b->is_dir; + if (is_dir_a != is_dir_b) { + return is_dir_a ? -1 : 1; + } + + return strverscmp (node_a->name, node_b->name); +} + +void +db_sort (Database *db) +{ + assert (db != NULL); + assert (db->entries != NULL); + +// trace ("start sorting\n"); + darray_sort (db->entries, sort_by_name); +// trace ("finished sorting\n"); +} + +static void +db_location_free_all (Database *db) +{ + assert (db != NULL); + g_return_if_fail (db->locations != NULL); + + GList *l = db->locations; + while (l) { +// trace ("free location\n"); + db_location_free (l->data); + l = l->next; + } + g_list_free (db->locations); + db->locations = NULL; +} + +bool +db_clear (Database *db) +{ + assert (db != NULL); + +// trace ("clear locations\n"); + db_entries_clear (db); + db_location_free_all (db); + return true; +} + +bool +db_support(const char *search_path, bool is_data_prefix) +{ + if (is_data_prefix) + return true; + + regex_t reg; + regmatch_t pmatch[1]; + const char *pattern = "^((/boot)|(/dev)|(/proc)|(/sys)|(/root)|(/run)|(/data)).*$"; + + regcomp(®, pattern, REG_EXTENDED); + if (regexec(®, search_path, 1, pmatch, 0) == 0) { + regfree(®); + return false; + } + + regfree(®); + return true; +} diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/database.h b/dde-file-manager-5.5.3/3rdparty/fsearch/database.h new file mode 100644 index 0000000..2117b5a --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/database.h @@ -0,0 +1,102 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#pragma once + +#include +#include +#include +#include "array.h" +#include "btree.h" + +typedef struct _Database Database; + +typedef struct _DatabaseLocation DatabaseLocation; + +typedef struct _FsearchConfig FsearchConfig; + +void +db_location_free(DatabaseLocation *location); + +bool +db_location_load(Database *db, const char *location_name); + +bool +db_location_add(Database *db, + const char *location_name, + FsearchConfig *config, + bool *state, + void (*callback)(const char *)); + +bool +db_location_remove(Database *db, const char *path); + +bool +db_location_write_to_file(DatabaseLocation *location, const char *fname); + +BTreeNode * +db_location_get_entries(DatabaseLocation *location); + +void +db_free(Database *db); + +Database * +db_new(); + +gboolean +db_list_append_node(BTreeNode *node, + gpointer data); + +void +db_update_sort_index(Database *db); + +bool +db_save_locations(Database *db); + +void +db_update_entries_list(Database *db); + +void +db_build_initial_entries_list(Database *db); + +time_t +db_get_timestamp(Database *db); + +uint32_t +db_get_num_entries(Database *db); + +void +db_unlock(Database *db); + +void +db_lock(Database *db); + +bool +db_try_lock(Database *db); + +DynamicArray * +db_get_entries(Database *db); + +void +db_sort(Database *db); + +bool +db_clear(Database *db); + +bool +db_support(const char *search_path, bool is_data_prefix); diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/database_search.c b/dde-file-manager-5.5.3/3rdparty/fsearch/database_search.c new file mode 100644 index 0000000..9cc1124 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/database_search.c @@ -0,0 +1,788 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "database_search.h" +#include "string_utils.h" +#include "query.h" +//#include "debug.h" +#include "utf8.h" + +#define OVECCOUNT 3 + + + +typedef struct search_query_s { + char *query; + uint32_t (*search_func)(const char *, const char *); + size_t query_len; + uint32_t has_uppercase; + uint32_t has_separator; + uint32_t is_utf8; + //uint32_t found; +} search_query_t; + +typedef struct search_context_s { + DatabaseSearch *search; + BTreeNode **results; + search_query_t **queries; + uint32_t num_queries; + uint32_t num_results; + uint32_t start_pos; + uint32_t end_pos; +} search_thread_context_t; + +DatabaseSearchResult * +db_search (DatabaseSearch *search, FsearchQuery *q); + +static DatabaseSearchResult * +db_search_empty (DatabaseSearch *search); + +DatabaseSearchEntry * +db_search_entry_new (BTreeNode *node, uint32_t pos); + +static void +db_search_entry_free (DatabaseSearchEntry *entry); + +static gpointer +fsearch_search_thread (gpointer user_data) +{ + DatabaseSearch *search = user_data; + + g_mutex_lock (&search->query_mutex); + while (true) { + search->search_thread_started = true; + g_cond_wait (&search->search_thread_start_cond, &search->query_mutex); + printf("---------------------------g_cond_wait (&search->search_thread_start_cond)\n"); + if (search->search_thread_terminate) { + break; + } + while (true) { + FsearchQuery *query = search->query_ctx; + if (!query) { + break; + } + search->query_ctx = NULL; + g_mutex_unlock (&search->query_mutex); + // if query is empty string we are done here + DatabaseSearchResult *result = NULL; + if (fs_str_is_empty (query->query)) { + if (!search->hide_results) { + result = db_search_empty (search); + } + else { + result = calloc (1, sizeof (DatabaseSearchResult)); + } + } + else { + result = db_search (search, query); + } + result->cb_data = query->callback_data; + query->callback (result, query->sender); + printf("+++++++++++++++++++++++++++++++++++++++++++query->callback\n"); + fsearch_query_free (query); + g_mutex_lock (&search->query_mutex); + } + } + g_mutex_unlock (&search->query_mutex); + return NULL; +} + + +static search_thread_context_t * +search_thread_context_new (DatabaseSearch *search, + search_query_t **queries, + uint32_t num_queries, + uint32_t start_pos, + uint32_t end_pos) +{ + search_thread_context_t *ctx = calloc (1, sizeof(search_thread_context_t)); + assert (ctx != NULL); + assert (end_pos >= start_pos); + + ctx->search = search; + ctx->queries = queries; + ctx->num_queries = num_queries; + ctx->results = calloc (end_pos - start_pos + 1, sizeof (BTreeNode *)); + assert (ctx->results != NULL); + + ctx->num_results = 0; + ctx->start_pos = start_pos; + ctx->end_pos = end_pos; + return ctx; +} + +static inline bool +filter_node (BTreeNode *node, FsearchFilter filter) +{ + if (filter == FSEARCH_FILTER_NONE) { + return true; + } + bool is_dir = node->is_dir; + if (filter == FSEARCH_FILTER_FILES + && !is_dir) { + return true; + } + if (filter == FSEARCH_FILTER_FOLDERS + && is_dir) { + return true; + } + return false; +} + +static void * +search_thread (void * user_data) +{ + search_thread_context_t *ctx = (search_thread_context_t *)user_data; +// assert (ctx != NULL); +// assert (ctx->results != NULL); + if(ctx==NULL) + { + return NULL; + } + if(ctx->results==NULL) + { + return NULL; + } + const uint32_t start = ctx->start_pos; + const uint32_t end = ctx->end_pos; + const uint32_t max_results = ctx->search->max_results; + const uint32_t num_queries = ctx->num_queries; + const FsearchFilter filter = ctx->search->filter; + search_query_t **queries = ctx->queries; + const uint32_t search_in_path = ctx->search->search_in_path; + const uint32_t auto_search_in_path = ctx->search->auto_search_in_path; + DynamicArray *entries = ctx->search->entries; + BTreeNode **results = ctx->results; + + uint32_t num_results = 0; + char full_path[PATH_MAX] = ""; + for (uint32_t i = start; i <= end; i++) { + if (max_results && num_results == max_results) { + break; + } + BTreeNode *node = darray_get_item (entries, i); + if (!node) { + continue; + } + if (!filter_node (node, filter)) { + continue; + } + + const char *haystack_path = NULL; + const char *haystack_name = node->name; + if (search_in_path) { + btree_node_get_path_full (node, full_path, sizeof (full_path)); + haystack_path = full_path; + } + + uint32_t num_found = 0; + while (true) { + if (num_found == num_queries) { + results[num_results] = node; + num_results++; + break; + } + search_query_t *query = queries[num_found++]; + if (!query) { + break; + } + char *ptr = query->query; + uint32_t (*search_func)(const char *, const char *) = query->search_func; + + const char *haystack = NULL; + if (search_in_path || (auto_search_in_path && query->has_separator)) { + if (!haystack_path) { + btree_node_get_path_full (node, full_path, sizeof (full_path)); + haystack_path = full_path; + } + haystack = haystack_path; + } + else { + haystack = haystack_name; + } + if (!search_func (haystack, ptr)) { + break; + } + } + + } + ctx->num_results = num_results; + return NULL; +} + +#ifdef DEBUG +static struct timeval tm1; +#endif + +static inline void timer_start() +{ +#ifdef DEBUG + gettimeofday(&tm1, NULL); +#endif +} + +static inline void timer_stop() +{ +#ifdef DEBUG + struct timeval tm2; + gettimeofday(&tm2, NULL); + + unsigned long long t = 1000 * (tm2.tv_sec - tm1.tv_sec) + (tm2.tv_usec - tm1.tv_usec) / 1000; + trace ("%llu ms\n", t); +#endif +} + +static void * +search_regex_thread (void * user_data) +{ + return NULL; +} + +static int +is_regex (const char *query) +{ + char regex_chars[] = { + '$', + '(', + ')', + '*', + '+', + '.', + '?', + '[', + '\\', + '^', + '{', + '|', + '\0' + }; + + return (strpbrk(query, regex_chars) != NULL); +} + +static uint32_t +search_wildcard_icase (const char *haystack, const char *needle) +{ + return !fnmatch (needle, haystack, FNM_CASEFOLD) ? 1 : 0; +} + +static uint32_t +search_wildcard (const char *haystack, const char *needle) +{ + return !fnmatch (needle, haystack, 0) ? 1 : 0; +} + +static uint32_t +search_normal_icase_u8 (const char *haystack, const char *needle) +{ + // TODO: make this faster + return utf8casestr (haystack, needle) ? 1 : 0; +} + +static uint32_t +search_normal_icase (const char *haystack, const char *needle) +{ + return strcasestr (haystack, needle) ? 1 : 0; +} + +static uint32_t +search_normal (const char *haystack, const char *needle) +{ + return strstr (haystack, needle) ? 1 : 0; +} + +static void +search_query_free (void * data) +{ + search_query_t *query = data; + assert (query != NULL); + + if (query->query != NULL) { + g_free (query->query); + query->query = NULL; + } + g_free (query); + query = NULL; +} + +static search_query_t * +search_query_new (const char *query, bool match_case) +{ + search_query_t *new = calloc (1, sizeof (search_query_t)); + assert (new != NULL); + + new->query = g_strdup (query); + new->query_len = strlen (query); + new->has_uppercase = fs_str_has_upper (query); + new->has_separator = strchr (query, '/') ? 1 : 0; + // TODO: this might not work at all times? + if (utf8len (query) != new->query_len) { + new->is_utf8 = 1; + } + else { + new->is_utf8 = 0; + } + if (strchr (query, '*') || strchr (query, '?')) { + if (match_case) { + new->search_func = search_wildcard; + } + else { + new->search_func = search_wildcard_icase; + } + } + else { + if (match_case) { + new->search_func = search_normal; + } + else { + if (new->is_utf8) { + new->search_func = search_normal_icase_u8; + } + else { + new->search_func = search_normal_icase; + } + } + } + return new; +} + +static search_query_t ** +build_queries (DatabaseSearch *search, FsearchQuery *q) +{ + assert (search != NULL); + assert (q->query != NULL); + + char *tmp_query_copy = strdup (q->query); + assert (tmp_query_copy != NULL); + // remove leading/trailing whitespace + g_strstrip (tmp_query_copy); + + // check if regex characters are present + const bool is_reg = is_regex (q->query); + if (is_reg && search->enable_regex) { + search_query_t **queries = calloc (2, sizeof (search_query_t *)); + queries[0] = search_query_new (tmp_query_copy, search->match_case); + queries[1] = NULL; + g_free (tmp_query_copy); + tmp_query_copy = NULL; + + return queries; + } + // whitespace is regarded as AND so split query there in multiple queries + char **tmp_queries = g_strsplit_set (tmp_query_copy, " ", -1); + assert (tmp_queries != NULL); + + uint32_t tmp_queries_len = g_strv_length (tmp_queries); + search_query_t **queries = calloc (tmp_queries_len + 1, sizeof (search_query_t *)); + for (uint32_t i = 0; i < tmp_queries_len; i++) { + queries[i] = search_query_new (tmp_queries[i], search->match_case); + } + + g_free (tmp_query_copy); + tmp_query_copy = NULL; + g_strfreev (tmp_queries); + tmp_queries = NULL; + + return queries; +} + +static DatabaseSearchResult * +db_search_empty (DatabaseSearch *search) +{ + assert (search != NULL); + assert (search->entries != NULL); + + const uint32_t num_results = MIN (search->max_results, search->num_entries); + GPtrArray *results = g_ptr_array_sized_new (num_results); + g_ptr_array_set_free_func (results, (GDestroyNotify)db_search_entry_free); + + DynamicArray *entries = search->entries; + + uint32_t num_folders = 0; + uint32_t num_files = 0; + uint32_t pos = 0; + for (uint32_t i = 0; pos < num_results && i < search->num_entries; ++i) { + BTreeNode *node = darray_get_item (entries, i); + if (!node) { + continue; + } + + if (!filter_node (node, search->filter)) { + continue; + } + if (node->is_dir) { + num_folders++; + } + else { + num_files++; + } + DatabaseSearchEntry *entry = db_search_entry_new (node, pos); + g_ptr_array_add (results, entry); + pos++; + } + DatabaseSearchResult *result_ctx = calloc (1, sizeof (DatabaseSearchResult)); + assert (result_ctx != NULL); + result_ctx->results = results; + result_ctx->num_folders = num_folders; + result_ctx->num_files = num_files; + return result_ctx; +} + + DatabaseSearchResult * +db_search (DatabaseSearch *search, FsearchQuery *q) +{ + assert (search != NULL); + assert (search->entries != NULL); + + search_query_t **queries = build_queries (search, q); + + const uint32_t num_threads = MIN(fsearch_thread_pool_get_num_threads (search->pool), search->num_entries); + const uint32_t num_items_per_thread = MAX(search->num_entries / num_threads, 1); + + search_thread_context_t *thread_data[num_threads]; + memset (thread_data, 0, num_threads * sizeof (search_thread_context_t *)); + + const uint32_t max_results = search->max_results; + const bool limit_results = max_results ? true : false; + const bool is_reg = is_regex (search->query); + uint32_t num_queries = 0; + while (queries[num_queries]) { + num_queries++; + } + uint32_t start_pos = 0; + uint32_t end_pos = num_items_per_thread - 1; + timer_start (); + GList *temp = fsearch_thread_pool_get_threads (search->pool); + for (uint32_t i = 0; i < num_threads; i++) { + thread_data[i] = search_thread_context_new (search, + queries, + num_queries, + start_pos, + i == num_threads - 1 ? search->num_entries - 1 : end_pos); + + start_pos = end_pos + 1; + end_pos += num_items_per_thread; + + fsearch_thread_pool_push_data (search->pool, + temp, + is_reg && search->enable_regex ? + search_regex_thread : search_thread, + thread_data[i]); + temp = temp->next; + } + temp = fsearch_thread_pool_get_threads (search->pool); + while (temp) { + fsearch_thread_pool_wait_for_thread (search->pool, temp); + temp = temp->next; + } + +// trace ("search done: "); + timer_stop (); + + // get total number of entries found + uint32_t num_results = 0; + for (uint32_t i = 0; i < num_threads; ++i) { + num_results += thread_data[i]->num_results; + } + GPtrArray *results = g_ptr_array_sized_new (MIN (num_results, max_results)); + g_ptr_array_set_free_func (results, (GDestroyNotify)db_search_entry_free); + uint32_t num_folders = 0; + uint32_t num_files = 0; + + uint32_t pos = 0; + for (uint32_t i = 0; i < num_threads; i++) { + search_thread_context_t *ctx = thread_data[i]; + if (!ctx) { + break; + } + for (uint32_t j = 0; j < ctx->num_results; ++j) { + if (limit_results) { + if (pos >= max_results) { + break; + } + } + BTreeNode *node = ctx->results[j]; + if (node->is_dir) { + num_folders++; + } + else { + num_files++; + } + DatabaseSearchEntry *entry = db_search_entry_new (node, pos); + g_ptr_array_add (results, entry); + pos++; + } + if (ctx->results) { + g_free (ctx->results); + ctx->results = NULL; + } + if (ctx) { + g_free (ctx); + ctx = NULL; + } + } + for (uint32_t i = 0; i < num_queries; ++i) { + search_query_free (queries[i]); + queries[i] = NULL; + } + free (queries); + queries = NULL; + DatabaseSearchResult *result_ctx = calloc (1, sizeof (DatabaseSearchResult)); + assert (result_ctx != NULL); + result_ctx->results = results; + result_ctx->num_folders = num_folders; + result_ctx->num_files = num_files; + return result_ctx; +} + +void +db_search_results_clear (DatabaseSearch *search) +{ + assert (search != NULL); + + // free entries + if (search->results) { + g_ptr_array_free (search->results, TRUE); + search->results = NULL; + } + search->num_folders = 0; + search->num_files = 0; + return; +} + +void +db_search_free (DatabaseSearch *search) +{ + assert (search != NULL); + + db_search_results_clear (search); + if (search->query) { + g_free (search->query); + search->query = NULL; + } + g_mutex_lock (&search->query_mutex); + if (search->query_ctx) { + fsearch_query_free (search->query_ctx); + search->query_ctx = NULL; + } + g_mutex_unlock (&search->query_mutex); + + search->search_thread_terminate = true; + g_cond_signal (&search->search_thread_start_cond); + g_thread_join (search->search_thread); + g_mutex_clear (&search->query_mutex); + g_cond_clear (&search->search_thread_start_cond); + g_free (search); + search = NULL; + return; +} + +BTreeNode * +db_search_entry_get_node (DatabaseSearchEntry *entry) +{ + return entry->node; +} + +uint32_t +db_search_entry_get_pos (DatabaseSearchEntry *entry) +{ + return entry->pos; +} + +void +db_search_entry_set_pos (DatabaseSearchEntry *entry, uint32_t pos) +{ + entry->pos = pos; +} + +static void +db_search_entry_free (DatabaseSearchEntry *entry) +{ + if (entry) { + g_free (entry); + entry = NULL; + } +} + +DatabaseSearchEntry * +db_search_entry_new (BTreeNode *node, uint32_t pos) +{ + DatabaseSearchEntry *entry = calloc (1, sizeof (DatabaseSearchEntry)); + assert (entry != NULL); + + entry->node = node; + entry->pos = pos; + return entry; +} + +DatabaseSearch * +db_search_new (FsearchThreadPool *pool) +{ + DatabaseSearch *db_search = calloc (1, sizeof (DatabaseSearch)); + assert (db_search != NULL); + + db_search->pool = pool; + db_search->search_thread_started = false; + g_mutex_init (&db_search->query_mutex); + g_cond_init (&db_search->search_thread_start_cond); + db_search->search_thread = g_thread_new("fsearch_search_thread", fsearch_search_thread, db_search); + return db_search; +} + +void +db_search_set_search_in_path (DatabaseSearch *search, bool search_in_path) +{ + assert (search != NULL); + + search->search_in_path = search_in_path; +} + +void +db_search_set_query (DatabaseSearch *search, const char *query) +{ + assert (search != NULL); + + if (search->query) { + g_free (search->query); + } + search->query = g_strdup (query); +} + +void +db_search_update (DatabaseSearch *search, + DynamicArray *entries, + uint32_t num_entries, + uint32_t max_results, + FsearchFilter filter, + const char *query, + bool hide_results, + bool match_case, + bool enable_regex, + bool auto_search_in_path, + bool search_in_path) +{ + assert (search != NULL); + + search->entries = entries; + search->num_entries = num_entries; + db_search_set_query (search, query); + search->enable_regex = enable_regex; + search->search_in_path = search_in_path; + search->auto_search_in_path = auto_search_in_path; + search->hide_results = hide_results; + search->match_case = match_case; + search->max_results = max_results; + search->filter = filter; +} + +uint32_t +db_search_get_num_results (DatabaseSearch *search) +{ + assert (search != NULL); + return search->results->len; +} + +uint32_t +db_search_get_num_files (DatabaseSearch *search) +{ + assert (search != NULL); + return search->num_files; +} + +uint32_t +db_search_get_num_folders (DatabaseSearch *search) +{ + assert (search != NULL); + return search->num_folders; +} + +static void +update_index (DatabaseSearch *search) +{ + assert (search != NULL); + + for (uint32_t i = 0; i < search->results->len; ++i) { + DatabaseSearchEntry *entry = g_ptr_array_index (search->results, i); + entry->pos = i; + } +} + +void +db_search_remove_entry (DatabaseSearch *search, DatabaseSearchEntry *entry) +{ + if (search == NULL) { + return; + } + if (entry == NULL) { + return; + } + + g_ptr_array_remove (search->results, (void *) entry); + update_index (search); +} + +GPtrArray * +db_search_get_results (DatabaseSearch *search) +{ + assert (search != NULL); + return search->results; +} + +static void +db_search_queue (DatabaseSearch *search, FsearchQuery *query) +{ + g_mutex_lock (&search->query_mutex); + if (search->query_ctx) { + fsearch_query_free (search->query_ctx); + } + search->query_ctx = query; + + g_mutex_unlock (&search->query_mutex); + // 确保search线程处于wait状态,否则会照成流程阻塞 + while (!search->search_thread_started) { + usleep(100); + } + g_cond_signal (&search->search_thread_start_cond); + + printf("---------------------------g_cond_signal (&search->search_thread_start_cond)\n"); +} + +void +db_perform_search (DatabaseSearch *search, void (*callback)(void *, void *), void *callback_data, void *sender) +{ + assert (search != NULL); + if (search->entries == NULL) { + return; + } + + db_search_results_clear (search); + + FsearchQuery *q = fsearch_query_new (search->query, callback, callback_data, sender, false, false, false, false); + db_search_queue (search, q); +} diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/database_search.h b/dde-file-manager-5.5.3/3rdparty/fsearch/database_search.h new file mode 100644 index 0000000..047daf4 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/database_search.h @@ -0,0 +1,133 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ +#pragma once + +#include +#include "array.h" +#include "btree.h" +#include "query.h" +#include "fsearch_thread_pool.h" + +typedef struct _DatabaseSearch DatabaseSearch; +typedef struct _DatabaseSearchEntry DatabaseSearchEntry; + +// search modes +enum { + DB_SEARCH_MODE_NORMAL = 0, + DB_SEARCH_MODE_REGEX = 1, +}; +struct _DatabaseSearchEntry { + BTreeNode *node; + uint32_t pos; +}; +typedef enum { + FSEARCH_FILTER_NONE, + FSEARCH_FILTER_FOLDERS, + FSEARCH_FILTER_FILES, +} FsearchFilter; + +typedef struct { + GPtrArray *results; + void *cb_data; + uint32_t num_folders; + uint32_t num_files; +} DatabaseSearchResult; + +struct _DatabaseSearch { + GPtrArray *results; + FsearchThreadPool *pool; + + DynamicArray *entries; + uint32_t num_entries; + + GThread *search_thread; + bool search_thread_terminate; + GMutex query_mutex; + GCond search_thread_start_cond; + + char *query; + FsearchQuery *query_ctx; + FsearchFilter filter; + uint32_t max_results; + uint32_t num_folders; + uint32_t num_files; + bool hide_results; + bool match_case; + bool enable_regex; + bool search_in_path; + bool auto_search_in_path; + bool search_thread_started; +}; + +void +db_search_free(DatabaseSearch *search); + +DatabaseSearch * +db_search_new(FsearchThreadPool *pool); + +BTreeNode * +db_search_entry_get_node(DatabaseSearchEntry *entry); + +uint32_t +db_search_entry_get_pos(DatabaseSearchEntry *entry); + +void +db_search_entry_set_pos(DatabaseSearchEntry *entry, uint32_t pos); + +void +db_search_set_query(DatabaseSearch *search, const char *query); + +void +db_search_update(DatabaseSearch *search, + DynamicArray *entries, + uint32_t num_entries, + uint32_t max_results, + FsearchFilter filter, + const char *query, + bool hide_results, + bool match_case, + bool enable_regex, + bool auto_search_in_path, + bool search_in_path); + +void +db_search_results_clear(DatabaseSearch *search); + +void +db_search_set_search_in_path(DatabaseSearch *search, bool search_in_path); + +uint32_t +db_search_get_num_results(DatabaseSearch *search); + +uint32_t +db_search_get_num_files(DatabaseSearch *search); + +uint32_t +db_search_get_num_folders(DatabaseSearch *search); + +GPtrArray * +db_search_get_results(DatabaseSearch *search); + +void +db_search_remove_entry(DatabaseSearch *search, DatabaseSearchEntry *entry); + +void +db_perform_search(DatabaseSearch *search, void (*callback)(void *, void *), void *callback_data, void *sender); + +DatabaseSearchResult * +db_search(DatabaseSearch *search, FsearchQuery *q); diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch.c b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch.c new file mode 100644 index 0000000..1e41dcf --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch.c @@ -0,0 +1,163 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +//#ifdef HAVE_CONFIG_H +//#include +//#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fsearch.h" +#include "fsearch_config.h" +#include "fsearch_limits.h" +//#include "utils.h" +#include "database.h" +#include "database_search.h" +//#include "debug.h" +enum { + DATABASE_UPDATE, + DATABASE_UPDATED, + LAST_SIGNAL +}; + +//static guint signals [LAST_SIGNAL]; + +gpointer +load_database (FsearchApplication*app, const char *path, bool *state); + +Database * +fsearch_application_get_db (FsearchApplication *fsearch) +{ + return fsearch->db; +} + +FsearchThreadPool * +fsearch_application_get_thread_pool (FsearchApplication *fsearch) +{ + return fsearch->pool; +} + +FsearchConfig * +fsearch_application_get_config (FsearchApplication *fsearch) +{ + return fsearch->config; +} +static void +build_location_callback (const char *text) +{ + if (text) { + //g_idle_add (update_db_cb, g_strdup (text)); + } +} + +static bool +make_location_dir (void) +{ + gchar config_dir[PATH_MAX] = ""; + config_build_dir (config_dir, sizeof (config_dir)); + gchar location_dir[PATH_MAX] = ""; + g_assert (0 <= snprintf (location_dir, sizeof (location_dir), "%s/%s", config_dir, "database")); + return !g_mkdir_with_parents (location_dir, 0700); +} + +void +fsearch_application_init (FsearchApplication *app) +{ + config_make_dir (); + make_location_dir (); + app->config = calloc (1, sizeof (FsearchConfig)); + if (!config_load (app->config)) { + if (!config_load_default (app->config)) { + } + } + app->db = NULL; + app->search = NULL; + g_mutex_init (&app->mutex); +} + +static void +fsearch_application_shutdown (FsearchApplication *app) +{ + FsearchApplication *fsearch = app; + + if (fsearch->db) { + db_save_locations (fsearch->db); + db_clear (fsearch->db); + } + if (fsearch->pool) { + fsearch_thread_pool_free (fsearch->pool); + } + config_save (fsearch->config); + config_free (fsearch->config); + g_mutex_clear (&fsearch->mutex); +// G_APPLICATION_CLASS (fsearch_application_parent_class)->shutdown (app); +} +static void +prepare_windows_for_db_update (FsearchApplication *app) +{ + return; +} + +#ifdef DEBUG +static struct timeval tm1; +#endif + +static inline void timer_start() +{ +#ifdef DEBUG + gettimeofday(&tm1, NULL); +#endif +} + +static inline void timer_stop() +{ +#ifdef DEBUG + struct timeval tm2; + gettimeofday(&tm2, NULL); + + unsigned long long t = 1000 * (tm2.tv_sec - tm1.tv_sec) + (tm2.tv_usec - tm1.tv_usec) / 1000; + trace ("%llu ms\n", t); +#endif +} + + gpointer +load_database (FsearchApplication*app, const char *path, bool *state) +{ + timer_start (); + app->db = db_new (); + if (db_location_add (app->db, path, app->config, state, build_location_callback)) { + db_build_initial_entries_list (app->db); + } + timer_stop (); + + return NULL; +} + +void +fsearch_application_startup (FsearchApplication* app) +{ + (app)->pool = fsearch_thread_pool_init (); +} + diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch.h b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch.h new file mode 100644 index 0000000..1efc379 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch.h @@ -0,0 +1,64 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#pragma once + +#include +#include +//#include +//#include +#include "database.h" +#include "fsearch_config.h" +#include "fsearch_thread_pool.h" +//#include "glib_support.h" +#include "database_search.h" + +struct _FsearchApplication { + Database *db; + DatabaseSearch *search; + FsearchConfig *config; + FsearchThreadPool *pool; + DatabaseSearchResult *result; + GMutex mutex; +}; +typedef struct _FsearchApplication FsearchApplication; + + +void +fsearch_update_database(FsearchApplication *fsearch); + +Database * +fsearch_application_get_db(FsearchApplication *fsearch); + +FsearchConfig * +fsearch_application_get_config(FsearchApplication *fsearch); + +FsearchThreadPool * +fsearch_application_get_thread_pool(FsearchApplication *fsearch); + +void +fsearch_application_activate(FsearchApplication *app); + +void +fsearch_application_startup(FsearchApplication *app); + +gpointer +load_database(FsearchApplication *app, const char *path, bool *state); + +void +fsearch_application_init(FsearchApplication *app); diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_config.c b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_config.c new file mode 100644 index 0000000..e4f5dcc --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_config.c @@ -0,0 +1,579 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#include +#include +#include +#include +#include + +#include "fsearch_config.h" +#include "fsearch_limits.h" +//#include "debug.h" + +const char *config_file_name = "fsearch.conf"; +const char *config_folder_name = "fsearch"; + +void +config_build_dir (char *path, size_t len) +{ + g_assert (path != NULL); + g_assert (len >= 0); + + const gchar *xdg_conf_dir = g_get_user_config_dir (); + snprintf (path, len, "%s/%s", xdg_conf_dir, config_folder_name); + return; +} + +static void +config_build_path (char *path, size_t len) +{ + g_assert (path != NULL); + g_assert (len >= 0); + + const gchar *xdg_conf_dir = g_get_user_config_dir (); + snprintf (path, len, "%s/%s/%s", xdg_conf_dir, config_folder_name, config_file_name); + return; +} + +bool +config_make_dir (void) +{ + gchar config_dir[PATH_MAX] = ""; + config_build_dir (config_dir, sizeof (config_dir)); + return !g_mkdir_with_parents (config_dir, 0700); +} + +static void +config_load_handle_error (GError *error) +{ + if (!error) { + return; + } + switch (error->code) { + case G_KEY_FILE_ERROR_INVALID_VALUE: + fprintf(stderr, "load_config: invalid value: %s\n", error->message); + break; + case G_KEY_FILE_ERROR_KEY_NOT_FOUND: + case G_KEY_FILE_ERROR_GROUP_NOT_FOUND: + // new config, use default value and don't report anything + break; + default: + fprintf(stderr, "load_config: unknown error: %s\n", error->message); + } + g_error_free (error); +} + +static uint32_t +config_load_integer (GKeyFile *key_file, + const char *group_name, + const char *key, + uint32_t default_value) +{ + GError *error = NULL; + uint32_t result = g_key_file_get_integer (key_file, group_name, key, &error); + if (error != NULL) { + result = default_value; + config_load_handle_error (error); + } + return result; +} + +static bool +config_load_boolean (GKeyFile *key_file, + const char *group_name, + const char *key, + bool default_value) +{ + GError *error = NULL; + bool result = g_key_file_get_boolean (key_file, group_name, key, &error); + if (error != NULL) { + result = default_value; + config_load_handle_error (error); + } + return result; +} + +static char * +config_load_string (GKeyFile *key_file, + const char *group_name, + const char *key, + char *default_value) +{ + GError *error = NULL; + char *result = g_key_file_get_string (key_file, group_name, key, &error); + if (error != NULL) { + result = default_value; + config_load_handle_error (error); + } + return result; +} + +bool +config_load (FsearchConfig *config) +{ + g_assert (config != NULL); + + bool result = false; + GKeyFile *key_file = g_key_file_new (); + g_assert (key_file != NULL); + + gchar config_path[PATH_MAX] = ""; + config_build_path (config_path, sizeof (config_path)); + + GError *error = NULL; + if (g_key_file_load_from_file (key_file, config_path, G_KEY_FILE_NONE, &error)) { +// trace ("loaded config file\n"); + // Interface + config->restore_column_config = config_load_boolean (key_file, + "Interface", + "restore_column_configuration", + false); + config->enable_list_tooltips = config_load_boolean (key_file, + "Interface", + "enable_list_tooltips", + true); + config->enable_dark_theme = config_load_boolean (key_file, + "Interface", + "enable_dark_theme", + false); + config->show_menubar = config_load_boolean (key_file, + "Interface", + "show_menubar", + true); + config->show_statusbar = config_load_boolean (key_file, + "Interface", + "show_statusbar", + true); + config->show_filter = config_load_boolean (key_file, + "Interface", + "show_filter", + true); + config->show_search_button = config_load_boolean (key_file, + "Interface", + "show_search_button", + true); + config->show_base_2_units = config_load_boolean (key_file, + "Interface", + "show_base_2_units", + false); + config->action_after_file_open = config_load_integer(key_file, + "Interface", + "action_after_file_open", + 0); + config->action_after_file_open_keyboard = config_load_boolean (key_file, + "Interface", + "action_after_file_open_keyboard", + false); + config->action_after_file_open_mouse = config_load_boolean (key_file, + "Interface", + "action_after_file_open_mouse", + false); + + // Warning Dialogs + config->show_dialog_failed_opening = config_load_boolean(key_file, + "Dialogs", + "show_dialog_failed_opening", + true); + + // Applications + config->folder_open_cmd = config_load_string (key_file, + "Applications", + "folder_open_cmd", + NULL); + + // Window + config->restore_window_size = config_load_boolean (key_file, + "Interface", + "restore_window_size", + false); + config->window_width = config_load_integer (key_file, + "Interface", + "window_width", + 800); + config->window_height = config_load_integer (key_file, + "Interface", + "window_height", + 600); + + // Columns + config->show_listview_icons = config_load_boolean (key_file, + "Interface", + "show_listview_icons", + true); + config->show_path_column = config_load_boolean (key_file, + "Interface", + "show_path_column", + true); + config->show_type_column = config_load_boolean (key_file, + "Interface", + "show_type_column", + true); + config->show_size_column = config_load_boolean (key_file, + "Interface", + "show_size_column", + true); + config->show_modified_column = config_load_boolean (key_file, + "Interface", + "show_modified_column", + true); + + // Column Size + config->name_column_width = config_load_integer (key_file, + "Interface", + "name_column_width", + 250); + config->path_column_width = config_load_integer (key_file, + "Interface", + "path_column_width", + 250); + config->type_column_width = config_load_integer (key_file, + "Interface", + "type_column_width", + 100); + config->size_column_width = config_load_integer (key_file, + "Interface", + "size_column_width", + 75); + config->modified_column_width = config_load_integer (key_file, + "Interface", + "modified_column_width", + 75); + + // Column position + config->name_column_pos = config_load_integer (key_file, + "Interface", + "name_column_pos", + 0); + config->path_column_pos = config_load_integer (key_file, + "Interface", + "path_column_pos", + 1); + config->type_column_pos = config_load_integer (key_file, + "Interface", + "type_column_pos", + 2); + config->size_column_pos = config_load_integer (key_file, + "Interface", + "size_column_pos", + 3); + config->modified_column_pos = config_load_integer (key_file, + "Interface", + "modified_column_pos", + 4); + + // Search + config->search_as_you_type = config_load_boolean (key_file, + "Search", + "search_as_you_type", + true); + config->auto_search_in_path = config_load_boolean (key_file, + "Search", + "auto_search_in_path", + true); + config->match_case = config_load_boolean (key_file, + "Search", + "match_case", + false); + config->enable_regex = config_load_boolean (key_file, + "Search", + "enable_regex", + false); + config->search_in_path = config_load_boolean (key_file, + "Search", + "search_in_path", + false); + config->hide_results_on_empty_search = config_load_boolean (key_file, + "Search", + "hide_results_on_empty_search", + true); + config->limit_results = config_load_boolean (key_file, + "Search", + "limit_results", + false); + config->num_results = config_load_integer (key_file, + "Search", + "num_results", + 1000); + + // Database + config->update_database_on_launch = config_load_boolean (key_file, + "Database", + "update_database_on_launch", + false); + config->exclude_hidden_items = config_load_boolean (key_file, + "Database", + "exclude_hidden_files_and_folders", + false); + config->follow_symlinks = config_load_boolean (key_file, + "Database", + "follow_symbolic_links", + false); + + char *exclude_files_str = config_load_string (key_file, "Database", "exclude_files", NULL); + if (exclude_files_str) { + config->exclude_files = g_strsplit (exclude_files_str, ";", -1); + free (exclude_files_str); + exclude_files_str = NULL; + } + + // Locations + uint32_t pos = 1; + while (true) { + char key[100] = ""; + snprintf (key, sizeof (key), "location_%d", pos++); + char *value = config_load_string (key_file, "Database", key, NULL); + if (value) { + config->locations = g_list_append (config->locations, value); + } + else { + break; + } + } + // Exclude + pos = 1; + while (true) { + char key[100] = ""; + snprintf (key, sizeof (key), "exclude_location_%d", pos++); + char *value = config_load_string (key_file, "Database", key, NULL); + if (value) { + config->exclude_locations = g_list_append (config->exclude_locations, value); + } + else { + break; + } + } + + result = true; + } + else { + fprintf(stderr, "load config failed: %s\n", error->message); + g_error_free (error); + } + + g_key_file_free (key_file); + return result; +} + +bool +config_load_default (FsearchConfig *config) +{ + g_assert (config != NULL); + + // Search + config->auto_search_in_path = true; + config->search_as_you_type = true; + config->match_case = false; + config->enable_regex = false; + config->search_in_path = false; + config->hide_results_on_empty_search = true; + config->limit_results = true; + config->num_results = 1000; + + // Interface + config->enable_dark_theme = false; + config->enable_list_tooltips = true; + config->restore_column_config = false; + config->show_menubar = true; + config->show_statusbar = true; + config->show_filter = true; + config->show_search_button = true; + config->show_base_2_units = false; + config->action_after_file_open = 0; + config->action_after_file_open_keyboard = false; + config->action_after_file_open_mouse = false; + + // Columns + config->show_listview_icons = true; + config->show_path_column = true; + config->show_type_column = true; + config->show_size_column = true; + config->show_modified_column = true; + + config->name_column_pos = 0; + config->path_column_pos = 1; + config->type_column_pos = 2; + config->size_column_pos = 3; + config->modified_column_pos = 4; + + config->name_column_width = 250; + config->path_column_width = 250; + config->type_column_width = 100; + config->size_column_width = 75; + config->modified_column_width = 125; + + // Warning Dialogs + config->show_dialog_failed_opening = true; + + // Window + config->restore_window_size = false; + config->window_width = 800; + config->window_height = 600; + + // Database + config->update_database_on_launch = false; + config->exclude_hidden_items = false; + config->follow_symlinks = false; + + // Locations + config->locations = NULL; + config->exclude_locations = NULL; + + return true; +} + +bool +config_save (FsearchConfig *config) +{ + g_assert (config != NULL); + + bool result = false; + GKeyFile *key_file = g_key_file_new (); + g_assert (key_file != NULL); + + // Interface + g_key_file_set_boolean (key_file, "Interface", "restore_column_configuration", config->restore_column_config); + g_key_file_set_boolean (key_file, "Interface", "enable_list_tooltips", config->enable_list_tooltips); + g_key_file_set_boolean (key_file, "Interface", "enable_dark_theme", config->enable_dark_theme); + g_key_file_set_boolean (key_file, "Interface", "show_menubar", config->show_menubar); + g_key_file_set_boolean (key_file, "Interface", "show_statusbar", config->show_statusbar); + g_key_file_set_boolean (key_file, "Interface", "show_filter", config->show_filter); + g_key_file_set_boolean (key_file, "Interface", "show_search_button", config->show_search_button); + g_key_file_set_boolean (key_file, "Interface", "show_base_2_units", config->show_base_2_units); + g_key_file_set_integer (key_file, "Interface", "action_after_file_open", config->action_after_file_open); + g_key_file_set_boolean (key_file, "Interface", "action_after_file_open_keyboard", config->action_after_file_open_keyboard); + g_key_file_set_boolean (key_file, "Interface", "action_after_file_open_mouse", config->action_after_file_open_mouse); + + // Warning Dialogs + g_key_file_set_boolean (key_file, "Dialogs", "show_dialog_failed_opening", config->show_dialog_failed_opening); + + // Window + g_key_file_set_boolean (key_file, "Interface", "restore_window_size", config->restore_window_size); + g_key_file_set_integer (key_file, "Interface", "window_width", config->window_width); + g_key_file_set_integer (key_file, "Interface", "window_height", config->window_height); + + // Columns visibility + g_key_file_set_boolean (key_file, "Interface", "show_listview_icons", config->show_listview_icons); + g_key_file_set_boolean (key_file, "Interface", "show_path_column", config->show_path_column); + g_key_file_set_boolean (key_file, "Interface", "show_type_column", config->show_type_column); + g_key_file_set_boolean (key_file, "Interface", "show_size_column", config->show_size_column); + g_key_file_set_boolean (key_file, "Interface", "show_modified_column", config->show_modified_column); + + // Column width + g_key_file_set_integer (key_file, "Interface", "name_column_width", config->name_column_width); + g_key_file_set_integer (key_file, "Interface", "path_column_width", config->path_column_width); + g_key_file_set_integer (key_file, "Interface", "type_column_width", config->type_column_width); + g_key_file_set_integer (key_file, "Interface", "size_column_width", config->size_column_width); + g_key_file_set_integer (key_file, "Interface", "modified_column_width", config->modified_column_width); + + // Column position + g_key_file_set_integer (key_file, "Interface", "name_column_pos", config->name_column_pos); + g_key_file_set_integer (key_file, "Interface", "path_column_pos", config->path_column_pos); + g_key_file_set_integer (key_file, "Interface", "type_column_pos", config->type_column_pos); + g_key_file_set_integer (key_file, "Interface", "size_column_pos", config->size_column_pos); + g_key_file_set_integer (key_file, "Interface", "modified_column_pos", config->modified_column_pos); + + // Applications + if (config->folder_open_cmd) { + g_key_file_set_string (key_file, "Applications", "folder_open_cmd", config->folder_open_cmd); + } + + // Search + g_key_file_set_boolean (key_file, "Search", "search_as_you_type", config->search_as_you_type); + g_key_file_set_boolean (key_file, "Search", "auto_search_in_path", config->auto_search_in_path); + g_key_file_set_boolean (key_file, "Search", "search_in_path", config->search_in_path); + g_key_file_set_boolean (key_file, "Search", "enable_regex", config->enable_regex); + g_key_file_set_boolean (key_file, "Search", "match_case", config->match_case); + g_key_file_set_boolean (key_file, "Search", "hide_results_on_empty_search", config->hide_results_on_empty_search); + g_key_file_set_boolean (key_file, "Search", "limit_results", config->limit_results); + g_key_file_set_integer (key_file, "Search", "num_results", config->num_results); + + // Database + g_key_file_set_boolean (key_file, "Database", "update_database_on_launch", config->update_database_on_launch); + g_key_file_set_boolean (key_file, "Database", "exclude_hidden_files_and_folders", config->exclude_hidden_items); + g_key_file_set_boolean (key_file, "Database", "follow_symbolic_links", config->follow_symlinks); + + if (config->locations) { + uint32_t pos = 1; + for (GList *l = config->locations; l != NULL; l = l->next) { + char location[100] = ""; + snprintf (location, sizeof (location), "location_%d", pos); + g_key_file_set_string (key_file, "Database", location, l->data); + pos++; + } + } + + if (config->exclude_locations) { + uint32_t pos = 1; + for (GList *l = config->exclude_locations; l != NULL; l = l->next) { + char location[100] = ""; + snprintf (location, sizeof (location), "exclude_location_%d", pos); + g_key_file_set_string (key_file, "Database", location, l->data); + pos++; + } + } + + if (config->exclude_files) { + char *exclude_files_str = g_strjoinv (";", config->exclude_files); + g_key_file_set_string (key_file, "Database", "exclude_files", exclude_files_str); + free (exclude_files_str); + } + + gchar config_path[PATH_MAX] = ""; + config_build_path (config_path, sizeof (config_path)); + + GError *error = NULL; + if (g_key_file_save_to_file (key_file, config_path, &error)) { +// trace ("saved config file\n"); + result = true; + } + else { + fprintf(stderr, "save config failed: %s\n", error->message); + } + + g_key_file_free (key_file); + return result; +} + +void +config_free (FsearchConfig *config) +{ + g_assert (config != NULL); + + if (config->folder_open_cmd) { + free (config->folder_open_cmd); + config->folder_open_cmd = NULL; + } + if (config->locations) { + g_list_free(config->locations); +// g_list_free_full (config->locations, (GDestroyNotify)free); + config->locations = NULL; + } + if (config->exclude_locations) { + g_list_free(config->exclude_locations); +// g_list_free_full (config->exclude_locations, (GDestroyNotify)free); + config->exclude_locations = NULL; + } + if (config->exclude_files) { + g_strfreev (config->exclude_files); + config->exclude_files = NULL; + } + free (config); + config = NULL; +} + diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_config.h b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_config.h new file mode 100644 index 0000000..36a486d --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_config.h @@ -0,0 +1,111 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#pragma once + +#include +#include +#include + +typedef struct _FsearchConfig FsearchConfig; + +struct _FsearchConfig { + // Search + bool limit_results; + bool hide_results_on_empty_search; + bool search_in_path; + bool enable_regex; + bool match_case; + bool auto_search_in_path; + bool search_as_you_type; + bool show_base_2_units; + + // Applications + char *folder_open_cmd; + + // Window + bool restore_window_size; + int32_t window_width; + int32_t window_height; + + // Interface + bool enable_dark_theme; + bool enable_list_tooltips; + bool restore_column_config; + uint32_t action_after_file_open; + bool action_after_file_open_keyboard; + bool action_after_file_open_mouse; + + // Warning Dialogs + bool show_dialog_failed_opening; + + // View menu + bool show_menubar; + bool show_statusbar; + bool show_filter; + bool show_search_button; + + // Columns + bool show_listview_icons; + bool show_path_column; + bool show_type_column; + bool show_size_column; + bool show_modified_column; + + uint32_t name_column_width; + uint32_t path_column_width; + uint32_t type_column_width; + uint32_t size_column_width; + uint32_t modified_column_width; + + uint32_t name_column_pos; + uint32_t path_column_pos; + uint32_t type_column_pos; + uint32_t size_column_pos; + uint32_t modified_column_pos; + + // database + bool update_database_on_launch; + bool exclude_hidden_items; + bool follow_symlinks; + + uint32_t num_results; + + GList *locations; + GList *exclude_locations; + char **exclude_files; +}; + + +bool +config_make_dir(void); + +bool +config_load(FsearchConfig *config); + +bool +config_load_default(FsearchConfig *config); + +bool +config_save(FsearchConfig *config); + +void +config_build_dir(char *path, size_t len); + +void +config_free(FsearchConfig *config); diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_limits.h b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_limits.h new file mode 100644 index 0000000..309e9f9 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_limits.h @@ -0,0 +1,26 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#pragma once + +#include + +#ifndef PATH_MAX +#define PATH_MAX 4096 /* max # of characters in a path name */ +#endif + diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_thread_pool.c b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_thread_pool.c new file mode 100644 index 0000000..9698f09 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_thread_pool.c @@ -0,0 +1,266 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#include + +#include "fsearch_thread_pool.h" +#include +struct _FsearchThreadPool { + GList *threads; + uint32_t num_threads; +}; + +typedef struct thread_context_s { + GThread *thread; + gpointer (*thread_func)(gpointer thread_data); + + gpointer *thread_data; + + GMutex mutex; + GCond start_cond; + GCond finished_cond; + bool thread_waited; + FsearchThreadStatus status; + bool terminate; +} thread_context_t; + +static bool +thread_pool_has_thread (FsearchThreadPool *pool, GList *thread) +{ + GList *temp = pool->threads; + while (temp) { + if (temp == thread) { + return true; + } + temp = temp->next; + } + return false; +} + +static gpointer +fsearch_thread_pool_thread (gpointer user_data) +{ + thread_context_t *ctx = user_data; + + g_mutex_lock (&ctx->mutex); + while (!ctx->terminate) { + // 线程已开启 + ctx->thread_waited = true; + g_cond_wait (&ctx->start_cond, &ctx->mutex); + ctx->status = THREAD_BUSY; + if (ctx->thread_data) { + ctx->thread_func (ctx->thread_data); + ctx->status = THREAD_FINISHED; + ctx->thread_data = NULL; + g_cond_signal (&ctx->finished_cond); + } + ctx->status = THREAD_IDLE; + } + g_mutex_unlock (&ctx->mutex); + return NULL; +} + +static void +thread_context_free (thread_context_t *ctx) +{ + if (!ctx) { + return; + } + + g_mutex_lock (&ctx->mutex); + if (ctx->thread_data) { +// trace ("search data still there\n"); + } + + // terminate thread + ctx->terminate = true; + g_cond_signal (&ctx->start_cond); + g_mutex_unlock (&ctx->mutex); + g_thread_join (ctx->thread); + + g_mutex_clear (&ctx->mutex); + g_cond_clear (&ctx->start_cond); + g_cond_clear (&ctx->finished_cond); + g_free (ctx); + ctx = NULL; +} + +static thread_context_t * +thread_context_new (void) +{ + thread_context_t *ctx = g_new0 (thread_context_t, 1); + if (!ctx) { + return NULL; + } + ctx->thread_data = NULL; + ctx->thread_func = NULL; + ctx->terminate = false; + ctx->status = THREAD_IDLE; + g_mutex_init (&ctx->mutex); + g_cond_init (&ctx->start_cond); + g_cond_init (&ctx->finished_cond); + ctx->thread_waited = false; + + ctx->thread = g_thread_new("thread pool", fsearch_thread_pool_thread, ctx); + return ctx; +} + +FsearchThreadPool * +fsearch_thread_pool_init (void) +{ + FsearchThreadPool *pool = g_new0 (FsearchThreadPool, 1); + pool->threads = NULL; + pool->num_threads = 0; + + uint32_t num_cpus = g_get_num_processors (); + for (uint32_t i = 0; i < num_cpus; i++) { + thread_context_t *ctx = thread_context_new (); + if (ctx) { + pool->threads = g_list_prepend (pool->threads, ctx); + pool->num_threads++; + + // 等待线程开启 + while (!ctx->thread_waited) { + usleep(100); + } + } + } + + return pool; +} + +void +fsearch_thread_pool_free (FsearchThreadPool *pool) +{ + if (!pool) { + return; + } + GList *thread = pool->threads; + for (uint32_t i = 0; thread && i < pool->num_threads; i++) { + thread_context_t *ctx = thread->data; + thread_context_free (ctx); + thread = thread->next; + } + pool->num_threads = 0; + g_free (pool); + pool = NULL; +} + +GList * +fsearch_thread_pool_get_threads (FsearchThreadPool *pool) +{ + if (!pool) { + return NULL; + } + return pool->threads; +} + +gpointer +fsearch_thread_pool_get_data (FsearchThreadPool *pool, GList *thread) +{ + if (!pool || !thread) { + return NULL; + } + if (!thread_pool_has_thread (pool, thread)) { + return NULL; + } + thread_context_t *ctx = thread->data; + if (!ctx) { + return NULL; + } + return ctx->thread_data; +} + +bool +fsearch_thread_pool_task_is_idle (FsearchThreadPool *pool, GList *thread) +{ + bool res = false; + if (!thread_pool_has_thread (pool, thread)) { + return res; + } + thread_context_t *ctx = thread->data; + if (!ctx) { + return res; + } + + res = ctx->status == THREAD_IDLE ? true : false; + + return res; +} + +bool +fsearch_thread_pool_task_is_busy (FsearchThreadPool *pool, GList *thread) +{ + bool res = false; + if (!thread_pool_has_thread (pool, thread)) { + return res; + } + thread_context_t *ctx = thread->data; + if (!ctx) { + return res; + } + + res = ctx->status == THREAD_BUSY ? true : false; + + return res; +} + +bool +fsearch_thread_pool_wait_for_thread (FsearchThreadPool *pool, GList *thread) +{ + thread_context_t *ctx = thread->data; + g_mutex_lock (&ctx->mutex); + while (fsearch_thread_pool_task_is_busy (pool, thread)) { + g_cond_wait (&ctx->finished_cond, &ctx->mutex); + } + g_mutex_unlock (&ctx->mutex); + return true; +} + +uint32_t +fsearch_thread_pool_get_num_threads (FsearchThreadPool *pool) +{ + if (!pool) { + return 0; + } + return pool->num_threads; +} + +bool +fsearch_thread_pool_push_data (FsearchThreadPool *pool, + GList *thread, + ThreadFunc thread_func, + gpointer thread_data) +{ + if (!pool || !thread || !thread_func || !thread_data) { + return false; + } + if (!thread_pool_has_thread (pool, thread)) { + return false; + } + thread_context_t *ctx = thread->data; + g_mutex_lock (&ctx->mutex); + ctx->thread_func = thread_func; + ctx->thread_data = thread_data; + ctx->status = THREAD_BUSY; + + g_cond_signal (&ctx->start_cond); + g_mutex_unlock (&ctx->mutex); + return true; +} + diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_thread_pool.h b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_thread_pool.h new file mode 100644 index 0000000..12532a3 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/fsearch_thread_pool.h @@ -0,0 +1,65 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#pragma once + +#include +#include +#include + +typedef struct _FsearchThreadPool FsearchThreadPool; +typedef GThreadFunc ThreadFunc; + +typedef enum { + THREAD_IDLE, + THREAD_BUSY, + THREAD_FINISHED +} FsearchThreadStatus; + +FsearchThreadPool * +fsearch_thread_pool_init(void); + +void +fsearch_thread_pool_free(FsearchThreadPool *pool); + +GList * +fsearch_thread_pool_get_threads(FsearchThreadPool *pool); + +uint32_t +fsearch_thread_pool_get_num_threads(FsearchThreadPool *pool); + +bool +fsearch_thread_pool_push_data(FsearchThreadPool *pool, + GList *thread, + ThreadFunc thread_func, + gpointer thread_data); + +bool +fsearch_thread_pool_wait_for_thread(FsearchThreadPool *pool, GList *thread); + +bool +fsearch_thread_pool_task_is_busy(FsearchThreadPool *pool, GList *thread); + +bool +fsearch_thread_pool_task_is_idle(FsearchThreadPool *pool, GList *thread); + +gpointer +fsearch_thread_pool_get_data(FsearchThreadPool *pool, GList *thread); + +bool +fsearch_thread_pool_set_task_finished(FsearchThreadPool *pool, GList *thread); diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/query.c b/dde-file-manager-5.5.3/3rdparty/fsearch/query.c new file mode 100644 index 0000000..8a4c4a5 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/query.c @@ -0,0 +1,60 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#define _GNU_SOURCE +#include +#include +#include +#include "query.h" + +FsearchQuery * +fsearch_query_new (const char *query, + void (*callback)(void *, void *), + void *callback_data, + void *sender, + bool match_case, + bool enable_regex, + bool auto_search_in_path, + bool search_in_path) +{ + FsearchQuery *q = calloc (1, sizeof (FsearchQuery)); + assert (q != NULL); + if (query) { + q->query = strdup (query); + } + q->callback = callback; + q->callback_data = callback_data; + q->sender = sender; + q->match_case = match_case; + q->enable_regex = enable_regex; + q->auto_search_in_path = auto_search_in_path; + q->search_in_path = search_in_path; + return q; +} + +void +fsearch_query_free (FsearchQuery *query) +{ + assert (query != NULL); + if (query->query) { + free (query->query); + query->query = NULL; + } + free (query); + query = NULL; +} diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/query.h b/dde-file-manager-5.5.3/3rdparty/fsearch/query.h new file mode 100644 index 0000000..8f17579 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/query.h @@ -0,0 +1,46 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#pragma once + +#include + +typedef struct { + char *query; + bool match_case; + bool enable_regex; + bool auto_search_in_path; + bool search_in_path; + + void (*callback)(void *, void *); + void *callback_data; + void *sender; +} FsearchQuery; + +FsearchQuery * +fsearch_query_new(const char *query, + void (*callback)(void *, void *), + void *callback_data, + void *sender, + bool match_case, + bool enable_regex, + bool auto_search_in_path, + bool search_in_path); + +void +fsearch_query_free(FsearchQuery *query); diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/string_utils.c b/dde-file-manager-5.5.3/3rdparty/fsearch/string_utils.c new file mode 100644 index 0000000..05b452f --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/string_utils.c @@ -0,0 +1,64 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#include +#include +#include +#include +#include "string_utils.h" + +bool +fs_str_is_empty (const char *str) +{ + // query is considered empty if: + // - fist character is null terminator + // - or it has only space characters + while (*str != '\0') { + if (!isspace (*str)) { + return false; + } + str++; + } + return true; +} + +bool +fs_str_has_upper (const char *strc) +{ + assert (strc != NULL); + const char *ptr = strc; + while (*ptr != '\0') { + if (isupper (*ptr)) { + return true; + } + ptr++; + } + return false; +} + +char * +fs_str_copy (char *dest, char *end, const char *src) +{ + char *ptr = dest; + while (ptr != end && *src != '\0') { + *ptr++ = *src++; + } + *ptr = '\0'; + return ptr; +} + diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/string_utils.h b/dde-file-manager-5.5.3/3rdparty/fsearch/string_utils.h new file mode 100644 index 0000000..9b33592 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/string_utils.h @@ -0,0 +1,32 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + 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 2 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 . + */ + +#pragma once +#include +#include + +bool +fs_str_is_empty(const char *str); + +bool +fs_str_has_upper(const char *str); + +char * +fs_str_copy(char *dest, + char *end, + const char *src); diff --git a/dde-file-manager-5.5.3/3rdparty/fsearch/utf8.h b/dde-file-manager-5.5.3/3rdparty/fsearch/utf8.h new file mode 100644 index 0000000..e47ef42 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/fsearch/utf8.h @@ -0,0 +1,1285 @@ +// The latest version of this library is available on GitHub; +// https://github.com/sheredom/utf8.h + +// This is free and unencumbered software released into the public domain. +// +// Anyone is free to copy, modify, publish, use, compile, sell, or +// distribute this software, either in source code form or as a compiled +// binary, for any purpose, commercial or non-commercial, and by any +// means. +// +// In jurisdictions that recognize copyright laws, the author or authors +// of this software dedicate any and all copyright interest in the +// software to the public domain. We make this dedication for the benefit +// of the public at large and to the detriment of our heirs and +// successors. We intend this dedication to be an overt act of +// relinquishment in perpetuity of all present and future rights to this +// software under copyright law. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// For more information, please refer to + +#ifndef SHEREDOM_UTF8_H_INCLUDED +#define SHEREDOM_UTF8_H_INCLUDED + +#if defined(_MSC_VER) +#pragma warning(push) + +// disable 'bytes padding added after construct' warning +#pragma warning(disable : 4820) +#endif + +#include +#include + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#if defined(_MSC_VER) +typedef __int32 utf8_int32_t; +#else +#include +typedef int32_t utf8_int32_t; +#endif + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wold-style-cast" +#pragma clang diagnostic ignored "-Wcast-qual" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__clang__) || defined(__GNUC__) +#define utf8_nonnull __attribute__((nonnull)) +#define utf8_pure __attribute__((pure)) +#define utf8_restrict __restrict__ +#define utf8_weak __attribute__((weak)) +#elif defined(_MSC_VER) +#define utf8_nonnull +#define utf8_pure +#define utf8_restrict __restrict +#define utf8_weak __inline +#else +#error Non clang, non gcc, non MSVC compiler found! +#endif + +#ifdef __cplusplus +#define utf8_null NULL +#else +#define utf8_null 0 +#endif + +// Return less than 0, 0, greater than 0 if src1 < src2, src1 == src2, src1 > +// src2 respectively, case insensitive. +utf8_nonnull utf8_pure utf8_weak int utf8casecmp(const void *src1, + const void *src2); + +// Append the utf8 string src onto the utf8 string dst. +utf8_nonnull utf8_weak void *utf8cat(void *utf8_restrict dst, + const void *utf8_restrict src); + +// Find the first match of the utf8 codepoint chr in the utf8 string src. +utf8_nonnull utf8_pure utf8_weak void *utf8chr(const void *src, + utf8_int32_t chr); + +// Return less than 0, 0, greater than 0 if src1 < src2, +// src1 == src2, src1 > src2 respectively. +utf8_nonnull utf8_pure utf8_weak int utf8cmp(const void *src1, + const void *src2); + +// Copy the utf8 string src onto the memory allocated in dst. +utf8_nonnull utf8_weak void *utf8cpy(void *utf8_restrict dst, + const void *utf8_restrict src); + +// Number of utf8 codepoints in the utf8 string src that consists entirely +// of utf8 codepoints not from the utf8 string reject. +utf8_nonnull utf8_pure utf8_weak size_t utf8cspn(const void *src, + const void *reject); + +// Duplicate the utf8 string src by getting its size, malloc'ing a new buffer +// copying over the data, and returning that. Or 0 if malloc failed. +utf8_nonnull utf8_weak void *utf8dup(const void *src); + +// Number of utf8 codepoints in the utf8 string str, +// excluding the null terminating byte. +utf8_nonnull utf8_pure utf8_weak size_t utf8len(const void *str); + +// Return less than 0, 0, greater than 0 if src1 < src2, src1 == src2, src1 > +// src2 respectively, case insensitive. Checking at most n bytes of each utf8 +// string. +utf8_nonnull utf8_pure utf8_weak int utf8ncasecmp(const void *src1, + const void *src2, size_t n); + +// Append the utf8 string src onto the utf8 string dst, +// writing at most n+1 bytes. Can produce an invalid utf8 +// string if n falls partway through a utf8 codepoint. +utf8_nonnull utf8_weak void *utf8ncat(void *utf8_restrict dst, + const void *utf8_restrict src, size_t n); + +// Return less than 0, 0, greater than 0 if src1 < src2, +// src1 == src2, src1 > src2 respectively. Checking at most n +// bytes of each utf8 string. +utf8_nonnull utf8_pure utf8_weak int utf8ncmp(const void *src1, + const void *src2, size_t n); + +// Copy the utf8 string src onto the memory allocated in dst. +// Copies at most n bytes. If there is no terminating null byte in +// the first n bytes of src, the string placed into dst will not be +// null-terminated. If the size (in bytes) of src is less than n, +// extra null terminating bytes are appended to dst such that at +// total of n bytes are written. Can produce an invalid utf8 +// string if n falls partway through a utf8 codepoint. +utf8_nonnull utf8_weak void *utf8ncpy(void *utf8_restrict dst, + const void *utf8_restrict src, size_t n); + +// Similar to utf8dup, except that at most n bytes of src are copied. If src is +// longer than n, only n bytes are copied and a null byte is added. +// +// Returns a new string if successful, 0 otherwise +utf8_nonnull utf8_weak void *utf8ndup(const void *src, size_t n); + +// Locates the first occurence in the utf8 string str of any byte in the +// utf8 string accept, or 0 if no match was found. +utf8_nonnull utf8_pure utf8_weak void *utf8pbrk(const void *str, + const void *accept); + +// Find the last match of the utf8 codepoint chr in the utf8 string src. +utf8_nonnull utf8_pure utf8_weak void *utf8rchr(const void *src, int chr); + +// Number of bytes in the utf8 string str, +// including the null terminating byte. +utf8_nonnull utf8_pure utf8_weak size_t utf8size(const void *str); + +// Number of utf8 codepoints in the utf8 string src that consists entirely +// of utf8 codepoints from the utf8 string accept. +utf8_nonnull utf8_pure utf8_weak size_t utf8spn(const void *src, + const void *accept); + +// The position of the utf8 string needle in the utf8 string haystack. +utf8_nonnull utf8_pure utf8_weak void *utf8str(const void *haystack, + const void *needle); + +// The position of the utf8 string needle in the utf8 string haystack, case +// insensitive. +utf8_nonnull utf8_pure utf8_weak void *utf8casestr(const void *haystack, + const void *needle); + +// Return 0 on success, or the position of the invalid +// utf8 codepoint on failure. +utf8_nonnull utf8_pure utf8_weak void *utf8valid(const void *str); + +// Sets out_codepoint to the next utf8 codepoint in str, and returns the address +// of the utf8 codepoint after the current one in str. +utf8_nonnull utf8_weak void * +utf8codepoint(const void *utf8_restrict str, + utf8_int32_t *utf8_restrict out_codepoint); + +// Returns the size of the given codepoint in bytes. +utf8_weak size_t utf8codepointsize(utf8_int32_t chr); + +// Write a codepoint to the given string, and return the address to the next +// place after the written codepoint. Pass how many bytes left in the buffer to +// n. If there is not enough space for the codepoint, this function returns +// null. +utf8_nonnull utf8_weak void *utf8catcodepoint(void *utf8_restrict str, + utf8_int32_t chr, size_t n); + +// Returns 1 if the given character is lowercase, or 0 if it is not. +utf8_weak int utf8islower(utf8_int32_t chr); + +// Returns 1 if the given character is uppercase, or 0 if it is not. +utf8_weak int utf8isupper(utf8_int32_t chr); + +// Transform the given string into all lowercase codepoints. +utf8_nonnull utf8_weak void utf8lwr(void *utf8_restrict str); + +// Transform the given string into all uppercase codepoints. +utf8_nonnull utf8_weak void utf8upr(void *utf8_restrict str); + +// Make a codepoint lower case if possible. +utf8_weak utf8_int32_t utf8lwrcodepoint(utf8_int32_t cp); + +// Make a codepoint upper case if possible. +utf8_weak utf8_int32_t utf8uprcodepoint(utf8_int32_t cp); + +#undef utf8_weak +#undef utf8_pure +#undef utf8_nonnull + +int utf8casecmp(const void *src1, const void *src2) +{ + utf8_int32_t src1_cp, src2_cp, src1_orig_cp, src2_orig_cp; + + for (;;) { + src1 = utf8codepoint(src1, &src1_cp); + src2 = utf8codepoint(src2, &src2_cp); + + // take a copy of src1 & src2 + src1_orig_cp = src1_cp; + src2_orig_cp = src2_cp; + + // lower the srcs if required + src1_cp = utf8lwrcodepoint(src1_cp); + src2_cp = utf8lwrcodepoint(src2_cp); + + // check if the lowered codepoints match + if ((0 == src1_orig_cp) && (0 == src2_orig_cp)) { + return 0; + } else if (src1_cp == src2_cp) { + continue; + } + + // if they don't match, then we return the difference between the characters + return src1_cp - src2_cp; + } +} + +void *utf8cat(void *utf8_restrict dst, const void *utf8_restrict src) +{ + char *d = (char *)dst; + const char *s = (const char *)src; + + // find the null terminating byte in dst + while ('\0' != *d) { + d++; + } + + // overwriting the null terminating byte in dst, append src byte-by-byte + while ('\0' != *s) { + *d++ = *s++; + } + + // write out a new null terminating byte into dst + *d = '\0'; + + return dst; +} + +void *utf8chr(const void *src, utf8_int32_t chr) +{ + char c[5] = {'\0', '\0', '\0', '\0', '\0'}; + + if (0 == chr) { + // being asked to return position of null terminating byte, so + // just run s to the end, and return! + const char *s = (const char *)src; + while ('\0' != *s) { + s++; + } + return (void *)s; + } else if (0 == ((utf8_int32_t)0xffffff80 & chr)) { + // 1-byte/7-bit ascii + // (0b0xxxxxxx) + c[0] = (char)chr; + } else if (0 == ((utf8_int32_t)0xfffff800 & chr)) { + // 2-byte/11-bit utf8 code point + // (0b110xxxxx 0b10xxxxxx) + c[0] = 0xc0 | (char)(chr >> 6); + c[1] = 0x80 | (char)(chr & 0x3f); + } else if (0 == ((utf8_int32_t)0xffff0000 & chr)) { + // 3-byte/16-bit utf8 code point + // (0b1110xxxx 0b10xxxxxx 0b10xxxxxx) + c[0] = 0xe0 | (char)(chr >> 12); + c[1] = 0x80 | (char)((chr >> 6) & 0x3f); + c[2] = 0x80 | (char)(chr & 0x3f); + } else { // if (0 == ((int)0xffe00000 & chr)) { + // 4-byte/21-bit utf8 code point + // (0b11110xxx 0b10xxxxxx 0b10xxxxxx 0b10xxxxxx) + c[0] = 0xf0 | (char)(chr >> 18); + c[1] = 0x80 | (char)((chr >> 12) & 0x3f); + c[2] = 0x80 | (char)((chr >> 6) & 0x3f); + c[3] = 0x80 | (char)(chr & 0x3f); + } + + // we've made c into a 2 utf8 codepoint string, one for the chr we are + // seeking, another for the null terminating byte. Now use utf8str to + // search + return utf8str(src, c); +} + +int utf8cmp(const void *src1, const void *src2) +{ + const unsigned char *s1 = (const unsigned char *)src1; + const unsigned char *s2 = (const unsigned char *)src2; + + while (('\0' != *s1) || ('\0' != *s2)) { + if (*s1 < *s2) { + return -1; + } else if (*s1 > *s2) { + return 1; + } + + s1++; + s2++; + } + + // both utf8 strings matched + return 0; +} + +int utf8coll(const void *src1, const void *src2); + +void *utf8cpy(void *utf8_restrict dst, const void *utf8_restrict src) +{ + char *d = (char *)dst; + const char *s = (const char *)src; + + // overwriting anything previously in dst, write byte-by-byte + // from src + while ('\0' != *s) { + *d++ = *s++; + } + + // append null terminating byte + *d = '\0'; + + return dst; +} + +size_t utf8cspn(const void *src, const void *reject) +{ + const char *s = (const char *)src; + size_t chars = 0; + + while ('\0' != *s) { + const char *r = (const char *)reject; + size_t offset = 0; + + while ('\0' != *r) { + // checking that if *r is the start of a utf8 codepoint + // (it is not 0b10xxxxxx) and we have successfully matched + // a previous character (0 < offset) - we found a match + if ((0x80 != (0xc0 & *r)) && (0 < offset)) { + return chars; + } else { + if (*r == s[offset]) { + // part of a utf8 codepoint matched, so move our checking + // onwards to the next byte + offset++; + r++; + } else { + // r could be in the middle of an unmatching utf8 code point, + // so we need to march it on to the next character beginning, + + do { + r++; + } while (0x80 == (0xc0 & *r)); + + // reset offset too as we found a mismatch + offset = 0; + } + } + } + + // the current utf8 codepoint in src did not match reject, but src + // could have been partway through a utf8 codepoint, so we need to + // march it onto the next utf8 codepoint starting byte + do { + s++; + } while ((0x80 == (0xc0 & *s))); + chars++; + } + + return chars; +} + +size_t utf8size(const void *str); + +void *utf8dup(const void *src) +{ + const char *s = (const char *)src; + char *n = utf8_null; + + // figure out how many bytes (including the terminator) we need to copy first + size_t bytes = utf8size(src); + + n = (char *)malloc(bytes); + + if (utf8_null == n) { + // out of memory so we bail + return utf8_null; + } else { + bytes = 0; + + // copy src byte-by-byte into our new utf8 string + while ('\0' != s[bytes]) { + n[bytes] = s[bytes]; + bytes++; + } + + // append null terminating byte + n[bytes] = '\0'; + return n; + } +} + +void *utf8fry(const void *str); + +size_t utf8len(const void *str) +{ + const unsigned char *s = (const unsigned char *)str; + size_t length = 0; + + while ('\0' != *s) { + if (0xf0 == (0xf8 & *s)) { + // 4-byte utf8 code point (began with 0b11110xxx) + s += 4; + } else if (0xe0 == (0xf0 & *s)) { + // 3-byte utf8 code point (began with 0b1110xxxx) + s += 3; + } else if (0xc0 == (0xe0 & *s)) { + // 2-byte utf8 code point (began with 0b110xxxxx) + s += 2; + } else { // if (0x00 == (0x80 & *s)) { + // 1-byte ascii (began with 0b0xxxxxxx) + s += 1; + } + + // no matter the bytes we marched s forward by, it was + // only 1 utf8 codepoint + length++; + } + + return length; +} + +int utf8ncasecmp(const void *src1, const void *src2, size_t n) +{ + utf8_int32_t src1_cp, src2_cp, src1_orig_cp, src2_orig_cp; + + do { + const unsigned char *const s1 = (const unsigned char *)src1; + const unsigned char *const s2 = (const unsigned char *)src2; + + // first check that we have enough bytes left in n to contain an entire + // codepoint + if (0 == n) { + return 0; + } + + if ((1 == n) && ((0xc0 == (0xe0 & *s1)) || (0xc0 == (0xe0 & *s2)))) { + const utf8_int32_t c1 = (0xe0 & *s1); + const utf8_int32_t c2 = (0xe0 & *s2); + + if (c1 < c2) { + return -1; + } else if (c1 > c2) { + return 1; + } else { + return 0; + } + } + + if ((2 >= n) && ((0xe0 == (0xf0 & *s1)) || (0xe0 == (0xf0 & *s2)))) { + const utf8_int32_t c1 = (0xf0 & *s1); + const utf8_int32_t c2 = (0xf0 & *s2); + + if (c1 < c2) { + return -1; + } else if (c1 > c2) { + return 1; + } else { + return 0; + } + } + + if ((3 >= n) && ((0xf0 == (0xf8 & *s1)) || (0xf0 == (0xf8 & *s2)))) { + const utf8_int32_t c1 = (0xf8 & *s1); + const utf8_int32_t c2 = (0xf8 & *s2); + + if (c1 < c2) { + return -1; + } else if (c1 > c2) { + return 1; + } else { + return 0; + } + } + + src1 = utf8codepoint(src1, &src1_cp); + src2 = utf8codepoint(src2, &src2_cp); + n -= utf8codepointsize(src1_cp); + + // Take a copy of src1 & src2 + src1_orig_cp = src1_cp; + src2_orig_cp = src2_cp; + + // Lower srcs if required + src1_cp = utf8lwrcodepoint(src1_cp); + src2_cp = utf8lwrcodepoint(src2_cp); + + // Check if the lowered codepoints match + if ((0 == src1_orig_cp) && (0 == src2_orig_cp)) { + return 0; + } else if (src1_cp == src2_cp) { + continue; + } + + // If they don't match, then we return which of the original's are less + if (src1_orig_cp < src2_orig_cp) { + return -1; + } else if (src1_orig_cp > src2_orig_cp) { + return 1; + } + } while (0 < n); + + // both utf8 strings matched + return 0; +} + +void *utf8ncat(void *utf8_restrict dst, const void *utf8_restrict src, + size_t n) +{ + char *d = (char *)dst; + const char *s = (const char *)src; + + // find the null terminating byte in dst + while ('\0' != *d) { + d++; + } + + // overwriting the null terminating byte in dst, append src byte-by-byte + // stopping if we run out of space + do { + *d++ = *s++; + } while (('\0' != *s) && (0 != --n)); + + // write out a new null terminating byte into dst + *d = '\0'; + + return dst; +} + +int utf8ncmp(const void *src1, const void *src2, size_t n) +{ + const unsigned char *s1 = (const unsigned char *)src1; + const unsigned char *s2 = (const unsigned char *)src2; + + while ((0 != n--) && (('\0' != *s1) || ('\0' != *s2))) { + if (*s1 < *s2) { + return -1; + } else if (*s1 > *s2) { + return 1; + } + + s1++; + s2++; + } + + // both utf8 strings matched + return 0; +} + +void *utf8ncpy(void *utf8_restrict dst, const void *utf8_restrict src, + size_t n) +{ + char *d = (char *)dst; + const char *s = (const char *)src; + size_t index; + + // overwriting anything previously in dst, write byte-by-byte + // from src + for (index = 0; index < n; index++) { + d[index] = s[index]; + if ('\0' == s[index]) { + break; + } + } + + // append null terminating byte + for (; index < n; index++) { + d[index] = 0; + } + + return dst; +} + +void *utf8ndup(const void *src, size_t n) +{ + const char *s = (const char *)src; + char *c = utf8_null; + size_t bytes = 0; + + // Find the end of the string or stop when n is reached + while ('\0' != s[bytes] && bytes < n) { + bytes++; + } + + // In case bytes is actually less than n, we need to set it + // to be used later in the copy byte by byte. + n = bytes; + + c = (char *)malloc(bytes + 1); + if (utf8_null == c) { + // out of memory so we bail + return utf8_null; + } + + bytes = 0; + + // copy src byte-by-byte into our new utf8 string + while ('\0' != s[bytes] && bytes < n) { + c[bytes] = s[bytes]; + bytes++; + } + + // append null terminating byte + c[bytes] = '\0'; + return c; +} + +void *utf8rchr(const void *src, int chr) +{ + const char *s = (const char *)src; + const char *match = utf8_null; + char c[5] = {'\0', '\0', '\0', '\0', '\0'}; + + if (0 == chr) { + // being asked to return position of null terminating byte, so + // just run s to the end, and return! + while ('\0' != *s) { + s++; + } + return (void *)s; + } else if (0 == ((int)0xffffff80 & chr)) { + // 1-byte/7-bit ascii + // (0b0xxxxxxx) + c[0] = (char)chr; + } else if (0 == ((int)0xfffff800 & chr)) { + // 2-byte/11-bit utf8 code point + // (0b110xxxxx 0b10xxxxxx) + c[0] = 0xc0 | (char)(chr >> 6); + c[1] = 0x80 | (char)(chr & 0x3f); + } else if (0 == ((int)0xffff0000 & chr)) { + // 3-byte/16-bit utf8 code point + // (0b1110xxxx 0b10xxxxxx 0b10xxxxxx) + c[0] = 0xe0 | (char)(chr >> 12); + c[1] = 0x80 | (char)((chr >> 6) & 0x3f); + c[2] = 0x80 | (char)(chr & 0x3f); + } else { // if (0 == ((int)0xffe00000 & chr)) { + // 4-byte/21-bit utf8 code point + // (0b11110xxx 0b10xxxxxx 0b10xxxxxx 0b10xxxxxx) + c[0] = 0xf0 | (char)(chr >> 18); + c[1] = 0x80 | (char)((chr >> 12) & 0x3f); + c[2] = 0x80 | (char)((chr >> 6) & 0x3f); + c[3] = 0x80 | (char)(chr & 0x3f); + } + + // we've created a 2 utf8 codepoint string in c that is + // the utf8 character asked for by chr, and a null + // terminating byte + + while ('\0' != *s) { + size_t offset = 0; + + while (s[offset] == c[offset]) { + offset++; + } + + if ('\0' == c[offset]) { + // we found a matching utf8 code point + match = s; + s += offset; + } else { + s += offset; + + // need to march s along to next utf8 codepoint start + // (the next byte that doesn't match 0b10xxxxxx) + if ('\0' != *s) { + do { + s++; + } while (0x80 == (0xc0 & *s)); + } + } + } + + // return the last match we found (or 0 if no match was found) + return (void *)match; +} + +void *utf8pbrk(const void *str, const void *accept) +{ + const char *s = (const char *)str; + + while ('\0' != *s) { + const char *a = (const char *)accept; + size_t offset = 0; + + while ('\0' != *a) { + // checking that if *a is the start of a utf8 codepoint + // (it is not 0b10xxxxxx) and we have successfully matched + // a previous character (0 < offset) - we found a match + if ((0x80 != (0xc0 & *a)) && (0 < offset)) { + return (void *)s; + } else { + if (*a == s[offset]) { + // part of a utf8 codepoint matched, so move our checking + // onwards to the next byte + offset++; + a++; + } else { + // r could be in the middle of an unmatching utf8 code point, + // so we need to march it on to the next character beginning, + + do { + a++; + } while (0x80 == (0xc0 & *a)); + + // reset offset too as we found a mismatch + offset = 0; + } + } + } + + // we found a match on the last utf8 codepoint + if (0 < offset) { + return (void *)s; + } + + // the current utf8 codepoint in src did not match accept, but src + // could have been partway through a utf8 codepoint, so we need to + // march it onto the next utf8 codepoint starting byte + do { + s++; + } while ((0x80 == (0xc0 & *s))); + } + + return utf8_null; +} + +size_t utf8size(const void *str) +{ + const char *s = (const char *)str; + size_t size = 0; + while ('\0' != s[size]) { + size++; + } + + // we are including the null terminating byte in the size calculation + size++; + return size; +} + +size_t utf8spn(const void *src, const void *accept) +{ + const char *s = (const char *)src; + size_t chars = 0; + + while ('\0' != *s) { + const char *a = (const char *)accept; + size_t offset = 0; + + while ('\0' != *a) { + // checking that if *r is the start of a utf8 codepoint + // (it is not 0b10xxxxxx) and we have successfully matched + // a previous character (0 < offset) - we found a match + if ((0x80 != (0xc0 & *a)) && (0 < offset)) { + // found a match, so increment the number of utf8 codepoints + // that have matched and stop checking whether any other utf8 + // codepoints in a match + chars++; + s += offset; + break; + } else { + if (*a == s[offset]) { + offset++; + a++; + } else { + // a could be in the middle of an unmatching utf8 codepoint, + // so we need to march it on to the next character beginning, + do { + a++; + } while (0x80 == (0xc0 & *a)); + + // reset offset too as we found a mismatch + offset = 0; + } + } + } + + // if a got to its terminating null byte, then we didn't find a match. + // Return the current number of matched utf8 codepoints + if ('\0' == *a) { + return chars; + } + } + + return chars; +} + +void *utf8str(const void *haystack, const void *needle) +{ + const char *h = (const char *)haystack; + utf8_int32_t throwaway_codepoint; + + // if needle has no utf8 codepoints before the null terminating + // byte then return haystack + if ('\0' == *((const char *)needle)) { + return (void *)haystack; + } + + while ('\0' != *h) { + const char *maybeMatch = h; + const char *n = (const char *)needle; + + while (*h == *n && (*h != '\0' && *n != '\0')) { + n++; + h++; + } + + if ('\0' == *n) { + // we found the whole utf8 string for needle in haystack at + // maybeMatch, so return it + return (void *)maybeMatch; + } else { + // h could be in the middle of an unmatching utf8 codepoint, + // so we need to march it on to the next character beginning + // starting from the current character + h = (const char *)utf8codepoint(maybeMatch, &throwaway_codepoint); + } + } + + // no match + return utf8_null; +} + +void *utf8casestr(const void *haystack, const void *needle) +{ + const void *h = haystack; + + // if needle has no utf8 codepoints before the null terminating + // byte then return haystack + if ('\0' == *((const char *)needle)) { + return (void *)haystack; + } + + for (;;) { + const void *maybeMatch = h; + const void *n = needle; + utf8_int32_t h_cp, n_cp; + + // Get the next code point and track it + const void *nextH = h = utf8codepoint(h, &h_cp); + n = utf8codepoint(n, &n_cp); + + while ((0 != h_cp) && (0 != n_cp)) { + h_cp = utf8lwrcodepoint(h_cp); + n_cp = utf8lwrcodepoint(n_cp); + + // if we find a mismatch, bail out! + if (h_cp != n_cp) { + break; + } + + h = utf8codepoint(h, &h_cp); + n = utf8codepoint(n, &n_cp); + } + + if (0 == n_cp) { + // we found the whole utf8 string for needle in haystack at + // maybeMatch, so return it + return (void *)maybeMatch; + } + + if (0 == h_cp) { + // no match + return utf8_null; + } + + // Roll back to the next code point in the haystack to test + h = nextH; + } +} + +void *utf8valid(const void *str) +{ + const char *s = (const char *)str; + + while ('\0' != *s) { + if (0xf0 == (0xf8 & *s)) { + // ensure each of the 3 following bytes in this 4-byte + // utf8 codepoint began with 0b10xxxxxx + if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2])) || + (0x80 != (0xc0 & s[3]))) { + return (void *)s; + } + + // ensure that our utf8 codepoint ended after 4 bytes + if (0x80 == (0xc0 & s[4])) { + return (void *)s; + } + + // ensure that the top 5 bits of this 4-byte utf8 + // codepoint were not 0, as then we could have used + // one of the smaller encodings + if ((0 == (0x07 & s[0])) && (0 == (0x30 & s[1]))) { + return (void *)s; + } + + // 4-byte utf8 code point (began with 0b11110xxx) + s += 4; + } else if (0xe0 == (0xf0 & *s)) { + // ensure each of the 2 following bytes in this 3-byte + // utf8 codepoint began with 0b10xxxxxx + if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2]))) { + return (void *)s; + } + + // ensure that our utf8 codepoint ended after 3 bytes + if (0x80 == (0xc0 & s[3])) { + return (void *)s; + } + + // ensure that the top 5 bits of this 3-byte utf8 + // codepoint were not 0, as then we could have used + // one of the smaller encodings + if ((0 == (0x0f & s[0])) && (0 == (0x20 & s[1]))) { + return (void *)s; + } + + // 3-byte utf8 code point (began with 0b1110xxxx) + s += 3; + } else if (0xc0 == (0xe0 & *s)) { + // ensure the 1 following byte in this 2-byte + // utf8 codepoint began with 0b10xxxxxx + if (0x80 != (0xc0 & s[1])) { + return (void *)s; + } + + // ensure that our utf8 codepoint ended after 2 bytes + if (0x80 == (0xc0 & s[2])) { + return (void *)s; + } + + // ensure that the top 4 bits of this 2-byte utf8 + // codepoint were not 0, as then we could have used + // one of the smaller encodings + if (0 == (0x1e & s[0])) { + return (void *)s; + } + + // 2-byte utf8 code point (began with 0b110xxxxx) + s += 2; + } else if (0x00 == (0x80 & *s)) { + // 1-byte ascii (began with 0b0xxxxxxx) + s += 1; + } else { + // we have an invalid 0b1xxxxxxx utf8 code point entry + return (void *)s; + } + } + + return utf8_null; +} + +void *utf8codepoint(const void *utf8_restrict str, + utf8_int32_t *utf8_restrict out_codepoint) +{ + const char *s = (const char *)str; + + if (0xf0 == (0xf8 & s[0])) { + // 4 byte utf8 codepoint + *out_codepoint = ((0x07 & s[0]) << 18) | ((0x3f & s[1]) << 12) | + ((0x3f & s[2]) << 6) | (0x3f & s[3]); + s += 4; + } else if (0xe0 == (0xf0 & s[0])) { + // 3 byte utf8 codepoint + *out_codepoint = + ((0x0f & s[0]) << 12) | ((0x3f & s[1]) << 6) | (0x3f & s[2]); + s += 3; + } else if (0xc0 == (0xe0 & s[0])) { + // 2 byte utf8 codepoint + *out_codepoint = ((0x1f & s[0]) << 6) | (0x3f & s[1]); + s += 2; + } else { + // 1 byte utf8 codepoint otherwise + *out_codepoint = s[0]; + s += 1; + } + + return (void *)s; +} + +size_t utf8codepointsize(utf8_int32_t chr) +{ + if (0 == ((utf8_int32_t)0xffffff80 & chr)) { + return 1; + } else if (0 == ((utf8_int32_t)0xfffff800 & chr)) { + return 2; + } else if (0 == ((utf8_int32_t)0xffff0000 & chr)) { + return 3; + } else { // if (0 == ((int)0xffe00000 & chr)) { + return 4; + } +} + +void *utf8catcodepoint(void *utf8_restrict str, utf8_int32_t chr, size_t n) +{ + char *s = (char *)str; + + if (0 == ((utf8_int32_t)0xffffff80 & chr)) { + // 1-byte/7-bit ascii + // (0b0xxxxxxx) + if (n < 1) { + return utf8_null; + } + s[0] = (char)chr; + s += 1; + } else if (0 == ((utf8_int32_t)0xfffff800 & chr)) { + // 2-byte/11-bit utf8 code point + // (0b110xxxxx 0b10xxxxxx) + if (n < 2) { + return utf8_null; + } + s[0] = 0xc0 | (char)(chr >> 6); + s[1] = 0x80 | (char)(chr & 0x3f); + s += 2; + } else if (0 == ((utf8_int32_t)0xffff0000 & chr)) { + // 3-byte/16-bit utf8 code point + // (0b1110xxxx 0b10xxxxxx 0b10xxxxxx) + if (n < 3) { + return utf8_null; + } + s[0] = 0xe0 | (char)(chr >> 12); + s[1] = 0x80 | (char)((chr >> 6) & 0x3f); + s[2] = 0x80 | (char)(chr & 0x3f); + s += 3; + } else { // if (0 == ((int)0xffe00000 & chr)) { + // 4-byte/21-bit utf8 code point + // (0b11110xxx 0b10xxxxxx 0b10xxxxxx 0b10xxxxxx) + if (n < 4) { + return utf8_null; + } + s[0] = 0xf0 | (char)(chr >> 18); + s[1] = 0x80 | (char)((chr >> 12) & 0x3f); + s[2] = 0x80 | (char)((chr >> 6) & 0x3f); + s[3] = 0x80 | (char)(chr & 0x3f); + s += 4; + } + + return s; +} + +int utf8islower(utf8_int32_t chr) { return chr != utf8uprcodepoint(chr); } + +int utf8isupper(utf8_int32_t chr) { return chr != utf8lwrcodepoint(chr); } + +void utf8lwr(void *utf8_restrict str) +{ + void *p, *pn; + utf8_int32_t cp; + + p = (char *)str; + pn = utf8codepoint(p, &cp); + + while (cp != 0) { + const utf8_int32_t lwr_cp = utf8lwrcodepoint(cp); + const size_t size = utf8codepointsize(lwr_cp); + + if (lwr_cp != cp) { + utf8catcodepoint(p, lwr_cp, size); + } + + p = pn; + pn = utf8codepoint(p, &cp); + } +} + +void utf8upr(void *utf8_restrict str) +{ + void *p, *pn; + utf8_int32_t cp; + + p = (char *)str; + pn = utf8codepoint(p, &cp); + + while (cp != 0) { + const utf8_int32_t lwr_cp = utf8uprcodepoint(cp); + const size_t size = utf8codepointsize(lwr_cp); + + if (lwr_cp != cp) { + utf8catcodepoint(p, lwr_cp, size); + } + + p = pn; + pn = utf8codepoint(p, &cp); + } +} + +utf8_int32_t utf8lwrcodepoint(utf8_int32_t cp) +{ + if (((0x0041 <= cp) && (0x005a >= cp)) || + ((0x00c0 <= cp) && (0x00d6 >= cp)) || + ((0x00d8 <= cp) && (0x00de >= cp)) || + ((0x0391 <= cp) && (0x03a1 >= cp)) || + ((0x03a3 <= cp) && (0x03ab >= cp))) { + cp += 32; + } else if (((0x0100 <= cp) && (0x012f >= cp)) || + ((0x0132 <= cp) && (0x0137 >= cp)) || + ((0x014a <= cp) && (0x0177 >= cp)) || + ((0x0182 <= cp) && (0x0185 >= cp)) || + ((0x01a0 <= cp) && (0x01a5 >= cp)) || + ((0x01de <= cp) && (0x01ef >= cp)) || + ((0x01f8 <= cp) && (0x021f >= cp)) || + ((0x0222 <= cp) && (0x0233 >= cp)) || + ((0x0246 <= cp) && (0x024f >= cp)) || + ((0x03d8 <= cp) && (0x03ef >= cp))) { + cp |= 0x1; + } else if (((0x0139 <= cp) && (0x0148 >= cp)) || + ((0x0179 <= cp) && (0x017e >= cp)) || + ((0x01af <= cp) && (0x01b0 >= cp)) || + ((0x01b3 <= cp) && (0x01b6 >= cp)) || + ((0x01cd <= cp) && (0x01dc >= cp))) { + cp += 1; + cp &= ~0x1; + } else { + switch (cp) { + default: break; + case 0x0178: cp = 0x00ff; break; + case 0x0243: cp = 0x0180; break; + case 0x018e: cp = 0x01dd; break; + case 0x023d: cp = 0x019a; break; + case 0x0220: cp = 0x019e; break; + case 0x01b7: cp = 0x0292; break; + case 0x01c4: cp = 0x01c6; break; + case 0x01c7: cp = 0x01c9; break; + case 0x01ca: cp = 0x01cc; break; + case 0x01f1: cp = 0x01f3; break; + case 0x01f7: cp = 0x01bf; break; + case 0x0187: cp = 0x0188; break; + case 0x018b: cp = 0x018c; break; + case 0x0191: cp = 0x0192; break; + case 0x0198: cp = 0x0199; break; + case 0x01a7: cp = 0x01a8; break; + case 0x01ac: cp = 0x01ad; break; + case 0x01af: cp = 0x01b0; break; + case 0x01b8: cp = 0x01b9; break; + case 0x01bc: cp = 0x01bd; break; + case 0x01f4: cp = 0x01f5; break; + case 0x023b: cp = 0x023c; break; + case 0x0241: cp = 0x0242; break; + case 0x03fd: cp = 0x037b; break; + case 0x03fe: cp = 0x037c; break; + case 0x03ff: cp = 0x037d; break; + case 0x037f: cp = 0x03f3; break; + case 0x0386: cp = 0x03ac; break; + case 0x0388: cp = 0x03ad; break; + case 0x0389: cp = 0x03ae; break; + case 0x038a: cp = 0x03af; break; + case 0x038c: cp = 0x03cc; break; + case 0x038e: cp = 0x03cd; break; + case 0x038f: cp = 0x03ce; break; + case 0x0370: cp = 0x0371; break; + case 0x0372: cp = 0x0373; break; + case 0x0376: cp = 0x0377; break; + case 0x03f4: cp = 0x03d1; break; + case 0x03cf: cp = 0x03d7; break; + case 0x03f9: cp = 0x03f2; break; + case 0x03f7: cp = 0x03f8; break; + case 0x03fa: cp = 0x03fb; break; + }; + } + + return cp; +} + +utf8_int32_t utf8uprcodepoint(utf8_int32_t cp) +{ + if (((0x0061 <= cp) && (0x007a >= cp)) || + ((0x00e0 <= cp) && (0x00f6 >= cp)) || + ((0x00f8 <= cp) && (0x00fe >= cp)) || + ((0x03b1 <= cp) && (0x03c1 >= cp)) || + ((0x03c3 <= cp) && (0x03cb >= cp))) { + cp -= 32; + } else if (((0x0100 <= cp) && (0x012f >= cp)) || + ((0x0132 <= cp) && (0x0137 >= cp)) || + ((0x014a <= cp) && (0x0177 >= cp)) || + ((0x0182 <= cp) && (0x0185 >= cp)) || + ((0x01a0 <= cp) && (0x01a5 >= cp)) || + ((0x01de <= cp) && (0x01ef >= cp)) || + ((0x01f8 <= cp) && (0x021f >= cp)) || + ((0x0222 <= cp) && (0x0233 >= cp)) || + ((0x0246 <= cp) && (0x024f >= cp)) || + ((0x03d8 <= cp) && (0x03ef >= cp))) { + cp &= ~0x1; + } else if (((0x0139 <= cp) && (0x0148 >= cp)) || + ((0x0179 <= cp) && (0x017e >= cp)) || + ((0x01af <= cp) && (0x01b0 >= cp)) || + ((0x01b3 <= cp) && (0x01b6 >= cp)) || + ((0x01cd <= cp) && (0x01dc >= cp))) { + cp -= 1; + cp |= 0x1; + } else { + switch (cp) { + default: break; + case 0x00ff: cp = 0x0178; break; + case 0x0180: cp = 0x0243; break; + case 0x01dd: cp = 0x018e; break; + case 0x019a: cp = 0x023d; break; + case 0x019e: cp = 0x0220; break; + case 0x0292: cp = 0x01b7; break; + case 0x01c6: cp = 0x01c4; break; + case 0x01c9: cp = 0x01c7; break; + case 0x01cc: cp = 0x01ca; break; + case 0x01f3: cp = 0x01f1; break; + case 0x01bf: cp = 0x01f7; break; + case 0x0188: cp = 0x0187; break; + case 0x018c: cp = 0x018b; break; + case 0x0192: cp = 0x0191; break; + case 0x0199: cp = 0x0198; break; + case 0x01a8: cp = 0x01a7; break; + case 0x01ad: cp = 0x01ac; break; + case 0x01b0: cp = 0x01af; break; + case 0x01b9: cp = 0x01b8; break; + case 0x01bd: cp = 0x01bc; break; + case 0x01f5: cp = 0x01f4; break; + case 0x023c: cp = 0x023b; break; + case 0x0242: cp = 0x0241; break; + case 0x037b: cp = 0x03fd; break; + case 0x037c: cp = 0x03fe; break; + case 0x037d: cp = 0x03ff; break; + case 0x03f3: cp = 0x037f; break; + case 0x03ac: cp = 0x0386; break; + case 0x03ad: cp = 0x0388; break; + case 0x03ae: cp = 0x0389; break; + case 0x03af: cp = 0x038a; break; + case 0x03cc: cp = 0x038c; break; + case 0x03cd: cp = 0x038e; break; + case 0x03ce: cp = 0x038f; break; + case 0x0371: cp = 0x0370; break; + case 0x0373: cp = 0x0372; break; + case 0x0377: cp = 0x0376; break; + case 0x03d1: cp = 0x03f4; break; + case 0x03d7: cp = 0x03cf; break; + case 0x03f2: cp = 0x03f9; break; + case 0x03f8: cp = 0x03f7; break; + case 0x03fb: cp = 0x03fa; break; + }; + } + + return cp; +} + +#undef utf8_restrict +#undef utf8_null + +#ifdef __cplusplus +} // extern "C" +#endif + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + +#endif // SHEREDOM_UTF8_H_INCLUDED diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/bitstream.c b/dde-file-manager-5.5.3/3rdparty/qrencode/bitstream.c new file mode 100644 index 0000000..a0b9283 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/bitstream.c @@ -0,0 +1,238 @@ +/* + * qrencode - QR Code encoder + * + * Binary sequence class. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include + +#include "bitstream.h" + +BitStream *BitStream_new(void) +{ + BitStream *bstream; + + bstream = (BitStream *)malloc(sizeof(BitStream)); + if(bstream == NULL) return NULL; + + bstream->length = 0; + bstream->data = NULL; + + return bstream; +} + +static int BitStream_allocate(BitStream *bstream, int length) +{ + unsigned char *data; + + if(bstream == NULL) { + return -1; + } + + data = (unsigned char *)malloc(length); + if(data == NULL) { + return -1; + } + + if(bstream->data) { + free(bstream->data); + } + bstream->length = length; + bstream->data = data; + + return 0; +} + +static BitStream *BitStream_newFromNum(int bits, unsigned int num) +{ + unsigned int mask; + int i; + unsigned char *p; + BitStream *bstream; + + bstream = BitStream_new(); + if(bstream == NULL) return NULL; + + if(BitStream_allocate(bstream, bits)) { + BitStream_free(bstream); + return NULL; + } + + p = bstream->data; + mask = 1 << (bits - 1); + for(i=0; i> 1; + } + + return bstream; +} + +static BitStream *BitStream_newFromBytes(int size, unsigned char *data) +{ + unsigned char mask; + int i, j; + unsigned char *p; + BitStream *bstream; + + bstream = BitStream_new(); + if(bstream == NULL) return NULL; + + if(BitStream_allocate(bstream, size * 8)) { + BitStream_free(bstream); + return NULL; + } + + p = bstream->data; + for(i=0; i> 1; + } + } + + return bstream; +} + +int BitStream_append(BitStream *bstream, BitStream *arg) +{ + unsigned char *data; + + if(arg == NULL) { + return -1; + } + if(arg->length == 0) { + return 0; + } + if(bstream->length == 0) { + if(BitStream_allocate(bstream, arg->length)) { + return -1; + } + memcpy(bstream->data, arg->data, arg->length); + return 0; + } + + data = (unsigned char *)malloc(bstream->length + arg->length); + if(data == NULL) { + return -1; + } + memcpy(data, bstream->data, bstream->length); + memcpy(data + bstream->length, arg->data, arg->length); + + free(bstream->data); + bstream->length += arg->length; + bstream->data = data; + + return 0; +} + +int BitStream_appendNum(BitStream *bstream, int bits, unsigned int num) +{ + BitStream *b; + int ret; + + if(bits == 0) return 0; + + b = BitStream_newFromNum(bits, num); + if(b == NULL) return -1; + + ret = BitStream_append(bstream, b); + BitStream_free(b); + + return ret; +} + +int BitStream_appendBytes(BitStream *bstream, int size, unsigned char *data) +{ + BitStream *b; + int ret; + + if(size == 0) return 0; + + b = BitStream_newFromBytes(size, data); + if(b == NULL) return -1; + + ret = BitStream_append(bstream, b); + BitStream_free(b); + + return ret; +} + +unsigned char *BitStream_toByte(BitStream *bstream) +{ + int i, j, size, bytes; + unsigned char *data, v; + unsigned char *p; + + size = BitStream_size(bstream); + if(size == 0) { + return NULL; + } + data = (unsigned char *)malloc((size + 7) / 8); + if(data == NULL) { + return NULL; + } + + bytes = size / 8; + + p = bstream->data; + for(i=0; idata); + free(bstream); + } +} diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/bitstream.h b/dde-file-manager-5.5.3/3rdparty/qrencode/bitstream.h new file mode 100644 index 0000000..ffe743c --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/bitstream.h @@ -0,0 +1,38 @@ +/* + * qrencode - QR Code encoder + * + * Binary sequence class. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __BITSTREAM_H__ +#define __BITSTREAM_H__ + +typedef struct { + int length; + unsigned char *data; +} BitStream; + +extern BitStream *BitStream_new(void); +extern int BitStream_append(BitStream *bstream, BitStream *arg); +extern int BitStream_appendNum(BitStream *bstream, int bits, unsigned int num); +extern int BitStream_appendBytes(BitStream *bstream, int size, unsigned char *data); +#define BitStream_size(__bstream__) (__bstream__->length) +extern unsigned char *BitStream_toByte(BitStream *bstream); +extern void BitStream_free(BitStream *bstream); + +#endif /* __BITSTREAM_H__ */ diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/config.h b/dde-file-manager-5.5.3/3rdparty/qrencode/config.h new file mode 100644 index 0000000..163925f --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/config.h @@ -0,0 +1,98 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define if you have the iconv() function and it works. */ +#undef HAVE_ICONV + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if using pthread is enabled. */ +#undef HAVE_LIBPTHREAD + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Major version number */ +#undef MAJOR_VERSION +#define MAJOR_VERSION 1 + +/* Micro version number */ +#undef MICRO_VERSION +#define MICRO_VERSION 1 + +/* Minor version number */ +#undef MINOR_VERSION +#define MINOR_VERSION 1 + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION +#define VERSION "1.1.1" + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to 'static' if no test programs will be compiled. */ +#define __STATIC static +#undef WITH_TESTS + diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/mask.c b/dde-file-manager-5.5.3/3rdparty/qrencode/mask.c new file mode 100644 index 0000000..47c658c --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/mask.c @@ -0,0 +1,330 @@ +/* + * qrencode - QR Code encoder + * + * Masking. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include + +#include "qrencode.h" +#include "qrspec.h" +#include "mask.h" + +__STATIC int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level) +{ + unsigned int format; + unsigned char v; + int i; + int blacks = 0; + + format = QRspec_getFormatInfo(mask, level); + + for(i=0; i<8; i++) { + if(format & 1) { + blacks += 2; + v = 0x85; + } else { + v = 0x84; + } + frame[width * 8 + width - 1 - i] = v; + if(i < 6) { + frame[width * i + 8] = v; + } else { + frame[width * (i + 1) + 8] = v; + } + format= format >> 1; + } + for(i=0; i<7; i++) { + if(format & 1) { + blacks += 2; + v = 0x85; + } else { + v = 0x84; + } + frame[width * (width - 7 + i) + 8] = v; + if(i == 0) { + frame[width * 8 + 7] = v; + } else { + frame[width * 8 + 6 - i] = v; + } + format= format >> 1; + } + + return blacks; +} + +/** + * Demerit coefficients. + * See Section 8.8.2, pp.45, JIS X0510:2004. + */ +#define N1 (3) +#define N2 (3) +#define N3 (40) +#define N4 (10) + +#define MASKMAKER(__exp__) \ + int x, y;\ + int b = 0;\ +\ + for(y=0; y= maskNum) { + errno = EINVAL; + return NULL; + } + + masked = (unsigned char *)malloc(width * width); + if(masked == NULL) return NULL; + + maskMakers[mask](width, frame, masked); + Mask_writeFormatInformation(width, masked, mask, level); + + return masked; +} + + +//static int n1; +//static int n2; +//static int n3; +//static int n4; + +__STATIC int Mask_calcN1N3(int length, int *runLength) +{ + int i; + int demerit = 0; + int fact; + + for(i=0; i= 5) { + demerit += N1 + (runLength[i] - 5); + //n1 += N1 + (runLength[i] - 5); + } + if((i & 1)) { + if(i >= 3 && i < length-2 && (runLength[i] % 3) == 0) { + fact = runLength[i] / 3; + if(runLength[i-2] == fact && + runLength[i-1] == fact && + runLength[i+1] == fact && + runLength[i+2] == fact) { + if(i == 3 || runLength[i-3] >= 4 * fact) { + demerit += N3; + //n3 += N3; + } else if(i+4 >= length || runLength[i+3] >= 4 * fact) { + demerit += N3; + //n3 += N3; + } + } + } + } + } + + return demerit; +} + +__STATIC int Mask_calcN2(int width, unsigned char *frame) +{ + int x, y; + unsigned char *p; + unsigned char b22, w22; + int demerit = 0; + + p = frame + width + 1; + for(y=1; y + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __MASK_H__ +#define __MASK_H__ + +extern unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level); +extern unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level); + +#ifdef WITH_TESTS +extern int Mask_calcN2(int width, unsigned char *frame); +extern int Mask_calcN1N3(int length, int *runLength); +extern int Mask_calcRunLength(int width, unsigned char *frame, int dir, int *runLength); +extern int Mask_evaluateSymbol(int width, unsigned char *frame); +extern int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level); +extern unsigned char *Mask_makeMaskedFrame(int width, unsigned char *frame, int mask); +#endif + +#endif /* __MASK_H__ */ diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/mmask.c b/dde-file-manager-5.5.3/3rdparty/qrencode/mmask.c new file mode 100644 index 0000000..99470f2 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/mmask.c @@ -0,0 +1,177 @@ +/* + * qrencode - QR Code encoder + * + * Masking for Micro QR Code. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include + +#include "qrencode.h" +#include "mqrspec.h" +#include "mmask.h" + +__STATIC void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level) +{ + unsigned int format; + unsigned char v; + int i; + + format = MQRspec_getFormatInfo(mask, version, level); + + for(i=0; i<8; i++) { + v = 0x84 | (format & 1); + frame[width * (i + 1) + 8] = v; + format = format >> 1; + } + for(i=0; i<7; i++) { + v = 0x84 | (format & 1); + frame[width * 8 + 7 - i] = v; + format = format >> 1; + } +} + +#define MASKMAKER(__exp__) \ + int x, y;\ +\ + for(y=0; y= maskNum) { + errno = EINVAL; + return NULL; + } + + width = MQRspec_getWidth(version); + masked = (unsigned char *)malloc(width * width); + if(masked == NULL) return NULL; + + maskMakers[mask](width, frame, masked); + MMask_writeFormatInformation(version, width, masked, mask, level); + + return masked; +} + +__STATIC int MMask_evaluateSymbol(int width, unsigned char *frame) +{ + int x, y; + unsigned char *p; + int sum1 = 0, sum2 = 0; + + p = frame + width * (width - 1); + for(x=1; x maxScore) { + maxScore = score; + free(bestMask); + bestMask = mask; + mask = (unsigned char *)malloc(width * width); + if(mask == NULL) break; + } + } + free(mask); + return bestMask; +} diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/mmask.h b/dde-file-manager-5.5.3/3rdparty/qrencode/mmask.h new file mode 100644 index 0000000..f6556e8 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/mmask.h @@ -0,0 +1,34 @@ +/* + * qrencode - QR Code encoder + * + * Masking for Micro QR Code. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __MMASK_H__ +#define __MMASK_H__ + +extern unsigned char *MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level); +extern unsigned char *MMask_mask(int version, unsigned char *frame, QRecLevel level); + +#ifdef WITH_TESTS +extern int MMask_evaluateSymbol(int width, unsigned char *frame); +extern void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level); +extern unsigned char *MMask_makeMaskedFrame(int width, unsigned char *frame, int mask); +#endif + +#endif /* __MMASK_H__ */ diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/mqrspec.c b/dde-file-manager-5.5.3/3rdparty/qrencode/mqrspec.c new file mode 100644 index 0000000..76d2d26 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/mqrspec.c @@ -0,0 +1,280 @@ +/* + * qrencode - QR Code encoder + * + * Micor QR Code specification in convenient format. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * The following data / specifications are taken from + * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) + * or + * "Automatic identification and data capture techniques -- + * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include +#ifdef HAVE_LIBPTHREAD +#include +#endif + +#include "mqrspec.h" + +/****************************************************************************** + * Version and capacity + *****************************************************************************/ + +typedef struct { + int width; //< Edge length of the symbol + int ec[4]; //< Number of ECC code (bytes) +} MQRspec_Capacity; + +/** + * Table of the capacity of symbols + * See Table 1 (pp.106) and Table 8 (pp.113) of Appendix 1, JIS X0510:2004. + */ +static const MQRspec_Capacity mqrspecCapacity[MQRSPEC_VERSION_MAX + 1] = { + { 0, {0, 0, 0, 0}}, + { 11, {2, 0, 0, 0}}, + { 13, {5, 6, 0, 0}}, + { 15, {6, 8, 0, 0}}, + { 17, {8, 10, 14, 0}} +}; + +int MQRspec_getDataLengthBit(int version, QRecLevel level) +{ + int w; + int ecc; + + w = mqrspecCapacity[version].width - 1; + ecc = mqrspecCapacity[version].ec[level]; + if(ecc == 0) return 0; + return w * w - 64 - ecc * 8; +} + +int MQRspec_getDataLength(int version, QRecLevel level) +{ + return (MQRspec_getDataLengthBit(version, level) + 4) / 8; +} + +int MQRspec_getECCLength(int version, QRecLevel level) +{ + return mqrspecCapacity[version].ec[level]; +} + +int MQRspec_getWidth(int version) +{ + return mqrspecCapacity[version].width; +} + +/****************************************************************************** + * Length indicator + *****************************************************************************/ + +/** + * See Table 3 (pp.107) of Appendix 1, JIS X0510:2004. + */ +static const int lengthTableBits[4][4] = { + { 3, 4, 5, 6}, + { 0, 3, 4, 5}, + { 0, 0, 4, 5}, + { 0, 0, 3, 4} +}; + +int MQRspec_lengthIndicator(QRencodeMode mode, int version) +{ + return lengthTableBits[mode][version - 1]; +} + +int MQRspec_maximumWords(QRencodeMode mode, int version) +{ + int bits; + int words; + + bits = lengthTableBits[mode][version - 1]; + words = (1 << bits) - 1; + if(mode == QR_MODE_KANJI) { + words *= 2; // the number of bytes is required + } + + return words; +} + +/****************************************************************************** + * Format information + *****************************************************************************/ + +/* See calcFormatInfo in tests/test_mqrspec.c */ +static const unsigned int formatInfo[4][8] = { + {0x4445, 0x55ae, 0x6793, 0x7678, 0x06de, 0x1735, 0x2508, 0x34e3}, + {0x4172, 0x5099, 0x62a4, 0x734f, 0x03e9, 0x1202, 0x203f, 0x31d4}, + {0x4e2b, 0x5fc0, 0x6dfd, 0x7c16, 0x0cb0, 0x1d5b, 0x2f66, 0x3e8d}, + {0x4b1c, 0x5af7, 0x68ca, 0x7921, 0x0987, 0x186c, 0x2a51, 0x3bba} +}; + +/* See Table 10 of Appendix 1. (pp.115) */ +static const int typeTable[MQRSPEC_VERSION_MAX + 1][3] = { + {-1, -1, -1}, + { 0, -1, -1}, + { 1, 2, -1}, + { 3, 4, -1}, + { 5, 6, 7} +}; + +unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level) +{ + int type; + + if(mask < 0 || mask > 3) return 0; + if(version <= 0 || version > MQRSPEC_VERSION_MAX) return 0; + if(level == QR_ECLEVEL_H) return 0; + type = typeTable[version][level]; + if(type < 0) return 0; + + return formatInfo[mask][type]; +} + +/****************************************************************************** + * Frame + *****************************************************************************/ + +/** + * Cache of initial frames. + */ +/* C99 says that static storage shall be initialized to a null pointer + * by compiler. */ +static unsigned char *frames[MQRSPEC_VERSION_MAX + 1]; +#ifdef HAVE_LIBPTHREAD +static pthread_mutex_t frames_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +/** + * Put a finder pattern. + * @param frame + * @param width + * @param ox,oy upper-left coordinate of the pattern + */ +static void putFinderPattern(unsigned char *frame, int width, int ox, int oy) +{ + static const unsigned char finder[] = { + 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, + 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, + 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, + }; + int x, y; + const unsigned char *s; + + frame += oy * width + ox; + s = finder; + for(y=0; y<7; y++) { + for(x=0; x<7; x++) { + frame[x] = s[x]; + } + frame += width; + s += 7; + } +} + +static unsigned char *MQRspec_createFrame(int version) +{ + unsigned char *frame, *p, *q; + int width; + int x, y; + + width = mqrspecCapacity[version].width; + frame = (unsigned char *)malloc(width * width); + if(frame == NULL) return NULL; + + memset(frame, 0, width * width); + /* Finder pattern */ + putFinderPattern(frame, width, 0, 0); + /* Separator */ + p = frame; + for(y=0; y<7; y++) { + p[7] = 0xc0; + p += width; + } + memset(frame + width * 7, 0xc0, 8); + /* Mask format information area */ + memset(frame + width * 8 + 1, 0x84, 8); + p = frame + width + 8; + for(y=0; y<7; y++) { + *p = 0x84; + p += width; + } + /* Timing pattern */ + p = frame + 8; + q = frame + width * 8; + for(x=1; x MQRSPEC_VERSION_MAX) return NULL; + +#ifdef HAVE_LIBPTHREAD + pthread_mutex_lock(&frames_mutex); +#endif + if(frames[version] == NULL) { + frames[version] = MQRspec_createFrame(version); + } +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&frames_mutex); +#endif + if(frames[version] == NULL) return NULL; + + width = mqrspecCapacity[version].width; + frame = (unsigned char *)malloc(width * width); + if(frame == NULL) return NULL; + memcpy(frame, frames[version], width * width); + + return frame; +} + +void MQRspec_clearCache(void) +{ + int i; + +#ifdef HAVE_LIBPTHREAD + pthread_mutex_lock(&frames_mutex); +#endif + for(i=1; i<=MQRSPEC_VERSION_MAX; i++) { + free(frames[i]); + frames[i] = NULL; + } +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&frames_mutex); +#endif +} diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/mqrspec.h b/dde-file-manager-5.5.3/3rdparty/qrencode/mqrspec.h new file mode 100644 index 0000000..2d4b90d --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/mqrspec.h @@ -0,0 +1,157 @@ +/* + * qrencode - QR Code encoder + * + * Micro QR Code specification in convenient format. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __MQRSPEC_H__ +#define __MQRSPEC_H__ + +#include "qrencode.h" + +/****************************************************************************** + * Version and capacity + *****************************************************************************/ + +/** + * Maximum width of a symbol + */ +#define MQRSPEC_WIDTH_MAX 17 + +/** + * Return maximum data code length (bits) for the version. + * @param version + * @param level + * @return maximum size (bits) + */ +extern int MQRspec_getDataLengthBit(int version, QRecLevel level); + +/** + * Return maximum data code length (bytes) for the version. + * @param version + * @param level + * @return maximum size (bytes) + */ +extern int MQRspec_getDataLength(int version, QRecLevel level); + +/** + * Return maximum error correction code length (bytes) for the version. + * @param version + * @param level + * @return ECC size (bytes) + */ +extern int MQRspec_getECCLength(int version, QRecLevel level); + +/** + * Return a version number that satisfies the input code length. + * @param size input code length (byte) + * @param level + * @return version number + */ +extern int MQRspec_getMinimumVersion(int size, QRecLevel level); + +/** + * Return the width of the symbol for the version. + * @param version + * @return width + */ +extern int MQRspec_getWidth(int version); + +/** + * Return the numer of remainder bits. + * @param version + * @return number of remainder bits + */ +extern int MQRspec_getRemainder(int version); + +/****************************************************************************** + * Length indicator + *****************************************************************************/ + +/** + * Return the size of lenght indicator for the mode and version. + * @param mode + * @param version + * @return the size of the appropriate length indicator (bits). + */ +extern int MQRspec_lengthIndicator(QRencodeMode mode, int version); + +/** + * Return the maximum length for the mode and version. + * @param mode + * @param version + * @return the maximum length (bytes) + */ +extern int MQRspec_maximumWords(QRencodeMode mode, int version); + +/****************************************************************************** + * Version information pattern + *****************************************************************************/ + +/** + * Return BCH encoded version information pattern that is used for the symbol + * of version 7 or greater. Use lower 18 bits. + * @param version + * @return BCH encoded version information pattern + */ +extern unsigned int MQRspec_getVersionPattern(int version); + +/****************************************************************************** + * Format information + *****************************************************************************/ + +/** + * Return BCH encoded format information pattern. + * @param mask + * @param version + * @param level + * @return BCH encoded format information pattern + */ +extern unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level); + +/****************************************************************************** + * Frame + *****************************************************************************/ + +/** + * Return a copy of initialized frame. + * When the same version is requested twice or more, a copy of cached frame + * is returned. + * @param version + * @return Array of unsigned char. You can free it by free(). + */ +extern unsigned char *MQRspec_newFrame(int version); + +/** + * Clear the frame cache. Typically for debug. + */ +extern void MQRspec_clearCache(void); + +/****************************************************************************** + * Mode indicator + *****************************************************************************/ + +/** + * Mode indicator. See Table 2 in Appendix 1 of JIS X0510:2004, pp.107. + */ +#define MQRSPEC_MODEID_NUM 0 +#define MQRSPEC_MODEID_AN 1 +#define MQRSPEC_MODEID_8 2 +#define MQRSPEC_MODEID_KANJI 3 + +#endif /* __MQRSPEC_H__ */ diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/qrencode.c b/dde-file-manager-5.5.3/3rdparty/qrencode/qrencode.c new file mode 100644 index 0000000..8daedf0 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/qrencode.c @@ -0,0 +1,932 @@ +/* + * qrencode - QR Code encoder + * + * Copyright (C) 2006-2012 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include + +#include "qrencode.h" +#include "qrspec.h" +#include "mqrspec.h" +#include "bitstream.h" +#include "qrinput.h" +#include "rscode.h" +#include "split.h" +#include "mask.h" +#include "mmask.h" + +/****************************************************************************** + * Raw code + *****************************************************************************/ + +typedef struct { + int dataLength; + unsigned char *data; + int eccLength; + unsigned char *ecc; +} RSblock; + +typedef struct { + int version; + int dataLength; + int eccLength; + unsigned char *datacode; + unsigned char *ecccode; + int b1; + int blocks; + RSblock *rsblock; + int count; +} QRRawCode; + +static void RSblock_initBlock(RSblock *block, int dl, unsigned char *data, int el, unsigned char *ecc, RS *rs) +{ + block->dataLength = dl; + block->data = data; + block->eccLength = el; + block->ecc = ecc; + + encode_rs_char(rs, data, ecc); +} + +static int RSblock_init(RSblock *blocks, int spec[5], unsigned char *data, unsigned char *ecc) +{ + int i; + RSblock *block; + unsigned char *dp, *ep; + RS *rs; + int el, dl; + + dl = QRspec_rsDataCodes1(spec); + el = QRspec_rsEccCodes1(spec); + rs = init_rs(8, 0x11d, 0, 1, el, 255 - dl - el); + if(rs == NULL) return -1; + + block = blocks; + dp = data; + ep = ecc; + for(i=0; idatacode = QRinput_getByteStream(input); + if(raw->datacode == NULL) { + free(raw); + return NULL; + } + + QRspec_getEccSpec(input->version, input->level, spec); + + raw->version = input->version; + raw->b1 = QRspec_rsBlockNum1(spec); + raw->dataLength = QRspec_rsDataLength(spec); + raw->eccLength = QRspec_rsEccLength(spec); + raw->ecccode = (unsigned char *)malloc(raw->eccLength); + if(raw->ecccode == NULL) { + free(raw->datacode); + free(raw); + return NULL; + } + + raw->blocks = QRspec_rsBlockNum(spec); + raw->rsblock = (RSblock *)calloc(raw->blocks, sizeof(RSblock)); + if(raw->rsblock == NULL) { + QRraw_free(raw); + return NULL; + } + ret = RSblock_init(raw->rsblock, spec, raw->datacode, raw->ecccode); + if(ret < 0) { + QRraw_free(raw); + return NULL; + } + + raw->count = 0; + + return raw; +} + +/** + * Return a code (byte). + * This function can be called iteratively. + * @param raw raw code. + * @return code + */ +__STATIC unsigned char QRraw_getCode(QRRawCode *raw) +{ + int col, row; + unsigned char ret; + + if(raw->count < raw->dataLength) { + row = raw->count % raw->blocks; + col = raw->count / raw->blocks; + if(col >= raw->rsblock[0].dataLength) { + row += raw->b1; + } + ret = raw->rsblock[row].data[col]; + } else if(raw->count < raw->dataLength + raw->eccLength) { + row = (raw->count - raw->dataLength) % raw->blocks; + col = (raw->count - raw->dataLength) / raw->blocks; + ret = raw->rsblock[row].ecc[col]; + } else { + return 0; + } + raw->count++; + return ret; +} + +__STATIC void QRraw_free(QRRawCode *raw) +{ + if(raw != NULL) { + free(raw->datacode); + free(raw->ecccode); + free(raw->rsblock); + free(raw); + } +} + +/****************************************************************************** + * Raw code for Micro QR Code + *****************************************************************************/ + +typedef struct { + int version; + int dataLength; + int eccLength; + unsigned char *datacode; + unsigned char *ecccode; + RSblock *rsblock; + int oddbits; + int count; +} MQRRawCode; + +__STATIC void MQRraw_free(MQRRawCode *raw); +__STATIC MQRRawCode *MQRraw_new(QRinput *input) +{ + MQRRawCode *raw; + RS *rs; + + raw = (MQRRawCode *)malloc(sizeof(MQRRawCode)); + if(raw == NULL) return NULL; + + raw->version = input->version; + raw->dataLength = MQRspec_getDataLength(input->version, input->level); + raw->eccLength = MQRspec_getECCLength(input->version, input->level); + raw->oddbits = raw->dataLength * 8 - MQRspec_getDataLengthBit(input->version, input->level); + raw->datacode = QRinput_getByteStream(input); + if(raw->datacode == NULL) { + free(raw); + return NULL; + } + raw->ecccode = (unsigned char *)malloc(raw->eccLength); + if(raw->ecccode == NULL) { + free(raw->datacode); + free(raw); + return NULL; + } + + raw->rsblock = (RSblock *)calloc(1, sizeof(RSblock)); + if(raw->rsblock == NULL) { + MQRraw_free(raw); + return NULL; + } + + rs = init_rs(8, 0x11d, 0, 1, raw->eccLength, 255 - raw->dataLength - raw->eccLength); + if(rs == NULL) { + MQRraw_free(raw); + return NULL; + } + + RSblock_initBlock(raw->rsblock, raw->dataLength, raw->datacode, raw->eccLength, raw->ecccode, rs); + + raw->count = 0; + + return raw; +} + +/** + * Return a code (byte). + * This function can be called iteratively. + * @param raw raw code. + * @return code + */ +__STATIC unsigned char MQRraw_getCode(MQRRawCode *raw) +{ + unsigned char ret; + + if(raw->count < raw->dataLength) { + ret = raw->datacode[raw->count]; + } else if(raw->count < raw->dataLength + raw->eccLength) { + ret = raw->ecccode[raw->count - raw->dataLength]; + } else { + return 0; + } + raw->count++; + return ret; +} + +__STATIC void MQRraw_free(MQRRawCode *raw) +{ + if(raw != NULL) { + free(raw->datacode); + free(raw->ecccode); + free(raw->rsblock); + free(raw); + } +} + + +/****************************************************************************** + * Frame filling + *****************************************************************************/ + +typedef struct { + int width; + unsigned char *frame; + int x, y; + int dir; + int bit; + int mqr; +} FrameFiller; + +static FrameFiller *FrameFiller_new(int width, unsigned char *frame, int mqr) +{ + FrameFiller *filler; + + filler = (FrameFiller *)malloc(sizeof(FrameFiller)); + if(filler == NULL) return NULL; + filler->width = width; + filler->frame = frame; + filler->x = width - 1; + filler->y = width - 1; + filler->dir = -1; + filler->bit = -1; + filler->mqr = mqr; + + return filler; +} + +static unsigned char *FrameFiller_next(FrameFiller *filler) +{ + unsigned char *p; + int x, y, w; + + if(filler->bit == -1) { + filler->bit = 0; + return filler->frame + filler->y * filler->width + filler->x; + } + + x = filler->x; + y = filler->y; + p = filler->frame; + w = filler->width; + + if(filler->bit == 0) { + x--; + filler->bit++; + } else { + x++; + y += filler->dir; + filler->bit--; + } + + if(filler->dir < 0) { + if(y < 0) { + y = 0; + x -= 2; + filler->dir = 1; + if(!filler->mqr && x == 6) { + x--; + y = 9; + } + } + } else { + if(y == w) { + y = w - 1; + x -= 2; + filler->dir = -1; + if(!filler->mqr && x == 6) { + x--; + y -= 8; + } + } + } + if(x < 0 || y < 0) return NULL; + + filler->x = x; + filler->y = y; + + if(p[y * w + x] & 0x80) { + // This tail recursion could be optimized. + return FrameFiller_next(filler); + } + return &p[y * w + x]; +} + +#ifdef WITH_TESTS +extern unsigned char *FrameFiller_test(int version) +{ + int width; + unsigned char *frame, *p; + FrameFiller *filler; + int i, length; + + width = QRspec_getWidth(version); + frame = QRspec_newFrame(version); + if(frame == NULL) return NULL; + filler = FrameFiller_new(width, frame, 0); + if(filler == NULL) { + free(frame); + return NULL; + } + length = QRspec_getDataLength(version, QR_ECLEVEL_L) * 8 + + QRspec_getECCLength(version, QR_ECLEVEL_L) * 8 + + QRspec_getRemainder(version); + for(i=0; iversion = version; + qrcode->width = width; + qrcode->data = data; + + return qrcode; +} + +void QRcode_free(QRcode *qrcode) +{ + if(qrcode != NULL) { + free(qrcode->data); + free(qrcode); + } +} + +__STATIC QRcode *QRcode_encodeMask(QRinput *input, int mask) +{ + int width, version; + QRRawCode *raw; + unsigned char *frame, *masked, *p, code, bit; + FrameFiller *filler; + int i, j; + QRcode *qrcode = NULL; + + if(input->mqr) { + errno = EINVAL; + return NULL; + } + if(input->version < 0 || input->version > QRSPEC_VERSION_MAX) { + errno = EINVAL; + return NULL; + } + if(input->level > QR_ECLEVEL_H) { + errno = EINVAL; + return NULL; + } + + raw = QRraw_new(input); + if(raw == NULL) return NULL; + + version = raw->version; + width = QRspec_getWidth(version); + frame = QRspec_newFrame(version); + if(frame == NULL) { + QRraw_free(raw); + return NULL; + } + filler = FrameFiller_new(width, frame, 0); + if(filler == NULL) { + QRraw_free(raw); + free(frame); + return NULL; + } + + /* inteleaved data and ecc codes */ + for(i=0; idataLength + raw->eccLength; i++) { + code = QRraw_getCode(raw); + bit = 0x80; + for(j=0; j<8; j++) { + p = FrameFiller_next(filler); + if(p == NULL) goto EXIT; + *p = 0x02 | ((bit & code) != 0); + bit = bit >> 1; + } + } + QRraw_free(raw); + raw = NULL; + /* remainder bits */ + j = QRspec_getRemainder(version); + for(i=0; ilevel); + } else { + masked = Mask_makeMask(width, frame, mask, input->level); + } + if(masked == NULL) { + goto EXIT; + } + qrcode = QRcode_new(version, width, masked); + if(qrcode == NULL) { + free(masked); + } + +EXIT: + QRraw_free(raw); + free(filler); + free(frame); + return qrcode; +} + +__STATIC QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask) +{ + int width, version; + MQRRawCode *raw; + unsigned char *frame, *masked, *p, code, bit; + FrameFiller *filler; + int i, j; + QRcode *qrcode = NULL; + + if(!input->mqr) { + errno = EINVAL; + return NULL; + } + if(input->version <= 0 || input->version > MQRSPEC_VERSION_MAX) { + errno = EINVAL; + return NULL; + } + if(input->level > QR_ECLEVEL_Q) { + errno = EINVAL; + return NULL; + } + + raw = MQRraw_new(input); + if(raw == NULL) return NULL; + + version = raw->version; + width = MQRspec_getWidth(version); + frame = MQRspec_newFrame(version); + if(frame == NULL) { + MQRraw_free(raw); + return NULL; + } + filler = FrameFiller_new(width, frame, 1); + if(filler == NULL) { + MQRraw_free(raw); + free(frame); + return NULL; + } + + /* inteleaved data and ecc codes */ + for(i=0; idataLength + raw->eccLength; i++) { + code = MQRraw_getCode(raw); + if(raw->oddbits && i == raw->dataLength - 1) { + bit = 1 << (raw->oddbits - 1); + for(j=0; joddbits; j++) { + p = FrameFiller_next(filler); + if(p == NULL) goto EXIT; + *p = 0x02 | ((bit & code) != 0); + bit = bit >> 1; + } + } else { + bit = 0x80; + for(j=0; j<8; j++) { + p = FrameFiller_next(filler); + if(p == NULL) goto EXIT; + *p = 0x02 | ((bit & code) != 0); + bit = bit >> 1; + } + } + } + MQRraw_free(raw); + raw = NULL; + + /* masking */ + if(mask < 0) { + masked = MMask_mask(version, frame, input->level); + } else { + masked = MMask_makeMask(version, frame, mask, input->level); + } + if(masked == NULL) { + goto EXIT; + } + + qrcode = QRcode_new(version, width, masked); + +EXIT: + MQRraw_free(raw); + free(filler); + free(frame); + return qrcode; +} + +QRcode *QRcode_encodeInput(QRinput *input) +{ + if(input->mqr) { + return QRcode_encodeMaskMQR(input, -1); + } else { + return QRcode_encodeMask(input, -1); + } +} + +static QRcode *QRcode_encodeStringReal(const char *string, int version, QRecLevel level, int mqr, QRencodeMode hint, int casesensitive) +{ + QRinput *input; + QRcode *code; + int ret; + + if(string == NULL) { + errno = EINVAL; + return NULL; + } + if(hint != QR_MODE_8 && hint != QR_MODE_KANJI) { + errno = EINVAL; + return NULL; + } + + if(mqr) { + input = QRinput_newMQR(version, level); + } else { + input = QRinput_new2(version, level); + } + if(input == NULL) return NULL; + + ret = Split_splitStringToQRinput(string, input, hint, casesensitive); + if(ret < 0) { + QRinput_free(input); + return NULL; + } + code = QRcode_encodeInput(input); + QRinput_free(input); + + return code; +} + +QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive) +{ + return QRcode_encodeStringReal(string, version, level, 0, hint, casesensitive); +} + +QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive) +{ + return QRcode_encodeStringReal(string, version, level, 1, hint, casesensitive); +} + +static QRcode *QRcode_encodeDataReal(const unsigned char *data, int length, int version, QRecLevel level, int mqr) +{ + QRinput *input; + QRcode *code; + int ret; + + if(data == NULL || length == 0) { + errno = EINVAL; + return NULL; + } + + if(mqr) { + input = QRinput_newMQR(version, level); + } else { + input = QRinput_new2(version, level); + } + if(input == NULL) return NULL; + + ret = QRinput_append(input, QR_MODE_8, length, data); + if(ret < 0) { + QRinput_free(input); + return NULL; + } + code = QRcode_encodeInput(input); + QRinput_free(input); + + return code; +} + +QRcode *QRcode_encodeData(int size, const unsigned char *data, int version, QRecLevel level) +{ + return QRcode_encodeDataReal(data, size, version, level, 0); +} + +QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level) +{ + if(string == NULL) { + errno = EINVAL; + return NULL; + } + return QRcode_encodeDataReal((unsigned char *)string, strlen(string), version, level, 0); +} + +QRcode *QRcode_encodeDataMQR(int size, const unsigned char *data, int version, QRecLevel level) +{ + return QRcode_encodeDataReal(data, size, version, level, 1); +} + +QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level) +{ + if(string == NULL) { + errno = EINVAL; + return NULL; + } + return QRcode_encodeDataReal((unsigned char *)string, strlen(string), version, level, 1); +} + + +/****************************************************************************** + * Structured QR-code encoding + *****************************************************************************/ + +static QRcode_List *QRcode_List_newEntry(void) +{ + QRcode_List *entry; + + entry = (QRcode_List *)malloc(sizeof(QRcode_List)); + if(entry == NULL) return NULL; + + entry->next = NULL; + entry->code = NULL; + + return entry; +} + +static void QRcode_List_freeEntry(QRcode_List *entry) +{ + if(entry != NULL) { + QRcode_free(entry->code); + free(entry); + } +} + +void QRcode_List_free(QRcode_List *qrlist) +{ + QRcode_List *list = qrlist, *next; + + while(list != NULL) { + next = list->next; + QRcode_List_freeEntry(list); + list = next; + } +} + +int QRcode_List_size(QRcode_List *qrlist) +{ + QRcode_List *list = qrlist; + int size = 0; + + while(list != NULL) { + size++; + list = list->next; + } + + return size; +} + +#if 0 +static unsigned char QRcode_parity(const char *str, int size) +{ + unsigned char parity = 0; + int i; + + for(i=0; ihead; + + while(list != NULL) { + if(head == NULL) { + entry = QRcode_List_newEntry(); + if(entry == NULL) goto ABORT; + head = entry; + tail = head; + } else { + entry = QRcode_List_newEntry(); + if(entry == NULL) goto ABORT; + tail->next = entry; + tail = tail->next; + } + tail->code = QRcode_encodeInput(list->input); + if(tail->code == NULL) { + goto ABORT; + } + list = list->next; + } + + return head; +ABORT: + QRcode_List_free(head); + return NULL; +} + +static QRcode_List *QRcode_encodeInputToStructured(QRinput *input) +{ + QRinput_Struct *s; + QRcode_List *codes; + + s = QRinput_splitQRinputToStruct(input); + if(s == NULL) return NULL; + + codes = QRcode_encodeInputStructured(s); + QRinput_Struct_free(s); + + return codes; +} + +static QRcode_List *QRcode_encodeDataStructuredReal( + int size, const unsigned char *data, + int version, QRecLevel level, + int eightbit, QRencodeMode hint, int casesensitive) +{ + QRinput *input; + QRcode_List *codes; + int ret; + + if(version <= 0) { + errno = EINVAL; + return NULL; + } + if(!eightbit && (hint != QR_MODE_8 && hint != QR_MODE_KANJI)) { + errno = EINVAL; + return NULL; + } + + input = QRinput_new2(version, level); + if(input == NULL) return NULL; + + if(eightbit) { + ret = QRinput_append(input, QR_MODE_8, size, data); + } else { + ret = Split_splitStringToQRinput((char *)data, input, hint, casesensitive); + } + if(ret < 0) { + QRinput_free(input); + return NULL; + } + codes = QRcode_encodeInputToStructured(input); + QRinput_free(input); + + return codes; +} + +QRcode_List *QRcode_encodeDataStructured(int size, const unsigned char *data, int version, QRecLevel level) { + return QRcode_encodeDataStructuredReal(size, data, version, level, 1, QR_MODE_NUL, 0); +} + +QRcode_List *QRcode_encodeString8bitStructured(const char *string, int version, QRecLevel level) { + if(string == NULL) { + errno = EINVAL; + return NULL; + } + return QRcode_encodeDataStructured(strlen(string), (unsigned char *)string, version, level); +} + +QRcode_List *QRcode_encodeStringStructured(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive) +{ + if(string == NULL) { + errno = EINVAL; + return NULL; + } + return QRcode_encodeDataStructuredReal(strlen(string), (unsigned char *)string, version, level, 0, hint, casesensitive); +} + +/****************************************************************************** + * System utilities + *****************************************************************************/ + +void QRcode_APIVersion(int *major_version, int *minor_version, int *micro_version) +{ + if(major_version != NULL) { + *major_version = MAJOR_VERSION; + } + if(minor_version != NULL) { + *minor_version = MINOR_VERSION; + } + if(micro_version != NULL) { + *micro_version = MICRO_VERSION; + } +} + +char *QRcode_APIVersionString(void) +{ + return VERSION; +} + +void QRcode_clearCache(void) +{ + QRspec_clearCache(); + MQRspec_clearCache(); + free_rs_cache(); +} diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/qrencode.h b/dde-file-manager-5.5.3/3rdparty/qrencode/qrencode.h new file mode 100644 index 0000000..e554bb9 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/qrencode.h @@ -0,0 +1,566 @@ +/** + * qrencode - QR Code encoder + * + * Copyright (C) 2006-2012 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** \mainpage + * Libqrencode is a library for encoding data in a QR Code symbol, a kind of 2D + * symbology. + * + * \section encoding Encoding + * + * There are two methods to encode data: encoding a string/data or + * encoding a structured data. + * + * \subsection encoding-string Encoding a string/data + * You can encode a string by calling QRcode_encodeString(). + * The given string is parsed automatically and encoded. If you want to encode + * data that can be represented as a C string style (NUL terminated), you can + * simply use this way. + * + * If the input data contains Kanji (Shift-JIS) characters and you want to + * encode them as Kanji in QR Code, you should give QR_MODE_KANJI as a hint. + * Otherwise, all of non-alphanumeric characters are encoded as 8 bit data. + * If you want to encode a whole string in 8 bit mode, you can use + * QRcode_encodeString8bit() instead. + * + * Please note that a C string can not contain NUL characters. If your data + * contains NUL, you must use QRcode_encodeData(). + * + * \subsection encoding-input Encoding a structured data + * You can construct a structured input data manually. If the structure of the + * input data is known, you can use this way. + * At first, create a ::QRinput object by QRinput_new(). Then add input data + * to the QRinput object by QRinput_append(). Finally call QRcode_encodeInput() + * to encode the QRinput data. + * You can reuse the QRinput data again to encode it in other symbols with + * different parameters. + * + * \section result Result + * The encoded symbol is resulted as a ::QRcode object. It will contain + * its version number, width of the symbol and an array represents the symbol. + * See ::QRcode for the details. You can free the object by QRcode_free(). + * + * Please note that the version of the result may be larger than specified. + * In such cases, the input data would be too large to be encoded in a + * symbol of the specified version. + * + * \section structured Structured append + * Libqrencode can generate "Structured-appended" symbols that enables to split + * a large data set into mulitple QR codes. A QR code reader concatenates + * multiple QR code symbols into a string. + * Just like QRcode_encodeString(), you can use QRcode_encodeStringStructured() + * to generate structured-appended symbols. This functions returns an instance + * of ::QRcode_List. The returned list is a singly-linked list of QRcode: you + * can retrieve each QR code in this way: + * + * \code + * QRcode_List *qrcodes; + * QRcode_List *entry; + * QRcode *qrcode; + * + * qrcodes = QRcode_encodeStringStructured(...); + * entry = qrcodes; + * while(entry != NULL) { + * qrcode = entry->code; + * // do something + * entry = entry->next; + * } + * QRcode_List_free(entry); + * \endcode + * + * Instead of using auto-parsing functions, you can construct your own + * structured input. At first, instantiate an object of ::QRinput_Struct + * by calling QRinput_Struct_new(). This object can hold multiple ::QRinput, + * and one QR code is generated for a ::QRinput. + * QRinput_Struct_appendInput() appends a ::QRinput to a ::QRinput_Struct + * object. In order to generate structured-appended symbols, it is required to + * embed headers to each symbol. You can use + * QRinput_Struct_insertStructuredAppendHeaders() to insert appropriate + * headers to each symbol. You should call this function just once before + * encoding symbols. + */ + +#ifndef __QRENCODE_H__ +#define __QRENCODE_H__ + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * Encoding mode. + */ +typedef enum { + QR_MODE_NUL = -1, ///< Terminator (NUL character). Internal use only + QR_MODE_NUM = 0, ///< Numeric mode + QR_MODE_AN, ///< Alphabet-numeric mode + QR_MODE_8, ///< 8-bit data mode + QR_MODE_KANJI, ///< Kanji (shift-jis) mode + QR_MODE_STRUCTURE, ///< Internal use only + QR_MODE_ECI, ///< ECI mode + QR_MODE_FNC1FIRST, ///< FNC1, first position + QR_MODE_FNC1SECOND, ///< FNC1, second position +} QRencodeMode; + +/** + * Level of error correction. + */ +typedef enum { + QR_ECLEVEL_L = 0, ///< lowest + QR_ECLEVEL_M, + QR_ECLEVEL_Q, + QR_ECLEVEL_H ///< highest +} QRecLevel; + +/** + * Maximum version (size) of QR-code symbol. + */ +#define QRSPEC_VERSION_MAX 40 + +/** + * Maximum version (size) of QR-code symbol. + */ +#define MQRSPEC_VERSION_MAX 4 + + +/****************************************************************************** + * Input data (qrinput.c) + *****************************************************************************/ + +/** + * Singly linked list to contain input strings. An instance of this class + * contains its version and error correction level too. It is required to + * set them by QRinput_setVersion() and QRinput_setErrorCorrectionLevel(), + * or use QRinput_new2() to instantiate an object. + */ +typedef struct _QRinput QRinput; + +/** + * Instantiate an input data object. The version is set to 0 (auto-select) + * and the error correction level is set to QR_ECLEVEL_L. + * @return an input object (initialized). On error, NULL is returned and errno + * is set to indicate the error. + * @throw ENOMEM unable to allocate memory. + */ +extern QRinput *QRinput_new(void); + +/** + * Instantiate an input data object. + * @param version version number. + * @param level Error correction level. + * @return an input object (initialized). On error, NULL is returned and errno + * is set to indicate the error. + * @throw ENOMEM unable to allocate memory for input objects. + * @throw EINVAL invalid arguments. + */ +extern QRinput *QRinput_new2(int version, QRecLevel level); + +/** + * Instantiate an input data object. Object's Micro QR Code flag is set. + * Unlike with full-sized QR Code, version number must be specified (>0). + * @param version version number (1--4). + * @param level Error correction level. + * @return an input object (initialized). On error, NULL is returned and errno + * is set to indicate the error. + * @throw ENOMEM unable to allocate memory for input objects. + * @throw EINVAL invalid arguments. + */ +extern QRinput *QRinput_newMQR(int version, QRecLevel level); + +/** + * Append data to an input object. + * The data is copied and appended to the input object. + * @param input input object. + * @param mode encoding mode. + * @param size size of data (byte). + * @param data a pointer to the memory area of the input data. + * @retval 0 success. + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + * @throw EINVAL input data is invalid. + * + */ +extern int QRinput_append(QRinput *input, QRencodeMode mode, int size, const unsigned char *data); + +/** + * Append ECI header. + * @param input input object. + * @param ecinum ECI indicator number (0 - 999999) + * @retval 0 success. + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + * @throw EINVAL input data is invalid. + * + */ +extern int QRinput_appendECIheader(QRinput *input, unsigned int ecinum); + +/** + * Get current version. + * @param input input object. + * @return current version. + */ +extern int QRinput_getVersion(QRinput *input); + +/** + * Set version of the QR code that is to be encoded. + * This function cannot be applied to Micro QR Code. + * @param input input object. + * @param version version number (0 = auto) + * @retval 0 success. + * @retval -1 invalid argument. + */ +extern int QRinput_setVersion(QRinput *input, int version); + +/** + * Get current error correction level. + * @param input input object. + * @return Current error correcntion level. + */ +extern QRecLevel QRinput_getErrorCorrectionLevel(QRinput *input); + +/** + * Set error correction level of the QR code that is to be encoded. + * This function cannot be applied to Micro QR Code. + * @param input input object. + * @param level Error correction level. + * @retval 0 success. + * @retval -1 invalid argument. + */ +extern int QRinput_setErrorCorrectionLevel(QRinput *input, QRecLevel level); + +/** + * Set version and error correction level of the QR code at once. + * This function is recommened for Micro QR Code. + * @param input input object. + * @param version version number (0 = auto) + * @param level Error correction level. + * @retval 0 success. + * @retval -1 invalid argument. + */ +extern int QRinput_setVersionAndErrorCorrectionLevel(QRinput *input, int version, QRecLevel level); + +/** + * Free the input object. + * All of data chunks in the input object are freed too. + * @param input input object. + */ +extern void QRinput_free(QRinput *input); + +/** + * Validate the input data. + * @param mode encoding mode. + * @param size size of data (byte). + * @param data a pointer to the memory area of the input data. + * @retval 0 success. + * @retval -1 invalid arguments. + */ +extern int QRinput_check(QRencodeMode mode, int size, const unsigned char *data); + +/** + * Set of QRinput for structured symbols. + */ +typedef struct _QRinput_Struct QRinput_Struct; + +/** + * Instantiate a set of input data object. + * @return an instance of QRinput_Struct. On error, NULL is returned and errno + * is set to indicate the error. + * @throw ENOMEM unable to allocate memory. + */ +extern QRinput_Struct *QRinput_Struct_new(void); + +/** + * Set parity of structured symbols. + * @param s structured input object. + * @param parity parity of s. + */ +extern void QRinput_Struct_setParity(QRinput_Struct *s, unsigned char parity); + +/** + * Append a QRinput object to the set. QRinput created by QRinput_newMQR() + * will be rejected. + * @warning never append the same QRinput object twice or more. + * @param s structured input object. + * @param input an input object. + * @retval >0 number of input objects in the structure. + * @retval -1 an error occurred. See Exceptions for the details. + * @throw ENOMEM unable to allocate memory. + * @throw EINVAL invalid arguments. + */ +extern int QRinput_Struct_appendInput(QRinput_Struct *s, QRinput *input); + +/** + * Free all of QRinput in the set. + * @param s a structured input object. + */ +extern void QRinput_Struct_free(QRinput_Struct *s); + +/** + * Split a QRinput to QRinput_Struct. It calculates a parity, set it, then + * insert structured-append headers. QRinput created by QRinput_newMQR() will + * be rejected. + * @param input input object. Version number and error correction level must be + * set. + * @return a set of input data. On error, NULL is returned, and errno is set + * to indicate the error. See Exceptions for the details. + * @throw ERANGE input data is too large. + * @throw EINVAL invalid input data. + * @throw ENOMEM unable to allocate memory. + */ +extern QRinput_Struct *QRinput_splitQRinputToStruct(QRinput *input); + +/** + * Insert structured-append headers to the input structure. It calculates + * a parity and set it if the parity is not set yet. + * @param s input structure + * @retval 0 success. + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory. + */ +extern int QRinput_Struct_insertStructuredAppendHeaders(QRinput_Struct *s); + +/** + * Set FNC1-1st position flag. + */ +extern int QRinput_setFNC1First(QRinput *input); + +/** + * Set FNC1-2nd position flag and application identifier. + */ +extern int QRinput_setFNC1Second(QRinput *input, unsigned char appid); + +/****************************************************************************** + * QRcode output (qrencode.c) + *****************************************************************************/ + +/** + * QRcode class. + * Symbol data is represented as an array contains width*width uchars. + * Each uchar represents a module (dot). If the less significant bit of + * the uchar is 1, the corresponding module is black. The other bits are + * meaningless for usual applications, but here its specification is described. + * + *
+ * MSB 76543210 LSB
+ *     |||||||`- 1=black/0=white
+ *     ||||||`-- data and ecc code area
+ *     |||||`--- format information
+ *     ||||`---- version information
+ *     |||`----- timing pattern
+ *     ||`------ alignment pattern
+ *     |`------- finder pattern and separator
+ *     `-------- non-data modules (format, timing, etc.)
+ * 
+ */ +typedef struct { + int version; ///< version of the symbol + int width; ///< width of the symbol + unsigned char *data; ///< symbol data +} QRcode; + +/** + * Singly-linked list of QRcode. Used to represent a structured symbols. + * A list is terminated with NULL. + */ +typedef struct _QRcode_List { + QRcode *code; + struct _QRcode_List *next; +} QRcode_List; + +/** + * Create a symbol from the input data. + * @warning This function is THREAD UNSAFE when pthread is disabled. + * @param input input data. + * @return an instance of QRcode class. The version of the result QRcode may + * be larger than the designated version. On error, NULL is returned, + * and errno is set to indicate the error. See Exceptions for the + * details. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory for input objects. + */ +extern QRcode *QRcode_encodeInput(QRinput *input); + +/** + * Create a symbol from the string. The library automatically parses the input + * string and encodes in a QR Code symbol. + * @warning This function is THREAD UNSAFE when pthread is disabled. + * @param string input string. It must be NUL terminated. + * @param version version of the symbol. If 0, the library chooses the minimum + * version for the given input data. + * @param level error correction level. + * @param hint tell the library how Japanese Kanji characters should be + * encoded. If QR_MODE_KANJI is given, the library assumes that the + * given string contains Shift-JIS characters and encodes them in + * Kanji-mode. If QR_MODE_8 is given, all of non-alphanumerical + * characters will be encoded as is. If you want to embed UTF-8 + * string, choose this. Other mode will cause EINVAL error. + * @param casesensitive case-sensitive(1) or not(0). + * @return an instance of QRcode class. The version of the result QRcode may + * be larger than the designated version. On error, NULL is returned, + * and errno is set to indicate the error. See Exceptions for the + * details. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory for input objects. + * @throw ERANGE input data is too large. + */ +extern QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive); + +/** + * Same to QRcode_encodeString(), but encode whole data in 8-bit mode. + * @warning This function is THREAD UNSAFE when pthread is disabled. + */ +extern QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level); + +/** + * Micro QR Code version of QRcode_encodeString(). + * @warning This function is THREAD UNSAFE when pthread is disabled. + */ +extern QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive); + +/** + * Micro QR Code version of QRcode_encodeString8bit(). + * @warning This function is THREAD UNSAFE when pthread is disabled. + */ +extern QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level); + +/** + * Encode byte stream (may include '\0') in 8-bit mode. + * @warning This function is THREAD UNSAFE when pthread is disabled. + * @param size size of the input data. + * @param data input data. + * @param version version of the symbol. If 0, the library chooses the minimum + * version for the given input data. + * @param level error correction level. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory for input objects. + * @throw ERANGE input data is too large. + */ +extern QRcode *QRcode_encodeData(int size, const unsigned char *data, int version, QRecLevel level); + +/** + * Micro QR Code version of QRcode_encodeData(). + * @warning This function is THREAD UNSAFE when pthread is disabled. + */ +extern QRcode *QRcode_encodeDataMQR(int size, const unsigned char *data, int version, QRecLevel level); + +/** + * Free the instance of QRcode class. + * @param qrcode an instance of QRcode class. + */ +extern void QRcode_free(QRcode *qrcode); + +/** + * Create structured symbols from the input data. + * @warning This function is THREAD UNSAFE when pthread is disabled. + * @param s + * @return a singly-linked list of QRcode. + */ +extern QRcode_List *QRcode_encodeInputStructured(QRinput_Struct *s); + +/** + * Create structured symbols from the string. The library automatically parses + * the input string and encodes in a QR Code symbol. + * @warning This function is THREAD UNSAFE when pthread is disabled. + * @param string input string. It must be NUL terminated. + * @param version version of the symbol. + * @param level error correction level. + * @param hint tell the library how Japanese Kanji characters should be + * encoded. If QR_MODE_KANJI is given, the library assumes that the + * given string contains Shift-JIS characters and encodes them in + * Kanji-mode. If QR_MODE_8 is given, all of non-alphanumerical + * characters will be encoded as is. If you want to embed UTF-8 + * string, choose this. Other mode will cause EINVAL error. + * @param casesensitive case-sensitive(1) or not(0). + * @return a singly-linked list of QRcode. On error, NULL is returned, and + * errno is set to indicate the error. See Exceptions for the details. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory for input objects. + */ +extern QRcode_List *QRcode_encodeStringStructured(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive); + +/** + * Same to QRcode_encodeStringStructured(), but encode whole data in 8-bit mode. + * @warning This function is THREAD UNSAFE when pthread is disabled. + */ +extern QRcode_List *QRcode_encodeString8bitStructured(const char *string, int version, QRecLevel level); + +/** + * Create structured symbols from byte stream (may include '\0'). Wholde data + * are encoded in 8-bit mode. + * @warning This function is THREAD UNSAFE when pthread is disabled. + * @param size size of the input data. + * @param data input dat. + * @param version version of the symbol. + * @param level error correction level. + * @return a singly-linked list of QRcode. On error, NULL is returned, and + * errno is set to indicate the error. See Exceptions for the details. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory for input objects. + */ +extern QRcode_List *QRcode_encodeDataStructured(int size, const unsigned char *data, int version, QRecLevel level); + +/** + * Return the number of symbols included in a QRcode_List. + * @param qrlist a head entry of a QRcode_List. + * @return number of symbols in the list. + */ +extern int QRcode_List_size(QRcode_List *qrlist); + +/** + * Free the QRcode_List. + * @param qrlist a head entry of a QRcode_List. + */ +extern void QRcode_List_free(QRcode_List *qrlist); + + +/****************************************************************************** + * System utilities + *****************************************************************************/ + +/** + * Return a string that identifies the library version. + * @param major_version + * @param minor_version + * @param micro_version + */ +extern void QRcode_APIVersion(int *major_version, int *minor_version, int *micro_version); + +/** + * Return a string that identifies the library version. + * @return a string identifies the library version. The string is held by the + * library. Do NOT free it. + */ +extern char *QRcode_APIVersionString(void); + +/** + * Clear all caches. This is only for debug purpose. If you are attacking a + * complicated memory leak bug, try this to reduce the reachable blocks record. + * @warning This function is THREAD UNSAFE when pthread is disabled. + */ +extern void QRcode_clearCache(void); + +#if defined(__cplusplus) +} +#endif + +#endif /* __QRENCODE_H__ */ diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/qrencode_inner.h b/dde-file-manager-5.5.3/3rdparty/qrencode/qrencode_inner.h new file mode 100644 index 0000000..3c40d06 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/qrencode_inner.h @@ -0,0 +1,88 @@ +/** + * qrencode - QR Code encoder + * + * Header for test use + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __QRENCODE_INNER_H__ +#define __QRENCODE_INNER_H__ + +/** + * This header file includes definitions for test use. + */ + +/****************************************************************************** + * Raw code + *****************************************************************************/ + +typedef struct { + int dataLength; + unsigned char *data; + int eccLength; + unsigned char *ecc; +} RSblock; + +typedef struct { + int version; + int dataLength; + int eccLength; + unsigned char *datacode; + unsigned char *ecccode; + int b1; + int blocks; + RSblock *rsblock; + int count; +} QRRawCode; + +extern QRRawCode *QRraw_new(QRinput *input); +extern unsigned char QRraw_getCode(QRRawCode *raw); +extern void QRraw_free(QRRawCode *raw); + +/****************************************************************************** + * Raw code for Micro QR Code + *****************************************************************************/ + +typedef struct { + int version; + int dataLength; + int eccLength; + unsigned char *datacode; + unsigned char *ecccode; + RSblock *rsblock; + int oddbits; + int count; +} MQRRawCode; + +extern MQRRawCode *MQRraw_new(QRinput *input); +extern unsigned char MQRraw_getCode(MQRRawCode *raw); +extern void MQRraw_free(MQRRawCode *raw); + +/****************************************************************************** + * Frame filling + *****************************************************************************/ +extern unsigned char *FrameFiller_test(int version); +extern unsigned char *FrameFiller_testMQR(int version); + +/****************************************************************************** + * QR-code encoding + *****************************************************************************/ +extern QRcode *QRcode_encodeMask(QRinput *input, int mask); +extern QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask); +extern QRcode *QRcode_new(int version, int width, unsigned char *data); + +#endif /* __QRENCODE_INNER_H__ */ diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/qrinput.c b/dde-file-manager-5.5.3/3rdparty/qrencode/qrinput.c new file mode 100644 index 0000000..fb62c29 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/qrinput.c @@ -0,0 +1,1731 @@ +/* + * qrencode - QR Code encoder + * + * Input data chunk class + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include + +#include "qrencode.h" +#include "qrspec.h" +#include "mqrspec.h" +#include "bitstream.h" +#include "qrinput.h" + +#define UNUSED(x) (void)x; +/****************************************************************************** + * Utilities + *****************************************************************************/ +int QRinput_isSplittableMode(QRencodeMode mode) +{ + return (mode >= QR_MODE_NUM && mode <= QR_MODE_KANJI); +} + +/****************************************************************************** + * Entry of input data + *****************************************************************************/ + +static QRinput_List *QRinput_List_newEntry(QRencodeMode mode, int size, const unsigned char *data) +{ + QRinput_List *entry; + + if(QRinput_check(mode, size, data)) { + errno = EINVAL; + return NULL; + } + + entry = (QRinput_List *)malloc(sizeof(QRinput_List)); + if(entry == NULL) return NULL; + + entry->mode = mode; + entry->size = size; + if(size > 0) { + entry->data = (unsigned char *)malloc(size); + if(entry->data == NULL) { + free(entry); + return NULL; + } + memcpy(entry->data, data, size); + } + entry->bstream = NULL; + entry->next = NULL; + + return entry; +} + +static void QRinput_List_freeEntry(QRinput_List *entry) +{ + if(entry != NULL) { + free(entry->data); + BitStream_free(entry->bstream); + free(entry); + } +} + +static QRinput_List *QRinput_List_dup(QRinput_List *entry) +{ + QRinput_List *n; + + n = (QRinput_List *)malloc(sizeof(QRinput_List)); + if(n == NULL) return NULL; + + n->mode = entry->mode; + n->size = entry->size; + n->data = (unsigned char *)malloc(n->size); + if(n->data == NULL) { + free(n); + return NULL; + } + memcpy(n->data, entry->data, entry->size); + n->bstream = NULL; + n->next = NULL; + + return n; +} + +/****************************************************************************** + * Input Data + *****************************************************************************/ + +QRinput *QRinput_new(void) +{ + return QRinput_new2(0, QR_ECLEVEL_L); +} + +QRinput *QRinput_new2(int version, QRecLevel level) +{ + QRinput *input; + + if(version < 0 || version > QRSPEC_VERSION_MAX || level > QR_ECLEVEL_H) { + errno = EINVAL; + return NULL; + } + + input = (QRinput *)malloc(sizeof(QRinput)); + if(input == NULL) return NULL; + + input->head = NULL; + input->tail = NULL; + input->version = version; + input->level = level; + input->mqr = 0; + input->fnc1 = 0; + + return input; +} + +QRinput *QRinput_newMQR(int version, QRecLevel level) +{ + QRinput *input; + + if(version <= 0 || version > MQRSPEC_VERSION_MAX) goto INVALID; + if((MQRspec_getECCLength(version, level) == 0)) goto INVALID; + + input = QRinput_new2(version, level); + if(input == NULL) return NULL; + + input->mqr = 1; + + return input; + +INVALID: + errno = EINVAL; + return NULL; +} + +int QRinput_getVersion(QRinput *input) +{ + return input->version; +} + +int QRinput_setVersion(QRinput *input, int version) +{ + if(input->mqr || version < 0 || version > QRSPEC_VERSION_MAX) { + errno = EINVAL; + return -1; + } + + input->version = version; + + return 0; +} + +QRecLevel QRinput_getErrorCorrectionLevel(QRinput *input) +{ + return input->level; +} + +int QRinput_setErrorCorrectionLevel(QRinput *input, QRecLevel level) +{ + if(input->mqr || level > QR_ECLEVEL_H) { + errno = EINVAL; + return -1; + } + + input->level = level; + + return 0; +} + +int QRinput_setVersionAndErrorCorrectionLevel(QRinput *input, int version, QRecLevel level) +{ + if(input->mqr) { + if(version <= 0 || version > MQRSPEC_VERSION_MAX) goto INVALID; + if((MQRspec_getECCLength(version, level) == 0)) goto INVALID; + } else { + if(version < 0 || version > QRSPEC_VERSION_MAX) goto INVALID; + if(level > QR_ECLEVEL_H) goto INVALID; + } + + input->version = version; + input->level = level; + + return 0; + +INVALID: + errno = EINVAL; + return -1; +} + +static void QRinput_appendEntry(QRinput *input, QRinput_List *entry) +{ + if(input->tail == NULL) { + input->head = entry; + input->tail = entry; + } else { + input->tail->next = entry; + input->tail = entry; + } + entry->next = NULL; +} + +int QRinput_append(QRinput *input, QRencodeMode mode, int size, const unsigned char *data) +{ + QRinput_List *entry; + + entry = QRinput_List_newEntry(mode, size, data); + if(entry == NULL) { + return -1; + } + + QRinput_appendEntry(input, entry); + + return 0; +} + +/** + * Insert a structured-append header to the head of the input data. + * @param input input data. + * @param size number of structured symbols. + * @param number index number of the symbol. (1 <= number <= size) + * @param parity parity among input data. (NOTE: each symbol of a set of structured symbols has the same parity data) + * @retval 0 success. + * @retval -1 error occurred and errno is set to indeicate the error. See Execptions for the details. + * @throw EINVAL invalid parameter. + * @throw ENOMEM unable to allocate memory. + */ +__STATIC int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int number, unsigned char parity) +{ + QRinput_List *entry; + unsigned char buf[3]; + + if(size > MAX_STRUCTURED_SYMBOLS) { + errno = EINVAL; + return -1; + } + if(number <= 0 || number > size) { + errno = EINVAL; + return -1; + } + + buf[0] = (unsigned char)size; + buf[1] = (unsigned char)number; + buf[2] = parity; + entry = QRinput_List_newEntry(QR_MODE_STRUCTURE, 3, buf); + if(entry == NULL) { + return -1; + } + + entry->next = input->head; + input->head = entry; + + return 0; +} + +int QRinput_appendECIheader(QRinput *input, unsigned int ecinum) +{ + unsigned char data[4]; + + if(ecinum > 999999) { + errno = EINVAL; + return -1; + } + + /* We manually create byte array of ecinum because + (unsigned char *)&ecinum may cause bus error on some architectures, */ + data[0] = ecinum & 0xff; + data[1] = (ecinum >> 8) & 0xff; + data[2] = (ecinum >> 16) & 0xff; + data[3] = (ecinum >> 24) & 0xff; + return QRinput_append(input, QR_MODE_ECI, 4, data); +} + +void QRinput_free(QRinput *input) +{ + QRinput_List *list, *next; + + if(input != NULL) { + list = input->head; + while(list != NULL) { + next = list->next; + QRinput_List_freeEntry(list); + list = next; + } + free(input); + } +} + +static unsigned char QRinput_calcParity(QRinput *input) +{ + unsigned char parity = 0; + QRinput_List *list; + int i; + + list = input->head; + while(list != NULL) { + if(list->mode != QR_MODE_STRUCTURE) { + for(i=list->size-1; i>=0; i--) { + parity ^= list->data[i]; + } + } + list = list->next; + } + + return parity; +} + +QRinput *QRinput_dup(QRinput *input) +{ + QRinput *n; + QRinput_List *list, *e; + + if(input->mqr) { + n = QRinput_newMQR(input->version, input->level); + } else { + n = QRinput_new2(input->version, input->level); + } + if(n == NULL) return NULL; + + list = input->head; + while(list != NULL) { + e = QRinput_List_dup(list); + if(e == NULL) { + QRinput_free(n); + return NULL; + } + QRinput_appendEntry(n, e); + list = list->next; + } + + return n; +} + +/****************************************************************************** + * Numeric data + *****************************************************************************/ + +/** + * Check the input data. + * @param size + * @param data + * @return result + */ +static int QRinput_checkModeNum(int size, const char *data) +{ + int i; + + for(i=0; i '9') + return -1; + } + + return 0; +} + +/** + * Estimates the length of the encoded bit stream of numeric data. + * @param size + * @return number of bits + */ +int QRinput_estimateBitsModeNum(int size) +{ + int w; + int bits; + + w = size / 3; + bits = w * 10; + switch(size - w * 3) { + case 1: + bits += 4; + break; + case 2: + bits += 7; + break; + default: + break; + } + + return bits; +} + +/** + * Convert the number data to a bit stream. + * @param entry + * @param mqr + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + */ +static int QRinput_encodeModeNum(QRinput_List *entry, int version, int mqr) +{ + int words, i, ret; + unsigned int val; + + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + if(mqr) { + if(version > 1) { + ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_NUM); + if(ret < 0) goto ABORT; + } + ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_NUM, version), entry->size); + if(ret < 0) goto ABORT; + } else { + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_NUM); + if(ret < 0) goto ABORT; + + ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_NUM, version), entry->size); + if(ret < 0) goto ABORT; + } + + words = entry->size / 3; + for(i=0; idata[i*3 ] - '0') * 100; + val += (entry->data[i*3+1] - '0') * 10; + val += (entry->data[i*3+2] - '0'); + + ret = BitStream_appendNum(entry->bstream, 10, val); + if(ret < 0) goto ABORT; + } + + if(entry->size - words * 3 == 1) { + val = entry->data[words*3] - '0'; + ret = BitStream_appendNum(entry->bstream, 4, val); + if(ret < 0) goto ABORT; + } else if(entry->size - words * 3 == 2) { + val = (entry->data[words*3 ] - '0') * 10; + val += (entry->data[words*3+1] - '0'); + BitStream_appendNum(entry->bstream, 7, val); + if(ret < 0) goto ABORT; + } + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + +/****************************************************************************** + * Alphabet-numeric data + *****************************************************************************/ + +const signed char QRinput_anTable[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +/** + * Check the input data. + * @param size + * @param data + * @return result + */ +static int QRinput_checkModeAn(int size, const char *data) +{ + int i; + + for(i=0; ibstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + if(mqr) { + if(version < 2) { + errno = EINVAL; + goto ABORT; + } + ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_AN); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_AN, version), entry->size); + if(ret < 0) goto ABORT; + } else { + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_AN); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_AN, version), entry->size); + if(ret < 0) goto ABORT; + } + + words = entry->size / 2; + for(i=0; idata[i*2 ]) * 45; + val += (unsigned int)QRinput_lookAnTable(entry->data[i*2+1]); + + ret = BitStream_appendNum(entry->bstream, 11, val); + if(ret < 0) goto ABORT; + } + + if(entry->size & 1) { + val = (unsigned int)QRinput_lookAnTable(entry->data[words * 2]); + + ret = BitStream_appendNum(entry->bstream, 6, val); + if(ret < 0) goto ABORT; + } + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + +/****************************************************************************** + * 8 bit data + *****************************************************************************/ + +/** + * Estimates the length of the encoded bit stream of 8 bit data. + * @param size + * @return number of bits + */ +int QRinput_estimateBitsMode8(int size) +{ + return size * 8; +} + +/** + * Convert the 8bits data to a bit stream. + * @param entry + * @param mqr + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + */ +static int QRinput_encodeMode8(QRinput_List *entry, int version, int mqr) +{ + int ret; + + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + if(mqr) { + if(version < 3) { + errno = EINVAL; + goto ABORT; + } + ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_8); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_8, version), entry->size); + if(ret < 0) goto ABORT; + } else { + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_8); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_8, version), entry->size); + if(ret < 0) goto ABORT; + } + + ret = BitStream_appendBytes(entry->bstream, entry->size, entry->data); + if(ret < 0) goto ABORT; + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + + +/****************************************************************************** + * Kanji data + *****************************************************************************/ + +/** + * Estimates the length of the encoded bit stream of kanji data. + * @param size + * @return number of bits + */ +int QRinput_estimateBitsModeKanji(int size) +{ + return (size / 2) * 13; +} + +/** + * Check the input data. + * @param size + * @param data + * @return result + */ +static int QRinput_checkModeKanji(int size, const unsigned char *data) +{ + int i; + unsigned int val; + + if(size & 1) + return -1; + + for(i=0; i 0x9ffc && val < 0xe040) || val > 0xebbf) { + return -1; + } + } + + return 0; +} + +/** + * Convert the kanji data to a bit stream. + * @param entry + * @param mqr + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + * @throw EINVAL invalid version. + */ +static int QRinput_encodeModeKanji(QRinput_List *entry, int version, int mqr) +{ + int ret, i; + unsigned int val, h; + + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + if(mqr) { + if(version < 2) { + errno = EINVAL; + goto ABORT; + } + ret = BitStream_appendNum(entry->bstream, version - 1, MQRSPEC_MODEID_KANJI); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, MQRspec_lengthIndicator(QR_MODE_KANJI, version), entry->size/2); + if(ret < 0) goto ABORT; + } else { + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_KANJI); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, QRspec_lengthIndicator(QR_MODE_KANJI, version), entry->size/2); + if(ret < 0) goto ABORT; + } + + for(i=0; isize; i+=2) { + val = ((unsigned int)entry->data[i] << 8) | entry->data[i+1]; + if(val <= 0x9ffc) { + val -= 0x8140; + } else { + val -= 0xc140; + } + h = (val >> 8) * 0xc0; + val = (val & 0xff) + h; + + ret = BitStream_appendNum(entry->bstream, 13, val); + if(ret < 0) goto ABORT; + } + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + +/****************************************************************************** + * Structured Symbol + *****************************************************************************/ + +/** + * Convert a structure symbol code to a bit stream. + * @param entry + * @param mqr + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + * @throw EINVAL invalid entry. + */ +static int QRinput_encodeModeStructure(QRinput_List *entry, int mqr) +{ + int ret; + + if(mqr) { + errno = EINVAL; + return -1; + } + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_STRUCTURE); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, 4, entry->data[1] - 1); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, 4, entry->data[0] - 1); + if(ret < 0) goto ABORT; + ret = BitStream_appendNum(entry->bstream, 8, entry->data[2]); + if(ret < 0) goto ABORT; + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + +/****************************************************************************** + * FNC1 + *****************************************************************************/ + +static int QRinput_checkModeFNC1Second(int size, const unsigned char *data) +{ + UNUSED(data) + if(size != 1) return -1; + + return 0; +} + +static int QRinput_encodeModeFNC1Second(QRinput_List *entry, int version) +{ + UNUSED(version) + int ret; + + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_FNC1SECOND); + if(ret < 0) goto ABORT; + + ret = BitStream_appendBytes(entry->bstream, 1, entry->data); + if(ret < 0) goto ABORT; + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + +/****************************************************************************** + * ECI header + *****************************************************************************/ +static unsigned int QRinput_decodeECIfromByteArray(unsigned char *data) +{ + int i; + unsigned int ecinum; + + ecinum = 0; + for(i=0; i<4; i++) { + ecinum = ecinum << 8; + ecinum |= data[3-i]; + } + + return ecinum; +} + +int QRinput_estimateBitsModeECI(unsigned char *data) +{ + unsigned int ecinum; + + ecinum = QRinput_decodeECIfromByteArray(data);; + + /* See Table 4 of JISX 0510:2004 pp.17. */ + if(ecinum < 128) { + return MODE_INDICATOR_SIZE + 8; + } else if(ecinum < 16384) { + return MODE_INDICATOR_SIZE + 16; + } else { + return MODE_INDICATOR_SIZE + 24; + } +} + +static int QRinput_encodeModeECI(QRinput_List *entry, int version) +{ + UNUSED(version) + int ret, words; + unsigned int ecinum, code; + + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) return -1; + + ecinum = QRinput_decodeECIfromByteArray(entry->data);; + + /* See Table 4 of JISX 0510:2004 pp.17. */ + if(ecinum < 128) { + words = 1; + code = ecinum; + } else if(ecinum < 16384) { + words = 2; + code = 0x8000 + ecinum; + } else { + words = 3; + code = 0xc0000 + ecinum; + } + + ret = BitStream_appendNum(entry->bstream, 4, QRSPEC_MODEID_ECI); + if(ret < 0) goto ABORT; + + ret = BitStream_appendNum(entry->bstream, words * 8, code); + if(ret < 0) goto ABORT; + + return 0; +ABORT: + BitStream_free(entry->bstream); + entry->bstream = NULL; + return -1; +} + +/****************************************************************************** + * Validation + *****************************************************************************/ + +int QRinput_check(QRencodeMode mode, int size, const unsigned char *data) +{ + if((mode == QR_MODE_FNC1FIRST && size < 0) || size <= 0) return -1; + + switch(mode) { + case QR_MODE_NUM: + return QRinput_checkModeNum(size, (const char *)data); + case QR_MODE_AN: + return QRinput_checkModeAn(size, (const char *)data); + case QR_MODE_KANJI: + return QRinput_checkModeKanji(size, data); + case QR_MODE_8: + return 0; + case QR_MODE_STRUCTURE: + return 0; + case QR_MODE_ECI: + return 0; + case QR_MODE_FNC1FIRST: + return 0; + case QR_MODE_FNC1SECOND: + return QRinput_checkModeFNC1Second(size, data); + case QR_MODE_NUL: + break; + } + + return -1; +} + +/****************************************************************************** + * Estimation of the bit length + *****************************************************************************/ + +/** + * Estimates the length of the encoded bit stream on the current version. + * @param entry + * @param version version of the symbol + * @param mqr + * @return number of bits + */ +static int QRinput_estimateBitStreamSizeOfEntry(QRinput_List *entry, int version, int mqr) +{ + int bits = 0; + int l, m; + int num; + + if(version == 0) version = 1; + + switch(entry->mode) { + case QR_MODE_NUM: + bits = QRinput_estimateBitsModeNum(entry->size); + break; + case QR_MODE_AN: + bits = QRinput_estimateBitsModeAn(entry->size); + break; + case QR_MODE_8: + bits = QRinput_estimateBitsMode8(entry->size); + break; + case QR_MODE_KANJI: + bits = QRinput_estimateBitsModeKanji(entry->size); + break; + case QR_MODE_STRUCTURE: + return STRUCTURE_HEADER_SIZE; + case QR_MODE_ECI: + bits = QRinput_estimateBitsModeECI(entry->data); + break; + case QR_MODE_FNC1FIRST: + return MODE_INDICATOR_SIZE; + case QR_MODE_FNC1SECOND: + return MODE_INDICATOR_SIZE + 8; + default: + return 0; + } + + if(mqr) { + l = QRspec_lengthIndicator(entry->mode, version); + m = version - 1; + bits += l + m; + } else { + l = QRspec_lengthIndicator(entry->mode, version); + m = 1 << l; + num = (entry->size + m - 1) / m; + + bits += num * (MODE_INDICATOR_SIZE + l); + } + + return bits; +} + +/** + * Estimates the length of the encoded bit stream of the data. + * @param input input data + * @param version version of the symbol + * @return number of bits + */ +__STATIC int QRinput_estimateBitStreamSize(QRinput *input, int version) +{ + QRinput_List *list; + int bits = 0; + + list = input->head; + while(list != NULL) { + bits += QRinput_estimateBitStreamSizeOfEntry(list, version, input->mqr); + list = list->next; + } + + return bits; +} + +/** + * Estimates the required version number of the symbol. + * @param input input data + * @return required version number + */ +static int QRinput_estimateVersion(QRinput *input) +{ + int bits; + int version, prev; + + version = 0; + do { + prev = version; + bits = QRinput_estimateBitStreamSize(input, prev); + version = QRspec_getMinimumVersion((bits + 7) / 8, input->level); + if (version < 0) { + return -1; + } + } while (version > prev); + + return version; +} + +/** + * Returns required length in bytes for specified mode, version and bits. + * @param mode + * @param version + * @param bits + * @return required length of code words in bytes. + */ +__STATIC int QRinput_lengthOfCode(QRencodeMode mode, int version, int bits) +{ + int payload, size, chunks, remain, maxsize; + + payload = bits - 4 - QRspec_lengthIndicator(mode, version); + switch(mode) { + case QR_MODE_NUM: + chunks = payload / 10; + remain = payload - chunks * 10; + size = chunks * 3; + if(remain >= 7) { + size += 2; + } else if(remain >= 4) { + size += 1; + } + break; + case QR_MODE_AN: + chunks = payload / 11; + remain = payload - chunks * 11; + size = chunks * 2; + if(remain >= 6) size++; + break; + case QR_MODE_8: + size = payload / 8; + break; + case QR_MODE_KANJI: + size = (payload / 13) * 2; + break; + case QR_MODE_STRUCTURE: + size = payload / 8; + break; + default: + size = 0; + break; + } + maxsize = QRspec_maximumWords(mode, version); + if(size < 0) size = 0; + if(maxsize > 0 && size > maxsize) size = maxsize; + + return size; +} + +/****************************************************************************** + * Data conversion + *****************************************************************************/ + +/** + * Convert the input data in the data chunk to a bit stream. + * @param entry + * @return number of bits (>0) or -1 for failure. + */ +static int QRinput_encodeBitStream(QRinput_List *entry, int version, int mqr) +{ + int words, ret; + QRinput_List *st1 = NULL, *st2 = NULL; + + if(entry->bstream != NULL) { + BitStream_free(entry->bstream); + entry->bstream = NULL; + } + + words = QRspec_maximumWords(entry->mode, version); + if(words != 0 && entry->size > words) { + st1 = QRinput_List_newEntry(entry->mode, words, entry->data); + if(st1 == NULL) goto ABORT; + st2 = QRinput_List_newEntry(entry->mode, entry->size - words, &entry->data[words]); + if(st2 == NULL) goto ABORT; + + ret = QRinput_encodeBitStream(st1, version, mqr); + if(ret < 0) goto ABORT; + ret = QRinput_encodeBitStream(st2, version, mqr); + if(ret < 0) goto ABORT; + entry->bstream = BitStream_new(); + if(entry->bstream == NULL) goto ABORT; + ret = BitStream_append(entry->bstream, st1->bstream); + if(ret < 0) goto ABORT; + ret = BitStream_append(entry->bstream, st2->bstream); + if(ret < 0) goto ABORT; + QRinput_List_freeEntry(st1); + QRinput_List_freeEntry(st2); + } else { + ret = 0; + switch(entry->mode) { + case QR_MODE_NUM: + ret = QRinput_encodeModeNum(entry, version, mqr); + break; + case QR_MODE_AN: + ret = QRinput_encodeModeAn(entry, version, mqr); + break; + case QR_MODE_8: + ret = QRinput_encodeMode8(entry, version, mqr); + break; + case QR_MODE_KANJI: + ret = QRinput_encodeModeKanji(entry, version, mqr); + break; + case QR_MODE_STRUCTURE: + ret = QRinput_encodeModeStructure(entry, mqr); + break; + case QR_MODE_ECI: + ret = QRinput_encodeModeECI(entry, version); + break; + case QR_MODE_FNC1SECOND: + ret = QRinput_encodeModeFNC1Second(entry, version); + break; + default: + break; + } + if(ret < 0) return -1; + } + + return BitStream_size(entry->bstream); +ABORT: + QRinput_List_freeEntry(st1); + QRinput_List_freeEntry(st2); + return -1; +} + +/** + * Convert the input data to a bit stream. + * @param input input data. + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + */ +static int QRinput_createBitStream(QRinput *input) +{ + QRinput_List *list; + int bits, total = 0; + + list = input->head; + while(list != NULL) { + bits = QRinput_encodeBitStream(list, input->version, input->mqr); + if(bits < 0) return -1; + total += bits; + list = list->next; + } + + return total; +} + +/** + * Convert the input data to a bit stream. + * When the version number is given and that is not sufficient, it is increased + * automatically. + * @param input input data. + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ENOMEM unable to allocate memory. + * @throw ERANGE input is too large. + */ +static int QRinput_convertData(QRinput *input) +{ + int bits; + int ver; + + ver = QRinput_estimateVersion(input); + if(ver > QRinput_getVersion(input)) { + QRinput_setVersion(input, ver); + } + + for(;;) { + bits = QRinput_createBitStream(input); + if(bits < 0) return -1; + ver = QRspec_getMinimumVersion((bits + 7) / 8, input->level); + if(ver < 0) { + errno = ERANGE; + return -1; + } else if(ver > QRinput_getVersion(input)) { + QRinput_setVersion(input, ver); + } else { + break; + } + } + + return 0; +} + +/** + * Append padding bits for the input data. + * @param bstream Bitstream to be appended. + * @param input input data. + * @retval 0 success + * @retval -1 an error occurred and errno is set to indeicate the error. + * See Execptions for the details. + * @throw ERANGE input data is too large. + * @throw ENOMEM unable to allocate memory. + */ +static int QRinput_appendPaddingBit(BitStream *bstream, QRinput *input) +{ + int bits, maxbits, words, maxwords, i, ret; + BitStream *padding = NULL; + unsigned char *padbuf; + int padlen; + + bits = BitStream_size(bstream); + maxwords = QRspec_getDataLength(input->version, input->level); + maxbits = maxwords * 8; + + if(maxbits < bits) { + errno = ERANGE; + return -1; + } + if(maxbits == bits) { + return 0; + } + + if(maxbits - bits <= 4) { + ret = BitStream_appendNum(bstream, maxbits - bits, 0); + goto DONE; + } + + words = (bits + 4 + 7) / 8; + + padding = BitStream_new(); + if(padding == NULL) return -1; + ret = BitStream_appendNum(padding, words * 8 - bits, 0); + if(ret < 0) goto DONE; + + padlen = maxwords - words; + if(padlen > 0) { + padbuf = (unsigned char *)malloc(padlen); + if(padbuf == NULL) { + ret = -1; + goto DONE; + } + for(i=0; iversion, input->level); + maxwords = maxbits / 8; + + if(maxbits < bits) { + errno = ERANGE; + return -1; + } + if(maxbits == bits) { + return 0; + } + + termbits = input->version * 2 + 1; + + if(maxbits - bits <= termbits) { + ret = BitStream_appendNum(bstream, maxbits - bits, 0); + goto DONE; + } + + bits += termbits; + + words = (bits + 7) / 8; + if(maxbits - words * 8 > 0) { + termbits += words * 8 - bits; + if(words == maxwords) termbits += maxbits - words * 8; + } else { + termbits += words * 8 - bits; + } + padding = BitStream_new(); + if(padding == NULL) return -1; + ret = BitStream_appendNum(padding, termbits, 0); + if(ret < 0) goto DONE; + + padlen = maxwords - words; + if(padlen > 0) { + padbuf = (unsigned char *)malloc(padlen); + if(padbuf == NULL) { + ret = -1; + goto DONE; + } + for(i=0; i 0) { + ret = BitStream_appendNum(padding, termbits, 0); + if(ret < 0) goto DONE; + } + } + + ret = BitStream_append(bstream, padding); + +DONE: + BitStream_free(padding); + return ret; +} + +static int QRinput_insertFNC1Header(QRinput *input) +{ + QRinput_List *entry = NULL; + + if(input->fnc1 == 1) { + entry = QRinput_List_newEntry(QR_MODE_FNC1FIRST, 0, NULL); + } else if(input->fnc1 == 2) { + entry = QRinput_List_newEntry(QR_MODE_FNC1SECOND, 1, &(input->appid)); + } + if(entry == NULL) { + return -1; + } + + if(input->head->mode != QR_MODE_STRUCTURE || input->head->mode != QR_MODE_ECI) { + entry->next = input->head; + input->head = entry; + } else { + entry->next = input->head->next; + input->head->next = entry; + } + + return 0; +} + +/** + * Merge all bit streams in the input data. + * @param input input data. + * @return merged bit stream + */ + +__STATIC BitStream *QRinput_mergeBitStream(QRinput *input) +{ + BitStream *bstream; + QRinput_List *list; + int ret; + + if(input->mqr) { + if(QRinput_createBitStream(input) < 0) { + return NULL; + } + } else { + if(input->fnc1) { + if(QRinput_insertFNC1Header(input) < 0) { + return NULL; + } + } + if(QRinput_convertData(input) < 0) { + return NULL; + } + } + + bstream = BitStream_new(); + if(bstream == NULL) return NULL; + + list = input->head; + while(list != NULL) { + ret = BitStream_append(bstream, list->bstream); + if(ret < 0) { + BitStream_free(bstream); + return NULL; + } + list = list->next; + } + + return bstream; +} + +/** + * Merge all bit streams in the input data and append padding bits + * @param input input data. + * @return padded merged bit stream + */ + +__STATIC BitStream *QRinput_getBitStream(QRinput *input) +{ + BitStream *bstream; + int ret; + + bstream = QRinput_mergeBitStream(input); + if(bstream == NULL) { + return NULL; + } + if(input->mqr) { + ret = QRinput_appendPaddingBitMQR(bstream, input); + } else { + ret = QRinput_appendPaddingBit(bstream, input); + } + if(ret < 0) { + BitStream_free(bstream); + return NULL; + } + + return bstream; +} + +/** + * Pack all bit streams padding bits into a byte array. + * @param input input data. + * @return padded merged byte stream + */ + +unsigned char *QRinput_getByteStream(QRinput *input) +{ + BitStream *bstream; + unsigned char *array; + + bstream = QRinput_getBitStream(input); + if(bstream == NULL) { + return NULL; + } + array = BitStream_toByte(bstream); + BitStream_free(bstream); + + return array; +} + +/****************************************************************************** + * Structured input data + *****************************************************************************/ + +static QRinput_InputList *QRinput_InputList_newEntry(QRinput *input) +{ + QRinput_InputList *entry; + + entry = (QRinput_InputList *)malloc(sizeof(QRinput_InputList)); + if(entry == NULL) return NULL; + + entry->input = input; + entry->next = NULL; + + return entry; +} + +static void QRinput_InputList_freeEntry(QRinput_InputList *entry) +{ + if(entry != NULL) { + QRinput_free(entry->input); + free(entry); + } +} + +QRinput_Struct *QRinput_Struct_new(void) +{ + QRinput_Struct *s; + + s = (QRinput_Struct *)malloc(sizeof(QRinput_Struct)); + if(s == NULL) return NULL; + + s->size = 0; + s->parity = -1; + s->head = NULL; + s->tail = NULL; + + return s; +} + +void QRinput_Struct_setParity(QRinput_Struct *s, unsigned char parity) +{ + s->parity = (int)parity; +} + +int QRinput_Struct_appendInput(QRinput_Struct *s, QRinput *input) +{ + QRinput_InputList *e; + + if(input->mqr) { + errno = EINVAL; + return -1; + } + + e = QRinput_InputList_newEntry(input); + if(e == NULL) return -1; + + s->size++; + if(s->tail == NULL) { + s->head = e; + s->tail = e; + } else { + s->tail->next = e; + s->tail = e; + } + + return s->size; +} + +void QRinput_Struct_free(QRinput_Struct *s) +{ + QRinput_InputList *list, *next; + + if(s != NULL) { + list = s->head; + while(list != NULL) { + next = list->next; + QRinput_InputList_freeEntry(list); + list = next; + } + free(s); + } +} + +static unsigned char QRinput_Struct_calcParity(QRinput_Struct *s) +{ + QRinput_InputList *list; + unsigned char parity = 0; + + list = s->head; + while(list != NULL) { + parity ^= QRinput_calcParity(list->input); + list = list->next; + } + + QRinput_Struct_setParity(s, parity); + + return parity; +} + +static int QRinput_List_shrinkEntry(QRinput_List *entry, int bytes) +{ + unsigned char *data; + + data = (unsigned char *)malloc(bytes); + if(data == NULL) return -1; + + memcpy(data, entry->data, bytes); + free(entry->data); + entry->data = data; + entry->size = bytes; + + return 0; +} + +__STATIC int QRinput_splitEntry(QRinput_List *entry, int bytes) +{ + QRinput_List *e; + int ret; + + e = QRinput_List_newEntry(entry->mode, entry->size - bytes, entry->data + bytes); + if(e == NULL) { + return -1; + } + + ret = QRinput_List_shrinkEntry(entry, bytes); + if(ret < 0) { + QRinput_List_freeEntry(e); + return -1; + } + + e->next = entry->next; + entry->next = e; + + return 0; +} + +QRinput_Struct *QRinput_splitQRinputToStruct(QRinput *input) +{ + QRinput *p; + QRinput_Struct *s; + int bits, maxbits, nextbits, bytes, ret; + QRinput_List *list, *next, *prev; + + if(input->mqr) { + errno = EINVAL; + return NULL; + } + + s = QRinput_Struct_new(); + if(s == NULL) return NULL; + + input = QRinput_dup(input); + if(input == NULL) { + QRinput_Struct_free(s); + return NULL; + } + + QRinput_Struct_setParity(s, QRinput_calcParity(input)); + maxbits = QRspec_getDataLength(input->version, input->level) * 8 - STRUCTURE_HEADER_SIZE; + + if(maxbits <= 0) { + QRinput_Struct_free(s); + QRinput_free(input); + return NULL; + } + + bits = 0; + list = input->head; + prev = NULL; + while(list != NULL) { + nextbits = QRinput_estimateBitStreamSizeOfEntry(list, input->version, input->mqr); + if(bits + nextbits <= maxbits) { + ret = QRinput_encodeBitStream(list, input->version, input->mqr); + if(ret < 0) goto ABORT; + bits += ret; + prev = list; + list = list->next; + } else { + bytes = QRinput_lengthOfCode(list->mode, input->version, maxbits - bits); + p = QRinput_new2(input->version, input->level); + if(p == NULL) goto ABORT; + if(bytes > 0) { + /* Splits this entry into 2 entries. */ + ret = QRinput_splitEntry(list, bytes); + if(ret < 0) { + QRinput_free(p); + goto ABORT; + } + /* First half is the tail of the current input. */ + next = list->next; + list->next = NULL; + /* Second half is the head of the next input, p.*/ + p->head = next; + /* Renew QRinput.tail. */ + p->tail = input->tail; + input->tail = list; + /* Point to the next entry. */ + prev = list; + list = next; + } else { + /* Current entry will go to the next input. */ + prev->next = NULL; + p->head = list; + p->tail = input->tail; + input->tail = prev; + } + ret = QRinput_Struct_appendInput(s, input); + if(ret < 0) { + QRinput_free(p); + goto ABORT; + } + input = p; + bits = 0; + } + } + ret = QRinput_Struct_appendInput(s, input); + if(ret < 0) goto ABORT; + if(s->size > MAX_STRUCTURED_SYMBOLS) { + QRinput_Struct_free(s); + errno = ERANGE; + return NULL; + } + ret = QRinput_Struct_insertStructuredAppendHeaders(s); + if(ret < 0) { + QRinput_Struct_free(s); + return NULL; + } + + return s; + +ABORT: + QRinput_free(input); + QRinput_Struct_free(s); + return NULL; +} + +int QRinput_Struct_insertStructuredAppendHeaders(QRinput_Struct *s) +{ + int i; + QRinput_InputList *list; + + if(s->size == 1) { + return 0; + } + + if(s->parity < 0) { + QRinput_Struct_calcParity(s); + } + i = 1; + list = s->head; + while(list != NULL) { + if(QRinput_insertStructuredAppendHeader(list->input, s->size, i, s->parity)) + return -1; + i++; + list = list->next; + } + + return 0; +} + +/****************************************************************************** + * Extended encoding mode (FNC1 and ECI) + *****************************************************************************/ + +int QRinput_setFNC1First(QRinput *input) +{ + if(input->mqr) { + errno = EINVAL; + return -1; + } + input->fnc1 = 1; + + return 0; +} + +int QRinput_setFNC1Second(QRinput *input, unsigned char appid) +{ + if(input->mqr) { + errno = EINVAL; + return -1; + } + input->fnc1 = 2; + input->appid = appid; + + return 0; +} diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/qrinput.h b/dde-file-manager-5.5.3/3rdparty/qrencode/qrinput.h new file mode 100644 index 0000000..9e6bad6 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/qrinput.h @@ -0,0 +1,123 @@ +/* + * qrencode - QR Code encoder + * + * Input data chunk class + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __QRINPUT_H__ +#define __QRINPUT_H__ + +#include "qrencode.h" +#include "bitstream.h" + +int QRinput_isSplittableMode(QRencodeMode mode); + +/****************************************************************************** + * Entry of input data + *****************************************************************************/ +typedef struct _QRinput_List QRinput_List; + +struct _QRinput_List { + QRencodeMode mode; + int size; ///< Size of data chunk (byte). + unsigned char *data; ///< Data chunk. + BitStream *bstream; + QRinput_List *next; +}; + +/****************************************************************************** + * Input Data + *****************************************************************************/ +struct _QRinput { + int version; + QRecLevel level; + QRinput_List *head; + QRinput_List *tail; + int mqr; + int fnc1; + unsigned char appid; +}; + +/****************************************************************************** + * Structured append input data + *****************************************************************************/ +typedef struct _QRinput_InputList QRinput_InputList; + +struct _QRinput_InputList { + QRinput *input; + QRinput_InputList *next; +}; + +struct _QRinput_Struct { + int size; ///< number of structured symbols + int parity; + QRinput_InputList *head; + QRinput_InputList *tail; +}; + +/** + * Pack all bit streams padding bits into a byte array. + * @param input input data. + * @return padded merged byte stream + */ +extern unsigned char *QRinput_getByteStream(QRinput *input); + + +extern int QRinput_estimateBitsModeNum(int size); +extern int QRinput_estimateBitsModeAn(int size); +extern int QRinput_estimateBitsMode8(int size); +extern int QRinput_estimateBitsModeKanji(int size); + +extern QRinput *QRinput_dup(QRinput *input); + +extern const signed char QRinput_anTable[128]; + +/** + * Look up the alphabet-numeric convesion table (see JIS X0510:2004, pp.19). + * @param __c__ character + * @return value + */ +#define QRinput_lookAnTable(__c__) \ + ((__c__ & 0x80)?-1:QRinput_anTable[(int)__c__]) + +/** + * Length of a standard mode indicator in bits. + */ + +#define MODE_INDICATOR_SIZE 4 + +/** + * Length of a segment of structured-append header. + */ +#define STRUCTURE_HEADER_SIZE 20 + +/** + * Maximum number of symbols in a set of structured-appended symbols. + */ +#define MAX_STRUCTURED_SYMBOLS 16 + +#ifdef WITH_TESTS +extern BitStream *QRinput_mergeBitStream(QRinput *input); +extern BitStream *QRinput_getBitStream(QRinput *input); +extern int QRinput_estimateBitStreamSize(QRinput *input, int version); +extern int QRinput_splitEntry(QRinput_List *entry, int bytes); +extern int QRinput_lengthOfCode(QRencodeMode mode, int version, int bits); +extern int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int index, unsigned char parity); +#endif + +#endif /* __QRINPUT_H__ */ diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/qrspec.c b/dde-file-manager-5.5.3/3rdparty/qrencode/qrspec.c new file mode 100644 index 0000000..a42706f --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/qrspec.c @@ -0,0 +1,562 @@ +/* + * qrencode - QR Code encoder + * + * QR Code specification in convenient format. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * The following data / specifications are taken from + * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) + * or + * "Automatic identification and data capture techniques -- + * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include +#ifdef HAVE_LIBPTHREAD +#include +#endif + +#include "qrspec.h" +#include "qrinput.h" + +/****************************************************************************** + * Version and capacity + *****************************************************************************/ + +typedef struct { + int width; //< Edge length of the symbol + int words; //< Data capacity (bytes) + int remainder; //< Remainder bit (bits) + int ec[4]; //< Number of ECC code (bytes) +} QRspec_Capacity; + +/** + * Table of the capacity of symbols + * See Table 1 (pp.13) and Table 12-16 (pp.30-36), JIS X0510:2004. + */ +static const QRspec_Capacity qrspecCapacity[QRSPEC_VERSION_MAX + 1] = { + { 0, 0, 0, { 0, 0, 0, 0}}, + { 21, 26, 0, { 7, 10, 13, 17}}, // 1 + { 25, 44, 7, { 10, 16, 22, 28}}, + { 29, 70, 7, { 15, 26, 36, 44}}, + { 33, 100, 7, { 20, 36, 52, 64}}, + { 37, 134, 7, { 26, 48, 72, 88}}, // 5 + { 41, 172, 7, { 36, 64, 96, 112}}, + { 45, 196, 0, { 40, 72, 108, 130}}, + { 49, 242, 0, { 48, 88, 132, 156}}, + { 53, 292, 0, { 60, 110, 160, 192}}, + { 57, 346, 0, { 72, 130, 192, 224}}, //10 + { 61, 404, 0, { 80, 150, 224, 264}}, + { 65, 466, 0, { 96, 176, 260, 308}}, + { 69, 532, 0, { 104, 198, 288, 352}}, + { 73, 581, 3, { 120, 216, 320, 384}}, + { 77, 655, 3, { 132, 240, 360, 432}}, //15 + { 81, 733, 3, { 144, 280, 408, 480}}, + { 85, 815, 3, { 168, 308, 448, 532}}, + { 89, 901, 3, { 180, 338, 504, 588}}, + { 93, 991, 3, { 196, 364, 546, 650}}, + { 97, 1085, 3, { 224, 416, 600, 700}}, //20 + {101, 1156, 4, { 224, 442, 644, 750}}, + {105, 1258, 4, { 252, 476, 690, 816}}, + {109, 1364, 4, { 270, 504, 750, 900}}, + {113, 1474, 4, { 300, 560, 810, 960}}, + {117, 1588, 4, { 312, 588, 870, 1050}}, //25 + {121, 1706, 4, { 336, 644, 952, 1110}}, + {125, 1828, 4, { 360, 700, 1020, 1200}}, + {129, 1921, 3, { 390, 728, 1050, 1260}}, + {133, 2051, 3, { 420, 784, 1140, 1350}}, + {137, 2185, 3, { 450, 812, 1200, 1440}}, //30 + {141, 2323, 3, { 480, 868, 1290, 1530}}, + {145, 2465, 3, { 510, 924, 1350, 1620}}, + {149, 2611, 3, { 540, 980, 1440, 1710}}, + {153, 2761, 3, { 570, 1036, 1530, 1800}}, + {157, 2876, 0, { 570, 1064, 1590, 1890}}, //35 + {161, 3034, 0, { 600, 1120, 1680, 1980}}, + {165, 3196, 0, { 630, 1204, 1770, 2100}}, + {169, 3362, 0, { 660, 1260, 1860, 2220}}, + {173, 3532, 0, { 720, 1316, 1950, 2310}}, + {177, 3706, 0, { 750, 1372, 2040, 2430}} //40 +}; + +int QRspec_getDataLength(int version, QRecLevel level) +{ + return qrspecCapacity[version].words - qrspecCapacity[version].ec[level]; +} + +int QRspec_getECCLength(int version, QRecLevel level) +{ + return qrspecCapacity[version].ec[level]; +} + +int QRspec_getMinimumVersion(int size, QRecLevel level) +{ + int i; + int words; + + for(i=1; i<= QRSPEC_VERSION_MAX; i++) { + words = qrspecCapacity[i].words - qrspecCapacity[i].ec[level]; + if(words >= size) return i; + } + + return -1; +} + +int QRspec_getWidth(int version) +{ + return qrspecCapacity[version].width; +} + +int QRspec_getRemainder(int version) +{ + return qrspecCapacity[version].remainder; +} + +/****************************************************************************** + * Length indicator + *****************************************************************************/ + +static const int lengthTableBits[4][3] = { + {10, 12, 14}, + { 9, 11, 13}, + { 8, 16, 16}, + { 8, 10, 12} +}; + +int QRspec_lengthIndicator(QRencodeMode mode, int version) +{ + int l; + + if(!QRinput_isSplittableMode(mode)) return 0; + if(version <= 9) { + l = 0; + } else if(version <= 26) { + l = 1; + } else { + l = 2; + } + + return lengthTableBits[mode][l]; +} + +int QRspec_maximumWords(QRencodeMode mode, int version) +{ + int l; + int bits; + int words; + + if(!QRinput_isSplittableMode(mode)) return 0; + if(version <= 9) { + l = 0; + } else if(version <= 26) { + l = 1; + } else { + l = 2; + } + + bits = lengthTableBits[mode][l]; + words = (1 << bits) - 1; + if(mode == QR_MODE_KANJI) { + words *= 2; // the number of bytes is required + } + + return words; +} + +/****************************************************************************** + * Error correction code + *****************************************************************************/ + +/** + * Table of the error correction code (Reed-Solomon block) + * See Table 12-16 (pp.30-36), JIS X0510:2004. + */ +static const int eccTable[QRSPEC_VERSION_MAX+1][4][2] = { + {{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}}, + {{ 1, 0}, { 1, 0}, { 1, 0}, { 1, 0}}, // 1 + {{ 1, 0}, { 1, 0}, { 1, 0}, { 1, 0}}, + {{ 1, 0}, { 1, 0}, { 2, 0}, { 2, 0}}, + {{ 1, 0}, { 2, 0}, { 2, 0}, { 4, 0}}, + {{ 1, 0}, { 2, 0}, { 2, 2}, { 2, 2}}, // 5 + {{ 2, 0}, { 4, 0}, { 4, 0}, { 4, 0}}, + {{ 2, 0}, { 4, 0}, { 2, 4}, { 4, 1}}, + {{ 2, 0}, { 2, 2}, { 4, 2}, { 4, 2}}, + {{ 2, 0}, { 3, 2}, { 4, 4}, { 4, 4}}, + {{ 2, 2}, { 4, 1}, { 6, 2}, { 6, 2}}, //10 + {{ 4, 0}, { 1, 4}, { 4, 4}, { 3, 8}}, + {{ 2, 2}, { 6, 2}, { 4, 6}, { 7, 4}}, + {{ 4, 0}, { 8, 1}, { 8, 4}, {12, 4}}, + {{ 3, 1}, { 4, 5}, {11, 5}, {11, 5}}, + {{ 5, 1}, { 5, 5}, { 5, 7}, {11, 7}}, //15 + {{ 5, 1}, { 7, 3}, {15, 2}, { 3, 13}}, + {{ 1, 5}, {10, 1}, { 1, 15}, { 2, 17}}, + {{ 5, 1}, { 9, 4}, {17, 1}, { 2, 19}}, + {{ 3, 4}, { 3, 11}, {17, 4}, { 9, 16}}, + {{ 3, 5}, { 3, 13}, {15, 5}, {15, 10}}, //20 + {{ 4, 4}, {17, 0}, {17, 6}, {19, 6}}, + {{ 2, 7}, {17, 0}, { 7, 16}, {34, 0}}, + {{ 4, 5}, { 4, 14}, {11, 14}, {16, 14}}, + {{ 6, 4}, { 6, 14}, {11, 16}, {30, 2}}, + {{ 8, 4}, { 8, 13}, { 7, 22}, {22, 13}}, //25 + {{10, 2}, {19, 4}, {28, 6}, {33, 4}}, + {{ 8, 4}, {22, 3}, { 8, 26}, {12, 28}}, + {{ 3, 10}, { 3, 23}, { 4, 31}, {11, 31}}, + {{ 7, 7}, {21, 7}, { 1, 37}, {19, 26}}, + {{ 5, 10}, {19, 10}, {15, 25}, {23, 25}}, //30 + {{13, 3}, { 2, 29}, {42, 1}, {23, 28}}, + {{17, 0}, {10, 23}, {10, 35}, {19, 35}}, + {{17, 1}, {14, 21}, {29, 19}, {11, 46}}, + {{13, 6}, {14, 23}, {44, 7}, {59, 1}}, + {{12, 7}, {12, 26}, {39, 14}, {22, 41}}, //35 + {{ 6, 14}, { 6, 34}, {46, 10}, { 2, 64}}, + {{17, 4}, {29, 14}, {49, 10}, {24, 46}}, + {{ 4, 18}, {13, 32}, {48, 14}, {42, 32}}, + {{20, 4}, {40, 7}, {43, 22}, {10, 67}}, + {{19, 6}, {18, 31}, {34, 34}, {20, 61}},//40 +}; + +void QRspec_getEccSpec(int version, QRecLevel level, int spec[5]) +{ + int b1, b2; + int data, ecc; + + b1 = eccTable[version][level][0]; + b2 = eccTable[version][level][1]; + data = QRspec_getDataLength(version, level); + ecc = QRspec_getECCLength(version, level); + + if(b2 == 0) { + spec[0] = b1; + spec[1] = data / b1; + spec[2] = ecc / b1; + spec[3] = spec[4] = 0; + } else { + spec[0] = b1; + spec[1] = data / (b1 + b2); + spec[2] = ecc / (b1 + b2); + spec[3] = b2; + spec[4] = spec[1] + 1; + } +} + +/****************************************************************************** + * Alignment pattern + *****************************************************************************/ + +/** + * Positions of alignment patterns. + * This array includes only the second and the third position of the alignment + * patterns. Rest of them can be calculated from the distance between them. + * + * See Table 1 in Appendix E (pp.71) of JIS X0510:2004. + */ +static const int alignmentPattern[QRSPEC_VERSION_MAX+1][2] = { + { 0, 0}, + { 0, 0}, {18, 0}, {22, 0}, {26, 0}, {30, 0}, // 1- 5 + {34, 0}, {22, 38}, {24, 42}, {26, 46}, {28, 50}, // 6-10 + {30, 54}, {32, 58}, {34, 62}, {26, 46}, {26, 48}, //11-15 + {26, 50}, {30, 54}, {30, 56}, {30, 58}, {34, 62}, //16-20 + {28, 50}, {26, 50}, {30, 54}, {28, 54}, {32, 58}, //21-25 + {30, 58}, {34, 62}, {26, 50}, {30, 54}, {26, 52}, //26-30 + {30, 56}, {34, 60}, {30, 58}, {34, 62}, {30, 54}, //31-35 + {24, 50}, {28, 54}, {32, 58}, {26, 54}, {30, 58}, //35-40 +}; + +/** + * Put an alignment marker. + * @param frame + * @param width + * @param ox,oy center coordinate of the pattern + */ +static void QRspec_putAlignmentMarker(unsigned char *frame, int width, int ox, int oy) +{ + static const unsigned char finder[] = { + 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, + 0xa1, 0xa0, 0xa0, 0xa0, 0xa1, + 0xa1, 0xa0, 0xa1, 0xa0, 0xa1, + 0xa1, 0xa0, 0xa0, 0xa0, 0xa1, + 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, + }; + int x, y; + const unsigned char *s; + + frame += (oy - 2) * width + ox - 2; + s = finder; + for(y=0; y<5; y++) { + for(x=0; x<5; x++) { + frame[x] = s[x]; + } + frame += width; + s += 5; + } +} + +static void QRspec_putAlignmentPattern(int version, unsigned char *frame, int width) +{ + int d, w, x, y, cx, cy; + + if(version < 2) return; + + d = alignmentPattern[version][1] - alignmentPattern[version][0]; + if(d < 0) { + w = 2; + } else { + w = (width - alignmentPattern[version][0]) / d + 2; + } + + if(w * w - 3 == 1) { + x = alignmentPattern[version][0]; + y = alignmentPattern[version][0]; + QRspec_putAlignmentMarker(frame, width, x, y); + return; + } + + cx = alignmentPattern[version][0]; + for(x=1; x QRSPEC_VERSION_MAX) return 0; + + return versionPattern[version - 7]; +} + +/****************************************************************************** + * Format information + *****************************************************************************/ + +/* See calcFormatInfo in tests/test_qrspec.c */ +static const unsigned int formatInfo[4][8] = { + {0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976}, + {0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0}, + {0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed}, + {0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b} +}; + +unsigned int QRspec_getFormatInfo(int mask, QRecLevel level) +{ + if(mask < 0 || mask > 7) return 0; + + return formatInfo[level][mask]; +} + +/****************************************************************************** + * Frame + *****************************************************************************/ + +/** + * Cache of initial frames. + */ +/* C99 says that static storage shall be initialized to a null pointer + * by compiler. */ +static unsigned char *frames[QRSPEC_VERSION_MAX + 1]; +#ifdef HAVE_LIBPTHREAD +static pthread_mutex_t frames_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +/** + * Put a finder pattern. + * @param frame + * @param width + * @param ox,oy upper-left coordinate of the pattern + */ +static void putFinderPattern(unsigned char *frame, int width, int ox, int oy) +{ + static const unsigned char finder[] = { + 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, + 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1, + 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, + 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, + }; + int x, y; + const unsigned char *s; + + frame += oy * width + ox; + s = finder; + for(y=0; y<7; y++) { + for(x=0; x<7; x++) { + frame[x] = s[x]; + } + frame += width; + s += 7; + } +} + + +static unsigned char *QRspec_createFrame(int version) +{ + unsigned char *frame, *p, *q; + int width; + int x, y; + unsigned int verinfo, v; + + width = qrspecCapacity[version].width; + frame = (unsigned char *)malloc(width * width); + if(frame == NULL) return NULL; + + memset(frame, 0, width * width); + /* Finder pattern */ + putFinderPattern(frame, width, 0, 0); + putFinderPattern(frame, width, width - 7, 0); + putFinderPattern(frame, width, 0, width - 7); + /* Separator */ + p = frame; + q = frame + width * (width - 7); + for(y=0; y<7; y++) { + p[7] = 0xc0; + p[width - 8] = 0xc0; + q[7] = 0xc0; + p += width; + q += width; + } + memset(frame + width * 7, 0xc0, 8); + memset(frame + width * 8 - 8, 0xc0, 8); + memset(frame + width * (width - 8), 0xc0, 8); + /* Mask format information area */ + memset(frame + width * 8, 0x84, 9); + memset(frame + width * 9 - 8, 0x84, 8); + p = frame + 8; + for(y=0; y<8; y++) { + *p = 0x84; + p += width; + } + p = frame + width * (width - 7) + 8; + for(y=0; y<7; y++) { + *p = 0x84; + p += width; + } + /* Timing pattern */ + p = frame + width * 6 + 8; + q = frame + width * 8 + 6; + for(x=1; x= 7) { + verinfo = QRspec_getVersionPattern(version); + + p = frame + width * (width - 11); + v = verinfo; + for(x=0; x<6; x++) { + for(y=0; y<3; y++) { + p[width * y + x] = 0x88 | (v & 1); + v = v >> 1; + } + } + + p = frame + width - 11; + v = verinfo; + for(y=0; y<6; y++) { + for(x=0; x<3; x++) { + p[x] = 0x88 | (v & 1); + v = v >> 1; + } + p += width; + } + } + /* and a little bit... */ + frame[width * (width - 8) + 8] = 0x81; + + return frame; +} + +unsigned char *QRspec_newFrame(int version) +{ + unsigned char *frame; + int width; + + if(version < 1 || version > QRSPEC_VERSION_MAX) return NULL; + +#ifdef HAVE_LIBPTHREAD + pthread_mutex_lock(&frames_mutex); +#endif + if(frames[version] == NULL) { + frames[version] = QRspec_createFrame(version); + } +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&frames_mutex); +#endif + if(frames[version] == NULL) return NULL; + + width = qrspecCapacity[version].width; + frame = (unsigned char *)malloc(width * width); + if(frame == NULL) return NULL; + memcpy(frame, frames[version], width * width); + + return frame; +} + +void QRspec_clearCache(void) +{ + int i; + +#ifdef HAVE_LIBPTHREAD + pthread_mutex_lock(&frames_mutex); +#endif + for(i=1; i<=QRSPEC_VERSION_MAX; i++) { + free(frames[i]); + frames[i] = NULL; + } +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&frames_mutex); +#endif +} diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/qrspec.h b/dde-file-manager-5.5.3/3rdparty/qrencode/qrspec.h new file mode 100644 index 0000000..54a3d9f --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/qrspec.h @@ -0,0 +1,181 @@ +/* + * qrencode - QR Code encoder + * + * QR Code specification in convenient format. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __QRSPEC_H__ +#define __QRSPEC_H__ + +#include "qrencode.h" + +/****************************************************************************** + * Version and capacity + *****************************************************************************/ + +/** + * Maximum width of a symbol + */ +#define QRSPEC_WIDTH_MAX 177 + +/** + * Return maximum data code length (bytes) for the version. + * @param version + * @param level + * @return maximum size (bytes) + */ +extern int QRspec_getDataLength(int version, QRecLevel level); + +/** + * Return maximum error correction code length (bytes) for the version. + * @param version + * @param level + * @return ECC size (bytes) + */ +extern int QRspec_getECCLength(int version, QRecLevel level); + +/** + * Return a version number that satisfies the input code length. + * @param size input code length (byte) + * @param level + * @return version number + */ +extern int QRspec_getMinimumVersion(int size, QRecLevel level); + +/** + * Return the width of the symbol for the version. + * @param version + * @return width + */ +extern int QRspec_getWidth(int version); + +/** + * Return the numer of remainder bits. + * @param version + * @return number of remainder bits + */ +extern int QRspec_getRemainder(int version); + +/****************************************************************************** + * Length indicator + *****************************************************************************/ + +/** + * Return the size of lenght indicator for the mode and version. + * @param mode + * @param version + * @return the size of the appropriate length indicator (bits). + */ +extern int QRspec_lengthIndicator(QRencodeMode mode, int version); + +/** + * Return the maximum length for the mode and version. + * @param mode + * @param version + * @return the maximum length (bytes) + */ +extern int QRspec_maximumWords(QRencodeMode mode, int version); + +/****************************************************************************** + * Error correction code + *****************************************************************************/ + +/** + * Return an array of ECC specification. + * @param version + * @param level + * @param spec an array of ECC specification contains as following: + * {# of type1 blocks, # of data code, # of ecc code, + * # of type2 blocks, # of data code} + */ +void QRspec_getEccSpec(int version, QRecLevel level, int spec[5]); + +#define QRspec_rsBlockNum(__spec__) (__spec__[0] + __spec__[3]) +#define QRspec_rsBlockNum1(__spec__) (__spec__[0]) +#define QRspec_rsDataCodes1(__spec__) (__spec__[1]) +#define QRspec_rsEccCodes1(__spec__) (__spec__[2]) +#define QRspec_rsBlockNum2(__spec__) (__spec__[3]) +#define QRspec_rsDataCodes2(__spec__) (__spec__[4]) +#define QRspec_rsEccCodes2(__spec__) (__spec__[2]) + +#define QRspec_rsDataLength(__spec__) \ + ((QRspec_rsBlockNum1(__spec__) * QRspec_rsDataCodes1(__spec__)) + \ + (QRspec_rsBlockNum2(__spec__) * QRspec_rsDataCodes2(__spec__))) +#define QRspec_rsEccLength(__spec__) \ + (QRspec_rsBlockNum(__spec__) * QRspec_rsEccCodes1(__spec__)) + +/****************************************************************************** + * Version information pattern + *****************************************************************************/ + +/** + * Return BCH encoded version information pattern that is used for the symbol + * of version 7 or greater. Use lower 18 bits. + * @param version + * @return BCH encoded version information pattern + */ +extern unsigned int QRspec_getVersionPattern(int version); + +/****************************************************************************** + * Format information + *****************************************************************************/ + +/** + * Return BCH encoded format information pattern. + * @param mask + * @param level + * @return BCH encoded format information pattern + */ +extern unsigned int QRspec_getFormatInfo(int mask, QRecLevel level); + +/****************************************************************************** + * Frame + *****************************************************************************/ + +/** + * Return a copy of initialized frame. + * When the same version is requested twice or more, a copy of cached frame + * is returned. + * @param version + * @return Array of unsigned char. You can free it by free(). + */ +extern unsigned char *QRspec_newFrame(int version); + +/** + * Clear the frame cache. Typically for debug. + */ +extern void QRspec_clearCache(void); + +/****************************************************************************** + * Mode indicator + *****************************************************************************/ + +/** + * Mode indicator. See Table 2 of JIS X0510:2004, pp.16. + */ +#define QRSPEC_MODEID_ECI 7 +#define QRSPEC_MODEID_NUM 1 +#define QRSPEC_MODEID_AN 2 +#define QRSPEC_MODEID_8 4 +#define QRSPEC_MODEID_KANJI 8 +#define QRSPEC_MODEID_FNC1FIRST 5 +#define QRSPEC_MODEID_FNC1SECOND 9 +#define QRSPEC_MODEID_STRUCTURE 3 +#define QRSPEC_MODEID_TERMINATOR 0 + +#endif /* __QRSPEC_H__ */ diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/rscode.c b/dde-file-manager-5.5.3/3rdparty/qrencode/rscode.c new file mode 100644 index 0000000..edc32e2 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/rscode.c @@ -0,0 +1,327 @@ +/* + * qrencode - QR Code encoder + * + * Reed solomon encoder. This code is taken from Phil Karn's libfec then + * editted and packed into a pair of .c and .h files. + * + * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q + * (libfec is released under the GNU Lesser General Public License.) + * + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#ifdef HAVE_LIBPTHREAD +# include +#endif + +#include "rscode.h" + +/* Stuff specific to the 8-bit symbol version of the general purpose RS codecs + * + */ +typedef unsigned char data_t; + + +/** + * Reed-Solomon codec control block + */ +struct _RS { + int mm; /* Bits per symbol */ + int nn; /* Symbols per block (= (1<= rs->nn) { + x -= rs->nn; + x = (x >> rs->mm) + (x & rs->nn); + } + return x; +} + + +#define MODNN(x) modnn(rs,x) + +#define MM (rs->mm) +#define NN (rs->nn) +#define ALPHA_TO (rs->alpha_to) +#define INDEX_OF (rs->index_of) +#define GENPOLY (rs->genpoly) +#define NROOTS (rs->nroots) +#define FCR (rs->fcr) +#define PRIM (rs->prim) +#define IPRIM (rs->iprim) +#define PAD (rs->pad) +#define A0 (NN) + + +/* Initialize a Reed-Solomon codec + * symsize = symbol size, bits + * gfpoly = Field generator polynomial coefficients + * fcr = first root of RS code generator polynomial, index form + * prim = primitive element to generate polynomial roots + * nroots = RS code generator polynomial degree (number of roots) + * pad = padding bytes at front of shortened block + */ +static RS *init_rs_char(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad) +{ + RS *rs; + + +/* Common code for intializing a Reed-Solomon control block (char or int symbols) + * Copyright 2004 Phil Karn, KA9Q + * May be used under the terms of the GNU Lesser General Public License (LGPL) + */ +//#undef NULL +//#define NULL ((void *)0) + + int i, j, sr,root,iprim; + + rs = NULL; + /* Check parameter ranges */ + if(symsize < 0 || symsize > (int)(8*sizeof(data_t))){ + goto done; + } + + if(fcr < 0 || fcr >= (1<= (1<= (1<= ((1<mm = symsize; + rs->nn = (1<pad = pad; + + rs->alpha_to = (data_t *)malloc(sizeof(data_t)*(rs->nn+1)); + if(rs->alpha_to == NULL){ + free(rs); + rs = NULL; + goto done; + } + rs->index_of = (data_t *)malloc(sizeof(data_t)*(rs->nn+1)); + if(rs->index_of == NULL){ + free(rs->alpha_to); + free(rs); + rs = NULL; + goto done; + } + + /* Generate Galois field lookup tables */ + rs->index_of[0] = A0; /* log(zero) = -inf */ + rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */ + sr = 1; + for(i=0;inn;i++){ + rs->index_of[sr] = i; + rs->alpha_to[i] = sr; + sr <<= 1; + if(sr & (1<nn; + } + if(sr != 1){ + /* field generator polynomial is not primitive! */ + free(rs->alpha_to); + free(rs->index_of); + free(rs); + rs = NULL; + goto done; + } + + /* Form RS code generator polynomial from its roots */ + rs->genpoly = (data_t *)malloc(sizeof(data_t)*(nroots+1)); + if(rs->genpoly == NULL){ + free(rs->alpha_to); + free(rs->index_of); + free(rs); + rs = NULL; + goto done; + } + rs->fcr = fcr; + rs->prim = prim; + rs->nroots = nroots; + rs->gfpoly = gfpoly; + + /* Find prim-th root of 1, used in decoding */ + for(iprim=1;(iprim % prim) != 0;iprim += rs->nn) + ; + rs->iprim = iprim / prim; + + rs->genpoly[0] = 1; + for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) { + rs->genpoly[i+1] = 1; + + /* Multiply rs->genpoly[] by @**(root + x) */ + for (j = i; j > 0; j--){ + if (rs->genpoly[j] != 0) + rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)]; + else + rs->genpoly[j] = rs->genpoly[j-1]; + } + /* rs->genpoly[0] can never be zero */ + rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)]; + } + /* convert rs->genpoly[] to index form for quicker encoding */ + for (i = 0; i <= nroots; i++) + rs->genpoly[i] = rs->index_of[rs->genpoly[i]]; + done:; + + return rs; +} + +RS *init_rs(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad) +{ + RS *rs; + +#ifdef HAVE_LIBPTHREAD + pthread_mutex_lock(&rslist_mutex); +#endif + for(rs = rslist; rs != NULL; rs = rs->next) { + if(rs->pad != pad) continue; + if(rs->nroots != nroots) continue; + if(rs->mm != symsize) continue; + if(rs->gfpoly != gfpoly) continue; + if(rs->fcr != fcr) continue; + if(rs->prim != prim) continue; + + goto DONE; + } + + rs = init_rs_char(symsize, gfpoly, fcr, prim, nroots, pad); + if(rs == NULL) goto DONE; + rs->next = rslist; + rslist = rs; + +DONE: +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&rslist_mutex); +#endif + return rs; +} + + +void free_rs_char(RS *rs) +{ + free(rs->alpha_to); + free(rs->index_of); + free(rs->genpoly); + free(rs); +} + +void free_rs_cache(void) +{ + RS *rs, *next; + +#ifdef HAVE_LIBPTHREAD + pthread_mutex_lock(&rslist_mutex); +#endif + rs = rslist; + while(rs != NULL) { + next = rs->next; + free_rs_char(rs); + rs = next; + } + rslist = NULL; +#ifdef HAVE_LIBPTHREAD + pthread_mutex_unlock(&rslist_mutex); +#endif +} + +/* The guts of the Reed-Solomon encoder, meant to be #included + * into a function body with the following typedefs, macros and variables supplied + * according to the code parameters: + + * data_t - a typedef for the data symbol + * data_t data[] - array of NN-NROOTS-PAD and type data_t to be encoded + * data_t parity[] - an array of NROOTS and type data_t to be written with parity symbols + * NROOTS - the number of roots in the RS code generator polynomial, + * which is the same as the number of parity symbols in a block. + Integer variable or literal. + * + * NN - the total number of symbols in a RS block. Integer variable or literal. + * PAD - the number of pad symbols in a block. Integer variable or literal. + * ALPHA_TO - The address of an array of NN elements to convert Galois field + * elements in index (log) form to polynomial form. Read only. + * INDEX_OF - The address of an array of NN elements to convert Galois field + * elements in polynomial form to index (log) form. Read only. + * MODNN - a function to reduce its argument modulo NN. May be inline or a macro. + * GENPOLY - an array of NROOTS+1 elements containing the generator polynomial in index form + + * The memset() and memmove() functions are used. The appropriate header + * file declaring these functions (usually ) must be included by the calling + * program. + + * Copyright 2004, Phil Karn, KA9Q + * May be used under the terms of the GNU Lesser General Public License (LGPL) + */ + +#undef A0 +#define A0 (NN) /* Special reserved value encoding zero in index form */ + +void encode_rs_char(RS *rs, const data_t *data, data_t *parity) +{ + int i, j; + data_t feedback; + + memset(parity,0,NROOTS*sizeof(data_t)); + + for(i=0;i + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __RSCODE_H__ +#define __RSCODE_H__ + +/* + * General purpose RS codec, 8-bit symbols. + */ + +typedef struct _RS RS; + +extern RS *init_rs(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad); +extern void encode_rs_char(RS *rs, const unsigned char *data, unsigned char *parity); +extern void free_rs_char(RS *rs); +extern void free_rs_cache(void); + +#endif /* __RSCODE_H__ */ diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/split.c b/dde-file-manager-5.5.3/3rdparty/qrencode/split.c new file mode 100644 index 0000000..a2cb0e0 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/split.c @@ -0,0 +1,326 @@ +/* + * qrencode - QR Code encoder + * + * Input data splitter. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * The following data / specifications are taken from + * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) + * or + * "Automatic identification and data capture techniques -- + * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include "qrencode.h" +#include "qrinput.h" +#include "qrspec.h" +#include "split.h" + +#define isdigit(__c__) ((unsigned char)((signed char)(__c__) - '0') < 10) +#define isalnum(__c__) (QRinput_lookAnTable(__c__) >= 0) + +#if !HAVE_STRDUP +#undef strdup +char *strdup(const char *s) +{ + size_t len = strlen(s) + 1; + void *new = malloc(len); + if(new == NULL) return NULL; + return (char *)memcpy(new, s, len); +} +#endif + +static QRencodeMode Split_identifyMode(const char *string, QRencodeMode hint) +{ + unsigned char c, d; + unsigned int word; + + c = string[0]; + + if(c == '\0') return QR_MODE_NUL; + if(isdigit(c)) { + return QR_MODE_NUM; + } else if(isalnum(c)) { + return QR_MODE_AN; + } else if(hint == QR_MODE_KANJI) { + d = string[1]; + if(d != '\0') { + word = ((unsigned int)c << 8) | d; + if((word >= 0x8140 && word <= 0x9ffc) || (word >= 0xe040 && word <= 0xebbf)) { + return QR_MODE_KANJI; + } + } + } + + return QR_MODE_8; +} + +static int Split_eatNum(const char *string, QRinput *input, QRencodeMode hint); +static int Split_eatAn(const char *string, QRinput *input, QRencodeMode hint); +static int Split_eat8(const char *string, QRinput *input, QRencodeMode hint); +static int Split_eatKanji(const char *string, QRinput *input, QRencodeMode hint); + +static int Split_eatNum(const char *string, QRinput *input,QRencodeMode hint) +{ + const char *p; + int ret; + int run; + int dif; + int ln; + QRencodeMode mode; + + ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version); + + p = string; + while(isdigit(*p)) { + p++; + } + run = p - string; + mode = Split_identifyMode(p, hint); + if(mode == QR_MODE_8) { + dif = QRinput_estimateBitsModeNum(run) + 4 + ln + + QRinput_estimateBitsMode8(1) /* + 4 + l8 */ + - QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */; + if(dif > 0) { + return Split_eat8(string, input, hint); + } + } + if(mode == QR_MODE_AN) { + dif = QRinput_estimateBitsModeNum(run) + 4 + ln + + QRinput_estimateBitsModeAn(1) /* + 4 + la */ + - QRinput_estimateBitsModeAn(run + 1) /* - 4 - la */; + if(dif > 0) { + return Split_eatAn(string, input, hint); + } + } + + ret = QRinput_append(input, QR_MODE_NUM, run, (unsigned char *)string); + if(ret < 0) return -1; + + return run; +} + +static int Split_eatAn(const char *string, QRinput *input, QRencodeMode hint) +{ + const char *p, *q; + int ret; + int run; + int dif; + int la, ln; + + la = QRspec_lengthIndicator(QR_MODE_AN, input->version); + ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version); + + p = string; + while(isalnum(*p)) { + if(isdigit(*p)) { + q = p; + while(isdigit(*q)) { + q++; + } + dif = QRinput_estimateBitsModeAn(p - string) /* + 4 + la */ + + QRinput_estimateBitsModeNum(q - p) + 4 + ln + + (isalnum(*q)?(4 + ln):0) + - QRinput_estimateBitsModeAn(q - string) /* - 4 - la */; + if(dif < 0) { + break; + } else { + p = q; + } + } else { + p++; + } + } + + run = p - string; + + if(*p && !isalnum(*p)) { + dif = QRinput_estimateBitsModeAn(run) + 4 + la + + QRinput_estimateBitsMode8(1) /* + 4 + l8 */ + - QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */; + if(dif > 0) { + return Split_eat8(string, input, hint); + } + } + + ret = QRinput_append(input, QR_MODE_AN, run, (unsigned char *)string); + if(ret < 0) return -1; + + return run; +} + +static int Split_eatKanji(const char *string, QRinput *input, QRencodeMode hint) +{ + const char *p; + int ret; + int run; + + p = string; + while(Split_identifyMode(p, hint) == QR_MODE_KANJI) { + p += 2; + } + run = p - string; + ret = QRinput_append(input, QR_MODE_KANJI, run, (unsigned char *)string); + if(ret < 0) return -1; + + return run; +} + +static int Split_eat8(const char *string, QRinput *input, QRencodeMode hint) +{ + const char *p, *q; + QRencodeMode mode; + int ret; + int run; + int dif; + int la, ln, l8; + int swcost; + + la = QRspec_lengthIndicator(QR_MODE_AN, input->version); + ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version); + l8 = QRspec_lengthIndicator(QR_MODE_8, input->version); + + p = string + 1; + while(*p != '\0') { + mode = Split_identifyMode(p, hint); + if(mode == QR_MODE_KANJI) { + break; + } + if(mode == QR_MODE_NUM) { + q = p; + while(isdigit(*q)) { + q++; + } + if(Split_identifyMode(q, hint) == QR_MODE_8) { + swcost = 4 + l8; + } else { + swcost = 0; + } + dif = QRinput_estimateBitsMode8(p - string) /* + 4 + l8 */ + + QRinput_estimateBitsModeNum(q - p) + 4 + ln + + swcost + - QRinput_estimateBitsMode8(q - string) /* - 4 - l8 */; + if(dif < 0) { + break; + } else { + p = q; + } + } else if(mode == QR_MODE_AN) { + q = p; + while(isalnum(*q)) { + q++; + } + if(Split_identifyMode(q, hint) == QR_MODE_8) { + swcost = 4 + l8; + } else { + swcost = 0; + } + dif = QRinput_estimateBitsMode8(p - string) /* + 4 + l8 */ + + QRinput_estimateBitsModeAn(q - p) + 4 + la + + swcost + - QRinput_estimateBitsMode8(q - string) /* - 4 - l8 */; + if(dif < 0) { + break; + } else { + p = q; + } + } else { + p++; + } + } + + run = p - string; + ret = QRinput_append(input, QR_MODE_8, run, (unsigned char *)string); + if(ret < 0) return -1; + + return run; +} + +static int Split_splitString(const char *string, QRinput *input, + QRencodeMode hint) +{ + int length; + QRencodeMode mode; + + if(*string == '\0') return 0; + + mode = Split_identifyMode(string, hint); + if(mode == QR_MODE_NUM) { + length = Split_eatNum(string, input, hint); + } else if(mode == QR_MODE_AN) { + length = Split_eatAn(string, input, hint); + } else if(mode == QR_MODE_KANJI && hint == QR_MODE_KANJI) { + length = Split_eatKanji(string, input, hint); + } else { + length = Split_eat8(string, input, hint); + } + if(length == 0) return 0; + if(length < 0) return -1; + return Split_splitString(&string[length], input, hint); +} + +static char *dupAndToUpper(const char *str, QRencodeMode hint) +{ + char *newstr, *p; + QRencodeMode mode; + + newstr = strdup(str); + if(newstr == NULL) return NULL; + + p = newstr; + while(*p != '\0') { + mode = Split_identifyMode(p, hint); + if(mode == QR_MODE_KANJI) { + p += 2; + } else { + if (*p >= 'a' && *p <= 'z') { + *p = (char)((int)*p - 32); + } + p++; + } + } + + return newstr; +} + +int Split_splitStringToQRinput(const char *string, QRinput *input, + QRencodeMode hint, int casesensitive) +{ + char *newstr; + int ret; + + if(string == NULL || *string == '\0') { + errno = EINVAL; + return -1; + } + if(!casesensitive) { + newstr = dupAndToUpper(string, hint); + if(newstr == NULL) return -1; + ret = Split_splitString(newstr, input, hint); + free(newstr); + } else { + ret = Split_splitString(string, input, hint); + } + + return ret; +} diff --git a/dde-file-manager-5.5.3/3rdparty/qrencode/split.h b/dde-file-manager-5.5.3/3rdparty/qrencode/split.h new file mode 100644 index 0000000..b2cdbe5 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/qrencode/split.h @@ -0,0 +1,47 @@ +/* + * qrencode - QR Code encoder + * + * Input data splitter. + * Copyright (C) 2006-2011 Kentaro Fukuchi + * + * The following data / specifications are taken from + * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) + * or + * "Automatic identification and data capture techniques -- + * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __SPLIT_H__ +#define __SPLIT_H__ + +#include "qrencode.h" + +/** + * Split the input string (null terminated) into QRinput. + * @param string input string + * @param hint give QR_MODE_KANJI if the input string contains Kanji character encoded in Shift-JIS. If not, give QR_MODE_8. + * @param casesensitive 0 for case-insensitive encoding (all alphabet characters are replaced to UPPER-CASE CHARACTERS. + * @retval 0 success. + * @retval -1 an error occurred. errno is set to indicate the error. See + * Exceptions for the details. + * @throw EINVAL invalid input object. + * @throw ENOMEM unable to allocate memory for input objects. + */ +extern int Split_splitStringToQRinput(const char *string, QRinput *input, + QRencodeMode hint, int casesensitive); + +#endif /* __SPLIT_H__ */ diff --git a/dde-file-manager-5.5.3/3rdparty/stub-ext/stub-shadow.cpp b/dde-file-manager-5.5.3/3rdparty/stub-ext/stub-shadow.cpp new file mode 100644 index 0000000..d49ede2 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/stub-ext/stub-shadow.cpp @@ -0,0 +1,31 @@ +#include "stub-shadow.h" + +namespace stub_ext { + +WrapperMap stub_wrappers; + +Wrapper::Wrapper() +{ + +} + +Wrapper::~Wrapper() +{ + +} + +void freeWrapper(Wrapper *wrapper) +{ + if (!wrapper) + return; + + for (auto iter = stub_wrappers.begin(); iter != stub_wrappers.end();) { + if (iter->second == wrapper) + iter = stub_wrappers.erase(iter); + else + ++iter; + } + + delete wrapper; +} +} diff --git a/dde-file-manager-5.5.3/3rdparty/stub-ext/stub-shadow.h b/dde-file-manager-5.5.3/3rdparty/stub-ext/stub-shadow.h new file mode 100644 index 0000000..ec2044a --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/stub-ext/stub-shadow.h @@ -0,0 +1,171 @@ +#ifndef STUBSHADOW_H +#define STUBSHADOW_H +/* + * Author: Zhang Yu + * Maintainer: Zhang Yu + * + * MIT License + * + * Copyright (c) 2020 Zhang Yu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ + +#include +#include + +namespace stub_ext { + +#define LAMDA_FUNCTION_TYPE decltype(&Lamda::operator()) + +class Wrapper +{ +public: + Wrapper(); + virtual ~Wrapper(); +}; + +typedef std::unordered_map WrapperMap; +extern WrapperMap stub_wrappers; + +template +class LamdaWrapper : public Wrapper +{ +public: + LamdaWrapper(Lamda func): Wrapper(),_func(func){} + ~LamdaWrapper(){} + Lamda _func; +}; + +template +struct VFLocator +{ + +}; + +template +struct VFLocator +{ + typedef Ret (*Func)(Obj*, Args...); +}; + +template +struct VFLocator +{ + typedef Ret (*Func)(Obj*, Args...); +}; + +template +struct LamdaCaller +{ + +}; + +template +struct LamdaCaller +{ + template + static Ret call(LamdaWrapper *wrapper, OrgArgs... args) + { + return wrapper->_func(args...); + } +}; + +template +struct LamdaCaller +{ + template + static Ret call(LamdaWrapper *wrapper, OrgArgs... args) + { + return wrapper->_func(); + } +}; + +template +struct FuncShadow +{ + +}; + +template +struct FuncShadow +{ + typedef Ret (*Shadow)(Args...); + typedef Ret RetType; + + static Ret call(Args ...args) + { + Shadow shadow = &call; + long id = (long)shadow; + auto iter = stub_wrappers.find(id); + assert(stub_wrappers.find(id) != stub_wrappers.end()); + LamdaWrapper *wrapper = dynamic_cast *>(iter->second); + return LamdaCaller::call(wrapper, args...); + } +}; + +template +struct FuncShadow +{ + typedef Ret (*Shadow)(Obj *,Args...); + typedef Ret RetType; + static Ret call(Obj *obj, Args ...args) + { + Shadow shadow = &call; + long id = (long)shadow; + auto iter = stub_wrappers.find(id); + assert(stub_wrappers.find(id) != stub_wrappers.end()); + LamdaWrapper *wrapper = dynamic_cast *>(iter->second); + return LamdaCaller::call(wrapper, obj, args...); + } +}; + + +template +struct FuncShadow +{ + typedef Ret (*Shadow)(Obj *,Args...); + typedef Ret RetType; + static Ret call(Obj *obj, Args ...args) + { + Shadow shadow = &call; + long id = (long)shadow; + auto iter = stub_wrappers.find(id); + assert(stub_wrappers.find(id) != stub_wrappers.end()); + LamdaWrapper *wrapper = dynamic_cast *>(iter->second); + return LamdaCaller::call(wrapper, obj, args...); + } +}; + +template +typename FuncShadow::Shadow depictShadow(Wrapper **wrapper, Func func, Lamda lamda) +{ + *wrapper = new LamdaWrapper(lamda); + typename FuncShadow::Shadow shadow = &FuncShadow::call; + long id = (long)shadow; + assert(stub_wrappers.find(id) == stub_wrappers.end()); + stub_wrappers.insert(std::make_pair(id,*wrapper)); + return shadow; +} + +void freeWrapper(Wrapper *wrapper); + +} + +#endif // STUBSHADOW_H diff --git a/dde-file-manager-5.5.3/3rdparty/stub-ext/stubext.h b/dde-file-manager-5.5.3/3rdparty/stub-ext/stubext.h new file mode 100644 index 0000000..d3ce080 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/stub-ext/stubext.h @@ -0,0 +1,87 @@ +#ifndef STUBEXT_H +#define STUBEXT_H +/* + * Author: Zhang Yu + * Maintainer: Zhang Yu + * + * MIT License + * + * Copyright (c) 2020 Zhang Yu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. +*/ + +//需修改Stub的私用成员函数和成员变量为保护类型 +#include "stub.h" + +#include "stub-shadow.h" + +#define VADDR(CLASS_NAME,MEMBER_NAME) (typename stub_ext::VFLocator::Func)(&CLASS_NAME::MEMBER_NAME) + +namespace stub_ext { + +class StubExt : public Stub +{ +public: + StubExt() : Stub() {} + + template + bool set_lamda(T addr, Lamda lamda) + { + char *fn = addrof(addr); + if (m_result.find(fn) != m_result.end()) + reset(addr); + + Wrapper *wrapper = nullptr; + auto addr_stub = depictShadow(&wrapper,addr,lamda); + if (set(addr, addr_stub)) { + m_wrappers.insert(std::make_pair(fn, wrapper)); + return true; + } else { + freeWrapper(wrapper); + } + return false; + } + + template + void reset(T addr) + { + Stub::reset(addr); + char *fn = addrof(addr); + auto iter = m_wrappers.find(fn); + if (iter != m_wrappers.end()) { + freeWrapper(iter->second); + m_wrappers.erase(iter); + } + } + + ~StubExt() + { + clear(); + for (auto iter = m_wrappers.begin(); iter != m_wrappers.end(); ++iter) { + freeWrapper(iter->second); + } + } +protected: + std::map m_wrappers; +}; + +} + +#endif // STUBEXT_H diff --git a/dde-file-manager-5.5.3/3rdparty/test-prj-running.sh b/dde-file-manager-5.5.3/3rdparty/test-prj-running.sh new file mode 100755 index 0000000..de1f9b3 --- /dev/null +++ b/dde-file-manager-5.5.3/3rdparty/test-prj-running.sh @@ -0,0 +1,39 @@ +#!/bin/bash + + +#workdir=$(cd ../../$(dirname $0)/build-filemanager-unknown-Debug/test; pwd) +workdir=${1} #编译路径 +executable=${2} #可执行程序的文件名 + +#下面是覆盖率目录操作,一种正向操作,一种逆向操作 +extract_info=${3} #针对当前目录进行覆盖率操作 +remove_info=${4} #排除当前目录进行覆盖率操作 + +if [ ! $# -eq 4 ]; then + echo "param number set err: "$# ": "$* + echo "wrong param set,usage: <编译路径> <可执行程序> <期望覆盖的路径> <不期望覆盖的路径>" + exit 0 +fi + +build_dir=$workdir +result_coverage_dir=$build_dir/coverage +result_report_dir=$build_dir/report/report.xml + +$build_dir/$executable --gtest_output=xml:$result_report_dir + + +lcov -d $build_dir -c -o $build_dir/coverage.info + +lcov --extract $build_dir/coverage.info $extract_info --output-file $build_dir/coverage.info +lcov --remove $build_dir/coverage.info $remove_info --output-file $build_dir/coverage.info + +lcov --list-full-path -e $build_dir/coverage.info –o $build_dir/coverage-stripped.info + +genhtml -o $result_coverage_dir $build_dir/coverage.info + +nohup x-www-browser $result_coverage_dir/index.html & +nohup x-www-browser $result_report_dir & + +lcov -d $build_dir –z + +exit 0 diff --git a/dde-file-manager-5.5.3/CHANGELOG.md b/dde-file-manager-5.5.3/CHANGELOG.md new file mode 100644 index 0000000..5ec0125 --- /dev/null +++ b/dde-file-manager-5.5.3/CHANGELOG.md @@ -0,0 +1,1512 @@ + +## 4.8.6.4 (2019-06-12) + + +#### Bug Fixes + +* DFileDialog disable menu from titlebar ([e2f5c9a9](https://github.com/linuxdeepin/dde-file-manager/commit/e2f5c9a9bef2dadd261d83931985fbcf4f3631a3)) +* typos in multiple DFMEvent subclasses. ([de2e33a6](https://github.com/linuxdeepin/dde-file-manager/commit/de2e33a6aad845f12e529c9786256364f5cafa14)) + + + + +## 4.8.6.3 (2019-06-11) + + +#### Bug Fixes + +* copy dialog disable menu from titlebar ([daa6d016](https://github.com/linuxdeepin/dde-file-manager/commit/daa6d0168da0d17b8dbb92705eef8a81fc192f09)) +* should remember auto merged status ([9eda50be](https://github.com/linuxdeepin/dde-file-manager/commit/9eda50be4f33973fb38bfb34217dc629bbf3529a)) + + + + +## 4.8.6.2 (2019-06-05) + + +#### Bug Fixes + +* should convert to QVariant first ([80ea04c7](https://github.com/linuxdeepin/dde-file-manager/commit/80ea04c79c27f5cbfa66f0aeff68697c0bb78b94)) + + + + +## 4.8.6.1 (2019-06-01) + + +#### Bug Fixes + +* should require auth ([dcc549c2](https://github.com/linuxdeepin/dde-file-manager/commit/dcc549c2b3ac6aa9af1552b3d813e3027464925e)) +* remove com.deepin.filemanager.daemon.policy ([b18c95b2](https://github.com/linuxdeepin/dde-file-manager/commit/b18c95b271b263cb52e26771b80b1bff8ecedbcc)) +* several usb-device-formatter issues ([155fa8cf](https://github.com/linuxdeepin/dde-file-manager/commit/155fa8cf33b26c6dee870af5dbbff4b8e4aa6f6c)) +* lsar -J result changed after util-linux v2.33 ([64247173](https://github.com/linuxdeepin/dde-file-manager/commit/64247173a042283529ee0118e0ad442227bd9a13)) +* wallpaper geometry not updated after switching monitor configuration. ([2e98db25](https://github.com/linuxdeepin/dde-file-manager/commit/2e98db2556eb0fa78ad1d75e8e428f89105f9801)) +* merged desktop HiDPI icon blur ([2d1d1b2d](https://github.com/linuxdeepin/dde-file-manager/commit/2d1d1b2dfc9a0342639081f9c85843651e643678)) +* redirect once for share panel in property dialog ([a5a35225](https://github.com/linuxdeepin/dde-file-manager/commit/a5a3522592822dab38cd74777ee7bcdb7683042b)) +* update the geometry of the background widget before emit the backgroundGeometryChanged signal ([e23460b5](https://github.com/linuxdeepin/dde-file-manager/commit/e23460b5858c0c829a487794d4b1b52824b07484)) +* desktop icons obscured by dock if scaling is enabled ... ([4b64fa31](https://github.com/linuxdeepin/dde-file-manager/commit/4b64fa312192df4d8434b268eb8cd32cf83479e6)) +* also try redirected URL for previewing. ([69e01d9a](https://github.com/linuxdeepin/dde-file-manager/commit/69e01d9a541c49c3012f74e77aeaf4dfdd762898)) +* dde-file-manager/dde-xdg-user-dirs-update set to executable ([10deedc8](https://github.com/linuxdeepin/dde-file-manager/commit/10deedc89191bf683f594ab7748e66fb24589adc)) +* crash if cannot found Delete menu action for Recent scheme ([082a2701](https://github.com/linuxdeepin/dde-file-manager/commit/082a27014fc0617c238a449667a83993387edcd9)) +* **dev-formatter:** use customQtThemeConfigPathByUserHome() ([6da134e7](https://github.com/linuxdeepin/dde-file-manager/commit/6da134e7f9778714d23aec32f510cd29765aa1ef)) + + + + +## 4.8.5.1 (2019-05-24) + + +#### Bug Fixes + +* Anything support disabled for non x86 arch ([990795ff](https://github.com/linuxdeepin/dde-file-manager/commit/990795ff3a9863b52afdd02558864855f7b9d0c7)) + + + + +## 4.8.5 (2019-05-23) + + +#### Bug Fixes + +* desktop won't start when fileDialogOnly process exist ([a9b91e0c](https://github.com/linuxdeepin/dde-file-manager/commit/a9b91e0cdc6a2658d8abaadc8056c531654f80d9)) +* use customQtThemeConfigPathByUserHome() ([1275fdb0](https://github.com/linuxdeepin/dde-file-manager/commit/1275fdb0e8167bebc978b21510a72cd954ff6899)) +* sidebar bookmark item cannot click after reorder ([1f0e9f3d](https://github.com/linuxdeepin/dde-file-manager/commit/1f0e9f3d49e69a53d35f9961cae662a47141065e)) +* should no longer show virtual entry property dialog ([c41bf089](https://github.com/linuxdeepin/dde-file-manager/commit/c41bf0892ad4364ee346e26cfb94c37a333d7ffa)) +* disk size sometimes can display negative number ([63d08b6a](https://github.com/linuxdeepin/dde-file-manager/commit/63d08b6af80cf42acff0dc3f7f44f4fb961b03fb)) +* drag file to other app from mergeddesktop ([2bd8374d](https://github.com/linuxdeepin/dde-file-manager/commit/2bd8374d8f85b6ed1a5fcfb2096666d240fd96cf)) +* search keyword contains brackets ([b256b5b3](https://github.com/linuxdeepin/dde-file-manager/commit/b256b5b39d2c8504fc5e9f615609f775426eb5a3)) + +#### Features + +* check if expand entry will make desktop full ([afd87d71](https://github.com/linuxdeepin/dde-file-manager/commit/afd87d71a59d067649e02fe57d16fa20ee6db13b)) +* **pro:** able to disable desktop shortcut and context menu ([3e05fe49](https://github.com/linuxdeepin/dde-file-manager/commit/3e05fe499973d786638108bc1c0b189f68ad2588)) + + + + +## 4.8.4 (2019-05-09) + + +#### Bug Fixes + +* hide indexing database in NTFS partition for Windows. ([4e8e6282](https://github.com/linuxdeepin/dde-file-manager/commit/4e8e6282654f36d46eca6c4520bc88712e77fc43)) +* loop call of update usershare ([0f58c7dc](https://github.com/linuxdeepin/dde-file-manager/commit/0f58c7dc8c9f7e27165f4245b666d1ef0d566a4b)) +* debug build FTBFS. ([eabfe29c](https://github.com/linuxdeepin/dde-file-manager/commit/eabfe29c7029b08cdb9d548afe83896d4ec513e8)) +* should create fileinfo to get local file ([64a95a81](https://github.com/linuxdeepin/dde-file-manager/commit/64a95a81305d7547374fbf13d1095a2f7ebed80b)) +* always update mergeddesktop file data ([98a20187](https://github.com/linuxdeepin/dde-file-manager/commit/98a201876e992751fb1b605c57a3a34302dd516b)) +* unable to access mtp mount device ([e4468c06](https://github.com/linuxdeepin/dde-file-manager/commit/e4468c06317ce52f51f7e7c59f990af3a2adea0e)) +* file mimetype results are not accurate on gvfs mount device ([55c050ea](https://github.com/linuxdeepin/dde-file-manager/commit/55c050eae00c6a59a8fef74cc98dcc6e2f85ba0d)) +* Update usershare info when getChildren ([aad94bdc](https://github.com/linuxdeepin/dde-file-manager/commit/aad94bdce2782ecb77388d6a0722c6e740e2d14b)) +* should create file info to get permissions ([33aba8ab](https://github.com/linuxdeepin/dde-file-manager/commit/33aba8ab0089a915ce46a7a6d30b098aee4f0a04)) +* fix typo in method name. ([cc715000](https://github.com/linuxdeepin/dde-file-manager/commit/cc715000b39c218538a6e5ba69cceeaa249e4ce1)) +* file permission error ([36d60f88](https://github.com/linuxdeepin/dde-file-manager/commit/36d60f88c03f2c4cd949fa3ec585712da4b9d4c7)) +* **dde-desktop:** the background window size and screen size are inconsistent ([d212babd](https://github.com/linuxdeepin/dde-file-manager/commit/d212babd50e6c4492f8f73d790e38290b153dbe4)) + + + + +## 4.8.3 (2019-04-25) + + +#### Bug Fixes + +* temporary disable paste on merged desktop ([55d0c9e5](https://github.com/linuxdeepin/dde-file-manager/commit/55d0c9e58bd854b831c14240b8c63f410b5d2bcf)) + + + + +## 4.8.2 (2019-04-25) + + +#### Bug Fixes + +* workaround for merged desktop ([b7a2f85e](https://github.com/linuxdeepin/dde-file-manager/commit/b7a2f85e907fd04759fb8ca77791778200e3e21f)) +* desktop widget hierarchy caused glitch ([8d329d86](https://github.com/linuxdeepin/dde-file-manager/commit/8d329d864c48d188680d0fd83e27241e997cdac8)) +* avoid save profile when using merged desktop ([1579ac11](https://github.com/linuxdeepin/dde-file-manager/commit/1579ac11ebf722715c00d1478000fb783d347071)) +* copy status not correct ([bd07342d](https://github.com/linuxdeepin/dde-file-manager/commit/bd07342d60f4f3c5fc91ba6e94fc4579684364f8)) +* **dde-wallpaper:** find wallpaper thumbnails with no results (#146) ([854383fb](https://github.com/linuxdeepin/dde-file-manager/commit/854383fb96f4ce1b9d7f257a9440ceec1c53494d)) + + + + +## 4.8.1 (2019-04-22) + + +#### Features + +* fileItemDisableFlag() for merged desktop ([8e328e33](https://github.com/linuxdeepin/dde-file-manager/commit/8e328e33a334cc3cb5e88415c3408ed3f82ee98e)) +* file watcher support for dfmmd scheme ([ca5d0486](https://github.com/linuxdeepin/dde-file-manager/commit/ca5d048664078627030ff1796e0f0eae091de201)) + +#### Bug Fixes + +* duplicated items from merged desktop controller ([ad3d514d](https://github.com/linuxdeepin/dde-file-manager/commit/ad3d514d23d46e1abffae7b49198fae88fe12f9e)) +* disable drag on merged desktop ([40d88ae7](https://github.com/linuxdeepin/dde-file-manager/commit/40d88ae7ed33af8f7877456be5848cd0d173eae3)) +* invalid command args quotes for QProcess ([6b27a341](https://github.com/linuxdeepin/dde-file-manager/commit/6b27a3419c05ee4141e98a6d2c45429dbed6e50b)) +* avoid crashing on file stat job. ([846ad1c3](https://github.com/linuxdeepin/dde-file-manager/commit/846ad1c3979d605e416cfec0c3d4305fc2b25cbd)) +* use plural for zero items. ([e0aa1e69](https://github.com/linuxdeepin/dde-file-manager/commit/e0aa1e694694647505ed6b34deda808478a1f5ba)) +* merge order caused compile error ([39a1e331](https://github.com/linuxdeepin/dde-file-manager/commit/39a1e331d00a5cc201376a15a2c0359916ca67bb)) +* some merged desktop check ([7f2acf05](https://github.com/linuxdeepin/dde-file-manager/commit/7f2acf054f894cf141770876c1c7239f989301d8)) +* The desktop background flash when the wallpaper is changed by user setting ([fc112bde](https://github.com/linuxdeepin/dde-file-manager/commit/fc112bdec9de480da2f11e8129dc6b6ce89b5166)) +* use macro ([3a655f5c](https://github.com/linuxdeepin/dde-file-manager/commit/3a655f5cc608d388e68b486fb20fd1f476bdc240)) +* avoid crash in some case ([42abe05b](https://github.com/linuxdeepin/dde-file-manager/commit/42abe05b24b082742ba65f2335956ed553b89962)) +* using keyboard navigation causes wrong number of files in the status bar. ([5b74ac8c](https://github.com/linuxdeepin/dde-file-manager/commit/5b74ac8c8eee521fc360facba76f1db11961cc5d)) +* wrong number of items in disk properties dialog. ([4c78d270](https://github.com/linuxdeepin/dde-file-manager/commit/4c78d2709b2ba98f1537a1a3ebdeed9f535c6d4d)) +* can open terminal under merged desktop scheme ([9795c6eb](https://github.com/linuxdeepin/dde-file-manager/commit/9795c6eb79d7111d02e7336f57b2d895023d14ab)) +* show hidden file on desktop not working ([dd00701e](https://github.com/linuxdeepin/dde-file-manager/commit/dd00701e1ec111a0cc990837220931ae38e602c5)) +* list of recently used files empties unexpectedly. https://github.com/linuxdeepin/internal-discussion/issues/1090 ([d9545d68](https://github.com/linuxdeepin/dde-file-manager/commit/d9545d684ede1ee11ee3fd660375222e5100563c)) +* right mouse button drag on virtual entry lead crash ([e8336f04](https://github.com/linuxdeepin/dde-file-manager/commit/e8336f040946be8ad5302be3adc357113dfdfbf9)) +* unknown mtime should show up properly now. ([e1f85519](https://github.com/linuxdeepin/dde-file-manager/commit/e1f85519c59f35a8ca82cee52c13b19b2f80bcce)) +* disable desktop context menu for merged desktop mode (#121) ([f05f9e5a](https://github.com/linuxdeepin/dde-file-manager/commit/f05f9e5a3a5ef8efdc36ec0ea807d5855c8751ff)) +* **desktop:** will show titlebar in a short time ([496d722c](https://github.com/linuxdeepin/dde-file-manager/commit/496d722c35a75384c39d9b08393764e5822ecdbb)) + + + + +## 4.8.0 (2019-04-09) + + +#### Bug Fixes + +* also prompt the user to set executable bits for ELF files. ([ad9910df](https://github.com/linuxdeepin/dde-file-manager/commit/ad9910dfcfc3f900972db8a91d1883fdd10183bf)) +* crash on create file (#115) ([74beb59e](https://github.com/linuxdeepin/dde-file-manager/commit/74beb59ebfda31382fee666ccbf99e9a3962770b)) +* stray question mark in string. (#114) ([45029ef3](https://github.com/linuxdeepin/dde-file-manager/commit/45029ef38e149f30e4f0bcf15ea88e54121b09d4)) +* **dialog:** default button and recommend button not same (#112) ([ac591df8](https://github.com/linuxdeepin/dde-file-manager/commit/ac591df87bab4440c71a0a4a143ed9a7dc19c665)) + +#### Features + +* merged desktop (#118) ([96e69027](https://github.com/linuxdeepin/dde-file-manager/commit/96e69027c6a87ed13b1b834130baae2bdbb01b31)) +* implement clear recent history. (#111) ([e25bca7d](https://github.com/linuxdeepin/dde-file-manager/commit/e25bca7d43cbeaa4b6b2f46560efad426beac59c)) + + + + +## 4.7.9 (2019-04-04) + + +#### Bug Fixes + +* can not close wallpaper settings view on click empty area ([dab419cb](https://github.com/linuxdeepin/dde-file-manager/commit/dab419cb213bb45c0b645a6337135e0a02c5b730)) +* zero size plain text file is not executable script (#108) ([5707925e](https://github.com/linuxdeepin/dde-file-manager/commit/5707925e0aed73af7f8c0509e1005f3d66fe5482)) +* the mode switch widget overlaps with other widgets ([58b0f7a0](https://github.com/linuxdeepin/dde-file-manager/commit/58b0f7a093155fdc2dfd7915efc424c39358c12b)) +* file search view property dialog is empty (#104) ([11ecac82](https://github.com/linuxdeepin/dde-file-manager/commit/11ecac82d04f082f41788988b41486c637609ba2)) +* dock mount plugin label content as plain text (#101) ([ecb7cbd0](https://github.com/linuxdeepin/dde-file-manager/commit/ecb7cbd07cb4c190f74da8c7fe8d995e16dc2a94)) +* potential crash when an optical media is inserted. (#100) ([52d1cf67](https://github.com/linuxdeepin/dde-file-manager/commit/52d1cf6783b6a9a437a279a96fb4eeb2099b4320)) +* optical drive detection. (#99) ([2a524d63](https://github.com/linuxdeepin/dde-file-manager/commit/2a524d633f172362fe55b4538816a3efbdc9c702)) +* avoid crash when we cannot got device info (#98) ([24d1b3cd](https://github.com/linuxdeepin/dde-file-manager/commit/24d1b3cd5ec810f8443b614a5eae1edfffe93819)) +* Nothing on desktop in multi-screen and copy mode ([46f0028a](https://github.com/linuxdeepin/dde-file-manager/commit/46f0028a43eaeff6f8a20dd827a3245ef84e1ff0)) +* **Desktop:** use right-click menu when use window scale ratio, desktop will draw the content misplaced ([91c00d2d](https://github.com/linuxdeepin/dde-file-manager/commit/91c00d2d0b5f59cc05a7a2c77b28dbdf2bf4dcec)) + +#### Features + +* mount disk image. (#110) ([9dace08c](https://github.com/linuxdeepin/dde-file-manager/commit/9dace08c2eb697a8b10447f61f974fd16be271fb)) +* context menu icon visible state now configurable (#96) ([e2b4ff1f](https://github.com/linuxdeepin/dde-file-manager/commit/e2b4ff1f90df9d8ce401e0ae4f91ca48e6909b33)) + + + + +## 4.7.8.2 (2019-03-29) + + +#### Bug Fixes + +* crash when open systemdisk property (#93) ([5c8d4b6f](https://github.com/linuxdeepin/dde-file-manager/commit/5c8d4b6f194d8b1b7923dc0435e888530dbd8f24)) + + + + +## 4.7.8.1 (2019-03-29) + + +#### Bug Fixes + +* use setPlainText for computer view items (#91) ([f3a53417](https://github.com/linuxdeepin/dde-file-manager/commit/f3a534178da8fb7a6acd9d80544ff2c0aee84f17)) +* build error if enable DISABLE_ANYTHING ([1358fa39](https://github.com/linuxdeepin/dde-file-manager/commit/1358fa39a3331d1cd4bc7f9879f63133623b21a5)) +* MenuAction::Unknow is no longer the last one (#89) ([931c97f8](https://github.com/linuxdeepin/dde-file-manager/commit/931c97f8c73c6aa535e9979970dec40138ccd6a2)) +* allowed find parent view mode (#88) ([857eb615](https://github.com/linuxdeepin/dde-file-manager/commit/857eb6152d0fe4a7c3daf09f9cccef7df7a3ca78)) + + + + +## 4.7.8 (2019-03-27) + + +#### Bug Fixes + +* user dirs changed to English in other DEs (#67) ([b84dde56](https://github.com/linuxdeepin/dde-file-manager/commit/b84dde56ffc56a744e92dea802a8da892255ef16)) +* whel not working on ComputerView (#82) ([2191f7d3](https://github.com/linuxdeepin/dde-file-manager/commit/2191f7d3a5d4f0c4ac90f8fd3314260bd9834dbe)) +* disk property display name not correct ([832ffda4](https://github.com/linuxdeepin/dde-file-manager/commit/832ffda4d1654b1bb20cc4646169761be137b84b)) +* set proper working directory when running executables ([4d861c9b](https://github.com/linuxdeepin/dde-file-manager/commit/4d861c9bafa67015d30487162753de5b669b2e13)) +* UI stuck when searching ([266b285a](https://github.com/linuxdeepin/dde-file-manager/commit/266b285a8e02b944dc0faeb2716ea2d052ffc9ac)) +* locker protect for handle xbel file changed ([70021a74](https://github.com/linuxdeepin/dde-file-manager/commit/70021a74462684109eebb86dac8baa1aecbf8a20)) +* use concurrent to handle recent file changed ([e7a23aed](https://github.com/linuxdeepin/dde-file-manager/commit/e7a23aed0333d4a47e0c315f82b758e35a85c671)) +* can't use anything for subdirectory ([79778fa5](https://github.com/linuxdeepin/dde-file-manager/commit/79778fa55201fa0aa1e51bedf7f57c93d49b5550)) +* user share dialog cannot open twice ([92e33ede](https://github.com/linuxdeepin/dde-file-manager/commit/92e33ede74f9603f3ae7de33c08be32f51f63ecc)) +* **dde-file-manager:** crash at getNodeByIndex ([cc5031e0](https://github.com/linuxdeepin/dde-file-manager/commit/cc5031e0bb92d85cb346519d705562df8c673182)) +* **dde-wallpaper:** the mode switch widget overlaps with other widgets ([20d62130](https://github.com/linuxdeepin/dde-file-manager/commit/20d62130f343ad1107d11c7ab40f3fb611459b30)) + +#### Features + +* menu plugin can know menu is triggered on desktop (#78) ([24bb2f89](https://github.com/linuxdeepin/dde-file-manager/commit/24bb2f892bc0b9b23f678e8794a5bf5a4b5e4cfc)) +* read ~/.dde_env when run via pkexec ([8e04d77b](https://github.com/linuxdeepin/dde-file-manager/commit/8e04d77bc3eda884ebe4ec861a114d1f6dfa4bd5)) +* add backup file type for deepin-clone ([6646405a](https://github.com/linuxdeepin/dde-file-manager/commit/6646405a07a83ceac6f8672665e8dc8f93784c68)) +* support copy file on preview dialog ([92a15496](https://github.com/linuxdeepin/dde-file-manager/commit/92a15496587232e47e7bacdaa69a373beb70d59e)) +* get the search results with segment of quick search ([696a93b1](https://github.com/linuxdeepin/dde-file-manager/commit/696a93b152158e7cb7126aff116a64b260409b66)) +* handle sigterm ([c85a7ba4](https://github.com/linuxdeepin/dde-file-manager/commit/c85a7ba4c83271513aa9a6e7c2efce899b3af144)) +* **dde-wallpaper:** support wallpaper slideshow ([d371c5d1](https://github.com/linuxdeepin/dde-file-manager/commit/d371c5d120a036d3931a08332ae3ca29a30232c8)) + + + + +## 4.7.7.1 (2019-03-04) + + +#### Features + +* notify on device got disconnected ([64e9ce81](https://github.com/linuxdeepin/dde-file-manager/commit/64e9ce81526614df358085e2dc821923ac753749)) +* Ctrl+I to show property dialog on desktop ([fbc650a6](https://github.com/linuxdeepin/dde-file-manager/commit/fbc650a6feea4c88b08e90de76a5da7f8e02269f)) +* show source path on property dialog for trash url ([25a44d7f](https://github.com/linuxdeepin/dde-file-manager/commit/25a44d7f1514af63ac09261b6fe1fef334179f70)) + +#### Bug Fixes + +* enter ~ navigate to home dir ([e0440d76](https://github.com/linuxdeepin/dde-file-manager/commit/e0440d76daa92e3229b11ad380fb7b4421783ce3)) +* crash in loongson platform ([648ce30d](https://github.com/linuxdeepin/dde-file-manager/commit/648ce30d86ecf760db611987884788f3a1ff6209)) +* fs type for /home ([72e49a99](https://github.com/linuxdeepin/dde-file-manager/commit/72e49a99c0bba445c86354ec4a0d2ebe6abe37de)) +* cannot browse Samsung devices ([ef95c920](https://github.com/linuxdeepin/dde-file-manager/commit/ef95c920cc7b83f35cf7fddb5a1d51a204a465a4)) + + + + +## 4.7.7 (2019-02-25) + + +#### Features + +* disable deepin anything on arm64(aarch64) ([359dd607](https://github.com/linuxdeepin/dde-file-manager/commit/359dd60722706c47c291c4ac329d007beb462404)) +* crumb item context menu ([3dc9d110](https://github.com/linuxdeepin/dde-file-manager/commit/3dc9d110682611a06c422e6bf10b496f1262b927)) +* hidden option to control crumbbar clickable area visible ([c1faa8e1](https://github.com/linuxdeepin/dde-file-manager/commit/c1faa8e160f3ad5693d906ecbcabf3d9a3edda66)) +* remove addressbar clickable area ([e21c64d7](https://github.com/linuxdeepin/dde-file-manager/commit/e21c64d75906ba3ee68340d71e82bf439ef32a2f)) +* **dde-wallpaper:** enable screensaver function for deepin professional ([4ae45381](https://github.com/linuxdeepin/dde-file-manager/commit/4ae453812c2e00b5017c798146829c06d61ab4af)) + +#### Bug Fixes + +* only do show filedialog via dbus call ([b6e97adc](https://github.com/linuxdeepin/dde-file-manager/commit/b6e97adcc6472b9de98107521d23c8d5ed283d7e)) +* ComputerPropertyDialog value label width not correct ([927a83aa](https://github.com/linuxdeepin/dde-file-manager/commit/927a83aa5605da714b38a190160653d5db1c69a7)) +* open folder when select a folder and click open in DFileDialog ([882f2295](https://github.com/linuxdeepin/dde-file-manager/commit/882f2295b73f278c7a33292c4b47c26267a90310)) +* wrong search button icon on admin mode ([4233adb0](https://github.com/linuxdeepin/dde-file-manager/commit/4233adb0fee6fd843173d84c76a686d91af90839)) +* use default-terminal provided by deepin-daemon if possible ([3ba6625c](https://github.com/linuxdeepin/dde-file-manager/commit/3ba6625c624e810e27c1a0dea3556955227f8b1d)) + + + + +## 4.7.6 (2019-02-11) + +fix: add missing header file + +## 4.7.5 (2019-01-25) + + +#### Bug Fixes + +* won't select file after file rename or create ([8469d743](https://github.com/linuxdeepin/dde-file-manager/commit/8469d743d60ea3b892d9b7590aa127d7c3815105)) +* dbus service exec argv use -d ([414f6c03](https://github.com/linuxdeepin/dde-file-manager/commit/414f6c03a03a074d3b44bb82ac53ebdf893af501)) +* update status bar when fileview data change ([45fd6f1b](https://github.com/linuxdeepin/dde-file-manager/commit/45fd6f1b00cfebae89b82cc4dfccc58219e07c2c)) +* search filter date use range ([ffc3e5bb](https://github.com/linuxdeepin/dde-file-manager/commit/ffc3e5bb6855fa085c4ad98a0ef6609ec4c2e45c)) +* advance search bar i18n ([ca5fd082](https://github.com/linuxdeepin/dde-file-manager/commit/ca5fd0822bc61d23a40f77af7555c0c851cb239f)) +* advance search file size range ([65313b00](https://github.com/linuxdeepin/dde-file-manager/commit/65313b00a2abbb1788070afa425ebb69861e7453)) +* don't watch whole locale share dir for recent file support ([4e4ec08f](https://github.com/linuxdeepin/dde-file-manager/commit/4e4ec08fc13e969047538faabe85acb4ebf054d3)) +* wrong sort order in recentfile view ([7c9b8312](https://github.com/linuxdeepin/dde-file-manager/commit/7c9b8312f6f4f862fa8f9b57696f42fa43ce6b80)) +* avoid using dpkg-parsechangelog ([76189d11](https://github.com/linuxdeepin/dde-file-manager/commit/76189d11eba0d497b7b7cab578292feab6108d9c)) +* update dde-dock-dev package version limit ([bbb3d0e9](https://github.com/linuxdeepin/dde-file-manager/commit/bbb3d0e9279c7fd6a02433b5c5ab6d1e14fa25ea)) +* not apply saved view state in some case ([903bb1fe](https://github.com/linuxdeepin/dde-file-manager/commit/903bb1fe4da34245c0e4853739fdfb6e83b9b0c5)) +* **dde-desktop:** the application will be auto quit on sw_64 platform ([5ac98c53](https://github.com/linuxdeepin/dde-file-manager/commit/5ac98c53bde00169ecec03424632cd4714786343)) + +#### Features + +* advance search ([419e539e](https://github.com/linuxdeepin/dde-file-manager/commit/419e539e74242bd2ef13dea254182aa510061dcd)) + + + + +## 4.7.4.4 (2019-01-15) + + +#### Bug Fixes + +* chinese garbled ([138c9c08](https://github.com/linuxdeepin/dde-file-manager/commit/138c9c08ff1a5a3dd4186b6816edbecb85d58ba6)) +* remove debug output which should be deleted ([3ba87c74](https://github.com/linuxdeepin/dde-file-manager/commit/3ba87c74953c3198726832ec95e97345a5c480d6)) +* only apply selection change in current view ([9edf74dc](https://github.com/linuxdeepin/dde-file-manager/commit/9edf74dc32879c50c65ffd56225a912ef5ce5c06)) +* avoid crash when paste file to unsupported url ([63273c3e](https://github.com/linuxdeepin/dde-file-manager/commit/63273c3ee988fbb651138d0bd1edb5946ccc38eb)) + + + + +## 4.7.4.3 (2019-01-11) + + +#### Bug Fixes + +* try stop device when do eject from sidebar ([f7d5be54](https://github.com/linuxdeepin/dde-file-manager/commit/f7d5be544e2cee792d3adb4aa12758508a39270b)) +* do powerOff if a external disk can powerOff ([1225cc3b](https://github.com/linuxdeepin/dde-file-manager/commit/1225cc3b1a64809d4bbbe3e09af2703dbf62ef78)) + + + + +## 4.7.4.2 (2019-01-10) + + +#### Bug Fixes + +* detect format by content when generate thumbnail for wallpaper ([e37f55ae](https://github.com/linuxdeepin/dde-file-manager/commit/e37f55aec15b2e75c10eefc77988a9f2b33657f5)) +* crash when copy file ([434e4502](https://github.com/linuxdeepin/dde-file-manager/commit/434e4502a56aff3c1815772e22a32d0824bf67d9)) +* DnD on device sidebar item ([203fc1df](https://github.com/linuxdeepin/dde-file-manager/commit/203fc1dffdd9e47f4f49d340facbe2fe080bc0a3)) +* **recent:** disable drag and drop files to sidebar. ([ff701a37](https://github.com/linuxdeepin/dde-file-manager/commit/ff701a37028a97b37a58f8fcb8f382936eb2e96c)) + +#### Features + +* display icon at context menu in QT_DEBUG build ([f409c782](https://github.com/linuxdeepin/dde-file-manager/commit/f409c782bb813e81ead8759dab448a476c77f41a)) + + + + +## 4.7.4.1 (2019-01-07) + + +#### Bug Fixes + +* build failed on deepin_professional ([dd86e610](https://github.com/linuxdeepin/dde-file-manager/commit/dd86e6108b210570bbb57b0ff01d1a8c8c730399)) +* **dde-wallpaper:** not stop screensaver preview when switch to set wallpaper mode ([a76b22e0](https://github.com/linuxdeepin/dde-file-manager/commit/a76b22e0d09c3c6e27c5b0cfdcb719c238a44d41)) + + + + +## 4.7.4 (2019-01-07) + + +#### Bug Fixes + +* **dde-desktop:** + * fix the "Wallpaper" to "Set Wallpaper" ([279251f2](https://github.com/linuxdeepin/dde-file-manager/commit/279251f2665fcc86339a35ed90383e9551a33311)) + * translate error: "Wallpaper" on chinese ([dfa567da](https://github.com/linuxdeepin/dde-file-manager/commit/dfa567da1aa5366b271c7e6a540718f186845142)) +* **dde-wallpaper:** the tool widgets and the switch mode widget is overlap ([29d7c09d](https://github.com/linuxdeepin/dde-file-manager/commit/29d7c09d3d1962f215797f54db24595267cbb267)) + + + + +## 4.7.3 (2019-01-03) + + +#### Bug Fixes + +* mute error dialog for some type ([613ec1e7](https://github.com/linuxdeepin/dde-file-manager/commit/613ec1e733840b1bc1cb79856fbfd0c3f7d878b7)) + + + + +## 4.7.2 (2019-01-02) + + +#### Bug Fixes + +* can disable screensaver on dde-desktop project ([d0f5393b](https://github.com/linuxdeepin/dde-file-manager/commit/d0f5393baf23947669785d00bdb532bc3cb153c6)) +* **dde-wallpaper:** the svg cover image is blurry on HI-DPI ([3293f4b4](https://github.com/linuxdeepin/dde-file-manager/commit/3293f4b4021256eebffecd07d429947f8a2e893a)) + + + + +## 4.7.1.12 (2018-12-29) + + +#### Bug Fixes + +* no longer treat home dir as template dir ([87662ed9](https://github.com/linuxdeepin/dde-file-manager/commit/87662ed928f795ed12203a1b79a1f437e949ba8f)) + + + + +## 4.7.1.11 (2018-12-29) + + +#### Features + +* disable automount in live system ([1ac5d667](https://github.com/linuxdeepin/dde-file-manager/commit/1ac5d667b57cc67f9846467e7ae860306f694c26)) +* support set/preview screensaver ([edd7de5c](https://github.com/linuxdeepin/dde-file-manager/commit/edd7de5c449215d9699283112642528465652b40)) +* **screensaver:** support set lock screen at awake ([d955143f](https://github.com/linuxdeepin/dde-file-manager/commit/d955143fd0bb7209e26315e99e2e096a7b092288)) + +#### Bug Fixes + +* **dde-wallpaper:** + * the svg cover image is blurry on HI-DPI ([433481da](https://github.com/linuxdeepin/dde-file-manager/commit/433481da481f491f03a60edefa5c31f8cde45b3c)) + * change the screensaver start time list ([559c06dd](https://github.com/linuxdeepin/dde-file-manager/commit/559c06ddd87c126608e606b9a0f333608f54862f)) + * set the DSegmentedControl button minimum width to 40px ([53ceff8d](https://github.com/linuxdeepin/dde-file-manager/commit/53ceff8df8a34cbc4af8b16fa5ea7e9df7453778)) + * the delete button position is warong ([ad77c2d9](https://github.com/linuxdeepin/dde-file-manager/commit/ad77c2d904ced42847fb421d6a521117bac0dbc1)) + + + + +## 4.7.1.10 (2018-12-21) + + +#### Bug Fixes + +* add a timeout for TagManagerDaemon/disposeClientData ([5c72e0b8](https://github.com/linuxdeepin/dde-file-manager/commit/5c72e0b8a2bcdfa0d9844d4665e547db66504e7f)) +* dark theme header view section border color ([1b7af3f7](https://github.com/linuxdeepin/dde-file-manager/commit/1b7af3f77ce536bce07948b65eaeb2718446ddfc)) +* OpenWidthDialog support touch scrolling ([a9415fb6](https://github.com/linuxdeepin/dde-file-manager/commit/a9415fb6866e8314811cc1ac77aa6cef02f8659e)) +* ComputerView item vertical align spacing ([ff5a8d9d](https://github.com/linuxdeepin/dde-file-manager/commit/ff5a8d9d88428b39d9b56da54e17dc1a8dc0de17)) +* Device icon not changed when switching theme ([3820e168](https://github.com/linuxdeepin/dde-file-manager/commit/3820e168e372d5c9d88ad5080314055af8b015da)) +* trash view wrong sort order ([4fceafaa](https://github.com/linuxdeepin/dde-file-manager/commit/4fceafaa1ceb543b81ee21f18c32ea56b83e2d71)) +* wrong item disappeared when remote device removed ([d14c17fd](https://github.com/linuxdeepin/dde-file-manager/commit/d14c17fd5802491d5a40fb2ec207b2de2ecf8bc1)) + + + + +## 4.7.1.9 (2018-12-14) + + +#### Features + +* open with for multiple file selected ([250cc486](https://github.com/linuxdeepin/dde-file-manager/commit/250cc486bec256fa9c8831c1cb63c22b237d4f71)) + +#### Bug Fixes + +* file suffix keep letter-case ([f10e75c7](https://github.com/linuxdeepin/dde-file-manager/commit/f10e75c77a70989a4f3ebebf755edf67770066ad)) +* Dialog size not correct when using icon from theme ([520e4dee](https://github.com/linuxdeepin/dde-file-manager/commit/520e4deea668b2cac8b8cb206aed32f73b25b0a4)) +* display 'Disk info' in sidebar root item ([4f64df4f](https://github.com/linuxdeepin/dde-file-manager/commit/4f64df4f89a39d7b0ccd03e955918f64f18d52eb)) +* **dock-plugin:** the icon will not change after the system theme changes ([bd48579d](https://github.com/linuxdeepin/dde-file-manager/commit/bd48579d6edef6065c1f7ca8e25c49cbae296d19)) + + + + +## 4.7.1.8 (2018-12-10) + + +#### Bug Fixes + +* remove focus border highlight ([42e9f8fd](https://github.com/linuxdeepin/dde-file-manager/commit/42e9f8fdd9e2f2926fda1af3b48cccbe10444cbe)) + + + + +## 4.7.1.7 (2018-12-07) + + +#### Bug Fixes + +* QStorageInfo cannot get device on invalid symlink ([85d63953](https://github.com/linuxdeepin/dde-file-manager/commit/85d6395341e5b238b7b4216d21e692e63d91c722)) +* mount plugin for dock ver 1.1 ([5272d6a5](https://github.com/linuxdeepin/dde-file-manager/commit/5272d6a55117f065e2b82b1dc76802c09b5da686)) +* **dde-desktop:** relayout on the font size changed ([d1cc1313](https://github.com/linuxdeepin/dde-file-manager/commit/d1cc1313fee743cec7bf29e689ed1b1170c49d88)) + +#### Features + +* mac style headerview snapping ([9a661b07](https://github.com/linuxdeepin/dde-file-manager/commit/9a661b074752f57f14e9a43b6af2c51d25334ac8)) +* dav scheme basic support ([7870d32a](https://github.com/linuxdeepin/dde-file-manager/commit/7870d32af7525cd351042392e85e02c677b13afe)) +* ask for adding executable permission for flatpak file ([0ab1fb20](https://github.com/linuxdeepin/dde-file-manager/commit/0ab1fb20fbb5aaf8466872382d278f4664e0b4a1)) +* disk property for /home if available ([e0ff94a9](https://github.com/linuxdeepin/dde-file-manager/commit/e0ff94a941c592a0674a0d4a7b9adcdc824046cd)) + + + + +## 4.7.1.6 (2018-12-03) + + +#### Features + +* ask for adding executable permission for AppImage file ([d7990128](https://github.com/linuxdeepin/dde-file-manager/commit/d7990128e6d38cbb352f229855ac0b437d22be11)) +* keep the suffix when the file name is truncated ([77e76229](https://github.com/linuxdeepin/dde-file-manager/commit/77e762291feac47a2ec748af52553fddf9860c9b)) + +#### Bug Fixes + +* call QAbstractItemModel::endRemoveRows() ([cf1b43dd](https://github.com/linuxdeepin/dde-file-manager/commit/cf1b43dd720b03a199d6187815cdc1ac2c1a344f)) + + + + +## 4.7.1.5 (2018-11-30) + + +#### Bug Fixes + +* crash when remove file out of current view ([a2aa4ccd](https://github.com/linuxdeepin/dde-file-manager/commit/a2aa4ccde7da7a585831be07e944f4651b3e294d)) +* no longer remove device which should be ignored ([7675f3bc](https://github.com/linuxdeepin/dde-file-manager/commit/7675f3bc39b4850e32e35f209899869a745b868b)) +* no longer refresh device list when unmounting removable dev ([69db1f9c](https://github.com/linuxdeepin/dde-file-manager/commit/69db1f9cea01e2be91a1976268ab8fc7dc79c09e)) +* crash when insert a blank dvd disc ([0fe51d0b](https://github.com/linuxdeepin/dde-file-manager/commit/0fe51d0bc1e62ec99cb846c5145d2f282ec9d7e2)) +* **text_preview:** encoding support russian in cyrllic. ([b30e02e6](https://github.com/linuxdeepin/dde-file-manager/commit/b30e02e6541df97e9fd5eb9bb9adf3eee0e0d282)) + + + + +## 4.7.1.4 (2018-11-27) + + +#### Features + +* filesystem type on propertydialog #41 ([197e57d4](https://github.com/linuxdeepin/dde-file-manager/commit/197e57d476ff6254169de046cf2c962c3539d920)) + +#### Bug Fixes + +* eject removable device from dock ([75e142e9](https://github.com/linuxdeepin/dde-file-manager/commit/75e142e9ea0482faa889dd0e680a8889b10eb5c4)) +* vendor support for context menu ([df26771a](https://github.com/linuxdeepin/dde-file-manager/commit/df26771ac03eb5d9cfc234bda37d43dae824be4d)) +* adjust item height when changing font size ([91e009e6](https://github.com/linuxdeepin/dde-file-manager/commit/91e009e6896a1a26499c9858841dff403b819053)) +* file template is not true-empty ([5b26d9ef](https://github.com/linuxdeepin/dde-file-manager/commit/5b26d9efedf50e576ebdc468e96b150ebbe3ae46)) +* no longer set itself as default filemanager ([63b044ff](https://github.com/linuxdeepin/dde-file-manager/commit/63b044ff390701a5a00ca69f1773799d4c6f4cfd)) + + + + +## 4.7.1.3 (2018-11-23) + + +#### Features + +* selected text color ([cd284298](https://github.com/linuxdeepin/dde-file-manager/commit/cd284298af078179ea4f84e434744436d687520e)) +* support preview the gif image ([3751bf14](https://github.com/linuxdeepin/dde-file-manager/commit/3751bf14ec0390edf13ecde242948c422da44682)) +* GenericName and Vendor in .desktop file ([f92fe0e5](https://github.com/linuxdeepin/dde-file-manager/commit/f92fe0e5c3810132b7e8f955a615d4e01161b5a6)) +* Support for deepin vendor desktop file ([d2f93e5d](https://github.com/linuxdeepin/dde-file-manager/commit/d2f93e5dd12641ef67eba117ebc31a76a4efce1e)) +* display folder size as '-' ([a670ecec](https://github.com/linuxdeepin/dde-file-manager/commit/a670ececc95a1b433ea343914ae4c52cbde7e738)) + +#### Bug Fixes + +* for removable device, do eject instead of unmount ([1f8fe6ee](https://github.com/linuxdeepin/dde-file-manager/commit/1f8fe6ee3276a603139788bbdaafb66e51bbb6ea)) +* GenericName and vendor support ([4b58acba](https://github.com/linuxdeepin/dde-file-manager/commit/4b58acba3b8795bc9360c5145090bf359be3ebc9)) +* cannot mount afc. ([e6d7a570](https://github.com/linuxdeepin/dde-file-manager/commit/e6d7a570253695da1a7840a3321bd97553bdea7d)) +* can not set as default app in some case ([95a6d377](https://github.com/linuxdeepin/dde-file-manager/commit/95a6d377ef2572a4a4f4a1666b4d8c7e8eb0e1c0)) +* older qt version support ([a7e2eba2](https://github.com/linuxdeepin/dde-file-manager/commit/a7e2eba29cb99f2fa70be34802e3f1b7b379d491)) +* recent view flashing. ([33a2dd64](https://github.com/linuxdeepin/dde-file-manager/commit/33a2dd648f28701f738ed0bd85d43ac043f67760)) +* don't warning if ntfs mounted via kernel drv ([4b39c53e](https://github.com/linuxdeepin/dde-file-manager/commit/4b39c53e4055c8c9d03f05a2444a9f7235c99e6f)) +* **dock-plugin:** pixmap align ([777e8302](https://github.com/linuxdeepin/dde-file-manager/commit/777e8302e5525bf5d164d36adc1ac1a7105e7087)) +* **fileutils:** remove unused code. ([86742aac](https://github.com/linuxdeepin/dde-file-manager/commit/86742aac40e59ea8fa8a32e3480ab6ebffed830a)) +* **recent:** + * search open location error. ([6a80e562](https://github.com/linuxdeepin/dde-file-manager/commit/6a80e5622c4ea7486a3e6d37d195c8c96806a8c6)) + * use modified datetime. ([45a795b7](https://github.com/linuxdeepin/dde-file-manager/commit/45a795b7dc5070b92cb6da6cb5dcf1a5e6810ff1)) + * use the correct last time. ([e3ec6545](https://github.com/linuxdeepin/dde-file-manager/commit/e3ec654579c960255701ea60a954cc8fdce09fb5)) + + + + +## 4.7.1.1 (2018-11-12) + + +#### Bug Fixes + +* undefined symbol on archlinux ([34748039](https://github.com/linuxdeepin/dde-file-manager/commit/3474803988d5a143ff5910f936da2ec4e014c0a9)) +* xbel does not exist for listening failure. ([73763a4e](https://github.com/linuxdeepin/dde-file-manager/commit/73763a4eeb4d210f1f27027f370e479e446fd9da)) +* **recent:** + * don't popup dialog. ([79686f09](https://github.com/linuxdeepin/dde-file-manager/commit/79686f09d304c15f410f5f006e141b49673b1a39)) + * conflict with gtk recent manager. ([a68d84f7](https://github.com/linuxdeepin/dde-file-manager/commit/a68d84f765add370b6ffb82cd79fadc21160e3b1)) + + + + +## 4.7.1 (2018-11-09) + + +#### Bug Fixes + +* Wrong selected item number ([11faeef0](https://github.com/linuxdeepin/dde-file-manager/commit/11faeef0c26e31e7781bad72d91247a2f771a520)) +* mount plugin ignore loop device ([e6992de3](https://github.com/linuxdeepin/dde-file-manager/commit/e6992de318f0a5aa050030e9af978b0b2cabaf8e)) +* lag when copy large file on desktop ([e637e230](https://github.com/linuxdeepin/dde-file-manager/commit/e637e2305ec44986acaaa16ccaa3922c8e19bd38)) +* multiple file DnD issue in some case ([bd4ef257](https://github.com/linuxdeepin/dde-file-manager/commit/bd4ef25754ac85cf5b0a612d4422cf3b79252dc4)) +* open with dialog missing recommend apps ([a6a132c4](https://github.com/linuxdeepin/dde-file-manager/commit/a6a132c42c2c5107d5b470af782099a0e0fbe75e)) +* delete files trash. ([3e10b5c9](https://github.com/linuxdeepin/dde-file-manager/commit/3e10b5c99679a26a110553a87c9e6e4bc68ab547)) +* missing header file ([df6cf62c](https://github.com/linuxdeepin/dde-file-manager/commit/df6cf62cf1e29db37d8a58b9b8768a227b33376b)) +* workaround for recent file support ([154d2528](https://github.com/linuxdeepin/dde-file-manager/commit/154d25283845986d0d307b4dc2d68dc380929d74)) +* disable set wallpaper for gif file ([b0f2569a](https://github.com/linuxdeepin/dde-file-manager/commit/b0f2569a78c6a8bb65fb114d257782bcc019687d)) +* wrong open with section when symlink no longer valid ([2409f208](https://github.com/linuxdeepin/dde-file-manager/commit/2409f208948d98dabd2effc994ee6b65e05eeacd)) +* root partition wrong file count in property dialog ([201b722c](https://github.com/linuxdeepin/dde-file-manager/commit/201b722cbf4e76e04901fd00bc22448de0e24da2)) +* subtitle empty floder. ([2f605bb0](https://github.com/linuxdeepin/dde-file-manager/commit/2f605bb0f2e9b5f68ead19a3c0b188f67c6d87e8)) +* goto home dir when hide recent entry ([3ad1e9cd](https://github.com/linuxdeepin/dde-file-manager/commit/3ad1e9cda6350a353d7c086bb239c2b7a0aeb8fc)) +* do not resize column if rowCount is 0 ([6de65107](https://github.com/linuxdeepin/dde-file-manager/commit/6de651076dd94ebc9ceed883f8b678e93f589641)) +* mount plugin i18n ([3b1623d3](https://github.com/linuxdeepin/dde-file-manager/commit/3b1623d3ebf6718916c0906fa60451ef5ab8d6ce)) +* tooltip hide right after mouse leave ([9500afc2](https://github.com/linuxdeepin/dde-file-manager/commit/9500afc23a491081c4d1a48ef53bf248b4b45591)) +* **mountPlugin:** unmount all will now unmount vfs device ([97541409](https://github.com/linuxdeepin/dde-file-manager/commit/9754140981ebecf8b83623ee76556d7b023d9d69)) +* **pro:** remove DnD limit for some desktop file ([d70f59c7](https://github.com/linuxdeepin/dde-file-manager/commit/d70f59c79615f89d35e6904f9bcdb6c5d93eb387)) +* **recent:** + * support decompress file. ([36466703](https://github.com/linuxdeepin/dde-file-manager/commit/3646670377b808f6079fd5ec7cdb262083286ab7)) + * support tag color display. ([cc4a8d11](https://github.com/linuxdeepin/dde-file-manager/commit/cc4a8d11a0fbf0b0cba0bd35e6af89a82718b41f)) + * support listening delete files. ([5f3979a4](https://github.com/linuxdeepin/dde-file-manager/commit/5f3979a4d6a0335e059770700b740029468b107e)) + + + + +## 4.6.10 (2018-11-01) + + +#### Features + +* support recent file settings are displayed. ([a5ea5541](https://github.com/linuxdeepin/dde-file-manager/commit/a5ea5541388eaf4b382c5aaf21669be537977825)) +* **desktop:** support keyboard chinese positioning. ([85e366f5](https://github.com/linuxdeepin/dde-file-manager/commit/85e366f5c3e5844df559b3ef355ea660247e5a37)) +* **xbel:** support for removing files from recent. ([1d728071](https://github.com/linuxdeepin/dde-file-manager/commit/1d7280710838d5d52edaab8a3fc0af730f8dfc3c)) + +#### Bug Fixes + +* remove warning of style sheet ([7e1b5782](https://github.com/linuxdeepin/dde-file-manager/commit/7e1b578251314f6ae3a65739b11fed59e4640ac6)) +* recent uses normal right menu. ([55265e1f](https://github.com/linuxdeepin/dde-file-manager/commit/55265e1f9e28d9492a166cc3ed89000df59e5886)) +* check only when dir got accessed ([a8603248](https://github.com/linuxdeepin/dde-file-manager/commit/a860324810af132f5f8462bb90a7d54fb091add5)) +* override the recent right menu. ([e00987e0](https://github.com/linuxdeepin/dde-file-manager/commit/e00987e03e207c59bb0a0cbe96f857bf07bb0f9d)) +* check smb dir permission with anonymous access ([a057e515](https://github.com/linuxdeepin/dde-file-manager/commit/a057e515b95b78dc3f356c551b1e0431de4b79ee)) +* allowed DnD when previous DnD copy not finished ([57c42479](https://github.com/linuxdeepin/dde-file-manager/commit/57c4247939774a99a2c19d6c90b6ea09904d58e5)) +* can not sort on recent view ([5bec3eba](https://github.com/linuxdeepin/dde-file-manager/commit/5bec3eba3655e34bc480750916d04a745c03c9f4)) +* file filtering cannot be selected. ([b372e1d7](https://github.com/linuxdeepin/dde-file-manager/commit/b372e1d7b9358086159f34cd1764cf00d4d8f72c)) +* check if file are in the same folder ([bea0d224](https://github.com/linuxdeepin/dde-file-manager/commit/bea0d224db441d50d535f371f0f4ea480a44a891)) +* invalid setting in usershare:/// ([6bc5423e](https://github.com/linuxdeepin/dde-file-manager/commit/6bc5423eb19c2386da66d41fc314ce3cf03e2233)) +* update device list for open file dialog ([d80d18ed](https://github.com/linuxdeepin/dde-file-manager/commit/d80d18ed21e57e549ecc1da3fcc82c00bb9f7c4d)) +* **DFMSettings:** no signal when a key first write to config file ([0bf9c69f](https://github.com/linuxdeepin/dde-file-manager/commit/0bf9c69f189977123cacf27dad445213b9e08dc8)) +* **GitHub:** issue should report to developer-center ([7ec1672d](https://github.com/linuxdeepin/dde-file-manager/commit/7ec1672d8ebcd7162657a8dddc31f42443759a80)) +* **background:** not update background pixmap when resolution changed ([fffcd811](https://github.com/linuxdeepin/dde-file-manager/commit/fffcd81188ddde127d44ff2e689046e4b4bb6afb)) +* **icon_mode:** rename editor display incomplete. ([b772bf19](https://github.com/linuxdeepin/dde-file-manager/commit/b772bf1955cc067dd581ae51fcd06c249260d19d)) +* **recent:** + * new item does not show time. ([ea996306](https://github.com/linuxdeepin/dde-file-manager/commit/ea996306dbd05821b541d6981b3fb6ae092f931b)) + * sort menu text does not display. ([3db6f293](https://github.com/linuxdeepin/dde-file-manager/commit/3db6f293b59ac91139b7203daf887096c04d185d)) +* **sidebar:** recent item does not display the property menu. ([7bba0def](https://github.com/linuxdeepin/dde-file-manager/commit/7bba0def1991f41d8267d45eadfb2d3a015be43a)) +* **tabbar:** no recent name is displayed. ([fa329e8a](https://github.com/linuxdeepin/dde-file-manager/commit/fa329e8ac3d392e892bf90c71652a50899116bee)) + + + + +## 4.6.9 (2018-10-25) + + +#### Features + +* setting for toggle recent file entry in sidebar ([bc832825](https://github.com/linuxdeepin/dde-file-manager/commit/bc832825d8ae9862414a49d4f3ebea8dcc9489e7)) +* 'open with' context menu for folder ([be91c1f1](https://github.com/linuxdeepin/dde-file-manager/commit/be91c1f1a7ae4ba783aa1ab5384b2ad67b8a7300)) +* do not limit the minimum height of the line edit on rename(icon mode) ([89237a2c](https://github.com/linuxdeepin/dde-file-manager/commit/89237a2c78af3477150b62b74e5cfeec28b26ca0)) +* auto resize column width when the column header view section handle double clicked ([45339f7d](https://github.com/linuxdeepin/dde-file-manager/commit/45339f7d26b0094fd1afee088698d8fbca839eea)) +* enable open-with option for debug build ([6dadfa75](https://github.com/linuxdeepin/dde-file-manager/commit/6dadfa75c599cba067a144ab719dcf16de598c83)) +* support use windows style display partition name ([543321c0](https://github.com/linuxdeepin/dde-file-manager/commit/543321c023d1eeff3ef866b2979c50810ffcecf5)) +* add two unidentified mimetype. ([cf603dc9](https://github.com/linuxdeepin/dde-file-manager/commit/cf603dc9f7c2d72b47648b4b38e0ffb875ed2b8e)) +* root mode supports HiDPI. ([130278cd](https://github.com/linuxdeepin/dde-file-manager/commit/130278cdf1c1f1bd80876fcc0c4534c7ae39b856)) +* **ctxMenu:** + * Support template folder to create new file ([c36406c7](https://github.com/linuxdeepin/dde-file-manager/commit/c36406c76ed3358f74cdd8f8fe9449480c874408)) + * Support template file to create new file ([285016c2](https://github.com/linuxdeepin/dde-file-manager/commit/285016c2814a8bcc89eb27dd692c0c869429ed0f)) +* **mountplugin:** add network device back ([0eda4d9c](https://github.com/linuxdeepin/dde-file-manager/commit/0eda4d9c48e38a85aa64f794efed3c9c4c281380)) +* **propertyDlg:** show fs idtype when debug enabled ([564b48a4](https://github.com/linuxdeepin/dde-file-manager/commit/564b48a4c37ed9008e63e48937ff6a7a73ee9427)) +* **recent:** monitor file support. ([374a2ed9](https://github.com/linuxdeepin/dde-file-manager/commit/374a2ed9f7d205b94d7dfe3612f4c81f83f53c69)) +* **usb_formatter:** support HiDPI. ([472cf954](https://github.com/linuxdeepin/dde-file-manager/commit/472cf954d3ebac03aa06d2b1eb316b29263aa1b9)) + +#### Bug Fixes + +* use qobject_cast instead of dynamic_cast ([be2f8ed4](https://github.com/linuxdeepin/dde-file-manager/commit/be2f8ed416719b924589a775a3e0e8b7d56c7028)) +* preview not working on dde-desktop ([88ce6879](https://github.com/linuxdeepin/dde-file-manager/commit/88ce6879abc8ec83a53ca632b2b2a01b4f0a99dd)) +* wrong context menu when switching views ([7193e4db](https://github.com/linuxdeepin/dde-file-manager/commit/7193e4dba20788152135e426b3f53becf6f27f26)) +* rename on property dialog for .desktop file ([f8037edf](https://github.com/linuxdeepin/dde-file-manager/commit/f8037edf79cc5da8b8ac9e0a115f9a0878695bd4)) +* i18n strings and typo ([a091ea8f](https://github.com/linuxdeepin/dde-file-manager/commit/a091ea8fa68a16475013c91ca7c242efc7bd0d7d)) +* avoid divide zero. ([ed0ed24e](https://github.com/linuxdeepin/dde-file-manager/commit/ed0ed24e9cee50439d9e5d3dcd024cb414b8e044)) +* Cannot select item in some case (#55 on gh) ([1543830e](https://github.com/linuxdeepin/dde-file-manager/commit/1543830e221eda26c0a8c1a744c5e3199983ee02)) +* always update vfs device info when changed ([68b4db18](https://github.com/linuxdeepin/dde-file-manager/commit/68b4db188175788688d1a9850c2fb3d76f42bbec)) +* file model event order not correct ([09dce730](https://github.com/linuxdeepin/dde-file-manager/commit/09dce730f6cca9770874440d6e98946dd0f2ff11)) +* keep the directory modified datetime when copy/move it ([89dcc877](https://github.com/linuxdeepin/dde-file-manager/commit/89dcc877101d1e25a5044f0bdc96bb24ff753a40)) +* crash when preview file ([a974e0b9](https://github.com/linuxdeepin/dde-file-manager/commit/a974e0b98751b77c1d1702e6078da6a3c8c30738)) +* replace gvfs-open with gio ([887f1a35](https://github.com/linuxdeepin/dde-file-manager/commit/887f1a35ef0a40aad90a8aeda0d2b3e4c1abd78b)) +* **ComputerDialog:** add computer name. ([f2714f9e](https://github.com/linuxdeepin/dde-file-manager/commit/f2714f9e92e26ee0d29ae329aa8231b7fdd8ec06)) +* **DFileSystemModel:** check idle when do refresh ([172de247](https://github.com/linuxdeepin/dde-file-manager/commit/172de247307806f93bc59d1b1f3c874d1f847e47)) +* **desktop:** avoid infinity EP query loop ([eddc6f2e](https://github.com/linuxdeepin/dde-file-manager/commit/eddc6f2e2981bd3bcdbc186f809ac2c2cdd9d181)) +* **mountPlugin:** + * crash when vfsDevice create failed ([4e84a38b](https://github.com/linuxdeepin/dde-file-manager/commit/4e84a38bfb2534f02ea7e23f9775fcdd4b514f52)) + * crash when icon ptr is null ([b43a4e28](https://github.com/linuxdeepin/dde-file-manager/commit/b43a4e2800ee883b4751e0e7ccf1f98f4be2cb8a)) +* **statusBar:** file size and number of files are incorrectly calculated ([3a63071a](https://github.com/linuxdeepin/dde-file-manager/commit/3a63071a796f1c9dc09e4f5cf1c2a88a40ba7cf3)) +* **trash:** not exist warning when copy file out ([cf5c3560](https://github.com/linuxdeepin/dde-file-manager/commit/cf5c3560a89494a36c8f6dbf339c2b1dba57f1fb)) + + + + +## 4.6.8.4 (2018-09-13) + + +#### Bug Fixes + +* size too big of bmp image thumbnail ([b4b52f43](https://github.com/linuxdeepin/dde-file-manager/commit/b4b52f436936c61ba0893d7873f45c40ee541f3e)) +* can not monitor disk device added(UDisks2 <= 2.1.7) ([f8077abb](https://github.com/linuxdeepin/dde-file-manager/commit/f8077abbac77c138cce06ed261dcb5a494d964db)) +* **DTaskDlg:** disable pause btn on sw ([ffb6f3f8](https://github.com/linuxdeepin/dde-file-manager/commit/ffb6f3f850d20135693b31c7bb3cc70891dd2518)) +* **desktop:** background not align center ([2bf46b98](https://github.com/linuxdeepin/dde-file-manager/commit/2bf46b981ef499b53a5a34d2b212b6703debeb4a)) +* **fileView:** crash on slow device ([7d75ae65](https://github.com/linuxdeepin/dde-file-manager/commit/7d75ae65c105dc6e80eb1742fc229f4ed58f544b)) +* **mime:** use mimeType from fileinfo if is avfs file ([83dffe39](https://github.com/linuxdeepin/dde-file-manager/commit/83dffe39da2e1b45fa05cc879b3658142265886e)) +* **wallpaper:** wrong delete walllpaper widget ([386c7427](https://github.com/linuxdeepin/dde-file-manager/commit/386c742700271d7038237cf970f257c49cd6ca01)) + +#### Features + +* **dde-desktop:** support preload mode of dde-desktop ([d4061799](https://github.com/linuxdeepin/dde-file-manager/commit/d40617990242e7ad406aeb21f155e0a5199e8fec)) + + + + +## 4.6.8.3 (2018-09-06) + + +#### Bug Fixes + +* can not build on loongson/sw ([e6938029](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/e6938029f646c50beda9e2caee82ead546e1f490)) + + + + +## 4.6.8.2 (2018-09-06) + + +#### Features + +* use QGlobalStatic for some singleton ([c2cde2b4](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/c2cde2b4b8eef9254482388d9cf8a7009cea0f78)) +* **desktop:** + * draw background ([b2e66431](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/b2e664310f29f3de055798a7840e8644a9142e76)) + * use pure raster surfaces ([1532a522](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/1532a522899804838fd9146668a51e46d59d674f)) + + + + +## 4.6.8.1 (2018-09-04) + + +#### Bug Fixes + +* **fileinfo:** check if fileinfo create failed ([2bb3b651](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/2bb3b651dd7054b680ad4c619e793109fcdbfc9f)) +* **mountPlugin:** internal impl of formatDiskSize ([936c90d9](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/936c90d916595b922f7f10aa657c67eb175eb46e)) +* **preview:** can't preview svg from search result ([6d9cc3c0](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/6d9cc3c0c51692cd5c69a473eb67fc5f791596a4)) + +#### Features + +* update depends ([3dc24fb8](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/3dc24fb81d94b6667ed37a0c1e469fb84c3fe5dc)) + + + + +## 4.6.8 (2018-08-31) + + +#### Bug Fixes + +* **computerView:** disable new tab option if couldn't add new tab ([e4c61e2c](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/e4c61e2c1d7fcb96484f4dbc82c506cf4c7d18c3)) +* **icon:** remove mipsel special icon ([420bd78e](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/420bd78e52e5ae76a3fac07f0eed9224a9a07e5f)) +* **mime:** show msoffice mime file as Document ([8391d2dd](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/8391d2dd96f7b44cc3038a45ec409cfec24d10fc)) +* **sidebar:** + * disable new tab option if couldn't add new tab ([686ba26d](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/686ba26def90e35ac1b4c928ed49ee33a3111618)) + * fix dark theme phone icon missing ([69669fa9](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/69669fa9a724e9d318be2c40ef61bd1dd44101fe)) + +#### Features + +* **computerView:** Friendly file size (#35) ([3445c117](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/3445c11777eb450a1fdd89e9805ed7527149e5d7)) + + + + +## 4.6.7 (2018-08-28) + + +#### Features + +* support only ReadWrite mode for DGIOFileDevice ([a36d5161](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/a36d51613cae7b3befe50a02bb8201c659b27c72)) + +#### Bug Fixes + +* the platform plugin version is wrong of judgment ([affb8732](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/affb8732e8c9337a4b45d94e713a2ec22349f68d)) +* **config:** default config file for pro support not correct ([b40f2ce2](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/b40f2ce21eb9e55c89ba283cfda75fdacb0a1b9d)) +* **fileOp:** use g_file_replace() ([5a8847a0](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/5a8847a0c7fe1f964a9c2dfa4739de017afdb52a)) +* **permission:** add executable flag for folder ([dc5b1d72](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/dc5b1d729fb63cb297175fb25e2d9d793c553a1a)) +* **propertyDlg:** no longer show openWith and auth section for trash file ([b830fe2f](https://github.com/linuxdeepin/dde-file-manager/tree/master/commit/b830fe2ff3cf4435970cb3a06f846997afb9bd30)) + + + + +## 4.6.6 (2018-08-23) + + +#### Features + +* allowed disable quick search ([1cf9c53f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1cf9c53fad25ccdf52bc70d8da274a0003b22819)) +* **mount:** now support ask-question signal ([cd54c28e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/cd54c28e4f7449235493d46acda16048af5e7447)) + +#### Bug Fixes + +* DnD on sidebar ([b28b4ee7](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b28b4ee78dfc9c4235ea6cdf84ab5efd341580f5)) +* can not write file to sftp mount path ([ba9d0a92](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ba9d0a92767b450b8809540056c87acab3b74700)) +* **DTaskDialog:** the process bar label is not at center ([10601287](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/10601287bf268989e55bee0f8511093469d46fa4)) +* **Image Preview:** the preview image on the high-DPI screen is stretched ([a3b73c0d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a3b73c0d5e824d3e11f74466b01b8c9c250c832a)) +* **authDlg:** checkbox set text ([054806d7](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/054806d70c6c9edacec36224656f25d46e6d07b3)) +* **bookmark:** Auto mount for ftp and sftp scheme ([65c51d0f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/65c51d0fdd33fb963db68211d2332ee3ac3e2d52)) +* **bookmarm:** always display remove bookmark option in context menu ([9192aecc](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9192aeccc99910e65def8d10bb22d006f331884c)) +* **fileDlg:** press enter on save dialog ([e1587089](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e158708954b41d63a44ec75a2c12c5f2e836b1ec)) +* **i10n:** comment for partition label i10n ([22d90335](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/22d903350007cdafd4b612ecfbd4f36006facc99)) +* **mount:** ask question dialog now got a max width ([5709edf8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5709edf8e92e91f86ff569c96675e3e418d028f0)) +* **mountPlugin:** + * Do not show partition if hintIgnore is true ([da70b6ed](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/da70b6ed0bb9031b4d1f0cfa29386a0b76b1747a)) + * default config in resource file ([684eea1c](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/684eea1c02ebd655db06e852761123e51d05bf30)) +* **previewDlg:** reset counter when start ([1c681c81](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1c681c81190ec32662dc8b3b9832b78eb58f747a)) +* **propertyDlg:** + * Single file symlink-chain ([82418bf4](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/82418bf464c695ea5a75d8b2afe55d3d7f65b721)) + * File display name and SymLink size ([27f1d13b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/27f1d13be20278439a2ebc319fd9dfa80d4c4120)) +* **share:** Use checkbox's setText() ([9d7e6ad5](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9d7e6ad5bc982eff24a96196e56d805ad3b31424)) +* **shareDlg:** use checkbox setText() ([f3455233](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f3455233a57de578cb0eed02faa7ca3b4fe39787)) +* **sidebar:** + * DFMSplitter use QGuiApplication::setOverrideCursor ([bdb4efe6](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/bdb4efe603b10ca9dd48f36c389b7b2996c9114d)) + * splitter cursor fix ([668d2346](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/668d234625e0a46780d08fc8f20dd572a6c097b1)) + * remove limit for i10n partition label ([4d356caf](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4d356caf3158325da71ffd6b26e6358603f310b6)) +* **tagedit:** disable mouse move event. ([103f59e8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/103f59e86291932ea4c27b3ae73af7b822730005)) +* **trash:** item count not correct ([3009fc6b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3009fc6b5cb472800af3530fca0405cbc2cfafbe)) + + + + +## 4.6.5 (2018-08-12) + + +#### Bug Fixes + +* crash at ErrorHandle::timerEvent, because the pasteFilesV2 function is exit ([4780ecd6](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4780ecd615203b4e6512ed2fa5da6147328e535a)) +* the search result is incomplete on quick search ([c147323b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c147323bb4292d5d52d67f8818bd639f6ddd7008)) +* **bookmark:** Bookmark rename fix ([9416dd71](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9416dd71eea834d3a5c9fb59755e9f2ea0648fbe)) +* **desktop:** set desktop item active ([37c127c3](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/37c127c33e338a45732f8ad847e4b0a7ed9514cb)) +* **mime:** support another appimage mime type ([6f72016f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6f72016fc1f437ceff83617509af295aa68a3cf7)) +* **preview:** preview dlg always at center ([78a5a6a2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/78a5a6a26abfaa660a8a9e247ffeb83441e6acb0)) +* **share:** Now can add bookmark ([e1ae9a8b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e1ae9a8b832029e10cb2cbfb992c616cc5314453)) +* **tab:** do not exec lambda if tab no longer valid ([a499cdf7](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a499cdf78341420ddc5f63afb73f840709993b03)) +* **trash:** Press delete key will ask for comfirm ([77aa2352](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/77aa23525a8feb1c677ce9fe45c922773f8cbf63)) +* **view:** fast switching view may lead crash ([64069332](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/640693327a0585da4f7691e9c48b1e00571014e2)) + +#### Features + +* add the "TargetIsSelfError" error type(DFileCopyMoveJob) ([dadaeb85](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/dadaeb850b7aa35ae548f31c2d9cef5939e76900)) +* **computerView:** hide internal disk header if no item avaliable ([2419cce3](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2419cce3b50333582b24764363ffe7eef107c6cd)) + + + + +## 4.6.4 (2018-08-08) + + +#### Features + +* **disk:** disk i10n by label name ([f0a91db2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f0a91db2df1a989b564b49cc740cb1b5217eaebc)) + +#### Bug Fixes + +* can not build on gcc 5.4.0 ([848db899](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/848db899607c6fe2ece9c0c95c36a71ee290ea8a)) +* **completer:** hide completer after press enter ([31417988](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/31417988b2ba82f7b9d39d8856c75e4719965250)) +* **daemon:** dquicksearch memory leak fix ([cf0598d4](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/cf0598d4c1bb3f333371380965cc3e7b3e95de4f)) +* **mount:** + * Use udisk interface to calc partition size ([4fb42b9b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4fb42b9bfff2f387758ef0960bf6a55f1a89a7f9)) + * don't mount device if it should be ignore ([e027a912](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e027a9124c31e220e399238c50bf30264c472317)) +* **quicksearch:** memory leak caused by missing regfree call ([42be8f8e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/42be8f8e02737e6fa7a1d20569b08447cbabd441)) +* **trash:** + * the icon from theme ([c00068a4](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c00068a4ceb1c7d2f490aa0ca35db662b89e2abb)) + * dialog file count ([64e55057](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/64e55057996c2a4361164b452d1bd52625b1423f)) + + + + +## 4.6.3 (2018-08-06) + + +#### Bug Fixes + +* can not copy file by drag/drop(the 'Ctrl' key is pressed) ([b970fbae](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b970fbae551536edd124c122bb1e4619fccc3c0c)) +* ignore the cut operation of the same folder ([7ea543bd](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/7ea543bd74c8b0b72bd9eb80b93bbac764f6d6cb)) +* the type of error is wrong when copy a file ([45f4f122](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/45f4f122b7d8922d64e4dc1ddf0207ca09712808)) +* the remaining time of the file copy is error ([84118a28](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/84118a284f10c65fcec5d5d5d6ded266884cbf64)) +* invalid sort by file type ([8893a90e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/8893a90e17c685472d9c949dad56e0a01af47613)) +* use QByteArray::difference_type to replace int. if not will cause compiler error in clang. ([4d822e11](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4d822e11d964598f26237a6d224d74129c13efee)) +* if search failure, should not close quick-search. ([4afbab31](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4afbab31ba5206d9295060705cb409b9f72a5615)) +* creating a new archive, it shown in a wrong position. ([30713dd9](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/30713dd927e14634914130123c56e07342d6ee76)) +* crash when call DAbstractFileInfo::fileIcon on copy/move files ([8e973d90](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/8e973d90cd682ce7ebb686ca68bd199dbc34de50)) +* not update error message of the DTaskDialog ([31535edc](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/31535edce6c62c459769ae4b889bc7127e1f8896)) +* copy files from nautilus to dde-file-manager cause dde-file-manager segment fault. ([e4b3144a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e4b3144aaab3c18baa19bd606867259e33ddd3eb)) +* compact (\') in sql statement. ([fe3ef80b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/fe3ef80bc7eaebc6d546ef8c0b1b17a828613b9e)) +* crash when copy a large number of image file ([9573fe2b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9573fe2b923711ea1efbe19ca4123c8c88f3b6d5)) +* **bookmark:** save mount point state ([d6705ac6](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d6705ac6d6cc06717f63971c054efa6faf713f80)) +* **desktop:** add aosGlobal config file to watcher ([02d4273d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/02d4273d9c732ab4348b6cd1d5ae8d04edb90760)) +* **device:** return the correct mount point ([8c9612d1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/8c9612d1ea9e24d50e16e0c9781cc22b98d49440)) +* **i10n:** + * translation fix ([48b3bec9](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/48b3bec97899262e713bf5e2bdbb539e77850b7b)) + * Translation fix ([974a6aea](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/974a6aeafe8ca74a53b9d93394fb50b83624ba8f)) +* **license:** Option to disable ffmpeg, #31 on gh ([b52b8dc9](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b52b8dc97d9e64053f305233b2df462ad79f90b3)) +* **mount:** only show items mounted under '/media/' ([319aebeb](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/319aebeb2b053730a8e1f0e9d4a3ccd35fce6626)) +* **sidebar:** Cache data->urls() to avoid data expired ([775aca85](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/775aca8528b2f124387ae0b53f7328aae0eea085)) +* **trashPlugin:** show warning dialog ([ce636146](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ce636146877b7a2eb9f14d98b7b66933dd8d247e)) + +#### Features + +* support 'Alt' Key and mouse wheel button to scroll view(Horizontal) ([4bba89b3](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4bba89b3e1c68c6f51ebcfaa6d084849d7387e3e)) +* set the icon color scheme from the window text color when get a file icon from theme ([d2327505](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d2327505536d488da38585e081be48dae1d4f2d0)) +* support wildcard in quick-search. ([da524977](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/da524977e3e6321d9e558c9c63671f215030c2d2)) +* **bookmark:** + * auto mount partition for non-local bookmark ([d229d0b0](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d229d0b0c8d7b88e1709ee736d22681a86741ee4)) + * save mount locate url ([df6405b1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/df6405b1f30fe895e908a373e7ac7d05db480ecb)) +* **crumb:** new crumb icons ([884ab321](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/884ab321a4954c3832386460dafbf0dd907b43db)) +* **mount:** use dde-file-manager with mount scheme if needed ([4bd80a5f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4bd80a5fdf056ac8eff8072f7b7e1ca37764d7b4)) + + + + +## 4.6.2 (2018-07-27) + + +#### Bug Fixes + +* build failed on Qt 5.6.1 ([2f087eec](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2f087eecbb9e2c65f6a8f5108602050d6c22820a)) +* **propertyDlg:** + * fix crash on readLine() call ([50791e7e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/50791e7e56d00530512f198d8478e443a19e2cbe)) + * memory from /proc/meminfo ([7d962cef](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/7d962cef16f38a703b80523525c88bb9919677ac)) + +#### Features + +* support get a file thumbnail by a process ([65fd32b2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/65fd32b2de821db2fcbb80ae5877c4524e7c1322)) + + + + +## 4.6.0 (2018-07-26) + + +#### Bug Fixes + +* deepin-anything-server can not load deepin-anthing-monitor.so successfully. ([a794c3f3](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a794c3f393ee5717eae6853e61f08b00ff5ed8b3)) +* the searched directory property dialog size info is error ([04865f6b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/04865f6bf241b781504078cd784b87b13974fd72)) +* crash in DStorageInfo::setPath ([8d18efea](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/8d18efea96e45b1963dfb0355921dac9822ccad1)) +* can not auto start the com.deepin.filemanager.filedialog DBus service ([04e865a1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/04e865a10170af7c7cb81911767192b2ef29c081)) +* can not rename file when click a selected file ([8789327d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/8789327d967bfbc4c0aeeb0ea3e77fa1a31f4098)) +* the trash is emptry state is error ([e806bbef](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e806bbef920365e4750b38f5e311285f5b4c8d78)) +* can not get the system disk size ([280e3d43](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/280e3d4322a56d8541e1642d4dac12fbb5d76747)) +* can not update .lft(quick-search) timely. ([061a17a4](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/061a17a4f1dc01eb8af8469049516bb0d9de2845)) +* crash on preview the video files ([2db2fdd4](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2db2fdd4f17788d6f1217cc47089c97ab1bdd667)) +* crash in RequestEP::processEPChanged ([27c650a5](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/27c650a54994a3ae02c1de65e887f73b27789979)) +* crash in DFileSystemModel::index ([3dd0a386](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3dd0a38659321dde5fa888636563f69318aa5aea)) +* skip the not-exists files when deleting files ([acaddc1b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/acaddc1bc745c65b272ca9f4fa9df227ead9a801)) +* can not copy file to mtp device ([c3939d3a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c3939d3aec68b3155fb4725ec32ea2369b1ceff6)) +* No progress of move the samba files(from one samba to another samba) ([f6500352](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f65003521b17b27059897e889cd376c1df54df9b)) +* load the translates failed on the settings dialog ([b260e486](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b260e486f632837c1961ca6abaa92590197c7302)) +* dde-desktop can not be show, if it was shown first time. And you click it, then it shown by itselft. ([5001cafb](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5001cafbc0493114a0eef33dcd8ad654dec9dda9)) +* force deletion of files in the trash ([de479229](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/de479229931db7023c933af4ee9f63df1af1428f)) +* set the start position of the progress bar to 0 o'clock(DTaskDialog) ([0b903951](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/0b903951a85f86e08bc3ec902b1805c8aad180aa)) +* can not create the mkv video thumbnail ([821061f2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/821061f20b7436614ae3b6ebb1fbcd7ff19f99d6)) +* the ghost signal of DAbstractFileWatcher is invalid ([8074ff62](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/8074ff62604ff4ef4a3bd64847564fa70b4b85a5)) +* crash in DFileSystemModel::remove ([83a62b1e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/83a62b1ee4176a5cbfd1b05e70a47782ab67e91e)) +* task dialog is not popup when emptying the recycle bin ([79bb736b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/79bb736b67b37513338dfec54097897dbbe69a42)) +* crash on destory DFMSortInodeDirIterator ([307d0018](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/307d0018f11ebf0ef051e72e457796477915dadd)) +* fix do not trigger create file thumbnail when scroll file view ([7de960b6](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/7de960b6c371572fdc27032c75d0fec1c5e3d0bf)) +* some network device may not shown in network share ([6115244d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6115244d50d881f8f6e36efe382dfb737c0595c6)) +* crash on destory DAbstractFileInfoPrivate ([fa73efb2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/fa73efb2b33f14641af85a9f24e68b2fbc3bb1f7)) +* not jump to home path when unmount samba device ([b70e1cb1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b70e1cb15b0accea4cdd65e5f10aa578f243bee1)) +* inactive label url does not jump after the current url is deleted ([cf054a02](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/cf054a02af71b98bb3820078b78c585f08e0e29a)) +* two windows appear when you open the file manager and use root mode ([e58746a7](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e58746a71c914071caaae455537109c4e7509d3e)) +* disable search in "network:///" ([117203df](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/117203df7d0c43ddc0d708952da9d9a76f8d9042)) +* config file load issue ([5bb16fc8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5bb16fc811c21c444e213f28f394eef9ad48fd10)) +* inefficent use of cpu and segment faults in quick-search. ([4601771c](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4601771cad137d29447f3f21c17fa41297a1a8d5)) +* the DFileCopyMoveJob class progress value more than 1.0 ([aa816037](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/aa816037db7b65c18840d3db022622721ffeb036)) +* did not jump out of the while loop ([dc969474](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/dc969474a43634e6596e7bb84f163ade0b0c5a21)) +* when search something by quick-search, quick-search will segment fault. ([6a3942d6](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6a3942d6f7ded078095c0152c40847a9814deda3)) +* can not watch signals after closing or opening text/video/doc preview. ([9b1f5bb0](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9b1f5bb09523c750932639410d325bb7492915af)) +* click a file which is editting, it's icon will disappear. ([4e10dda1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4e10dda1dfb8985a524fa7eb11b6c676d8df4330)) +* can not drop files to a selected directory ([9d7dd038](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9d7dd0384f1fa6d5c648fcdd6e87a962f6f28c27)) +* no notify when bookmark item is removed ([a5d494f7](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a5d494f7d04d317e2298323cda4f2639b05cca9b)) +* crash on reanme file in list view mode by "F2" key ([374bd1e9](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/374bd1e92acb7b3f2519a11e276cfbdcd7b8170e)) +* wrong parsing of line breaks when generating text thumbnails ([ccae4466](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ccae4466aeb7a6bc7f8959f856982fe65a2fa60d)) +* Use udisks2 to send patition rename signal ([49255cff](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/49255cffddd0d47a93090ac281aaef2f3d032f52)) +* remove unecessary function call ([cc4b7263](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/cc4b7263ba8dd4b6a89abcc9deb9719d1cf4b89e)) +* sidebar resize issue ([b5215847](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b5215847943e4944b1d7b5c22fca89eaf2968c8d)) +* change pinyin '叶' to the used most often one ([1ac7cfb3](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1ac7cfb353335181a17d18a221c01f9ce5cd9c34)) +* fix create thumbnails failed when images file changed suffix name ([61c14d93](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/61c14d93ef20db4f066522786e1d5e014888e7dc)) +* can not preview it, if the images file changed suffix name ([62fe8d92](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/62fe8d92767aba3440e1447494c3dd81f1a131b2)) +* can not drag files to trash on dde-dock ([6889d4c2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6889d4c2efb1c3d1b039e355f65780d9868fdae2)) +* can not communicate with DQuickSearchDaemon and fix DQuickSearchFilter singleton error. ([e7c3a611](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e7c3a611c14b59f2b604c79846882c68cc51ce5b)) +* clean dirty name filters when file mode change ([e7019b13](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e7019b13c26457bb9bdabfa80c3258a6004a6bcd)) +* make deepin-anything-server-plugins light-weight, compile the dependence into binary. ([299e3ce8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/299e3ce8d57d6322569e6628dd68c2b1e80334fa)) +* can not set property "hideOnAccept" of dbus file chooser dialog ([63fabde8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/63fabde81aeb75d9f4deb4d2d4260cd4d6dc4f98)) +* drop action is wrong on drag move ([b6df179f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b6df179fd46f791a2f60039f650f690f8e554a6d)) +* disable drag/drop on file chooser dialog ([b8897001](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b8897001369533942ddbc7ffa87a5ffebf3f6cd6)) +* file name length exceeds limit ([3bee6f75](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3bee6f75c81c863a3133ef0f81006805192f966e)) +* disable auto remove item when drop of MoveAction finished ([b84a80eb](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b84a80ebfac8ed30c92ea53543a930ec79dc204a)) +* file list mode header view sort indicator state is wrong ([a7206eac](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a7206eace9b717f4dcf40fd0ab57cd301e87652f)) +* optimize pixmap get of file icon ([c19a39dd](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c19a39ddc3534e7c269644407c6fc0cab31566c5)) +* hide the unmount button if the "canUnmount" property is false of the device ([2ebb7d44](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2ebb7d44193c201a87433dec18cc66c596b4d780)) +* the "GA_DisableNonRemovableDeviceUnmount" setting is invalid ([617ea39d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/617ea39d4dcd04344da9dca06bd88e4181255a6d)) +* do nothing if the new file name is empty ([f3fc70ac](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f3fc70ac610e7dd13c3f3a1103b533e7d02d6d2f)) +* the saved window size is wrong on window close if the window state is maximized ([944b5d00](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/944b5d0020885d88d0fb95f5952240f2596ccb5a)) +* a wrong file info if the file url is redirected when set root url on DFileView ([3faa490e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3faa490e131669dc5bb64d8741d90b2fb7be8c1f)) +* not refresh when preview files settings changed ([8dda41fe](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/8dda41feb049a4c4d6139ba5412e6dc592aaf366)) +* set the default view mode invalid ([0e15fe20](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/0e15fe20720ea4ac4cd44fb2800aecb75b753533)) +* null pointer exception ([9843ac16](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9843ac1641e7a277191d6fcb28550a68faa4ed04)) +* failed on build if the cxx flags contains "-Werror=format-security" ([70b936f6](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/70b936f660706e0bdc6eb99f3163bad237526364)) +* the file chooser dialog theme not is "light" ([da1d9c10](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/da1d9c10fc461b92f8f4b89a789c8afb610325ce)) +* crash in DFileDialog:: selectedUrls ([e35190b1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e35190b19fc7e0ab0161677761a68d95ee45b404)) +* the default file view mode is wrong(IconView is 1, not 0) ([17b017cf](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/17b017cf4fc5ca61cf4830b37d9939eb54b24385)) +* crash in dde-dock disk plugin ([a53d44dc](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a53d44dc3f88ba7a5fb1c1f22367356fc464f58d)) +* always open in a new window when opening a url by command line ([d901d050](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d901d050ca9f19657def4de228f490363aa223ea)) +* cpu occupancy rate 100% after setting values in the settings dialog ([cdf80742](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/cdf807421746a150451ae2a39f13efad3ebcfc74)) +* Do not popup error dialog when auto mount ([61843845](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/618438456ac40d4d7ae36c7d5983bbe2450f4ce9)) +* type error with use clang compilation ([6d030855](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6d03085555ae6396da024b32bf6c09d87622a7b8)) +* now you can choose to hide the suffix of file, when you are renaming a file. ([00bd8397](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/00bd8397ae40698a73429aa9e1c235c77aa03784)) +* the text background is malposition on icon file view ([6a7b3ab8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6a7b3ab8c3381e0138be9ae6774ad86e7978db6c)) +* Change tag color backend api changed ([cf044f94](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/cf044f947bec5d2edf6fda3c52b1dbebbc697340)) +* Sidebar bookmark reorder saving issue. ([b993ff2e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b993ff2e0dcb7d42f0d797d8fdca21ef56eb3f82)) +* Bookmark can't rename issue ([1c611da6](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1c611da62913253c4eb32ed99268a045babf0c35)) +* force push conflict resolving issue ([4ee8a20a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4ee8a20a2439b48818f35a62a0e85917230891ce)) +* showPropertyDialog cause file manager crash ([01d73d92](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/01d73d9239225f7627379db422249dafce23ebb3)) +* Size constraint when remove item from sidebar ([f7efa533](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f7efa5335aed92d1d2e7a687617a7f41260bae7d)) +* **CVI:** don't show context menu when read-only ([210df2fa](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/210df2fa63b5cae935a01600756ea74d982a1f2e)) +* **addressbar:** + * Revert completer to case sensitive ([c6de8732](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c6de87324c8ec1e7d0295c91327e778abc0cedfb)) + * weird lost focus issue ([733ae20e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/733ae20e0e23ebe62d53c3ee90fba337a7948756)) + * reset completer model with history flag ([cedce824](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/cedce824beeb23e745f8224f4d0de4b0c4c11624)) + * Tab to complete selected item ([2392a58f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2392a58f9ac84a12e8eeabbac2776e5993c80853)) + * Press tab on cant't complete url ([7d13eb69](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/7d13eb696faa8201f39d589302a162700c28d81a)) + * context menu casue addressbar hide. ([252476fc](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/252476fc1fff70ab8da64af61868d28fdd8152db)) + * completion logic changed. ([7e94979e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/7e94979e10a874e047b98a74f7d655008af6ce42)) + * auto completion deleting key issue. ([d00c6596](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d00c6596220ee84a5ade35d41e8a99523b932d30)) +* **authDlg:** no longer use fixed dialog size ([1c3d329e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1c3d329e4413d779781cd96088dfe5afc9af6cb4)) +* **batchRename:** suffix not correct ([969e0e59](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/969e0e5931251abb6edd85c489dea8e919e9d12b)) +* **bookmark:** + * now can't add dup tag bookmark ([465c65c4](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/465c65c436d2a01cd4473915d5b09ae99ab79a8e)) + * create file info if url is bookmark root url ([64779cd1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/64779cd1c259627940de4db6bb2804db76e455fc)) + * now can entry the dir which was added as bookmark in leftsidebar. ([d0be85d7](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d0be85d718de02e307fa159711368a6ddff52dda)) +* **char-detector:** replace uchardet to KCodecs for prober the charset of files. ([e8bd4a23](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e8bd4a23647eee871ad1caf8c10c465be2dbd6e7)) +* **cleanup:** tidy code ([0557586f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/0557586f47056b83beed0c6fe376a072a5e0d174)) +* **completer:** + * Set base string before set complete prefix ([c3994582](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c3994582814b78df3fcef255ffb6eee54a965081)) + * detect prefix fix ([c348cafd](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c348cafd82241e88b10711db1560fb149d9d8186)) + * reset complete model when switch complete type ([7d6d8004](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/7d6d80048d1ae2e3b9c698f5c292edea498d22d2)) + * Clear completeModel when hide addressbar ([c072ff6d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c072ff6dbe83ed0c02269952d168453216bd2a10)) + * Press enter to start changedirectory directly ([42124198](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/42124198e83284f8e68112ae534f171142866131)) +* **contextmenu:** remove duplicate item ([71c1631c](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/71c1631c77da48e481abd256a36372bca0b43a4a)) +* **crumb:** + * arrow not hide when toggle addressbar ([e8a027b3](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e8a027b3704e022e6af95880db7b93ac51d3686e)) + * Go to searchTargetUrl when exit search. ([2723d663](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2723d6634d5ba6afa25d79e7c958a2495bacd197)) + * Unexpected back action while searching. ([7d8c5ba2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/7d8c5ba2203cdbd9e288c340a2829578268365fc)) + * Click clear btn to exit address editing ([408cf81c](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/408cf81c0ea169555d433c33011faea7bbf92462)) + * backspace cdup wont update crumbbar. ([3e2daf7f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3e2daf7f6eaa0ba3458c02292390aadba7b3f7cd)) + * smb scheme url display issue. ([12a6b1e8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/12a6b1e8b19bf5aaf7ac79e1e186ab41e9efa9c6)) + * Crumb item display name and order. ([f181e1c9](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f181e1c99d665e7eb6ab08ef4fbbee061fcb83ae)) +* **crumbbar:** right click no context menu ([9ea8eae1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9ea8eae17f8d8e5d238f1b0da98c44f8ee0a64d7)) +* **dde-anythingmonitor:** add "plugin" for qmake CONFIG ([58e814d2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/58e814d2100a3bb71f2f389f6c022c5ec0d66228)) +* **dde-desktop:** + * can not remove the file by "delete" key ([e3281ce6](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e3281ce694ea9d074e9d1c57b575fd7cf0192b3c)) + * crash when start the application ([878cd0d0](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/878cd0d0e30b9a92160b4464017c863aea0f38a7)) +* **dde-file-manager-daemon:** the cache location is "/.cache" ([04e4888e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/04e4888ecb982f535e9a2b173bbdc6dde4ace9ff)) +* **desktop:** check if is a symbol link ([fb0b2e35](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/fb0b2e358c0e5fab2b5c21cc67ec9f11d488bd2f)) +* **deviceFormatter:** Center align titlebar text ([0a09c078](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/0a09c078aad36867659aa9336362243f86859859)) +* **fileView:** + * header not shown when dragging scrollbar ([d69525a1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d69525a163fe5f7dd8b918213b234d5f318d1c9c)) + * Default size, save sort order by click ([77beba0c](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/77beba0cfec27ea5cad3755a15556eef82ae75b9)) +* **filedialog:** update indicator icon when show ([d0fed062](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d0fed06248a72d48357e1ae85b7d694b3a5680cb)) +* **hint:** Hint in shortcut list dialog. ([ad71d4f4](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ad71d4f4939ccf79a3a17ab54da32282a8ab9042)) +* **i18n:** text update ([0a7dfbc3](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/0a7dfbc396dfaeb792cc8e2a4ac2f2027b63f00b)) +* **mountDlg:** password text too small ([adb9302a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/adb9302aa6c2129def9a905d155f1a39e7ac5c42)) +* **mountPlugin:** + * media-optical icon ([dd574640](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/dd574640be05033ec004d921a316083bf0378a0e)) + * update device list after mount ([be5e6329](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/be5e6329773bd0217c42c5f040a85d5882c0a8fb)) + * Always reload config when needed ([38c01033](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/38c01033530aa98496d8f77c27dd5ce09276931c)) +* **network:** can't open ftp and sftp scheme ([2941f4a5](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2941f4a5fdda41bb6d1d4051ba4bb19adc7d650c)) +* **patitionRename:** disable rename if patition not unmounted ([454cae3c](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/454cae3c8fc5502210a08087de5b62517680352b)) +* **property:** Correct property menu for trash url ([e2ca9333](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e2ca93337339ca5546ec03881d9dd21a761872fb)) +* **propertyDlg:** + * check owner than writable ([67ed3633](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/67ed36337091f6c05da18915384844a82f961bf7)) + * Open with section url not correct ([34383446](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/34383446a2407adc6a5553906ffaf4159a22fba5)) +* **properyDlg:** file name label with elided text ([e1b89fec](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e1b89fec48f83a4a81171043764c437b78e8f495)) +* **search:** + * disable network scheme search outside network:// ([95c3af1a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/95c3af1ab7913178701feac41a59ed616addfd08)) + * Search in search url. ([7e02eabf](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/7e02eabf2745bcc7f2e8c1cc0ddfabe370c352ef)) + * Now search support network scheme ([30a16d38](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/30a16d384cf53349fe0158e875758a14a7d6ed61)) +* **sidebar:** + * don't show ctx menu at fileDialog ([4bcc4d79](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4bcc4d7945a601d6b5ff26d9bfd474f9c4fc267d)) + * remember size on hide ([5b59b732](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5b59b732c312d1ec9a334facbb55054873285179)) + * check content widget visiable ([28242abd](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/28242abd332bc9a3455c0f0a250aa6b8f7cd986c)) + * correct properties menu for devices ([97c007d8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/97c007d8d5c168e164e7308f9bbcfb61f3c9126d)) + * Save tag order when create. ([0fb6fd2f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/0fb6fd2ff13b6a993d3f8c7d262419e77bf0aa9b)) + * spliter line visiable fix. ([a430dfa4](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a430dfa46a905a19a4ec6cbec4f49a3822d31f76)) + * smb scheme missing context menu. ([3daf5401](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3daf54018172dbd306cecfa414dd5b7390d3bf8a)) + * bookmark url cd to target location ([2947f3ca](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2947f3cae0b5ce4f6f66ab8e2c89ac532fd81a03)) + * select all when start rename. ([956c601f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/956c601f08ebc6fc47b8d7d4f3897fab19933273)) + * Rename edit styling. ([1abfc446](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1abfc4464f73b362508b6df78d2bf485e9acff8f)) + * cant cd to device with network scheme ([b662778d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b662778d1d9ad26fbac29a87af773a5cfa1fbe20)) + * Press esc to exit rename state. ([4db573bc](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4db573bcf0a3b037bd4c24821ce4d470061f0866)) + * bookmark item context menu disable. ([73183c9a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/73183c9ab6bf6c0f77117f176b7a57bd7ee86b73)) + * Device context menu missing item. ([ac7268d1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ac7268d1e6a5c3e6ba8d701484b6b6c0225dda81)) + * open in new window from context menu lead crash. ([d34e31f1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d34e31f14be2c3e9bff71221186e125601375f11)) + * background transparent. ([a6eb8cb6](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a6eb8cb6374ae584eb0ba778bfd63a2d6ff5aad0)) +* **tag:** after deleting a tag, the UI of file-manager do not refresh. ([39e5c745](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/39e5c7456155a3ace65cfe373fb064c5f464e65e)) +* **toolbar:** check parent visible before calling show() ([f5f6f44e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f5f6f44e5428b93d9ca6006c24a58ed424a0103f)) +* **udisklistener:** + * Should start watch changes ([43a646c8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/43a646c8f45e0059660ffa5986f9bde14044cc32)) + * crash when remove device. ([46681810](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/466818108d159a4f1c6450a291e7aa05e428e657)) +* **wallpaper:** optimization of thumbnail speed ([c5e80d86](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c5e80d860e50c513b9259964586b2537e1c459bd)) + +#### Performance + +* **cache:** fix pixmap cache not working ([5285ed3a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5285ed3a7c68fcbe673f38aa43d123250d7dbc0e)) +* **dde-desktop:** remove the timer of repainting. ([b25e70dc](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b25e70dc8594a67e45bdc6c69c4cd824ed63ce53)) +* **tag:** remove the warning, becase multi sqlite use the same connection name. ([26d38cb6](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/26d38cb6f12a096dae09ccc745bd93c26932d896)) + +#### Features + +* keep it permissions when copy a fodler ([b0caa7dd](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b0caa7ddb69af265f1b57eea0a68d29cbc66a89c)) +* support gio for gvfs mount files on DFileCopyMoveJob ([daf7464f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/daf7464f68704c3d5fd51761ca4d378169f3a585)) +* if local files changed, quick-search lft can watched and then update this cache. ([1bfac759](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1bfac75922de820cf9754e09d6cba3aa6f0896b8)) +* support fuzzy search. ([4b6e533a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4b6e533a5f88d676fe107d2dfad9ad90ee9d9396)) +* keep its modification time when copying a file ([aae1a516](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/aae1a51635d9a9a1c3fbd1b029a2f249d155b590)) +* sort the files by inode when coopy/move ([df8d6dba](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/df8d6dba1636e64e52e494379e5eccd5a9ea048b)) +* check the file integrity when copy ([04e1844a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/04e1844ad265b434367901c779b5600c6b36bb6a)) +* add class DStorageInfo ([fece5bdb](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/fece5bdba143fb76f035e695e932f3420dba2fad)) +* add new IO operation interfaces of file copy/move ([0371a1fa](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/0371a1fa9805f4962e0dc4e43f77c15aa4d5ef56)) +* add UI for the switch of quick-search. ([648510de](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/648510de51c9eea9edaf2dc1ab683afed71706b3)) +* disable DDE file chooser dialog for "handbrake" ([24a2c611](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/24a2c6117b379b525d79101e094f25afd5a2585e)) +* register quick-search to dde-file-manager-daemon. ([275b7f9a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/275b7f9ad3f111d4e61b3316e2382cc7aa17b0f3)) +* keep the left sidebar width when the window width change ([f99afbea](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f99afbeaffe6d0e7fecdd1c0a3ca22ad3e25c4c6)) +* support fast search. (1), handle that partion was unmounted suddenly. (2), increase api for searching in specify path. (3), new way to load .lft which exists but be filtered. (4), new way to get the mount point of the specify path. ([f6ed7079](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f6ed7079631e4920ee08ef6f2630eb85a3244946)) +* disable DDE file chooser dialog for "libreoffice" ([4b98de18](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4b98de182f8ca9fb420dfdeae84fa0b746d84525)) +* support touch event for DFileView ([dd3f9ed2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/dd3f9ed288df7a5ea8302af1397d92d69913342e)) +* support custom the non allowable characters of file name ([e21238d4](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e21238d44eab955ba558179828bb4a0856ed3ed8)) +* add udisks2 support ([c8a1c113](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c8a1c1137de27c7d6202f4685ddebee424839034)) +* add file io library ([5c69af6f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5c69af6f4170763924790ab7eebda4f36addbc18)) +* increasing monitoring for dde-anythingmonitor, you can configure it configuration files. ([a9b43a39](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a9b43a395658e8d2b07e13e55df239658a689f2c)) +* set the file manager window default size to 800x600 ([564de733](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/564de7335543e62bf1381eb2beb1d992f8cb3d68)) +* support "standard://" url ([614eb98b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/614eb98b4721d158a5982ef5475aabdf53a042ea)) +* add DFMSettings class ([62aaf3d5](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/62aaf3d597d602f84efd5140f0b90f5b4275174b)) +* add "addChildrenList" for JobController ([1cc5f90e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1cc5f90ebf5077d2faaa2e4c89b6a024cc88ea25)) +* add error dialog on failed for mount device ([3349b0b7](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3349b0b785ec3698c1d164529a3968a52ab09076)) +* change the api of TagManager for changing the color of tag. ([2b6f0a1c](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2b6f0a1c3cd44d0eaf7e50b2523d325b4d15c8c4)) +* **ProgressBar:** round radius and better UX ([d8cb7863](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d8cb786380166f253f5b7f00c18629c128b679b0)) +* **addressbar:** + * placeholder text center alignment ([24637cae](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/24637cae33c7d20eca9969308ba7cb5b1e1b1d14)) + * glowing animation ([5f49b8a9](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5f49b8a982f36bafb798b2148356be87cb447198)) +* **authDlg:** + * disable combobox when user can't set permission ([2c4673f3](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2c4673f346f472a5774c53ad827751329e86ac66)) + * set permission from auth dialog ([eee31551](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/eee31551356875d23bec82c5cdfac1de774d9c7b)) +* **authMgr:** + * interface for permission management ([64290a15](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/64290a15869559cf5b2eea99e671c1cec2219431)) + * Add back the auth manager widget ([16bd61b7](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/16bd61b775c9268634d524e31ae1d764c0f804ec)) +* **bookmark:** Can only have one bookmark with same url ([c15ed1a8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c15ed1a8183fbade737ad944f66b7de0cd88d3a5)) +* **cli:** Use -r arg to open as root ([076160db](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/076160dbec8c367b688f640e2d9d61b8b89195c7)) +* **completer:** Case-insensitive completion. ([71640631](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/71640631ccb508553815df7c62d01bae26988675)) +* **computerView:** rename patition at computer view ([65fdb91b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/65fdb91ba5c1da64ccb56d88c6e287c881f7cd7e)) +* **doc:** + * better index page ([bb8935f8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/bb8935f86513111f1f9bb1601603f30b48ccccce)) + * Documentation improvement. ([586f2123](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/586f2123153793cb8bd2d484318f38d66f1999a7)) + * Macro for \param and \return. ([b356f093](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b356f093df5c82d5f38b034857b1c1ca8e88b63b)) + * Documention infrastructure for DFM. ([05ae37dc](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/05ae37dcce0cd6b9e0053bbeb7c0d6b150f95279)) +* **fileView:** + * uniform view for all type of file ([ecbcea9a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ecbcea9a03b58edebd373e9562edcd1185526af9)) + * remember column width ([2506d45f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2506d45f4503a91aa98e7c675199be06e2c36061)) + * column size adjustable ([e0fb498d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e0fb498d203dfa35471578f2c1ee905922dbb5b3)) +* **filejob:** check the target storage free space ([83f838e8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/83f838e8e1a6d6cd79e5e2889b8347e444d0bb33)) +* **fileview-sortorder:** now showing files supports to configure through a json file. ([342f4213](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/342f4213d08feab70501c99066242d9658775507)) +* **github:** Adding issue template ([e699f70f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e699f70f26725da4481e6cd2bee6fc883ef2ab62)) +* **gvfsMountCli:** warn user if we got any error ([d0aef908](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d0aef908246983c5726be0e49096ed0531f1477d)) +* **gvfsMountMgr:** Show a dialog when we got error ([9ebb06bf](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9ebb06bf2935a61b62ac2e463df1e6c61ad6611d)) +* **menuExt:** Set the working dir and allowed Args key ([4001d50a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4001d50a35716ca6f464088119b8dfda26c6a05b)) +* **mount:** + * check if is encrypted ([37803366](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/37803366abd872e23d91cd19beb8214a8fbdaca6)) + * new scheme for mounting support ([6f2fc705](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6f2fc70575227c64361dee2b6d671b5cb2f610eb)) +* **mountPlugin:** better scroll behavior ([1a093d77](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1a093d7700799c5e907517abac10eb5d797967a8)) +* **network:** slient option to prevent request network ([8edd92f1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/8edd92f109250375c5bb4e770e3527b6bddaef61)) +* **partition:** ability to rename partition ([8a2fb7ff](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/8a2fb7ffa4e3427f4737010e6a5b273d6cbc99aa)) +* **quick-search:** + * support filter files when is searching files. ([564a492f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/564a492fe66d809a490e8f2c91b3c3428f2a4835)) + * create quick-search plugin(which is used to update .lft). ([44bde2b2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/44bde2b2ec0dc2f0e64e7b487c0945385969d92f)) +* **setting:** allow hide system disk ([26c23a19](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/26c23a190fc17d79d563284a6616cded0828dd1c)) +* **shortcut:** Ctrl + number to switch view mode ([6e3bd763](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6e3bd763d57f597bc41865267a0e1973bf5f1945)) +* **sidebar:** + * remember sidebar width ([be425a8c](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/be425a8c25f0e7e0c0ea81155c414ecab3b826d5)) + * bookmark support drag-to-delete ([1ee8e4f6](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1ee8e4f640824b7cf1f9d3fcfb7bb4587af6e863)) + * tag now support remember drag order ([ded51b54](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ded51b54f70e06a545d622510c6b89bf4f738058)) + * new sort order interface ([e4327492](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e432749261f91acfc756ed3a593f65bfb442c815)) + * Sidebar save bookmark to new place. ([a202b3c8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a202b3c8bd7cd1c97bdd4894f0b75c38f9242273)) +* **smb:** Display a notice msg when samba not installed ([cb03f103](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/cb03f103cd1c2a24bc72ddb6c7ff456329deb9ed)) +* **tag:** now anythingmonitor support white-list and black-list. ([5fd0ac87](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5fd0ac87b5f976babdbeedcdb3e3882751cbd9b4)) +* **theme:** use icon from theme ([09dd4814](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/09dd48146b973ccb1400f21a15cbc4aacbd22fa1)) +* **trash:** Folder is empty hint ([3dc08271](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3dc082712dd592c27805a6dde0c12ff209e6eb5f)) + + + + +## 4.5.4 (2018-05-18) + + + + + +## 4.5.3 (2018-05-18) + + +#### Bug Fixes + +* crash in remove files on tag file view ([51f247ea](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/51f247ea4a33fc3069e4815a89bdf0a5c0d0769e)) + + + + +## 4.5.2 (2018-05-17) + + +#### Bug Fixes + +* crash in DStyledItemDelegate::commitDataAndCloseActiveEditor ([d7373f08](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d7373f08f4f1087d96688a7fa24d77db7845b862)) +* remove the mount-point of files when storing file into sqlite. ([3eec6a61](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3eec6a61e8f009c06120a82f0d894e2f67e87995)) +* **menu:** be out of a Sperator befor tag-info(menu action). ([e290cc55](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e290cc55750a1d119ee7ad8dc05d1faeb722c836)) +* **wallpaper:** thumbnail support HiDPI. ([ab202327](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ab202327168d6b9485718b232487958c8d24dc57)) + + + + +## 4.5.1 (2018-05-16) + + +#### Bug Fixes + +* setting "Always to open in new window" does not work in computer view ([aced802f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/aced802f8050e7cc91458c1a30e1eb2ce0799bb9)) +* crash when access bookmark:/// ([731cb483](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/731cb4834d29cb0b42756c8c79a362eed922e504)) +* ignore G_IO_ERROR_CANCELLED error on copy/move file by gio ([1455d618](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1455d6187ec670105c2a946e4164a3faecff22b9)) +* the last line of the file name in the icon mode is incomplete ([f532cd78](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f532cd784249ed0b6365c04959a26283e8999851)) +* cannot revocaion same operator on file chooser dialog ([c6c89c47](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c6c89c478da6bda7c9c914ffbf558a82b0e70d2a)) +* remove extra columns of the search view ([532b9aeb](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/532b9aeb33e417fafec7aaaf48689a6ba9220419)) +* distinguish cutting-operation of files in different partion through dde-file-manager. ([6f4e8fde](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6f4e8fde6d80c2783aca79a11263e1825882e27c)) +* preview plain text files on search/tag file view ([5e90d796](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5e90d796c235b03f1092e5040e0143a170ab17b6)) +* the file item will be removed when move the file in current directory ([b292dec3](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b292dec348a84879377679e2f159971710820a6c)) +* show multiple text edit widget on multiple window when rename the tag file on left sidebar ([82da0142](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/82da01428ac591808cddd6709f8765d52774fb73)) +* change std::thread to QThread in dde-anythingmonitor and after renaming files will emit untagFiles and filesWereTagged. ([bcdfc47a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/bcdfc47add78b10b8c3f59a42aed118623d848cc)) +* cannot revocation the batch rename operator of file ([f35b5103](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f35b51030bb7995889eea7d7f6567b802f4d00db)) +* not sync tag info when reversal file operator by "Ctrl+Z" ([ff92b949](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ff92b9493ff7911c5410923981334e023f987eda)) +* change the tag name to determine if the old and new names are equal ([57fa131f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/57fa131f1d75f2c14995fef5dd6e8c35441d3019)) +* search file view not update when delete the searched file ([5a0bc120](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5a0bc12042b82e399be59f6e42ba676f8d96eb13)) +* add inspection for checking whether the thread is running if call DThreadUtil::runInThread. ([b36e513b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b36e513b9063f7ef94155ac9525d8e1410429ac3)) +* in dark theme, the deep-blue was shown light-blue. ([c3756c8f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c3756c8f04d20571b9f2d559b03d57df7cb4e529)) +* the tag file view not update when the local file deleted. ([0b8494e0](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/0b8494e009c44ac39030f02ee1835e703873e5cf)) +* Change tag color backend api changed ([991fedd8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/991fedd8abdac7f864809c76efed2d7c4ed54046)) +* after deleting a empty tag can not get signal from daemon. ([bd69e2e4](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/bd69e2e4441b94897661a440c36408d8385be5bc)) +* the file non-exists if it url format is "tag:///{Tag Name}" format ([15a8adea](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/15a8adeab76d0712ffe763a87bfd2ecf9a84e980)) +* the "OpenInTerminal" menu action is invalid in tag file view ([8e86a571](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/8e86a571b0822f338acbf113281fda3c03a0b3da)) +* cannot preview file on tag file view ([ef48435f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ef48435fc4d4b9d62ba69ffbd47eef9587696540)) +* **dde-anythingmonitor:** cpu occupancy rate is high ([2bc85248](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2bc8524823fe5f335d993b83fb2aa3081bc32a4b)) +* **dde-desktop:** crash when drag/drop files ([b640c0ea](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b640c0ea1a82ed8d829568d6f0fffd7973cd8370)) +* **video preview plugin:** pause button not visible ([cbc04090](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/cbc04090b72a30ce1ae7571b58965c6d2a7b5167)) + +#### Features + +* support operator+= for usual container in Qt. ([366b4490](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/366b449019197bc79d9d432f17989c232e45bd13)) +* use asynchronous operator for tagging files ([0b314716](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/0b314716947f70bd71350a037d70bdf95221404d)) +* change the api of TagManager for changing the color of tag. ([f50c71a1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f50c71a1a438f1ce13281de3a00f7bb3a26f9f3a)) +* save the file tag name list in trashinfo ([3130bcb2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3130bcb2f9b7c633b906f4a3cfe838c335479bdf)) +* support search on tag file view ([f5c00011](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f5c00011bb3b819f3796ff292cabb87936105126)) +* add a new api for DUrl and adjust DUrl::fromUserTaggedFile make it easy. ([4d195392](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4d195392499cb29b4cf50770b144d0eb7deae639)) + + + + +## 4.5.0 (2018-05-04) + + +#### Bug Fixes + +* after cutting files and moving file to trash remove old file. ([9e721960](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9e7219607d788705e0cc162db87e0d91a6e66452)) +* crash in FileJob::doMove ([53c6c559](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/53c6c5596089bb7639b29c5e84f8220bf7cc8267)) +* update left sidebar on tag list changed ([cebad2a0](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/cebad2a0985657ea99b5efbf65495b7e7da2c895)) +* sync the property of tag after deleting files. ([76265637](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/7626563744955aeff8110651468c2034defe6c58)) +* update tag file view when the local file modified of the tag file ([96cce4d7](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/96cce4d76a982225cbb07a82e5679e26289f5b0b)) +* update tag view when the file tag/untag ([1aa7a334](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1aa7a3346efdfb9beeb8344c2b2897c86987b000)) +* update tag database when file renamed/deleted ([6ff53beb](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6ff53bebdb26c119a32f0de50807fdfb03f1b0ae)) +* sync the property of files through signals of dbus. ([d210aea8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d210aea886a591a62fb77de09acd1b6cdaeb1ec4)) +* crash in tag file view ([be16e6ee](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/be16e6ee32e039b91eac6761a7dbd89ab367a2a5)) +* can not delete tag ([637440f5](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/637440f51b7d3a9e217ec94f6647fe142af905db)) +* the default color tag translates ([040852fb](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/040852fbd4b3d8228976d720ea406e23d0a96416)) +* when setting file tag information, other files will be mistakenly deleted ([b174d64b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b174d64b7f7afe827ad4c85bf312e8f9df0e4698)) +* the tag edit widget position ([ee99f1b8](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ee99f1b86220dc0a0f51fcf90b593e77116c4560)) +* fix translates in DFileDialog::onAcceptButtonClicked ([436b2071](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/436b20710e7a55a30ac880f44b47fa56942a538d)) +* failed on copy file if the target is existed(ths "m_isSkip"/"m_isCoExisted"/"m_isReplaced" is dirty) ([0f294494](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/0f2944946aa305dfb163658376cec8274c6401a6)) +* cannot save the file view state(view mode & icon size) ([4a080f92](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4a080f92acd907f75a08b9487e59a5cd01a5c3fe)) +* crash in RequestEP::processEPChanged ([f50af033](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f50af0331fdaf5ad4c7b7419b0541a05c12c8739)) +* bookmarkitem rename crash issue. ([7470bc79](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/7470bc799a98225286dc95e8ca4806fd2b36b447)) +* can not drag move file to trash ([f88c0a03](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f88c0a03507cfd5a6c9600f56ae2484aa57cdf34)) +* Enter smb scheme and cd to real path. ([321fcf52](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/321fcf52b2f2e8221768bc4d81a2b457aac9d6c4)) +* can not get the file extension propertys on dde-desktop ([2665bf3c](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2665bf3c1e85047d9490db82b507a2573406beef)) +* carsh in close preview directory at destory size worker thread ([cfabe5eb](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/cfabe5eb0c46b24019e0d8668f946fde9c30fd14)) +* ComputerViewItem not correct issue ([54e02a42](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/54e02a42863fae00b2cfce3a299d9203e2758007)) +* can not open help in dde-desktop ([fff57238](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/fff572389b251b143fc61b1a6e49ebbab4490de3)) +* support hi-DPI for ExpandedItem ([c242abb0](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c242abb0d030c36f5899e22cd427eeac0bfe7885)) +* crash on preview the music files ([6728e7b3](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6728e7b33251e6f22c742031c3b1e4f5998389ae)) +* file icon view text background path on select single file and the file name is need expansion ([0be51a23](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/0be51a23fdfa02a8b358289f2ee3b9eef1c71534)) +* crash in RequestEP::processEPChanged ([29177816](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/29177816fa65243743df8c09580c80b533af1162)) +* reset configs not apply on file view ([11cbf960](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/11cbf96038d5ac26a70b8653c67c4e92d44516e7)) +* Can't type trailing space when editing file name. ([322ebe1d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/322ebe1da324d7e6bd2845b6e10ddd7c8bd9e496)) +* keep the trash file view column count to 2 ([45b4184e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/45b4184e70df43ae4a954251019ca103e51ac919)) +* Ctrl + Shift + Tab can not toggle previous tab ([638b8a5c](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/638b8a5c321014de0abaabe0ee29e56d23b40fc0)) +* can not select files by mouse button click when the Shfit key is pressed ([a9cb0406](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a9cb040691ca4d7d67f430b1f03f6d1d4b7c0052)) +* trash file view font is wrong ([a3aa78ae](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a3aa78ae85601e0b9c08ac7bc3ac6ecbbc419c98)) +* can not share file on search file view ([3d1f5cbf](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3d1f5cbf050d38ea1d9f3e19c9045650d524a7d5)) +* the files not refresh on add tag info ([3fc15155](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3fc1515575f4e8f37de0cf92abb7367e348e4f45)) +* a logic error when changing the color of tag and delete redundant code. ([f58c5943](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f58c59433c0158245d45581759efb4876fa174ab)) +* destory file preview resources on dialog close ([fa7b2733](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/fa7b27338bd7b02101134ccb5be3d0a94e658e94)) +* can not get the files through tag and tag files through DTagEdit. ([3462058b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3462058b0a69293d8b01ad28847eb908ce6b000b)) +* new way to get home path of user(s). ([8c6df80a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/8c6df80a118801c9afd9bb2ab2913941ee0f190a)) +* crash in RequestEP::processEPChanged ([062a3cb2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/062a3cb24f7824c2ac1cc255156d65c067d891af)) +* crash when clean trash by dock trash plugin ([1b30c18b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1b30c18b40555862a255947aeeda0922b12a3d3c)) +* support multi read and single write. ([e3c4f49a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/e3c4f49a75ac29f83afbecf452587f8f5ffcf07e)) +* open search file view on mount device by left sidebar ([087fe6fe](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/087fe6fe485627ee26f57dd30e92887c4e4d3587)) +* **dde-desktop:** update file view when the file tag info changed ([bc6a729d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/bc6a729d57817247809209e93670d4be17cb53b6)) +* **desktop:** delay show wallpaper choose frame ([ad289da9](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ad289da9ce80982a7abb2014aea32712d9df8d86)) +* **tag:** + * after delete a tag through left-sidebar will cause segment fault. ([260d4e2f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/260d4e2f76990b40d44d3d71ba324a46a84640a5)) + * change the returned type of a API and delete redundant code. ([f9bc5246](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f9bc52464c953808f8131f968ea77973bc99b4de)) + * fail to umount partion and segment fault. ([79ca3f5d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/79ca3f5d41f3a0cdc8564e2ade9606532ebafe75)) +* **wallpaper:** delayed loading wallpaper ([dc62a6e5](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/dc62a6e5dfa17d9dc5526fe8baadfab97b102d1f)) + +#### Features + +* after delete tags will emit a signal which includes the files in current tags. ([dae4ea45](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/dae4ea456ec3e79a31435997cda1f45b413ce1c5)) +* update file view when file tag info changed ([74df5c5a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/74df5c5ab3bfac660cd918490e704d5189ac05e4)) +* support operation the file on tag file view ([61d1852d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/61d1852d7bda42865efa748ef4272397ea2469ca)) +* update translates ([418e258f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/418e258feb0207f7116520a418e2eb05dcb0087c)) +* add tooltip for tag action widget on hover state ([9e897967](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9e8979678a679ee11e241e332b6295f90d8967f2)) +* copy the file tag infos when copy the file ([6bdff4ee](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6bdff4ee749753541f2989a9122db678da4492b2)) +* add signal "DFileService::fileCopied" ([c0bcf69b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c0bcf69bba396a57999dbe6b446f980be36582eb)) +* add new API for tagging support. ([6813841e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6813841ea9fb9812674c510ff95cf98cac27f09e)) +* update translates ([7a8e8df9](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/7a8e8df99d798a6942c6ae4e28d080722c8d71ff)) +* popup dialog when copy file failed by gio ([f6178b25](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f6178b25f167d5ee12a51467abb40395dc2abd2c)) +* support disable menu actions by config file ([9a77414b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9a77414b61f6f0db7c7143559752986f3eb17211)) +* support custom hidden files ([df2d9b05](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/df2d9b057bc99bf2e263d88b0868e580cc7f0e0b)) +* can set border color for DStyledItemDelegate::paintCircleList ([4e400319](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4e400319a0155324cd5e9d63ac75e3ed6d5980cd)) +* paint the file tag infos on file views ([9d077c1d](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9d077c1db22154aaf909c309607217743f36d8fa)) +* support extension popertys for DFileInfo ([21dac0fd](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/21dac0fd22aa43bd29e1ff24ce7abd8a5a3218bb)) +* can undo restore trash files by Ctrl+Z ([cb48d412](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/cb48d412fa3980220b2e8a6cfe30fdd1d006747f)) +* **dock disk plugin:** update disk info when show ([4fa57584](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4fa57584e8bf2aba989c55758e901f67711bc797)) +* **tag:** + * support tag protocol(tag://) and give supports to monitor tag(s). ([6531d482](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/6531d482a034862c16a22216cd23e61db14ad914)) + * support file watcher. ([fa661305](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/fa661305a2a4da03213ec4ca3b9ae3534671ff99)) + + + + +## 4.4.7 (2017-11-29) + + +#### Bug Fixes + +* don't disconnect menu connection of ToolBarSettingsMenu ([f9a7fefc](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f9a7fefcf318c5e834e647e60a7f1ae7b5ec2820)) + + + + +## 4.4.6 (2017-11-29) + + +#### Bug Fixes + +* copy large files in different window error by disconnect menu triggered connection when action is triggered ([72079c2e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/72079c2e5827f441990cdb6f98953cc846b761fb)) + + + + +## 4.4.5 (2017-11-28) + + +#### Bug Fixes + +* **zone:** video size error ([aac90e55](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/aac90e556d450d865ca787b34f26d5f7c091e085)) + +#### Features + +* add desktop geometry debug info ([5037a497](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5037a497c1603b49a36c96154656e75767703e1c)) + + + + +## 4.4.4 (2017-11-20) + +#### Bug Fixes + +* update translations ([1e18fc14](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4b31cc5a1418de87b56c26c8b69c27b48794958d)) + + +## 4.4.3 (2017-11-16) + + +#### Bug Fixes + +* replocale when override file ([1e18fc14](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1e18fc14d150e6bf17769510671ead84648e9997)) +* avoid strip in debian build. ([a9e113a2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a9e113a232aa61c29471539dc3805d5a07f67f60)) +* sync all profile at the same time ([b4f1b01c](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/b4f1b01ccfa8d9b828c7737a3d730ce470dedf15)) +* can't write file in anonymity writable mode ([5d1a95fe](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5d1a95fe33917f45ea9be78d91b3e5e77490c99c)) +* fix build error in sw for security label ([f4bbf131](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f4bbf131a1f19cbe18d56a8f560df5418c75ed2f)) +* update translations ([aa98aabc](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/aa98aabc08ec9e4affda6aaaaec7918987539b19)) +* update translations ([27e0d624](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/27e0d624794a2fb03d7d392760c2edc67f9cb579)) +* expandWidget show when drag ([c28129ac](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c28129ac9bcf89acd422d92f51d062fc6933b30a)) + + + + +## 4.4.2 (2017-11-09) + + +#### Bug Fixes + +* update link file icon in desktop when device is mounted ([3b3bfcba](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3b3bfcba3855bd36192fed51f4021fd3e26f5628)) +* fix volume custom letter support ([7d870833](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/7d870833c957b2bd238d9f381c526ec78daf6776)) +* refactor trash property dialog by DDialog ([76c7f390](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/76c7f3908bc0508378eb80b5cfea4565d755454a)) +* **diskmount:** add hdpi support ([35823b59](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/35823b59b1b3a3d73065cbf367eb4ecd522a6863)) + + + + +## 4.4.1 (2017-11-07) + + +#### Bug Fixes + +* crash when show computer property dialogby contextmenu of computer bookmark item in leftbar ([68dd3961](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/68dd39617479abb2432832db27cf86a00cda8ef0)) +* double delete crash ([53db4247](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/53db4247f4b5eaca1781624dcdd0107db43cc612)) +* add cryptsetup depends ([a57f1fd5](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/a57f1fd5c55c2c02b630969f7e9fe7c3e554fc86)) + +#### Features + +* add dfm platform config file to disable unmount function in x86 pro ([8514d873](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/8514d873c7b9fea410d323c05f0aad2f764db1e8)) + + + + +## 4.4.0 (2017-11-02) + + +#### Bug Fixes + +* update editing select area ([4a5463a2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/4a5463a2c320fe66d48a7938f661f7f1692626ca)) +* fix no mini button ([30391ab2](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/30391ab2dd25c637e1cd867b0db4b178fd2ce4fb)) +* update auto mount and open checkbox state in dfm setting dialog ([bb750190](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/bb750190240ada372fb85d8466d68b8377835ec6)) +* auto mount luks device when bookmark of luks is pressed ([f07cbd0c](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f07cbd0cdac649285bd091321526744044f854c8)) +* show conflicted dialog when cut same file from smb to native by gio ([062fd218](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/062fd2184c41198eb82af1b244ee4627a2f369f3)) +* abandon code for delete temp copying file ([25e6cf2a](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/25e6cf2a7d0a8c54508a0284cfc520599ef811ae)) +* set window FramelessWindowHint flag for pro ([59f7d6dc](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/59f7d6dc2722a06dfd37de0e2468f0dc0d54da26)) +* **dde-desktop:** fix move to trash by delete key press event ([11856a31](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/11856a31c4cba32c2ce500f82896092bf6ef645d)) + +#### Features + +* update help document ([779f5d71](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/779f5d7141c4467313b3d7dea1e264133b55cebb)) + + + + +## 4.3.5 (2017-10-30) + + +#### Bug Fixes + +* don't draw additionalIcon when do rename action ([da774c0b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/da774c0b9e76ad6cccc5ae3138767c11b18f3930)) +* update translations ([3051bcd5](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/3051bcd51f64ed28c256d266bb3a8d17f4be339c)) +* do copy action when do drop action in same disk if ctrl key is pressed ([5248ca1b](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5248ca1be1a61b669ec6417ea11dc5593925d448)) +* remove dde-file-manager-intergation recommends ([831e65d3](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/831e65d3c77c64979f786ffd8cebbf6d5576a98b)) +* show computer and trash property dialog not as normal desktop file ([d7bae00f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/d7bae00f490db147aeff86b4a249520f90a15b3c)) +* close preview dialog when open preivew file ([171ef041](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/171ef041c44e1fa14d3253a996ee7397dce41332)) +* show and rasie verticalScrollBar of leftbar 100ms later after leftbar resize normally ([ca847cd1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/ca847cd1564ae2bc5e2d2acda78efb9424af9615)) + +#### Features + +* new view style of search and trash ([5ea6c63f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5ea6c63f08128ff3484d2c9247affacc35216983)) +* auto play music when preview and stop when privewhide ([2d33daca](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/2d33daca9fd638e69f55e4aaf7e2c3d52ec054ed)) +* add support for windows url shortcut support ([9cd6f16f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9cd6f16fc76da4c663970097eb54f3e124791f11)) +* add clog support for changlog ([1ab524b6](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/1ab524b6140ad20c7e8d13f9e95eabcc11f08c74)) +* wallpaper thumbnail support pixel ratio cache folder ([605df99f](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/605df99f2b11e2ecd50940a9d397d9f53511acf4)) +* add flatpak applications path support ([72c9a7a5](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/72c9a7a5dd955273f7cbb08c2ef89b351805206b)) +* hotzone update corner support hiDPI ([f1822680](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/f182268083ae54f94190465f2bbe0bb32284726d)) +* hot zone support hidpi and update new demo video ([28e353ff](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/28e353ffe8e094f4db90893feba9e15694c8495c)) +* wallpaper chooser use DRegionMonitor and support hiDPI ([5a0f8db1](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/5a0f8db14565dc73682afaef0532ed6be4c817ec)) +* wallpaper chooser use DRegionMonitor and support hiDPI ([079c36f4](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/079c36f4f31d792479fb015f696fc5a833461f2b)) +* hot zone support hidpi and update new demo video ([c3b6c7a5](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/c3b6c7a5c7108cdd12e0a76cc22ce87cd14d5017)) +* **desktop:** + * keep file position when rename ([9afbe8bb](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9afbe8bb9d83acf27563b604be1b8e84c1a200e1)) + * drag animation ([9697270e](https://github.com/linuxdeepin/dde-file-manager/tree/develop2.0/commit/9697270e617747e5858606899cc0e3f5563c7f9b)) + + + diff --git a/dde-file-manager-5.5.3/LICENSE b/dde-file-manager-5.5.3/LICENSE new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/dde-file-manager-5.5.3/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/dde-file-manager-5.5.3/LICENSE.MIT b/dde-file-manager-5.5.3/LICENSE.MIT new file mode 100644 index 0000000..6a89fb7 --- /dev/null +++ b/dde-file-manager-5.5.3/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 coolxv + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dde-file-manager-5.5.3/README.md b/dde-file-manager-5.5.3/README.md new file mode 100644 index 0000000..dca1fe6 --- /dev/null +++ b/dde-file-manager-5.5.3/README.md @@ -0,0 +1,113 @@ +### dde-file-manager + +Deepin File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + +### Dependencies + +### Build dependencies + +_The **master** branch is current development branch, build dependencies may changes without update README.md, refer to `./debian/control` for a working build depends list_ + +* pkg-config +* dh-systemd +* libxcb1-dev +* libxcb-ewmh-dev +* libxcb-util0-dev +* libx11-dev +* libgsettings-qt-dev +* libsecret-1-dev +* libpoppler-cpp-dev +* libpolkit-agent-1-dev +* libpolkit-qt5-1-dev +* libjemalloc-dev +* libmagic-dev +* libtag1-dev +* libdmr-dev +* x11proto-core-dev +* libdframeworkdbus-dev +* dde-dock-dev(>=4.0.5) +* deepin-gettext-tools +* libdtkcore-dev +* libudisks2-qt5-dev +* libdisomaster-dev +* libgio-qt-dev +* libqt5xdg-dev +* libmediainfo-dev +* libdde-file-manager-dev +* libssl-dev +* ffmpeg module(s): + - libffmpegthumbnailer-dev +* Qt5(>= 5.6) with modules: + - qtbase5-dev + - qtbase5-private-dev + - libqt5x11extras5-dev + - qt5-qmake + - libqt5svg5-dev + - qttools5-dev-tools + - qtmultimedia5-dev + - qtdeclarative5-dev + - libkf5codecs-dev +* Deepin-tool-kit(>=2.0) with modules: + - libdtkwidget-dev +* deepin-anything with modules: + - deepin-anything-dev + - deepin-anything-server-dev + +## Installation + +### Build from source code + +1. Make sure you have installed all dependencies. + +_Package name may be different between distros, if dde-file-manager is available from your distro, check the packaging script delivered from your distro is a better idea._ + +Assume you are using [Deepin](https://distrowatch.com/table.php?distribution=deepin) or other debian-based distro which got dde-file-manager delivered: + +``` shell +$ apt build-dep dde-file-manager +``` + +2. Build: +``` +$ cd dde-file-manager +$ mkdir Build +$ cd Build +$ qmake .. +$ make +``` + +3. Install: +``` +$ sudo make install +``` + +The executable binary file could be found at `/usr/bin/dde-file-manager` + +## Usage + +Execute `dde-file-manager` + +## Documentations + + - [Development Documentation](https://linuxdeepin.github.io/dde-file-manager/) + - [User Documentation](https://wiki.deepin.org/wiki/Deepin_File_Manager) | [用户文档](https://wiki.deepin.org/index.php?title=%E6%B7%B1%E5%BA%A6%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86%E5%99%A8) + +## Getting help + + - [Official Forum](https://bbs.deepin.org/) + - [Developer Center](https://github.com/linuxdeepin/developer-center) + - [Gitter](https://gitter.im/orgs/linuxdeepin/rooms) + - [IRC Channel](https://webchat.freenode.net/?channels=deepin) + - [Wiki](https://wiki.deepin.org/) + +## Getting involved + +We encourage you to report issues and contribute changes + + - [Contribution guide for developers](https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers-en) (English) + - [开发者代码贡献指南](https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers) (中文) + - [Translate for your language on Transifex](https://www.transifex.com/linuxdeepin/deepin-file-manager/) + +## License + +dde-file-manager is licensed under [GPLv3](LICENSE) diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/+.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/+.svg new file mode 100755 index 0000000..886d90a --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/+.svg @@ -0,0 +1,13 @@ + + + + + + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/-.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/-.svg new file mode 100755 index 0000000..594bc2e --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/-.svg @@ -0,0 +1,13 @@ + + + + - + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/1.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/1.svg new file mode 100755 index 0000000..acf746d --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/1.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/2.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/2.svg new file mode 100755 index 0000000..4f14d31 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/2.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/Ctrl.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/Ctrl.svg new file mode 100755 index 0000000..4e9bce1 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/Ctrl.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/Enter.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/Enter.svg new file mode 100755 index 0000000..2dff2f9 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/Enter.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/F.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/F.svg new file mode 100755 index 0000000..29cb27f --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/F.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/I.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/I.svg new file mode 100755 index 0000000..9cb8544 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/I.svg @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/QM.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/QM.svg new file mode 100755 index 0000000..89358c9 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/QM.svg @@ -0,0 +1,20 @@ + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/Shift.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/Shift.svg new file mode 100755 index 0000000..bb6e74f --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/Shift.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/T.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/T.svg new file mode 100755 index 0000000..43399c0 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/T.svg @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/Z.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/Z.svg new file mode 100755 index 0000000..8a32898 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/Z.svg @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/attention.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/attention.svg new file mode 100755 index 0000000..23149c0 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/attention.svg @@ -0,0 +1,9 @@ + + + attention + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/close_icon.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/close_icon.svg new file mode 100755 index 0000000..9047265 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/close_icon.svg @@ -0,0 +1,15 @@ + + + + Rectangle 9 + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/dde-file-manager.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/dde-file-manager.svg new file mode 100755 index 0000000..5a8c31e --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/dde-file-manager.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/deepin_file_manager.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/deepin_file_manager.svg new file mode 100755 index 0000000..06c03ed --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/deepin_file_manager.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/deepin_launcher.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/deepin_launcher.svg new file mode 100755 index 0000000..5793b38 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/deepin_launcher.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/exit.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/exit.svg new file mode 100755 index 0000000..e24bf5a --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/exit.svg @@ -0,0 +1,11 @@ + + + 图标/控件/24/退出 + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/file_vault.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/file_vault.svg new file mode 100755 index 0000000..814a77d --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/file_vault.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/fileinfo.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/fileinfo.svg new file mode 100755 index 0000000..6f5eec8 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/fileinfo.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/filter.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/filter.svg new file mode 100755 index 0000000..61d6429 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/filter.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/found.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/found.svg new file mode 100644 index 0000000..cde4095 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/found.svg @@ -0,0 +1,12 @@ + + + 图标/dock/控件/跨屏快传/24/黑 + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/icon_menu.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/icon_menu.svg new file mode 100755 index 0000000..35dd6ea --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/icon_menu.svg @@ -0,0 +1,84 @@ + + + + + + image/svg+xml + + img_upload + + + + + + img_upload + Created with Sketch. + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/icon_view.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/icon_view.svg new file mode 100755 index 0000000..ec07c4d --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/icon_view.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/list_view.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/list_view.svg new file mode 100755 index 0000000..615a574 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/list_view.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/network.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/network.svg new file mode 100755 index 0000000..3d8b03a --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/network.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/notes.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/notes.svg new file mode 100755 index 0000000..e9a3aa6 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/notes.svg @@ -0,0 +1,11 @@ + + + notes + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/pause.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/pause.svg new file mode 100755 index 0000000..8e94a9a --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/pause.svg @@ -0,0 +1,16 @@ + + + + pause-normal + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/phone.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/phone.svg new file mode 100755 index 0000000..ee1f4db --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/phone.svg @@ -0,0 +1,9 @@ + + + 形状结合 + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/tips.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/tips.svg new file mode 100755 index 0000000..011c05f --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/tips.svg @@ -0,0 +1,9 @@ + + + tips + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/unmount_normal.svg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/unmount_normal.svg new file mode 100755 index 0000000..a687ab1 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/common/unmount_normal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/d_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/d_file-manager.md new file mode 100644 index 0000000..9322af5 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/d_file-manager.md @@ -0,0 +1,634 @@ +# File Manager|dde-file-manager| + +## Overview + +File Manager is a powerful, simple and easy-to-use file management tool. It follows the classic function and layout of traditional file manager, and simplifies the user operation and adds many features. The open-and-shut navigation bar, the search box with intelligent identification, a variety of views and sorting let you manage files easily. It's beyond classic, just to give you a better experience! + +![1|overview](fig/d_overview.png) + +## Guide + +You can run, close and create a shortcut for File Manager by the following ways. + +### Run File Manager + +1. Click ![Launcher](../common/deepin_launcher.svg) on dock to enter Launcher interface. +2. Locate ![FileManager](../common/deepin_file_manager.svg) by scrolling mouse wheel or searching by "File Manager" in Launcher interface. +3. Right-click ![FileManager](../common/deepin_file_manager.svg), you can + - Click **Send to desktop** to create a desktop shortcut. + - Click **Send to dock** to fix the application on dock. + - Click **Add to startup** to add the application to startup, it will automatically run when the system starts up. + + >![tips](../common/tips.svg) Tips: You can also press **Super** + **E** to start File Manager. + +### Exit File Manager + +- On File Manager interface, click ![close](../common/close_icon.svg) to exit. +- Right-click ![FileManager](../common/deepin_file_manager.svg) on Dock, select **Close All** to exit File Manager. +- Click ![Settings](../common/icon_menu.svg) and select **Exit** to exit File Manager. + +### View Shortcut Keys + +On Document Viewer interface, press **Ctrl + Shift + /** to view all shortcut keys quickly, which helps you to use them skillfully and improves your working efficiency. + +![1|hotkey](fig/hotkey.png) + +## Main Interface + +On File Manager interface, you can execute many operations with the functional bars. It is designed to be easy-to-use, user-friendly and efficient improving. + +![1|maininterface](fig/d_maininterface.png) + +| No. | Name | Description | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | Left panel | Click icons in left panel to quickly visit local files, disks, computers in LAN, bookmarks and tags. | +| 2 | Address bar | You can quickly switch visiting history, switch among directory levels, search and input address in address bar. | +| 3 | View | Click ![icon_view](../common/icon_view.svg) and ![list_view](../common/list_view.svg) to switch view modes. | +| 4 | Info column | Click ![fileinfo](../common/fileinfo.svg) to view basic information and tags of files(folders). | +| 5 | Main menu | You can create new window, switch themes, set share password, make settings, view manual and application information, and exit the application in Main menu. | +| 6 | Status bar | You can view the number of files or selected files. | + + +> ![tips](../common/tips.svg) Tips: you can drag the dividing line on the right of left panel to change its width. + + +## Basic Functions + +File Manager is featured with the basic functions as a file manager, you can easily create, copy, rename or delete files/folders with it. + +### New Document/Folder + + +#### New Document + +1. Right-click in the blank area on File Manager. +2. Select **New document**. +3. In the pop-up menu, select the document format you want to create. +4. Input a name for the new document. + +![0|newdoc](fig/p_newdoc.png) + +#### New Folder + +1. Right-click in the blank area on File Manager +2. Select **New folder**. +3. Input a name for the new folder. + +### Rename File/Folder + +1. Select the file/folder, right-click to select **Rename**. +2. Input a new name for the file/folder, and press **Enter**, or click at any blank area. + +![0|rename](fig/d_contextmenu.png) + +> ![tips](../common/tips.svg)Tips: Check "Hide file extension when rename" in **Settings** to rename file more conveniently. + +### Batch Rename + +1. On File Manager interface, select multiple files. +2. Right-click and select **Rename**. + - **Replace Text**: Input the content to be replaced in Find box, and input content to rename in Replace box. + - **Add Text**: Input the content to add in Add box, and select the location. + - **Custom Text**: Input the file name and SN. +3. Click **Rename** to finish operation. + +![1|batch_rename](fig/d_rename.png) + +### View Files + +Click ![icon_view](../common/icon_view.svg) and ![list_view](../common/list_view.svg) on the interface to switch icon view and list view. + +- Icon view: displaying filenames, icons or thumbnails. + +![1|iconview](fig/d_iconview.png) + +- List view: displaying file icons or thumbnails, names, time modified, sizes, types and etc in a list. + +![1|listview](fig/d_listview.png) + +> ![tips](../common/tips.svg)Tips: +> +> - In list view, place the cursor on the dividing line between any two columns and drag it to change the width of the current column. Double-click the dividing line to adjust to the biggest width of the current column automatically. + +> - Press **Ctrl**+**1** or **Ctrl**+ **2** to switch icon view and list view. + +### Sorting + +1. Right-click in the blank area on File Manager. +2. Select **Sort by**. +3. Choose among the sorting options, which include **Name**, **Time modified**, **Size** and **Type**. + +> ![tips](../common/tips.svg)Tips: you can click the head of the columns in the list view to change the sort order. + + +### Open Files + +1. On File Manager, right-click the file you want to open. +2. In the context menu, select **Open with** > **Select default program**. +3. Select the application you want to open the file in the list. + +> ![notes](../common/notes.svg)Notes: It will use the default application to open the file when you double-click it. You can select multiple files of the same type, right-click and select **Open with** to open them at a time. + +![0|open_with](fig/d_open.png) + + + +### Hide Files + +1. On File Manager, right-click the file you want to hide. +2. Select **Properties**, check **Hide this file**. + +### Copy File/Folder + +1. Select the files/folders to be copied, right-click and select **Copy**. +2. Enter the directory to which the files/folders will be pasted, right-click and select **Paste**. + +### Compress File/Folder + +1. Select the files/folders to be compressed, right-click and select **Compress**. +2. Compressing interface of Archive Manager pops up, set the format, name, storing path and so on, click **Compress**. + +> ![tips](../common/tips.svg)Tips: Select **Add to xxx.7z** or **Add to xxx.zip** to compress quickly. + +### Delete File/Folder + +1. Select the files/folders and right-click. +2. Select **Delete**. + + - You can find the deleted files in Trash. Right-click files in Trash, you can choose **Restore** or **Delete**. + - The shortcut of the deleted files will become invalid. + +> ![attention](../common/attention.svg)Attention: File/folder in external device will be permanently deleted and can not be restored when you select **Delete**. + +### Undo Operation +In file manager, use **Ctrl + Z** to undo the previous steps, including: +- Delete the newly created file/folder. +- Resume the renamed file/folder to the previous name. +- Restore the deleted file/folder from trash. +- Restore the moved (via dragging or cutting) file/folder to the previous location. +- Delete the copied and pasted file/folder. + +> ![attention](../common/attention.svg)Attention: It can undo two continuous steps at most. If there is file overwriting or permanently file deleting, then you can only return to that step. + + + +### File/Folder Properties + +In Properties of files, you can view the basic info, open with list, and permissions. In properties of folders, you can see basic info, sharing info, and permissions. + +1. On File Manager interface, right-click a file. +2. Select **Properties**. + +![0|info](fig/info.png) + + +> ![notes](../common/notes.svg)Notes: If you check the properties of multiple files at a time, the total size and quantities will be displayed. If you check the properties of a shortcut, the source file location will be displayed in addition. You can use shortcuts **Ctrl + I** to view the properties as well. + +## Common Operations + +File Manager is featured with many useful functions, which are all designed to ease the commonly used operations. + +### Switch Address Bar + +There are three sections in address bar, namely back/forward buttons, breadcrumb bar, and directory/search bar. By default, breadcrumb bar is displayed in the address bar. + +![0|addressbar](fig/addressbar1.png) + +- Clicking back/forward buttons to quickly view the previous address or the next address. +- Each level of the location of a file will form a breadcrumb. You can switch quickly among levels by clicking all breadcrumbs. + +By clicking the search icon, or right-click the file path and select **Edit address**, the address bar will be switched into inputting box. By clicking out of the inputting box, the address bar will restore to breadcrumbs automatically. + +![0|addressbar](fig/addressbar2.png) + +- The inputting box can identify smartly. You can input keywords or an address and press **Enter**, the system will identify automatically and search or visit. + +### Search Files + +File Manager supports multiple indexing methods, including ordinary search by file name and file content, and advanced search by file type and creating time, so as to improve work efficiency and facilitate file management. + +- If you need to search in a specified directory, please enter it before search. + +> ![notes](../common/notes.svg)Notes: In **Settings**, check "Auto index internal disk" and "Index external storage device after connected to computer" to quicken the searching speed. + +#### Full-Text Search + +You can search a file by keywords in its content. +1. In File Manager, click ![icon_menu](../common/icon_menu.svg) > **Settings**. +2. Check **Full-Text search** under **Index** of **Advanced**. +3. Press **Ctrl + F** or click the searching button in the address bar to start searching. Enter the keywords and press **Enter**. + +#### Advanced Search + +When there are many files and the search is slow, you can enable advanced search to narrow the search scope and improve the search efficiency. + +1. In search bar, input the keywords and press **Enter**. When the results appear, you will see ![filter](../common/filter.svg) icon, you can click it to do advanced search. +2. Select the searching range, file type and size, and modified time, accessed time and created time to narrow the search results. + +![0|filter](fig/d_filter.png) + + +### Recent Files +By default, there is a **Recent** entry on left panel. Click it to view the recently used files. Files are sorted by default in reverse order of access time. + +> ![notes](../common/notes.svg)Notes: If you want to hide "Recent", you can uncheck "Display recent file entry in left panel" in Settings > Basic > Hidden files. To hide the access record of a specific file, right-click the file and select **Remove** which will not delete the file. + +### Manage Tabs + +File Manager supports multi-tab view. + +1. On File Manager, right-click the folder. +2. In the pop-up context menu, select **Open in new tab**. +3. When the window has multi-tabs, you can: + - Click + in tab bar to add a new tab. + - Click × on the tab to close it or hover the cursor on the tab, middle-click to close it. + +![1|tab](fig/d_tab.png) + +> ![tips](../common/tips.svg)Tips: When the File Manager has only one tab, the tab bar is hidden, you can press **Ctrl + T** to add a new tab. + +### Manage Bookmarks + +To quickly visit a folder from the left panel, you can add bookmarks for frequently used folders. + +- Add Bookmarks: On File Manager, right-click the folder, in the pop-up context menu, select **Add to bookmark**. + +- Move Bookmarks: you can move bookmarks within the bookmark area. Drag and drop the bookmark to the designated location. + +- Delete Bookmarks: you can delete bookmarks by right-clicking the bookmark and select **Remove**, or right-clicking the bookmarked folder and select **Remove bookmark**. + +### Manage Tags + +By adding tags on file/folder, you can classify and manage your files better. + +> ![notes](../common/notes.svg)Notes: currently only x86 platform supports **Tag information**. All contents related to "Tag information" in this manual are only applicable for x86 platform. + +#### Add Tags + +You can add tag to multiple files/folders at a time, or add multiple tags to a single file/folder; you can also add tags in Properties of the file/folder. The tag appears in the left panel. + +##### By Tag Information + +1. Right-click a file/folder, select **Tag information**. +2. Input tag info. Use comma to separate tags in case of multiple tags. +3. Click any blank area to save the setting. + +> ![notes](../common/notes.svg)Notes: The tag color is randomly assigned from eight default colors. + + +![1|taginfo](fig/d_taginfo.png) + + +##### By Color Tag + +Right-click a file/folder, select a "color button" to create a color tag directly. + +![1|colortag](fig/d_colortag.png) + +##### By Information Column on the Right Side + +Select a file/folder, click ![fileinfo](../common/fileinfo.svg), and add tags in the information column on the right side. + +![1|infotag](fig/d_infotag.png) + + + +> ![notes](../common/notes.svg)Notes: If a file has a tag, copy or cut and then paste it, the new file still has the same tag. + +#### Rename Tag + +Right-click a tag in the left panel, select **Rename** to modify the current tag. + +![1|renametag](fig/renametag.png) + +#### Change Tag Color + +Right-click a tag in the left panel, select a "Color button" to change the current tag color. + +#### Change Tag Order + +Drag and drop the tag upwards or downwards to change its order. + +#### Delete Tag +Right-click a tag in left panel, select **Remove** to delete the tag. + + + +### Preview Files + +File Manager supports file preview by pressing space bar. Select a file and press the space bar on the keyboard to quickly preview it. In the preview window, you can view the file info, including image resolution, document size, text content. It also supports gif format, audio and video playback. + +#### Preview Video + +1. Select a video and press the space bar to start video preview. +2. Click in the preview window to pause video playing. +3. Drag the progress bar to play forward or backward. +4. Click **Open** at the bottom to open the video by default program. + +![1|videopreview](fig/videopreview.png) + +![notes](../common/notes.svg)Notes: You can select multiple files and press space bar to preview them at a time. + +### Permission Management +Select a file/folder and right-click, select **Properties**, click **Permissions** to set **Owner**, **Group** and **Others**. + +![0|permission](fig/permission.png) + +### My Shares + +You can share folders in File Manager, if there are some folders shared, the share icon will show on the left panel, if not, the share icon will be removed. + +#### Share Local Files + +1. On File Manager interface, right-click a folder, select **Share folder**. +2. In the properties window, check **Share this folder**. + +>![notes](../common/notes.svg) Notes: If smb service is not turned on, authentication window pops up. Input password to turn smb on. + +3. Input **Share name**, and choose **Permission** and **Anonymous** according to actual needs before closing the window. +4. To set share password, click ![menu](../common/icon_menu.svg) and select **Set share password**. +5. Input password and click **Confirm**. + +![0|share](fig/share.png) + +> ![tips](../common/tips.svg)Tips: You can cancel sharing by unchecking **Share this folder**, or right-click the folder and select **Cancel sharing**. + +#### Visit Sharing Folders + +You can find sharing folders of other users in the same LAN in **Computers in LAN**. You can also visit sharing folders via smb. + + + +1. On File Manager interface, click ![icon_menu](../common/icon_menu.svg) > **Connect to Server**, input the sharing address of the LAN user, e.g. smb://xx.x.xx.xxx (usually it should be an IP address), click **Connect**. Or, input the server's address in the address bar directly and press **Enter**. +2. Select the shared folder you want to visit, input the username and password in the pop-up dialogue box. + - Unencrypted folders can be visited by anonymous access without inputting username and password. + - When you visit encrypted folders, a window pops up and you will have to input user name and password before visiting. + - Username: i.e. the name used by the sharer when logging in the system. + - Password: i.e. the sharing password set when the sharer shares the folder. +3. Click **Connect**. + +![1|viewshare](fig/visitshare.png) + + + +### Open in New Window as Admin + +1. Right-click in the blank area on File Manager. +2. Select **Open in new window as admin**, input your login password in the pop-up window and click **Confirm**. +3. The file will be opened in a new window, in which you can operate with admin permissions. And you will exit admin permissions when you close this window. + +### Open in Terminal + +1. Right-click in the blank area on File Manager. +2. Select **Open in terminal**, Terminal will be opened, and its directory will be the current one. + +![0|openinterminal](fig/p_openinterminal.png) + +### Burn CD + +You can copy music, video, pictures, or mirror files to a CD or DVD through the burning feature. Please prepare an imprint drive, a CD, or DVD disc in advance. + +1. Insert the disc into the recording drive. + +2. Open File Manager and click the CD Icon in the left panel to enter the burning interface. + +![cd](fig/d_cd_interface.png) + +3. Right click the file (folder) and select **Add to disc** or drag the file (folder) directly to the burning interface. + +4. In the burning interface, click **Burn** in the upper right corner. + +>![notes](../common/notes.svg)Notes: if you want to delete a file/folder from the burning list, right-click it and select **Delete** to remove it from the list. + +5. A dialog box pops up. Input the disc name. You can also enter the **Advanced settings** interface, set the file system and write speed, or check "Allow files to be added later", "Verify data" and so on, and click **Burn**. + +![cd](fig/d_cd_rename.png) + +6. After burning, a prompt box will pop up in the interface, and click **OK**. + +>![notes](../common/notes.svg)Notes: +>- For now, as for ISO9660 files, the system supports reading and burning; but, as for UDF files, it supports reading instead of burning. +>- If you need to erase the disc data, you can right-click the disc icon in the left panel and select **Unmount**, right-click the disc icon again and select **Erase**. + +### Create Link + +1. On File Manager interface, right-click the item to create a link for. +2. Select **Create link**. +3. In the pop-up window, select a location and input the name of the link. +4. Click **Save** to finish creating the link. + +> ![tips](../common/tips.svg)Tips: By selecting **Send to desktop** for an item, you can create a link on desktop with one click. + +### Send to Other Device + +When there is an external device inserted, you can directly send file/folder to it. + +1. On File Manager interface, select a file/folder. +2. Right-click and select **Send to**. +3. Select the device you want to send to. +4. File/folder will be copied to the device. + +### Send to Bluetooth +If your computer is equipped with Bluetooth module, you can transfer files in short distance through Bluetooth. + +Prerequisite: The Bluetooth devices of sender and receiver have been paired and connected successfully. Refer to [Connect to a Bluetooth Device](dman:///dde#Connect to a Bluetooth Device) for details. + +1. On File Manager interface, right-click the file or package to be sent. +2. Select **Send to** > **Send to Bluetooth**. +3. Select the receiver in the pop-up dialog box, and click **Next**. +4. A file receiving request will pop up on the receiving device. After the receiver agrees the request, the sender starts to transfer the file. + + + +> ![tips](../common/tips.svg)Tips: If you need to transfer a folder, you can compress it in advance and send it via Bluetooth. + + + +## Add Corner Marker to Files/Folders + +You can assign an icon file to a file or folder icon through the command line and display it as a corner marker. +>![notes](../common/notes.svg)Notes: +>- The corner marker files support formats such as svg, jpg, png, bmp, and gif, but not bigger than 100KB. +>- The corner marker could not be added to files in USB disks and CD-ROM disks. + +### Add Single Corner Marker + +1. Open Terminal, input **gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path)"**, which means to add a corner marker in the lower right corner of the file/folder icon by default. +>![attention](../common/attention.svg)Attention: the special corner markers defined by the system could not be replaced. +2. You can add position codes into the above command to add a corner marker to the upper left corner(lu), lower left corner(ld), upper right corner(ru) or lower right corner(rd). +For example, to add a corner marker to the upper left corner, you have to input: +**gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path);lu"** +![mark](fig/single.png) + +### Add Multiple Corner Markers +To add 2~4 corner markers to a file/folder, you can input "|" in the command to separate multiple paths of the corner marker files. Only one corner marker can be added to the same corner, but you can replace it. + +For example, to add 4 corner markers to a file/folder icon, you can input: +**gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path);lu|xxx(icon path);ld|xxx(icon path);ru|xxx(icon path);rd"** + +![mark](fig/multi.png) + +### Cancel Corner Markers +Open Terminal, input **gio set xxx(file path) -t stringv metadata::emblems ""** to cancel all corner markers on the file/folder icon. + +## Disk Management + +On File Manager interface, you can manage local and external disks. + +Local disks are displayed in the left panel of File Manager. When you mount any external disks or insert other mobile storage devices, the corresponding icons will be displayed in the left panel. + + + + + + + + + + + + + + + + + +
Local disksAll disks of local harddisk divisions
External disksIncluding mobile hard disks, CDs/DVDs and USB flash disks.
Mobile devicesIncluding mobile phone storage, storage cards, SD cards and so on.
+ +> ![notes](../common/notes.svg)Notes: If disks or folders in the disk are encrypted, you will have to input password before visiting them. + +### Local Disks +#### Hide Local Disks +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Check **Hide system disk** under **Advanced** > **Other**. + + +#### Rename Local Disks + +1. Right-click a local disk in the left panel or in the computer interface. +2. Select **Rename**. +3. Input the new name and press **Enter** or click any blank area to save the modification. + +> ![tips](../common/tips.svg)Tips: In the computer interface, double click any local disk slowly, after the editing box appears, you can rename it directly. + +![0|disk](fig/d_rename_disk.png) + +### External Disks +#### Eject External Disks + +1. In the left panel of File Manager, right-click the disk you want to remove. + +2. Select **Safely Remove**. + +3. The disk will be removed from the disk list, and so will all partition of it . + + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg)Tips: you can also select **Eject** or click ![unmount](../common/unmount_normal.svg) in the left panel to unmount the disk. + +#### Rename External Disks +1. In the left panel or on computer interface, right-click the disk you want to rename. +2. Select **Unmount** and then select **Rename**. +3. Input the new name and press **Enter** or click any blank area to save the modification. + +#### Format External Disks + +1. In the left panel of File Manager, right-click the disk to format. + +2. Select **Unmount** and then select **Format**. + +3. In the pop-up window, choose the type and volume label for the disk. + +4. Click **Format**. + + ![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg)Notes: If you check **Quick Format**, the disk can be formatted quickly in a few seconds, but the data could be restored by file recovery tools. If you don't want these data to be restored, you can uncheck this option box and format the disk. + + +## Main Menu + +You can create new window, switch themes, connect to server, set share password (see [Share Local Files](#Share Local Files)), make settings, view manual and version information in Main Menu. + + +### New Window + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Select **New window** to open a new window. + +### Connect to Server + +You can [visit sharing folders](#Visit Sharing Folders) by connecting to server. + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Select **Connect to Server**, input server's IP address (XX.XX.XX.XX) in the editing box. + - Click ![+](../common/+.svg) to add the address into **My Favorites**. + - Select an address from **My Favorites** and click ![-](../common/-.svg) to delete in from **My Favorites**. +3. Click **Connect**. + +![connect](fig/connecttoserver.png) + + + +### Settings + +#### Basic + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Select **Basic**. + - You can check **Always open folder in new window** + - You can set whether to open folder by one click or double click. + - You can select a directory under **Open from default window** or **Open in new tab**. + - You can set up the icon size. + - You can set the **Default View** as icon view or list view. + - Check **Show hidden files** to show all hidden files. + - Check **Hide file extension when rename**, so the extension would not be displayed when renaming. + - Check **Display recent file entry in left panel**, then the recently visited file would be displayed in left panel. + + +#### Advanced +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Select **Advanced**. + - You can check **Auto index internal disk**, when you search files, the files in internal disks would be searched. + - You can check **Index external storage device after connected to computer**, In **Index**, when you search files, the files in the external disks would be searched as well. + - You can check **Full-Text search** to search by content. + - You can select which types of files can be previewed. + - You can check **Auto mount**, when any external disks connect to the computer, they would be mounted automatically. + - You can check **Open after auto mount**, when any external disks connect to the computer, they would be mounted automatically and opened. + - Check **Show item counts and sizes in the path of mounted MTP devices** to display the status bar information at the bottom of the MTP device's path after it is mounted. + - Check **Keep showing the mounted Samba shares** to show the remote mount link always in the left panel. + - You can check **Use the file chooser dialog of File Manager**, when selecting files, File Manager window would be opened. + - You can check **Ask for my confirmation when deleting files**, when deleting files, a hint dialog would pop up. + - You can check **Hide system disk**, local disks would not be displayed in left panel and computer interface. + - You can check **Show file system on disk icon**. + + + +### Theme + +The window theme includes Light Theme, Dark Theme and System Theme. + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Theme** to select one. + + + +### Help + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Help** to view the manual. + + + +### About + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **About** to view version information and introduction about File Manager. + + + +### Exit + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Exit**. diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/e_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/e_file-manager.md new file mode 100644 index 0000000..906afd6 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/e_file-manager.md @@ -0,0 +1,671 @@ +# File Manager|dde-file-manager| + +## Overview + +File Manager is a powerful, simple and easy-to-use file management tool. It follows the classic function and layout of traditional file manager, and simplifies the user operation and adds many features. The open-and-shut navigation bar, the search box with intelligent identification, a variety of views and sorting let you manage files easily. It's beyond classic, just to give you a better experience! + +![1|overview](fig/eu_overview.png) + +## Guide + +You can run, close and create a shortcut for File Manager by the following ways. + +### Run File Manager + +1. Click ![Launcher](../common/deepin_launcher.svg) on dock to enter Launcher interface. +2. Locate ![FileManager](../common/deepin_file_manager.svg) by scrolling mouse wheel or searching by "File Manager" in Launcher interface. +3. Right-click ![FileManager](../common/deepin_file_manager.svg), you can + - Click **Send to desktop** to create a desktop shortcut. + - Click **Send to dock** to fix the application on dock. + - Click **Add to startup** to add the application to startup, it will automatically run when the system starts up. + + >![tips](../common/tips.svg) Tips: You can also press **Super** + **E** to start File Manager. + +### Exit File Manager + +- On File Manager interface, click ![close](../common/close_icon.svg) to exit. +- Right-click ![FileManager](../common/deepin_file_manager.svg) on Dock, select **Close All** to exit File Manager. +- Click ![Settings](../common/icon_menu.svg) and select **Exit** to exit File Manager. + +### View Shortcut Keys + +On Document Viewer interface, press **Ctrl + Shift + /** to view all shortcut keys quickly, which helps you to use them skillfully and improves your working efficiency. + +![1|hotkey](fig/hotkey.png) + +## Main Interface + +On File Manager interface, you can execute many operations with the functional bars. It is designed to be easy-to-use, user-friendly and efficient improving. + +![1|maininterface](fig/eu_maininterface.png) + +| No. | Name | Description | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | Left panel | Click icons in left panel to quickly visit local files, disks, computers in LAN, bookmarks and tags. | +| 2 | Address bar | You can quickly switch visiting history, switch among directory levels, search and input address in address bar. | +| 3 | View | Click ![icon_view](../common/icon_view.svg) and ![list_view](../common/list_view.svg) to switch view modes. | +| 4 | Info column | Click ![fileinfo](../common/fileinfo.svg) to view basic information and tags of files(folders). | +| 5 | Main menu | You can create new window, switch themes, set share password, make settings, view manual and application information, and exit the application in Main menu. | +| 6 | Status bar | You can view the number of files or selected files. | + + +> ![tips](../common/tips.svg) Tips: you can drag the dividing line on the right of left panel to change its width. + + +## Basic Functions + +File Manager is featured with the basic functions as a file manager, you can easily create, copy, rename or delete files/folders with it. + +### New Document/Folder + + +#### New Document + +1. On File Manager interface, right-click and select **New document**. +2. In the pop-up menu, select the document format you want to create. +3. Input a name for the new document, and press **Enter**, or click at blank area. + +![0|newdoc](fig/e_newdoc.png) + +#### New Folder + +1. On File Manager interface, right-click and select **New folder**. +2. Input a name for the new folder, and press **Enter**, or click at blank area. + +### Rename File/Folder + +1. Select the file/folder, right-click to select **Rename**. +2. Input a new name for the file/folder, and press **Enter**, or click at any blank area. + +![0|rename](fig/e_contextmenu.png) + +> ![tips](../common/tips.svg) Tips: Check "Hide file extension when rename" in **Settings** to rename file more conveniently. + +### Batch Rename + +1. On File Manager interface, select multiple files. +2. Right-click and select **Rename**. + - **Replace Text**: Input the content to be replaced in Find box, and input content to rename in Replace box. + - **Add Text**: Input the content to add in Add box, and select the location. + - **Custom Text**: Input the file name and SN. +3. Click **Rename** to finish operation. + +![1|batch_rename](fig/eu_rename.png) + +### View Files + +Click ![icon_view](../common/icon_view.svg) and ![list_view](../common/list_view.svg) on the interface to switch icon view and list view. + +- Icon view: displaying filenames, icons or thumbnails. + +![1|iconview](fig/eu_iconview.png) + +- List view: displaying file icons or thumbnails, names, time modified, sizes, types and etc in a list. + +![1|listview](fig/eu_listview.png) + +> ![tips](../common/tips.svg) Tips: +> +> - In list view, place the cursor on the dividing line between any two columns and drag it to change the width of the current column. Double-click the dividing line to adjust to the biggest width of the current column automatically. +> - Press **Ctrl**+**1** or **Ctrl**+ **2** to switch icon view and list view. + +### Sorting + +1. Right-click in the blank area on File Manager, select **Sort by**. +2. Choose among the sorting options, which include **Name**, **Time modified**, **Size** and **Type**. + +> ![tips](../common/tips.svg) Tips: you can click the head of the columns in the list view to change the sort order. + + +### Open Files + +1. On File Manager, right-click the file you want to open. +2. In the context menu, select **Open with**>**Select default program**. +3. Select the application you want to open the file in the list. + +> ![notes](../common/notes.svg) Notes: It will use the default application to open the file when you double-click it. You can right-click multiple files of the same type, and select **Open with** to open them at a time. + +![0|open_with](fig/eu_open.png) + + + +### Hide Files + +1. On File Manager, right-click the file you want to hide. +2. Select **Properties**, check **Hide this file**. + +### Copy File/Folder + +1. Select the files/folders to be copied, right-click and select **Copy**. +2. Enter the directory to which the files/folders will be pasted, right-click and select **Paste**. + +### Compress File/Folder + +1. Select the files/folders to be compressed, right-click and select **Compress**. +2. Input a file name and select a file format for the to be compressed file. +3. Select a location to store it. +4. Select **Compress** to generate the compressed file. + +> ![notes](../common/notes.svg) Notes: Switch on **Advanced Options** to set password and split volumes sizes. **Encrypt the archive** and **Split to volumes** are only applicable for some formats. + +### Delete File/Folder + +Right-click file/folder to select **Delete**. + - You can find the deleted files in Trash. Right-click files in Trash, you can choose **Restore** or **Delete**. + - The shortcut of the deleted files will become invalid. + +> ![attention](../common/attention.svg) Attention: File/folder in external device will be permanently deleted and can not be restored when you select **Delete**. + +### Undo Operation +In file manager, use **Ctrl + Z** to undo the previous steps, including: +- Delete the newly created file/folder. +- Resume the renamed file/folder to the previous name. +- Restore the deleted file/folder from trash. +- Restore the moved (via dragging or cutting) file/folder to the previous location. +- Delete the copied and pasted file/folder. + +> ![attention](../common/attention.svg) Attention: It can undo two continuous steps at most. If there is file overwriting or permanently file deleting, then you can only return to that step. + + + +### File/Folder Properties + +In Properties of files, you can view the basic info, open with list, and permissions. In properties of folders, you can see basic info, sharing info, and permissions. + +1. On File Manager interface, right-click a file. +2. Select **Properties**. + +![0|info](fig/info.png) + + +> ![notes](../common/notes.svg) Notes: If you check the properties of multiple files at a time, the total size and quantities will be displayed. If you check the properties of a shortcut, the source file location will be displayed in addition. You can use shortcuts **Ctrl + I** to view the properties as well. + +## Common Operations + +File Manager is featured with many useful functions, which are all designed to ease the commonly used operations. + +### Switch Address Bar + +There are three sections in address bar, namely back/forward buttons, breadcrumb bar, and directory/search bar. By default, breadcrumb bar is displayed in the address bar. + +![0|addressbar](fig/addressbar1.png) + +- Clicking back/forward buttons to quickly view the previous address or the next address. +- Each level of the location of a file will form a breadcrumb. You can switch quickly among levels by clicking all breadcrumbs. + +By clicking the search icon, or right-click the file path and select **Edit address**, the address bar will be switched into inputting box. By clicking out of the inputting box, the address bar will restore to breadcrumbs automatically. + +![0|addressbar](fig/addressbar2.png) + +- The inputting box can identify smartly. You can input keywords or an address and press **Enter**, the system will identify automatically and search or visit. + +### Search Files + +Click the search button or press **Ctrl + F** to switch to the search bar. Or, input the keywords and press **Enter**, the search results will be shown in the window. + +- If you need to search in a specified directory, please enter it before search. + +> ![notes](../common/notes.svg) Notes: In **Settings**, check "Auto index internal disk" and "Index external storage device after connected to computer" to quicken the searching speed. + +#### Full-Text Search + +You can search a file by keywords in its content. +1. In File Manager, click ![icon_menu](../common/icon_menu.svg) > **Settings**. +2. Check **Full-Text search** under **Index** of **Advanced**. +3. Press **Ctrl + F** or click the searching button in the address bar to start searching. Enter the keywords and press **Enter**. + +#### Advanced Search + +When there are many files and the search is slow, you can enable advanced search to narrow the search scope and improve the search efficiency. + +1. In search bar, input the keywords and press **Enter**. When the results appear, you will see ![filter](../common/filter.svg) icon, you can click it to do advanced search. +2. Select the searching range, file type and size, and modified time, accessed time and created time to narrow the search results. + +![0|filter](fig/eu_filter.png) + + +### Recent Files +By default, there is a **Recent** entry on left panel. Click it to view the recently used files. Files are sorted by default in reverse order of access time. + +> ![notes](../common/notes.svg) Notes: If you want to hide "Recent", you can uncheck "Display recent file entry in left panel" in Settings > Basic > Hidden files. To hide the access record of a specific file, right-click the file and select **Remove** which will not delete the file. + +### Manage Tabs + +File Manager supports multi-tab view. + +1. On File Manager, right-click the folder. +2. In the pop-up context menu, select **Open in new tab**. +3. When the window has multi-tabs, you can: + - Click + in tab bar to add a new tab. + - Click × on the tab to close it. + - Place the cursor on the tab, middle-click to close it. + +![1|tab](fig/eu_tab.png) + +> ![tips](../common/tips.svg) Tips: When the File Manager has only one tab, the tab bar is hidden, you can press **Ctrl + T** to add a new tab. + +### Manage Bookmarks + +To quickly visit a folder from the left panel, you can add bookmarks for frequently used folders. + +- Add Bookmarks: On File Manager, right-click the folder, in the pop-up context menu, select **Add to bookmark**. + +- Move Bookmarks: you can move bookmarks within the bookmark area. Drag and drop the bookmark to the designated location. + +- Delete Bookmarks: you can delete bookmarks by right-clicking the bookmark and select **Remove**, or right-clicking the bookmarked folder and select **Remove bookmark**. + +### Manage Tags + +By adding tags on file/folder, you can classify and manage your files better. + +> ![notes](../common/notes.svg) Notes: currently only x86 platform supports **Tag information**. All contents related to "Tag information" in this manual are only applicable for x86 platform. + +#### Add Tags + +You can add tag to multiple files/folders at a time, or add multiple tags to a single file/folder; you can also add tags in Properties of the file/folder. The tag appears in the left panel. + +##### By Tag Information + +1. Right-click a file/folder, select **Tag information**. +2. Input tag info. Use comma to separate tags in case of multiple tags. +3. Click any blank area to finish adding tag. + +> ![notes](../common/notes.svg) Notes: The tag color is randomly assigned from eight default colors. + + +![1|taginfo](fig/eu_taginfo.png) + + +##### By Color Tag + +Right-click a file/folder, select a "color button" to create a color tag directly. + +![1|colortag](fig/eu_colortag.png) + +##### By Information Column on the Right Side + +Select a file/folder, click ![fileinfo](../common/fileinfo.svg), and add tags in the information column on the right side. + +![1|infotag](fig/eu_infotag.png) + + + +> ![notes](../common/notes.svg) Notes: If a file has a tag, copy or cut and then paste it, the new file still has the same tag. + +#### Rename Tag + +Right-click a tag in the left panel, select **Rename** to modify the current tag. + +![1|renametag](fig/renametag.png) + +#### Change Tag Color + +Right-click a tag in the left panel, select a "Color button" to change the current tag color. + +#### Change Tag Order + +Drag and drop the tag upwards or downwards to change its order. + +#### Delete Tag +Right-click a tag in left panel, select **Remove** to delete the tag. + + + +### Preview Files + +File Manager supports file preview by pressing space bar. Select a file and press the space bar on the keyboard to quickly preview it. In the preview window, you can view the file info, including image resolution, document size, text content. It also supports gif format, audio and video playback. + +#### Preview Video + +1. Select a video and press the space bar to start video preview. +2. Click in the preview window to pause video playing. +3. Drag the progress bar to play forward or backward. +4. Click **Open** at the bottom to open the video by default program. + +![1|videopreview](fig/videopreview.png) + +>![notes](../common/notes.svg) Notes: You can select multiple files and press space bar to preview them at a time. + +### Permission Management +In file/folder properties, click **Permissions** to set **Owner**, **Group** and **Others**. + +![0|permission](fig/permission.png) + +### My Shares + +You can share folders in File Manager, if there are some folders shared, the share icon will show on the left panel, if not, the share icon will be removed. + +#### Share Local Files + +1. On File Manager interface, right-click a folder, select **Share folder**. +2. In the properties window, check **Share this folder**. +3. Input **Share name**, and choose **Permission**, and **Anonymous** according to actual needs before closing the window. +5. To set share password, click ![menu](../common/icon_menu.svg) and select **Set share password**. +5. Input password and click **Confirm**. + +![0|share](fig/share.png) + +> ![tips](../common/tips.svg) Tips: You can cancel sharing by unchecking **Share this folder**, or right-click the folder and select **Cancel sharing**. + +#### Visit Sharing Folders + +You can find sharing folders of other users in the same LAN in **Computers in LAN**. You can also visit sharing folders via smb. + +1. On File Manager interface, click ![icon_menu](../common/icon_menu.svg) > **Connect to Server**, input the sharing address of the LAN user, e.g. smb://xx.x.xx.xxx (usually it should be an IP address), click **Connect**. Or, input the server's address in the address bar directly and press **Enter**. +2. Double-click the shared document you need to visit, input the username and password in the pop-up dialogue box. + - Unencrypted folders can be visited by anonymous access without inputting username and password. + - When you visit encrypted folders, a window pops up and you will have to input user name and password before visiting. If you check **Remember password**, you don't have to input password when you visit the folder next time. + - Username: i.e. the name used by the sharer when logging in the system. + - Password: i.e. the sharing password set when the sharer shares the folder. +3. Click **Connect**. + +![1|viewshare](fig/visitshare.png) + + + +### Open in Terminal + +1. Right-click in the blank area on File Manager. +2. Select **Open in terminal**, Terminal will be opened, and its directory will be the current one. + +![0|openinterminal](fig/e_openinterminal.png) + +### Burn CD + +You can copy music, video, pictures, or mirror files to a CD or DVD through the burning feature. Please prepare a recorder and a CD or DVD in advance. + + +1. Insert the disc into the recording drive. + +2. Open File Manager and click the CD Icon in the left panel to enter the burning interface. + +![cd](fig/eu_cd_interface.png) + +3. Right click the file (folder) and select **Add to disc** or drag the file (folder) directly to the burning interface. + +4. In the burning interface, click **Burn** in the upper right corner. + +>![notes](../common/notes.svg) Notes: if you want to delete a file/folder from the burning list, right-click it and select **Delete** to remove it from the list. + +5. A dialog box pops up. Input the disc name. You can also enter the **Advanced settings** interface, set the file system and write speed, or check "Allow files to be added later", "Verify data" and so on, and click **Burn**. + +![cd](fig/eu_cd_rename.png) + +6. After burning, a prompt box will pop up in the interface, and click **OK**. + +>![notes](../common/notes.svg) Notes: +> - The ISO9660 file system supports all CD and DVD formats, while the UDF file system only supports some CD formats. +> - If you need to erase the disc data, you can right-click the disc icon in the left panel and select **Unmount**, right-click the disc icon again and select **Erase**. + +### Create Link + +1. On File Manager interface, right-click the item to create a link for. +2. Select **Create link**. +3. In the pop-up window, select a location and input the name of the link. +4. Click **Save** to finish creating the link. + +> ![tips](../common/tips.svg) Tips: By selecting **Send to desktop** for an item, you can create a link on desktop with one click. + +### Send to Other Device + +When there is an external device inserted, you can directly send file/folder to it. + +1. On File Manager interface, select a file/folder. +2. Right-click and select **Send to**. +3. Select the device you want to send to. +4. File/folder will be copied to the device. + +## Add Corner Marker to Files/Folders + +You can assign an icon file to a file or folder icon through the command line and display it as a corner marker. +>![notes](../common/notes.svg) Notes: +>- The corner marker files support formats such as svg, jpg, png, bmp, and gif, but not bigger than 100KB. +>- The corner marker could not be added to files in USB disks and CD-ROM disks. + +### Add Single Corner Marker + +1. Open Terminal, input **gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path)"**, which means to add a corner marker in the lower right corner of the file/folder icon by default. + +>![attention](../common/attention.svg) Attention: the special corner markers defined by the system could not be replaced. + +2. You can add position codes into the above command to add a corner marker to the upper left corner(lu), lower left corner(ld), upper right corner(ru) or lower right corner(rd). +For example, to add a corner marker to the upper left corner, you have to input: +**gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path);lu"** + +![mark](fig/single.png) + +### Add Multiple Corner Markers + +To add 2~4 corner markers to a file/folder, you can input "|" in the command to separate multiple paths of the corner marker files. Only one corner marker can be added to the same corner, but you can replace it. + +For example, to add 4 corner markers to a file/folder icon, you can input: +**gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path);lu|xxx(icon path);ld|xxx(icon path);ru|xxx(icon path);rd"** + +![mark](fig/multi.png) + +### Cancel Corner Markers + +Open Terminal, input **gio set xxx(file path) -t stringv metadata::emblems ""** to cancel all corner markers on the file/folder icon. + +## File Vault + +File Vault is designed to create a special safe space for you and protect your privacy. With the advanced encryption technology and convenient operations, it's quite easy to use. + +### Set Vault Password + +You will have to set a password when you use File Vault for the first time as follows: + +1. Click ![file_vault](../common/file_vault.svg) in the left panel or double-click **My Vault** in the **Computer** interface, and then click **Create** in the pop-up dialogue box. +2. Set the "Method", "Password", "Repeat password" and "Hint", click **Next**. + +![0|password](fig/password.png) + +> ![notes](../common/notes.svg) Notes: the password must contain upper case letters, lower case letters, Arabic numbers and special symbols at the same time and no less than 8 digits. Otherwise, you are not able to go to the next step. + +3. A key/QR code is generated. It is recommended to save it in case you forget it. Click **Next**. +4. Click **Encrypt**; enter your login password in the pop-up authentication box and click **Confirm**. + + ![encrypt](fig/encrypt.png) + +5. Click **OK** when encryption finishes. +6. You can now save your files in File Vault. + + + +### Lock File Vault + +After you put files into File Vault, right-click![file_vault](../common/file_vault.svg) in the left panel or right-click **My Vault** in the **Computer** interface. + +- Select **Lock** to lock File Vault. +- Select **Auto lock** and select in the sub-menu: + + Select "Never", which means the file vault remains unlock until the screen is locked or the computer is shutdown. + + Select "5 minutes", "10 minutes" or "20 minutes", which means File Vault will be locked automatically in corresponding time. + +![0|right](fig/right.png) + + + +### Unlock File Vault + +Right-click![file_vault](../common/file_vault.svg) or **My Vault** in the **Computer** interface. + +- Select **Unlock**, input password in the pop-up dialogue box and click **Unlock**. +- Select **Unlock by key**, input the 32-digit recovery key in the pop-up dialogue box and click **Unlock**. + +> ![tips](../common/tips.svg) Tips: You can click ![file_vault](../common/file_vault.svg) in the left panel or double-click **My Vault** in the **Computer** interface and input password. + +### Delete File Vault + +You can delete a vault only after unlocking it. + +1. Right-click ![file_vault](../common/file_vault.svg) in the left panel or right-click **My Vault** in the **Computer** interface and select **Remove File Vault**. +2. Input file vault password in the pop-up dialogue box and click **Remove**. +3. Input your login password in the pop-up dialogue box and click **Confirm** to finish this operation. + +> ![attention](../common/attention.svg) Attention: Files inside the vault would be deleted as you remove the file vault. Please backup them before you remove the file vault if needed. + +## Disk Management + +On File Manager interface, you can manage local and external disks. + +Local disks are displayed in the left panel of File Manager. When you mount any external disks or insert other mobile storage devices, the corresponding icons will be displayed in the left panel. + + + + + + + + + + + + + + + + + +
Local disksAll disks of local harddisk divisions
External disksIncluding mobile hard disks, CDs/DVDs and USB flash disks.
Mobile devicesIncluding mobile phone storage, storage cards, SD cards and so on.
+ +> ![notes](../common/notes.svg) Notes: If disks or folders in the disk are encrypted, you will have to input password before visiting them. + +### Local Disks + +#### Hide Local Disks + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Check **Hide system disk** under **Advanced** > **Other**. + + +#### Rename Local Disks + +1. Right-click a local disk in the left panel or in the computer interface. +2. Select **Rename**. +3. Input the new name and press **Enter** or click any blank area to save the modification. + +> ![tips](../common/tips.svg) Tips: In the computer interface, double click any local disk slowly, after the editing box appears, you can rename it directly. + +![0|disk](fig/eu_rename_disk.png) + +### External Disks + +#### Eject External Disks + +1. In the left panel of File Manager, right-click the disk you want to remove. + +2. Select **Safely Remove**. + +3. The disk will be removed from the disk list, and so will all partition of it . + + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) Tips: you can also select **Eject** or click ![unmount](../common/unmount_normal.svg) in the left panel to unmount the disk. + +#### Rename External Disks + +1. In the left panel or on computer interface, right-click the disk you want to rename. +2. Select **Unmount** and then select **Rename**. +3. Input the new name and press **Enter** or click any blank area to save the modification. + +#### Format External Disks + +1. In the left panel of File Manager, right-click the disk to format. + +2. Select **Unmount** and then select **Format**. + +3. In the pop-up window, choose the type and volume label for the disk. + +4. Click **Format**. + + ![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) Notes: If you check **Quick Format**, the disk can be formatted quickly in a few seconds, but the data could be restored by file recovery tools. If you don't want these data to be restored, you can uncheck this option box and format the disk. + + +## Main Menu + +You can create new window, switch themes, connect to server, set share password (see [Share Local Files](#Share Local Files)), make settings, view manual and version information in Main Menu. + + +### New Window + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Select **New window** to open a new window. + +### Connect to Server + +You can [visit sharing folders](#Visit Sharing Folders) by connecting to server. + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Select **Connect to Server**, input server's IP address (XX.XX.XX.XX) in the editing box. + - Click ![+](../common/+.svg) to add the address into **My Favorites**. + - Select an address from **My Favorites** and click ![-](../common/-.svg) to delete in from **My Favorites**. +3. Click **Connect**. + +![connect](fig/connecttoserver.png) + + + +### Settings + +#### Basic + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Select **Basic**. + - You can check **Always open folder in new window** + - You can set whether to open folder by one click or double click. + - You can select a directory under **Open from default window** or **Open in new tab**. + - You can set up the icon size. + - You can set the **Default View** as icon view or list view. + - Check **Show hidden files** to show all hidden files. + - Check **Hide file extension when rename**, so the extension would not be displayed when renaming. + - Check **Display recent file entry in left panel**, then the recently visited file would be displayed in left panel. + + +#### Advanced + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Select **Advanced**. + - You can check **Auto index internal disk**, when you search files, the files in internal disks would be searched. + - You can check **Index external storage device after connected to computer**, In **Index**, when you search files, the files in the external disks would be searched as well. + - You can check **Full-Text search** to search by content. + - You can select which types of files can be previewed. + - You can check **Auto mount**, when any external disks connect to the computer, they would be mounted automatically. + - You can check **Open after auto mount**, when any external disks connect to the computer, they would be mounted automatically and opened. + - Check **Show item counts and sizes in the path of mounted MTP devices** to display the status bar information at the bottom of the MTP device's path after it is mounted. + - You can check **Use the file chooser dialog of File Manager**, when selecting files, File Manager window would be opened. + - You can check **Ask for my confirmation when deleting files**, when deleting files, a hint dialog would pop up. + - You can check **Hide system disk**, local disks would not be displayed in left panel and computer interface. + - You can check **Show file system on disk icon**. + + + +### Theme + +The window theme includes Light Theme, Dark Theme and System Theme. + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Theme** to select one. + + + +### Help + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Help** to view the manual. + + + +### About + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **About** to view version information and introduction about File Manager. + + + +### Exit + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Exit**. diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/eu_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/eu_file-manager.md new file mode 100644 index 0000000..4ceda24 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/eu_file-manager.md @@ -0,0 +1,672 @@ +# File Manager|dde-file-manager| + +## Overview + +File Manager is a powerful, simple and easy-to-use file management tool. It follows the classic function and layout of traditional file manager, and simplifies the user operation and adds many features. The open-and-shut navigation bar, the search box with intelligent identification, a variety of views and sorting let you manage files easily. It's beyond classic, just to give you a better experience! + +![1|overview](fig/eu_overview.png) + +## Guide + +You can run, close and create a shortcut for File Manager by the following ways. + +### Run File Manager + +1. Click ![Launcher](../common/deepin_launcher.svg) on dock to enter Launcher interface. +2. Locate ![FileManager](../common/deepin_file_manager.svg) by scrolling mouse wheel or searching by "File Manager" in Launcher interface. +3. Right-click ![FileManager](../common/deepin_file_manager.svg), you can + - Click **Send to desktop** to create a desktop shortcut. + - Click **Send to dock** to fix the application on dock. + - Click **Add to startup** to add the application to startup, it will automatically run when the system starts up. + + >![tips](../common/tips.svg) Tips: You can also press **Super** + **E** to start File Manager. + +### Exit File Manager + +- On File Manager interface, click ![close](../common/close_icon.svg) to exit. +- Right-click ![FileManager](../common/deepin_file_manager.svg) on Dock, select **Close All** to exit File Manager. +- Click ![Settings](../common/icon_menu.svg) and select **Exit** to exit File Manager. + +### View Shortcut Keys + +On Document Viewer interface, press **Ctrl + Shift + /** to view all shortcut keys quickly, which helps you to use them skillfully and improves your working efficiency. + +![1|hotkey](fig/hotkey.png) + +## Main Interface + +On File Manager interface, you can execute many operations with the functional bars. It is designed to be easy-to-use, user-friendly and efficient improving. + +![1|maininterface](fig/eu_maininterface.png) + +| No. | Name | Description | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | Left panel | Click icons in left panel to quickly visit local files, disks, computers in LAN, bookmarks and tags. | +| 2 | Address bar | You can quickly switch visiting history, switch among directory levels, search and input address in address bar. | +| 3 | View | Click ![icon_view](../common/icon_view.svg) and ![list_view](../common/list_view.svg) to switch view modes. | +| 4 | Info column | Click ![fileinfo](../common/fileinfo.svg) to view basic information and tags of files(folders). | +| 5 | Main menu | You can create new window, switch themes, set share password, make settings, view manual and application information, and exit the application in Main menu. | +| 6 | Status bar | You can view the number of files or selected files. | + + +> ![tips](../common/tips.svg) Tips: you can drag the dividing line on the right of left panel to change its width. + + +## Basic Functions + +File Manager is featured with the basic functions as a file manager, you can easily create, copy, rename or delete files/folders with it. + +### New Document/Folder + + +#### New Document + +1. On File Manager interface, right-click and select **New document**. +2. In the pop-up menu, select the document format you want to create. +3. Input a name for the new document, and press **Enter**, or click at blank area. + +![0|newdoc](fig/e_newdoc.png) + +#### New Folder + +1. On File Manager interface, right-click and select **New folder**. +2. Input a name for the new folder, and press **Enter**, or click at blank area. + +### Rename File/Folder + +1. Select the file/folder, right-click to select **Rename**. +2. Input a new name for the file/folder, and press **Enter**, or click at any blank area. + +![0|rename](fig/e_contextmenu.png) + +> ![tips](../common/tips.svg) Tips: Check "Hide file extension when rename" in **Settings** to rename file more conveniently. + +### Batch Rename + +1. On File Manager interface, select multiple files. +2. Right-click and select **Rename**. + - **Replace Text**: Input the content to be replaced in Find box, and input content to rename in Replace box. + - **Add Text**: Input the content to add in Add box, and select the location. + - **Custom Text**: Input the file name and SN. +3. Click **Rename** to finish operation. + +![1|batch_rename](fig/eu_rename.png) + +### View Files + +Click ![icon_view](../common/icon_view.svg) and ![list_view](../common/list_view.svg) on the interface to switch icon view and list view. + +- Icon view: displaying filenames, icons or thumbnails. + +![1|iconview](fig/eu_iconview.png) + +- List view: displaying file icons or thumbnails, names, time modified, sizes, types and etc in a list. + +![1|listview](fig/eu_listview.png) + +> ![tips](../common/tips.svg) Tips: +> +> - In list view, place the cursor on the dividing line between any two columns and drag it to change the width of the current column. Double-click the dividing line to adjust to the biggest width of the current column automatically. +> - Press **Ctrl**+**1** or **Ctrl**+ **2** to switch icon view and list view. + +### Sorting + +1. Right-click in the blank area on File Manager, select **Sort by**. +2. Choose among the sorting options, which include **Name**, **Time modified**, **Size** and **Type**. + +> ![tips](../common/tips.svg) Tips: you can click the head of the columns in the list view to change the sort order. + + +### Open Files + +1. On File Manager, right-click the file you want to open. +2. In the context menu, select **Open with**>**Select default program**. +3. Select the application you want to open the file in the list. + +> ![notes](../common/notes.svg) Notes: It will use the default application to open the file when you double-click it. You can right-click multiple files of the same type, and select **Open with** to open them at a time. + +![0|open_with](fig/eu_open.png) + + + +### Hide Files + +1. On File Manager, right-click the file you want to hide. +2. Select **Properties**, check **Hide this file**. + +### Copy File/Folder + +1. Select the files/folders to be copied, right-click and select **Copy**. +2. Enter the directory to which the files/folders will be pasted, right-click and select **Paste**. + +### Compress File/Folder + +1. Select the files/folders to be compressed, right-click and select **Compress**. +2. Input a file name and select a file format for the to be compressed file. +3. Select a location to store it. +4. Select **Compress** to generate the compressed file. + +> ![notes](../common/notes.svg) Notes: Switch on **Advanced Options** to set password and split volumes sizes. **Encrypt the archive** and **Split to volumes** are only applicable for some formats. + +### Delete File/Folder + +Right-click file/folder to select **Delete**. + - You can find the deleted files in Trash. Right-click files in Trash, you can choose **Restore** or **Delete**. + - The shortcut of the deleted files will become invalid. + +> ![attention](../common/attention.svg) Attention: File/folder in external device will be permanently deleted and can not be restored when you select **Delete**. + +### Undo Operation +In file manager, use **Ctrl + Z** to undo the previous steps, including: +- Delete the newly created file/folder. +- Resume the renamed file/folder to the previous name. +- Restore the deleted file/folder from trash. +- Restore the moved (via dragging or cutting) file/folder to the previous location. +- Delete the copied and pasted file/folder. + +> ![attention](../common/attention.svg) Attention: It can undo two continuous steps at most. If there is file overwriting or permanently file deleting, then you can only return to that step. + + + +### File/Folder Properties + +In Properties of files, you can view the basic info, open with list, and permissions. In properties of folders, you can see basic info, sharing info, and permissions. + +1. On File Manager interface, right-click a file. +2. Select **Properties**. + +![0|info](fig/info.png) + + +> ![notes](../common/notes.svg) Notes: If you check the properties of multiple files at a time, the total size and quantities will be displayed. If you check the properties of a shortcut, the source file location will be displayed in addition. You can use shortcuts **Ctrl + I** to view the properties as well. + +## Common Operations + +File Manager is featured with many useful functions, which are all designed to ease the commonly used operations. + +### Switch Address Bar + +There are three sections in address bar, namely back/forward buttons, breadcrumb bar, and directory/search bar. By default, breadcrumb bar is displayed in the address bar. + +![0|addressbar](fig/addressbar1.png) + +- Clicking back/forward buttons to quickly view the previous address or the next address. +- Each level of the location of a file will form a breadcrumb. You can switch quickly among levels by clicking all breadcrumbs. + +By clicking the search icon, or right-click the file path and select **Edit address**, the address bar will be switched into inputting box. By clicking out of the inputting box, the address bar will restore to breadcrumbs automatically. + +![0|addressbar](fig/addressbar2.png) + +- The inputting box can identify smartly. You can input keywords or an address and press **Enter**, the system will identify automatically and search or visit. + +### Search Files + +Click the search button or press **Ctrl + F** to switch to the search bar. Or, input the keywords and press **Enter**, the search results will be shown in the window. + +- If you need to search in a specified directory, please enter it before search. + +> ![notes](../common/notes.svg) Notes: In **Settings**, check "Auto index internal disk" and "Index external storage device after connected to computer" to quicken the searching speed. + +#### Full-Text Search + +You can search a file by keywords in its content. +1. In File Manager, click ![icon_menu](../common/icon_menu.svg) > **Settings**. +2. Check **Full-Text search** under **Index** of **Advanced**. +3. Press **Ctrl + F** or click the searching button in the address bar to start searching. Enter the keywords and press **Enter**. + +#### Advanced Search + +When there are many files and the search is slow, you can enable advanced search to narrow the search scope and improve the search efficiency. + +1. In search bar, input the keywords and press **Enter**. When the results appear, you will see ![filter](../common/filter.svg) icon, you can click it to do advanced search. +2. Select the searching range, file type and size, and modified time, accessed time and created time to narrow the search results. + +![0|filter](fig/eu_filter.png) + + +### Recent Files +By default, there is a **Recent** entry on left panel. Click it to view the recently used files. Files are sorted by default in reverse order of access time. + +> ![notes](../common/notes.svg) Notes: If you want to hide "Recent", you can uncheck "Display recent file entry in left panel" in Settings > Basic > Hidden files. To hide the access record of a specific file, right-click the file and select **Remove** which will not delete the file. + +### Manage Tabs + +File Manager supports multi-tab view. + +1. On File Manager, right-click the folder. +2. In the pop-up context menu, select **Open in new tab**. +3. When the window has multi-tabs, you can: + - Click + in tab bar to add a new tab. + - Click × on the tab to close it. + - Place the cursor on the tab, middle-click to close it. + +![1|tab](fig/eu_tab.png) + +> ![tips](../common/tips.svg) Tips: When the File Manager has only one tab, the tab bar is hidden, you can press **Ctrl + T** to add a new tab. + +### Manage Bookmarks + +To quickly visit a folder from the left panel, you can add bookmarks for frequently used folders. + +- Add Bookmarks: On File Manager, right-click the folder, in the pop-up context menu, select **Add to bookmark**. + +- Move Bookmarks: you can move bookmarks within the bookmark area. Drag and drop the bookmark to the designated location. + +- Delete Bookmarks: you can delete bookmarks by right-clicking the bookmark and select **Remove**, or right-clicking the bookmarked folder and select **Remove bookmark**. + +### Manage Tags + +By adding tags on file/folder, you can classify and manage your files better. + +> ![notes](../common/notes.svg) Notes: currently only x86 platform supports **Tag information**. All contents related to "Tag information" in this manual are only applicable for x86 platform. + +#### Add Tags + +You can add tag to multiple files/folders at a time, or add multiple tags to a single file/folder; you can also add tags in Properties of the file/folder. The tag appears in the left panel. + +##### By Tag Information + +1. Right-click a file/folder, select **Tag information**. +2. Input tag info. Use comma to separate tags in case of multiple tags. +3. Click any blank area to finish adding tag. + +> ![notes](../common/notes.svg) Notes: The tag color is randomly assigned from eight default colors. + + +![1|taginfo](fig/eu_taginfo.png) + + +##### By Color Tag + +Right-click a file/folder, select a "color button" to create a color tag directly. + +![1|colortag](fig/eu_colortag.png) + +##### By Information Column on the Right Side + +Select a file/folder, click ![fileinfo](../common/fileinfo.svg), and add tags in the information column on the right side. + +![1|infotag](fig/eu_infotag.png) + + + +> ![notes](../common/notes.svg) Notes: If a file has a tag, copy or cut and then paste it, the new file still has the same tag. + +#### Rename Tag + +Right-click a tag in the left panel, select **Rename** to modify the current tag. + +![1|renametag](fig/renametag.png) + +#### Change Tag Color + +Right-click a tag in the left panel, select a "Color button" to change the current tag color. + +#### Change Tag Order + +Drag and drop the tag upwards or downwards to change its order. + +#### Delete Tag +Right-click a tag in left panel, select **Remove** to delete the tag. + + + +### Preview Files + +File Manager supports file preview by pressing space bar. Select a file and press the space bar on the keyboard to quickly preview it. In the preview window, you can view the file info, including image resolution, document size, text content. It also supports gif format, audio and video playback. + +#### Preview Video + +1. Select a video and press the space bar to start video preview. +2. Click in the preview window to pause video playing. +3. Drag the progress bar to play forward or backward. +4. Click **Open** at the bottom to open the video by default program. + +![1|videopreview](fig/videopreview.png) + +>![notes](../common/notes.svg) Notes: You can select multiple files and press space bar to preview them at a time. + +### Permission Management +In file/folder properties, click **Permissions** to set **Owner**, **Group** and **Others**. + +![0|permission](fig/permission.png) + +### My Shares + +You can share folders in File Manager, if there are some folders shared, the share icon will show on the left panel, if not, the share icon will be removed. + +#### Share Local Files + +1. On File Manager interface, right-click a folder, select **Share folder**. +2. In the properties window, check **Share this folder**. +3. Input **Share name**, and choose **Permission**, and **Anonymous** according to actual needs before closing the window. +5. To set share password, click ![menu](../common/icon_menu.svg) and select **Set share password**. +5. Input password and click **Confirm**. + +![0|share](fig/share.png) + +> ![tips](../common/tips.svg) Tips: You can cancel sharing by unchecking **Share this folder**, or right-click the folder and select **Cancel sharing**. + +#### Visit Sharing Folders + +You can find sharing folders of other users in the same LAN in **Computers in LAN**. You can also visit sharing folders via smb. + + + +1. On File Manager interface, click ![icon_menu](../common/icon_menu.svg) > **Connect to Server**, input the sharing address of the LAN user, e.g. smb://xx.x.xx.xxx (usually it should be an IP address), click **Connect**. Or, input the server's address in the address bar directly and press **Enter**. +2. Double-click the shared document you need to visit, input the username and password in the pop-up dialogue box. + - Unencrypted folders can be visited by anonymous access without inputting username and password. + - When you visit encrypted folders, a window pops up and you will have to input user name and password before visiting. If you check **Remember password**, you don't have to input password when you visit the folder next time. + - Username: i.e. the name used by the sharer when logging in the system. + - Password: i.e. the sharing password set when the sharer shares the folder. +3. Click **Connect**. + +![1|viewshare](fig/visitshare.png) + + + +### Open in Terminal + +1. Right-click in the blank area on File Manager. +2. Select **Open in terminal**, Terminal will be opened, and its directory will be the current one. + +![0|openinterminal](fig/e_openinterminal.png) + +### Burn CD + +You can copy music, video, pictures, or mirror files to a CD or DVD through the burning feature. Please prepare a recorder and a CD or DVD in advance. + + +1. Insert the disc into the recording drive. + +2. Open File Manager and click the CD Icon in the left panel to enter the burning interface. + +![cd](fig/eu_cd_interface.png) + +3. Right click the file (folder) and select **Add to disc** or drag the file (folder) directly to the burning interface. + +4. In the burning interface, click **Burn** in the upper right corner. + +>![notes](../common/notes.svg) Notes: if you want to delete a file/folder from the burning list, right-click it and select **Delete** to remove it from the list. + +5. A dialog box pops up. Input the disc name. You can also enter the **Advanced settings** interface, set the file system and write speed, or check "Allow files to be added later", "Verify data" and so on, and click **Burn**. + +![cd](fig/eu_cd_rename.png) + +6. After burning, a prompt box will pop up in the interface, and click **OK**. + +>![notes](../common/notes.svg) Notes: +> - The ISO9660 file system supports all CD and DVD formats, while the UDF file system only supports some CD formats. +> - If you need to erase the disc data, you can right-click the disc icon in the left panel and select **Unmount**, right-click the disc icon again and select **Erase**. + +### Create Link + +1. On File Manager interface, right-click the item to create a link for. +2. Select **Create link**. +3. In the pop-up window, select a location and input the name of the link. +4. Click **Save** to finish creating the link. + +> ![tips](../common/tips.svg) Tips: By selecting **Send to desktop** for an item, you can create a link on desktop with one click. + +### Send to Other Device + +When there is an external device inserted, you can directly send file/folder to it. + +1. On File Manager interface, select a file/folder. +2. Right-click and select **Send to**. +3. Select the device you want to send to. +4. File/folder will be copied to the device. + +## Add Corner Marker to Files/Folders + +You can assign an icon file to a file or folder icon through the command line and display it as a corner marker. +>![notes](../common/notes.svg) Notes: +>- The corner marker files support formats such as svg, jpg, png, bmp, and gif, but not bigger than 100KB. +>- The corner marker could not be added to files in USB disks and CD-ROM disks. + +### Add Single Corner Marker + +1. Open Terminal, input **gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path)"**, which means to add a corner marker in the lower right corner of the file/folder icon by default. + +>![attention](../common/attention.svg) Attention: the special corner markers defined by the system could not be replaced. + +2. You can add position codes into the above command to add a corner marker to the upper left corner(lu), lower left corner(ld), upper right corner(ru) or lower right corner(rd). +For example, to add a corner marker to the upper left corner, you have to input: +**gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path);lu"** + +![mark](fig/single.png) + +### Add Multiple Corner Markers + +To add 2~4 corner markers to a file/folder, you can input "|" in the command to separate multiple paths of the corner marker files. Only one corner marker can be added to the same corner, but you can replace it. + +For example, to add 4 corner markers to a file/folder icon, you can input: +**gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path);lu|xxx(icon path);ld|xxx(icon path);ru|xxx(icon path);rd"** + +![mark](fig/multi.png) + +### Cancel Corner Markers + +Open Terminal, input **gio set xxx(file path) -t stringv metadata::emblems ""** to cancel all corner markers on the file/folder icon. + +## File Vault + +File Vault is designed to create a special safe space for you and protect your privacy. With the advanced encryption technology and convenient operations, it's quite easy to use. + +### Set Vault Password + +You will have to set a password when you use File Vault for the first time as follows: + +1. Click ![file_vault](../common/file_vault.svg) in the left panel or double-click **My Vault** in the **Computer** interface, and then click **Create** in the pop-up dialogue box. +2. Set the "Method", "Password", "Repeat password" and "Hint", click **Next**. + +![0|password](fig/password.png) + +> ![notes](../common/notes.svg) Notes: the password must contain upper case letters, lower case letters, Arabic numbers and special symbols at the same time and no less than 8 digits. Otherwise, you are not able to go to the next step. + +3. A key/QR code is generated. It is recommended to save it in case you forget it. Click **Next**. +4. Click **Encrypt**; enter your login password in the pop-up authentication box and click **Confirm**. + + ![encrypt](fig/encrypt.png) + +5. Click **OK** when encryption finishes. +6. You can now save your files in File Vault. + + + +### Lock File Vault + +After you put files into File Vault, right-click![file_vault](../common/file_vault.svg) in the left panel or right-click **My Vault** in the **Computer** interface. + +- Select **Lock** to lock File Vault. +- Select **Auto lock** and select in the sub-menu: + + Select "Never", which means the file vault remains unlock until the screen is locked or the computer is shutdown. + + Select "5 minutes", "10 minutes" or "20 minutes", which means File Vault will be locked automatically in corresponding time. + +![0|right](fig/right.png) + + + +### Unlock File Vault + +Right-click![file_vault](../common/file_vault.svg) or **My Vault** in the **Computer** interface. + +- Select **Unlock**, input password in the pop-up dialogue box and click **Unlock**. +- Select **Unlock by key**, input the 32-digit recovery key in the pop-up dialogue box and click **Unlock**. + +> ![tips](../common/tips.svg) Tips: You can click ![file_vault](../common/file_vault.svg) in the left panel or double-click **My Vault** in the **Computer** interface and input password. + +### Delete File Vault + +You can delete a vault only after unlocking it. + +1. Right-click ![file_vault](../common/file_vault.svg) in the left panel or right-click **My Vault** in the **Computer** interface and select **Remove File Vault**. +2. Input file vault password in the pop-up dialogue box and click **Remove**. +3. Input your login password in the pop-up dialogue box and click **Confirm** to finish this operation. + +> ![attention](../common/attention.svg) Attention: Files inside the vault would be deleted as you remove the file vault. Please backup them before you remove the file vault if needed. + +## Disk Management + +On File Manager interface, you can manage local and external disks. + +Local disks are displayed in the left panel of File Manager. When you mount any external disks or insert other mobile storage devices, the corresponding icons will be displayed in the left panel. + + + + + + + + + + + + + + + + + +
Local disksAll disks of local harddisk divisions
External disksIncluding mobile hard disks, CDs/DVDs and USB flash disks.
Mobile devicesIncluding mobile phone storage, storage cards, SD cards and so on.
+ +> ![notes](../common/notes.svg) Notes: If disks or folders in the disk are encrypted, you will have to input password before visiting them. + +### Local Disks + +#### Hide Local Disks + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Check **Hide system disk** under **Advanced** > **Other**. + + +#### Rename Local Disks + +1. Right-click a local disk in the left panel or in the computer interface. +2. Select **Rename**. +3. Input the new name and press **Enter** or click any blank area to save the modification. + +> ![tips](../common/tips.svg) Tips: In the computer interface, double click any local disk slowly, after the editing box appears, you can rename it directly. + +![0|disk](fig/eu_rename_disk.png) + +### External Disks + +#### Eject External Disks + +1. In the left panel of File Manager, right-click the disk you want to remove. + +2. Select **Safely Remove**. + +3. The disk will be removed from the disk list, and so will all partition of it . + + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) Tips: you can also select **Eject** or click ![unmount](../common/unmount_normal.svg) in the left panel to unmount the disk. + +#### Rename External Disks + +1. In the left panel or on computer interface, right-click the disk you want to rename. +2. Select **Unmount** and then select **Rename**. +3. Input the new name and press **Enter** or click any blank area to save the modification. + +#### Format External Disks + +1. In the left panel of File Manager, right-click the disk to format. + +2. Select **Unmount** and then select **Format**. + +3. In the pop-up window, choose the type and volume label for the disk. + +4. Click **Format**. + + ![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) Notes: If you check **Quick Format**, the disk can be formatted quickly in a few seconds, but the data could be restored by file recovery tools. If you don't want these data to be restored, you can uncheck this option box and format the disk. + + +## Main Menu + +You can create new window, switch themes, connect to server, set share password (see [Share Local Files](#Share Local Files)), make settings, view manual and version information in Main Menu. + + +### New Window + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Select **New window** to open a new window. + +### Connect to Server + +You can [visit sharing folders](#Visit Sharing Folders) by connecting to server. + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Select **Connect to Server**, input server's IP address (XX.XX.XX.XX) in the editing box. + - Click ![+](../common/+.svg) to add the address into **My Favorites**. + - Select an address from **My Favorites** and click ![-](../common/-.svg) to delete in from **My Favorites**. +3. Click **Connect**. + +![connect](fig/connecttoserver.png) + + + +### Settings + +#### Basic + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Select **Basic**. + - You can check **Always open folder in new window** + - You can set whether to open folder by one click or double click. + - You can select a directory under **Open from default window** or **Open in new tab**. + - You can set up the icon size. + - You can set the **Default View** as icon view or list view. + - Check **Show hidden files** to show all hidden files. + - Check **Hide file extension when rename**, so the extension would not be displayed when renaming. + - Check **Display recent file entry in left panel**, then the recently visited file would be displayed in left panel. + + +#### Advanced + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Select **Advanced**. + - You can check **Auto index internal disk**, when you search files, the files in internal disks would be searched. + - You can check **Index external storage device after connected to computer**, In **Index**, when you search files, the files in the external disks would be searched as well. + - You can check **Full-Text search** to search by content. + - You can select which types of files can be previewed. + - You can check **Auto mount**, when any external disks connect to the computer, they would be mounted automatically. + - You can check **Open after auto mount**, when any external disks connect to the computer, they would be mounted automatically and opened. + - You can check **Use the file chooser dialog of File Manager**, when selecting files, File Manager window would be opened. + - You can check **Ask for my confirmation when deleting files**, when deleting files, a hint dialog would pop up. + - You can check **Hide system disk**, local disks would not be displayed in left panel and computer interface. + - You can check **Show file system on disk icon**. + + + +### Theme + +The window theme includes Light Theme, Dark Theme and System Theme. + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Theme** to select one. + + + +### Help + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Help** to view the manual. + + + +### About + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **About** to view version information and introduction about File Manager. + + + +### Exit + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Exit**. diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/Screenshot_dde-file-manager_20211130170404.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/Screenshot_dde-file-manager_20211130170404.png new file mode 100644 index 0000000..e80a137 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/Screenshot_dde-file-manager_20211130170404.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/addressbar1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/addressbar1.png new file mode 100644 index 0000000..5984a0c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/addressbar1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/addressbar2.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/addressbar2.png new file mode 100644 index 0000000..afc1b01 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/addressbar2.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/cd_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/cd_interface.png new file mode 100644 index 0000000..2833be0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/cd_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/cd_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/cd_rename.png new file mode 100644 index 0000000..8f4d26c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/cd_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/connecttoserver.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/connecttoserver.png new file mode 100644 index 0000000..c903e0d Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/connecttoserver.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_cd_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_cd_interface.png new file mode 100644 index 0000000..11cef96 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_cd_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_cd_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_cd_rename.png new file mode 100644 index 0000000..0a9e36d Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_cd_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_colortag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_colortag.png new file mode 100644 index 0000000..b8d4d06 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_colortag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_contextmenu.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_contextmenu.png new file mode 100644 index 0000000..c2fa84f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_contextmenu.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_filter.png new file mode 100644 index 0000000..a29bfbc Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_iconview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_iconview.png new file mode 100644 index 0000000..600e2aa Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_iconview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_infotag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_infotag.png new file mode 100644 index 0000000..36a490c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_infotag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_listview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_listview.png new file mode 100644 index 0000000..6022ce9 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_listview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_maininterface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_maininterface.png new file mode 100644 index 0000000..15b3bbe Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_maininterface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_newdoc.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_newdoc.png new file mode 100644 index 0000000..4aa80e7 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_newdoc.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_open.png new file mode 100644 index 0000000..a15905e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_openinterminal.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_openinterminal.png new file mode 100644 index 0000000..b2ec571 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_openinterminal.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_overview.png new file mode 100644 index 0000000..1f7ac98 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_rename.png new file mode 100644 index 0000000..fd11d26 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_rename_disk.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_rename_disk.png new file mode 100644 index 0000000..65808d4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_rename_disk.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_tab.png new file mode 100644 index 0000000..555a403 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_taginfo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_taginfo.png new file mode 100644 index 0000000..f3d0b2f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/d_taginfo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/disk1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/disk1.png new file mode 100644 index 0000000..2910cd2 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/disk1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/disk2.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/disk2.png new file mode 100644 index 0000000..8f62054 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/disk2.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_colortag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_colortag.png new file mode 100644 index 0000000..daaa866 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_colortag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_contextmenu.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_contextmenu.png new file mode 100644 index 0000000..7270f23 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_contextmenu.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_filter.png new file mode 100644 index 0000000..562aa75 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_iconview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_iconview.png new file mode 100644 index 0000000..48d347c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_iconview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_infotag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_infotag.png new file mode 100644 index 0000000..1b7c43b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_infotag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_listview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_listview.png new file mode 100644 index 0000000..de4b2e7 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_listview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_maininterface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_maininterface.png new file mode 100644 index 0000000..5c5fb84 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_maininterface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_newdoc.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_newdoc.png new file mode 100644 index 0000000..046b5b0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_newdoc.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_open.png new file mode 100644 index 0000000..fabfd1f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_openinterminal.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_openinterminal.png new file mode 100644 index 0000000..969ede9 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_openinterminal.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_overview.png new file mode 100644 index 0000000..4e391c4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_rename.png new file mode 100644 index 0000000..17c1c50 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_renametag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_renametag.png new file mode 100644 index 0000000..feacbc3 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_renametag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_share.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_share.png new file mode 100644 index 0000000..b26b998 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_share.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_tab.png new file mode 100644 index 0000000..2a3cd93 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_taginfo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_taginfo.png new file mode 100644 index 0000000..667a29a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/e_taginfo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/encrypt.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/encrypt.png new file mode 100644 index 0000000..de87b70 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/encrypt.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_cd_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_cd_interface.png new file mode 100644 index 0000000..b954f94 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_cd_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_cd_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_cd_rename.png new file mode 100644 index 0000000..bbf5e00 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_cd_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_colortag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_colortag.png new file mode 100644 index 0000000..417a6cb Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_colortag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_filter.png new file mode 100644 index 0000000..cd945ee Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_iconview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_iconview.png new file mode 100644 index 0000000..e729536 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_iconview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_infotag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_infotag.png new file mode 100644 index 0000000..12ce5b0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_infotag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_listview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_listview.png new file mode 100644 index 0000000..8f22a68 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_listview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_maininterface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_maininterface.png new file mode 100644 index 0000000..30ec70c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_maininterface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_open.png new file mode 100644 index 0000000..b69bc12 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_overview.png new file mode 100644 index 0000000..08a7ce6 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_rename.png new file mode 100644 index 0000000..2cffb54 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_rename_disk.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_rename_disk.png new file mode 100644 index 0000000..bfbed8a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_rename_disk.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_share.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_share.png new file mode 100644 index 0000000..b26b998 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_share.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_tab.png new file mode 100644 index 0000000..f027ccd Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_taginfo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_taginfo.png new file mode 100644 index 0000000..fd8e032 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eu_taginfo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eye.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eye.png new file mode 100644 index 0000000..3924c40 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/eye.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/finish.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/finish.png new file mode 100644 index 0000000..897c939 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/finish.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_colortag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_colortag.png new file mode 100644 index 0000000..17db6df Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_colortag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_contextmenu.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_contextmenu.png new file mode 100644 index 0000000..5510bd0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_contextmenu.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_filter.png new file mode 100644 index 0000000..562aa75 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_iconview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_iconview.png new file mode 100644 index 0000000..48d347c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_iconview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_infotag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_infotag.png new file mode 100644 index 0000000..1b7c43b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_infotag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_listview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_listview.png new file mode 100644 index 0000000..de4b2e7 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_listview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_maininterface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_maininterface.png new file mode 100644 index 0000000..5c5fb84 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_maininterface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_multi.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_multi.png new file mode 100644 index 0000000..066fe45 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_multi.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_newdoc.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_newdoc.png new file mode 100644 index 0000000..4aa80e7 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_newdoc.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_open.png new file mode 100644 index 0000000..eea5877 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_openinterminal.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_openinterminal.png new file mode 100644 index 0000000..b2ec571 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_openinterminal.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_overview.png new file mode 100644 index 0000000..4e391c4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_rename.png new file mode 100644 index 0000000..17c1c50 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_single.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_single.png new file mode 100644 index 0000000..8699c2c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_single.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_tab.png new file mode 100644 index 0000000..2a3cd93 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_taginfo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_taginfo.png new file mode 100644 index 0000000..7becb52 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/h_taginfo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/hotkey.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/hotkey.png new file mode 100644 index 0000000..6f01a95 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/hotkey.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/info.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/info.png new file mode 100644 index 0000000..c4a4986 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/info.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/multi.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/multi.png new file mode 100644 index 0000000..867f35a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/multi.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/myphone.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/myphone.png new file mode 100644 index 0000000..d2e9acb Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/myphone.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/myphone1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/myphone1.png new file mode 100644 index 0000000..2721684 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/myphone1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_colortag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_colortag.png new file mode 100644 index 0000000..4b907ff Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_colortag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_contextmenu.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_contextmenu.png new file mode 100644 index 0000000..6fe7e21 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_contextmenu.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_filter.png new file mode 100644 index 0000000..621134f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_iconview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_iconview.png new file mode 100644 index 0000000..0e39ea4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_iconview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_infotag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_infotag.png new file mode 100644 index 0000000..5783d38 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_infotag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_listview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_listview.png new file mode 100644 index 0000000..ec22339 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_listview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_main-interface.psd b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_main-interface.psd new file mode 100644 index 0000000..7a7876e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_main-interface.psd differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_maininterface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_maininterface.png new file mode 100644 index 0000000..cf7ed7c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_maininterface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_newdoc.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_newdoc.png new file mode 100644 index 0000000..4aa80e7 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_newdoc.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_open.png new file mode 100644 index 0000000..e3a6c76 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_openinterminal.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_openinterminal.png new file mode 100644 index 0000000..b2ec571 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_openinterminal.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_overview.png new file mode 100644 index 0000000..4b28d95 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_rename.png new file mode 100644 index 0000000..13ddb5e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_rename_disk.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_rename_disk.png new file mode 100644 index 0000000..644f4cf Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_rename_disk.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_tab.png new file mode 100644 index 0000000..ad3468f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_taginfo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_taginfo.png new file mode 100644 index 0000000..179a52b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/p_taginfo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/password.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/password.png new file mode 100644 index 0000000..9b5bf16 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/password.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/permission.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/permission.png new file mode 100644 index 0000000..4adbeff Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/permission.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/phone_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/phone_interface.png new file mode 100644 index 0000000..4b36079 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/phone_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/renametag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/renametag.png new file mode 100644 index 0000000..b11ef1b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/renametag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/right.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/right.png new file mode 100644 index 0000000..df413e8 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/right.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/save.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/save.png new file mode 100644 index 0000000..69fac45 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/save.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/share-copy.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/share-copy.png new file mode 100644 index 0000000..3a3768f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/share-copy.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/share.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/share.png new file mode 100644 index 0000000..b26b998 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/share.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/single.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/single.png new file mode 100644 index 0000000..7ef355e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/single.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/unlock.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/unlock.png new file mode 100644 index 0000000..c3ca5ef Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/unlock.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/videopreview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/videopreview.png new file mode 100644 index 0000000..d45e12d Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/videopreview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/visitshare.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/visitshare.png new file mode 100644 index 0000000..dd8404e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/fig/visitshare.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/i_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/i_file-manager.md new file mode 100644 index 0000000..4ceda24 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/i_file-manager.md @@ -0,0 +1,672 @@ +# File Manager|dde-file-manager| + +## Overview + +File Manager is a powerful, simple and easy-to-use file management tool. It follows the classic function and layout of traditional file manager, and simplifies the user operation and adds many features. The open-and-shut navigation bar, the search box with intelligent identification, a variety of views and sorting let you manage files easily. It's beyond classic, just to give you a better experience! + +![1|overview](fig/eu_overview.png) + +## Guide + +You can run, close and create a shortcut for File Manager by the following ways. + +### Run File Manager + +1. Click ![Launcher](../common/deepin_launcher.svg) on dock to enter Launcher interface. +2. Locate ![FileManager](../common/deepin_file_manager.svg) by scrolling mouse wheel or searching by "File Manager" in Launcher interface. +3. Right-click ![FileManager](../common/deepin_file_manager.svg), you can + - Click **Send to desktop** to create a desktop shortcut. + - Click **Send to dock** to fix the application on dock. + - Click **Add to startup** to add the application to startup, it will automatically run when the system starts up. + + >![tips](../common/tips.svg) Tips: You can also press **Super** + **E** to start File Manager. + +### Exit File Manager + +- On File Manager interface, click ![close](../common/close_icon.svg) to exit. +- Right-click ![FileManager](../common/deepin_file_manager.svg) on Dock, select **Close All** to exit File Manager. +- Click ![Settings](../common/icon_menu.svg) and select **Exit** to exit File Manager. + +### View Shortcut Keys + +On Document Viewer interface, press **Ctrl + Shift + /** to view all shortcut keys quickly, which helps you to use them skillfully and improves your working efficiency. + +![1|hotkey](fig/hotkey.png) + +## Main Interface + +On File Manager interface, you can execute many operations with the functional bars. It is designed to be easy-to-use, user-friendly and efficient improving. + +![1|maininterface](fig/eu_maininterface.png) + +| No. | Name | Description | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | Left panel | Click icons in left panel to quickly visit local files, disks, computers in LAN, bookmarks and tags. | +| 2 | Address bar | You can quickly switch visiting history, switch among directory levels, search and input address in address bar. | +| 3 | View | Click ![icon_view](../common/icon_view.svg) and ![list_view](../common/list_view.svg) to switch view modes. | +| 4 | Info column | Click ![fileinfo](../common/fileinfo.svg) to view basic information and tags of files(folders). | +| 5 | Main menu | You can create new window, switch themes, set share password, make settings, view manual and application information, and exit the application in Main menu. | +| 6 | Status bar | You can view the number of files or selected files. | + + +> ![tips](../common/tips.svg) Tips: you can drag the dividing line on the right of left panel to change its width. + + +## Basic Functions + +File Manager is featured with the basic functions as a file manager, you can easily create, copy, rename or delete files/folders with it. + +### New Document/Folder + + +#### New Document + +1. On File Manager interface, right-click and select **New document**. +2. In the pop-up menu, select the document format you want to create. +3. Input a name for the new document, and press **Enter**, or click at blank area. + +![0|newdoc](fig/e_newdoc.png) + +#### New Folder + +1. On File Manager interface, right-click and select **New folder**. +2. Input a name for the new folder, and press **Enter**, or click at blank area. + +### Rename File/Folder + +1. Select the file/folder, right-click to select **Rename**. +2. Input a new name for the file/folder, and press **Enter**, or click at any blank area. + +![0|rename](fig/e_contextmenu.png) + +> ![tips](../common/tips.svg) Tips: Check "Hide file extension when rename" in **Settings** to rename file more conveniently. + +### Batch Rename + +1. On File Manager interface, select multiple files. +2. Right-click and select **Rename**. + - **Replace Text**: Input the content to be replaced in Find box, and input content to rename in Replace box. + - **Add Text**: Input the content to add in Add box, and select the location. + - **Custom Text**: Input the file name and SN. +3. Click **Rename** to finish operation. + +![1|batch_rename](fig/eu_rename.png) + +### View Files + +Click ![icon_view](../common/icon_view.svg) and ![list_view](../common/list_view.svg) on the interface to switch icon view and list view. + +- Icon view: displaying filenames, icons or thumbnails. + +![1|iconview](fig/eu_iconview.png) + +- List view: displaying file icons or thumbnails, names, time modified, sizes, types and etc in a list. + +![1|listview](fig/eu_listview.png) + +> ![tips](../common/tips.svg) Tips: +> +> - In list view, place the cursor on the dividing line between any two columns and drag it to change the width of the current column. Double-click the dividing line to adjust to the biggest width of the current column automatically. +> - Press **Ctrl**+**1** or **Ctrl**+ **2** to switch icon view and list view. + +### Sorting + +1. Right-click in the blank area on File Manager, select **Sort by**. +2. Choose among the sorting options, which include **Name**, **Time modified**, **Size** and **Type**. + +> ![tips](../common/tips.svg) Tips: you can click the head of the columns in the list view to change the sort order. + + +### Open Files + +1. On File Manager, right-click the file you want to open. +2. In the context menu, select **Open with**>**Select default program**. +3. Select the application you want to open the file in the list. + +> ![notes](../common/notes.svg) Notes: It will use the default application to open the file when you double-click it. You can right-click multiple files of the same type, and select **Open with** to open them at a time. + +![0|open_with](fig/eu_open.png) + + + +### Hide Files + +1. On File Manager, right-click the file you want to hide. +2. Select **Properties**, check **Hide this file**. + +### Copy File/Folder + +1. Select the files/folders to be copied, right-click and select **Copy**. +2. Enter the directory to which the files/folders will be pasted, right-click and select **Paste**. + +### Compress File/Folder + +1. Select the files/folders to be compressed, right-click and select **Compress**. +2. Input a file name and select a file format for the to be compressed file. +3. Select a location to store it. +4. Select **Compress** to generate the compressed file. + +> ![notes](../common/notes.svg) Notes: Switch on **Advanced Options** to set password and split volumes sizes. **Encrypt the archive** and **Split to volumes** are only applicable for some formats. + +### Delete File/Folder + +Right-click file/folder to select **Delete**. + - You can find the deleted files in Trash. Right-click files in Trash, you can choose **Restore** or **Delete**. + - The shortcut of the deleted files will become invalid. + +> ![attention](../common/attention.svg) Attention: File/folder in external device will be permanently deleted and can not be restored when you select **Delete**. + +### Undo Operation +In file manager, use **Ctrl + Z** to undo the previous steps, including: +- Delete the newly created file/folder. +- Resume the renamed file/folder to the previous name. +- Restore the deleted file/folder from trash. +- Restore the moved (via dragging or cutting) file/folder to the previous location. +- Delete the copied and pasted file/folder. + +> ![attention](../common/attention.svg) Attention: It can undo two continuous steps at most. If there is file overwriting or permanently file deleting, then you can only return to that step. + + + +### File/Folder Properties + +In Properties of files, you can view the basic info, open with list, and permissions. In properties of folders, you can see basic info, sharing info, and permissions. + +1. On File Manager interface, right-click a file. +2. Select **Properties**. + +![0|info](fig/info.png) + + +> ![notes](../common/notes.svg) Notes: If you check the properties of multiple files at a time, the total size and quantities will be displayed. If you check the properties of a shortcut, the source file location will be displayed in addition. You can use shortcuts **Ctrl + I** to view the properties as well. + +## Common Operations + +File Manager is featured with many useful functions, which are all designed to ease the commonly used operations. + +### Switch Address Bar + +There are three sections in address bar, namely back/forward buttons, breadcrumb bar, and directory/search bar. By default, breadcrumb bar is displayed in the address bar. + +![0|addressbar](fig/addressbar1.png) + +- Clicking back/forward buttons to quickly view the previous address or the next address. +- Each level of the location of a file will form a breadcrumb. You can switch quickly among levels by clicking all breadcrumbs. + +By clicking the search icon, or right-click the file path and select **Edit address**, the address bar will be switched into inputting box. By clicking out of the inputting box, the address bar will restore to breadcrumbs automatically. + +![0|addressbar](fig/addressbar2.png) + +- The inputting box can identify smartly. You can input keywords or an address and press **Enter**, the system will identify automatically and search or visit. + +### Search Files + +Click the search button or press **Ctrl + F** to switch to the search bar. Or, input the keywords and press **Enter**, the search results will be shown in the window. + +- If you need to search in a specified directory, please enter it before search. + +> ![notes](../common/notes.svg) Notes: In **Settings**, check "Auto index internal disk" and "Index external storage device after connected to computer" to quicken the searching speed. + +#### Full-Text Search + +You can search a file by keywords in its content. +1. In File Manager, click ![icon_menu](../common/icon_menu.svg) > **Settings**. +2. Check **Full-Text search** under **Index** of **Advanced**. +3. Press **Ctrl + F** or click the searching button in the address bar to start searching. Enter the keywords and press **Enter**. + +#### Advanced Search + +When there are many files and the search is slow, you can enable advanced search to narrow the search scope and improve the search efficiency. + +1. In search bar, input the keywords and press **Enter**. When the results appear, you will see ![filter](../common/filter.svg) icon, you can click it to do advanced search. +2. Select the searching range, file type and size, and modified time, accessed time and created time to narrow the search results. + +![0|filter](fig/eu_filter.png) + + +### Recent Files +By default, there is a **Recent** entry on left panel. Click it to view the recently used files. Files are sorted by default in reverse order of access time. + +> ![notes](../common/notes.svg) Notes: If you want to hide "Recent", you can uncheck "Display recent file entry in left panel" in Settings > Basic > Hidden files. To hide the access record of a specific file, right-click the file and select **Remove** which will not delete the file. + +### Manage Tabs + +File Manager supports multi-tab view. + +1. On File Manager, right-click the folder. +2. In the pop-up context menu, select **Open in new tab**. +3. When the window has multi-tabs, you can: + - Click + in tab bar to add a new tab. + - Click × on the tab to close it. + - Place the cursor on the tab, middle-click to close it. + +![1|tab](fig/eu_tab.png) + +> ![tips](../common/tips.svg) Tips: When the File Manager has only one tab, the tab bar is hidden, you can press **Ctrl + T** to add a new tab. + +### Manage Bookmarks + +To quickly visit a folder from the left panel, you can add bookmarks for frequently used folders. + +- Add Bookmarks: On File Manager, right-click the folder, in the pop-up context menu, select **Add to bookmark**. + +- Move Bookmarks: you can move bookmarks within the bookmark area. Drag and drop the bookmark to the designated location. + +- Delete Bookmarks: you can delete bookmarks by right-clicking the bookmark and select **Remove**, or right-clicking the bookmarked folder and select **Remove bookmark**. + +### Manage Tags + +By adding tags on file/folder, you can classify and manage your files better. + +> ![notes](../common/notes.svg) Notes: currently only x86 platform supports **Tag information**. All contents related to "Tag information" in this manual are only applicable for x86 platform. + +#### Add Tags + +You can add tag to multiple files/folders at a time, or add multiple tags to a single file/folder; you can also add tags in Properties of the file/folder. The tag appears in the left panel. + +##### By Tag Information + +1. Right-click a file/folder, select **Tag information**. +2. Input tag info. Use comma to separate tags in case of multiple tags. +3. Click any blank area to finish adding tag. + +> ![notes](../common/notes.svg) Notes: The tag color is randomly assigned from eight default colors. + + +![1|taginfo](fig/eu_taginfo.png) + + +##### By Color Tag + +Right-click a file/folder, select a "color button" to create a color tag directly. + +![1|colortag](fig/eu_colortag.png) + +##### By Information Column on the Right Side + +Select a file/folder, click ![fileinfo](../common/fileinfo.svg), and add tags in the information column on the right side. + +![1|infotag](fig/eu_infotag.png) + + + +> ![notes](../common/notes.svg) Notes: If a file has a tag, copy or cut and then paste it, the new file still has the same tag. + +#### Rename Tag + +Right-click a tag in the left panel, select **Rename** to modify the current tag. + +![1|renametag](fig/renametag.png) + +#### Change Tag Color + +Right-click a tag in the left panel, select a "Color button" to change the current tag color. + +#### Change Tag Order + +Drag and drop the tag upwards or downwards to change its order. + +#### Delete Tag +Right-click a tag in left panel, select **Remove** to delete the tag. + + + +### Preview Files + +File Manager supports file preview by pressing space bar. Select a file and press the space bar on the keyboard to quickly preview it. In the preview window, you can view the file info, including image resolution, document size, text content. It also supports gif format, audio and video playback. + +#### Preview Video + +1. Select a video and press the space bar to start video preview. +2. Click in the preview window to pause video playing. +3. Drag the progress bar to play forward or backward. +4. Click **Open** at the bottom to open the video by default program. + +![1|videopreview](fig/videopreview.png) + +>![notes](../common/notes.svg) Notes: You can select multiple files and press space bar to preview them at a time. + +### Permission Management +In file/folder properties, click **Permissions** to set **Owner**, **Group** and **Others**. + +![0|permission](fig/permission.png) + +### My Shares + +You can share folders in File Manager, if there are some folders shared, the share icon will show on the left panel, if not, the share icon will be removed. + +#### Share Local Files + +1. On File Manager interface, right-click a folder, select **Share folder**. +2. In the properties window, check **Share this folder**. +3. Input **Share name**, and choose **Permission**, and **Anonymous** according to actual needs before closing the window. +5. To set share password, click ![menu](../common/icon_menu.svg) and select **Set share password**. +5. Input password and click **Confirm**. + +![0|share](fig/share.png) + +> ![tips](../common/tips.svg) Tips: You can cancel sharing by unchecking **Share this folder**, or right-click the folder and select **Cancel sharing**. + +#### Visit Sharing Folders + +You can find sharing folders of other users in the same LAN in **Computers in LAN**. You can also visit sharing folders via smb. + + + +1. On File Manager interface, click ![icon_menu](../common/icon_menu.svg) > **Connect to Server**, input the sharing address of the LAN user, e.g. smb://xx.x.xx.xxx (usually it should be an IP address), click **Connect**. Or, input the server's address in the address bar directly and press **Enter**. +2. Double-click the shared document you need to visit, input the username and password in the pop-up dialogue box. + - Unencrypted folders can be visited by anonymous access without inputting username and password. + - When you visit encrypted folders, a window pops up and you will have to input user name and password before visiting. If you check **Remember password**, you don't have to input password when you visit the folder next time. + - Username: i.e. the name used by the sharer when logging in the system. + - Password: i.e. the sharing password set when the sharer shares the folder. +3. Click **Connect**. + +![1|viewshare](fig/visitshare.png) + + + +### Open in Terminal + +1. Right-click in the blank area on File Manager. +2. Select **Open in terminal**, Terminal will be opened, and its directory will be the current one. + +![0|openinterminal](fig/e_openinterminal.png) + +### Burn CD + +You can copy music, video, pictures, or mirror files to a CD or DVD through the burning feature. Please prepare a recorder and a CD or DVD in advance. + + +1. Insert the disc into the recording drive. + +2. Open File Manager and click the CD Icon in the left panel to enter the burning interface. + +![cd](fig/eu_cd_interface.png) + +3. Right click the file (folder) and select **Add to disc** or drag the file (folder) directly to the burning interface. + +4. In the burning interface, click **Burn** in the upper right corner. + +>![notes](../common/notes.svg) Notes: if you want to delete a file/folder from the burning list, right-click it and select **Delete** to remove it from the list. + +5. A dialog box pops up. Input the disc name. You can also enter the **Advanced settings** interface, set the file system and write speed, or check "Allow files to be added later", "Verify data" and so on, and click **Burn**. + +![cd](fig/eu_cd_rename.png) + +6. After burning, a prompt box will pop up in the interface, and click **OK**. + +>![notes](../common/notes.svg) Notes: +> - The ISO9660 file system supports all CD and DVD formats, while the UDF file system only supports some CD formats. +> - If you need to erase the disc data, you can right-click the disc icon in the left panel and select **Unmount**, right-click the disc icon again and select **Erase**. + +### Create Link + +1. On File Manager interface, right-click the item to create a link for. +2. Select **Create link**. +3. In the pop-up window, select a location and input the name of the link. +4. Click **Save** to finish creating the link. + +> ![tips](../common/tips.svg) Tips: By selecting **Send to desktop** for an item, you can create a link on desktop with one click. + +### Send to Other Device + +When there is an external device inserted, you can directly send file/folder to it. + +1. On File Manager interface, select a file/folder. +2. Right-click and select **Send to**. +3. Select the device you want to send to. +4. File/folder will be copied to the device. + +## Add Corner Marker to Files/Folders + +You can assign an icon file to a file or folder icon through the command line and display it as a corner marker. +>![notes](../common/notes.svg) Notes: +>- The corner marker files support formats such as svg, jpg, png, bmp, and gif, but not bigger than 100KB. +>- The corner marker could not be added to files in USB disks and CD-ROM disks. + +### Add Single Corner Marker + +1. Open Terminal, input **gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path)"**, which means to add a corner marker in the lower right corner of the file/folder icon by default. + +>![attention](../common/attention.svg) Attention: the special corner markers defined by the system could not be replaced. + +2. You can add position codes into the above command to add a corner marker to the upper left corner(lu), lower left corner(ld), upper right corner(ru) or lower right corner(rd). +For example, to add a corner marker to the upper left corner, you have to input: +**gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path);lu"** + +![mark](fig/single.png) + +### Add Multiple Corner Markers + +To add 2~4 corner markers to a file/folder, you can input "|" in the command to separate multiple paths of the corner marker files. Only one corner marker can be added to the same corner, but you can replace it. + +For example, to add 4 corner markers to a file/folder icon, you can input: +**gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path);lu|xxx(icon path);ld|xxx(icon path);ru|xxx(icon path);rd"** + +![mark](fig/multi.png) + +### Cancel Corner Markers + +Open Terminal, input **gio set xxx(file path) -t stringv metadata::emblems ""** to cancel all corner markers on the file/folder icon. + +## File Vault + +File Vault is designed to create a special safe space for you and protect your privacy. With the advanced encryption technology and convenient operations, it's quite easy to use. + +### Set Vault Password + +You will have to set a password when you use File Vault for the first time as follows: + +1. Click ![file_vault](../common/file_vault.svg) in the left panel or double-click **My Vault** in the **Computer** interface, and then click **Create** in the pop-up dialogue box. +2. Set the "Method", "Password", "Repeat password" and "Hint", click **Next**. + +![0|password](fig/password.png) + +> ![notes](../common/notes.svg) Notes: the password must contain upper case letters, lower case letters, Arabic numbers and special symbols at the same time and no less than 8 digits. Otherwise, you are not able to go to the next step. + +3. A key/QR code is generated. It is recommended to save it in case you forget it. Click **Next**. +4. Click **Encrypt**; enter your login password in the pop-up authentication box and click **Confirm**. + + ![encrypt](fig/encrypt.png) + +5. Click **OK** when encryption finishes. +6. You can now save your files in File Vault. + + + +### Lock File Vault + +After you put files into File Vault, right-click![file_vault](../common/file_vault.svg) in the left panel or right-click **My Vault** in the **Computer** interface. + +- Select **Lock** to lock File Vault. +- Select **Auto lock** and select in the sub-menu: + + Select "Never", which means the file vault remains unlock until the screen is locked or the computer is shutdown. + + Select "5 minutes", "10 minutes" or "20 minutes", which means File Vault will be locked automatically in corresponding time. + +![0|right](fig/right.png) + + + +### Unlock File Vault + +Right-click![file_vault](../common/file_vault.svg) or **My Vault** in the **Computer** interface. + +- Select **Unlock**, input password in the pop-up dialogue box and click **Unlock**. +- Select **Unlock by key**, input the 32-digit recovery key in the pop-up dialogue box and click **Unlock**. + +> ![tips](../common/tips.svg) Tips: You can click ![file_vault](../common/file_vault.svg) in the left panel or double-click **My Vault** in the **Computer** interface and input password. + +### Delete File Vault + +You can delete a vault only after unlocking it. + +1. Right-click ![file_vault](../common/file_vault.svg) in the left panel or right-click **My Vault** in the **Computer** interface and select **Remove File Vault**. +2. Input file vault password in the pop-up dialogue box and click **Remove**. +3. Input your login password in the pop-up dialogue box and click **Confirm** to finish this operation. + +> ![attention](../common/attention.svg) Attention: Files inside the vault would be deleted as you remove the file vault. Please backup them before you remove the file vault if needed. + +## Disk Management + +On File Manager interface, you can manage local and external disks. + +Local disks are displayed in the left panel of File Manager. When you mount any external disks or insert other mobile storage devices, the corresponding icons will be displayed in the left panel. + + + + + + + + + + + + + + + + + +
Local disksAll disks of local harddisk divisions
External disksIncluding mobile hard disks, CDs/DVDs and USB flash disks.
Mobile devicesIncluding mobile phone storage, storage cards, SD cards and so on.
+ +> ![notes](../common/notes.svg) Notes: If disks or folders in the disk are encrypted, you will have to input password before visiting them. + +### Local Disks + +#### Hide Local Disks + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Check **Hide system disk** under **Advanced** > **Other**. + + +#### Rename Local Disks + +1. Right-click a local disk in the left panel or in the computer interface. +2. Select **Rename**. +3. Input the new name and press **Enter** or click any blank area to save the modification. + +> ![tips](../common/tips.svg) Tips: In the computer interface, double click any local disk slowly, after the editing box appears, you can rename it directly. + +![0|disk](fig/eu_rename_disk.png) + +### External Disks + +#### Eject External Disks + +1. In the left panel of File Manager, right-click the disk you want to remove. + +2. Select **Safely Remove**. + +3. The disk will be removed from the disk list, and so will all partition of it . + + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) Tips: you can also select **Eject** or click ![unmount](../common/unmount_normal.svg) in the left panel to unmount the disk. + +#### Rename External Disks + +1. In the left panel or on computer interface, right-click the disk you want to rename. +2. Select **Unmount** and then select **Rename**. +3. Input the new name and press **Enter** or click any blank area to save the modification. + +#### Format External Disks + +1. In the left panel of File Manager, right-click the disk to format. + +2. Select **Unmount** and then select **Format**. + +3. In the pop-up window, choose the type and volume label for the disk. + +4. Click **Format**. + + ![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) Notes: If you check **Quick Format**, the disk can be formatted quickly in a few seconds, but the data could be restored by file recovery tools. If you don't want these data to be restored, you can uncheck this option box and format the disk. + + +## Main Menu + +You can create new window, switch themes, connect to server, set share password (see [Share Local Files](#Share Local Files)), make settings, view manual and version information in Main Menu. + + +### New Window + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Select **New window** to open a new window. + +### Connect to Server + +You can [visit sharing folders](#Visit Sharing Folders) by connecting to server. + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Select **Connect to Server**, input server's IP address (XX.XX.XX.XX) in the editing box. + - Click ![+](../common/+.svg) to add the address into **My Favorites**. + - Select an address from **My Favorites** and click ![-](../common/-.svg) to delete in from **My Favorites**. +3. Click **Connect**. + +![connect](fig/connecttoserver.png) + + + +### Settings + +#### Basic + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Select **Basic**. + - You can check **Always open folder in new window** + - You can set whether to open folder by one click or double click. + - You can select a directory under **Open from default window** or **Open in new tab**. + - You can set up the icon size. + - You can set the **Default View** as icon view or list view. + - Check **Show hidden files** to show all hidden files. + - Check **Hide file extension when rename**, so the extension would not be displayed when renaming. + - Check **Display recent file entry in left panel**, then the recently visited file would be displayed in left panel. + + +#### Advanced + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Select **Advanced**. + - You can check **Auto index internal disk**, when you search files, the files in internal disks would be searched. + - You can check **Index external storage device after connected to computer**, In **Index**, when you search files, the files in the external disks would be searched as well. + - You can check **Full-Text search** to search by content. + - You can select which types of files can be previewed. + - You can check **Auto mount**, when any external disks connect to the computer, they would be mounted automatically. + - You can check **Open after auto mount**, when any external disks connect to the computer, they would be mounted automatically and opened. + - You can check **Use the file chooser dialog of File Manager**, when selecting files, File Manager window would be opened. + - You can check **Ask for my confirmation when deleting files**, when deleting files, a hint dialog would pop up. + - You can check **Hide system disk**, local disks would not be displayed in left panel and computer interface. + - You can check **Show file system on disk icon**. + + + +### Theme + +The window theme includes Light Theme, Dark Theme and System Theme. + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Theme** to select one. + + + +### Help + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Help** to view the manual. + + + +### About + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **About** to view version information and introduction about File Manager. + + + +### Exit + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Exit**. diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/p_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/p_file-manager.md new file mode 100644 index 0000000..c8518f1 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/en_US/p_file-manager.md @@ -0,0 +1,824 @@ +# File Manager|dde-file-manager| + +## Overview + +File Manager is a powerful, simple and easy-to-use file management tool. It follows the classic function and layout of traditional file manager, and simplifies the user operation and adds many features. The open-and-shut navigation bar, the search box with intelligent identification, a variety of views and sorting let you manage files easily. + +![1|overview](fig/p_overview.png) + +## Guide + +You can run, close and create a shortcut for File Manager by the following ways. + +### Run File Manager + +1. Click ![Launcher](../common/deepin_launcher.svg) on dock to enter Launcher interface. +2. Locate ![FileManager](../common/deepin_file_manager.svg) by scrolling mouse wheel or searching by "File Manager" in Launcher interface. +3. Right-click ![FileManager](../common/deepin_file_manager.svg), you can + - Click **Send to desktop** to create a desktop shortcut. + - Click **Send to dock** to fix the application on dock. + - Click **Add to startup** to add the application to startup, it will automatically run when the system starts up. + + >![tips](../common/tips.svg) Tips: You can also press **Super** + **E** to start File Manager. + +### Exit File Manager + +- On File Manager interface, click ![close](../common/close_icon.svg) to exit. +- Right-click ![FileManager](../common/deepin_file_manager.svg) on Dock, select **Close All** to exit File Manager. +- Click ![Settings](../common/icon_menu.svg) and select **Exit** to exit File Manager. + +### View Shortcut Keys + +On Document Viewer interface, press **Ctrl + Shift + /** to view all shortcut keys quickly, which helps you to use them skillfully and improves your working efficiency. + +![1|hotkey](fig/hotkey.png) + +## Main Interface + +On File Manager interface, you can execute many operations with the functional bars. It is designed to be easy-to-use, user-friendly and efficient improving. + +![1|maininterface](fig/p_maininterface.png) + +| No. | Name | Description | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | Left panel | Click icons in left panel to quickly visit local files, disks, computers in LAN, bookmarks and tags. | +| 2 | Address bar | You can quickly switch visiting history, switch among directory levels, search and input address in address bar. | +| 3 | View | Click ![icon_view](../common/icon_view.svg) and ![list_view](../common/list_view.svg) to switch view modes. | +| 4 | Info column | Click ![fileinfo](../common/fileinfo.svg) to view basic information and tags of files(folders). | +| 5 | Main menu | You can create new window, switch themes, set share password, make settings, view manual and application information, and exit the application in Main menu. | +| 6 | Status bar | You can view the number of files or selected files. | + + +> ![tips](../common/tips.svg) Tips: you can drag the dividing line on the right of left panel to change its width. + + +## Basic Functions + +File Manager is featured with the basic functions as a file manager, you can easily create, copy, rename or delete files/folders with it. + +### New Document/Folder + + +#### New Document + +1. On File Manager interface, right-click and select **New document**. +2. In the pop-up menu, select the document format you want to create. +3. Input a name for the new document, and press **Enter**, or click at blank area. + +![0|newdoc](fig/p_newdoc.png) + +#### New Folder + +1. On File Manager interface, right-click and select **New folder**. +2. Input a name for the new folder, and press **Enter**, or click at blank area. + +### Rename File/Folder + +1. Select the file/folder, right-click to select **Rename**. +2. Input a new name for the file/folder, and press **Enter**, or click at any blank area. + +![0|rename](fig/p_contextmenu.png) + +> ![tips](../common/tips.svg) Tips: Check "Hide file extension when rename" in **Settings** to rename file more conveniently. + +### Batch Rename + +1. On File Manager interface, select multiple files. +2. Right-click and select **Rename**. + - **Replace Text**: Input the content to be replaced in Find box, and input content to rename in Replace box. + - **Add Text**: Input the content to add in Add box, and select the location. + - **Custom Text**: Input the file name and SN. +3. Click **Rename** to finish operation. + +![1|batch_rename](fig/p_rename.png) + +### View Files + +Click ![icon_view](../common/icon_view.svg) and ![list_view](../common/list_view.svg) on the interface to switch icon view and list view. + +- Icon view: displaying filenames, icons or thumbnails. + +![1|iconview](fig/p_iconview.png) + +- List view: displaying file icons or thumbnails, names, time modified, sizes, types and etc in a list. + +![1|listview](fig/p_listview.png) + +> ![tips](../common/tips.svg) Tips: +> +> - In list view, place the cursor on the dividing line between any two columns and drag it to change the width of the current column. Double-click the dividing line to adjust to the biggest width of the current column automatically. +> - Press **Ctrl**+**1** or **Ctrl**+ **2** to switch icon view and list view. + +### Sorting + +1. Right-click in the blank area on File Manager, select **Sort by**. +2. Choose among the sorting options, which include **Name**, **Time modified**, **Size** and **Type**. + +> ![tips](../common/tips.svg) Tips: you can click the head of the columns in the list view to change the sort order. + + +### Open Files + +1. On File Manager, right-click the file you want to open. +2. In the context menu, select **Open with**>**Select default program**. +3. Select the application you want to open the file in the list. + +> ![notes](../common/notes.svg) Notes: It will use the default application to open the file when you double-click it. You can right-click multiple files of the same type, and select **Open with** to open them at a time. + +![0|open_with](fig/p_open.png) + + + +### Hide Files + +1. On File Manager, right-click the file you want to hide. +2. Select **Properties**, check **Hide this file**. + +### Copy File/Folder + +1. Select the files/folders to be copied, right-click and select **Copy**. +2. Enter the directory to which the files/folders will be pasted, right-click and select **Paste**. + +### Compress File/Folder + +1. Select the files/folders to be compressed, right-click and select **Compress**. +2. Compress interface of Archive Manager pops up. Set the format, name, storage location and so on, click **Compress**. + +> ![tips](../common/tips.svg) Tips: you can also select **Add to xxx.7z** or **Add to xxx.zip** in the context menu to compress file (folders) quick. + +### Delete File/Folder + +Right-click file/folder to select **Delete**. + - You can find the deleted files in Trash. Right-click files in Trash, you can choose **Restore** or **Delete**. + - The shortcut of the deleted files will become invalid. + +> ![attention](../common/attention.svg) Attention: File/folder in external device will be permanently deleted and can not be restored when you select **Delete**. + +### Undo Operation +In file manager, use **Ctrl + Z** to undo the previous steps, including: +- Delete the newly created file/folder. +- Resume the renamed file/folder to the previous name. +- Restore the deleted file/folder from trash. +- Restore the moved (via dragging or cutting) file/folder to the previous location. +- Delete the copied and pasted file/folder. + +> ![attention](../common/attention.svg) Attention: It can undo two continuous steps at most. If there is file overwriting or permanently file deleting, then you can only return to that step. + + + +### File/Folder Properties + +In Properties of files, you can view the basic info, open with list, and permissions. In properties of folders, you can see basic info, sharing info, and permissions. + +1. On File Manager interface, right-click a file. +2. Select **Properties**. + +![0|info](fig/info.png) + + +> ![notes](../common/notes.svg) Notes: If you check the properties of multiple files at a time, the total size and quantities will be displayed. If you check the properties of a shortcut, the source file location will be displayed in addition. You can use shortcuts **Ctrl + I** to view the properties as well. + +### Virus Scan + +1. On File Manager interface, right-click a file(folder). +2. Select **Virus scan**, the **Virus Scan** interface of Security Center pops up, so you can scan the file(folder) for virus. Refer to [Virus Scan](dman:///deepin-defender#Virus Scan) of Security Center for detailed operations. + + >![notes](../common/notes.svg) Notes: + >- If there is a scanning task in Security Center currently, click **View** in the pop-up dialog box to enter the virus scanning interface of Security Center. + >- **Add "Virus scan" to the context menu** is enabled by default in Security Center. You can also enter Security Center setting interface and uncheck this function. After unchecking, "Virus Scan" will not be displayed in the context menu. + + + +## Common Operations + +File Manager is featured with many useful functions, which are all designed to ease the commonly used operations. + +### Switch Address Bar + +There are three sections in address bar, namely back/forward buttons, breadcrumb bar, and directory/search bar. By default, breadcrumb bar is displayed in the address bar. + +![0|addressbar](fig/addressbar1.png) + +- Clicking back/forward buttons to quickly view the previous address or the next address. +- Each level of the location of a file will form a breadcrumb. You can switch quickly among levels by clicking all breadcrumbs. + +By clicking the search icon, or right-click the file path and select **Edit address**, the address bar will be switched into inputting box. By clicking out of the inputting box, the address bar will restore to breadcrumbs automatically. + +![0|addressbar](fig/addressbar2.png) + +- The inputting box can identify smartly. You can input keywords or an address and press **Enter**, the system will identify automatically and search or visit. + +### Search Files + +File Manager supports multiple search methods, including both general search by file name and file content, and advanced search by file type, creation time, and so on, which is helpful to improve efficiency and facilitate file management. + +- If you need to search in a specified directory, please enter it before search. + +> ![notes](../common/notes.svg) Notes: In **Settings**, check "Auto index internal disk" and "Index external storage device after connected to computer" to quicken the searching speed. + +#### Full-Text Search + +You can search a file by keywords in its content. +1. In File Manager, click ![icon_menu](../common/icon_menu.svg) > **Settings**. +2. Check **Full-Text search** under **Index** of **Advanced**. +3. Press **Ctrl + F** or click the searching button in the address bar to start searching. Enter the keywords and press **Enter**. + +#### Advanced Search + +When there are many files and the search is slow, you can enable advanced search to narrow the search scope and improve the search efficiency. + +1. In search bar, input the keywords and press **Enter**. When the results appear, you will see ![filter](../common/filter.svg) icon, you can click it to do advanced search. +2. Select the searching range, file type and size, and modified time, accessed time and created time to narrow the search results. + +![0|filter](fig/p_filter.png) + + +### Recent Files +By default, there is a **Recent** entry on left panel. Click it to view the recently used files. Files are sorted by default in reverse order of access time. + +> ![notes](../common/notes.svg) Notes: If you want to hide "Recent", you can uncheck "Display recent file entry in left panel" in Settings > Basic > Hidden files. To hide the access record of a specific file, right-click the file and select **Remove** which will not delete the file. + +### Manage Tabs + +File Manager supports multi-tab view. + +1. On File Manager, right-click the folder. +2. In the pop-up context menu, select **Open in new tab**. +3. When the window has multi-tabs, you can: + - Click + in tab bar to add a new tab. + - Place the cursor onto the tab, click × on the tab or middle-click to close it. + +![1|tab](fig/p_tab.png) + +> ![tips](../common/tips.svg) Tips: When the File Manager has only one tab, the tab bar is hidden, you can press **Ctrl + T** to add a new tab. + +### Manage Bookmarks + +To quickly visit a folder from the left panel, you can add bookmarks for frequently used folders. + +- Add Bookmarks: On File Manager, right-click the folder, in the pop-up context menu, select **Add to bookmark**. + +- Move Bookmarks: you can move bookmarks within the bookmark area. Drag and drop the bookmark to the designated location. + +- Delete Bookmarks: you can delete bookmarks by right-clicking the bookmark and select **Remove**, or right-clicking the bookmarked folder and select **Remove bookmark**. + +### Manage Tags + +By adding tags on file/folder, you can classify and manage your files better. + +> ![notes](../common/notes.svg) Notes: currently only x86 platform supports **Tag information**. + +#### Add Tags + +You can add tag to multiple files/folders at a time, or add multiple tags to a single file/folder. The tag appears in the left panel. + +##### By Tag Information + +1. Right-click a file/folder, select **Tag information**. +2. Input tag name. Use comma to separate tags in case of multiple tags. +3. Click any blank area to finish adding tag. + +> ![notes](../common/notes.svg) Notes: The tag color is randomly assigned from eight default colors. + + +![1|taginfo](fig/p_taginfo.png) + + +##### By Color Tag + +Right-click a file/folder, select a "color button" to create a color tag directly. + +![1|colortag](fig/p_colortag.png) + +##### By Information Column on the Right Side + +Select a file/folder, click ![fileinfo](../common/fileinfo.svg), and add tags in the information column on the right side. + +![1|infotag](fig/p_infotag.png) + + + +> ![notes](../common/notes.svg) Notes: If a file has a tag, copy or cut and then paste it, the new file still has the same tag. + +#### Rename Tag + +Right-click a tag in the left panel, select **Rename** to modify the current tag. + +![1|renametag](fig/renametag.png) + +#### Change Tag Color + +Right-click a tag in the left panel, select a "Color button" to change the current tag color. + +#### Change Tag Order + +Drag and drop the tag upwards or downwards to change its order. + +#### Delete Tag +Right-click a tag in left panel, select **Remove** to delete the tag. + + + +### Preview Files + +File Manager supports file preview by pressing space bar. Select a file and press the space bar on the keyboard to quickly preview it. In the preview window, you can view the file info, including image resolution, document size, text content. It also supports gif format, audio and video playback. + +#### Preview Video + +1. Select a video and press the space bar to start video preview. +2. Click in the preview window to pause video playing. +3. Drag the progress bar to play forward or backward. +4. Click **Open** at the bottom to open the video by default program. + +![1|videopreview](fig/videopreview.png) + +>![notes](../common/notes.svg) Notes: You can select multiple files and press space bar to preview them at a time. + +### Permission Management +In file/folder properties, click **Permissions** to set **Owner**, **Group** and **Others**. + +![0|permission](fig/permission.png) + +### My Shares + +You can share folders in File Manager, if there are some folders shared, the share icon will show on the left panel, if not, the share icon will be removed. + +#### Share Local Files + +1. On File Manager interface, right-click a folder, select **Share folder**. +2. In the properties window, check **Share this folder**. + +>![notes](../common/notes.svg) Notes: If smb service is not turned on, authentication window pops up. Input password to turn smb on. + +3. Input **Share name**, and choose **Permission**, and **Anonymous** according to actual needs before closing the window. +4. To set share password, click ![menu](../common/icon_menu.svg) and select **Set share password**. +5. Input password and click **Confirm**. + +![0|share](fig/share.png) + +> ![tips](../common/tips.svg) Tips: You can cancel sharing by unchecking **Share this folder**, or right-click the folder and select **Cancel sharing**. + +#### Visit Sharing Folders + +You can find sharing folders of other users in the same LAN in **Computers in LAN**. You can also visit sharing folders via smb. + +1. On File Manager interface, click ![icon_menu](../common/icon_menu.svg) > **Connect to Server**, input the server address, e.g. smb://xx.x.xx.xxx (usually it should be an IP address), click **Connect**. Or, input the server's address in the address bar directly and press **Enter**. +2. Double-click the shared document you need to visit, input the username and password in the pop-up window. + - Unencrypted folders can be visited by anonymous access without inputting username and password. + - When you visit encrypted folders, a window pops up and you will have to input user name and password before visiting. If you check **Remember password**, you don't have to input password when you visit the folder next time. + - Username: i.e. the name used by the sharer when logging in the system. + - Password: i.e. the sharing password set when the sharer shares the folder. +3. Click **Connect**. + +![1|viewshare](fig/visitshare.png) + + + +### Open as Admin + +Prerequisite: Please enable **Developer Mode** from Control Center > General Settings. + +1. Right-click in the blank area on File Manager. +2. Select **Open as admin**, input your login password in the pop-up window and click **Confirm**. +3. The file will be opened in a new window, in which you can operate with admin permissions. And you will exit admin permissions when you close this window. + +### Open in Terminal + +1. Right-click in the blank area on File Manager. +2. Select **Open in terminal**, Terminal will be opened, and its directory will be the current one. + +![0|openinterminal](fig/p_openinterminal.png) + +### Burn CD + +You can copy music, video, pictures, or mirror files to a CD or DVD through the burning feature. The ISO9660 file system supports all CD and DVD formats, while the UDF file system only supports some CD formats. + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeFormatISO9660UDF
Blank disksDVD-R, DVD+R, CD-R, CD-RWSupportedSupported
Non DVD-R, DVD+R, CD-R, CD-RWSupportedNot Supported
Non blank disksDVD-R, DVD+R, CD-R, CD-RWAdding files afterwards is supported.Only formats burned by primitive tools of Windows are supported.
Non DVD-R, DVD+R, CD-R, CD-RWAdding files afterwards is supported.Adding files afterwards is not supported
+ + + + + + +1. Insert the disc into the recording drive. + +2. Open File Manager and click the CD Icon in the left panel to enter the burning interface. + +![cd](fig/cd_interface.png) + +3. Right click the file (folder) and select **Add to disc** or drag the file (folder) directly to the burning interface. + +4. In the burning interface, click **Burn** in the upper right corner. + +>![notes](../common/notes.svg) Notes: if you want to delete a file/folder from the burning list, right-click it and select **Delete** to remove it from the list. + +5. A window pops up. Input the disc name. You can also enter the **Advanced settings** interface, set the file system and write speed, or check "Allow files to be added later", "Verify data" and so on, and click **Burn**. + +![cd](fig/cd_rename.png) + +6. After burning, a prompt box will pop up in the interface, and click **OK**. + +>![notes](../common/notes.svg) Notes: If you need to erase the disc data, you can right-click the disc icon in the left panel and select **Unmount**, right-click the disc icon again and select **Erase**. + +### Create Link + +1. On File Manager interface, right-click the item to create a link for. +2. Select **Create link**. +3. In the pop-up window, select a location and input the name of the link. +4. Click **Save** to finish creating the link. + +> ![tips](../common/tips.svg) Tips: By selecting **Send to desktop** for an item, you can create a link on desktop with one click. + +### Send to Other Device + +When there is an external device inserted, you can directly send file/folder to it. + +1. On File Manager interface, select a file/folder. +2. Right-click and select **Send to**. +3. Select the device you want to send to. +4. File/folder will be copied to the device. + +### Send to Bluetooth +If your computer is equipped with Bluetooth module, you can transfer files in short distance through Bluetooth. + +Prerequisite: The Bluetooth devices of sender and receiver have been paired and connected successfully. Refer to [Connect to a Bluetooth Device](dman:///dde#Connect to a Bluetooth Device) for details. + +1. On File Manager interface, right-click the file or package to be sent. +2. Select **Send to** > **Send to Bluetooth**. +3. Select the receiver in the pop-up window, and click **Next**. +4. A file receiving request will pop up on the receiving device. After the receiver agrees the request, the sender starts to transfer the file. + + + +## UnionTech OS Assistant + +UnionTech OS Assistant is a practical tool to realize cross terminal cooperation, efficient transmission, and real-time synchronization. It only needs to connect the mobile phone and PC, or use wireless delivery to easily transfer pictures, videos, files, etc. + +>![notes](../common/notes.svg)Notes: Only Android phones are supported. + +### Preparation + +#### Install UnionTech OS Assistant + +1. Click ![icon](../common/found.svg) in the system tray or open File Manager and click **My Phone** in the left panel. + +2. Click **Install UnionTech OS Assistant**, a window with a QR code inside pops up. + + - Scan the QR code with your WeChat or browser to download and install UnionTech OS Assistant. + - Click **Download APK** to download it locally and import it into your phone for installation. + +![phone](fig/myphone.png) + +#### Log in UnionTech OS Assistant + +There are three ways to log in UnionTech OS Assistant, including: cell phone quick login, WeChat login, and account password login. Please choose one to login. If you haven't registered your account yet, please click **Register** on the login screen to register. + +#### Discovery Settings + +Use the "Discovery Settings" function to set how your phone and computer are discovered. In the UnionTech OS Assistant screen, click **Discovery Settings** in the upper right corner; on the computer system tray, right-click the icon ![icon](../common/found.svg) and select **Discovery Settings**, you can choose: + +- **Discoverable for everyone**: Within the LAN, all devices that are on the same network and in the same network segment are allowed to discover this phone or computer. +- **Discoverable for the same Union ID only**: Within the LAN, only devices logged into the same Union ID are allowed to discover this phone or computer. +- **Undiscoverable**: All devices are not allowed to discover this phone or computer. +- **Discoverable for remote devices with the same Union ID** (computer side): Remote devices logged into the same Union ID are allowed to discover this computer. + + + + +### Connect PC with Phone + +After logging into UnionTech OS Assistant, you can connect your phone to your computer by **Scan and Connect** or **Search Computer**. + +#### Scan and Connect + +Prerequisite: The phone and the computer are on the same wireless network and in the same network segment. + +After the network connection is successful, then perform the following steps. + +1. At the computer side, click ![icon](../common/found.svg)in the system tray or open File Manager and click **My Phone** in the left panel, "Scan and connect with UnionTech OS Assistant" interface pops up. +2. At the phone side, enter UnionTech OS Assistant interface and click **Scan and Connect**, scan the QR code pops up in step 1. + +#### Search Computer + +Prerequisite: The phone and the computer are on the same wireless network and in the same network segment (sending files to each other is supported, instead of viewing and editing files), or they have logged into the same Union ID; the phone and computer are discoverable. + +1. In UnionTech OS Assistant interface on your phone, click "Search Computer". + +2. Select the computer to be connected. + +If you need to disconnect, you can: + + - Click ![icon](../common/exit.svg) in UnionTech OS Assistant on your phone. + - Right-click ![icon](../common/found.svg) in the system tray on PC, select your phone and click **Disconnect**. + +### Manage Files +After the connection between the mobile phone and PC is successful, files can be transfered, viewed and managed easily. + +#### Transfer Files + +- **In UnionTech OS Assistant interface** + + Send files from your phone to your computer: In the UnionTech OS Assistant interface, click **Transfer Assistant** and send files to your computer in the transfer window. + +- **In File Manager interface** + + Send files from your computer to your phone: In the **File Manager > My Phone** interface, in the transfer window on the right side, you can select a computer file to transfer it in this window; or right-click a file on your computer and select **Send to My Phone**. + +- **By wireless delivery** + + When the devices are logged into the same Union ID or in the same wireless network and in the same network segment, and are discoverable, you can transfer files from one device to another through wireless delivery. + 1. On the computer, right-click the file you want to deliver and select **Wireless Deliver**. + + 2. In the pop-up window, select the phone or computer you want to deliver to. + + >![icon](../common/notes.svg) Notes: + >- You need to install UnionTech OS Assistant on the cell phone and log in to your account to receive the files delivered from the computer. + >- After logging in to the same Union ID, you can perform the remote delivery. + + +#### View/Edit Files + +- View computer files on your phone: In the interface of UnionTech OS Assistant, click **My Computer**, you can open, download or share computer files. +- View/edit phone files from computer side: In the interface of **File Manager > My Phone**, the folders of photo albums, videos, documents, etc. are categorized and displayed, you can open and edit the files in the folders, and the files will be synced to your phone after being edited and saved. + +## Add Corner Marker to Files/Folders + +You can assign an icon file to a file or folder icon through the command line and display it as a corner marker. +>![notes](../common/notes.svg) Notes: +>- The corner marker files support formats such as svg, jpg, png, bmp, and gif, but not bigger than 100KB. +>- The corner marker could not be added to files in USB disks and CD-ROM disks. + +### Add Single Corner Marker + +1. Open Terminal, input **gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path)"**, which means to add a corner marker in the lower right corner of the file/folder icon by default. + +>![attention](../common/attention.svg) Attention: the special corner markers defined by the system could not be replaced. + +2. You can add position codes into the above command to add a corner marker to the upper left corner(lu), lower left corner(ld), upper right corner(ru) or lower right corner(rd). +For example, to add a corner marker to the upper left corner, you have to input: +**gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path);lu"** + +![mark](fig/single.png) + +### Add Multiple Corner Markers + +To add 2~4 corner markers to a file/folder, you can input "|" in the command to separate multiple paths of the corner marker files. Only one corner marker can be added to the same corner, but you can replace it. + +For example, to add 4 corner markers to a file/folder icon, you can input: +**gio set xxx(file path) -t stringv metadata::emblems "xxx(icon path);lu|xxx(icon path);ld|xxx(icon path);ru|xxx(icon path);rd"** + +![mark](fig/multi.png) + +### Cancel Corner Markers + +Open Terminal, input **gio set xxx(file path) -t stringv metadata::emblems ""** to cancel all corner markers on the file/folder icon. + +## File Vault + +File Vault is designed to create a special safe space for you and protect your privacy. With the advanced encryption technology and convenient operations, it's quite easy to use. + +### Set Vault Password + +You will have to set a password when you use File Vault for the first time as follows: + +1. Click ![file_vault](../common/file_vault.svg) in the left panel or double-click **My Vault** in the **Computer** interface, and then click **Create** in the pop-up dialogue box. +2. Set the "Method", "Password", "Repeat password" and "Hint", click **Next**. + +![0|password](fig/password.png) + +> ![notes](../common/notes.svg) Notes: the password must contain upper case letters, lower case letters, Arabic numbers and special symbols at the same time and no less than 8 digits. Otherwise, you are not able to go to the next step. + +3. In the pop up window, set the storage location of the key file, which helps you to retrieve password if you forget it. Click **Next**. + +![encrypt](fig/save.png) + +4. Click **Encrypt**; enter your login password in the pop-up authentication window and click **Confirm**. + +5. Click **OK** when encryption finishes. + +![encrypt](fig/finish.png) + +### Lock File Vault + +After you put files into File Vault, right-click![file_vault](../common/file_vault.svg) in the left panel or right-click **My Vault** in the **Computer** interface. + +- Select **Lock** to lock File Vault. +- Select **Auto lock** and select in the sub-menu: + + Select "Never", which means the file vault remains unlock until the screen is locked or the computer is shutdown. + + Select "5 minutes", "10 minutes" or "20 minutes", which means File Vault will be locked automatically in corresponding time. + +![0|right](fig/right.png) + + + +### Unlock File Vault + +1. Click![file_vault](../common/file_vault.svg) or double-click **My Vault** in the **Computer** interface. +2. Input password in the pop-up window and click **Unlock**. +3. If you forget the vault password, click **Forgot Password?**, select the location where the key file is stored, and then click **Verify Key** to retrieve the password. + +![encrypt](fig/unlock.png) + +> ![tips](../common/tips.svg) Tips: You can also right-click ![file_vault](../common/file_vault.svg) in the left panel or **My Vault** in the **Computer** interface and select **Unlock**. + +### Delete File Vault + +You can delete a vault only after unlocking it. + +1. Right-click ![file_vault](../common/file_vault.svg) in the left panel or right-click **My Vault** in the **Computer** interface and select **Remove File Vault**. +2. Input file vault password in the pop-up window and click **Remove**. +3. Input your login password in the pop-up window and click **Confirm** to finish this operation. + +> ![attention](../common/attention.svg) Attention: Files inside the vault would be deleted as you remove the file vault. Please backup them before you remove the file vault if needed. + +## Disk Management + +On File Manager interface, you can manage local and external disks. + +Local disks are displayed in the left panel of File Manager. When you mount any external disks or insert other mobile storage devices, the corresponding icons will be displayed in the left panel. + + + + + + + + + + + + + + + + + +
Local disksAll disks of local harddisk divisions
External disksIncluding mobile hard disks, CDs/DVDs and USB flash disks.
Mobile devicesIncluding mobile phone storage, storage cards, SD cards and so on.
+ +> ![notes](../common/notes.svg) Notes: If disks or folders in the disk are encrypted, you will have to input password before visiting them. + +### Local Disks + +#### Hide Local Disks + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Check **Hide system disk** under **Advanced** > **Other**. + + +#### Rename Local Disks + +1. Right-click a local disk in the left panel or in the computer interface. +2. Select **Rename**. +3. Input the new name and press **Enter** or click any blank area to save the modification. + +> ![tips](../common/tips.svg) Tips: In the computer interface, double click any local disk slowly, after the editing box appears, you can rename it directly. + +![0|disk](fig/p_rename_disk.png) + +### External Disks + +#### Eject External Disks + +1. In the left panel of File Manager, right-click the disk you want to remove. + +2. Select **Safely Remove**. + +3. The disk will be removed from the disk list, and so will all partition of it . + + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) Tips: you can also select **Eject** or click ![unmount](../common/unmount_normal.svg) in the left panel to unmount the disk. + +#### Rename External Disks + +1. In the left panel or on computer interface, right-click the disk you want to rename. +2. Select **Unmount** and then select **Rename**. +3. Input the new name and press **Enter** or click any blank area to save the modification. + +#### Format External Disks + +1. In the left panel of File Manager, right-click the disk to format. + +2. Select **Unmount** and then select **Format**. + +3. In the pop-up window, choose the type and volume label for the disk. + +4. Click **Format**. + + ![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) Notes: If you check **Quick Format**, the disk can be formatted quickly in a few seconds, but the data could be restored by file recovery tools. If you don't want these data to be restored, you can uncheck this option box and format the disk. + + +## Main Menu + +You can create new window, switch themes, connect to server, set share password (see [Share Local Files](#Share Local Files)), make settings, view manual and version information in Main Menu. + + +### New Window + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Select **New window** to open a new window. + +### Connect to Server + +You can [visit sharing folders](#Visit Sharing Folders) by connecting to server. + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Select **Connect to Server**, input server's IP address (XX.XX.XX.XX) in the editing box. + - Click ![+](../common/+.svg) to add the address into **My Favorites**. + - Select an address from **My Favorites** and click ![-](../common/-.svg) to delete in from **My Favorites**. +3. Click **Connect**. + +![connect](fig/connecttoserver.png) + + + +### Settings + +#### Basic + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Select **Basic**. + - You can check **Always open folder in new window** + - You can set whether to open folder by one click or double click. + - You can select a directory under **Open from default window** or **Open in new tab**. + - You can set up the icon size. + - You can set the **Default View** as icon view or list view. + - Check **Show hidden files** to show all hidden files. + - Check **Hide file extension when rename**, so the extension would not be displayed when renaming. + - Check **Display recent file entry in left panel**, then the recently visited file would be displayed in left panel. + + +#### Advanced + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** on the interface of File Manager. +2. Select **Advanced**. + - You can check **Auto index internal disk**, when you search files, the files in internal disks would be searched. + - You can check **Index external storage device after connected to computer**, In **Index**, when you search files, the files in the external disks would be searched as well. + - You can check **Full-Text search** to search by content. + - You can select which types of files can be previewed. + - You can check **Auto mount**, when any external disks connect to the computer, they would be mounted automatically. + - You can check **Open after auto mount**, when any external disks connect to the computer, they would be mounted automatically and opened. + - Check **Show item counts and sizes in the path of mounted MTP devices** to display the status bar information at the bottom of the MTP device's path after it is mounted. + - Check **Keep showing the mounted Samba shares** to show the remote mount link always in the left panel. + - You can check **Use the file chooser dialog of File Manager**, when selecting files, File Manager window would be opened. + - You can check **Ask for my confirmation when deleting files**, when deleting files, a hint dialog would pop up. + - You can check **Hide system disk**, local disks would not be displayed in left panel and computer interface. + - You can check **Show file system on disk icon**. + + + +### Theme + +The window theme includes Light Theme, Dark Theme and System Theme. + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Theme** to select one. + + + +### Help + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Help** to view the manual. + + + +### About + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **About** to view version information and introduction about File Manager. + + + +### Exit + +1. Click ![icon_menu](../common/icon_menu.svg)on the interface. +2. Click **Exit**. diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/d_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/d_file-manager.md new file mode 100755 index 0000000..33cbd4e --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/d_file-manager.md @@ -0,0 +1,623 @@ +# 文件管理器|dde-file-manager| + +## 概述 + +文件管理器是一款功能强大、简单易用的文件管理工具。它沿用了传统文件管理器的经典功能和布局,并在此基础上简化了用户操作,增加了很多特色功能。一目了然的导航栏、智能识别的搜索框、多样化的视图及排序让您管理起来得心应手,经典和超越,只为给您更好的体验! + +![1|overview](fig/overview.png) + +## 使用入门 + +通过以下方式运行或关闭文件管理器,或者创建文件管理器的快捷方式。 + +### 运行文件管理器 + +1. 单击任务栏上的启动器图标 ![deepin_launcher ](../common/deepin_launcher.svg),进入启动器界面。 +2. 上下滚动鼠标滚轮浏览或通过搜索,找到文件管理器图标 ![deepin_file_manager](../common/deepin_file_manager.svg),单击运行。 +3. 右键单击 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 单击 **发送到桌面**,在桌面创建快捷方式。 + - 单击 **发送到任务栏**,将应用程序固定到任务栏。 + - 单击 **开机自动启动**,将应用程序添加到开机启动项,在电脑开机时自动运行该应用。 + +> ![tips](../common/tips.svg)窍门:您也可以使用快捷键 **Super + E** 启动文件管理器。 + +### 关闭文件管理器 + +- 在文件管理器界面,单击 ![close_icon](../common/close_icon.svg),退出文件管理器。 +- 在任务栏右键单击 ![deepin_file_manager](../common/deepin_file_manager.svg),选择 **关闭所有** ,退出文件管理器。 +- 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg),选择 **退出**,退出文件管理器。 + +### 查看快捷键 + +在文件管理器界面,使用快捷键 **Ctrl + Shift + /** 打开快捷键预览界面,熟练地使用快捷键,将大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主界面 + +文件管理器的主界面简单易用、功能全面,熟练地使用界面功能将使文件管理更加简单高效。 + +![1|main_interface](fig/main_introduce.png) + + +| 标号 | 名称 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 导航栏 | 单击导航图标,快速访问本地文件、磁盘、网络邻居、书签、标记等。 | +| 2 | 地址栏 | 通过地址栏,您可以快速切换访问历史、在上下级目录间切换、搜索、输入地址访问。 | +| 3 | 图标/列表视图 | 单击 ![icon_view](../common/icon_view.svg),![list_view](../common/list_view.svg)图标,以图标或列表形式查看文件(夹)。 | +| 4 | 信息栏 | 单击 ![fileinfo](../common/fileinfo.svg),查看文件(夹)的基本信息和标记。 | +| 5 | 菜单栏 | 通过主菜单,您可以新建窗口、切换窗口主题、设置共享密码、设置文件管理器、查看帮助文档和关于信息、退出文件管理器。 | +| 6 | 状态栏 | 显示文件数量或者已选中文件的数量。 | + + +> ![tips](../common/tips.svg)窍门:可拖动左侧导航栏右边的分隔线来改变其宽度。 + +## 基本功能 + +文件管理器具备基本的文件管理功能,对文件(夾)进行新建、复制、重命名、删除等操作都非常简单。 + +### 新建文件 + +#### 新建文档 + +1. 在文件管理器空白区域,单击鼠标右键。 +2. 单击 **新建文档**。 +3. 选择新建文件的类型。 +4. 输入新建文件的名称。 + +![0|newdo](fig/newdo.png) + +#### 新建文件夹 + +1. 在文件管理器空白区域,单击鼠标右键。 +2. 单击 **新建文件夹**。 +3. 输入新建文件夹的名称。 + +### 重命名文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **重命名**。 +3. 输入文件名称,按 **Enter** 键或者单击界面空白区域保存设置。 + +![0|rename](fig/d_rename.png) + +> ![tips](../common/tips.svg)窍门:在 **设置** 中勾选“重命名时隐藏文件扩展名”,能更方便地修改文件名称。 + +### 批量重命名 + +1. 在文件管理器界面,选中多个文件。 +2. 右键单击文件,并选择 **重命名**。 + - **替换文本** 查找需要替换的文本,并输入替换后的文本,文件名中的关键字将被统一替换。 + - **添加文本** 输入需要添加的文本,并选择位置是名称之前还是之后,文件名将统一加入被添加的文本。 + - **自定义文本** 输入文件名,并输入序列的递进数字,文件名将统一改成新文件名+递进数字。 +4. 单击 **重命名** 来完成操作。 + +![1|rename](fig/batch_rename.png) + +### 查看文件 + +单击菜单栏上的图标 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 来切换图标视图和列表视图。 + +- 图标视图:平铺显示文件的名称、图标或缩略图。 + +![1|iconview](fig/iconview.png) + +- 列表视图:列表显示文件图标或缩略图、名称、修改时间、大小、类型等信息。 + +![1|listview](fig/listview.png) + +> ![tips](../common/tips.svg)窍门: +> - 在列表视图中,把光标置于两列之间的分隔线上,拖动它来改变列的宽度;双击分隔线可将当前列自动调整为本列内容最宽的宽度。 +> - 使用快捷键 **Ctrl + 1** 和 **Ctrl + 2**,切换图标视图和列表视图。 + + +### 排序文件 + +1. 在文件管理器空白区域,单击鼠标右键。 +2. 选择 **排序方式**。 +3. 在子菜单中选择以名称、修改时间、大小或类型来排序文件。 + +> ![tips](../common/tips.svg)窍门:在列表视图中,单击表头栏的列标签来切换升序、降序。 + +### 打开文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **打开方式** > **选择默认程序**。 +3. 在程序列表中选择应用程序。 + +> ![notes](../common/notes.svg)说明:直接双击文件会使用默认程序打开。您可以选择相同类型的多个文件,右键选择 **打开方式** 选项,同时打开多个文件。 + +![0|open](fig/d_open.png) + + + +### 隐藏文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **属性**,勾选 **隐藏此文件**。 + +### 复制文件 + +1. 在文件管理器界面,右键单击文件。 +2. 单击 **复制**。 +3. 选择一个目标存储位置。 +4. 单击鼠标右键,然后选择 **粘贴**。 + +### 压缩文件 + +1. 在文件管理器界面,右键单击文件(夹)。 +2. 选择 **压缩**。 +3. 弹出归档管理器压缩界面,可以设置压缩包格式、名称、存储路径等,单击 **压缩**。 + +> ![tips](../common/tips.svg)窍门:您也可以直接在右键菜单中选择 **添加到xxx.7z** 或 **添加到xxx.zip**,快速将文件(夹)压缩成7z或zip格式。 + + + +### 删除文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **删除** 。 + - 被删除的文件可以在回收站中找到,右键单击回收站中的文件可以进行 **还原** 或 **删除** 操作。 + - 被删除的文件的快捷方式将会失效。 + +> ![attention](../common/attention.svg)注意:外接设备删除文件会将文件彻底删除,无法从回收站找回。 + +### 撤销操作 + +在文件管理器中,可以用 **Ctrl + Z** 来撤销上一步操作,包括: + +- 删除新建的文件。 +- 恢复重命名(包括重命名文件后缀)之前的名字。 +- 从回收站还原刚删除的文件。 +- 恢复文件到移动(剪切移动、鼠标移动)前的原始路径。 +- 删除复制粘贴的文件。 + +>![attention](../common/attention.svg)注意:撤销动作最多只能返回两步;如果操作中有覆盖某个同名文件和彻底删除文件,则撤销只能返回到这一步。 + +### 文件属性 + +文件属性会显示文件的基本信息、打开方式和权限设置。文件夹属性会显示文件夹的基本信息、共享信息和权限设置。 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **属性**,查看文件属性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg)说明:查看多个文件属性会显示文件总大小和数量;查看快捷方式的属性将会额外显示源文件地址。您还可以使用快捷键 **Ctrl + I** 查看文件属性。 + +## 常用操作 + +文件管理器具备很多特色功能,这些功能都让文件管理更加简单、高效。 + +### 切换地址栏 + +地址栏由历史导航、面包屑和输入框共同组成。通常情况下地址栏显示面包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 单击历史导航按钮,可以快速在历史浏览记录间切换,查看前一个地址或者后一个地址。 +- 文件所在位置的每一个层级都会形成一个面包屑,通过来回单击面包屑可以快速在不同文件层级间切换。 + +单击搜索图标,或者在文件路径上右键单击并选择“编辑地址”,地址栏会切换为输入框状态。在输入框外单击时,地址栏会自动恢复到面包屑状态。 + +![0|addressbar](fig/addressbar2.png) + +- 输入框带有智能识别功能,输入关键词或者访问地址后,系统会自动识别并进行搜索或访问。 + +### 搜索文件 + +文件管理器支持多种检索方式,既支持通过文件名称、文件内容进行普通搜索,也支持通过文件类型、创建时间等进行高级搜索,提高工作效率,便于文件管理。 + +- 指定目录搜索时,请先进入该目录,然后再进行搜索。 + + > ![notes](../common/notes.svg)说明:在文件管理器的 **设置** 中,默认勾选了“自动索引内置磁盘”,您可以选择勾选“连接电脑后索引外部存储设备”,加快在外部设备的搜索速度。 + + +#### 全文搜索 + +您可以通过文件内容关键字来搜索文件。 +1. 在文件管理器中,单击 ![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在高级设置项勾选“全文搜索”开启此功能。 +3. 使用快捷键 **Ctrl + F** 或在地址栏中单击搜索按钮进入搜索状态,输入关键字后按下键盘上的 **Enter** 键,搜索相关文件。 + +#### 高级搜索 + +当文件较多,搜索较慢时,启用高级搜索缩小搜索范围,提高搜索效率。 +1. 在搜索状态下,输入关键字后按 **Enter** 键,当搜索到结果时,搜索框右侧显示图标 ![filter](../common/filter.svg),单击该图标可进行高级搜索的操作。 +2. 选择搜索范围、文件大小、文件类型、修改时间、访问时间和创建时间,进行更精准的搜索。 + +![0|filter](fig/filter.png) + +### 最近使用 + +在左侧导航栏上默认有 **最近使用** 入口,单击可以查看最近使用的文件。文件默认按照访问时间倒序排列。 + +> ![notes](../common/notes.svg)说明:若想隐藏“最近使用”,可在设置 > 基本设置 > 隐藏文件,取消勾选“显示最近使用文件”。若要隐藏某一个文件的访问记录,右键单击文件选择 **移除**,该操作不会删除文件。 + +### 多标签页 + +文件管理器支持多标签页显示。 + +1. 在文件管理器界面,右键单击文件夹。 +2. 选择 **在新标签中打开**。 +3. 当窗口有多个标签页时,可以: + - 单击标签页右侧的按钮 + ,继续添加标签页。 + - 将鼠标指针置于标签页上,单击关闭按钮 × 或单击鼠标中键,关闭标签页。 + + ![1|tab](fig/d_tab.png) + +> ![tips](../common/tips.svg)窍门:文件管理器窗口只有一个标签时,标签页是隐藏的,您还可以使用快捷键 **Ctrl** + **T** 来新建标签页。 + +### 书签管理 + +为常用文件夹添加书签,以便从左侧导航栏快速访问。 + +- 添加书签:右键单击文件夹,选择 **添加书签**,在导航栏创建书签。 +- 移动书签:在导航栏上下拖动书签调整书签排序。 +- 删除书签:右键单击书签,选择 **移除** 来删除书签;或右键单击已添加书签的文件夹,选择 **移除书签** 来删除书签。 + +### 标记信息 + +通过给文件/文件夹添加标记,可以更好地分类管理您的文件。 + +> ![notes](../common/notes.svg)说明:当前仅x86平台支持 **标记信息** 功能,该帮助手册中涉及的标记信息相关内容仅适用于x86平台。 + +#### 添加标记 + +您可以为一个文件(夹)添加多个标记,也可以同时为多个文件(夹)添加标记;添加成功的标记会出现在左侧导航栏内。 + +##### 通过编辑框添加标记 + +1. 右键单击文件(夹),选择 **标记信息**。 +2. 输入标记名称,若要添加多个标记,可用逗号分隔。 +3. 单击界面空白区域保存设置。 + +>![notes](../common/notes.svg)说明:标记颜色从8种默认颜色中随机分配。 + +![1|taginfo](fig/d_taginfo.png) + + + +##### 通过颜色按钮添加标记 + +右键单击文件(夹),选择“颜色按钮”,直接生成这个颜色的标记。 + +![1|colortag](fig/d_colortag.png) + +##### 通过右侧信息栏添加标记 +选择文件(夹)后,单击菜单栏上的图标 ![fileinfo](../common/fileinfo.svg),在右侧信息栏中也可以添加标记。 + +![1|infotag](fig/d_infotag.png) + +>![notes](../common/notes.svg)说明:如果文件有标记,则复制或剪切该文件产生的文件仍然具有同样的标记。 + + +#### 重命名标记 + +在侧边导航栏中,右键单击某个标记,选择 **重命名**,修改当前标记的名称。 + +![1|renametag](fig/rename_tag.png) + +#### 修改标记颜色 + +在左侧导航栏中,右键单击某个标记,选择“颜色按钮”,即可修改当前标记的颜色。 + +#### 排序标记 + +上下拖动标记即可调整标记排序。 + +#### 删除标记 + +右键单击某个标记,选择 **移除**,删除当前标记。 + +### 文件预览 + +文件管理器支持空格键预览功能,选中文件并按下键盘上的空格键就可以快速预览文件。预览窗口可以查看图片分辨率、文档大小、文本内容等,还支持gif、音频、视频播放。 + +#### 预览视频 + +1. 选择您要预览的视频文件,按下空格键,即可开始预览。 +2. 单击视频任意地方可暂停播放。 +3. 播放过程中,可以拖动进度条来快进快退。 +4. 单击底部 **打开** 按扭,在默认程序中打开该视频文件。 + + ![1|video_preview](fig/video_preview.png) + +> ![notes](../common/notes.svg)说明:您也可以同时选择多个文件,按下空格键进行预览。 + + +### 权限管理 +选择对应文件(夹),单击右键,选择属性,单击 **权限管理**, 为所有者,群组,和其他用户设置文件权限。 + +![2|permission](fig/permission.png) + +### 我的共享 + +当您设置了共享文件时,“我的共享”会出现在导航栏上。当所有共享文件都取消共享后,“我的共享”自动从导航栏中移除。 + +#### 共享本地文件 + +1. 在文件管理器界面,右键单击文件夹,选择 **共享文件夹**。 +2. 在文件夹的属性窗口,勾选 **共享此文件夹**。 + + > ![notes](../common/notes.svg)说明: 如果smb服务未开启,共享文件夹时会弹出密码认证窗口,输入登录密码完成认证即可开启smb服务。 + +3. 根据需要设置 **共享名**、**权限**、**匿名访问** 后关闭窗口。 +4. 单击 ![icon_menu](../common/icon_menu.svg)> **设置共享密码**。 +5. 在弹出的对话框中输入共享密码,单击 **确定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg)窍门:取消勾选 **共享此文件夹** 可以取消文件共享,也可以右键单击文件,选择 **取消共享**。 + + +#### 访问共享文件 + +局域网中其他用户共享的文件一般都可以在网络邻居中找到,您也可以通过smb访问共享文件。 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **连接到服务器**,在编辑框中输入服务器地址,如:smb://xx.x.xx.xxx(一般为IP地址),单击 **连接**;或者直接在地址栏中输入服务器地址,按下键盘上的 **Enter** 键。 +2. 选择需要访问的共享文件夹,在弹出的窗口中输入用户名和共享密码,或者匿名访问。 + - 未加密的共享文件可以匿名访问,不需要输入用户名和密码。 + - 加密的共享文件需要输入用户名和密码之后才能访问。 + + - 用户名:共享者登录系统的用户名。 + - 密码:共享文件时设置的共享密码。 +3. 单击 **连接**。 + +![1|visit share](fig/visitshare.png) + +### 以管理员身份打开 + +1. 在文件管理器中,右键单击文件夹。 +2. 选择 **以管理员身份打开**,在弹出的对话框中输入用户登录密码,单击 **确定**。 +3. 该文件夹会以新窗口打开,在此窗口中可以进行高级权限的操作,关闭窗口后,终止管理员权限。 + +### 在终端中打开 + +1. 在文件管理器界面空白区域,单击鼠标右键。 +2. 选择 **在终端中打开**,会启动终端应用程序,终端的路径为当前目录。 + +![0|open_terminal](fig/open_terminal.png) + +### 刻录光盘 + +您可以通过刻录功能将音乐、视频、图片或镜像文件复制到CD或DVD中。请提前准备一部刻录机、一张CD或DVD光盘。 + + +1. 将光盘插入到刻录机中。 +2. 打开文件管理器,单击导航栏中的光盘图标,进入刻录CD的界面。 + +![cd](fig/d_cd_interface.png) + +3. 右键单击 文件(夹),选择 **添加至光盘刻录** 或直接将文件(夹)拖拽到刻录CD的界面。 +4. 在刻录CD界面,单击右上角按钮 **刻录**。 + + >![notes](../common/notes.svg)说明:如果要从刻录列表中删除某个文件(夹),右键单击该文件(夹),选择 **删除**,将该文件(夹)从列表中移除。 + +5. 弹出对话框,输入光盘名称。您也可以进入 **高级设置** 界面,设置文件系统、写入速度,或勾选“允许追加数据”、“核验数据”等,单击 **刻录**。 + +![cd](fig/d_cd_rename.png) + +6. 刻录完成后界面弹出提示框,单击 **确定**。 + +>![notes](../common/notes.svg)说明: +>- 当前系统仅支持对ISO9660格式的文件进行读取与刻录,而UDF格式的文件只支持读取,暂不支持刻录。 +>- 如果需要擦除光盘数据,可以右键单击导航栏中光盘图标,选择 **卸载**,再次右键单击该光盘图标并选择 **擦除**。 + +### 创建快捷方式 + +1. 在文件管理器界面,右键单击文件(夹)。 +2. 选择 **创建链接**。 +3. 在弹窗中选择创建位置、链接名称。 +4. 单击 **保存**,在目标位置会生成该文件(夹)的快捷方式。 + +> ![tips](../common/tips.svg)窍门:选择 **发送到桌面** 可以直接在桌面上生成该文件(夹)的快捷方式。 + +### 发送文件(夹)到外接磁盘 + +当有外接磁盘接入时,您可以将文件(夹)发送到外接磁盘。 + +1. 在文件管理器界面上,右键单击文件(夹)。 +2. 选择 **发送到** > 外接磁盘。 +3. 文件(夹)将会被发送到移动外接磁盘。 + +### 发送文件到蓝牙 + +若您的电脑配置了蓝牙模块,便可以通过蓝牙进行短距离文件传输的操作。 + +前提条件:发送端与接收端蓝牙设备已配对并成功连接。具体连接方法请参阅 [连接蓝牙设备](dman:///dde#连接蓝牙设备)。 + +1. 在文件管理器界面,右键单击需要发送的文件或文件压缩包。 +2. 选择 **发送到** > **发送到蓝牙**。 +3. 在弹出的蓝牙文件传输对话框中勾选接收设备,单击 **下一步**。 +4. 此时接收端会收到文件接收的请求,待接收端同意请求后,发送端开始传输文件。 + + + +## 文件角标 + +您可以通过命令行,将图标文件指定给一个文件(夹)作为角标显示出来。 + >![icon](../common/notes.svg)说明: + >- 角标文件支持svg、jpg、png、bmp、gif格式,且大小不超过100KB。 + >- U盘及光盘下的文件,不支持添加角标。 + +### 添加单个角标 + +1. 在终端输入命令 **gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径)"** ,该命令默认在文件(夹)右下角添加角标。 + + >![icon](../common/attention.svg)注意:系统已定义的特殊角标,不支持被替换。 + +2. 您也可以在上述命令中加入位置参数,将角标添加在文件(夹)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + + 例如:在文件(夹)左上角添加角标 + + **gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径);lu"** + +![mark](fig/single.png) + +### 添加多个角标 + +在命令行中加入“**|**”符号将角标文件路径链接起来,为文件(夹)添加2~4个角标。文件(夹)同一个位置不支持叠加角标,仅支持替换。 + +例如:在文件(夹)四个角都添加角标 + +**gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径);lu|xxx(图标路径);ld|xxx(图标路径);ru|xxx(图标路径);rd"** + +![mark](fig/multi.png) + +### 撤销角标 + +在终端中输入命令 **gio set xxx(文件路径) -t stringv metadata::emblems ""** 撤销文件(夹)上所有的角标。 + +## 磁盘管理 + +文件管理器管理本地磁盘和外接磁盘。本地磁盘显示在文件管理器的左侧导航栏上或计算机界面;挂载外接磁盘或者插入其他移动存储设备时,也会在导航栏看到相应的磁盘图标。 + + + + + + + + + + + + + + + + + +
本地磁盘本地硬盘分区的所有磁盘
外接磁盘包括移动硬盘、U盘、光盘
移动设备手机内存、存储卡、SD卡等
+ +> ![notes](../common/notes.svg)说明:如果磁盘或磁盘中的文件夹已加密,请输入密码后查看文件。 + +### 本地磁盘 + +#### 隐藏本地磁盘 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在高级设置选项中勾选 **隐藏系统盘**。 + +#### 重命名本地磁盘 + +1. 在左侧导航栏或计算机界面,右键单击本地磁盘。 +2. 选择 **重命名**。 +3. 输入新名称,按下键盘上的 **Enter** 键或单击界面空白区域保存修改。 + +> ![tips](../common/tips.svg)窍门:在计算机界面,慢速双击本地磁盘,呈现编辑框后便可进行重命名操作。 + +![0|disk](fig/d_rename_disk.png) + +### 外接磁盘 + +#### 弹出外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要移除的磁盘。 +2. 选择 **安全移除**。 +3. 磁盘将从磁盘列表中删除,一并弹出该磁盘的所有分区。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg)窍门:如果要弹出光盘,请选择 **弹出** 来移除光盘。单击导航栏中磁盘右边的 ![unmount](../common/unmount_normal.svg) 同样可以弹出磁盘或光盘。 + +#### 重命名外接磁盘 +1. 在左侧导航栏或计算机界面,右键单击需要重命名的磁盘。 +2. 选择 **卸载** 后,再次单击右键选择 **重命名**。 +3. 输入新的卷标名称,按下键盘上的 **Enter** 键或单击空白区域保存修改。 + + + +#### 格式化外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要格式化的磁盘。 +2. 选择 **卸载** 后,再次单击右键选择 **格式化**。 +3. 设置格式化之后的文件类型和卷标。 +4. 单击 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg)说明:快速格式化速度快,但是数据仍然可能通过工具被恢复,如果想要格式化后的数据无法被恢复,可以取消勾选“快速格式化”,然后执行格式化操作。 + +## 主菜单 + +在主菜单中,您可以新建窗口、切换窗口主题、连接到服务器、[设置共享密码](#共享本地文件)、设置文件管理器、查看帮助手册和版本介绍。 + +### 新建窗口 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **新建窗口**,打开一个新的文件管理器窗口。 + +### 连接到服务器 + +通过连接服务器 [访问局域网共享文件](#访问共享文件)。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **连接到服务器**,在编辑框中输入服务器IP地址。 + - 单击 ![+](../common/+.svg) 按钮可将该地址添加到“个人收藏服务器”列表中。 + - 在“个人收藏服务器”列表中选中一个地址,单击 ![_](../common/-.svg) 按钮,将该地址从收藏列表中移除。 +3. 单击 **连接**。 + +![conncet](fig/connect_to_server.png) + + +### 设置 + +#### 基础设置 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)> **设置** 。 +2. 选择 **基础设置** 选项。 + + 勾选 **总是在新窗口打开文件夹**。 + + 设置双击或单击打开文件。 + + 设置 **从默认窗口打开**、**从新标签打开** 哪个目录。 + + 设置文件图标 **默认大小** 。 + + 设置 **默认视图** 以图标展示或列表展示。 + + 勾选 **显示隐藏文件**,文件管理器中被隐藏的文件会显示出来。 + + 勾选 **重命名时隐藏文件扩展名**,重命名时不会显示扩展名。 + + 勾选 **显示最近使用文件**,在左侧导航栏显示最近使用的文件。 + +#### 高级设置 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)> **设置** 。 +2. 选择 **高级设置** 选项。 + + 勾选 **自动索引内置磁盘**,搜索文件时会搜索内置磁盘中的文件。 + + 勾选 **连接电脑后索引外部存储设备**,搜索文件时也会搜索外接设备中的文件。 + + 勾选 **全文搜索**,通过文件中的内容来索引。 + + 勾选预览文件类型。 + + 勾选 **自动挂载**,接入外接磁盘时自动挂载。 + + 勾选 **自动挂载后打开**,接入外接磁盘时自动挂载并打开该磁盘。 + + 勾选 **MTP挂载路径下显示文件统计详情**,MTP设备挂载后,显示其路径底部的状态栏信息。 + + 勾选 **Samba共享端常驻显示挂载入口**,远程挂载链接常驻显示在导航栏中。 + + 勾选 **使用文件管理器的文件选择对话框**,选择文件时打开文件管理器窗口。 + + 勾选 **开启普通删除提示**,删除文件时弹出提示对话框。 + + 勾选 **隐藏系统盘**,导航栏和计算机界面将不显示本地磁盘。 + + 勾选 **在磁盘图标上显示文件系统标签**。 + +### 主题 + +窗口主题包含浅色主题、深色主题和系统主题。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **主题**,选择一个主题。 + +### 帮助 + +查看帮助手册,进一步了解和使用文件管理器。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **帮助**。 +3. 查看文件管理器的帮助手册。 + + +### 关于 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **关于**。 +3. 查看文件管理器的版本和介绍。 + + +### 退出 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **退出**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/e_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/e_file-manager.md new file mode 100755 index 0000000..8f6cc2e --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/e_file-manager.md @@ -0,0 +1,659 @@ +# 文件管理器|dde-file-manager| + +## 概述 + +文件管理器是一款功能强大、简单易用的文件管理工具。它沿用了传统文件管理器的经典功能和布局,并在此基础上简化了用户操作,增加了很多特色功能。一目了然的导航栏、智能识别的搜索框、多样化的视图及排序让您管理起来得心应手,经典和超越,只为给您更好的体验! + +![1|overview](fig/e_overview.png) + +## 使用入门 + +通过以下方式运行或关闭文件管理器,或者创建文件管理器的快捷方式。 + +### 运行文件管理器 + +1. 单击任务栏上的启动器图标 ![deepin_launcher ](../common/deepin_launcher.svg),进入启动器界面。 +2. 上下滚动鼠标滚轮浏览或通过搜索,找到文件管理器图标 ![deepin_file_manager](../common/deepin_file_manager.svg),单击运行。 +3. 右键单击 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 单击 **发送到桌面**,在桌面创建快捷方式。 + - 单击 **发送到任务栏**,将应用程序固定到任务栏。 + - 单击 **开机自动启动**,将应用程序添加到开机启动项,在电脑开机时自动运行该应用。 + +> ![tips](../common/tips.svg)窍门:您也可以使用快捷键 **Super + E** 启动文件管理器。 + +### 关闭文件管理器 + +- 在文件管理器界面,单击 ![close_icon](../common/close_icon.svg),退出文件管理器。 +- 在任务栏右键单击 ![deepin_file_manager](../common/deepin_file_manager.svg),选择 **关闭所有** ,退出文件管理器。 +- 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg),选择 **退出**,退出文件管理器。 + +### 查看快捷键 + +在文件管理器界面,使用快捷键 **Ctrl + Shift + /** 打开快捷键预览界面。熟练地使用快捷键,将大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主界面 + +文件管理器的主界面简单易用、功能全面,熟练地使用界面功能将使文件管理更加简单高效。 + +![1|main_interface](fig/e_main_interface.png) + + +| 标号 | 名称 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 导航栏 | 单击导航图标,快速访问本地文件、磁盘、网络邻居、书签、标记等。 | +| 2 | 地址栏 | 通过地址栏,您可以快速切换访问历史、在上下级目录间切换、搜索、输入地址访问。 | +| 3 | 图标/列表视图 | 单击 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg)图标,以图标或列表形式查看文件(夹)。 | +| 4 | 信息栏 | 单击 ![fileinfo](../common/fileinfo.svg), 查看文件(夹)的基本信息和标记。 | +| 5 | 菜单栏 | 通过主菜单,您可以新建窗口、切换窗口主题、设置共享密码、设置文件管理器、查看帮助文档和关于信息、退出文件管理器。 | +| 6 | 状态栏 | 显示文件数量或者已选中文件的数量。 | + + +> ![tips](../common/tips.svg) 窍门:可拖动左侧导航栏右边的分隔线来改变其宽度。 + +## 基本功能 + +文件管理器具备基本的文件管理功能,对文件(夹)进行新建、复制、重命名、删除等操作都非常简单。 + +### 新建文件 + +#### 新建文档 + +1. 在文件管理器空白区域,单击鼠标右键。 +2. 选择 **新建文档**。 +3. 在下拉菜单中选择新建文件的类型。 +4. 输入新建文件的名称。 + +![0|newdo](fig/e_newdo.png) + +#### 新建文件夹 + +1. 在文件管理器空白区域,单击鼠标右键。 +2. 选择 **新建文件夹**。 +3. 输入新建文件夹的名称。 + +### 重命名文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **重命名**。 +3. 输入文件名称,按 **Enter** 键或者单击界面空白区域。 + +![1|rename](fig/d_rename.png) + +> ![tips](../common/tips.svg) 窍门:在 **设置** 中勾选“重命名时隐藏文件扩展名”,能更方便地修改文件名称。 + +### 批量重命名 + +1. 在文件管理器界面,选中多个文件。 +2. 右击文件,并选择 **重命名**。 + - **替换文本** 查找需要替换的文本,并输入替换后的文本,文件名中的关键字将被统一替换。 + - **添加文本** 输入需要添加的文本,并选择位置是名称之前还是之后,文件名将统一加入被添加的文本。 + - **自定义文本** 输入文件名,并输入序列的递进数字,文件名将统一改成新文件名+递进数字。 +4. 单击 **重命名** 来完成操作。 + +![1|rename](fig/e_batch_rename.png) + +### 查看文件 + +单击菜单栏上的图标 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 来切换图标视图和列表视图。 + +- 图标视图:平铺显示文件的名称、图标或缩略图。 + +![1|icon_view](fig/e_iconview.png) + +- 列表视图:列表显示文件图标或缩略图、名称、修改时间、大小、类型等信息。 + +![1|list_view](fig/e_listview.png) + +> ![tips](../common/tips.svg) 窍门: +> - 在列表视图中,把光标置于两列之间的分隔线上,拖动它来改变列的宽度;双击分隔线可将当前列自动调整为本列内容最宽的宽度。 +> - 使用快捷键 **Ctrl + 1** 和 **Ctrl + 2**,切换图标视图和列表视图。 + + +### 排序文件 + +1. 在文件管理器界面,单击鼠标右键。 +2. 选择 **排序方式**。 +3. 在子菜单中选择以名称、修改时间、大小或类型来排序文件。 + +> ![tips](../common/tips.svg)窍门:在列表视图中,单击表头栏的列标签来切换升序、降序。 + +### 打开文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **打开方式** > **选择默认程序**。 +3. 在程序列表中选择应用程序。 + +> ![notes](../common/notes.svg) 说明:直接双击文件会使用默认程序打开。您可以选择相同类型的多个文件,右键选择 **打开方式** 选项,同时打开多个文件。 + +![0|open](fig/d_open.png) + + + +### 隐藏文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **属性**,勾选 **隐藏此文件**。 + +### 复制文件 + +1. 在文件管理器界面,右键单击文件。 +2. 单击 **复制**。 +3. 选择一个目标存储位置。 +4. 单击鼠标右键,然后选择 **粘贴**。 + +### 压缩文件 + +1. 在文件管理器界面,右键单击文件(夹)。 +2. 选择 **压缩**。 +3. 弹出归档管理器压缩界面,可以设置压缩包格式、名称、存储路径等,单击 **压缩**。 + +> ![tips](../common/tips.svg) 窍门:您也可以直接在右键菜单中选择 **添加到xxx.7z** 或 **添加到xxx.zip**,快速将文件(夹)压缩成7z或zip格式。 + +### 删除文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **删除** 。 + - 被删除的文件可以在回收站中找到,右键单击回收站中的文件可以进行 **还原** 或 **删除** 操作。 + - 被删除的文件的快捷方式将会失效。 + +> ![attention](../common/attention.svg)注意:外接设备删除文件会将文件彻底删除,无法从回收站找回。 + +### 撤销操作 + +在文件管理器中,可以用 **Ctrl + Z** 来撤销上一步操作,包括: + +- 删除新建的文件。 +- 恢复重命名(包括重命名文件后缀)之前的名字。 +- 从回收站还原刚删除的文件。 +- 恢复文件到移动(剪切移动、鼠标移动)前的原始路径。 +- 删除复制粘贴的文件。 + +>![attention](../common/attention.svg) 注意:撤销动作最多只能返回两步;如果操作中有覆盖某个同名文件和彻底删除文件,则撤销只能返回到这一步。 + +### 文件属性 + +文件属性会显示文件的基本信息,打开方式和权限设置。文件夹属性会显示文件夹的基本信息,共享信息和权限设置。 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **属性**,查看文件属性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg) 说明:查看多个文件属性会显示文件总大小和数量;查看快捷方式的属性将会额外显示源文件地址。您还可以使用 **Ctrl + I** 组合键查看文件属性。 + + +## 常用操作 + +文件管理器具备很多特色功能,这些功能都让文件管理更加简单、高效。 + +### 切换地址栏 + +地址栏由历史导航、面包屑和输入框共同组成,通常情况下地址栏显示面包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 单击历史导航按钮,可以快速在历史浏览记录间切换,查看前一个地址或者后一个地址。 +- 文件所在位置的每一个层级都会形成一个面包屑,通过来回单击面包屑可以快速在不同文件层级间切换。 + +单击搜索按钮,或者在文件路径上右键单击并选择 **编辑地址**,地址栏会切换为输入框状态。在输入框外单击时,地址栏会自动恢复到面包屑状态。 + +![0|addressbar](fig/addressbar2.png) + +- 输入框带有智能识别功能,输入关键字或者访问地址,系统会自动识别并进行搜索或访问。 + +### 搜索文件 + +文件管理器支持多种检索方式,既支持通过文件名称、文件内容进行普通搜索,也支持通过文件类型、创建时间等进行高级搜索,提高工作效率,便于文件管理。 + +- 指定目录搜索时,请先进入该目录,然后再进行搜索。 + +> ![notes](../common/notes.svg) 说明:在文件管理器的 **设置** 中,默认勾选了“自动索引内置磁盘”,您可以选择勾选“连接电脑后索引外部存储设备”,加快在外部设备的搜索速度。 + +#### 全文搜索 + +您可以通过文件内容关键字来搜索文件。 +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在高级设置项勾选“全文搜索”来开启此功能。 +3. 使用快捷键 **Ctrl + F** 或在地址栏中单击搜索按钮进入搜索状态,输入关键字后按下键盘上的 **Enter** 键,搜索相关文件。 + +#### 高级搜索 + +当文件较多,搜索较慢时,启用高级搜索缩小搜索范围,提高搜索效率。 +1. 在搜索状态下,输入关键字后按 **Enter** 键,当搜索到结果时,搜索框右侧显示图标 ![filter](../common/filter.svg),单击该图标可进行高级搜索的操作。 +2. 选择搜索范围、文件大小、文件类型、修改时间、访问时间和创建时间,进行更精准的搜索。 + +![0|filter](fig/e_filter.png) + + +### 最近使用 + +在左侧导航栏上默认有 **最近使用** 入口,单击可以查看最近使用的文件。文件默认按照访问时间倒序排列。 + +> ![notes](../common/notes.svg) 说明:若想隐藏“最近使用”,可在 **设置** > **基本设置** > **隐藏文件**,取消勾选“显示最近使用文件”。若要隐藏某一个文件的访问记录,右键单击该文件选择 **移除**,该操作不会删除文件。 + +### 多标签页 + +文件管理器支持多标签页显示。 + +1. 在文件管理器界面,右键单击文件夹。 +2. 选择 **在新标签中打开**。 +3. 当窗口有多个标签页时,可以: + - 单击标签页右侧的按钮 + ,继续添加标签页。 + - 将鼠标指针置于标签页上,单击关闭按钮 × 或单击鼠标中键,关闭标签页。 + + ![1|tab](fig/e_tab.png) + +> ![tips](../common/tips.svg) 窍门:文件管理器窗口只有一个标签时,标签栏是隐藏的,您还可以使用快捷键 **Ctrl** + **T** 来新建标签。 + +### 书签管理 + +为常用文件夹添加书签,以便从左侧导航栏快速访问。 + +- 添加书签:右键单击文件夹,选择 **添加书签** 在导航栏创建书签。 +- 移动书签:在导航栏上下拖动书签调整排序。 +- 删除书签:右键单击书签,选择 **移除** 来删除书签;或右键单击已添加书签的文件夹,选择 **移除书签** 来删除书签。 + +### 标记信息 + +通过给文件(夹)添加标记,可以更好地分类管理您的文件。 + +> ![notes](../common/notes.svg) 说明:仅x86平台支持标记信息功能。 + +#### 添加标记 + +您可以为一个文件(夹)添加多个标记,也可以同时为多个文件(夹)添加标记;添加成功的标记会出现在左侧导航栏内。 + +##### 通过编辑框添加标记 + +1. 右键单击文件(夹),选择 **标记信息**。 +2. 输入标记名称,若要添加多个标记,可用逗号分隔。 +3. 单击界面空白区域保存设置。 + +>![notes](../common/notes.svg) 说明:标记颜色从8种默认颜色中随机分配。 + +![1|tag_info](fig/e_tag_info.png) + + +##### 通过颜色按钮添加标记 + +右键单击文件(夹),选择颜色按钮,直接生成这个颜色的标记。 + +![1|color_tag](fig/e_color_tag.png) + +##### 通过右侧信息栏添加标记 + +选择文件(夹)后,单击菜单栏上的图标 ![fileinfo](../common/fileinfo.svg),在右侧信息栏中也可以添加标记。 + +![1|info_tag](fig/e_info_tag.png) + +>![notes](../common/notes.svg) 说明:如果文件有标记,则复制或剪切该文件产生的文件仍然具有同样的标记。 + + +#### 重命名标记 + +在侧边导航栏中,右键单击某个标记,选择 **重命名**,修改当前标记的名称。 + +![1|rename_tag](fig/rename_tag.png) + +#### 修改标记颜色 + +在左侧导航栏中,右键单击某个标记,选择颜色按钮,即可修改当前标记的颜色。 + +#### 排序标记 + +上下拖动标记即可调整标记排序。 + +#### 删除标记 + +右键单击某个标记,选择 **移除**,删除当前标记。 + + +### 文件预览 + +文件管理器支持空格键预览功能,选中文件并按下键盘上的空格键可以快速预览文件。在预览窗口中可以查看图片分辨率、文档大小、文本内容等,还支持gif、音频、视频播放。 + +#### 预览视频 + +1. 选择您要预览的视频文件,按下空格键,即可开始预览。 +2. 单击视频任意地方可暂停播放。 +3. 播放过程中,可以拖动进度条来快进快退。 +4. 单击底部 **打开** 按扭,在默认程序中打开该视频文件。 + +![1|video_preview](fig/video_preview.png) + +> ![notes](../common/notes.svg) 说明:您也可以同时选择多个文件,按下空格键进行预览。 + + +### 权限管理 + +选择对应文件(夹),单击右键,选择属性,单击 **权限管理**, 为所有者、群组和其他用户设置文件权限。 + +![2|permission](fig/permission.png) + +### 我的共享 + +当您设置了共享文件时,“我的共享”会出现在导航栏上。取消所有共享文件后,“我的共享”自动从导航栏中移除。 + +#### 共享本地文件 + +1. 在文件管理器界面,右键单击文件夹,选择 **共享文件夹**。 +2. 在文件夹的属性窗口,勾选 **共享此文件夹**。 +3. 根据需要设置 **共享名**、**权限** 、**匿名访问** 后关闭窗口。 +4. 单击 ![icon_menu](../common/icon_menu.svg)> **设置共享密码**。 +5. 输入共享密码,单击 **确定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg) 窍门:取消勾选 **共享此文件夹** 可以取消文件共享,也可以右键单击文件,选择 **取消共享**。 + + +#### 访问共享文件 + +局域网中其他用户共享的文件都可以在网络邻居中找到,您也可以通过smb访问共享文件。 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **连接到服务器**,在编辑框中输入服务器地址,如:smb://xx.x.xx.xxx(一般为IP地址),单击 **连接**;或者直接在地址栏中输入服务器地址,按下键盘上的 **Enter** 键。 +2. 选择需要访问的共享文件夹,在弹出的窗口中输入用户名和共享密码,或者匿名访问。 + - 未加密的共享文件可以匿名访问,不需要输入用户名和密码。 + - 加密的共享文件需要输入用户名和密码之后才能访问。 + + - 用户名:共享者登录系统的用户名。 + - 密码:共享文件时设置的共享密码。 +3. 单击 **连接**。 + +![1|visitshareshare](fig/visitshare.png) + + + +### 在终端中打开 + +1. 在文件管理器中,单击鼠标右键。 +2. 选择 **在终端中打开**,会启动终端应用程序,终端的路径为当前目录。 + +![0|open_terminal](fig/e_open_terminal.png) + +### 刻录光盘 + +您可以通过刻录功能将音乐、视频、图片或镜像文件复制到CD或DVD中。请提前准备一部刻录机、一张CD或DVD光盘。 + +1. 将光盘插入到刻录机中。 +2. 打开文件管理器,单击导航栏中的光盘图标,进入刻录CD的界面。 + +![cd](fig/e_cd_interface.png) + +3. 右键单击 文件(夹),选择 **添加至光盘刻录** 或直接将文件(夹)拖拽到刻录CD的界面。 +4. 在刻录CD界面,单击右上角按钮 **刻录**。 + + >![notes](../common/notes.svg) 说明:如果要从刻录列表中删除某个文件(夹),右键单击该文件(夹),选择 **删除**,将该文件(夹)从列表中移除。 + +5. 弹出对话框,输入光盘名称。您也可以进入 **高级设置** 界面,设置文件系统、写入速度,或勾选“允许追加数据”、“核验数据”等,单击 **刻录**。 + +![cd](fig/e_cd_rename.png) + +6. 刻录完成后界面弹出提示框,单击 **确定**。 + +>![notes](../common/notes.svg) 说明: +>- 当前系统仅支持对ISO9660格式的文件进行读取与刻录,而UDF格式的文件只支持读取,暂不支持刻录。 +>- 如果需要擦除光盘数据,可以右键单击导航栏中光盘图标,选择 **卸载**,再次右键单击该光盘图标并选择 **擦除**。 + +### 创建快捷方式 + +1. 在文件管理器界面上,右键单击文件(夹)。 +2. 选择 **创建链接**。 +3. 在弹窗中选择创建位置、链接名称。 +4. 单击 **保存**,在目标位置会生成该文件(夹)的快捷方式。 + +> ![tips](../common/tips.svg)窍门:选择 **发送到桌面** 可以直接在桌面上生成该文件(夹)的快捷方式。 + +### 发送文件(夹)到外接磁盘 + +当有外接磁盘接入时,您可以将文件或文件夹发送到外接磁盘。 + +1. 在文件管理器界面,右键单击需要发送的文件(夹)。 +2. 选择 **发送到** > 外接磁盘。 +3. 文件(夹)将会被发送到移动外接磁盘。 + + +## 文件角标 + +您可以通过命令行,将图标文件指定给某个文件(夹)作为角标显示出来。 + +>![icon](../common/notes.svg)说明: +>- 角标文件支持svg、jpg、png、bmp、gif格式,且大小不超过100KB。 +>- U盘及光盘下的文件,不支持添加角标。 + +### 添加单个角标 + +1. 在终端输入命令 **gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径)"** ,该命令默认在文件(夹)右下角添加角标。 + + >![icon](../common/attention.svg)注意:系统已定义的特殊角标,不支持被替换。 + +2. 您也可以在上述命令中加入位置参数,将角标添加在文件(夹)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + + 例如:在文件(夹)左上角添加角标 + + **gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径);lu"** + +![mark](fig/single.png) + +### 添加多个角标 + +在命令行中加入“**|**”符号将角标文件路径链接起来,为文件(夹)添加2~4个角标。文件(夹)同一个位置不支持叠加角标,仅支持替换。 + +例如:在文件(夹)四个角都添加角标 + +**gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径);lu|xxx(图标路径);ld|xxx(图标路径);ru|xxx(图标路径);rd"** + +![mark](fig/multi.png) + +### 撤销角标 + +在终端中输入命令 **gio set xxx(文件路径) -t stringv metadata::emblems ""** 撤销文件(夹)上所有的角标。 + + + +## 文件保险箱 + +文件保险箱旨在为您打造专属的安全空间,为您的隐私保驾护航。先进的加密技术,便捷的操作流程,使用起来得心应手。 + +### 设置保险箱密码 + +首次使用保险箱需要对其进行密码设置,具体步骤如下: + +1. 单击导航栏中的保险箱图标 ![file_vault](../common/file_vault.svg) ,或者在计算机界面双击 **我的保险箱**,在弹出的窗口中单击 **开启** 按钮。 +2. 设置解锁类型、保险箱密码、重复保险箱密码等,单击**下一步**。 + +![0|password](fig/password.png) + + > ![notes](../common/notes.svg)说明: 密码必须同时包含大写字母、小写字母、数字和符号,且字符不小于8位,否则无法进入下一步。 + +3. 此时保险箱密码生成密钥/二维码,建议您将密钥/二维码保存,若忘记密码,可用密钥/二维码开启保险箱,单击 **下一步**。 +4. 单击 **加密保险箱**;弹出认证窗口,输入用户登录密码,单击 **确定**。 + +![encrypt](fig/encrypt.png) + +5. 在加密完成窗口中单击 **确定**,完成保险箱密码设置 。 + + + +### 锁上保险箱 + +将文件放入保险箱后,右键单击 ![file_vault](../common/file_vault.svg) 或者在计算机界面右键单击 **我的保险箱**。 +- 选择 **立即上锁**,立即将文件保险箱锁上。 +- 选择 **自动上锁**,在其下拉列表进行设置: + + 选择“从不”,计算机在锁屏或关机前一直保持未上锁状态。 + + 选择“5分钟”、“10分钟”或者“20分钟”后自动上锁保险箱。 + +![0|right](fig/right.png) + + +### 解锁保险箱 + +右键单击 ![file_vault](../common/file_vault.svg) 或者计算机界面 **我的保险箱**。 + +- 选择 **解锁**,在弹出的对话框中输入保险箱密码,单击 **解锁**。 +- 选择 **密钥解锁**,在弹出的对话框中输入32位密钥,单击 **解锁**。 +>![0|tips](../common/tips.svg) 窍门:您也可以单击 ![file_vault](../common/file_vault.svg) 或者双击计算机界面 **我的保险箱**,直接使用密码解锁保险箱。 + + +### 删除保险箱 +删除保险箱需要提前解锁保险箱。 +1. 右键单击 ![file_vault](../common/file_vault.svg) 或者在计算机界面右键单击 **我的保险箱**,选择 **删除保险箱**。 +2. 弹出删除保险箱窗口,输入保险箱密码,单击 **删除**。 +3. 在认证窗口中输入用户登录密码,单击 **确定** 完成删除操作。 +> ![attention](../common/attention.svg) 注意:删除保险箱会将里面的文件一并删除。在进行删除操作前,请将保险箱中的文件备份。 + +## 磁盘管理 + +文件管理器管理本地磁盘和外接磁盘。本地磁盘显示在文件管理器的左侧导航栏上或计算机界面;挂载外接磁盘或者插入其他移动存储设备时,也会在导航栏看到相应的磁盘图标。 + + + + + + + + + + + + + + + + + +
本地磁盘本地硬盘分区的所有磁盘
外接磁盘包括移动硬盘、U盘、光盘
移动设备手机内存、存储卡、SD卡等
+ +> ![notes](../common/notes.svg) 说明:如果磁盘或磁盘中的文件夹已加密,请输入密码后查看文件。 + +### 本地磁盘 + +#### 隐藏本地磁盘 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在高级设置选项中勾选 **隐藏系统盘**。 + +#### 重命名本地磁盘 + +1. 在左侧导航栏或计算机界面,右键单击本地磁盘。 +2. 选择 **重命名**。 +3. 输入新名称,按下键盘上的 **Enter** 键或单击空白处保存修改。 + +> ![tips](../common/tips.svg) 窍门:在计算机界面,慢速双击本地磁盘,呈现编辑框后即可进行重命名操作。 + +![0|disk](fig/e_rename_disk.png) + +### 外接磁盘 + +#### 弹出外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要移除的磁盘。 +2. 选择 **安全移除**。 +3. 磁盘将从磁盘列表中删除,一并弹出该磁盘的所有分区。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) 窍门:如果要弹出光盘,请选择 **弹出** 来移除光盘。单击导航栏中磁盘右边的 ![unmount](../common/unmount_normal.svg) 同样可以弹出磁盘或光盘。 + +#### 重命名外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要重命名的磁盘。 +2. 选择 **卸载**,再次单击右键选择 **重命名**。 +3. 输入新的卷标名称,按下键盘上的 **Enter** 键或单击空白处保存修改。 + + + +#### 格式化外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要格式化的磁盘。 +2. 选择 **卸载**,再次单击右键选择 **格式化**。 +3. 设置格式化之后的文件类型和卷标。 +4. 单击 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) 说明:快速格式化速度快,但是数据仍然可能通过工具被恢复,如果想要格式化后的数据无法被恢复,可以取消勾选“快速格式化”,然后执行格式化操作。 + +## 主菜单 + +在主菜单中,您可以新建窗口、切换窗口主题、连接到服务器、[设置共享密码](#共享本地文件)、设置文件管理器、查看帮助手册和版本介绍。 + +### 新建窗口 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **新建窗口**,打开一个新的文件管理器窗口。 + +### 连接到服务器 + +通过连接服务器 [访问局域网共享文件](#访问共享文件)。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **连接到服务器**,在编辑框中输入服务器IP地址。 + - 单击 ![+](../common/+.svg) 按钮可将该地址添加到“个人收藏服务器”列表中。 + - 在“个人收藏服务器”列表中选中一个地址,单击 ![_](../common/-.svg) 按钮,将该地址从收藏列表中移除。 +3. 单击 **连接**。 + +![conncet](fig/connect_to_server.png) + + +### 设置 + +#### 基础设置 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg) > **设置** 。 +2. 选择 **基础设置** 选项。 + + 勾选 **总是在新窗口打开文件夹**。 + + 设置双击或单击打开文件。 + + 设置 **从默认窗口打开**、**从新标签打开**哪个目录。 + + 设置文件图标 **默认大小** 。 + + 设置 **默认视图** 以图标展示或列表展示。 + + 勾选 **显示隐藏文件**,文件管理器中被隐藏的文件会显示出来。 + + 勾选 **重命名时隐藏文件扩展名**,重命名时不会显示扩展名。 + + 勾选 **显示最近使用文件**,在左侧导航栏显示最近使用的文件。 + +#### 高级设置 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg) > **设置** 。 +2. 选择 **高级设置** 选项。 + + 勾选 **自动索引内置磁盘**,搜索文件时会搜索内置磁盘中的文件。 + + 勾选 **连接电脑后索引外部存储设备**,搜索文件时也会搜索外接设备中的文件。 + + 勾选 **全文搜索**,通过文件中的内容来索引。 + + 勾选预览文件类型。 + + 勾选 **自动挂载**,接入外接磁盘时自动挂载。 + + 勾选 **自动挂载后打开**,接入外接磁盘时自动挂载并打开该磁盘。 + + 勾选 **MTP挂载路径下显示文件统计详情**,MTP设备挂载后,显示其路径底部的状态栏信息。 + + 勾选 **使用文件管理器的文件选择对话框**,选择文件时打开文件管理器窗口。 + + 勾选 **开启普通删除提示**,删除文件时弹出提示对话框。 + + 勾选 **隐藏系统盘**,导航栏和计算机界面将不显示本地磁盘。 + + 勾选 **在磁盘图标上显示文件系统标签**。 + + +### 主题 + +窗口主题包含浅色主题、深色主题和系统主题。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **主题**,选择一个主题。 + +### 帮助 + +查看帮助手册,进一步了解和使用文件管理器。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **帮助**。 +3. 查看文件管理器的帮助手册。 + + +### 关于 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **关于**。 +3. 查看文件管理器的版本和介绍。 + + +### 退出 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **退出**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/eu_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/eu_file-manager.md new file mode 100755 index 0000000..c7e7781 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/eu_file-manager.md @@ -0,0 +1,664 @@ +# 文件管理器|dde-file-manager| + +## 概述 + +文件管理器是一款功能强大、简单易用的文件管理工具。它沿用了传统文件管理器的经典功能和布局,并在此基础上简化了用户操作,增加了很多特色功能。一目了然的导航栏、智能识别的搜索框、多样化的视图及排序让您管理起来得心应手,经典和超越,只为给您更好的体验! + +![1|overview](fig/e_overview.png) + +## 使用入门 + +通过以下方式运行或关闭文件管理器,或者创建文件管理器的快捷方式。 + +### 运行文件管理器 + +1. 单击任务栏上的启动器图标 ![deepin_launcher ](../common/deepin_launcher.svg),进入启动器界面。 +2. 上下滚动鼠标滚轮浏览或通过搜索,找到文件管理器图标 ![deepin_file_manager](../common/deepin_file_manager.svg),单击运行。 +3. 右键单击 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 单击 **发送到桌面**,在桌面创建快捷方式。 + - 单击 **发送到任务栏**,将应用程序固定到任务栏。 + - 单击 **开机自动启动**,将应用程序添加到开机启动项,在电脑开机时自动运行该应用。 + +> ![tips](../common/tips.svg) 窍门:您也可以使用快捷键 **Super + E** 启动文件管理器。 + +### 关闭文件管理器 + +- 在文件管理器界面,单击 ![close_icon](../common/close_icon.svg),退出文件管理器。 +- 在任务栏右键单击 ![deepin_file_manager](../common/deepin_file_manager.svg),选择 **关闭所有** ,退出文件管理器。 +- 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg),选择 **退出**,退出文件管理器。 + +### 查看快捷键 + +在文件管理器界面,使用快捷键 **Ctrl + Shift + /** 打开快捷键预览界面。熟练地使用快捷键,将大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主界面 + +文件管理器的主界面简单易用、功能全面,熟练地使用界面功能将使文件管理更加简单高效。 + +![1|main_interface](fig/e_main_interface.png) + + +| 标号 | 名称 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 导航栏 | 单击导航图标,快速访问本地文件、磁盘、网络邻居、书签、标记等。 | +| 2 | 地址栏 | 通过地址栏,您可以快速切换访问历史、在上下级目录间切换、搜索、输入地址访问。 | +| 3 | 图标/列表视图 | 单击 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg) 图标,以图标或列表形式查看文件(夹)。 | +| 4 | 信息栏 | 单击 ![fileinfo](../common/fileinfo.svg), 查看文件(夹)的基本信息和标记。 | +| 5 | 菜单栏 | 通过主菜单,您可以新建窗口、切换窗口主题、设置共享密码、设置文件管理器、查看帮助文档和关于信息、退出文件管理器。 | +| 6 | 状态栏 | 显示文件数量或者已选中文件的数量。 | + + +> ![tips](../common/tips.svg) 窍门:可拖动左侧导航栏右边的分隔线来改变其宽度。 + +## 基本功能 + +文件管理器具备基本的文件管理功能,对文件(夹)进行新建、复制、重命名、删除等操作都非常简单。 + +### 新建文件 + +#### 新建文档 + +1. 在文件管理器空白区域,单击鼠标右键。 +2. 选择 **新建文档**。 +3. 在下拉菜单中选择新建文件的类型。 +4. 输入新建文件的名称。 + +![0|newdo](fig/e_newdo.png) + +#### 新建文件夹 + +1. 在文件管理器空白区域,单击鼠标右键。 +2. 选择 **新建文件夹**。 +3. 输入新建文件夹的名称。 + +### 重命名文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **重命名**。 +3. 输入文件名称,按 **Enter** 键或者单击界面空白区域。 + +![1|rename](fig/d_rename.png) + +> ![tips](../common/tips.svg) 窍门:在 **设置** 中勾选“重命名时隐藏文件扩展名”,能更方便地修改文件名称。 + +### 批量重命名 + +1. 在文件管理器界面,选中多个文件。 +2. 右击文件,并选择 **重命名**。 + - **替换文本** 查找需要替换的文本,并输入替换后的文本,文件名中的关键字将被统一替换。 + - **添加文本** 输入需要添加的文本,并选择位置是名称之前还是之后,文件名将统一加入被添加的文本。 + - **自定义文本** 输入文件名,并输入序列的递进数字,文件名将统一改成新文件名+递进数字。 +4. 单击 **重命名** 来完成操作。 + +![1|rename](fig/e_batch_rename.png) + +### 查看文件 + +单击菜单栏上的图标 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 来切换图标视图和列表视图。 + +- 图标视图:平铺显示文件的名称、图标或缩略图。 + +![1|icon_view](fig/e_iconview.png) + +- 列表视图:列表显示文件图标或缩略图、名称、修改时间、大小、类型等信息。 + +![1|list_view](fig/e_listview.png) + +> ![tips](../common/tips.svg) 窍门: +> - 在列表视图中,把光标置于两列之间的分隔线上,拖动它来改变列的宽度;双击分隔线可将当前列自动调整为本列内容最宽的宽度。 +> - 使用快捷键 **Ctrl + 1** 和 **Ctrl + 2**,切换图标视图和列表视图。 + + +### 排序文件 + +1. 在文件管理器界面,单击鼠标右键。 +2. 选择 **排序方式**。 +3. 在子菜单中选择以名称、修改时间、大小或类型来排序文件。 + +> ![tips](../common/tips.svg) 窍门:在列表视图中,单击表头栏的列标签来切换升序、降序。 + +### 打开文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **打开方式** > **选择默认程序**。 +3. 在程序列表中选择应用程序。 + +> ![notes](../common/notes.svg) 说明:直接双击文件会使用默认程序打开。您可以选择相同类型的多个文件,右键选择 **打开方式** 选项,同时打开多个文件。 + +![0|open](fig/d_open.png) + + + +### 隐藏文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **属性**,勾选 **隐藏此文件**。 + +### 复制文件 + +1. 在文件管理器界面,右键单击文件。 +2. 单击 **复制**。 +3. 选择一个目标存储位置。 +4. 单击鼠标右键,然后选择 **粘贴**。 + +### 压缩文件 + +1. 在文件管理器界面,右键单击文件(夹)。 +2. 选择 **压缩**。 +3. 弹出归档管理器压缩界面,可以设置压缩包格式、名称、存储路径等,单击 **压缩**。 + +> ![tips](../common/tips.svg) 窍门:您也可以直接在右键菜单中选择 **添加到xxx.7z** 或 **添加到xxx.zip**,快速将文件(夹)压缩成7z或zip格式。 + +### 删除文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **删除** 。 + - 被删除的文件可以在回收站中找到,右键单击回收站中的文件可以进行 **还原** 或 **删除** 操作。 + - 被删除的文件的快捷方式将会失效。 + +> ![attention](../common/attention.svg)注意:外接设备删除文件会将文件彻底删除,无法从回收站找回。 + +### 撤销操作 + +在文件管理器中,可以用 **Ctrl + Z** 来撤销上一步操作,包括: + +- 删除新建的文件。 +- 恢复重命名(包括重命名文件后缀)之前的名字。 +- 从回收站还原刚删除的文件。 +- 恢复文件到移动(剪切移动、鼠标移动)前的原始路径。 +- 删除复制粘贴的文件。 + +>![attention](../common/attention.svg) 注意:撤销动作最多只能返回两步;如果操作中有覆盖某个同名文件和彻底删除文件,则撤销只能返回到这一步。 + +### 文件属性 + +文件属性会显示文件的基本信息,打开方式和权限设置。文件夹属性会显示文件夹的基本信息,共享信息和权限设置。 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **属性**,查看文件属性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg)说明:查看多个文件属性会显示文件总大小和数量;查看快捷方式的属性将会额外显示源文件地址。您还可以使用 **Ctrl + I** 组合键查看文件属性。 + + + +## 常用操作 + +文件管理器具备很多特色功能,这些功能都让文件管理更加简单、高效。 + +### 切换地址栏 + +地址栏由历史导航、面包屑和输入框共同组成,通常情况下地址栏显示面包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 单击历史导航按钮,可以快速在历史浏览记录间切换,查看前一个地址或者后一个地址。 +- 文件所在位置的每一个层级都会形成一个面包屑,通过来回单击面包屑可以快速在不同文件层级间切换。 + +单击搜索按钮,或者在文件路径上右键单击并选择 **编辑地址**,地址栏会切换为输入框状态。在输入框外单击时,地址栏会自动恢复到面包屑状态。 + +![0|addressbar](fig/addressbar2.png) + +- 输入框带有智能识别功能,输入关键字或者访问地址,系统会自动识别并进行搜索或访问。 + +### 搜索文件 + +文件管理器支持多种检索方式,既支持通过文件名称、文件内容进行普通搜索,也支持通过文件类型、创建时间等进行高级搜索,提高工作效率,便于文件管理。 + +- 指定目录搜索时,请先进入该目录,然后再进行搜索。 + +> ![notes](../common/notes.svg) 说明:在文件管理器的 **设置** 中,默认勾选了“自动索引内置磁盘”,您可以选择勾选“连接电脑后索引外部存储设备”,加快在外部设备的搜索速度。 + +#### 全文搜索 + +您可以通过文件内容关键字来搜索文件。 +1. 在文件管理器中,单击 ![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在高级设置项勾选“全文搜索”来开启此功能。 +3. 使用快捷键 **Ctrl + F** 或在地址栏中单击搜索按钮进入搜索状态,输入关键字后按下键盘上的 **Enter** 键,搜索相关文件。 + +#### 高级搜索 + +当文件较多,搜索较慢时,启用高级搜索缩小搜索范围,提高搜索效率。 +1. 在搜索状态下,输入关键字后按 **Enter** 键,当搜索到结果时,搜索框右侧显示图标 ![filter](../common/filter.svg),单击该图标可进行高级搜索的操作。 +2. 选择搜索范围、文件大小、文件类型、修改时间、访问时间和创建时间,进行更精准的搜索。 + +![0|filter](fig/e_filter.png) + + +### 最近使用 + +在左侧导航栏上默认有 **最近使用** 入口,单击可以查看最近使用的文件。文件默认按照访问时间倒序排列。 + +> ![notes](../common/notes.svg)说明:若想隐藏“最近使用”,可在 **设置** > **基本设置** > **隐藏文件**,取消勾选“显示最近使用文件”。若要隐藏某一个文件的访问记录,右键单击该文件选择 **移除**,该操作不会删除文件。 + +### 多标签页 + +文件管理器支持多标签页显示。 + +1. 在文件管理器界面上,右键单击文件夹。 +2. 选择 **在新标签中打开**。 +3. 当窗口有多个标签页时,可以: + - 单击标签页右侧的按钮 + ,继续添加标签页。 + - 将鼠标指针置于标签页上,单击关闭按钮 × 或单击鼠标中键,关闭标签页。 + + ![1|tab](fig/e_tab.png) + +> ![tips](../common/tips.svg) 窍门:文件管理器窗口只有一个标签时,标签栏是隐藏的,您还可以使用快捷键 **Ctrl** + **T** 来新建标签。 + +### 书签管理 + +为常用文件夹添加书签,以便从左侧导航栏快速访问。 + +- 添加书签:右键单击文件夹,选择 **添加书签** 在导航栏创建书签。 +- 移动书签:在导航栏上下拖动书签调整排序。 +- 删除书签:右键单击书签,选择 **移除** 来删除书签;或右键单击已添加书签的文件夹,选择 **移除书签** 来删除书签。 + +### 标记信息 + +通过给文件(夹)添加标记,可以更好地分类管理您的文件。 + +> ![notes](../common/notes.svg) 说明:仅x86平台支持标记信息功能。 + +#### 添加标记 + +您可以为一个文件(夹)添加多个标记,也可以同时为多个文件(夹)添加标记;添加成功的标记会出现在左侧导航栏内。 + +##### 通过编辑框添加标记 + +1. 右键单击文件(夹),选择 **标记信息**。 +2. 输入标记名称,若要添加多个标记,可用逗号分隔。 +3. 单击界面空白区域保存设置。 + +>![notes](../common/notes.svg) 说明:标记颜色从8种默认颜色中随机分配。 + +![1|tag_info](fig/e_tag_info.png) + + +##### 通过颜色按钮添加标记 + +右键单击文件(夹),选择颜色按钮,直接生成这个颜色的标记。 + +![1|color_tag](fig/e_color_tag.png) + +##### 通过右侧信息栏添加标记 + +选择文件(夹)后,单击菜单栏上的图标 ![fileinfo](../common/fileinfo.svg),在右侧信息栏中也可以添加标记。 + +![1|info_tag](fig/e_info_tag.png) + +>![notes](../common/notes.svg) 说明:如果文件有标记,则复制或剪切该文件产生的文件仍然具有同样的标记。 + + +#### 重命名标记 + +在侧边导航栏中,右键单击某个标记,选择 **重命名**,修改当前标记的名称。 + +![1|rename_tag](fig/rename_tag.png) + +#### 修改标记颜色 + +在左侧导航栏中,右键单击某个标记,选择颜色按钮,即可修改当前标记的颜色。 + +#### 排序标记 + +上下拖动标记即可调整标记排序。 + +#### 删除标记 + +右键单击某个标记,选择 **移除**,删除当前标记。 + + +### 文件预览 + +文件管理器支持空格键预览功能,选中文件并按下键盘上的空格键可以快速预览文件。在预览窗口中可以查看图片分辨率、文档大小、文本内容等,还支持gif、音频、视频播放。 + +#### 预览视频 + +1. 选择您要预览的视频文件,按下空格键,即可开始预览。 +2. 单击视频任意地方可暂停播放。 +3. 播放过程中,可以拖动进度条来快进快退。 +4. 单击底部 **打开** 按扭,在默认程序中打开该视频文件。 + +![1|video_preview](fig/video_preview.png) + +> ![notes](../common/notes.svg) 说明:您也可以同时选择多个文件,按下空格键进行预览。 + + +### 权限管理 + +选择对应文件(夹),单击右键,选择属性,单击 **权限管理**, 为所有者、群组和其他用户设置文件权限。 + +![2|permission](fig/permission.png) + +### 我的共享 + +当您设置了共享文件时,“我的共享”会出现在导航栏上。取消所有共享文件后,“我的共享”自动从导航栏中移除。 + +#### 共享本地文件 + +1. 在文件管理器界面,右键单击文件夹。 +2. 选择 **共享文件夹**。 +3. 在文件夹的属性窗口,勾选 **共享此文件夹**。 +4. 根据需要设置 **共享名**、**权限**、**匿名访问** 后关闭窗口。 +5. 单击 ![icon_menu](../common/icon_menu.svg) > **设置共享密码**。 +7. 在弹窗中输入共享密码,单击 **确定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg) 窍门:取消勾选 **共享此文件夹** 可以取消文件共享,也可以右键单击文件,选择 **取消共享**。 + + +#### 访问共享文件 + +局域网中其他用户共享的文件都可以在网络邻居中找到,您也可以通过smb访问共享文件。 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **连接到服务器**,在编辑框中输入服务器地址,如:smb://xx.x.xx.xxx(一般为IP地址),单击 **连接**;或者直接在地址栏中输入服务器地址,按下键盘上的 **Enter** 键。 +2. 选择需要访问的共享文件夹,在弹出的窗口中输入用户名和共享密码,或者匿名访问。 + - 未加密的共享文件可以匿名访问,不需要输入用户名和密码。 + - 加密的共享文件需要输入用户名和密码之后才能访问。 + + - 用户名:共享者登录系统的用户名。 + - 密码:共享文件时设置的共享密码。 +3. 单击 **连接**。 + +![1|visitshareshare](fig/visitshare.png) + + + +### 在终端中打开 + +1. 在文件管理器中,单击鼠标右键。 +2. 选择 **在终端中打开**,会启动终端应用程序,终端的路径为当前目录。 + +![0|open_terminal](fig/e_open_terminal.png) + +### 刻录光盘 + +您可以通过刻录功能将音乐、视频、图片或镜像文件复制到光盘中。请提前准备一部刻录机、一张CD或DVD光盘。 + +1. 将光盘插入到刻录机中。 +2. 打开文件管理器,单击导航栏中的光盘图标,进入刻录CD的界面。 + +![cd](fig/e_cd_interface.png) + +3. 右键单击 文件(夹),选择 **添加至光盘刻录** 或直接将文件(夹)拖拽到刻录CD的界面。 +4. 在刻录CD界面,单击右上角按钮 **刻录**。 + + >![notes](../common/notes.svg) 说明:如果要从刻录列表中删除某个文件(夹),右键单击该文件(夹),选择 **删除**,将该文件(夹)从列表中移除。 + +5. 在弹窗中输入光盘名称。您也可以进入 **高级设置** 界面,设置文件系统、写入速度,或勾选“允许追加数据”、“核验数据”等,单击 **刻录**。 + +![cd](fig/e_cd_rename.png) + +6. 刻录完成后界面弹出提示框,单击 **确定**。 + +>![notes](../common/notes.svg) 说明: +>- 当前系统仅支持对ISO9660格式的文件进行读取与刻录,而UDF格式的文件只支持读取,暂不支持刻录。 +>- 如果需要擦除光盘数据,可以右键单击导航栏中光盘图标,选择 **卸载**,再次右键单击该光盘图标并选择 **擦除**。 + +### 创建快捷方式 + +1. 在文件管理器界面,右键单击文件(夹)。 +2. 选择 **创建链接**。 +3. 在弹窗中选择创建位置、链接名称。 +4. 单击 **保存**,在目标位置会生成该文件(夹)的快捷方式。 + +> ![tips](../common/tips.svg) 窍门:选择 **发送到桌面** 可以直接在桌面上生成该文件(夹)的快捷方式。 + +### 发送文件(夹)到外接磁盘 + +当有外接磁盘接入时,您可以将文件或文件夹发送到外接磁盘。 + +1. 在文件管理器界面,右键单击需要发送的文件(夹)。 +2. 选择 **发送到** > 外接磁盘。 +3. 文件(夹)将会被发送到移动外接磁盘。 + + + +## 文件角标 + +您可以通过命令行,将图标文件指定给一个文件或文件夹作为角标显示出来。 + +>![icon](../common/notes.svg)说明: +>- 角标文件支持svg、jpg、png、bmp、gif格式,且大小不超过100KB。 +>- U盘及光盘下的文件,不支持添加角标。 + +### 添加单个角标 + +1. 在终端输入命令 **gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径)"** ,该命令默认在文件(夹)右下角添加角标。 + + >![icon](../common/attention.svg)注意:系统已定义的特殊角标,不支持被替换。 + +2. 您也可以在上述命令中加入位置参数,将角标添加在文件(夹)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + + 例如:在文件(夹)左上角添加角标 + + **gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径);lu"** + +![mark](fig/single.png) + +### 添加多个角标 + +在命令行中加入“**|**”符号将角标文件路径链接起来,为文件(夹)添加2~4个角标。文件(夹)同一个位置不支持叠加角标,仅支持替换。 + +例如:在文件(夹)四个角都添加角标 + +**gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径);lu|xxx(图标路径);ld|xxx(图标路径);ru|xxx(图标路径);rd"** + +![mark](fig/multi.png) + +### 撤销角标 + +在终端中输入命令 **gio set xxx(文件路径) -t stringv metadata::emblems ""** 撤销文件(夹)上所有的角标。 + + + +## 文件保险箱 + +文件保险箱旨在为您打造专属的安全空间,为您的隐私保驾护航。先进的加密技术,便捷的操作流程,使用起来得心应手。 + +### 设置保险箱密码 + +首次使用保险箱需要对其进行密码设置,具体步骤如下: + +1. 单击导航栏中的保险箱图标 ![file_vault](../common/file_vault.svg),或者在计算机界面双击 **我的保险箱**,在弹窗中单击 **开启**。 +2. 设置解锁类型、保险箱密码等,单击 **下一步**。 + +![0|password](fig/password.png) + + > ![notes](../common/notes.svg)说明: 密码必须同时包含大写字母、小写字母、数字和符号,且字符不小于8位,否则无法进入下一步。 + +3. 此时保险箱密码生成密钥,请将密钥备份,若忘记密码,可用密钥重新访问保险箱,单击 **下一步**。 +4. 单击 **加密保险箱**,弹出密码认证窗口,输入用户登录密码后单击 **确定**。 + +![encrypt](fig/encrypt.png) + +5. 在加密完成对话框中单击 **确定**, 完成保险箱密码设置。 + + + +### 锁上保险箱 + +将文件放入保险箱后,右键单击 ![file_vault](../common/file_vault.svg) 或者在计算机界面右键单击 **我的保险箱**。 +- 选择 **立即上锁**,立即将文件保险箱锁上。 +- 选择 **自动上锁**,在其下拉列表进行设置: + + 选择“从不”,计算机在锁屏或关机前一直保持未上锁状态。 + + 选择“5分钟”、“10分钟”或者“20分钟”后自动上锁保险箱。 + +![0|right](fig/right.png) + + +### 解锁保险箱 + +右键单击 ![file_vault](../common/file_vault.svg) 或者计算机界面 **我的保险箱**。 + +- 选择 **解锁**,在弹窗中输入保险箱密码,单击 **解锁**。 +- 选择 **密钥解锁**,在弹窗中输入32位密钥,单击 **解锁**。 +>![0|tips](../common/tips.svg)窍门:您也可以单击![file_vault](../common/file_vault.svg) 或者双击计算机界面 **我的保险箱**,直接使用密码解锁保险箱。 + + +### 删除保险箱 + +删除保险箱需要提前解锁保险箱。 +1. 右键单击 ![file_vault](../common/file_vault.svg) 或者 **我的保险箱**,选择 **删除保险箱**。 +2. 弹出删除保险箱窗口,输入保险箱密码,单击 **删除**。 +3. 在认证窗口中输入用户登录密码,单击 **确定** 完成操作。 +> ![attention](../common/attention.svg)注意:删除保险箱会将里面的文件一并删除。在进行删除操作前,请将保险箱中的文件备份。 + +## 磁盘管理 + +文件管理器管理本地磁盘和外接磁盘。本地磁盘显示在文件管理器的左侧导航栏上或计算机界面;挂载外接磁盘或者插入其他移动存储设备时,也会在导航栏看到相应的磁盘图标。 + + + + + + + + + + + + + + + + + +
本地磁盘本地硬盘分区的所有磁盘
外接磁盘包括移动硬盘、U盘、光盘
移动设备手机内存、存储卡、SD卡等
+ + + +> ![notes](../common/notes.svg)说明:如果磁盘或磁盘中的文件夹已加密,请输入密码后查看文件。 + +### 本地磁盘 + +#### 隐藏本地磁盘 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在高级设置选项中勾选 **隐藏系统盘**。 + +#### 重命名本地磁盘 + +1. 在左侧导航栏或计算机界面,右键单击本地磁盘。 +2. 选择 **重命名**。 +3. 输入新名称,按下键盘上的 **Enter** 键或单击空白处保存修改。 + +> ![tips](../common/tips.svg)窍门:在计算机界面,慢速双击本地磁盘,呈现编辑框后便可进行重命名操作。 + +![0|disk](fig/e_rename_disk.png) + +### 外接磁盘 + +#### 弹出外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要移除的磁盘。 +2. 选择 **安全移除**。 +3. 磁盘将从磁盘列表中删除,一并弹出该磁盘的所有分区。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg)窍门:如果要弹出光盘,请选择 **弹出** 来移除光盘。单击导航栏中磁盘右边的按钮 ![unmount](../common/unmount_normal.svg) 同样可以弹出磁盘或光盘。 + +#### 重命名外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要重命名的磁盘。 +2. 选择 **卸载**后,再次单击右键选择 **重命名**。 +3. 输入新的卷标名称,按下键盘上的 **Enter** 键或单击空白处保存修改。 + + + +#### 格式化外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要格式化的磁盘。 +2. 选择 **卸载** 后,再次单击右键选择 **格式化**。 +3. 设置格式化之后的文件类型和卷标。 +4. 单击 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg)说明:快速格式化速度快,但是数据仍然可能通过工具被恢复,如果想要格式化后的数据无法被恢复,可以取消勾选“快速格式化”,然后执行格式化操作。 + +## 主菜单 + +在主菜单中,您可以新建窗口、切换窗口主题、连接到服务器、[设置共享密码](#共享本地文件)、设置文件管理器、查看帮助手册和版本介绍。 + +### 新建窗口 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **新建窗口**,打开一个新的文件管理器窗口。 + +### 连接到服务器 + +通过连接服务器 [访问局域网共享文件](#访问共享文件)。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **连接到服务器**,在编辑框中输入服务器IP地址。 + - 单击 ![+](../common/+.svg) 按钮可将该地址添加到“个人收藏服务器”列表中。 + - 在“个人收藏服务器”列表中选中一个地址,单击 ![_](../common/-.svg) 按钮,将该地址从收藏列表中移除。 +3. 单击 **连接**。 + +![conncet](fig/connect_to_server.png) + + +### 设置 + +#### 基础设置 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)> **设置** 。 +2. 选择 **基础设置** 选项。 + + 勾选 **总是在新窗口打开文件夹**。 + + 设置双击或单击打开文件。 + + 设置 **从默认窗口打开**、**从新标签打开**哪个目录。 + + 设置文件图标 **默认大小** 。 + + 设置 **默认视图** 以图标展示或列表展示。 + + 勾选 **显示隐藏文件**,文件管理器中被隐藏的文件会显示出来。 + + 勾选 **重命名时隐藏文件扩展名**,重命名时不会显示扩展名。 + + 勾选 **显示最近使用文件**,在左侧导航栏显示最近使用的文件。 + +#### 高级设置 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)> **设置** 。 +2. 选择 **高级设置** 选项。 + + 勾选 **自动索引内置磁盘**,搜索文件时会搜索内置磁盘中的文件。 + + 勾选 **连接电脑后索引外部存储设备**,搜索文件时也会搜索外接设备中的文件。 + + 勾选 **全文搜索**,通过文件中的内容来索引。 + + 勾选预览文件类型。 + + 勾选 **自动挂载**,接入外接磁盘时自动挂载。 + + 勾选 **自动挂载后打开**,接入外接磁盘时自动挂载并打开该磁盘。 + + 勾选 **使用文件管理器的文件选择对话框**,选择文件时打开文件管理器窗口。 + + 勾选 **开启普通删除提示**,删除文件时弹出提示对话框。 + + 勾选 **隐藏系统盘**,导航栏和计算机界面将不显示本地磁盘。 + + 勾选 **在磁盘图标上显示文件系统标签**。 + + +### 主题 + +窗口主题包含浅色主题、深色主题和跟随系统主题。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **主题**,选择一个主题。 + +### 帮助 + +查看帮助手册,进一步了解和使用文件管理器。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **帮助**。 +3. 查看文件管理器的帮助手册。 + + +### 关于 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **关于**。 +3. 查看文件管理器的版本和介绍。 + + +### 退出 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **退出**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/addressbar1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/addressbar1.png new file mode 100755 index 0000000..5984a0c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/addressbar1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/addressbar2.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/addressbar2.png new file mode 100755 index 0000000..afc1b01 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/addressbar2.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/batch_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/batch_rename.png new file mode 100755 index 0000000..b16db1f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/batch_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/cd_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/cd_interface.png new file mode 100755 index 0000000..3793b74 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/cd_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/cd_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/cd_rename.png new file mode 100644 index 0000000..482a94a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/cd_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/connect_to_pc.jpg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/connect_to_pc.jpg new file mode 100755 index 0000000..e571dd0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/connect_to_pc.jpg differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/connect_to_pc.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/connect_to_pc.png new file mode 100644 index 0000000..8635ad7 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/connect_to_pc.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/connect_to_server.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/connect_to_server.png new file mode 100755 index 0000000..c41df59 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/connect_to_server.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_cd_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_cd_interface.png new file mode 100755 index 0000000..7d57220 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_cd_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_cd_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_cd_rename.png new file mode 100755 index 0000000..be3330c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_cd_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_colortag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_colortag.png new file mode 100755 index 0000000..78f0f47 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_colortag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_infotag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_infotag.png new file mode 100755 index 0000000..18e8799 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_infotag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_open.png new file mode 100755 index 0000000..7549026 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_rename.png new file mode 100755 index 0000000..f20dba9 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_rename_disk.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_rename_disk.png new file mode 100755 index 0000000..9e0064a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_rename_disk.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_tab.png new file mode 100644 index 0000000..03299dd Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_taginfo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_taginfo.png new file mode 100755 index 0000000..482624d Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/d_taginfo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/disk1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/disk1.png new file mode 100755 index 0000000..695ef25 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/disk1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/disk2.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/disk2.png new file mode 100755 index 0000000..f5e39de Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/disk2.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_batch_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_batch_rename.png new file mode 100644 index 0000000..34387c2 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_batch_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_cd_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_cd_interface.png new file mode 100755 index 0000000..54685bc Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_cd_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_cd_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_cd_rename.png new file mode 100755 index 0000000..cd3cddf Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_cd_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_color_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_color_tag.png new file mode 100644 index 0000000..86a1137 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_color_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_filter.png new file mode 100755 index 0000000..5f3985b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_iconview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_iconview.png new file mode 100755 index 0000000..ea014ed Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_iconview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_info_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_info_tag.png new file mode 100644 index 0000000..7190ef0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_info_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_listview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_listview.png new file mode 100755 index 0000000..efc0bfa Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_listview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_main_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_main_interface.png new file mode 100755 index 0000000..e7ab2ce Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_main_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_newdo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_newdo.png new file mode 100755 index 0000000..18f4c52 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_newdo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_open.png new file mode 100755 index 0000000..75880d0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_open_terminal.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_open_terminal.png new file mode 100755 index 0000000..8d19e86 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_open_terminal.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_overview.png new file mode 100755 index 0000000..b0bcddf Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_rename.png new file mode 100755 index 0000000..49ae32f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_rename_disk.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_rename_disk.png new file mode 100755 index 0000000..bcc7cdc Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_rename_disk.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_tab.png new file mode 100755 index 0000000..d4c567b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_tag_info.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_tag_info.png new file mode 100644 index 0000000..bde5b2a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/e_tag_info.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/encrypt.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/encrypt.png new file mode 100644 index 0000000..2df3520 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/encrypt.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/filter.png new file mode 100755 index 0000000..b82360a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/finish.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/finish.png new file mode 100644 index 0000000..70e3ab1 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/finish.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/found.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/found.png new file mode 100644 index 0000000..5d7a09a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/found.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/hotkey.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/hotkey.png new file mode 100755 index 0000000..6a728f1 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/hotkey.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/iconview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/iconview.png new file mode 100755 index 0000000..edc0d19 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/iconview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/info.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/info.png new file mode 100755 index 0000000..4171cbb Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/info.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/listview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/listview.png new file mode 100755 index 0000000..7d47d03 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/listview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/login.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/login.png new file mode 100644 index 0000000..d02667b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/login.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/main_introduce.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/main_introduce.png new file mode 100755 index 0000000..9840331 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/main_introduce.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/multi.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/multi.png new file mode 100644 index 0000000..23aab44 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/multi.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/myphone.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/myphone.png new file mode 100644 index 0000000..d6a5e4d Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/myphone.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/myphone1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/myphone1.png new file mode 100644 index 0000000..e20f40b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/myphone1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/newdo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/newdo.png new file mode 100755 index 0000000..70cea24 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/newdo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/open.png new file mode 100755 index 0000000..ebc4e75 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/open_terminal.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/open_terminal.png new file mode 100755 index 0000000..cd3e6eb Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/open_terminal.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/overview.png new file mode 100755 index 0000000..39010d0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_batch_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_batch_rename.png new file mode 100644 index 0000000..74b26de Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_batch_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_color_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_color_tag.png new file mode 100644 index 0000000..f9d81cf Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_color_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_filter.png new file mode 100644 index 0000000..7e0645c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_iconview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_iconview.png new file mode 100644 index 0000000..25a7db2 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_iconview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_info_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_info_tag.png new file mode 100644 index 0000000..f712069 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_info_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_listview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_listview.png new file mode 100644 index 0000000..5ee80a9 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_listview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_main_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_main_interface.png new file mode 100644 index 0000000..b1f018c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_main_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_main_interface.psd b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_main_interface.psd new file mode 100644 index 0000000..35ddb81 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_main_interface.psd differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_overview.png new file mode 100644 index 0000000..d6afa9c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_rename_disk.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_rename_disk.png new file mode 100644 index 0000000..c0d41ad Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_rename_disk.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_share.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_share.png new file mode 100755 index 0000000..934ffdc Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_share.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_tab.png new file mode 100644 index 0000000..15da2e2 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_tag_info.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_tag_info.png new file mode 100644 index 0000000..9897f30 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/p_tag_info.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/password.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/password.png new file mode 100644 index 0000000..e218157 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/password.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/permission.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/permission.png new file mode 100755 index 0000000..9ff1530 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/permission.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/phone_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/phone_interface.png new file mode 100755 index 0000000..e53ed3f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/phone_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/rename.png new file mode 100755 index 0000000..55d3ea1 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/rename_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/rename_tag.png new file mode 100755 index 0000000..4a7c9e9 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/rename_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/right.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/right.png new file mode 100755 index 0000000..0c8bac5 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/right.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/save.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/save.png new file mode 100644 index 0000000..5586d71 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/save.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/share.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/share.png new file mode 100755 index 0000000..b93ff23 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/share.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/single.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/single.png new file mode 100644 index 0000000..0c1ddce Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/single.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/success.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/success.png new file mode 100755 index 0000000..c04aeb2 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/success.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/tab.png new file mode 100755 index 0000000..df698a5 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/unlock.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/unlock.png new file mode 100644 index 0000000..865e127 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/unlock.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/uos1.jpg b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/uos1.jpg new file mode 100755 index 0000000..5a1ec07 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/uos1.jpg differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/uos2.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/uos2.png new file mode 100644 index 0000000..df39d52 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/uos2.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/video_preview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/video_preview.png new file mode 100755 index 0000000..ccaf00f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/video_preview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/visitshare.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/visitshare.png new file mode 100755 index 0000000..0fd2037 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/visitshare.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/wireless_delivery.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/wireless_delivery.png new file mode 100755 index 0000000..dd4261b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/wireless_delivery.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/wireless_delivery1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/wireless_delivery1.png new file mode 100644 index 0000000..1b31162 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/fig/wireless_delivery1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/i_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/i_file-manager.md new file mode 100755 index 0000000..c7e7781 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/i_file-manager.md @@ -0,0 +1,664 @@ +# 文件管理器|dde-file-manager| + +## 概述 + +文件管理器是一款功能强大、简单易用的文件管理工具。它沿用了传统文件管理器的经典功能和布局,并在此基础上简化了用户操作,增加了很多特色功能。一目了然的导航栏、智能识别的搜索框、多样化的视图及排序让您管理起来得心应手,经典和超越,只为给您更好的体验! + +![1|overview](fig/e_overview.png) + +## 使用入门 + +通过以下方式运行或关闭文件管理器,或者创建文件管理器的快捷方式。 + +### 运行文件管理器 + +1. 单击任务栏上的启动器图标 ![deepin_launcher ](../common/deepin_launcher.svg),进入启动器界面。 +2. 上下滚动鼠标滚轮浏览或通过搜索,找到文件管理器图标 ![deepin_file_manager](../common/deepin_file_manager.svg),单击运行。 +3. 右键单击 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 单击 **发送到桌面**,在桌面创建快捷方式。 + - 单击 **发送到任务栏**,将应用程序固定到任务栏。 + - 单击 **开机自动启动**,将应用程序添加到开机启动项,在电脑开机时自动运行该应用。 + +> ![tips](../common/tips.svg) 窍门:您也可以使用快捷键 **Super + E** 启动文件管理器。 + +### 关闭文件管理器 + +- 在文件管理器界面,单击 ![close_icon](../common/close_icon.svg),退出文件管理器。 +- 在任务栏右键单击 ![deepin_file_manager](../common/deepin_file_manager.svg),选择 **关闭所有** ,退出文件管理器。 +- 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg),选择 **退出**,退出文件管理器。 + +### 查看快捷键 + +在文件管理器界面,使用快捷键 **Ctrl + Shift + /** 打开快捷键预览界面。熟练地使用快捷键,将大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主界面 + +文件管理器的主界面简单易用、功能全面,熟练地使用界面功能将使文件管理更加简单高效。 + +![1|main_interface](fig/e_main_interface.png) + + +| 标号 | 名称 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 导航栏 | 单击导航图标,快速访问本地文件、磁盘、网络邻居、书签、标记等。 | +| 2 | 地址栏 | 通过地址栏,您可以快速切换访问历史、在上下级目录间切换、搜索、输入地址访问。 | +| 3 | 图标/列表视图 | 单击 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg) 图标,以图标或列表形式查看文件(夹)。 | +| 4 | 信息栏 | 单击 ![fileinfo](../common/fileinfo.svg), 查看文件(夹)的基本信息和标记。 | +| 5 | 菜单栏 | 通过主菜单,您可以新建窗口、切换窗口主题、设置共享密码、设置文件管理器、查看帮助文档和关于信息、退出文件管理器。 | +| 6 | 状态栏 | 显示文件数量或者已选中文件的数量。 | + + +> ![tips](../common/tips.svg) 窍门:可拖动左侧导航栏右边的分隔线来改变其宽度。 + +## 基本功能 + +文件管理器具备基本的文件管理功能,对文件(夹)进行新建、复制、重命名、删除等操作都非常简单。 + +### 新建文件 + +#### 新建文档 + +1. 在文件管理器空白区域,单击鼠标右键。 +2. 选择 **新建文档**。 +3. 在下拉菜单中选择新建文件的类型。 +4. 输入新建文件的名称。 + +![0|newdo](fig/e_newdo.png) + +#### 新建文件夹 + +1. 在文件管理器空白区域,单击鼠标右键。 +2. 选择 **新建文件夹**。 +3. 输入新建文件夹的名称。 + +### 重命名文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **重命名**。 +3. 输入文件名称,按 **Enter** 键或者单击界面空白区域。 + +![1|rename](fig/d_rename.png) + +> ![tips](../common/tips.svg) 窍门:在 **设置** 中勾选“重命名时隐藏文件扩展名”,能更方便地修改文件名称。 + +### 批量重命名 + +1. 在文件管理器界面,选中多个文件。 +2. 右击文件,并选择 **重命名**。 + - **替换文本** 查找需要替换的文本,并输入替换后的文本,文件名中的关键字将被统一替换。 + - **添加文本** 输入需要添加的文本,并选择位置是名称之前还是之后,文件名将统一加入被添加的文本。 + - **自定义文本** 输入文件名,并输入序列的递进数字,文件名将统一改成新文件名+递进数字。 +4. 单击 **重命名** 来完成操作。 + +![1|rename](fig/e_batch_rename.png) + +### 查看文件 + +单击菜单栏上的图标 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 来切换图标视图和列表视图。 + +- 图标视图:平铺显示文件的名称、图标或缩略图。 + +![1|icon_view](fig/e_iconview.png) + +- 列表视图:列表显示文件图标或缩略图、名称、修改时间、大小、类型等信息。 + +![1|list_view](fig/e_listview.png) + +> ![tips](../common/tips.svg) 窍门: +> - 在列表视图中,把光标置于两列之间的分隔线上,拖动它来改变列的宽度;双击分隔线可将当前列自动调整为本列内容最宽的宽度。 +> - 使用快捷键 **Ctrl + 1** 和 **Ctrl + 2**,切换图标视图和列表视图。 + + +### 排序文件 + +1. 在文件管理器界面,单击鼠标右键。 +2. 选择 **排序方式**。 +3. 在子菜单中选择以名称、修改时间、大小或类型来排序文件。 + +> ![tips](../common/tips.svg) 窍门:在列表视图中,单击表头栏的列标签来切换升序、降序。 + +### 打开文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **打开方式** > **选择默认程序**。 +3. 在程序列表中选择应用程序。 + +> ![notes](../common/notes.svg) 说明:直接双击文件会使用默认程序打开。您可以选择相同类型的多个文件,右键选择 **打开方式** 选项,同时打开多个文件。 + +![0|open](fig/d_open.png) + + + +### 隐藏文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **属性**,勾选 **隐藏此文件**。 + +### 复制文件 + +1. 在文件管理器界面,右键单击文件。 +2. 单击 **复制**。 +3. 选择一个目标存储位置。 +4. 单击鼠标右键,然后选择 **粘贴**。 + +### 压缩文件 + +1. 在文件管理器界面,右键单击文件(夹)。 +2. 选择 **压缩**。 +3. 弹出归档管理器压缩界面,可以设置压缩包格式、名称、存储路径等,单击 **压缩**。 + +> ![tips](../common/tips.svg) 窍门:您也可以直接在右键菜单中选择 **添加到xxx.7z** 或 **添加到xxx.zip**,快速将文件(夹)压缩成7z或zip格式。 + +### 删除文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **删除** 。 + - 被删除的文件可以在回收站中找到,右键单击回收站中的文件可以进行 **还原** 或 **删除** 操作。 + - 被删除的文件的快捷方式将会失效。 + +> ![attention](../common/attention.svg)注意:外接设备删除文件会将文件彻底删除,无法从回收站找回。 + +### 撤销操作 + +在文件管理器中,可以用 **Ctrl + Z** 来撤销上一步操作,包括: + +- 删除新建的文件。 +- 恢复重命名(包括重命名文件后缀)之前的名字。 +- 从回收站还原刚删除的文件。 +- 恢复文件到移动(剪切移动、鼠标移动)前的原始路径。 +- 删除复制粘贴的文件。 + +>![attention](../common/attention.svg) 注意:撤销动作最多只能返回两步;如果操作中有覆盖某个同名文件和彻底删除文件,则撤销只能返回到这一步。 + +### 文件属性 + +文件属性会显示文件的基本信息,打开方式和权限设置。文件夹属性会显示文件夹的基本信息,共享信息和权限设置。 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **属性**,查看文件属性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg)说明:查看多个文件属性会显示文件总大小和数量;查看快捷方式的属性将会额外显示源文件地址。您还可以使用 **Ctrl + I** 组合键查看文件属性。 + + + +## 常用操作 + +文件管理器具备很多特色功能,这些功能都让文件管理更加简单、高效。 + +### 切换地址栏 + +地址栏由历史导航、面包屑和输入框共同组成,通常情况下地址栏显示面包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 单击历史导航按钮,可以快速在历史浏览记录间切换,查看前一个地址或者后一个地址。 +- 文件所在位置的每一个层级都会形成一个面包屑,通过来回单击面包屑可以快速在不同文件层级间切换。 + +单击搜索按钮,或者在文件路径上右键单击并选择 **编辑地址**,地址栏会切换为输入框状态。在输入框外单击时,地址栏会自动恢复到面包屑状态。 + +![0|addressbar](fig/addressbar2.png) + +- 输入框带有智能识别功能,输入关键字或者访问地址,系统会自动识别并进行搜索或访问。 + +### 搜索文件 + +文件管理器支持多种检索方式,既支持通过文件名称、文件内容进行普通搜索,也支持通过文件类型、创建时间等进行高级搜索,提高工作效率,便于文件管理。 + +- 指定目录搜索时,请先进入该目录,然后再进行搜索。 + +> ![notes](../common/notes.svg) 说明:在文件管理器的 **设置** 中,默认勾选了“自动索引内置磁盘”,您可以选择勾选“连接电脑后索引外部存储设备”,加快在外部设备的搜索速度。 + +#### 全文搜索 + +您可以通过文件内容关键字来搜索文件。 +1. 在文件管理器中,单击 ![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在高级设置项勾选“全文搜索”来开启此功能。 +3. 使用快捷键 **Ctrl + F** 或在地址栏中单击搜索按钮进入搜索状态,输入关键字后按下键盘上的 **Enter** 键,搜索相关文件。 + +#### 高级搜索 + +当文件较多,搜索较慢时,启用高级搜索缩小搜索范围,提高搜索效率。 +1. 在搜索状态下,输入关键字后按 **Enter** 键,当搜索到结果时,搜索框右侧显示图标 ![filter](../common/filter.svg),单击该图标可进行高级搜索的操作。 +2. 选择搜索范围、文件大小、文件类型、修改时间、访问时间和创建时间,进行更精准的搜索。 + +![0|filter](fig/e_filter.png) + + +### 最近使用 + +在左侧导航栏上默认有 **最近使用** 入口,单击可以查看最近使用的文件。文件默认按照访问时间倒序排列。 + +> ![notes](../common/notes.svg)说明:若想隐藏“最近使用”,可在 **设置** > **基本设置** > **隐藏文件**,取消勾选“显示最近使用文件”。若要隐藏某一个文件的访问记录,右键单击该文件选择 **移除**,该操作不会删除文件。 + +### 多标签页 + +文件管理器支持多标签页显示。 + +1. 在文件管理器界面上,右键单击文件夹。 +2. 选择 **在新标签中打开**。 +3. 当窗口有多个标签页时,可以: + - 单击标签页右侧的按钮 + ,继续添加标签页。 + - 将鼠标指针置于标签页上,单击关闭按钮 × 或单击鼠标中键,关闭标签页。 + + ![1|tab](fig/e_tab.png) + +> ![tips](../common/tips.svg) 窍门:文件管理器窗口只有一个标签时,标签栏是隐藏的,您还可以使用快捷键 **Ctrl** + **T** 来新建标签。 + +### 书签管理 + +为常用文件夹添加书签,以便从左侧导航栏快速访问。 + +- 添加书签:右键单击文件夹,选择 **添加书签** 在导航栏创建书签。 +- 移动书签:在导航栏上下拖动书签调整排序。 +- 删除书签:右键单击书签,选择 **移除** 来删除书签;或右键单击已添加书签的文件夹,选择 **移除书签** 来删除书签。 + +### 标记信息 + +通过给文件(夹)添加标记,可以更好地分类管理您的文件。 + +> ![notes](../common/notes.svg) 说明:仅x86平台支持标记信息功能。 + +#### 添加标记 + +您可以为一个文件(夹)添加多个标记,也可以同时为多个文件(夹)添加标记;添加成功的标记会出现在左侧导航栏内。 + +##### 通过编辑框添加标记 + +1. 右键单击文件(夹),选择 **标记信息**。 +2. 输入标记名称,若要添加多个标记,可用逗号分隔。 +3. 单击界面空白区域保存设置。 + +>![notes](../common/notes.svg) 说明:标记颜色从8种默认颜色中随机分配。 + +![1|tag_info](fig/e_tag_info.png) + + +##### 通过颜色按钮添加标记 + +右键单击文件(夹),选择颜色按钮,直接生成这个颜色的标记。 + +![1|color_tag](fig/e_color_tag.png) + +##### 通过右侧信息栏添加标记 + +选择文件(夹)后,单击菜单栏上的图标 ![fileinfo](../common/fileinfo.svg),在右侧信息栏中也可以添加标记。 + +![1|info_tag](fig/e_info_tag.png) + +>![notes](../common/notes.svg) 说明:如果文件有标记,则复制或剪切该文件产生的文件仍然具有同样的标记。 + + +#### 重命名标记 + +在侧边导航栏中,右键单击某个标记,选择 **重命名**,修改当前标记的名称。 + +![1|rename_tag](fig/rename_tag.png) + +#### 修改标记颜色 + +在左侧导航栏中,右键单击某个标记,选择颜色按钮,即可修改当前标记的颜色。 + +#### 排序标记 + +上下拖动标记即可调整标记排序。 + +#### 删除标记 + +右键单击某个标记,选择 **移除**,删除当前标记。 + + +### 文件预览 + +文件管理器支持空格键预览功能,选中文件并按下键盘上的空格键可以快速预览文件。在预览窗口中可以查看图片分辨率、文档大小、文本内容等,还支持gif、音频、视频播放。 + +#### 预览视频 + +1. 选择您要预览的视频文件,按下空格键,即可开始预览。 +2. 单击视频任意地方可暂停播放。 +3. 播放过程中,可以拖动进度条来快进快退。 +4. 单击底部 **打开** 按扭,在默认程序中打开该视频文件。 + +![1|video_preview](fig/video_preview.png) + +> ![notes](../common/notes.svg) 说明:您也可以同时选择多个文件,按下空格键进行预览。 + + +### 权限管理 + +选择对应文件(夹),单击右键,选择属性,单击 **权限管理**, 为所有者、群组和其他用户设置文件权限。 + +![2|permission](fig/permission.png) + +### 我的共享 + +当您设置了共享文件时,“我的共享”会出现在导航栏上。取消所有共享文件后,“我的共享”自动从导航栏中移除。 + +#### 共享本地文件 + +1. 在文件管理器界面,右键单击文件夹。 +2. 选择 **共享文件夹**。 +3. 在文件夹的属性窗口,勾选 **共享此文件夹**。 +4. 根据需要设置 **共享名**、**权限**、**匿名访问** 后关闭窗口。 +5. 单击 ![icon_menu](../common/icon_menu.svg) > **设置共享密码**。 +7. 在弹窗中输入共享密码,单击 **确定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg) 窍门:取消勾选 **共享此文件夹** 可以取消文件共享,也可以右键单击文件,选择 **取消共享**。 + + +#### 访问共享文件 + +局域网中其他用户共享的文件都可以在网络邻居中找到,您也可以通过smb访问共享文件。 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **连接到服务器**,在编辑框中输入服务器地址,如:smb://xx.x.xx.xxx(一般为IP地址),单击 **连接**;或者直接在地址栏中输入服务器地址,按下键盘上的 **Enter** 键。 +2. 选择需要访问的共享文件夹,在弹出的窗口中输入用户名和共享密码,或者匿名访问。 + - 未加密的共享文件可以匿名访问,不需要输入用户名和密码。 + - 加密的共享文件需要输入用户名和密码之后才能访问。 + + - 用户名:共享者登录系统的用户名。 + - 密码:共享文件时设置的共享密码。 +3. 单击 **连接**。 + +![1|visitshareshare](fig/visitshare.png) + + + +### 在终端中打开 + +1. 在文件管理器中,单击鼠标右键。 +2. 选择 **在终端中打开**,会启动终端应用程序,终端的路径为当前目录。 + +![0|open_terminal](fig/e_open_terminal.png) + +### 刻录光盘 + +您可以通过刻录功能将音乐、视频、图片或镜像文件复制到光盘中。请提前准备一部刻录机、一张CD或DVD光盘。 + +1. 将光盘插入到刻录机中。 +2. 打开文件管理器,单击导航栏中的光盘图标,进入刻录CD的界面。 + +![cd](fig/e_cd_interface.png) + +3. 右键单击 文件(夹),选择 **添加至光盘刻录** 或直接将文件(夹)拖拽到刻录CD的界面。 +4. 在刻录CD界面,单击右上角按钮 **刻录**。 + + >![notes](../common/notes.svg) 说明:如果要从刻录列表中删除某个文件(夹),右键单击该文件(夹),选择 **删除**,将该文件(夹)从列表中移除。 + +5. 在弹窗中输入光盘名称。您也可以进入 **高级设置** 界面,设置文件系统、写入速度,或勾选“允许追加数据”、“核验数据”等,单击 **刻录**。 + +![cd](fig/e_cd_rename.png) + +6. 刻录完成后界面弹出提示框,单击 **确定**。 + +>![notes](../common/notes.svg) 说明: +>- 当前系统仅支持对ISO9660格式的文件进行读取与刻录,而UDF格式的文件只支持读取,暂不支持刻录。 +>- 如果需要擦除光盘数据,可以右键单击导航栏中光盘图标,选择 **卸载**,再次右键单击该光盘图标并选择 **擦除**。 + +### 创建快捷方式 + +1. 在文件管理器界面,右键单击文件(夹)。 +2. 选择 **创建链接**。 +3. 在弹窗中选择创建位置、链接名称。 +4. 单击 **保存**,在目标位置会生成该文件(夹)的快捷方式。 + +> ![tips](../common/tips.svg) 窍门:选择 **发送到桌面** 可以直接在桌面上生成该文件(夹)的快捷方式。 + +### 发送文件(夹)到外接磁盘 + +当有外接磁盘接入时,您可以将文件或文件夹发送到外接磁盘。 + +1. 在文件管理器界面,右键单击需要发送的文件(夹)。 +2. 选择 **发送到** > 外接磁盘。 +3. 文件(夹)将会被发送到移动外接磁盘。 + + + +## 文件角标 + +您可以通过命令行,将图标文件指定给一个文件或文件夹作为角标显示出来。 + +>![icon](../common/notes.svg)说明: +>- 角标文件支持svg、jpg、png、bmp、gif格式,且大小不超过100KB。 +>- U盘及光盘下的文件,不支持添加角标。 + +### 添加单个角标 + +1. 在终端输入命令 **gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径)"** ,该命令默认在文件(夹)右下角添加角标。 + + >![icon](../common/attention.svg)注意:系统已定义的特殊角标,不支持被替换。 + +2. 您也可以在上述命令中加入位置参数,将角标添加在文件(夹)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + + 例如:在文件(夹)左上角添加角标 + + **gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径);lu"** + +![mark](fig/single.png) + +### 添加多个角标 + +在命令行中加入“**|**”符号将角标文件路径链接起来,为文件(夹)添加2~4个角标。文件(夹)同一个位置不支持叠加角标,仅支持替换。 + +例如:在文件(夹)四个角都添加角标 + +**gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径);lu|xxx(图标路径);ld|xxx(图标路径);ru|xxx(图标路径);rd"** + +![mark](fig/multi.png) + +### 撤销角标 + +在终端中输入命令 **gio set xxx(文件路径) -t stringv metadata::emblems ""** 撤销文件(夹)上所有的角标。 + + + +## 文件保险箱 + +文件保险箱旨在为您打造专属的安全空间,为您的隐私保驾护航。先进的加密技术,便捷的操作流程,使用起来得心应手。 + +### 设置保险箱密码 + +首次使用保险箱需要对其进行密码设置,具体步骤如下: + +1. 单击导航栏中的保险箱图标 ![file_vault](../common/file_vault.svg),或者在计算机界面双击 **我的保险箱**,在弹窗中单击 **开启**。 +2. 设置解锁类型、保险箱密码等,单击 **下一步**。 + +![0|password](fig/password.png) + + > ![notes](../common/notes.svg)说明: 密码必须同时包含大写字母、小写字母、数字和符号,且字符不小于8位,否则无法进入下一步。 + +3. 此时保险箱密码生成密钥,请将密钥备份,若忘记密码,可用密钥重新访问保险箱,单击 **下一步**。 +4. 单击 **加密保险箱**,弹出密码认证窗口,输入用户登录密码后单击 **确定**。 + +![encrypt](fig/encrypt.png) + +5. 在加密完成对话框中单击 **确定**, 完成保险箱密码设置。 + + + +### 锁上保险箱 + +将文件放入保险箱后,右键单击 ![file_vault](../common/file_vault.svg) 或者在计算机界面右键单击 **我的保险箱**。 +- 选择 **立即上锁**,立即将文件保险箱锁上。 +- 选择 **自动上锁**,在其下拉列表进行设置: + + 选择“从不”,计算机在锁屏或关机前一直保持未上锁状态。 + + 选择“5分钟”、“10分钟”或者“20分钟”后自动上锁保险箱。 + +![0|right](fig/right.png) + + +### 解锁保险箱 + +右键单击 ![file_vault](../common/file_vault.svg) 或者计算机界面 **我的保险箱**。 + +- 选择 **解锁**,在弹窗中输入保险箱密码,单击 **解锁**。 +- 选择 **密钥解锁**,在弹窗中输入32位密钥,单击 **解锁**。 +>![0|tips](../common/tips.svg)窍门:您也可以单击![file_vault](../common/file_vault.svg) 或者双击计算机界面 **我的保险箱**,直接使用密码解锁保险箱。 + + +### 删除保险箱 + +删除保险箱需要提前解锁保险箱。 +1. 右键单击 ![file_vault](../common/file_vault.svg) 或者 **我的保险箱**,选择 **删除保险箱**。 +2. 弹出删除保险箱窗口,输入保险箱密码,单击 **删除**。 +3. 在认证窗口中输入用户登录密码,单击 **确定** 完成操作。 +> ![attention](../common/attention.svg)注意:删除保险箱会将里面的文件一并删除。在进行删除操作前,请将保险箱中的文件备份。 + +## 磁盘管理 + +文件管理器管理本地磁盘和外接磁盘。本地磁盘显示在文件管理器的左侧导航栏上或计算机界面;挂载外接磁盘或者插入其他移动存储设备时,也会在导航栏看到相应的磁盘图标。 + + + + + + + + + + + + + + + + + +
本地磁盘本地硬盘分区的所有磁盘
外接磁盘包括移动硬盘、U盘、光盘
移动设备手机内存、存储卡、SD卡等
+ + + +> ![notes](../common/notes.svg)说明:如果磁盘或磁盘中的文件夹已加密,请输入密码后查看文件。 + +### 本地磁盘 + +#### 隐藏本地磁盘 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在高级设置选项中勾选 **隐藏系统盘**。 + +#### 重命名本地磁盘 + +1. 在左侧导航栏或计算机界面,右键单击本地磁盘。 +2. 选择 **重命名**。 +3. 输入新名称,按下键盘上的 **Enter** 键或单击空白处保存修改。 + +> ![tips](../common/tips.svg)窍门:在计算机界面,慢速双击本地磁盘,呈现编辑框后便可进行重命名操作。 + +![0|disk](fig/e_rename_disk.png) + +### 外接磁盘 + +#### 弹出外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要移除的磁盘。 +2. 选择 **安全移除**。 +3. 磁盘将从磁盘列表中删除,一并弹出该磁盘的所有分区。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg)窍门:如果要弹出光盘,请选择 **弹出** 来移除光盘。单击导航栏中磁盘右边的按钮 ![unmount](../common/unmount_normal.svg) 同样可以弹出磁盘或光盘。 + +#### 重命名外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要重命名的磁盘。 +2. 选择 **卸载**后,再次单击右键选择 **重命名**。 +3. 输入新的卷标名称,按下键盘上的 **Enter** 键或单击空白处保存修改。 + + + +#### 格式化外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要格式化的磁盘。 +2. 选择 **卸载** 后,再次单击右键选择 **格式化**。 +3. 设置格式化之后的文件类型和卷标。 +4. 单击 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg)说明:快速格式化速度快,但是数据仍然可能通过工具被恢复,如果想要格式化后的数据无法被恢复,可以取消勾选“快速格式化”,然后执行格式化操作。 + +## 主菜单 + +在主菜单中,您可以新建窗口、切换窗口主题、连接到服务器、[设置共享密码](#共享本地文件)、设置文件管理器、查看帮助手册和版本介绍。 + +### 新建窗口 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **新建窗口**,打开一个新的文件管理器窗口。 + +### 连接到服务器 + +通过连接服务器 [访问局域网共享文件](#访问共享文件)。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **连接到服务器**,在编辑框中输入服务器IP地址。 + - 单击 ![+](../common/+.svg) 按钮可将该地址添加到“个人收藏服务器”列表中。 + - 在“个人收藏服务器”列表中选中一个地址,单击 ![_](../common/-.svg) 按钮,将该地址从收藏列表中移除。 +3. 单击 **连接**。 + +![conncet](fig/connect_to_server.png) + + +### 设置 + +#### 基础设置 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)> **设置** 。 +2. 选择 **基础设置** 选项。 + + 勾选 **总是在新窗口打开文件夹**。 + + 设置双击或单击打开文件。 + + 设置 **从默认窗口打开**、**从新标签打开**哪个目录。 + + 设置文件图标 **默认大小** 。 + + 设置 **默认视图** 以图标展示或列表展示。 + + 勾选 **显示隐藏文件**,文件管理器中被隐藏的文件会显示出来。 + + 勾选 **重命名时隐藏文件扩展名**,重命名时不会显示扩展名。 + + 勾选 **显示最近使用文件**,在左侧导航栏显示最近使用的文件。 + +#### 高级设置 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)> **设置** 。 +2. 选择 **高级设置** 选项。 + + 勾选 **自动索引内置磁盘**,搜索文件时会搜索内置磁盘中的文件。 + + 勾选 **连接电脑后索引外部存储设备**,搜索文件时也会搜索外接设备中的文件。 + + 勾选 **全文搜索**,通过文件中的内容来索引。 + + 勾选预览文件类型。 + + 勾选 **自动挂载**,接入外接磁盘时自动挂载。 + + 勾选 **自动挂载后打开**,接入外接磁盘时自动挂载并打开该磁盘。 + + 勾选 **使用文件管理器的文件选择对话框**,选择文件时打开文件管理器窗口。 + + 勾选 **开启普通删除提示**,删除文件时弹出提示对话框。 + + 勾选 **隐藏系统盘**,导航栏和计算机界面将不显示本地磁盘。 + + 勾选 **在磁盘图标上显示文件系统标签**。 + + +### 主题 + +窗口主题包含浅色主题、深色主题和跟随系统主题。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **主题**,选择一个主题。 + +### 帮助 + +查看帮助手册,进一步了解和使用文件管理器。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **帮助**。 +3. 查看文件管理器的帮助手册。 + + +### 关于 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **关于**。 +3. 查看文件管理器的版本和介绍。 + + +### 退出 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **退出**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/p_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/p_file-manager.md new file mode 100755 index 0000000..a7b300c --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_CN/p_file-manager.md @@ -0,0 +1,827 @@ +# 文件管理器|dde-file-manager| + +## 概述 + +文件管理器是一款功能强大、简单易用的文件管理工具。它沿用了一般文件管理器的经典功能和布局,并在此基础上简化了用户操作,增加了很多特色功能。文件管理器拥有一目了然的导航栏、智能识别的搜索框、多样化的视图和排序,这些特点让文件管理不再复杂。 + +![1|overview](fig/p_overview.png) + +## 使用入门 + +通过以下方式运行或关闭文件管理器,或者创建文件管理器的快捷方式。 + +### 运行文件管理器 + +1. 单击任务栏上的启动器图标 ![deepin_launcher ](../common/deepin_launcher.svg),进入启动器界面。 +2. 上下滚动鼠标滚轮浏览或通过搜索,找到文件管理器图标 ![deepin_file_manager](../common/deepin_file_manager.svg),单击运行。 +3. 右键单击 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 单击 **发送到桌面**,在桌面创建快捷方式。 + - 单击 **发送到任务栏**,将应用程序固定到任务栏。 + - 单击 **开机自动启动**,将应用程序添加到开机启动项,在电脑开机时自动运行该应用。 + +> ![tips](../common/tips.svg) 窍门:您也可以使用快捷键 **Super + E** 启动文件管理器。 + +### 关闭文件管理器 + +- 在文件管理器界面,单击 ![close_icon](../common/close_icon.svg),退出文件管理器。 +- 在任务栏右键单击 ![deepin_file_manager](../common/deepin_file_manager.svg),选择 **关闭所有** ,退出文件管理器。 +- 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg),选择 **退出**,退出文件管理器。 + +### 查看快捷键 +在文件管理器界面,使用快捷键 **Ctrl + Shift + /** 打开快捷键预览界面。熟练地使用快捷键,将大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主界面 + +文件管理器的主界面简单易用、功能全面,熟练地使用界面功能将使文件管理更加简单高效。 + +![1|main_interface](fig/p_main_interface.png) + + +| 标号 | 名称 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 导航栏 | 单击导航图标,快速访问本地文件、磁盘、网络邻居、书签、标记等。 | +| 2 | 地址栏 | 通过地址栏,您可以快速切换访问历史、在上下级目录间切换、搜索、输入地址访问。 | +| 3 | 图标/列表视图 | 单击 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg)图标,以图标或列表形式查看文件(夹)。 | +| 4 | 信息栏 | 单击 ![fileinfo](../common/fileinfo.svg), 查看文件(夹)的基本信息和标记。 | +| 5 | 菜单栏 | 通过主菜单,您可以新建窗口、切换窗口主题、设置共享密码、设置文件管理器、查看帮助文档和关于信息、退出文件管理器。 | +| 6 | 状态栏 | 显示文件数量或者已选中文件的数量。 | + + +> ![tips](../common/tips.svg) 窍门:可拖动左侧导航栏右边的分隔线来改变其宽度。 + +## 基本功能 + +文件管理器具备基本的文件管理功能,对文件(夹)进行新建、复制、重命名、删除等操作都非常简单。 + +### 新建文件 + +#### 新建文档 + +1. 在文件管理器空白区域,单击鼠标右键。 +2. 选择 **新建文档**。 +3. 在下拉菜单中选择新建文件的类型。 +4. 输入新建文件的名称。 + +![0|newdo](fig/newdo.png) + +#### 新建文件夹 + +1. 在文件管理器空白区域,单击鼠标右键。 +2. 选择 **新建文件夹**。 +3. 输入新建文件夹的名称。 + +### 重命名文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **重命名**。 +3. 输入文件名称,按 **Enter** 键或者单击界面空白区域。 + +![1|rename](fig/rename.png) + +> ![tips](../common/tips.svg) 窍门:在 **设置** 中勾选“重命名时隐藏文件扩展名”,能更方便地修改文件名称。 + +### 批量重命名 + +1. 在文件管理器界面,选中多个文件。 +2. 右击文件,并选择 **重命名**。 + - **替换文本** 查找需要替换的文本,并输入替换后的文本,文件名中的关键字将被统一替换。 + - **添加文本** 输入需要添加的文本,并选择位置是名称之前还是之后,文件名将统一加入被添加的文本。 + - **自定义文本** 输入文件名,并输入序列的递进数字,文件名将统一改成新文件名+递进数字。 +4. 单击 **重命名** 来完成操作。 + +![1|rename](fig/p_batch_rename.png) + +### 查看文件 + +单击菜单栏上的图标 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 来切换图标视图和列表视图。 + +- 图标视图:平铺显示文件的名称、图标或缩略图。 + +![1|icon_view](fig/p_iconview.png) + +- 列表视图:列表显示文件图标或缩略图、名称、修改时间、大小、类型等信息。 + +![1|list_view](fig/p_listview.png) + +> ![tips](../common/tips.svg) 窍门: +> - 在列表视图中,把光标置于两列之间的分隔线上,拖动它来改变列的宽度;双击分隔线可将当前列自动调整为本列内容最宽的宽度。 +> - 使用快捷键 **Ctrl + 1** 和 **Ctrl + 2**,切换图标视图和列表视图。 + + +### 排序文件 + +1. 在文件管理器界面,单击鼠标右键。 +2. 选择 **排序方式**。 +3. 在子菜单中选择以名称、修改时间、大小或类型来排序文件。 + +> ![tips](../common/tips.svg) 窍门:在列表视图中,单击表头栏的列标签来切换升序、降序。 + +### 打开文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **打开方式** > **选择默认程序**。 +3. 在程序列表中选择应用程序。 + +> ![notes](../common/notes.svg) 说明:直接双击文件会使用默认程序打开。您可以选择相同类型的多个文件,右键选择 **打开方式** 选项,同时打开多个文件。 + +![0|open](fig/open.png) + + + +### 隐藏文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **属性**,勾选 **隐藏此文件**。 + +### 复制文件 + +1. 在文件管理器界面,右键单击文件。 +2. 单击 **复制**。 +3. 选择一个目标存储位置。 +4. 单击鼠标右键,然后选择 **粘贴**。 + +### 压缩文件 + +1. 在文件管理器界面,右键单击文件(夹)。 +2. 选择 **压缩**。 +3. 弹出归档管理器压缩界面,可以设置压缩包格式、名称、存储路径等,单击 **压缩**。 + +> ![tips](../common/tips.svg) 窍门:您也可以直接在右键菜单中选择 **添加到xxx.7z** 或 **添加到xxx.zip**,快速将文件(夹)压缩成7z或zip格式。 + +### 删除文件 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **删除** 。 + - 被删除的文件可以在回收站中找到,右键单击回收站中的文件可以进行 **还原** 或 **删除** 操作。 + - 被删除的文件的快捷方式将会失效。 + +> ![attention](../common/attention.svg) 注意:外接设备删除文件会将文件彻底删除,无法从回收站找回。 + +### 撤销操作 + +在文件管理器中,可以用 **Ctrl + Z** 来撤销上一步操作,包括: + +- 删除新建的文件。 +- 恢复重命名(包括重命名文件后缀)之前的名字。 +- 从回收站还原刚删除的文件。 +- 恢复文件到移动(剪切移动、鼠标移动)前的原始路径。 +- 删除复制粘贴的文件。 + +>![attention](../common/attention.svg) 注意:撤销动作最多只能返回两步;如果操作中有覆盖某个同名文件和彻底删除文件,则撤销只能返回到这一步。 + +### 文件属性 + +文件属性会显示文件的基本信息,打开方式和权限设置。文件夹属性会显示文件夹的基本信息,共享信息和权限设置。 + +1. 在文件管理器界面,右键单击文件。 +2. 选择 **属性**,查看文件属性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg) 说明:查看多个文件属性会显示文件总大小和数量;查看快捷方式的属性将会额外显示源文件地址。您还可以使用 **Ctrl + I** 组合键查看文件属性。 + + +### 病毒查杀 + +1. 在文件管理器界面,右键单击文件(夹)。 +2. 选择 **病毒查杀**,弹出安全中心病毒查杀界面,您可以对该文件(夹)进行安全扫描,具体操作请参阅安全中心 [病毒查杀](dman:///deepin-defender#病毒查杀)。 + + > ![notes](../common/notes.svg) 说明: + > - 如果当前安全中心有查杀任务,则在弹出的对话框中单击 **查看** 进入安全中心病毒查杀界面进行查看。 + > - 安全中心默认开启 **加入“病毒查杀”到文件右键菜单** 的功能,您也可以进入安全中心设置界面,取消勾选该功能。取消勾选后文件管理器右键菜单中不会显示病毒查杀的选项。 + +## 常用操作 + +文件管理器具备很多特色功能,这些功能都让文件管理更加简单、高效。 + +### 切换地址栏 + +地址栏由历史导航、面包屑和输入框共同组成,通常情况下地址栏显示面包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 单击历史导航按钮,可以快速在历史浏览记录间切换,查看前一个地址或者后一个地址。 +- 文件所在位置的每一个层级都会形成一个面包屑,通过来回单击面包屑可以快速在不同文件层级间切换。 + +单击搜索按钮,或者在文件路径上右键单击并选择 **编辑地址**,地址栏会切换为输入框状态。在输入框外单击时,地址栏会自动恢复到面包屑状态。 + +![0|addressbar](fig/addressbar2.png) + +- 输入框带有智能识别功能,输入关键字或者访问地址,系统会自动识别并进行搜索或访问。 + +### 搜索文件 +文件管理器支持多种检索方式,既支持通过文件名称、文件内容进行普通搜索,也支持通过文件类型、创建时间等进行高级搜索,提高工作效率,便于文件管理。 + +- 指定目录搜索时,请先进入该目录,然后再进行搜索。 + +> ![notes](../common/notes.svg) 说明:在文件管理器的 **设置** 中,默认勾选了“自动索引内置磁盘”,您可以选择勾选“连接电脑后索引外部存储设备”,加快在外部设备的搜索速度。 + +#### 全文搜索 + +您可以通过文件内容关键字来搜索文件。 +1. 在文件管理器中,单击 ![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在高级设置项勾选“全文搜索”来开启此功能。 +3. 使用快捷键 **Ctrl + F** 或在地址栏中单击搜索按钮进入搜索状态,输入关键字后按下键盘上的 **Enter** 键,搜索相关文件。 + +#### 高级搜索 + +当文件较多,搜索较慢时,启用高级搜索缩小搜索范围,提高搜索效率。 +1. 在搜索状态下,输入关键字后按 **Enter** 键,当搜索到结果时,搜索框右侧显示图标 ![filter](../common/filter.svg),单击该图标可进行高级搜索的操作。 +2. 选择搜索范围、文件大小、文件类型、修改时间、访问时间和创建时间,进行更精准的搜索。 + +![0|filter](fig/p_filter.png) + + +### 最近使用 + +在左侧导航栏上默认有 **最近使用** 入口,单击可以查看最近使用的文件。文件默认按照访问时间倒序排列。 + +> ![notes](../common/notes.svg) 说明:若想隐藏“最近使用”,可在 **设置** > **基本设置** > **隐藏文件**,取消勾选“显示最近使用文件”。若要隐藏某一个文件的访问记录,右键单击该文件选择 **移除**,该操作不会删除文件。 + +### 多标签页 + +文件管理器支持多标签页显示。 + +1. 在文件管理器界面,右键单击文件夹。 +2. 选择 **在新标签中打开**。 +3. 当窗口有多个标签页时,可以: + - 单击标签页右侧的按钮 + ,继续添加标签页。 + - 将鼠标指针置于标签页上,单击关闭按钮 × 或单击鼠标中键,关闭标签页。 + + ![1|tab](fig/p_tab.png) + +> ![tips](../common/tips.svg) 窍门:文件管理器窗口只有一个标签时,标签栏是隐藏的,您还可以使用快捷键 **Ctrl** + **T** 来新建标签。 + +### 书签管理 + +为常用文件夹添加书签,以便从左侧导航栏快速访问。 + +- 添加书签:右键单击文件夹,选择 **添加书签** 在导航栏创建书签。 +- 移动书签:在导航栏上下拖动书签调整排序。 +- 删除书签:右键单击书签,选择 **移除** 来删除书签;或右键单击已添加书签的文件夹,选择 **移除书签** 来删除书签。 + +### 标记信息 + +通过给文件/文件夹添加标记,可以更好地分类管理您的文件。 + +> ![notes](../common/notes.svg) 说明:仅x86平台支持标记信息功能。 + +#### 添加标记 + +您可以为一个文件(夹)添加多个标记,也可以同时为多个文件(夹)添加标记;添加成功的标记会出现在左侧导航栏内。 + +##### 通过编辑框添加标记 + +1. 右键单击文件(夹),选择 **标记信息**。 +2. 输入标记名称,若要添加多个标记,可用逗号分隔。 +3. 单击界面空白区域保存设置。 + +>![notes](../common/notes.svg) 说明:标记颜色从8种默认颜色中随机分配。 + +![1|tag_info](fig/p_tag_info.png) + + +##### 通过颜色按钮添加标记 + +右键单击文件(夹),选择颜色按钮,直接生成这个颜色的标记。 + +![1|color_tag](fig/p_color_tag.png) + +##### 通过右侧信息栏添加标记 + +选择文件(夹)后,单击菜单栏上的图标 ![fileinfo](../common/fileinfo.svg),在右侧信息栏中也可以添加标记。 + +![1|info_tag](fig/p_info_tag.png) + +>![notes](../common/notes.svg) 说明:如果文件有标记,则复制或剪切该文件产生的文件仍然具有同样的标记。 + + +#### 重命名标记 + +在侧边导航栏中,右键单击某个标记,选择 **重命名**,修改当前标记的名称。 + +![1|rename_tag](fig/rename_tag.png) + +#### 修改标记颜色 + +在左侧导航栏中,右键单击某个标记,选择颜色按钮,即可修改当前标记的颜色。 + +#### 排序标记 + +上下拖动标记即可调整标记排序。 + +#### 删除标记 + +右键单击某个标记,选择 **移除**,删除当前标记。 + + +### 文件预览 + +文件管理器支持空格键预览功能,选中文件并按下键盘上的空格键可以快速预览文件。在预览窗口中可以查看图片分辨率、文档大小、文本内容等,还支持gif、音频、视频播放。 + +#### 预览视频 + +1. 选择您要预览的视频文件,按下空格键,即可开始预览。 +2. 单击视频任意地方可暂停播放。 +3. 播放过程中,可以拖动进度条来快进快退。 +4. 单击底部 **打开** 按扭,在默认程序中打开该视频文件。 + +![1|video_preview](fig/video_preview.png) + +> ![notes](../common/notes.svg) 说明:您也可以同时选择多个文件,按下空格键进行预览。 + + +### 权限管理 + +选择对应文件(夹),单击右键,选择属性,单击 **权限管理**, 为所有者、群组和其他用户设置文件权限。 + +![2|permission](fig/permission.png) + +### 我的共享 + +当您设置了共享文件时,“我的共享”会出现在导航栏上。取消所有共享文件后,“我的共享”自动从导航栏中移除。 + +#### 共享本地文件 + +1. 在文件管理器界面,右键单击文件夹,选择 **共享文件夹**。 +2. 在文件夹的属性窗口中,勾选 **共享此文件夹**。 + + > ![notes](../common/notes.svg) 说明: 如果smb服务未开启,共享文件夹时会弹出密码认证窗口,输入登录密码完成认证即可开启smb服务。 + +3. 根据需要设置 **共享名**、**权限**、**匿名访问** 后关闭窗口。 +4. 单击 ![icon_menu](../common/icon_menu.svg)> **设置共享密码**。 +5. 输入共享密码,单击 **确定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg) 窍门:在文件夹的属性窗口中取消勾选 **共享此文件夹** ,可以取消文件共享;也可以右键单击文件,选择 **取消共享**。 + + +#### 访问共享文件 + +局域网中其他用户共享的文件都可以在网络邻居中找到,您也可以通过smb访问共享文件。 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **连接到服务器**,在编辑框中输入服务器地址,如:smb://xx.x.xx.xxx(一般为IP地址),单击 **连接**;或者直接在地址栏中输入服务器地址,按下键盘上的 **Enter** 键。 +2. 选择需要访问的共享文件夹,在弹出的窗口中输入用户名和共享密码,或者匿名访问。 + - 未加密的共享文件可以匿名访问,不需要输入用户名和密码。 + - 加密的共享文件需要输入用户名和密码之后才能访问。 + + - 用户名:共享者登录系统的用户名。 + - 密码:共享文件时设置的共享密码。 +3. 单击 **连接**。 + +![1|visitshareshare](fig/visitshare.png) + + + +### 以管理员身份打开 + +前提条件:“控制中心”>“通用”中开发者模式已打开。 + +1. 在文件管理器中,右键单击文件夹。 +2. 选择 **以管理员身份打开**,在弹窗中输入用户登录密码,单击 **确定**。 +3. 该文件夹会以新窗口打开,在此窗口中可以进行高级权限的操作,关闭窗口后,终止管理员权限。 + +### 在终端中打开 + +1. 在文件管理器中,单击鼠标右键。 +2. 选择 **在终端中打开**,会启动终端应用程序,终端的路径为当前目录。 + +![0|open_terminal](fig/open_terminal.png) + +### 刻录光盘 + +您可以通过刻录功能将音乐、视频、图片或镜像文件复制到光盘中。其中,ISO9660文件系统支持所有的CD和DVD光盘格式,UDF文件系统仅支持部分光盘格式。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
类型光盘格式ISO9660UDF
空盘DVD-R、DVD+R、CD-R、CD-RW支持支持
非DVD-R、DVD+R、CD-R、CD-RW支持不支持
非空盘DVD-R、DVD+R、CD-R、CD-RW支持追加文件仅支持Windows原生工具刻录的格式
非DVD-R、DVD+R、CD-R、CD-RW支持追加文件不支持追加文件
+ + + +1. 将光盘插入到刻录机中。 +2. 打开文件管理器,单击导航栏中的光盘图标,进入刻录CD的界面。 + +![cd](fig/cd_interface.png) + +3. 右键单击 文件(夹),选择 **添加至光盘刻录** 或直接将文件(夹)拖拽到刻录CD的界面。 +4. 在刻录CD界面,单击右上角按钮 **刻录**。 + + >![notes](../common/notes.svg) 说明:如果要从刻录列表中删除某个文件(夹),右键单击该文件(夹),选择 **删除**,将该文件(夹)从列表中移除。 + +5. 在弹窗中输入光盘名称。您也可以进入 **高级设置** 界面,设置文件系统、写入速度,或勾选“允许追加数据”、“核验数据”等,单击 **刻录**。 + +![cd](fig/cd_rename.png) + +6. 刻录完成后界面弹出对话框,单击 **确定**。 + +>![notes](../common/notes.svg) 说明:如果需要擦除光盘数据,可以右键单击导航栏中光盘图标,选择 **卸载**,再次右键单击该光盘图标并选择 **擦除**。 + +### 创建快捷方式 + +1. 在文件管理器界面,右键单击文件(夹)。 +2. 选择 **创建链接**。 +3. 在弹窗中选择创建位置、链接名称。 +4. 单击 **保存**,在目标位置会生成该文件(夹)的快捷方式。 + +> ![tips](../common/tips.svg) 窍门:选择 **发送到桌面** 可以直接在桌面上生成该文件(夹)的快捷方式。 + +### 发送文件(夹)到外接磁盘 + +当有外接磁盘接入时,您可以将文件或文件夹发送到外接磁盘。 + +1. 在文件管理器界面,右键单击需要发送的文件(夹)。 +2. 选择 **发送到** > 外接磁盘。 +3. 文件(夹)将会被发送到移动外接磁盘。 + +### 发送文件到蓝牙 + +如果您的电脑配置了蓝牙模块,便可通过蓝牙进行短距离文件传输的操作。 + +前提条件:发送端与接收端蓝牙设备已配对并成功连接。具体连接方法请参阅 [连接蓝牙设备](dman:///dde#连接蓝牙设备)。 + +1. 在文件管理器界面,右键单击需要发送的文件或文件压缩包。 +2. 选择 **发送到** > **发送到蓝牙**。 +3. 在蓝牙文件传输窗口中勾选接收设备,单击 **下一步**。 +4. 此时接收端会收到文件接收的请求,待接收端同意请求后,发送端开始传输文件。 + +## 手机助手 + +统信UOS助手是一款实现手机与电脑间跨端协作、高效传输以及实时同步的工具。将手机与电脑连接或通过无线投送功能,轻松实现图片、视频、文件等的传输。 + +>![icon](../common/notes.svg) 说明:仅安卓手机支持安装统信UOS助手。 + +### 准备工作 + +#### 安装统信UOS助手 + +1. 单击左侧导航栏 **我的手机** 或系统托盘中的图标 ![icon](../common/found.svg)。 +2. 在我的手机界面,单击 **安装统信UOS助手**,弹出二维码窗口。 + - 通过手机微信或浏览器扫描二维码,下载并安装统信UOS助手。 + - 单击 **下载APK安装包**,将安装包下载到电脑端,下载完成后再导入至手机端进行安装。 + + + ![phone](fig/myphone.png) + +#### 登录统信UOS助手 + +统信UOS助手支持手机快捷登录、微信登录、帐号密码登录这三种登录方式,可以选择其中任意一种方式进行登录。如果您尚未注册帐号,请在登录界面单击 **注册帐号** 进行注册。 + +phone + +#### 设置发现方式 + +通过“发现设置”功能,设置手机和电脑被发现的方式。 + +在统信UOS助手界面,单击右上角的 **发现设置**;在电脑系统托盘上,右键单击图标 ![icon](../common/found.svg),选择 **发现设置**,您可以选择: + +- **允许被所有人发现**:在局域网内,允许所有处于同一网络且在同一网段的设备发现本手机或电脑。 +- **仅限同一Union ID帐号发现**:在局域网内,允许登录同一个Union ID的设备发现本手机或电脑。 +- **不被发现**:所有设备都不能发现本手机或电脑。 +- **允许被登录同一Union ID的远程设备发现**(电脑端):允许登录同一个Union ID的远程设备发现本电脑。 + +![pic](fig/found.png) + + + +### 连接手机与电脑 + +登录统信UOS助手后,您可以通过扫码连接或搜索电脑的方式将手机与电脑连接起来。 + +phone + +#### 扫码连接 + +前提条件:手机与电脑处于同一无线网络且在同一网段中。 + +1. 在电脑端,单击文件管理器左侧导航栏 **我的手机** 或系统托盘中的图标 ![icon](../common/found.svg),弹出“使用统信UOS助手扫码连接”的窗口。 +2. 在手机端,进入统信UOS助手界面,单击 **扫码连接**,扫描步骤1窗口中的二维码,完成连接。 + +#### 搜索电脑 + +前提条件:手机与电脑处于同一无线网络且在同一网段中(仅支持互发文件,不支持查看和编辑文件)或登录同一个Union ID帐号,且手机与电脑允许被发现。 + +1. 在统信UOS助手界面,单击 **搜索电脑**。 +2. 在搜索列表中选择需要连接的电脑,完成连接。 + + +如果需要断开连接,您可以: + +- 在统信UOS助手界面上单击按钮 ![icon](../common/exit.svg) 断开连接。 +- 在电脑上右键单击系统托盘中的图标 ![icon](../common/found.svg),选择您的手机,在弹窗中单击 **断开连接**。 + +### 管理文件 + +手机与电脑连接成功后,您可以发送文件、查看文件和管理文件。 + + +#### 传输文件 + + +- **通过统信UOS助手界面进行文件传输** + + 发送手机文件至电脑:在统信UOS助手界面,单击 **传输助手**,在传输窗口中发送文件至电脑端。 + +- **通过文件管理器界面进行文件传输** + + 发送电脑文件至手机:在 **文件管理器 > 我的手机** 界面,右侧传输窗口中,您可以选择电脑文件至该窗口中进行发送;或右键单击电脑中的某个文件,选择 **发送到我的手机**。 + +- **通过无线投送功能进行文件传输** + + 当设备处于同一无线网络且在同一网段中或已登录同一Union ID帐号,且设备允许被发现,您可以通过无线投送功能,将文件从一台设备投送到另一台设备中。 + 1. 在电脑上右键单击需要投送的文件,选择 **无线投送**。 + 2. 在弹窗中选择需要投送的手机或电脑,完成投送。 + + >![icon](../common/notes.svg) 说明: + >- 手机端需要安装统信UOS助手并登录帐号后,才能接收电脑端投送的文件。 + >- 登录同一Union ID后,可以进行远程投送的操作。 + + +#### 查看/编辑文件 + +- 在手机上查看电脑文件:在统信UOS助手界面,单击 **我的电脑**,您可以打开、下载或分享电脑文件。 +- 在电脑上查看/编辑手机文件:在 **文件管理器 > 我的手机** 界面,分类展示手机相册、视频、文档等文件夹,您可以打开、编辑文件夹中的文件,文件经过编辑并保存后将同步至手机端。 + + + +## 文件角标 + +您可以通过命令行,将图标文件指定给一个文件或文件夹作为角标显示出来。 + +>![icon](../common/notes.svg) 说明: +>- 角标文件支持svg、jpg、png、bmp、gif格式,且大小不超过100KB。 +>- U盘及光盘下的文件,不支持添加角标。 + +### 添加单个角标 + +1. 在终端输入命令 **gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径)"** ,该命令默认在文件(夹)右下角添加角标。 + + >![icon](../common/attention.svg) 注意:系统已定义的特殊角标,不支持被替换。 + +2. 您也可以在上述命令中加入位置参数,将角标添加在文件(夹)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + + 例如:在文件(夹)左上角添加角标 + + **gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径);lu"** + +![mark](fig/single.png) + +### 添加多个角标 + +在命令行中加入“**|**”符号将角标文件路径链接起来,为文件(夹)添加2~4个角标。文件(夹)同一个位置不支持叠加角标,仅支持替换。 + +例如:在文件(夹)四个角都添加角标 + +**gio set xxx(文件路径) -t stringv metadata::emblems "xxx(图标路径);lu|xxx(图标路径);ld|xxx(图标路径);ru|xxx(图标路径);rd"** + +![mark](fig/multi.png) + +### 撤销角标 + +在终端中输入命令 **gio set xxx(文件路径) -t stringv metadata::emblems ""** 撤销文件(夹)上所有的角标。 + + + +## 文件保险箱 + +文件保险箱旨在为您打造专属的安全空间,为您的隐私保驾护航。 + +### 设置保险箱密码 + +首次使用保险箱需要对其进行密码设置,具体步骤如下: + +1. 单击导航栏中的保险箱图标 ![file_vault](../common/file_vault.svg),或者在计算机界面双击 “我的保险箱”,在弹出的对话框中单击 **开启**。 +2. 设置解锁类型、保险箱密码和密码提示信息,单击 **下一步**。 + +![password](fig/password.png) + + > ![notes](../common/notes.svg) 说明: 密码必须同时包含大写字母、小写字母、数字和符号,且字符不小于8位,否则无法进入下一步。 + +3. 在保存密钥文件窗口中,设置密钥文件的存储位置,单击 **下一步**。如果您忘记了保险箱密码,可使用密钥文件找回密码。 + +![encrypt](fig/save.png) + +4. 单击 **加密保险箱**,弹出认证窗口,输入用户登录密码后单击 **确定**。 + +![encrypt](fig/encrypt.png) + +5. 在加密完成窗口中单击 **确定**, 完成保险箱密码设置。 + +![encrypt](fig/finish.png) + +### 锁定保险箱 + +将文件放入保险箱后,右键单击 ![file_vault](../common/file_vault.svg) 或者在计算机界面右键单击 **我的保险箱**。 +- 选择 **立即上锁**,立即将文件保险箱锁上。 +- 选择 **自动上锁**,在其下拉选项中: + + 选择“从不”,计算机在锁屏或关机前一直保持未上锁状态。 + + 选择“5分钟”、“10分钟”或者“20分钟”后自动上锁保险箱。 + +![0|right](fig/right.png) + + +### 解锁保险箱 + +1. 单击 ![file_vault](../common/file_vault.svg) 或者在计算机界面双击 **我的保险箱**。 +2. 在解锁保险箱窗口中,输入保险箱密码,单击 **解锁**。 +3. 如果忘记了保险箱密码,单击 **忘记密码**,选择密钥文件的存储位置后,单击 **验证密钥** 找回密码。 + +![encrypt](fig/unlock.png) + + +>![0|tips](../common/tips.svg) 窍门:您也可以右键单击 ![file_vault](../common/file_vault.svg) 或者 **我的保险箱**,选择 **解锁**,解锁保险箱。 + + +### 删除保险箱 + +删除保险箱需要提前解锁保险箱。 +1. 右键单击 ![file_vault](../common/file_vault.svg) 或者 **我的保险箱**,选择 **删除保险箱**。 +2. 弹出删除保险箱窗口,输入保险箱密码,单击 **删除**。 +3. 在认证窗口中输入用户登录密码,单击 **确定** 完成操作。 +> ![attention](../common/attention.svg) 注意:删除保险箱会将里面的文件永久删除,在进行删除操作前,请将保险箱中的文件备份。 + +## 磁盘管理 + +文件管理器管理本地磁盘和外接磁盘。本地磁盘显示在文件管理器的左侧导航栏上或计算机界面;挂载外接磁盘或者插入其他移动存储设备时,也会在导航栏看到相应的磁盘图标。 + + + + + + + + + + + + + + + + + +
本地磁盘本地硬盘分区的所有磁盘
外接磁盘包括移动硬盘、U盘、光盘
移动设备手机内存、存储卡、SD卡等
+ + + +> ![notes](../common/notes.svg) 说明:如果磁盘或磁盘中的文件夹已加密,请输入密码后查看文件。 + +### 本地磁盘 + +#### 隐藏本地磁盘 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在高级设置选项中勾选 **隐藏系统盘**。 + +#### 重命名本地磁盘 + +1. 在左侧导航栏或计算机界面,右键单击本地磁盘。 +2. 选择 **重命名**。 +3. 输入新名称,按下键盘上的 **Enter** 键或单击空白处保存修改。 + +> ![tips](../common/tips.svg) 窍门:在计算机界面,慢速双击本地磁盘,呈现编辑框后便可进行重命名操作。 + +![0|disk](fig/p_rename_disk.png) + +### 外接磁盘 + +#### 弹出外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要移除的磁盘。 +2. 选择 **安全移除**。 +3. 磁盘将从磁盘列表中删除,一并弹出该磁盘的所有分区。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) 窍门:如果要弹出光盘,请选择 **弹出** 来移除光盘。单击导航栏中磁盘右边的按钮 ![unmount](../common/unmount_normal.svg) 同样可以弹出磁盘或光盘。 + +#### 重命名外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要重命名的磁盘。 +2. 选择 **卸载**后,再次单击右键选择 **重命名**。 +3. 输入新的卷标名称,按下键盘上的 **Enter** 键或单击空白处保存修改。 + + + +#### 格式化外接磁盘 + +1. 在左侧导航栏或计算机界面,右键单击需要格式化的磁盘。 +2. 选择 **卸载** 后,再次单击右键选择 **格式化**。 +3. 设置格式化之后的文件类型和卷标。 +4. 单击 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) 说明:快速格式化速度快,但是数据仍然可能通过工具被恢复,如果想要格式化后的数据无法被恢复,可以取消勾选“快速格式化”,然后执行格式化操作。 + +## 主菜单 + +在主菜单中,您可以新建窗口、切换窗口主题、连接到服务器、[设置共享密码](#共享本地文件)、设置文件管理器、查看帮助手册和版本介绍。 + +### 新建窗口 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **新建窗口**,打开一个新的文件管理器窗口。 + +### 连接到服务器 + +通过连接服务器 [访问局域网共享文件](#访问共享文件)。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **连接到服务器**,在编辑框中输入服务器IP地址。 + - 单击 ![+](../common/+.svg) 按钮可将该地址添加到“个人收藏服务器”列表中。 + - 在“个人收藏服务器”列表中选中一个地址,单击 ![_](../common/-.svg) 按钮,将该地址从收藏列表中移除。 +3. 单击 **连接**。 + +![conncet](fig/connect_to_server.png) + + +### 设置 + +#### 基础设置 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)> **设置** 。 +2. 选择 **基础设置** 选项。 + + 勾选 **总是在新窗口打开文件夹**。 + + 设置双击或单击打开文件。 + + 设置 **从默认窗口打开**、**从新标签打开**哪个目录。 + + 设置文件图标 **默认大小** 。 + + 设置 **默认视图** 以图标展示或列表展示。 + + 勾选 **显示隐藏文件**,文件管理器中被隐藏的文件会显示出来。 + + 勾选 **重命名时隐藏文件扩展名**,重命名时不会显示扩展名。 + + 勾选 **显示最近使用文件**,在左侧导航栏显示最近使用的文件。 + +#### 高级设置 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)> **设置** 。 +2. 选择 **高级设置** 选项。 + + 勾选 **自动索引内置磁盘**,搜索文件时会搜索内置磁盘中的文件。 + + 勾选 **连接电脑后索引外部存储设备**,搜索文件时也会搜索外接设备中的文件。 + + 勾选 **全文搜索**,通过文件中的内容来索引。 + + 勾选预览文件类型。 + + 勾选 **自动挂载**,接入外接磁盘时自动挂载。 + + 勾选 **自动挂载后打开**,接入外接磁盘时自动挂载并打开该磁盘。 + + 勾选 **MTP挂载路径下显示文件统计详情**,MTP设备挂载后,显示其路径底部的状态栏信息。 + + 勾选 **Samba共享端常驻显示挂载入口**,远程挂载链接常驻显示在导航栏中。 + + 勾选 **使用文件管理器的文件选择对话框**,选择文件时打开文件管理器窗口。 + + 勾选 **开启普通删除提示**,删除文件时弹出提示对话框。 + + 勾选 **隐藏系统盘**,导航栏和计算机界面将不显示本地磁盘。 + + 勾选 **在磁盘图标上显示文件系统标签**。 + + +### 主题 + +窗口主题包含浅色主题、深色主题和跟随系统主题。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **主题**,选择一个主题。 + +### 帮助 + +查看帮助手册,进一步了解和使用文件管理器。 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **帮助**。 +3. 查看文件管理器的帮助手册。 + + +### 关于 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **关于**。 +3. 查看文件管理器的版本和介绍。 + + +### 退出 + +1. 在文件管理器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **退出**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/d_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/d_file-manager.md new file mode 100755 index 0000000..43ed061 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/d_file-manager.md @@ -0,0 +1,631 @@ +# 檔案管理員|dde-file-manager| + +## 概述 + +檔案管理員是一款功能強大、簡單易用的文件管理工具。它沿用了傳統檔案管理員的經典功能和佈局,並在此基礎上簡化了用戶操作,增加了很多特色功能。一目了然的導航欄、智能識別的搜索框、多樣化的視圖及排序讓您管理起來得心應手,經典和超越,只為給您更好的體驗! + +![1|overview](fig/d_overview.png) + + + +## 使用入門 + +通過以下方式運行或關閉檔案管理員,或者創建檔案管理員的快捷方式。 + +### 運行檔案管理員 + +1. 單擊任務欄上的啟動器圖標 ![deepin_launcher ](../common/deepin_launcher.svg),進入啟動器界面。 +2. 上下滾動鼠標滾輪瀏覽或通過搜索,找到檔案管理員圖標 ![deepin_file_manager](../common/deepin_file_manager.svg),單擊運行。 +3. 右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 單擊 **傳送到桌面**,在桌面創建快捷方式。 + - 單擊 **傳送到任務欄**,將應用程序固定到任務欄。 + - 單擊 **加至開機啟動**,將應用程序添加到開機啟動項,在電腦開機時自動運行該應用。 + +> ![tips](../common/tips.svg)竅門:您也可以使用快捷鍵 **Super + E** 啟動檔案管理員。 + +### 關閉檔案管理員 + +- 在檔案管理員界面,單擊 ![close_icon](../common/close_icon.svg),關閉檔案管理員。 +- 在任務欄右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),選擇 **關閉所有**,關閉檔案管理員。 +- 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg),選擇 **退出** ,關閉檔案管理員。 + +### 查看快捷鍵 + +在檔案管理員界面,使用快捷鍵 **Ctrl + Shift + /** 打開快捷鍵預覽界面,熟練地使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/d_hotkey.png) + +## 主界面 + +檔案管理員的主界面簡單易用、功能全面,熟練地使用界面功能將使檔案管理更加簡單高效。 + +![1|main_interface](fig/d_maininterface.png) + + +| 標號 | 名稱 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 導航欄 | 單擊導航圖標,快速訪問本地文件、磁盤、共享文件、書籤、標記等。 | +| 2 | 地址欄 | 通過地址欄,快速切換訪問歷史、在上下級目錄間切換、搜索、輸入地址訪問。 | +| 3 | 圖標/列表視圖 | 單擊 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg)圖標,以圖標或列表形式查看文件(夾)。 | +| 4 | 訊息欄 | 單擊 ![fileinfo](../common/fileinfo.svg), 查看文件(夾)的基本訊息和標記。 | +| 5 | 菜單欄 | 通過主菜單,您可以新建窗口、切換窗口主題、設置共享密碼、設置檔案管理員、查看幫助文檔和關於訊息、退出檔案管理員。 | +| 6 | 狀態欄 | 顯示文件數量或者已選中文件的數量。 | + +> ![tips](../common/tips.svg) 竅門:可拖動左側導航欄右邊的分隔線來改變其寬度。 + +## 基本功能 + +檔案管理員具備基本的檔案管理功能,對文件(夾)進行新建、複製、重命名、刪除等操作都非常簡單。 + +### 新建文件 + +#### 新建文檔 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **新建文檔**。 +3. 選擇新建文件的類型。 +4. 輸入新建文檔的名稱。 + +![0|newdo](fig/newdo.png) + +#### 新建文件夾 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **新建文件夾**。 +3. 輸入新建文件夾的名稱。 + +### 重命名文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **重命名**。 +3. 輸入文件名稱,按 **Enter** 鍵或者單擊界面空白區域保存設置。 + +![0|contextmenu](fig/d_rename.png) + +> ![tips](../common/tips.svg) 竅門:在 **設置** 中勾選「重命名時隱藏文件擴展名」,能更方便地修改文件名稱。 + +### 批量重命名 + +1. 在檔案管理員界面,選中多個文件。 +2. 右鍵單擊文件,選擇 **重命名**。 + - **替換文本** 查找需要替換的文本,並輸入替換後的文本,文件名中的關鍵字將被統一替換。 + - **添加文本** 輸入需要添加的文本,並選擇位置是名稱之前還是之後,文件名將統一加入被添加的文本。 + - **自定義文本** 輸入文件名,並輸入序列的遞進數字,文件名將統一改成新文件名+遞進數字。 +4. 單擊 **重命名** 來完成操作。 + +![1|rename](fig/d_batch_rename.png) + +### 查看文件 + +單擊菜單欄上的圖標 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 來切換圖標視圖和列表視圖。 + +- 圖標視圖:平鋪顯示文件的名稱、圖標或縮略圖。 + +![1|icon_view](fig/d_icon_view.png) + +- 列表視圖:列表顯示文件圖標或縮略圖、名稱、修改時間、大小、類型等訊息。 + +![1|list_view](fig/d_list_view.png) + +> ![tips](../common/tips.svg) 竅門: +> - 在列表視圖中,把光標置於兩列之間的分隔線上, 拖動它來改變列的寬度;雙擊分隔線可將當前列自動調整為本列內容最寬的寬度。 +> - 使用 **Ctrl + 1** 和 **Ctrl + 2** 快捷鍵,切換圖標視圖和列表視圖。 + + +### 排序文件 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **排序方式**。 +3. 在子菜單中選擇以名稱、修改時間、大小或類型來排序文件。 + +> ![tips](../common/tips.svg) 竅門:在列表視圖中,單擊表頭欄的列標籤來切換升序、降序。 + +### 打開文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **打開方式** > **選擇默認程序**。 +3. 在程序列表中選擇應用程序。 + +> ![notes](../common/notes.svg) 說明:直接雙擊文件會使用默認程序打開。您可以選擇相同類型的多個文件,單擊右鍵選擇 **打開方式** 選項,同時打開多個文件。 + +![0|open](fig/d_open.png) + + + +### 隱藏文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **屬性**,勾選 **隱藏此文件**。 + +### 複製文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **複製**。 +3. 選擇一個目標存儲位置。 +4. 單擊鼠標右鍵,選擇 **黏貼**。 + +### 壓縮文件 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **壓縮**。 +3. 彈出歸檔管理器壓縮界面,可以設置壓縮包格式、名稱、存儲路徑等,單擊 **壓縮**。 + +> ![tips](../common/tips.svg) 竅門:您也可以直接在右鍵菜單中選擇 **添加到xxx.7z** 或 **添加到xxx.zip**,快速將文件(夾)壓縮成7z或zip格式。 + +### 刪除文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **刪除** 。 + + - 被刪除的文件可以在回收站中找到,右鍵單擊回收站中的文件可以進行 **還原** 或 **刪除** 操作。 + - 被刪除的文件的快捷方式將會失效。 + +> ![attention](../common/attention.svg) 注意:从外接設備中刪除文件會將文件徹底刪除,無法從回收站找回。 + +### 撤銷操作 + +在檔案管理員中,可以用 **Ctrl + Z** 來撤銷上一步操作,包括: + +- 刪除新建的文件。 +- 恢復重命名(包括重命名文件後綴)之前的名字。 +- 從回收站還原剛刪除的文件。 +- 恢復文件到移動(剪切移動、鼠標移動)前的原始路徑。 +- 刪除複製黏貼的文件。 + +>![attention](../common/attention.svg) 注意:撤銷動作最多只能返回兩步;如果操作中有覆蓋某個同名文件和徹底刪除文件,則撤銷只能返回到這一步。 + +### 文件屬性 + +文件屬性會顯示文件的基本訊息、打開方式和權限設置。文件夾屬性會顯示文件夾的基本訊息、共享訊息和權限設置。 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **屬性**,查看文件屬性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg) 說明:查看多個文件屬性會顯示文件總大小和數量;查看快捷方式的屬性將會額外顯示源文件地址。您還可以使用快捷鍵 **Ctrl + I** 查看文件屬性。 + + + +## 常用操作 + +檔案管理員具備很多特色功能,這些功能都讓檔案管理更加簡單、高效。 + +### 切換地址欄 + +地址欄由歷史導航、麵包屑和輸入框共同組成。通常情況下地址欄顯示麵包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 單擊歷史導航按鈕,快速在歷史瀏覽記錄間切換,查看前一個地址或者後一個地址。 +- 文件所在位置的每一個層級都會形成一個麵包屑,通過來回單擊麵包屑可以快速在不同文件層級間切換。 + +單擊搜索圖標,或者在文件路徑上單擊右鍵並選擇「編輯地址」,地址欄會切換為輸入框狀態。在輸入框外單擊時,地址欄會自動恢復到麵包屑狀態。 + +![0|addressbar](fig/addressbar2.png) + +- 輸入框帶有智能識別功能,輸入關鍵字或者訪問地址,系統會自動識別並進行搜索或訪問。 + +### 搜索文件 + +檔案管理員支持多種檢索方式,既支持通過文件名稱、文件內容進行普通搜索,也支持通過文件類型、創建時間等進行高級搜索,提高工作效率,便於文件管理。 + +- 指定目錄搜索時,請先進入該目錄,然後再進行搜索。 + + > ![notes](../common/notes.svg) 說明:在檔案管理員的 **設置** 中,默認勾選了「自動索引內置磁盤」,您可以選擇勾選「連接電腦後索引外部存儲設備」,加快在外部設備的搜索速度。 + +#### 全文搜索 + +您可以通過文件內容關鍵字來搜索文件。 +1. 在檔案管理員中,單擊 ![icon_menu](../common/icon_menu.svg) > **設置**。 +2. 在高級設置項勾選「全文搜索」開啟此功能。 +3. 使用快捷鍵 **Ctrl + F** 或在地址欄中單擊搜索按鈕進入搜索狀態,輸入關鍵字後按下鍵盤上的 **Enter** 鍵,搜索相關文件。 + +#### 高級搜索 + +當文件較多,搜索較慢時,啟用高級搜索縮小搜索範圍,提高搜索效率。 + +1. 在搜索狀態下,輸入關鍵字後按 **Enter** 鍵,當搜索到結果時,搜索框右側顯示圖標 ![filter](../common/filter.svg) ,單擊該圖標可進行高級搜索的操作。 +2. 選擇搜索範圍、文件大小、文件類型、修改時間、訪問時間和創建時間,進行更精準的搜索。 +![0|filter](fig/d_filter.png) + +### 最近使用 + +在左側導航欄上默認有 **最近使用** 入口,單擊可以查看最近使用的文件。文件默認按照訪問時間倒序排列。 + +> ![notes](../common/notes.svg) 說明:若想隱藏「最近使用」,可在設置 > 基本設置 > 隱藏文件,取消勾選「顯示最近使用文件」。若要隱藏某一個文件的訪問記錄,右鍵單擊該文件選擇 **移除**,該操作不會刪除文件。 + +### 多標籤頁 + +檔案管理員支持多標籤頁顯示。 + +1. 在檔案管理員界面,右鍵單擊文件夾。 +2. 選擇 **在新標籤中打開**。 +3. 當窗口有多個標籤頁時,可以: + - 單擊標籤頁右側的按鈕 + ,繼續添加標籤頁。 + - 將鼠標指針置於標籤頁上,單擊關閉按鈕 **×** 或單擊鼠標中鍵,關閉標籤頁。 + +![1|tab](fig/d_tab.png) + +> ![tips](../common/tips.svg) 竅門:檔案管理員窗口只有一個標籤時,標籤頁是隱藏的,您還可以使用快捷鍵 **Ctrl + T** 來新建標籤頁。 + +### 書籤管理 + +為常用文件夾添加書籤,以便從左側導航欄快速訪問。 + +- 添加書籤:右鍵單擊文件夾,選擇 **添加書籤**,在導航欄創建書籤。 +- 移動書籤:在導航欄上下拖動書籤調整書籤排序。 +- 刪除書籤:右鍵單擊書籤,選擇 **移除** 來刪除書籤;或右鍵單擊已添加書籤的文件夾,選擇 **移除書籤** 來刪除書籤。 + +### 標記訊息 + +通過給文件/文件夾添加標記,可以更好地分類管理您的文件。 + +> ![notes](../common/notes.svg) 說明:當前僅x86平台支持 **標記訊息** 功能,該幫助手冊中涉及的標記訊息相關內容僅適用於x86平台。 + +#### 添加標記 + +您可以為一個文件(夾)添加多個標記,也可以同時為多個文件(夾)添加標記;添加成功的標記會出現在左側導航欄內。 + +##### 通過編輯框添加標記 + +1. 右鍵單擊文件(夾),選擇 **標記訊息**。 +2. 輸入標記名稱,若要添加多個標記,可用逗號分隔。 +3. 單擊界面空白區域保存設置。 + +>![notes](../common/notes.svg) 說明:標記顏色從8種默認顏色中隨機分配。 + +![1|tag_info](fig/d_tag_info.png) + + +##### 通過顏色按鈕添加標記 + +右鍵單擊文件(夾),選擇「顏色按鈕」,直接生成這個顏色的標記。 + +![1|color_tag](fig/d_color_tag.png) + +##### 通過右側訊息欄添加標記 + +選擇文件(夾)後,單擊菜單欄上的圖標 ![fileinfo](../common/fileinfo.svg),在右側訊息欄中也可以添加標記。 + +![1|info_tag](fig/d_info_tag.png) + +>![notes](../common/notes.svg) 說明:如果文件有標記,則複製或剪切該文件產生的文件仍然具有同樣的標記。 + + +#### 重命名標記 + +在左側導航欄中,右鍵單擊某個標記,選擇 **重命名**,修改當前標記的名稱。 + +![1|rename_tag](fig/rename_tag.png) + +#### 修改標記顏色 + +在左側導航欄中,右鍵單擊某個標記,選擇「顏色按鈕」,即可修改當前標記的顏色。 + +#### 排序標記 + +上下拖動標記即可調整標記排序。 + +#### 刪除標記 + +右鍵單擊某個標記,選擇 **移除**,刪除當前標記。 + + +### 文件預覽 + +檔案管理員支持空格鍵預覽功能,選中文件並按下鍵盤上的空格鍵就可以快速預覽文件。預覽窗口可以查看圖片解像度、文檔大小、文本內容等,還支持gif、音頻、影片播放。 + +#### 預覽影片 + +1. 選擇您要預覽的影片文件,按下空格鍵,即可開始預覽。 +2. 單擊影片任意地方可暫停播放。 +3. 播放過程中,可以拖動進度條來快進快退。 +4. 單擊底部 **打開** 按扭,在默認程序中打開該影片文件。 + +![1|video_preview](fig/video_preview.png) + +> ![notes](../common/notes.svg) 說明:您也可以同時選擇多個文件,按下空格鍵進行預覽。 + + +### 權限管理 +選擇對應文件(夾),單擊右鍵,選擇屬性,單擊 **權限管理**, 為所有者,群組,和其他用戶設置文件權限。 + +![2|permission](fig/permission.png) + +### 我的共享 + +當您設置了共享文件時,「我的共享」會出現在導航欄上。當所有共享文件都取消共享後,「我的共享」自動從導航欄中移除。 + +#### 共享本地文件 + +1. 在檔案管理員界面,右鍵單擊文件夾選擇 **共享文件夾**。 +2. 在文件夾的屬性窗口,勾選 **共享此文件夾**。 + + > ![notes](../common/notes.svg) 說明: 如果smb服務未開啟,共享文件夾時會彈出密碼認證窗口,輸入登錄密碼完成認證即可開啟smb服務。 + +3. 根據需要設置 **共享名**、**權限**、**匿名訪問** 後關閉窗口。 +4. 單擊 ![icon_menu](../common/icon_menu.svg) > **設置共享密碼**。 +5. 輸入共享密碼,單擊 **確定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg) 竅門:取消勾選 **共享此文件夾** 可以取消文件共享,也可以右鍵單擊文件,選擇 **取消共享**。 + + +#### 訪問共享文件 + +局域網中其他用戶共享的文件一般都可以在網絡鄰居中找到,您也可以通過smb訪問共享文件。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **連接到伺服器**,在編輯框中輸入伺服器地址,如:smb://xx.x.xx.xxx(一般為IP位址),單擊 **連接**;或者直接在地址欄中輸入伺服器地址,按下鍵盤上的 **Enter** 鍵。 +2. 選擇需要訪問的共享文件夾,在彈出的窗口中輸入用戶名和共享密碼,或者匿名訪問。 + - 未加密的網絡文件可以匿名訪問,不需要輸入用戶名和密碼。 + - 加密的網絡文件需要輸入用戶名和密碼之後才能訪問。 + + - 用戶名:共享者登錄系統的用戶名。 + - 密碼:共享文件時設置的共享密碼。 +3. 單擊 **連接**。 + +![1|visitshareshare](fig/visitshare.png) + +### 以管理員身份打開 + +1. 在檔案管理員界面上,右鍵單擊文件夾。 +2. 選擇 **以管理員身份打開**,在彈出的對話框中輸入用戶登錄密碼,單擊 **確定**。 +3. 該文件夾會以新窗口打開,在此窗口中可以進行高級權限的操作,關閉窗口後,終止管理員權限。 + +### 在終端中打開 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **在終端中打開**,會啟動終端應用程序,終端的路徑為當前目錄。 + +![0|open_terminal](fig/openinterminal.png) + +### 刻錄光盤 + +您可以通過刻錄功能將音樂、影片、圖片或鏡像文件複製到CD或DVD中。請提前準備一部刻錄機、一張CD或DVD光盤。 + + +1. 將光盤插入到刻錄機中。 +2. 打開檔案管理員,單擊導航欄中的光盤圖標,進入刻錄CD的界面。 + +![cd](fig/d_cd_interface.png) + +3. 右鍵單擊 文件(夾),選擇 **添加至光盤刻錄** 或直接將文件(夾)拖拽到刻錄CD的界面。 +4. 在刻錄CD界面,單擊右上角按鈕 **刻錄**。 + + >![notes](../common/notes.svg) 說明:如果要從刻錄列表中刪除某個文件(夾),右鍵單擊該文件(夾),選擇 **刪除**,將該文件(夾)從列表中移除。 + +5. 彈出對話框,輸入光盤名稱。您也可以進入 **高級設置** 界面,設置文件系統、寫入速度,或勾選「允許追加數據」、「核驗數據」等,單擊 **刻錄**。 + +![cd](fig/d_cd_rename.png) + +6. 刻錄完成後界面彈出提示框,單擊 **確定**。 + +>![notes](../common/notes.svg) 說明: +>- 當前系統僅支持對ISO9660格式的文件進行讀取與刻錄,而UDF格式的文件只支持讀取,暫不支持刻錄。 +>- 如果需要擦除光盤數據,可以右鍵單擊導航欄中光盤圖標,選擇 **卸載**,再次右鍵單擊該光盤圖標並選擇 **擦除**。 + +### 創建快捷方式 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **創建鏈接**。 +3. 在彈窗中選擇創建位置、鏈接名稱。 +4. 單擊 **保存**,在目標位置會生成該文件(夾)的快捷方式。 + +> ![tips](../common/tips.svg) 竅門:選擇 **發送到桌面** 可以直接在桌面上生成該文件(夾)的快捷方式。 + +### 發送文件(夾)到外接磁盤 + +當有外接磁盤接入時,您可以將文件或文件夾發送到外接磁盤。 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **發送到** > 外接磁盤。 +3. 文件(夾)將會被發送到移動外接磁盤。 + +### 發送文件到藍牙 + +若您的電腦配置了藍牙模塊,便可通過藍牙進行短距離文件傳輸的操作。 + +前提條件:發送端與接收端藍牙設備已配對並成功連接。具體連接方法請參閱 [連接藍牙設備](dman:///dde#連接藍牙設備)。 + +1. 在檔案管理員界面,右鍵單擊需要發送的文件或文件壓縮包。 +2. 選擇 **發送到** > **發送到藍牙**。 +3. 在彈出的藍牙文件傳輸對話框中勾選接收設備,單擊 **下一步**。 +4. 此時接收端會收到文件接收的請求,待接收端同意請求後,發送端開始傳輸文件。 + + + +## 文件角標 + +您可以通過命令行,將圖標文件指定給一個文件或文件夾作為角標顯示出來。 + +>![icon](../common/notes.svg) 說明: +>- 角標文件支持svg、jpg、png、bmp、gif格式,且大小不超過100KB。 +>- USB記憶體及光盤下的文件,不支持添加角標。 + +### 添加單個角標 + +1. 在終端輸入命令 **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑)"** ,該命令默認在文件(夾)右下角添加角標。 + + >![icon](../common/attention.svg) 注意:系統已定義的特殊角標,不支持被替換。 + +2. 您也可以在上述命令中加入位置參數,將角標添加在文件(夾)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + + 例如:在文件(夾)左上角添加角標 + + **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑);lu"** + +![mark](fig/d_single.png) + +### 添加多個角標 + +在命令行中加入“**|**”符號將角標文件路徑連接起來,為文件(夾)添加2~4個角標。文件(夾)同一個位置不支持疊加角標,僅支持替換。 + +例如:在文件(夾)四個角都添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑);lu|xxx(圖標路徑);ld|xxx(圖標路徑);ru|xxx(圖標路徑);rd"** + +![mark](fig/d_multi.png) + +### 撤銷角標 + +在終端中輸入命令 **gio set xxx(文件路徑) -t stringv metadata::emblems ""** 撤銷文件(夾)上所有的角標。 + + + + +## 磁盤管理 + +檔案管理員管理本地磁盤和外接磁盤。本地磁盤顯示在檔案管理員的左側導航欄上或計算機界面;掛載外接磁盤或者插入其他移動存儲設備時,也會在導航欄看到相應的磁盤圖標。 + + + + + + + + + + + + + + + + + +
本地磁盤本地硬碟分區的所有磁盤
外接磁盤包括移動硬碟、USB記憶體、光盤
移動設備手機內存、存儲卡、SD卡等
+ +> ![notes](../common/notes.svg) 說明:如果磁盤或磁盤中的文件夾已加密,請輸入密碼後查看文件。 + +### 本地磁盤 + +#### 隱藏本地磁盤 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg) > **設置**。 +2. 在高級設置選項中勾選 **隱藏系統盤**。 + +#### 重命名本地磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊本地磁盤。 +2. 選擇 **重命名**。 +3. 輸入新名稱,按下鍵盤上的 **Enter** 鍵或單擊界面空白區域保存修改。 + +> ![tips](../common/tips.svg)竅門:在計算機界面,慢速雙擊本地磁盤,呈現編輯框後也可以進行重命名操作。 + +![disk](fig/d_rename_disk.png) + +### 外接磁盤 + +#### 彈出外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要移除的磁盤。 +2. 選擇 **安全移除**。 +3. 磁盤將從磁盤列表中刪除,一併彈出該磁盤的所有分區。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) 竅門:如果要彈出光盤,請選擇 **彈出** 來移除光盤。單擊導航欄中磁盤右邊的按鈕 ![unmount](../common/unmount_normal.svg),同樣可以彈出磁盤或光盤。 + +#### 重命名外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要重命名的磁盤。 +2. 選擇 **卸載** 後,再次單擊右鍵選擇 **重命名**。 +3. 輸入新的卷標名稱,按下鍵盤上的 **Enter** 鍵或單擊界面空白區域保存修改。 + + + +#### 格式化外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要格式化的磁盤。 +2. 選擇 **卸載** 後,再次單擊右鍵選擇 **格式化**。 +3. 設置格式化之後的文件類型和卷標。 +4. 單擊 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) 說明:快速格式化速度快,但是數據仍然可能通過工具被恢復,如果想要格式化後的數據無法被恢復,可以取消勾選「快速格式化」,然後執行格式化操作。 + +## 主菜單 + +在主菜單中,您可以新建窗口,切換窗口主題,[設置共享密碼](#共享本地文件),設置檔案管理員,查看幫助手冊和版本介紹。 + +### 新建窗口 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **新建窗口**,打開一個新的檔案管理員窗口。 + +### 連接到伺服器 + +通過連接伺服器 [訪問局域網共享文件](#訪問共享文件)。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **連接到伺服器**,在編輯框中輸入伺服器IP位址。 + - 單擊 ![+](../common/+.svg) 按鈕可將該地址添加到「個人收藏伺服器」列表中。 + - 在「個人收藏伺服器」列表中選中一個地址,單擊 ![_](../common/-.svg) 按鈕,將該地址從收藏列表中移除。 +3. 單擊 **連接**。 + +![conncet](fig/connect_to_server.png) + + +### 設置 +#### 基礎設置 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)> **設置** 。 +2. 選擇 **基礎設置** 選項。 + + 勾選 **總是在新窗口打開文件夾**。 + + 設置雙擊或單擊打開文件。 + + 設置 **從默認窗口打開**、**從新標籤打開** 哪個目錄。 + + 設置文件圖標 **默認大小** 。 + + 設置 **默認視圖** 以圖標展示或列表展示。 + + 勾選 **顯示隱藏文件**,檔案管理員中被隱藏的文件會顯示出來。 + + 勾選 **重命名時隱藏文件擴展名**,重命名時不會顯示擴展名。 + + 勾選 **顯示最近使用文件**,在左側導航欄顯示最近使用的文件。 + +#### 高級設置 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)> **設置** 。 +2. 選擇 **高級設置** 選項。 + + 勾選 **自動索引內置磁盤**,搜索文件時會搜索內置磁盤中的文件。 + + 勾選 **連接電腦後索引外部存儲設備**,搜索文件時也會搜索外接設備中的文件。 + + 勾選 **全文搜索**,通過文件中的內容來索引。 + + 勾選預覽文件類型。 + + 勾選 **自動掛載**,接入外接磁盤時自動掛載。 + + 勾選 **自動掛載後打開**,接入外接磁盤時自動掛載並打開該磁盤。 + + 勾選 **MTP掛載路徑下顯示文件統計詳情**,MTP設備掛載後,顯示其路徑底部的狀態欄訊息。 + + 勾選 **Samba共享端常駐顯示掛載入口**,遠程掛載鏈接常駐顯示在導航欄中。 + + 勾選 **使用檔案管理員的文件選擇對話框**,選擇文件時打開檔案管理員窗口。 + + 勾選 **開啟普通刪除提示**,刪除文件時彈出提示對話框。 + + 勾選 **隱藏系統盤**,導航欄和計算機界面將不顯示本地磁盤。 + + 勾選 **在磁盤圖標上顯示文件系統標籤**。 + +### 主題 + +窗口主題包含淺色主題、深色主題和系統主題。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **主題**,選擇一個主題。 + + + +### 幫助 + +查看幫助手冊,進一步了解和使用檔案管理員。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **幫助**。 +3. 查看檔案管理員的幫助手冊。 + + +### 關於 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **關於**。 +3. 查看檔案管理員的版本和介紹。 + + +### 退出 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **退出**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/e_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/e_file-manager.md new file mode 100755 index 0000000..3fce176 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/e_file-manager.md @@ -0,0 +1,654 @@ +# 檔案管理員|dde-file-manager| + +## 概述 + +檔案管理員是一款功能強大、簡單易用的文件管理工具。它沿用了傳統檔案管理員的經典功能和佈局,並在此基礎上簡化了用戶操作,增加了很多特色功能。一目了然的導航欄、智能識別的搜索框、多樣化的視圖及排序讓您管理起來得心應手,經典和超越,只為給您更好的體驗! + +![1|overview](fig/e_overview.png) + + + +## 使用入門 + +通過以下方式運行或關閉檔案管理員,或者創建檔案管理員的快捷方式。 + +### 運行檔案管理員 + +1. 單擊任務欄上的啟動器圖標 ![deepin_launcher ](../common/deepin_launcher.svg),進入啟動器界面。 +2. 上下滾動鼠標滾輪瀏覽或通過搜索,找到檔案管理員圖標 ![deepin_file_manager](../common/deepin_file_manager.svg),單擊運行。 +3. 右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 單擊 **傳送到桌面**,在桌面創建快捷方式。 + - 單擊 **傳送到任務欄**,將應用程序固定到任務欄。 + - 單擊 **加至開機啟動**,將應用程序添加到開機啟動項,在電腦開機時自動運行該應用。 + +> ![tips](../common/tips.svg)竅門:您也可以使用快捷鍵 **Super + E** 啟動檔案管理員。 + +### 關閉檔案管理員 + +- 在檔案管理員界面,單擊 ![close_icon](../common/close_icon.svg),關閉檔案管理員。 +- 在任務欄右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),選擇 **關閉所有**,關閉檔案管理員。 +- 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg),選擇 **退出** ,關閉檔案管理員。 + +### 查看快捷鍵 + +在檔案管理員界面,使用快捷鍵 **Ctrl + Shift + /** 打開快捷鍵預覽界面。熟練地使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主界面 + +檔案管理員的主界面簡單易用、功能全面,熟練地使用界面功能將使檔案管理更加簡單高效。 + +![1|main_interface](fig/e_main_interface.png) + + +| 標號 | 名稱 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 導航欄 | 單擊導航圖標,快速訪問本地文件、磁盤、共享文件、書籤、標記等。 | +| 2 | 地址欄 | 通過地址欄,快速切換訪問歷史、在上下級目錄間切換、搜索、輸入地址訪問。 | +| 3 | 圖標/列表視圖 | 單擊 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg)圖標,以圖標或列表形式查看文件(夾)。 | +| 4 | 訊息欄 | 單擊 ![fileinfo](../common/fileinfo.svg), 查看文件(夾)的基本訊息和標記。 | +| 5 | 菜單欄 | 通過主菜單,您可以新建窗口、切換窗口主題、設置共享密碼、設置檔案管理員、查看幫助文檔和關於訊息、退出檔案管理員。 | +| 6 | 狀態欄 | 顯示文件數量或者已選中文件的數量。 | + +> ![tips](../common/tips.svg)竅門:可拖動左側導航欄右邊的分隔線來改變其寬度。 + +## 基本功能 + +檔案管理員具備基本的檔案管理功能,對文件(夾)進行新建、複製、重命名、刪除等操作都非常簡單。 + +### 新建文件 + +#### 新建文檔 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **新建文檔**。 +3. 選擇新建文件的類型。 +4. 輸入新建文檔的名稱。 + +![0|newdo](fig/e_newdo.png) + +#### 新建文件夾 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **新建文件夾**。 +3. 輸入新建文件夾的名稱。 + +### 重命名文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **重命名**。 +3. 輸入文件名稱,按 **Enter** 鍵或者單擊界面空白區域保存設置。 + +![0|contextmenu](fig/d_rename.png) + +> ![tips](../common/tips.svg)竅門:在 **設置** 中勾選「重命名時隱藏文件擴展名」,能更方便地修改文件名稱。 + +### 批量重命名 + +1. 在檔案管理員界面,選中多個文件。 +2. 右鍵單擊文件,選擇 **重命名**。 + - **替換文本** 查找需要替換的文本,並輸入替換後的文本,文件名中的關鍵字將被統一替換。 + - **添加文本** 輸入需要添加的文本,並選擇位置是名稱之前還是之後,文件名將統一加入被添加的文本。 + - **自定義文本** 輸入文件名,並輸入序列的遞進數字,文件名將統一改成新文件名+遞進數字。 +4. 單擊 **重命名** 來完成操作。 + +![1|rename](fig/e_batch_rename.png) + +### 查看文件 + +單擊菜單欄上的圖標 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 來切換圖標視圖和列表視圖。 + +- 圖標視圖:平鋪顯示文件的名稱、圖標或縮略圖。 + +![1|icon_view](fig/e_icon_view.png) + +- 列表視圖:列表顯示文件圖標或縮略圖、名稱、修改時間、大小、類型等訊息。 + +![1|list_view](fig/e_list_view.png) + +> ![tips](../common/tips.svg)竅門: +> - 在列表視圖中,把光標置於兩列之間的分隔線上, 拖動它來改變列的寬度;雙擊分隔線可將當前列自動調整為本列內容最寬的寬度。 +> - 使用 **Ctrl + 1** 和 **Ctrl + 2** 快捷鍵,切換圖標視圖和列表視圖。 + + +### 排序文件 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **排序方式**。 +3. 在子菜單中選擇以名稱、修改時間、大小或類型來排序文件。 + +> ![tips](../common/tips.svg)竅門:在列表視圖中,單擊表頭欄的列標籤來切換升序、降序。 + +### 打開文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **打開方式** > **選擇默認程序**。 +3. 在程序列表中選擇應用程序。 + +> ![notes](../common/notes.svg)說明:直接雙擊文件會使用默認程序打開。您可以選擇相同類型的多個文件,單擊右鍵選擇 **打開方式** 選項,一次打開多個文件。 + +![0|open](fig/d_open.png) + + + +### 隱藏文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **屬性**,勾選 **隱藏此文件**。 + +### 複製文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **複製**。 +3. 選擇一個目標存儲位置。 +4. 單擊鼠標右鍵,選擇 **黏貼**。 + +### 壓縮文件 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **壓縮**。 +3. 彈出歸檔管理器壓縮界面,可以設置壓縮包格式、名稱、存儲路徑等,單擊 **壓縮**。 + +> ![tips](../common/tips.svg)竅門:您也可以直接在右鍵菜單中選擇 **添加到xxx.7z** 或 **添加到xxx.zip**,快速將文件(夾)壓縮成7z或zip格式。 + +### 刪除文件 + +1. 在檔案管理員界面上,右鍵單擊文件。 +2. 選擇 **刪除** 。 + - 被刪除的文件可以在回收站中找到,右鍵單擊回收站中的文件可以進行 **還原** 或 **刪除** 操作。 + - 被刪除的文件的快捷方式將會失效。 + +> ![attention](../common/attention.svg)注意:从外接設備中刪除文件會將文件徹底刪除,無法從回收站找回。 + +### 撤銷操作 + +在檔案管理員中,可以用 **Ctrl + Z** 來撤銷上一步操作,包括: + +- 刪除新建的文件。 +- 恢復重命名(包括重命名文件後綴)之前的名字。 +- 從回收站還原剛刪除的文件。 +- 恢復文件到移動(剪切移動、鼠標移動)前的原始路徑。 +- 刪除複製黏貼的文件。 + +>![attention](../common/attention.svg)注意:撤銷動作最多只能返回兩步;如果操作中有覆蓋某個同名文件和徹底刪除文件,則撤銷只能返回到這一步。 + +### 文件屬性 + +文件屬性會顯示文件的基本訊息、打開方式和權限設置。文件夾屬性會顯示文件夾的基本訊息、共享訊息和權限設置。 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **屬性**,查看文件屬性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg)說明:查看多個文件屬性會顯示文件總大小和數量;查看快捷方式的屬性將會額外顯示源文件地址。您還可以使用 **Ctrl + I** 組合鍵查看文件屬性。 + + + +## 常用操作 + +檔案管理員具備很多特色功能,這些功能都讓檔案管理更加簡單、高效。 + +### 切換地址欄 + +地址欄由歷史導航、麵包屑和輸入框共同組成。通常情況下地址欄顯示麵包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 單擊歷史導航按鈕,快速在歷史瀏覽記錄間切換,查看前一個地址或者後一個地址。 +- 文件所在位置的每一個層級都會形成一個麵包屑,通過來回單擊麵包屑可以快速在不同文件層級間切換。 + +單擊搜索圖標,或者在文件路徑上單擊右鍵並選擇「編輯地址」,地址欄會切換為輸入框狀態。在輸入框外單擊時,地址欄會自動恢復到麵包屑狀態。 + +![0|addressbar](fig/addressbar2.png) + +- 輸入框帶有智能識別功能,輸入關鍵詞或者訪問地址,系統會自動識別並進行搜索或訪問。 + +### 搜索文件 + +檔案管理員支持多種檢索方式,既支持通過文件名稱、文件內容進行普通搜索,也支持通過文件類型、創建時間等進行高級搜索,提高工作效率,便於文件管理。 + +- 指定目錄搜索時,請先進入該目錄,然後再進行搜索。 + + > ![notes](../common/notes.svg)說明:在檔案管理員的 **設置** 中,默認勾選了「自動索引內置磁盤」,您可以選擇勾選「連接電腦後索引外部存儲設備」,加快在外部設備的搜索速度。 + +#### 全文搜索 + +您可以通過文件內容關鍵字來搜索文件。 +1. 在檔案管理員中,單擊 ![icon_menu](../common/icon_menu.svg) > **設置**。 +2. 在高級設置項勾選「全文搜索」開啟此功能。 +3. 使用快捷鍵 **Ctrl + F** 或在地址欄中單擊搜索按鈕進入搜索狀態,輸入關鍵字後按下鍵盤上的 **Enter** 鍵,搜索相關文件。 + +#### 高級搜索 + +當文件較多,搜索較慢時,啟用高級搜索縮小搜索範圍,提高搜索效率。 + +1. 在搜索狀態下,輸入關鍵字後按 **Enter** 鍵,當搜索到結果時,搜索框右側顯示 ![filter](../common/filter.svg) 圖標,點擊該圖標可進行高級搜索的操作。 +2. 選擇搜索範圍、文件大小、文件類型、修改時間、訪問時間和創建時間,進行更精準的搜索。 +![0|filter](fig/e_filter.png) + +### 最近使用 + +在左側導航欄上默認有 **最近使用** 入口,單擊可以查看最近使用的文件。文件默認按照訪問時間倒序排列。 + +> ![notes](../common/notes.svg)說明:若想隱藏「最近使用」,可在設置 > 基本設置 > 隱藏文件,取消勾選「顯示最近使用文件」。若要隱藏某一個文件的訪問記錄,右鍵單擊該文件選擇 **移除**,該操作不會刪除文件。 + +### 多標籤頁 + +檔案管理員支持多標籤頁顯示。 + +1. 在檔案管理員界面上,右鍵單擊文件夾。 +2. 選擇 **在新標籤中打開**。 +3. 當窗口有多個標籤頁時,可以: + - 單擊標籤頁右側的按鈕 + ,繼續添加標籤頁。 + - 將鼠標指針置於標籤頁上,單擊關閉按鈕 **×** 或單擊鼠標中鍵,關閉標籤頁。 + +![1|tab](fig/e_tab.png) + +> ![tips](../common/tips.svg)竅門:檔案管理員窗口只有一個標籤時,標籤頁是隱藏的,您還可以使用快捷鍵 **Ctrl + T** 來新建標籤頁。 + +### 書籤管理 + +為常用文件夾添加書籤,以便從左側導航欄快速訪問。 + +- 添加書籤:右鍵單擊文件夾,選擇 **添加書籤** 就可以在導航欄創建書籤。 +- 移動書籤:在導航欄上下拖動書籤調整書籤排序。 +- 刪除書籤:右鍵單擊書籤,選擇 **移除** 來刪除書籤;或右鍵單擊已添加書籤的文件夾,選擇 **移除書籤** 來刪除書籤。 + +### 標記訊息 + +通過給文件(夾)添加標記,可以更好地分類管理您的文件。 + +> ![notes](../common/notes.svg)說明:當前僅x86平台支持 **標記訊息** 功能,該幫助手冊中涉及的標記訊息相關內容僅適用於x86平台。 + +#### 添加標記 + +您可以為一個文件(夾)添加多個標記,也可以同時為多個文件(夾)添加標記;添加成功的標記會出現在左側導航欄內。 + +##### 通過編輯框添加標記 + +1. 右鍵單擊文件(夾),選擇 **標記訊息**。 +2. 輸入標記名稱,若要添加多個標記,可用逗號分隔。 +3. 單擊界面空白區域保存設置。 + +>![notes](../common/notes.svg)說明:標記顏色從8種默認顏色中隨機分配。 + +![1|tag_info](fig/e_tag_info.png) + + +##### 通過顏色按鈕添加標記 + +右鍵單擊文件(夾),選擇「顏色按鈕」,直接生成這個顏色的標記。 + +![1|color_tag](fig/e_color_tag.png) + +##### 通過右側訊息欄添加標記 +選擇文件(夾)後,單擊菜單欄上的圖標 ![fileinfo](../common/fileinfo.svg),在右側訊息欄中也可以添加標記。 + +![1|info_tag](fig/e_info_tag.png) + +>![notes](../common/notes.svg)說明:如果文件有標記,則複製或剪切該文件產生的文件仍然具有同樣的標記。 + + +#### 重命名標記 + +在左側導航欄中,右鍵單擊某個標記,選擇 **重命名**,修改當前標記的名稱。 + +![1|rename_tag](fig/rename_tag.png) + +#### 修改標記顏色 + +在左側導航欄中,右鍵單擊某個標記,選擇「顏色按鈕」,即可修改當前標記的顏色。 + +#### 排序標記 + +上下拖動標記即可調整標記排序。 + +#### 刪除標記 + +右鍵單擊某個標記,選擇 **移除**,刪除當前標記。 + + +### 文件預覽 + +檔案管理員支持空格鍵預覽功能,選中文件並按下鍵盤上的空格鍵就可以快速預覽文件。預覽窗口可以查看圖片解像度、文檔大小、文本內容等,還支持gif、音頻、影片播放。 + +#### 預覽影片 + +1. 選擇您要預覽的影片文件,按下空格鍵,即可開始預覽。 +2. 單擊影片任意地方可暫停播放。 +3. 播放過程中,可以拖動進度條來快進快退。 +4. 單擊底部 **打開** 按扭,在默認程序中打開該影片文件。 + +![1|video_preview](fig/video_preview.png) + +> ![notes](../common/notes.svg)說明:您也可以同時選擇多個文件,按下空格鍵進行預覽。 + + +### 權限管理 +選擇對應文件(夾),單擊右鍵,選擇屬性,單擊 **權限管理**, 為所有者,群組,和其他用戶設置文件權限。 + +![2|permission](fig/permission.png) + +### 我的共享 + +當您設置了共享文件時,「我的共享」將會出現在導航欄上。當所有共享文件都取消共享後,「我的共享」自動從導航欄中移除。 + +#### 共享本地文件 + +1. 在檔案管理員界面,右鍵單擊文件夾選擇 **共享文件夾**。 +2. 在文件夾的屬性窗口,勾選 **共享此文件夾**。 +3. 根據需要設置 **共享名**、**權限** 、**匿名訪問** 後關閉窗口。 +4. 單擊 ![icon_menu](../common/icon_menu.svg) > **設置共享密碼**。 +5. 輸入共享密碼,單擊 **確定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg)竅門:取消勾選 **共享此文件夾** 可以取消文件共享,也可以右鍵單擊文件,選擇 **取消共享**。 + + +#### 訪問共享文件 + +局域網中其他用戶共享的文件一般都可以在網絡鄰居中找到,您也可以通過smb訪問共享文件。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **連接到伺服器**,在編輯框中輸入伺服器地址,如:smb://xx.x.xx.xxx(一般為IP位址),單擊 **連接**;或者直接在地址欄中輸入伺服器地址,按下鍵盤上的 **Enter** 鍵。 +2. 選擇需要訪問的共享文件夾,在彈出的窗口中輸入用戶名和共享密碼,或者匿名訪問。 + - 未加密的網絡文件可以匿名訪問,不需要輸入用戶名和密碼。 + - 加密的網絡文件需要輸入用戶名和密碼之後才能訪問。 + + - 用戶名:共享者登錄系統的用戶名。 + - 密碼:共享文件時設置的共享密碼。 +3. 單擊 **連接**。 + +![1|visitshareshare](fig/visitshare.png) + + + +### 在終端中打開 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **在終端中打開**,會啟動終端應用程序,終端的路徑為當前目錄。 + +![0|open_terminal](fig/e_openinterminal.png) + +### 刻錄光盤 +您可以通過刻錄功能將音樂、影片、圖片或鏡像文件複製到CD或DVD中。請提前準備一部刻錄機、一張CD或DVD光盤。 + +1. 將光盤插入到刻錄機中。 +2. 打開檔案管理員,單擊導航欄中的光盤圖標,進入刻錄CD的界面。 + +![cd](fig/e_cd_interface.png) + +3. 右鍵單擊 文件(夾),選擇 **添加至光盤刻錄** 或直接將文件(夾)拖拽到刻錄CD的界面。 +4. 在刻錄CD界面,單擊右上角按鈕 **刻錄**。 + + >![notes](../common/notes.svg)說明:如果要從刻錄列表中刪除某個文件(夾),右鍵單擊該文件(夾),選擇 **刪除**,將該文件(夾)從列表中移除。 + +5. 彈出對話框,輸入光盤名稱。您也可以進入 **高級設置** 界面,設置文件系統、寫入速度,或勾選「允許追加數據」、「核驗數據」等,單擊 **刻錄**。 + +![cd](fig/e_cd_rename.png) + +6. 刻錄完成後界面彈出提示框,單擊 **確定**。 + +>![notes](../common/notes.svg)說明: +>- 當前系統僅支持對ISO9660格式的文件進行讀取與刻錄,而UDF格式的文件只支持讀取,暫不支持刻錄。 +>- 如果需要擦除光盤數據,可以右鍵單擊導航欄中光盤圖標,選擇 **卸載**,再次右鍵單擊該光盤圖標並選擇 **擦除**。 + +### 創建快捷方式 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **創建鏈接**。 +3. 在彈窗中選擇創建位置、鏈接名稱。 +4. 單擊 **保存**,在目標位置會生成該文件(夾)的快捷方式。 + +> ![tips](../common/tips.svg)竅門:選擇 **發送到桌面** 可以直接在桌面上生成該文件(夾)的快捷方式。 + +### 發送文件(夾)到外接磁盤 + +當有外接磁盤接入時,您可以將文件或文件夾發送到外接磁盤。 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **發送到** > 外接磁盤。 +3. 文件(夾)將會被發送到移動外接磁盤。 + + + +## 文件角標 + +您可以通過命令行,將圖標文件指定給一個文件或文件夾作為角標顯示出來。 + +>![icon](../common/notes.svg)說明: +>- 角標文件支持svg、jpg、png、bmp、gif格式,且大小不超過100KB。 +>- USB記憶體及光盤下的文件,不支持添加角標。 + +### 添加單個角標 + +1. 在終端輸入命令 **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑)"** ,該命令默認在文件(夾)右下角添加角標。 + + >![icon](../common/attention.svg)注意:系統已定義的特殊角標,不支持被替換。 + +2. 您也可以在上述命令中加入位置參數,將角標添加在文件(夾)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + + 例如:在文件(夾)左上角添加角標 + + **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑);lu"** + +![mark](fig/single.png) + +### 添加多個角標 + +在命令行中加入“**|**”符號將角標文件路徑連接起來,為文件(夾)添加2~4個角標。文件(夾)同一個位置不支持疊加角標,僅支持替換。 + +例如:在文件(夾)四個角都添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑);lu|xxx(圖標路徑);ld|xxx(圖標路徑);ru|xxx(圖標路徑);rd"** + +![mark](fig/multi.png) + +### 撤銷角標 + +在終端中輸入命令 **gio set xxx(文件路徑) -t stringv metadata::emblems ""** 撤銷文件(夾)上所有的角標。 + + +## 文件保險箱 + +文件保險箱旨在為您打造專屬的安全空間,為您的私隱保駕護航。先進的加密技術,便捷的操作流程,使用起來得心應手。 + +### 設置保險箱密碼 + +首次使用保險箱需要對其進行密碼設置,具體步驟如下: + +1. 單擊導航欄中的保險箱圖標 ![file_vault](../common/file_vault.svg),或者在計算機界面雙擊 **我的保險箱**,在彈窗中單擊 **建立**。 +2. 設置解鎖類型、保險箱密碼等,單擊 **下一步**。 + +![0|password](fig/password.png) + + > ![notes](../common/notes.svg)說明: 密碼必須同時包含大寫字母、小寫字母、數字和符號,且字符不小於8位,否則無法進入下一步。 + +3. 此時保險箱密碼生成密鑰/二維碼,建議您將密鑰/二維碼保存,若忘記密碼,可用密鑰/二維碼開啟保險箱,單擊 **下一步**。 +4. 單擊 **加密保險箱**;彈出認證窗口,單擊 **確定**。 +5. 加密完成後在彈窗中單擊 **確定**,完成保險箱密碼設置。 + + + +### 鎖上保險箱 + +將文件放入保險箱後,右鍵單擊 ![file_vault](../common/file_vault.svg) 或者在計算機界面右鍵單擊 **我的保險箱**。 +- 選擇 **立即上鎖**,立即將文件保險箱鎖上。 +- 選擇 **自動上鎖**,在其下拉列表進行設置: + + 選擇「從不」,計算機在鎖屏或關機前一直保持未上鎖狀態。 + + 選擇「5分鐘」、「10分鐘」或者「20分鐘」後自動上鎖保險箱。 + +![0|right](fig/right.png) + + +### 解鎖保險箱 + +右鍵單擊 ![file_vault](../common/file_vault.svg) 或者計算機界面 **我的保險箱**。 + +- 選擇 **解鎖**,在彈窗中輸入保險箱密碼,單擊 **解鎖**。 +- 選擇 **密鑰解鎖**,在彈窗中輸入32位密鑰,單擊 **解鎖**。 + +>![0|tips](../common/tips.svg)竅門:您也可以單擊 ![file_vault](../common/file_vault.svg) 或者雙擊計算機界面 **我的保險箱**,使用密碼解鎖保險箱。 + + +### 刪除保險箱 +刪除保險箱需要提前解鎖保險箱。 +1. 右鍵單擊 ![file_vault](../common/file_vault.svg) 或者在計算機界面右鍵單擊 **我的保險箱**,選擇 **刪除保險箱**。 +2. 彈出刪除保險箱窗口,輸入保險箱密碼,單擊 **刪除**。 +3. 在密碼認證窗口中輸入用戶登錄密碼,單擊 **確定** 完成操作。 +> ![attention](../common/attention.svg)注意:刪除保險箱會將裏面的文件一併刪除。在進行刪除操作前,請將保險箱中的文件備份。 + +## 磁盤管理 + +檔案管理員管理本地磁盤和外接磁盤。本地磁盤顯示在檔案管理員的左側導航欄上或計算機界面;掛載外接磁盤或者插入其他移動存儲設備時,也會在導航欄看到相應的磁盤圖標。 + + + + + + + + + + + + + + + + + +
本地磁盤本地硬碟分區的所有磁盤
外接磁盤包括移動硬碟、USB記憶體、光盤
移動設備手機內存、存儲卡、SD卡等
+ +> ![notes](../common/notes.svg)說明:如果磁盤或磁盤中的文件夾已加密,請輸入密碼後查看文件。 + +### 本地磁盤 + +#### 隱藏本地磁盤 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg) > **設置**。 +2. 在高級設置選項中勾選 **隱藏系統盤**。 + +#### 重命名本地磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊本地磁盤。 +2. 選擇 **重命名**。 +3. 輸入新名稱,按下鍵盤上的 **Enter** 鍵或單擊界面空白區域保存修改。 + +> ![tips](../common/tips.svg)竅門:在計算機界面,慢速雙擊本地磁盤,呈現編輯框後便可進行重命名操作。 + +![0|disk](fig/e_rename_disk.png) + +### 外接磁盤 + +#### 彈出外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要移除的磁盤。 +2. 選擇 **安全移除**。 +3. 磁盤將從磁盤列表中刪除,一併彈出該磁盤的所有分區。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg)竅門:如果要彈出光盤,請選擇 **彈出** 來移除光盤。單擊導航欄中磁盤右邊的 ![unmount](../common/unmount_normal.svg) 同樣可以彈出磁盤或光盤。 + +#### 重命名外接磁盤 +1. 在左側導航欄或計算機界面,右鍵單擊需要重命名的磁盤。 +2. 選擇 **卸載**後,再次單擊右鍵選擇 **重命名**。 +3. 輸入新的卷標名稱,按下鍵盤上的 **Enter** 鍵或單擊界面空白區域保存修改。 + + + +#### 格式化外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要格式化的磁盤。 +2. 選擇 **卸載** 後,再次單擊右鍵選擇 **格式化**。 +3. 設置格式化之後的文件類型和卷標。 +4. 單擊 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg)說明:快速格式化速度快,但是數據仍然可能通過工具被恢復,如果想要格式化後的數據無法被恢復,可以取消勾選“快速格式化”,然後執行格式化操作。 + +## 主菜單 + +在主菜單中,您可以新建窗口,切換窗口主題,[設置共享密碼](#共享本地文件),設置檔案管理員,查看幫助手冊和版本介紹。 + +### 新建窗口 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **新建窗口**,打開一個新的檔案管理員窗口。 + +### 連接到伺服器 + +通過連接伺服器 [訪問局域網共享文件](#訪問共享文件)。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **連接到伺服器**,在編輯框中輸入伺服器IP位址。 + - 單擊 ![+](../common/+.svg) 按鈕可將該地址添加到「個人收藏伺服器」列表中。 + - 在「個人收藏伺服器」列表中選中一個地址,單擊 ![_](../common/-.svg) 按鈕,將該地址從收藏列表中移除。 +3. 單擊 **連接**。 + +![conncet](fig/connect_to_server.png) + + +### 設置 +#### 基礎設置 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)> **設置** 。 +2. 選擇 **基礎設置** 選項。 + + 勾選 **總是在新窗口打開文件夾**。 + + 設置雙擊或單擊打開文件。 + + 設置 **從默認窗口打開**、**從新標籤打開** 哪個目錄。 + + 設置文件圖標 **默認大小** 。 + + 設置 **默認視圖** 以圖標展示或列表展示。 + + 勾選 **顯示隱藏文件**,檔案管理員中被隱藏的文件會顯示出來。 + + 勾選 **重命名時隱藏文件擴展名**,重命名時不會顯示擴展名。 + + 勾選 **顯示最近使用文件**,在左側導航欄顯示最近使用的文件。 + +#### 高級設置 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)> **設置** 。 +2. 選擇 **高級設置** 選項。 + + 勾選 **自動索引內置磁盤**,搜索文件時會搜索內置磁盤中的文件。 + + 勾選 **連接電腦後索引外部存儲設備**,搜索文件時也會搜索外接設備中的文件。 + + 勾選 **全文搜索**,通過文件中的內容來索引。 + + 勾選預覽文件類型。 + + 勾選 **自動掛載**,接入外接磁盤時自動掛載。 + + 勾選 **自動掛載後打開**,接入外接磁盤時自動掛載並打開該磁盤。 + + 勾選 **MTP掛載路徑下顯示文件統計詳情**,MTP設備掛載後,顯示其路徑底部的狀態欄訊息。 + + 勾選 **使用檔案管理員的文件選擇對話框**,選擇文件時打開檔案管理員窗口。 + + 勾選 **開啟普通刪除提示**,刪除文件時彈出提示對話框。 + + 勾選 **隱藏系統盤**,導航欄和計算機界面將不顯示本地磁盤。 + + 勾選 **在磁盤圖標上顯示文件系統標籤**。 + +### 主題 + +窗口主題包含淺色主題、深色主題和系統主題。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **主題**,選擇一個主題。 + + + +### 幫助 + +查看幫助手冊,進一步了解和使用檔案管理員。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **幫助**。 +3. 查看檔案管理員的幫助手冊。 + + +### 關於 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **關於**。 +3. 查看檔案管理員的版本和介紹。 + + +### 退出 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **退出**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/eu_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/eu_file-manager.md new file mode 100755 index 0000000..b4ece1a --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/eu_file-manager.md @@ -0,0 +1,660 @@ +# 檔案管理員|dde-file-manager| + +## 概述 + +檔案管理員是一款功能強大、簡單易用的文件管理工具。它沿用了傳統檔案管理員的經典功能和佈局,並在此基礎上簡化了用戶操作,增加了很多特色功能。一目了然的導航欄、智能識別的搜索框、多樣化的視圖及排序讓您管理起來得心應手,經典和超越,只為給您更好的體驗! + +![1|overview](fig/e_overview.png) + + + +## 使用入門 + +通過以下方式運行或關閉檔案管理員,或者創建檔案管理員的快捷方式。 + +### 運行檔案管理員 + +1. 單擊任務欄上的啟動器圖標 ![deepin_launcher ](../common/deepin_launcher.svg),進入啟動器界面。 +2. 上下滾動鼠標滾輪瀏覽或通過搜索,找到檔案管理員圖標 ![deepin_file_manager](../common/deepin_file_manager.svg),單擊運行。 +3. 右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 單擊 **傳送到桌面**,在桌面創建快捷方式。 + - 單擊 **傳送到任務欄**,將應用程序固定到任務欄。 + - 單擊 **加至開機啟動**,將應用程序添加到開機啟動項,在電腦開機時自動運行該應用。 + +> ![tips](../common/tips.svg) 竅門:您也可以使用快捷鍵 **Super + E** 啟動檔案管理員。 + +### 關閉檔案管理員 + +- 在檔案管理員界面,單擊 ![close_icon](../common/close_icon.svg),關閉檔案管理員。 +- 在任務欄右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),選擇 **關閉所有**,關閉檔案管理員。 +- 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg),選擇 **退出** ,關閉檔案管理員。 + +### 查看快捷鍵 + +在檔案管理員界面,使用快捷鍵 **Ctrl + Shift + /** 打開快捷鍵預覽界面。熟練地使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主界面 + +檔案管理員的主界面簡單易用、功能全面,熟練地使用界面功能將使檔案管理更加簡單高效。 + +![1|main_interface](fig/e_main_interface.png) + + +| 標號 | 名稱 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 導航欄 | 單擊導航圖標,快速訪問本地文件、磁盤、共享文件、書籤、標記等。 | +| 2 | 地址欄 | 通過地址欄,快速切換訪問歷史、在上下級目錄間切換、搜索、輸入地址訪問。 | +| 3 | 圖標/列表視圖 | 單擊 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg) 圖標,以圖標或列表形式查看文件(夾)。 | +| 4 | 訊息欄 | 單擊 ![fileinfo](../common/fileinfo.svg), 查看文件(夾)的基本訊息和標記。 | +| 5 | 菜單欄 | 通過主菜單,您可以新建窗口、切換窗口主題、設置共享密碼、設置檔案管理員、查看幫助文檔和關於訊息、退出檔案管理員。 | +| 6 | 狀態欄 | 顯示文件數量或者已選中文件的數量。 | + +> ![tips](../common/tips.svg) 竅門:可拖動左側導航欄右邊的分隔線來改變其寬度。 + +## 基本功能 + +檔案管理員具備基本的檔案管理功能,對文件(夾)進行新建、複製、重命名、刪除等操作都非常簡單。 + +### 新建文件 + +#### 新建文檔 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **新建文檔**。 +3. 選擇新建文件的類型。 +4. 輸入新建文檔的名稱。 + +![0|newdo](fig/e_newdo.png) + +#### 新建文件夾 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **新建文件夾**。 +3. 輸入新建文件夾的名稱。 + +### 重命名文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **重命名**。 +3. 輸入文件名稱,按 **Enter** 鍵或者單擊界面空白區域保存設置。 + +![0|contextmenu](fig/d_rename.png) + +> ![tips](../common/tips.svg) 竅門:在 **設置** 中勾選「重命名時隱藏文件擴展名」,能更方便地修改文件名稱。 + +### 批量重命名 + +1. 在檔案管理員界面,選中多個文件。 +2. 右鍵單擊文件,選擇 **重命名**。 + - **替換文本** 查找需要替換的文本,並輸入替換後的文本,文件名中的關鍵字將被統一替換。 + - **添加文本** 輸入需要添加的文本,並選擇位置是名稱之前還是之後,文件名將統一加入被添加的文本。 + - **自定義文本** 輸入文件名,並輸入序列的遞進數字,文件名將統一改成新文件名+遞進數字。 +4. 單擊 **重命名** 來完成操作。 + +![1|rename](fig/e_batch_rename.png) + +### 查看文件 + +單擊菜單欄上的圖標 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 來切換圖標視圖和列表視圖。 + +- 圖標視圖:平鋪顯示文件的名稱、圖標或縮略圖。 + +![1|icon_view](fig/e_icon_view.png) + +- 列表視圖:列表顯示文件圖標或縮略圖、名稱、修改時間、大小、類型等訊息。 + +![1|list_view](fig/e_list_view.png) + +> ![tips](../common/tips.svg) 竅門: +> - 在列表視圖中,把光標置於兩列之間的分隔線上, 拖動它來改變列的寬度;雙擊分隔線可將當前列自動調整為本列內容最寬的寬度。 +> - 使用 **Ctrl + 1** 和 **Ctrl + 2** 快捷鍵,切換圖標視圖和列表視圖。 + + +### 排序文件 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **排序方式**。 +3. 在子菜單中選擇以名稱、修改時間、大小或類型來排序文件。 + +> ![tips](../common/tips.svg) 竅門:在列表視圖中,單擊表頭欄的列標籤來切換升序、降序。 + +### 打開文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **打開方式** > **選擇默認程序**。 +3. 在程序列表中選擇應用程序。 + +> ![notes](../common/notes.svg) 說明:直接雙擊文件會使用默認程序打開。您可以選擇相同類型的多個文件,單擊右鍵選擇 **打開方式** 選項,一次打開多個文件。 + +![0|open](fig/d_open.png) + + + +### 隱藏文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **屬性**,勾選 **隱藏此文件**。 + +### 複製文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **複製**。 +3. 選擇一個目標存儲位置。 +4. 單擊鼠標右鍵,選擇 **黏貼**。 + +### 壓縮文件 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **壓縮**。 +3. 彈出歸檔管理器壓縮界面,可以設置壓縮包格式、名稱、存儲路徑等,單擊 **壓縮**。 + +> ![tips](../common/tips.svg) 竅門:您也可以直接在右鍵菜單中選擇 **添加到xxx.7z** 或 **添加到xxx.zip**,快速將文件(夾)壓縮成7z或zip格式。 + +### 刪除文件 + +1. 在檔案管理員界面上,右鍵單擊文件。 +2. 選擇 **刪除** 。 + - 被刪除的文件可以在回收站中找到,右鍵單擊回收站中的文件可以進行 **還原** 或 **刪除** 操作。 + - 被刪除的文件的快捷方式將會失效。 + +> ![attention](../common/attention.svg) 注意:从外接設備中刪除文件會將文件徹底刪除,無法從回收站找回。 + +### 撤銷操作 + +在檔案管理員中,可以用 **Ctrl + Z** 來撤銷上一步操作,包括: + +- 刪除新建的文件。 +- 恢復重命名(包括重命名文件後綴)之前的名字。 +- 從回收站還原剛刪除的文件。 +- 恢復文件到移動(剪切移動、鼠標移動)前的原始路徑。 +- 刪除複製黏貼的文件。 + +>![attention](../common/attention.svg) 注意:撤銷動作最多只能返回兩步;如果操作中有覆蓋某個同名文件和徹底刪除文件,則撤銷只能返回到這一步。 + +### 文件屬性 + +文件屬性會顯示文件的基本訊息、打開方式和權限設置。文件夾屬性會顯示文件夾的基本訊息、共享訊息和權限設置。 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **屬性**,查看文件屬性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg) 說明:查看多個文件屬性會顯示文件總大小和數量;查看快捷方式的屬性將會額外顯示源文件地址。您還可以使用 **Ctrl + I** 組合鍵查看文件屬性。 + + + +## 常用操作 + +檔案管理員具備很多特色功能,這些功能都讓檔案管理更加簡單、高效。 + +### 切換地址欄 + +地址欄由歷史導航、麵包屑和輸入框共同組成。通常情況下地址欄顯示麵包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 單擊歷史導航按鈕,快速在歷史瀏覽記錄間切換,查看前一個地址或者後一個地址。 +- 文件所在位置的每一個層級都會形成一個麵包屑,通過來回單擊麵包屑可以快速在不同文件層級間切換。 + +單擊搜索圖標,或者在文件路徑上單擊右鍵並選擇「編輯地址」,地址欄會切換為輸入框狀態。在輸入框外單擊時,地址欄會自動恢復到麵包屑狀態。 + +![0|addressbar](fig/addressbar2.png) + +- 輸入框帶有智能識別功能,輸入關鍵詞或者訪問地址,系統會自動識別並進行搜索或訪問。 + +### 搜索文件 + +檔案管理員支持多種檢索方式,既支持通過文件名稱、文件內容進行普通搜索,也支持通過文件類型、創建時間等進行高級搜索,提高工作效率,便於文件管理。 + +- 指定目錄搜索時,請先進入該目錄,然後再進行搜索。 + + > ![notes](../common/notes.svg) 說明:在檔案管理員的 **設置** 中,默認勾選了「自動索引內置磁盤」,您可以選擇勾選「連接電腦後索引外部存儲設備」,加快在外部設備的搜索速度。 + +#### 全文搜索 + +您可以通過文件內容關鍵字來搜索文件。 +1. 在檔案管理員中,單擊 ![icon_menu](../common/icon_menu.svg) > **設置**。 +2. 在高級設置項勾選「全文搜索」開啟此功能。 +3. 使用快捷鍵 **Ctrl + F** 或在地址欄中單擊搜索按鈕進入搜索狀態,輸入關鍵字後按下鍵盤上的 **Enter** 鍵,搜索相關文件。 + +#### 高級搜索 + +當文件較多,搜索較慢時,啟用高級搜索縮小搜索範圍,提高搜索效率。 + +1. 在搜索狀態下,輸入關鍵字後按 **Enter** 鍵,當搜索到結果時,搜索框右側顯示 ![filter](../common/filter.svg) 圖標,點擊該圖標可進行高級搜索的操作。 +2. 選擇搜索範圍、文件大小、文件類型、修改時間、訪問時間和創建時間,進行更精準的搜索。 + +![0|filter](fig/e_filter.png) + +### 最近使用 + +在左側導航欄上默認有 **最近使用** 入口,單擊可以查看最近使用的文件。文件默認按照訪問時間倒序排列。 + +> ![notes](../common/notes.svg) 說明:若想隱藏「最近使用」,可在 **設置 > 基本設置 > 隱藏文件**,取消勾選「顯示最近使用文件」。若要隱藏某一個文件的訪問記錄,右鍵單擊該文件選擇 **移除**,該操作不會刪除文件。 + +### 多標籤頁 + +檔案管理員支持多標籤頁顯示。 + +1. 在檔案管理員界面上,右鍵單擊文件夾。 +2. 選擇 **在新標籤中打開**。 +3. 當窗口有多個標籤頁時,可以: + - 單擊標籤頁右側的按鈕 + ,繼續添加標籤頁。 + - 將鼠標指針置於標籤頁上,單擊關閉按鈕 **×** 或單擊鼠標中鍵,關閉標籤頁。 + +![1|tab](fig/e_tab.png) + +> ![tips](../common/tips.svg) 竅門:檔案管理員窗口只有一個標籤時,標籤頁是隱藏的,您還可以使用快捷鍵 **Ctrl + T** 來新建標籤頁。 + +### 書籤管理 + +為常用文件夾添加書籤,以便從左側導航欄快速訪問。 + +- 添加書籤:右鍵單擊文件夾,選擇 **添加書籤** 就可以在導航欄創建書籤。 +- 移動書籤:在導航欄上下拖動書籤調整書籤排序。 +- 刪除書籤:右鍵單擊書籤,選擇 **移除** 來刪除書籤;或右鍵單擊已添加書籤的文件夾,選擇 **移除書籤** 來刪除書籤。 + +### 標記訊息 + +通過給文件(夾)添加標記,可以更好地分類管理您的文件。 + +> ![notes](../common/notes.svg) 說明:當前僅x86平台支持 **標記訊息** 功能,該幫助手冊中涉及的標記訊息相關內容僅適用於x86平台。 + +#### 添加標記 + +您可以為一個文件(夾)添加多個標記,也可以同時為多個文件(夾)添加標記;添加成功的標記會出現在左側導航欄內。 + +##### 通過編輯框添加標記 + +1. 右鍵單擊文件(夾),選擇 **標記訊息**。 +2. 輸入標記名稱,若要添加多個標記,可用逗號分隔。 +3. 單擊界面空白區域保存設置。 + +>![notes](../common/notes.svg) 說明:標記顏色從8種默認顏色中隨機分配。 + +![1|tag_info](fig/e_tag_info.png) + + +##### 通過顏色按鈕添加標記 + +右鍵單擊文件(夾),選擇「顏色按鈕」,直接生成這個顏色的標記。 + +![1|color_tag](fig/e_color_tag.png) + +##### 通過右側訊息欄添加標記 + +選擇文件(夾)後,單擊菜單欄上的圖標 ![fileinfo](../common/fileinfo.svg),在右側訊息欄中也可以添加標記。 + +![1|info_tag](fig/e_info_tag.png) + +>![notes](../common/notes.svg) 说明:如果文件有標記,則複製或剪切該文件產生的文件仍然具有同樣的標記。 + + +#### 重命名標記 + +在左側導航欄中,右鍵單擊某個標記,選擇 **重命名**,修改當前標記的名稱。 + +![1|rename_tag](fig/rename_tag.png) + +#### 修改標記顏色 + +在左側導航欄中,右鍵單擊某個標記,選擇「顏色按鈕」,即可修改當前標記的顏色。 + +#### 排序標記 + +上下拖動標記即可調整標記排序。 + +#### 刪除標記 + +右鍵單擊某個標記,選擇 **移除**,刪除當前標記。 + + +### 文件預覽 + +檔案管理員支持空格鍵預覽功能,選中文件並按下鍵盤上的空格鍵就可以快速預覽文件。預覽窗口可以查看圖片解像度、文檔大小、文本內容等,還支持gif、音頻、影片播放。 + +#### 預覽影片 + +1. 選擇您要預覽的影片文件,按下空格鍵,即可開始預覽。 +2. 單擊影片任意地方可暫停播放。 +3. 播放過程中,可以拖動進度條來快進快退。 +4. 單擊底部 **打開** 按扭,在默認程序中打開該影片文件。 + +![1|video_preview](fig/video_preview.png) + +> ![notes](../common/notes.svg) 說明:您也可以同時選擇多個文件,按下空格鍵進行預覽。 + + +### 權限管理 + +選擇對應文件(夾),單擊右鍵,選擇屬性,單擊 **權限管理**, 為所有者,群組,和其他用戶設置文件權限。 + +![2|permission](fig/permission.png) + +### 我的共享 + +當您設置了共享文件時,「我的共享」將會出現在導航欄上。當所有共享文件都取消共享後,「我的共享」自動從導航欄中移除。 + +#### 共享本地文件 + +1. 在檔案管理員界面,右鍵單擊文件夾選擇 **共享文件夾**。 +2. 在文件夾的屬性窗口,勾選 **共享此文件夾**。 +3. 根據需要設置 **共享名**、**權限** 、**匿名訪問** 後關閉窗口。 +4. 單擊 ![icon_menu](../common/icon_menu.svg) > **設置共享密碼**。 +5. 輸入共享密碼,單擊 **確定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg) 竅門:取消勾選 **共享此文件夾** 可以取消文件共享,也可以右鍵單擊文件,選擇 **取消共享**。 + + +#### 訪問共享文件 + +局域網中其他用戶共享的文件一般都可以在網絡鄰居中找到,您也可以通過smb訪問共享文件。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **連接到伺服器**,在編輯框中輸入伺服器地址,如:smb://xx.x.xx.xxx(一般為IP位址),單擊 **連接**;或者直接在地址欄中輸入伺服器地址,按下鍵盤上的 **Enter** 鍵。 +2. 選擇需要訪問的共享文件夾,在彈出的窗口中輸入用戶名和共享密碼,或者匿名訪問。 + - 未加密的網絡文件可以匿名訪問,不需要輸入用戶名和密碼。 + - 加密的網絡文件需要輸入用戶名和密碼之後才能訪問。 + + - 用戶名:共享者登錄系統的用戶名。 + - 密碼:共享文件時設置的共享密碼。 +3. 單擊 **連接**。 + +![1|visitshareshare](fig/visitshare.png) + + + +### 在終端中打開 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **在終端中打開**,會啟動終端應用程序,終端的路徑為當前目錄。 + +![0|open_terminal](fig/e_openinterminal.png) + +### 刻錄光盤 + +您可以通過刻錄功能將音樂、影片、圖片或鏡像文件複製到光盤中。請提前準備一部刻錄機、一張CD或DVD光盤。 + + +1. 將光盤插入到刻錄機中。 +2. 打開檔案管理員,單擊導航欄中的光盤圖標,進入刻錄CD的界面。 + +![cd](fig/e_cd_interface.png) + +3. 右鍵單擊 文件(夾),選擇 **添加至光盤刻錄** 或直接將文件(夾)拖拽到刻錄CD的界面。 +4. 在刻錄CD界面,單擊右上角按鈕 **刻錄**。 + + >![notes](../common/notes.svg) 說明:如果要從刻錄列表中刪除某個文件(夾),右鍵單擊該文件(夾),選擇 **刪除**,將該文件(夾)從列表中移除。 + +5. 彈出對話框,輸入光盤名稱。您也可以進入 **高級設置** 界面,設置文件系統、寫入速度,或勾選「允許追加數據」、「核驗數據」等,單擊 **刻錄**。 + +![cd](fig/e_cd_rename.png) + +6. 刻錄完成後界面彈出提示框,單擊 **確定**。 + +>![notes](../common/notes.svg) 說明: +>- 當前系統僅支持對ISO9660格式的文件進行讀取與刻錄,而UDF格式的文件只支持讀取,暫不支持刻錄。 +>- 如果需要擦除光盤數據,可以右鍵單擊導航欄中光盤圖標,選擇 **卸載**,再次右鍵單擊該光盤圖標並選擇 **擦除**。 + +### 創建快捷方式 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **創建鏈接**。 +3. 在彈窗中選擇創建位置、鏈接名稱。 +4. 單擊 **保存**,在目標位置會生成該文件(夾)的快捷方式。 + +> ![tips](../common/tips.svg) 竅門:選擇 **發送到桌面** 可以直接在桌面上生成該文件(夾)的快捷方式。 + +### 發送文件(夾)到外接磁盤 + +當有外接磁盤接入時,您可以將文件或文件夾發送到外接磁盤。 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **發送到** > 外接磁盤。 +3. 文件(夾)將會被發送到移動外接磁盤。 + + +## 文件角標 + +您可以通過命令行,將圖標文件指定給一個文件或文件夾作為角標顯示出來。 + +>![icon](../common/notes.svg) 說明: +>- 角標文件支持svg、jpg、png、bmp、gif格式,且大小不超過100KB。 +>- USB記憶體及光盤下的文件,不支持添加角標。 + +### 添加單個角標 + +1. 在終端輸入命令 **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑)"** ,該命令默認在文件(夾)右下角添加角標。 + + >![icon](../common/attention.svg)注意:系統已定義的特殊角標,不支持被替換。 + +2. 您也可以在上述命令中加入位置參數,將角標添加在文件(夾)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + + 例如:在文件(夾)左上角添加角標 + + **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑);lu"** + +![mark](fig/single.png) + +### 添加多個角標 + +在命令行中加入“**|**”符號將角標文件路徑連接起來,為文件(夾)添加2~4個角標。文件(夾)同一個位置不支持疊加角標,僅支持替換。 + +例如:在文件(夾)四個角都添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑);lu|xxx(圖標路徑);ld|xxx(圖標路徑);ru|xxx(圖標路徑);rd"** + +![mark](fig/multi.png) + +### 撤銷角標 + +在終端中輸入命令 **gio set xxx(文件路徑) -t stringv metadata::emblems ""** 撤銷文件(夾)上所有的角標。 + + +## 文件保險箱 + +文件保險箱旨在為您打造專屬的安全空間,為您的私隱保駕護航。先進的加密技術,便捷的操作流程,使用起來得心應手。 + +### 設置保險箱密碼 + +首次使用保險箱需要對其進行密碼設置,具體步驟如下: + +1. 單擊導航欄中的保險箱圖標 ![file_vault](../common/file_vault.svg),或者在計算機界面雙擊 **我的保險箱**,在彈窗中單擊 **建立**。 +2. 設置解鎖類型、保險箱密碼等,單擊 **下一步**。 + +![0|password](fig/password.png) + + > ![notes](../common/notes.svg)說明: 密碼必須同時包含大寫字母、小寫字母、數字和符號,且字符不小於8位,否則無法進入下一步。 + +3. 此時保險箱密碼生成密鑰,請將密鑰備份,若忘記密碼,可用密鑰重新訪問保險,單擊 **下一步**。 +4. 單擊 **加密保險箱**;在彈窗中輸入用戶登錄密碼,單擊 **確定**。 +5. 加密完成後在彈窗中單擊 **確定**,完成保險箱密碼設置。 + + + +### 鎖上保險箱 + +將文件放入保險箱後,右鍵單擊 ![file_vault](../common/file_vault.svg) 或者在計算機界面右鍵單擊 **我的保險箱**。 +- 選擇 **立即上鎖**,立即將文件保險箱鎖上。 +- 選擇 **自動上鎖**,在其下拉列表進行設置: + + 選擇「從不」,計算機在鎖屏或關機前一直保持未上鎖狀態。 + + 選擇「5分鐘」、「10分鐘」或者「20分鐘」後自動上鎖保險箱。 + +![0|right](fig/right.png) + + +### 解鎖保險箱 + +右鍵單擊 ![file_vault](../common/file_vault.svg) 或者計算機界面 **我的保險箱**。 + +- 選擇 **解鎖**,在彈窗中輸入保險箱密碼,單擊 **解鎖**。 +- 選擇 **密鑰解鎖**,在彈窗中輸入32位密鑰,單擊 **解鎖**。 + +>![0|tips](../common/tips.svg) 竅門:您也可以單擊 ![file_vault](../common/file_vault.svg) 或者雙擊計算機界面 **我的保險箱**,使用密碼解鎖保險箱。 + + +### 刪除保險箱 +刪除保險箱需要提前解鎖保險箱。 +1. 右鍵單擊 ![file_vault](../common/file_vault.svg) 或者在計算機界面右鍵單擊 **我的保險箱**,選擇 **刪除保險箱**。 +2. 彈出刪除保險箱窗口,輸入保險箱密碼,單擊 **刪除**。 +3. 在密碼認證窗口中輸入用戶登錄密碼,單擊 **確定** 完成操作。 +> ![attention](../common/attention.svg) 注意:刪除保險箱會將裏面的文件一併刪除。在進行刪除操作前,請將保險箱中的文件備份。 + +## 磁盤管理 + +檔案管理員管理本地磁盤和外接磁盤。本地磁盤顯示在檔案管理員的左側導航欄上或計算機界面;掛載外接磁盤或者插入其他移動存儲設備時,也會在導航欄看到相應的磁盤圖標。 + + + + + + + + + + + + + + + + + +
本地磁盤本地硬碟分區的所有磁盤
外接磁盤包括移動硬碟、USB記憶體、光盤
移動設備手機內存、存儲卡、SD卡等
+ + + +> ![notes](../common/notes.svg)說明:如果磁盤或磁盤中的文件夾已加密,請輸入密碼後查看文件。 + +### 本地磁盤 + +#### 隱藏本地磁盤 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg) > **設置**。 +2. 在高級設置選項中勾選 **隱藏系統盤**。 + +#### 重命名本地磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊本地磁盤。 +2. 選擇 **重命名**。 +3. 輸入新名稱,按下鍵盤上的 **Enter** 鍵或單擊界面空白區域保存修改。 + +> ![tips](../common/tips.svg) 竅門:在計算機界面,慢速雙擊本地磁盤,呈現編輯框後便可進行重命名操作。 + +![0|disk](fig/e_rename_disk.png) + +### 外接磁盤 + +#### 彈出外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要移除的磁盤。 +2. 選擇 **安全移除**。 +3. 磁盤將從磁盤列表中刪除,一併彈出該磁盤的所有分區。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) 竅門:如果要彈出光盤,請選擇 **彈出** 來移除光盤。單擊導航欄中磁盤右邊的 ![unmount](../common/unmount_normal.svg) 同樣可以彈出磁盤或光盤。 + +#### 重命名外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要重命名的磁盤。 +2. 選擇 **卸載**後,再次單擊右鍵選擇 **重命名**。 +3. 輸入新的卷標名稱,按下鍵盤上的 **Enter** 鍵或單擊界面空白區域保存修改。 + + + +#### 格式化外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要格式化的磁盤。 +2. 選擇 **卸載** 後,再次單擊右鍵選擇 **格式化**。 +3. 設置格式化之後的文件類型和卷標。 +4. 單擊 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) 說明:快速格式化速度快,但是數據仍然可能通過工具被恢復,如果想要格式化後的數據無法被恢復,可以取消勾選「快速格式化」,然後執行格式化操作。 + +## 主菜單 + +在主菜單中,您可以新建窗口,切換窗口主題,[設置共享密碼](#共享本地文件),設置檔案管理員,查看幫助手冊和版本介紹。 + +### 新建窗口 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **新建窗口**,打開一個新的檔案管理員窗口。 + +### 連接到伺服器 + +通過連接伺服器 [訪問局域網共享文件](#訪問共享文件)。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **連接到伺服器**,在編輯框中輸入伺服器IP位址。 + - 單擊 ![+](../common/+.svg) 按鈕可將該地址添加到「個人收藏伺服器」列表中。 + - 在「個人收藏伺服器」列表中選中一個地址,單擊 ![_](../common/-.svg) 按鈕,將該地址從收藏列表中移除。 +3. 單擊 **連接**。 + +![conncet](fig/connect_to_server.png) + + +### 設置 +#### 基礎設置 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)> **設置** 。 +2. 選擇 **基礎設置** 選項。 + + 勾選 **總是在新窗口打開文件夾**。 + + 設置雙擊或單擊打開文件。 + + 設置 **從默認窗口打開**、**從新標籤打開** 哪個目錄。 + + 設置文件圖標 **默認大小** 。 + + 設置 **默認視圖** 以圖標展示或列表展示。 + + 勾選 **顯示隱藏文件**,檔案管理員中被隱藏的文件會顯示出來。 + + 勾選 **重命名時隱藏文件擴展名**,重命名時不會顯示擴展名。 + + 勾選 **顯示最近使用文件**,在左側導航欄顯示最近使用的文件。 + +#### 高級設置 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg) > **設置** 。 +2. 選擇 **高級設置** 選項。 + + 勾選 **自動索引內置磁盤**,搜索文件時會搜索內置磁盤中的文件。 + + 勾選 **連接電腦後索引外部存儲設備**,搜索文件時也會搜索外接設備中的文件。 + + 勾選 **全文搜索**,通過文件中的內容來索引。 + + 勾選預覽文件類型。 + + 勾選 **自動掛載**,接入外接磁盤時自動掛載。 + + 勾選 **自動掛載後打開**,接入外接磁盤時自動掛載並打開該磁盤。 + + 勾選 **使用檔案管理員的文件選擇對話框**,選擇文件時打開檔案管理員窗口。 + + 勾選 **開啟普通刪除提示**,刪除文件時彈出提示對話框。 + + 勾選 **隱藏系統盤**,導航欄和計算機界面將不顯示本地磁盤。 + + 勾選 **在磁盤圖標上顯示文件系統標籤**。 + +### 主題 + +窗口主題包含淺色主題、深色主題和系統主題。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **主題**,選擇一個主題。 + + + +### 幫助 + +查看幫助手冊,進一步了解和使用檔案管理員。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **幫助**。 +3. 查看檔案管理員的幫助手冊。 + + +### 關於 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **關於**。 +3. 查看檔案管理員的版本和介紹。 + + +### 退出 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **退出**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/addressbar1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/addressbar1.png new file mode 100755 index 0000000..5984a0c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/addressbar1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/addressbar2.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/addressbar2.png new file mode 100755 index 0000000..afc1b01 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/addressbar2.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/batch_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/batch_rename.png new file mode 100644 index 0000000..1047252 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/batch_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/cd_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/cd_interface.png new file mode 100644 index 0000000..b0ef5cf Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/cd_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/cd_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/cd_rename.png new file mode 100644 index 0000000..16b2b97 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/cd_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/color_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/color_tag.png new file mode 100644 index 0000000..9edce0f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/color_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/connect_to_server.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/connect_to_server.png new file mode 100755 index 0000000..53b761c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/connect_to_server.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_batch_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_batch_rename.png new file mode 100644 index 0000000..5f49651 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_batch_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_cd_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_cd_interface.png new file mode 100755 index 0000000..0d32fbf Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_cd_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_cd_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_cd_rename.png new file mode 100755 index 0000000..7f54215 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_cd_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_color_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_color_tag.png new file mode 100755 index 0000000..e784c8f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_color_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_filter.png new file mode 100755 index 0000000..0602b3d Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_hotkey.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_hotkey.png new file mode 100755 index 0000000..74bccd4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_hotkey.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_icon_view.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_icon_view.png new file mode 100755 index 0000000..10a3ae8 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_icon_view.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_info_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_info_tag.png new file mode 100755 index 0000000..1656081 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_info_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_list_view.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_list_view.png new file mode 100755 index 0000000..b010ad9 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_list_view.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_maininterface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_maininterface.png new file mode 100755 index 0000000..9aefa00 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_maininterface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_maininterface.psd b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_maininterface.psd new file mode 100755 index 0000000..84f2ca1 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_maininterface.psd differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_multi.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_multi.png new file mode 100755 index 0000000..4201437 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_multi.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_open.png new file mode 100755 index 0000000..212c577 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_overview.png new file mode 100755 index 0000000..26fbe13 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_rename.png new file mode 100755 index 0000000..c3e6086 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_rename_disk.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_rename_disk.png new file mode 100755 index 0000000..026b371 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_rename_disk.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_single.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_single.png new file mode 100755 index 0000000..b995605 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_single.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_tab.png new file mode 100644 index 0000000..e8a4d43 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_tag_info.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_tag_info.png new file mode 100755 index 0000000..62e04dc Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/d_tag_info.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/disk1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/disk1.png new file mode 100755 index 0000000..c2b14c2 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/disk1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/disk2.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/disk2.png new file mode 100755 index 0000000..d0b48d2 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/disk2.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_batch_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_batch_rename.png new file mode 100644 index 0000000..740b229 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_batch_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_cd_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_cd_interface.png new file mode 100755 index 0000000..b97d744 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_cd_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_cd_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_cd_rename.png new file mode 100755 index 0000000..4d4a2e3 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_cd_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_color_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_color_tag.png new file mode 100644 index 0000000..3e1960e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_color_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_filter.png new file mode 100755 index 0000000..3059931 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_icon_view.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_icon_view.png new file mode 100644 index 0000000..df38ca8 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_icon_view.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_info_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_info_tag.png new file mode 100644 index 0000000..4452c9c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_info_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_list_view.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_list_view.png new file mode 100755 index 0000000..e7ca7f3 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_list_view.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_main_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_main_interface.png new file mode 100755 index 0000000..e8f2fc6 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_main_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_newdo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_newdo.png new file mode 100755 index 0000000..f82d3e0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_newdo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_openinterminal.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_openinterminal.png new file mode 100755 index 0000000..812195e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_openinterminal.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_overview.png new file mode 100755 index 0000000..d66ab4f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_rename_disk.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_rename_disk.png new file mode 100755 index 0000000..b9afdec Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_rename_disk.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_tab.png new file mode 100755 index 0000000..2cfd24f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_tag_info.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_tag_info.png new file mode 100644 index 0000000..567d8d5 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/e_tag_info.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/encrypt.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/encrypt.png new file mode 100755 index 0000000..11d1209 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/encrypt.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/encrypt01.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/encrypt01.png new file mode 100755 index 0000000..45fc2d7 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/encrypt01.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/eye.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/eye.png new file mode 100755 index 0000000..3924c40 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/eye.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/filter.png new file mode 100644 index 0000000..9d1b757 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/finish.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/finish.png new file mode 100644 index 0000000..059b96f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/finish.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/h_color_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/h_color_tag.png new file mode 100755 index 0000000..5e3857c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/h_color_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/h_tag_info.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/h_tag_info.png new file mode 100755 index 0000000..4049f0f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/h_tag_info.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/hk-main.psd b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/hk-main.psd new file mode 100644 index 0000000..713e706 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/hk-main.psd differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/hotkey.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/hotkey.png new file mode 100755 index 0000000..08002ad Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/hotkey.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/icon_view.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/icon_view.png new file mode 100644 index 0000000..983b758 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/icon_view.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/info.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/info.png new file mode 100644 index 0000000..1c70d2b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/info.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/info_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/info_tag.png new file mode 100644 index 0000000..7c23d60 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/info_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/key.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/key.png new file mode 100755 index 0000000..8fe72b8 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/key.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/list_view.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/list_view.png new file mode 100644 index 0000000..63f55ee Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/list_view.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/main_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/main_interface.png new file mode 100644 index 0000000..02807c4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/main_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/multi.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/multi.png new file mode 100644 index 0000000..761cd7b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/multi.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/myphone.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/myphone.png new file mode 100644 index 0000000..8b8a2ff Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/myphone.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/myphone1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/myphone1.png new file mode 100644 index 0000000..8341f17 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/myphone1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/newdo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/newdo.png new file mode 100755 index 0000000..a5ef116 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/newdo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/open.png new file mode 100755 index 0000000..edfa05e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/open_file.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/open_file.png new file mode 100755 index 0000000..9763014 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/open_file.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/openinterminal.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/openinterminal.png new file mode 100755 index 0000000..4a13ae5 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/openinterminal.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/overview.png new file mode 100644 index 0000000..ad94299 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/p_rename_disk.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/p_rename_disk.png new file mode 100644 index 0000000..b026ba2 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/p_rename_disk.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/p_share.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/p_share.png new file mode 100755 index 0000000..98d5f4a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/p_share.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/password.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/password.png new file mode 100644 index 0000000..ade501b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/password.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/permission.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/permission.png new file mode 100755 index 0000000..22fe854 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/permission.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/phone_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/phone_interface.png new file mode 100755 index 0000000..19a1429 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/phone_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/rename.png new file mode 100755 index 0000000..3c4418f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/rename_tag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/rename_tag.png new file mode 100755 index 0000000..c5629b4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/rename_tag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/right.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/right.png new file mode 100755 index 0000000..8a65ec8 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/right.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/save.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/save.png new file mode 100644 index 0000000..784a69b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/save.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/share.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/share.png new file mode 100755 index 0000000..ed0b0dd Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/share.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/single.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/single.png new file mode 100644 index 0000000..98bb737 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/single.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/tab.png new file mode 100644 index 0000000..0428572 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/tag_info.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/tag_info.png new file mode 100644 index 0000000..0287897 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/tag_info.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/unlock.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/unlock.png new file mode 100644 index 0000000..d6deb7f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/unlock.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/video_preview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/video_preview.png new file mode 100644 index 0000000..74f2240 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/video_preview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/visitshare.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/visitshare.png new file mode 100755 index 0000000..c2f537e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/fig/visitshare.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/i_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/i_file-manager.md new file mode 100755 index 0000000..b4ece1a --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/i_file-manager.md @@ -0,0 +1,660 @@ +# 檔案管理員|dde-file-manager| + +## 概述 + +檔案管理員是一款功能強大、簡單易用的文件管理工具。它沿用了傳統檔案管理員的經典功能和佈局,並在此基礎上簡化了用戶操作,增加了很多特色功能。一目了然的導航欄、智能識別的搜索框、多樣化的視圖及排序讓您管理起來得心應手,經典和超越,只為給您更好的體驗! + +![1|overview](fig/e_overview.png) + + + +## 使用入門 + +通過以下方式運行或關閉檔案管理員,或者創建檔案管理員的快捷方式。 + +### 運行檔案管理員 + +1. 單擊任務欄上的啟動器圖標 ![deepin_launcher ](../common/deepin_launcher.svg),進入啟動器界面。 +2. 上下滾動鼠標滾輪瀏覽或通過搜索,找到檔案管理員圖標 ![deepin_file_manager](../common/deepin_file_manager.svg),單擊運行。 +3. 右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 單擊 **傳送到桌面**,在桌面創建快捷方式。 + - 單擊 **傳送到任務欄**,將應用程序固定到任務欄。 + - 單擊 **加至開機啟動**,將應用程序添加到開機啟動項,在電腦開機時自動運行該應用。 + +> ![tips](../common/tips.svg) 竅門:您也可以使用快捷鍵 **Super + E** 啟動檔案管理員。 + +### 關閉檔案管理員 + +- 在檔案管理員界面,單擊 ![close_icon](../common/close_icon.svg),關閉檔案管理員。 +- 在任務欄右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),選擇 **關閉所有**,關閉檔案管理員。 +- 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg),選擇 **退出** ,關閉檔案管理員。 + +### 查看快捷鍵 + +在檔案管理員界面,使用快捷鍵 **Ctrl + Shift + /** 打開快捷鍵預覽界面。熟練地使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主界面 + +檔案管理員的主界面簡單易用、功能全面,熟練地使用界面功能將使檔案管理更加簡單高效。 + +![1|main_interface](fig/e_main_interface.png) + + +| 標號 | 名稱 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 導航欄 | 單擊導航圖標,快速訪問本地文件、磁盤、共享文件、書籤、標記等。 | +| 2 | 地址欄 | 通過地址欄,快速切換訪問歷史、在上下級目錄間切換、搜索、輸入地址訪問。 | +| 3 | 圖標/列表視圖 | 單擊 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg) 圖標,以圖標或列表形式查看文件(夾)。 | +| 4 | 訊息欄 | 單擊 ![fileinfo](../common/fileinfo.svg), 查看文件(夾)的基本訊息和標記。 | +| 5 | 菜單欄 | 通過主菜單,您可以新建窗口、切換窗口主題、設置共享密碼、設置檔案管理員、查看幫助文檔和關於訊息、退出檔案管理員。 | +| 6 | 狀態欄 | 顯示文件數量或者已選中文件的數量。 | + +> ![tips](../common/tips.svg) 竅門:可拖動左側導航欄右邊的分隔線來改變其寬度。 + +## 基本功能 + +檔案管理員具備基本的檔案管理功能,對文件(夾)進行新建、複製、重命名、刪除等操作都非常簡單。 + +### 新建文件 + +#### 新建文檔 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **新建文檔**。 +3. 選擇新建文件的類型。 +4. 輸入新建文檔的名稱。 + +![0|newdo](fig/e_newdo.png) + +#### 新建文件夾 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **新建文件夾**。 +3. 輸入新建文件夾的名稱。 + +### 重命名文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **重命名**。 +3. 輸入文件名稱,按 **Enter** 鍵或者單擊界面空白區域保存設置。 + +![0|contextmenu](fig/d_rename.png) + +> ![tips](../common/tips.svg) 竅門:在 **設置** 中勾選「重命名時隱藏文件擴展名」,能更方便地修改文件名稱。 + +### 批量重命名 + +1. 在檔案管理員界面,選中多個文件。 +2. 右鍵單擊文件,選擇 **重命名**。 + - **替換文本** 查找需要替換的文本,並輸入替換後的文本,文件名中的關鍵字將被統一替換。 + - **添加文本** 輸入需要添加的文本,並選擇位置是名稱之前還是之後,文件名將統一加入被添加的文本。 + - **自定義文本** 輸入文件名,並輸入序列的遞進數字,文件名將統一改成新文件名+遞進數字。 +4. 單擊 **重命名** 來完成操作。 + +![1|rename](fig/e_batch_rename.png) + +### 查看文件 + +單擊菜單欄上的圖標 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 來切換圖標視圖和列表視圖。 + +- 圖標視圖:平鋪顯示文件的名稱、圖標或縮略圖。 + +![1|icon_view](fig/e_icon_view.png) + +- 列表視圖:列表顯示文件圖標或縮略圖、名稱、修改時間、大小、類型等訊息。 + +![1|list_view](fig/e_list_view.png) + +> ![tips](../common/tips.svg) 竅門: +> - 在列表視圖中,把光標置於兩列之間的分隔線上, 拖動它來改變列的寬度;雙擊分隔線可將當前列自動調整為本列內容最寬的寬度。 +> - 使用 **Ctrl + 1** 和 **Ctrl + 2** 快捷鍵,切換圖標視圖和列表視圖。 + + +### 排序文件 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **排序方式**。 +3. 在子菜單中選擇以名稱、修改時間、大小或類型來排序文件。 + +> ![tips](../common/tips.svg) 竅門:在列表視圖中,單擊表頭欄的列標籤來切換升序、降序。 + +### 打開文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **打開方式** > **選擇默認程序**。 +3. 在程序列表中選擇應用程序。 + +> ![notes](../common/notes.svg) 說明:直接雙擊文件會使用默認程序打開。您可以選擇相同類型的多個文件,單擊右鍵選擇 **打開方式** 選項,一次打開多個文件。 + +![0|open](fig/d_open.png) + + + +### 隱藏文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **屬性**,勾選 **隱藏此文件**。 + +### 複製文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **複製**。 +3. 選擇一個目標存儲位置。 +4. 單擊鼠標右鍵,選擇 **黏貼**。 + +### 壓縮文件 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **壓縮**。 +3. 彈出歸檔管理器壓縮界面,可以設置壓縮包格式、名稱、存儲路徑等,單擊 **壓縮**。 + +> ![tips](../common/tips.svg) 竅門:您也可以直接在右鍵菜單中選擇 **添加到xxx.7z** 或 **添加到xxx.zip**,快速將文件(夾)壓縮成7z或zip格式。 + +### 刪除文件 + +1. 在檔案管理員界面上,右鍵單擊文件。 +2. 選擇 **刪除** 。 + - 被刪除的文件可以在回收站中找到,右鍵單擊回收站中的文件可以進行 **還原** 或 **刪除** 操作。 + - 被刪除的文件的快捷方式將會失效。 + +> ![attention](../common/attention.svg) 注意:从外接設備中刪除文件會將文件徹底刪除,無法從回收站找回。 + +### 撤銷操作 + +在檔案管理員中,可以用 **Ctrl + Z** 來撤銷上一步操作,包括: + +- 刪除新建的文件。 +- 恢復重命名(包括重命名文件後綴)之前的名字。 +- 從回收站還原剛刪除的文件。 +- 恢復文件到移動(剪切移動、鼠標移動)前的原始路徑。 +- 刪除複製黏貼的文件。 + +>![attention](../common/attention.svg) 注意:撤銷動作最多只能返回兩步;如果操作中有覆蓋某個同名文件和徹底刪除文件,則撤銷只能返回到這一步。 + +### 文件屬性 + +文件屬性會顯示文件的基本訊息、打開方式和權限設置。文件夾屬性會顯示文件夾的基本訊息、共享訊息和權限設置。 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **屬性**,查看文件屬性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg) 說明:查看多個文件屬性會顯示文件總大小和數量;查看快捷方式的屬性將會額外顯示源文件地址。您還可以使用 **Ctrl + I** 組合鍵查看文件屬性。 + + + +## 常用操作 + +檔案管理員具備很多特色功能,這些功能都讓檔案管理更加簡單、高效。 + +### 切換地址欄 + +地址欄由歷史導航、麵包屑和輸入框共同組成。通常情況下地址欄顯示麵包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 單擊歷史導航按鈕,快速在歷史瀏覽記錄間切換,查看前一個地址或者後一個地址。 +- 文件所在位置的每一個層級都會形成一個麵包屑,通過來回單擊麵包屑可以快速在不同文件層級間切換。 + +單擊搜索圖標,或者在文件路徑上單擊右鍵並選擇「編輯地址」,地址欄會切換為輸入框狀態。在輸入框外單擊時,地址欄會自動恢復到麵包屑狀態。 + +![0|addressbar](fig/addressbar2.png) + +- 輸入框帶有智能識別功能,輸入關鍵詞或者訪問地址,系統會自動識別並進行搜索或訪問。 + +### 搜索文件 + +檔案管理員支持多種檢索方式,既支持通過文件名稱、文件內容進行普通搜索,也支持通過文件類型、創建時間等進行高級搜索,提高工作效率,便於文件管理。 + +- 指定目錄搜索時,請先進入該目錄,然後再進行搜索。 + + > ![notes](../common/notes.svg) 說明:在檔案管理員的 **設置** 中,默認勾選了「自動索引內置磁盤」,您可以選擇勾選「連接電腦後索引外部存儲設備」,加快在外部設備的搜索速度。 + +#### 全文搜索 + +您可以通過文件內容關鍵字來搜索文件。 +1. 在檔案管理員中,單擊 ![icon_menu](../common/icon_menu.svg) > **設置**。 +2. 在高級設置項勾選「全文搜索」開啟此功能。 +3. 使用快捷鍵 **Ctrl + F** 或在地址欄中單擊搜索按鈕進入搜索狀態,輸入關鍵字後按下鍵盤上的 **Enter** 鍵,搜索相關文件。 + +#### 高級搜索 + +當文件較多,搜索較慢時,啟用高級搜索縮小搜索範圍,提高搜索效率。 + +1. 在搜索狀態下,輸入關鍵字後按 **Enter** 鍵,當搜索到結果時,搜索框右側顯示 ![filter](../common/filter.svg) 圖標,點擊該圖標可進行高級搜索的操作。 +2. 選擇搜索範圍、文件大小、文件類型、修改時間、訪問時間和創建時間,進行更精準的搜索。 + +![0|filter](fig/e_filter.png) + +### 最近使用 + +在左側導航欄上默認有 **最近使用** 入口,單擊可以查看最近使用的文件。文件默認按照訪問時間倒序排列。 + +> ![notes](../common/notes.svg) 說明:若想隱藏「最近使用」,可在 **設置 > 基本設置 > 隱藏文件**,取消勾選「顯示最近使用文件」。若要隱藏某一個文件的訪問記錄,右鍵單擊該文件選擇 **移除**,該操作不會刪除文件。 + +### 多標籤頁 + +檔案管理員支持多標籤頁顯示。 + +1. 在檔案管理員界面上,右鍵單擊文件夾。 +2. 選擇 **在新標籤中打開**。 +3. 當窗口有多個標籤頁時,可以: + - 單擊標籤頁右側的按鈕 + ,繼續添加標籤頁。 + - 將鼠標指針置於標籤頁上,單擊關閉按鈕 **×** 或單擊鼠標中鍵,關閉標籤頁。 + +![1|tab](fig/e_tab.png) + +> ![tips](../common/tips.svg) 竅門:檔案管理員窗口只有一個標籤時,標籤頁是隱藏的,您還可以使用快捷鍵 **Ctrl + T** 來新建標籤頁。 + +### 書籤管理 + +為常用文件夾添加書籤,以便從左側導航欄快速訪問。 + +- 添加書籤:右鍵單擊文件夾,選擇 **添加書籤** 就可以在導航欄創建書籤。 +- 移動書籤:在導航欄上下拖動書籤調整書籤排序。 +- 刪除書籤:右鍵單擊書籤,選擇 **移除** 來刪除書籤;或右鍵單擊已添加書籤的文件夾,選擇 **移除書籤** 來刪除書籤。 + +### 標記訊息 + +通過給文件(夾)添加標記,可以更好地分類管理您的文件。 + +> ![notes](../common/notes.svg) 說明:當前僅x86平台支持 **標記訊息** 功能,該幫助手冊中涉及的標記訊息相關內容僅適用於x86平台。 + +#### 添加標記 + +您可以為一個文件(夾)添加多個標記,也可以同時為多個文件(夾)添加標記;添加成功的標記會出現在左側導航欄內。 + +##### 通過編輯框添加標記 + +1. 右鍵單擊文件(夾),選擇 **標記訊息**。 +2. 輸入標記名稱,若要添加多個標記,可用逗號分隔。 +3. 單擊界面空白區域保存設置。 + +>![notes](../common/notes.svg) 說明:標記顏色從8種默認顏色中隨機分配。 + +![1|tag_info](fig/e_tag_info.png) + + +##### 通過顏色按鈕添加標記 + +右鍵單擊文件(夾),選擇「顏色按鈕」,直接生成這個顏色的標記。 + +![1|color_tag](fig/e_color_tag.png) + +##### 通過右側訊息欄添加標記 + +選擇文件(夾)後,單擊菜單欄上的圖標 ![fileinfo](../common/fileinfo.svg),在右側訊息欄中也可以添加標記。 + +![1|info_tag](fig/e_info_tag.png) + +>![notes](../common/notes.svg) 说明:如果文件有標記,則複製或剪切該文件產生的文件仍然具有同樣的標記。 + + +#### 重命名標記 + +在左側導航欄中,右鍵單擊某個標記,選擇 **重命名**,修改當前標記的名稱。 + +![1|rename_tag](fig/rename_tag.png) + +#### 修改標記顏色 + +在左側導航欄中,右鍵單擊某個標記,選擇「顏色按鈕」,即可修改當前標記的顏色。 + +#### 排序標記 + +上下拖動標記即可調整標記排序。 + +#### 刪除標記 + +右鍵單擊某個標記,選擇 **移除**,刪除當前標記。 + + +### 文件預覽 + +檔案管理員支持空格鍵預覽功能,選中文件並按下鍵盤上的空格鍵就可以快速預覽文件。預覽窗口可以查看圖片解像度、文檔大小、文本內容等,還支持gif、音頻、影片播放。 + +#### 預覽影片 + +1. 選擇您要預覽的影片文件,按下空格鍵,即可開始預覽。 +2. 單擊影片任意地方可暫停播放。 +3. 播放過程中,可以拖動進度條來快進快退。 +4. 單擊底部 **打開** 按扭,在默認程序中打開該影片文件。 + +![1|video_preview](fig/video_preview.png) + +> ![notes](../common/notes.svg) 說明:您也可以同時選擇多個文件,按下空格鍵進行預覽。 + + +### 權限管理 + +選擇對應文件(夾),單擊右鍵,選擇屬性,單擊 **權限管理**, 為所有者,群組,和其他用戶設置文件權限。 + +![2|permission](fig/permission.png) + +### 我的共享 + +當您設置了共享文件時,「我的共享」將會出現在導航欄上。當所有共享文件都取消共享後,「我的共享」自動從導航欄中移除。 + +#### 共享本地文件 + +1. 在檔案管理員界面,右鍵單擊文件夾選擇 **共享文件夾**。 +2. 在文件夾的屬性窗口,勾選 **共享此文件夾**。 +3. 根據需要設置 **共享名**、**權限** 、**匿名訪問** 後關閉窗口。 +4. 單擊 ![icon_menu](../common/icon_menu.svg) > **設置共享密碼**。 +5. 輸入共享密碼,單擊 **確定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg) 竅門:取消勾選 **共享此文件夾** 可以取消文件共享,也可以右鍵單擊文件,選擇 **取消共享**。 + + +#### 訪問共享文件 + +局域網中其他用戶共享的文件一般都可以在網絡鄰居中找到,您也可以通過smb訪問共享文件。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **連接到伺服器**,在編輯框中輸入伺服器地址,如:smb://xx.x.xx.xxx(一般為IP位址),單擊 **連接**;或者直接在地址欄中輸入伺服器地址,按下鍵盤上的 **Enter** 鍵。 +2. 選擇需要訪問的共享文件夾,在彈出的窗口中輸入用戶名和共享密碼,或者匿名訪問。 + - 未加密的網絡文件可以匿名訪問,不需要輸入用戶名和密碼。 + - 加密的網絡文件需要輸入用戶名和密碼之後才能訪問。 + + - 用戶名:共享者登錄系統的用戶名。 + - 密碼:共享文件時設置的共享密碼。 +3. 單擊 **連接**。 + +![1|visitshareshare](fig/visitshare.png) + + + +### 在終端中打開 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **在終端中打開**,會啟動終端應用程序,終端的路徑為當前目錄。 + +![0|open_terminal](fig/e_openinterminal.png) + +### 刻錄光盤 + +您可以通過刻錄功能將音樂、影片、圖片或鏡像文件複製到光盤中。請提前準備一部刻錄機、一張CD或DVD光盤。 + + +1. 將光盤插入到刻錄機中。 +2. 打開檔案管理員,單擊導航欄中的光盤圖標,進入刻錄CD的界面。 + +![cd](fig/e_cd_interface.png) + +3. 右鍵單擊 文件(夾),選擇 **添加至光盤刻錄** 或直接將文件(夾)拖拽到刻錄CD的界面。 +4. 在刻錄CD界面,單擊右上角按鈕 **刻錄**。 + + >![notes](../common/notes.svg) 說明:如果要從刻錄列表中刪除某個文件(夾),右鍵單擊該文件(夾),選擇 **刪除**,將該文件(夾)從列表中移除。 + +5. 彈出對話框,輸入光盤名稱。您也可以進入 **高級設置** 界面,設置文件系統、寫入速度,或勾選「允許追加數據」、「核驗數據」等,單擊 **刻錄**。 + +![cd](fig/e_cd_rename.png) + +6. 刻錄完成後界面彈出提示框,單擊 **確定**。 + +>![notes](../common/notes.svg) 說明: +>- 當前系統僅支持對ISO9660格式的文件進行讀取與刻錄,而UDF格式的文件只支持讀取,暫不支持刻錄。 +>- 如果需要擦除光盤數據,可以右鍵單擊導航欄中光盤圖標,選擇 **卸載**,再次右鍵單擊該光盤圖標並選擇 **擦除**。 + +### 創建快捷方式 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **創建鏈接**。 +3. 在彈窗中選擇創建位置、鏈接名稱。 +4. 單擊 **保存**,在目標位置會生成該文件(夾)的快捷方式。 + +> ![tips](../common/tips.svg) 竅門:選擇 **發送到桌面** 可以直接在桌面上生成該文件(夾)的快捷方式。 + +### 發送文件(夾)到外接磁盤 + +當有外接磁盤接入時,您可以將文件或文件夾發送到外接磁盤。 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **發送到** > 外接磁盤。 +3. 文件(夾)將會被發送到移動外接磁盤。 + + +## 文件角標 + +您可以通過命令行,將圖標文件指定給一個文件或文件夾作為角標顯示出來。 + +>![icon](../common/notes.svg) 說明: +>- 角標文件支持svg、jpg、png、bmp、gif格式,且大小不超過100KB。 +>- USB記憶體及光盤下的文件,不支持添加角標。 + +### 添加單個角標 + +1. 在終端輸入命令 **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑)"** ,該命令默認在文件(夾)右下角添加角標。 + + >![icon](../common/attention.svg)注意:系統已定義的特殊角標,不支持被替換。 + +2. 您也可以在上述命令中加入位置參數,將角標添加在文件(夾)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + + 例如:在文件(夾)左上角添加角標 + + **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑);lu"** + +![mark](fig/single.png) + +### 添加多個角標 + +在命令行中加入“**|**”符號將角標文件路徑連接起來,為文件(夾)添加2~4個角標。文件(夾)同一個位置不支持疊加角標,僅支持替換。 + +例如:在文件(夾)四個角都添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑);lu|xxx(圖標路徑);ld|xxx(圖標路徑);ru|xxx(圖標路徑);rd"** + +![mark](fig/multi.png) + +### 撤銷角標 + +在終端中輸入命令 **gio set xxx(文件路徑) -t stringv metadata::emblems ""** 撤銷文件(夾)上所有的角標。 + + +## 文件保險箱 + +文件保險箱旨在為您打造專屬的安全空間,為您的私隱保駕護航。先進的加密技術,便捷的操作流程,使用起來得心應手。 + +### 設置保險箱密碼 + +首次使用保險箱需要對其進行密碼設置,具體步驟如下: + +1. 單擊導航欄中的保險箱圖標 ![file_vault](../common/file_vault.svg),或者在計算機界面雙擊 **我的保險箱**,在彈窗中單擊 **建立**。 +2. 設置解鎖類型、保險箱密碼等,單擊 **下一步**。 + +![0|password](fig/password.png) + + > ![notes](../common/notes.svg)說明: 密碼必須同時包含大寫字母、小寫字母、數字和符號,且字符不小於8位,否則無法進入下一步。 + +3. 此時保險箱密碼生成密鑰,請將密鑰備份,若忘記密碼,可用密鑰重新訪問保險,單擊 **下一步**。 +4. 單擊 **加密保險箱**;在彈窗中輸入用戶登錄密碼,單擊 **確定**。 +5. 加密完成後在彈窗中單擊 **確定**,完成保險箱密碼設置。 + + + +### 鎖上保險箱 + +將文件放入保險箱後,右鍵單擊 ![file_vault](../common/file_vault.svg) 或者在計算機界面右鍵單擊 **我的保險箱**。 +- 選擇 **立即上鎖**,立即將文件保險箱鎖上。 +- 選擇 **自動上鎖**,在其下拉列表進行設置: + + 選擇「從不」,計算機在鎖屏或關機前一直保持未上鎖狀態。 + + 選擇「5分鐘」、「10分鐘」或者「20分鐘」後自動上鎖保險箱。 + +![0|right](fig/right.png) + + +### 解鎖保險箱 + +右鍵單擊 ![file_vault](../common/file_vault.svg) 或者計算機界面 **我的保險箱**。 + +- 選擇 **解鎖**,在彈窗中輸入保險箱密碼,單擊 **解鎖**。 +- 選擇 **密鑰解鎖**,在彈窗中輸入32位密鑰,單擊 **解鎖**。 + +>![0|tips](../common/tips.svg) 竅門:您也可以單擊 ![file_vault](../common/file_vault.svg) 或者雙擊計算機界面 **我的保險箱**,使用密碼解鎖保險箱。 + + +### 刪除保險箱 +刪除保險箱需要提前解鎖保險箱。 +1. 右鍵單擊 ![file_vault](../common/file_vault.svg) 或者在計算機界面右鍵單擊 **我的保險箱**,選擇 **刪除保險箱**。 +2. 彈出刪除保險箱窗口,輸入保險箱密碼,單擊 **刪除**。 +3. 在密碼認證窗口中輸入用戶登錄密碼,單擊 **確定** 完成操作。 +> ![attention](../common/attention.svg) 注意:刪除保險箱會將裏面的文件一併刪除。在進行刪除操作前,請將保險箱中的文件備份。 + +## 磁盤管理 + +檔案管理員管理本地磁盤和外接磁盤。本地磁盤顯示在檔案管理員的左側導航欄上或計算機界面;掛載外接磁盤或者插入其他移動存儲設備時,也會在導航欄看到相應的磁盤圖標。 + + + + + + + + + + + + + + + + + +
本地磁盤本地硬碟分區的所有磁盤
外接磁盤包括移動硬碟、USB記憶體、光盤
移動設備手機內存、存儲卡、SD卡等
+ + + +> ![notes](../common/notes.svg)說明:如果磁盤或磁盤中的文件夾已加密,請輸入密碼後查看文件。 + +### 本地磁盤 + +#### 隱藏本地磁盤 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg) > **設置**。 +2. 在高級設置選項中勾選 **隱藏系統盤**。 + +#### 重命名本地磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊本地磁盤。 +2. 選擇 **重命名**。 +3. 輸入新名稱,按下鍵盤上的 **Enter** 鍵或單擊界面空白區域保存修改。 + +> ![tips](../common/tips.svg) 竅門:在計算機界面,慢速雙擊本地磁盤,呈現編輯框後便可進行重命名操作。 + +![0|disk](fig/e_rename_disk.png) + +### 外接磁盤 + +#### 彈出外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要移除的磁盤。 +2. 選擇 **安全移除**。 +3. 磁盤將從磁盤列表中刪除,一併彈出該磁盤的所有分區。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) 竅門:如果要彈出光盤,請選擇 **彈出** 來移除光盤。單擊導航欄中磁盤右邊的 ![unmount](../common/unmount_normal.svg) 同樣可以彈出磁盤或光盤。 + +#### 重命名外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要重命名的磁盤。 +2. 選擇 **卸載**後,再次單擊右鍵選擇 **重命名**。 +3. 輸入新的卷標名稱,按下鍵盤上的 **Enter** 鍵或單擊界面空白區域保存修改。 + + + +#### 格式化外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要格式化的磁盤。 +2. 選擇 **卸載** 後,再次單擊右鍵選擇 **格式化**。 +3. 設置格式化之後的文件類型和卷標。 +4. 單擊 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) 說明:快速格式化速度快,但是數據仍然可能通過工具被恢復,如果想要格式化後的數據無法被恢復,可以取消勾選「快速格式化」,然後執行格式化操作。 + +## 主菜單 + +在主菜單中,您可以新建窗口,切換窗口主題,[設置共享密碼](#共享本地文件),設置檔案管理員,查看幫助手冊和版本介紹。 + +### 新建窗口 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **新建窗口**,打開一個新的檔案管理員窗口。 + +### 連接到伺服器 + +通過連接伺服器 [訪問局域網共享文件](#訪問共享文件)。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **連接到伺服器**,在編輯框中輸入伺服器IP位址。 + - 單擊 ![+](../common/+.svg) 按鈕可將該地址添加到「個人收藏伺服器」列表中。 + - 在「個人收藏伺服器」列表中選中一個地址,單擊 ![_](../common/-.svg) 按鈕,將該地址從收藏列表中移除。 +3. 單擊 **連接**。 + +![conncet](fig/connect_to_server.png) + + +### 設置 +#### 基礎設置 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)> **設置** 。 +2. 選擇 **基礎設置** 選項。 + + 勾選 **總是在新窗口打開文件夾**。 + + 設置雙擊或單擊打開文件。 + + 設置 **從默認窗口打開**、**從新標籤打開** 哪個目錄。 + + 設置文件圖標 **默認大小** 。 + + 設置 **默認視圖** 以圖標展示或列表展示。 + + 勾選 **顯示隱藏文件**,檔案管理員中被隱藏的文件會顯示出來。 + + 勾選 **重命名時隱藏文件擴展名**,重命名時不會顯示擴展名。 + + 勾選 **顯示最近使用文件**,在左側導航欄顯示最近使用的文件。 + +#### 高級設置 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg) > **設置** 。 +2. 選擇 **高級設置** 選項。 + + 勾選 **自動索引內置磁盤**,搜索文件時會搜索內置磁盤中的文件。 + + 勾選 **連接電腦後索引外部存儲設備**,搜索文件時也會搜索外接設備中的文件。 + + 勾選 **全文搜索**,通過文件中的內容來索引。 + + 勾選預覽文件類型。 + + 勾選 **自動掛載**,接入外接磁盤時自動掛載。 + + 勾選 **自動掛載後打開**,接入外接磁盤時自動掛載並打開該磁盤。 + + 勾選 **使用檔案管理員的文件選擇對話框**,選擇文件時打開檔案管理員窗口。 + + 勾選 **開啟普通刪除提示**,刪除文件時彈出提示對話框。 + + 勾選 **隱藏系統盤**,導航欄和計算機界面將不顯示本地磁盤。 + + 勾選 **在磁盤圖標上顯示文件系統標籤**。 + +### 主題 + +窗口主題包含淺色主題、深色主題和系統主題。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **主題**,選擇一個主題。 + + + +### 幫助 + +查看幫助手冊,進一步了解和使用檔案管理員。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **幫助**。 +3. 查看檔案管理員的幫助手冊。 + + +### 關於 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **關於**。 +3. 查看檔案管理員的版本和介紹。 + + +### 退出 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **退出**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/p_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/p_file-manager.md new file mode 100755 index 0000000..f20ca52 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_HK/p_file-manager.md @@ -0,0 +1,820 @@ +# 檔案管理員|dde-file-manager| + +## 概述 + +檔案管理員是一款功能強大、簡單易用的文件管理工具。它沿用了一般檔案管理員的經典功能和佈局,並在此基礎上簡化了用戶操作,增加了很多特色功能。檔案管理員擁有一目了然的導航欄、智能識別的搜索框、多樣化的視圖和排序,這些特點讓文件管理不再複雜。 + +![1|overview](fig/overview.png) + + + +## 使用入門 + +通過以下方式運行或關閉檔案管理員,或者創建檔案管理員的快捷方式。 + +### 運行檔案管理員 + +1. 單擊任務欄上的啟動器圖標 ![deepin_launcher ](../common/deepin_launcher.svg),進入啟動器界面。 +2. 上下滾動鼠標滾輪瀏覽或通過搜索,找到檔案管理員圖標 ![deepin_file_manager](../common/deepin_file_manager.svg),單擊運行。 +3. 右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 單擊 **傳送到桌面**,在桌面創建快捷方式。 + - 單擊 **傳送到任務欄**,將應用程序固定到任務欄。 + - 單擊 **加至開機啟動**,將應用程序添加到開機啟動項,在電腦開機時自動運行該應用。 + +> ![tips](../common/tips.svg)竅門:您也可以使用快捷鍵 **Super + E** 啟動檔案管理員。 + +### 關閉檔案管理員 + +- 在檔案管理員界面,單擊 ![close_icon](../common/close_icon.svg),關閉檔案管理員。 +- 在任務欄右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),選擇 **關閉所有**,關閉檔案管理員。 +- 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg),選擇 **退出** ,關閉檔案管理員。 + +### 查看快捷鍵 + +在檔案管理員界面,使用快捷鍵 **Ctrl + Shift + /** 打開快捷鍵預覽界面。熟練地使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主界面 + +檔案管理員的主界面簡單易用、功能全面,熟練地使用界面功能將使檔案管理更加簡單高效。 + +![1|main_interface](fig/main_interface.png) + + +| 標號 | 名稱 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 導航欄 | 單擊導航圖標,快速訪問本地文件、磁盤、共享文件、書籤、標記等。 | +| 2 | 地址欄 | 通過地址欄,快速切換訪問歷史、在上下級目錄間切換、搜索、輸入地址訪問。 | +| 3 | 圖標/列表視圖 | 單擊 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg)圖標,以圖標或列表形式查看文件(夾)。 | +| 4 | 訊息欄 | 單擊 ![fileinfo](../common/fileinfo.svg), 查看文件(夾)的基本訊息和標記。 | +| 5 | 菜單欄 | 通過主菜單,您可以新建窗口、切換窗口主題、設置共享密碼、設置檔案管理員、查看幫助文檔和關於訊息、退出檔案管理員。 | +| 6 | 狀態欄 | 顯示文件數量或者已選中文件的數量。 | + +> ![tips](../common/tips.svg)竅門:可拖動左側導航欄右邊的分隔線來改變其寬度。 + +## 基本功能 + +檔案管理員具備基本的檔案管理功能,對文件(夾)進行新建、複製、重命名、刪除等操作都非常簡單。 + +### 新建文件 + +#### 新建文檔 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **新建文檔**。 +3. 選擇新建文件的類型。 +4. 輸入新建文檔的名稱。 + +![0|newdo](fig/newdo.png) + +#### 新建文件夾 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **新建文件夾**。 +3. 輸入新建文件夾的名稱。 + +### 重命名文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **重命名**。 +3. 輸入文件名稱,按 **Enter** 鍵或者單擊界面空白區域保存設置。 + +![0|contextmenu](fig/rename.png) + +> ![tips](../common/tips.svg)竅門:在 **設置** 中勾選「重命名時隱藏文件擴展名」,能更方便地修改文件名稱。 + +### 批量重命名 + +1. 在檔案管理員界面,選中多個文件。 +2. 右鍵單擊文件,選擇 **重命名**。 + - **替換文本** 查找需要替換的文本,並輸入替換後的文本,文件名中的關鍵字將被統一替換。 + - **添加文本** 輸入需要添加的文本,並選擇位置是名稱之前還是之後,文件名將統一加入被添加的文本。 + - **自定義文本** 輸入文件名,並輸入序列的遞進數字,文件名將統一改成新文件名+遞進數字。 +4. 單擊 **重命名** 來完成操作。 + +![1|rename](fig/batch_rename.png) + +### 查看文件 + +單擊菜單欄上的圖標 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 來切換圖標視圖和列表視圖。 + +- 圖標視圖:平鋪顯示文件的名稱、圖標或縮略圖。 + +![1|icon_view](fig/icon_view.png) + +- 列表視圖:列表顯示文件圖標或縮略圖、名稱、修改時間、大小、類型等訊息。 + +![1|list_view](fig/list_view.png) + +> ![tips](../common/tips.svg)竅門: +> - 在列表視圖中,把光標置於兩列之間的分隔線上, 拖動它來改變列的寬度;雙擊分隔線可將當前列自動調整為本列內容最寬的寬度。 +> - 使用 **Ctrl + 1** 和 **Ctrl + 2** 快捷鍵,切換圖標視圖和列表視圖。 + + +### 排序文件 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **排序方式**。 +3. 在子菜單中選擇以名稱、修改時間、大小或類型來排序文件。 + +> ![tips](../common/tips.svg)竅門:在列表視圖中,單擊表頭欄的列標籤來切換升序、降序。 + +### 打開文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **打開方式** > **選擇默認程序**。 +3. 在程序列表中選擇應用程序。 + +> ![notes](../common/notes.svg)說明:直接雙擊文件會使用默認程序打開。您可以選擇相同類型的多個文件,單擊右鍵選擇 **打開方式** 選項,一次打開多個文件。 + +![0|open](fig/open.png) + + + +### 隱藏文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **屬性**,勾選 **隱藏此文件**。 + +### 複製文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **複製**。 +3. 選擇一個目標存儲位置。 +4. 單擊鼠標右鍵,選擇 **黏貼**。 + +### 壓縮文件 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **壓縮**。 +3. 彈出歸檔管理器壓縮界面,可以設置壓縮包格式、名稱、存儲路徑等,單擊 **壓縮**。 + +> ![tips](../common/tips.svg)竅門:您也可以直接在右鍵菜單中選擇 **添加到xxx.7z** 或 **添加到xxx.zip**,快速將文件(夾)壓縮成7z或zip格式。 + +### 刪除文件 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **刪除** 。 + - 被刪除的文件可以在回收站中找到,右鍵單擊回收站中的文件可以進行 **還原** 或 **刪除** 操作。 + - 被刪除的文件的快捷方式將會失效。 + +> ![attention](../common/attention.svg)注意:从外接設備中刪除文件會將文件徹底刪除,無法從回收站找回。 + +### 撤銷操作 + +在檔案管理員中,可以用 **Ctrl + Z** 來撤銷上一步操作,包括: + +- 刪除新建的文件。 +- 恢復重命名(包括重命名文件後綴)之前的名字。 +- 從回收站還原剛刪除的文件。 +- 恢復文件到移動(剪切移動、鼠標移動)前的原始路徑。 +- 刪除複製黏貼的文件。 + +>![attention](../common/attention.svg)注意:撤銷動作最多只能返回兩步;如果操作中有覆蓋某個同名文件和徹底刪除文件,則撤銷只能返回到這一步。 + +### 文件屬性 + +文件屬性會顯示文件的基本訊息、打開方式和權限設置。文件夾屬性會顯示文件夾的基本訊息、共享訊息和權限設置。 + +1. 在檔案管理員界面,右鍵單擊文件。 +2. 選擇 **屬性**,查看文件屬性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg)說明:查看多個文件屬性會顯示文件總大小和數量;查看快捷方式的屬性將會額外顯示源文件地址。您還可以使用 **Ctrl + I** 組合鍵查看文件屬性。 + +### 病毒查殺 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **病毒查殺**,彈出安全中心病毒查殺界面,您可以對該文件(夾)進行安全掃描,具體操作請參閱安全中心 [病毒查殺](dman:///deepin-defender#病毒查殺)。 + +> ![notes](../common/notes.svg)說明: +> - 如果當前安全中心有查殺任務,則在彈出的對話框中單擊 **查看** 進入安全中心病毒查殺界面進行查看。 +> - 安全中心默認開啟 **加入「病毒查殺」到文件右鍵菜單** 的功能,您也可以進入安全中心設置界面,取消勾選該功能。取消勾選後檔案管理員右鍵菜單中不會顯示病毒查殺的選項。 + +## 常用操作 + +檔案管理員具備很多特色功能,這些功能都讓檔案管理更加簡單、高效。 + +### 切換地址欄 + +地址欄由歷史導航、麵包屑和輸入框共同組成。通常情況下地址欄顯示麵包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 單擊歷史導航按鈕,快速在歷史瀏覽記錄間切換,查看前一個地址或者後一個地址。 +- 文件所在位置的每一個層級都會形成一個麵包屑,通過來回單擊麵包屑可以快速在不同文件層級間切換。 + +單擊搜索圖標,或者在文件路徑上單擊右鍵並選擇「編輯地址」,地址欄會切換為輸入框狀態。在輸入框外單擊時,地址欄會自動恢復到麵包屑狀態。 + +![0|addressbar](fig/addressbar2.png) + +- 輸入框帶有智能識別功能,輸入關鍵詞或者訪問地址,系統會自動識別並進行搜索或訪問。 + +### 搜索文件 + +檔案管理員支持多種檢索方式,既支持通過文件名稱、文件內容進行普通搜索,也支持通過文件類型、創建時間等進行高級搜索,提高工作效率,便於文件管理。 + +- 指定目錄搜索時,請先進入該目錄,然後再進行搜索。 + + > ![notes](../common/notes.svg)說明:在檔案管理員的 **設置** 中,默認勾選了「自動索引內置磁盤」,您可以選擇勾選「連接電腦後索引外部存儲設備」,加快在外部設備的搜索速度。 + +#### 全文搜索 + +您可以通過文件內容關鍵字來搜索文件。 +1. 在檔案管理員中,單擊 ![icon_menu](../common/icon_menu.svg) > **設置**。 +2. 在高級設置項勾選「全文搜索」開啟此功能。 +3. 使用快捷鍵 **Ctrl + F** 或在地址欄中單擊搜索按鈕進入搜索狀態,輸入關鍵字後按下鍵盤上的 **Enter** 鍵,搜索相關文件。 + +#### 高級搜索 + +當文件較多,搜索較慢時,啟用高級搜索縮小搜索範圍,提高搜索效率。 + +1. 在搜索狀態下,輸入關鍵字後按 **Enter** 鍵,當搜索到結果時,搜索框右側顯示 ![filter](../common/filter.svg) 圖標,點擊該圖標可進行高級搜索的操作。 +2. 選擇搜索範圍、文件大小、文件類型、修改時間、訪問時間和創建時間,進行更精準的搜索。 + +![0|filter](fig/filter.png) + +### 最近使用 + +在左側導航欄上默認有 **最近使用** 入口,單擊可以查看最近使用的文件。文件默認按照訪問時間倒序排列。 + +> ![notes](../common/notes.svg)說明:若想隱藏「最近使用」,可在設置 > 基本設置 > 隱藏文件,取消勾選「顯示最近使用文件」。若要隱藏某一個文件的訪問記錄,右鍵單擊該文件選擇 **移除**,該操作不會刪除文件。 + +### 多標籤頁 + +檔案管理員支持多標籤頁顯示。 + +1. 在檔案管理員界面上,右鍵單擊文件夾。 +2. 選擇 **在新標籤中打開**。 +3. 當窗口有多個標籤頁時,可以: + - 單擊標籤頁右側的按鈕 + ,繼續添加標籤頁。 + - 將鼠標指針置於標籤頁上,單擊關閉按鈕 **×** 或單擊鼠標中鍵,關閉標籤頁。 + +![1|tab](fig/tab.png) + +> ![tips](../common/tips.svg)竅門:檔案管理員窗口只有一個標籤時,標籤頁是隱藏的,您還可以使用快捷鍵 **Ctrl + T** 來新建標籤頁。 + +### 書籤管理 + +為常用文件夾添加書籤,以便從左側導航欄快速訪問。 + +- 添加書籤:右鍵單擊文件夾,選擇 **添加書籤** 就可以在導航欄創建書籤。 +- 移動書籤:在導航欄上下拖動書籤調整書籤排序。 +- 刪除書籤:右鍵單擊書籤,選擇 **移除** 來刪除書籤;或右鍵單擊已添加書籤的文件夾,選擇 **移除書籤** 來刪除書籤。 + +### 標記訊息 + +通過給文件/文件夾添加標記,可以更好地分類管理您的文件。 + +> ![notes](../common/notes.svg)說明:當前僅x86平台支持 **標記訊息** 功能,該幫助手冊中涉及的標記訊息相關內容僅適用於x86平台。 + +#### 添加標記 + +您可以為一個文件(夾)添加多個標記,也可以同時為多個文件(夾)添加標記;添加成功的標記會出現在左側導航欄內。 + +##### 通過編輯框添加標記 + +1. 右鍵單擊文件(夾),選擇 **標記訊息**。 +2. 輸入標記名稱,若要添加多個標記,可用逗號分隔。 +3. 單擊界面空白區域保存設置。 + +>![notes](../common/notes.svg)說明:標記顏色從8種默認顏色中隨機分配。 + +![1|tag_info](fig/tag_info.png) + + +##### 通過顏色按鈕添加標記 + +右鍵單擊文件(夾),選擇「顏色按鈕」,直接生成這個顏色的標記。 + +![1|color_tag](fig/color_tag.png) + +##### 通過右側訊息欄添加標記 +選擇文件(夾)後,單擊菜單欄上的圖標 ![fileinfo](../common/fileinfo.svg),在右側訊息欄中也可以添加標記。 + +![1|info_tag](fig/info_tag.png) + +>![notes](../common/notes.svg)说明:如果文件有標記,則複製或剪切該文件產生的文件仍然具有同樣的標記。 + + +#### 重命名標記 + +在左側導航欄中,右鍵單擊某個標記,選擇 **重命名**,修改當前標記的名稱。 + +![1|rename_tag](fig/rename_tag.png) + +#### 修改標記顏色 + +在左側導航欄中,右鍵單擊某個標記,選擇「顏色按鈕」,即可修改當前標記的顏色。 + +#### 排序標記 + +上下拖動標記即可調整標記排序。 + +#### 刪除標記 + +右鍵單擊某個標記,選擇 **移除**,刪除當前標記。 + + +### 文件預覽 + +檔案管理員支持空格鍵預覽功能,選中文件並按下鍵盤上的空格鍵就可以快速預覽文件。預覽窗口可以查看圖片解像度、文檔大小、文本內容等,還支持gif、音頻、影片播放。 + +#### 預覽影片 + +1. 選擇您要預覽的影片文件,按下空格鍵,即可開始預覽。 +2. 單擊影片任意地方可暫停播放。 +3. 播放過程中,可以拖動進度條來快進快退。 +4. 單擊底部 **打開** 按扭,在默認程序中打開該影片文件。 + +![1|video_preview](fig/video_preview.png) + +> ![notes](../common/notes.svg)說明:您也可以同時選擇多個文件,按下空格鍵進行預覽。 + + +### 權限管理 +選擇對應文件/文件夾,單擊右鍵,選擇屬性,單擊 **權限管理**, 為所有者,群組,和其他用戶設置文件權限。 + +![2|permission](fig/permission.png) + +### 我的共享 + +當您設置了共享文件時,「我的共享」會出現在導航欄上。當所有共享文件都取消共享後,「我的共享」自動從導航欄中移除。 + +#### 共享本地文件 + +1. 在檔案管理員界面,右鍵單擊文件夾選擇 **共享文件夾**。 +2. 在文件夾的屬性窗口中,勾選 **共享此文件夾**。 + + > ![notes](../common/notes.svg)說明: 如果smb服務未開啟,共享文件夾時會彈出密碼認證窗口,輸入登錄密碼完成認證即可開啟smb服務。 + +3. 根據需要設置 **共享名**、**權限** 、**匿名訪問** 後關閉窗口。 +4. 單擊 ![icon_menu](../common/icon_menu.svg) > **設置共享密碼**。 +5. 輸入共享密碼,單擊 **確定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg)竅門:在文件夾的屬性窗口中取消勾選 **共享此文件夾**, 可以取消文件共享;也可以右鍵單擊文件,選擇 **取消共享**。 + + +#### 訪問共享文件 + +局域網中其他用戶共享的文件一般都可以在網絡鄰居中找到,您也可以通過smb訪問共享文件。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **連接到伺服器**,在編輯框中輸入伺服器地址,如:smb://xx.x.xx.xxx(一般為IP位址),單擊 **連接**;或者直接在地址欄中輸入伺服器地址,按下鍵盤上的 **Enter** 鍵。 +2. 選擇需要訪問的共享文件夾,在彈出的窗口中輸入用戶名和共享密碼,或者匿名訪問。 + - 未加密的網絡文件可以匿名訪問,不需要輸入用戶名和密碼。 + - 加密的網絡文件需要輸入用戶名和密碼之後才能訪問。 + + - 用戶名:共享者登錄系統的用戶名。 + - 密碼:共享文件時設置的共享密碼。 +3. 單擊 **連接**。 + +![1|visitshareshare](fig/visitshare.png) + +### 以管理員身份打開 + +前提條件: 「控制中心」 > 「常規」中 **開發者模式** 已開啟。 + +1. 在檔案管理員界面,右鍵單擊文件夾。 +2. 選擇 **以管理員身份打開**,在彈窗中輸入用戶登錄密碼,單擊 **確定**。 +3. 該文件夾會以新窗口打開,在此窗口中可以進行高級權限的操作,關閉窗口後,終止管理員權限。 + +### 在終端中打開 + +1. 在檔案管理員空白區域,單擊鼠標右鍵。 +2. 選擇 **在終端中打開**,會啟動終端應用程序,終端的路徑為當前目錄。 + +![0|open_terminal](fig/openinterminal.png) + +### 刻錄光盤 + +您可以通過刻錄功能將音樂、影片、圖片或鏡像文件複製到光盤中。其中,ISO9660文件系統支持所有的CD和DVD光盤格式,UDF文件系統僅支持部分光盤格式。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
類型光盤格式ISO9660UDF
空盤DVD-R、DVD+R、CD-R、CD-RW支持支持
非DVD-R、DVD+R、CD-R、CD-RW支持不支持
非空盤DVD-R、DVD+R、CD-R、CD-RW支持追加文件僅支持Windows原生工具刻錄的格式
非DVD-R、DVD+R、CD-R、CD-RW支持追加文件不支持追加文件
+ + +1. 將光盤插入到刻錄機中。 +2. 打開檔案管理員,單擊導航欄中的光盤圖標,進入刻錄CD的界面。 + +![cd](fig/cd_interface.png) + +3. 右鍵單擊 文件(夾),選擇 **添加至光盤刻錄** 或直接將文件(夾)拖拽到刻錄CD的界面。 +4. 在刻錄CD界面,單擊右上角 **刻錄**。 + + >![notes](../common/notes.svg)說明:如果要從刻錄列表中刪除某個文件(夾),右鍵單擊該文件(夾),選擇 **刪除**,將該文件(夾)從列表中移除。 + +5. 在彈窗中輸入光盤名稱。您也可以進入 **高級設置** 界面,設置文件系統、寫入速度,或勾選「允許追加數據」、「核驗數據」等,單擊 **刻錄**。 + +![cd](fig/cd_rename.png) + +6. 刻錄完成後界面彈出對話框,單擊 **確定**。 + +>![notes](../common/notes.svg)說明:如果需要擦除光盤數據,可以右鍵單擊導航欄中光盤圖標,選擇 **卸載**,再次右鍵單擊該光盤圖標並選擇 **擦除**。 + +### 創建快捷方式 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **創建鏈接**。 +3. 在彈窗中選擇創建位置、鏈接名稱。 +4. 單擊 **保存**,在目標位置會生成該文件(夾)的快捷方式。 + +> ![tips](../common/tips.svg)竅門:選擇 **發送到桌面** 可以直接在桌面上生成該文件(夾)的快捷方式。 + +### 發送文件(夾)到外接磁盤 + +當有外接磁盤接入時,您可以將文件或文件夾發送到外接磁盤。 + +1. 在檔案管理員界面,右鍵單擊文件(夾)。 +2. 選擇 **發送到** > 外接磁盤。 +3. 文件(夾)將會被發送到移動外接磁盤。 + +### 發送文件到藍牙 + +若您的電腦配置了藍牙模塊,便可通過藍牙進行短距離文件傳輸的操作。 + +前提條件:發送端與接收端藍牙設備已配對並成功連接。具體連接方法請參閱 [連接藍牙設備](dman:///dde#連接藍牙設備)。 + +1. 在檔案管理員界面,右鍵單擊需要發送的文件或文件壓縮包。 +2. 選擇 **發送到** > **發送到藍牙**。 +3. 在彈出的藍牙文件傳輸對話框中勾選接收設備,單擊 **下一步**。 +4. 此時接收端會收到文件接收的請求,待接收端同意請求後,發送端開始傳輸文件。 + +## 手機助手 + +統信UOS助手是一款實現手機與電腦間跨端協作、高效傳輸以及實時同步的工具。將手機與電腦連接或通過無線投送功能,輕鬆實現圖片、影片、文件等的傳輸。 + +>![icon](../common/notes.svg) 說明:僅安卓手機支持安裝統信UOS助手。 + +### 準備工作 + +#### 安裝統信UOS助手 + +1. 單擊左側導航欄 **我的手機** 或系統托盤中的圖標 ![icon](../common/found.svg)。 +2. 在我的手機界面,單擊 **安裝統信UOS助手**,彈出二維碼窗口。 + - 通過手機微信或瀏覽器掃描二維碼,下載並安裝統信UOS助手。 + - 單擊 **下載APK安裝包**,將安裝包下載到電腦端,下載完成後再導入至手機端進行安裝。 + + + ![phone](fig/myphone.png) + +#### 登錄統信UOS助手 + +統信UOS助手支持手機快捷登錄、微信登錄、帳號密碼登錄這三種登錄方式,可以選擇其中任意一種方式進行登錄。如果您尚未註冊帳號,請在登錄界面單擊 **註冊帳號** 進行註冊。 + + + +#### 設置發現方式 + +通過“發現設置”功能,設置手機和電腦被發現的方式。 + +在統信UOS助手界面,單擊右上角的 **發現設置**;在電腦系統托盤上,右鍵單擊圖標 ![icon](../common/found.svg),選擇 **發現設置**,您可以選擇: + +- **允許被所有人發現**:在局域網內,允許所有處於同一網絡且在同一網段的設備發現本手機或電腦。 +- **僅限同一Union ID帳號發現**:在局域網內,允許登錄同一個Union ID的設備發現本手機或電腦。 +- **不被發現**:所有設備都不能發現本手機或電腦。 +- **允許被登錄同一Union ID的遠程設備發現**(電腦端):允許登錄同一個Union ID的遠程設備發現本電腦。 + + + + + +### 連接手機與電腦 + +登錄統信UOS助手後,您可以通過掃碼連接或搜索電腦的方式將手機與電腦連接起來。 + + + +#### 掃碼連接 + +前提條件:手機與電腦處於同一無線網絡且在同一網段中。 + +1. 在電腦端,單擊文件管理器左側導航欄 **我的手機** 或系統托盤中的圖標 ![icon](../common/found.svg),彈出“使用統信UOS助手掃碼連接”的窗口。 +2. 在手機端,進入統信UOS助手界面,單擊 **掃碼連接**,掃描步驟1窗口中的二維碼,完成連接。 + +#### 搜索電腦 + +前提條件:手機與電腦處於同一無線網絡且在同一網段中(僅支持互發文件,不支持查看和編輯文件)或登錄同一個Union ID帳號;手機與電腦允許被發現。 + +1. 在統信UOS助手界面,單擊 **搜索電腦**。 +2. 在搜索列表中選擇需要連接的電腦,完成連接。 + + +如果需要斷開連接,您可以: + +- 在統信UOS助手界面上單擊按鈕 ![icon](../common/exit.svg) 斷開連接。 +- 在電腦上右鍵單擊系統托盤中的圖標 ![icon](../common/found.svg),選擇您的手機,在彈窗中單擊 **斷開連接**。 + +### 管理文件 + +手機與電腦連接成功後,您可以發送文件、查看文件和管理文件。 + + +#### 傳輸文件 + + +- **通過統信UOS助手界面進行文件傳輸** + + 發送手機文件至電腦:在統信UOS助手界面,單擊 **傳輸助手**,在傳輸窗口中發送文件至電腦端。 + +- **通過檔案管理員界面進行文件傳輸** + + 發送電腦文件至手機:在 **檔案管理員 > 我的手機** 界面,右側傳輸窗口中,您可以選擇電腦文件至該窗口中進行發送;或右鍵單擊電腦中的某個文件,選擇 **發送到我的手機**。 + +- **通過無線投送功能進行文件傳輸** + + 當設備處於同一無線網絡且在同一網段中或已登錄同一Union ID帳號,且設備允許被發現,您可以通過無線投送功能,將文件從一台設備投送到另一台設備中。 + 1. 在電腦上右鍵單擊需要投送的文件,選擇 **無線投送**。 + 2. 在彈窗中選擇需要投送的手機或電腦,完成投送。 + + >![icon](../common/notes.svg) 說明: + >- 手機端需要安裝統信UOS助手並登錄帳號後,才能接收電腦端投送的文件。 + >- 登錄同一Union ID後,可以進行遠程投送的操作。 + + +#### 查看/編輯文件 + +- 在手機上查看電腦文件:在統信UOS助手界面,單擊 **我的電腦**,您可以打開、下載或分享電腦文件。 +- 在電腦上查看/編輯手機文件:在 **檔案管理員 > 我的手機** 界面,分類展示手機相冊、影片、文檔等文件夾,您可以打開、編輯文件夾中的文件,文件經過編輯並保存後將同步至手機端。 + + +## 文件角標 + +您可以通過命令行,將圖標文件指定給一個文件或文件夾作為角標顯示出來。 + +>![icon](../common/notes.svg)說明: +>- 角標文件支持svg、jpg、png、bmp、gif格式,且大小不超過100KB。 +>- USB記憶體及光盤下的文件,不支持添加角標。 + +### 添加單個角標 + +1. 在終端輸入命令 **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑)"** ,該命令默認在文件(夾)右下角添加角標。 + + >![icon](../common/attention.svg)注意:系統已定義的特殊角標,不支持被替換。 + +2. 您也可以在上述命令中加入位置參數,將角標添加在文件(夾)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + + 例如:在文件(夾)左上角添加角標 + + **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑);lu"** + +![mark](fig/single.png) + +### 添加多個角標 + +在命令行中加入“**|**”符號將角標文件路徑連接起來,為文件(夾)添加2~4個角標。文件(夾)同一個位置不支持疊加角標,僅支持替換。 + +例如:在文件(夾)四個角都添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖標路徑);lu|xxx(圖標路徑);ld|xxx(圖標路徑);ru|xxx(圖標路徑);rd"** + +![mark](fig/multi.png) + +### 撤銷角標 + +在終端中輸入命令 **gio set xxx(文件路徑) -t stringv metadata::emblems ""** 撤銷文件(夾)上所有的角標。 + + +## 文件保險箱 + +文件保險箱旨在為您打造專屬的安全空間,為您的私隱保駕護航。 + +### 設置保險箱密碼 + +首次使用保險箱需要對其進行密碼設置,具體步驟如下: + +1. 單擊導航欄中的保險箱圖標 ![file_vault](../common/file_vault.svg),或者在計算機界面雙擊 **我的保險箱**,在彈窗中單擊 **建立**。 +2. 設置解鎖類型、保險箱密碼等,單擊 **下一步**。 + +![password](fig/password.png) + + > ![notes](../common/notes.svg)說明: 密碼必須同時包含大寫字母、小寫字母、數字和符號,且字符不小於8位,否則無法進入下一步。 + +3. 在保存密鑰文件窗口中,設置密鑰文件的存儲位置,單擊 **下一步**。如果您忘記了保險箱密碼,可使用密鑰文件找回密碼。 + +![encrypt](fig/save.png) + +4. 單擊 **加密保險箱**,彈出認證窗口,輸入用戶登錄密碼後單擊 **確定**。 + +5. 加密完成後在彈窗中單擊 **確定**,完成保險箱密碼設置。 + +![encrypt](fig/finish.png) + +### 鎖定保險箱 + +將文件放入保險箱後,右鍵單擊 ![file_vault](../common/file_vault.svg) 或者在計算機界面右鍵單擊 **我的保險箱**。 +- 選擇 **立即上鎖**,立即將文件保險箱鎖上。 +- 選擇 **自動上鎖**,在其下拉選項中: + + 選擇「從不」,計算機在鎖屏或關機前一直保持未上鎖狀態。 + + 選擇「5分鐘」、「10分鐘」或者「20分鐘」後自動上鎖保險箱。 + +![0|right](fig/right.png) + + +### 解鎖保險箱 + +1. 單擊 ![file_vault](../common/file_vault.svg) 或者在計算機界面雙擊 **我的保險箱**。 +2. 在解鎖保險箱窗口中,輸入保險箱密碼,單擊 **解鎖**。 +3. 如果忘記了保險箱密碼,單擊 **忘記密碼**,選擇密鑰文件的存儲位置後,單擊 **驗證密鑰** 找回密碼。 + +![encrypt](fig/unlock.png) + + +>![0|tips](../common/tips.svg)竅門:您也可以右鍵單擊 ![file_vault](../common/file_vault.svg) 或者 **我的保險箱**,選擇 **解鎖**,解鎖保險箱。 + + +### 刪除保險箱 + +刪除保險箱需要提前解鎖保險箱。 +1. 右鍵單擊 ![file_vault](../common/file_vault.svg) 或者 **我的保險箱**,選擇 **刪除保險箱**。 +2. 彈出刪除保險箱窗口,輸入保險箱密碼,單擊 **刪除**。 +3. 在密碼認證窗口中輸入用戶登錄密碼,單擊 **確定** 完成操作。 +> ![attention](../common/attention.svg)注意:刪除保險箱會將裏面的文件一併刪除。在進行刪除操作前,請將保險箱中的文件備份。 + + +## 磁盤管理 + +檔案管理員管理本地磁盤和外接磁盤。本地磁盤顯示在檔案管理員的左側導航欄上或計算機界面;掛載外接磁盤或者插入其他移動存儲設備時,也會在導航欄看到相應的磁盤圖標。 + + + + + + + + + + + + + + + + + +
本地磁盤本地硬碟分區的所有磁盤
外接磁盤包括移動硬碟、USB記憶體、光盤
移動設備手機內存、存儲卡、SD卡等
+ + + +> ![notes](../common/notes.svg)說明:如果磁盤或磁盤中的文件夾已加密,請輸入密碼後查看文件。 + +### 本地磁盤 + +#### 隱藏本地磁盤 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg) > **設置**。 +2. 在高級設置選項中勾選 **隱藏系統盤**。 + +#### 重命名本地磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊本地磁盤。 +2. 選擇 **重命名**。 +3. 輸入新名稱,按下鍵盤上的 **Enter** 鍵或單擊界面空白區域保存修改。 + +> ![tips](../common/tips.svg)竅門:在計算機界面,慢速雙擊本地磁盤,呈現編輯框後便可進行重命名操作。 + +![0|disk](fig/p_rename_disk.png) + +### 外接磁盤 + +#### 彈出外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要移除的磁盤。 +2. 選擇 **安全移除**。 +3. 磁盤將從磁盤列表中刪除,一併彈出該磁盤的所有分區。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg)竅門:如果要彈出光盤,請選擇 **彈出** 來移除光盤。單擊導航欄中磁盤右邊的 ![unmount](../common/unmount_normal.svg) 同樣可以彈出磁盤或光盤。 + +#### 重命名外接磁盤 +1. 在左側導航欄或計算機界面,右鍵單擊需要重命名的磁盤。 +2. 選擇 **卸載**後,再次單擊右鍵選擇 **重命名**。 +3. 輸入新的卷標名稱,按下鍵盤上的 **Enter** 鍵或單擊界面空白區域保存修改。 + + + +#### 格式化外接磁盤 + +1. 在左側導航欄或計算機界面,右鍵單擊需要格式化的磁盤。 +2. 選擇 **卸載** 後,再次單擊右鍵選擇 **格式化**。 +3. 設置格式化之後的文件類型和卷標。 +4. 單擊 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg)說明:快速格式化速度快,但是數據仍然可能通過工具被恢復,如果想要格式化後的數據無法被恢復,可以取消勾選「快速格式化」,然後執行格式化操作。 + +## 主菜單 + +在主菜單中,您可以新建窗口,切換窗口主題,[設置共享密碼](#共享本地文件),設置檔案管理員,查看幫助手冊和版本介紹。 + +### 新建窗口 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **新建窗口**,打開一個新的檔案管理員窗口。 + +### 連接到伺服器 + +通過連接伺服器 [訪問局域網共享文件](#訪問共享文件)。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **連接到伺服器**,在編輯框中輸入伺服器IP位址。 + - 單擊 ![+](../common/+.svg) 按鈕可將該地址添加到「個人收藏伺服器」列表中。 + - 在「個人收藏伺服器」列表中選中一個地址,單擊 ![_](../common/-.svg) 按鈕,將該地址從收藏列表中移除。 +3. 單擊 **連接**。 + +![conncet](fig/connect_to_server.png) + + +### 設置 +#### 基礎設置 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)> **設置** 。 +2. 選擇 **基礎設置** 選項。 + + 勾選 **總是在新窗口打開文件夾**。 + + 設置雙擊或單擊打開文件。 + + 設置 **從默認窗口打開**、**從新標籤打開** 哪個目錄。 + + 設置文件圖標 **默認大小** 。 + + 設置 **默認視圖** 以圖標展示或列表展示。 + + 勾選 **顯示隱藏文件**,檔案管理員中被隱藏的文件會顯示出來。 + + 勾選 **重命名時隱藏文件擴展名**,重命名時不會顯示擴展名。 + + 勾選 **顯示最近使用文件**,在左側導航欄顯示最近使用的文件。 + +#### 高級設置 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)> **設置** 。 +2. 選擇 **高級設置** 選項。 + + 勾選 **自動索引內置磁盤**,搜索文件時會搜索內置磁盤中的文件。 + + 勾選 **連接電腦後索引外部存儲設備**,搜索文件時也會搜索外接設備中的文件。 + + 勾選 **全文搜索**,通過文件中的內容來索引。 + + 勾選預覽文件類型。 + + 勾選 **自動掛載**,接入外接磁盤時自動掛載。 + + 勾選 **自動掛載後打開**,接入外接磁盤時自動掛載並打開該磁盤。 + + 勾選 **MTP掛載路徑下顯示文件統計詳情**,MTP設備掛載後,顯示其路徑底部的狀態欄訊息。 + + 勾選 **Samba共享端常駐顯示掛載入口**,遠程掛載鏈接常駐顯示在導航欄中。 + + 勾選 **使用檔案管理員的文件選擇對話框**,選擇文件時打開檔案管理員窗口。 + + 勾選 **開啟普通刪除提示**,刪除文件時彈出提示對話框。 + + 勾選 **隱藏系統盤**,導航欄和計算機界面將不顯示本地磁盤。 + + 勾選 **在磁盤圖標上顯示文件系統標籤**。 + +### 主題 + +窗口主題包含淺色主題、深色主題和系統主題。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **主題**,選擇一個主題。 + + + +### 幫助 + +查看幫助手冊,進一步了解和使用檔案管理員。 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **幫助**。 +3. 查看檔案管理員的幫助手冊。 + + +### 關於 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **關於**。 +3. 查看檔案管理員的版本和介紹。 + + +### 退出 + +1. 在檔案管理員界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **退出**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/d_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/d_file-manager.md new file mode 100644 index 0000000..989affa --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/d_file-manager.md @@ -0,0 +1,626 @@ +# 檔案管理器|dde-file-manager| + +## 概述 + +檔案管理器是一款功能強大、簡單易用的文件管理工具。它沿用了傳統檔案管理器的經典功能和布局,並在此基礎上簡化了使用者操作,增加了很多特色功能。一目了然的導航欄、智慧識別的搜尋框、多樣化的檢視及排序讓您管理起來得心應手,經典和超越,只為給您更好的體驗! + +![1|overview](fig/d_overview.png) + +## 使用入門 + +透過以下方式執行或關閉檔案管理器,或者建立檔案管理器的捷徑。 + +### 執行檔案管理器 + +1. 單擊桌面底部的 ![deepin_launcher ](../common/deepin_launcher.svg),進入啟動器介面。 +2. 上下滾動滑鼠滾輪瀏覽或透過搜尋找到檔案管理器![deepin_file_manager](../common/deepin_file_manager.svg),單擊執行。 +3. 右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 單擊 **建立桌面捷徑**,在桌面建立捷徑。 + - 單擊 **釘選到Dock**,將應用程式固定到Dock。 + - 單擊 **開機啟動**,將應用程式添加到開機啟動項,在電腦開機時自動執行該應用。 + +>![tips](../common/tips.svg) 竅門:您可以使用組合鍵 **Super + E** 啟動檔案管理器。 + +### 關閉檔案管理器 + +- 在檔案管理器介面,單擊 ![close_icon](../common/close_icon.svg),關閉檔案管理器。 +- 在任務欄右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),選擇 **全部關閉** 來關閉檔案管理器。 +- 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg),選擇 **退出** 來關閉檔案管理器。 + +### 查看快捷鍵 + +在檔案管理器介面上,按下**Ctrl + Shift + /** 組合鍵來查看快捷鍵,熟練的使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主介面 + +檔案管理器的主介面簡單易用、功能全面,熟練地使用介面功能將使文件管理更加簡單高效。 + +![1|main-interface](fig/d_maininterface.png) + + +| 標號 | 名稱 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 導航欄 | 單擊導航圖示,快速存取本機文件、磁碟、網路鄰居、書籤、標記等。 | +| 2 | 地址欄 | 透過地址欄,您可以快速切換訪問歷史、在上下級目錄間切換、搜尋、輸入地址訪問。 | +| 3 | 圖示/列表檢視 | 單擊 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg)圖示,以圖示或列表形式查看檔案(資料夾)。 | +| 4 | 訊息欄 | 單擊 ![fileinfo](../common/fileinfo.svg), 查看檔案(資料夾)的基本訊息和標記。 | +| 5 | 選單欄 | 透過主選單,您可以建立視窗、切換視窗主題、設定共享密碼、設定檔案管理器、查看說明文件和關於訊息、關閉檔案管理器。 | +| 6 | 狀態欄 | 顯示文件數量或者已選中文件的數量。 | + + +> ![tips](../common/tips.svg) 竅門:可拖動左側導航欄右邊的分隔線來改變其寬度。 + +## 基本功能 + +檔案管理器具備基本的文件管理功能,對檔案(資料夾)進行新增、複製、重新命名、刪除等操作都非常簡單。 + +### 新增文件 + +#### 新增文件 + +1. 在檔案管理器空白區域,單擊滑鼠右鍵。 +2. 單擊 **新增文件**。 +3. 選擇新增文件的類型。 +4. 輸入新增文件的名稱。 + +![0|newdo](fig/newdo.png) + +#### 新增資料夾 + +1. 在檔案管理器空白區域,單擊滑鼠右鍵。 +2. 單擊 **新增資料夾**。 +3. 輸入資料夾的名稱。 + +### 重新命名文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **重新命名**。 +3. 輸入檔案名稱,按 **Enter** 鍵或者滑鼠單擊介面空白區域以儲存。 + +![0|contextmenu](fig/d_rename.png) + +> ![tips](../common/tips.svg)竅門:在 **設定** 中勾選「重新命名時隱藏檔案副檔名」,能更方便地修改檔案名稱。 + +### 批次重新命名 + +1. 在檔案管理器介面上,選中多個文件。 +2. 右擊文件,並選擇 **重新命名**。 + - **取代文件** 尋找需要取代的文字,並輸入取代後的文字,檔案名中的關鍵字將被統一取代。 + - **加入文件** 輸入需要加入的文字,並選擇目錄是檔名之前還是之後,檔案名將統一加入被添加的文字。 + - **自訂文件** 輸入檔案名,並輸入序列的遞進數字,檔案名將統一改成新檔案名+遞進數字。 +4. 單擊 **重新命名** 來完成操作。 + +![1|rename](fig/d_batchrename.png) + +### 查看文件 + +單擊介面上的 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 圖示來切換圖示檢視和列表檢視。 + +- 圖示檢視:平鋪顯示文件的名稱、圖示或縮圖。 + +![1|icon-view](fig/d_iconview.png) + +- 列表檢視:列表顯示文件圖示或縮圖、名稱、修改時間、大小、類型等訊息。 + +![1|list-view](fig/d_listview.png) + +> ![tips](../common/tips.svg)竅門:使用 **Ctrl + 1** 和 **Ctrl + 2** 快捷鍵,切換圖示檢視和列表檢視。 + + +### 排序文件 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 選擇 **排序順序**。 +3. 在子選單中選擇以檔案名稱、修改時間、大小或類型來排序文件。 + +> ![tips](../common/tips.svg)竅門:在列表檢視中,單擊表頭欄的列標記來切換升序、降序。 + +### 開啟文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **用其他程式開啟** > **選擇預設開啟程式**。 +3. 在程式列表中選擇應用程式。 + +> ![notes](../common/notes.svg)說明:直接雙擊文件會使用預設程式打開。您可以選擇相同類型的多個文件,右鍵選擇「用其他程式開啟」選項,一次開啟多個文件。 + +![0|open](fig/d_open.png) + +### 隱藏文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **屬性**,勾選 **隱藏此文件**。 + +### 複製文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 單擊 **複製**。 +3. 選擇一個目標儲存位置。 +4. 單擊滑鼠右鍵,然後選擇 **貼上**。 + +### 壓縮文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 單擊 **壓縮**。 +3. 彈出歸檔管理器壓縮介面,可以設定壓縮包格式、名稱、儲存路徑等,單擊 **壓縮**。 + + + +> ![tips](../common/tips.svg)竅門:您也可以直接在右鍵選單中選擇 **添加到xxx.7z** 或 **添加到xxx.zip**,快速將檔案(資料夾)壓縮成7z或zip格式。 + +### 刪除文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **刪除** 。 + + - 被刪除的文件可以在回收桶中找到,右鍵單擊回收站中的文件可以進行 **還原** 或 **刪除** 操作。 + - 被刪除的文件的捷徑將會失效。 + +> ![attention](../common/attention.svg)注意:外接裝置刪除文件會將文件徹底刪除,無法從回收桶找回。 + +### 復原操作 + +在檔案管理器中,可以用 **Ctrl + Z** 來復原上一步操作,包括: + +- 刪除建立的文件。 +- 復原重新命名(包括重新命名文件後綴)之前的名字。 +- 從回收站還原剛刪除的文件。 +- 復原文件到移動(剪下移動、滑鼠移動)前的原始路徑。 +- 刪除複製貼上的文件。 + +>![attention](../common/attention.svg)注意:復原動作最多只能返回兩步;如果操作中有覆蓋某個同名文件和徹底刪除文件,則復原只能返回到這一步。 + +### 文件屬性 + +文件屬性會顯示文件的基本資訊,開啟方式和權限設定。資料夾内容會顯示資料夾的基本資訊,共用訊息和權限設定。 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **屬性**,查看文件屬性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg)說明:查看多個文件屬性會顯示文件總大小和數量;查看捷徑的屬性將會額外顯示來源文件地址。您還可以使用 **Ctrl + I** 組合鍵查看文件屬性。 + + + +## 常用操作 + +檔案管理器具備很多特色功能,這些功能都讓文件管理更加簡單、高效。 + +### 切換地址欄 + +地址欄由歷史導航、麵包屑和輸入框共同組成。通常情況下地址欄顯示麵包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 單擊歷史導航按鈕,您可以快速在歷史瀏覽記錄間切換,查看前一個地址或者後一個地址。 +- 文件所在位置的每一個層級都會形成一個麵包屑,透過來回單擊麵包屑可以快速在不同文件層級間切換。 + +當您單擊搜尋圖示,或者在文件路徑上右鍵選擇「編輯位址」,地址欄會切換為輸入框狀態。在輸入框外單擊時,位址欄會自動復原到麵包屑狀態。 + +![0|addressbar](fig/addressbar2.png) + +- 輸入框帶有智慧識別功能,您可以輸入關鍵字或者訪問地址,系統會自動識別並進行搜尋或訪問。 + +### 搜尋文件 + +檔案管理器支援多種檢索方式,既支援透過檔案名稱、文件內容進行普通搜尋,也支援透過文件類型、建立時間等進行進階搜尋,提高工作效率,便於文件管理。 + - 需要指定目錄搜尋時,請先進入該目錄,然後再進行搜尋。 + +> ![notes](../common/notes.svg)說明: +> 在檔案管理器的 **設定** 中,預設勾選了「自動索引內部硬碟」,您可以選擇勾選「外部裝置連上電腦時索引」,加快在外部裝置的搜尋速度。 + +#### 全文搜尋 + +您可以透過文件內容關鍵字來搜尋文件。 + +1. 在檔案管理器中,單擊 ![icon_menu](../common/icon_menu.svg) > **設定**。 +2. 在進階設定項勾選「全文搜尋」來開啟此功能。 +3. 使用組合鍵 **Ctrl + F** 或在地址欄中單擊搜尋按鈕進入搜尋狀態,輸入關鍵字後按下鍵盤上的 **Enter** 鍵,搜尋相關文件。 + +#### 進階搜尋 + +當文件較多,搜尋較慢時,啟用進階搜尋縮小搜尋範圍,提高搜尋效率。 + +1. 在搜尋狀態下,輸入關鍵字後按 **Enter** 鍵,當搜尋到結果時,搜尋框右側顯示 ![filter](../common/filter.svg) 圖示,點擊該圖示可進行進階搜尋的操作。 + +2. 選擇搜尋範圍、檔案大小、文件類型、修改時間、訪問時間和建立時間,進行更精準的搜尋。 + +![0|filter](fig/d_filter.png) + +### 最近使用 + +在左方面板上預設有 **最近** 入口,單擊可以查看最近使用的檔案項目。文件預設按照訪問時間倒序排列。 + + +> ![notes](../common/notes.svg)說明:若想隱藏「最近」,可在設定 > 基本設定 > 隱藏文件,取消勾選「在左方面板顯示最近檔案項目」。若要隱藏某一個文件的訪問記錄,右擊該文件選擇 **移除**,該操作不會刪除文件。 + +### 多分頁 + +檔案管理器支援多分頁顯示。 + +1. 在檔案管理器介面上,右鍵單擊資料夾。 +2. 選擇 **在新分頁中開啟**。 +3. 當視窗有多個分頁時,可以: + - 單擊標記欄右側的 + 繼續添加分頁。 + - 單擊標記上的 × 關閉分頁或將滑鼠置於分頁欄上,單擊滑鼠中鍵關閉分頁。 + + ![1|tab](fig/d_tab.png) + +> ![tips](../common/tips.svg)竅門:檔案管理器視窗只有一個分頁時,分頁欄是隱藏的,您還可以使用快捷鍵 **Ctrl** + **T** 來建立分頁。 + +### 書籤管理 + +為常用資料夾添加書籤,以便從左側導航欄快速訪問。 + +- 添加書籤:右鍵單擊資料夾,選擇 **加到書籤** 就可以在導航欄建立書籤。 +- 移動書籤:在導航欄上下拖動書籤調整書籤排序。 +- 刪除書籤:右鍵單擊書籤,選擇 **移除** 來刪除書籤;或右鍵單擊已添加書籤的資料夾,選擇 **移除書籤** 來刪除書籤。 + +### 標記内容 + +透過給檔案(資料夾)添加標記,可以更好地分類管理您的文件。 + +> ![notes](../common/notes.svg)說明:目前僅x86平台支援 **標記内容** 功能,本幫助手冊中涉及的標記訊息相關內容僅適用於x86平台。 + +#### 添加標記 + +您可以一次為多個檔案(資料夾)添加標記,一個檔案(資料夾)也可以添加多個標記;您還可以在檔案(資料夾)的屬性中添加標記。添加成功的標記會出現在左側導航欄內。 + +##### 透過編輯框添加標記 + +1. 右鍵單擊檔案(資料夾),選擇 **標記内容**。 +2. 輸入標記名稱。若要添加多個標記,用逗號分隔。 +3. 編輯完成後單擊空白處儲存設定。 + +>![notes](../common/notes.svg)說明:標記顏色從8種預設顏色中隨機分配。 + +![1|tag info](fig/d_taginfo.png) + + + +##### 透過顏色按鈕添加標記 + +右鍵單擊檔案(資料夾),選擇「顏色按鈕」,直接生成這個顏色的標記。 + +![1|color tag](fig/d_colortag.png) + +##### 透過右側訊息欄添加標記 +選擇檔案(資料夾)後,單擊 ![fileinfo](../common/fileinfo.svg),在右側訊息欄中也可以添加標記。 + +![1|info tag](fig/d_infotag.png) + + + +>![notes](../common/notes.svg)說明:複製或剪下有標記的文件,所產生的文件仍然具有同樣的標記。 + + +#### 重新命名標記 + +在側邊導航欄中,右鍵單擊某個標記,選擇 **重新命名**,修改目前標記的名稱。 + +![1|rename tag](fig/renametag.png) + +#### 修改標記顏色 + +在左側導航欄中,右鍵單擊某個標記,選擇「顏色按鈕」,即可修改目前標記的顏色。 + +#### 排序標記 + +上下拖動標記即可調整標記排序。 + +#### 刪除標記 + +右鍵單擊某個標記,選擇 **移除**,刪除目前標記。 + + + +### 文件預覽 + +檔案管理器支援空白鍵預覽功能,選中文件並按下鍵盤上的空白鍵就可以快速預覽文件。預覽視窗可以查看圖片解析度、檔案大小、文字內容等,還支援gif、音訊、影片播放。 + +#### 預覽影片 + +1. 選擇您要預覽的影片檔案,按下空白鍵,即可開始預覽。 +2. 單擊影片任意地方可暫停播放。 +3. 播放過程中,可以拖動進度條來快進快退。 +4. 單擊底部 **開啟** 按扭,在預設程式中開啟該影片檔案。 + +![1|video preview](fig/videopreview.png) + +> ![notes](../common/notes.svg)說明:您也可以同時選擇多個文件,按下空白鍵進行預覽。 + + +### 權限管理 +選擇對應檔案/資料夾,單擊右鍵,選擇屬性,單擊 **存取權限**, 為擁有者,群組,和其他使用者設定檔案權限。 + +![2|permission](fig/permission.png) + +### 共用資料夾 + +當您設定了共用資料夾時,「我的共用」將會出現在導航欄上。當所有共用資料夾都取消共用後,「我的共用」自動從導航欄中移除。 + +#### 共用本機文件 + +1. 在檔案管理器介面上,右鍵單擊資料夾。 +2. 選擇 **共用資料夾**。 +3. 在資料夾的屬性視窗,勾選 **共用資料夾**。 + + > ![notes](../common/notes.svg) 說明: 如果smb服務未開啟,則彈出密碼認證視窗,輸入登入密碼完成認證即可開啟smb服務。 + +4. 根據需要設定 **共用名稱**、**存取權限**、**匿名**後關閉視窗。 +5. 在檔案管理器介面上,單擊 ![icon_menu](../common/icon_menu.svg) > **設定共用密碼**。 +6. 輸入共用密碼後單擊 **確定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg)竅門:取消勾選 **共用資料夾** 可以取消文件共用,也可以右鍵單擊文件,選擇 **取消共用**。 + + +#### 訪問共用文件 + +區域網路中其他使用者共用的文件都可以在網路鄰居中找到,您也可以透過smb訪問共用文件。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **連線到伺服器**,在編輯框中輸入伺服器地址,如:smb://xx.x.xx.xxx(一般為IP位址),單擊 **連接**;或者直接在地址欄中輸入伺服器地址,按下鍵盤上的 **Enter** 鍵。 +2. 輸入使用者名稱和共用密碼。 + - 未加密的共用文件可以匿名訪問,不需要輸入使用者名稱和密碼。 + - 加密的共用文件會彈出登入框,輸入使用者名稱和密碼之後才能訪問。 + - 使用者名稱:共用者登入系統的使用者名稱。 + - 密碼:共用文件時設置的共用密碼。 +3. 單擊 **連線**。 + +![1|visitshareshare](fig/visitshare.png) + + + +### 以管理員身份開新視窗 + +1. 在檔案管理器介面空白處單擊滑鼠右鍵。 +2. 選擇 **以管理員身份開新視窗**,在彈出的對話框中輸入使用者密碼,點擊 **確定**。 +3. 該資料夾會以新視窗打開,在此視窗中可以進行進階權限的操作,關閉視窗後,終止管理員權限。 + +### 從終端中開啟 + +1. 在檔案管理器介面空白處單擊滑鼠右鍵。 +2. 選擇 **開啟終端機**,會啟動終端應用程式,終端的路徑為目前目錄。 + +![0|open-terminal](fig/openinterminal.png) + +### 燒錄光碟 +您可以透過燒錄功能將音樂、影片、圖片或鏡像文件複製到CD或DVD中。請提前準備一部燒錄機、一張CD或DVD光碟。 + +1. 將光碟插入到燒錄機中。 +2. 打開檔案管理器,單擊導航欄中的光碟圖示,進入燒錄CD的介面。 + +![cd](fig/d_cd_interface.png) + +3. 右鍵單擊 檔案(資料夾),選擇 **添加至光碟燒錄** 或直接將檔案(資料夾)拖曳到燒錄CD的介面。 +4. 在燒錄CD介面,單擊右上角按鈕 **燒錄**。 + + >![notes](../common/notes.svg)說明:如果要從燒錄列表中刪除某個檔案(資料夾),右鍵單擊該檔案(資料夾),選擇 **刪除**,將該檔案(資料夾)從列表中移除。 + +5. 彈出對話框,輸入光碟名稱。您也可以進入 **進階設定** 介面,設定檔案系統、寫入速度,或勾選「允許追加資料」、「核驗資料」等,單擊 **燒錄**。 + +![cd](fig/d_cd_rename.png) + +6. 燒錄完成後介面彈出提示框,單擊 **確定**。 + +>![notes](../common/notes.svg)說明: +>- 目前系統僅支援對ISO9660格式的文件進行讀取與燒錄,而UDF格式的文件只支援讀取,暫不支援燒錄。 +>- 如果需要擦除光碟資料,可以右鍵單擊導航欄中光碟圖示,選擇 **卸载**,再次右鍵單擊該光碟圖示並選擇 **清除**。 + + + +### 建立捷徑 + +1. 在檔案管理器介面上,右鍵單擊文件或資料夾。 +2. 選擇 **建立連結**。 +3. 在跳出視窗中選擇建立位置、連結名稱。 +4. 單擊 **儲存**,在目標位置會生成該檔案(資料夾)的捷徑。 + +> ![tips](../common/tips.svg)竅門:選擇 **傳送到桌面** 可以直接在桌面上生成該檔案(資料夾)的捷徑。 + +### 傳送文件到外接磁碟 + +當有外接磁碟接入時,您可以將文件或資料夾發送到外接磁碟。 + +1. 在檔案管理器介面上,右鍵單擊文件或資料夾。 +2. 選擇 **傳送到** > 外接磁碟。 +3. 文件或資料夾將會被傳送到移動外接磁碟。 + +### 傳送文件到藍牙 +若您的電腦配備了藍牙模組,便可透過藍牙進行短距離文件傳輸的操作。 + +前提條件:傳送端與接收端藍牙設備已配對並成功連接。具體連接方法可參考 [連接藍牙設備](dman:///dde#連接藍牙設備)。 + +1. 在檔案管理器界面,右鍵單擊需要傳送的文件或文件壓縮包。 +2. 選擇 **傳送到** > **傳送到藍牙**。 +3. 在彈出的藍牙文件傳輸對話框中勾選接收設備,點擊 **下一步**。 +4. 此時接收端會收到文件接收的請求,待接收端同意請求後,傳送端開始傳輸文件。 + +>![tips](../common/tips.svg)竅門:若您需要傳輸資料夾,可提前將資料夾壓縮後再透過藍牙發送。 + +## 文件角標 + +您可以透過命令列,將圖示文件指定給一個文件或資料夾作為角標顯示出來。 + >![icon](../common/notes.svg)說明: + >- 角標文件支援svg、jpg、png、bmp、gif格式,且大小不超過100KB。 + >- 隨身碟及光碟下的文件,不支援添加角標。 + +### 添加單個角標 + +1. 在終端輸入指令 **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑)"** ,該指令預設在檔案(資料夾)右下角添加角標。 + + >![icon](../common/attention.svg)注意:系統已定義的特殊角標,不支援被取代。 + +2. 您也可以在上述指令中加入位置參數,將角標添加在檔案(資料夾)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + +例如:在檔案(資料夾)左上角添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑);lu"** + +![mark](fig/single.png) + +### 添加多個角標 + +在命令列中加入“**|**”符號將角標文件路徑連結起來,為檔案(資料夾)添加2~4個角標。檔案(資料夾)同一個位置不支援疊加角標,僅支援取代。 + +例如:在檔案(資料夾)四個角都添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑);lu|xxx(圖示路徑);ld|xxx(圖示路徑);ru|xxx(圖示路徑);rd"** + +![mark](fig/multi.png) + +### 復原角標 + +在終端中輸入指令 **gio set xxx(文件路徑) -t stringv metadata::emblems ""** 復原檔案(資料夾)上所有的角標。 + +## 磁碟管理 + +檔案管理器管理本機磁碟和外接磁碟。本機磁碟顯示在檔案管理器的左側導航欄上或電腦介面;掛載外接磁碟或者插入其他移動儲存裝置時,也會在導航欄看到相應的磁碟圖示。 + + + + + + + + + + + + + + + + + +
本機磁碟本機硬碟分區的所有磁碟
外接磁碟包括行動硬碟、隨身碟、光碟
移動裝置手機記憶體、記憶卡、SD卡等
+ +> ![notes](../common/notes.svg)說明:如果磁碟或磁碟中的資料夾被加密了,請輸入密碼後查看文件。 + +### 本機磁碟 + +#### 隱藏本機磁碟 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg) > **設定**。 +2. 在進階設定選項中勾選 **隱藏系統硬碟**。 + +#### 重新命名本機磁碟 +1. 在左側導航欄或電腦介面,右鍵單擊需要重新命名的本機磁碟。 +2. 選擇 **重新命名**。 +3. 輸入新名稱後按下鍵盤上的 **Enter** 鍵或單擊空白處儲存修改。 + +> ![tips](../common/tips.svg)竅門:在電腦介面,慢速雙擊本機磁碟,呈現編輯框後便可進行重新命名操作。 + +![0|disk](fig/d_rename_disk.png) + +### 外接磁碟 + +#### 彈出外接磁碟 + +1. 在左側導航欄或電腦介面,右鍵單擊需要移除的磁碟。 +2. 選擇 **安全移除**。 +3. 磁碟將從磁碟列表中刪除,一併彈出該磁碟的所有分區。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg)竅門:如果要彈出光碟,請選擇 **彈出** 來移除光碟。單擊導航欄中磁碟右邊的 ![unmount](../common/unmount_normal.svg) 同樣可以彈出磁碟或光碟。 + +#### 重新命名外接磁碟 +1. 在左側導航欄或電腦介面,右鍵單擊需要重新命名的磁碟。 +2. 選擇 **移除**後,再次單擊右鍵選擇 **重新命名**。 +3. 輸入新的卷標名稱,按下鍵盤上的 **Enter** 鍵或單擊空白處儲存修改。 + +#### 格式化外接磁碟 + +1. 在左側導航欄或電腦介面,右鍵單擊需要格式化的磁碟。 +2. 選擇 **卸载**,再次單擊右鍵選擇 **檔案格式**。 +3. 在格式化跳出視窗中設定格式化之後的文件類型和卷標。 +4. 單擊 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg)說明:快速格式化速度快,但是資料仍然可能透過工具被復原,如果想要格式化後的資料無法被復原,可以取消勾選「快速格式化」,然後執行格式化操作。 + +## 主選單 + +在主選單中,您可以新增視窗、切換主題、連線到伺服器、設定共用密碼(見[共用本機文件](#共用本機文件))、設定檔案管理器、查看說明手冊和版本介紹。 + +### 新增視窗 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **新增視窗**。 + +### 連線到伺服器 + +透過連接伺服器訪問區域網路共用文件(見[訪問共用文件](#訪問共用文件))。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **連線到伺服器**,在編輯框中輸入伺服器IP位址(XX.XX.XX.XX)。 + - 單擊 ![+](../common/+.svg) 按鈕可將該地址添加到「個人收藏伺服器」列表中。 + - 在「個人收藏伺服器」列表中選中一個地址,單擊 ![_](../common/-.svg) 按鈕,將該地址從收藏列表中移除。 +3. 單擊 **連線**。 + +![conncet](fig/connect_to_server.png) + + +### 設定 + +#### 基本設定 +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **設定** 。 +2. 選擇 **基本** + + 勾選 **永遠在新視窗開啟**。 + + 設定雙擊或單擊打開文件。 + + 設定 **視窗預設開啟**、**新建分頁時開啟**哪個目錄。 + + 設定檔案圖示大小 。 + + 設定 **預設顯示** 以圖示顯示或列表展示。 + + 勾選 **顯示隱藏檔案**,檔案管理器中被隱藏的檔案會顯示出來。 + + 勾選 **重新命名時隱藏檔案副檔名**,重新命名時不會顯示副檔名。 + + 勾選 **在左方面板顯示最近檔案項目**,在左側導航欄顯示最近使用的檔案。 + +#### 進階設定 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **設定** 。 +2. 選擇 **進階** 選項。 + + 勾選 **自動索引內部硬碟**,搜尋文件時會搜尋內建磁碟中的文件。 + + 勾選 **外部装置連上電腦時索引**,搜尋文件時也會搜尋外接裝置中的文件。 + + 勾選 **全文搜尋**,透過文件中的內容來索引。 + + 勾選預覽文件類型。 + + 勾選 **自動掛載**,接入外接磁碟時自動掛載。 + + 勾選 **自動掛載後開啟**,接入外接磁碟時自動掛載並打開該磁碟。 + + 勾選 **MTP掛載路徑下顯示文件統計詳情**,MTP裝置掛載後,顯示其路徑底部的狀態欄訊息。 + + 勾選 **Samba共享端常駐顯示掛載入口**,遠端掛載連結常駐顯示在導航欄中。 + + 勾選 **使用檔案管理器的選擇檔案對話框**,選擇文件時打開檔案管理器視窗。 + + 勾選 **開啟普通刪除提示**,刪除文件時彈出提示對話框。 + + 勾選 **隱藏系統硬碟**,導航欄和電腦介面將不顯示本機磁碟。 + + 勾選 **在磁碟圖標上顯示文件系統標記**。 + +### 主題 + +視窗主題包含亮色主題、暗色主題和系統主題。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **主題**,選擇一個主題。 + +### 說明 + +查看說明手冊,進一步了解和使用檔案管理器。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **說明**。 +3. 查看檔案管理器的說明手冊。 + + +### 關於 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **關於**。 +3. 查看檔案管理器的版本和介紹。 + + +### 退出 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **退出**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/e_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/e_file-manager.md new file mode 100644 index 0000000..8fd0d69 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/e_file-manager.md @@ -0,0 +1,657 @@ +# 檔案管理器|dde-file-manager| + +## 概述 + +檔案管理器是一款功能強大、簡單易用的文件管理工具。它沿用了傳統檔案管理器的經典功能和布局,並在此基礎上簡化了使用者操作,增加了很多特色功能。一目了然的導航欄、智慧識別的搜尋框、多樣化的檢視及排序讓您管理起來得心應手,經典和超越,只為給您更好的體驗! + +![1|overview](fig/eu_overview.png) + +## 使用入門 + +透過以下方式執行或關閉檔案管理器,或者建立檔案管理器的捷徑。 + +### 執行檔案管理器 + +1. 單擊桌面底部的 ![deepin_launcher ](../common/deepin_launcher.svg),進入啟動器介面。 +2. 上下滾動滑鼠滾輪瀏覽或透過搜尋找到檔案管理器![deepin_file_manager](../common/deepin_file_manager.svg),單擊執行。 +3. 右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 單擊 **建立桌面捷徑**,在桌面建立捷徑。 + - 單擊 **釘選到Dock**,將應用程式固定到Dock。 + - 單擊 **開機啟動**,將應用程式添加到開機啟動項,在電腦開機時自動執行該應用。 + +>![tips](../common/tips.svg) 竅門:您可以使用組合鍵 **Super + E** 啟動檔案管理器。 + +### 關閉檔案管理器 + +- 在檔案管理器介面,單擊 ![close_icon](../common/close_icon.svg),關閉檔案管理器。 +- 在任務欄右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),選擇 **全部關閉** 來關閉檔案管理器。 +- 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg),選擇 **離開** 來關閉檔案管理器。 + +### 查看快捷鍵 + +在檔案管理器介面上,按下**Ctrl + Shift + /** 組合鍵來查看快捷鍵,熟練的使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主介面 + +檔案管理器的主介面簡單易用、功能全面,熟練地使用介面功能將使文件管理更加簡單高效。 + +![1|main-interface](fig/maininterface.png) + + +| 標號 | 名稱 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 導航欄 | 單擊導航圖示,快速存取本機文件、磁碟、網路鄰居、書籤、標記等。 | +| 2 | 地址欄 | 透過地址欄,您可以快速切換訪問歷史、在上下級目錄間切換、搜尋、輸入地址訪問。 | +| 3 | 圖示/列表檢視 | 單擊 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg)圖示,以圖示或列表形式查看文件(夾)。 | +| 4 | 訊息欄 | 單擊 ![fileinfo](../common/fileinfo.svg), 查看文件(夾)的基本訊息和標記。 | +| 5 | 選單欄 | 透過主選單,您可以建立視窗、切換視窗主題、設定共享密碼、設定檔案管理器、查看說明文件和關於訊息、關閉檔案管理器。 | +| 6 | 狀態欄 | 顯示文件數量或者已選中文件的數量。 | + + +> ![tips](../common/tips.svg) 竅門:可拖動左側導航欄右邊的分隔線來改變其寬度。 + +## 基本功能 + +檔案管理器具備基本的文件管理功能,對文件(夾)進行新增、複製、重新命名、刪除等操作都非常簡單。 + +### 新增文件 + +#### 新增文件 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 單擊 **新增文件**。 +3. 選擇新增文件的類型。 +4. 輸入新增文件的名稱。 + +![0|newdo](fig/e_newdo.png) + +#### 新增資料夾 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 單擊 **新增資料夾**。 +3. 輸入資料夾的名稱。 + +### 重新命名文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **重新命名**。 +3. 輸入檔案名稱,按 **Enter** 鍵或者滑鼠單擊介面空白區域。 + +![0|contextmenu](fig/eu_rename.png) + +> ![tips](../common/tips.svg) 竅門:在 **設定** 中勾選「重新命名時隱藏檔案副檔名」,能更方便地修改檔案名稱。 + +### 批次重新命名 + +1. 在檔案管理器介面上,選中多個文件。 +2. 右擊文件,並選擇 **重新命名**。 + - **取代文件**尋找需要取代的文字,並輸入取代後的文字,檔案名中的關鍵字將被統一取代。 + - **加入文件** 輸入需要加入的文字,並選擇目錄是檔名之前還是之後,檔案名將統一加入被添加的文字。 + - **自訂文件** 輸入檔案名,並輸入序列的遞進數字,檔案名將統一改成新檔案名+遞進數字。 +4. 單擊 **重新命名** 來完成操作。 + +![1|rename](fig/batchrename.png) + +### 查看文件 + +單擊介面上的 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 圖示來切換圖示檢視和列表檢視。 + +- 圖示檢視:平鋪顯示文件的名稱、圖示或縮圖。 + +![1|icon-view](fig/iconview.png) + +- 列表檢視:列表顯示文件圖示或縮圖、名稱、修改時間、大小、類型等訊息。 + +![1|list-view](fig/listview.png) + +> ![tips](../common/tips.svg) 竅門:使用 **Ctrl + 1** 和 **Ctrl + 2** 快捷鍵,切換圖示檢視和列表檢視。 + + +### 排序文件 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 選擇 **排序順序**。 +3. 在子選單中選擇以檔案名稱、修改時間、大小或類型來排序文件。 + +> ![tips](../common/tips.svg) 竅門:在列表檢視中,單擊表頭欄的列標籤來切換升序、降序。 + +### 開啟文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **用其他程式開啟** > **選擇預設開啟程式**。 +3. 在程式列表中選擇應用程式。 + +> ![notes](../common/notes.svg) 說明:直接雙擊文件會使用預設程式打開。您可以選擇相同類型的多個文件,右鍵選擇「用其他程式開啟」選項,一次開啟多個文件。 + +![0|open](fig/eu_open.png) + +### 隱藏文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **屬性**,勾選 **隱藏此文件**。 + +### 複製文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 單擊 **複製**。 +3. 選擇一個目標儲存位置。 +4. 單擊滑鼠右鍵,然後選擇 **貼上**。 + +### 壓縮文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 單擊 **壓縮**。 +3. 輸入壓縮包名稱,選擇壓縮包類型和目標儲存位置。 +4. 單擊 **壓縮**。 + +> ![notes](../common/notes.svg) 說明:開啟「進階選項」 開關設定解壓密碼和分卷大小。加密文件和分卷壓縮僅支援部分壓縮格式。 + +### 刪除文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **刪除** 。 + - 被刪除的文件可以在回收桶中找到,右鍵單擊回收站中的文件可以進行 **還原** 或 **刪除** 操作。 + - 被刪除的文件的捷徑將會失效。 + +> ![attention](../common/attention.svg) 注意:外接裝置刪除文件會將文件徹底刪除,無法從回收桶找回。 + +### 復原操作 + +在檔案管理器中,可以用 **Ctrl + Z** 來復原上一步操作,包括: + +- 刪除建立的文件。 +- 復原重新命名(包括重新命名文件後綴)之前的名字。 +- 從回收站還原剛刪除的文件。 +- 復原文件到移動(剪下移動、滑鼠移動)前的原始路徑。 +- 刪除複製貼上的文件。 + +>![attention](../common/attention.svg) 注意:復原動作最多只能返回兩步;如果操作中有覆蓋某個同名文件和徹底刪除文件,則復原只能返回到這一步。 + +### 文件屬性 + +文件屬性會顯示文件的基本資訊,開啟方式和權限設定。資料夾内容會顯示資料夾的基本資訊,共用訊息和權限設定。 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **屬性**,查看文件屬性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg) 說明:查看多個文件屬性會顯示文件總大小和數量;查看捷徑的屬性將會額外顯示來源文件地址。您還可以使用 **Ctrl + I** 組合鍵查看文件屬性。 + + +## 常用操作 + +檔案管理器具備很多特色功能,這些功能都讓文件管理更加簡單、高效。 + +### 切換地址欄 + +地址欄由歷史導航、麵包屑和輸入框共同組成。通常情況下地址欄顯示麵包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 單擊歷史導航按鈕,您可以快速在歷史瀏覽記錄間切換,查看前一個地址或者後一個地址。 +- 文件所在位置的每一個層級都會形成一個麵包屑,透過來回單擊麵包屑可以快速在不同文件層級間切換。 + +當您單擊搜尋圖示,或者在文件路徑上右鍵選擇"編輯位址",地址欄會切換為輸入框狀態。在輸入框外單擊時,位址欄會自動復原到麵包屑狀態。 + +![0|addressbar](fig/addressbar2.png) + +- 輸入框帶有智慧識別功能,您可以輸入關鍵字或者訪問地址Enter,系統會自動識別並進行搜尋或訪問。 + +### 搜尋文件 + +在檔案管理器中單擊搜尋按鈕,或使用 **Ctrl + F** 快捷鍵進入搜尋狀態,或在地址欄中輸入關鍵字後按 **Enter** 鍵,搜尋相關文件。 + - 需要指定目錄搜尋時,請先進入該目錄,然後再進行搜尋。 + +> ![notes](../common/notes.svg) 說明: +> 在檔案管理器的 **設定**中,預設勾選了“自動索引內部硬碟”,您可以選擇勾選“外部裝置連上電腦時索引”,加快在外部裝置的搜尋速度。 + +#### 全文搜尋 + +您可以透過文件內容關鍵字來搜尋文件。 + +1. 在檔案管理器中,單擊 ![icon_menu](../common/icon_menu.svg) > **設定**。 +2. 在進階設定項勾選“全文搜尋”來開啟此功能。 +3. 使用組合鍵 **Ctrl + F** 或在地址欄中單擊搜尋按鈕進入搜尋狀態,輸入關鍵字後按下鍵盤上的 **Enter** 鍵,搜尋相關文件。 + +#### 進階搜尋 + +當文件較多,搜尋較慢時,啟用進階搜尋縮小搜尋範圍,提高搜尋效率。 + +1. 在搜尋狀態下,輸入關鍵字後按 **Enter** 鍵,當搜尋到結果時,搜尋框右側顯示 ![filter](../common/filter.svg) 圖示,單擊該圖示可進行進階搜尋的操作。 + +2. 選擇搜尋範圍、檔案大小、文件類型、修改時間、訪問時間和建立時間,進行更精準的搜尋。 + +![0|filter](fig/filter.png) + +### 最近使用 + +在左方面板上預設有 **最近** 入口,單擊可以查看最近使用的檔案項目。文件預設按照訪問時間倒序排列。 + + +> ![notes](../common/notes.svg) 說明:若想隱藏「最近」,可在設定 > 基本設定 > 隱藏文件,取消勾選「在左方面板顯示最近檔案項目」。若要隱藏某一個文件的訪問記錄,右擊該文件選擇 **移除**,該操作不會刪除文件。 + +### 多分頁 + +檔案管理器支援多分頁顯示。 + +1. 在檔案管理器介面上,右鍵單擊資料夾。 +2. 選擇 **在新分頁中開啟**。 +3. 當視窗有多個分頁時,可以: + - 單擊標籤欄右側的 + 繼續添加分頁。 + - 單擊標籤上的 × 關閉分頁或將滑鼠置於分頁欄上,單擊滑鼠中鍵關閉分頁。 + + ![1|tab](fig/eu_tab.png) + +> ![tips](../common/tips.svg) 竅門:檔案管理器視窗只有一個分頁時,分頁欄是隱藏的,您還可以使用快捷鍵 **Ctrl** + **T** 來建立分頁。 + +### 書籤管理 + +為常用資料夾添加書籤,以便從左側導航欄快速訪問。 + +- 添加書籤:右鍵單擊資料夾,選擇 **加到書籤** 就可以在導航欄建立書籤。 +- 移動書籤:在導航欄上下拖動書籤調整書籤排序。 +- 刪除書籤:右鍵單擊書籤,選擇 **移除** 來刪除書籤;或右鍵單擊已添加書籤的資料夾,選擇 **移除書籤** 來刪除書籤。 + +### 標記内容 + +透過給資料(夾)添加標記,可以更好地分類管理您的文件。 + +> ![notes](../common/notes.svg) 說明:目前僅x86平台支援 **標記内容** 功能。 + +#### 添加標記 + +您可以一次為多個檔案(資料夾)添加標記,一個檔案(資料夾)也可以添加多個標記;您還可以在檔案(資料夾)的屬性中添加標記。添加成功的標記會出現在左側導航欄內。 + +##### 透過編輯框添加標記 + +1. 右鍵單擊檔案(資料夾),選擇 **標記内容**。 +2. 輸入標記名稱。若要添加多個標記,用逗號分隔。 +3. 編輯完成後單擊空白處儲存設定。 + +>![notes](../common/notes.svg) 說明:標記顏色從8種預設顏色中隨機分配。 + +![1|tag info](fig/eu_taginfo.png) + + + +##### 透過顏色按鈕添加標記 + +右鍵單擊檔案(資料夾),選擇「顏色按鈕」,直接生成這個顏色的標記。 + +![1|color tag](fig/eu_colortag.png) + +##### 透過右側訊息欄添加標記 +選擇檔案(資料夾)後,單擊 ![fileinfo](../common/fileinfo.svg),在右側訊息欄中也可以添加標記。 + +![1|info tag](fig/infotag.png) + + + +>![notes](../common/notes.svg) 說明:複製或剪下有標記的文件,所產生的文件仍然具有同樣的標記。 + + +#### 重新命名標記 + +在側邊導航欄中,右鍵單擊某個標記,選擇 **重新命名**,修改目前標記的名稱。 + +![1|rename tag](fig/renametag.png) + +#### 修改標記顏色 + +在左側導航欄中,右鍵單擊某個標記,選擇「顏色按鈕」,即可修改目前標記的顏色。 + +#### 排序標記 + +上下拖動標記即可調整標記排序。 + +#### 刪除標記 + +右鍵單擊某個標記,選擇 **移除**,刪除目前標記。 + + + +### 文件預覽 + +檔案管理器支援空白鍵預覽功能,選中文件並按下鍵盤上的空白鍵就可以快速預覽文件。預覽視窗可以查看圖片解析度、檔案大小、文字內容等,還支援gif、音訊、影片播放。 + +#### 預覽影片 + +1. 選擇您要預覽的影片檔案,按下空白鍵,即可開始預覽。 +2. 單擊影片任意地方可暫停播放。 +3. 播放過程中,可以拖動進度條來快進快退。 +4. 單擊底部 **開啟** 按扭,在預設程式中開啟該影片檔案。 + +![1|video preview](fig/videopreview.png) + +> ![notes](../common/notes.svg) 說明:您也可以同時選擇多個文件,按下空白鍵進行預覽。 + + +### 權限管理 +選擇對應文件/資料夾,單擊右鍵,選擇屬性,單擊 **存取權限**, 為擁有者,群組,和其他使用者設定檔案權限。 + +![2|permission](fig/permission.png) + +### 共用資料夾 + +當您設定了共用資料夾時,「我的共用」將會出現在導航欄上。當所有共用資料夾都取消共用後,「我的共用」自動從導航欄中移除。 + +#### 共用本機文件 + +1. 在檔案管理器介面上,右鍵單擊資料夾。 +2. 選擇 **共用資料夾**。 +3. 在資料夾的屬性視窗,勾選 **共用資料夾**。 +4. 根據需要設定 **共用名稱**、**存取權限**、**匿名** 後關閉視窗。 +5. 在檔案管理器介面上,單擊 ![icon_menu](../common/icon_menu.svg) > **設定共用密碼**。 +6. 輸入共用密碼後單擊 **確定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg) 竅門:取消勾選 **共用資料夾** 可以取消文件共用,也可以右鍵單擊文件,選擇 **取消共用**。 + + +#### 訪問共用文件 + +區域網路中其他使用者共用的文件都可以在網路鄰居中找到,您也可以透過smb訪問共用文件。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **連線到伺服器**,在編輯框中輸入伺服器地址,如:smb://xx.x.xx.xxx(一般為IP位址),單擊 **連接**;或者直接在地址欄中輸入伺服器地址,按下鍵盤上的 **Enter** 鍵。 +2. 輸入使用者名稱和共用密碼。 + - 未加密的共用文件可以匿名訪問,不需要輸入使用者名稱和密碼。 + - 加密的共用文件會彈出登入框,輸入使用者名稱和密碼之後才能訪問。 + - 使用者名稱:共用者登入系統的使用者名稱。 + - 密碼:共用文件時設置的共用密碼。 +3. 單擊 **連線**。 + +![1|visitshareshare](fig/visitshare.png) + + + + + +### 從終端中開啟 + +1. 在檔案管理器介面空白處單擊滑鼠右鍵。 +2. 選擇 **開啟終端機**,會啟動終端應用程式,終端的路徑為目前目錄。 + +![0|open-terminal](fig/e_openinterminal.png) + +### 燒錄光碟 +您可以透過燒錄功能將音樂、影片、圖片或鏡像檔案複製到光碟中。請提前準備一部燒錄機、一張CD或DVD光碟。 + +1. 將光碟插入到燒錄機中。 +2. 打開檔案管理器,單擊導航欄中的光碟圖示,進入燒錄CD的介面。 + +![cd](fig/eu_cd_interface.png) + +3. 右鍵單擊 文件(夾),選擇 **添加至光碟燒錄** 或直接將文件(夾)拖曳到燒錄CD的介面。 +4. 在燒錄CD介面,單擊右上角按鈕 **燒錄**。 + + >![notes](../common/notes.svg) 說明:如果要從燒錄列表中刪除某個文件(夾),右鍵單擊該文件(夾),選擇 **刪除**,將該文件(夾)從列表中移除。 + +5. 彈出對話框,輸入光碟名稱。您也可以進入 **進階設定** 介面,設定檔案系統、寫入速度,或勾選「允許追加資料」、「核驗資料」等,單擊 **燒錄**。 + +![cd](fig/eu_cd_rename.png) + +6. 燒錄完成後介面彈出提示框,單擊 **確定**。 + +>![notes](../common/notes.svg) 說明: +> - 當前系統僅支援對ISO9660格式的文件進行讀取與燒錄,而UDF格式的文件只支援讀取,暫不支援燒錄。 +> - 如果需要擦除光碟資料,可以右鍵單擊導航欄中光碟圖示,選擇 **卸载**,再次右鍵單擊該光碟圖示並選擇 **清除**。 + + + +### 建立捷徑 + +1. 在檔案管理器介面上,右鍵單擊文件或資料夾。 +2. 選擇 **建立連結**。 +3. 在跳出視窗中選擇建立位置、連結名稱。 +4. 單擊 **儲存**,在目標位置會生成該文件(夾)的捷徑。 + +> ![tips](../common/tips.svg) 竅門:選擇 **傳送到桌面** 可以直接在桌面上生成該文件(夾)的捷徑。 + +### 傳送文件到外接磁碟 + +當有外接磁碟接入時,您可以將文件或資料夾發送到外接磁碟。 + +1. 在檔案管理器介面上,右鍵單擊文件或資料夾。 +2. 選擇 **傳送到** > 外接磁碟。 +3. 文件或資料夾將會被傳送到移動外接磁碟。 + + + + +## 文件角標 + +您可以透過命令列,將圖示文件指定給一個文件或資料夾作為角標顯示出來。 + >![icon](../common/notes.svg) 說明: + >- 角標文件支援svg、jpg、png、bmp、gif格式,且大小不超過100KB。 + >- 隨身碟及光碟下的文件,不支援添加角標。 + +### 添加單個角標 + +1. 在終端輸入指令 **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑)"** ,該指令預設在文件(夾)右下角添加角標。 + + >![icon](../common/attention.svg) 注意:系統已定義的特殊角標,不支援被取代。 + +2. 您也可以在上述指令中加入位置參數,將角標添加在文件(夾)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + +例如:在文件(夾)左上角添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑);lu"** + +![mark](fig/single.png) + +### 添加多個角標 + +在命令列中加入“**|**”符號將角標文件路徑連結起來,為文件(夾)添加2~4個角標。文件(夾)同一個位置不支援疊加角標,僅支援取代。 + +例如:在文件(夾)四個角都添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑);lu|xxx(圖示路徑);ld|xxx(圖示路徑);ru|xxx(圖示路徑);rd"** + +![mark](fig/multi.png) + +### 復原角標 + +在終端中輸入指令 **gio set xxx(文件路徑) -t stringv metadata::emblems ""** 復原文件(夾)上所有的角標。 + +## 文件保險箱 + +文件保險箱旨在為您打造專屬的安全空間,為您的隱私保駕護航。先進的加密技術,便捷的操作流程,使用起來得心應手。 + +### 設定保險箱密碼 + +首次使用保險箱需要對其進行密碼設定,具體步驟如下: + +1. 滑鼠左鍵單擊檔案管理器導航欄中 ![file_vault](../common/file_vault.svg) 圖示,或者在電腦介面雙擊 「我的保險箱」,在彈出的保險箱對話框中單擊 **建立** 按鈕。 +2. 在設定解鎖方式的對話框中設定解鎖類型、保險箱密碼、重複保險箱密碼等,單擊**下一步**。 + +![0|password](fig/password.png) + +> ![notes](../common/notes.svg) 說明: 密碼必須同時包含大寫字母、小寫字母、數字和符號,且字元不小於8位,否則無法進入下一步。 + +3. 此時保險箱密碼生成金鑰/二維碼,建議您將金鑰/二維碼儲存,若忘記密碼,可用金鑰/二維碼開啟保險箱。單擊 **下一步**。 +4. 單擊 **加密保險箱**;在彈出的認證對話框中輸入使用者登入密碼,單擊 **確定**。 +5. 在彈出的完成加密對話框中單擊 **確定** 。設定完成後可將文件放入保險箱中。 + +### 鎖定保險箱 + +將文件放入保險箱後,右鍵單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者在電腦介面右鍵單擊「我的保險箱」。 +- 選擇 **立即上鎖**,立即將文件保險箱鎖上。 +- 選擇 **自動上鎖**,在其下拉選單進行設定: + + 選擇「永不」,電腦在鎖定螢幕或關機前一直保持未上鎖狀態。 + + 選擇「5分鐘」、「10分鐘」或者「20分鐘」後自動上鎖保險箱。 + +![0|right](fig/right.png) + + +### 解鎖保險箱 + +右鍵單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者電腦介面 「我的保險箱」。 + +- 選擇 **解鎖**,在彈出的對話框中輸入保險箱密碼,單擊 **解鎖**。 +- 選擇 **金鑰解鎖**,在彈出的對話框中輸入32位金鑰,單擊 **解鎖**。 +>![0|tips](../common/tips.svg) 竅門:您也可以單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者雙擊電腦介面 「我的保險箱」,直接使用密碼解鎖保險箱。 + + +### 刪除保險箱 + +刪除保險箱需要提前解鎖保險箱。 +1. 右鍵單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者在電腦介面右鍵單擊 「我的保險箱」,選擇 **刪除保險箱**。 +2. 在彈出的刪除保險箱對話框中輸入保險箱密碼,單擊 **刪除**。 +3. 在彈出的認證對話框中輸入使用者登入密碼,單擊 **確定** 完成刪除操作。 +> ![attention](../common/attention.svg) 注意:刪除保險箱會將裡面的文件一併刪除。在進行刪除操作前,請將保險箱中的文件備份。 + +## 磁碟管理 + +檔案管理器可以管理本機和外接磁碟。 + +### 查看磁碟 + +您的本機磁碟會顯示在檔案管理器的左側導航欄上。當您掛載外接磁碟或者插入其他移動儲存裝置時,也會在導航欄上看到相應的磁碟圖示。 + + + + + + + + + + + + + + + + + +
本機磁碟本機硬碟分區的所有磁碟
外接磁碟包括行動硬碟、隨身碟、光碟
移動裝置手機記憶體、記憶卡、SD卡等
+ +> ![notes](../common/notes.svg) 說明:如果磁碟或磁碟中的資料夾被加密了,請輸入密碼後查看文件。 + +### 本機磁碟 + +#### 隱藏本機磁碟 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg) > **設定**。 +2. 在進階設定選項中勾選 **隱藏系統硬碟**。 + +#### 重新命名本機磁碟 +1. 在左側導航欄或電腦介面,右鍵單擊需要重新命名的本機磁碟。 +2. 選擇 **重新命名**。 +3. 輸入新名稱後按下鍵盤上的 **Enter** 鍵或單擊空白處儲存修改。 + +> ![tips](../common/tips.svg) 竅門:在電腦介面,慢速雙擊本機磁碟,呈現編輯框後便可進行重新命名操作。 + +![0|disk](fig/eu_rename_disk.png) + +### 外接磁碟 + +#### 彈出外接磁碟 + +1. 在左側導航欄或電腦介面,右鍵單擊需要移除的磁碟。 +2. 選擇 **安全移除**。 +3. 磁碟將從磁碟列表中刪除,一併彈出該磁碟的所有分區。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) 竅門:如果要彈出光碟,請選擇 **彈出** 來移除光碟。單擊導航欄中磁碟右邊的 ![unmount](../common/unmount_normal.svg) 同樣可以彈出磁碟或光碟。 + +#### 重新命名外接磁碟 +1. 在左側導航欄或電腦介面,右鍵單擊需要重新命名的磁碟。 +2. 選擇 **移除**後,再次單擊右鍵選擇 **重新命名**。 +3. 輸入新的卷標名稱,按下鍵盤上的 **Enter** 鍵或單擊空白處儲存修改。 + +#### 格式化外接磁碟 + +1. 在左側導航欄或電腦介面,右鍵單擊需要格式化的磁碟。 +2. 選擇 **卸载**,再次單擊右鍵選擇 **檔案格式**。 +3. 在格式化跳出視窗中設定格式化之後的文件類型和卷標。 +4. 單擊 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) 說明:快速格式化速度快,但是資料仍然可能透過工具被復原,如果想要格式化後的資料無法被復原,可以取消勾選「快速格式化」,然後執行格式化操作。 + +## 主選單 + +在主選單中,您可以新增視窗、切換視窗主題、連線到伺服器、設定共用密碼(見[共用本機文件](#共用本機文件))、設定檔案管理器、查看說明手冊和版本介紹。 + +### 新增視窗 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **新增視窗**。 + +### 連線到伺服器 + +透過連接伺服器訪問區域網路共用文件(見[訪問共用文件](#訪問共用文件))。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **連線到伺服器**,在編輯框中輸入伺服器IP位址(XX.XX.XX.XX)。 + - 單擊 ![+](../common/+.svg) 按鈕可將該地址添加到“個人收藏伺服器”列表中。 + - 在“個人收藏伺服器”列表中選中一個地址,單擊 ![_](../common/-.svg) 按鈕,將該地址從收藏列表中移除。 +3. 單擊 **連線**。 + +![conncet](fig/connect_to_server.png) + + +### 設定 + +#### 基本設定 +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **設定** 。 +2. 選擇 **基本** + + 勾選 **永遠在新視窗開啟**。 + + 設定雙擊或單擊打開文件。 + + 設定 **視窗預設開啟**、**新建分頁時開啟**哪個目錄。 + + 設定檔案圖示大小 。 + + 設定 **預設顯示** 以圖示顯示或列表展示。 + + 勾選 **顯示隱藏檔案**,檔案管理器中被隱藏的檔案會顯示出來。 + + 勾選 **重新命名時隱藏檔案副檔名**,重新命名時不會顯示副檔名。 + + 勾選 **在左方面板顯示最近檔案項目**,在左側導航欄顯示最近使用的檔案。 + +#### 進階設定 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **設定** 。 +2. 選擇 **進階** 選項。 + + 勾選 **自動索引內部硬碟**,搜尋文件時會搜尋內建磁碟中的文件。 + + 勾選 **外部装置連上電腦時索引**,搜尋文件時也會搜尋外接裝置中的文件。 + + 勾選 **全文搜尋**,透過文件中的內容來索引。 + + 勾選預覽文件類型。 + + 勾選 **自動掛載**,接入外接磁碟時自動掛載。 + + 勾選 **自動掛載後開啟**,接入外接磁碟時自動掛載並打開該磁碟。 + + 勾選 **MTP掛載路徑下顯示文件統計詳情**,MTP裝置掛載後,顯示其路徑底部的狀態欄訊息。 + + 勾選 **使用檔案管理器的選擇檔案對話框**,選擇文件時打開檔案管理器視窗。 + + 勾選 **開啟普通刪除提示**,刪除文件時彈出提示對話框。 + + 勾選 **隱藏系統硬碟**,導航欄和電腦介面將不顯示本機磁碟。 + + 勾選 **在磁碟圖標上顯示文件系統標籤**。 + +### 主題 + +視窗主題包含亮色主題、暗色主題和系統主題。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **主題**,選擇一個主題。 + +### 說明 + +查看說明手冊,進一步了解和使用檔案管理器。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **說明**。 +3. 查看檔案管理器的說明手冊。 + + +### 關於 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **關於**。 +3. 查看檔案管理器的版本和介紹。 + + +### 離開 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **離開**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/eu_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/eu_file-manager.md new file mode 100644 index 0000000..53324e0 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/eu_file-manager.md @@ -0,0 +1,656 @@ +# 檔案管理器|dde-file-manager| + +## 概述 + +檔案管理器是一款功能強大、簡單易用的文件管理工具。它沿用了傳統檔案管理器的經典功能和布局,並在此基礎上簡化了使用者操作,增加了很多特色功能。一目了然的導航欄、智慧識別的搜尋框、多樣化的檢視及排序讓您管理起來得心應手,經典和超越,只為給您更好的體驗! + +![1|overview](fig/eu_overview.png) + +## 使用入門 + +透過以下方式執行或關閉檔案管理器,或者建立檔案管理器的捷徑。 + +### 執行檔案管理器 + +1. 單擊桌面底部的 ![deepin_launcher ](../common/deepin_launcher.svg),進入啟動器介面。 +2. 上下滾動滑鼠滾輪瀏覽或透過搜尋找到檔案管理器![deepin_file_manager](../common/deepin_file_manager.svg),單擊執行。 +3. 右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 單擊 **建立桌面捷徑**,在桌面建立捷徑。 + - 單擊 **釘選到Dock**,將應用程式固定到Dock。 + - 單擊 **開機啟動**,將應用程式添加到開機啟動項,在電腦開機時自動執行該應用。 + +>![tips](../common/tips.svg) 竅門:您可以使用組合鍵 **Super + E** 啟動檔案管理器。 + +### 關閉檔案管理器 + +- 在檔案管理器介面,單擊 ![close_icon](../common/close_icon.svg),關閉檔案管理器。 +- 在任務欄右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),選擇 **全部關閉** 來關閉檔案管理器。 +- 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg),選擇 **離開** 來關閉檔案管理器。 + +### 查看快捷鍵 + +在檔案管理器介面上,按下**Ctrl + Shift + /** 組合鍵來查看快捷鍵,熟練的使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主介面 + +檔案管理器的主介面簡單易用、功能全面,熟練地使用介面功能將使文件管理更加簡單高效。 + +![1|main-interface](fig/maininterface.png) + + +| 標號 | 名稱 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 導航欄 | 單擊導航圖示,快速存取本機文件、磁碟、網路鄰居、書籤、標記等。 | +| 2 | 地址欄 | 透過地址欄,您可以快速切換訪問歷史、在上下級目錄間切換、搜尋、輸入地址訪問。 | +| 3 | 圖示/列表檢視 | 單擊 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg)圖示,以圖示或列表形式查看文件(夾)。 | +| 4 | 訊息欄 | 單擊 ![fileinfo](../common/fileinfo.svg), 查看文件(夾)的基本訊息和標記。 | +| 5 | 選單欄 | 透過主選單,您可以建立視窗、切換視窗主題、設定共享密碼、設定檔案管理器、查看說明文件和關於訊息、關閉檔案管理器。 | +| 6 | 狀態欄 | 顯示文件數量或者已選中文件的數量。 | + + +> ![tips](../common/tips.svg) 竅門:可拖動左側導航欄右邊的分隔線來改變其寬度。 + +## 基本功能 + +檔案管理器具備基本的文件管理功能,對文件(夾)進行新增、複製、重新命名、刪除等操作都非常簡單。 + +### 新增文件 + +#### 新增文件 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 單擊 **新增文件**。 +3. 選擇新增文件的類型。 +4. 輸入新增文件的名稱。 + +![0|newdo](fig/e_newdo.png) + +#### 新增資料夾 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 單擊 **新增資料夾**。 +3. 輸入資料夾的名稱。 + +### 重新命名文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **重新命名**。 +3. 輸入檔案名稱,按 **Enter** 鍵或者滑鼠單擊介面空白區域。 + +![0|contextmenu](fig/eu_rename.png) + +> ![tips](../common/tips.svg) 竅門:在 **設定** 中勾選「重新命名時隱藏檔案副檔名」,能更方便地修改檔案名稱。 + +### 批次重新命名 + +1. 在檔案管理器介面上,選中多個文件。 +2. 右擊文件,並選擇 **重新命名**。 + - **取代文件**尋找需要取代的文字,並輸入取代後的文字,檔案名中的關鍵字將被統一取代。 + - **加入文件** 輸入需要加入的文字,並選擇目錄是檔名之前還是之後,檔案名將統一加入被添加的文字。 + - **自訂文件** 輸入檔案名,並輸入序列的遞進數字,檔案名將統一改成新檔案名+遞進數字。 +4. 單擊 **重新命名** 來完成操作。 + +![1|rename](fig/batchrename.png) + +### 查看文件 + +單擊介面上的 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 圖示來切換圖示檢視和列表檢視。 + +- 圖示檢視:平鋪顯示文件的名稱、圖示或縮圖。 + +![1|icon-view](fig/iconview.png) + +- 列表檢視:列表顯示文件圖示或縮圖、名稱、修改時間、大小、類型等訊息。 + +![1|list-view](fig/listview.png) + +> ![tips](../common/tips.svg) 竅門:使用 **Ctrl + 1** 和 **Ctrl + 2** 快捷鍵,切換圖示檢視和列表檢視。 + + +### 排序文件 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 選擇 **排序順序**。 +3. 在子選單中選擇以檔案名稱、修改時間、大小或類型來排序文件。 + +> ![tips](../common/tips.svg) 竅門:在列表檢視中,單擊表頭欄的列標籤來切換升序、降序。 + +### 開啟文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **用其他程式開啟** > **選擇預設開啟程式**。 +3. 在程式列表中選擇應用程式。 + +> ![notes](../common/notes.svg) 說明:直接雙擊文件會使用預設程式打開。您可以選擇相同類型的多個文件,右鍵選擇「用其他程式開啟」選項,一次開啟多個文件。 + +![0|open](fig/eu_open.png) + +### 隱藏文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **屬性**,勾選 **隱藏此文件**。 + +### 複製文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 單擊 **複製**。 +3. 選擇一個目標儲存位置。 +4. 單擊滑鼠右鍵,然後選擇 **貼上**。 + +### 壓縮文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 單擊 **壓縮**。 +3. 輸入壓縮包名稱,選擇壓縮包類型和目標儲存位置。 +4. 單擊 **壓縮**。 + +> ![notes](../common/notes.svg) 說明:開啟「進階選項」 開關設定解壓密碼和分卷大小。加密文件和分卷壓縮僅支援部分壓縮格式。 + +### 刪除文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **刪除** 。 + - 被刪除的文件可以在回收桶中找到,右鍵單擊回收站中的文件可以進行 **還原** 或 **刪除** 操作。 + - 被刪除的文件的捷徑將會失效。 + +> ![attention](../common/attention.svg) 注意:外接裝置刪除文件會將文件徹底刪除,無法從回收桶找回。 + +### 復原操作 + +在檔案管理器中,可以用 **Ctrl + Z** 來復原上一步操作,包括: + +- 刪除建立的文件。 +- 復原重新命名(包括重新命名文件後綴)之前的名字。 +- 從回收站還原剛刪除的文件。 +- 復原文件到移動(剪下移動、滑鼠移動)前的原始路徑。 +- 刪除複製貼上的文件。 + +>![attention](../common/attention.svg) 注意:復原動作最多只能返回兩步;如果操作中有覆蓋某個同名文件和徹底刪除文件,則復原只能返回到這一步。 + +### 文件屬性 + +文件屬性會顯示文件的基本資訊,開啟方式和權限設定。資料夾内容會顯示資料夾的基本資訊,共用訊息和權限設定。 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **屬性**,查看文件屬性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg) 說明:查看多個文件屬性會顯示文件總大小和數量;查看捷徑的屬性將會額外顯示來源文件地址。您還可以使用 **Ctrl + I** 組合鍵查看文件屬性。 + + +## 常用操作 + +檔案管理器具備很多特色功能,這些功能都讓文件管理更加簡單、高效。 + +### 切換地址欄 + +地址欄由歷史導航、麵包屑和輸入框共同組成。通常情況下地址欄顯示麵包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 單擊歷史導航按鈕,您可以快速在歷史瀏覽記錄間切換,查看前一個地址或者後一個地址。 +- 文件所在位置的每一個層級都會形成一個麵包屑,透過來回單擊麵包屑可以快速在不同文件層級間切換。 + +當您單擊搜尋圖示,或者在文件路徑上右鍵選擇"編輯位址",地址欄會切換為輸入框狀態。在輸入框外單擊時,位址欄會自動復原到麵包屑狀態。 + +![0|addressbar](fig/addressbar2.png) + +- 輸入框帶有智慧識別功能,您可以輸入關鍵字或者訪問地址Enter,系統會自動識別並進行搜尋或訪問。 + +### 搜尋文件 + +在檔案管理器中單擊搜尋按鈕,或使用 **Ctrl + F** 快捷鍵進入搜尋狀態,或在地址欄中輸入關鍵字後按 **Enter** 鍵,搜尋相關文件。 + - 需要指定目錄搜尋時,請先進入該目錄,然後再進行搜尋。 + +> ![notes](../common/notes.svg) 說明: +> 在檔案管理器的 **設定**中,預設勾選了“自動索引內部硬碟”,您可以選擇勾選“外部裝置連上電腦時索引”,加快在外部裝置的搜尋速度。 + +#### 全文搜尋 + +您可以透過文件內容關鍵字來搜尋文件。 + +1. 在檔案管理器中,單擊 ![icon_menu](../common/icon_menu.svg) > **設定**。 +2. 在進階設定項勾選“全文搜尋”來開啟此功能。 +3. 使用組合鍵 **Ctrl + F** 或在地址欄中單擊搜尋按鈕進入搜尋狀態,輸入關鍵字後按下鍵盤上的 **Enter** 鍵,搜尋相關文件。 + +#### 進階搜尋 + +當文件較多,搜尋較慢時,啟用進階搜尋縮小搜尋範圍,提高搜尋效率。 + +1. 在搜尋狀態下,輸入關鍵字後按 **Enter** 鍵,當搜尋到結果時,搜尋框右側顯示 ![filter](../common/filter.svg) 圖示,單擊該圖示可進行進階搜尋的操作。 + +2. 選擇搜尋範圍、檔案大小、文件類型、修改時間、訪問時間和建立時間,進行更精準的搜尋。 + +![0|filter](fig/filter.png) + +### 最近使用 + +在左方面板上預設有 **最近** 入口,單擊可以查看最近使用的檔案項目。文件預設按照訪問時間倒序排列。 + + +> ![notes](../common/notes.svg) 說明:若想隱藏「最近」,可在設定 > 基本設定 > 隱藏文件,取消勾選「在左方面板顯示最近檔案項目」。若要隱藏某一個文件的訪問記錄,右擊該文件選擇 **移除**,該操作不會刪除文件。 + +### 多分頁 + +檔案管理器支援多分頁顯示。 + +1. 在檔案管理器介面上,右鍵單擊資料夾。 +2. 選擇 **在新分頁中開啟**。 +3. 當視窗有多個分頁時,可以: + - 單擊標籤欄右側的 + 繼續添加分頁。 + - 單擊標籤上的 × 關閉分頁或將滑鼠置於分頁欄上,單擊滑鼠中鍵關閉分頁。 + + ![1|tab](fig/eu_tab.png) + +> ![tips](../common/tips.svg) 竅門:檔案管理器視窗只有一個分頁時,分頁欄是隱藏的,您還可以使用快捷鍵 **Ctrl** + **T** 來建立分頁。 + +### 書籤管理 + +為常用資料夾添加書籤,以便從左側導航欄快速訪問。 + +- 添加書籤:右鍵單擊資料夾,選擇 **加到書籤** 就可以在導航欄建立書籤。 +- 移動書籤:在導航欄上下拖動書籤調整書籤排序。 +- 刪除書籤:右鍵單擊書籤,選擇 **移除** 來刪除書籤;或右鍵單擊已添加書籤的資料夾,選擇 **移除書籤** 來刪除書籤。 + +### 標記内容 + +透過給資料(夾)添加標記,可以更好地分類管理您的文件。 + +> ![notes](../common/notes.svg) 說明:目前僅x86平台支援 **標記内容** 功能。 + +#### 添加標記 + +您可以一次為多個檔案(資料夾)添加標記,一個檔案(資料夾)也可以添加多個標記;您還可以在檔案(資料夾)的屬性中添加標記。添加成功的標記會出現在左側導航欄內。 + +##### 透過編輯框添加標記 + +1. 右鍵單擊檔案(資料夾),選擇 **標記内容**。 +2. 輸入標記名稱。若要添加多個標記,用逗號分隔。 +3. 編輯完成後單擊空白處儲存設定。 + +>![notes](../common/notes.svg) 說明:標記顏色從8種預設顏色中隨機分配。 + +![1|tag info](fig/eu_taginfo.png) + + + +##### 透過顏色按鈕添加標記 + +右鍵單擊檔案(資料夾),選擇「顏色按鈕」,直接生成這個顏色的標記。 + +![1|color tag](fig/eu_colortag.png) + +##### 透過右側訊息欄添加標記 +選擇檔案(資料夾)後,單擊 ![fileinfo](../common/fileinfo.svg),在右側訊息欄中也可以添加標記。 + +![1|info tag](fig/infotag.png) + + + +>![notes](../common/notes.svg) 說明:複製或剪下有標記的文件,所產生的文件仍然具有同樣的標記。 + + +#### 重新命名標記 + +在側邊導航欄中,右鍵單擊某個標記,選擇 **重新命名**,修改目前標記的名稱。 + +![1|rename tag](fig/renametag.png) + +#### 修改標記顏色 + +在左側導航欄中,右鍵單擊某個標記,選擇「顏色按鈕」,即可修改目前標記的顏色。 + +#### 排序標記 + +上下拖動標記即可調整標記排序。 + +#### 刪除標記 + +右鍵單擊某個標記,選擇 **移除**,刪除目前標記。 + + + +### 文件預覽 + +檔案管理器支援空白鍵預覽功能,選中文件並按下鍵盤上的空白鍵就可以快速預覽文件。預覽視窗可以查看圖片解析度、檔案大小、文字內容等,還支援gif、音訊、影片播放。 + +#### 預覽影片 + +1. 選擇您要預覽的影片檔案,按下空白鍵,即可開始預覽。 +2. 單擊影片任意地方可暫停播放。 +3. 播放過程中,可以拖動進度條來快進快退。 +4. 單擊底部 **開啟** 按扭,在預設程式中開啟該影片檔案。 + +![1|video preview](fig/videopreview.png) + +> ![notes](../common/notes.svg) 說明:您也可以同時選擇多個文件,按下空白鍵進行預覽。 + + +### 權限管理 +選擇對應文件/資料夾,單擊右鍵,選擇屬性,單擊 **存取權限**, 為擁有者,群組,和其他使用者設定檔案權限。 + +![2|permission](fig/permission.png) + +### 共用資料夾 + +當您設定了共用資料夾時,「我的共用」將會出現在導航欄上。當所有共用資料夾都取消共用後,「我的共用」自動從導航欄中移除。 + +#### 共用本機文件 + +1. 在檔案管理器介面上,右鍵單擊資料夾。 +2. 選擇 **共用資料夾**。 +3. 在資料夾的屬性視窗,勾選 **共用資料夾**。 +4. 根據需要設定 **共用名稱**、**存取權限**、**匿名** 後關閉視窗。 +5. 在檔案管理器介面上,單擊 ![icon_menu](../common/icon_menu.svg) > **設定共用密碼**。 +6. 輸入共用密碼後單擊 **確定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg) 竅門:取消勾選 **共用資料夾** 可以取消文件共用,也可以右鍵單擊文件,選擇 **取消共用**。 + + +#### 訪問共用文件 + +區域網路中其他使用者共用的文件都可以在網路鄰居中找到,您也可以透過smb訪問共用文件。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **連線到伺服器**,在編輯框中輸入伺服器地址,如:smb://xx.x.xx.xxx(一般為IP位址),單擊 **連接**;或者直接在地址欄中輸入伺服器地址,按下鍵盤上的 **Enter** 鍵。 +2. 輸入使用者名稱和共用密碼。 + - 未加密的共用文件可以匿名訪問,不需要輸入使用者名稱和密碼。 + - 加密的共用文件會彈出登入框,輸入使用者名稱和密碼之後才能訪問。 + - 使用者名稱:共用者登入系統的使用者名稱。 + - 密碼:共用文件時設置的共用密碼。 +3. 單擊 **連線**。 + +![1|visitshareshare](fig/visitshare.png) + + + + + +### 從終端中開啟 + +1. 在檔案管理器介面空白處單擊滑鼠右鍵。 +2. 選擇 **開啟終端機**,會啟動終端應用程式,終端的路徑為目前目錄。 + +![0|open-terminal](fig/e_openinterminal.png) + +### 燒錄光碟 +您可以透過燒錄功能將音樂、影片、圖片或鏡像檔案複製到光碟中。請提前準備一部燒錄機、一張CD或DVD光碟。 + +1. 將光碟插入到燒錄機中。 +2. 打開檔案管理器,單擊導航欄中的光碟圖示,進入燒錄CD的介面。 + +![cd](fig/eu_cd_interface.png) + +3. 右鍵單擊 文件(夾),選擇 **添加至光碟燒錄** 或直接將文件(夾)拖曳到燒錄CD的介面。 +4. 在燒錄CD介面,單擊右上角按鈕 **燒錄**。 + + >![notes](../common/notes.svg) 說明:如果要從燒錄列表中刪除某個文件(夾),右鍵單擊該文件(夾),選擇 **刪除**,將該文件(夾)從列表中移除。 + +5. 彈出對話框,輸入光碟名稱。您也可以進入 **進階設定** 介面,設定檔案系統、寫入速度,或勾選「允許追加資料」、「核驗資料」等,單擊 **燒錄**。 + +![cd](fig/eu_cd_rename.png) + +6. 燒錄完成後介面彈出提示框,單擊 **確定**。 + +>![notes](../common/notes.svg) 說明: +> - 當前系統僅支援對ISO9660格式的文件進行讀取與燒錄,而UDF格式的文件只支援讀取,暫不支援燒錄。 +> - 如果需要擦除光碟資料,可以右鍵單擊導航欄中光碟圖示,選擇 **卸载**,再次右鍵單擊該光碟圖示並選擇 **清除**。 + + + +### 建立捷徑 + +1. 在檔案管理器介面上,右鍵單擊文件或資料夾。 +2. 選擇 **建立連結**。 +3. 在跳出視窗中選擇建立位置、連結名稱。 +4. 單擊 **儲存**,在目標位置會生成該文件(夾)的捷徑。 + +> ![tips](../common/tips.svg) 竅門:選擇 **傳送到桌面** 可以直接在桌面上生成該文件(夾)的捷徑。 + +### 傳送文件到外接磁碟 + +當有外接磁碟接入時,您可以將文件或資料夾發送到外接磁碟。 + +1. 在檔案管理器介面上,右鍵單擊文件或資料夾。 +2. 選擇 **傳送到** > 外接磁碟。 +3. 文件或資料夾將會被傳送到移動外接磁碟。 + + + + +## 文件角標 + +您可以透過命令列,將圖示文件指定給一個文件或資料夾作為角標顯示出來。 + >![icon](../common/notes.svg) 說明: + >- 角標文件支援svg、jpg、png、bmp、gif格式,且大小不超過100KB。 + >- 隨身碟及光碟下的文件,不支援添加角標。 + +### 添加單個角標 + +1. 在終端輸入指令 **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑)"** ,該指令預設在文件(夾)右下角添加角標。 + + >![icon](../common/attention.svg) 注意:系統已定義的特殊角標,不支援被取代。 + +2. 您也可以在上述指令中加入位置參數,將角標添加在文件(夾)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + +例如:在文件(夾)左上角添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑);lu"** + +![mark](fig/single.png) + +### 添加多個角標 + +在命令列中加入“**|**”符號將角標文件路徑連結起來,為文件(夾)添加2~4個角標。文件(夾)同一個位置不支援疊加角標,僅支援取代。 + +例如:在文件(夾)四個角都添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑);lu|xxx(圖示路徑);ld|xxx(圖示路徑);ru|xxx(圖示路徑);rd"** + +![mark](fig/multi.png) + +### 復原角標 + +在終端中輸入指令 **gio set xxx(文件路徑) -t stringv metadata::emblems ""** 復原文件(夾)上所有的角標。 + +## 文件保險箱 + +文件保險箱旨在為您打造專屬的安全空間,為您的隱私保駕護航。先進的加密技術,便捷的操作流程,使用起來得心應手。 + +### 設定保險箱密碼 + +首次使用保險箱需要對其進行密碼設定,具體步驟如下: + +1. 滑鼠左鍵單擊檔案管理器導航欄中 ![file_vault](../common/file_vault.svg) 圖示,或者在電腦介面雙擊 「我的保險箱」,在彈出的保險箱對話框中單擊 **建立** 按鈕。 +2. 在設定解鎖方式的對話框中設定解鎖類型、保險箱密碼、重複保險箱密碼等,單擊**下一步**。 + +![0|password](fig/password.png) + +> ![notes](../common/notes.svg) 說明: 密碼必須同時包含大寫字母、小寫字母、數字和符號,且字元不小於8位,否則無法進入下一步。 + +3. 此時保險箱密碼生成金鑰/二維碼,建議您將金鑰/二維碼儲存,若忘記密碼,可用金鑰/二維碼開啟保險箱。單擊 **下一步**。 +4. 單擊 **加密保險箱**;在彈出的認證對話框中輸入使用者登入密碼,單擊 **確定**。 +5. 在彈出的完成加密對話框中單擊 **確定** 。設定完成後可將文件放入保險箱中。 + +### 鎖定保險箱 + +將文件放入保險箱後,右鍵單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者在電腦介面右鍵單擊「我的保險箱」。 +- 選擇 **立即上鎖**,立即將文件保險箱鎖上。 +- 選擇 **自動上鎖**,在其下拉選單進行設定: + + 選擇「永不」,電腦在鎖定螢幕或關機前一直保持未上鎖狀態。 + + 選擇「5分鐘」、「10分鐘」或者「20分鐘」後自動上鎖保險箱。 + +![0|right](fig/right.png) + + +### 解鎖保險箱 + +右鍵單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者電腦介面 「我的保險箱」。 + +- 選擇 **解鎖**,在彈出的對話框中輸入保險箱密碼,單擊 **解鎖**。 +- 選擇 **金鑰解鎖**,在彈出的對話框中輸入32位金鑰,單擊 **解鎖**。 +>![0|tips](../common/tips.svg) 竅門:您也可以單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者雙擊電腦介面 「我的保險箱」,直接使用密碼解鎖保險箱。 + + +### 刪除保險箱 + +刪除保險箱需要提前解鎖保險箱。 +1. 右鍵單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者在電腦介面右鍵單擊 「我的保險箱」,選擇 **刪除保險箱**。 +2. 在彈出的刪除保險箱對話框中輸入保險箱密碼,單擊 **刪除**。 +3. 在彈出的認證對話框中輸入使用者登入密碼,單擊 **確定** 完成刪除操作。 +> ![attention](../common/attention.svg) 注意:刪除保險箱會將裡面的文件一併刪除。在進行刪除操作前,請將保險箱中的文件備份。 + +## 磁碟管理 + +檔案管理器可以管理本機和外接磁碟。 + +### 查看磁碟 + +您的本機磁碟會顯示在檔案管理器的左側導航欄上。當您掛載外接磁碟或者插入其他移動儲存裝置時,也會在導航欄上看到相應的磁碟圖示。 + + + + + + + + + + + + + + + + + +
本機磁碟本機硬碟分區的所有磁碟
外接磁碟包括行動硬碟、隨身碟、光碟
移動裝置手機記憶體、記憶卡、SD卡等
+ +> ![notes](../common/notes.svg) 說明:如果磁碟或磁碟中的資料夾被加密了,請輸入密碼後查看文件。 + +### 本機磁碟 + +#### 隱藏本機磁碟 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg) > **設定**。 +2. 在進階設定選項中勾選 **隱藏系統硬碟**。 + +#### 重新命名本機磁碟 +1. 在左側導航欄或電腦介面,右鍵單擊需要重新命名的本機磁碟。 +2. 選擇 **重新命名**。 +3. 輸入新名稱後按下鍵盤上的 **Enter** 鍵或單擊空白處儲存修改。 + +> ![tips](../common/tips.svg) 竅門:在電腦介面,慢速雙擊本機磁碟,呈現編輯框後便可進行重新命名操作。 + +![0|disk](fig/eu_rename_disk.png) + +### 外接磁碟 + +#### 彈出外接磁碟 + +1. 在左側導航欄或電腦介面,右鍵單擊需要移除的磁碟。 +2. 選擇 **安全移除**。 +3. 磁碟將從磁碟列表中刪除,一併彈出該磁碟的所有分區。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) 竅門:如果要彈出光碟,請選擇 **彈出** 來移除光碟。單擊導航欄中磁碟右邊的 ![unmount](../common/unmount_normal.svg) 同樣可以彈出磁碟或光碟。 + +#### 重新命名外接磁碟 +1. 在左側導航欄或電腦介面,右鍵單擊需要重新命名的磁碟。 +2. 選擇 **移除**後,再次單擊右鍵選擇 **重新命名**。 +3. 輸入新的卷標名稱,按下鍵盤上的 **Enter** 鍵或單擊空白處儲存修改。 + +#### 格式化外接磁碟 + +1. 在左側導航欄或電腦介面,右鍵單擊需要格式化的磁碟。 +2. 選擇 **卸载**,再次單擊右鍵選擇 **檔案格式**。 +3. 在格式化跳出視窗中設定格式化之後的文件類型和卷標。 +4. 單擊 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) 說明:快速格式化速度快,但是資料仍然可能透過工具被復原,如果想要格式化後的資料無法被復原,可以取消勾選「快速格式化」,然後執行格式化操作。 + +## 主選單 + +在主選單中,您可以新增視窗、切換視窗主題、連線到伺服器、設定共用密碼(見[共用本機文件](#共用本機文件))、設定檔案管理器、查看說明手冊和版本介紹。 + +### 新增視窗 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **新增視窗**。 + +### 連線到伺服器 + +透過連接伺服器訪問區域網路共用文件(見[訪問共用文件](#訪問共用文件))。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **連線到伺服器**,在編輯框中輸入伺服器IP位址(XX.XX.XX.XX)。 + - 單擊 ![+](../common/+.svg) 按鈕可將該地址添加到“個人收藏伺服器”列表中。 + - 在“個人收藏伺服器”列表中選中一個地址,單擊 ![_](../common/-.svg) 按鈕,將該地址從收藏列表中移除。 +3. 單擊 **連線**。 + +![conncet](fig/connect_to_server.png) + + +### 設定 + +#### 基本設定 +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **設定** 。 +2. 選擇 **基本** + + 勾選 **永遠在新視窗開啟**。 + + 設定雙擊或單擊打開文件。 + + 設定 **視窗預設開啟**、**新建分頁時開啟**哪個目錄。 + + 設定檔案圖示大小 。 + + 設定 **預設顯示** 以圖示顯示或列表展示。 + + 勾選 **顯示隱藏檔案**,檔案管理器中被隱藏的檔案會顯示出來。 + + 勾選 **重新命名時隱藏檔案副檔名**,重新命名時不會顯示副檔名。 + + 勾選 **在左方面板顯示最近檔案項目**,在左側導航欄顯示最近使用的檔案。 + +#### 進階設定 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **設定** 。 +2. 選擇 **進階** 選項。 + + 勾選 **自動索引內部硬碟**,搜尋文件時會搜尋內建磁碟中的文件。 + + 勾選 **外部装置連上電腦時索引**,搜尋文件時也會搜尋外接裝置中的文件。 + + 勾選 **全文搜尋**,透過文件中的內容來索引。 + + 勾選預覽文件類型。 + + 勾選 **自動掛載**,接入外接磁碟時自動掛載。 + + 勾選 **自動掛載後開啟**,接入外接磁碟時自動掛載並打開該磁碟。 + + 勾選 **使用檔案管理器的選擇檔案對話框**,選擇文件時打開檔案管理器視窗。 + + 勾選 **開啟普通刪除提示**,刪除文件時彈出提示對話框。 + + 勾選 **隱藏系統硬碟**,導航欄和電腦介面將不顯示本機磁碟。 + + 勾選 **在磁碟圖標上顯示文件系統標籤**。 + +### 主題 + +視窗主題包含亮色主題、暗色主題和系統主題。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **主題**,選擇一個主題。 + +### 說明 + +查看說明手冊,進一步了解和使用檔案管理器。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **說明**。 +3. 查看檔案管理器的說明手冊。 + + +### 關於 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **關於**。 +3. 查看檔案管理器的版本和介紹。 + + +### 離開 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **離開**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/Screen Capture_dde-file-manager_20200923094019.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/Screen Capture_dde-file-manager_20200923094019.png new file mode 100644 index 0000000..feed66e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/Screen Capture_dde-file-manager_20200923094019.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/addressbar1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/addressbar1.png new file mode 100644 index 0000000..5984a0c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/addressbar1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/addressbar2.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/addressbar2.png new file mode 100644 index 0000000..afc1b01 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/addressbar2.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/batchrename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/batchrename.png new file mode 100644 index 0000000..b9ec5d1 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/batchrename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/cd_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/cd_interface.png new file mode 100644 index 0000000..19a23f3 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/cd_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/cd_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/cd_rename.png new file mode 100644 index 0000000..3f830d3 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/cd_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/colortag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/colortag.png new file mode 100644 index 0000000..66b1ec2 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/colortag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/connect_to_server.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/connect_to_server.png new file mode 100644 index 0000000..6dec591 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/connect_to_server.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/contextmenu.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/contextmenu.png new file mode 100644 index 0000000..d0bc243 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/contextmenu.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_batchrename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_batchrename.png new file mode 100644 index 0000000..8ace72a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_batchrename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_cd_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_cd_interface.png new file mode 100644 index 0000000..f04acc0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_cd_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_cd_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_cd_rename.png new file mode 100644 index 0000000..5ed59f6 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_cd_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_colortag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_colortag.png new file mode 100644 index 0000000..40cc3e6 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_colortag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_contextmenu.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_contextmenu.png new file mode 100644 index 0000000..4982edd Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_contextmenu.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_filter.png new file mode 100644 index 0000000..394b89d Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_iconview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_iconview.png new file mode 100644 index 0000000..d059274 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_iconview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_infotag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_infotag.png new file mode 100644 index 0000000..6e5f191 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_infotag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_listview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_listview.png new file mode 100644 index 0000000..f677e8a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_listview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_maininterface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_maininterface.png new file mode 100644 index 0000000..0d8436d Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_maininterface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_open.png new file mode 100644 index 0000000..5f5bb36 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_overview.png new file mode 100644 index 0000000..2b8d48b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_rename.png new file mode 100644 index 0000000..a0fac9a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_rename_disk.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_rename_disk.png new file mode 100644 index 0000000..caf5209 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_rename_disk.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_tab.png new file mode 100644 index 0000000..e06f9f5 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_taginfo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_taginfo.png new file mode 100644 index 0000000..40feb11 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/d_taginfo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/disk1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/disk1.png new file mode 100644 index 0000000..c0b7f1d Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/disk1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/disk2.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/disk2.png new file mode 100644 index 0000000..614e56a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/disk2.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/e_newdo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/e_newdo.png new file mode 100644 index 0000000..f28fa26 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/e_newdo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/e_openinterminal.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/e_openinterminal.png new file mode 100644 index 0000000..3b5197e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/e_openinterminal.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/e_share.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/e_share.png new file mode 100644 index 0000000..15653b4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/e_share.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/encrypt.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/encrypt.png new file mode 100644 index 0000000..11d1209 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/encrypt.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/encrypt01.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/encrypt01.png new file mode 100644 index 0000000..45fc2d7 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/encrypt01.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_cd_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_cd_interface.png new file mode 100644 index 0000000..1f13fa7 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_cd_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_cd_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_cd_rename.png new file mode 100644 index 0000000..35eee1e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_cd_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_colortag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_colortag.png new file mode 100644 index 0000000..9f0bab4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_colortag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_open.png new file mode 100644 index 0000000..5ed5c59 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_overview.png new file mode 100644 index 0000000..724d6aa Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_rename.png new file mode 100644 index 0000000..e550de7 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_rename_disk.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_rename_disk.png new file mode 100644 index 0000000..2268a86 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_rename_disk.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_share.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_share.png new file mode 100644 index 0000000..15653b4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_share.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_tab.png new file mode 100644 index 0000000..a7a50a6 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_taginfo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_taginfo.png new file mode 100644 index 0000000..9f94ff4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eu_taginfo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eye.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eye.png new file mode 100644 index 0000000..3924c40 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/eye.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/filter.png new file mode 100644 index 0000000..365d99e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/finish.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/finish.png new file mode 100644 index 0000000..8835f68 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/finish.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/hotkey.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/hotkey.png new file mode 100644 index 0000000..d1896d4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/hotkey.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/iconview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/iconview.png new file mode 100644 index 0000000..f120e46 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/iconview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/info.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/info.png new file mode 100644 index 0000000..d4eb2cb Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/info.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/infotag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/infotag.png new file mode 100644 index 0000000..6f825b2 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/infotag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/key.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/key.png new file mode 100644 index 0000000..03aa6b0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/key.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/listview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/listview.png new file mode 100644 index 0000000..e74c873 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/listview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/maininterface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/maininterface.png new file mode 100644 index 0000000..f41f59c Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/maininterface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/multi.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/multi.png new file mode 100644 index 0000000..e145b3e Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/multi.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/myphone.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/myphone.png new file mode 100644 index 0000000..2ee6ae0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/myphone.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/myphone1.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/myphone1.png new file mode 100644 index 0000000..e3c89da Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/myphone1.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/newdo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/newdo.png new file mode 100644 index 0000000..c4e2700 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/newdo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/open.png new file mode 100644 index 0000000..f370906 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/openfile.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/openfile.png new file mode 100644 index 0000000..9763014 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/openfile.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/openinterminal.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/openinterminal.png new file mode 100644 index 0000000..2e90d05 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/openinterminal.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_batchrename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_batchrename.png new file mode 100644 index 0000000..db20ea8 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_batchrename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_colortag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_colortag.png new file mode 100644 index 0000000..2a5e12a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_colortag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_contextmenu.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_contextmenu.png new file mode 100644 index 0000000..c1a0dfd Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_contextmenu.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_filter.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_filter.png new file mode 100644 index 0000000..fd79ab1 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_filter.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_iconview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_iconview.png new file mode 100644 index 0000000..0dc5200 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_iconview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_infotag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_infotag.png new file mode 100644 index 0000000..edcf64b Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_infotag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_listview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_listview.png new file mode 100644 index 0000000..94d5942 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_listview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_maininterface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_maininterface.png new file mode 100644 index 0000000..d6f45ac Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_maininterface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_maininterface.psd b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_maininterface.psd new file mode 100644 index 0000000..b949ec0 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_maininterface.psd differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_open.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_open.png new file mode 100644 index 0000000..ced0712 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_open.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_overview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_overview.png new file mode 100644 index 0000000..3da951a Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_overview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_rename_disk.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_rename_disk.png new file mode 100644 index 0000000..bdd0d27 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_rename_disk.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_tab.png new file mode 100644 index 0000000..6f6b335 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_taginfo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_taginfo.png new file mode 100644 index 0000000..bc67340 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/p_taginfo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/password.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/password.png new file mode 100644 index 0000000..9fc7584 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/password.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/permission.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/permission.png new file mode 100644 index 0000000..f5c6a86 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/permission.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/phone_interface.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/phone_interface.png new file mode 100644 index 0000000..03ba16d Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/phone_interface.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/rename.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/rename.png new file mode 100644 index 0000000..17e9c03 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/rename.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/renametag.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/renametag.png new file mode 100644 index 0000000..f4c1f13 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/renametag.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/right.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/right.png new file mode 100644 index 0000000..7aaf5ef Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/right.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/save.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/save.png new file mode 100644 index 0000000..96246b7 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/save.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/share.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/share.png new file mode 100644 index 0000000..15653b4 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/share.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/share_copy.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/share_copy.png new file mode 100644 index 0000000..d754a0f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/share_copy.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/single.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/single.png new file mode 100644 index 0000000..e3111a1 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/single.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/tab.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/tab.png new file mode 100644 index 0000000..d2a8680 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/tab.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/taginfo.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/taginfo.png new file mode 100644 index 0000000..636d01f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/taginfo.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/unlock.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/unlock.png new file mode 100644 index 0000000..d6deb7f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/unlock.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/videopreview.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/videopreview.png new file mode 100644 index 0000000..5dd6585 Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/videopreview.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/visitshare.png b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/visitshare.png new file mode 100644 index 0000000..7e9f04f Binary files /dev/null and b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/fig/visitshare.png differ diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/i_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/i_file-manager.md new file mode 100644 index 0000000..53324e0 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/i_file-manager.md @@ -0,0 +1,656 @@ +# 檔案管理器|dde-file-manager| + +## 概述 + +檔案管理器是一款功能強大、簡單易用的文件管理工具。它沿用了傳統檔案管理器的經典功能和布局,並在此基礎上簡化了使用者操作,增加了很多特色功能。一目了然的導航欄、智慧識別的搜尋框、多樣化的檢視及排序讓您管理起來得心應手,經典和超越,只為給您更好的體驗! + +![1|overview](fig/eu_overview.png) + +## 使用入門 + +透過以下方式執行或關閉檔案管理器,或者建立檔案管理器的捷徑。 + +### 執行檔案管理器 + +1. 單擊桌面底部的 ![deepin_launcher ](../common/deepin_launcher.svg),進入啟動器介面。 +2. 上下滾動滑鼠滾輪瀏覽或透過搜尋找到檔案管理器![deepin_file_manager](../common/deepin_file_manager.svg),單擊執行。 +3. 右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 單擊 **建立桌面捷徑**,在桌面建立捷徑。 + - 單擊 **釘選到Dock**,將應用程式固定到Dock。 + - 單擊 **開機啟動**,將應用程式添加到開機啟動項,在電腦開機時自動執行該應用。 + +>![tips](../common/tips.svg) 竅門:您可以使用組合鍵 **Super + E** 啟動檔案管理器。 + +### 關閉檔案管理器 + +- 在檔案管理器介面,單擊 ![close_icon](../common/close_icon.svg),關閉檔案管理器。 +- 在任務欄右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),選擇 **全部關閉** 來關閉檔案管理器。 +- 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg),選擇 **離開** 來關閉檔案管理器。 + +### 查看快捷鍵 + +在檔案管理器介面上,按下**Ctrl + Shift + /** 組合鍵來查看快捷鍵,熟練的使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主介面 + +檔案管理器的主介面簡單易用、功能全面,熟練地使用介面功能將使文件管理更加簡單高效。 + +![1|main-interface](fig/maininterface.png) + + +| 標號 | 名稱 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 導航欄 | 單擊導航圖示,快速存取本機文件、磁碟、網路鄰居、書籤、標記等。 | +| 2 | 地址欄 | 透過地址欄,您可以快速切換訪問歷史、在上下級目錄間切換、搜尋、輸入地址訪問。 | +| 3 | 圖示/列表檢視 | 單擊 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg)圖示,以圖示或列表形式查看文件(夾)。 | +| 4 | 訊息欄 | 單擊 ![fileinfo](../common/fileinfo.svg), 查看文件(夾)的基本訊息和標記。 | +| 5 | 選單欄 | 透過主選單,您可以建立視窗、切換視窗主題、設定共享密碼、設定檔案管理器、查看說明文件和關於訊息、關閉檔案管理器。 | +| 6 | 狀態欄 | 顯示文件數量或者已選中文件的數量。 | + + +> ![tips](../common/tips.svg) 竅門:可拖動左側導航欄右邊的分隔線來改變其寬度。 + +## 基本功能 + +檔案管理器具備基本的文件管理功能,對文件(夾)進行新增、複製、重新命名、刪除等操作都非常簡單。 + +### 新增文件 + +#### 新增文件 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 單擊 **新增文件**。 +3. 選擇新增文件的類型。 +4. 輸入新增文件的名稱。 + +![0|newdo](fig/e_newdo.png) + +#### 新增資料夾 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 單擊 **新增資料夾**。 +3. 輸入資料夾的名稱。 + +### 重新命名文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **重新命名**。 +3. 輸入檔案名稱,按 **Enter** 鍵或者滑鼠單擊介面空白區域。 + +![0|contextmenu](fig/eu_rename.png) + +> ![tips](../common/tips.svg) 竅門:在 **設定** 中勾選「重新命名時隱藏檔案副檔名」,能更方便地修改檔案名稱。 + +### 批次重新命名 + +1. 在檔案管理器介面上,選中多個文件。 +2. 右擊文件,並選擇 **重新命名**。 + - **取代文件**尋找需要取代的文字,並輸入取代後的文字,檔案名中的關鍵字將被統一取代。 + - **加入文件** 輸入需要加入的文字,並選擇目錄是檔名之前還是之後,檔案名將統一加入被添加的文字。 + - **自訂文件** 輸入檔案名,並輸入序列的遞進數字,檔案名將統一改成新檔案名+遞進數字。 +4. 單擊 **重新命名** 來完成操作。 + +![1|rename](fig/batchrename.png) + +### 查看文件 + +單擊介面上的 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 圖示來切換圖示檢視和列表檢視。 + +- 圖示檢視:平鋪顯示文件的名稱、圖示或縮圖。 + +![1|icon-view](fig/iconview.png) + +- 列表檢視:列表顯示文件圖示或縮圖、名稱、修改時間、大小、類型等訊息。 + +![1|list-view](fig/listview.png) + +> ![tips](../common/tips.svg) 竅門:使用 **Ctrl + 1** 和 **Ctrl + 2** 快捷鍵,切換圖示檢視和列表檢視。 + + +### 排序文件 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 選擇 **排序順序**。 +3. 在子選單中選擇以檔案名稱、修改時間、大小或類型來排序文件。 + +> ![tips](../common/tips.svg) 竅門:在列表檢視中,單擊表頭欄的列標籤來切換升序、降序。 + +### 開啟文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **用其他程式開啟** > **選擇預設開啟程式**。 +3. 在程式列表中選擇應用程式。 + +> ![notes](../common/notes.svg) 說明:直接雙擊文件會使用預設程式打開。您可以選擇相同類型的多個文件,右鍵選擇「用其他程式開啟」選項,一次開啟多個文件。 + +![0|open](fig/eu_open.png) + +### 隱藏文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **屬性**,勾選 **隱藏此文件**。 + +### 複製文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 單擊 **複製**。 +3. 選擇一個目標儲存位置。 +4. 單擊滑鼠右鍵,然後選擇 **貼上**。 + +### 壓縮文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 單擊 **壓縮**。 +3. 輸入壓縮包名稱,選擇壓縮包類型和目標儲存位置。 +4. 單擊 **壓縮**。 + +> ![notes](../common/notes.svg) 說明:開啟「進階選項」 開關設定解壓密碼和分卷大小。加密文件和分卷壓縮僅支援部分壓縮格式。 + +### 刪除文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **刪除** 。 + - 被刪除的文件可以在回收桶中找到,右鍵單擊回收站中的文件可以進行 **還原** 或 **刪除** 操作。 + - 被刪除的文件的捷徑將會失效。 + +> ![attention](../common/attention.svg) 注意:外接裝置刪除文件會將文件徹底刪除,無法從回收桶找回。 + +### 復原操作 + +在檔案管理器中,可以用 **Ctrl + Z** 來復原上一步操作,包括: + +- 刪除建立的文件。 +- 復原重新命名(包括重新命名文件後綴)之前的名字。 +- 從回收站還原剛刪除的文件。 +- 復原文件到移動(剪下移動、滑鼠移動)前的原始路徑。 +- 刪除複製貼上的文件。 + +>![attention](../common/attention.svg) 注意:復原動作最多只能返回兩步;如果操作中有覆蓋某個同名文件和徹底刪除文件,則復原只能返回到這一步。 + +### 文件屬性 + +文件屬性會顯示文件的基本資訊,開啟方式和權限設定。資料夾内容會顯示資料夾的基本資訊,共用訊息和權限設定。 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **屬性**,查看文件屬性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg) 說明:查看多個文件屬性會顯示文件總大小和數量;查看捷徑的屬性將會額外顯示來源文件地址。您還可以使用 **Ctrl + I** 組合鍵查看文件屬性。 + + +## 常用操作 + +檔案管理器具備很多特色功能,這些功能都讓文件管理更加簡單、高效。 + +### 切換地址欄 + +地址欄由歷史導航、麵包屑和輸入框共同組成。通常情況下地址欄顯示麵包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 單擊歷史導航按鈕,您可以快速在歷史瀏覽記錄間切換,查看前一個地址或者後一個地址。 +- 文件所在位置的每一個層級都會形成一個麵包屑,透過來回單擊麵包屑可以快速在不同文件層級間切換。 + +當您單擊搜尋圖示,或者在文件路徑上右鍵選擇"編輯位址",地址欄會切換為輸入框狀態。在輸入框外單擊時,位址欄會自動復原到麵包屑狀態。 + +![0|addressbar](fig/addressbar2.png) + +- 輸入框帶有智慧識別功能,您可以輸入關鍵字或者訪問地址Enter,系統會自動識別並進行搜尋或訪問。 + +### 搜尋文件 + +在檔案管理器中單擊搜尋按鈕,或使用 **Ctrl + F** 快捷鍵進入搜尋狀態,或在地址欄中輸入關鍵字後按 **Enter** 鍵,搜尋相關文件。 + - 需要指定目錄搜尋時,請先進入該目錄,然後再進行搜尋。 + +> ![notes](../common/notes.svg) 說明: +> 在檔案管理器的 **設定**中,預設勾選了“自動索引內部硬碟”,您可以選擇勾選“外部裝置連上電腦時索引”,加快在外部裝置的搜尋速度。 + +#### 全文搜尋 + +您可以透過文件內容關鍵字來搜尋文件。 + +1. 在檔案管理器中,單擊 ![icon_menu](../common/icon_menu.svg) > **設定**。 +2. 在進階設定項勾選“全文搜尋”來開啟此功能。 +3. 使用組合鍵 **Ctrl + F** 或在地址欄中單擊搜尋按鈕進入搜尋狀態,輸入關鍵字後按下鍵盤上的 **Enter** 鍵,搜尋相關文件。 + +#### 進階搜尋 + +當文件較多,搜尋較慢時,啟用進階搜尋縮小搜尋範圍,提高搜尋效率。 + +1. 在搜尋狀態下,輸入關鍵字後按 **Enter** 鍵,當搜尋到結果時,搜尋框右側顯示 ![filter](../common/filter.svg) 圖示,單擊該圖示可進行進階搜尋的操作。 + +2. 選擇搜尋範圍、檔案大小、文件類型、修改時間、訪問時間和建立時間,進行更精準的搜尋。 + +![0|filter](fig/filter.png) + +### 最近使用 + +在左方面板上預設有 **最近** 入口,單擊可以查看最近使用的檔案項目。文件預設按照訪問時間倒序排列。 + + +> ![notes](../common/notes.svg) 說明:若想隱藏「最近」,可在設定 > 基本設定 > 隱藏文件,取消勾選「在左方面板顯示最近檔案項目」。若要隱藏某一個文件的訪問記錄,右擊該文件選擇 **移除**,該操作不會刪除文件。 + +### 多分頁 + +檔案管理器支援多分頁顯示。 + +1. 在檔案管理器介面上,右鍵單擊資料夾。 +2. 選擇 **在新分頁中開啟**。 +3. 當視窗有多個分頁時,可以: + - 單擊標籤欄右側的 + 繼續添加分頁。 + - 單擊標籤上的 × 關閉分頁或將滑鼠置於分頁欄上,單擊滑鼠中鍵關閉分頁。 + + ![1|tab](fig/eu_tab.png) + +> ![tips](../common/tips.svg) 竅門:檔案管理器視窗只有一個分頁時,分頁欄是隱藏的,您還可以使用快捷鍵 **Ctrl** + **T** 來建立分頁。 + +### 書籤管理 + +為常用資料夾添加書籤,以便從左側導航欄快速訪問。 + +- 添加書籤:右鍵單擊資料夾,選擇 **加到書籤** 就可以在導航欄建立書籤。 +- 移動書籤:在導航欄上下拖動書籤調整書籤排序。 +- 刪除書籤:右鍵單擊書籤,選擇 **移除** 來刪除書籤;或右鍵單擊已添加書籤的資料夾,選擇 **移除書籤** 來刪除書籤。 + +### 標記内容 + +透過給資料(夾)添加標記,可以更好地分類管理您的文件。 + +> ![notes](../common/notes.svg) 說明:目前僅x86平台支援 **標記内容** 功能。 + +#### 添加標記 + +您可以一次為多個檔案(資料夾)添加標記,一個檔案(資料夾)也可以添加多個標記;您還可以在檔案(資料夾)的屬性中添加標記。添加成功的標記會出現在左側導航欄內。 + +##### 透過編輯框添加標記 + +1. 右鍵單擊檔案(資料夾),選擇 **標記内容**。 +2. 輸入標記名稱。若要添加多個標記,用逗號分隔。 +3. 編輯完成後單擊空白處儲存設定。 + +>![notes](../common/notes.svg) 說明:標記顏色從8種預設顏色中隨機分配。 + +![1|tag info](fig/eu_taginfo.png) + + + +##### 透過顏色按鈕添加標記 + +右鍵單擊檔案(資料夾),選擇「顏色按鈕」,直接生成這個顏色的標記。 + +![1|color tag](fig/eu_colortag.png) + +##### 透過右側訊息欄添加標記 +選擇檔案(資料夾)後,單擊 ![fileinfo](../common/fileinfo.svg),在右側訊息欄中也可以添加標記。 + +![1|info tag](fig/infotag.png) + + + +>![notes](../common/notes.svg) 說明:複製或剪下有標記的文件,所產生的文件仍然具有同樣的標記。 + + +#### 重新命名標記 + +在側邊導航欄中,右鍵單擊某個標記,選擇 **重新命名**,修改目前標記的名稱。 + +![1|rename tag](fig/renametag.png) + +#### 修改標記顏色 + +在左側導航欄中,右鍵單擊某個標記,選擇「顏色按鈕」,即可修改目前標記的顏色。 + +#### 排序標記 + +上下拖動標記即可調整標記排序。 + +#### 刪除標記 + +右鍵單擊某個標記,選擇 **移除**,刪除目前標記。 + + + +### 文件預覽 + +檔案管理器支援空白鍵預覽功能,選中文件並按下鍵盤上的空白鍵就可以快速預覽文件。預覽視窗可以查看圖片解析度、檔案大小、文字內容等,還支援gif、音訊、影片播放。 + +#### 預覽影片 + +1. 選擇您要預覽的影片檔案,按下空白鍵,即可開始預覽。 +2. 單擊影片任意地方可暫停播放。 +3. 播放過程中,可以拖動進度條來快進快退。 +4. 單擊底部 **開啟** 按扭,在預設程式中開啟該影片檔案。 + +![1|video preview](fig/videopreview.png) + +> ![notes](../common/notes.svg) 說明:您也可以同時選擇多個文件,按下空白鍵進行預覽。 + + +### 權限管理 +選擇對應文件/資料夾,單擊右鍵,選擇屬性,單擊 **存取權限**, 為擁有者,群組,和其他使用者設定檔案權限。 + +![2|permission](fig/permission.png) + +### 共用資料夾 + +當您設定了共用資料夾時,「我的共用」將會出現在導航欄上。當所有共用資料夾都取消共用後,「我的共用」自動從導航欄中移除。 + +#### 共用本機文件 + +1. 在檔案管理器介面上,右鍵單擊資料夾。 +2. 選擇 **共用資料夾**。 +3. 在資料夾的屬性視窗,勾選 **共用資料夾**。 +4. 根據需要設定 **共用名稱**、**存取權限**、**匿名** 後關閉視窗。 +5. 在檔案管理器介面上,單擊 ![icon_menu](../common/icon_menu.svg) > **設定共用密碼**。 +6. 輸入共用密碼後單擊 **確定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg) 竅門:取消勾選 **共用資料夾** 可以取消文件共用,也可以右鍵單擊文件,選擇 **取消共用**。 + + +#### 訪問共用文件 + +區域網路中其他使用者共用的文件都可以在網路鄰居中找到,您也可以透過smb訪問共用文件。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **連線到伺服器**,在編輯框中輸入伺服器地址,如:smb://xx.x.xx.xxx(一般為IP位址),單擊 **連接**;或者直接在地址欄中輸入伺服器地址,按下鍵盤上的 **Enter** 鍵。 +2. 輸入使用者名稱和共用密碼。 + - 未加密的共用文件可以匿名訪問,不需要輸入使用者名稱和密碼。 + - 加密的共用文件會彈出登入框,輸入使用者名稱和密碼之後才能訪問。 + - 使用者名稱:共用者登入系統的使用者名稱。 + - 密碼:共用文件時設置的共用密碼。 +3. 單擊 **連線**。 + +![1|visitshareshare](fig/visitshare.png) + + + + + +### 從終端中開啟 + +1. 在檔案管理器介面空白處單擊滑鼠右鍵。 +2. 選擇 **開啟終端機**,會啟動終端應用程式,終端的路徑為目前目錄。 + +![0|open-terminal](fig/e_openinterminal.png) + +### 燒錄光碟 +您可以透過燒錄功能將音樂、影片、圖片或鏡像檔案複製到光碟中。請提前準備一部燒錄機、一張CD或DVD光碟。 + +1. 將光碟插入到燒錄機中。 +2. 打開檔案管理器,單擊導航欄中的光碟圖示,進入燒錄CD的介面。 + +![cd](fig/eu_cd_interface.png) + +3. 右鍵單擊 文件(夾),選擇 **添加至光碟燒錄** 或直接將文件(夾)拖曳到燒錄CD的介面。 +4. 在燒錄CD介面,單擊右上角按鈕 **燒錄**。 + + >![notes](../common/notes.svg) 說明:如果要從燒錄列表中刪除某個文件(夾),右鍵單擊該文件(夾),選擇 **刪除**,將該文件(夾)從列表中移除。 + +5. 彈出對話框,輸入光碟名稱。您也可以進入 **進階設定** 介面,設定檔案系統、寫入速度,或勾選「允許追加資料」、「核驗資料」等,單擊 **燒錄**。 + +![cd](fig/eu_cd_rename.png) + +6. 燒錄完成後介面彈出提示框,單擊 **確定**。 + +>![notes](../common/notes.svg) 說明: +> - 當前系統僅支援對ISO9660格式的文件進行讀取與燒錄,而UDF格式的文件只支援讀取,暫不支援燒錄。 +> - 如果需要擦除光碟資料,可以右鍵單擊導航欄中光碟圖示,選擇 **卸载**,再次右鍵單擊該光碟圖示並選擇 **清除**。 + + + +### 建立捷徑 + +1. 在檔案管理器介面上,右鍵單擊文件或資料夾。 +2. 選擇 **建立連結**。 +3. 在跳出視窗中選擇建立位置、連結名稱。 +4. 單擊 **儲存**,在目標位置會生成該文件(夾)的捷徑。 + +> ![tips](../common/tips.svg) 竅門:選擇 **傳送到桌面** 可以直接在桌面上生成該文件(夾)的捷徑。 + +### 傳送文件到外接磁碟 + +當有外接磁碟接入時,您可以將文件或資料夾發送到外接磁碟。 + +1. 在檔案管理器介面上,右鍵單擊文件或資料夾。 +2. 選擇 **傳送到** > 外接磁碟。 +3. 文件或資料夾將會被傳送到移動外接磁碟。 + + + + +## 文件角標 + +您可以透過命令列,將圖示文件指定給一個文件或資料夾作為角標顯示出來。 + >![icon](../common/notes.svg) 說明: + >- 角標文件支援svg、jpg、png、bmp、gif格式,且大小不超過100KB。 + >- 隨身碟及光碟下的文件,不支援添加角標。 + +### 添加單個角標 + +1. 在終端輸入指令 **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑)"** ,該指令預設在文件(夾)右下角添加角標。 + + >![icon](../common/attention.svg) 注意:系統已定義的特殊角標,不支援被取代。 + +2. 您也可以在上述指令中加入位置參數,將角標添加在文件(夾)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + +例如:在文件(夾)左上角添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑);lu"** + +![mark](fig/single.png) + +### 添加多個角標 + +在命令列中加入“**|**”符號將角標文件路徑連結起來,為文件(夾)添加2~4個角標。文件(夾)同一個位置不支援疊加角標,僅支援取代。 + +例如:在文件(夾)四個角都添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑);lu|xxx(圖示路徑);ld|xxx(圖示路徑);ru|xxx(圖示路徑);rd"** + +![mark](fig/multi.png) + +### 復原角標 + +在終端中輸入指令 **gio set xxx(文件路徑) -t stringv metadata::emblems ""** 復原文件(夾)上所有的角標。 + +## 文件保險箱 + +文件保險箱旨在為您打造專屬的安全空間,為您的隱私保駕護航。先進的加密技術,便捷的操作流程,使用起來得心應手。 + +### 設定保險箱密碼 + +首次使用保險箱需要對其進行密碼設定,具體步驟如下: + +1. 滑鼠左鍵單擊檔案管理器導航欄中 ![file_vault](../common/file_vault.svg) 圖示,或者在電腦介面雙擊 「我的保險箱」,在彈出的保險箱對話框中單擊 **建立** 按鈕。 +2. 在設定解鎖方式的對話框中設定解鎖類型、保險箱密碼、重複保險箱密碼等,單擊**下一步**。 + +![0|password](fig/password.png) + +> ![notes](../common/notes.svg) 說明: 密碼必須同時包含大寫字母、小寫字母、數字和符號,且字元不小於8位,否則無法進入下一步。 + +3. 此時保險箱密碼生成金鑰/二維碼,建議您將金鑰/二維碼儲存,若忘記密碼,可用金鑰/二維碼開啟保險箱。單擊 **下一步**。 +4. 單擊 **加密保險箱**;在彈出的認證對話框中輸入使用者登入密碼,單擊 **確定**。 +5. 在彈出的完成加密對話框中單擊 **確定** 。設定完成後可將文件放入保險箱中。 + +### 鎖定保險箱 + +將文件放入保險箱後,右鍵單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者在電腦介面右鍵單擊「我的保險箱」。 +- 選擇 **立即上鎖**,立即將文件保險箱鎖上。 +- 選擇 **自動上鎖**,在其下拉選單進行設定: + + 選擇「永不」,電腦在鎖定螢幕或關機前一直保持未上鎖狀態。 + + 選擇「5分鐘」、「10分鐘」或者「20分鐘」後自動上鎖保險箱。 + +![0|right](fig/right.png) + + +### 解鎖保險箱 + +右鍵單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者電腦介面 「我的保險箱」。 + +- 選擇 **解鎖**,在彈出的對話框中輸入保險箱密碼,單擊 **解鎖**。 +- 選擇 **金鑰解鎖**,在彈出的對話框中輸入32位金鑰,單擊 **解鎖**。 +>![0|tips](../common/tips.svg) 竅門:您也可以單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者雙擊電腦介面 「我的保險箱」,直接使用密碼解鎖保險箱。 + + +### 刪除保險箱 + +刪除保險箱需要提前解鎖保險箱。 +1. 右鍵單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者在電腦介面右鍵單擊 「我的保險箱」,選擇 **刪除保險箱**。 +2. 在彈出的刪除保險箱對話框中輸入保險箱密碼,單擊 **刪除**。 +3. 在彈出的認證對話框中輸入使用者登入密碼,單擊 **確定** 完成刪除操作。 +> ![attention](../common/attention.svg) 注意:刪除保險箱會將裡面的文件一併刪除。在進行刪除操作前,請將保險箱中的文件備份。 + +## 磁碟管理 + +檔案管理器可以管理本機和外接磁碟。 + +### 查看磁碟 + +您的本機磁碟會顯示在檔案管理器的左側導航欄上。當您掛載外接磁碟或者插入其他移動儲存裝置時,也會在導航欄上看到相應的磁碟圖示。 + + + + + + + + + + + + + + + + + +
本機磁碟本機硬碟分區的所有磁碟
外接磁碟包括行動硬碟、隨身碟、光碟
移動裝置手機記憶體、記憶卡、SD卡等
+ +> ![notes](../common/notes.svg) 說明:如果磁碟或磁碟中的資料夾被加密了,請輸入密碼後查看文件。 + +### 本機磁碟 + +#### 隱藏本機磁碟 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg) > **設定**。 +2. 在進階設定選項中勾選 **隱藏系統硬碟**。 + +#### 重新命名本機磁碟 +1. 在左側導航欄或電腦介面,右鍵單擊需要重新命名的本機磁碟。 +2. 選擇 **重新命名**。 +3. 輸入新名稱後按下鍵盤上的 **Enter** 鍵或單擊空白處儲存修改。 + +> ![tips](../common/tips.svg) 竅門:在電腦介面,慢速雙擊本機磁碟,呈現編輯框後便可進行重新命名操作。 + +![0|disk](fig/eu_rename_disk.png) + +### 外接磁碟 + +#### 彈出外接磁碟 + +1. 在左側導航欄或電腦介面,右鍵單擊需要移除的磁碟。 +2. 選擇 **安全移除**。 +3. 磁碟將從磁碟列表中刪除,一併彈出該磁碟的所有分區。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) 竅門:如果要彈出光碟,請選擇 **彈出** 來移除光碟。單擊導航欄中磁碟右邊的 ![unmount](../common/unmount_normal.svg) 同樣可以彈出磁碟或光碟。 + +#### 重新命名外接磁碟 +1. 在左側導航欄或電腦介面,右鍵單擊需要重新命名的磁碟。 +2. 選擇 **移除**後,再次單擊右鍵選擇 **重新命名**。 +3. 輸入新的卷標名稱,按下鍵盤上的 **Enter** 鍵或單擊空白處儲存修改。 + +#### 格式化外接磁碟 + +1. 在左側導航欄或電腦介面,右鍵單擊需要格式化的磁碟。 +2. 選擇 **卸载**,再次單擊右鍵選擇 **檔案格式**。 +3. 在格式化跳出視窗中設定格式化之後的文件類型和卷標。 +4. 單擊 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) 說明:快速格式化速度快,但是資料仍然可能透過工具被復原,如果想要格式化後的資料無法被復原,可以取消勾選「快速格式化」,然後執行格式化操作。 + +## 主選單 + +在主選單中,您可以新增視窗、切換視窗主題、連線到伺服器、設定共用密碼(見[共用本機文件](#共用本機文件))、設定檔案管理器、查看說明手冊和版本介紹。 + +### 新增視窗 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **新增視窗**。 + +### 連線到伺服器 + +透過連接伺服器訪問區域網路共用文件(見[訪問共用文件](#訪問共用文件))。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **連線到伺服器**,在編輯框中輸入伺服器IP位址(XX.XX.XX.XX)。 + - 單擊 ![+](../common/+.svg) 按鈕可將該地址添加到“個人收藏伺服器”列表中。 + - 在“個人收藏伺服器”列表中選中一個地址,單擊 ![_](../common/-.svg) 按鈕,將該地址從收藏列表中移除。 +3. 單擊 **連線**。 + +![conncet](fig/connect_to_server.png) + + +### 設定 + +#### 基本設定 +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **設定** 。 +2. 選擇 **基本** + + 勾選 **永遠在新視窗開啟**。 + + 設定雙擊或單擊打開文件。 + + 設定 **視窗預設開啟**、**新建分頁時開啟**哪個目錄。 + + 設定檔案圖示大小 。 + + 設定 **預設顯示** 以圖示顯示或列表展示。 + + 勾選 **顯示隱藏檔案**,檔案管理器中被隱藏的檔案會顯示出來。 + + 勾選 **重新命名時隱藏檔案副檔名**,重新命名時不會顯示副檔名。 + + 勾選 **在左方面板顯示最近檔案項目**,在左側導航欄顯示最近使用的檔案。 + +#### 進階設定 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **設定** 。 +2. 選擇 **進階** 選項。 + + 勾選 **自動索引內部硬碟**,搜尋文件時會搜尋內建磁碟中的文件。 + + 勾選 **外部装置連上電腦時索引**,搜尋文件時也會搜尋外接裝置中的文件。 + + 勾選 **全文搜尋**,透過文件中的內容來索引。 + + 勾選預覽文件類型。 + + 勾選 **自動掛載**,接入外接磁碟時自動掛載。 + + 勾選 **自動掛載後開啟**,接入外接磁碟時自動掛載並打開該磁碟。 + + 勾選 **使用檔案管理器的選擇檔案對話框**,選擇文件時打開檔案管理器視窗。 + + 勾選 **開啟普通刪除提示**,刪除文件時彈出提示對話框。 + + 勾選 **隱藏系統硬碟**,導航欄和電腦介面將不顯示本機磁碟。 + + 勾選 **在磁碟圖標上顯示文件系統標籤**。 + +### 主題 + +視窗主題包含亮色主題、暗色主題和系統主題。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **主題**,選擇一個主題。 + +### 說明 + +查看說明手冊,進一步了解和使用檔案管理器。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **說明**。 +3. 查看檔案管理器的說明手冊。 + + +### 關於 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **關於**。 +3. 查看檔案管理器的版本和介紹。 + + +### 離開 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **離開**。 diff --git a/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/p_file-manager.md b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/p_file-manager.md new file mode 100644 index 0000000..c58ef38 --- /dev/null +++ b/dde-file-manager-5.5.3/assets/dde-file-manager/file-manager/zh_TW/p_file-manager.md @@ -0,0 +1,807 @@ +# 檔案管理器|dde-file-manager| + +## 概述 + +檔案管理器是一款功能強大、簡單易用的文件管理工具。它沿用了一般檔案管理器的經典功能和布局,並在此基礎上簡化了使用者操作,增加了很多特色功能。檔案管理器擁有一目了然的導航欄、智慧識別的搜尋框、多樣化的檢視和排序,這些特點讓文件管理不再複雜。 + +![1|overview](fig/p_overview.png) + +## 使用入門 + +透過以下方式執行或關閉檔案管理器,或者建立檔案管理器的捷徑。 + +### 執行檔案管理器 + +1. 單擊桌面底部的 ![deepin_launcher ](../common/deepin_launcher.svg),進入啟動器介面。 +2. 上下滾動滑鼠滾輪瀏覽或透過搜尋找到檔案管理器![deepin_file_manager](../common/deepin_file_manager.svg),單擊執行。 +3. 右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),您可以: + - 單擊 **建立桌面捷徑**,在桌面建立捷徑。 + - 單擊 **釘選到Dock**,將應用程式固定到Dock。 + - 單擊 **開機啟動**,將應用程式添加到開機啟動項,在電腦開機時自動執行該應用。 + +>![tips](../common/tips.svg) 竅門:您可以使用組合鍵 **Super + E** 啟動檔案管理器。 + +### 關閉檔案管理器 + +- 在檔案管理器介面,單擊 ![close_icon](../common/close_icon.svg),關閉檔案管理器。 +- 在任務欄右鍵單擊 ![deepin_file_manager](../common/deepin_file_manager.svg),選擇 **全部關閉** 來關閉檔案管理器。 +- 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg),選擇 **離開** 來關閉檔案管理器。 + +### 查看快捷鍵 + +在檔案管理器介面上,按下**Ctrl + Shift + /** 組合鍵來查看快捷鍵,熟練的使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 主介面 + +檔案管理器的主介面簡單易用、功能全面,熟練地使用介面功能將使文件管理更加簡單高效。 + +![1|main-interface](fig/p_maininterface.png) + + +| 標號 | 名稱 | 描述 | +| ---- | ------------- | ------------------------------------------------------------ | +| 1 | 導航欄 | 單擊導航圖示,快速存取本機文件、磁碟、網路鄰居、書籤、標記等。 | +| 2 | 地址欄 | 透過地址欄,您可以快速切換訪問歷史、在上下級目錄間切換、搜尋、輸入地址訪問。 | +| 3 | 圖示/列表檢視 | 單擊 ![icon_view](../common/icon_view.svg) , ![list_view](../common/list_view.svg)圖示,以圖示或列表形式查看文件(夾)。 | +| 4 | 訊息欄 | 單擊 ![fileinfo](../common/fileinfo.svg), 查看文件(夾)的基本訊息和標記。 | +| 5 | 選單欄 | 透過主選單,您可以建立視窗、切換視窗主題、設定共享密碼、設定檔案管理器、查看說明文件和關於訊息、關閉檔案管理器。 | +| 6 | 狀態欄 | 顯示文件數量或者已選中文件的數量。 | + + +> ![tips](../common/tips.svg) 竅門:可拖動左側導航欄右邊的分隔線來改變其寬度。 + +## 基本功能 + +檔案管理器具備基本的文件管理功能,對文件(夾)進行新增、複製、重新命名、刪除等操作都非常簡單。 + +### 新增文件 + +#### 新增文件 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 單擊 **新增文件**。 +3. 選擇新增文件的類型。 +4. 輸入新增文件的名稱。 + +![0|newdo](fig/newdo.png) + +#### 新增資料夾 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 單擊 **新增資料夾**。 +3. 輸入資料夾的名稱。 + +### 重新命名文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **重新命名**。 +3. 輸入檔案名稱,按 **Enter** 鍵或者滑鼠單擊介面空白區域。 + +![0|contextmenu](fig/p_contextmenu.png) + +> ![tips](../common/tips.svg) 竅門:在 **設定** 中勾選「重新命名時隱藏檔案副檔名」,能更方便地修改檔案名稱。 + +### 批次重新命名 + +1. 在檔案管理器介面上,選中多個文件。 +2. 右擊文件,並選擇 **重新命名**。 + - **取代文件**尋找需要取代的文字,並輸入取代後的文字,檔案名中的關鍵字將被統一取代。 + - **加入文件** 輸入需要加入的文字,並選擇目錄是檔名之前還是之後,檔案名將統一加入被添加的文字。 + - **自訂文件** 輸入檔案名,並輸入序列的遞進數字,檔案名將統一改成新檔案名+遞進數字。 +4. 單擊 **重新命名** 來完成操作。 + +![1|rename](fig/p_batchrename.png) + +### 查看文件 + +單擊介面上的 ![icon_view](../common/icon_view.svg) 、![list_view](../common/list_view.svg) 圖示來切換圖示檢視和列表檢視。 + +- 圖示檢視:平鋪顯示文件的名稱、圖示或縮圖。 + +![1|icon-view](fig/p_iconview.png) + +- 列表檢視:列表顯示文件圖示或縮圖、名稱、修改時間、大小、類型等訊息。 + +![1|list-view](fig/p_listview.png) + +> ![tips](../common/tips.svg) 竅門:使用 **Ctrl + 1** 和 **Ctrl + 2** 快捷鍵,切換圖示檢視和列表檢視。 + + +### 排序文件 + +1. 在檔案管理器介面上,單擊滑鼠右鍵。 +2. 選擇 **排序順序**。 +3. 在子選單中選擇以檔案名稱、修改時間、大小或類型來排序文件。 + +> ![tips](../common/tips.svg) 竅門:在列表檢視中,單擊表頭欄的列標籤來切換升序、降序。 + +### 開啟文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **用其他程式開啟** > **選擇預設開啟程式**。 +3. 在程式列表中選擇應用程式。 + +> ![notes](../common/notes.svg) 說明:直接雙擊文件會使用預設程式打開。您可以選擇相同類型的多個文件,右鍵選擇「用其他程式開啟」選項,一次開啟多個文件。 + +![0|open](fig/p_open.png) + +### 隱藏文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **屬性**,勾選 **隱藏此文件**。 + +### 複製文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 單擊 **複製**。 +3. 選擇一個目標儲存位置。 +4. 單擊滑鼠右鍵,然後選擇 **貼上**。 + +### 壓縮文件 + +1. 在檔案管理器介面,右鍵單擊文件(夾)。 +2. 選擇 **壓縮**。 +3. 彈出歸檔管理器壓縮介面,可以設定壓縮包格式、名稱、儲存路徑等,單擊 **壓縮**。 + +> ![tips](../common/tips.svg) 竅門:您也可以直接在右鍵選單中選擇 **添加到xxx.7z** 或 **添加到xxx.zip**,快速將文件(夾)壓縮成7z或zip格式。 + + +### 刪除文件 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **刪除** 。 + - 被刪除的文件可以在回收桶中找到,右鍵單擊回收站中的文件可以進行 **還原** 或 **刪除** 操作。 + - 被刪除的文件的捷徑將會失效。 + +> ![attention](../common/attention.svg) 注意:外接裝置刪除文件會將文件徹底刪除,無法從回收桶找回。 + +### 復原操作 + +在檔案管理器中,可以用 **Ctrl + Z** 來復原上一步操作,包括: + +- 刪除建立的文件。 +- 復原重新命名(包括重新命名文件後綴)之前的名字。 +- 從回收站還原剛刪除的文件。 +- 復原文件到移動(剪下移動、滑鼠移動)前的原始路徑。 +- 刪除複製貼上的文件。 + +>![attention](../common/attention.svg) 注意:復原動作最多只能返回兩步;如果操作中有覆蓋某個同名文件和徹底刪除文件,則復原只能返回到這一步。 + +### 文件屬性 + +文件屬性會顯示文件的基本資訊,開啟方式和權限設定。資料夾内容會顯示資料夾的基本資訊,共用訊息和權限設定。 + +1. 在檔案管理器介面上,右鍵單擊文件。 +2. 選擇 **屬性**,查看文件屬性。 + +![2|info](fig/info.png) + +> ![notes](../common/notes.svg) 說明:查看多個文件屬性會顯示文件總大小和數量;查看捷徑的屬性將會額外顯示來源文件地址。您還可以使用 **Ctrl + I** 組合鍵查看文件屬性。 + +### 病毒查殺 + +1. 在檔案管理器界面上,右鍵單擊文件(夾)。 +2. 選擇 **病毒查殺**,彈出安全中心病毒查殺界面,您可以對該文件(夾)進行安全掃描,具體操作請參閱安全中心的 [病毒查殺](dman:///deepin-defender#病毒查殺)。 + + > ![notes](../common/notes.svg) 說明: + > - 如果當前安全中心有查殺任務,則在彈出的對話框中單擊 **查看** 進入安全中心病毒查殺界面進行查看。 + > - 安全中心默認開啟 **加入「病毒查殺」到文件右鍵選單** 的功能,您也可以進入安全中心設置界面,取消勾選該功能。取消勾選後檔案管理器右鍵菜單中不會顯示病毒查殺的選項。 + +## 常用操作 + +檔案管理器具備很多特色功能,這些功能都讓文件管理更加簡單、高效。 + +### 切換地址欄 + +地址欄由歷史導航、麵包屑和輸入框共同組成。通常情況下地址欄顯示麵包屑。 + +![0|addressbar](fig/addressbar1.png) + +- 單擊歷史導航按鈕,您可以快速在歷史瀏覽記錄間切換,查看前一個地址或者後一個地址。 +- 文件所在位置的每一個層級都會形成一個麵包屑,透過來回單擊麵包屑可以快速在不同文件層級間切換。 + +當您單擊搜尋圖示,或者在文件路徑上右鍵選擇 **編輯位址**,地址欄會切換為輸入框狀態。在輸入框外單擊時,位址欄會自動復原到麵包屑狀態。 + +![0|addressbar](fig/addressbar2.png) + +- 輸入框帶有智慧識別功能,您可以輸入關鍵字或者訪問地址Enter,系統會自動識別並進行搜尋或訪問。 + +### 搜尋文件 + +檔案管理器支援多種檢索方式,既支援透過檔案名稱、文件內容進行普通搜尋,也支援透過文件類型、建立時間等進行進階搜尋,提高工作效率,便於文件管理。 + - 需要指定目錄搜尋時,請先進入該目錄,然後再進行搜尋。 + +> ![notes](../common/notes.svg) 說明: +> 在檔案管理器的 **設定**中,預設勾選了 **自動索引內部硬碟**,您可以選擇勾選 **外部裝置連上電腦時索引**,加快在外部裝置的搜尋速度。 + +#### 全文搜尋 + +您可以透過文件內容關鍵字來搜尋文件。 + +1. 在檔案管理器中,單擊 ![icon_menu](../common/icon_menu.svg) > **設定**。 +2. 在進階設定項勾選 **全文搜尋** 來開啟此功能。 +3. 使用組合鍵 **Ctrl + F** 或在地址欄中單擊搜尋按鈕進入搜尋狀態,輸入關鍵字後按下鍵盤上的 **Enter** 鍵,搜尋相關文件。 + +#### 進階搜尋 + +當文件較多,搜尋較慢時,啟用進階搜尋縮小搜尋範圍,提高搜尋效率。 + +1. 在搜尋狀態下,輸入關鍵字後按 **Enter** 鍵,當搜尋到結果時,搜尋框右側顯示 ![filter](../common/filter.svg) 圖示,單擊該圖示可進行進階搜尋的操作。 + +2. 選擇搜尋範圍、檔案大小、文件類型、修改時間、訪問時間和建立時間,進行更精準的搜尋。 + +![0|filter](fig/p_filter.png) + +### 最近使用 + +在左方面板上預設有 **最近** 入口,單擊可以查看最近使用的檔案項目。文件預設按照訪問時間倒序排列。 + + +> ![notes](../common/notes.svg) 說明:若想隱藏「最近」,可在設定 > 基本設定 > 隱藏文件,取消勾選「在左方面板顯示最近檔案項目」。若要隱藏某一個文件的訪問記錄,右擊該文件選擇 **移除**,該操作不會刪除文件。 + +### 多分頁 + +檔案管理器支援多分頁顯示。 + +1. 在檔案管理器介面上,右鍵單擊資料夾。 +2. 選擇 **在新分頁中開啟**。 +3. 當視窗有多個分頁時,可以: + - 單擊標籤欄右側的 + 繼續添加分頁。 + - 將滑鼠指標置於分頁上,單擊關閉按鈕 × 或單擊滑鼠中鍵,關閉分頁。 + + ![1|tab](fig/p_tab.png) + +> ![tips](../common/tips.svg) 竅門:檔案管理器視窗只有一個分頁時,分頁欄是隱藏的,您還可以使用快捷鍵 **Ctrl** + **T** 來建立分頁。 + +### 書籤管理 + +為常用資料夾添加書籤,以便從左側導航欄快速訪問。 + +- 添加書籤:右鍵單擊資料夾,選擇 **加到書籤** 就可以在導航欄建立書籤。 +- 移動書籤:在導航欄上下拖動書籤調整書籤排序。 +- 刪除書籤:右鍵單擊書籤,選擇 **移除** 來刪除書籤;或右鍵單擊已添加書籤的資料夾,選擇 **移除書籤** 來刪除書籤。 + +### 標記内容 + +透過給資料(夾)添加標記,可以更好地分類管理您的文件。 + +> ![notes](../common/notes.svg) 說明:目前僅x86平台支援 **標記内容** 功能。 + +#### 添加標記 + +您可以一次為多個檔案(資料夾)添加標記,一個檔案(資料夾)也可以添加多個標記;添加成功的標記會出現在左側導航欄內。 + +##### 透過編輯框添加標記 + +1. 右鍵單擊檔案(資料夾),選擇 **標記内容**。 +2. 輸入標記名稱。若要添加多個標記,用逗號分隔。 +3. 編輯完成後單擊空白處儲存設定。 + +>![notes](../common/notes.svg) 說明:標記顏色從8種預設顏色中隨機分配。 + +![1|tag info](fig/p_taginfo.png) + + + +##### 透過顏色按鈕添加標記 + +右鍵單擊檔案(資料夾),選擇「顏色按鈕」,直接生成這個顏色的標記。 + +![1|color tag](fig/p_colortag.png) + +##### 透過右側訊息欄添加標記 +選擇檔案(資料夾)後,單擊 ![fileinfo](../common/fileinfo.svg),在右側訊息欄中也可以添加標記。 + +![1|info tag](fig/p_infotag.png) + + + +>![notes](../common/notes.svg) 說明:複製或剪下有標記的文件,所產生的文件仍然具有同樣的標記。 + + +#### 重新命名標記 + +在側邊導航欄中,右鍵單擊某個標記,選擇 **重新命名**,修改目前標記的名稱。 + +![1|rename tag](fig/renametag.png) + +#### 修改標記顏色 + +在左側導航欄中,右鍵單擊某個標記,選擇「顏色按鈕」,即可修改目前標記的顏色。 + +#### 排序標記 + +上下拖動標記即可調整標記排序。 + +#### 刪除標記 + +右鍵單擊某個標記,選擇 **移除**,刪除目前標記。 + + + +### 文件預覽 + +檔案管理器支援空白鍵預覽功能,選中文件並按下鍵盤上的空白鍵就可以快速預覽文件。預覽視窗可以查看圖片解析度、檔案大小、文字內容等,還支援gif、音訊、影片播放。 + +#### 預覽影片 + +1. 選擇您要預覽的影片檔案,按下空白鍵,即可開始預覽。 +2. 單擊影片任意地方可暫停播放。 +3. 播放過程中,可以拖動進度條來快進快退。 +4. 單擊底部 **開啟** 按扭,在預設程式中開啟該影片檔案。 + +![1|video preview](fig/videopreview.png) + +> ![notes](../common/notes.svg) 說明:您也可以同時選擇多個文件,按下空白鍵進行預覽。 + + +### 權限管理 +選擇對應文件/資料夾,單擊右鍵,選擇屬性,單擊 **存取權限**, 為擁有者,群組,和其他使用者設定檔案權限。 + +![2|permission](fig/permission.png) + +### 共用資料夾 + +當您設定了共用資料夾時,「我的共用」將會出現在導航欄上。當所有共用資料夾都取消共用後,「我的共用」自動從導航欄中移除。 + +#### 共用本機文件 + +1. 在檔案管理器介面,右鍵單擊資料夾。 +2. 選擇 **共享資料夾**。 +3. 在資料夾的屬性視窗,勾選 **共享此資料夾**。 + + > ![notes](../common/notes.svg) 說明: 如果smb服務未開啟,則彈出密碼認證視窗,輸入登入密碼完成認證即可開啟smb服務。 + +4. 根據需要設定 **共享名**、**權限**、**匿名訪問** 後關閉視窗。 +5. 單擊 ![icon_menu](../common/icon_menu.svg)> **設定共享密碼**。 +7. 在彈出的視窗中輸入共享密碼,單擊 **確定**。 + +![2|share](fig/share.png) + +> ![tips](../common/tips.svg) 竅門:取消勾選 **共用資料夾** 可以取消文件共用,也可以右鍵單擊文件,選擇 **取消共用**。 + + +#### 訪問共用文件 + +區域網路中其他使用者共用的文件都可以在網路鄰居中找到,您也可以透過smb訪問共用文件。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **連線到伺服器**,在編輯框中輸入伺服器地址,如:smb://xx.x.xx.xxx(一般為IP位址),單擊 **連接**;或者直接在地址欄中輸入伺服器地址,按下鍵盤上的 **Enter** 鍵。 +2. 輸入使用者名稱和共用密碼。 + - 未加密的共用文件可以匿名訪問,不需要輸入使用者名稱和密碼。 + - 加密的共用文件會彈出登入框,輸入使用者名稱和密碼之後才能訪問。 + - 使用者名稱:共用者登入系統的使用者名稱。 + - 密碼:共用文件時設置的共用密碼。 +3. 單擊 **連線**。 + +![1|visitshareshare](fig/visitshare.png) + + + +### 以管理員身份開新視窗 + +前提條件:「控制中心」>「一般設定」中開發者模式已打開。 + +1. 在檔案管理器介面空白處單擊滑鼠右鍵。 +2. 選擇 **以管理員身份開新視窗**,在彈出的視窗中輸入使用者密碼,單擊 **確定**。 +3. 該資料夾會以新視窗打開,在此視窗中可以進行進階權限的操作,關閉視窗後,終止管理員權限。 + +### 從終端中開啟 + +1. 在檔案管理器介面空白處單擊滑鼠右鍵。 +2. 選擇 **開啟終端機**,會啟動終端應用程式,終端的路徑為目前目錄。 + +![0|open-terminal](fig/openinterminal.png) + +### 燒錄光碟 +您可以透過燒錄功能將音樂、影片、圖片或鏡像檔案複製到光碟中。其中,ISO9660檔案系統支援所有的CD和DVD光碟格式,UDF檔案系統僅支援部分光碟格式。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
類型光碟格式ISO9660UDF
空盤DVD-R、DVD+R、CD-R、CD-RW支援支援
非DVD-R、DVD+R、CD-R、CD-RW支援不支援
非空盤DVD-R、DVD+R、CD-R、CD-RW支援追加文件僅支援Windows原生工具燒錄的格式
非DVD-R、DVD+R、CD-R、CD-RW支援追加文件不支援追加文件
+ + +1. 將光碟插入到燒錄機中。 +2. 打開檔案管理器,單擊導航欄中的光碟圖示,進入燒錄CD的介面。 + +![cd](fig/cd_interface.png) + +3. 右鍵單擊 文件(夾),選擇 **添加至光碟燒錄** 或直接將文件(夾)拖曳到燒錄CD的介面。 +4. 在燒錄CD介面,單擊右上角按鈕 **燒錄**。 + + >![notes](../common/notes.svg) 說明:如果要從燒錄列表中刪除某個文件(夾),右鍵單擊該文件(夾),選擇 **刪除**,將該文件(夾)從列表中移除。 + +5. 彈出視窗,輸入光碟名稱。您也可以進入 **進階設定** 介面,設定檔案系統、寫入速度,或勾選「允許追加資料」、「核驗資料」等,單擊 **燒錄**。 + +![cd](fig/cd_rename.png) + +6. 燒錄完成後介面彈出提示框,單擊 **確定**。 + +>![notes](../common/notes.svg) 說明:如果需要擦除光碟資料,可以右鍵單擊導航欄中光碟圖示,選擇 **卸载**,再次右鍵單擊該光碟圖示並選擇 **清除**。 + + + +### 建立捷徑 + +1. 在檔案管理器介面上,右鍵單擊文件或資料夾。 +2. 選擇 **建立連結**。 +3. 在跳出視窗中選擇建立位置、連結名稱。 +4. 單擊 **儲存**,在目標位置會生成該文件(夾)的捷徑。 + +> ![tips](../common/tips.svg) 竅門:選擇 **傳送到桌面** 可以直接在桌面上生成該文件(夾)的捷徑。 + +### 傳送文件到外接磁碟 + +當有外接磁碟接入時,您可以將文件或資料夾發送到外接磁碟。 + +1. 在檔案管理器介面上,右鍵單擊文件或資料夾。 +2. 選擇 **傳送到** > 外接磁碟。 +3. 文件或資料夾將會被傳送到移動外接磁碟。 + +### 傳送文件到藍牙 +若您的電腦配備了藍牙模組,便可透過藍牙進行短距離文件傳輸的操作。 + +前提條件:傳送端與接收端藍牙設備已配對並成功連接。具體連接方法可參考 [連接藍牙設備](dman:///dde#連接藍牙設備)。 + +1. 在檔案管理器界面,右鍵單擊需要傳送的文件或文件壓縮包。 +2. 選擇 **傳送到** > **傳送到藍牙**。 +3. 在彈出的藍牙文件傳輸視窗中勾選接收設備,單擊 **下一步**。 +4. 此時接收端會收到文件接收的請求,待接收端同意請求後,傳送端開始傳輸文件。 + +## 統信UOS助手 + +統信UOS助手是一款實現手機與電腦間跨端協作、高效傳輸以及即時同步的工具,將手機與電腦連接,或者使用無線投送功能,即可輕鬆傳輸圖片、影片、文件等。 + +>![icon](../common/notes.svg) 說明:僅安卓手機支援安裝統信UOS助手。 + +### 準備工作 + +#### 安裝統信UOS助手 + +1. 單擊左側導航欄 **我的手機** 或系統工具列中的圖示 ![icon](../common/found.svg)。 +2. 在我的手機介面,單擊 **安裝統信UOS助手**,彈出二維碼視窗。 + - 透過手機微信或瀏覽器掃描二維碼,下載並安裝統信UOS助手。 + - 單擊 **下載APK安裝包**,將安裝包下載到電腦端,下載完成後再匯入至手機端進行安裝。 + + ![phone](fig/myphone.png) + +#### 登入統信UOS助手 + +統信UOS助手支援三種登入方式:手機快捷登入、微信登入、帳號密碼登入,請選擇一種方式進行登入。如果您尚未註冊帳號,請在登入介面單擊 **註冊帳號** 進行註冊。 + +#### 設定發現方式 + +通過「發現設定」功能,設定手機和電腦被發現的方式。在統信UOS助手介面,單擊右上角的 **發現設定**;在電腦系統工具列上,右鍵單擊圖示 ![icon](../common/found.svg),選擇 **發現設定**,您可以選擇: + +- **允許被所有人發現**:在區域網路內,允許所有處於同一網路且在同一網段的裝置發現本手機或電腦。 +- **僅限同一Union ID帳號發現**:在區域網路內,允許登入同一個Union ID的裝置發現本手機或電腦。 +- **不被發現**:所有裝置都不能發現本手機或電腦。 +- **允許被登入同一Union ID的遠端裝置發現**(電腦端):允許登入同一個Union ID的遠端裝置發現本電腦。 + + + +### 連接手機端與電腦端 + +登入統信UOS助手後,您可以透過掃碼連接或搜尋電腦的方式將手機與電腦連接起來。 + +#### 掃碼連接 + +前提條件:手機與電腦連接同一無線網路且在同一個網段內。 + +1. 在電腦端,單擊檔案管理器左側導航欄 **我的手機** 或系統工具列中的圖示 ![icon](../common/found.svg),彈出「使用統信UOS助手掃碼連接」的視窗。 +2. 在手機端,進入統信UOS助手介面,單擊 **掃碼連接**,掃描步驟1視窗中的二維碼,完成連接。 + +#### 搜尋電腦 + +前提條件:手機與電腦處於同一無線網路且在同一網段中(僅支援互發文件,不支援查看和編輯文件)或登入同一個Union ID帳號;且手機與電腦允許被發現。 + +1. 在統信UOS助手介面,單擊 **搜尋電腦**。 +2. 在搜尋列表中選擇需要連接的電腦,完成連接。 + +如果需要斷開連接,您可以: + +- 在統信UOS助手介面上單擊按鈕 ![icon](../common/exit.svg) 斷開連接。 +- 在電腦上右鍵單擊系統工具列中的圖示 ![icon](../common/found.svg),選擇您的手機,在跳出視窗中單擊 **斷開連接**。 + +### 管理文件 + +手機與電腦連線成功後,您可以發送文件、查看文件和管理文件。 + +#### 傳輸文件 + +- **透過統信UOS助手介面進行文件傳輸** + + 發送手機文件至電腦:在統信UOS助手介面,單擊 **傳輸助手**,在傳輸視窗中發送文件至電腦端。 + +- **透過檔案管理器介面進行文件傳輸** + + 發送電腦文件至手機:在 **檔案管理器 > 我的手機** 介面,右側傳輸視窗中,您可以選擇電腦文件至該視窗中進行發送;或者右鍵單擊電腦中某個文件,選擇 **發送到我的手機**。 + +- **透過無線投送功能進行文件傳輸** + + 當裝置處於同一無線網路且在同一網段中或已登入同一Union ID帳號,且裝置允許被發現,您可以透過無線投送功能,將文件從一台裝置投送到另一台裝置中。 + 1. 在電腦上,右鍵單擊需要投送的文件,選擇 **無線投送**。 + 2. 在跳出視窗中選擇需要投送的手機或電腦,完成投送。 + + >![icon](../common/notes.svg) 說明: + >- 手機端需要安裝統信UOS助手並登入帳號後,才能接收電腦端投送的文件。 + >- 登入同一Union ID後,可以進行遠端投送的操作。 + +#### 查看/編輯文件 + +- 在手機上查看電腦文件:在統信UOS助手介面,單擊 **我的電腦**,您可以打開、下載或分享電腦文件。 +- 在電腦上查看/編輯手機文件:在 **檔案管理器 > 我的手機** 介面,分類展示手機相冊、影片、文件等資料夾,您可以打開、編輯資料夾中的文件,文件經過編輯並儲存後將同步至手機端。 + + +## 文件角標 + +您可以透過命令列,將圖示文件指定給一個文件或資料夾作為角標顯示出來。 + >![icon](../common/notes.svg) 說明: + >- 角標文件支援svg、jpg、png、bmp、gif格式,且大小不超過100KB。 + >- 隨身碟及光碟下的文件,不支援添加角標。 + +### 添加單個角標 + +1. 在終端輸入指令 **gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑)"** ,該指令預設在文件(夾)右下角添加角標。 + + >![icon](../common/attention.svg) 注意:系統已定義的特殊角標,不支援被取代。 + +2. 您也可以在上述指令中加入位置參數,將角標添加在文件(夾)的左上角(lu)、左下角(ld)、右上角(ru)或右下角(rd)。 + +例如:在文件(夾)左上角添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑);lu"** + +![mark](fig/single.png) + +### 添加多個角標 + +在命令列中加入**|**符號將角標文件路徑連結起來,為文件(夾)添加2~4個角標。文件(夾)同一個位置不支援疊加角標,僅支援取代。 + +例如:在文件(夾)四個角都添加角標 + +**gio set xxx(文件路徑) -t stringv metadata::emblems "xxx(圖示路徑);lu|xxx(圖示路徑);ld|xxx(圖示路徑);ru|xxx(圖示路徑);rd"** + +![mark](fig/multi.png) + +### 復原角標 + +在終端中輸入指令 **gio set xxx(文件路徑) -t stringv metadata::emblems ""** 復原文件(夾)上所有的角標。 + +## 文件保險箱 + +文件保險箱旨在為您打造專屬的安全空間,為您的隱私保駕護航。先進的加密技術,便捷的操作流程,使用起來得心應手。 + +### 設定保險箱密碼 + +首次使用保險箱需要對其進行密碼設定,具體步驟如下: + +1. 單擊導航欄中的保險箱圖示 ![file_vault](../common/file_vault.svg),或者在電腦介面雙擊 **我的保險箱**,在彈出的視窗中單擊 **建立**。 +2. 設定解鎖類型、保險箱密碼等,單擊 **下一步**。 + + +![0|password](fig/password.png) + +> ![notes](../common/notes.svg) 說明: 密碼必須同時包含大寫字母、小寫字母、數字和符號,且字元不小於8位,否則無法進入下一步。 + +3. 在儲存金鑰文件視窗中,設定金鑰文件的儲存位置,如果您忘記了保險箱密碼,可使用金鑰文件找回密碼。單擊 **下一步**。 + +![encrypt](fig/save.png) + +4. 單擊 **加密保險箱**,彈出認證視窗,輸入使用者登入密碼後單擊 **確定**。 + +5. 在加密完成對話框中單擊 **確定**, 完成保險箱密碼設定。 + +![encrypt](fig/finish.png) + +### 鎖定保險箱 + +將文件放入保險箱後,右鍵單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者在電腦介面右鍵單擊「我的保險箱」。 +- 選擇 **立即上鎖**,立即將文件保險箱鎖上。 +- 選擇 **自動上鎖**,在其下拉選單進行設定: + + 選擇「永不」,電腦在鎖定螢幕或關機前一直保持未上鎖狀態。 + + 選擇「5分鐘」、「10分鐘」或者「20分鐘」後自動上鎖保險箱。 + +![0|right](fig/right.png) + + +### 解鎖保險箱 + +1. 單擊 ![file_vault](../common/file_vault.svg) 或者在電腦介面雙擊 **我的保險箱**。 +2. 在解鎖保險箱的視窗中,輸入保險箱密碼,單擊 **解鎖**。 +3. 如果忘記了保險箱密碼,單擊 **忘記密碼**,選擇金鑰文件的儲存位置後,單擊 **驗證金鑰** 找回密碼。 + +![encrypt](fig/unlock.png) + + +>![0|tips](../common/tips.svg)竅門:您也可以右鍵單擊 ![file_vault](../common/file_vault.svg) 或者 **我的保險箱**,選擇 **解鎖**,解鎖保險箱。 + + +### 刪除保險箱 + +刪除保險箱需要提前解鎖保險箱。 +1. 右鍵單擊導航欄 ![file_vault](../common/file_vault.svg) 圖示或者在電腦介面右鍵單擊 「我的保險箱」,選擇 **刪除保險箱**。 +2. 在彈出的刪除保險箱視窗中輸入保險箱密碼,單擊 **刪除**。 +3. 在彈出的認證視窗中輸入使用者登入密碼,單擊 **確定** 完成刪除操作。 +> ![attention](../common/attention.svg) 注意:刪除保險箱會將裡面的文件一併刪除。在進行刪除操作前,請將保險箱中的文件備份。 + +## 磁碟管理 + +檔案管理器可以管理本機和外接磁碟。 + +### 查看磁碟 + +您的本機磁碟會顯示在檔案管理器的左側導航欄上。當您掛載外接磁碟或者插入其他移動儲存裝置時,也會在導航欄上看到相應的磁碟圖示。 + + + + + + + + + + + + + + + + + +
本機磁碟本機硬碟分區的所有磁碟
外接磁碟包括行動硬碟、隨身碟、光碟
移動裝置手機記憶體、記憶卡、SD卡等
+ +> ![notes](../common/notes.svg) 說明:如果磁碟或磁碟中的資料夾被加密了,請輸入密碼後查看文件。 + +### 本機磁碟 + +#### 隱藏本機磁碟 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg) > **設定**。 +2. 在進階設定選項中勾選 **隱藏系統硬碟**。 + +#### 重新命名本機磁碟 +1. 在左側導航欄或電腦介面,右鍵單擊需要重新命名的本機磁碟。 +2. 選擇 **重新命名**。 +3. 輸入新名稱後按下鍵盤上的 **Enter** 鍵或單擊空白處儲存修改。 + +> ![tips](../common/tips.svg) 竅門:在電腦介面,慢速雙擊本機磁碟,呈現編輯框後便可進行重新命名操作。 + +![0|disk](fig/p_rename_disk.png) + +### 外接磁碟 + +#### 彈出外接磁碟 + +1. 在左側導航欄或電腦介面,右鍵單擊需要移除的磁碟。 +2. 選擇 **安全移除**。 +3. 磁碟將從磁碟列表中刪除,一併彈出該磁碟的所有分區。 + +![0|disk](fig/disk1.png) + +> ![tips](../common/tips.svg) 竅門:如果要彈出光碟,請選擇 **彈出** 來移除光碟。單擊導航欄中磁碟右邊的 ![unmount](../common/unmount_normal.svg) 同樣可以彈出磁碟或光碟。 + +#### 重新命名外接磁碟 +1. 在左側導航欄或電腦介面,右鍵單擊需要重新命名的磁碟。 +2. 選擇 **移除**後,再次單擊右鍵選擇 **重新命名**。 +3. 輸入新的卷標名稱,按下鍵盤上的 **Enter** 鍵或單擊空白處儲存修改。 + +#### 格式化外接磁碟 + +1. 在左側導航欄或電腦介面,右鍵單擊需要格式化的磁碟。 +2. 選擇 **卸载**,再次單擊右鍵選擇 **檔案格式**。 +3. 在格式化跳出視窗中設定格式化之後的文件類型和卷標。 +4. 單擊 **格式化**。 + +![0|disk](fig/disk2.png) + +> ![notes](../common/notes.svg) 說明:快速格式化速度快,但是資料仍然可能透過工具被復原,如果想要格式化後的資料無法被復原,可以取消勾選「快速格式化」,然後執行格式化操作。 + +## 主選單 + +在主選單中,您可以新增視窗、切換視窗主題、連線到伺服器、設定共用密碼(見[共用本機文件](#共用本機文件))、設定檔案管理器、查看說明手冊和版本介紹。 + +### 新增視窗 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **新增視窗**。 + +### 連線到伺服器 + +透過連接伺服器訪問區域網路共用文件(見[訪問共用文件](#訪問共用文件))。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 選擇 **連線到伺服器**,在編輯框中輸入伺服器IP位址(XX.XX.XX.XX)。 + - 單擊 ![+](../common/+.svg) 按鈕可將該地址添加到 **個人收藏伺服器** 列表中。 + - 在 **個人收藏伺服器** 列表中選中一個地址,單擊 ![_](../common/-.svg) 按鈕,將該地址從收藏列表中移除。 +3. 單擊 **連線**。 + +![conncet](fig/connect_to_server.png) + + +### 設定 + +#### 基本設定 +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **設定** 。 +2. 選擇 **基本** + + 勾選 **永遠在新視窗開啟**。 + + 設定雙擊或單擊打開文件。 + + 設定 **視窗預設開啟**、**新建分頁時開啟**哪個目錄。 + + 設定檔案圖示大小 。 + + 設定 **預設顯示** 以圖示顯示或列表展示。 + + 勾選 **顯示隱藏檔案**,檔案管理器中被隱藏的檔案會顯示出來。 + + 勾選 **重新命名時隱藏檔案副檔名**,重新命名時不會顯示副檔名。 + + 勾選 **在左方面板顯示最近檔案項目**,在左側導航欄顯示最近使用的檔案。 + +#### 進階設定 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **設定** 。 +2. 選擇 **進階** 選項。 + + 勾選 **自動索引內部硬碟**,搜尋文件時會搜尋內建磁碟中的文件。 + + 勾選 **外部装置連上電腦時索引**,搜尋文件時也會搜尋外接裝置中的文件。 + + 勾選 **全文搜尋**,透過文件中的內容來索引。 + + 勾選預覽文件類型。 + + 勾選 **自動掛載**,接入外接磁碟時自動掛載。 + + 勾選 **自動掛載後開啟**,接入外接磁碟時自動掛載並打開該磁碟。 + + 勾選 **MTP掛載路徑下顯示文件統計詳情**,MTP裝置掛載後,顯示其路徑底部的狀態欄訊息。 + + 勾選 **Samba共享端常駐顯示掛載入口**,遠端掛載連結常駐顯示在導航欄中。 + + 勾選 **使用檔案管理器的選擇檔案對話框**,選擇文件時打開檔案管理器視窗。 + + 勾選 **開啟普通刪除提示**,刪除文件時彈出提示對話框。 + + 勾選 **隱藏系統硬碟**,導航欄和電腦介面將不顯示本機磁碟。 + + 勾選 **在磁碟圖標上顯示文件系統標籤**。 + +### 主題 + +視窗主題包含亮色主題、暗色主題和系統主題。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **主題**,選擇一個主題。 + +### 說明 + +查看說明手冊,進一步了解和使用檔案管理器。 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **說明**。 +3. 查看檔案管理器的說明手冊。 + + +### 關於 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **關於**。 +3. 查看檔案管理器的版本和介紹。 + + +### 離開 + +1. 在檔案管理器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **離開**。 diff --git a/dde-file-manager-5.5.3/debian/changelog b/dde-file-manager-5.5.3/debian/changelog new file mode 100644 index 0000000..ef50fd3 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/changelog @@ -0,0 +1,29 @@ +dde-file-manager (5.5.3-1) unstable; urgency=medium + + * update + + -- Deepin Packages Builder Fri, 24 Dec 2021 10:20:58 +0800 + +dde-file-manager (1.0.1-1) stable; urgency=low + + * Autobuild Tag 1.0.1 + + -- TagBuilder Tue, 26 Jul 2016 06:56:58 +0000 + +dde-file-manager (1.0-3) stable; urgency=low + + * Rebuild Version 1.0 + + -- TagBuilder Tue, 26 Jul 2016 04:42:53 +0000 + +dde-file-manager (1.0-2) stable; urgency=low + + * Rebuild Version 1.0 + + -- TagBuilder Tue, 26 Jul 2016 04:17:56 +0000 + +dde-file-manager (1.0-1) unstable; urgency=medium + + * Initial release + + -- Deepin Packages Builder Tue, 16 Feb 2016 11:08:50 +0800 diff --git a/dde-file-manager-5.5.3/debian/compat b/dde-file-manager-5.5.3/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/compat @@ -0,0 +1 @@ +9 diff --git a/dde-file-manager-5.5.3/debian/control b/dde-file-manager-5.5.3/debian/control new file mode 100644 index 0000000..f205a00 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/control @@ -0,0 +1,144 @@ +Source: dde-file-manager +Section: libdevel +Priority: optional +Maintainer: Deepin Packages Builder +Build-Depends: + debhelper (>=9), + pkg-config, + qt5-qmake, + qtbase5-dev, + qtbase5-private-dev, + libqt5x11extras5-dev, + libjemalloc-dev, + libqt5svg5-dev, + libmagic-dev, + libsecret-1-dev, + libpoppler-cpp-dev, + libpolkit-agent-1-dev, + libpolkit-qt5-1-dev, + qtmultimedia5-dev, + libffmpegthumbnailer-dev, + libtag1-dev, + libdtkwidget-dev, + libdtkgui-dev, + libxcb1-dev, + x11proto-core-dev, + libx11-dev, + qttools5-dev-tools, + libglib2.0-dev, + dde-dock-dev(>=4.8.4.1), + libxcb-ewmh-dev, + libxcb-shape0-dev, + libdframeworkdbus-dev, + libxcb-util0-dev, + qtdeclarative5-dev, + deepin-gettext-tools, + libkf5codecs-dev, + libdtkcore-dev, + libdtkcore5-bin, + libdmr-dev, + dh-systemd, + deepin-anything-dev[i386 amd64], + deepin-anything-server-dev[i386 amd64], + libudisks2-qt5-dev(>=5.0.6), + libxrender-dev, + libmtdev-dev, + libfontconfig1-dev, + libfreetype6-dev, + libegl1-mesa-dev, + libglibmm-2.4-dev, + libgio-qt-dev(>=0.0.11), + libdisomaster-dev(>=5.0.7), + libssl-dev, + libmediainfo-dev, + libqt5xdg-dev, + libtag1-dev, + libicu-dev, + liblucene++-dev, + libgsf-1-dev, + libglib2.0-dev, + libboost-date-time-dev, + libboost-filesystem-dev, + libboost-iostreams-dev, + libboost-regex-dev, + libboost-system-dev, + libboost-test-dev, + libboost-thread-dev, + libdocparser-dev, + deepin-desktop-base | deepin-desktop-server | deepin-desktop-device +Standards-Version: 3.9.8 +Homepage: http://www.deepin.org + +Package: dde-file-manager +Architecture: any +Depends: + ${shlibs:Depends}, + ${misc:Depends}, + libdde-file-manager( =${binary:Version}), + socat, + cryfs, + deepin-anything-dkms[i386 amd64], + deepin-anything-server[i386 amd64], + libblockdev-crypto2, + dde-device-formatter +Conflicts: dde-file-manager-oem +Replaces: dde-file-manager-oem +Recommends: dde-qt5integration, avfs, samba +Description: File manager front end + File manager front-end of Deepin OS + +Package: dde-desktop +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libdde-file-manager( =${binary:Version}) +Conflicts: dde-workspace (<< 2.90.5), dde-file-manager-oem +Replaces: dde-file-manager-oem +Recommends: qt5dxcb-plugin, deepin-screensaver +Description: deepin desktop-environment - desktop module + Deepin Desktop Environment (DDE) - desktop module. + +Package: dde-disk-mount-plugin +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libdde-file-manager( =${binary:Version}) +Description: plugin of dde-dock + Disk mount plugin of dde-dock which is created by libdde-file-manager + +Package: dde-select-dialog-wayland +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libdde-file-manager( =${binary:Version}) +Description: dbus service for wayland + Deepin select dialog for wayland. + +Package: dde-select-dialog-x11 +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libdde-file-manager( =${binary:Version}) +Description: dbus service for x11 + Deepin select dialog for x11. + +Package: libdde-file-manager +Architecture: any +Depends: + ${shlibs:Depends}, + ${misc:Depends}, + libpoppler-cpp0v5 (>= 0.48.0), + gvfs-backends(>=1.27.3), + cryptsetup, + libkf5codecs5, + deepin-anything-libs[i386 amd64], + liblucene++-dev, + libgsf-1-dev, + libglib2.0-dev, + libdisomaster (>=5.0.7), + libdocparser +Recommends: + libudfburn +Breaks: dde-file-manager(<=1.2.3-3) +Multi-Arch: same +Description: DDE File Manager library + This package contains the shared libraries. + +Package: libdde-file-manager-dev +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libdde-file-manager( =${binary:Version}) +Description: DDE File Manager Devel library + This package contains the header files and static libraries + of libdde-file-manager diff --git a/dde-file-manager-5.5.3/debian/copyright b/dde-file-manager-5.5.3/debian/copyright new file mode 100644 index 0000000..d614f5c --- /dev/null +++ b/dde-file-manager-5.5.3/debian/copyright @@ -0,0 +1,21 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: dde-file-manager + +Files: * +Copyright: 2017 Deepin Technology Co., Ltd. +License: GPL-3+ + This package 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 package 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 + . + On Debian systems, the complete text of the GNU General + Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". diff --git a/dde-file-manager-5.5.3/debian/dde-desktop.install b/dde-file-manager-5.5.3/debian/dde-desktop.install new file mode 100644 index 0000000..1fe73d6 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-desktop.install @@ -0,0 +1,5 @@ +usr/bin/dde-desktop +usr/share/applications/dde-computer.desktop +usr/share/applications/dde-trash.desktop +usr/share/dde-desktop/translations/*.qm +usr/share/dbus-1/services/com.deepin.dde.desktop.service diff --git a/dde-file-manager-5.5.3/debian/dde-desktop.install.loongarch64 b/dde-file-manager-5.5.3/debian/dde-desktop.install.loongarch64 new file mode 100644 index 0000000..1fe73d6 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-desktop.install.loongarch64 @@ -0,0 +1,5 @@ +usr/bin/dde-desktop +usr/share/applications/dde-computer.desktop +usr/share/applications/dde-trash.desktop +usr/share/dde-desktop/translations/*.qm +usr/share/dbus-1/services/com.deepin.dde.desktop.service diff --git a/dde-file-manager-5.5.3/debian/dde-desktop.install.mips64el b/dde-file-manager-5.5.3/debian/dde-desktop.install.mips64el new file mode 100644 index 0000000..1fe73d6 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-desktop.install.mips64el @@ -0,0 +1,5 @@ +usr/bin/dde-desktop +usr/share/applications/dde-computer.desktop +usr/share/applications/dde-trash.desktop +usr/share/dde-desktop/translations/*.qm +usr/share/dbus-1/services/com.deepin.dde.desktop.service diff --git a/dde-file-manager-5.5.3/debian/dde-desktop.install.mipsel b/dde-file-manager-5.5.3/debian/dde-desktop.install.mipsel new file mode 100644 index 0000000..1fe73d6 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-desktop.install.mipsel @@ -0,0 +1,5 @@ +usr/bin/dde-desktop +usr/share/applications/dde-computer.desktop +usr/share/applications/dde-trash.desktop +usr/share/dde-desktop/translations/*.qm +usr/share/dbus-1/services/com.deepin.dde.desktop.service diff --git a/dde-file-manager-5.5.3/debian/dde-desktop.install.riscv64 b/dde-file-manager-5.5.3/debian/dde-desktop.install.riscv64 new file mode 100644 index 0000000..1fe73d6 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-desktop.install.riscv64 @@ -0,0 +1,5 @@ +usr/bin/dde-desktop +usr/share/applications/dde-computer.desktop +usr/share/applications/dde-trash.desktop +usr/share/dde-desktop/translations/*.qm +usr/share/dbus-1/services/com.deepin.dde.desktop.service diff --git a/dde-file-manager-5.5.3/debian/dde-desktop.install.sw_64 b/dde-file-manager-5.5.3/debian/dde-desktop.install.sw_64 new file mode 100644 index 0000000..1fe73d6 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-desktop.install.sw_64 @@ -0,0 +1,5 @@ +usr/bin/dde-desktop +usr/share/applications/dde-computer.desktop +usr/share/applications/dde-trash.desktop +usr/share/dde-desktop/translations/*.qm +usr/share/dbus-1/services/com.deepin.dde.desktop.service diff --git a/dde-file-manager-5.5.3/debian/dde-disk-mount-plugin.install b/dde-file-manager-5.5.3/debian/dde-disk-mount-plugin.install new file mode 100644 index 0000000..60e37e3 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-disk-mount-plugin.install @@ -0,0 +1,5 @@ +usr/lib/dde-dock/plugins/system-trays/libdde-disk-mount-plugin.so + +usr/share/glib-2.0/schemas/*.disk-mount.gschema.xml + +usr/share/dde-disk-mount-plugin/translations/*.qm diff --git a/dde-file-manager-5.5.3/debian/dde-file-manager.install b/dde-file-manager-5.5.3/debian/dde-file-manager.install new file mode 100644 index 0000000..7e9f433 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-file-manager.install @@ -0,0 +1,23 @@ +usr/bin/dde-file-manager +usr/bin/dde-file-manager-daemon +usr/bin/dde-file-manager-pkexec +usr/bin/dde-property-dialog + +usr/lib/*/deepin-anything-server-lib/plugins/handlers/libdde-anythingmonitor.so + +usr/share/applications/dde-file-manager.desktop +usr/share/applications/dde-open.desktop + +usr/share/polkit-1/actions/*.policy + +usr/share/deepin-manual/manual-assets/application + +etc/dbus-1/system.d/com.deepin.filemanager.daemon.conf + +src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialog.xml usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialog.xml +src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialogmanager.xml usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialogmanager.xml +src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialog.service usr/share/dbus-1/services/com.deepin.filemanager.filedialog.service +usr/share/dbus-1/services/org.freedesktop.FileManager.service +usr/share/dbus-1/system-services/com.deepin.filemanager.daemon.service + +usr/lib/systemd/system/ lib/systemd/ diff --git a/dde-file-manager-5.5.3/debian/dde-file-manager.install.arm64 b/dde-file-manager-5.5.3/debian/dde-file-manager.install.arm64 new file mode 100644 index 0000000..3512c5f --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-file-manager.install.arm64 @@ -0,0 +1,24 @@ +usr/bin/dde-file-manager +usr/bin/dde-file-manager-daemon +usr/bin/dde-file-manager-pkexec +usr/bin/dde-property-dialog +usr/bin/dde-computer.sh +usr/bin/dde-trash.sh +usr/bin/file-manager.sh + +usr/share/applications/dde-file-manager.desktop +usr/share/applications/dde-open.desktop + +usr/share/polkit-1/actions/*.policy + +usr/share/deepin-manual/manual-assets/application/dde-file-manager + +etc/dbus-1/system.d/com.deepin.filemanager.daemon.conf + +usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialog.xml +usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialogmanager.xml +usr/share/dbus-1/services/com.deepin.filemanager.filedialog.service +usr/share/dbus-1/services/org.freedesktop.FileManager.service +usr/share/dbus-1/system-services/com.deepin.filemanager.daemon.service + +usr/lib/systemd/system/ lib/systemd/ diff --git a/dde-file-manager-5.5.3/debian/dde-file-manager.install.loongarch64 b/dde-file-manager-5.5.3/debian/dde-file-manager.install.loongarch64 new file mode 100644 index 0000000..3512c5f --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-file-manager.install.loongarch64 @@ -0,0 +1,24 @@ +usr/bin/dde-file-manager +usr/bin/dde-file-manager-daemon +usr/bin/dde-file-manager-pkexec +usr/bin/dde-property-dialog +usr/bin/dde-computer.sh +usr/bin/dde-trash.sh +usr/bin/file-manager.sh + +usr/share/applications/dde-file-manager.desktop +usr/share/applications/dde-open.desktop + +usr/share/polkit-1/actions/*.policy + +usr/share/deepin-manual/manual-assets/application/dde-file-manager + +etc/dbus-1/system.d/com.deepin.filemanager.daemon.conf + +usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialog.xml +usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialogmanager.xml +usr/share/dbus-1/services/com.deepin.filemanager.filedialog.service +usr/share/dbus-1/services/org.freedesktop.FileManager.service +usr/share/dbus-1/system-services/com.deepin.filemanager.daemon.service + +usr/lib/systemd/system/ lib/systemd/ diff --git a/dde-file-manager-5.5.3/debian/dde-file-manager.install.mips64el b/dde-file-manager-5.5.3/debian/dde-file-manager.install.mips64el new file mode 100644 index 0000000..3512c5f --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-file-manager.install.mips64el @@ -0,0 +1,24 @@ +usr/bin/dde-file-manager +usr/bin/dde-file-manager-daemon +usr/bin/dde-file-manager-pkexec +usr/bin/dde-property-dialog +usr/bin/dde-computer.sh +usr/bin/dde-trash.sh +usr/bin/file-manager.sh + +usr/share/applications/dde-file-manager.desktop +usr/share/applications/dde-open.desktop + +usr/share/polkit-1/actions/*.policy + +usr/share/deepin-manual/manual-assets/application/dde-file-manager + +etc/dbus-1/system.d/com.deepin.filemanager.daemon.conf + +usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialog.xml +usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialogmanager.xml +usr/share/dbus-1/services/com.deepin.filemanager.filedialog.service +usr/share/dbus-1/services/org.freedesktop.FileManager.service +usr/share/dbus-1/system-services/com.deepin.filemanager.daemon.service + +usr/lib/systemd/system/ lib/systemd/ diff --git a/dde-file-manager-5.5.3/debian/dde-file-manager.install.mipsel b/dde-file-manager-5.5.3/debian/dde-file-manager.install.mipsel new file mode 100644 index 0000000..3512c5f --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-file-manager.install.mipsel @@ -0,0 +1,24 @@ +usr/bin/dde-file-manager +usr/bin/dde-file-manager-daemon +usr/bin/dde-file-manager-pkexec +usr/bin/dde-property-dialog +usr/bin/dde-computer.sh +usr/bin/dde-trash.sh +usr/bin/file-manager.sh + +usr/share/applications/dde-file-manager.desktop +usr/share/applications/dde-open.desktop + +usr/share/polkit-1/actions/*.policy + +usr/share/deepin-manual/manual-assets/application/dde-file-manager + +etc/dbus-1/system.d/com.deepin.filemanager.daemon.conf + +usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialog.xml +usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialogmanager.xml +usr/share/dbus-1/services/com.deepin.filemanager.filedialog.service +usr/share/dbus-1/services/org.freedesktop.FileManager.service +usr/share/dbus-1/system-services/com.deepin.filemanager.daemon.service + +usr/lib/systemd/system/ lib/systemd/ diff --git a/dde-file-manager-5.5.3/debian/dde-file-manager.install.riscv64 b/dde-file-manager-5.5.3/debian/dde-file-manager.install.riscv64 new file mode 100644 index 0000000..2215aa4 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-file-manager.install.riscv64 @@ -0,0 +1,24 @@ +usr/bin/dde-file-manager +usr/bin/dde-file-manager-daemon +usr/bin/dde-file-manager-pkexec +usr/bin/dde-property-dialog +usr/bin/dde-computer.sh +usr/bin/dde-trash.sh +usr/bin/file-manager.sh + +usr/share/applications/dde-file-manager.desktop +usr/share/applications/dde-open.desktop + +usr/share/polkit-1/actions/*.policy + +usr/share/deepin-manual/manual-assets/application/dde-file-manager + +etc/dbus-1/system.d/com.deepin.filemanager.daemon.conf + +src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialog.xml usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialog.xml +src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialogmanager.xml usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialogmanager.xml +src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialog.service usr/share/dbus-1/services/com.deepin.filemanager.filedialog.service +usr/share/dbus-1/services/org.freedesktop.FileManager.service +usr/share/dbus-1/system-services/com.deepin.filemanager.daemon.service + +usr/lib/systemd/system/ lib/systemd/ diff --git a/dde-file-manager-5.5.3/debian/dde-file-manager.install.sw_64 b/dde-file-manager-5.5.3/debian/dde-file-manager.install.sw_64 new file mode 100644 index 0000000..3512c5f --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-file-manager.install.sw_64 @@ -0,0 +1,24 @@ +usr/bin/dde-file-manager +usr/bin/dde-file-manager-daemon +usr/bin/dde-file-manager-pkexec +usr/bin/dde-property-dialog +usr/bin/dde-computer.sh +usr/bin/dde-trash.sh +usr/bin/file-manager.sh + +usr/share/applications/dde-file-manager.desktop +usr/share/applications/dde-open.desktop + +usr/share/polkit-1/actions/*.policy + +usr/share/deepin-manual/manual-assets/application/dde-file-manager + +etc/dbus-1/system.d/com.deepin.filemanager.daemon.conf + +usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialog.xml +usr/share/dbus-1/interfaces/com.deepin.filemanager.filedialogmanager.xml +usr/share/dbus-1/services/com.deepin.filemanager.filedialog.service +usr/share/dbus-1/services/org.freedesktop.FileManager.service +usr/share/dbus-1/system-services/com.deepin.filemanager.daemon.service + +usr/lib/systemd/system/ lib/systemd/ diff --git a/dde-file-manager-5.5.3/debian/dde-select-dialog-wayland.install b/dde-file-manager-5.5.3/debian/dde-select-dialog-wayland.install new file mode 100644 index 0000000..17e1b75 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-select-dialog-wayland.install @@ -0,0 +1,2 @@ +usr/bin/dde-select-dialog-wayland +usr/share/dbus-1/services/com.deepin.filemanager.filedialog_wayland.service \ No newline at end of file diff --git a/dde-file-manager-5.5.3/debian/dde-select-dialog-x11.install b/dde-file-manager-5.5.3/debian/dde-select-dialog-x11.install new file mode 100644 index 0000000..a3abc2c --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-select-dialog-x11.install @@ -0,0 +1,2 @@ +usr/bin/dde-select-dialog-x11 +usr/share/dbus-1/services/com.deepin.filemanager.filedialog_x11.service \ No newline at end of file diff --git a/dde-file-manager-5.5.3/debian/dde-sharefiles.install b/dde-file-manager-5.5.3/debian/dde-sharefiles.install new file mode 100644 index 0000000..967b48e --- /dev/null +++ b/dde-file-manager-5.5.3/debian/dde-sharefiles.install @@ -0,0 +1,3 @@ +usr/share/dde-file-manager/sharefiles/config/* +usr/share/dde-file-manager/sharefiles/lib/* +usr/share/dde-file-manager/sharefiles/public/* diff --git a/dde-file-manager-5.5.3/debian/libdde-file-manager-dev.install b/dde-file-manager-5.5.3/debian/libdde-file-manager-dev.install new file mode 100644 index 0000000..6a5f3ed --- /dev/null +++ b/dde-file-manager-5.5.3/debian/libdde-file-manager-dev.install @@ -0,0 +1,3 @@ +usr/include/dde-file-manager/ +usr/lib/*/pkgconfig/dde-file-manager.pc +usr/lib/*/libdde-file-manager.so diff --git a/dde-file-manager-5.5.3/debian/libdde-file-manager.install b/dde-file-manager-5.5.3/debian/libdde-file-manager.install new file mode 100644 index 0000000..c5cdfb7 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/libdde-file-manager.install @@ -0,0 +1,16 @@ +usr/lib/*/libdde-file-manager.so.* +usr/share/dde-file-manager/translations/*.qm +usr/share/dde-file-manager/templates/* +usr/share/dde-file-manager/mimetypes/* +usr/share/dde-file-manager/mimetypeassociations/* +usr/share/dde-file-manager/extensions/appEntry/.readme +usr/share/icons/* + +usr/lib/*/dde-file-manager/plugins/* +usr/lib/*/dde-file-manager/tools/* + +usr/share/glib-2.0/schemas/*.filemanager.gschema.xml + +usr/share/deepin/dde-file-manager/oem-menuextensions/.readme + +usr/share/applications/context-menus/.readme diff --git a/dde-file-manager-5.5.3/debian/libdde-file-manager.lintian-overrides b/dde-file-manager-5.5.3/debian/libdde-file-manager.lintian-overrides new file mode 100644 index 0000000..7c3ca0b --- /dev/null +++ b/dde-file-manager-5.5.3/debian/libdde-file-manager.lintian-overrides @@ -0,0 +1 @@ +libdde-file-manager: possible-gpl-code-linked-with-openssl diff --git a/dde-file-manager-5.5.3/debian/postinst b/dde-file-manager-5.5.3/debian/postinst new file mode 100644 index 0000000..12cbf12 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/postinst @@ -0,0 +1,26 @@ +#!/bin/bash + +set -e + +HOME="/home" +for dir in $HOME/* +do + if [ -d "$dir" ] + then + home_desktop="$dir/Desktop/dde-home.desktop" + if [ -f "$home_desktop" ] + then + rm -f $home_desktop + fi + + fi +done + +home_desktop="/usr/share/applications/dde-home.desktop" +if [ -f $home_desktop ] +then + rm -f $home_desktop +fi + +#DEBHELPER# +exit 0 diff --git a/dde-file-manager-5.5.3/debian/rules b/dde-file-manager-5.5.3/debian/rules new file mode 100755 index 0000000..1c018c0 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/rules @@ -0,0 +1,16 @@ +#!/usr/bin/make -f + +export QT_SELECT=5 +include /usr/share/dpkg/default.mk + +DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) + +%: + dh $@ --parallel + +override_dh_shlibdeps: + dh_shlibdeps -l$(shell pwd)/debian/dde-sharefiles/usr/share/dde-file-manager/sharefiles/lib + +override_dh_auto_configure: + dh_auto_configure -- VERSION=$(VERSION) LIB_INSTALL_DIR=/usr/lib/$(DEB_HOST_MULTIARCH) DEFINES+="VERSION=$(DEB_VERSION_UPSTREAM)" filemanager.pro + diff --git a/dde-file-manager-5.5.3/debian/source/format b/dde-file-manager-5.5.3/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/dde-file-manager-5.5.3/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/dde-file-manager-5.5.3/debian/source/lintian-overrides b/dde-file-manager-5.5.3/debian/source/lintian-overrides new file mode 100644 index 0000000..9b1043c --- /dev/null +++ b/dde-file-manager-5.5.3/debian/source/lintian-overrides @@ -0,0 +1 @@ +dde-file-manager source: source-is-missing diff --git a/dde-file-manager-5.5.3/docs/PLUGIN-README.md b/dde-file-manager-5.5.3/docs/PLUGIN-README.md new file mode 100644 index 0000000..12bbf62 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/PLUGIN-README.md @@ -0,0 +1,117 @@ +## 深度文管上下文菜单 OEM 支持插件 + +在启用此插件支持后,在深度文件管理器载入此插件时,会识别指定目录下的 `.desktop` 文件,并将其视为扩展菜单项,加入到文件管理器的上下文菜单中。 + +### OEM 方式 + +每个定制菜单项为一个独立的 Application 类型的 `.desktop` 文件(遵循 [desktop-entry-spec](https://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#extra-actions-identifier))。对于每个文件,在其 `[Desktop Entry]` 下至少需要包含 `Name` 和 `Exec` 字段,`Name` 的内容为添加到上下文菜单中时将会显示的名称,`Exec` 的内容为当单击此新增的菜单项时将会执行的行为(遵循 desktop 文件规范标准,可以使用 `%u` 等参数)。 + +定制菜单支持使用 `Actions` 字段增加指定的子菜单,子菜单需至少包含 `Name` 和 `Exec` 字段,可以通过 `Icon` 指定图标。若指定子菜单,则入口项(原本 `[Desktop Entry]` 下)的 `Exec` 字段将不再有效。 + +对于文件管理器菜单项定制,支持额外的字段可供定制,可以使用 `X-DFM-MenuTypes` 字段来指定菜单项在何种情况会显示,此字段可包含一个或多个类型,其中包括 `SingleFile`, `SingleDir`, `MultiFileDirs` 和 `EmptyArea` 四种。 + +| 名称 | 含义 | +| :- | :- | +| `SingleFile` | 在单独的文件上触发上下文菜单 | +| `SingleDir` | 在单独的文件夹/目录上触发上下文菜单 | +| `MultiFileDirs` | 在多个文件/文件夹上触发上下文菜单 | +| `EmptyArea`| 在空白区域触发上下文菜单 | + +可以使用 `;` 作为分割填写多个值,但注意,包含 `X-DFM-MenuTypes` 字段但内容为空的情况和不包含 `X-DFM-MenuTypes` 字段的情况不同,包含但为空将不会在任何位置显示,不包含将会视为会在任何情况下显示。 + +`MimeType` 可以根据被选中的文件类型决定菜单项是否显示被添加的项,支持模糊匹配(如 `MimeType=image/*;` )。 同 `X-DFM-MenuTypes` 一样, `MimeType` 只能用在 `[Desktop Entry]` 项目中,使用 `;` 作为分割填写多个值, `MimeType` 字段但内容为空的情况和不包含 `MimeType` 字段的情况不同,包含但为空将不会在任何位置显示,不包含将会视为 `MimeType=*;`。 + +`X-DFM-ExcludeMimeTypes` 可以排除特定的文件类型,只能用在 `[Desktop Entry]` 项目中,使用 `;` 作为分割填写多个值,支持模糊匹配。优先于 `MimeTypes`项过滤文件,即如果 `MimeTypes` 和 `X-DFM-ExcludeMimeTypes`同时包含某种文件类型时,该文件类型被选中将无法显示菜单。 + +注意: MimeType 本身呈树形结构关系,配置 `MimeType` 所对应的值将匹配文件所对应的最佳匹配 MimeType 及其完整父级关系,即若文件的 MimeType 关系树中任意一项匹配了 `MimeType` 中所配置的值,则匹配成功。例如,若配置 `MimeType=text/plain;` 则除 `text/plain` 外还会匹配 `application/json` `application/xml` 等类型的文件,因为它们的父级 MimeType 关系中包含 `text/plain`。 而 `X-DFM-ExcludeMimeTypes` 则仅对完全匹配此配置中所包含的 MimeType 进行过滤,不过滤其父级关系。如 `*.xlxs` 文件的父级 MimeType 有 `application/zip`,但 `ExcludeMimeTypes=application/zip` 不会过滤掉 `*.xlxs` 文件。 + +`X-DFM-NotShowIn` 可以决定是否在桌面或者文件管理器显示菜单,此字段可包含一个或多个类型,其中包括 `FileManager`, `Desktop` 两种,字段不存在或字段为空时在桌面和文件管理均可显示。 + +| 名称 | 含义 | +| :- | :- | +| `FileManager` | 在文件管理器中触发上下文菜单 | +| `Desktop` | 在桌面触发上下文菜单 | + +`X-DFM-SupportSchemes` 可以决定是否在指定的目录scheme下显示菜单,此字段可包含一个或多个类型,其中包括 `file`, `trash`, `recent`, `bookmark` 等多种,字段不包含时任何位置均可显示菜单,字段内容为空时将不显示菜单。 +| 名称 | 含义 | +| :- | :- | +| `file` | 在本地文件上触发上下文菜单 | +| `trash ` | 在回收站中触发上下文菜单 | +| `recent ` | 在最近文件中触发上下文菜单 | +| `bookmark ` | 在书签文件触发上下文菜单 | + + +`X-DFM-SupportSuffix` 可以决定是否根据(全)后缀名过滤显示菜单,如在 `test.7z.002` `test.7z.003` `test.7z.004` 等文件上显示压缩菜单,由于分卷文件 `MimeType` 是 `application/octet-stream` 无法通过文件类型显示,特增加通过后缀显示菜单,此情况可以用 `7z.*` 来支持。 + + +OEM 厂商需要将待添加的 `desktop` 文件放置到 `/usr/share/deepin/dde-file-manager/oem-menuextensions/` 位置,在下次启动文件管理器时[^1],选中任意一个或多个文件并触发上下文菜单,将可以看到新增的项目位于其中。 + +### 示例 `.desktop` 文件 + +可以将下面的示例存储为 `test.desktop` 并放置到 `/usr/share/deepin/dde-file-manager/oem-menuextensions/` 中,关闭现有的所有文件管理器窗口并打开新的文件管理器窗口,定制的菜单将会出现在单独目录或多选文件的情况的上下文菜单中。 + +### 示例 1 - 单项菜单 + +``` ini +[Desktop Entry] +Type=Application +Exec=/home/wzc/Temp/test.sh %U +Icon=utilities-terminal +Name=示例菜单项名称 +X-DFM-MenuTypes=SingleDir;MultiFileDirs; +``` + +### 示例 2 - 包含子菜单 + +注意这种情况时,由于包含子菜单,故在 `[Desktop Entry]` 下添加 `Exec` 不会起任何作用。另外,`X-DFM-MenuTypes` 只能用在 `[Desktop Entry]` 项目中,不能用在子菜单中。 + +``` ini +[Desktop Entry] +Type=Application +Icon=utilities-terminal +Name=示例菜单项名称 +Actions=TestAction; +X-DFM-MenuTypes=SingleDir;MultiFileDirs; + +[Desktop Action TestAction] +Name=示例子菜单 +Exec=/home/wzc/Temp/test.sh %U +``` + +### 完整示例 - 复制文件路径 + +1. 切换到 `.desktop` 文件所在目录 `/usr/share/deepin/dde-file-manager/oem-menuextensions/` 。 +``` +sudo mkdir /usr/share/deepin/dde-file-manager +sudo mkdir /usr/share/deepin/dde-file-manager/oem-menuextensions +cd /usr/share/deepin/dde-file-manager/oem-menuextensions +``` +2. 使用文本编辑器(如 `deepin-editor` 或 `vim` )创建一个文本文件(需要root权限保存), 名称可以自定义, 后缀名为`.desktop`。 +``` +sudo deepin-editor copyfilepath.desktop +``` +3. 在文件中加入以下内容, `Icon` 图标可以去 `/usr/share/icons/` 中选择合适的图标。 +``` +[Desktop Entry] +Type=Application +Icon=edit-copy +Name=复制文件路径 +X-DFM-MenuTypes=SingleFile; +Exec=~/copyfilepath.sh %u +MimeType=text/plain; +X-DFM-NotShowIn=Desktop +X-DFM-ExcludeMimeTypes=application/xml; +``` +4. 在主目录下创建 `copyfilepath.sh` 脚本。 +``` +cd ~ +deepin-editor copyfilepath.sh +``` +在文本中加入以下内容 +``` +#!/bin/bash +echo -n $1 | xclip -i -selection clipboard +``` +至此,重新启动文件管理器,文件列表中常规文本文件的右键菜单会多一个菜单项 `复制文件路径`,点击即可将文件路径复制到剪切板中。 + +[^1]: 注:这是由于菜单列表仅在文件管理器(桌面)启动时识别并记录一次。在部分平台,深度文件管理器存在加速启动用的进程常驻后台,您可能需要结束所有文件管理器进程。类似的,对于桌面,也需要重启桌面的相应进程才能使桌面使用新增的菜单。 diff --git a/dde-file-manager-5.5.3/docs/README.md b/dde-file-manager-5.5.3/docs/README.md new file mode 100644 index 0000000..4581c0e --- /dev/null +++ b/dde-file-manager-5.5.3/docs/README.md @@ -0,0 +1,14 @@ +## Documentation + +We are using `qdoc` to generate the documentation of `dde-file-manager`. + +### Generate the doc + +You can `cd` to this folder and run: + +``` shell +$ qdoc --single-exec master.qdocconf +``` + +The generated documentation located at `./html/deepin file manager/*`. + diff --git a/dde-file-manager-5.5.3/docs/config.qdocconf b/dde-file-manager-5.5.3/docs/config.qdocconf new file mode 100644 index 0000000..698cace --- /dev/null +++ b/dde-file-manager-5.5.3/docs/config.qdocconf @@ -0,0 +1,21 @@ +include(./qdoc-configs/qt-html-templates-online.qdocconf) + +project = Deepin File Manager +description = A file management tool for Deepin Desktop Environment. + +sourcedirs += ../ +headerdirs += ../ +exampledirs += qdoc/snippets + +macro.param = "\\e" +macro.return = "Returns" + +naturallanguage = en +outputencoding = UTF-8 +sourceencoding = UTF-8 + +sources.fileextensions = "*.cpp *.qdoc *.mm *.qml" +headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx" + +outputformats = HTML +outputdir = ./html/ diff --git a/dde-file-manager-5.5.3/docs/master.qdocconf b/dde-file-manager-5.5.3/docs/master.qdocconf new file mode 100644 index 0000000..a14b35d --- /dev/null +++ b/dde-file-manager-5.5.3/docs/master.qdocconf @@ -0,0 +1 @@ +./config.qdocconf \ No newline at end of file diff --git a/dde-file-manager-5.5.3/docs/old/deepin-screenshut.png b/dde-file-manager-5.5.3/docs/old/deepin-screenshut.png new file mode 100644 index 0000000..3881b7b Binary files /dev/null and b/dde-file-manager-5.5.3/docs/old/deepin-screenshut.png differ diff --git a/dde-file-manager-5.5.3/docs/old/file-manager-args.pdf b/dde-file-manager-5.5.3/docs/old/file-manager-args.pdf new file mode 100644 index 0000000..f37dd51 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/old/file-manager-args.pdf differ diff --git a/dde-file-manager-5.5.3/docs/old/view-plgin.pdf b/dde-file-manager-5.5.3/docs/old/view-plgin.pdf new file mode 100644 index 0000000..dd61ef0 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/old/view-plgin.pdf differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/compat.qdocconf b/dde-file-manager-5.5.3/docs/qdoc-configs/compat.qdocconf new file mode 100644 index 0000000..12d061a --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/compat.qdocconf @@ -0,0 +1,9 @@ +macro.0 = "\\\\0" +macro.n = "\\\\n" +macro.r = "\\\\r" +macro.img = "\\image" +macro.endquote = "\\endquotation" +macro.relatesto = "\\relates" + +spurious = "Missing comma in .*" \ + "Missing pattern .*" diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/config.qdocconf b/dde-file-manager-5.5.3/docs/qdoc-configs/config.qdocconf new file mode 100644 index 0000000..16d4e32 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/config.qdocconf @@ -0,0 +1,16 @@ +#Include this file to inherit configuration related to Qt Project based modules. + +dita.metadata.default.author = Deepin File Manager Team +dita.metadata.default.permissions = all +dita.metadata.default.publisher = Deepin File Manager Team +dita.metadata.default.copyryear = 2019 +dita.metadata.default.copyrholder = Deepin Technology +dita.metadata.default.audience = programmer + +#Set the main DFM index.html +navigation.homepage = index.html +navigation.hometitle = "DFM $DFM_VER" + +sourcedirs += includes + +url = https://linuxdeepin.github.io/dde-file-manager/ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/externalsites/external-resources.qdoc b/dde-file-manager-5.5.3/docs/qdoc-configs/externalsites/external-resources.qdoc new file mode 100644 index 0000000..6019f50 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/externalsites/external-resources.qdoc @@ -0,0 +1,494 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ +/*! + \externalpage http://www.freedesktop.org/ + \title freedesktop.org +*/ + +/*! + \externalpage http://www.freedesktop.org/Standards/xembed-spec + \title XEmbed Specification +*/ + +/*! + \externalpage http://www.freedesktop.org/Standards/icon-theme-spec + \title Icon Themes Specification +*/ + +/*! + \externalpage http://www.cups.org/ + \title Common Unix Printing System (CUPS) + \keyword CUPS +*/ + +/*! + \externalpage http://www.freedesktop.org/wiki/Standards_2fdesktop_2dentry_2dspec + \title Desktop Entry Specification +*/ + +/*! + \externalpage http://www.kde.org/ + \title The K Desktop Environment + \keyword KDE +*/ + +/*! + \externalpage http://www.cmake.org/cmake/help/documentation.html + \title CMake Documentation +*/ + +/*! + \externalpage http://www.cmake.org/cmake/help/v2.8.11/cmake.html#command:find_package + \title CMake find_package Documentation +*/ + +/*! + \externalpage http://www.cmake.org/cmake/help/v2.8.11/cmake.html#prop_tgt:AUTOMOC + \title CMake AUTOMOC Documentation +*/ + + +/*! + \externalpage http://www.cmake.org/cmake/help/v2.8.11/cmake.html#prop_tgt:LOCATION + \title CMake LOCATION Documentation +*/ + +/*! + \externalpage http://www.cmake.org/cmake/help/v2.8.11/cmake.html#prop_tgt:POSITION_INDEPENDENT_CODE + \title CMake POSITION_INDEPENDENT_CODE Documentation +*/ + +/*! + \externalpage http://www.cmake.org/cmake/help/v2.8.11/cmake.html#command:target_link_libraries + \title CMake target_link_libraries Documentation +*/ + +/*! + \externalpage http://www.gnome.org/ + \title GNOME +*/ + +/*! + \externalpage http://www.gnu.org/software/emacs/ + \title GNU Emacs +*/ + +/*! + \externalpage http://gnuwin32.sourceforge.net/packages.html + \title GnuWin32 Project +*/ + +/*! + \externalpage http://www.w3.org/Graphics/SVG/About.html + \title About SVG + \keyword Scalable Vector Graphics +*/ + +/*! + \externalpage http://www.w3.org/TR/SVG/types.html#ColorKeywords + \title SVG color keyword names +*/ + +/*! + \externalpage http://www.w3.org/Graphics/SVG/ + \title SVG Working Group +*/ + +/*! + \externalpage http://www.w3.org/TR/SVGMobile/ + \title Mobile SVG Profiles + \omit + Mobile SVG Profiles: SVG Tiny and SVG Basic + \endomit +*/ + +/*! + \externalpage http://www.w3.org/TR/SVGMobile12/ + \title SVG 1.2 Tiny +*/ + +/*! + \externalpage http://www.w3.org/Graphics/SVG/feature/1.2/#SVG-static + \title SVG 1.2 Tiny Static Features +*/ + + + +/*! + \externalpage http://tdm-gcc.tdragon.net/ + \title TDM-GCC +*/ + +/*! + \externalpage http://www.dependencywalker.com/ + \title Dependency Walker +*/ + +/*! + \externalpage http://webkit.org/ + \title WebKit Open Source Project +*/ + +/*! + \externalpage http://www.informit.com/store/product.aspx?isbn=0132354160 + \title C++ GUI Programming with Qt 4, 2nd Edition +*/ + +/*! + \externalpage http://www.openssl.org/ + \title OpenSSL Toolkit +*/ + +/*! + \externalpage http://arora-browser.org/ + \title Arora Browser +*/ + +/*! + \externalpage http://www.activestate.com/Products/activeperl/index.mhtml + \title ActivePerl +*/ + +/*! + \externalpage https://chromium.googlesource.com/angle/angle/+/master/README.md + \title ANGLE +*/ + +/*! + \externalpage http://msdn.microsoft.com/en-us/directx/default.aspx + \title Direct X SDK +*/ + +/*! + \externalpage http://www.w3.org/TR/html401/ + \title HTML 4 +*/ + +/*! + \externalpage http://www.w3.org/TR/html5/ + \title HTML 5 +*/ + +/*! + \externalpage http://site.icu-project.org/ + \title ICU +*/ + +/*! + \externalpage https://mingw-w64.org/ + \title MinGW +*/ + +/*! + \externalpage http://www.python.org/ + \title Python +*/ + +/*! + \externalpage http://pyxml.sourceforge.net/topics/xbel/ + \title XML Bookmark Exchange Language Resource Page +*/ + +/*! + \externalpage http://www.w3.org/TR/xquery/#errors + \title error handling in the XQuery language +*/ + +/*! + \externalpage http://xaos.sourceforge.net/ + \title XaoS +*/ + +/*! + \externalpage http://www.unixodbc.org + \title http://www.unixodbc.org +*/ + +/*! + \externalpage http://www.postgresql.org + \title http://www.postgresql.org +*/ + +/*! + \externalpage http://www.postgresql.org/docs/current/static/installation-platform-notes.html#INSTALLATION-NOTES-MINGW + \title PostgreSQL MinGW/Native Windows +*/ + +/*! + \externalpage http://www.freetds.org + \title http://www.freetds.org +*/ + +/*! + \externalpage http://www.sybase.com + \title http://www.sybase.com +*/ + +/*! + \externalpage http://linux.sybase.com + \title http://linux.sybase.com +*/ + +/*! + \externalpage http://www.sqlite.org + \title http://www.sqlite.org +*/ + +/*! + \externalpage http://www.amazon.com/Threads-Primer-Guide-Multithreaded-Programming/dp/0134436989/ref=sr_1_1?ie=UTF8&qid=1354884049&sr=8-1&keywords=a+guide+to+multithreaded+programming + \title Threads Primer: A Guide to Multithreaded Programming +*/ + +/*! + \externalpage http://www.amazon.com/Thread-Time-MultiThreaded-Programming-Guide/dp/0131900676/ref=sr_1_sc_3?ie=UTF8&qid=1354884427&sr=8-3-spell&keywords=The+Mulltithread+Programming+Guide + \title Thread Time: The Multithreaded Programming Guide +*/ + +/*! + \externalpage http://www.amazon.com/Pthreads-Programming-Standard-Multiprocessing-Nutshell/dp/1565921151/ref=sr_1_1?s=books&ie=UTF8&qid=1354884565&sr=1-1&keywords=threads+Programming%3A+A+POSIX+Standard+for+Better+Multiprocessing + \title Pthreads Programming: A POSIX Standard for Better Multiprocessing +*/ + +/*! + \externalpage http://www.amazon.com/Win32-Multithreaded-Programming-Aaron-Cohen/dp/B00007GW3Z/ref=sr_1_1?s=books&ie=UTF8&qid=1354884647&sr=1-1&keywords=Win32+Multithreaded+Programming + \title Win32 Multithreaded Programming +*/ + +/*! + \externalpage http://www.phptr.com/content/images/0131872494/samplechapter/blanchette_ch10.pdf + \title "Item View Classes" Chapter of C++ GUI Programming with Qt 4 +*/ + +/*! + \externalpage https://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AppleHIGuidelines/Intro/Intro.html + \title Mac OS X Aqua +*/ + +/*! + \externalpage http://www.kdedevelopers.org/node/2345 + \title KDE applications +*/ + +/*! + \externalpage http://cgi.netscape.com/newsref/std/cookie_spec.html + \title Netscape Cookie Specification +*/ + +/*! + \externalpage http://msdn.microsoft.com/en-us/library/ms533046(VS.85).aspx + \title Mitigating Cross-site Scripting With HTTP-only Cookies +*/ + +/*! + \externalpage http://en.tldp.org/HOWTO/Framebuffer-HOWTO.html + \title Framebuffer HOWTO +*/ + +/*! + \externalpage http://wap.trafikanten.no + \title Trafikanten +*/ + +/*! + \externalpage http://www.w3.org/TR/scxml/ + \title State Chart XML: State Machine Notation for Control Abstraction +*/ + +/*! + \externalpage http://www.wisdom.weizmann.ac.il/~dharel/SCANNED.PAPERS/Statecharts.pdf + \title Statecharts: A visual formalism for complex systems +*/ + +/*! + \externalpage http://www.gnu.org/licenses/gpl.html + \title GNU General Public License +*/ + +/*! + \externalpage http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + \title GNU Lesser General Public License, version 2.1 +*/ + +/*! + \externalpage http://developers.sun.com/sunstudio/downloads/patches/index.jsp + \title Sun Studio Patches +*/ + +/*! + \externalpage http://www.qtcentre.org + \title Qt Centre +*/ + +/*! + \externalpage http://www.kde.org + \title KDE +*/ + +/*! + \externalpage http://www.directfb.org/index.php?path=Main%2FDownloads&page=1 + \title DirectFB - df_window example +*/ + +/*! + \externalpage http://www.directfb.org/docs/DirectFB_Reference_1_4/IDirectFBPalette.html + \title DirectFB - IDirectFBPalette +*/ + +/*! + \externalpage http://www.cplusplus.com/reference/clibrary/cstring/memcpy/ + \title C++ Reference - memcpy +*/ + +/*! + \externalpage http://www.directfb.org/docs/DirectFB_Reference_1_4/IDirectFB_CreateInputEventBuffer.html + \title DirectFB - CreateInputEventBuffer +*/ + +/*! + \externalpage http://www.directfb.org/docs/DirectFB_Reference_1_4/types.html#DFBSurfaceBlittingFlags + \title DirectFB - DFBSurfaceBlittingFlags +*/ + +/*! + \externalpage http://directfb.org/docs/DirectFB_Reference_1_4/IDirectFBImageProvider.html + \title DirectFB - IDirectFBImageProvider +*/ + +/*! + \externalpage http://www.directfb.org/docs/DirectFB_Reference_1_4/IDirectFBSurface.html + \title DirectFB - IDirectFBSurface +*/ + +/*! + \externalpage http://www.directfb.org/docs/DirectFB_Reference_1_4/IDirectFBWindow + \title DirectFB - IDirectFBWindow +*/ + +/*! + \externalpage http://www.directfb.org/docs/DirectFB_Reference_1_4/types.html#DFBSurfaceDescription + \title DirectFB - DFBSurfaceDescription +*/ + +/*! + \externalpage http://www.w3.org/TR/REC-CSS2/selector.html#q1 + \title Standard CSS2 selector +*/ + +/*! + \externalpage http://www.w3.org/XML/Core/#Publications + \title W3C XML specifications +*/ + +/*! + \externalpage http://www.w3.org/XML/Schema + \title XML Schema +*/ + +/*! + \externalpage http://opensource.org/licenses/bsd-license.php + \title New and Modified BSD Licenses +*/ + +/*! + \externalpage http://www.ecma-international.org/publications/standards/Ecma-262.htm + \title ECMAScript Language Specification +*/ + +/*! + \externalpage https://developer.mozilla.org/en/JavaScript + \title JavaScript Resources +*/ + +/*! + \externalpage https://developer.mozilla.org/en/JavaScript/Guide + \title JavaScript Guide +*/ + +/*! + \externalpage https://developer.mozilla.org/en/JavaScript/About_JavaScript + \title About JavaScript +*/ + +/*! + \externalpage http://www.libusb.org/ + \title libusb +*/ + +/*! + \externalpage https://developer.mozilla.org/en/JavaScript/Reference/Reserved_Words + \title JavaScript Reserved Words +*/ + +/*! + \externalpage http://publicsuffix.org/ + \title publicsuffix.org +*/ + +/*! + \externalpage http://accessibility.linuxfoundation.org/a11yspecs/ia2/docs/html/_accessible_event_i_d_8idl.html + \title AccessibleEventID.idl File Reference +*/ + +/*! + \externalpage http://msdn.microsoft.com/en-us/library/dd318066.aspx + \title Microsoft Active Accessibility Event Constants +*/ + +/*! + \externalpage ftp://ftp.qt-project.org/pub/qt/solutions/lgpl/qtmotifextension-2.7_1-opensource.tar.gz + \title Motif Extension +*/ + +/*! + \externalpage http://www.opengl.org/registry/ + \title OpenGL Registry +*/ + +/*! + \externalpage http://www.khronos.org/registry/gles/ + \title Khronos OpenGL ES API Registry +*/ + +/*! + \externalpage https://github.com/iksaif/qsslkey-p11 + \title qsslkey example +*/ + +/*! + \externalpage http://www.w3.org/TR/2009/WD-webdatabase-20091029/ + \title HTML5 Web Database API +*/ + +/*! + \externalpage http://lldb.llvm.org/ + \title The LLDB Debugger +*/ + +/*! + \externalpage https://login.qt.io/ + \title Qt Account Sign-up +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/externalsites/qt-webpages.qdoc b/dde-file-manager-5.5.3/docs/qdoc-configs/externalsites/qt-webpages.qdoc new file mode 100644 index 0000000..f17f85d --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/externalsites/qt-webpages.qdoc @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ +/*! + \externalpage http://qt.io/ + \title Qt Homepage +*/ +/*! + \externalpage http://bugreports.qt.io + \title Qt Bug Tracker +*/ +/*! + \externalpage http://qt.io/download + \title Downloads +*/ +/*! + \externalpage http://www.qt.io/about-us/ + \title The Qt Company +*/ +/*! + \externalpage http://qt.io/licensing/ + \title Qt Licensing Overview +*/ +/*! + \externalpage http://doc.qt.io/archives/qq/ + \title Qt Quarterly +*/ +/*! + \externalpage http://doc.qt.io/archives/qq/qq19-plurals.html + \title Qt Quarterly: Plural Form in Translation +*/ +/*! + \externalpage https://code.qt.io/ + \title Public Qt Repository +*/ +/*! + \externalpage https://code.qt.io/cgit/%7bnon-gerrit%7d/qt-labs/qtestlib-tools.git/ + \title qtestlib-tools +*/ + +/*! + \externalpage http://wiki.qt.io/Qt_Coding_Style + \title Qt Coding Style +*/ +/*! + \externalpage http://doc.qt.io/archives/qt-eclipse-1.6/index.html + \title Eclipse Plugin +*/ +/*! + \externalpage http://doc.qt.io/archives/qq/qq11-events.html + \title Qt Quarterly: Another Look at Events +*/ +/*! + \externalpage https://www.youtube.com/watch?v=P4kv-AoAJ-Q + \title Livecoding video effects with Qt5 +*/ +/*! + \externalpage http://blog.qt.io/2012/02/29/pimp-my-video-shader-effects-and-multimedia/ + \title Pimp my video +*/ +/*! + \externalpage http://wiki.qt.io/QtMediaHub + \title QtMediaHub +*/ +/*! + \externalpage http://wiki.qt.io/Qt_RaspberryPi + \title QtonPi +*/ + +/*! + \externalpage http://wiki.qt.io/jom + \title jom +*/ + +/*! + \externalpage http://doc.qt.io/qt-4.8 + \title Qt 4.8 Reference Documentation +*/ + +/*! + \externalpage http://doc.qt.io/qt-4.8/qtquick.html + \title Qt Quick 1 Reference Documentation +*/ + +/*! + \externalpage http://wiki.qt.io/Qt_Localization + \title external: Translating Qt Into Other Languages +*/ + +/*! + \externalpage http://wiki.qt.io/Qt_Multimedia_Backends + \title Qt Multimedia Backends +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/externalsites/qtcreator.qdoc b/dde-file-manager-5.5.3/docs/qdoc-configs/externalsites/qtcreator.qdoc new file mode 100644 index 0000000..7f2322d --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/externalsites/qtcreator.qdoc @@ -0,0 +1,551 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \externalpage http://doc.qt.io/qtcreator/creator-deployment-qnx.html + \title Qt Creator: Deploying Applications to QNX Neutrino Devices +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-developing-baremetal.html + \title Qt Creator: Connecting Bare Metal Devices +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-developing-qnx.html + \title Qt Creator: Connecting QNX Devices +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-developing-generic-linux.html + \title Qt Creator: Connecting Embedded Linux Devices +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-deployment-embedded-linux.html + \title Qt Creator: Deploying Applications to Embedded Linux Devices +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-faq.html + \title Qt Creator: FAQ +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-tips.html + \title Qt Creator: Tips and Tricks +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-help.html + \title Qt Creator: Using the Help Mode +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-quick-tour.html + \title Qt Creator: User Interface +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-cli.html + \title Qt Creator: Using Command Line Options +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-task-lists.html + \title Qt Creator: Showing Task List Files in Issues Pane +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-managing-sessions.html + \title Qt Creator: Managing Sessions +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-editor-external.html + \title Qt Creator: Using External Tools +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-version-control.html + \title Qt Creator: Using Version Control Systems +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-bazaar.html + \title Qt Creator: Using Bazaar +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-clearcase.html + \title Qt Creator: Using ClearCase +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-cvs.html + \title Qt Creator: Using CVS +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-git.html + \title Qt Creator: Using Git +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-mercurial.html + \title Qt Creator: Using Mercurial +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-perforce.html + \title Qt Creator: Using Perforce +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-vcs-subversion.html + \title Qt Creator: Using Subversion +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-keyboard-shortcuts.html + \title Qt Creator: Keyboard Shortcuts +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/quick-screens.html + \title Qt Creator: Creating Screens +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/qmldesigner-pathview-editor.html + \title Qt Creator: Editing PathView Properties +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/qmldesigner-connections.html + \title Qt Creator: Adding Connections +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/qtcreator-transitions-example.html + \title Qt Creator: Creating a Qt Quick Application +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/qtquick-iso-icon-browser.html + \title Qt Creator: Browsing ISO 7000 Icons +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/quick-export-to-qml.html + \title Qt Creator: Exporting Designs from Graphics Software +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-qml-modules-with-plugins.html + \title Qt Creator: Using QML Modules with Plugins +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-visual-editor.html + \title Qt Creator: Developing Qt Quick Applications +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-using-qt-quick-designer.html + \title Qt Creator: Using Qt Quick Designer +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/quick-projects.html + \title Qt Creator: Creating Qt Quick Projects +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/quick-components.html + \title Qt Creator: Creating Components +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/qt-quick-toolbars.html + \title Qt Creator: Using Qt Quick Toolbars +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/quick-buttons.html + \title Qt Creator: Creating Buttons +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/quick-scalable-image.html + \title Qt Creator: Creating Scalable Buttons and Borders +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-editor-options.html + \title Qt Creator: Configuring the Editor +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-editor-functions.html + \title Qt Creator: Writing Code +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-coding-navigating.html + \title Qt Creator: Working in Edit Mode +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-highlighting.html + \title Qt Creator: Semantic Highlighting +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-checking-code-syntax.html + \title Qt Creator: Checking Code Syntax +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-completing-code.html + \title Qt Creator: Completing Code +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-editor-codepasting.html + \title Qt Creator: Pasting and Fetching Code Snippets +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-macros.html + \title Qt Creator: Using Text Editing Macros +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-editor-fakevim.html + \title Qt Creator: Using FakeVim Mode +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-indenting-code.html + \title Qt Creator: Indenting Text or Code +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-editor-finding.html + \title Qt Creator: Finding and Replacing +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-editor-refactoring.html + \title Qt Creator: Refactoring +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-editor-locator.html + \title Qt Creator: Searching with the Locator +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-coding.html + \title Qt Creator: Coding +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-editor-options-text.html + \title Qt Creator: Specifying Text Editor Settings +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-finding-overview.html + \title Qt Creator: Finding +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-mime-types.html + \title Qt Creator: Editing MIME Types +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-modeling.html + \title Qt Creator: Modeling +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-qml-debugging-example.html + \title Qt Creator: Debugging a Qt Quick Example Application +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-debugging-example.html + \title Qt Creator: Debugging a C++ Example Application +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-debugger-engines.html + \title Qt Creator: Setting Up Debugger +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-debugging-qml.html + \title Qt Creator: Debugging Qt Quick Projects +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-debugging.html + \title Qt Creator: Debugging +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-debugger-operating-modes.html + \title Qt Creator: Launching the Debugger +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-debug-mode.html + \title Qt Creator: Interacting with the Debugger +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-debugging-helpers.html + \title Qt Creator: Using Debugging Helpers +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-troubleshooting-debugging.html + \title Qt Creator: Troubleshooting Debugger +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/index.html + \title Qt Creator Manual +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-advanced.html + \title Qt Creator: Advanced Use +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-os-supported-platforms.html + \title Qt Creator: Supported Platforms +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-connecting-mobile.html + \title Qt Creator: Connecting Devices +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-usability.html + \title Qt Creator: Optimizing Applications for Mobile Devices +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-acknowledgements.html + \title Qt Creator: Acknowledgements +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-help-overview.html + \title Qt Creator: Getting Help +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/technical-support.html + \title Qt Creator: Technical Support +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-overview.html + \title Qt Creator: IDE Overview +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-testing.html + \title Qt Creator: Testing +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-deployment.html + \title Qt Creator: Deploying to Devices +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-tutorials.html + \title Qt Creator: Tutorials +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-known-issues.html + \title Qt Creator: Known Issues +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-design-mode.html + \title Qt Creator: Designing User Interfaces +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-glossary.html + \title Qt Creator: Glossary +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-getting-started.html + \title Qt Creator: Getting Started +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-analyzer.html + \title Qt Creator: Detecting Memory Leaks +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-cache-profiler.html + \title Qt Creator: Profiling Function Execution +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-running-valgrind-remotely.html + \title Qt Creator: Running Valgrind Tools Remotely +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-valgrind-overview.html + \title Qt Creator: Using Valgrind Code Analysis Tools +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-analyze-mode.html + \title Qt Creator: Analyzing Code +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-qml-performance-monitor.html + \title Qt Creator: Profiling QML Applications +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-deploying-android.html + \title Qt Creator: Deploying Applications to Android Devices +*/ + +/*! + \externalpage http://doc.qt.io/qtcreator/creator-developing-ios.html + \title Qt Creator: Connecting iOS devices +*/ + +/*! + \externalpage http://doc.qt.io/qtcreator/creator-developing-android.html + \title Qt Creator: Connecting Android Devices +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-build-example-application.html + \title Qt Creator: Building and Running an Example +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-generic.html + \title Qt Creator: Setting Up a Generic Project +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-sharing-project-settings.html + \title Qt Creator: Sharing Project Settings +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-opening.html + \title Qt Creator: Opening Projects +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-managing.html + \title Qt Creator: Managing Projects +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-cmake.html + \title Qt Creator: Setting Up CMake +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-targets.html + \title Qt Creator: Adding Kits +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-tool-chains.html + \title Qt Creator: Adding Compilers +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-qbs.html + \title Qt Creator: Setting Up Qbs +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-creating.html + \title Qt Creator: Creating Projects +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-wizards.html + \title Qt Creator: Adding New Custom Wizards +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-wizards-json.html + \title Qt Creator: Adding JSON-Based Wizards +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-wizards-xml.html + \title Qt Creator: Adding XML-Based Wizards +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-projects-autotools.html + \title Qt Creator: Setting Up an Autotools Project +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-configuring-projects.html + \title Qt Creator: Configuring Projects +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-build-process-customizing.html + \title Qt Creator: Customizing the Build Process +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-build-settings.html + \title Qt Creator: Specifying Build Settings +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-code-style-settings.html + \title Qt Creator: Specifying Code Style Settings +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-run-settings.html + \title Qt Creator: Specifying Run Settings +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-qmake-libraries.html + \title Qt Creator: Adding Libraries to Projects +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-other.html + \title Qt Creator: Using Other Build Systems +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-running-targets.html + \title Qt Creator: Running on Multiple Platforms +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-build-dependencies.html + \title Qt Creator: Specifying Dependencies +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-building-running.html + \title Qt Creator: Building and Running +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-editor-settings.html + \title Qt Creator: Specifying Editor Settings +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-qmake.html + \title Qt Creator: Adding Qt Versions +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-building-targets.html + \title Qt Creator: Building for Multiple Platforms +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-using-qt-designer.html + \title Qt Creator: Developing Widget Based Applications +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-writing-program.html + \title Qt Creator: Creating a Qt Widget Based Application +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/adding-plugins.html + \title Qt Creator: Adding Qt Designer Plugins +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-configuring.html + \title Qt Creator: Configuring Qt Creator +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-debuggers.html + \title Qt Creator: Adding Debuggers +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/qtcreator-accelbubble-example.html + \title Qt Creator: Creating a Mobile Application +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-diff-editor.html + \title Qt Creator: Comparing Files +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-beautifier.html + \title Qt Creator: Beautifying Source Code +*/ + +/*! + \externalpage http://doc.qt.io/qtcreator/creator-clang-codemodel.html + \title Qt Creator: Parsing C++ Files with the Clang Code Model +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-quick-ui-forms.html + \title Qt Creator: Qt Quick UI Forms +*/ + +/*! + \externalpage http://doc.qt.io/qtcreator/creator-clang-static-analyzer.html + \title Qt Creator: Using Clang Static Analyzer +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-cpu-usage-analyzer.html + \title Qt Creator: Analyzing CPU Usage +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-autotest.html + \title Qt Creator: Running Autotests +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-project-creating.html#creating-c-classes + \title Qt Creator: Creating C++ Classes +*/ +/*! + \externalpage http://doc.qt.io/qtcreator/creator-writing-program.html + \title Creating a Qt Widget Based Application +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/externalsites/rfc.qdoc b/dde-file-manager-5.5.3/docs/qdoc-configs/externalsites/rfc.qdoc new file mode 100644 index 0000000..411decd --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/externalsites/rfc.qdoc @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \externalpage http://www.ietf.org/rfc/rfc1179.txt + \title RFC 1179 + \keyword lpr +*/ + +/*! + \externalpage http://www.rfc-editor.org/rfc/rfc1738.txt + \title RFC 1738 +*/ + +/*! + \externalpage http://www.rfc-editor.org/rfc/rfc1928.txt + \title RFC 1928 +*/ + +/*! + \externalpage http://www.rfc-editor.org/rfc/rfc1929.txt + \title RFC 1929 +*/ + +/*! + \externalpage http://www.rfc-editor.org/rfc/rfc2045.txt + \title RFC 2045 +*/ + +/*! + \externalpage http://www.rfc-editor.org/rfc/rfc2109.txt + \title RFC 2109 + HTTP State Management Mechanism +*/ + +/*! + \externalpage http://www.rfc-editor.org/rfc/rfc2965.txt + \title RFC 2965 + HTTP State Management Mechanism +*/ + +/*! + \externalpage http://www.rfc-editor.org/rfc/rfc3174.txt + \title RFC 3174 +*/ + +/*! + \externalpage http://www.rfc-editor.org/rfc/rfc3491.txt + \title RFC 3491 +*/ + +/*! + \externalpage http://www.rfc-editor.org/rfc/rfc3986.txt + \title RFC 3986 +*/ + +/*! + \externalpage http://www.rfc-editor.org/rfc/rfc2822.txt + \title RFC 2822 +*/ + +/*! + \externalpage http://www.rfc-editor.org/rfc/rfc1036.txt + \title RFC 1036 +*/ + +/*! + \externalpage http://www.rfc-editor.org/rfc/rfc850.txt + \title RFC 850 +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/html-config.qdocconf b/dde-file-manager-5.5.3/docs/qdoc-configs/html-config.qdocconf new file mode 100644 index 0000000..9b3b05b --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/html-config.qdocconf @@ -0,0 +1,31 @@ +#Additional HTML settings + +HTML.nonavigationbar = "false" + +HTML.tocdepth = 2 + +HTML.extraimages += template/images/arrow_bc.png \ + template/images/home.png \ + template/images/ico_out.png \ + template/images/ico_note.png \ + template/images/ico_note_attention.png \ + template/images/btn_prev.png \ + template/images/btn_next.png \ + template/images/bullet_dn.png \ + template/images/bullet_sq.png \ + template/images/bgrContent.png \ + template/images/logo.png + +#specify which files in the output directory should be packed into the qch file. +#these files are assumed to be in each module's output directory."qtquick/images/ico_out.png" for example. +qhp.extraFiles += images/arrow_bc.png \ + images/home.png \ + images/ico_out.png \ + images/ico_note.png \ + images/ico_note_attention.png \ + images/btn_prev.png \ + images/btn_next.png \ + images/bullet_dn.png \ + images/bullet_sq.png \ + images/bgrContent.png \ + images/logo.png diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/html-footer-online.qdocconf b/dde-file-manager-5.5.3/docs/qdoc-configs/html-footer-online.qdocconf new file mode 100644 index 0000000..7168c68 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/html-footer-online.qdocconf @@ -0,0 +1,9 @@ +# HTML footer for qt.io + +HTML.footer += \ + "\n" \ + "\n" \ + "\n" \ + "\n" \ + "\n" + diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/html-footer.qdocconf b/dde-file-manager-5.5.3/docs/qdoc-configs/html-footer.qdocconf new file mode 100644 index 0000000..d7bd833 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/html-footer.qdocconf @@ -0,0 +1,20 @@ +#Default HTML footer for QDoc builds. + +HTML.footer = \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + "\n" \ + "
\n" \ + "

\n" \ + " © 2018 Deepin Technology Ltd.\n" \ + " Documentation contributions included herein are the copyrights of\n" \ + " their respective owners.
" \ + " The documentation provided herein is licensed under the terms of the" \ + " GNU Free Documentation" \ + " License version 1.3 as published by the Free Software Foundation.
" \ + " Qt and respective logos are trademarks of The Qt Company Ltd. " \ + " in Finland and/or other countries worldwide. All other trademarks are property\n" \ + " of their respective owners.

\n" \ + "
\n" \ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/html-header-offline.qdocconf b/dde-file-manager-5.5.3/docs/qdoc-configs/html-header-offline.qdocconf new file mode 100644 index 0000000..d84f38f --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/html-header-offline.qdocconf @@ -0,0 +1,31 @@ +#Default HTML header for QDoc builds. + +#specify the CSS file used by this template +HTML.stylesheets = template/style/offline.css + +#for including files into the qch file +qhp.extraFiles += style/offline.css + +HTML.headerstyles = \ + " \n" + +HTML.endheader = \ + "\n" + +HTML.postheader = \ + "\n" \ + "
\n"\ + "
\n" \ + "
\n" \ + "
\n"\ + "
    \n"\ + + + +HTML.postpostheader = \ + "
\n"\ + "
\n" \ + "
\n" \ + "
\n" \ + "
\n" \ + "
\n" \ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/html-header-online.qdocconf b/dde-file-manager-5.5.3/docs/qdoc-configs/html-header-online.qdocconf new file mode 100644 index 0000000..482bd41 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/html-header-online.qdocconf @@ -0,0 +1,55 @@ +# HTML Header with qt.io branding and online links + +HTML.stylesheets = template/style/online.css \ + template/style/gsc.css \ + template/style/list_arrow.png \ + template/style/list_expand.png \ + template/style/icomoon.eot \ + template/style/icomoon.svg \ + template/style/icomoon.ttf \ + template/style/icomoon.woff \ + template/style/cookiebar-x.png \ + template/style/doc_search.png \ + template/style/theqtcompany.png + +#for including files into the qch file. Relative to the outputdir of a QDoc build. +qhp.extraFiles += style/online.css \ + style/gsc.css \ + style/list_arrow.png \ + style/list_expand.png \ + style/icomoon.eot \ + style/icomoon.svg \ + style/icomoon.ttf \ + style/icomoon.woff \ + style/cookiebar-x.png \ + style/doc_search.png \ + style/theqtcompany.png + +HTML.headerstyles = \ + " \n" + +HTML.scripts = template/scripts/extras.js \ + template/scripts/main.js + +HTML.endheader = \ + "\n" + +# minimal header +HTML.postheader = \ + "\n" \ + "
\n"\ + "
\n" \ + "
\n" \ + "
\n"\ + "
    \n"\ + +HTML.postpostheader = \ + "
\n"\ + "
\n" \ + "
\n" \ + "
\n" \ + "
\n" \ + "
\n" \ + +HTML.prologue = \ + "
\n" diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/includes-online/search.qdoc b/dde-file-manager-5.5.3/docs/qdoc-configs/includes-online/search.qdoc new file mode 100644 index 0000000..8d3c7d2 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/includes-online/search.qdoc @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page search-results.html +\title Search Results + +\raw HTML + + + +\endraw +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/includes/examples-run.qdocinc b/dde-file-manager-5.5.3/docs/qdoc-configs/includes/examples-run.qdocinc new file mode 100644 index 0000000..e9b8575 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/includes/examples-run.qdocinc @@ -0,0 +1,5 @@ +\section1 Running the Example + +To run the example from \l{Qt Creator Manual}{Qt Creator}, open the \gui Welcome +mode and select the example from \gui Examples. For more information, visit +\l{Qt Creator: Building and Running an Example}{Building and Running an Example}. diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/qt-html-templates-offline-simple.qdocconf b/dde-file-manager-5.5.3/docs/qdoc-configs/qt-html-templates-offline-simple.qdocconf new file mode 100644 index 0000000..4a65cc3 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/qt-html-templates-offline-simple.qdocconf @@ -0,0 +1,35 @@ +# Specify a custom CSS file used by this template +HTML.stylesheets += template/style/offline-simple.css +qhp.extraFiles += style/offline-simple.css + +# Override the header styles +HTML.headerstyles = \ + " \n" \ + " \n" + +HTML.postheader = \ + "\n" \ + "
\n"\ + "
\n" \ + "
\n" \ + "
\n" \ + " \n" + +HTML.postpostheader = \ + "
\n"\ + "
\n" \ + "
\n" \ + "
\n" \ + "
\n" \ + "
\n" + +HTML.navigationseparator = \ + "\n" + +# Add some padding around code snippets, as we cannot +# currectly style them for QTextBrowser using only CSS. +codeindent = 2 +codeprefix = "\n\n" +codesuffix = "\n\n" diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/qt-html-templates-offline.qdocconf b/dde-file-manager-5.5.3/docs/qdoc-configs/qt-html-templates-offline.qdocconf new file mode 100644 index 0000000..07f26d1 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/qt-html-templates-offline.qdocconf @@ -0,0 +1,33 @@ +#include standard set of HTML header and footer. +include(html-config.qdocconf) +include(html-header-offline.qdocconf) +include(html-footer.qdocconf) + +#uncomment if navigation bar is not wanted +#HTML.nonavigationbar = "true" + +HTML.stylesheets = template/style/offline.css +HTML.extraimages += template/images/ico_out.png \ + template/images/ico_note.png \ + template/images/ico_note_attention.png \ + template/images/btn_prev.png \ + template/images/btn_next.png \ + template/images/bullet_dn.png \ + template/images/bullet_sq.png \ + template/images/bgrContent.png + +#specify which files in the output directory should be packed into the qch file. +qhp.extraFiles += style/offline.css \ + images/ico_out.png \ + images/ico_note.png \ + images/ico_note_attention.png \ + images/btn_prev.png \ + images/btn_next.png \ + images/bullet_dn.png \ + images/bullet_sq.png \ + images/bgrContent.png + +# By default, include override definitions for a simplified template/CSS, +# suited for rendering HTML with QTextBrowser. Comment out this line to +# select the standard CSS. +#include(qt-html-templates-offline-simple.qdocconf) diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/qt-html-templates-online.qdocconf b/dde-file-manager-5.5.3/docs/qdoc-configs/qt-html-templates-online.qdocconf new file mode 100644 index 0000000..69c399d --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/qt-html-templates-online.qdocconf @@ -0,0 +1,10 @@ +#include standard set of HTML header and footer. +HTML.nonavigationbar = "false" +HTML.tocdepth = 2 +include(html-header-online.qdocconf) +include(html-footer-online.qdocconf) + +#uncomment if navigation bar is not wanted +#HTML.nonavigationbar = "true" + +sourcedirs += includes-online diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-dark_gradient.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-dark_gradient.png new file mode 100644 index 0000000..6ae10f3 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-dark_gradient.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-footer-bg.jpg b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-footer-bg.jpg new file mode 100644 index 0000000..c0ff209 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-footer-bg.jpg differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-footer_shadow.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-footer_shadow.png new file mode 100644 index 0000000..5a7063d Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-footer_shadow.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-gradient.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-gradient.png new file mode 100644 index 0000000..aa38227 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-gradient.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-header-bg.jpg b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-header-bg.jpg new file mode 100644 index 0000000..c9a6d96 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-header-bg.jpg differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-logo.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-logo.png new file mode 100644 index 0000000..01256ab Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/Qt-logo.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/arrow.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/arrow.png new file mode 100644 index 0000000..f2a83a5 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/arrow.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/arrow_bc.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/arrow_bc.png new file mode 100644 index 0000000..f2a83a5 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/arrow_bc.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/arrow_down.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/arrow_down.png new file mode 100644 index 0000000..9d01e97 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/arrow_down.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_l.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_l.png new file mode 100644 index 0000000..90b1da1 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_l.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_l_blank.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_l_blank.png new file mode 100644 index 0000000..5a9673d Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_l_blank.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_ll_blank.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_ll_blank.png new file mode 100644 index 0000000..95a1c45 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_ll_blank.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_r.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_r.png new file mode 100644 index 0000000..f0fb121 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_r.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_ul_blank.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_ul_blank.png new file mode 100644 index 0000000..7051261 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bg_ul_blank.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bgrContent.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bgrContent.png new file mode 100644 index 0000000..1a81b03 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bgrContent.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/blu_dot.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/blu_dot.png new file mode 100644 index 0000000..c332148 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/blu_dot.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/box_bg.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/box_bg.png new file mode 100644 index 0000000..3322f92 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/box_bg.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/breadcrumb.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/breadcrumb.png new file mode 100644 index 0000000..0ded551 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/breadcrumb.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/btn_next.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/btn_next.png new file mode 100644 index 0000000..c649f18 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/btn_next.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/btn_prev.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/btn_prev.png new file mode 100644 index 0000000..d1d2989 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/btn_prev.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bullet_dn.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bullet_dn.png new file mode 100644 index 0000000..f776247 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bullet_dn.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bullet_gt.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bullet_gt.png new file mode 100644 index 0000000..7561b4e Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bullet_gt.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bullet_sq.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bullet_sq.png new file mode 100644 index 0000000..a84845e Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bullet_sq.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bullet_up.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bullet_up.png new file mode 100644 index 0000000..7de2f06 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/bullet_up.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/feedbackground.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/feedbackground.png new file mode 100644 index 0000000..3a38d99 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/feedbackground.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/header_bg.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/header_bg.png new file mode 100644 index 0000000..a436aa6 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/header_bg.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/home.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/home.png new file mode 100644 index 0000000..8de6d0c Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/home.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/horBar.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/horBar.png new file mode 100644 index 0000000..100fe91 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/horBar.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/ico_note.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/ico_note.png new file mode 100644 index 0000000..1379404 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/ico_note.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/ico_note_attention.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/ico_note_attention.png new file mode 100644 index 0000000..b85b696 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/ico_note_attention.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/ico_out.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/ico_out.png new file mode 100644 index 0000000..790a05e Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/ico_out.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/logo.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/logo.png new file mode 100644 index 0000000..698dde9 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/logo.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/page.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/page.png new file mode 100644 index 0000000..1db151b Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/page.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/page_bg.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/page_bg.png new file mode 100644 index 0000000..9b3bd99 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/page_bg.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/spinner.gif b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/spinner.gif new file mode 100644 index 0000000..1ed786f Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/spinner.gif differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/sprites-combined.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/sprites-combined.png new file mode 100644 index 0000000..c4f01c4 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/images/sprites-combined.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/scripts/extras.js b/dde-file-manager-5.5.3/docs/qdoc-configs/template/scripts/extras.js new file mode 100644 index 0000000..ba7a4a5 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/template/scripts/extras.js @@ -0,0 +1,80 @@ +var vOffset_init = 65; +var vOffset = vOffset_init; +var c = 'collapsed'; + +function toggleList(toggle, content, maxItems) { + if (toggle.css('display') == 'none') { + vOffset = vOffset_init; + toggle.removeClass(c); + content.show(); + return; + } else + vOffset = 8; + + if (maxItems > content.children().length) + return; + content.hide(); + toggle.addClass(c); +} + +$(function () { + $('a[href*=#]:not([href=#])').on('click', function (e) { + if (e.which == 2 || e.metaKey || e.ctrlKey || e.shiftKey) + return true; + var target = $(this.hash.replace(/(\.)/g, "\\$1")); + target = target.length ? target : $('[name=' + this.hash.slice(1) + ']'); + if (target.length) { + setTimeout(function () { + $('html, body').animate({scrollTop: target.offset().top - vOffset}, 50);}, 50); + } + }); +}); + +$(window).load(function () { + var hashChanged = function() { + var h = window.location.hash; + var re = /[^a-z0-9_\.\#\-]/i + if (h.length > 1 && !re.test(h)) { + setTimeout(function () { + var tgt = $(h.replace(/(\.)/g, "\\$1")); + tgt = tgt.length ? tgt : $('[name=' + h.slice(1) + ']'); + $(window).scrollTop(tgt.offset().top - vOffset); + }, 0); + } + } + $(window).bind('hashchange', hashChanged); + hashChanged.call(); + + if (!$('.sidebar toc').is(':empty')) { + $('
').prependTo('.sidebar .toc'); + var toc = $('.sidebar .toc ul'); + var tocToggle = $('#toc-toggle'); + var tocCallback = function() { toggleList(tocToggle, toc, 4); }; + + $('#toc-toggle').on('click', function(e) { + e.stopPropagation(); + toc.toggle(); + tocToggle.toggleClass(c); + }); + + tocCallback.call(); + $(window).resize(tocCallback); + } + + if (!$('#sidebar-content').is(':empty')) { + $('#sidebar-content h2').first().clone().prependTo('#sidebar-content'); + $('').prependTo('#sidebar-content'); + var sb = $('#sidebar-content .sectionlist'); + var sbToggle = $('#sidebar-toggle'); + var sbCallback = function() { toggleList(sbToggle, sb, 0); }; + + $('#sidebar-toggle').on('click', function(e) { + e.stopPropagation(); + sb.toggle(); + sbToggle.toggleClass(c); + }); + + sbCallback.call(); + $(window).resize(sbCallback); + } +}); diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/scripts/main.js b/dde-file-manager-5.5.3/docs/qdoc-configs/template/scripts/main.js new file mode 100644 index 0000000..823cebe --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/template/scripts/main.js @@ -0,0 +1,241 @@ +"use strict"; + +function createCookie(name, value, days) { + var expires; + if (days) { + var date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = "; expires=" + date.toGMTString(); + } else { + expires = ""; + } + document.cookie = escape(name) + "=" + escape(value) + expires + "; path=/"; + $('.cookies_yum').click(function() { + $(this).fadeOut() + }); +} +function readCookie(name) { + var nameEQ = escape(name) + "="; + var ca = document.cookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) === ' ') c = c.substring(1, c.length); + if (c.indexOf(nameEQ) === 0) return unescape(c.substring(nameEQ.length, c.length)); + } + return null; +} +function eraseCookie(name) { + createCookie(name, "", -1); +} +function load_sdk(s, id, src) { + var js, fjs = document.getElementsByTagName(s)[0]; + if (document.getElementById(id)) return; + js = document.createElement(s); + js.id = id; + js.src = src; + fjs.parentNode.insertBefore(js, fjs); +} +$(document).ready(function($) { + if (document.documentElement.clientWidth < 1280) { + oneQt.extraLinksToMain(); + } + + $('#menuextras .search').click(function(e){ + e.preventDefault(); + $('.big_bar.account').slideUp(); + $('.big_bar.search').slideToggle(); + $('.big_bar_search').focus(); + $(this).toggleClass('open'); + }); + $('.cookies_yum').click(function() { + $('.cookies_yum').fadeOut(); + createCookie("cookies_nom", "yum", 180); + var cookie_added = 1; + }); + if (!(readCookie('cookies_nom') == 'yum')) { + $('.cookies_yum').fadeIn(); + } else { + var cookie_added = 1; + } + + Modernizr.load({test: Modernizr.input.placeholder, + nope: wpThemeFolder + '/js/placeholders.min.js'}); + + $('#navbar .navbar-toggle').click(function(e) { + e.preventDefault(); + if ($(this).hasClass('opened')) { + $(this).removeClass('opened'); + $('#navbar .navbar-menu').css('max-height', '0px'); + } + else { + $(this).addClass('opened'); + $('#navbar .navbar-menu').css('max-height', $('#navbar .navbar-menu ul').outerHeight() + 'px'); + } + }); + + $(window).resize(function() { + oneQt.stickySidebar(); + oneQt.footerPosition(); + if (document.documentElement.clientWidth < 1280) { + oneQt.extraLinksToMain(); + } else { + oneQt.mainLinkstoExtra(); + } + }); + + $(window).scroll(function() { + oneQt.stickySidebar(); + oneQt.stickyHeader(); + }); + + oneQt.stickySidebar(); + oneQt.footerPosition(); + oneQt.tabContents(); +}); + +$( window ).load(function() { + load_sdk('script', 'facebook-jssdk','//connect.facebook.net/en_US/sdk.js#xfbml=1&appId=207346529386114&version=v2.0'); + load_sdk('script', 'twitter-wjs', '//platform.twitter.com/widgets.js'); + $.getScript("//www.google.com/jsapi", function(){ + google.load("feeds", "1", {"callback": oneQt.liveFeeds}); + }); +}); + +var oneQt = { + stickySidebar: function() { + if ($('#sidebar').length && $('#sidebar').outerHeight() > 20) { + var $sidebar = $('#sidebar'); + var $win = $(window); + var $sidebarContainer = $sidebar.parent(); + var headerHeight = $('#navbar').outerHeight(); + if ($win.outerHeight() - headerHeight > $sidebar.innerHeight() && + $win.scrollTop() > $sidebarContainer.offset().top) { + var newTop = headerHeight + $win.scrollTop() - $sidebarContainer.offset().top; + if (newTop + $sidebar.innerHeight() > $sidebarContainer.innerHeight()) + newTop = $sidebarContainer.innerHeight() - $sidebar.innerHeight(); + + $sidebar.css({top: newTop +'px'}) + } + else { + $sidebar.css({top: '0'}) + } + } + }, + + footerPosition: function () { + $('#footerbar').removeClass('fixed'); + if (($('.hbspt-form').length > 0) || ($('#customerInfo').length > 0) || ($('.purchase_bar').length > 0)) { + var footerBottomPos = $('#footerbar').offset().top + $('#footerbar').outerHeight(); + if (footerBottomPos < $(window).height()) + $('#footerbar').addClass('fixed'); + } + }, + + stickyHeader: function () { + var originalHeaderHeight = 79; + if ($(window).scrollTop() > originalHeaderHeight) { + $('#navbar').addClass('fixed'); + $('#bottom_header').fadeOut(); + + if (!(cookie_added == 1)) { + $('.cookies_yum').fadeOut(); + createCookie("cookies_nom", "yum", 180); + var cookie_added = 1; + } + } + else { + $('#navbar').removeClass('fixed'); + $('#bottom_header').fadeIn(); + } + }, + + tabContents: function () { + $('.tab-container').each(function(i) { + var $el = $(this); + $el.find('.tab-titles li:eq(0)').addClass('active'); + $el.find('.tab-contents .tab:eq(0)').addClass('active'); + $el.find('.tab-titles a').click(function(e) { + e.preventDefault(); + var index = $(this).parent().index(); + $el.find('.tab-titles li').removeClass('active'); + $el.find('.tab-contents .tab').removeClass('active'); + $(this).parent().addClass('active'); + $el.find('.tab-contents .tab').eq(index).addClass('active'); + }) + }); + }, + + liveFeeds: function () { + $('.feed-container').each(function(i) { + var feedUrl = $(this).data('url'); + if (feedUrl != "") oneQt.blogFeed($(this), feedUrl); + }); + }, + + blogFeed: function ($container, feedUrl) { + var feed = new google.feeds.Feed(feedUrl); + feed.setNumEntries(3); + feed.load(function(result) { + $container.html(''); + if (!result.error) { + for (var i = 0; i < result.feed.entries.length; i++) { + var entry = result.feed.entries[i]; + var $article = $('
'); + $container.append($article); + var html = '
'; + html += ' '; + html += '
'; + html += '
'; + html += '

' + html += '

' + html += '

'; + html += '
    '; + html += '
'; + html += '
'; + $article.append(html); + $article.find('h4 a').text(result.feed.title); + $article.find('h3 a').text(entry.title); + $article.find('p a').text(entry.author); + try { + for (var j=0; j'); + $li.find('a').text(entry.categories[j]); + $article.find('.taglist').append($li); + } + } catch(e) {} + } + if (result.feed.link && result.feed.link != "") { + var linkHtml = 'Show all'; + $container.append(linkHtml); + } + } + }); + }, + + extraLinksToMain: function() { + var extramenuLinks = $('#menuextras').find('li'); + var mainmenu = $('#mainmenu'); + var count = 0; + if ($(extramenuLinks).length > 2) { + $(extramenuLinks).each(function() { + if (count < 3) { + var newLink = $(this); + $(newLink).addClass('dynamic-add'); + $(mainmenu).append(newLink); + } + count++; + }); + } + }, + + mainLinkstoExtra: function() { + var mainmenuLinks = $('#mainmenu').find('.dynamic-add'); + var extramenu = $('#menuextras'); + var count = 0; + $(mainmenuLinks).each(function() { + var newLink = $(this); + $(extramenu).prepend(newLink); + count++; + }); + } +} diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/cookiebar-x.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/cookiebar-x.png new file mode 100644 index 0000000..6aea1e6 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/cookiebar-x.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/doc_search.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/doc_search.png new file mode 100644 index 0000000..0d7bccd Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/doc_search.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/gsc.css b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/gsc.css new file mode 100644 index 0000000..e3d6391 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/gsc.css @@ -0,0 +1,192 @@ +.gsc-control-cse table, table td, table th { + border: none !important; + margin-bottom: 10px !important +} +.gsc-control-cse { + width: 100% !important; + box-sizing: border-box !important +} +.gsc-control-cse * { + font-family: 'Open Sans', Arial, Helvetica, sans-serif !important; + line-height: 1.5 !important; + font-weight: 300 !important +} +.gsc-control-cse, +.gsc-control-cse .gsc-table-result { + width: 100% !important; + font-family: 'Open Sans', Arial, Helvetica, sans-serif !important; + font-weight: 300 !important; + font-size: 13px !important +} +.gsc-resultsHeader { + width: 100% !important; + clear: both !important +} +.gsc-resultsHeader td.gsc-twiddleRegionCell { + width: 75% !important +} +.gsc-resultsbox-visible { + display: block !important +} +.gsc-resultsbox-invisible { + display: none !important +} +.gsc-results { + padding-bottom: 2px !important; + width: 99% !important +} +.gsc-result { + margin-bottom: 10px !important +} +.gsc-result .gs-title { + height: 1.4em !important; + overflow: hidden !important +} +.gsc-result div.gs-watermark { + display: none !important +} +.gsc-results .gsc-result img.gs-ad-marker { + display: none !important +} +.gsc-webResult:after { + content: "." !important; + display: block !important; + height: 0 !important; + clear: both !important; + visibility: hidden !important +} +.gsc-webResult { + zoom: 1 !important +} +.gsc-webResult .gsc-result { + margin: 0 !important; + padding: .5em 0 !important; + border-bottom: 1px solid #ebebeb !important +} +.gsc-above-wrapper-area { + border-bottom: 1px solid #E9E9E9 !important; + padding: 5px 0 5px 0 !important +} +.gsc-above-wrapper-area-invisible { + display: none !important +} +.gsc-above-wrapper-area-container { + width: 100% !important +} +.gsc-result-info { + text-align: left !important; + color: #676767 !important; + font-size: 13px !important; + padding-left: 8px !important; + margin: 10px 0 10px 0 !important +} +.gsc-result-info-container { + text-align: left !important +} +.gsc-result-info-invisible { + display: none !important +} +.gsc-orderby-container { + text-align: right !important; + background: transparent !important +} +.gsc-orderby-invisible { + display: none !important +} +.gsc-orderby-label { + color: #676767 !important; + padding: 5px 5px 6px 0 !important +} +.gsc-selected-option-container { + background-color: transparent !important; + border: 1px solid #eee !important; + border: 1px solid rgba(0, 0, 0, 0.1) !important; + border-radius: 2px !important; + box-shadow: none !important; + color: #444 !important; + cursor: default !important; + font-size: 11px !important; + font-weight: bold !important; + height: 20px !important; + line-height: 20px !important; + max-width: 90% !important; + min-width: 54px !important; + outline: 0 !important; + padding: 0 28px 0 6px !important; + position: relative !important; + text-align: center !important; + width: 50px !important !important +} +.gsc-selected-option { + position: relative !important; + width: 100% !important; +} +.gsc-control-cse .gsc-option-selector { + border: none !important; + height: 11px !important; + margin-top: -4px !important; + position: absolute !important; + right: 5px !important; + top: 8px !important; + width: 7px !important; + padding: 0 5px 0 5px !important; + background: url(//ssl.gstatic.com/ui/v1/disclosure/small-grey-disclosure-arrow-down.png) center no-repeat +} +.gsc-results .gsc-cursor-box .gsc-trailing-more-results { + margin-bottom: 0 !important; + display: inline !important +} +.gsc-results .gsc-cursor { + display: inline !important +} +.gsc-results .gsc-cursor-box { + margin: 10px 5px 10px !important +} +.gsc-results .gsc-cursor-box .gsc-cursor-page { + cursor: pointer !important; + color: #000000 !important; + text-decoration: underline !important; + margin-right: 8px !important; + display: inline !important +} +.gsc-results .gsc-cursor-box .gsc-cursor-current-page { + cursor: default !important; + color: white !important; + background-color: #5caa15 !important; + font-weight: bold !important; + text-decoration: none !important; + padding: 0 3px 0 3px !important; + margin-top: 10px !important; + cursor: pointer !important +} +.gs-result .gs-title, +.gs-result .gs-title * { + color: #5caa15 !important; + text-decoration: underline !important +} +.gs-webResult div.gs-visibleUrl-long, +.gs-promotion div.gs-visibleUrl-long { + overflow: hidden !important; + display: none !important +} +.gs-webResult div.gs-per-result-labels a.gs-label { + text-decoration: underline !important; + cursor: pointer !important; + padding: 3px !important; + color: #26282a !important +} +.gs-webResult div.gs-per-result-labels a.gs-label.gs-labelActive { + cursor: default !important; + text-decoration: none !important +} +.gsc-control-cse:after { + content: "." !important; + display: block !important; + clear: both !important; + height: 0 !important; + visibility: hidden !important +} + +*:first-child + html .gsc-inline-block { + display: inline !important +} diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/icomoon.eot b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/icomoon.eot new file mode 100644 index 0000000..68f0fa6a Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/icomoon.eot differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/icomoon.svg b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/icomoon.svg new file mode 100644 index 0000000..3246f83 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/icomoon.svg @@ -0,0 +1,20 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/icomoon.ttf b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/icomoon.ttf new file mode 100644 index 0000000..4518527 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/icomoon.ttf differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/icomoon.woff b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/icomoon.woff new file mode 100644 index 0000000..5c8466c Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/icomoon.woff differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/list_arrow.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/list_arrow.png new file mode 100644 index 0000000..7bb07b3 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/list_arrow.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/list_expand.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/list_expand.png new file mode 100644 index 0000000..d214514 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/list_expand.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/offline-simple.css b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/offline-simple.css new file mode 100644 index 0000000..82e99c4 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/offline-simple.css @@ -0,0 +1,168 @@ +pre, .LegaleseLeft { + background-color: #f0f0f0; + font-family: Courier, monospace; + font-weight: 600; + vertical-align: top; + margin: 15px 85px 15px 35px; + padding: 25px; + width: 90%; + overflow-x:auto; +} + +pre a[href] { + color: #5caa15; +} + +p { + width: 70%; + margin: 15px 0px 10px 15px; +} + +table p { + margin: 0px; + padding: 0px; +} + +a[href] { + color: #007330; + text-decoration: none; +} + +/* Different color for ext. links */ +a[href|="http://"], a[href|="https://"] { + color: #6bb8db; +} + +h1.title { + margin-top: 30px; + margin-left: 6px; + padding: 6px; +} + +h2, p.h2 { + background-color: #F2F3F4; + padding: 4px; + margin: 30px 0px 20px 10px; +} + +h3 { + margin: 30px 0px 30px 6px; +} + +ul, ol { + margin-top: 4px; + margin-bottom: 0px; +} + +ul li, ol li { + margin-bottom: 8px; +} + +.mainContent li.level2 { + margin-left: 16px; +} + +.rightAlign { + text-align: right; +} + +h3.fn, span.fn { + border-width: 3px; + border-style: solid; + border-color: #aaaaaa; + background-color: #eeeeee; + word-spacing: 3px; + padding: 5px; + text-decoration: none; + font-weight: 400; + margin: 45px 0px 0px 6px; +} +.fngroup h3.fngroupitem { + margin-bottom: 5px; +} +table { + max-width: 80%; + padding: 15px 45px 15px 15px; +} + +table th { + text-align: left; + padding: 8px; +} + +table td { + padding: 6px 10px 6px 10px; +} + +table tr.odd { + background-color: #eeeeee; +} + +table.qmlname td { + padding: 0px; + margin-left: 6px; +} + +table.qmlname p .name, +h3.fn .name, h3.fn .type { + font-weight: bold; +} + +.context h3.fn { + font-weight: 400; +} + +.qmlreadonly, .qmldefault { + font-family: Courier, monospace; + margin-right: 6px; +} + +code { + font-family: Courier, monospace; + font-weight: 400; +} + +p.naviNextPrevious { + text-align: right; + margin-right: 20px; +} + +span.naviSeparator { + white-space: pre; +} + +.toc h3 { + margin: 0px 0px 10px 6px; +} + +.toc ul { + list-style-type: none; +} + +.navigationbar table { + padding: 0; + margin: 0; +} + +.navigationbar table tr { + background-color: #eeeeee; +} + +td#buildversion { + background-color: #ffffff; +} + +.footer, .footer p { + padding: 5px 0px 5px 0px; + margin: 45px 15px 5px 15px; + font-size: 8.5pt; + background-color: #cccccc; +} + +.footer p { + margin: 0px; +} + +.video { + margin: 15px 0 0 15px; +} diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/offline.css b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/offline.css new file mode 100644 index 0000000..13c9427 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/offline.css @@ -0,0 +1,805 @@ +body { + font: normal 400 14px/1.2 Arial; + margin-top: 85px; + font-family: Arial, Helvetica; + text-align: left; + margin-left: 5px; + margin-right: 5px; + background-color: #fff; +} + +p { + line-height: 20px +} + +img { + margin-left: 0px; + max-width: 800px; + height: auto; +} + +.content .border img { + box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5) +} + +.content .border .player { + box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5) +} + +.content .indexboxcont li { + font: normal bold 13px/1 Verdana + } + +.content .normallist li { + font: normal 13px/1 Verdana + } + +.descr { + margin-top: 35px; + margin-bottom: 45px; + margin-left: 5px; + text-align: left; + vertical-align: top; +} + +.name { + max-width: 75%; + font-weight: 100; +} + +tt { + text-align: left +} + +/* +----------- +links +----------- +*/ + +a:link { + color: #007330; + text-decoration: none; + text-align: left; +} + +a.qa-mark:target:before { + content: "***"; + color: #ff0000; +} + +a:hover { + color: #44a51c; + text-align: left; +} + +a:visited { + color: #007330; + text-align: left; +} + +a:visited:hover { + color: #44a51c; + text-align: left; +} + +/* +----------- +offline viewing: HTML links display an icon +----------- +*/ + +a[href*="http://"], a[href*="ftp://"], a[href*="https://"] { + text-decoration: none; + background-image: url(../images/ico_out.png); + background-repeat: no-repeat; + background-position: left; + padding-left: 20px; + text-align: left; +} + +.flags { + text-decoration: none; + text-height: 24px; +} + +.flags:target { + background-color: #FFFFD6; +} + +/* +------------------------------- +NOTE styles +------------------------------- +*/ + +.notetitle, .tiptitle, .fastpathtitle { + font-weight: bold +} + +.attentiontitle, .cautiontitle, .dangertitle, .importanttitle, .remembertitle, .restrictiontitle { + font-weight: bold +} + +.note, .tip, .fastpath { + background: #F2F2F2 url(../images/ico_note.png); + background-repeat: no-repeat; + background-position: top left; + padding: 5px; + padding-left: 40px; + padding-bottom: 10px; + border: #999 1px dotted; + color: #666666; + margin: 5px; +} + +.attention, .caution, .danger, .important, .remember, .restriction { + background: #F2F2F2 url(../images/ico_note_attention.png); + background-repeat: no-repeat; + background-position: top left; + padding: 5px; + padding-left: 40px; + padding-bottom: 10px; + border: #999 1px dotted; + color: #666666; + margin: 5px; +} + +/* +------------------------------- +Top navigation +------------------------------- +*/ + +.qtref { + display: block; + position: relative; + height: 15px; + z-index: 1; + font-size: 11px; + padding-right: 10px; + float: right; +} + +.naviNextPrevious { + clear: both; + display: block; + position: relative; + text-align: right; + top: -47px; + float: right; + height: 20px; + z-index: 1; + padding-right: 10px; + padding-top: 2px; + vertical-align: top; + margin: 0px; +} + +.naviNextPrevious > a:first-child { + background-image: url(../images/btn_prev.png); + background-repeat: no-repeat; + background-position: left; + padding-left: 20px; + height: 20px; + padding-left: 20px; + } + +.naviNextPrevious > a:last-child { + background-image: url(../images/btn_next.png); + background-repeat: no-repeat; + background-position: right; + padding-right: 20px; + height: 20px; + margin-left: 30px; + } + +.naviSeparator { display: none } +/* +----------- +footer and license +----------- +*/ + +.footer { + text-align: left; + padding-top: 45px; + padding-left: 5px; + margin-top: 45px; + margin-bottom: 45px; + font-size: 10px; + border-top: 1px solid #999; +} + +.footer p { + line-height: 14px; + font-size: 11px; + padding: 0; + margin: 0; +} + +.footer a[href*="http://"], a[href*="ftp://"], a[href*="https://"] { + font-weight: bold; +} + +.footerNavi { + width: auto; + text-align: right; + margin-top: 50px; + z-index: 1; +} + +.navigationbar { + display: block; + position: relative; + top: -20px; + border-top: 1px solid #cecece; + border-bottom: 1px solid #cecece; + background-color: #F2F2F2; + z-index: 1; + height: 20px; + padding-left: 7px; + margin: 0px; + padding-top: 2px; + margin-left: -5px; + margin-right: -5px; +} + +.navigationbar .first { + background: url(../images/home.png); + background-position: left; + background-repeat: no-repeat; + padding-left: 20px; + } + +.navigationbar ul { + margin: 0px; + padding: 0px; + } + + .navigationbar ul li { + list-style-type: none; + padding-top: 2px; + padding-left: 4px; + margin: 0; + height: 20px; + } + +.navigationbar li { + float: left + } + + .navigationbar li a, .navigationbar td a { + display: block; + text-decoration: none; + background: url(../images/arrow_bc.png); + background-repeat: no-repeat; + background-position: right; + padding-right: 17px; + } + +table.buildversion { + float: right; + margin-top: -18px !important; +} + +.navigationbar table { + border-radius: 0; + border: 0 none; + background-color: #F2F2F2; + margin: 0; +} + +.navigationbar table td { + padding: 0; + border: 0 none; +} + +#buildversion { + font-style: italic; + font-size: small; + float: right; + margin-right: 5px; +} + +/* + +/* table of content +no display +*/ + +/* +----------- +headers +----------- +*/ + +@media screen { + .title { + color: #313131; + font-size: 24px; + font-weight: normal; + left: 0; + padding-bottom: 20px; + padding-left: 10px; + padding-top: 20px; + position: absolute; + right: 0; + top: 0; + background-color: #E6E6E6; + border-bottom: 1px #CCC solid; + border-top: 2px #CCC solid; + font-weight: bold; + margin-left: 0px; + margin-right: 0px; + } + .subtitle, .small-subtitle { + display: block; + clear: left; + } +} + +h1 { + margin: 0 +} + +h2, p.h2 { + font: 500 16px/1.2 Arial; + font-weight: 100; + background-color: #F2F3F4; + padding: 4px; + margin-bottom: 30px; + margin-top: 30px; + border-top: #E0E0DE 1px solid; + border-bottom: #E0E0DE 1px solid; + max-width: 99%; +} + +h2:target { + background-color: #F2F3D4; +} + +h3 { + font: 500 14px/1.2 Arial; + font-weight: 100; + text-decoration: underline; + margin-bottom: 30px; + margin-top: 30px; +} + +h3.fn, span.fn { + border-width: 1px; + border-style: solid; + border-color: #E6E6E6; + -moz-border-radius: 7px 7px 7px 7px; + -webkit-border-radius: 7px 7px 7px 7px; + border-radius: 7px 7px 7px 7px; + background-color: #F6F6F6; + word-spacing: 3px; + padding: 5px 5px; + text-decoration: none; + font-weight: bold; + max-width: 75%; + font-size: 14px; + margin: 0px; + margin-top: 45px; +} +.fngroup h3.fngroupitem { + margin-bottom: 5px; +} +h3.fn code { + float: right; +} +h3.fn:target { + background-color: #F6F6D6; +} + +.name { + color: #1A1A1A +} + +.type { + color: #808080 +} + +@media print { + .title { + color: #0066CB; + font-family: Arial, Helvetica; + font-size: 32px; + font-weight: normal; + left: 0; + position: absolute; + right: 0; + top: 0; + } +} + +/* +----------------- +table styles +----------------- +*/ + +.table img { + border: none; + margin-left: 0px; + -moz-box-shadow: 0px 0px 0px #fff; + -webkit-box-shadow: 0px 0px 0px #fff; + box-shadow: 0px 0px 0px #fff; +} + +/* table with border alternative colours*/ + +table, pre, .LegaleseLeft { + -moz-border-radius: 7px 7px 7px 7px; + -webkit-border-radius: 7px 7px 7px 7px; + border-radius: 7px 7px 7px 7px; + background-color: #F6F6F6; + border: 1px solid #E6E6E6; + border-collapse: separate; + margin-bottom: 25px; + margin-left: 15px; + font-size: 12px; + line-height: 1.2; +} + + table tr.even { + background-color: white; + color: #66666E; + } + + table tr.odd { + background-color: #F6F6F6; + color: #66666E; + } + + table tr:target { + background-color: #F6F6D6; + } + + table thead { + text-align: left; + padding-left: 20px; + background-color: #e1e0e0; + border-left: none; + border-right: none; + } + + table thead th { + padding-top: 5px; + padding-left: 10px; + padding-bottom: 5px; + border-bottom: 2px solid #D1D1D1; + padding-right: 10px; + } + + table th { + text-align: left; + padding-left: 20px; + } + + table td { + padding: 3px 15px 3px 20px; + border-bottom: #CCC dotted 1px; + } + + table p { + margin: 0px + } + +.LegaleseLeft { + font-family: monospace; + white-space: pre-wrap; +} +/* table bodless & white*/ + +.borderless { + border-radius: 0px 0px 0px 0px; + background-color: #fff; + border: 1px solid #fff; +} + +.borderless tr { + background-color: #FFF; + color: #66666E; + } + +.borderless td { + border: none; + border-bottom: #fff dotted 1px; + } + +/* +----------- +List +----------- +*/ + +ul { + margin-top: 10px; +} + +li { + margin-bottom: 10px; + padding-left: 8px; + list-style: outside; + text-align: left; +} + + ul > li { + list-style-type: square; + } + +ol { + margin: 10px; + padding: 0; +} + +ol.A > li { + list-style-type: upper-alpha; +} + +ol.a > li{ + list-style-type: lower-alpha; +} + + ol > li { + margin-left: 30px; + padding-left: 8px; + list-style: decimal; + } + +.centerAlign { + text-align: left +} + +.cpp, .LegaleseLeft { + display: block; + margin: 10px; + overflow: auto; + padding: 20px 20px 20px 20px; +} + +.js { + display: block; + margin: 10px; + overflow: auto; + padding: 20px 20px 20px 20px; +} + +.memItemLeft { + padding-right: 3px +} + +.memItemRight { + padding: 3px 15px 3px 0 +} + +.qml { + display: block; + margin: 10px; + overflow: auto; + padding: 20px 20px 20px 20px; +} + +.qmldefault { + padding-left: 5px; + float: right; + color: red; +} + +.qmlreadonly { + padding-left: 5px; + float: right; + color: #254117; +} + +.rightAlign { + padding: 3px 5px 3px 10px; + text-align: right; +} + +.qmldoc { + margin-left: 15px +} + +.flowList { + padding: 25px +} +.flowList dd { + display: inline-block; + margin-left: 10px; + width: 255px; + line-height: 1.15em; + overflow-x: hidden; + text-overflow: ellipsis +} +.alphaChar { + font-size: 2em; + position: relative +} +/* +----------- +Content table +----------- +*/ + +@media print { + .toc { + float: right; + clear: right; + padding-bottom: 10px; + padding-top: 50px; + width: 100%; + background-image: url(../images/bgrContent.png); + background-position: top; + background-repeat: no-repeat; + } +} + +@media screen { + .toc { + float: right; + clear: right; + vertical-align: top; + -moz-border-radius: 7px 7px 7px 7px; + -webkit-border-radius: 7px 7px 7px 7px; + border-radius: 7px 7px 7px 7px; + background: #FFF url('../images/bgrContent.png'); + background-position: top; + background-repeat: repeat-x; + border: 1px solid #E6E6E6; + padding-left: 5px; + padding-bottom: 10px; + height: auto; + width: 200px; + text-align: left; + margin-left: 20px; + } +} + + +.toc h3 { + text-decoration: none +} + +.toc h3 { + font: 500 14px/1.2 Arial; + font-weight: 100; + padding: 0px; + margin: 0px; + padding-top: 5px; + padding-left: 5px; +} + +.toc ul { + padding-left: 10px; + padding-right: 5px; +} + +.toc ul li { + margin-left: 15px; + list-style-image: url(../images/bullet_dn.png); + marker-offset: 0px; + margin-bottom: 8px; + padding-left: 0px; + } + +.toc .level1 { + border: none +} + +.toc .level2 { + border: none; + margin-left: 25px; +} + +.level3 { + border: none; + margin-left: 30px; +} + +.clearfix { + clear: both +} + +/* +----------- +Landing page +----------- +*/ + +.col-group { + white-space: nowrap; + vertical-align: top; +} + + +.landing h2 { + background-color: transparent; + border: none; + margin-bottom: 0px; + font-size: 18px; +} + +.landing a, .landing li { + font-size: 13px; + font-weight: bold !important; +} + +.col-1 { + display: inline-block; + white-space: normal; + width: 70%; + height: 100%; + float: left; +} + +.col-2 { + display: inline-block; + white-space: normal; + width: 20%; + margin-left: 5%; + position: relative; + top: -20px; +} + +.col-1 h1 { + margin: 20px 0 0 0; + } + +.col-1 h2 { + font-size: 18px; + font-weight: bold !important; +} + +.landingicons { + display: inline-block; + width: 100%; +} + +.icons1of3 { + display: inline-block; + width: 33.3333%; + float: left; +} + +.icons1of3 h2, .doc-column h2 { + font-size: 15px; + margin: 0px; + padding: 0px; +} + +div.multi-column { + position: relative; +} + +div.multi-column div { + display: -moz-inline-box; + display: inline-block; + vertical-align: top; + margin-top: 1em; + margin-right: 4em; + width: 24em; +} + +.mainContent .video { + width:40%; + max-width:640px; + margin: 15px 0 0 15px; + position:relative; + display:table +} + +.mainContent .video > .vspan { + padding-top:60%; + display:block +} +.mainContent .video iframe { + width:100%; + height:100%; + position:absolute; + top:0; + left:0 +} diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/online.css b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/online.css new file mode 100644 index 0000000..7d84863 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/online.css @@ -0,0 +1,1752 @@ +#navbar { + position:fixed; + top:0; + left:0; + z-index:100; + background:#fff; + width:100% +} +#navbar .container { + overflow:visible +} +.fixed .container { + overflow:visible +} +.box-shadowed-nav #navbar { + border-bottom:1px solid #eee +} +#navbar .navbar-header { + position:relative +} +#navbar .navbar-toggle { + display:none; + float:right; + line-height:18px; + min-width:95px; + position:relative; + text-align:center; + border-left:1px solid #eee; + border-right:1px solid #eee; + padding:10px 0 10px 0 +} +#navbar .navbar-toggle:hover figure { + background:#5caa15 +} +#navbar .navbar-toggle span { + color:#bdbebf; + font-weight:300 +} +#navbar .navbar-toggle figure { + background:#7fc241; + border-radius:100%; + -webkit-border-radius:100%; + -moz-border-radius:100%; + transition:all 0.2s ease-in-out; + -webkit-transition:all 0.2s ease-in-out; + -moz-transition:all 0.2s ease-in-out; + -ms-transition:all 0.2s ease-in-out; + -o-transition:all 0.2s ease-in-out; + height:26px; + width:34px; + padding:8px 0 0 0; + margin-top:3px; + margin-left:auto; + margin-right:auto; + text-align:center +} +#navbar .navbar-toggle figure span.line { + display:inline-block; + width:1.125em; + height:0.1875em; + background:#fff; + transition:0.3s; + position:relative; + vertical-align:middle; + margin-top:-3px +} +#navbar .navbar-toggle figure span.line:before,#navbar .navbar-toggle figure span.line:after { + display:inline-block; + width:1.125em; + height:0.1875em; + background:#fff; + position:absolute; + left:0; + content:''; + -webkit-transform-origin:0.28571rem center; + transform-origin:0.28571rem center; + transition:0.3s; + -webkit-transition:0.3s; + -moz-transition:0.3s; + -ms-transition:0.3s; + -o-transition:0.3s +} +#navbar .navbar-toggle figure span.line:before { + top:6px +} +#navbar .navbar-toggle figure span.line:after { + top:-6px +} +#navbar .navbar-toggle.opened figure { + background:#5caa15 +} +#navbar .navbar-toggle.opened span { + color:#5caa15 +} +#navbar .navbar-toggle.opened span.line { + background:transparent +} +#navbar .navbar-toggle.opened span.line:before,#navbar .navbar-toggle.opened span.line:after { + -webkit-transform-origin:50% 50%; + -moz-transform-origin:50% 50%; + transform-origin:50% 50%; + top:0; + width:23px; + margin-left:-2px +} +#navbar .navbar-toggle.opened span.line:before { + transform:rotate3d(0, 0, 1, 45deg); + -webkit-transform:rotate3d(0, 0, 1, 45deg); + -moz-transform:rotate3d(0, 0, 1, 45deg); + -ms-transform:rotate3d(0, 0, 1, 45deg); + -o-transform:rotate3d(0, 0, 1, 45deg); + left:0 +} +#navbar .navbar-toggle.opened span.line:after { + transform:rotate3d(0, 0, 1, -45deg); + -webkit-transform:rotate3d(0, 0, 1, -45deg); + -moz-transform:rotate3d(0, 0, 1, -45deg); + -ms-transform:rotate3d(0, 0, 1, -45deg); + -o-transform:rotate3d(0, 0, 1, -45deg) +} +#navbar .navbar-oneQt { + display:inline; + float:left; + width:31px; + padding:20px 8px; + margin:0 15px 0 0 +} +#navbar .navbar-oneQt:before { + content:attr(data-icon); + position:absolute; + top:15px; + left:0; + color:#80c342; + font-family:'Qt Icons'; + line-height:1; + font-size:3.125em; + transition:all 0.2s ease-in-out; + -webkit-transition:all 0.2s ease-in-out; + -moz-transition:all 0.2s ease-in-out; + -ms-transition:all 0.2s ease-in-out; + -o-transition:all 0.2s ease-in-out +} +.navbar-oneQt { + color: #80c342 !important; +} +.navbar-oneQt:hover { + color: #80c342; +} +#navbar .navbar-menu { + width:auto; + float:left +} +.lt-ie9 #navbar { + border-bottom:1px solid #ddd +} +#mainmenu { + float:left; + list-style:none; + margin-left:16px +} +#mainmenu li { + float:left; + margin-left:0; + list-style-type:none !important +} +#mainmenu li a { + display:block; + padding:29px 0.7em; + font-size:1.125em; + font-weight:300; + line-height:20px; + height:80px; + color:#26282a; + text-decoration:none; + border:0px solid #80c342; + -webkit-transition:all 0.2s ease-in-out; + box-sizing:border-box; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + *behavior:url(boxsizing.htc) +} +#mainmenu li a:hover { + color:#5caa15; + border-bottom:4px solid #80C342 +} +#mainmenu li.current-menu-item a { + color:#5caa15; + border-bottom:4px solid #80C342 +} +#menuextras, #mainmenu, #menuextraslanguages { + margin-bottom:0 + } +#menuextras { + display:inline-block; + float:right; + list-style-type:none; + margin-right:0; + margin-left:0; + letter-spacing:-0.31em; + line-height:0 +} +#menuextras li { + letter-spacing:normal; + float:left; + display:inline-block +} +#menuextras li a { + display:inline-block; + text-align:center; + height:80px; + border-left:1px solid #eee; + padding-top:14px; + box-sizing:border-box; + overflow:hidden; + min-width:85px; + font-weight:100 +} +#menuextras li:last-child a { + border-right:1px solid #eee; +} +#menuextras li a:before { + display:inline-block; + font-family:'Qt Icons'; + content:attr(data-icon); + font-size:2.125em; + width:100%; + color:#80c342; + line-height:1; + transition:all 0.2s ease-in-out; + -webkit-transition:all 0.2s ease-in-out; + -moz-transition:all 0.2s ease-in-out; + -ms-transition:all 0.2s ease-in-out; + -o-transition:all 0.2s ease-in-out +} +#menuextras li a:hover:before { + color:#5caa15 +} +#menuextras .search.open a { + color:#006325 +} +#menuextras .search a { + border-right:1px solid #eee +} +#menuextras li a span { + color:#bdbebf; + display:inline-block; + overflow:hidden; + max-height:30px; + transition:max-height 0.2s ease-in-out; + -webkit-transition:max-height 0.2s ease-in-out; + -moz-transition:max-height 0.2s ease-in-out; + -ms-transition:max-height 0.2s ease-in-out; + -o-transition:max-height 0.2s ease-in-out; + line-height:1.4; + font-size:0.875em +} +@media (min-width: 1320px) { + .context .flowListDiv dl.flowList { + -webkit-column-count:3; + -moz-column-count:3; + column-count:3 + } +} +@media (min-width: 1120px) { + #navbar.fixed,#navbar.shadow_bottom { + -moz-box-shadow:0px 0px 8px rgba(0,0,0,0.2); + -webkit-box-shadow:0px 0px 8px rgba(0,0,0,0.2); + box-shadow:0px 0px 8px rgba(0,0,0,0.2) + } + #navbar.fixed #menuextras li a,#navbar.shadow_bottom #menuextras li a { + padding-top:9px; + height:50px + } + #navbar.fixed #menuextras li a span,#navbar.shadow_bottom #menuextras li a span { + max-height:0 + } + #navbar.fixed #menuextras li a:before,#navbar.shadow_bottom #menuextras li a:before { + font-size:30px + } + #navbar.fixed #mainmenu li a { + height:50px; + padding:14px 0.7em + } + #navbar.fixed #mainmenu li a:hover { + border-bottom:4px solid #5caa15 + } + #navbar.fixed .navbar-toggle { + padding:13px 14px 9px + } + #navbar.fixed #menuextras li.navbar-search { + padding:0px 0 + } + #navbar.fixed #menuextras ul.menuextraslinks,#navbar.fixed #menuextras ul.menuextraslanguages { + display:none + } + #navbar.fixed .navbar-oneQt:before { + font-size:35px; + top:7px + } + #navbar.fixed #mainmenu li.current-menu-item a { + border-bottom:4px solid #80C342 + } + .flowListDiv dl.flowList { + -webkit-column-count:2; + -moz-column-count:2; + column-count:2 + } +} +@media (max-width: 1120px) { + #navbar { + padding:0; + position:relative + } + #navbar .container { + max-width:100% + } + #navbar .menuextraslanguages { + bottom:10px !important; + right:0 + } + #navbar .menuextraslanguages li a { + color:#7fc241 !important + } + #navbar .menuextraslanguages li.active a,#navbar .menuextraslanguages li a:hover { + border-color:#7fc241 !important + } + #navbar .container { + padding:0 + } + #navbar .navbar-toggle { + display:block + } + #navbar .navbar-oneQt,#navbar.fixed .navbar-oneQt,#navbar .navbar-oneQt:hover { + margin-left:0; + height:26px; + width:22px; + padding:7px 20px 7px 15px + } + #navbar .navbar-oneQt:before { + left:20px + } + #navbar .navbar-menu { + max-height:0; + overflow:hidden; + width:100%; + border-top:1px solid #eee; + -webkit-transition:all 600ms ease-in-out; + -moz-transition:all 600ms ease-in-out; + -o-transition:all 600ms ease-in-out; + transition:all 600ms ease-in-out; + position:relative + } + #mainmenu { + float:none; + width:100%; + padding:0; + margin:0 + } + #mainmenu li { + float:none; + list-style:none + } + #mainmenu li:nth-child(odd) { + background:rgba(0,0,0,0) + } + #mainmenu li a,#navbar.fixed #mainmenu li a { + padding:10px; + border-left:3px solid #fff; + height:auto; + width:100% + } + #mainmenu li.current-menu-item a,#navbar.fixed #mainmenu li.current-menu-item a { + border-bottom:none; + border-left:3px solid #5caa15; + padding:10px + } + #mainmenu li a:hover { + border-bottom:0; + padding:10px; + border-left:3px solid #5caa15 + } + #navbar.fixed { + -moz-box-shadow:0px 0px 0px rgba(0,0,0,0); + -webkit-box-shadow:0px 0px 0px rgba(0,0,0,0); + box-shadow:0px 0px 0px rgba(0,0,0,0) + } + .lt-ie9 #navbar.fixed { + border-bottom:none + } + #menuextras li.navbar-search { + padding:5px 0 + } + #footerbar .container { + padding:0 + } + body .main { + margin-top:0px + } + #footerbar .footer-main .footer-nav { + padding:3.9% 0 3.9% 3%; + border-bottom:1px solid #413d3b; + float:none; + display:block; + width:auto + } + #footerbar .footer-main .theqtcompany { + clear:both; + float:left; + margin:30px 0 28px 3% + } + #footerbar .footer-main .footer-social { + float:left; + padding:30px 0px 0px 3% + } + #footerbar #menu-footer-submenu { + clear:both; + float:none; + display:block; + padding:0px 0px 3.9% 3% + } + ul#menu-footer-submenu { + margin-left: 0 + } +} +.in-page-nav { + width:100%; + background:#eeeeee +} +.in-page-nav ul { + margin:0 auto; + letter-spacing:-0.31em; + max-width:1180px; + text-align:center +} +.in-page-nav ul li { + display:inline-block; + letter-spacing:normal +} +.in-page-nav ul li a { + color:#26282a; + padding:25px 10px; + display:inline-block +} +body.qt-account #navbar .navbar-oneQt { + width:auto; + height:auto +} +body.qt-account #navbar .navbar-oneQt:before { + left:0; + position:relative; + display:inline-block; + vertical-align:middle; + top:0; + margin-right:20px +} +body.qt-account #navbar .navbar-oneQt h2 { + margin:0; + color:#000; + display:inline-block; + vertical-align:middle +} +.landing header[role="banner"] { + background:#26282a +} +.landing header[role="banner"] figure { + max-width:1180px; + margin:auto; + position:relative +} +.landing header[role="banner"] figure img { + max-width:100% +} +.landing header[role="banner"] figcaption { + color:#fff; + position:absolute; + left:0px; + width:100%; + text-align:center +} +.landing header[role="banner"] figcaption.top { + top:0 +} +.landing header[role="banner"] figcaption.bottom { + bottom:0 +} +.landing header[role="banner"] figcaption h1 { + margin:50px auto 0 auto; + max-width:70%; + font-weight:600 +} +.landing header[role="banner"] figcaption h3 { + margin-bottom:40px +} +.cookies_yum { + background-color:#d6d6d6; + display:none; + line-height:1.625em; + width:100% +} +.cookies_yum img { + width:25px; + top:6px; + display:inline-block; + position:absolute; + left:6px +} +.cookies_yum div { + margin:0 auto; + max-width:1280px; + min-height:30px; + padding:6px 0px 6px 0px; + position:relative +} +.cookies_yum p { + color:#585a5c; + margin:0px; + font-size:0.79em; + display:inline-block; + line-height:1.2; + padding:0 30px 0 50px +} +.cookies_yum p a { + white-space:nowrap +} +.cookies_yum a:hover { + color:white +} +.cookies_yum .close { + width:15px; + height:15px; + background-image:url("cookiebar-x.png"); + background-size:15px 30px; + background-position:top left; + cursor:pointer; + top:13px; + right:13px; + position:absolute; + transition:none; +} +#sidebar-toggle,#toc-toggle { + width:24px; + height:14px; + background-size:24px 28px; + cursor:pointer; + background-image:url("list_expand.png"); + float:right +} +#sidebar-toggle.collapsed, +#toc-toggle.collapsed { + background-position:bottom left +} +#sidebar-content > h2 { + display:none +} +.cookies_yum .close:hover { + background-position:bottom left +} +#bottom_header { + display:block; + position:absolute; + width:100%; + z-index:50; + padding-top:15px +} +#bottom_header .container { + overflow:visible +} +#bottom_header .left { + font-weight:bolder +} +#bottom_header a { + color:white; + transition-duration:0.3s +} +#bottom_header .left a:hover { + padding-left:10px +} +.fixed .menuextraslanguages { + opacity:0; + visibility:hidden +} +@media (max-width: 1120px) { + .fixed .menuextraslanguages { + opacity:1 !important; + visibility:visible !important + } +} +#navbar .menuextraslanguages { + position:absolute; + right:0; + bottom:-35px; + transition:all 0.2s ease-in-out; + -webkit-transition:all 0.2s ease-in-out; + -moz-transition:all 0.2s ease-in-out; + -ms-transition:all 0.2s ease-in-out; + -o-transition:all 0.2s ease-in-out +} +#navbar .menuextraslanguages li { + display:inline; + list-style:none; + margin-left:3px; + padding:0px 4px; + font-size:0.6875em +} +#navbar .menuextraslanguages li.dark a { + color:#868482 +} +#navbar .menuextraslanguages li.dark a:hover { + border:2px solid #868482 +} +#navbar .menuextraslanguages li.active.dark a { + border-color:#868482; + color:#868482 +} +#navbar .menuextraslanguages a { + color:#fff; + padding:2px 4px; + border:2px solid transparent +} +#navbar .menuextraslanguages a:hover,#navbar .menuextraslanguages li.active a { + border:2px solid #fff; + color:#fff +} +#bottom_header .dark,#bottom_header .dark.active { + color:#868482; + transition-duration:0.3s; + border-color:#868482 !important +} +#navbar .big_bar { + width:100%; + height:100px; + background-color:#80C342; + display:none; + position:relative +} +#navbar .big_bar.search { + height:auto; + overflow:hidden; + display:none +} +#navbar .big_bar ::-webkit-input-placeholder { + color:#fff +} +#navbar .big_bar :-moz-input-placeholder { + color:#fff +} +#navbar .big_bar ::-moz-input-placeholder { + color:#fff +} +#navbar .big_bar :-ms-input-placeholder { + color:#fff +} +#navbar .big_bar:hover>div .big_bar_button.account { + background-position:right bottom +} +#navbar .big_bar.account h1 { + padding-top:20px +} +#navbar .big_bar.account h1,#navbar .big_bar.account h1 a { + color:#FFF; + margin-bottom:5px +} +#navbar .big_bar.account h1 a:hover { + color:#328930 +} +#navbar .big_bar_button:hover { + background-position:left bottom; + cursor:pointer +} +#navbar .big_bar_button.account { + background-position:right top +} +#navbar .big_bar input.big_bar_search { + background:none repeat scroll 0 0 transparent; + border:medium none; + color:#fff; + display:block; + float:left; + font-size:4em; + outline:0 none; + width:70%; + line-height:1.3; + height:auto; + margin:10px 5%; + padding:0; + box-sizing:border-box; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + *behavior:url(boxsizing.htc) +} +#navbar .big_bar_button { + background-color:transparent; + border:none; + width:18%; + transition-duration:0.3s; + display:block; + float:left; + position:relative; + font-family:'QT Icons'; + font-size:3.5em; + color:#fff; + margin:15px 2% 0 0 !important; + text-align:right; + padding-right:2px !important; + transition:all 0.2s ease-in-out; + -webkit-transition:all 0.2s ease-in-out; + -moz-transition:all 0.2s ease-in-out; + -ms-transition:all 0.2s ease-in-out; + -o-transition:all 0.2s ease-in-out +} +#navbar .big_bar_button:focus,#navbar .big_bar_button:hover { + outline:0; + color:#ebebeb +} +.hero_slide>div { + width:80%; + margin:0 auto +} +.hero_slide>div:first-child>div { + width:80%; + margin:0 auto +} +.hero_slide .content { + margin-top:70px +} +.hero_bar { + padding-top:50px; + padding-bottom:18px +} +.hero_bar p { + font-size:0.875em; + text-align:center +} +.hero_bar .arrow { + bottom:65px; + display:block; + margin:0 auto; + position:relative; + right:260px; + width:230px +} +.hero_bar .comment { + margin:0 +} +#footerbar { + background:#26282a; + color:#fff +} +#footerbar.fixed { + bottom:0; + left:0; + width:100% +} +#footerbar .footer-nav { + display:inline; + float:left +} +#footerbar .footer-main .footer-nav li { + float:left; + margin-right:1em +} +#footerbar .footer-main .footer-nav li a { + display:block; + padding:31px 10px 15px 0; + line-height:20px; + height:20px; + color:#d6d6d6 +} +#footerbar .footer-main .footer-nav li a:hover,#footerbar .footer-main .footer-nav li.current-menu-item a { + color:#eee +} +#footerbar .footer-main .footer-nav .sub-menu { + margin-left:0; + margin-bottom:0 +} +#footerbar .footer-main .footer-nav .sub-menu li { + float:none +} +#footerbar .footer-main .footer-nav .sub-menu ul { + padding:1px 1em; + font-size:0.786em; + line-height:8px; + float:none; + color:#5d5b59; + margin-bottom:0 +} +#footerbar .footer-main .footer-nav .sub-menu li a { + padding:1px 0; + font-size:0.786em; + line-height:8px; + float:none; + color:#d6d6d6 +} +#footerbar .footer-main .footer-nav .sub-menu li a:hover,#footerbar .footer-main .footer-nav .sub-menu li.current-menu-item a { + color:#eee +} +#footerbar .theqtcompany { + background:url("theqtcompany.png") no-repeat; + background-size:100%; + width:215px; + height:68px; + display:inline; + float:right; + margin:29px 0 28px 30px +} +#footerbar .footer-social { + display:inline; + float:right; + padding-top:31px; + width:164px +} +#footerbar .footer-main .footer-social>div { + margin-left:0.1em; + margin-bottom:10px +} +#footerbar .disclaimer { + font-size:0.786em; + line-height:2.73; + color:#868584; + padding-top:20px; + padding-bottom:0.5% +} +#footerbar .disclaimer a { + color:#bdbebf +} +#footerbar .disclaimer a:hover { + color:#d6d6d6 +} +#footerbar .disclaimer ul li { + float:left; + vertical-align:middle; + margin-left:1.18em +} +#footerbar .disclaimer ul li:first-child { + margin-left:0 +} +#footerbar .disclaimer ul.lang-selector a { + color:#506a34; + color:rgba(128,195,66,0.3) +} +#footerbar .disclaimer ul.lang-selector a:hover { + color:#80c342; + color:rgba(128,195,66,0.7) +} +#menu-footer-menu, #menu-footer-menu ul { + margin-left:0; + margin-bottom:0 +} +@font-face { + font-family:'Open Sans'; + font-style:normal; + font-weight:300; + src:local("Open Sans Light"),local("OpenSans-Light"),url(//fonts.gstatic.com/s/opensans/v10/DXI1ORHCpsQm3Vp6mXoaTYnF5uFdDttMLvmWuJdhhgs.ttf) format("truetype") +} +@font-face { + font-family:'Open Sans'; + font-style:normal; + font-weight:400; + src:local("Open Sans"),local("OpenSans"),url(//fonts.gstatic.com/s/opensans/v10/cJZKeOuBrn4kERxqtaUH3aCWcynf_cDxXwCLxiixG1c.ttf) format("truetype") +} +@font-face { + font-family:'Open Sans'; + font-style:normal; + font-weight:600; + src:local("Open Sans Semibold"),local("OpenSans-Semibold"),url(//fonts.gstatic.com/s/opensans/v10/MTP_ySUJH_bn48VBG8sNSonF5uFdDttMLvmWuJdhhgs.ttf) format("truetype") +} +@font-face { + font-family:'Open Sans'; + font-style:normal; + font-weight:700; + src:local("Open Sans Bold"),local("OpenSans-Bold"),url(//fonts.gstatic.com/s/opensans/v10/k3k702ZOKiLJc3WVjuplzInF5uFdDttMLvmWuJdhhgs.ttf) format("truetype") +} +@font-face { + font-family:'Open Sans'; + font-style:normal; + font-weight:800; + src:local("Open Sans Extrabold"),local("OpenSans-Extrabold"),url(//fonts.gstatic.com/s/opensans/v10/EInbV5DfGHOiMmvb1Xr-honF5uFdDttMLvmWuJdhhgs.ttf) format("truetype") +} +@font-face { + font-family:'Droid Sans Mono'; + font-style:normal; + font-weight:400; + src:local("Droid Sans Mono"),local("DroidSansMono"),url(//fonts.gstatic.com/s/droidsansmono/v7/ns-m2xQYezAtqh7ai59hJUYuTAAIFFn5GTWtryCmBQ4.woff) format("woff") +} +@font-face { + font-family:'Qt Icons'; + src:url("../style/icomoon.eot?-tgjuoj"); + src:url("../style/icomoon.eot?#iefix-tgjuoj") format("embedded-opentype"),url("../style/icomoon.woff?-tgjuoj") format("woff"),url("../style/icomoon.ttf?-tgjuoj") format("truetype"),url("../style/icomoon.svg?-tgjuoj#icomoon") format("svg"); + font-weight:normal; + font-style:normal +} +.clearfix:before,.clearfix:after { + content:" "; + display:table +} +.clearfix:after { + clear:both +} +.clearfix { + *zoom:1 +} +.clearfix .right { + float:right +} +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { + margin:0; + padding:0; + border:0; + font-size:100% +} +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,caption,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { + vertical-align:baseline +} +body { + font-family:“Open Sans”, Arial, Helvetica, sans-serif; + line-height:1.5; + font-weight:400 +} +h1,h2,h3,h4,h5,h6 { + font-weight:300 +} +.context h2,.context h3,.context h4,.context h5,.context h6 { + margin:1.5em 0 1em +} +.context h1 { + margin-bottom:1em; + font-size:3.125em +} +.context h3.fn,.context h3.flags { + color:#26282a; + font-size:1.46em; + padding:15px 0 15px 0; + border-bottom:2px #eee solid; + word-wrap:break-word +} +.context .fngroup { + border-bottom:2px #eee solid; + padding-bottom:15px; + margin-bottom:1.5em +} +.context .fngroup h3.fngroupitem { + margin:0; + padding-bottom:0; + border:none +} +.context h3.fn .name, +.context h3 span.type, +.qmlname span.name { + font-weight: 400 +} +.qmlname { + font-size:1.46em +} +.qmlproto table { + border:none; + border-bottom:2px #eee solid +} +.qmlproto table p { + max-width:100% +} +.qmlproto table tr { + background-color:#fff +} +.qmlname td, .qmlname th { + border:none; + text-align:left; + padding:5px 0 0 0 +} +.qmlreadonly,.qmldefault { + padding:0 5px 0 5px; + font-size:0.75em; + background-color:#eee; + float:right +} +.qmlreadonly { + color:#414141 +} +.qmldefault { + color:#D14141 +} +.rightAlign { + padding:3px 5px 3px 10px; + text-align:right +} +article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section { + display:block +} +body { + line-height:1; + font-family:"Open Sans", Arial, Helvetica, sans-serif; + transition-duration:1s +} +ol,ul { + list-style:none +} +.context ol,.context ul { + margin-top:0.75em; + margin-left:20px +} + +.context ol > li { + margin-left: 20px +} + +.mainContent ol>li { + list-style-type: decimal; +} + +.mainContent ol.a >li { + list-style-type: lower-alpha; +} + +.mainContent ol.A >li { + list-style-type: upper-alpha; +} + +blockquote,q { + quotes:none +} +blockquote:before,blockquote:after,q:before,q:after { + content:''; + content:none; + width:100% +} +table { + border-collapse:collapse; + border-spacing:0; + margin-bottom:25px; + width:100% +} +a { + color:#5caa15; + text-decoration:none; + transition-duration:0.3s +} +a:hover { + color:#46a2da +} +.main,.navbar-header,#footerbar>div { + max-width:1280px; + width:95%; + margin:0 auto +} +.main { + margin-top:100px +} +.main_index { + background-color:#fff +} +.sectionlist { + margin-bottom:2em +} +[class*="col-"] { + letter-spacing:normal +} +.landing,.main_index .row { + letter-spacing:-0.31em +} +.main_index .row>div { + letter-spacing:normal +} +.col-1,.context { + width:80%; + display:inline-block; + background-color:#fff; + padding:35px; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box +} +.col-1 h2 { + font-size:2.1875em; + font-weight:300; + line-height:1.1; + margin-bottom:0.83em; + margin-top:1em +} +.icons1of3 img { + display:inline-block; + float:left; + margin-right:0.75em; + margin-top:-5px; + width:2.75em +} +div.multi-column { + position:relative +} +div.multi-column div { + display:-moz-inline-box; + display:inline-block; + vertical-align:top; + margin-top:1em; + margin-right:2em; + width:16em +} +.sidebar { + display:block; + float:right; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; + width:20%; + padding-left:30px +} +.toc,.sectionlist { + padding:35px; + background-color:#fff; + margin-bottom:2em +} +.sidebar-content:empty { + display:none; + visibility:hidden +} +.col-2 h2,.toc h3,.sidebar-content h2,.sidebar-content h3,.sectionlist h2 { + font-weight:400; + margin-bottom:2em +} +.toc h3 a { + color:#404244 +} +.title { + font-size:3em; + font-weight:300; + letter-spacing:-1px; + line-height:1.15em; + margin-bottom:0.5em; + word-wrap:break-word +} +.navigationbar,col-1 h2 { + font-size:0.75em +} +.navigationbar h1 { + font-size:3.125em; + margin-bottom:1em; + margin-top:1em +} +.navigationbar li { + display:inline-block; + margin-right:5px; + position:relative; + padding-right:10px; + color:#585a5c +} +.navigationbar li a { + color:#58585c +} +body { + background-color:#eee; + color:#404244 +} +.sectionlist li { + margin-bottom:5px +} +dd { + padding-bottom:0.25em; + padding-left:2em +} +.col-1 ul { + margin-bottom:1.56em +} +.mainContent li { + margin-top:0.8em; + line-height:1.25em +} +.mainContent li.level2 { + margin-left:10px; + margin-top:0.4em; + font-size:0.9375em; + line-height:1.15em; +} +.mainContent p { + line-height:1.56em; + margin-bottom:1.5em; + color:#404244; + max-width:85% +} +.mainContent b { + font-weight:600 +} +.context ul,.context ol { + margin-bottom:1.5em +} +.mainContent ul ul { + margin-top:0.5em +} +.mainContent .naviNextPrevious { + margin-top:25px; + max-width:100% +} +.naviNextPrevious.headerNavi { + display:none +} +.nextPage { + float:right +} +.prevPage:before { + content:"< " +} +.nextPage:after { + content:" >" +} +.navigationbar li:after { + color:#404244; + content:"›"; + display:inline-block; + font-size:1.5em; + line-height:1; + position:absolute; + right:-2px; + top:-4px +} +.navigationbar ul:last li a { + color:#80c342 +} +.sub-navigation { + margin-top:10px +} +.navigationbar li:last-child:after,.sub-navigation li:after { + content:none +} +.navigationbar { + margin-bottom:10px +} +#buildversion { + font-style:italic; + font-size:small; + float:right +} +.copy-notice { + width:65%; + font-size:0.75em; + margin-top:50px; + margin-bottom:25px; + line-height:1.75em; + color:#585a5c +} +li a.active { + color:#585a5c +} +.flowList { + padding:25px +} +.flowListDiv dl { + -webkit-column-count:1; + -moz-column-count:1; + column-count:1 +} +.flowList dd { + display:inline-block; + margin-left:10px; + width:90%; + line-height:1.15em; + overflow-x:hidden; + text-overflow:ellipsis +} +.alphaChar { + font-size:2em; + position:absolute +} +.flowList.odd { + background-color:#f9f9f9 +} +.context ul>li,.doc-column ul>li { + list-style-image:url("list_arrow.png"); + margin-left:15px; + color:#404244; + line-height:1.16em +} +.mainContent table p { + margin:0px; + padding:0px; + max-width:initial; + min-height:2em +} +.mainContent table p.centerAlign { + text-align:center +} +.context h2 { + font-size:2.1875em +} +.context h3 { + font-size:1.75em +} +.context h4 { + font-size:1.375em +} +.context p img { + margin-top:0.75em; + max-width:100% +} +.context .border img { + box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5) + } +.context .border .player { + box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5) + } +.context table { + vertical-align:initial +} +table .odd { + background-color:#f9f9f9 +} +table thead { + text-align:left; + padding-left:20px +} +table,table td,table th { + border:1px solid #eee +} +table td,table th { + padding:5px 20px; + line-height:1.3 +} +table.alignedsummary,table.propsummary { + width:initial +} +table.valuelist td.tblval { + font-size:0.75em +} +div.main_index .row { + border-bottom:1px solid #eee +} +div.main_index .row { + position:relative +} +div.main_index .row>div { + display:inline-block; + width:50%; + vertical-align:top; + padding:50px; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box +} +div.main_index h2 { + font-size:2.1875em; + margin-bottom:1em +} +#search_bar { + width:40%; + float:right +} +div.main_index .row:after { + content:""; + position:absolute; + top:0; + right:50%; + height:100%; + width:1px; + background-color:#eee +} +div.table { + overflow-x:auto +} +.context tr > td > pre { + font-size:0.85em +} +p.qt_commercial { + border:3px solid #5caa15; + margin:0 auto; + padding:15px; + width:28%; + text-align:center; + clear:both +} +h1.qt_commercial { + padding:20px; + background-color:#5caa15; + display:inline; + float:right; + font-size:1.25em; + line-height:1.25em; + height:1.25em; + color:#fff +} +div.qt_commercial { + border-top:5px solid #5caa15; + margin-bottom:50px +} +pre, .LegaleseLeft { + background-color:#404244; + color:#fff; + display:block; + font-family:"Droid Sans Mono"; + line-height:1.5; + overflow-x:auto; + margin-bottom:25px; + padding:25px; + margin-top:0.75em +} +.mainContent .LegaleseLeft p { + color:#fff; + white-space: pre-wrap +} +.copy_text { + background-color:#46a2da; + color:#fff; + border:2px solid #46a2da; + padding:10px 16px; + margin-left:-10px; + margin-top:-50px; + position:absolute; + opacity:0; + cursor:pointer; + float:right +} +.copy_text:hover { + background-color:#fff; + color:#46a2da +} +code,.codelike { + font-family:"Droid Sans Mono" +} +h3.fn code { + font-size:0.75em; + float:right; + background-color:#eee; + padding:3px; + margin: 3px 0 0 20px +} +pre:hover>.copy_text { + display:inline-block; + opacity:1; + transition:0.5s ease +} +#main_title_bar { + letter-spacing:-0.31em +} +#main_title_bar .search_bar { + letter-spacing:normal; + width:50%; + display:inline-block; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; + vertical-align:middle +} +#main_title_bar h1 { + letter-spacing:normal; + width:50%; + display:inline-block; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; + vertical-align:middle +} +#main_title_bar .search_bar * { + letter-spacing:normal; + padding:0; + margin:0; + border:none +} +#sidebar-toggle,#toc-toggle { + display:none +} +@media (max-width: 980px) { + body { + font-size:calc-em(14px) + } + #main_title_bar { + letter-spacing:-0.31em; + width:100% + } + #main_title_bar>h1,#main_title_bar .search_bar { + display:block; + width:100% + } + #main_title_bar .search_bar { + margin-bottom:15px + } + .main { + margin-top:0px + } + .main_index .row { + border:none !important + } + .title { + font-size:1.5em; + font-weight:400; + word-wrap:break-word + } + .col-1,.context,.naviNextPrevious,.sidebar { + padding:10px + } + .sidebar { + padding-top:0 + } + .search .sidebar { + display:none; + visibility:hidden + } + .col-2 h2,.toc h3,.sidebar-content h2,.sidebar-content h3,.sectionlist h2 { + text-align:center; + margin-bottom:0 + } + div.main_index .row:after { + content:none + } + div.main_index .row>div { + display:block !important; + width:100%; + padding:0; + margin:0 + } + .context,.sidebar,.col-1 { + width:100% + } + .main_index h2,h1 { + text-align:center + } + .context h4,.context h3,.context h2 { + text-align:center + } + .sidebar-content,.col-2,.toc { + background-color:#fff; + margin-bottom:1em; + padding:20px + } + #sidebar-toggle,#toc-toggle { + display:block + } + #sidebar-toggle.collapsed + h2 { + display:block + } + .mainContent p { + line-height:1.56em; + margin-bottom:1em; + max-width:100% + } + table td,table th { + padding:5px 5px + } + .sectionlist { + padding:0 + } +} +[id]:target,[name]:target,[name]:target+* { + -webkit-animation:highlighter 3s; + animation:highlighter 3s +} +@-webkit-keyframes highlighter { + 25% { + background-color:#d1e8f6; + color:#444 + } + 75% { + background-color:#d1e8f6; + color:#444 + } +} +@keyframes highlighter { + 25% { + background-color:#d1e8f6; + color:#444 + } + 75% { + background-color:#d1e8f6; + color:#444 + } +} +@-webkit-keyframes copypaste { + 25% { + opacity:1 + } + 100% { + border-radius:10px; + margin-top:-50px; + opacity:1 + } +} +@keyframes copypaste { + 25% { + opacity:1 + } + 100% { + border-radius:10px; + margin-top:-50px; + opacity:1 + } +} +#footer { + clear:both +} +.menuextraslanguages { + display:none; + visibility:hidden +} +form.gsc-search-box { + font-size: 25px !important; + margin-top: 0 !important; + margin-right: 0 !important; + margin-bottom: 4px !important; + margin-left: 0 !important; + width: 100% !important; +} +table.gsc-search-box { + border-style: none !important; + border-width: 0 !important; + border-spacing: 0 0 !important; + width: 100% !important; + margin-bottom: 2px !important; +} + +table.gsc-search-box td { + vertical-align: middle !important; +} + +table.gsc-search-box td.gsc-input { + padding-right: 0px !important; +} +table.gsc-search-box td.gsc-input input { + background-position: 15px center !important; +} + +td.gsc-search-button { + width: 1% !important; +} + +td.gsc-clear-button { + width: 14px !important; + visibility:hidden !important; + display:none !important; +} +table.gsc-branding td, +table.gsc-branding { + margin: 0 0 0 0 !important; + padding: 0 0 0 0 !important; + border: none !important; +} + +table.gsc-branding { + border-style: none !important; + border-width: 0 !important; + border-spacing: 0 0 !important; + width: 100% !important; +} + +.gsc-branding-text { + color: #676767 !important; +} + +td.gsc-branding-text { + vertical-align: top !important; +} +td.gsc-branding-text div.gsc-branding-text { + padding-bottom: 2px !important; + text-align: right !important; + font-size: 11px !important; + margin-right: 2px !important; +} + +td.gsc-branding-img { + width: 65px !important; + vertical-align: bottom !important; +} + +img.gsc-branding-img { + padding-top: 1px !important; + margin: 0 0 0 0 !important; + padding-right: 0 !important; + padding-left: 0 !important; + padding-bottom: 0 !important; + border: none !important; + display: inline !important; +} + +input.gsc-search-button { + background-color: white !important; + height: 35px !important; + width: 25px !important; + color: transparent !important; + background-image: url("doc_search.png") !important; + background-size: 25px auto; + background-position: 0px 5px; + background-repeat: no-repeat; + margin-left: -43px !important; + overflow: hidden; + min-width: 20px !important; +} + +input.gsc-search-button:hover { + cursor: pointer; +} + +input.gsc-search-button:focus { + outline: none; + box-shadow: none; +} + +.gsc-search-box-tools .gsc-clear-button { + display: none !important; + visibility: none !important; +} + +.gsc-overflow-hidden { + overflow: hidden !important; +} + +input.gsc-input { + background-color: #fff !important; + border: 1px solid #d6d6d6 !important; + border-radius: 5px !important; + box-sizing: border-box !important; + -moz-box-sizing: border-box !important; + color: #868482 !important; + outline: 0 none !important; + padding: 9px 10px 10px !important; + transition: color 0.5s ease 0s, box-shadow 0.5s ease 0s, background-color 0.5s ease 0s !important; +} + +input { + font-family: 'Open Sans', Arial, Helvetica, sans-serif !important; + line-height: 1.5 !important; + font-weight: 300 !important; + vertical-align:middle +} + +input:focus { + border-color: #46a2da; + box-shadow: 0 0 5px #46a2da; + color: #000; +} + +a.qa-mark:target:before { + content: "***"; + color: #ff0000; +} + +.mainContent .video { + width:60%; + max-width:640px; + margin: 0.5em 0 1.5em 0.5em; + position:relative; + display:table +} + +.mainContent .video > .vspan { + padding-top:60%; + display:block +} +.mainContent .video iframe { + width:100%; + height:100%; + position:absolute; + top:0; + left:0 +} diff --git a/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/theqtcompany.png b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/theqtcompany.png new file mode 100644 index 0000000..fee3d26 Binary files /dev/null and b/dde-file-manager-5.5.3/docs/qdoc-configs/template/style/theqtcompany.png differ diff --git a/dde-file-manager-5.5.3/docs/qdoc/classes.qdoc b/dde-file-manager-5.5.3/docs/qdoc/classes.qdoc new file mode 100644 index 0000000..01b56ba --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/classes.qdoc @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page classes.html + \title All DFM Classes + \ingroup classlists + + \brief Alphabetical list of classes. + + This is a list of all DFM classes. + + \generatelist classes DFM +*/ \ No newline at end of file diff --git a/dde-file-manager-5.5.3/docs/qdoc/componments.qdoc b/dde-file-manager-5.5.3/docs/qdoc/componments.qdoc new file mode 100644 index 0000000..bc42d46 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/componments.qdoc @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page componments.html + \title Componments + \nextpage Crumb Bar and Address Bar + + This is a list of topics about the componments of Deepin File Manager. + + \list + \li \l {Crumb Bar and Address Bar} + \endlist + + \sa {All DFM Classes} +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/componments/crumb.qdoc b/dde-file-manager-5.5.3/docs/qdoc/componments/crumb.qdoc new file mode 100644 index 0000000..5198ced --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/componments/crumb.qdoc @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page crumb.html + \title Crumb Bar and Address Bar + + Working in progress page... + + \sa {Crumb Bar and Address Bar (zh)} +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/componments/crumb_zh.qdoc b/dde-file-manager-5.5.3/docs/qdoc/componments/crumb_zh.qdoc new file mode 100644 index 0000000..bdcaac9 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/componments/crumb_zh.qdoc @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page crumb-zh.html + \title Crumb Bar and Address Bar (zh) + + 面包屑栏 和 地址栏 + + \section1 结构关系 + + 面包屑新增的类共三个,即 \b{面包屑栏} DFMCrumbBar , \b{面包屑项} DFMCrumbItem 和 \b{地址栏} + DFMAddressBar 。其中 \b{地址栏} 由 \b{面包屑栏} 管理, \b{面包屑栏} 由 DToolbar 管理,二 + 者互相独立,而 \b{面包屑项} 则由 \b{面包屑栏} 管理。 + + 另外根据需求我们需要提供插件接口并实现预制插件支持现有的协议,新增插件接口类 DFMCrumbInterface + 和相应实现类(称为\e{面包屑栏控制器},\e{CrumbController})。插件类的注册和加载由 DFMCrumbManager + 管理,并且 \b{地址栏} 和 \b{面包屑栏} 分别持有自己独立的面包屑栏控制器。 + + \section1 面包屑栏 + + \section2 控件结构 + + 使用 `QHBoxLayout` 盛放栏内主要内容,共三项,左箭头、面包屑容器 和 右箭头。箭头默认隐藏,当面包屑容 + 器宽度不足以完整显示面包屑容器内的项时据情况显示左右箭头。 + + 面包屑容器使用 QScrollArea 作为容器, QHBoxLayout 做为布局并将 \b{面包屑项} DFMCrumbItem 至于其中。 + + 由于面包屑栏也负责管理地址栏 DFMAddressBar 的状态,故除了面包屑栏状态外还负责地址栏的显示隐藏和状态的管理。 + + \section2 相关类 + + 详细文档请见 \l DFMCrumbBar 。 + + \section1 面包屑项 + + \section2 控件结构 + + 使用 QPushButton 作为面包屑项,接受点击和 Drop 事件。每个项均可设置文字和/或图标。点击时将跳转到项所指的 + Url , Drop 时复制文件到所指 Url 。 + + \section2 相关类 + + 为了方便新增一个简单的纯数据类(于 DFMCrumbInterface ,其构造函数此处省略): + + class CrumbData { + DUrl url; + QString iconName; + QString displayText; + QString iconKey = "icon"; + }; + + 详细文档请见 \l DFMCrumbItem 。 + + \section1 地址栏 + + \section2 控件结构 + + 使用 `QLineEdit` ,状态由面包屑栏管理。 + + 搜索栏应维护一个候选列表用于其接管的候选词列表控件(使用 `QStringListModel`)。用户输入时应检查候选词 + 列表并更新候选列表控件状态,补全状态。应响应 Tab 键补全。 + + \section2 相关类 + + 详细文档请见 \l DFMAddressBar 。 + + \section1 面包屑插件 + + 面包屑插件的任务为为(额外的)协议提供分割路径的功能。 + + 加载面包屑通过如下固定的 IID 识别区分插件: + + \code + #define DFMCrumbFactoryInterface_iid "com.deepin.filemanager.DFMCrumbFactoryInterface_iid" + \endcode + + 加载插件时通过 Url 的 scheme 作为插件 key ,当存在多个插件注册同一个 key 时,使用最后一个注册的插件。 + + - 插件的识别注册: DFMCrumbManager (单例) + - 插件实例工厂: `DFMCrumbFactory`, 其 `create(key)` 返回新 DFMCrumbInterface 实例的指针。 + + 由于插件应该能够针对不同的 Url 的 scheme 使得面包屑栏做出不同的行为,故插件接口类持有一个 `DFMCrumbBar` 实例的指针用以访问面包屑栏。 + + \section2 相关类 + + 详细文档请见 \l DFMCrumbManager , \l DFMCrumbInterface 。 + +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/componments_zh.qdoc b/dde-file-manager-5.5.3/docs/qdoc/componments_zh.qdoc new file mode 100644 index 0000000..345b774 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/componments_zh.qdoc @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page componments-zh.html + \title Componments (zh) + \nextpage Knowledge Base (zh) + + 开发者文档 - 组件 + + 这里是深度文件管理器各个组件的开发设计流程文档. + + \list + \li \l {Crumb Bar and Address Bar (zh)} {面包屑栏和地址栏} + \endlist + + \sa {All DFM Classes} +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/index.qdoc b/dde-file-manager-5.5.3/docs/qdoc/index.qdoc new file mode 100644 index 0000000..c80f1e3 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/index.qdoc @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page index.html + \title Developer Documentation Index + \nextpage Componments + + \section1 Welcome! + + This is the developer documentation page of Deepin File Manager! + + \section1 Languages + + Documentation languages index: + + \list + \li \l {Developer Documentation Index} {English} (Current) + \li \l {Developer Documentation Index (zh)} {简体中文} + \endlist + + \section1 Navigation + + Currently there are two main sections of the documentation page. + + \list + \li \l {Componments} {Componments of Deepin File Manager} + \li \l {All DFM Classes} {All Deepin File Manager C++ Classes} + \endlist + + \section1 Feedback and Contribution + + The developer documentation of Deepin File Manager is still working in progress, + If you got any issue and looking for help, please submit your issue via the + following methods.... + + \list + \li Ask in the \l {https://github.com/linuxdeepin/developer-center} {Developer Center} + \li Ask in our \l {https://bbs.deepin.org/} {Official Forum} + \li or submit an issue in \l {https://github.com/linuxdeepin/dde-file-manager/issues} {Issue board} + \endlist + + We also encourage you to report issues and contribute changes. + + \list + \li \l {https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers-en} {Contribution guide for developers} + \li \l {https://www.transifex.com/linuxdeepin/deepin-file-manager/} {Localization via Transifex} + \endlist +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/index_zh.qdoc b/dde-file-manager-5.5.3/docs/qdoc/index_zh.qdoc new file mode 100644 index 0000000..c4d94cd --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/index_zh.qdoc @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page index-zh.html + \title Developer Documentation Index (zh) + \nextpage {Componments (zh)} {组件} + + \section1 欢迎! + + 这里是深度文件管理器的开发者文档页面! + + \section1 文档语言 + + 文档语言列表: + + \list + \li \l {Developer Documentation Index} {English} + \li \l {Developer Documentation Index (zh)} {简体中文} (当前) + \endlist + + \section1 文档导航 + + 当前我们的文档页包含以下两个主要部分: + + \list + \li \l {Componments (zh)} {深度文件管理器 组件页} + \li \l {All DFM Classes} {深度文件管理器的所有 C++ 类} + \endlist + + \section1 知识库 + + 对于和文件管理器相关的,但不仅限于深度文件管理器的一些知识,可以在知识库中查看: + + \list + \li \l {Knowledge Base (zh)} {知识库 首页} + \endlist + + \section1 反馈 和 贡献方式 + + 开发者文档的相关页面还在逐渐完善中,如果你有任何问题或建议,你可以通过下面给出的途径反馈给我们: + + \list + \li 在 \l {https://github.com/linuxdeepin/developer-center} {开发者中心} 中提问 + \li 在 \l {https://bbs.deepin.org/} {官方论坛} 中提问 + \li 或者在 \l {https://github.com/linuxdeepin/dde-file-manager/issues} {Issue 面板} 中提交 Issue + \endlist + + 我们也建议你能够参与到深度文件管理器的开发中来,请参阅: + + \list + \li \l {https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers} {开发者代码贡献指南} + \li \l {https://www.transifex.com/linuxdeepin/deepin-file-manager/} {在 Transifex 上参与帮助多语言翻译} + \endlist +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/knowledgebase/contextmenuext_zh.qdoc b/dde-file-manager-5.5.3/docs/qdoc/knowledgebase/contextmenuext_zh.qdoc new file mode 100644 index 0000000..13c4550 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/knowledgebase/contextmenuext_zh.qdoc @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2017 ~ 2019 Deepin Technology Co., Ltd. + * + * Author: zccrs + * + * Maintainer: Gary Wang + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/* + * TODO: 使用 doxygen 生成文档以便复用 markdown 文档。 + */ + +/*! + \page context-menu-ext-zh.html + \title Context Menu Extension (zh) + + 知识库 - 编写上下文菜单扩展 + + \section1 上下文菜单 + + 在大多应用软件程序中,在特定位置按下上下文菜单按键(通常是鼠标右键)即可触发对应语义的上下文菜单。 + 在深度文件管理器中,在文件浏览视图位置的不同情况下,如在文件上、在文件夹上、或者是在空白位置 + 按下上下文菜单键都会触发不同内容的上下文菜单。 + + 通常情况,空白位置的上下文菜单会呈现创建文件或是对当前路径进行的其他常见操作,而在文件上触发上下文菜单 + 则会呈现可对文件进行的若干处理选项,如打开方式、剪切等内容。 + + 尽管默认的呈现内容应当涵盖了大部分的使用场景,用户或应用程序可能依然希望呈现额外的上下文菜单以便辅助使用。 + 本文即覆盖了编写自己的上下文菜单扩展的须知内容。 + + \section1 深度文件管理器的上下文菜单扩展支持 + + 深度文件管理器目前提供多种形式的上下文菜单扩展支持,为 desktop 格式的上下文菜单扩展支持、 json 格式的扩展支持和 + C++ 插件形式的上下文菜单扩展插件。 + + 在 v20 以上版本的文件管理器(版本号高于 5.0.0)中,我们提供了 desktop 格式形式的上下文菜单扩展支持和 C++ 插件形式的上下文菜单支持, + 在 v15 版本中,文件管理器提供了 json 文件形式的扩展支持和 C++ 插件形式的上下文菜单支持,为了方便用户和开发者,我们还 + 提供了适用于 v15 版本文件管理器的 desktop 格式形式的扩展支持插件。请根据您的实际需求选择对应的方案,配置方法参见下方的详细描述。 + + 需要注意的是,如果您希望为您的应用程序能够出现在 “打开方式” 的应用列表中,您应当考虑为您的应用程序编写适当的 + .desktop 文件并指定对应的 MimeType 文件(请参见 \l {https://www.freedesktop.org/wiki/Specifications/desktop-entry-spec/} {desktop-entry-spec})。 + 如果您希望您的自定义文件类型能够出现在 “新建文档” 的列表中,您应当参阅 \l {New File Templates (zh)} {新建文件模板} 。 + 对于上述的这两种需求情况,使用上下文菜单扩展都不是恰当的选择。 + + \section2 desktop 格式形式的上下文菜单扩展 + + 适用版本:适用于 v20 版本(即版本 > 5.0.0 )的深度文件管理器,或安装了 desktop 格式形式的上下文菜单扩展插件(在 Deepin 中包名为 dde-file-manager-menu-oem)的 v15 版本文件管理器。 + + 文件管理器会识别指定目录( `/usr/share/deepin/dde-file-manager/oem-menuextensions` )下的 `.desktop` 文件,并将其视为扩展菜单项,加入到文件管理器的上下文菜单中。 + 开发者或用户仅需按照正确的格式编写 desktop 文件并放置于对应目录即可使用。 + + 每个有效的 desktop 格式形式的上下文菜单扩展均为一个独立的 Application 类型的 `.desktop` 文件。对于每个文件,在其 `[Desktop Entry]` 下至少需要包含 `Name` 和 `Exec` 字段, + `Name` 的内容为添加到上下文菜单中时将会显示的名称,`Exec` 的内容为当单击此新增的菜单项时将会执行的行为(遵循 desktop 文件规范标准,可以使用 `%u` 等参数)。 + + 定制菜单支持使用 `Actions` 字段增加指定的子菜单,子菜单需至少包含 `Name` 和 `Exec` 字段,可以通过 `Icon` 指定图标。 + 若指定子菜单,则入口项(原本 `[Desktop Entry]` 下)的 `Exec` 字段将不再有效。 + + 对于文件管理器菜单项定制,支持额外的字段可供定制,可以使用 `X-DFM-MenuTypes` 字段来指定菜单项在何种情况会显示,此字段可包含一个或多个类型, + 其中包括 `SingleFile`, `SingleDir`, `MultiFileDirs` 和 `EmptyArea` 四种。 + + 对于此种类型的配置详细规则,请参阅:\l {https://github.com/linuxdeepin/dde-file-manager/blob/master/doc/PLUGIN-README.md} {项目源码仓库中所附带的 PLUGIN-README.md} + + \section3 示例扩展 + + 可以将下面的示例存储为 `test.desktop` 并放置到 `/usr/share/deepin/dde-file-manager/oem-menuextensions/` 中,关闭现有的所有文件管理器窗口并打开新的文件管理器窗口,定制的菜单将会出现在单独目录或多选文件的情况的上下文菜单中。 + + \code +[Desktop Entry] +Type=Application +Exec=/home/wzc/Temp/test.sh %U +Icon=utilities-terminal +Name=示例菜单项名称 +X-DFM-MenuTypes=SingleDir;MultiFileDirs; + \endcode + + \section2 Json 形式的上下文菜单扩展 + + 适用版本:仅适用于 v15 版本,即版本 <= 5.0.0 的深度文件管理器。 + + 注意:如果您计划在将来升级到 v20 版本的文件管理器,请考虑安装由我们提供的适用于 v15 版本的 desktop 格式形式的扩展支持插件,并使用 desktop 格式形式的扩展支持。 + + 默认情况下文件管理器会在开启时试图加载 `~/.config/deepin/dde-file-manager/menuextensions/` 目录 + (如需要编写此类扩展但发现此路径不存在时,手动创建完整路径即可)中的 json 文件作为上下文菜单扩展, + 对于一个上下文菜单扩展,应当包含有如下的通用字段。 + + \section3 通用字段 + + 支持扩展的右键菜单各个字段说明: + + \list + \li MenuType 菜单类型(必须指定) + \list + \li SingleFile 选中单个文件 + \li MultiFiles 选中多个文件 + \li SingleDir 选中单个目录 + \li MultiDirs 选中多个目录 + \li MultiFileDirs 选中多个文件和目录 + \li EmptyArea 空白区域 + \endlist + \li Icon 菜单项的指定图标(可选) + \list + \li Icon: /home/djf/Music/usb_normal_16px.svg + \endlist + \li Text[local] 根据不同的语言环境给出不同的菜单文本(必须指定) + \list + \li Text[zh_CN]: 示例文本 + \li Text[en]: Sample Text + \li ... + \endlist + \li Exec 点击菜单项执行的命令(必须指定) + \list + \li Exec: xterm 启动 XTerm 。注意此项只能跟一个名称,不能包含参数。 + \endlist + \li Args 执行命令的额外参数列表 + \list + \li "Args": ["."] 为执行 Exec 内容指定额外的一个参数(".")。 + \endlist + \li NotShowIn 在什么情况下不显示 + \list + \li "NotShowIn": ["Desktop"] 在桌面上不显示此菜单。 + \endlist + \li SubMenu 子菜单列表,子菜单列表不需要再次指定 MenuType 字段,其他字段参数一样,支持 SubMenu 中嵌套无限 + \endlist + + 如果 MenuType 为 SingleFile 或者 MultiFiles ,可以增加下面两个字段来细化菜单控制。 + + \list + \li MimeType 文件的MimeType类型,如果指定了这个参数,表示只拓展这个类型的文件右键菜单;以;隔开 + \list + \li MimeType:text/plain;image/jpeg + \endlist + \li Suffix 文件的后缀,如果指定了这个参数,表示只拓展后缀名为指定后缀的文件的右键菜单;以;隔开 + \list + \li Suffix: md;txt + \endlist + \li 如果MimeType和Suffix两个参数同时指定,表示文件类型为MimeType且后缀名为Suffix的文件才支持扩展右键菜单 + \endlist + + \section3 示例扩展 + + 下面的示例为 在文件管理器的空白区域触发上下文菜单,增加 “在 VSCode 中打开” 选项 的示例。 + + \code + [ + { + "MenuType": "EmptyArea", + "Icon": "Files", + "Text[zh_CN]": "在 VSCode 中打开", + "Text[en_US]": "Open with VSCode", + "Exec": "code", + "Args": ["."], + "NotShowIn": ["Desktop"], + } + ] + \endcode + + 下面为旧文档中所附带的示例。 + + \quotefile context-menu-ext.json + + \section2 遵守 Qt 插件规范的 C++ 上下文菜单插件 + + 注意:接口可能在将来废弃或调整,尽管适用于 v15 和 v20 版本,但仍不推荐使用。 + + 文件管理器支持加载 Qt 规范的 C++ 插件,实现需继承 MenuInterface ,遵守 Qt 的插件规范实现你的菜单插件接口。 + + \section3 插件头文件 + + 在安装好 libdde-file-manager-dev (文件管理器开发包)后即可得到对应的插件头文件 menuinterface.h ,使用时需在对应的代码中包含此文件。 + + \code + #include "dde-file-manager-plugins/menuinterface.h" + \endcode + + \section3 接口说明 + + \list + \li virtual QList additionalMenu(const QStringList &files, const QString& currentDir) 实现这个接口可以扩展选中文件的右键菜单 + \list + \li const QStringList &files 表示选中的文件的完整路径列表 + \li const QString& currentDir 表示选中的文件所在的目录 + \li QList 返回一组QAction指针列表 + \endlist + \li virtual QList additionalEmptyMenu(const QString ¤tDir, bool onDesktop = false) 实现这个接口可以扩展空白处的右键菜单 + \list + \li const QString& currentDir 表示空白处所在的文件目录 + \li const QString& currentDir 表示空白处所在的文件目录 + \li QList 返回一组QAction指针列表 + \endlist + \endlist + + \section3 插件安装目录 + + 在 Deepin 上,安装位置为 `/usr/lib//dde-file-manager/plugins/menu/` ,其中 表示对应架构名,可以通过 `gcc -dumpmachine` 得到。下表供参考: + + \list + \li x86 架构 + \list + \li /usr/lib/x86_64-linux-gnu/dde-file-manager/plugins/menu/ 64位 + \li /usr/lib/x86_32-linux-gnu/dde-file-manager/plugins/menu/ 32位 + \endlist + \li 龙芯架构 + \list + \li /usr/lib/mipsel-linux-gnu/dde-file-manager/plugins/menu/ + \endlist + \li 神威架构 + \list + \li /usr/lib/sw_64-linux-gnu/dde-file-manager/plugins/menu/ + \endlist + \endlist + + \section3 源码 + + 对于接口头文件的源码,可以直接参阅开发包所附带的头文件。以下为可供参考的简单右键菜单扩展插件实例源码。 + + context-menu-ext/content-menu-ext.pro: + + \quotefile context-menu-ext/content-menu-ext.pro + + context-menu-ext/dfmctxmenuplugin.h: + + \quotefile context-menu-ext/dfmctxmenuplugin.h + + context-menu-ext/dfmctxmenuplugin.cpp: + + \quotefile context-menu-ext/dfmctxmenuplugin.cpp + + \section1 参考链接 + + \list + \li \l {https://github.com/linuxdeepin/dde-file-manager/issues/21} {How to add entry to context menu?} + \endlist +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/knowledgebase/hidefilebyrule_zh.qdoc b/dde-file-manager-5.5.3/docs/qdoc/knowledgebase/hidefilebyrule_zh.qdoc new file mode 100644 index 0000000..d27f848 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/knowledgebase/hidefilebyrule_zh.qdoc @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2017 ~ 2019 Deepin Technology Co., Ltd. + * + * Author: zccrs + * + * Maintainer: Gary Wang + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page hide-file-by-rule-zh.html + \title Hide File by Rule (zh) + + 知识库 - 根据规则彻底隐藏文件 + + \section1 可能的应用场景 + + 深度文件管理器遵循一个约定俗成的标准来隐藏文件,即隐藏由文件名半角字符点(`.`)开头的文件。 + 文件管理器会默认不显示这些文件,除非手动设置了显示隐藏的文件的选项(或通过快捷键Ctrl+H + 来切换显示和隐藏状态)。 + + 但有时用户可能有需求根据某些规则隐藏掉特定的一些文件,例如,深度文件管理器后端存储标签和快速 + 索引信息时会在每个可写分区的根目录生成所用的数据库文件(.__deepin.db),以及 Windows 的 ntfs + 分区中很可能包含的 `System Volume Information` 目录。这些文件一定程度上可以认为是所谓的 + “系统文件”,因而可能被用户希望永久隐藏。 + + 用户也可能存在其他场景匹配此类需求,此时即可根据添加规则到配置文件来实现彻底隐藏指定规则的文件。 + + \section1 实际做法 + + 当存在“希望根据规则来隐藏特定文件或目录”的需求时,即可根据修改配置文件,添加规则的方式来达到目的。 + + \section2 配置文件的位置 + + 在1.8版本中统一了配置文件的格式和程序中的读写入口,针对根据规则彻底隐藏文件这个需求而言, + 所涉及的配置文件位于 `~/.config/deepin/` 目录下,对应的配置名称为 dde-file-manager.obtusely.json + ,是常规的 json 文件。 + + \section2 规则编写方式 + + 我们可以在 "PrivateFiles" 这个 json 对象中添加正则表达式规则。满足我们规则的文件 + 就会在文件管理器中隐身。 + + \code + { + "PrivateFiles": { + "Hide deepin system files": "^\\.__deepin.+", + "Hide System Volume Information": "System Volume Information", + "Hide $RECYCLE.BIN": "\\$RECYCLE\\.BIN", + "Hide .Trash-1000": "\\.Trash-1000" + } + } + \endcode + + \section2 注意 + + 根据此规则所隐藏的文件为彻底隐藏,不会受到“显示隐藏文件”选项状态的影响。 + + \section1 参考链接 + + \list + \li \l {https://docs.deepin.io/?p=703} {文件管理器新配置文件格式详解} + \li \l {https://bbs.deepin.org/forum.php?mod=viewthread&tid=172237} {教大家几招文件管理器隐私管理的技巧} + \li \l {https://github.com/linuxdeepin/developer-center/issues/923} {[需求]隐藏 .deepin.db、.deepin.lft、.deepin.num等文件} + \endlist +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/knowledgebase/newfiletemplates_zh.qdoc b/dde-file-manager-5.5.3/docs/qdoc/knowledgebase/newfiletemplates_zh.qdoc new file mode 100644 index 0000000..5afc881 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/knowledgebase/newfiletemplates_zh.qdoc @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * Gary Wang + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page new-file-templates-zh.html + \title New File Templates (zh) + + 知识库 - 新建文件模板 + + \section1 新建文件模板是什么 + + 当你在文件管理器中的空白位置打开上下文菜单(比如通过按下鼠标右键的方式)时,你将会看 + 到一个应用于空白位置的上下文菜单,其中就包括了一个 "新建文档" 的子菜单选项。你可以通 + 过选择这些项目来快速的创建对应类型的新文件,我们称呼这里出现的选项为 “模板”。 + + 新建文件模板可以快速的帮助用户完成创建文件的工作,不同的文件管理器都有对新建文件的模板 + 有着不同程度的支持。例如,在深度文件管理器中,可以通过 “新建文档 > 文本文档” 选项快速 + 创建完全空白的文本以便编辑,而在 Dolphin 文件管理器中可以通过 “新建 > HTML 文档” 来 + 创建包含最基本 HTML 结构的新 HTML 文档。 + + 不同的文件管理器都有着对新建文件模板功能的不同程度的支持,对于包含深度文件管理器在内的 + 大多文件管理器,用户除了使用內建的新建文件模板外,亦可通过自行配置的方式为文件管理器本身 + 新增额外的模板选项以供自己更方便的使用文件管理器。 + + \section1 深度文件管理器的新建文件模板支持 + + 除了內建的新建文件模板选项之外,深度文件管理器支持通过三种不同的方式自定义新建文件模板。 + 在深度文件管理器的 1.8 版本(内部版本 4.6.9)后,深度文件管理器支持共三种方式供用户 + 创建自己的新建文件模板,分别为单文件模板,元信息模板和深度文件管理器专有模板。 + + \section2 单文件模板 + + \section3 简介 + + 单文件模板是位于 freedesktop 规范内 xdg-user-dirs 所记录的模板目录内的单文件。 + 常被 GNOME Nautilus (鹦鹉螺)及其衍生版本文件管理器所支持,而并非 Nautilus 所 + 衍生的部分文件管理器,如 PCManFM 和深度文件管理器也都支持这种单文件模板。 + + 单文件模板的优点在于使用简单方便,用户只需要在对应的模板目录下放置准备好的模板文件即可, + 不需要进行额外的任何配置即可使其出现在支持单文件模板的文件管理器的新建菜单选项中。 + + \section3 使用方式 + + 通过在终端执行 `xdg-user-dir TEMPLATES` 即可查看你的模板目录的位置,这时只需要 + 把你准备好的模板文件放置在这个文件夹内即完成了配置工作。对于深度文件管理器,此时只需 + 关闭现在所有已打开的文件管理器窗口,并重新打开新的深度文件管理器窗口即可看到你所添加 + 的项目。 + + 如果你的新建文件模板文件夹不存在,手动创建该文件夹即可,你也可以通过配置来改变包括新建 + 文件模板文件夹的路径在内的用户文件夹路径,此做法不在本篇知识库的讨论范围内,请自行参阅 + \l {https://jlk.fjfi.cvut.cz/arch/manpages/man/xdg-user-dirs-update.1} {xdg-user-dirs-update(1)} + 和其他相关内容了解如何操作。 + + \section2 元信息模板 + + \section3 简介 + + 元信息模板通过在指定的文件模板路径创建包含有所需元信息的 .desktop 文件的方式来创建 + 新建文件的模板选项。该种方式较为复杂但有着相对较高的可配置性。例如可以通过给定不同国家 + 语言的元信息来使得新建文件的选项名称能够在不同的系统语言下分别呈现不同的内容。因而可供 + 软件的开发商用来增加文件管理器对其软件的支持所使用。此类模板被 KDE 的文件管理器 + (如 Dolphin 或 Konqueror) 所支持,此外 PCManFM 和深度文件管理器也都对此类模板 + 有着不同程度的支持。 + + \section3 使用方式 + + 通过在终端执行 `kf5-config --path templates` 即可查看元信息模板所使用的目录位置, + 这时候应当在你得到的目录下创建新的 .desktop 文件并给定必要的信息以供使用。这些信息包 + 含在 `[Desktop Entry]` 项内,分别需要提供 Name, Comment, Type, URL 和 Icon + 这五个信息,以表示对应项目的名称,描述信息,类型,模板文件位置以及项目图标。 + + 该类型所使用的一个全局的路径为 `/usr/share/templates` ,如果你是第三方软件的开发者或 + 打包者,你很可能希望将你所提供的文件源信息模板安装到这个路径下,并将实际的模板文件放置在 + 元信息模板文件所在目录的 `.source` 子目录下。 + + 深度文件管理器有着对此类模板的完整支持,但在深度文件管理器中,会检查元信息的有效性,当 + 原信息无效时(例如元信息中的 URL 所指向的实际模板文件不存在),会忽略此元信息模板。故 + 如果你所添加的元信息模板无法在深度文件管理器中显时,请检查元信息是否提供有误。对于详细的 + 编写格式以及示例,可参阅 \l {https://userbase.kde.org/Adding_an_entry_to_the_Create_New_menu} {KDE 用户维基中的 “为新建菜单添加一个项目” 条目} + + \section2 深度文件管理器专有模板 + + 在深度文件管理器的较早版本(早于版本号为 1.8 的深度文件管理器)中,深度文件管理器只支 + 持自己的文件管理器模板用以定制文件管理器的新建文档选项。我们暂时不提供这种模板的编写和 + 使用方式。如果您在使用早于 1.8 版的文件管理器,请升级您的文件管理器并使用上方提到的另 + 外两种文件模板配置方式。如果您的确需要使用深度文件管理器的专有模板支持,您可以联系深度 + 进行商业支持或自行阅读源码等方式了解此类模板的创建和使用方式。 + + \section1 参考链接 + + \list + \li \l {https://userbase.kde.org/Adding_an_entry_to_the_Create_New_menu} {KDE 用户维基中的 “为新建菜单添加一个项目” 条目} + \li \l {https://www.freedesktop.org/wiki/Software/xdg-user-dirs/} {freedesktop.org 上的 `xdg-user-dirs`} + \endlist +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/knowledgebase_zh.qdoc b/dde-file-manager-5.5.3/docs/qdoc/knowledgebase_zh.qdoc new file mode 100644 index 0000000..a99bb70 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/knowledgebase_zh.qdoc @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page knowledge-base-zh.html + \title Knowledge Base (zh) + \nextpage New File Templates (zh) + + 知识库 - 首页 + + 这里是一些和深度文件管理器相关的知识库页面,这个页面的内容包括但不限于可被应用在深度 + 文件管理器的开发和使用中的知识. + + \list + \li \l {New File Templates (zh)} {新建文件模板} + \li \l {Hide File by Rule (zh)} {根据规则彻底隐藏匹配的文件} + \li \l {Context Menu Extension (zh)} {编写上下文菜单扩展} + \endlist +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/schemes/burn.qdoc b/dde-file-manager-5.5.3/docs/qdoc/schemes/burn.qdoc new file mode 100644 index 0000000..e5b9156 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/schemes/burn.qdoc @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2017 ~ 2019 Deepin Technology Co., Ltd. + * + * Author: Chris Xiong + * + * Maintainer: Chris Xiong + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page burn-scheme.html + \title Burn Scheme + + The Burn scheme is used for the optical media authoring feature in the file manager. + + \section1 Scheme Structure and Other Basics + + URL of this scheme has the following structure: + + burn://// + + These three sections will be referred to as the device segment, the status segment and the path segment + in the rest of this documentation. DUrl contains functions to fetch these segments for your convenience. + Macros for the strings used by the status segment can also be found there. + + Examples: + + burn:///dev/sr0/disc_files/EFI/ + + burn:///dev/sr0/staging_files/README.txt + + Each file using this scheme has a corresponding file in the local file hierarchy as its backer file. + If the middle segment of the path is "disc_files", its backer file is in the mount point of the optical + disc. Otherwise its backer file is in a temporary folder containing the files staged to be burnt (usually + ~/.cache/deepin/dde-file-manager/diskburn/). + + \section1 FileInfo Usage + + FileInfo objects for files of this scheme have proxies to its backing file. Therefore you can expect most + functions to work exactly the same as if you are dealing with the actual file. Some of the notable differences + are documented as follows: + + \list + \li canRedirectionFileUrl() returns false for directories, even though redirectedFileUrl() can still be used + in this case. + \li if the path segment contains nothing but slashes, parentUrl() and goToUrlWhenDeleted() will return the home + directory of the current user. + \endlis + + \section2 Controller Usage + + The controller mainly deals with files staged for burning. Some of its functions have a different purpose and + distinctive behaviors. + + \list + \li pasteFile adds files to the staging collection. The files are actually pasted into the staging folder for + the target device. If the pasted file is a single ISO file and both the target disc and its staging folder + are empty, the user will be prompted whether to burn the image file. + \li deleteFiles and moveToTrash both remove files completely, when used on staging files. + \li The directory iterator returned by this controller will iterate through both on disc files and staging + files of the same path if created for a on disc URL. If created for a staging URL however, it only iterates + through staging files with that path. If there are files with the same name on the disc and in the staging + folder, the staging one will be ignored. + \li The file watcher employed by the scheme only watches for staging files. However, it does watch for the mount + point of the disc to generate a signal when the mount point is removed. It also watch for signals from UDisks + for the same purpose because the first method doesn't work when disc is ejected by pressing the eject button + on the drive with certain system configurations. Manual ejection detection is still somewhat broken even with + the workaround at the moment. + \endlist + + In order to actually start a burn session, invoke the dialog BurnOptDialog. The user will be asked for options + and confirmation. Erasing a disc is initiated by calling AppController::actionOpticalBlank. + +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/schemes/dfmroot.qdoc b/dde-file-manager-5.5.3/docs/qdoc/schemes/dfmroot.qdoc new file mode 100644 index 0000000..a851436 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/schemes/dfmroot.qdoc @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2017 ~ 2019 Deepin Technology Co., Ltd. + * + * Author: Chris Xiong + * + * Maintainer: Chris Xiong + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page dfmroot-scheme.html + \title DFMRoot Scheme + + The DFMRoot scheme is primarily designed to be used by the new Computer View. It is essentially an enhanced version of the computer scheme found in Gvfs. + + The scheme deals with 3 types of locations: user directories, local disks / loop devices handled by UDisks2, and network locations mounted by Gvfs. + + \section1 Scheme Structure + + All locations handled by DFMRoot are virtual entries located directly under the root directory. They are distinguished by different suffices. + + \list + \li suffix "userdir" + + Entries with this suffix have one of the following basenames: + \c desktop, \c videos, \c music, \c pictures, \c documents, \c downloads + + They all refer to the corresponding directory in the current user's home directory. + If a location is explicitly disabled by the user-dirs.dir file, it will be treated as if it doesn't exist. + + \li suffix "localdisk" + + Entries with this suffix has the name of a block device as its basename. + + Note: for encrypted block devices, the cleartext device is never be used to construct the URL of this + scheme. The controller doesn't acknowledge the existence of such devices either. In such case, block + device containing the encrypted data should be used instead. + + \li suffix "gvfsmp" + + Entries with this suffix has percent-encoded path of mount point as its basename. + This could be confusing: path of gvfs-managed mount point may already contain percent-encoded or + sometimes even double percent-encoded components. + In any case, a single decode pass should always result in the correct mount point path. + Please note that this scheme only handles GVolume that has a mount point, i.e. already mounted. + \endlist + + \section2 Sample URLs + + \list + \li dfmroot:///desktop.userdir + \li dfmroot:///sda2.localdisk + \li dfmroot:///mmcblk0p1.localdisk + \li dfmroot:///nvme0n1p3.localdisk + \li dfmroot:///sr0.localdisk + \li dfmroot:///%2Frun%2Fuser%2F1000%2Fgvfs%2Fsmb-share%3Aserver%3D10.0.12.150%2Cshare%3Dshare.gvfsmp + \li dfmroot:///%2Frun%2Fuser%2F1000%2Fgvfs%2Farchive%3Ahost%3Dfile%25253A%25252F%25252F%25252Fhome%25252Fc%25252Fdevel%25252Ftest.iso.gvfsmp + \endlist + + \section1 FileInfo Usage + Entries using this scheme can always be redirected. Use \c redirectedFileUrl() to obtain its + location in the local file hierarchy. + + You can determine the type of an entry by calling \c fileType(). The returned value has the type \c DFMRootFileInfo::ItemType. + + Extra properties returned for FileInfo of this type: + \table + \header + \li prop/suffix + \li gvfsmp + \li localdisk + \row + \li fsUsed + \li {2, 1} (quint64) Used size of the volume, in bytes. + \row + \li fsSize + \li {2, 1} (quint64) Total size of the volume, in bytes. + \row + \li fsType + \li {2, 1} (QString) Filesystem name of the volume. + \row + \li rooturi + \li (QString) Root URI of the mount, e.g. smb://127.0.0.1/share + \li - + \row + \li encrypted + \li - + \li (bool) whether the block device is encrypted + \row + \li unlocked + \li - + \li (bool) false if the device is encrypted and locked. True otherwise. + \row + \li udisksblk + \li - + \li (QString) DBus path of the block device. If the device is encrypted + and unlocked, this will refer to the cleartext device instead. + \row + \li mounted + \li {2, 1} (bool) Whether the volume is mounted. + \endtable + User directories do not have any extra properties. + + + \section1 Controller Usage + \section2 Re-labelling a filesystem + Only items controlled by udisks can be re-labeled. Call renameFile with an event with following parameters to change the label of a filesystem: + \list + \li fromUrl: the URL of the item to be re-labeled. + \li toUrl: a URL whose path section is the desired filesystem label. + \endlist + The user will be prompted for their (or the administrator's) password if necessary. + + \section2 If you want to mount/unmount a filesystem... + You have to make calls to udisks manually, or check out if anything in AppController satisfy your needs. + + \section1 Dodging slippery behaviors of Gio/Gvfs + + \list + \li Gvfs volumes that has one of the following URI schemes are automatically mounted when detected (while fetching content of DFMRoot or have a file watcher actively watching its changes): mtp, afc, gphoto2. + \li 'GMount's of the following class are ignored: GUnixMount. + \li 'GMount's originated from a udisks mount are ignored. + \li 'GMount's that correspond to a blank writable optical disc are ignored. + \endlist + + +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/schemes/mount.qdoc b/dde-file-manager-5.5.3/docs/qdoc/schemes/mount.qdoc new file mode 100644 index 0000000..a0bd066 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/schemes/mount.qdoc @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * GNU Free Documentation License Usage + * Alternatively, this file may be used under the terms of the GNU Free + * Documentation License version 1.3 as published by the Free Software + * Foundation and appearing in the file included in the packaging of + * this file. Please review the following information to ensure + * the GNU Free Documentation License version 1.3 requirements + * will be met: https://www.gnu.org/licenses/fdl-1.3.html. + */ + +/*! + \page mount-scheme.html + \title Mount Scheme + + Mount scheme `mount://` did the work which mount a device and then + change directory to the mount point. + + \section1 Scheme Struct + + Mount scheme simply contains a device scheme url in the url fragment: + + mount://# + + the url which is going to be mounted should be a `udisks` scheme url, + or a `device` scheme url. + + \section1 Example Urls + + mount://test#udisks:///org/freedesktop/UDisks2/block_devices/sda1 + + This will mount /dev/sda1 and then open it. + +*/ diff --git a/dde-file-manager-5.5.3/docs/qdoc/snippets/context-menu-ext.json b/dde-file-manager-5.5.3/docs/qdoc/snippets/context-menu-ext.json new file mode 100644 index 0000000..99389fa --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/snippets/context-menu-ext.json @@ -0,0 +1,103 @@ +[ + { + "MenuType": "SingleFile", + "Icon": "/home/djf/Music/usb_normal_16px.svg", + "Text[zh_CN]": "文件SingleFile", + "Text[zh_HK]": "文件SingleFile", + "Text[zh_TW]": "文件SingleFile", + "MimeType": "", + "Suffix": "md;", + "Exec": "", + "SubMenu": [ + { + "Icon": "111111111", + "Text[zh_CN]": "sub文件SingleFile", + "Text[zh_HK]": "sub文件SingleFile", + "Text[zh_TW]": "sub文件SingleFile", + "Exec": "dde-file-manager", + "SubMenu": [ + { + "Icon": "dssd", + "Text[zh_CN]": "sub文件SingleFile", + "Text[zh_HK]": "sub文件SingleFile", + "Text[zh_TW]": "sub文件SingleFile", + "Exec": "dde-file-manager" + }, + { + "Icon": "dssd", + "Text[zh_CN]": "sub文件SingleFile", + "Text[zh_HK]": "sub文件SingleFile", + "Text[zh_TW]": "sub文件SingleFile", + "Exec": "dde-file-manager" + } + ] + }, + { + "Icon": "2222222", + "Text[zh_CN]": "sub文件SingleFile", + "Text[zh_HK]": "sub文件SingleFile", + "Text[zh_TW]": "sub文件SingleFile", + "Exec": "dde-file-manager" + } + ] + }, + { + "MenuType": "SingleFile", + "Icon": "Files", + "Text[zh_CN]": "文件SingleFile2", + "Text[zh_HK]": "文件SingleFile2", + "Text[zh_TW]": "文件SingleFile2", + "MimeType": "", + "Exec": "dde-file-manager" + }, + { + "MenuType": "MultiFiles", + "Icon": "Files", + "Text[zh_CN]": "文件MultiFiles", + "Text[zh_HK]": "文件MultiFiles", + "Text[zh_TW]": "文件MultiFiles", + "MimeType": "text/plain;image/jpeg", + "Exec": "dde-file-manager" + }, + { + "MenuType": "MultiFiles", + "Icon": "Files", + "Text[zh_CN]": "文件MultiFiles2", + "Text[zh_HK]": "文件MultiFiles2", + "Text[zh_TW]": "文件MultiFiles2", + "MimeType": "", + "Exec": "dde-file-manager" + }, + { + "MenuType": "SingleDir", + "Icon": "Files", + "Text[zh_CN]": "文件SingleDir", + "Text[zh_HK]": "文件SingleDir", + "Text[zh_TW]": "文件SingleDir", + "Exec": "dde-file-manager" + }, + { + "MenuType": "MultiDirs", + "Icon": "Files", + "Text[zh_CN]": "文件MultiDir", + "Text[zh_HK]": "文件MultiDir", + "Text[zh_TW]": "文件MultiDir", + "Exec": "dde-file-manager" + }, + { + "MenuType": "MultiFileDirs", + "Icon": "Files", + "Text[zh_CN]": "文件MultiFileDirs", + "Text[zh_HK]": "文件MultiFileDirs", + "Text[zh_TW]": "文件MultiFileDirs", + "Exec": "dde-file-manager" + }, + { + "MenuType": "EmptyArea", + "Icon": "Files", + "Text[zh_CN]": "EmptyArea", + "Text[zh_HK]": "EmptyArea", + "Text[zh_TW]": "EmptyArea", + "Exec": "dde-file-manager" + } +] \ No newline at end of file diff --git a/dde-file-manager-5.5.3/docs/qdoc/snippets/context-menu-ext/content-menu-ext.pro b/dde-file-manager-5.5.3/docs/qdoc/snippets/context-menu-ext/content-menu-ext.pro new file mode 100644 index 0000000..59fe226 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/snippets/context-menu-ext/content-menu-ext.pro @@ -0,0 +1,25 @@ +# Still need the widgets module since MenuInterface need it. +QT += widgets + +CONFIG += link_pkgconfig +PKGCONFIG += dde-file-manager + +TARGET = dde-file-manager-mounter-plugin +TEMPLATE = lib + +DEFINES += DFMMOUNTERPLUGIN_LIBRARY + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated. +DEFINES += QT_DEPRECATED_WARNINGS + +SOURCES += \ + dfmctxmenuplugin.cpp + +HEADERS += \ + dfmctxmenuplugin.h + +unix { + target.path = $$[QT_INSTALL_LIBS]/dde-file-manager/plugins/menu/ + INSTALLS += target +} diff --git a/dde-file-manager-5.5.3/docs/qdoc/snippets/context-menu-ext/dfmctxmenuplugin.cpp b/dde-file-manager-5.5.3/docs/qdoc/snippets/context-menu-ext/dfmctxmenuplugin.cpp new file mode 100644 index 0000000..aa5bbfc --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/snippets/context-menu-ext/dfmctxmenuplugin.cpp @@ -0,0 +1,12 @@ +#include "dfmctxmenuplugin.h" + +DFMCtxMenuPlugin::DFMCtxMenuPlugin() +{ +} + +QList DFMCtxMenuPlugin::additionalMenu(const QStringList &files, const QString ¤tDir) +{ + QList actionPtrList; + actionPtrList.append(new QAction("Sample Text")); + return actionPtrList; +} diff --git a/dde-file-manager-5.5.3/docs/qdoc/snippets/context-menu-ext/dfmctxmenuplugin.h b/dde-file-manager-5.5.3/docs/qdoc/snippets/context-menu-ext/dfmctxmenuplugin.h new file mode 100644 index 0000000..5e039c8 --- /dev/null +++ b/dde-file-manager-5.5.3/docs/qdoc/snippets/context-menu-ext/dfmctxmenuplugin.h @@ -0,0 +1,17 @@ +#ifndef DFMCTXMENUPLUGIN_H +#define DFMCTXMENUPLUGIN_H + +#include "dde-file-manager-plugins/menuinterface.h" + +class DFMCtxMenuPlugin : public MenuInterface +{ + Q_OBJECT + Q_INTERFACES(MenuInterface) + Q_PLUGIN_METADATA(IID MenuInterface_iid) +public: + DFMCtxMenuPlugin(); + + QList additionalMenu(const QStringList &files, const QString& currentDir) override; +}; + +#endif // DFMCTXMENUPLUGIN_H diff --git a/dde-file-manager-5.5.3/filemanager.pro b/dde-file-manager-5.5.3/filemanager.pro new file mode 100644 index 0000000..5df6547 --- /dev/null +++ b/dde-file-manager-5.5.3/filemanager.pro @@ -0,0 +1,45 @@ +TEMPLATE = subdirs + +include(./src/common/common.pri) + +isEmpty(PREFIX){ + PREFIX = /usr +} + +SUBDIRS += \ + dde-file-manager \ + dde-file-manager-daemon \ + dde-file-manager-lib \ + dde-file-manager-plugins \ + dde-dock-plugins \ + dde-desktop \ + dde-select-dialog-x11 \ + dde-select-dialog-wayland \ + dde-file-thumbnail-tool \ + gschema + +!CONFIG(DISABLE_ANYTHING) { + message("Deepin Anything server plugin enabled for" $$ARCH) + SUBDIRS += deepin-anything-server-plugins +} + +dde-file-manager.subdir = src/dde-file-manager +dde-file-manager-lib.subdir = src/dde-file-manager-lib +dde-file-manager-daemon.subdir = src/dde-file-manager-daemon +dde-file-manager-plugins.subdir = src/dde-file-manager-plugins +dde-dock-plugins.subdir = src/dde-dock-plugins +dde-desktop.subdir = src/dde-desktop +dde-file-thumbnail-tool.subdir = src/dde-file-thumbnail-tool +gschema.subdir = src/gschema +deepin-anything-server-plugins.subdir = src/deepin-anything-server-plugins +dde-select-dialog-x11.subdir = src/dde-select-dialog-x11 +dde-select-dialog-wayland.subdir = src/dde-select-dialog-wayland + +dde-file-manager.depends = dde-file-manager-lib +dde-dock-plugins.depends = dde-file-manager-lib +dde-desktop.depends = dde-file-manager-lib +dde-file-manager-daemon.depends = dde-file-manager-lib +deepin-anything-server-plugins.depends = dde-file-manager-lib +#dde-sharefiles.depends = dde-file-manager-lib +dde-select-dialog-x11.depends = dde-file-manager-lib +dde-select-dialog-wayland.depends = dde-file-manager-lib diff --git a/dde-file-manager-5.5.3/rpm/dde-file-manager.spec b/dde-file-manager-5.5.3/rpm/dde-file-manager.spec new file mode 100644 index 0000000..0ec68df --- /dev/null +++ b/dde-file-manager-5.5.3/rpm/dde-file-manager.spec @@ -0,0 +1,239 @@ +%define specrelease 8%{?dist} +%if 0%{?openeuler} +%define specrelease 8 +%endif + +Name: dde-file-manager +Version: 5.2.20 +Release: %{specrelease} +Summary: Deepin File Manager +License: GPLv3 +URL: https://github.com/linuxdeepin/dde-file-manager +Source0: %{name}_%{version}.orig.tar.xz + +BuildRequires: gcc-c++ +BuildRequires: desktop-file-utils +BuildRequires: deepin-gettext-tools +BuildRequires: dde-dock-devel +BuildRequires: file-devel +#BuildRequires: jemalloc-devel +#BuildRequires: cmake(KF5Codecs) +BuildRequires: pkgconfig(atk) +BuildRequires: dtkgui-devel +BuildRequires: pkgconfig(dtkwidget) >= 5.1 +BuildRequires: pkgconfig(dframeworkdbus) >= 2.0 +BuildRequires: pkgconfig(gtk+-2.0) +BuildRequires: pkgconfig(gsettings-qt) +BuildRequires: pkgconfig(libsecret-1) +BuildRequires: pkgconfig(poppler-cpp) +BuildRequires: pkgconfig(polkit-agent-1) +BuildRequires: pkgconfig(polkit-qt5-1) +BuildRequires: pkgconfig(Qt5Core) +BuildRequires: pkgconfig(Qt5Concurrent) +BuildRequires: pkgconfig(Qt5DBus) +BuildRequires: pkgconfig(Qt5Gui) +BuildRequires: pkgconfig(Qt5Svg) +BuildRequires: pkgconfig(Qt5Multimedia) +BuildRequires: pkgconfig(Qt5X11Extras) +BuildRequires: qt5-qtbase-private-devel +%{?_qt5:Requires: %{_qt5}%{?_isa} = %{_qt5_version}} +BuildRequires: pkgconfig(taglib) +#BuildRequires: pkgconfig(uchardet) +BuildRequires: pkgconfig(xcb-util) +BuildRequires: pkgconfig(xcb-ewmh) +BuildRequires: qt5-linguist +BuildRequires: jemalloc-devel +#BuildRequires: udisks2-qt5 +BuildRequires: udisks2-qt5-devel +BuildRequires: disomaster-devel +BuildRequires: libgio-qt libgio-qt-devel +BuildRequires: openssl-devel +BuildRequires: libqtxdg-devel +BuildRequires: libmediainfo-devel +BuildRequires: kf5-kcodecs-devel +#BuildRequires: libudisks2-qt5-devel +BuildRequires: lucene++-devel +BuildRequires: htmlcxx-devel +BuildRequires: libgsf-devel +BuildRequires: mimetic-devel +BuildRequires: boost-devel +%ifarch %{ix86} x86_64 +BuildRequires: deepin-anything-devel deepin-anything-server +%endif + + +# run command by QProcess +#Requires: deepin-shortcut-viewer +Requires: deepin-terminal +Requires: dde-desktop +#Requires: file-roller +Requires: jemalloc +Requires: libglvnd-glx +Requires: libdde-file-manager +Requires: cryfs +%ifarch %{ix86} x86_64 +Requires: deepin-anything-dkms deepin-anything-server +%endif +#Requires: gvfs-client +#Requires: samba +#Requires: xdg-user-dirs +#Requires: gstreamer-plugins-good +Recommends: deepin-manual + +%description +File manager front end of Deepin OS. + +%package devel +Summary: Development package for %{name} +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description devel +Header files and libraries for %{name}. + +%package -n libdde-file-manager +Summary: DDE File Manager library +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: kf5-kcodecs +Requires: jemalloc +Requires: poppler-cpp +Requires: libmediainfo +Requires: libzen +Requires: udisks2-qt5 +Requires: taglib +Requires: libgio-qt +%ifarch %{ix86} x86_64 +Requires: deepin-anything-libs +%endif + +%description -n libdde-file-manager +DDE File Manager library. + +%package -n dde-disk-mount-plugin +Summary: plugin of dde-dock +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description -n dde-disk-mount-plugin +plugin of dde-dock. + +%package -n dde-desktop +Summary: Deepin desktop environment - desktop module +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: dde-dock +Requires: dde-launcher +Requires: dde-session-ui + +%description -n dde-desktop +Deepin desktop environment - desktop module. + +%prep +%setup -q -n %{name}-%{version} + +# fix file permissions +find -type f -perm 775 -exec chmod 644 {} \; +#sed -i '/target.path/s|lib|%{_lib}|' src/dde-dock-plugins/disk-mount/disk-mount.pro +sed -i '/deepin-daemon/s|lib|libexec|' src/dde-zone/mainwindow.h +sed -i 's|lib/gvfs|libexec|' src/%{name}-lib/gvfs/networkmanager.cpp +#sed -i 's|%{_datadir}|%{_libdir}|' dde-sharefiles/appbase.pri +sed -i 's|/lib/dde-dock/plugins|/lib64/dde-dock/plugins|' src/dde-dock-plugins/disk-mount/disk-mount.pro + +%build +export PATH=%{_qt5_bindir}:$PATH +%qmake_qt5 PREFIX=%{_prefix} DISABLE_JEMALLOC=1 QMAKE_CFLAGS_ISYSTEM= CONFIG+="DISABLE_FFMPEG" DEFINES+="VERSION=%{version}" filemanager.pro +%make_build + +%install +%make_install INSTALL_ROOT=%{buildroot} + +%check +desktop-file-validate %{buildroot}%{_datadir}/applications/%{name}.desktop +desktop-file-validate %{buildroot}%{_datadir}/applications/dde-computer.desktop ||: +desktop-file-validate %{buildroot}%{_datadir}/applications/dde-trash.desktop ||: +desktop-file-validate %{buildroot}%{_datadir}/applications/dde-home.desktop ||: + +%ldconfig_scriptlets + +%files +%doc README.md +%license LICENSE +%config(noreplace) %{_sysconfdir}/dbus-1/system.d/com.deepin.filemanager.daemon.conf +%{_bindir}/%{name} +%{_bindir}/%{name}-daemon +%{_bindir}/%{name}-pkexec +%ifnarch x86_64 +%{_bindir}/*.sh +%{_sysconfdir}/xdg/autostart/dde-file-manager-autostart.desktop +%endif +%{_bindir}/dde-property-dialog +/usr/lib/systemd/system/dde-filemanager-daemon.service + +%{_datadir}/applications/dde-open.desktop +%{_datadir}/applications/%{name}.desktop +%{_datadir}/dbus-1/interfaces/com.deepin.filemanager.filedialog.xml +%{_datadir}/dbus-1/interfaces/com.deepin.filemanager.filedialogmanager.xml +%{_datadir}/dbus-1/services/com.deepin.filemanager.filedialog.service +%{_datadir}/dbus-1/services/org.freedesktop.FileManager.service +%{_datadir}/dbus-1/system-services/com.deepin.filemanager.daemon.service +%{_polkit_qt_policydir}/com.deepin.filemanager.daemon.policy +%{_polkit_qt_policydir}/com.deepin.pkexec.dde-file-manager.policy +%{_datadir}/deepin-manual/manual-assets/application/dde-file-manager +%{_datadir}/applications/context-menus/.readme + +%files -n libdde-file-manager +%{_libdir}/dde-file-manager/plugins/previews/libdde-image-preview-plugin.so +%{_libdir}/dde-file-manager/plugins/previews/libdde-music-preview-plugin.so +%{_libdir}/dde-file-manager/plugins/previews/libdde-pdf-preview-plugin.so +%{_libdir}/dde-file-manager/plugins/previews/libdde-text-preview-plugin.so +%{_libdir}/libdde-file-manager.so.1.8.2 +%{_datadir}/dde-file-manager/mimetypeassociations/mimetypeassociations.json +%{_datadir}/dde-file-manager/mimetypes/archive.mimetype +%{_datadir}/dde-file-manager/mimetypes/audio.mimetype +%{_datadir}/dde-file-manager/mimetypes/backup.mimetype +%{_datadir}/dde-file-manager/mimetypes/executable.mimetype +%{_datadir}/dde-file-manager/mimetypes/image.mimetype +%{_datadir}/dde-file-manager/mimetypes/text.mimetype +%{_datadir}/dde-file-manager/mimetypes/video.mimetype +%{_datadir}/dde-file-manager/templates/newDoc.wps +%{_datadir}/dde-file-manager/templates/newExcel.et +%{_datadir}/dde-file-manager/templates/newPowerPoint.dps +%{_datadir}/dde-file-manager/templates/newDoc.doc +%{_datadir}/dde-file-manager/templates/newExcel.xls +%{_datadir}/dde-file-manager/templates/newPowerPoint.ppt +%{_datadir}/dde-file-manager/templates/newTxt.txt +%{_datadir}/dde-file-manager/translations/ +%{_datadir}/deepin/dde-file-manager/oem-menuextensions/.readme +%{_datadir}/glib-2.0/schemas/com.deepin.dde.filemanager.gschema.xml +%{_datadir}/icons/hicolor/scalable/apps/dde-file-manager.svg +%{_libdir}/libdde-file-manager.so.1 +%{_libdir}/libdde-file-manager.so.1.8 +%ifarch x86_64 +%{_libdir}/deepin-anything-server-lib/plugins/handlers/libdde-anythingmonitor.so +%endif + +%files -n dde-disk-mount-plugin +%{_libdir}/dde-dock/plugins/system-trays/libdde-disk-mount-plugin.so +%{_datadir}/dde-disk-mount-plugin/translations +%{_datadir}/glib-2.0/schemas/com.deepin.dde.dock.module.disk-mount.gschema.xml + +%files devel +%{_includedir}/%{name}/*.h +%{_includedir}/%{name}/gvfs/ +%{_includedir}/%{name}/%{name}-plugins/ +%{_includedir}/%{name}/private/ +%{_libdir}/pkgconfig/%{name}.pc +%{_libdir}/lib%{name}.so + +%files -n dde-desktop +%{_bindir}/dde-desktop +%{_datadir}/applications/dde-computer.desktop +%{_datadir}/applications/dde-home.desktop +%{_datadir}/applications/dde-trash.desktop +%dir %{_datadir}/dde-desktop +%{_datadir}/dde-desktop/translations/ +%{_datadir}/dbus-1/services/com.deepin.dde.desktop.service + +%changelog +* Mon Jul 06 2020 uoser - 5.1.0.9-7 +- Move plug-in library to /usr/lib64 directory + +* Wed Jun 17 2020 uoser - 5.1.0.9 +- Remove the disk capacity information displayed in the computer properties diff --git a/dde-file-manager-5.5.3/src/chinese2pinyin/chinese2pinyin.cpp b/dde-file-manager-5.5.3/src/chinese2pinyin/chinese2pinyin.cpp new file mode 100644 index 0000000..be0ef41 --- /dev/null +++ b/dde-file-manager-5.5.3/src/chinese2pinyin/chinese2pinyin.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +// Copyright (c) 2015 LiuLang. All rights reserved. +// Use of this source is governed by General Public License that can be found +// in the LICENSE file. + +#include "chinese2pinyin.h" + +#include +#include +#include + +namespace Pinyin { + +static QHash dict = {}; + +const char kDictFile[] = ":/misc/pinyin.dict"; + +void InitDict() { + if (!dict.isEmpty()) { + return; + } + + dict.reserve(25333); + + QFile file(kDictFile); + + if (!file.open(QIODevice::ReadOnly)) + return; + + QByteArray content = file.readAll(); + + file.close(); + + QTextStream stream(&content, QIODevice::ReadOnly); + + while (!stream.atEnd()) { + const QString line = stream.readLine(); + const QStringList items = line.split(QChar(':')); + + if (items.size() == 2) { + dict.insert(static_cast(items[0].toInt(nullptr, 16)), items[1]); + } + } +} + +QString Chinese2Pinyin(const QString& words) { + InitDict(); + + QString result; + + for (int i = 0; i < words.length(); ++i) { + const uint key = words.at(i).unicode(); + auto find_result = dict.find(key); + + if (find_result != dict.end()) { + result.append(find_result.value()); + } else { + result.append(words.at(i)); + } + } + + return result; +} + +} // namespace Pinyin end diff --git a/dde-file-manager-5.5.3/src/chinese2pinyin/chinese2pinyin.h b/dde-file-manager-5.5.3/src/chinese2pinyin/chinese2pinyin.h new file mode 100644 index 0000000..6a91803 --- /dev/null +++ b/dde-file-manager-5.5.3/src/chinese2pinyin/chinese2pinyin.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +// Copyright (c) 2015 LiuLang. All rights reserved. +// Use of this source is governed by General Public License that can be found +// in the LICENSE file. + +#ifndef SERVICE_BACKEND_CHINESE2PINYIN_H_ +#define SERVICE_BACKEND_CHINESE2PINYIN_H_ + +#include + +namespace Pinyin { +QString Chinese2Pinyin(const QString& words); +}; + +#endif // SERVICE_BACKEND_CHINESE2PINYIN_H_ diff --git a/dde-file-manager-5.5.3/src/chinese2pinyin/chinese2pinyin.pri b/dde-file-manager-5.5.3/src/chinese2pinyin/chinese2pinyin.pri new file mode 100644 index 0000000..b3e29e0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/chinese2pinyin/chinese2pinyin.pri @@ -0,0 +1,10 @@ +HEADERS += \ + $$PWD/chinese2pinyin.h + +SOURCES += \ + $$PWD/chinese2pinyin.cpp + +RESOURCES += \ + $$PWD/data.qrc + +INCLUDEPATH += $$PWD diff --git a/dde-file-manager-5.5.3/src/chinese2pinyin/data.qrc b/dde-file-manager-5.5.3/src/chinese2pinyin/data.qrc new file mode 100644 index 0000000..a125979 --- /dev/null +++ b/dde-file-manager-5.5.3/src/chinese2pinyin/data.qrc @@ -0,0 +1,5 @@ + + + pinyin.dict + + diff --git a/dde-file-manager-5.5.3/src/chinese2pinyin/pinyin.dict b/dde-file-manager-5.5.3/src/chinese2pinyin/pinyin.dict new file mode 100644 index 0000000..e3a11c2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/chinese2pinyin/pinyin.dict @@ -0,0 +1,25333 @@ +0x3400:qiu1 +0x3401:tian3 +0x3404:kua4 +0x3405:wu3 +0x3406:yin3 +0x340c:si4 +0x3416:ye4 +0x341c:chou2 +0x3421:nuo4 +0x3424:qiu2 +0x3428:xu4 +0x3429:xing2 +0x342b:xiong1 +0x342c:liu2 +0x342d:lin3 +0x342e:xiang1 +0x342f:yong1 +0x3430:xin4 +0x3431:zhen3 +0x3432:dai4 +0x3433:wu4 +0x3434:pan1 +0x3437:ma3 +0x3438:qian4 +0x3439:yi4 +0x343a:zhong4 +0x343b:n3 +0x343c:cheng4 +0x3441:zhuo1 +0x3442:fang3 +0x3443:ao3 +0x3444:wu3 +0x3445:zuo4 +0x3447:zhou4 +0x3448:dong4 +0x3449:su4 +0x344a:yi4 +0x344b:jiong4 +0x344c:wang1 +0x344d:lei3 +0x344e:nao3 +0x344f:zhu4 +0x3454:xu3 +0x3458:jie4 +0x3459:die2 +0x345a:nuo2 +0x345b:su4 +0x345c:yi4 +0x345d:long4 +0x345e:ying4 +0x345f:beng3 +0x3463:lan2 +0x3464:miao2 +0x3465:yi4 +0x3466:li4 +0x3467:ji4 +0x3468:yu3 +0x3469:luo2 +0x346a:chai2 +0x346e:hun2 +0x346f:xu3 +0x3470:hui4 +0x3471:rao3 +0x3473:zhou4 +0x3475:han4 +0x3476:xi4 +0x3477:tai4 +0x3478:ai3 +0x3479:hui4 +0x347a:jun4 +0x347b:ma4 +0x347c:lve4 +0x347d:tang2 +0x347e:xiao2 +0x347f:tiao2 +0x3480:zha3 +0x3481:yu3 +0x3482:ku4 +0x3483:er4 +0x3484:nang4 +0x3485:qi3 +0x3486:chi4 +0x3487:mu4 +0x3488:han4 +0x3489:tang3 +0x348a:se4 +0x348c:qiong2 +0x348d:lei2 +0x348e:sa3 +0x3491:hui4 +0x3492:pu2 +0x3493:ta4 +0x3494:shu3 +0x3496:ou3 +0x3497:tai2 +0x3499:mian2 +0x349a:wen3 +0x349b:diao4 +0x349c:yu2 +0x349d:mie4 +0x349e:jun4 +0x349f:niao3 +0x34a0:xie4 +0x34a1:you2 +0x34a4:she4 +0x34a6:lei3 +0x34a7:li4 +0x34a9:luo3 +0x34ab:ji4 +0x34b0:quan2 +0x34b2:cai2 +0x34b3:liang3 +0x34b4:gu3 +0x34b5:mao4 +0x34b7:gua3 +0x34b8:sui4 +0x34bb:mao4 +0x34bc:man2 +0x34be:shi4 +0x34bf:li2 +0x34c1:wang3 +0x34c2:kou4 +0x34c3:chui2 +0x34c4:zhen4 +0x34c8:bing4 +0x34c9:huan4 +0x34ca:dong4 +0x34cb:gong4 +0x34ce:lian2 +0x34cf:jiong3 +0x34d0:lu4 +0x34d1:xing4 +0x34d3:nan2 +0x34d4:xie4 +0x34d6:bi4 +0x34d7:jie2 +0x34d8:su4 +0x34dc:you4 +0x34dd:xing2 +0x34de:qi4 +0x34e0:dian4 +0x34e1:fu3 +0x34e2:luo4 +0x34e3:qia4 +0x34e4:jie2 +0x34e7:yan3 +0x34e8:ci2 +0x34ea:lang3 +0x34ed:he2 +0x34ef:li2 +0x34f0:hua4 +0x34f1:tou2 +0x34f2:pian4 +0x34f4:jun4 +0x34f5:e4 +0x34f6:qie4 +0x34f7:yi4 +0x34f8:jue2 +0x34f9:rui4 +0x34fa:jian4 +0x34fc:chi4 +0x34fd:chong2 +0x34fe:chi2 +0x3500:lve4 +0x3502:lin2 +0x3503:jue2 +0x3504:su4 +0x3505:xiao4 +0x3506:chan2 +0x3509:zhu2 +0x350a:dan3 +0x350b:jian4 +0x350c:zhou4 +0x350d:duo3 +0x350e:xie4 +0x350f:li4 +0x3511:chi4 +0x3512:xi2 +0x3513:jian3 +0x3515:ji2 +0x3517:fei4 +0x3518:chu4 +0x3519:bang3 +0x351a:kou3 +0x351c:ba2 +0x351d:liang3 +0x351e:kuai4 +0x3520:he2 +0x3522:jue2 +0x3523:lei2 +0x3524:shen3 +0x3525:pi2 +0x3526:yang3 +0x3527:lv4 +0x3528:bei4 +0x3529:e4 +0x352a:lu3 +0x352d:che4 +0x352e:nuo2 +0x352f:suan3 +0x3530:heng2 +0x3531:yu3 +0x3533:gui3 +0x3534:yi4 +0x3535:xian4 +0x3536:gong4 +0x3537:lou4 +0x3539:le4 +0x353a:shi4 +0x353c:sun3 +0x353d:yao4 +0x353e:jie2 +0x353f:zou4 +0x3541:que4 +0x3542:yin2 +0x3544:zhi4 +0x3545:jia3 +0x3546:hu4 +0x3547:la2 +0x3548:hou4 +0x3549:ke4 +0x354b:jing4 +0x354c:ai4 +0x354e:e4 +0x354f:chu2 +0x3550:xie3 +0x3551:chu2 +0x3552:wei2 +0x3555:huan4 +0x3556:su4 +0x3557:you4 +0x3559:jun4 +0x355a:zhao3 +0x355b:xu4 +0x355c:shi3 +0x355f:kui4 +0x3561:he2 +0x3562:gai4 +0x3563:yan3 +0x3564:qiu2 +0x3565:yi3 +0x3566:hua4 +0x3568:fan4 +0x3569:zhang4 +0x356a:dan3 +0x356b:fang3 +0x356c:song4 +0x356d:ao4 +0x356e:fu3 +0x356f:nei4 +0x3570:he4 +0x3571:you2 +0x3572:hua2 +0x3574:chen2 +0x3575:guo2 +0x3576:ng4 +0x3577:hua4 +0x3578:li4 +0x3579:fa2 +0x357a:hao2 +0x357b:pou3 +0x357d:si4 +0x3580:le4 +0x3581:lin4 +0x3582:yi4 +0x3583:hou3 +0x3585:xu4 +0x3586:qu2 +0x3587:er2 +0x358f:nei4 +0x3590:wei3 +0x3591:xie4 +0x3592:ti2 +0x3593:hong2 +0x3594:tun3 +0x3595:bo4 +0x3596:nie4 +0x3597:yin2 +0x359e:wai1 +0x359f:shou4 +0x35a0:ba4 +0x35a1:ye4 +0x35a2:ji2 +0x35a3:tou4 +0x35a4:han2 +0x35a5:jiong3 +0x35a6:dong3 +0x35a7:wen3 +0x35a8:lu4 +0x35a9:sou3 +0x35aa:guo2 +0x35ab:ling2 +0x35ad:tian3 +0x35ae:lun2 +0x35b6:ye4 +0x35b7:shi2 +0x35b8:xue2 +0x35b9:fen4 +0x35ba:chun3 +0x35bb:rou2 +0x35bc:duo3 +0x35bd:ze2 +0x35be:e4 +0x35bf:xie2 +0x35c1:e4 +0x35c2:sheng3 +0x35c3:wen3 +0x35c4:man2 +0x35c5:hu2 +0x35c6:ge2 +0x35c7:xia2 +0x35c8:man4 +0x35c9:bi4 +0x35ca:ji2 +0x35cb:hou2 +0x35cc:zhi4 +0x35d1:bai4 +0x35d2:ai4 +0x35d5:gou4 +0x35d6:dan4 +0x35d7:bai3 +0x35d8:bo2 +0x35d9:na4 +0x35da:li4 +0x35db:xiao4 +0x35dc:xiu4 +0x35e2:dong4 +0x35e3:ti4 +0x35e4:cu4 +0x35e5:kuo4 +0x35e6:lao2 +0x35e7:zhi4 +0x35e8:ai3 +0x35e9:xi1 +0x35eb:qie4 +0x35f0:chu4 +0x35f1:ji2 +0x35f2:huo4 +0x35f3:ta3 +0x35f4:yan2 +0x35f5:xu4 +0x35f7:sai3 +0x35fc:ye4 +0x35fd:xiang3 +0x35ff:xia4 +0x3600:zuo4 +0x3601:yi4 +0x3602:ci2 +0x3605:xian2 +0x3606:tai2 +0x3607:rong2 +0x3608:yi1 +0x3609:zhi4 +0x360a:yi4 +0x360b:xian2 +0x360c:ju4 +0x360d:ji2 +0x360e:han3 +0x3610:pao4 +0x3611:li4 +0x3613:lan2 +0x3614:can3 +0x3615:han3 +0x3616:yan2 +0x3619:yan2 +0x361a:han3 +0x361c:chi3 +0x361d:nian3 +0x361e:huo4 +0x3620:bi4 +0x3621:xia2 +0x3622:weng3 +0x3623:xuan2 +0x3625:you2 +0x3626:qin2 +0x3627:xu4 +0x3628:nei4 +0x3629:bi4 +0x362a:hao4 +0x362b:jing3 +0x362c:ao4 +0x362d:ao4 +0x3632:ju2 +0x3634:zuo4 +0x3635:bu4 +0x3636:jie2 +0x3637:ai4 +0x3638:zang4 +0x3639:ci2 +0x363a:fa2 +0x363f:nie4 +0x3640:liu4 +0x3641:mang3 +0x3642:dui4 +0x3644:bi4 +0x3645:bao3 +0x3647:chu4 +0x3648:han2 +0x3649:tian3 +0x364a:chang2 +0x364f:fu4 +0x3650:duo3 +0x3651:yu3 +0x3652:ye3 +0x3653:kui2 +0x3654:han2 +0x3655:kuai4 +0x3657:kuai4 +0x3659:long3 +0x365b:bu3 +0x365c:chi2 +0x365d:xie2 +0x365e:nie4 +0x365f:lang3 +0x3660:yi4 +0x3662:man2 +0x3663:zhang4 +0x3664:xia4 +0x3665:gun3 +0x3668:ji4 +0x3669:liao2 +0x366a:ye4 +0x366b:ji2 +0x366c:yin2 +0x366e:da1 +0x366f:yi4 +0x3670:xie4 +0x3671:hao4 +0x3672:yong3 +0x3673:han3 +0x3674:chan4 +0x3675:tai2 +0x3676:tang2 +0x3677:zhi2 +0x3678:bao4 +0x3679:meng2 +0x367a:gui4 +0x367b:chan2 +0x367c:lei3 +0x367e:xi4 +0x3681:qiao2 +0x3682:rang2 +0x3683:yun2 +0x3685:long2 +0x3686:fu4 +0x3689:gu3 +0x368c:hua4 +0x368d:guo2 +0x368f:gao3 +0x3690:tao4 +0x3692:shan3 +0x3693:lai2 +0x3694:nie4 +0x3695:fu2 +0x3696:gao3 +0x3697:qie2 +0x3698:ban4 +0x369b:xi4 +0x369c:xu4 +0x369d:kui2 +0x369e:meng3 +0x369f:chuo4 +0x36a1:ji3 +0x36a2:nu2 +0x36a3:xiao2 +0x36a4:yi4 +0x36a5:yu2 +0x36a6:yi2 +0x36a7:yan3 +0x36a9:ran3 +0x36aa:hao4 +0x36ab:sha4 +0x36ad:you2 +0x36af:xin2 +0x36b0:bi3 +0x36b2:dian3 +0x36b4:bu4 +0x36b6:si4 +0x36b7:er3 +0x36b9:mao3 +0x36ba:yun4 +0x36bd:qiao3 +0x36bf:pao2 +0x36c2:nuo3 +0x36c3:jie2 +0x36c5:er4 +0x36c6:duo3 +0x36ca:duo3 +0x36cd:qie4 +0x36cf:ou4 +0x36d0:sou3 +0x36d1:can4 +0x36d2:dou4 +0x36d4:peng2 +0x36d5:yi4 +0x36d7:zuo4 +0x36d8:po4 +0x36d9:qie4 +0x36da:tong3 +0x36db:xin4 +0x36dc:you2 +0x36dd:bei4 +0x36de:long4 +0x36e5:ta4 +0x36e6:lan3 +0x36e7:man3 +0x36e8:qiang3 +0x36e9:zhou2 +0x36ea:yan4 +0x36ec:lu4 +0x36ee:sao3 +0x36ef:mian3 +0x36f1:rui4 +0x36f2:fa4 +0x36f3:cha4 +0x36f4:nao3 +0x36f6:chou2 +0x36f8:shu4 +0x36f9:pian2 +0x36fb:kui3 +0x36fc:sha4 +0x36fe:xian2 +0x36ff:zhi4 +0x3703:lian4 +0x3704:xun2 +0x3705:xu4 +0x3706:mi4 +0x3707:hui4 +0x3708:mu4 +0x370a:pang4 +0x370b:yi4 +0x370c:gou4 +0x370d:tang2 +0x370e:qi2 +0x370f:yun2 +0x3710:shu4 +0x3711:fu2 +0x3712:yi4 +0x3713:da2 +0x3715:lian2 +0x3716:cao2 +0x3717:can3 +0x3718:ju4 +0x3719:lu4 +0x371a:su4 +0x371b:nen4 +0x371c:ao4 +0x371d:an3 +0x371e:qian4 +0x3723:ran2 +0x3724:shen3 +0x3725:mai2 +0x3726:han4 +0x3727:yue4 +0x3728:er2 +0x3729:ao4 +0x372a:xian3 +0x372b:ma4 +0x372e:lan4 +0x3730:yue4 +0x3731:dong4 +0x3732:weng3 +0x3733:huai2 +0x3734:meng4 +0x3735:niao3 +0x3736:wan3 +0x3737:mi2 +0x3738:nie4 +0x3739:qu2 +0x373a:zan4 +0x373b:lian4 +0x373c:zhi2 +0x373d:zi3 +0x373e:hai2 +0x373f:xu4 +0x3740:hao4 +0x3741:xun2 +0x3742:zhi4 +0x3743:fan4 +0x3744:chun2 +0x3745:gou4 +0x3747:chun2 +0x3748:luan2 +0x3749:zhu4 +0x374a:shou3 +0x374b:liao2 +0x374c:jie2 +0x374d:xie3 +0x374e:ding4 +0x374f:jie4 +0x3750:rong2 +0x3751:mang2 +0x3753:ge2 +0x3754:yao4 +0x3755:ning2 +0x3756:yi2 +0x3757:lang2 +0x3758:yong2 +0x3759:yin2 +0x375b:su4 +0x375d:lin2 +0x375e:ya4 +0x375f:mao2 +0x3760:ming2 +0x3761:zui4 +0x3762:yu3 +0x3763:ye4 +0x3764:gou4 +0x3765:mi3 +0x3766:jun4 +0x3767:wen3 +0x376a:dian4 +0x376b:long2 +0x376d:xing3 +0x376e:cui4 +0x376f:qiao2 +0x3770:mian2 +0x3771:meng4 +0x3772:qin3 +0x3774:wan2 +0x3775:de2 +0x3776:ai4 +0x3778:bian4 +0x3779:nou2 +0x377a:lian2 +0x377b:jin3 +0x377d:chui2 +0x377e:zuo3 +0x377f:bo2 +0x3781:yao4 +0x3782:tui3 +0x3783:ji2 +0x3785:guo3 +0x3786:ji3 +0x3787:wei3 +0x378a:xu4 +0x378b:nian3 +0x378c:yun4 +0x378e:ba3 +0x378f:zhe2 +0x3790:ju1 +0x3791:wei3 +0x3792:xi4 +0x3793:qi3 +0x3794:yi2 +0x3795:xie4 +0x3796:ci4 +0x3797:qiu2 +0x3798:tun2 +0x3799:niao4 +0x379a:qi4 +0x379b:ji3 +0x379f:dian4 +0x37a0:lao2 +0x37a1:zhan3 +0x37a4:yin2 +0x37a5:cen2 +0x37a6:ji3 +0x37a7:hui4 +0x37a8:zai3 +0x37a9:lan2 +0x37aa:nao2 +0x37ab:ju4 +0x37ac:qin4 +0x37ad:dai4 +0x37af:jie2 +0x37b0:xu3 +0x37b2:yong4 +0x37b3:dou3 +0x37b4:chi2 +0x37b6:min3 +0x37b7:huang2 +0x37b8:sui4 +0x37b9:ke3 +0x37ba:zu2 +0x37bb:hao4 +0x37bc:cheng2 +0x37bd:xue4 +0x37be:ni2 +0x37bf:chi4 +0x37c0:lian2 +0x37c1:an4 +0x37c2:chi3 +0x37c4:xiang2 +0x37c5:yang2 +0x37c6:hua2 +0x37c7:cuo2 +0x37c8:qiu2 +0x37c9:lao2 +0x37ca:fu2 +0x37cb:dui4 +0x37cc:mang2 +0x37cd:lang2 +0x37ce:tuo3 +0x37cf:han2 +0x37d0:mang3 +0x37d1:bo2 +0x37d3:qi2 +0x37d4:han2 +0x37d6:long4 +0x37d8:tiao2 +0x37d9:lao3 +0x37da:qi2 +0x37db:zan4 +0x37dc:mi2 +0x37dd:pei2 +0x37de:zhan4 +0x37df:xiang4 +0x37e0:gang3 +0x37e2:qi2 +0x37e4:lu4 +0x37e6:yun4 +0x37e7:e4 +0x37e8:quan2 +0x37e9:min2 +0x37ea:wei3 +0x37eb:quan2 +0x37ec:shu3 +0x37ed:min2 +0x37f0:ming3 +0x37f1:yao3 +0x37f2:jue2 +0x37f3:li4 +0x37f4:kuai4 +0x37f5:gang3 +0x37f6:yuan2 +0x37f7:da5 +0x37f9:lao2 +0x37fa:lou2 +0x37fb:qian4 +0x37fc:ao2 +0x37fd:biao3 +0x37ff:mang2 +0x3800:dao3 +0x3802:ao2 +0x3804:xi2 +0x3805:fu2 +0x3807:jiu4 +0x3808:run4 +0x3809:tong2 +0x380a:qu1 +0x380b:e4 +0x380d:ji2 +0x380e:ji2 +0x380f:hua2 +0x3810:jiao4 +0x3811:zui4 +0x3812:biao3 +0x3813:meng2 +0x3814:bai4 +0x3815:wei3 +0x3816:ji4 +0x3817:ao4 +0x3818:yu3 +0x3819:hao2 +0x381a:dui4 +0x381b:wo4 +0x381c:ni4 +0x381d:cuan2 +0x381f:li2 +0x3820:lu2 +0x3821:niao3 +0x3822:hua4 +0x3823:lai4 +0x3825:lv4 +0x3827:mi2 +0x3828:yu4 +0x382a:ju4 +0x382d:zhan3 +0x382f:yi3 +0x3831:ji4 +0x3832:bi3 +0x3834:ren4 +0x3836:fan2 +0x3837:ge2 +0x3838:ku4 +0x3839:jie4 +0x383a:miao2 +0x383d:tong2 +0x383f:ci3 +0x3840:bi4 +0x3841:kai3 +0x3842:li4 +0x3844:sun3 +0x3845:nuo3 +0x3847:ji2 +0x3848:men2 +0x3849:xian2 +0x384a:qia4 +0x384b:e4 +0x384c:mao4 +0x384f:tou2 +0x3851:qiao3 +0x3854:wu4 +0x3856:chuang2 +0x3857:ti2 +0x3858:lian2 +0x3859:bi4 +0x385b:mang2 +0x385c:xue3 +0x385d:feng4 +0x385e:lei3 +0x3860:zheng4 +0x3861:chu2 +0x3862:man4 +0x3863:long2 +0x3865:yin3 +0x3867:zheng4 +0x3868:qian1 +0x3869:luan2 +0x386a:nie2 +0x386b:yi4 +0x386d:ji4 +0x386e:ji2 +0x386f:zhai2 +0x3870:yu3 +0x3871:jiu3 +0x3872:huan2 +0x3873:di3 +0x3875:ling2 +0x3876:ji4 +0x3877:ben3 +0x3878:zha3 +0x3879:ci4 +0x387a:dan4 +0x387b:liao4 +0x387c:yi4 +0x387d:zhao4 +0x387e:xian4 +0x387f:chi4 +0x3880:ci4 +0x3881:chi3 +0x3882:yan3 +0x3883:lang2 +0x3884:dou4 +0x3885:long4 +0x3886:chan2 +0x3888:tui2 +0x3889:cha2 +0x388a:ai3 +0x388b:chi3 +0x388d:ying2 +0x388e:cha4 +0x388f:tou2 +0x3891:tui2 +0x3892:cha2 +0x3893:yao3 +0x3894:zong3 +0x3897:qiao4 +0x3898:lian2 +0x3899:qin2 +0x389a:lu3 +0x389b:yan4 +0x389e:yi4 +0x389f:chan3 +0x38a0:jiong3 +0x38a1:jiang3 +0x38a3:jing4 +0x38a5:dong4 +0x38a7:juan4 +0x38a8:han4 +0x38a9:di4 +0x38ac:hong2 +0x38ae:chi2 +0x38af:min2 +0x38b0:bi4 +0x38b2:xun4 +0x38b3:lu2 +0x38b5:she4 +0x38b6:bi4 +0x38b8:bi4 +0x38ba:xian2 +0x38bb:wei3 +0x38bc:bie4 +0x38bd:er3 +0x38be:juan4 +0x38c0:zhen4 +0x38c1:bei4 +0x38c2:yi4 +0x38c3:yu3 +0x38c4:qu2 +0x38c5:zan4 +0x38c6:mi2 +0x38c7:ni3 +0x38c8:si4 +0x38cc:shan4 +0x38cd:tai2 +0x38ce:mu4 +0x38cf:jing4 +0x38d0:bian4 +0x38d1:rong2 +0x38d2:ceng4 +0x38d3:can4 +0x38d9:di2 +0x38da:tong2 +0x38db:ta4 +0x38dc:xing2 +0x38de:duo2 +0x38df:xi4 +0x38e0:tong2 +0x38e2:ti2 +0x38e3:shan3 +0x38e4:jian4 +0x38e5:zhi4 +0x38e7:yin4 +0x38ea:huan3 +0x38eb:zhong3 +0x38ec:qi4 +0x38ef:xie4 +0x38f0:xie4 +0x38f1:ze2 +0x38f2:wei2 +0x38f5:ta4 +0x38f6:zhan1 +0x38f7:ning4 +0x38fb:yi4 +0x38fc:ren3 +0x38fd:shu4 +0x38fe:cha4 +0x38ff:zhuo2 +0x3901:mian3 +0x3902:ji2 +0x3903:fang2 +0x3904:pei4 +0x3905:ai4 +0x3906:fan4 +0x3907:ao3 +0x3908:qin4 +0x3909:qia4 +0x390a:xiao4 +0x390d:qiao3 +0x390f:tong2 +0x3911:you4 +0x3913:ben4 +0x3914:fu2 +0x3915:chu4 +0x3916:zhu4 +0x3918:chu4 +0x391a:hang2 +0x391b:nin2 +0x391c:jue2 +0x391e:cha4 +0x391f:kong3 +0x3920:lie4 +0x3921:li4 +0x3922:xu4 +0x3924:yu2 +0x3925:hai4 +0x3926:li4 +0x3927:hou2 +0x3928:gong3 +0x3929:ke4 +0x392a:yuan4 +0x392b:de2 +0x392c:hui4 +0x392e:kuang2 +0x392f:jiong3 +0x3930:zan3 +0x3931:fu4 +0x3932:qie4 +0x3933:bei3 +0x3934:xi2 +0x3935:ci2 +0x3936:pang2 +0x3938:xi4 +0x3939:qiu2 +0x393a:huang3 +0x393d:chou2 +0x393e:san4 +0x3940:de2 +0x3941:de2 +0x3942:te4 +0x3943:men4 +0x3944:ling2 +0x3945:shou4 +0x3946:dian4 +0x3947:can2 +0x3948:die2 +0x3949:che4 +0x394a:peng2 +0x394c:ju2 +0x394d:ji4 +0x394e:lai2 +0x394f:tian3 +0x3950:yuan4 +0x3952:cai3 +0x3953:qi3 +0x3954:yu2 +0x3955:lian2 +0x395a:yu2 +0x395b:ji2 +0x395c:wei4 +0x395d:mi3 +0x395e:cui4 +0x395f:xie2 +0x3960:xu3 +0x3961:xi4 +0x3962:qiu2 +0x3963:hui4 +0x3965:yu2 +0x3966:qie4 +0x3967:shun4 +0x3968:chui2 +0x3969:duo3 +0x396a:lou2 +0x396c:pang2 +0x396d:tai4 +0x396e:zhou4 +0x396f:yin3 +0x3971:fei3 +0x3972:shen4 +0x3973:yuan2 +0x3974:yi2 +0x3975:hun4 +0x3976:se4 +0x3977:ye4 +0x3978:min3 +0x3979:fen3 +0x397a:he2 +0x397c:yin3 +0x397d:ce4 +0x397e:ni4 +0x397f:ao4 +0x3980:feng2 +0x3981:lian2 +0x3982:chang2 +0x3983:chan3 +0x3984:ma2 +0x3985:di4 +0x3987:lu4 +0x3989:yi4 +0x398a:hua2 +0x398c:tui4 +0x398d:e4 +0x398e:hua4 +0x398f:sun3 +0x3990:ni4 +0x3991:lian3 +0x3992:li2 +0x3993:xian4 +0x3994:yan4 +0x3995:long2 +0x3996:men4 +0x3997:jian4 +0x399a:bian3 +0x399b:yu2 +0x399c:huo4 +0x399d:miao3 +0x399e:chou2 +0x399f:hai4 +0x39a1:le4 +0x39a2:jie2 +0x39a3:wei4 +0x39a4:yi4 +0x39a5:huan2 +0x39a6:he4 +0x39a7:can3 +0x39a8:lan2 +0x39a9:yin3 +0x39aa:xie4 +0x39ac:luo3 +0x39ad:ling2 +0x39ae:qian2 +0x39af:huo4 +0x39b1:wo3 +0x39b4:ge2 +0x39b6:die2 +0x39b7:yong3 +0x39b8:ji3 +0x39b9:ang4 +0x39ba:ru3 +0x39bb:xi2 +0x39bc:shuang4 +0x39bd:xu4 +0x39be:yi2 +0x39bf:hu4 +0x39c0:ji2 +0x39c1:qu4 +0x39c2:tian2 +0x39c4:qian3 +0x39c5:mu4 +0x39c7:mao3 +0x39c8:yin3 +0x39c9:gai4 +0x39ca:ba2 +0x39cb:xian3 +0x39cc:mao4 +0x39cd:fang3 +0x39ce:ya2 +0x39d0:song3 +0x39d1:wei2 +0x39d2:xue2 +0x39d4:guai4 +0x39d5:jiu4 +0x39d6:e4 +0x39d7:zi3 +0x39d8:cui4 +0x39d9:bi4 +0x39da:wa3 +0x39dc:lie4 +0x39df:kuai3 +0x39e1:hai4 +0x39e3:zhu4 +0x39e4:chong4 +0x39e5:xian3 +0x39e6:xuan4 +0x39e8:qiu2 +0x39e9:pei4 +0x39ea:gui3 +0x39eb:er2 +0x39ec:gong3 +0x39ed:qiong2 +0x39ef:lao3 +0x39f0:li4 +0x39f1:chen4 +0x39f2:san3 +0x39f3:bo2 +0x39f4:wo3 +0x39f5:pou2 +0x39f7:duo4 +0x39f9:te4 +0x39fa:ta4 +0x39fb:zhi3 +0x39fc:biao4 +0x39fd:gu4 +0x3a00:bing3 +0x3a01:zhi2 +0x3a02:dong3 +0x3a03:cheng2 +0x3a04:zhao4 +0x3a05:nei4 +0x3a06:lin3 +0x3a07:po2 +0x3a08:ji3 +0x3a09:min3 +0x3a0a:wei3 +0x3a0b:che3 +0x3a0c:gou4 +0x3a0e:ru2 +0x3a10:bu3 +0x3a12:kui2 +0x3a13:lao2 +0x3a14:han4 +0x3a15:ying2 +0x3a16:zhi4 +0x3a17:jie2 +0x3a18:xing3 +0x3a19:xie2 +0x3a1a:xun2 +0x3a1b:shan3 +0x3a1c:qian2 +0x3a1d:xie4 +0x3a1e:su4 +0x3a1f:hai2 +0x3a20:mi4 +0x3a21:hun2 +0x3a24:hui4 +0x3a25:na4 +0x3a26:song3 +0x3a27:ben4 +0x3a28:liu4 +0x3a29:jie2 +0x3a2a:huang4 +0x3a2b:lan3 +0x3a2d:hu4 +0x3a2e:dou1 +0x3a2f:huo4 +0x3a30:ge2 +0x3a31:yao2 +0x3a32:ce4 +0x3a33:gui3 +0x3a34:jian4 +0x3a35:jian3 +0x3a36:chou2 +0x3a37:jin4 +0x3a38:ma4 +0x3a39:hui4 +0x3a3a:men2 +0x3a3b:can2 +0x3a3c:lve4 +0x3a3d:pi3 +0x3a3e:yang4 +0x3a3f:ju4 +0x3a40:ju4 +0x3a41:que4 +0x3a44:shai1 +0x3a46:jiu4 +0x3a47:hua4 +0x3a48:xian4 +0x3a49:xie2 +0x3a4b:su4 +0x3a4c:fei4 +0x3a4d:ce4 +0x3a4e:ye4 +0x3a52:qin2 +0x3a53:hui3 +0x3a54:tun2 +0x3a56:qiang2 +0x3a57:xi2 +0x3a58:yi3 +0x3a5a:meng2 +0x3a5b:tuan2 +0x3a5c:lan3 +0x3a5d:hao2 +0x3a5e:ci4 +0x3a5f:zhai4 +0x3a60:piao3 +0x3a61:luo3 +0x3a62:mi2 +0x3a66:xie2 +0x3a67:bo2 +0x3a68:hui4 +0x3a69:qi3 +0x3a6a:xie2 +0x3a6d:bo2 +0x3a6e:qian2 +0x3a6f:ban3 +0x3a70:jiao3 +0x3a71:jue2 +0x3a72:kun3 +0x3a73:song3 +0x3a74:ju2 +0x3a75:e4 +0x3a76:nie4 +0x3a78:die2 +0x3a79:die2 +0x3a7b:gui3 +0x3a7d:qi2 +0x3a7e:chui2 +0x3a80:yu2 +0x3a81:qin2 +0x3a83:ke3 +0x3a84:fu2 +0x3a86:di3 +0x3a87:xian4 +0x3a88:gui4 +0x3a89:he2 +0x3a8a:qun2 +0x3a8b:han4 +0x3a8c:tong3 +0x3a8d:bo2 +0x3a8e:shan3 +0x3a8f:bi3 +0x3a90:lu4 +0x3a91:ye4 +0x3a92:ni2 +0x3a93:chuai2 +0x3a94:san4 +0x3a95:diao4 +0x3a96:lu4 +0x3a97:tou3 +0x3a98:lian3 +0x3a99:ke3 +0x3a9a:san4 +0x3a9b:zhen3 +0x3a9c:chuai3 +0x3a9d:lian4 +0x3a9e:mao4 +0x3aa0:qian4 +0x3aa1:ke3 +0x3aa2:shao3 +0x3aa3:qiao4 +0x3aa4:bi4 +0x3aa6:yin4 +0x3aa8:shan4 +0x3aa9:su4 +0x3aaa:sa4 +0x3aab:rui4 +0x3aac:zhuo2 +0x3aad:lu2 +0x3aae:ling2 +0x3aaf:cha2 +0x3ab1:huan4 +0x3ab4:jia2 +0x3ab5:ban4 +0x3ab6:hu2 +0x3ab7:dou3 +0x3ab9:lou3 +0x3abb:juan4 +0x3abc:ke3 +0x3abd:suo3 +0x3abe:ge2 +0x3abf:zhe2 +0x3ac0:ding3 +0x3ac1:duan4 +0x3ac2:zhu4 +0x3ac3:yan3 +0x3ac4:pang2 +0x3ac5:cha2 +0x3aca:yi3 +0x3acd:you2 +0x3ace:gun3 +0x3acf:yao3 +0x3ad0:yao3 +0x3ad1:shi2 +0x3ad2:gong3 +0x3ad3:qi3 +0x3ad4:gen4 +0x3ad7:hou4 +0x3ad8:mi4 +0x3ad9:fu2 +0x3ada:hu1 +0x3adb:guang4 +0x3adc:dan4 +0x3adf:yan2 +0x3ae2:qu4 +0x3ae4:chang3 +0x3ae5:ming3 +0x3ae7:bao4 +0x3aeb:xian3 +0x3aef:mao4 +0x3af0:lang3 +0x3af1:nan3 +0x3af2:pei4 +0x3af3:chen2 +0x3af6:cou3 +0x3af8:qie4 +0x3af9:dai4 +0x3afb:kun4 +0x3afc:die2 +0x3afd:lu4 +0x3b02:yu2 +0x3b03:tai2 +0x3b04:chan4 +0x3b05:man4 +0x3b06:mian2 +0x3b07:huan4 +0x3b09:nuan3 +0x3b0a:huan3 +0x3b0b:hou2 +0x3b0c:jing4 +0x3b0d:bo2 +0x3b0e:xian3 +0x3b0f:li4 +0x3b10:jin3 +0x3b12:mang3 +0x3b13:piao4 +0x3b14:hao2 +0x3b15:yang2 +0x3b17:xian4 +0x3b18:su4 +0x3b19:wei3 +0x3b1a:che4 +0x3b1c:jin4 +0x3b1d:ceng2 +0x3b1e:he4 +0x3b20:shai4 +0x3b21:ling2 +0x3b23:dui4 +0x3b25:pu4 +0x3b26:yue4 +0x3b27:bo2 +0x3b29:hui4 +0x3b2a:die2 +0x3b2b:yan4 +0x3b2c:ju4 +0x3b2d:jiao4 +0x3b2e:kuai4 +0x3b2f:lie4 +0x3b30:yu2 +0x3b31:ti4 +0x3b33:wu3 +0x3b34:hong3 +0x3b35:xiao2 +0x3b36:hao4 +0x3b3b:huang3 +0x3b3c:fu4 +0x3b3f:dun4 +0x3b41:reng2 +0x3b42:jiao3 +0x3b44:xin4 +0x3b47:yuan4 +0x3b48:jue2 +0x3b49:hua2 +0x3b4b:bang4 +0x3b4c:mou2 +0x3b4f:wei3 +0x3b51:mei4 +0x3b52:si4 +0x3b53:bian4 +0x3b54:lu2 +0x3b58:he2 +0x3b59:she2 +0x3b5a:lv3 +0x3b5b:pai4 +0x3b5c:rong2 +0x3b5d:qiu2 +0x3b5e:lie4 +0x3b5f:gong3 +0x3b60:xian3 +0x3b61:xi4 +0x3b64:niao3 +0x3b68:xie2 +0x3b69:lei4 +0x3b6b:cuan2 +0x3b6c:zhuo2 +0x3b6d:fei4 +0x3b6e:zuo4 +0x3b6f:die2 +0x3b70:ji4 +0x3b71:he2 +0x3b72:ji2 +0x3b78:tu2 +0x3b79:xian2 +0x3b7a:yan3 +0x3b7b:tang2 +0x3b7c:ta4 +0x3b7d:di3 +0x3b7e:jue2 +0x3b7f:ang2 +0x3b80:han2 +0x3b81:yao2 +0x3b82:ju2 +0x3b83:rui2 +0x3b84:bang3 +0x3b86:nie4 +0x3b87:tian4 +0x3b88:nai4 +0x3b8b:you3 +0x3b8c:mian2 +0x3b8f:nai4 +0x3b90:xing3 +0x3b91:qi4 +0x3b93:gen4 +0x3b94:tong2 +0x3b95:er2 +0x3b96:jia2 +0x3b97:qin2 +0x3b98:mao4 +0x3b99:e4 +0x3b9a:li4 +0x3b9b:chi2 +0x3b9d:he2 +0x3b9e:jie2 +0x3b9f:ji2 +0x3ba1:guan4 +0x3ba2:hou2 +0x3ba3:gai4 +0x3ba5:fen4 +0x3ba6:se4 +0x3ba8:ji2 +0x3baa:qiong2 +0x3bab:he2 +0x3bad:xian2 +0x3bae:jie2 +0x3baf:hua2 +0x3bb0:bi2 +0x3bb3:zhen4 +0x3bb6:shi4 +0x3bb8:song4 +0x3bb9:zhi3 +0x3bba:ben3 +0x3bbe:lang3 +0x3bbf:bi4 +0x3bc0:xian3 +0x3bc1:bang4 +0x3bc2:dai4 +0x3bc5:pi2 +0x3bc6:chan3 +0x3bc7:bi4 +0x3bc8:su4 +0x3bc9:huo4 +0x3bca:hen2 +0x3bcb:ying3 +0x3bcc:chuan2 +0x3bcd:jiang3 +0x3bce:nen4 +0x3bcf:gu3 +0x3bd0:fang3 +0x3bd3:ta4 +0x3bd4:cui4 +0x3bd6:de2 +0x3bd7:ran3 +0x3bd8:kuan3 +0x3bd9:che4 +0x3bda:da2 +0x3bdb:hu2 +0x3bdc:cui4 +0x3bdd:lu4 +0x3bde:juan4 +0x3bdf:lu4 +0x3be0:qian4 +0x3be1:pao4 +0x3be2:zhen4 +0x3be4:li4 +0x3be5:cao2 +0x3be6:qi2 +0x3be9:ti4 +0x3bea:ling2 +0x3beb:qu2 +0x3bec:lian3 +0x3bed:lu3 +0x3bee:shu3 +0x3bef:gong4 +0x3bf0:zhe2 +0x3bf1:biao3 +0x3bf2:jin4 +0x3bf3:qing2 +0x3bf6:zong1 +0x3bf7:pu2 +0x3bf8:jin3 +0x3bf9:biao3 +0x3bfa:jian4 +0x3bfb:gun3 +0x3bff:lie4 +0x3c00:li2 +0x3c01:luo3 +0x3c02:shen3 +0x3c03:mian2 +0x3c04:jian4 +0x3c05:di2 +0x3c06:bei4 +0x3c08:lian3 +0x3c0a:xun2 +0x3c0b:pin2 +0x3c0c:que4 +0x3c0d:long2 +0x3c0e:zui4 +0x3c10:jue2 +0x3c12:she2 +0x3c14:xie4 +0x3c16:lan3 +0x3c17:cu4 +0x3c18:yi2 +0x3c19:nuo2 +0x3c1a:li2 +0x3c1b:yue4 +0x3c1d:yi3 +0x3c1f:ji4 +0x3c20:kang4 +0x3c21:xie4 +0x3c23:zi4 +0x3c24:ke3 +0x3c25:hui4 +0x3c26:qu4 +0x3c2a:wa2 +0x3c2c:xun2 +0x3c2e:shen4 +0x3c2f:kou4 +0x3c30:qie4 +0x3c31:sha4 +0x3c32:xu4 +0x3c33:ya4 +0x3c34:po2 +0x3c35:zu2 +0x3c36:you3 +0x3c37:zi4 +0x3c38:lian3 +0x3c39:jin4 +0x3c3a:xia2 +0x3c3b:yi3 +0x3c3c:qie4 +0x3c3d:mi3 +0x3c3e:jiao4 +0x3c40:chi3 +0x3c41:shi4 +0x3c43:yin3 +0x3c44:mo4 +0x3c45:yi4 +0x3c47:se4 +0x3c48:jin4 +0x3c49:ye4 +0x3c4b:que4 +0x3c4c:che4 +0x3c4d:luan2 +0x3c4f:zheng4 +0x3c56:cui4 +0x3c58:an4 +0x3c59:xiu3 +0x3c5a:can2 +0x3c5b:chuan3 +0x3c5c:zha2 +0x3c5e:ji2 +0x3c5f:bo2 +0x3c62:lang2 +0x3c63:tui3 +0x3c65:ling2 +0x3c66:e4 +0x3c67:wo4 +0x3c68:lian4 +0x3c69:du2 +0x3c6a:men4 +0x3c6b:lan4 +0x3c6c:wei3 +0x3c6d:duan4 +0x3c6e:kuai4 +0x3c6f:ai2 +0x3c70:zai3 +0x3c71:hui4 +0x3c72:yi4 +0x3c73:mo4 +0x3c74:zi4 +0x3c75:ben4 +0x3c76:beng4 +0x3c78:bi4 +0x3c79:li4 +0x3c7a:lu2 +0x3c7b:luo3 +0x3c7d:dan4 +0x3c7f:que4 +0x3c80:chen2 +0x3c82:cheng2 +0x3c83:jiu4 +0x3c84:kou4 +0x3c85:ji4 +0x3c86:ling2 +0x3c88:shao2 +0x3c89:kai4 +0x3c8a:rui4 +0x3c8b:chuo4 +0x3c8c:neng4 +0x3c8e:lou2 +0x3c8f:bao3 +0x3c92:bao4 +0x3c93:rong2 +0x3c95:lei4 +0x3c98:qu2 +0x3c9b:zhi3 +0x3c9c:tan2 +0x3c9d:rong3 +0x3c9e:zu2 +0x3c9f:ying3 +0x3ca0:mao2 +0x3ca1:nai4 +0x3ca2:bian4 +0x3ca5:tang2 +0x3ca6:han4 +0x3ca7:zao4 +0x3ca8:rong2 +0x3cab:pu2 +0x3cad:tan3 +0x3caf:ran2 +0x3cb0:ning2 +0x3cb1:lie4 +0x3cb2:die2 +0x3cb3:die2 +0x3cb4:zhong4 +0x3cb6:lv4 +0x3cb7:dan4 +0x3cb9:gui3 +0x3cba:ji2 +0x3cbb:ni4 +0x3cbc:yi4 +0x3cbd:nian4 +0x3cbe:yu3 +0x3cbf:wang3 +0x3cc0:guo4 +0x3cc1:ze4 +0x3cc2:yan2 +0x3cc3:cui4 +0x3cc4:xian2 +0x3cc5:jiao3 +0x3cc6:shu3 +0x3cc7:fu4 +0x3cc8:pei4 +0x3ccd:bu4 +0x3cce:bian4 +0x3ccf:chi3 +0x3cd0:sa4 +0x3cd1:yi4 +0x3cd2:bian4 +0x3cd4:dui4 +0x3cd5:lan2 +0x3cd7:chai4 +0x3cd9:xuan4 +0x3cda:yu4 +0x3cdb:yu2 +0x3ce0:ta4 +0x3ce5:ju4 +0x3ce6:xie4 +0x3ce7:xi2 +0x3ce8:jian3 +0x3cea:pan4 +0x3ceb:ta4 +0x3cec:xuan2 +0x3ced:xian2 +0x3cee:niao4 +0x3cf4:mi4 +0x3cf5:ji4 +0x3cf6:gou4 +0x3cf7:wen3 +0x3cf9:wang3 +0x3cfa:you2 +0x3cfb:ze2 +0x3cfc:bi4 +0x3cfd:mi3 +0x3cff:xie4 +0x3d00:fan4 +0x3d01:yi4 +0x3d03:lei4 +0x3d04:ying2 +0x3d06:jin4 +0x3d07:she4 +0x3d08:yin4 +0x3d09:ji3 +0x3d0b:su4 +0x3d0f:wang3 +0x3d10:mian4 +0x3d11:su4 +0x3d12:yi4 +0x3d13:zai3 +0x3d14:se4 +0x3d15:ji2 +0x3d16:luo4 +0x3d18:mao4 +0x3d19:zha2 +0x3d1a:sui4 +0x3d1b:zhi4 +0x3d1c:bian4 +0x3d1d:li2 +0x3d25:qiao4 +0x3d26:guan4 +0x3d28:zhen4 +0x3d2a:nie4 +0x3d2b:jun4 +0x3d2c:xie4 +0x3d2d:yao3 +0x3d2e:xie4 +0x3d30:neng2 +0x3d33:long3 +0x3d34:chen2 +0x3d35:mi4 +0x3d36:que4 +0x3d38:na4 +0x3d3c:su4 +0x3d3d:xie4 +0x3d3e:bo2 +0x3d3f:ding3 +0x3d40:cuan4 +0x3d42:chuang3 +0x3d43:che4 +0x3d44:han4 +0x3d45:dan4 +0x3d46:hao4 +0x3d4a:shen3 +0x3d4b:mi4 +0x3d4c:chan4 +0x3d4d:men4 +0x3d4e:han3 +0x3d4f:cui3 +0x3d50:jue2 +0x3d51:he4 +0x3d52:fei4 +0x3d53:shi2 +0x3d54:che3 +0x3d55:shen4 +0x3d56:nv4 +0x3d57:fu4 +0x3d58:man4 +0x3d5d:yi4 +0x3d5e:chou2 +0x3d61:bao2 +0x3d62:lei2 +0x3d63:ke3 +0x3d64:dian4 +0x3d65:bi4 +0x3d66:sui2 +0x3d67:ge2 +0x3d68:bi4 +0x3d69:yi4 +0x3d6a:xian2 +0x3d6b:ni3 +0x3d6c:ying2 +0x3d6d:zhu3 +0x3d6e:chun2 +0x3d6f:feng2 +0x3d70:xu4 +0x3d71:piao3 +0x3d72:wu3 +0x3d73:liao2 +0x3d74:cang2 +0x3d75:zou4 +0x3d77:bian4 +0x3d78:yao4 +0x3d79:huan2 +0x3d7a:pai2 +0x3d7b:sou4 +0x3d7d:dui4 +0x3d7e:jing4 +0x3d7f:xi2 +0x3d81:guo2 +0x3d84:yan2 +0x3d85:xue2 +0x3d86:chu2 +0x3d87:heng2 +0x3d88:ying2 +0x3d8c:lian2 +0x3d8d:xian3 +0x3d8e:huan2 +0x3d91:lian4 +0x3d92:shan3 +0x3d93:cang2 +0x3d94:bei4 +0x3d95:jian3 +0x3d96:shu4 +0x3d97:fan4 +0x3d98:dian4 +0x3d9a:ba4 +0x3d9b:yu2 +0x3d9e:nang3 +0x3d9f:lei3 +0x3da0:yi4 +0x3da1:dai4 +0x3da3:chan2 +0x3da4:chao3 +0x3da6:jin4 +0x3da7:nen4 +0x3dab:liao3 +0x3dac:mei2 +0x3dad:jiu4 +0x3daf:liu4 +0x3db0:han2 +0x3db2:yong4 +0x3db3:jin4 +0x3db4:chi3 +0x3db5:ren4 +0x3db6:nong2 +0x3db9:hong4 +0x3dba:tian4 +0x3dbf:bo2 +0x3dc0:qiong2 +0x3dc2:shu4 +0x3dc3:cui3 +0x3dc4:hui4 +0x3dc5:chao3 +0x3dc6:dou4 +0x3dc7:guai4 +0x3dc8:e4 +0x3dc9:wei4 +0x3dca:fen2 +0x3dcb:tan2 +0x3dcd:lun2 +0x3dce:he4 +0x3dcf:yong3 +0x3dd0:hui3 +0x3dd2:yu2 +0x3dd3:zong3 +0x3dd4:yan4 +0x3dd5:qiu2 +0x3dd6:zhao4 +0x3dd7:jiong3 +0x3dd8:tai2 +0x3ddf:tui4 +0x3de0:lin2 +0x3de1:jiong3 +0x3de2:zha3 +0x3de4:he4 +0x3de6:xu4 +0x3dea:cui4 +0x3deb:qing3 +0x3dec:mo4 +0x3def:beng4 +0x3df0:li2 +0x3df3:yan4 +0x3df4:ge2 +0x3df5:mo4 +0x3df6:bei4 +0x3df7:juan3 +0x3df8:die2 +0x3df9:shao4 +0x3dfb:wu2 +0x3dfc:yan4 +0x3dfe:jue2 +0x3e00:tai2 +0x3e01:han3 +0x3e03:dian3 +0x3e04:ji4 +0x3e05:jie2 +0x3e09:xie4 +0x3e0a:la4 +0x3e0b:fan2 +0x3e0c:huo4 +0x3e0d:xi4 +0x3e0e:nie4 +0x3e0f:mi2 +0x3e10:ran2 +0x3e11:cuan4 +0x3e12:yin2 +0x3e13:mi4 +0x3e15:jue2 +0x3e17:tong2 +0x3e18:wan4 +0x3e1a:li3 +0x3e1b:shao2 +0x3e1c:kong4 +0x3e1d:kan3 +0x3e1e:ban3 +0x3e20:tiao3 +0x3e22:bei4 +0x3e23:ye4 +0x3e24:pian4 +0x3e25:chan2 +0x3e26:hu4 +0x3e27:ken4 +0x3e29:an4 +0x3e2a:chun2 +0x3e2b:qian2 +0x3e2c:bei4 +0x3e2e:fen2 +0x3e30:tuo2 +0x3e31:tuo2 +0x3e32:zuo2 +0x3e33:ling2 +0x3e35:gui3 +0x3e37:shi4 +0x3e38:hou3 +0x3e39:lie4 +0x3e3b:si4 +0x3e3d:bei4 +0x3e3e:ren4 +0x3e3f:du2 +0x3e40:bo2 +0x3e41:liang2 +0x3e42:ci4 +0x3e43:bi4 +0x3e44:ji4 +0x3e45:zong3 +0x3e47:he2 +0x3e48:li2 +0x3e49:yuan2 +0x3e4a:yue4 +0x3e4c:chan3 +0x3e4d:di2 +0x3e4e:lei2 +0x3e4f:jin3 +0x3e50:chong2 +0x3e51:si4 +0x3e52:pu3 +0x3e53:yi4 +0x3e56:huan4 +0x3e57:tao2 +0x3e58:ru2 +0x3e59:ying2 +0x3e5a:ying2 +0x3e5b:rao2 +0x3e5c:yin2 +0x3e5d:shi4 +0x3e5e:yin2 +0x3e5f:jue2 +0x3e60:tun2 +0x3e61:xuan2 +0x3e64:qie4 +0x3e65:zhu4 +0x3e68:you4 +0x3e6b:xi4 +0x3e6c:shi3 +0x3e6d:yi4 +0x3e6e:mo4 +0x3e71:hu2 +0x3e72:xiao4 +0x3e73:wu2 +0x3e75:jing4 +0x3e76:ting2 +0x3e77:shi3 +0x3e78:ni2 +0x3e7a:ta4 +0x3e7c:chu3 +0x3e7d:chan3 +0x3e7e:piao3 +0x3e7f:diao3 +0x3e80:nao2 +0x3e81:nao3 +0x3e82:gan3 +0x3e83:gou3 +0x3e84:yu3 +0x3e85:hou2 +0x3e89:hu4 +0x3e8a:yang4 +0x3e8c:xian4 +0x3e8e:rong2 +0x3e8f:lou2 +0x3e90:zhao3 +0x3e91:can2 +0x3e92:liao4 +0x3e93:piao4 +0x3e94:hai4 +0x3e95:fan2 +0x3e96:han3 +0x3e97:dan4 +0x3e98:zhan4 +0x3e9a:ta3 +0x3e9b:zhu4 +0x3e9c:ban3 +0x3e9d:jian4 +0x3e9e:yu2 +0x3e9f:zhuo2 +0x3ea0:you4 +0x3ea1:li4 +0x3ea5:chan2 +0x3ea6:lian2 +0x3ea9:jiu4 +0x3eaa:pu2 +0x3eab:qiu2 +0x3eac:gong3 +0x3ead:zi3 +0x3eae:yu2 +0x3eb1:reng2 +0x3eb2:niu3 +0x3eb3:mei2 +0x3eb5:jiu2 +0x3eb7:xu4 +0x3eb8:ping2 +0x3eb9:bian4 +0x3eba:mao4 +0x3ebf:yi2 +0x3ec0:you2 +0x3ec2:ping2 +0x3ec4:bao3 +0x3ec5:hui4 +0x3ec9:bu4 +0x3eca:mang2 +0x3ecb:la4 +0x3ecc:tu2 +0x3ecd:wu2 +0x3ece:li4 +0x3ecf:ling2 +0x3ed1:ji4 +0x3ed2:jun4 +0x3ed4:duo3 +0x3ed5:jue2 +0x3ed6:dai4 +0x3ed7:bei4 +0x3edd:la4 +0x3ede:bian4 +0x3edf:sui2 +0x3ee0:tu2 +0x3ee1:die2 +0x3ee7:duo4 +0x3eea:sui4 +0x3eeb:bi4 +0x3eec:tu2 +0x3eed:se4 +0x3eee:can4 +0x3eef:tu2 +0x3ef0:mian3 +0x3ef2:lv3 +0x3ef5:zhan4 +0x3ef6:bi3 +0x3ef7:ji2 +0x3ef8:cen2 +0x3efa:li4 +0x3efd:sui4 +0x3eff:shu3 +0x3f02:e2 +0x3f07:qiong2 +0x3f08:luo2 +0x3f09:yin4 +0x3f0a:tun2 +0x3f0b:gu3 +0x3f0c:yu3 +0x3f0d:lei3 +0x3f0e:bei4 +0x3f0f:nei3 +0x3f10:pian2 +0x3f11:lian4 +0x3f12:qiu3 +0x3f13:lian2 +0x3f16:li4 +0x3f17:ding3 +0x3f18:wa3 +0x3f19:zhou4 +0x3f1b:xing2 +0x3f1c:ang4 +0x3f1d:fan4 +0x3f1e:peng4 +0x3f1f:bai2 +0x3f20:tuo2 +0x3f22:e3 +0x3f23:bai3 +0x3f24:qi4 +0x3f25:chu2 +0x3f26:gong3 +0x3f27:tong2 +0x3f28:han2 +0x3f29:cheng2 +0x3f2a:jia2 +0x3f2b:huan4 +0x3f2c:xing4 +0x3f2d:dian4 +0x3f2e:mai2 +0x3f2f:dong4 +0x3f30:e2 +0x3f31:ruan3 +0x3f32:lie4 +0x3f33:sheng3 +0x3f34:ou3 +0x3f35:di4 +0x3f36:yu2 +0x3f37:chuan2 +0x3f38:rong2 +0x3f3a:tang2 +0x3f3b:cong2 +0x3f3c:piao2 +0x3f3d:shuang3 +0x3f3e:lu4 +0x3f3f:tong2 +0x3f40:zheng4 +0x3f41:li4 +0x3f42:sa4 +0x3f47:guai4 +0x3f48:yi4 +0x3f49:han3 +0x3f4a:xie4 +0x3f4b:luo2 +0x3f4c:liu4 +0x3f4e:dan3 +0x3f51:tan2 +0x3f55:you2 +0x3f56:nan2 +0x3f58:gang3 +0x3f59:jun4 +0x3f5a:chi4 +0x3f5b:kou4 +0x3f5c:wan3 +0x3f5d:li4 +0x3f5e:liu2 +0x3f5f:lie4 +0x3f60:xia2 +0x3f62:an3 +0x3f63:yu4 +0x3f64:ju2 +0x3f65:rou2 +0x3f66:xun2 +0x3f68:cuo2 +0x3f69:can4 +0x3f6a:zeng3 +0x3f6b:yong3 +0x3f6c:fu4 +0x3f6d:ruan3 +0x3f6f:xi2 +0x3f70:shu4 +0x3f71:jiao3 +0x3f72:jiao3 +0x3f73:han4 +0x3f74:zhang4 +0x3f77:shui4 +0x3f78:chen2 +0x3f79:fan4 +0x3f7a:ji2 +0x3f7d:gu4 +0x3f7e:wu4 +0x3f80:qie4 +0x3f81:shu4 +0x3f83:tuo2 +0x3f84:du2 +0x3f85:si4 +0x3f86:ran2 +0x3f87:mu4 +0x3f88:fu4 +0x3f89:ling2 +0x3f8a:ji2 +0x3f8b:xiu4 +0x3f8c:xuan3 +0x3f8d:nai2 +0x3f8f:jie4 +0x3f90:li4 +0x3f91:da2 +0x3f92:ji4 +0x3f94:lv3 +0x3f95:shen3 +0x3f96:li3 +0x3f97:lang3 +0x3f98:geng3 +0x3f99:yin3 +0x3f9b:qin3 +0x3f9c:qie4 +0x3f9d:che4 +0x3f9e:you3 +0x3f9f:bu4 +0x3fa0:huang2 +0x3fa1:que4 +0x3fa2:lai4 +0x3fa5:xu4 +0x3fa6:bang4 +0x3fa7:ke4 +0x3fa8:qi3 +0x3faa:sheng3 +0x3fad:zhou4 +0x3fae:huang2 +0x3faf:tui2 +0x3fb0:hu2 +0x3fb1:bei4 +0x3fb5:ji4 +0x3fb6:gu3 +0x3fb8:gao3 +0x3fb9:chai2 +0x3fba:ma4 +0x3fbb:zhu4 +0x3fbc:tui3 +0x3fbd:tui2 +0x3fbe:lian2 +0x3fbf:lang2 +0x3fc3:dai4 +0x3fc4:ai4 +0x3fc5:xian3 +0x3fc7:xi2 +0x3fc9:tui2 +0x3fca:can3 +0x3fcb:sao4 +0x3fcd:jie4 +0x3fce:fen4 +0x3fcf:qun2 +0x3fd1:yao4 +0x3fd2:dao3 +0x3fd3:jia2 +0x3fd4:lei3 +0x3fd5:yan2 +0x3fd6:lu2 +0x3fd7:tui2 +0x3fd8:ying2 +0x3fd9:pi4 +0x3fda:luo4 +0x3fdb:li2 +0x3fdc:bie3 +0x3fde:mao4 +0x3fdf:bai2 +0x3fe2:yao4 +0x3fe3:he2 +0x3fe4:chun3 +0x3fe5:hu2 +0x3fe6:ning4 +0x3fe7:chou2 +0x3fe8:li4 +0x3fe9:tang3 +0x3fea:huan2 +0x3feb:bi4 +0x3fed:che4 +0x3fee:yang4 +0x3fef:da2 +0x3ff0:ao2 +0x3ff1:xue2 +0x3ff5:ran3 +0x3ff7:zao4 +0x3ff8:wan3 +0x3ff9:ta4 +0x3ffa:bao2 +0x3ffc:yan2 +0x3ffe:zhu4 +0x3fff:ya3 +0x4000:fan2 +0x4001:you4 +0x4003:tui2 +0x4004:meng2 +0x4005:she4 +0x4006:jin4 +0x4007:gu3 +0x4008:qi4 +0x4009:qiao2 +0x400a:jiao3 +0x400b:yan2 +0x400d:kan4 +0x400e:mian3 +0x400f:xian4 +0x4010:san3 +0x4011:na4 +0x4013:huan4 +0x4014:niu2 +0x4015:cheng4 +0x4017:jue2 +0x4018:xi2 +0x4019:qi4 +0x401a:ang2 +0x401b:mei4 +0x401c:gu3 +0x401f:fan2 +0x4020:qu2 +0x4021:chan4 +0x4022:shun4 +0x4023:bi4 +0x4024:mao4 +0x4025:shuo4 +0x4026:gu3 +0x4027:hong3 +0x4028:huan4 +0x4029:luo4 +0x402a:hang2 +0x402b:jia2 +0x402c:quan2 +0x402e:mang2 +0x402f:bu3 +0x4030:gu3 +0x4032:mu4 +0x4033:ai4 +0x4034:ying3 +0x4035:shun4 +0x4036:lang3 +0x4037:jie2 +0x4038:di4 +0x4039:jie2 +0x403b:pin4 +0x403c:ren4 +0x403d:yan2 +0x403e:du3 +0x403f:di4 +0x4041:lang3 +0x4042:xian4 +0x4044:xing4 +0x4045:bei4 +0x4046:an3 +0x4047:mi4 +0x4048:qi4 +0x4049:qi4 +0x404a:wo4 +0x404b:she2 +0x404c:yu4 +0x404d:jia4 +0x404e:cheng2 +0x404f:yao3 +0x4050:ying4 +0x4051:yang2 +0x4052:ji2 +0x4053:jie4 +0x4054:han4 +0x4055:min2 +0x4056:lou1 +0x4057:kai3 +0x4058:yao3 +0x4059:yan3 +0x405a:sun3 +0x405b:gui3 +0x405c:huang3 +0x405d:ying2 +0x405e:sheng3 +0x405f:cha2 +0x4060:lian2 +0x4062:xuan2 +0x4063:chuan2 +0x4064:che4 +0x4065:ni4 +0x4066:qu4 +0x4067:miao2 +0x4068:huo4 +0x4069:yu2 +0x406a:nan3 +0x406b:hu2 +0x406c:ceng2 +0x406e:qian2 +0x406f:she4 +0x4070:jiang3 +0x4071:ao4 +0x4072:mai2 +0x4073:mang3 +0x4074:zhan3 +0x4075:bian3 +0x4076:jiao3 +0x4077:jue2 +0x4078:nong2 +0x4079:bi4 +0x407a:shi4 +0x407b:li4 +0x407c:mo4 +0x407d:lie4 +0x407e:mie4 +0x407f:mo4 +0x4080:xi1 +0x4081:chan2 +0x4082:qu2 +0x4083:jiao4 +0x4084:huo4 +0x4086:xu4 +0x4087:nang2 +0x4088:tong2 +0x4089:hou2 +0x408a:yu4 +0x408d:bo2 +0x408e:zuan3 +0x4090:chuo4 +0x4092:jie2 +0x4094:xing4 +0x4095:hui4 +0x4096:shi2 +0x409a:yao2 +0x409b:yu2 +0x409c:bang4 +0x409d:jie2 +0x409e:zhe4 +0x40a0:she2 +0x40a1:di3 +0x40a2:dong3 +0x40a3:ci2 +0x40a4:fu4 +0x40a5:min2 +0x40a6:zhen3 +0x40a7:zhen3 +0x40a9:yan4 +0x40aa:diao4 +0x40ab:hong2 +0x40ac:gong3 +0x40ae:lve4 +0x40af:guai4 +0x40b0:la4 +0x40b1:cui4 +0x40b2:fa3 +0x40b3:cuo3 +0x40b4:yan2 +0x40b6:jie2 +0x40b8:guo2 +0x40b9:suo3 +0x40ba:wan3 +0x40bb:zheng4 +0x40bc:nie4 +0x40bd:diao4 +0x40be:lai3 +0x40bf:ta4 +0x40c0:cui4 +0x40c2:gun3 +0x40c7:mian2 +0x40c9:min2 +0x40ca:ju3 +0x40cb:yu2 +0x40cd:zhao4 +0x40ce:ze2 +0x40d1:pan2 +0x40d2:he2 +0x40d3:gou4 +0x40d4:hong2 +0x40d5:lao2 +0x40d6:wu4 +0x40d7:chuo4 +0x40d9:lu4 +0x40da:cu4 +0x40db:lian2 +0x40dd:qiao4 +0x40de:shu2 +0x40e1:cen2 +0x40e3:hui3 +0x40e4:su4 +0x40e5:chuang2 +0x40e7:long2 +0x40e9:nao2 +0x40ea:tan2 +0x40eb:dan3 +0x40ec:wei3 +0x40ed:gan3 +0x40ee:da2 +0x40ef:li4 +0x40f1:xian4 +0x40f2:pan2 +0x40f3:la4 +0x40f5:niao3 +0x40f6:huai2 +0x40f7:ying2 +0x40f8:xian4 +0x40f9:lan4 +0x40fa:mo2 +0x40fb:ba4 +0x40fd:fu2 +0x40fe:bi3 +0x4100:huo4 +0x4101:yi4 +0x4102:liu4 +0x4105:juan4 +0x4106:huo2 +0x4107:cheng2 +0x4108:dou4 +0x4109:e2 +0x410b:yan3 +0x410c:zhui4 +0x410d:du4 +0x410e:qi3 +0x410f:yu2 +0x4110:quan4 +0x4111:huo2 +0x4112:nie4 +0x4113:heng2 +0x4114:ju3 +0x4115:she4 +0x4118:peng2 +0x4119:ming2 +0x411a:cao2 +0x411b:lou2 +0x411c:li2 +0x411d:chun3 +0x411f:cui4 +0x4120:shan4 +0x4122:qi2 +0x4124:lai4 +0x4125:ling2 +0x4126:liao3 +0x4127:reng2 +0x4128:yu2 +0x4129:nao2 +0x412a:chuo4 +0x412b:qi3 +0x412c:yi2 +0x412d:nian2 +0x412f:jian3 +0x4130:ya2 +0x4132:chui2 +0x4136:bi4 +0x4137:dan4 +0x4138:po4 +0x4139:nian2 +0x413a:zhi4 +0x413b:chao2 +0x413c:tian3 +0x413d:tian3 +0x413e:rou4 +0x413f:yi4 +0x4140:lie4 +0x4141:an4 +0x4142:he2 +0x4143:qiong2 +0x4144:li4 +0x4146:zi4 +0x4147:su4 +0x4148:yuan4 +0x4149:ya4 +0x414a:du4 +0x414b:wan3 +0x414d:dong4 +0x414e:you3 +0x414f:hui4 +0x4150:jian3 +0x4151:rui2 +0x4152:mang2 +0x4153:ju3 +0x4156:an3 +0x4157:sui4 +0x4158:lai2 +0x4159:hun4 +0x415a:qiang3 +0x415c:duo4 +0x415e:na4 +0x415f:can3 +0x4160:ti2 +0x4161:xu3 +0x4162:jiu4 +0x4163:huang2 +0x4164:qi4 +0x4165:jie2 +0x4166:mao2 +0x4167:yan4 +0x4169:zhi3 +0x416a:tui2 +0x416c:ai4 +0x416d:pang2 +0x416e:cang4 +0x416f:tang2 +0x4170:en3 +0x4171:hun4 +0x4172:qi2 +0x4173:chu2 +0x4174:suo3 +0x4175:zhuo2 +0x4176:nou4 +0x4177:tu2 +0x4178:zu2 +0x4179:lou2 +0x417a:miao3 +0x417b:li2 +0x417c:man2 +0x417d:gu3 +0x417e:cen2 +0x417f:hua2 +0x4180:mei3 +0x4182:lian2 +0x4183:dao3 +0x4184:shan4 +0x4185:ci2 +0x4188:zhi4 +0x4189:ba4 +0x418a:cui4 +0x418b:qiu1 +0x418d:long2 +0x418f:fei4 +0x4190:guo2 +0x4191:cheng2 +0x4192:jiu4 +0x4193:e4 +0x4195:jue2 +0x4196:hong2 +0x4197:jiao4 +0x4198:cuan2 +0x4199:yao2 +0x419a:tong2 +0x419b:cha2 +0x419c:you4 +0x419d:shu4 +0x419e:yao3 +0x419f:ge2 +0x41a0:huan4 +0x41a1:lang2 +0x41a2:jue2 +0x41a3:chen2 +0x41a6:shen4 +0x41a8:ming2 +0x41a9:ming2 +0x41ab:chuang1 +0x41ac:yun3 +0x41ae:jin4 +0x41af:chuo4 +0x41b1:tan3 +0x41b3:qiong2 +0x41b5:cheng2 +0x41b7:yu4 +0x41b8:cheng2 +0x41b9:tong3 +0x41bb:qiao4 +0x41bd:ju4 +0x41be:lan2 +0x41bf:yi4 +0x41c0:rong2 +0x41c3:si4 +0x41c5:fa2 +0x41c7:meng2 +0x41c8:gui4 +0x41cb:hai4 +0x41cc:qiao4 +0x41cd:chuo4 +0x41ce:que4 +0x41cf:dui4 +0x41d0:li4 +0x41d1:ba4 +0x41d2:jie4 +0x41d4:luo4 +0x41d6:yun3 +0x41d8:hu4 +0x41d9:yin3 +0x41db:zhi3 +0x41dc:lian3 +0x41de:gan3 +0x41df:jian4 +0x41e0:zhou4 +0x41e1:zhu4 +0x41e2:ku3 +0x41e3:na4 +0x41e4:dui4 +0x41e5:ze2 +0x41e6:yang3 +0x41e7:zhu4 +0x41e8:gong4 +0x41e9:yi4 +0x41ec:chuang3 +0x41ed:lao3 +0x41ee:ren4 +0x41ef:rong2 +0x41f1:na4 +0x41f2:ce4 +0x41f5:yi2 +0x41f6:jue2 +0x41f7:bi3 +0x41f8:cheng2 +0x41f9:jun4 +0x41fa:chou2 +0x41fb:hui4 +0x41fc:chi4 +0x41fd:zhi4 +0x41fe:yan2 +0x4201:lun2 +0x4202:bing4 +0x4203:zhao3 +0x4204:han2 +0x4205:yu4 +0x4206:dai4 +0x4207:zhao4 +0x4208:fei2 +0x4209:sha4 +0x420a:ling2 +0x420b:ta4 +0x420d:mang2 +0x420e:ye4 +0x420f:bao2 +0x4210:kui4 +0x4211:gua3 +0x4212:nan3 +0x4213:ge2 +0x4215:chi2 +0x4217:suo3 +0x4218:ci2 +0x4219:zhou4 +0x421a:tai2 +0x421b:kuai4 +0x421c:qin4 +0x421e:du3 +0x421f:ce4 +0x4220:huan3 +0x4222:sai3 +0x4223:zheng4 +0x4224:qian2 +0x4227:wei3 +0x422a:xi4 +0x422b:na4 +0x422c:pu2 +0x422d:huai2 +0x422e:ju3 +0x4232:pan2 +0x4233:ta4 +0x4234:qian4 +0x4236:rong2 +0x4237:luo4 +0x4238:hu2 +0x4239:sou3 +0x423b:pu2 +0x423c:mie4 +0x423e:shuo4 +0x423f:mai4 +0x4240:shu4 +0x4241:ling2 +0x4242:lei3 +0x4243:jiang3 +0x4244:leng2 +0x4245:zhi4 +0x4246:diao3 +0x4248:san3 +0x4249:hu2 +0x424a:fan4 +0x424b:mei4 +0x424c:sui4 +0x424d:jian3 +0x424e:tang2 +0x424f:xie4 +0x4251:mo2 +0x4252:fan2 +0x4253:lei2 +0x4255:ceng2 +0x4256:ling2 +0x4258:cong2 +0x4259:yun2 +0x425a:meng2 +0x425b:yu4 +0x425c:zhi4 +0x425d:qi3 +0x425e:dan3 +0x425f:huo4 +0x4260:wei2 +0x4261:tan2 +0x4262:se4 +0x4263:xie4 +0x4264:sou3 +0x4265:song3 +0x4267:liu2 +0x4268:yi4 +0x426a:lei4 +0x426b:li2 +0x426c:fei4 +0x426d:lie4 +0x426e:lin4 +0x426f:xian4 +0x4270:yao2 +0x4272:bie4 +0x4273:xian3 +0x4274:rang2 +0x4275:zhuan4 +0x4277:dan4 +0x4278:bian4 +0x4279:ling2 +0x427a:hong2 +0x427b:qi2 +0x427c:liao4 +0x427d:ban3 +0x427e:mi4 +0x427f:hu2 +0x4280:hu2 +0x4282:ce4 +0x4283:pei4 +0x4284:qiong2 +0x4285:ming2 +0x4286:jiu4 +0x4287:bu4 +0x4288:mei2 +0x4289:san3 +0x428a:mei4 +0x428d:li2 +0x428e:quan3 +0x4290:en4 +0x4291:xiang3 +0x4293:shi4 +0x4296:lan3 +0x4297:huang2 +0x4298:jiu4 +0x4299:yan2 +0x429b:sa3 +0x429c:tuan2 +0x429d:xie4 +0x429e:zhe2 +0x429f:men2 +0x42a0:xi4 +0x42a1:man2 +0x42a3:huang2 +0x42a4:tan2 +0x42a5:xiao4 +0x42a6:ya2 +0x42a7:bi4 +0x42a8:luo2 +0x42a9:fan2 +0x42aa:li4 +0x42ab:cui3 +0x42ac:cha4 +0x42ad:chou2 +0x42ae:di2 +0x42af:kuang4 +0x42b0:chu3 +0x42b2:chan3 +0x42b3:mi2 +0x42b4:qian4 +0x42b5:qiu2 +0x42b6:zhen4 +0x42ba:gu3 +0x42bb:yan3 +0x42bc:chi3 +0x42bd:guai4 +0x42be:mu4 +0x42bf:bo2 +0x42c0:kua4 +0x42c1:geng3 +0x42c2:yao2 +0x42c3:mao4 +0x42c4:wang3 +0x42c8:ru2 +0x42c9:jue2 +0x42cb:min2 +0x42cc:jiang3 +0x42ce:zhan4 +0x42cf:zuo4 +0x42d0:yue4 +0x42d1:bing3 +0x42d3:zhou4 +0x42d4:bi4 +0x42d5:ren4 +0x42d6:yu4 +0x42d8:chuo4 +0x42d9:er3 +0x42da:yi4 +0x42db:mi2 +0x42dc:qing4 +0x42de:wang3 +0x42df:ji4 +0x42e0:bu3 +0x42e2:bie4 +0x42e3:fan2 +0x42e4:yao4 +0x42e5:li2 +0x42e6:fan2 +0x42e7:qu2 +0x42e8:fu3 +0x42e9:er2 +0x42ed:huo4 +0x42ee:jin4 +0x42ef:qi3 +0x42f0:ju2 +0x42f1:lai2 +0x42f2:che3 +0x42f3:bei4 +0x42f4:niu4 +0x42f5:yi4 +0x42f6:xu4 +0x42f7:liu2 +0x42f8:xun2 +0x42f9:fu2 +0x42fb:nin2 +0x42fc:ting3 +0x42fd:beng3 +0x42fe:zha3 +0x4302:ou4 +0x4303:shuo4 +0x4304:geng3 +0x4305:tang2 +0x4306:gui4 +0x4307:hui4 +0x4308:ta4 +0x430a:yao2 +0x430c:qi4 +0x430d:han4 +0x430e:lve4 +0x430f:mi4 +0x4310:mi4 +0x4312:lu4 +0x4313:fan2 +0x4314:ou4 +0x4315:mi2 +0x4316:jie2 +0x4317:fu3 +0x4318:mi2 +0x4319:huang3 +0x431a:su4 +0x431b:yao2 +0x431c:nie4 +0x431d:jin4 +0x431e:lian3 +0x431f:bi4 +0x4320:qing4 +0x4321:ti3 +0x4322:ling2 +0x4323:zuan3 +0x4324:zhi3 +0x4325:yin3 +0x4326:dao3 +0x4327:chou2 +0x4328:cai4 +0x4329:mi4 +0x432a:yan2 +0x432b:lan3 +0x432c:chong2 +0x432f:guan4 +0x4330:she4 +0x4331:luo4 +0x4334:luo4 +0x4335:zhu2 +0x4337:chou2 +0x4338:juan4 +0x4339:jiong3 +0x433a:er3 +0x433b:yi4 +0x433c:rui4 +0x433d:cai3 +0x433e:ren2 +0x433f:fu2 +0x4340:lan2 +0x4341:sui4 +0x4342:yu2 +0x4343:yao2 +0x4344:dian3 +0x4345:ling2 +0x4346:zhu4 +0x4347:ta4 +0x4348:ping2 +0x4349:qian2 +0x434a:jue2 +0x434b:chui2 +0x434c:bu4 +0x434d:gu3 +0x434e:cun4 +0x4350:han3 +0x4351:han3 +0x4352:mou3 +0x4353:hu4 +0x4354:hong2 +0x4355:di3 +0x4356:fu2 +0x4357:xuan4 +0x4358:mi2 +0x4359:mei2 +0x435a:lang4 +0x435b:gu4 +0x435c:zhao4 +0x435d:ta4 +0x435e:yu4 +0x435f:zong4 +0x4360:li2 +0x4361:liao4 +0x4362:wu2 +0x4363:lei2 +0x4364:ji3 +0x4365:lei4 +0x4366:li2 +0x4368:bo2 +0x4369:ang3 +0x436a:kui4 +0x436b:tuo2 +0x436e:zhao4 +0x436f:gui3 +0x4371:xu2 +0x4372:nai2 +0x4373:chuo4 +0x4374:duo4 +0x4376:dong4 +0x4377:gui4 +0x4378:bo2 +0x437a:huan2 +0x437b:xuan3 +0x437c:can2 +0x437d:li4 +0x437e:tui2 +0x437f:huang2 +0x4380:xue4 +0x4381:hu2 +0x4382:bao3 +0x4383:ran3 +0x4384:tiao2 +0x4385:fu4 +0x4386:liao4 +0x4388:yi4 +0x4389:shu4 +0x438a:po4 +0x438b:he4 +0x438c:cu4 +0x438e:na4 +0x438f:an4 +0x4390:chao3 +0x4391:lu4 +0x4392:zhan3 +0x4393:ta4 +0x4397:qiao2 +0x4398:su4 +0x439a:guan4 +0x439d:chu2 +0x439f:er2 +0x43a0:er2 +0x43a1:nuan3 +0x43a2:qi3 +0x43a3:si4 +0x43a4:chu2 +0x43a6:yan3 +0x43a7:bang4 +0x43a8:an4 +0x43aa:ne4 +0x43ab:chuang4 +0x43ac:ba4 +0x43ae:ti4 +0x43af:han4 +0x43b0:zuo2 +0x43b1:ba4 +0x43b2:zhe2 +0x43b3:wa4 +0x43b4:sheng4 +0x43b5:bi4 +0x43b6:er4 +0x43b7:zhu4 +0x43b8:wu4 +0x43b9:wen2 +0x43ba:zhi3 +0x43bb:zhou3 +0x43bc:lu4 +0x43bd:wen2 +0x43be:gun3 +0x43bf:qiu2 +0x43c0:la4 +0x43c1:zai3 +0x43c2:sou3 +0x43c3:mian2 +0x43c4:zhi4 +0x43c5:qi4 +0x43c6:cao2 +0x43c7:piao4 +0x43c8:lian2 +0x43ca:long2 +0x43cb:su4 +0x43cc:qi4 +0x43cd:yuan4 +0x43ce:feng2 +0x43d0:jue2 +0x43d1:di4 +0x43d2:pian4 +0x43d3:guan3 +0x43d4:niu3 +0x43d5:ren3 +0x43d6:zhen4 +0x43d7:gai4 +0x43d8:pi3 +0x43d9:tan3 +0x43da:chao3 +0x43db:chun3 +0x43dd:chun2 +0x43de:mo4 +0x43df:bie4 +0x43e0:qi4 +0x43e1:shi4 +0x43e2:bi3 +0x43e3:jue2 +0x43e4:si4 +0x43e6:hua2 +0x43e7:na2 +0x43e8:hui3 +0x43ea:er4 +0x43ec:mou2 +0x43ee:xi2 +0x43ef:zhi4 +0x43f0:ren3 +0x43f1:ju2 +0x43f2:die2 +0x43f3:zhe4 +0x43f4:shao4 +0x43f5:meng3 +0x43f6:bi4 +0x43f7:han4 +0x43f8:yu2 +0x43f9:xian4 +0x43fb:neng2 +0x43fc:can2 +0x43fd:bu4 +0x43ff:qi3 +0x4400:ji4 +0x4401:niao3 +0x4402:lu4 +0x4403:jiong3 +0x4404:han4 +0x4405:yi2 +0x4406:cai3 +0x4407:chun2 +0x4408:zhi2 +0x4409:zi4 +0x440a:da2 +0x440c:tian3 +0x440d:zhou4 +0x440f:chun3 +0x4411:zhe2 +0x4413:rou2 +0x4414:bin4 +0x4415:ji2 +0x4416:yi2 +0x4417:du3 +0x4418:jue2 +0x4419:ge2 +0x441a:ji2 +0x441d:suo3 +0x441e:ruo4 +0x441f:xiang4 +0x4420:huang3 +0x4421:qi2 +0x4422:zhu4 +0x4423:cuo4 +0x4424:chi2 +0x4425:weng3 +0x4427:kao4 +0x4428:gu3 +0x4429:kai3 +0x442a:fan4 +0x442c:cao2 +0x442d:zhi4 +0x442e:chan3 +0x442f:lei2 +0x4432:zhe2 +0x4433:yu2 +0x4434:gui4 +0x4435:huang2 +0x4436:jin3 +0x4438:guo2 +0x4439:sao4 +0x443a:tan4 +0x443c:xi4 +0x443d:man2 +0x443e:duo2 +0x443f:ao2 +0x4440:pi4 +0x4441:wu4 +0x4442:ai3 +0x4443:meng2 +0x4444:pi4 +0x4445:meng2 +0x4446:yang3 +0x4447:zhi4 +0x4448:bo2 +0x4449:ying2 +0x444a:wei2 +0x444b:nao2 +0x444c:lan2 +0x444d:yan4 +0x444e:chan3 +0x444f:quan2 +0x4450:zhen3 +0x4451:pu2 +0x4453:tai2 +0x4454:fei4 +0x4455:shu3 +0x4457:dang4 +0x4458:cha2 +0x4459:ran2 +0x445a:tian2 +0x445b:chi3 +0x445c:ta4 +0x445d:jia3 +0x445e:shun4 +0x445f:huang2 +0x4460:liao3 +0x4464:jin4 +0x4465:e4 +0x4467:fu2 +0x4468:duo4 +0x446a:e4 +0x446c:yao4 +0x446d:di4 +0x446f:di4 +0x4470:bu4 +0x4471:man2 +0x4472:che4 +0x4473:lun2 +0x4474:qi2 +0x4475:mu4 +0x4476:can2 +0x447b:you2 +0x447d:da2 +0x447f:su4 +0x4480:fu2 +0x4481:ji4 +0x4482:jiang3 +0x4483:cao4 +0x4484:bo2 +0x4485:teng2 +0x4486:che4 +0x4487:fu4 +0x4488:bu3 +0x4489:wu3 +0x448b:yang3 +0x448c:ming4 +0x448d:pang3 +0x448e:mang3 +0x4490:meng2 +0x4491:cao3 +0x4492:tiao2 +0x4493:kai3 +0x4494:bai4 +0x4495:xiao3 +0x4496:xin4 +0x4497:qi4 +0x449a:shao3 +0x449b:heng2 +0x449c:niu2 +0x449d:xiao2 +0x449e:chen2 +0x44a0:fan3 +0x44a1:yin3 +0x44a2:ang2 +0x44a3:ran3 +0x44a4:ri4 +0x44a5:fa4 +0x44a6:fan4 +0x44a7:qu4 +0x44a8:shi3 +0x44a9:he2 +0x44aa:bian4 +0x44ab:dai4 +0x44ac:mo4 +0x44ad:deng3 +0x44b2:cha4 +0x44b3:duo3 +0x44b4:you3 +0x44b5:hao4 +0x44b8:xian2 +0x44b9:lei4 +0x44ba:jin3 +0x44bb:qi3 +0x44bd:mei2 +0x44c2:yan2 +0x44c3:yi4 +0x44c4:yin2 +0x44c5:qi2 +0x44c6:zhe2 +0x44c7:xi4 +0x44c8:yi4 +0x44c9:ye2 +0x44ca:e4 +0x44cc:zhi4 +0x44cd:han3 +0x44ce:chuo4 +0x44d0:chun2 +0x44d1:bing3 +0x44d2:kuai3 +0x44d3:chou2 +0x44d5:tuo3 +0x44d6:qiong2 +0x44d8:jiu4 +0x44da:cu2 +0x44db:fu3 +0x44dd:meng2 +0x44de:li4 +0x44df:lie4 +0x44e0:ta4 +0x44e2:gu4 +0x44e3:liang3 +0x44e5:la4 +0x44e6:dian3 +0x44e7:ci4 +0x44eb:ji4 +0x44ed:cha4 +0x44ee:mao4 +0x44ef:du2 +0x44f1:chai2 +0x44f2:rui4 +0x44f3:hen3 +0x44f4:ruan2 +0x44f6:lai4 +0x44f7:xing4 +0x44f9:yi4 +0x44fa:mei3 +0x44fc:he4 +0x44fd:ji4 +0x44ff:han3 +0x4501:li4 +0x4502:zi3 +0x4503:zu3 +0x4504:yao2 +0x4506:li2 +0x4507:qi3 +0x4508:gan3 +0x4509:li4 +0x450e:su4 +0x450f:chou4 +0x4511:xie2 +0x4512:bei4 +0x4513:xu3 +0x4514:jing4 +0x4515:pu2 +0x4516:ling2 +0x4517:xiang2 +0x4518:zuo4 +0x4519:diao4 +0x451a:chun2 +0x451b:qing3 +0x451c:nan2 +0x451e:lv4 +0x451f:chi2 +0x4520:shao3 +0x4521:yu2 +0x4522:hua2 +0x4523:li2 +0x4527:li2 +0x452a:dui4 +0x452c:yi4 +0x452d:ning4 +0x452f:hu2 +0x4530:fu2 +0x4532:cheng2 +0x4533:nan3 +0x4534:ce4 +0x4536:ti2 +0x4537:qin2 +0x4538:biao3 +0x4539:sui4 +0x453a:wei2 +0x453c:se4 +0x453d:ai4 +0x453e:e4 +0x453f:jie4 +0x4540:kuan3 +0x4541:fei3 +0x4543:yin4 +0x4545:sao3 +0x4546:dou4 +0x4547:hui4 +0x4548:xie4 +0x4549:ze2 +0x454a:tan2 +0x454b:chang3 +0x454c:zhi4 +0x454d:yi4 +0x454e:fu2 +0x454f:e2 +0x4551:jun4 +0x4553:cha2 +0x4554:xian2 +0x4555:man4 +0x4557:bi4 +0x4558:ling2 +0x4559:jie2 +0x455a:kui4 +0x455b:jia2 +0x455e:lang4 +0x4560:fei4 +0x4561:lu3 +0x4562:zha3 +0x4563:he2 +0x4565:ni3 +0x4566:ying2 +0x4567:xiao4 +0x4568:teng2 +0x4569:lao3 +0x456a:ze2 +0x456b:kui2 +0x456d:qian2 +0x456e:ju2 +0x456f:piao2 +0x4570:ban4 +0x4571:dou3 +0x4572:lin3 +0x4573:mi2 +0x4574:zhuo2 +0x4575:xie2 +0x4576:hu4 +0x4577:mi2 +0x4579:za2 +0x457a:cong2 +0x457b:ge2 +0x457c:nan2 +0x457d:zhu2 +0x457e:yan2 +0x457f:han4 +0x4581:yi4 +0x4582:luan2 +0x4583:yue4 +0x4584:ran2 +0x4585:ling2 +0x4586:niang4 +0x4587:yu4 +0x4588:nve4 +0x458a:yi2 +0x458b:nve4 +0x458c:qin2 +0x458d:qian2 +0x458e:xia2 +0x458f:chu3 +0x4590:jin4 +0x4591:mi4 +0x4593:na4 +0x4594:han4 +0x4595:zu3 +0x4596:xia2 +0x4597:yan2 +0x4598:tu2 +0x459b:suo3 +0x459c:yin2 +0x459d:chong2 +0x459e:zhou3 +0x459f:mang3 +0x45a0:yuan2 +0x45a1:nv4 +0x45a2:miao2 +0x45a3:sao4 +0x45a4:wan3 +0x45a5:li2 +0x45a7:na4 +0x45a8:shi2 +0x45a9:bi4 +0x45aa:ci2 +0x45ab:bang4 +0x45ad:juan4 +0x45ae:xiang3 +0x45af:gui4 +0x45b0:pai4 +0x45b2:xun2 +0x45b3:zha4 +0x45b4:yao2 +0x45b8:e2 +0x45b9:yang2 +0x45ba:tiao2 +0x45bb:you2 +0x45bc:jue2 +0x45bd:li2 +0x45bf:li2 +0x45c1:ji4 +0x45c2:hu3 +0x45c3:zhan4 +0x45c4:fu3 +0x45c5:chang2 +0x45c6:guan3 +0x45c7:ju2 +0x45c8:meng2 +0x45ca:cheng2 +0x45cb:mou2 +0x45cd:li3 +0x45d1:yi4 +0x45d2:bing4 +0x45d4:hou2 +0x45d5:wan3 +0x45d6:chi4 +0x45d8:ge2 +0x45d9:han2 +0x45da:bo2 +0x45dc:liu2 +0x45dd:can2 +0x45de:can2 +0x45df:yi4 +0x45e0:xuan2 +0x45e1:yan2 +0x45e2:suo3 +0x45e3:gao3 +0x45e4:yong2 +0x45e8:yu2 +0x45ea:zhe4 +0x45eb:ma2 +0x45ee:shuang3 +0x45ef:jin4 +0x45f0:guan4 +0x45f1:pu2 +0x45f2:lin4 +0x45f4:ting2 +0x45f6:la4 +0x45f7:yi4 +0x45f9:ci4 +0x45fa:yan3 +0x45fb:jie2 +0x45fd:wei4 +0x45fe:xian3 +0x45ff:ning2 +0x4600:fu4 +0x4601:ge2 +0x4603:mo4 +0x4604:fu4 +0x4605:nai2 +0x4606:xian3 +0x4607:wen2 +0x4608:li4 +0x4609:can2 +0x460a:mie4 +0x460c:ni4 +0x460d:chai4 +0x460f:xu4 +0x4610:nv4 +0x4611:mai4 +0x4613:kan4 +0x4615:hang2 +0x4618:yu4 +0x4619:wei4 +0x461a:zhu2 +0x461d:yi4 +0x4620:fu2 +0x4621:bi3 +0x4622:zhu3 +0x4623:zi3 +0x4624:shu4 +0x4625:xia2 +0x4626:ni2 +0x4628:jiao3 +0x4629:xuan4 +0x462b:nou4 +0x462c:rong2 +0x462d:die2 +0x462e:sa4 +0x4631:yu4 +0x4635:lu4 +0x4636:han4 +0x4638:yi4 +0x4639:zui4 +0x463a:zhan4 +0x463b:su4 +0x463c:wan3 +0x463d:ni2 +0x463e:guan3 +0x463f:jue2 +0x4640:beng3 +0x4641:can2 +0x4643:duo4 +0x4644:qi4 +0x4645:yao4 +0x4646:gui4 +0x4647:nuan3 +0x4648:hou2 +0x4649:xun2 +0x464a:xie4 +0x464c:hui4 +0x464e:xie2 +0x464f:bo2 +0x4650:ke4 +0x4652:xu4 +0x4653:bai3 +0x4655:chu4 +0x4657:ti4 +0x4658:chu3 +0x4659:chi2 +0x465a:niao3 +0x465b:guan4 +0x465c:feng2 +0x465d:xie4 +0x465f:duo4 +0x4660:jue2 +0x4661:hui4 +0x4662:zeng4 +0x4663:sa4 +0x4664:duo3 +0x4665:ling2 +0x4666:meng2 +0x4668:guo3 +0x4669:meng2 +0x466a:long2 +0x466c:ying4 +0x466e:guan4 +0x466f:cu4 +0x4670:li2 +0x4671:du2 +0x4673:e4 +0x4677:de2 +0x4678:de2 +0x4679:jiang3 +0x467a:lian2 +0x467c:shao4 +0x467d:xi4 +0x467f:wei4 +0x4682:he4 +0x4683:you2 +0x4684:lu4 +0x4685:lai2 +0x4686:ou3 +0x4687:sheng3 +0x4688:juan4 +0x4689:qi4 +0x468b:yun4 +0x468d:qi4 +0x468f:leng4 +0x4690:ji2 +0x4691:mai2 +0x4692:chuang2 +0x4693:nian3 +0x4695:li4 +0x4696:ling2 +0x4698:chen2 +0x469a:xian3 +0x469b:hu2 +0x469d:zu2 +0x469e:dai3 +0x469f:dai3 +0x46a0:hun4 +0x46a2:che4 +0x46a3:ti2 +0x46a5:nuo4 +0x46a6:zhi4 +0x46a7:liu2 +0x46a8:fei4 +0x46a9:jiao3 +0x46ab:ao2 +0x46ac:lin2 +0x46ae:reng2 +0x46af:tao3 +0x46b0:pi3 +0x46b1:xin4 +0x46b2:shan4 +0x46b3:xie4 +0x46b4:wa4 +0x46b5:tao3 +0x46b7:xi4 +0x46b8:xie4 +0x46b9:pi3 +0x46ba:yao2 +0x46bb:yao2 +0x46bc:nv4 +0x46bd:hao4 +0x46be:nin2 +0x46bf:yin4 +0x46c0:fan3 +0x46c1:nan2 +0x46c2:chi2 +0x46c3:wang4 +0x46c4:yuan3 +0x46c5:xia2 +0x46c6:zhou4 +0x46c7:yuan3 +0x46c8:shi4 +0x46c9:mi4 +0x46cb:ge2 +0x46cc:pao2 +0x46cd:fei4 +0x46ce:hu4 +0x46cf:ni2 +0x46d0:ci2 +0x46d1:mi4 +0x46d2:bian4 +0x46d4:na2 +0x46d5:yu4 +0x46d6:e4 +0x46d7:zhi3 +0x46d8:nin2 +0x46d9:xu4 +0x46da:lve4 +0x46db:hui4 +0x46dc:xun4 +0x46dd:nao2 +0x46de:han3 +0x46df:jia2 +0x46e0:dou4 +0x46e1:hua4 +0x46e4:cu4 +0x46e5:xi4 +0x46e6:song4 +0x46e7:mi2 +0x46e8:xin4 +0x46e9:wu4 +0x46ea:qiong2 +0x46eb:zheng4 +0x46ec:chou2 +0x46ed:xing4 +0x46ee:jiu4 +0x46ef:ju4 +0x46f0:hun2 +0x46f1:ti2 +0x46f2:man2 +0x46f3:jian3 +0x46f4:qi3 +0x46f5:shou4 +0x46f6:lei3 +0x46f7:wan3 +0x46f8:che4 +0x46f9:can4 +0x46fa:jie4 +0x46fb:you4 +0x46fc:hui3 +0x46fd:zha3 +0x46fe:su4 +0x46ff:ge2 +0x4700:nao3 +0x4701:xi4 +0x4704:chi2 +0x4705:wei2 +0x4706:mo4 +0x4707:gun3 +0x470a:zao4 +0x470b:hui4 +0x470c:luan2 +0x470d:liao2 +0x470e:lao2 +0x4711:qia4 +0x4712:ao4 +0x4713:nie4 +0x4714:sui2 +0x4715:mai4 +0x4716:tan4 +0x4717:xin4 +0x4718:jing3 +0x4719:an2 +0x471a:ta4 +0x471b:chan2 +0x471c:wei4 +0x471d:tuan3 +0x471e:ji4 +0x471f:chen2 +0x4720:che4 +0x4721:xu4 +0x4722:xian3 +0x4723:xin1 +0x4727:nao3 +0x4729:yan4 +0x472a:qiu2 +0x472b:hong2 +0x472c:song3 +0x472d:jun4 +0x472e:liao2 +0x472f:ju2 +0x4731:man3 +0x4732:lie4 +0x4734:chu4 +0x4735:chi3 +0x4736:xiang2 +0x4738:mei3 +0x4739:shu4 +0x473a:ce4 +0x473b:chi3 +0x473c:gu2 +0x473d:yu2 +0x4740:liao2 +0x4741:lao2 +0x4742:shu4 +0x4743:zhe2 +0x4748:e4 +0x474a:sha4 +0x474b:zong4 +0x474c:jue2 +0x474d:jun4 +0x474f:lou2 +0x4750:wei2 +0x4752:zhu4 +0x4753:la4 +0x4755:zhe2 +0x4756:zhao3 +0x4758:yi4 +0x475a:ni2 +0x475d:yi3 +0x475e:hao4 +0x475f:ya4 +0x4760:huan2 +0x4761:man4 +0x4762:man4 +0x4763:qu2 +0x4764:lao3 +0x4765:hao2 +0x4767:men2 +0x4768:xian2 +0x4769:zhen4 +0x476a:shu2 +0x476b:zuo2 +0x476c:zhu4 +0x476d:gou4 +0x476e:xuan4 +0x476f:yi4 +0x4770:ti2 +0x4772:jin4 +0x4773:can2 +0x4775:bu4 +0x4776:liang2 +0x4777:zhi4 +0x4778:ji4 +0x4779:wan3 +0x477a:guan4 +0x477c:qing2 +0x477d:ai4 +0x477e:fu4 +0x477f:gui4 +0x4780:gou4 +0x4781:xian4 +0x4782:ruan3 +0x4783:zhi4 +0x4784:biao4 +0x4785:yi2 +0x4786:suo3 +0x4787:die2 +0x4788:gui3 +0x4789:sheng4 +0x478a:xun4 +0x478b:chen4 +0x478c:she2 +0x478d:qing2 +0x4790:chun3 +0x4791:hong2 +0x4792:dong4 +0x4793:cheng1 +0x4794:wei3 +0x4795:die2 +0x4796:shu3 +0x4798:ji2 +0x4799:za2 +0x479a:qi2 +0x479c:fu4 +0x479d:ao3 +0x479e:fu2 +0x479f:po4 +0x47a1:tan3 +0x47a2:zha4 +0x47a3:che3 +0x47a4:qu2 +0x47a5:you4 +0x47a6:he2 +0x47a7:hou4 +0x47a8:gui3 +0x47a9:e4 +0x47aa:jiang4 +0x47ab:yun3 +0x47ac:tou4 +0x47ad:qiu3 +0x47af:fu4 +0x47b0:zuo2 +0x47b1:hu2 +0x47b3:bo2 +0x47b5:jue3 +0x47b6:di4 +0x47b7:jue2 +0x47b8:fu4 +0x47b9:huang2 +0x47bb:yong3 +0x47bc:chui3 +0x47bd:suo3 +0x47be:chi2 +0x47c2:man2 +0x47c3:ca4 +0x47c4:qi4 +0x47c5:jian4 +0x47c6:bi4 +0x47c8:zhi2 +0x47c9:zhu2 +0x47ca:qu2 +0x47cb:zhan3 +0x47cc:ji2 +0x47cd:dian2 +0x47cf:li4 +0x47d0:li4 +0x47d1:la3 +0x47d2:quan2 +0x47d4:fu4 +0x47d5:cha4 +0x47d6:tang4 +0x47d7:shi4 +0x47d8:hang4 +0x47d9:qie4 +0x47da:qi2 +0x47db:bo2 +0x47dc:na4 +0x47dd:tou4 +0x47de:chu2 +0x47df:cu4 +0x47e0:yue4 +0x47e1:di4 +0x47e2:chen2 +0x47e3:chu4 +0x47e4:bi4 +0x47e5:mang2 +0x47e6:ba2 +0x47e7:tian2 +0x47e8:min2 +0x47e9:lie3 +0x47ea:feng3 +0x47ec:qiu4 +0x47ed:tiao2 +0x47ee:fu2 +0x47ef:kuo4 +0x47f0:jian3 +0x47f4:zhen4 +0x47f5:qiu2 +0x47f6:cuo4 +0x47f7:chi4 +0x47f8:kui2 +0x47f9:lie4 +0x47fa:bang3 +0x47fb:du4 +0x47fc:wu3 +0x47fe:jue3 +0x47ff:lu4 +0x4800:chang3 +0x4802:chu2 +0x4803:liang3 +0x4804:tian3 +0x4805:kun3 +0x4806:chang2 +0x4807:jue2 +0x4808:tu2 +0x4809:hua4 +0x480a:fei4 +0x480b:bi3 +0x480d:qia2 +0x480e:wo4 +0x480f:ji4 +0x4810:qu4 +0x4811:kui3 +0x4812:hu2 +0x4813:cu4 +0x4814:sui4 +0x4817:qiu4 +0x4818:pi4 +0x4819:bei4 +0x481a:wa4 +0x481b:jiao3 +0x481c:rong2 +0x481e:cu4 +0x481f:die2 +0x4820:chi4 +0x4821:cuo2 +0x4822:meng4 +0x4823:xuan3 +0x4824:duo3 +0x4825:bie2 +0x4826:zhe4 +0x4827:chu2 +0x4828:chan4 +0x4829:gui4 +0x482a:duan4 +0x482b:zou4 +0x482c:deng4 +0x482d:lai2 +0x482e:teng2 +0x482f:yue4 +0x4830:quan2 +0x4831:shu3 +0x4832:ling2 +0x4834:qin3 +0x4835:fu4 +0x4836:she4 +0x4837:tiao3 +0x4839:ai2 +0x483b:qiong2 +0x483c:diao4 +0x483d:hai2 +0x483e:shan3 +0x483f:wai4 +0x4840:zhan3 +0x4841:long3 +0x4842:jiu4 +0x4843:li4 +0x4845:min3 +0x4846:rong2 +0x4847:yue4 +0x4848:jue2 +0x4849:kang3 +0x484a:fan2 +0x484b:qi2 +0x484c:hong2 +0x484d:fu2 +0x484e:lu2 +0x484f:hong2 +0x4850:tuo2 +0x4851:min2 +0x4852:tian2 +0x4853:juan4 +0x4854:qi3 +0x4855:zheng3 +0x4856:jing4 +0x4857:gong3 +0x4858:tian2 +0x4859:lang2 +0x485a:mao4 +0x485b:yin4 +0x485c:lu4 +0x485d:yun3 +0x485e:ju2 +0x485f:pi4 +0x4861:xie2 +0x4862:bian4 +0x4865:rong2 +0x4866:sang3 +0x4867:wu3 +0x4868:cha4 +0x4869:gu3 +0x486a:chan2 +0x486b:peng2 +0x486c:man4 +0x486f:shuang4 +0x4870:keng3 +0x4871:zhuan3 +0x4872:chan2 +0x4874:chuang2 +0x4875:sui4 +0x4876:bei4 +0x4877:kai4 +0x4879:zhi4 +0x487a:wei4 +0x487b:min2 +0x487c:ling2 +0x487e:nei4 +0x487f:ling2 +0x4880:qi4 +0x4881:yue4 +0x4883:yi4 +0x4884:xi3 +0x4885:chen2 +0x4887:rong3 +0x4888:chen2 +0x4889:nong2 +0x488a:you2 +0x488b:ji4 +0x488c:bo2 +0x488d:fang3 +0x4890:cu2 +0x4891:di3 +0x4893:yu2 +0x4894:ge2 +0x4895:xu4 +0x4896:lv4 +0x4897:he2 +0x4899:bai4 +0x489a:gong4 +0x489b:jiong3 +0x489d:ya4 +0x489e:nu4 +0x489f:you2 +0x48a0:song4 +0x48a1:xie4 +0x48a2:cang4 +0x48a3:yao2 +0x48a4:shu4 +0x48a5:yan2 +0x48a6:shuai4 +0x48a7:liao4 +0x48a9:yu4 +0x48aa:bo2 +0x48ab:sui2 +0x48ad:yan4 +0x48ae:lei4 +0x48af:lin2 +0x48b0:tai2 +0x48b1:du2 +0x48b2:yue4 +0x48b3:ji3 +0x48b5:yun2 +0x48b9:ju3 +0x48bb:chen2 +0x48bd:xiang4 +0x48be:xian3 +0x48c0:gui3 +0x48c1:yu3 +0x48c2:lei3 +0x48c4:tu2 +0x48c5:chen2 +0x48c6:xing2 +0x48c7:qiu2 +0x48c8:hang4 +0x48ca:dang3 +0x48cb:cai3 +0x48cc:di3 +0x48cd:yan3 +0x48d1:chan2 +0x48d3:li2 +0x48d4:suo3 +0x48d5:ma3 +0x48d6:ma3 +0x48d8:tang2 +0x48d9:pei2 +0x48da:lou2 +0x48dc:cuo2 +0x48dd:tu2 +0x48de:e4 +0x48df:can2 +0x48e0:jie2 +0x48e1:ti2 +0x48e2:ji2 +0x48e3:dang3 +0x48e4:jiao4 +0x48e5:bi3 +0x48e6:lei4 +0x48e7:yi4 +0x48e8:chun2 +0x48e9:chun2 +0x48ea:po4 +0x48eb:li2 +0x48ec:zai3 +0x48ed:tai4 +0x48ee:po4 +0x48ef:tian3 +0x48f0:ju4 +0x48f1:xu4 +0x48f2:fan4 +0x48f4:xu4 +0x48f5:er4 +0x48f6:huo2 +0x48f8:ran3 +0x48f9:fa2 +0x48fc:liang2 +0x48fd:ti3 +0x48fe:mi4 +0x4901:cen2 +0x4902:mei2 +0x4903:yin4 +0x4904:mian3 +0x4905:tu2 +0x4906:kui2 +0x4909:mi4 +0x490a:rong2 +0x490b:guo2 +0x490d:mi2 +0x490e:ju2 +0x490f:pi3 +0x4910:jin3 +0x4911:wang4 +0x4912:ji3 +0x4913:meng2 +0x4914:jian4 +0x4915:xue4 +0x4916:bao4 +0x4917:gan3 +0x4918:chan3 +0x4919:li4 +0x491a:li3 +0x491b:qiu2 +0x491c:dun4 +0x491d:ying4 +0x491e:yun3 +0x491f:chen2 +0x4920:ji1 +0x4921:ran3 +0x4923:lve4 +0x4925:gui3 +0x4926:yue4 +0x4927:hui4 +0x4928:pi4 +0x4929:cha2 +0x492a:duo3 +0x492b:chan2 +0x492d:kuan4 +0x492e:she4 +0x492f:xing2 +0x4930:weng3 +0x4931:shi4 +0x4932:chi4 +0x4933:ye4 +0x4934:han2 +0x4935:fei4 +0x4936:ye4 +0x4937:yan2 +0x4938:zuan4 +0x493a:yin3 +0x493b:duo4 +0x493c:xian4 +0x493f:qie4 +0x4940:chan3 +0x4941:han2 +0x4942:meng4 +0x4943:yue4 +0x4944:cu4 +0x4945:qian4 +0x4946:jin3 +0x4947:shan4 +0x4948:mu3 +0x494c:zheng4 +0x494d:zhi4 +0x494e:chun2 +0x494f:yu3 +0x4950:mou2 +0x4951:wan4 +0x4952:chou2 +0x4954:su4 +0x4955:pie3 +0x4956:tian2 +0x4957:kuan3 +0x4958:cu4 +0x4959:sui4 +0x495b:jie2 +0x495c:jian4 +0x495d:ao2 +0x495e:jiao3 +0x495f:ye4 +0x4961:ye4 +0x4962:long2 +0x4963:zao2 +0x4964:bao2 +0x4965:lian2 +0x4967:huan2 +0x4968:lv4 +0x4969:wei2 +0x496a:xian3 +0x496b:tie3 +0x496c:bo2 +0x496d:zheng4 +0x496e:zhu2 +0x496f:ba4 +0x4970:meng4 +0x4971:xie3 +0x4975:xiao3 +0x4976:li4 +0x4977:zha2 +0x4978:mi2 +0x497a:ye2 +0x497e:xie3 +0x4982:shan4 +0x4985:shan4 +0x4986:jue2 +0x4987:ji4 +0x4988:fang3 +0x498a:niao3 +0x498b:ao2 +0x498c:chu4 +0x498d:wu4 +0x498e:guan3 +0x498f:xie4 +0x4990:ting3 +0x4991:xie4 +0x4992:dang4 +0x4994:tan3 +0x4996:xia2 +0x4997:xu4 +0x4998:bi4 +0x4999:si4 +0x499a:huo4 +0x499b:zheng4 +0x499c:wu2 +0x499e:run4 +0x499f:chuai4 +0x49a0:shi3 +0x49a1:huan2 +0x49a2:kuo4 +0x49a3:fu4 +0x49a4:chuai4 +0x49a5:xian2 +0x49a6:qin2 +0x49a7:qie2 +0x49a8:lan2 +0x49aa:ya4 +0x49ac:que4 +0x49ae:chun3 +0x49af:zhi4 +0x49b1:kui3 +0x49b2:qian4 +0x49b3:hang4 +0x49b4:yi4 +0x49b5:ni3 +0x49b6:zheng4 +0x49b7:chuai4 +0x49b9:shi2 +0x49bb:ci4 +0x49bc:jue2 +0x49bd:xu4 +0x49be:yun3 +0x49c1:chu4 +0x49c2:dao4 +0x49c3:dian4 +0x49c4:ge4 +0x49c5:ti4 +0x49c6:hong2 +0x49c7:ni3 +0x49c9:li3 +0x49cb:xian3 +0x49cd:xi4 +0x49ce:xuan4 +0x49d2:lai2 +0x49d4:mu4 +0x49d5:cheng2 +0x49d6:jian4 +0x49d7:bi4 +0x49d8:qi2 +0x49d9:ling2 +0x49da:hao4 +0x49db:bang4 +0x49dc:tang2 +0x49dd:di4 +0x49de:fu4 +0x49df:xian4 +0x49e0:shuan4 +0x49e4:pu2 +0x49e5:hui4 +0x49e6:wei2 +0x49e7:yi3 +0x49e8:ye4 +0x49ea:che4 +0x49eb:hao2 +0x49ee:xian3 +0x49ef:chan2 +0x49f0:hun4 +0x49f2:han4 +0x49f3:ci2 +0x49f5:qi2 +0x49f6:kui2 +0x49f7:rou2 +0x49fa:xiong2 +0x49fc:hu2 +0x49fd:cui3 +0x49ff:que4 +0x4a00:di2 +0x4a01:che4 +0x4a04:yan4 +0x4a05:liao2 +0x4a06:bi2 +0x4a0b:nve4 +0x4a0c:bao2 +0x4a0d:ying3 +0x4a0e:hong2 +0x4a0f:ci2 +0x4a10:qia4 +0x4a11:ti2 +0x4a12:yu4 +0x4a13:lei2 +0x4a14:bao2 +0x4a16:ji4 +0x4a17:fu2 +0x4a18:xian4 +0x4a19:cen2 +0x4a1b:se4 +0x4a1e:yu3 +0x4a20:ai3 +0x4a21:han2 +0x4a22:dan4 +0x4a23:ge2 +0x4a24:di2 +0x4a25:hu4 +0x4a26:pang2 +0x4a29:ling2 +0x4a2a:mai2 +0x4a2b:mai4 +0x4a2c:lian2 +0x4a2e:xue3 +0x4a2f:zhen4 +0x4a30:po4 +0x4a31:fu4 +0x4a32:nou2 +0x4a33:xi4 +0x4a34:dui4 +0x4a35:dan4 +0x4a36:yun3 +0x4a37:xian4 +0x4a38:yin3 +0x4a3a:dui4 +0x4a3b:beng4 +0x4a3c:hu4 +0x4a3d:fei3 +0x4a3e:fei3 +0x4a3f:qian2 +0x4a40:bei4 +0x4a43:shi4 +0x4a44:tian3 +0x4a45:zhan3 +0x4a46:jian3 +0x4a48:hui4 +0x4a49:fu3 +0x4a4a:wan3 +0x4a4b:mo3 +0x4a4c:qiao2 +0x4a4d:liao3 +0x4a4f:mie4 +0x4a50:ge2 +0x4a51:hong2 +0x4a52:yu2 +0x4a53:qi2 +0x4a54:duo4 +0x4a55:ang2 +0x4a57:ba4 +0x4a58:di4 +0x4a59:xuan4 +0x4a5a:di4 +0x4a5b:bi4 +0x4a5c:zhou4 +0x4a5d:pao2 +0x4a5e:nian2 +0x4a5f:yi2 +0x4a61:jia2 +0x4a62:da2 +0x4a63:duo3 +0x4a64:xi4 +0x4a65:dan4 +0x4a66:tiao2 +0x4a67:xie4 +0x4a68:chang4 +0x4a69:yuan3 +0x4a6a:guan3 +0x4a6b:liang3 +0x4a6c:beng3 +0x4a6e:lu4 +0x4a6f:ji2 +0x4a70:xuan4 +0x4a71:shu4 +0x4a73:shu3 +0x4a74:hu2 +0x4a75:yun4 +0x4a76:chan3 +0x4a78:rong2 +0x4a79:e2 +0x4a7b:ba4 +0x4a7c:feng2 +0x4a7e:zhe4 +0x4a7f:fen2 +0x4a80:guan3 +0x4a81:bu3 +0x4a82:ge2 +0x4a84:huang2 +0x4a85:du2 +0x4a86:ti3 +0x4a87:bo2 +0x4a88:qian3 +0x4a89:la4 +0x4a8a:long2 +0x4a8b:wei4 +0x4a8c:zhan4 +0x4a8d:lan2 +0x4a8f:na4 +0x4a90:bi4 +0x4a91:tuo2 +0x4a92:jiao4 +0x4a94:bu3 +0x4a95:ju2 +0x4a96:po4 +0x4a97:xia2 +0x4a98:wei3 +0x4a99:fu2 +0x4a9a:he4 +0x4a9b:fan2 +0x4a9c:chan4 +0x4a9d:hu4 +0x4a9e:za2 +0x4aa4:fan2 +0x4aa5:die2 +0x4aa6:hong2 +0x4aa7:chi2 +0x4aa8:bao2 +0x4aa9:yin2 +0x4aac:bo2 +0x4aad:ruan3 +0x4aae:chou3 +0x4aaf:ying2 +0x4ab1:gai3 +0x4ab3:yun3 +0x4ab4:zhen3 +0x4ab5:ya3 +0x4ab7:hou4 +0x4ab8:min2 +0x4ab9:pei2 +0x4aba:ge2 +0x4abb:bian4 +0x4abd:hao4 +0x4abe:mi2 +0x4abf:sheng3 +0x4ac0:gen3 +0x4ac1:bi4 +0x4ac2:duo3 +0x4ac3:chun2 +0x4ac4:chua4 +0x4ac5:san4 +0x4ac6:cheng2 +0x4ac7:ran2 +0x4ac8:zen4 +0x4ac9:mao4 +0x4aca:bo2 +0x4acb:tui2 +0x4acc:pi3 +0x4acd:fu3 +0x4ad0:lin2 +0x4ad2:men2 +0x4ad3:wu2 +0x4ad4:qi4 +0x4ad5:zhi4 +0x4ad6:chen3 +0x4ad7:xia2 +0x4ad8:he2 +0x4ad9:sang3 +0x4adb:hou2 +0x4add:fu3 +0x4ade:rao2 +0x4adf:hun2 +0x4ae0:pei2 +0x4ae1:qian4 +0x4ae3:xi2 +0x4ae4:ming2 +0x4ae5:kui3 +0x4ae6:ge2 +0x4ae8:ao4 +0x4ae9:san3 +0x4aea:shuang3 +0x4aeb:lou2 +0x4aec:zhen3 +0x4aed:hui4 +0x4aee:can2 +0x4af0:lin4 +0x4af1:na2 +0x4af2:han4 +0x4af3:du2 +0x4af4:jin4 +0x4af5:mian2 +0x4af6:fan2 +0x4af7:e4 +0x4af8:nao2 +0x4af9:hong2 +0x4afa:hong2 +0x4afb:xue2 +0x4afc:xue4 +0x4afe:bi4 +0x4b00:you3 +0x4b01:yi2 +0x4b02:xue4 +0x4b03:sa4 +0x4b04:yu4 +0x4b05:li4 +0x4b06:li4 +0x4b07:yuan4 +0x4b08:dui4 +0x4b09:hao4 +0x4b0a:qie4 +0x4b0b:leng2 +0x4b0e:guo2 +0x4b0f:bu4 +0x4b10:wei3 +0x4b11:wei4 +0x4b13:an4 +0x4b14:xu4 +0x4b15:shang3 +0x4b16:heng2 +0x4b17:yang2 +0x4b19:yao2 +0x4b1b:bi4 +0x4b1d:heng2 +0x4b1e:tao2 +0x4b1f:liu2 +0x4b21:zhu4 +0x4b23:qi4 +0x4b24:chao2 +0x4b25:yi4 +0x4b26:dou4 +0x4b27:yuan2 +0x4b28:cu4 +0x4b2a:bo2 +0x4b2b:can3 +0x4b2c:yang3 +0x4b2e:yi2 +0x4b2f:nian2 +0x4b30:shao4 +0x4b31:ben4 +0x4b33:ban3 +0x4b34:mo4 +0x4b35:ai4 +0x4b36:en4 +0x4b37:she3 +0x4b39:zhi4 +0x4b3a:yang4 +0x4b3b:jian4 +0x4b3c:yuan4 +0x4b3d:dui4 +0x4b3e:ti2 +0x4b3f:wei3 +0x4b40:xun4 +0x4b41:zhi4 +0x4b42:yi4 +0x4b43:ren3 +0x4b44:shi4 +0x4b45:hu2 +0x4b46:ne4 +0x4b47:yi4 +0x4b48:jian4 +0x4b49:sui3 +0x4b4a:ying3 +0x4b4b:bao3 +0x4b4c:hu2 +0x4b4d:hu2 +0x4b4e:xie2 +0x4b50:yang4 +0x4b51:lian2 +0x4b53:en4 +0x4b55:jian4 +0x4b56:zhu4 +0x4b57:ying3 +0x4b58:yan4 +0x4b59:jin3 +0x4b5a:chuang2 +0x4b5b:dan4 +0x4b5d:kuai4 +0x4b5e:yi4 +0x4b5f:ye4 +0x4b60:jian3 +0x4b61:en4 +0x4b62:ning2 +0x4b63:ci2 +0x4b64:qian3 +0x4b65:xue4 +0x4b66:bo2 +0x4b67:mi3 +0x4b68:shui4 +0x4b69:mi4 +0x4b6a:liang2 +0x4b6b:qi3 +0x4b6c:qi3 +0x4b6d:shou3 +0x4b6e:bi4 +0x4b6f:bo2 +0x4b70:beng3 +0x4b71:bie2 +0x4b72:ni3 +0x4b73:wei4 +0x4b74:huan2 +0x4b75:fan2 +0x4b76:qi2 +0x4b77:liu2 +0x4b78:fu4 +0x4b79:ang2 +0x4b7a:ang2 +0x4b7c:qi2 +0x4b7d:qun2 +0x4b7e:tuo2 +0x4b7f:yi4 +0x4b80:bo2 +0x4b81:pian2 +0x4b82:bo2 +0x4b84:xuan2 +0x4b87:yu4 +0x4b88:chi2 +0x4b89:lu2 +0x4b8a:yi2 +0x4b8b:li4 +0x4b8d:niao3 +0x4b8e:xi4 +0x4b8f:wu2 +0x4b91:lei4 +0x4b93:zhao4 +0x4b94:zui3 +0x4b95:chuo4 +0x4b97:an4 +0x4b98:er2 +0x4b99:yu4 +0x4b9a:leng4 +0x4b9b:fu4 +0x4b9c:sha4 +0x4b9d:huan2 +0x4b9e:chu4 +0x4b9f:sou3 +0x4ba1:bi4 +0x4ba2:die2 +0x4ba4:di2 +0x4ba5:li4 +0x4ba7:han2 +0x4ba8:zai3 +0x4ba9:gu2 +0x4baa:cheng2 +0x4bab:lou2 +0x4bac:mo4 +0x4bad:mi4 +0x4bae:mai4 +0x4baf:ao4 +0x4bb0:dan3 +0x4bb1:zhu2 +0x4bb2:huang2 +0x4bb3:fan2 +0x4bb4:deng4 +0x4bb5:tong2 +0x4bb7:du2 +0x4bb8:hu2 +0x4bb9:wei4 +0x4bba:ji4 +0x4bbb:chi4 +0x4bbc:lin2 +0x4bbe:pang2 +0x4bbf:jian3 +0x4bc0:nie4 +0x4bc1:luo2 +0x4bc2:ji2 +0x4bc5:nie4 +0x4bc6:yi4 +0x4bc8:wan2 +0x4bc9:ya4 +0x4bca:qia4 +0x4bcb:bo2 +0x4bcd:ling2 +0x4bce:gan4 +0x4bcf:huo2 +0x4bd0:hai2 +0x4bd2:heng2 +0x4bd3:kui2 +0x4bd4:cen2 +0x4bd6:lang2 +0x4bd7:bi4 +0x4bd8:huan4 +0x4bd9:po4 +0x4bda:ou3 +0x4bdb:jian3 +0x4bdc:ti4 +0x4bdd:sui3 +0x4bdf:dui4 +0x4be0:ao3 +0x4be1:jian3 +0x4be2:mo2 +0x4be3:gui4 +0x4be4:kuai4 +0x4be5:an4 +0x4be6:ma4 +0x4be7:qing3 +0x4be8:fen2 +0x4bea:kao3 +0x4beb:hao4 +0x4bec:duo3 +0x4bee:nai2 +0x4bf0:jie4 +0x4bf1:fu4 +0x4bf2:pa2 +0x4bf4:chang2 +0x4bf5:nie4 +0x4bf6:man2 +0x4bf8:ci4 +0x4bfa:kuo4 +0x4bfc:di2 +0x4bfd:fu3 +0x4bfe:tiao2 +0x4bff:zu2 +0x4c00:wo3 +0x4c01:fei4 +0x4c02:cai4 +0x4c03:peng2 +0x4c04:shi4 +0x4c06:rou2 +0x4c07:qi2 +0x4c08:cha3 +0x4c09:pan2 +0x4c0a:bo2 +0x4c0b:man2 +0x4c0c:zong3 +0x4c0d:ci4 +0x4c0e:gui4 +0x4c0f:ji4 +0x4c10:lan2 +0x4c12:meng2 +0x4c13:mian2 +0x4c14:pan2 +0x4c15:lu2 +0x4c16:cuan2 +0x4c18:liu2 +0x4c19:yi3 +0x4c1a:wen2 +0x4c1b:li4 +0x4c1c:li4 +0x4c1d:zeng4 +0x4c1e:zhu3 +0x4c1f:hun2 +0x4c20:shen2 +0x4c21:chi4 +0x4c22:xing4 +0x4c23:wang3 +0x4c25:huo4 +0x4c26:pi3 +0x4c28:mei4 +0x4c29:che3 +0x4c2a:mei4 +0x4c2b:chao2 +0x4c2c:ju2 +0x4c2d:nou4 +0x4c2f:ni3 +0x4c30:ru2 +0x4c31:ling2 +0x4c32:ya4 +0x4c34:qi4 +0x4c37:bang4 +0x4c39:ze2 +0x4c3a:jie4 +0x4c3b:yu2 +0x4c3c:xin2 +0x4c3d:bei4 +0x4c3e:ba4 +0x4c3f:tuo2 +0x4c41:qiao2 +0x4c42:you3 +0x4c43:di3 +0x4c44:jie4 +0x4c45:mo4 +0x4c46:sheng2 +0x4c47:shan4 +0x4c48:qi2 +0x4c49:shan4 +0x4c4a:mi3 +0x4c4b:dan3 +0x4c4c:yi2 +0x4c4d:geng4 +0x4c4e:geng4 +0x4c4f:tou3 +0x4c51:xue2 +0x4c52:yi4 +0x4c53:ting2 +0x4c54:tiao2 +0x4c55:mou2 +0x4c56:liu2 +0x4c58:li2 +0x4c5a:lu4 +0x4c5b:xu4 +0x4c5c:cuo4 +0x4c5d:ba4 +0x4c5e:liu2 +0x4c5f:ju4 +0x4c60:zhan4 +0x4c61:ju2 +0x4c63:zu2 +0x4c64:xian4 +0x4c65:zhi2 +0x4c68:zhi4 +0x4c6b:la4 +0x4c6d:geng4 +0x4c6e:e2 +0x4c6f:mu2 +0x4c70:zhong4 +0x4c71:di4 +0x4c72:yan2 +0x4c74:geng4 +0x4c76:lang2 +0x4c77:yu2 +0x4c79:na4 +0x4c7a:hai2 +0x4c7b:hua2 +0x4c7c:zhan3 +0x4c7e:lou2 +0x4c7f:chan4 +0x4c80:die2 +0x4c81:wei4 +0x4c82:xuan2 +0x4c83:zao3 +0x4c84:min2 +0x4c8a:tuo3 +0x4c8b:cen2 +0x4c8c:kuan3 +0x4c8d:teng2 +0x4c8e:nei3 +0x4c8f:lao2 +0x4c90:lu3 +0x4c91:yi2 +0x4c92:xie4 +0x4c93:yan3 +0x4c94:qing2 +0x4c95:pu3 +0x4c96:chou2 +0x4c97:xian2 +0x4c98:guan3 +0x4c99:jie2 +0x4c9a:lai4 +0x4c9b:meng2 +0x4c9c:ye4 +0x4c9e:li4 +0x4c9f:yin4 +0x4ca2:teng2 +0x4ca3:yu2 +0x4ca6:cha2 +0x4ca7:du4 +0x4ca8:hong2 +0x4caa:xi4 +0x4cac:qi2 +0x4cae:yuan2 +0x4caf:ji2 +0x4cb0:yun4 +0x4cb1:fang3 +0x4cb3:hang2 +0x4cb4:zhen4 +0x4cb5:hu4 +0x4cb8:jie4 +0x4cb9:pei2 +0x4cba:gan4 +0x4cbb:xuan2 +0x4cbd:dao3 +0x4cbe:qiao3 +0x4cbf:ci2 +0x4cc0:die2 +0x4cc1:ba2 +0x4cc2:tiao2 +0x4cc3:wan3 +0x4cc4:ci2 +0x4cc5:zhi3 +0x4cc6:bai2 +0x4cc7:wu3 +0x4cc8:bao3 +0x4cc9:dan4 +0x4cca:ba2 +0x4ccb:tong2 +0x4cce:jiu4 +0x4ccf:gui4 +0x4cd0:ci4 +0x4cd1:you3 +0x4cd2:yuan2 +0x4cd3:lao3 +0x4cd4:jiu4 +0x4cd5:fou2 +0x4cd6:nei4 +0x4cd7:e2 +0x4cd8:e2 +0x4cd9:xing3 +0x4cda:he2 +0x4cdb:yan4 +0x4cdc:tu2 +0x4cdd:bu4 +0x4cde:beng3 +0x4cdf:kou4 +0x4ce0:chui2 +0x4ce2:qi2 +0x4ce3:yuan2 +0x4ce7:hou2 +0x4ce8:huang2 +0x4cea:juan4 +0x4ceb:kui2 +0x4cec:e4 +0x4ced:ji2 +0x4cee:mo4 +0x4cef:chong2 +0x4cf0:bao3 +0x4cf1:wu4 +0x4cf2:zhen4 +0x4cf3:xu4 +0x4cf4:da2 +0x4cf5:chi4 +0x4cf7:cong2 +0x4cf8:ma2 +0x4cf9:kou4 +0x4cfa:yan4 +0x4cfb:can2 +0x4cfd:he4 +0x4cff:lan2 +0x4d00:tong2 +0x4d01:yu4 +0x4d02:hang4 +0x4d03:nao2 +0x4d04:li4 +0x4d05:fen2 +0x4d06:pu2 +0x4d07:ling2 +0x4d08:ao3 +0x4d09:xuan2 +0x4d0a:yi2 +0x4d0b:xuan2 +0x4d0c:meng2 +0x4d0e:lei3 +0x4d0f:yan4 +0x4d10:bao3 +0x4d11:die2 +0x4d12:ling2 +0x4d13:shi1 +0x4d14:jiao1 +0x4d15:lie4 +0x4d16:jing1 +0x4d17:ju2 +0x4d18:ti1 +0x4d19:pi4 +0x4d1a:gang3 +0x4d1b:jiao3 +0x4d1c:huai2 +0x4d1d:bu4 +0x4d1e:di2 +0x4d1f:huan2 +0x4d20:yao3 +0x4d21:li4 +0x4d22:mi2 +0x4d26:ren2 +0x4d29:piao2 +0x4d2a:lu4 +0x4d2b:ling2 +0x4d2c:yi4 +0x4d2d:cai2 +0x4d2e:shan4 +0x4d30:shu2 +0x4d31:tuo2 +0x4d32:mo4 +0x4d33:he4 +0x4d34:tie4 +0x4d35:bing3 +0x4d36:peng2 +0x4d37:hun2 +0x4d39:guo3 +0x4d3a:bu4 +0x4d3b:li2 +0x4d3c:chan3 +0x4d3d:bai4 +0x4d3e:cuo2 +0x4d3f:meng2 +0x4d40:suo3 +0x4d41:qiang4 +0x4d42:zhi2 +0x4d43:kuang4 +0x4d44:bi2 +0x4d45:ao2 +0x4d46:meng2 +0x4d47:xian4 +0x4d49:tou2 +0x4d4b:wei3 +0x4d4f:lao3 +0x4d50:chan3 +0x4d51:ni4 +0x4d52:ni4 +0x4d53:li2 +0x4d54:dong3 +0x4d55:ju4 +0x4d56:jian4 +0x4d57:fu2 +0x4d58:sha4 +0x4d59:zha3 +0x4d5a:tao3 +0x4d5b:jian4 +0x4d5c:nong3 +0x4d5d:ya4 +0x4d5e:jing4 +0x4d5f:gan3 +0x4d60:di2 +0x4d61:jian3 +0x4d62:mei4 +0x4d63:da2 +0x4d64:jian3 +0x4d65:she4 +0x4d66:xie4 +0x4d67:zai4 +0x4d68:mang2 +0x4d69:li2 +0x4d6a:gun4 +0x4d6b:yu4 +0x4d6c:ta4 +0x4d6d:zhe4 +0x4d6e:yang4 +0x4d6f:tuan3 +0x4d71:he4 +0x4d72:diao4 +0x4d73:wei4 +0x4d74:yun4 +0x4d75:zha2 +0x4d76:qu2 +0x4d7a:ting3 +0x4d7b:gu3 +0x4d7d:ca4 +0x4d7e:fu2 +0x4d7f:tie4 +0x4d80:ta4 +0x4d81:ta4 +0x4d82:zhuo2 +0x4d83:han2 +0x4d84:ping2 +0x4d85:he2 +0x4d87:zhou4 +0x4d88:bo2 +0x4d89:liu2 +0x4d8a:nv4 +0x4d8c:pao4 +0x4d8d:di4 +0x4d8e:sha4 +0x4d8f:ti3 +0x4d90:kuai4 +0x4d91:ti4 +0x4d92:qi2 +0x4d93:ji4 +0x4d94:chi2 +0x4d95:pa2 +0x4d96:jin4 +0x4d97:ke4 +0x4d98:li4 +0x4d99:ju4 +0x4d9a:qu3 +0x4d9b:la4 +0x4d9c:gu4 +0x4d9d:qia4 +0x4d9e:qi2 +0x4d9f:xian4 +0x4da0:jian3 +0x4da1:shi2 +0x4da2:xian2 +0x4da3:ai2 +0x4da4:hua2 +0x4da5:ju3 +0x4da6:ze2 +0x4da7:yao3 +0x4da9:ji4 +0x4daa:cha2 +0x4dab:kan3 +0x4dae:yan2 +0x4db1:tong2 +0x4db2:nan2 +0x4db3:yue4 +0x4db5:chi2 +0x4e00:yi1 +0x4e01:ding1 +0x4e02:kao3 +0x4e03:qi1 +0x4e04:shang4 +0x4e05:xia4 +0x4e07:wan4 +0x4e08:zhang4 +0x4e09:san1 +0x4e0a:shang4 +0x4e0b:xia4 +0x4e0c:ji1 +0x4e0d:bu4 +0x4e0e:yu3 +0x4e0f:mian3 +0x4e10:gai4 +0x4e11:chou3 +0x4e12:chou3 +0x4e13:zhuan1 +0x4e14:qie3 +0x4e15:pi1 +0x4e16:shi4 +0x4e17:shi4 +0x4e18:qiu1 +0x4e19:bing3 +0x4e1a:ye4 +0x4e1b:cong2 +0x4e1c:dong1 +0x4e1d:si1 +0x4e1e:cheng2 +0x4e1f:diu1 +0x4e20:qiu1 +0x4e21:liang3 +0x4e22:diu1 +0x4e23:you3 +0x4e24:liang3 +0x4e25:yan2 +0x4e26:bing4 +0x4e27:sang1 +0x4e28:gun3 +0x4e29:jiu1 +0x4e2a:ge4 +0x4e2b:ya1 +0x4e2c:qiang2 +0x4e2d:zhong1 +0x4e2e:ji3 +0x4e2f:jie4 +0x4e30:feng1 +0x4e31:guan4 +0x4e32:chuan4 +0x4e33:chan3 +0x4e34:lin2 +0x4e35:zhuo3 +0x4e36:zhu3 +0x4e38:wan2 +0x4e39:dan1 +0x4e3a:wei4 +0x4e3b:zhu3 +0x4e3c:jing3 +0x4e3d:li4 +0x4e3e:ju3 +0x4e3f:pie3 +0x4e40:fu2 +0x4e41:yi2 +0x4e42:yi4 +0x4e43:nai3 +0x4e45:jiu3 +0x4e46:jiu3 +0x4e47:zhe2 +0x4e48:yao1 +0x4e49:yi4 +0x4e4b:zhi1 +0x4e4c:wu1 +0x4e4d:zha4 +0x4e4e:hu1 +0x4e4f:fa2 +0x4e50:le4 +0x4e51:zhong4 +0x4e52:ping1 +0x4e53:pang1 +0x4e54:qiao2 +0x4e55:hu3 +0x4e56:guai1 +0x4e57:cheng2 +0x4e58:cheng2 +0x4e59:yi3 +0x4e5a:yin3 +0x4e5c:mie1 +0x4e5d:jiu3 +0x4e5e:qi3 +0x4e5f:ye3 +0x4e60:xi2 +0x4e61:xiang1 +0x4e62:gai4 +0x4e63:jiu3 +0x4e66:shu1 +0x4e68:shi3 +0x4e69:ji1 +0x4e6a:nang2 +0x4e6b:jia1 +0x4e6d:shi2 +0x4e70:mai3 +0x4e71:luan4 +0x4e73:ru3 +0x4e74:xue2 +0x4e75:yan3 +0x4e76:fu3 +0x4e77:sha1 +0x4e78:na3 +0x4e79:gan1 +0x4e7e:gan1 +0x4e7f:chi4 +0x4e80:gui1 +0x4e81:gan1 +0x4e82:luan4 +0x4e83:lin2 +0x4e84:yi4 +0x4e85:jue2 +0x4e86:le5 +0x4e88:yu2 +0x4e89:zheng1 +0x4e8a:shi4 +0x4e8b:shi4 +0x4e8c:er4 +0x4e8d:chu4 +0x4e8e:yu2 +0x4e8f:yu2 +0x4e90:yu2 +0x4e91:yun2 +0x4e92:hu4 +0x4e93:qi2 +0x4e94:wu3 +0x4e95:jing3 +0x4e96:si4 +0x4e97:sui4 +0x4e98:gen4 +0x4e99:gen4 +0x4e9a:ya4 +0x4e9b:xie1 +0x4e9c:ya4 +0x4e9d:qi2 +0x4e9e:ya4 +0x4e9f:ji2 +0x4ea0:tou2 +0x4ea1:wang2 +0x4ea2:kang4 +0x4ea3:ta4 +0x4ea4:jiao1 +0x4ea5:hai4 +0x4ea6:yi4 +0x4ea7:chan3 +0x4ea8:heng1 +0x4ea9:mu3 +0x4eab:xiang3 +0x4eac:jing1 +0x4ead:ting2 +0x4eae:liang4 +0x4eaf:xiang3 +0x4eb0:jing1 +0x4eb1:ye4 +0x4eb2:qin1 +0x4eb3:bo2 +0x4eb4:you4 +0x4eb5:xie4 +0x4eb6:dan3 +0x4eb7:lian2 +0x4eb8:duo3 +0x4eb9:wei3 +0x4eba:ren2 +0x4ebb:ren2 +0x4ebc:ji2 +0x4ebe:wang2 +0x4ebf:yi4 +0x4ec0:shi2 +0x4ec1:ren2 +0x4ec2:le4 +0x4ec3:ding1 +0x4ec4:ze4 +0x4ec5:jin3 +0x4ec6:pu1 +0x4ec7:chou2 +0x4ec8:ba1 +0x4ec9:zhang3 +0x4eca:jin1 +0x4ecb:jie4 +0x4ecc:bing1 +0x4ecd:reng2 +0x4ece:cong2 +0x4ecf:fo2 +0x4ed0:san3 +0x4ed1:lun2 +0x4ed3:cang1 +0x4ed4:zi3 +0x4ed5:shi4 +0x4ed6:ta1 +0x4ed7:zhang4 +0x4ed8:fu4 +0x4ed9:xian1 +0x4eda:xian1 +0x4edb:tuo1 +0x4edc:hong2 +0x4edd:tong2 +0x4ede:ren4 +0x4edf:qian1 +0x4ee0:gan2 +0x4ee1:yi4 +0x4ee2:di2 +0x4ee3:dai4 +0x4ee4:ling4 +0x4ee5:yi3 +0x4ee6:chao4 +0x4ee7:chang2 +0x4ee8:sa1 +0x4eea:yi2 +0x4eeb:mu4 +0x4eec:men5 +0x4eed:ren4 +0x4eee:jia3 +0x4eef:chao4 +0x4ef0:yang3 +0x4ef1:qian2 +0x4ef2:zhong4 +0x4ef3:pi3 +0x4ef4:wan4 +0x4ef5:wu3 +0x4ef6:jian4 +0x4ef7:jia4 +0x4ef8:yao3 +0x4ef9:feng1 +0x4efa:cang1 +0x4efb:ren4 +0x4efc:wang2 +0x4efd:fen4 +0x4efe:di1 +0x4eff:fang3 +0x4f00:zhong1 +0x4f01:qi3 +0x4f02:pei4 +0x4f03:yu2 +0x4f04:diao4 +0x4f05:dun4 +0x4f06:wen4 +0x4f07:yi4 +0x4f08:xin3 +0x4f09:kang4 +0x4f0a:yi1 +0x4f0b:ji2 +0x4f0c:ai4 +0x4f0d:wu3 +0x4f0e:ji4 +0x4f0f:fu2 +0x4f10:fa2 +0x4f11:xiu1 +0x4f12:jin4 +0x4f13:bei1 +0x4f14:dan3 +0x4f15:fu1 +0x4f16:tang3 +0x4f17:zhong4 +0x4f18:you1 +0x4f19:huo3 +0x4f1a:hui4 +0x4f1b:yu3 +0x4f1c:cui4 +0x4f1d:chuan2 +0x4f1e:san3 +0x4f1f:wei3 +0x4f20:chuan2 +0x4f21:che1 +0x4f22:ya2 +0x4f23:xian4 +0x4f24:shang1 +0x4f25:chang1 +0x4f26:lun2 +0x4f27:cang1 +0x4f28:xun4 +0x4f29:xin4 +0x4f2a:wei3 +0x4f2b:zhu4 +0x4f2d:xuan2 +0x4f2e:nu2 +0x4f2f:bo2 +0x4f30:gu1 +0x4f31:ni3 +0x4f32:ni3 +0x4f33:xie4 +0x4f34:ban4 +0x4f35:xu4 +0x4f36:ling2 +0x4f37:zhou4 +0x4f38:shen1 +0x4f39:qu1 +0x4f3a:si4 +0x4f3b:beng1 +0x4f3c:si4 +0x4f3d:qie2 +0x4f3e:pi1 +0x4f3f:yi4 +0x4f40:si4 +0x4f41:ai3 +0x4f42:zheng1 +0x4f43:dian4 +0x4f44:han2 +0x4f45:mai4 +0x4f46:dan4 +0x4f47:zhu4 +0x4f48:bu4 +0x4f49:qu1 +0x4f4a:bi3 +0x4f4b:shao4 +0x4f4c:ci3 +0x4f4d:wei4 +0x4f4e:di1 +0x4f4f:zhu4 +0x4f50:zuo3 +0x4f51:you4 +0x4f52:yang1 +0x4f53:ti3 +0x4f54:zhan4 +0x4f55:he2 +0x4f56:bi4 +0x4f57:tuo2 +0x4f58:she2 +0x4f59:yu2 +0x4f5a:yi4 +0x4f5b:fo2 +0x4f5c:zuo4 +0x4f5d:kou4 +0x4f5e:ning4 +0x4f5f:tong2 +0x4f60:ni3 +0x4f61:xuan1 +0x4f62:qu2 +0x4f63:yong4 +0x4f64:wa3 +0x4f65:qian1 +0x4f67:ka3 +0x4f69:pei4 +0x4f6a:hui2 +0x4f6b:he4 +0x4f6c:lao3 +0x4f6d:xiang2 +0x4f6e:ge2 +0x4f6f:yang2 +0x4f70:bai3 +0x4f71:fa3 +0x4f72:ming2 +0x4f73:jia1 +0x4f74:er4 +0x4f75:bing4 +0x4f76:ji2 +0x4f77:hen3 +0x4f78:huo2 +0x4f79:gui3 +0x4f7a:quan2 +0x4f7b:tiao1 +0x4f7c:jiao3 +0x4f7d:ci4 +0x4f7e:yi4 +0x4f7f:shi3 +0x4f80:xing2 +0x4f81:shen1 +0x4f82:tuo1 +0x4f83:kan3 +0x4f84:zhi2 +0x4f85:gai1 +0x4f86:lai2 +0x4f87:yi2 +0x4f88:chi3 +0x4f89:kua1 +0x4f8a:guang1 +0x4f8b:li4 +0x4f8c:yin1 +0x4f8d:shi4 +0x4f8e:mi3 +0x4f8f:zhu1 +0x4f90:xu4 +0x4f91:you4 +0x4f92:an1 +0x4f93:lu4 +0x4f94:mou2 +0x4f95:er2 +0x4f96:lun2 +0x4f97:tong1 +0x4f98:cha4 +0x4f99:chi4 +0x4f9a:xun4 +0x4f9b:gong1 +0x4f9c:zhou1 +0x4f9d:yi1 +0x4f9e:ru3 +0x4f9f:jian4 +0x4fa0:xia2 +0x4fa1:jia4 +0x4fa2:zai4 +0x4fa3:lv3 +0x4fa5:jiao3 +0x4fa6:zhen1 +0x4fa7:ce4 +0x4fa8:qiao2 +0x4fa9:kuai4 +0x4faa:chai2 +0x4fab:ning4 +0x4fac:nong2 +0x4fad:jin3 +0x4fae:wu3 +0x4faf:hou2 +0x4fb0:jiong3 +0x4fb1:cheng3 +0x4fb2:zhen4 +0x4fb3:zuo4 +0x4fb4:chou3 +0x4fb5:qin1 +0x4fb6:lv3 +0x4fb7:ju2 +0x4fb8:shu4 +0x4fb9:ting3 +0x4fba:shen4 +0x4fbb:tuo1 +0x4fbc:bo2 +0x4fbd:nan2 +0x4fbe:hao1 +0x4fbf:bian4 +0x4fc0:tui3 +0x4fc1:yu3 +0x4fc2:xi4 +0x4fc3:cu4 +0x4fc4:e2 +0x4fc5:qiu2 +0x4fc6:xu2 +0x4fc7:kuang3 +0x4fc8:ku4 +0x4fc9:wu4 +0x4fca:jun4 +0x4fcb:yi4 +0x4fcc:fu3 +0x4fcd:lang2 +0x4fce:zu3 +0x4fcf:qiao4 +0x4fd0:li4 +0x4fd1:yong3 +0x4fd2:hun4 +0x4fd3:jing4 +0x4fd4:xian4 +0x4fd5:san4 +0x4fd6:pai3 +0x4fd7:su2 +0x4fd8:fu2 +0x4fd9:xi1 +0x4fda:li3 +0x4fdb:fu3 +0x4fdc:ping1 +0x4fdd:bao3 +0x4fde:yu2 +0x4fdf:si4 +0x4fe0:xia2 +0x4fe1:xin4 +0x4fe2:xiu1 +0x4fe3:yu3 +0x4fe4:ti4 +0x4fe5:che1 +0x4fe6:chou2 +0x4fe8:yan3 +0x4fe9:lia3 +0x4fea:li4 +0x4feb:lai2 +0x4fed:jian3 +0x4fee:xiu1 +0x4fef:fu3 +0x4ff0:he4 +0x4ff1:ju4 +0x4ff2:xiao4 +0x4ff3:pai2 +0x4ff4:jian4 +0x4ff5:biao4 +0x4ff6:chu4 +0x4ff7:fei4 +0x4ff8:feng4 +0x4ff9:ya4 +0x4ffa:an3 +0x4ffb:bei4 +0x4ffc:yu4 +0x4ffd:xin1 +0x4ffe:bi3 +0x4fff:jian4 +0x5000:chang1 +0x5001:chi2 +0x5002:bing4 +0x5003:zan2 +0x5004:yao2 +0x5005:cui4 +0x5006:lia3 +0x5007:wan3 +0x5008:lai2 +0x5009:cang1 +0x500a:zong4 +0x500b:ge4 +0x500c:guan1 +0x500d:bei4 +0x500e:tian1 +0x500f:shu1 +0x5010:shu1 +0x5011:men5 +0x5012:dao3 +0x5013:tan2 +0x5014:jue2 +0x5015:chui2 +0x5016:xing4 +0x5017:peng2 +0x5018:tang3 +0x5019:hou4 +0x501a:yi3 +0x501b:qi1 +0x501c:ti4 +0x501d:gan4 +0x501e:jing4 +0x501f:jie4 +0x5020:sui1 +0x5021:chang4 +0x5022:jie2 +0x5023:fang3 +0x5024:zhi2 +0x5025:kong1 +0x5026:juan4 +0x5027:zong1 +0x5028:ju4 +0x5029:qian4 +0x502a:ni2 +0x502b:lun2 +0x502c:zhuo1 +0x502d:wei1 +0x502e:luo3 +0x502f:song1 +0x5030:leng2 +0x5031:hun4 +0x5032:dong1 +0x5033:zi4 +0x5034:ben4 +0x5035:wu3 +0x5036:ju4 +0x5037:nai4 +0x5038:cai3 +0x5039:jian3 +0x503a:zhai4 +0x503b:ye1 +0x503c:zhi2 +0x503d:sha4 +0x503e:qing1 +0x5040:ying1 +0x5041:cheng1 +0x5042:jian1 +0x5043:yan3 +0x5044:nuan4 +0x5045:zhong4 +0x5046:chun3 +0x5047:jia3 +0x5048:jie2 +0x5049:wei3 +0x504a:yu3 +0x504b:bing3 +0x504c:ruo4 +0x504d:ti2 +0x504e:wei1 +0x504f:pian1 +0x5050:yan4 +0x5051:feng1 +0x5052:tang3 +0x5053:wo4 +0x5054:e4 +0x5055:xie2 +0x5056:che3 +0x5057:sheng3 +0x5058:kan3 +0x5059:di4 +0x505a:zuo4 +0x505b:cha1 +0x505c:ting2 +0x505d:bei4 +0x505e:ye4 +0x505f:huang2 +0x5060:yao3 +0x5061:zhan4 +0x5062:chou3 +0x5063:yan1 +0x5064:you3 +0x5065:jian4 +0x5066:xu1 +0x5067:zha1 +0x5068:ci1 +0x5069:fu4 +0x506a:bi1 +0x506b:zhi4 +0x506c:zong3 +0x506d:mian3 +0x506e:ji2 +0x506f:yi3 +0x5070:xie4 +0x5071:xun2 +0x5072:si1 +0x5073:duan1 +0x5074:ce4 +0x5075:zhen1 +0x5076:ou3 +0x5077:tou1 +0x5078:tou1 +0x5079:bei4 +0x507a:za2 +0x507b:lv3 +0x507c:jie2 +0x507d:wei3 +0x507e:fen4 +0x507f:chang2 +0x5080:gui1 +0x5081:sou3 +0x5082:zhi4 +0x5083:su4 +0x5084:xia1 +0x5085:fu4 +0x5086:yuan4 +0x5087:rong3 +0x5088:li4 +0x5089:ru4 +0x508a:yun3 +0x508b:gou4 +0x508c:ma4 +0x508d:bang4 +0x508e:dian1 +0x508f:tang2 +0x5090:hao4 +0x5091:jie2 +0x5092:xi1 +0x5093:shan4 +0x5094:qian4 +0x5095:jue2 +0x5096:cang1 +0x5097:chu4 +0x5098:san3 +0x5099:bei4 +0x509a:xiao4 +0x509b:yong3 +0x509c:yao2 +0x509d:tan4 +0x509e:suo1 +0x509f:yang3 +0x50a0:fa1 +0x50a1:bing4 +0x50a2:jia1 +0x50a3:dai3 +0x50a4:zai4 +0x50a5:tang3 +0x50a7:bin4 +0x50a8:chu3 +0x50a9:nuo2 +0x50aa:can1 +0x50ab:lei3 +0x50ac:cui1 +0x50ad:yong1 +0x50ae:zao1 +0x50af:zong3 +0x50b0:peng2 +0x50b1:song3 +0x50b2:ao4 +0x50b3:chuan2 +0x50b4:yu3 +0x50b5:zhai4 +0x50b6:cou4 +0x50b7:shang1 +0x50b8:qiang3 +0x50b9:jing4 +0x50ba:chi4 +0x50bb:sha3 +0x50bc:han4 +0x50bd:zhang1 +0x50be:qing1 +0x50bf:yan4 +0x50c0:di4 +0x50c1:xi1 +0x50c2:lv3 +0x50c3:bei4 +0x50c4:piao4 +0x50c5:jin3 +0x50c6:lian2 +0x50c7:lu4 +0x50c8:man4 +0x50c9:qian1 +0x50ca:xian1 +0x50cb:tan4 +0x50cc:ying2 +0x50cd:dong4 +0x50ce:zhuan4 +0x50cf:xiang4 +0x50d0:shan4 +0x50d1:qiao2 +0x50d2:jiong3 +0x50d3:tui3 +0x50d4:zun3 +0x50d5:pu2 +0x50d6:xi1 +0x50d7:lao2 +0x50d8:chang3 +0x50d9:guang1 +0x50da:liao2 +0x50db:qi1 +0x50dc:deng4 +0x50dd:chan2 +0x50de:wei3 +0x50df:ji1 +0x50e0:fan1 +0x50e1:hui4 +0x50e2:chuan3 +0x50e3:jian4 +0x50e4:dan4 +0x50e5:jiao3 +0x50e6:jiu4 +0x50e7:seng1 +0x50e8:fen4 +0x50e9:xian4 +0x50ea:jue2 +0x50eb:e4 +0x50ec:jiao1 +0x50ed:jian4 +0x50ee:tong2 +0x50ef:lin3 +0x50f0:bo2 +0x50f1:gu4 +0x50f3:su4 +0x50f4:xian4 +0x50f5:jiang1 +0x50f6:min3 +0x50f7:ye4 +0x50f8:jin4 +0x50f9:jia4 +0x50fa:qiao4 +0x50fb:pi4 +0x50fc:feng1 +0x50fd:zhou4 +0x50fe:ai4 +0x50ff:sai4 +0x5100:yi2 +0x5101:jun4 +0x5102:nong2 +0x5103:chan2 +0x5104:yi4 +0x5105:dang1 +0x5106:jing3 +0x5107:xuan1 +0x5108:kuai4 +0x5109:jian3 +0x510a:chu4 +0x510b:dan1 +0x510c:jiao3 +0x510d:sha3 +0x510e:zai4 +0x5110:bin4 +0x5111:an4 +0x5112:ru2 +0x5113:tai2 +0x5114:chou2 +0x5115:chai2 +0x5116:lan2 +0x5117:ni3 +0x5118:jin3 +0x5119:qian4 +0x511a:meng2 +0x511b:wu3 +0x511c:ning2 +0x511d:qiong2 +0x511e:ni3 +0x511f:chang2 +0x5120:lie4 +0x5121:lei3 +0x5122:lv3 +0x5123:kuang4 +0x5124:bao4 +0x5125:du2 +0x5126:biao1 +0x5127:zan3 +0x5128:zhi2 +0x5129:si4 +0x512a:you1 +0x512b:hao2 +0x512c:chen4 +0x512d:chen4 +0x512e:li4 +0x512f:teng2 +0x5130:wei3 +0x5131:long3 +0x5132:chu3 +0x5133:chan4 +0x5134:rang2 +0x5135:shu1 +0x5136:hui4 +0x5137:li4 +0x5138:luo2 +0x5139:zan3 +0x513a:nuo2 +0x513b:tang3 +0x513c:yan3 +0x513d:lei3 +0x513e:nang4 +0x513f:er2 +0x5140:wu4 +0x5141:yun3 +0x5142:zan1 +0x5143:yuan2 +0x5144:xiong1 +0x5145:chong1 +0x5146:zhao4 +0x5147:xiong1 +0x5148:xian1 +0x5149:guang1 +0x514a:dui4 +0x514b:ke4 +0x514c:dui4 +0x514d:mian3 +0x514e:tu4 +0x514f:chang2 +0x5150:er2 +0x5151:dui4 +0x5152:er2 +0x5153:xin1 +0x5154:tu4 +0x5155:si4 +0x5156:yan3 +0x5157:yan3 +0x5158:shi3 +0x515a:dang3 +0x515b:qian1 +0x515c:dou1 +0x515d:fen1 +0x515e:mao2 +0x515f:shen1 +0x5160:dou1 +0x5162:jing1 +0x5163:li3 +0x5164:huang2 +0x5165:ru4 +0x5166:wang2 +0x5167:nei4 +0x5168:quan2 +0x5169:liang3 +0x516a:yu2 +0x516b:ba1 +0x516c:gong1 +0x516d:liu4 +0x516e:xi1 +0x5170:lan2 +0x5171:gong4 +0x5172:tian1 +0x5173:guan1 +0x5174:xing1 +0x5175:bing1 +0x5176:qi2 +0x5177:ju4 +0x5178:dian3 +0x5179:zi1 +0x517b:yang3 +0x517c:jian1 +0x517d:shou4 +0x517e:ji4 +0x517f:yi4 +0x5180:ji4 +0x5181:chan3 +0x5182:jiong1 +0x5184:ran3 +0x5185:nei4 +0x5187:mao3 +0x5188:gang1 +0x5189:ran3 +0x518a:ce4 +0x518b:jiong1 +0x518c:ce4 +0x518d:zai4 +0x518e:gua3 +0x518f:jiong3 +0x5190:mao4 +0x5191:zhou4 +0x5192:mao4 +0x5193:gou4 +0x5194:xu3 +0x5195:mian3 +0x5196:mi4 +0x5197:rong3 +0x5198:yin2 +0x5199:xie3 +0x519a:kan3 +0x519b:jun1 +0x519c:nong2 +0x519d:yi2 +0x519e:mi2 +0x519f:shi4 +0x51a0:guan1 +0x51a1:meng2 +0x51a2:zhong3 +0x51a3:ju4 +0x51a4:yuan1 +0x51a5:ming2 +0x51a6:kou4 +0x51a8:fu4 +0x51a9:xie3 +0x51aa:mi4 +0x51ab:bing1 +0x51ac:dong1 +0x51ad:tai2 +0x51ae:gang1 +0x51af:feng2 +0x51b0:bing1 +0x51b1:hu4 +0x51b2:chong1 +0x51b3:jue2 +0x51b4:hu4 +0x51b5:kuang4 +0x51b6:ye3 +0x51b7:leng3 +0x51b8:pan4 +0x51b9:fu2 +0x51ba:min3 +0x51bb:dong4 +0x51bc:xian3 +0x51bd:lie4 +0x51be:xia2 +0x51bf:jian1 +0x51c0:jing4 +0x51c1:shu4 +0x51c2:mei3 +0x51c3:tu2 +0x51c4:qi1 +0x51c5:gu4 +0x51c6:zhun3 +0x51c7:song1 +0x51c8:jing4 +0x51c9:liang2 +0x51ca:qing4 +0x51cb:diao1 +0x51cc:ling2 +0x51cd:dong4 +0x51ce:gan4 +0x51cf:jian3 +0x51d0:yin1 +0x51d1:cou4 +0x51d2:yi2 +0x51d3:li4 +0x51d4:cang1 +0x51d5:ming3 +0x51d7:cui2 +0x51d8:si1 +0x51d9:duo2 +0x51da:jin4 +0x51db:lin3 +0x51dc:lin3 +0x51dd:ning2 +0x51de:xi1 +0x51df:du2 +0x51e0:ji1 +0x51e1:fan2 +0x51e2:fan2 +0x51e3:fan2 +0x51e4:feng4 +0x51e5:ju1 +0x51e6:chu3 +0x51e8:feng1 +0x51eb:fu2 +0x51ec:feng1 +0x51ed:ping2 +0x51ee:feng1 +0x51ef:kai3 +0x51f0:huang2 +0x51f1:kai3 +0x51f2:gan1 +0x51f3:deng4 +0x51f4:ping2 +0x51f5:qu1 +0x51f6:xiong1 +0x51f7:kuai4 +0x51f8:tu1 +0x51f9:ao1 +0x51fa:chu1 +0x51fb:ji2 +0x51fc:dang4 +0x51fd:han2 +0x51fe:han2 +0x51ff:zao2 +0x5200:dao1 +0x5201:diao1 +0x5202:dao1 +0x5203:ren4 +0x5204:ren4 +0x5205:chuang1 +0x5206:fen1 +0x5207:qie1 +0x5208:yi4 +0x5209:ji1 +0x520a:kan1 +0x520b:qian4 +0x520c:cun3 +0x520d:chu2 +0x520e:wen3 +0x520f:ji1 +0x5210:dan3 +0x5211:xing2 +0x5212:hua2 +0x5213:wan2 +0x5214:jue2 +0x5215:li2 +0x5216:yue4 +0x5217:lie4 +0x5218:liu2 +0x5219:ze2 +0x521a:gang1 +0x521b:chuang4 +0x521c:fu2 +0x521d:chu1 +0x521e:qu4 +0x521f:ju1 +0x5220:shan1 +0x5221:min3 +0x5222:ling2 +0x5223:zhong1 +0x5224:pan4 +0x5225:bie2 +0x5226:jie2 +0x5227:jie2 +0x5228:bao4 +0x5229:li4 +0x522a:shan1 +0x522b:bie2 +0x522c:chan3 +0x522d:jing3 +0x522e:gua1 +0x522f:gen1 +0x5230:dao4 +0x5231:chuang4 +0x5232:kui1 +0x5233:ku1 +0x5234:duo4 +0x5235:er4 +0x5236:zhi4 +0x5237:shua1 +0x5238:quan4 +0x5239:cha4 +0x523a:ci4 +0x523b:ke4 +0x523c:jie2 +0x523d:gui4 +0x523e:ci4 +0x523f:gui4 +0x5240:kai3 +0x5241:duo4 +0x5242:ji4 +0x5243:ti4 +0x5244:jing3 +0x5245:lou2 +0x5246:gen1 +0x5247:ze2 +0x5248:yuan1 +0x5249:cuo4 +0x524a:xue1 +0x524b:ke4 +0x524c:la4 +0x524d:qian2 +0x524e:cha4 +0x524f:chuang4 +0x5250:gua3 +0x5251:jian4 +0x5252:cuo4 +0x5253:li2 +0x5254:ti1 +0x5255:fei4 +0x5256:pou1 +0x5257:chan3 +0x5258:qi2 +0x5259:chuang4 +0x525a:zi4 +0x525b:gang1 +0x525c:wan1 +0x525d:bo1 +0x525e:ji1 +0x525f:duo1 +0x5260:qing2 +0x5261:yan3 +0x5262:zhuo2 +0x5263:jian4 +0x5264:ji4 +0x5265:bo1 +0x5266:yan1 +0x5267:ju4 +0x5268:huo4 +0x5269:sheng4 +0x526a:jian3 +0x526b:duo2 +0x526c:duan1 +0x526d:wu1 +0x526e:gua3 +0x526f:fu4 +0x5270:sheng4 +0x5271:jian4 +0x5272:ge1 +0x5273:zha1 +0x5274:kai3 +0x5275:chuang4 +0x5276:juan1 +0x5277:chan3 +0x5278:tuan2 +0x5279:lu4 +0x527a:li2 +0x527b:fou2 +0x527c:shan1 +0x527d:piao4 +0x527e:kou1 +0x527f:jiao3 +0x5280:gua1 +0x5281:qiao1 +0x5282:jue2 +0x5283:hua4 +0x5284:zha2 +0x5285:zhuo4 +0x5286:lian2 +0x5287:ju4 +0x5288:pi1 +0x5289:liu2 +0x528a:gui4 +0x528b:jiao3 +0x528c:gui4 +0x528d:jian4 +0x528e:jian4 +0x528f:tang1 +0x5290:huo1 +0x5291:ji4 +0x5292:jian4 +0x5293:yi4 +0x5294:jian4 +0x5295:zhi2 +0x5296:chan2 +0x5297:cuan2 +0x5298:mo2 +0x5299:li2 +0x529a:zhu2 +0x529b:li4 +0x529c:ya1 +0x529d:quan4 +0x529e:ban4 +0x529f:gong1 +0x52a0:jia1 +0x52a1:wu4 +0x52a2:mai4 +0x52a3:lie4 +0x52a4:jin4 +0x52a5:keng1 +0x52a6:xie2 +0x52a7:zhi3 +0x52a8:dong4 +0x52a9:zhu4 +0x52aa:nu3 +0x52ab:jie2 +0x52ac:qu2 +0x52ad:shao4 +0x52ae:yi4 +0x52af:zhu1 +0x52b0:miao3 +0x52b1:li4 +0x52b2:jing4 +0x52b3:lao2 +0x52b4:lao2 +0x52b5:juan4 +0x52b6:kou3 +0x52b7:yang2 +0x52b8:wa1 +0x52b9:xiao4 +0x52ba:mou2 +0x52bb:kuang1 +0x52bc:jie2 +0x52bd:lie4 +0x52be:he2 +0x52bf:shi4 +0x52c0:ke4 +0x52c1:jin4 +0x52c2:hao2 +0x52c3:bo2 +0x52c4:min3 +0x52c5:chi4 +0x52c6:lang2 +0x52c7:yong3 +0x52c8:yong3 +0x52c9:mian3 +0x52ca:ke4 +0x52cb:xun1 +0x52cc:juan4 +0x52cd:qing2 +0x52ce:lu4 +0x52cf:pou3 +0x52d0:meng3 +0x52d1:lai4 +0x52d2:le4 +0x52d3:kai4 +0x52d4:mian3 +0x52d5:dong4 +0x52d6:xu4 +0x52d7:xu4 +0x52d8:kan1 +0x52d9:wu4 +0x52da:yi4 +0x52db:xun1 +0x52dc:weng3 +0x52dd:sheng4 +0x52de:lao2 +0x52df:mu4 +0x52e0:lu4 +0x52e1:piao4 +0x52e2:shi4 +0x52e3:ji1 +0x52e4:qin2 +0x52e5:qiang3 +0x52e6:jiao3 +0x52e7:quan4 +0x52e8:yang3 +0x52e9:yi4 +0x52ea:jue2 +0x52eb:fan2 +0x52ec:juan4 +0x52ed:tong2 +0x52ee:ju4 +0x52ef:dan1 +0x52f0:xie2 +0x52f1:mai4 +0x52f2:xun1 +0x52f3:xun1 +0x52f4:lv4 +0x52f5:li4 +0x52f6:che4 +0x52f7:rang2 +0x52f8:quan4 +0x52f9:bao1 +0x52fa:shao2 +0x52fb:yun2 +0x52fc:jiu1 +0x52fd:bao4 +0x52fe:gou1 +0x52ff:wu4 +0x5300:yun2 +0x5303:gai4 +0x5304:gai4 +0x5305:bao1 +0x5306:cong1 +0x5308:xiong1 +0x5309:peng1 +0x530a:ju2 +0x530b:tao2 +0x530c:ge2 +0x530d:pu2 +0x530e:an4 +0x530f:pao2 +0x5310:fu2 +0x5311:gong1 +0x5312:da2 +0x5313:jiu4 +0x5314:qiong1 +0x5315:bi3 +0x5316:hua4 +0x5317:bei3 +0x5318:nao3 +0x5319:chi2 +0x531a:fang1 +0x531b:jiu4 +0x531c:yi2 +0x531d:za1 +0x531e:jiang4 +0x531f:kang4 +0x5320:jiang4 +0x5321:kuang1 +0x5322:hu1 +0x5323:xia2 +0x5324:qu1 +0x5325:bian4 +0x5326:gui3 +0x5327:qie4 +0x5328:zang1 +0x5329:kuang1 +0x532a:fei3 +0x532b:hu1 +0x532c:tou2 +0x532d:gui3 +0x532e:gui4 +0x532f:hui4 +0x5330:dan1 +0x5331:gui4 +0x5332:lian2 +0x5333:lian2 +0x5334:suan3 +0x5335:du2 +0x5336:jiu4 +0x5337:qu2 +0x5338:xi3 +0x5339:pi3 +0x533a:qu1 +0x533b:yi4 +0x533c:qia4 +0x533d:yan3 +0x533e:bian3 +0x533f:ni4 +0x5340:qu1 +0x5341:shi2 +0x5342:xin4 +0x5343:qian1 +0x5344:nian4 +0x5345:sa4 +0x5346:zu2 +0x5347:sheng1 +0x5348:wu3 +0x5349:hui4 +0x534a:ban4 +0x534b:shi4 +0x534c:xi4 +0x534d:wan4 +0x534e:hua2 +0x534f:xie2 +0x5350:wan4 +0x5351:bei1 +0x5352:zu2 +0x5353:zhuo1 +0x5354:xie2 +0x5355:dan1 +0x5356:mai4 +0x5357:nan2 +0x5358:dan1 +0x5359:ji2 +0x535a:bo2 +0x535b:shuai4 +0x535c:bu3 +0x535d:kuang4 +0x535e:bian4 +0x535f:bu3 +0x5360:zhan1 +0x5361:qia3 +0x5362:lu2 +0x5363:you3 +0x5364:lu3 +0x5365:xi1 +0x5366:gua4 +0x5367:wo4 +0x5368:xie4 +0x5369:jie2 +0x536a:jie2 +0x536b:wei4 +0x536c:ang2 +0x536d:qiong2 +0x536e:zhi1 +0x536f:mao3 +0x5370:yin4 +0x5371:wei1 +0x5372:shao4 +0x5373:ji2 +0x5374:que4 +0x5375:luan3 +0x5376:shi4 +0x5377:juan4 +0x5378:xie4 +0x5379:xu4 +0x537a:jin3 +0x537b:que4 +0x537c:wu4 +0x537d:ji2 +0x537e:e4 +0x537f:qing1 +0x5380:xi1 +0x5382:chang3 +0x5383:zhan1 +0x5384:e4 +0x5385:ting1 +0x5386:li4 +0x5387:zhe2 +0x5388:han3 +0x5389:li4 +0x538a:ya3 +0x538b:ya1 +0x538c:yan4 +0x538d:she4 +0x538e:zhi3 +0x538f:zha3 +0x5390:pang2 +0x5392:he2 +0x5393:ya2 +0x5394:zhi4 +0x5395:ce4 +0x5396:pang2 +0x5397:ti2 +0x5398:li2 +0x5399:she4 +0x539a:hou4 +0x539b:ting1 +0x539c:zui1 +0x539d:cuo4 +0x539e:fei4 +0x539f:yuan2 +0x53a0:ce4 +0x53a1:yuan2 +0x53a2:xiang1 +0x53a3:yan3 +0x53a4:li4 +0x53a5:jue2 +0x53a6:sha4 +0x53a7:dian1 +0x53a8:chu2 +0x53a9:jiu4 +0x53aa:qin2 +0x53ab:ao2 +0x53ac:gui3 +0x53ad:yan4 +0x53ae:si1 +0x53af:li4 +0x53b0:chang3 +0x53b1:lan2 +0x53b2:li4 +0x53b3:yan2 +0x53b4:yan3 +0x53b5:yuan2 +0x53b6:si1 +0x53b7:gong1 +0x53b8:lin2 +0x53b9:qiu2 +0x53ba:qu4 +0x53bb:qu4 +0x53bd:lei3 +0x53be:du1 +0x53bf:xian4 +0x53c0:zhuan1 +0x53c1:san1 +0x53c2:can1 +0x53c3:can1 +0x53c4:can1 +0x53c5:can1 +0x53c6:ai4 +0x53c7:dai4 +0x53c8:you4 +0x53c9:cha1 +0x53ca:ji2 +0x53cb:you3 +0x53cc:shuang1 +0x53cd:fan3 +0x53ce:shou1 +0x53cf:guai4 +0x53d0:ba2 +0x53d1:fa1 +0x53d2:ruo4 +0x53d3:shi4 +0x53d4:shu1 +0x53d5:zhuo2 +0x53d6:qu3 +0x53d7:shou4 +0x53d8:bian4 +0x53d9:xu4 +0x53da:jia3 +0x53db:pan4 +0x53dc:sou3 +0x53dd:gao4 +0x53de:wei4 +0x53df:sou3 +0x53e0:die2 +0x53e1:rui4 +0x53e2:cong2 +0x53e3:kou3 +0x53e4:gu3 +0x53e5:ju4 +0x53e6:ling4 +0x53e7:gua3 +0x53e8:tao1 +0x53e9:kou4 +0x53ea:zhi3 +0x53eb:jiao4 +0x53ec:zhao4 +0x53ed:ba1 +0x53ee:ding1 +0x53ef:ke3 +0x53f0:tai2 +0x53f1:chi4 +0x53f2:shi3 +0x53f3:you4 +0x53f4:qiu2 +0x53f5:po3 +0x53f6:ye4 +0x53f7:hao4 +0x53f8:si1 +0x53f9:tan4 +0x53fa:chi3 +0x53fb:le4 +0x53fc:diao1 +0x53fd:ji1 +0x53ff:hong1 +0x5400:mie1 +0x5401:xu1 +0x5402:mang2 +0x5403:chi1 +0x5404:ge4 +0x5405:xuan1 +0x5406:yao1 +0x5407:zi3 +0x5408:he2 +0x5409:ji2 +0x540a:diao4 +0x540b:cun4 +0x540c:tong2 +0x540d:ming2 +0x540e:hou4 +0x540f:li4 +0x5410:tu3 +0x5411:xiang4 +0x5412:zha4 +0x5413:xia4 +0x5414:ye3 +0x5415:lv3 +0x5416:a1 +0x5417:ma5 +0x5418:ou3 +0x5419:xue1 +0x541a:yi1 +0x541b:jun1 +0x541c:chou3 +0x541d:lin4 +0x541e:tun1 +0x541f:yin2 +0x5420:fei4 +0x5421:bi3 +0x5422:qin4 +0x5423:qin4 +0x5424:jie4 +0x5425:bu4 +0x5426:fou3 +0x5427:ba5 +0x5428:dun1 +0x5429:fen1 +0x542a:e2 +0x542b:han2 +0x542c:ting1 +0x542d:hang2 +0x542e:shun3 +0x542f:qi3 +0x5430:hong2 +0x5431:zhi1 +0x5432:shen3 +0x5433:wu2 +0x5434:wu2 +0x5435:chao3 +0x5436:ne5 +0x5437:xue4 +0x5438:xi1 +0x5439:chui1 +0x543a:dou1 +0x543b:wen3 +0x543c:hou3 +0x543d:ou1 +0x543e:wu2 +0x543f:gao4 +0x5440:ya1 +0x5441:jun4 +0x5442:lv3 +0x5443:e4 +0x5444:ge2 +0x5445:mei2 +0x5446:dai1 +0x5447:qi3 +0x5448:cheng2 +0x5449:wu2 +0x544a:gao4 +0x544b:fu1 +0x544c:jiao4 +0x544d:hong1 +0x544e:chi3 +0x544f:sheng1 +0x5450:ne4 +0x5451:tun1 +0x5452:fu3 +0x5453:yi4 +0x5454:dai1 +0x5455:ou1 +0x5456:li4 +0x5457:bai4 +0x5458:yuan2 +0x5459:kuai1 +0x545b:qiang1 +0x545c:wu1 +0x545d:e4 +0x545e:shi1 +0x545f:quan3 +0x5460:pen1 +0x5461:wen3 +0x5462:ni2 +0x5464:ling2 +0x5465:ran3 +0x5466:you1 +0x5467:di3 +0x5468:zhou1 +0x5469:shi4 +0x546a:zhou4 +0x546b:tie1 +0x546c:xi4 +0x546d:yi4 +0x546e:qi4 +0x546f:ping2 +0x5470:zi3 +0x5471:gu1 +0x5472:zi1 +0x5473:wei4 +0x5474:xu1 +0x5475:he1 +0x5476:nao2 +0x5477:xia1 +0x5478:pei1 +0x5479:yi4 +0x547a:xiao1 +0x547b:shen1 +0x547c:hu1 +0x547d:ming4 +0x547e:da2 +0x547f:qu1 +0x5480:ju3 +0x5482:za1 +0x5483:tuo1 +0x5484:duo1 +0x5485:pou4 +0x5486:pao2 +0x5487:bi4 +0x5488:fu2 +0x5489:yang1 +0x548a:he2 +0x548b:zha4 +0x548c:he2 +0x548d:hai1 +0x548e:jiu4 +0x548f:yong3 +0x5490:fu4 +0x5491:que4 +0x5492:zhou4 +0x5493:wa3 +0x5494:ka3 +0x5495:gu1 +0x5496:ka1 +0x5497:zuo3 +0x5498:bu4 +0x5499:long2 +0x549a:dong1 +0x549b:ning2 +0x549d:si1 +0x549e:xian4 +0x549f:huo4 +0x54a0:qi4 +0x54a1:er4 +0x54a2:e4 +0x54a3:guang1 +0x54a4:zha4 +0x54a5:xi4 +0x54a6:yi2 +0x54a7:lie3 +0x54a8:zi1 +0x54a9:mie1 +0x54aa:mi1 +0x54ab:zhi3 +0x54ac:yao3 +0x54ad:ji1 +0x54ae:zhou4 +0x54af:ge1 +0x54b0:shuai4 +0x54b1:zan2 +0x54b2:xiao4 +0x54b3:ke2 +0x54b4:hui1 +0x54b5:kua1 +0x54b6:huai4 +0x54b7:tao2 +0x54b8:xian2 +0x54b9:e4 +0x54ba:xuan3 +0x54bb:xiu1 +0x54bc:wai1 +0x54bd:yan1 +0x54be:lao3 +0x54bf:yi1 +0x54c0:ai1 +0x54c1:pin3 +0x54c2:shen3 +0x54c3:tong2 +0x54c4:hong1 +0x54c5:xiong1 +0x54c6:duo1 +0x54c7:wa1 +0x54c8:ha1 +0x54c9:zai1 +0x54ca:yu4 +0x54cb:di4 +0x54cc:pai4 +0x54cd:xiang3 +0x54ce:ai1 +0x54cf:hen3 +0x54d0:kuang1 +0x54d1:ya3 +0x54d2:da1 +0x54d3:xiao1 +0x54d4:bi4 +0x54d5:yue3 +0x54d7:hua1 +0x54d9:kuai4 +0x54da:duo3 +0x54dc:ji4 +0x54dd:nong2 +0x54de:mou1 +0x54df:yo5 +0x54e0:hao4 +0x54e1:yuan2 +0x54e2:long4 +0x54e3:pou3 +0x54e4:mang2 +0x54e5:ge1 +0x54e6:e2 +0x54e7:chi1 +0x54e8:shao4 +0x54e9:li1 +0x54ea:na3 +0x54eb:zu2 +0x54ec:he2 +0x54ed:ku1 +0x54ee:xiao1 +0x54ef:xian4 +0x54f0:lao2 +0x54f1:bo1 +0x54f2:zhe2 +0x54f3:zha1 +0x54f4:liang4 +0x54f5:ba1 +0x54f6:mie1 +0x54f7:le4 +0x54f8:sui1 +0x54f9:fou2 +0x54fa:bu3 +0x54fb:han4 +0x54fc:heng1 +0x54fd:geng3 +0x54fe:shuo1 +0x54ff:ge3 +0x5500:you3 +0x5501:yan4 +0x5502:gu3 +0x5503:gu3 +0x5504:bai4 +0x5505:han1 +0x5506:suo1 +0x5507:chun2 +0x5508:yi4 +0x5509:ai1 +0x550a:jia2 +0x550b:tu3 +0x550c:xian2 +0x550d:huan3 +0x550e:li4 +0x550f:xi1 +0x5510:tang2 +0x5511:zuo4 +0x5512:qiu2 +0x5513:che1 +0x5514:wu2 +0x5515:zao4 +0x5516:ya3 +0x5517:dou1 +0x5518:qi3 +0x5519:di2 +0x551a:qin4 +0x551b:ma4 +0x551d:hong3 +0x551e:dou3 +0x5520:lao2 +0x5521:liang3 +0x5522:suo3 +0x5523:zao4 +0x5524:huan4 +0x5526:sha1 +0x5527:ji1 +0x5528:zuo3 +0x5529:wo1 +0x552a:feng3 +0x552b:yin2 +0x552c:hu3 +0x552d:qi1 +0x552e:shou4 +0x552f:wei2 +0x5530:shua1 +0x5531:chang4 +0x5532:er2 +0x5533:li4 +0x5534:qiang4 +0x5535:an3 +0x5536:jie4 +0x5537:yo1 +0x5538:nian4 +0x5539:yu1 +0x553a:tian3 +0x553b:lai3 +0x553c:sha4 +0x553d:xi1 +0x553e:tuo4 +0x553f:hu1 +0x5540:ai2 +0x5541:zhou1 +0x5542:nou4 +0x5543:ken3 +0x5544:zhuo2 +0x5545:zhuo2 +0x5546:shang1 +0x5547:di2 +0x5548:heng4 +0x5549:lan2 +0x554a:a5 +0x554b:xiao1 +0x554c:xiang1 +0x554d:tun1 +0x554e:wu3 +0x554f:wen4 +0x5550:cui4 +0x5551:sha4 +0x5552:hu1 +0x5553:qi3 +0x5554:qi3 +0x5555:tao2 +0x5556:dan4 +0x5557:dan4 +0x5558:ye4 +0x5559:zi3 +0x555a:bi3 +0x555b:cui4 +0x555c:chuo4 +0x555d:he2 +0x555e:ya3 +0x555f:qi3 +0x5560:zhe2 +0x5561:fei1 +0x5562:liang3 +0x5563:xian2 +0x5564:pi2 +0x5565:sha4 +0x5566:la5 +0x5567:ze2 +0x5568:qing1 +0x5569:gua4 +0x556a:pa1 +0x556b:zhe3 +0x556c:se4 +0x556d:zhuan4 +0x556e:nie4 +0x556f:guo5 +0x5570:luo1 +0x5571:yan1 +0x5572:di4 +0x5573:quan2 +0x5574:tan1 +0x5575:bo5 +0x5576:ding4 +0x5577:lang1 +0x5578:xiao4 +0x557a:tang2 +0x557b:chi4 +0x557c:ti2 +0x557d:an2 +0x557e:jiu1 +0x557f:dan4 +0x5580:ka1 +0x5581:yong2 +0x5582:wei4 +0x5583:nan2 +0x5584:shan4 +0x5585:yu4 +0x5586:zhe2 +0x5587:la3 +0x5588:jie1 +0x5589:hou2 +0x558a:han3 +0x558b:die2 +0x558c:zhou1 +0x558d:chai2 +0x558e:wai1 +0x558f:re3 +0x5590:yu4 +0x5591:yin1 +0x5592:zan2 +0x5593:yao1 +0x5594:o1 +0x5595:mian3 +0x5596:hu2 +0x5597:yun3 +0x5598:chuan3 +0x5599:hui4 +0x559a:huan4 +0x559b:huan4 +0x559c:xi3 +0x559d:he1 +0x559e:ji1 +0x559f:kui4 +0x55a0:zhong3 +0x55a1:wei3 +0x55a2:sha4 +0x55a3:xu3 +0x55a4:huang2 +0x55a5:du4 +0x55a6:nie4 +0x55a7:xuan1 +0x55a8:liang4 +0x55a9:yu4 +0x55aa:sang1 +0x55ab:chi1 +0x55ac:qiao2 +0x55ad:yan4 +0x55ae:dan1 +0x55af:pen1 +0x55b0:can1 +0x55b1:li2 +0x55b2:yo5 +0x55b3:zha1 +0x55b4:wei1 +0x55b5:miao1 +0x55b6:ying2 +0x55b7:pen1 +0x55b9:kui2 +0x55ba:xi4 +0x55bb:yu4 +0x55bc:jie2 +0x55bd:lou5 +0x55be:ku4 +0x55bf:sao4 +0x55c0:huo4 +0x55c1:ti2 +0x55c2:yao2 +0x55c3:he4 +0x55c4:a2 +0x55c5:xiu4 +0x55c6:qiang1 +0x55c7:se4 +0x55c8:yong1 +0x55c9:su4 +0x55ca:hong3 +0x55cb:xie2 +0x55cc:yi4 +0x55cd:suo1 +0x55ce:ma5 +0x55cf:cha1 +0x55d0:hai4 +0x55d1:ke4 +0x55d2:ta4 +0x55d3:sang3 +0x55d4:tian2 +0x55d5:ru4 +0x55d6:sou1 +0x55d7:wa1 +0x55d8:ji1 +0x55d9:pang3 +0x55da:wu1 +0x55db:xian2 +0x55dc:shi4 +0x55dd:ge2 +0x55de:zi1 +0x55df:jie1 +0x55e0:luo4 +0x55e1:weng1 +0x55e2:wa4 +0x55e3:si4 +0x55e4:chi1 +0x55e5:hao2 +0x55e6:suo1 +0x55e8:hai1 +0x55e9:suo3 +0x55ea:qin2 +0x55eb:nie4 +0x55ec:he1 +0x55ee:sai4 +0x55f0:ge4 +0x55f1:na2 +0x55f2:dia3 +0x55f3:ai4 +0x55f5:tong1 +0x55f6:bi4 +0x55f7:ao2 +0x55f8:ao2 +0x55f9:lian2 +0x55fa:cui1 +0x55fb:zhe1 +0x55fc:mo4 +0x55fd:sou4 +0x55fe:sou3 +0x55ff:tan3 +0x5600:di2 +0x5601:qi1 +0x5602:jiao4 +0x5603:chong1 +0x5604:jiao1 +0x5605:kai3 +0x5606:tan4 +0x5607:san1 +0x5608:cao2 +0x5609:jia1 +0x560a:ai2 +0x560b:xiao1 +0x560c:piao1 +0x560d:lou5 +0x560e:ga1 +0x560f:gu3 +0x5610:xiao1 +0x5611:hu1 +0x5612:hui4 +0x5613:guo1 +0x5614:ou1 +0x5615:xian1 +0x5616:ze2 +0x5617:chang2 +0x5618:xu1 +0x5619:po2 +0x561a:de2 +0x561b:ma5 +0x561c:ma4 +0x561d:hu2 +0x561e:lei5 +0x561f:du1 +0x5620:ga1 +0x5621:tang1 +0x5622:ye3 +0x5623:beng1 +0x5624:ying1 +0x5626:jiao4 +0x5627:mi4 +0x5628:xiao4 +0x5629:hua1 +0x562a:mai3 +0x562b:ran2 +0x562c:zuo1 +0x562d:peng1 +0x562e:lao2 +0x562f:xiao4 +0x5630:ji1 +0x5631:zhu3 +0x5632:chao2 +0x5633:kui4 +0x5634:zui3 +0x5635:xiao1 +0x5636:si1 +0x5637:hao2 +0x5638:fu3 +0x5639:liao2 +0x563a:qiao2 +0x563b:xi1 +0x563c:xiu4 +0x563d:tan1 +0x563e:tan2 +0x563f:hei1 +0x5640:xun4 +0x5641:e3 +0x5642:zun3 +0x5643:fan1 +0x5644:chi1 +0x5645:hui1 +0x5646:zan3 +0x5647:chuang2 +0x5648:cu4 +0x5649:dan4 +0x564a:yu4 +0x564b:tun1 +0x564c:cheng1 +0x564d:jiao4 +0x564e:ye1 +0x564f:xi1 +0x5650:qi4 +0x5651:hao2 +0x5652:lian2 +0x5653:xu1 +0x5654:deng1 +0x5655:hui1 +0x5656:yin2 +0x5657:pu1 +0x5658:jue1 +0x5659:qin2 +0x565a:xun2 +0x565b:nie4 +0x565c:lu1 +0x565d:si1 +0x565e:yan3 +0x565f:ying4 +0x5660:da1 +0x5661:dan1 +0x5662:o1 +0x5663:zhou4 +0x5664:jin4 +0x5665:nong2 +0x5666:yue3 +0x5667:hui4 +0x5668:qi4 +0x5669:e4 +0x566a:zao4 +0x566b:yi1 +0x566c:shi4 +0x566d:jiao4 +0x566e:yuan1 +0x566f:ai3 +0x5670:yong1 +0x5671:jue2 +0x5672:kuai4 +0x5673:yu3 +0x5674:pen1 +0x5675:dao4 +0x5676:ge2 +0x5677:xin1 +0x5678:dun1 +0x5679:dang1 +0x567b:sai5 +0x567c:pi1 +0x567d:pi3 +0x567e:yin1 +0x567f:zui3 +0x5680:ning2 +0x5681:di2 +0x5682:lan4 +0x5683:ta4 +0x5684:huo4 +0x5685:ru2 +0x5686:hao1 +0x5687:xia4 +0x5688:ya4 +0x5689:duo1 +0x568a:xi4 +0x568b:chou2 +0x568c:ji4 +0x568d:jin4 +0x568e:hao2 +0x568f:ti4 +0x5690:chang2 +0x5693:ca1 +0x5694:ti4 +0x5695:lu1 +0x5696:hui4 +0x5697:bo2 +0x5698:you1 +0x5699:nie4 +0x569a:yin2 +0x569b:hu4 +0x569c:mo4 +0x569d:huang1 +0x569e:zhe2 +0x569f:li2 +0x56a0:liu2 +0x56a2:nang2 +0x56a3:xiao1 +0x56a4:mo2 +0x56a5:yan4 +0x56a6:li4 +0x56a7:lu2 +0x56a8:long2 +0x56a9:fu2 +0x56aa:dan4 +0x56ab:chen4 +0x56ac:pin2 +0x56ad:pi3 +0x56ae:xiang4 +0x56af:huo4 +0x56b0:mo2 +0x56b1:xi4 +0x56b2:duo3 +0x56b3:ku4 +0x56b4:yan2 +0x56b5:chan2 +0x56b6:ying1 +0x56b7:rang3 +0x56b8:dian3 +0x56b9:la1 +0x56ba:ta4 +0x56bb:xiao1 +0x56bc:jiao2 +0x56bd:chuo4 +0x56be:huan1 +0x56bf:huo4 +0x56c0:zhuan4 +0x56c1:nie4 +0x56c2:xiao1 +0x56c3:ca4 +0x56c4:li2 +0x56c5:chan3 +0x56c6:chai4 +0x56c7:li4 +0x56c8:yi4 +0x56c9:luo1 +0x56ca:nang2 +0x56cb:zan4 +0x56cc:su1 +0x56cd:xi3 +0x56cf:jian1 +0x56d0:za2 +0x56d1:zhu3 +0x56d2:lan2 +0x56d3:nie4 +0x56d4:nang1 +0x56d7:wei2 +0x56d8:hui2 +0x56d9:yin1 +0x56da:qiu2 +0x56db:si4 +0x56dc:nin2 +0x56dd:jian3 +0x56de:hui2 +0x56df:xin4 +0x56e0:yin1 +0x56e1:nan1 +0x56e2:tuan2 +0x56e3:tuan2 +0x56e4:dun4 +0x56e5:kang4 +0x56e6:yuan1 +0x56e7:jiong3 +0x56e8:pian1 +0x56e9:yun4 +0x56ea:cong1 +0x56eb:hu2 +0x56ec:hui2 +0x56ed:yuan2 +0x56ee:e2 +0x56ef:guo2 +0x56f0:kun4 +0x56f1:cong1 +0x56f2:wei2 +0x56f3:tu2 +0x56f4:wei2 +0x56f5:lun2 +0x56f6:guo2 +0x56f7:qun1 +0x56f8:ri4 +0x56f9:ling2 +0x56fa:gu4 +0x56fb:guo2 +0x56fc:tai1 +0x56fd:guo2 +0x56fe:tu2 +0x56ff:you4 +0x5700:guo2 +0x5701:yin2 +0x5702:hun4 +0x5703:pu3 +0x5704:yu3 +0x5705:han2 +0x5706:yuan2 +0x5707:lun2 +0x5708:quan1 +0x5709:yu3 +0x570a:qing1 +0x570b:guo2 +0x570c:chuan2 +0x570d:wei2 +0x570e:yuan2 +0x570f:quan1 +0x5710:ku1 +0x5711:fu4 +0x5712:yuan2 +0x5713:yuan2 +0x5714:e4 +0x5716:tu2 +0x5717:tu2 +0x5718:tuan2 +0x5719:lve4 +0x571a:hui4 +0x571b:yi4 +0x571c:yuan2 +0x571d:luan2 +0x571e:luan2 +0x571f:tu3 +0x5720:ya4 +0x5721:tu3 +0x5722:ting1 +0x5723:sheng4 +0x5724:pu3 +0x5725:lu4 +0x5727:ya1 +0x5728:zai4 +0x5729:wei2 +0x572a:ge1 +0x572b:yu4 +0x572c:wu1 +0x572d:gui1 +0x572e:pi3 +0x572f:yi2 +0x5730:di4 +0x5731:qian1 +0x5732:qian1 +0x5733:zhen4 +0x5734:zhuo2 +0x5735:dang4 +0x5736:qia4 +0x5739:kuang4 +0x573a:chang2 +0x573b:qi2 +0x573c:nie4 +0x573d:mo4 +0x573e:ji2 +0x573f:jia2 +0x5740:zhi3 +0x5741:zhi3 +0x5742:ban3 +0x5743:xun1 +0x5744:tou2 +0x5745:qin3 +0x5746:fen2 +0x5747:jun1 +0x5748:keng1 +0x5749:tun2 +0x574a:fang1 +0x574b:fen4 +0x574c:ben4 +0x574d:tan1 +0x574e:kan3 +0x574f:huai4 +0x5750:zuo4 +0x5751:keng1 +0x5752:bi4 +0x5753:xing2 +0x5754:di4 +0x5755:jing1 +0x5756:ji4 +0x5757:kuai4 +0x5758:di3 +0x5759:jing1 +0x575a:jian1 +0x575b:tan2 +0x575c:li4 +0x575d:ba4 +0x575e:wu4 +0x575f:fen2 +0x5760:zhui4 +0x5761:po1 +0x5762:pan3 +0x5763:tang1 +0x5764:kun1 +0x5765:qu1 +0x5766:tan3 +0x5767:zhi1 +0x5768:tuo2 +0x5769:gan1 +0x576a:ping2 +0x576b:dian4 +0x576c:gua4 +0x576d:ni2 +0x576e:tai2 +0x576f:pi1 +0x5770:jiong1 +0x5771:yang3 +0x5772:fo2 +0x5773:ao4 +0x5774:liu4 +0x5775:qiu1 +0x5776:mu4 +0x5777:ke3 +0x5778:gou4 +0x5779:xue4 +0x577a:ba2 +0x577b:chi2 +0x577c:che4 +0x577d:ling2 +0x577e:zhu4 +0x577f:fu4 +0x5780:hu1 +0x5781:zhi4 +0x5782:chui2 +0x5783:la1 +0x5784:long3 +0x5785:long3 +0x5786:lu2 +0x5787:ao4 +0x5789:pao2 +0x578b:xing2 +0x578c:dong4 +0x578d:ji4 +0x578e:ke4 +0x578f:lu4 +0x5790:ci2 +0x5791:chi3 +0x5792:lei3 +0x5793:gai1 +0x5794:yin1 +0x5795:hou4 +0x5796:dui1 +0x5797:zhao4 +0x5798:fu2 +0x5799:guang1 +0x579a:yao2 +0x579b:duo3 +0x579c:duo3 +0x579d:gui3 +0x579e:cha2 +0x579f:yang2 +0x57a0:yin2 +0x57a1:fa2 +0x57a2:gou4 +0x57a3:yuan2 +0x57a4:die2 +0x57a5:xie2 +0x57a6:ken3 +0x57a7:jiong1 +0x57a8:shou3 +0x57a9:e4 +0x57ab:dian4 +0x57ac:hong2 +0x57ad:wu4 +0x57ae:kua3 +0x57b1:dang4 +0x57b2:kai3 +0x57b4:nao3 +0x57b5:an3 +0x57b6:xing1 +0x57b7:xian4 +0x57b8:huan4 +0x57b9:bang1 +0x57ba:pei1 +0x57bb:ba4 +0x57bc:yi4 +0x57bd:yin4 +0x57be:han4 +0x57bf:xu4 +0x57c0:chui2 +0x57c1:cen2 +0x57c2:geng3 +0x57c3:ai1 +0x57c4:peng2 +0x57c5:fang2 +0x57c6:que4 +0x57c7:yong3 +0x57c8:xun4 +0x57c9:jia2 +0x57ca:di4 +0x57cb:mai2 +0x57cc:lang4 +0x57cd:xuan4 +0x57ce:cheng2 +0x57cf:yan2 +0x57d0:jin1 +0x57d1:zhe2 +0x57d2:lei4 +0x57d3:lie4 +0x57d4:pu3 +0x57d5:cheng2 +0x57d7:bu4 +0x57d8:shi2 +0x57d9:xun1 +0x57da:guo1 +0x57db:jiong1 +0x57dc:ye3 +0x57dd:nian4 +0x57de:di3 +0x57df:yu4 +0x57e0:bu4 +0x57e1:ya4 +0x57e2:juan3 +0x57e3:sui4 +0x57e4:pi2 +0x57e5:cheng1 +0x57e6:wan3 +0x57e7:ju4 +0x57e8:lun3 +0x57e9:zheng1 +0x57ea:kong1 +0x57eb:chong3 +0x57ec:dong1 +0x57ed:dai4 +0x57ee:tan4 +0x57ef:an3 +0x57f0:cai4 +0x57f1:shu2 +0x57f2:beng3 +0x57f3:kan3 +0x57f4:zhi2 +0x57f5:duo3 +0x57f6:yi4 +0x57f7:zhi2 +0x57f8:yi4 +0x57f9:pei2 +0x57fa:ji1 +0x57fb:zhun3 +0x57fc:qi2 +0x57fd:sao4 +0x57fe:ju4 +0x57ff:ni2 +0x5800:ku1 +0x5801:ke4 +0x5802:tang2 +0x5803:kun1 +0x5804:ni4 +0x5805:jian1 +0x5806:dui1 +0x5807:jin3 +0x5808:gang1 +0x5809:yu4 +0x580a:e4 +0x580b:peng2 +0x580c:gu4 +0x580d:tu4 +0x580e:leng4 +0x5810:ya2 +0x5811:qian4 +0x5813:an4 +0x5815:duo4 +0x5816:nao3 +0x5817:tu1 +0x5818:cheng2 +0x5819:yin1 +0x581a:hun2 +0x581b:bi4 +0x581c:lian4 +0x581d:guo1 +0x581e:die2 +0x581f:zhuan4 +0x5820:hou4 +0x5821:bao3 +0x5822:bao3 +0x5823:yu2 +0x5824:di1 +0x5825:mao2 +0x5826:jie1 +0x5827:ruan2 +0x5828:e4 +0x5829:geng4 +0x582a:kan1 +0x582b:zong1 +0x582c:yu2 +0x582d:huang2 +0x582e:e4 +0x582f:yao2 +0x5830:yan4 +0x5831:bao4 +0x5832:ji2 +0x5833:mei2 +0x5834:chang2 +0x5835:du3 +0x5836:tuo2 +0x5837:yin4 +0x5838:feng2 +0x5839:zhong4 +0x583a:jie4 +0x583b:zhen1 +0x583c:feng1 +0x583d:gang1 +0x583e:chuan3 +0x583f:jian3 +0x5842:xiang4 +0x5843:huang1 +0x5844:leng2 +0x5845:duan4 +0x5847:xuan1 +0x5848:ji4 +0x5849:ji2 +0x584a:kuai4 +0x584b:ying2 +0x584c:ta1 +0x584d:cheng2 +0x584e:yong3 +0x584f:kai3 +0x5850:su4 +0x5851:su4 +0x5852:shi2 +0x5853:mi4 +0x5854:ta3 +0x5855:weng3 +0x5856:cheng2 +0x5857:tu2 +0x5858:tang2 +0x5859:que4 +0x585a:zhong3 +0x585b:li4 +0x585c:peng2 +0x585d:bang4 +0x585e:sai1 +0x585f:zang4 +0x5860:dui1 +0x5861:tian2 +0x5862:wu4 +0x5863:cheng3 +0x5864:xun1 +0x5865:ge2 +0x5866:zhen4 +0x5867:ai4 +0x5868:gong1 +0x5869:yan2 +0x586a:kan3 +0x586b:tian2 +0x586c:yuan2 +0x586d:wen1 +0x586e:xie4 +0x586f:liu4 +0x5871:lang3 +0x5872:chang2 +0x5873:peng2 +0x5874:beng4 +0x5875:chen2 +0x5876:cu4 +0x5877:lu3 +0x5878:ou3 +0x5879:qian4 +0x587a:mei2 +0x587b:mo4 +0x587c:zhuan1 +0x587d:shuang3 +0x587e:shu2 +0x587f:lou3 +0x5880:chi2 +0x5881:man4 +0x5882:biao1 +0x5883:jing4 +0x5884:qi1 +0x5885:shu4 +0x5886:di4 +0x5887:zhang1 +0x5888:kan4 +0x5889:yong1 +0x588a:dian4 +0x588b:chen3 +0x588c:zhi1 +0x588d:xi4 +0x588e:guo1 +0x588f:qiang3 +0x5890:jin4 +0x5891:di1 +0x5892:shang1 +0x5893:mu4 +0x5894:cui1 +0x5895:yan4 +0x5896:ta3 +0x5897:zeng1 +0x5898:qi2 +0x5899:qiang2 +0x589a:liang2 +0x589c:zhui4 +0x589d:qiao1 +0x589e:zeng1 +0x589f:xu1 +0x58a0:shan4 +0x58a1:shan4 +0x58a2:ba2 +0x58a3:pu1 +0x58a4:kuai4 +0x58a5:dong3 +0x58a6:fan2 +0x58a7:que4 +0x58a8:mo4 +0x58a9:dun1 +0x58aa:dun1 +0x58ab:zun1 +0x58ac:di4 +0x58ad:sheng4 +0x58ae:duo4 +0x58af:duo4 +0x58b0:tan2 +0x58b1:deng4 +0x58b2:wu3 +0x58b3:fen2 +0x58b4:huang2 +0x58b5:tan2 +0x58b6:da1 +0x58b7:ye4 +0x58ba:ao4 +0x58bb:qiang2 +0x58bc:ji1 +0x58bd:qiao1 +0x58be:ken3 +0x58bf:yi4 +0x58c0:pi2 +0x58c1:bi4 +0x58c2:dian4 +0x58c3:jiang1 +0x58c4:ye3 +0x58c5:yong1 +0x58c6:bo2 +0x58c7:tan2 +0x58c8:lan3 +0x58c9:ju4 +0x58ca:huai4 +0x58cb:dang4 +0x58cc:rang3 +0x58cd:qian4 +0x58ce:xun1 +0x58cf:lan4 +0x58d0:xi3 +0x58d1:he4 +0x58d2:ai4 +0x58d3:ya1 +0x58d4:dao3 +0x58d5:hao2 +0x58d6:ruan2 +0x58d8:lei3 +0x58d9:kuang4 +0x58da:lu2 +0x58db:yan2 +0x58dc:tan2 +0x58dd:wei2 +0x58de:huai4 +0x58df:long3 +0x58e0:long3 +0x58e1:rui4 +0x58e2:li4 +0x58e3:lin2 +0x58e4:rang3 +0x58e6:xun1 +0x58e7:yan2 +0x58e8:lei2 +0x58e9:ba4 +0x58eb:shi4 +0x58ec:ren2 +0x58ee:zhuang4 +0x58ef:zhuang4 +0x58f0:sheng1 +0x58f1:yi1 +0x58f2:mai4 +0x58f3:ke2 +0x58f4:zhu3 +0x58f5:zhuang4 +0x58f6:hu2 +0x58f7:hu2 +0x58f8:kun3 +0x58f9:yi1 +0x58fa:hu2 +0x58fb:xu4 +0x58fc:kun3 +0x58fd:shou4 +0x58fe:mang3 +0x58ff:zun1 +0x5900:shou4 +0x5901:yi1 +0x5902:zhi3 +0x5903:gu1 +0x5904:chu4 +0x5905:jiang4 +0x5906:feng2 +0x5907:bei4 +0x5909:bian4 +0x590a:sui1 +0x590b:qun1 +0x590c:ling2 +0x590d:fu4 +0x590e:zuo4 +0x590f:xia4 +0x5910:xiong4 +0x5912:nao2 +0x5913:xia4 +0x5914:kui2 +0x5915:xi1 +0x5916:wai4 +0x5917:yuan4 +0x5918:mao3 +0x5919:su4 +0x591a:duo1 +0x591b:duo1 +0x591c:ye4 +0x591d:qing2 +0x591f:gou4 +0x5920:gou4 +0x5921:qi4 +0x5922:meng4 +0x5923:meng4 +0x5924:yin2 +0x5925:huo3 +0x5926:chen4 +0x5927:da4 +0x5928:ze4 +0x5929:tian1 +0x592a:tai4 +0x592b:fu1 +0x592c:guai4 +0x592d:yao1 +0x592e:yang1 +0x592f:hang1 +0x5930:gao3 +0x5931:shi1 +0x5932:ben3 +0x5933:tai4 +0x5934:tou2 +0x5935:yan3 +0x5936:bi3 +0x5937:yi2 +0x5938:kua1 +0x5939:jia1 +0x593a:duo2 +0x593c:kuang3 +0x593d:yun4 +0x593e:jia1 +0x593f:pa1 +0x5940:en1 +0x5941:lian2 +0x5942:huan4 +0x5943:di4 +0x5944:yan3 +0x5945:pao4 +0x5946:quan3 +0x5947:qi2 +0x5948:nai4 +0x5949:feng4 +0x594a:xie2 +0x594b:fen4 +0x594c:dian3 +0x594e:kui2 +0x594f:zou4 +0x5950:huan4 +0x5951:qi4 +0x5952:kai1 +0x5953:she1 +0x5954:ben1 +0x5955:yi4 +0x5956:jiang3 +0x5957:tao4 +0x5958:zang4 +0x5959:ben3 +0x595a:xi1 +0x595b:xiang3 +0x595c:fei3 +0x595d:diao1 +0x595e:xun4 +0x595f:keng1 +0x5960:dian4 +0x5961:ao4 +0x5962:she1 +0x5963:weng3 +0x5964:pan3 +0x5965:ao4 +0x5966:wu4 +0x5967:ao4 +0x5968:jiang3 +0x5969:lian2 +0x596a:duo2 +0x596b:yun1 +0x596c:jiang3 +0x596d:shi4 +0x596e:fen4 +0x596f:huo4 +0x5970:bi4 +0x5971:lian2 +0x5972:duo3 +0x5973:nv3 +0x5974:nu2 +0x5975:ding1 +0x5976:nai3 +0x5977:qian1 +0x5978:jian1 +0x5979:ta1 +0x597a:jiu3 +0x597b:nan2 +0x597c:cha4 +0x597d:hao3 +0x597e:xian1 +0x597f:fan4 +0x5980:ji3 +0x5981:shuo4 +0x5982:ru2 +0x5983:fei1 +0x5984:wang4 +0x5985:hong2 +0x5986:zhuang1 +0x5987:fu4 +0x5988:ma1 +0x5989:dan1 +0x598a:ren4 +0x598b:fu1 +0x598c:jing4 +0x598d:yan2 +0x598e:xie4 +0x598f:wen4 +0x5990:zhong1 +0x5991:pa1 +0x5992:du4 +0x5993:ji4 +0x5994:keng1 +0x5995:zhong4 +0x5996:yao1 +0x5997:jin4 +0x5998:yun2 +0x5999:miao4 +0x599a:pei1 +0x599c:yue4 +0x599d:zhuang1 +0x599e:niu1 +0x599f:yan4 +0x59a0:na4 +0x59a1:xin1 +0x59a2:fen2 +0x59a3:bi3 +0x59a4:yu2 +0x59a5:tuo3 +0x59a6:feng1 +0x59a7:yuan2 +0x59a8:fang2 +0x59a9:wu3 +0x59aa:yu4 +0x59ab:gui1 +0x59ac:du4 +0x59ad:ba2 +0x59ae:ni1 +0x59af:zhou2 +0x59b0:zhuo2 +0x59b1:zhao1 +0x59b2:da2 +0x59b3:nai3 +0x59b4:yuan3 +0x59b5:tou3 +0x59b6:xuan2 +0x59b7:zhi2 +0x59b8:e1 +0x59b9:mei4 +0x59ba:mo4 +0x59bb:qi1 +0x59bc:bi4 +0x59bd:shen1 +0x59be:qie4 +0x59bf:e1 +0x59c0:he2 +0x59c1:xu3 +0x59c2:fa2 +0x59c3:zheng1 +0x59c4:min2 +0x59c5:ban4 +0x59c6:mu3 +0x59c7:fu1 +0x59c8:ling2 +0x59c9:zi3 +0x59ca:zi3 +0x59cb:shi3 +0x59cc:ran3 +0x59cd:shan1 +0x59ce:yang1 +0x59cf:man2 +0x59d0:jie3 +0x59d1:gu1 +0x59d2:si4 +0x59d3:xing4 +0x59d4:wei3 +0x59d5:zi1 +0x59d6:ju4 +0x59d7:shan1 +0x59d8:pin1 +0x59d9:ren4 +0x59da:yao2 +0x59db:tong3 +0x59dc:jiang1 +0x59dd:shu1 +0x59de:ji2 +0x59df:gai1 +0x59e0:shang4 +0x59e1:kuo4 +0x59e2:juan1 +0x59e3:jiao1 +0x59e4:gou4 +0x59e5:mu3 +0x59e6:jian1 +0x59e7:jian1 +0x59e8:yi2 +0x59e9:nian4 +0x59ea:zhi2 +0x59eb:ji1 +0x59ec:ji1 +0x59ed:xian4 +0x59ee:heng2 +0x59ef:guang1 +0x59f0:jun1 +0x59f1:kua1 +0x59f2:yan4 +0x59f3:ming3 +0x59f4:lie4 +0x59f5:pei4 +0x59f6:yan3 +0x59f7:you4 +0x59f8:yan2 +0x59f9:cha4 +0x59fa:shen1 +0x59fb:yin1 +0x59fc:chi3 +0x59fd:gui3 +0x59fe:quan1 +0x59ff:zi1 +0x5a00:song1 +0x5a01:wei1 +0x5a02:hong2 +0x5a03:wa2 +0x5a04:lou2 +0x5a05:ya4 +0x5a06:rao3 +0x5a07:jiao1 +0x5a08:luan2 +0x5a09:ping1 +0x5a0a:xian4 +0x5a0b:shao4 +0x5a0c:li3 +0x5a0d:cheng2 +0x5a0e:xiao4 +0x5a0f:mang2 +0x5a11:suo1 +0x5a12:wu3 +0x5a13:wei3 +0x5a14:ke4 +0x5a15:lai4 +0x5a16:chuo4 +0x5a17:ding4 +0x5a18:niang2 +0x5a19:xing2 +0x5a1a:nan2 +0x5a1b:yu2 +0x5a1c:nuo2 +0x5a1d:pei1 +0x5a1e:nei3 +0x5a1f:juan1 +0x5a20:shen1 +0x5a21:zhi4 +0x5a22:han2 +0x5a23:di4 +0x5a24:zhuang1 +0x5a25:e2 +0x5a26:pin2 +0x5a27:tui4 +0x5a28:han4 +0x5a29:mian3 +0x5a2a:wu2 +0x5a2b:yan2 +0x5a2c:wu3 +0x5a2d:xi1 +0x5a2e:yan2 +0x5a2f:yu2 +0x5a30:si4 +0x5a31:yu2 +0x5a32:wa1 +0x5a34:xian2 +0x5a35:ju1 +0x5a36:qu3 +0x5a37:shui4 +0x5a38:qi1 +0x5a39:xian2 +0x5a3a:zhui1 +0x5a3b:dong1 +0x5a3c:chang1 +0x5a3d:lu4 +0x5a3e:ai3 +0x5a3f:e1 +0x5a40:e1 +0x5a41:lou2 +0x5a42:mian2 +0x5a43:cong2 +0x5a44:pou3 +0x5a45:ju2 +0x5a46:po2 +0x5a47:cai3 +0x5a48:ding2 +0x5a49:wan3 +0x5a4a:biao3 +0x5a4b:xiao1 +0x5a4c:shu3 +0x5a4d:qi3 +0x5a4e:hui1 +0x5a4f:fu4 +0x5a50:e1 +0x5a51:wo3 +0x5a52:tan2 +0x5a53:fei1 +0x5a55:jie2 +0x5a56:tian1 +0x5a57:ni2 +0x5a58:quan2 +0x5a59:jing4 +0x5a5a:hun1 +0x5a5b:jing1 +0x5a5c:qian1 +0x5a5d:dian4 +0x5a5e:xing4 +0x5a5f:hu4 +0x5a60:wa4 +0x5a61:lai2 +0x5a62:bi4 +0x5a63:yin1 +0x5a64:zhou1 +0x5a65:chuo4 +0x5a66:fu4 +0x5a67:jing4 +0x5a68:lun2 +0x5a69:yan4 +0x5a6a:lan2 +0x5a6b:kun1 +0x5a6c:yin2 +0x5a6d:ya4 +0x5a6f:li4 +0x5a70:dian3 +0x5a71:xian2 +0x5a73:hua4 +0x5a74:ying1 +0x5a75:chan2 +0x5a76:shen3 +0x5a77:ting2 +0x5a78:dang4 +0x5a79:yao3 +0x5a7a:wu4 +0x5a7b:nan4 +0x5a7c:ruo4 +0x5a7d:jia3 +0x5a7e:tou1 +0x5a7f:xu4 +0x5a80:yu2 +0x5a81:wei1 +0x5a82:ti2 +0x5a83:rou2 +0x5a84:mei3 +0x5a85:dan1 +0x5a86:ruan3 +0x5a87:qin1 +0x5a89:wu1 +0x5a8a:qian2 +0x5a8b:chun1 +0x5a8c:mao2 +0x5a8d:fu4 +0x5a8e:jie3 +0x5a8f:duan1 +0x5a90:xi1 +0x5a91:zhong4 +0x5a92:mei2 +0x5a93:huang2 +0x5a94:mian2 +0x5a95:an1 +0x5a96:ying1 +0x5a97:xuan1 +0x5a99:wei1 +0x5a9a:mei4 +0x5a9b:yuan4 +0x5a9c:zhen1 +0x5a9d:qiu1 +0x5a9e:ti2 +0x5a9f:xie4 +0x5aa0:tuo3 +0x5aa1:lian4 +0x5aa2:mao4 +0x5aa3:ran3 +0x5aa4:si1 +0x5aa5:pian1 +0x5aa6:wei4 +0x5aa7:wa1 +0x5aa8:jiu4 +0x5aa9:hu2 +0x5aaa:ao3 +0x5aad:xu1 +0x5aae:tou1 +0x5aaf:gui1 +0x5ab0:zou1 +0x5ab1:yao2 +0x5ab2:pi4 +0x5ab3:xi2 +0x5ab4:yuan2 +0x5ab5:ying4 +0x5ab6:rong2 +0x5ab7:ru4 +0x5ab8:chi1 +0x5ab9:liu2 +0x5aba:mei3 +0x5abb:pan2 +0x5abc:ao3 +0x5abd:ma1 +0x5abe:gou4 +0x5abf:kui4 +0x5ac0:qin2 +0x5ac1:jia4 +0x5ac2:sao3 +0x5ac3:zhen1 +0x5ac4:yuan2 +0x5ac5:cha1 +0x5ac6:yong2 +0x5ac7:ming2 +0x5ac8:ying1 +0x5ac9:ji2 +0x5aca:su4 +0x5acb:niao3 +0x5acc:xian2 +0x5acd:tao1 +0x5ace:pang2 +0x5acf:lang2 +0x5ad0:nao3 +0x5ad1:bao2 +0x5ad2:ai4 +0x5ad3:pi4 +0x5ad4:pin2 +0x5ad5:yi4 +0x5ad6:piao4 +0x5ad7:yu4 +0x5ad8:lei2 +0x5ad9:xuan2 +0x5ada:man4 +0x5adb:yi1 +0x5adc:zhang1 +0x5add:kang1 +0x5ade:yong2 +0x5adf:ni4 +0x5ae0:li2 +0x5ae1:di2 +0x5ae2:gui1 +0x5ae3:yan1 +0x5ae4:jin4 +0x5ae5:zhuan1 +0x5ae6:chang2 +0x5ae7:ce4 +0x5ae8:han1 +0x5ae9:nen4 +0x5aea:lao4 +0x5aeb:mo2 +0x5aec:zhe1 +0x5aed:hu4 +0x5aee:hu4 +0x5aef:ao4 +0x5af0:nen4 +0x5af1:qiang2 +0x5af3:pie4 +0x5af4:gu1 +0x5af5:wu3 +0x5af6:jiao2 +0x5af7:tuo3 +0x5af8:zhan3 +0x5af9:mao2 +0x5afa:xian2 +0x5afb:xian2 +0x5afc:mo4 +0x5afd:liao2 +0x5afe:lian2 +0x5aff:hua4 +0x5b00:gui1 +0x5b01:deng1 +0x5b02:zhi1 +0x5b03:xu1 +0x5b05:hua2 +0x5b06:xi1 +0x5b07:hui4 +0x5b08:rao3 +0x5b09:xi1 +0x5b0a:yan4 +0x5b0b:chan2 +0x5b0c:jiao1 +0x5b0d:mei3 +0x5b0e:fan4 +0x5b0f:fan1 +0x5b10:xian1 +0x5b11:yi4 +0x5b12:wei4 +0x5b13:jiao4 +0x5b14:fu4 +0x5b15:shi4 +0x5b16:bi4 +0x5b17:shan4 +0x5b18:sui4 +0x5b19:qiang2 +0x5b1a:lian3 +0x5b1b:huan2 +0x5b1d:niao3 +0x5b1e:dong3 +0x5b1f:yi4 +0x5b20:can2 +0x5b21:ai4 +0x5b22:niang2 +0x5b23:neng2 +0x5b24:ma1 +0x5b25:tiao3 +0x5b26:chou2 +0x5b27:jin4 +0x5b28:ci2 +0x5b29:yu2 +0x5b2a:pin2 +0x5b2c:xu1 +0x5b2d:nai3 +0x5b2e:yan1 +0x5b2f:tai2 +0x5b30:ying1 +0x5b31:can2 +0x5b32:niao3 +0x5b34:ying2 +0x5b35:mian2 +0x5b37:ma1 +0x5b38:shen3 +0x5b39:xing4 +0x5b3a:ni4 +0x5b3b:du2 +0x5b3c:liu3 +0x5b3d:yuan1 +0x5b3e:lan3 +0x5b3f:yan4 +0x5b40:shuang1 +0x5b41:ling2 +0x5b42:jiao3 +0x5b43:niang2 +0x5b44:lan3 +0x5b45:xian1 +0x5b46:ying1 +0x5b47:shuang1 +0x5b48:shuai1 +0x5b49:quan2 +0x5b4a:mi3 +0x5b4b:li2 +0x5b4c:luan2 +0x5b4d:yan2 +0x5b4e:zhu3 +0x5b4f:lan3 +0x5b50:zi3 +0x5b51:jie2 +0x5b52:jue2 +0x5b53:jue2 +0x5b54:kong3 +0x5b55:yun4 +0x5b56:zi1 +0x5b57:zi4 +0x5b58:cun2 +0x5b59:sun1 +0x5b5a:fu2 +0x5b5b:bei4 +0x5b5c:zi1 +0x5b5d:xiao4 +0x5b5e:xin4 +0x5b5f:meng4 +0x5b60:si4 +0x5b61:tai1 +0x5b62:bao1 +0x5b63:ji4 +0x5b64:gu1 +0x5b65:nu2 +0x5b66:xue2 +0x5b68:zhuan3 +0x5b69:hai2 +0x5b6a:luan2 +0x5b6b:sun1 +0x5b6c:huai4 +0x5b6d:mie1 +0x5b6e:cong2 +0x5b6f:qian1 +0x5b70:shu2 +0x5b71:chan2 +0x5b72:ya1 +0x5b73:zi1 +0x5b74:ni3 +0x5b75:fu1 +0x5b76:zi1 +0x5b77:li2 +0x5b78:xue2 +0x5b79:bo4 +0x5b7a:ru2 +0x5b7b:lai2 +0x5b7c:nie4 +0x5b7d:nie4 +0x5b7e:ying1 +0x5b7f:luan2 +0x5b80:mian2 +0x5b81:ning2 +0x5b82:rong3 +0x5b83:ta1 +0x5b84:gui3 +0x5b85:zhai2 +0x5b86:qiong2 +0x5b87:yu3 +0x5b88:shou3 +0x5b89:an1 +0x5b8a:tu2 +0x5b8b:song4 +0x5b8c:wan2 +0x5b8d:rou4 +0x5b8e:yao3 +0x5b8f:hong2 +0x5b90:yi2 +0x5b91:jing3 +0x5b92:zhun1 +0x5b93:mi4 +0x5b94:zhu3 +0x5b95:dang4 +0x5b96:hong2 +0x5b97:zong1 +0x5b98:guan1 +0x5b99:zhou4 +0x5b9a:ding4 +0x5b9b:wan3 +0x5b9c:yi2 +0x5b9d:bao3 +0x5b9e:shi2 +0x5b9f:shi2 +0x5ba0:chong3 +0x5ba1:shen3 +0x5ba2:ke4 +0x5ba3:xuan1 +0x5ba4:shi4 +0x5ba5:you4 +0x5ba6:huan4 +0x5ba7:yi2 +0x5ba8:tiao3 +0x5ba9:shi3 +0x5baa:xian4 +0x5bab:gong1 +0x5bac:cheng2 +0x5bad:qun2 +0x5bae:gong1 +0x5baf:xiao1 +0x5bb0:zai3 +0x5bb1:zha4 +0x5bb2:bao3 +0x5bb3:hai4 +0x5bb4:yan4 +0x5bb5:xiao1 +0x5bb6:jia1 +0x5bb7:shen3 +0x5bb8:chen2 +0x5bb9:rong2 +0x5bba:huang3 +0x5bbb:mi4 +0x5bbc:kou4 +0x5bbd:kuan1 +0x5bbe:bin1 +0x5bbf:su4 +0x5bc0:cai4 +0x5bc1:zan3 +0x5bc2:ji4 +0x5bc3:yuan1 +0x5bc4:ji4 +0x5bc5:yin2 +0x5bc6:mi4 +0x5bc7:kou4 +0x5bc8:qing1 +0x5bc9:que4 +0x5bca:zhen1 +0x5bcb:jian3 +0x5bcc:fu4 +0x5bcd:ning2 +0x5bce:bing4 +0x5bcf:huan2 +0x5bd0:mei4 +0x5bd1:qin3 +0x5bd2:han2 +0x5bd3:yu4 +0x5bd4:shi2 +0x5bd5:ning2 +0x5bd6:jin4 +0x5bd7:ning2 +0x5bd8:zhi4 +0x5bd9:yu3 +0x5bda:bao3 +0x5bdb:kuan1 +0x5bdc:ning2 +0x5bdd:qin3 +0x5bde:mo4 +0x5bdf:cha2 +0x5be0:ju4 +0x5be1:gua3 +0x5be2:qin3 +0x5be3:hu1 +0x5be4:wu4 +0x5be5:liao2 +0x5be6:shi2 +0x5be7:ning2 +0x5be8:zhai4 +0x5be9:shen3 +0x5bea:wei3 +0x5beb:xie3 +0x5bec:kuan1 +0x5bed:hui4 +0x5bee:liao2 +0x5bef:jun4 +0x5bf0:huan2 +0x5bf1:yi4 +0x5bf2:yi2 +0x5bf3:bao3 +0x5bf4:qin4 +0x5bf5:chong3 +0x5bf6:bao3 +0x5bf7:feng1 +0x5bf8:cun4 +0x5bf9:dui4 +0x5bfa:si4 +0x5bfb:xun2 +0x5bfc:dao3 +0x5bfd:lv4 +0x5bfe:dui4 +0x5bff:shou4 +0x5c00:po3 +0x5c01:feng1 +0x5c02:zhuan1 +0x5c03:fu1 +0x5c04:she4 +0x5c05:ke4 +0x5c06:jiang1 +0x5c07:jiang1 +0x5c08:zhuan1 +0x5c09:wei4 +0x5c0a:zun1 +0x5c0b:xun2 +0x5c0c:shu4 +0x5c0d:dui4 +0x5c0e:dao3 +0x5c0f:xiao3 +0x5c10:ji1 +0x5c11:shao3 +0x5c12:er3 +0x5c13:er3 +0x5c14:er3 +0x5c15:ga3 +0x5c16:jian1 +0x5c17:shu2 +0x5c18:chen2 +0x5c19:shang4 +0x5c1a:shang4 +0x5c1c:ga2 +0x5c1d:chang2 +0x5c1e:liao4 +0x5c1f:xian3 +0x5c20:xian3 +0x5c22:wang1 +0x5c23:wang1 +0x5c24:you2 +0x5c25:liao4 +0x5c26:liao4 +0x5c27:yao2 +0x5c28:mang2 +0x5c29:wang1 +0x5c2a:wang1 +0x5c2b:wang1 +0x5c2c:ga4 +0x5c2d:yao2 +0x5c2e:duo4 +0x5c2f:kui4 +0x5c30:zhong3 +0x5c31:jiu4 +0x5c32:gan1 +0x5c33:gu3 +0x5c34:gan1 +0x5c35:tui2 +0x5c36:gan1 +0x5c37:gan1 +0x5c38:shi1 +0x5c39:yin3 +0x5c3a:chi3 +0x5c3b:kao1 +0x5c3c:ni2 +0x5c3d:jin3 +0x5c3e:wei3 +0x5c3f:niao4 +0x5c40:ju2 +0x5c41:pi4 +0x5c42:ceng2 +0x5c43:xi4 +0x5c44:bi1 +0x5c45:ju1 +0x5c46:jie4 +0x5c47:tian2 +0x5c48:qu1 +0x5c49:ti4 +0x5c4a:jie4 +0x5c4b:wu1 +0x5c4c:diao3 +0x5c4d:shi1 +0x5c4e:shi3 +0x5c4f:ping2 +0x5c50:ji1 +0x5c51:xie4 +0x5c52:chen2 +0x5c53:xi4 +0x5c54:ni2 +0x5c55:zhan3 +0x5c56:xi1 +0x5c58:man3 +0x5c59:e1 +0x5c5a:lou4 +0x5c5b:ping2 +0x5c5c:ti4 +0x5c5d:fei4 +0x5c5e:shu3 +0x5c5f:xie4 +0x5c60:tu2 +0x5c61:lv3 +0x5c62:lv3 +0x5c63:xi3 +0x5c64:ceng2 +0x5c65:lv3 +0x5c66:ju4 +0x5c67:xie4 +0x5c68:ju4 +0x5c69:jue1 +0x5c6a:liao2 +0x5c6b:jue2 +0x5c6c:shu3 +0x5c6d:xi4 +0x5c6e:che4 +0x5c6f:tun2 +0x5c70:ni4 +0x5c71:shan1 +0x5c73:xian1 +0x5c74:li4 +0x5c75:xue1 +0x5c78:long2 +0x5c79:yi4 +0x5c7a:qi3 +0x5c7b:ren4 +0x5c7c:wu4 +0x5c7d:han4 +0x5c7e:shen1 +0x5c7f:yu3 +0x5c80:chu1 +0x5c81:sui4 +0x5c82:qi3 +0x5c84:yue4 +0x5c85:ban3 +0x5c86:yao3 +0x5c87:ang2 +0x5c88:ya2 +0x5c89:wu4 +0x5c8a:jie2 +0x5c8b:e4 +0x5c8c:ji2 +0x5c8d:qian1 +0x5c8e:fen1 +0x5c8f:yuan2 +0x5c90:qi2 +0x5c91:cen2 +0x5c92:qian2 +0x5c93:qi2 +0x5c94:cha4 +0x5c95:jie4 +0x5c96:qu1 +0x5c97:gang3 +0x5c98:xian4 +0x5c99:ao4 +0x5c9a:lan2 +0x5c9b:dao3 +0x5c9c:ba1 +0x5c9d:zuo4 +0x5c9e:zuo4 +0x5c9f:yang3 +0x5ca0:ju4 +0x5ca1:gang1 +0x5ca2:ke3 +0x5ca3:gou3 +0x5ca4:xue4 +0x5ca5:bei1 +0x5ca6:li4 +0x5ca7:tiao2 +0x5ca8:ju1 +0x5ca9:yan2 +0x5caa:fu2 +0x5cab:xiu4 +0x5cac:jia3 +0x5cad:ling2 +0x5cae:tuo2 +0x5caf:pei1 +0x5cb0:you3 +0x5cb1:dai4 +0x5cb2:kuang4 +0x5cb3:yue4 +0x5cb4:qu1 +0x5cb5:hu4 +0x5cb6:po4 +0x5cb7:min2 +0x5cb8:an4 +0x5cb9:tiao2 +0x5cba:ling2 +0x5cbb:chi2 +0x5cbd:dong1 +0x5cbf:kui1 +0x5cc0:xiu4 +0x5cc1:mao3 +0x5cc2:tong2 +0x5cc3:xue2 +0x5cc4:yi4 +0x5cc6:he1 +0x5cc7:ke1 +0x5cc8:luo4 +0x5cc9:e1 +0x5cca:fu4 +0x5ccb:xun2 +0x5ccc:die2 +0x5ccd:lu4 +0x5cce:an1 +0x5ccf:er3 +0x5cd0:gai1 +0x5cd1:quan2 +0x5cd2:tong2 +0x5cd3:yi2 +0x5cd4:mu3 +0x5cd5:shi2 +0x5cd6:an1 +0x5cd7:wei2 +0x5cd8:hu1 +0x5cd9:zhi4 +0x5cda:mi4 +0x5cdb:li3 +0x5cdc:ji1 +0x5cdd:tong2 +0x5cde:wei2 +0x5cdf:you4 +0x5ce1:xia2 +0x5ce2:li3 +0x5ce3:yao2 +0x5ce4:jiao4 +0x5ce5:zheng1 +0x5ce6:luan2 +0x5ce7:jiao1 +0x5ce8:e2 +0x5ce9:e2 +0x5cea:yu4 +0x5ceb:ye2 +0x5cec:bu1 +0x5ced:qiao4 +0x5cee:qun1 +0x5cef:feng1 +0x5cf0:feng1 +0x5cf1:nao2 +0x5cf2:li3 +0x5cf3:you2 +0x5cf4:xian4 +0x5cf5:hong2 +0x5cf6:dao3 +0x5cf7:shen1 +0x5cf8:cheng2 +0x5cf9:tu2 +0x5cfa:geng3 +0x5cfb:jun4 +0x5cfc:hao4 +0x5cfd:xia2 +0x5cfe:yin1 +0x5cff:yu3 +0x5d00:lang4 +0x5d01:kan3 +0x5d02:lao2 +0x5d03:lai2 +0x5d04:xian3 +0x5d05:que4 +0x5d06:kong1 +0x5d07:chong2 +0x5d08:chong2 +0x5d09:ta4 +0x5d0b:hua2 +0x5d0c:ju1 +0x5d0d:lai2 +0x5d0e:qi2 +0x5d0f:min2 +0x5d10:kun1 +0x5d11:kun1 +0x5d12:zu2 +0x5d13:gu4 +0x5d14:cui1 +0x5d15:ya2 +0x5d16:ya2 +0x5d17:gang3 +0x5d18:lun2 +0x5d19:lun2 +0x5d1a:leng2 +0x5d1b:jue2 +0x5d1c:duo1 +0x5d1d:zheng1 +0x5d1e:guo1 +0x5d1f:yin2 +0x5d20:dong1 +0x5d21:han2 +0x5d22:zheng1 +0x5d23:wei3 +0x5d24:yao2 +0x5d25:pi3 +0x5d26:yan1 +0x5d27:song1 +0x5d28:jie2 +0x5d29:beng1 +0x5d2a:zu2 +0x5d2b:jue2 +0x5d2c:dong1 +0x5d2d:zhan3 +0x5d2e:gu4 +0x5d2f:yin2 +0x5d31:ze2 +0x5d32:huang2 +0x5d33:yu2 +0x5d34:wei1 +0x5d35:yang2 +0x5d36:feng1 +0x5d37:qiu2 +0x5d38:dun4 +0x5d39:ti2 +0x5d3a:yi3 +0x5d3b:zhi4 +0x5d3c:shi4 +0x5d3d:zai3 +0x5d3e:yao3 +0x5d3f:e4 +0x5d40:zhu4 +0x5d41:kan1 +0x5d42:lv4 +0x5d43:yan3 +0x5d44:mei3 +0x5d45:gan1 +0x5d46:ji1 +0x5d47:ji1 +0x5d48:huan3 +0x5d49:ting2 +0x5d4a:sheng4 +0x5d4b:mei2 +0x5d4c:qian4 +0x5d4d:wu4 +0x5d4e:yu2 +0x5d4f:zong1 +0x5d50:lan2 +0x5d51:jue2 +0x5d52:yan2 +0x5d53:yan2 +0x5d54:wei3 +0x5d55:zong1 +0x5d56:cha2 +0x5d57:sui4 +0x5d58:rong2 +0x5d5a:qin1 +0x5d5b:yu2 +0x5d5d:lou3 +0x5d5e:tu2 +0x5d5f:dui1 +0x5d60:xi1 +0x5d61:weng1 +0x5d62:cang1 +0x5d63:dang1 +0x5d64:hong2 +0x5d65:jie2 +0x5d66:ai2 +0x5d67:liu2 +0x5d68:wu3 +0x5d69:song1 +0x5d6a:qiao1 +0x5d6b:zi1 +0x5d6c:wei2 +0x5d6d:beng1 +0x5d6e:dian1 +0x5d6f:cuo2 +0x5d70:qian3 +0x5d71:yong3 +0x5d72:nie4 +0x5d73:cuo2 +0x5d74:ji2 +0x5d77:song3 +0x5d78:zong1 +0x5d79:jiang4 +0x5d7a:liao2 +0x5d7c:chan3 +0x5d7d:die2 +0x5d7e:cen1 +0x5d7f:ding3 +0x5d80:tu1 +0x5d81:lou3 +0x5d82:zhang4 +0x5d83:zhan3 +0x5d84:zhan3 +0x5d85:ao2 +0x5d86:cao2 +0x5d87:qu1 +0x5d88:qiang1 +0x5d89:zui1 +0x5d8a:zui3 +0x5d8b:dao3 +0x5d8c:dao3 +0x5d8d:xi2 +0x5d8e:yu4 +0x5d8f:bo2 +0x5d90:long2 +0x5d91:xiang3 +0x5d92:ceng2 +0x5d93:bo1 +0x5d94:qin1 +0x5d95:jiao1 +0x5d96:yan3 +0x5d97:lao2 +0x5d98:zhan4 +0x5d99:lin2 +0x5d9a:liao2 +0x5d9b:liao2 +0x5d9c:jin1 +0x5d9d:deng4 +0x5d9e:duo4 +0x5d9f:zun1 +0x5da0:jiao4 +0x5da1:gui4 +0x5da2:yao2 +0x5da3:qiao2 +0x5da4:yao2 +0x5da5:jue2 +0x5da6:zhan1 +0x5da7:yi4 +0x5da8:xue2 +0x5da9:nao2 +0x5daa:ye4 +0x5dab:ye4 +0x5dac:yi2 +0x5dad:e4 +0x5dae:xian3 +0x5daf:ji2 +0x5db0:xie4 +0x5db1:ke3 +0x5db2:xi1 +0x5db3:di4 +0x5db4:ao4 +0x5db5:zui3 +0x5db7:yi2 +0x5db8:rong2 +0x5db9:dao3 +0x5dba:ling3 +0x5dbb:za2 +0x5dbc:yu3 +0x5dbd:yue4 +0x5dbe:yin3 +0x5dc0:jie1 +0x5dc1:li4 +0x5dc2:sui3 +0x5dc3:long2 +0x5dc4:long2 +0x5dc5:dian1 +0x5dc6:ying2 +0x5dc7:xi1 +0x5dc8:ju2 +0x5dc9:chan2 +0x5dca:ying3 +0x5dcb:kui1 +0x5dcc:yan2 +0x5dcd:wei1 +0x5dce:nao2 +0x5dcf:quan2 +0x5dd0:chao3 +0x5dd1:cuan2 +0x5dd2:luan2 +0x5dd3:dian1 +0x5dd4:dian1 +0x5dd6:yan2 +0x5dd7:yan2 +0x5dd8:yan3 +0x5dd9:nao2 +0x5dda:yan3 +0x5ddb:chuan1 +0x5ddc:gui4 +0x5ddd:chuan1 +0x5dde:zhou1 +0x5ddf:huang1 +0x5de0:jing1 +0x5de1:xun2 +0x5de2:chao2 +0x5de3:chao2 +0x5de4:lie1 +0x5de5:gong1 +0x5de6:zuo3 +0x5de7:qiao3 +0x5de8:ju4 +0x5de9:gong3 +0x5deb:wu1 +0x5dee:cha4 +0x5def:qiu2 +0x5df0:qiu2 +0x5df1:ji3 +0x5df2:yi3 +0x5df3:si4 +0x5df4:ba1 +0x5df5:zhi1 +0x5df6:zhao1 +0x5df7:xiang4 +0x5df8:yi2 +0x5df9:jin3 +0x5dfa:xun4 +0x5dfb:juan4 +0x5dfd:xun4 +0x5dfe:jin1 +0x5dff:fu2 +0x5e00:za1 +0x5e01:bi4 +0x5e02:shi4 +0x5e03:bu4 +0x5e04:ding1 +0x5e05:shuai4 +0x5e06:fan1 +0x5e07:nie4 +0x5e08:shi1 +0x5e09:fen1 +0x5e0a:pa4 +0x5e0b:zhi3 +0x5e0c:xi1 +0x5e0d:hu4 +0x5e0e:dan4 +0x5e0f:wei2 +0x5e10:zhang4 +0x5e11:tang3 +0x5e12:dai4 +0x5e13:ma4 +0x5e14:pei4 +0x5e15:pa4 +0x5e16:tie1 +0x5e17:fu2 +0x5e18:lian2 +0x5e19:zhi4 +0x5e1a:zhou3 +0x5e1b:bo2 +0x5e1c:zhi4 +0x5e1d:di4 +0x5e1e:mo4 +0x5e1f:yi4 +0x5e20:yi4 +0x5e21:ping2 +0x5e22:qia4 +0x5e23:juan4 +0x5e24:ru2 +0x5e25:shuai4 +0x5e26:dai4 +0x5e27:zheng4 +0x5e28:shui4 +0x5e29:qiao4 +0x5e2a:zhen1 +0x5e2b:shi1 +0x5e2c:qun2 +0x5e2d:xi2 +0x5e2e:bang1 +0x5e2f:dai4 +0x5e30:gui1 +0x5e31:chou2 +0x5e32:ping2 +0x5e33:zhang4 +0x5e34:sha1 +0x5e35:wan1 +0x5e36:dai4 +0x5e37:wei2 +0x5e38:chang2 +0x5e39:sha4 +0x5e3a:qi2 +0x5e3b:ze2 +0x5e3c:guo2 +0x5e3d:mao4 +0x5e3e:du3 +0x5e3f:hou2 +0x5e40:zheng4 +0x5e41:xu1 +0x5e42:mi4 +0x5e43:wei2 +0x5e44:wo4 +0x5e45:fu2 +0x5e46:yi4 +0x5e47:bang1 +0x5e48:ping2 +0x5e4a:gong1 +0x5e4b:pan2 +0x5e4c:huang3 +0x5e4d:dao1 +0x5e4e:mi4 +0x5e4f:jia1 +0x5e50:teng2 +0x5e51:hui1 +0x5e52:zhong1 +0x5e53:shan1 +0x5e54:man4 +0x5e55:mu4 +0x5e56:biao1 +0x5e57:guo2 +0x5e58:ze2 +0x5e59:mu4 +0x5e5a:bang1 +0x5e5b:zhang4 +0x5e5c:jiong3 +0x5e5d:chan3 +0x5e5e:fu2 +0x5e5f:zhi4 +0x5e60:hu1 +0x5e61:fan1 +0x5e62:chuang2 +0x5e63:bi4 +0x5e66:mi4 +0x5e67:qiao1 +0x5e68:chan1 +0x5e69:fen2 +0x5e6a:meng2 +0x5e6b:bang1 +0x5e6c:chou2 +0x5e6d:mie4 +0x5e6e:chu2 +0x5e6f:jie2 +0x5e70:xian3 +0x5e71:lan2 +0x5e72:gan1 +0x5e73:ping2 +0x5e74:nian2 +0x5e75:qian1 +0x5e76:bing4 +0x5e77:bing4 +0x5e78:xing4 +0x5e79:gan4 +0x5e7a:yao1 +0x5e7b:huan4 +0x5e7c:you4 +0x5e7d:you1 +0x5e7e:ji3 +0x5e7f:guang3 +0x5e80:pi3 +0x5e81:ting1 +0x5e82:ze4 +0x5e83:guang3 +0x5e84:zhuang1 +0x5e85:mo5 +0x5e86:qing4 +0x5e87:bi4 +0x5e88:qin2 +0x5e89:dun4 +0x5e8a:chuang2 +0x5e8b:gui3 +0x5e8c:ya3 +0x5e8d:bai4 +0x5e8e:jie4 +0x5e8f:xu4 +0x5e90:lu2 +0x5e91:wu3 +0x5e93:ku4 +0x5e94:ying4 +0x5e95:di3 +0x5e96:pao2 +0x5e97:dian4 +0x5e98:ya1 +0x5e99:miao4 +0x5e9a:geng1 +0x5e9b:ci1 +0x5e9c:fu3 +0x5e9d:tong2 +0x5e9e:pang2 +0x5e9f:fei4 +0x5ea0:xiang2 +0x5ea1:yi3 +0x5ea2:zhi4 +0x5ea3:tiao1 +0x5ea4:zhi4 +0x5ea5:xiu1 +0x5ea6:du4 +0x5ea7:zuo4 +0x5ea8:xiao1 +0x5ea9:tu2 +0x5eaa:gui3 +0x5eab:ku4 +0x5eac:pang2 +0x5ead:ting2 +0x5eae:you3 +0x5eaf:bu1 +0x5eb0:ding1 +0x5eb1:cheng3 +0x5eb2:lai2 +0x5eb3:bei1 +0x5eb4:ji2 +0x5eb5:an1 +0x5eb6:shu4 +0x5eb7:kang1 +0x5eb8:yong1 +0x5eb9:tuo3 +0x5eba:song1 +0x5ebb:shu4 +0x5ebc:qing3 +0x5ebd:yu4 +0x5ebe:yu3 +0x5ebf:miao4 +0x5ec0:sou1 +0x5ec1:ce4 +0x5ec2:xiang1 +0x5ec3:fei4 +0x5ec4:jiu4 +0x5ec5:he2 +0x5ec6:hui4 +0x5ec7:liu4 +0x5ec8:sha4 +0x5ec9:lian2 +0x5eca:lang2 +0x5ecb:sou1 +0x5ecc:zhi4 +0x5ecd:pou3 +0x5ece:qing3 +0x5ecf:jiu4 +0x5ed0:jiu4 +0x5ed1:jin3 +0x5ed2:ao2 +0x5ed3:kuo4 +0x5ed4:lou2 +0x5ed5:yin4 +0x5ed6:liao4 +0x5ed7:dai4 +0x5ed8:lu4 +0x5ed9:yi4 +0x5eda:chu2 +0x5edb:chan2 +0x5edc:tu1 +0x5edd:si1 +0x5ede:xin1 +0x5edf:miao4 +0x5ee0:chang3 +0x5ee1:wu3 +0x5ee2:fei4 +0x5ee3:guang3 +0x5ee5:kuai4 +0x5ee6:bi4 +0x5ee7:qiang2 +0x5ee8:xie4 +0x5ee9:lin3 +0x5eea:lin3 +0x5eeb:liao2 +0x5eec:lu2 +0x5eee:ying2 +0x5eef:xian1 +0x5ef0:ting1 +0x5ef1:yong1 +0x5ef2:li2 +0x5ef3:ting1 +0x5ef4:yin3 +0x5ef5:xun2 +0x5ef6:yan2 +0x5ef7:ting2 +0x5ef8:di2 +0x5ef9:po4 +0x5efa:jian4 +0x5efb:hui2 +0x5efc:nai3 +0x5efd:hui2 +0x5efe:gong3 +0x5eff:nian4 +0x5f00:kai1 +0x5f01:bian4 +0x5f02:yi4 +0x5f03:qi4 +0x5f04:nong4 +0x5f05:fen2 +0x5f06:ju3 +0x5f07:yan3 +0x5f08:yi4 +0x5f09:zang4 +0x5f0a:bi4 +0x5f0b:yi4 +0x5f0c:yi1 +0x5f0d:er4 +0x5f0e:san1 +0x5f0f:shi4 +0x5f10:er4 +0x5f11:shi4 +0x5f12:shi4 +0x5f13:gong1 +0x5f14:diao4 +0x5f15:yin3 +0x5f16:hu4 +0x5f17:fu2 +0x5f18:hong2 +0x5f19:wu1 +0x5f1a:tui2 +0x5f1b:chi2 +0x5f1c:jiang4 +0x5f1d:ba4 +0x5f1e:shen3 +0x5f1f:di4 +0x5f20:zhang1 +0x5f21:jue2 +0x5f22:tao1 +0x5f23:fu3 +0x5f24:di3 +0x5f25:mi2 +0x5f26:xian2 +0x5f27:hu2 +0x5f28:chao1 +0x5f29:nu3 +0x5f2a:jing4 +0x5f2b:zhen3 +0x5f2c:yi2 +0x5f2d:mi3 +0x5f2e:quan1 +0x5f2f:wan1 +0x5f30:shao1 +0x5f31:ruo4 +0x5f32:xuan1 +0x5f33:jing4 +0x5f34:dun1 +0x5f35:zhang1 +0x5f36:jiang4 +0x5f37:qiang2 +0x5f38:peng2 +0x5f39:dan4 +0x5f3a:qiang2 +0x5f3b:bi4 +0x5f3c:bi4 +0x5f3d:she4 +0x5f3e:dan4 +0x5f3f:jian3 +0x5f40:gou4 +0x5f42:fa1 +0x5f43:bi4 +0x5f44:kou1 +0x5f46:bie4 +0x5f47:xiao1 +0x5f48:dan4 +0x5f49:kuo4 +0x5f4a:qiang2 +0x5f4b:hong2 +0x5f4c:mi2 +0x5f4d:kuo4 +0x5f4e:wan1 +0x5f4f:jue2 +0x5f50:ji4 +0x5f51:ji4 +0x5f52:gui1 +0x5f53:dang1 +0x5f54:lu4 +0x5f55:lu4 +0x5f56:tuan4 +0x5f57:hui4 +0x5f58:zhi4 +0x5f59:hui4 +0x5f5a:hui4 +0x5f5b:yi2 +0x5f5c:yi2 +0x5f5d:yi2 +0x5f5e:yi2 +0x5f5f:huo4 +0x5f60:huo4 +0x5f61:shan1 +0x5f62:xing2 +0x5f63:wen2 +0x5f64:tong2 +0x5f65:yan4 +0x5f66:yan4 +0x5f67:yu4 +0x5f68:chi1 +0x5f69:cai3 +0x5f6a:biao1 +0x5f6b:diao1 +0x5f6c:bin1 +0x5f6d:peng2 +0x5f6e:yong3 +0x5f6f:piao1 +0x5f70:zhang1 +0x5f71:ying3 +0x5f72:chi1 +0x5f73:chi4 +0x5f74:zhuo2 +0x5f75:tuo3 +0x5f76:ji2 +0x5f77:pang2 +0x5f78:zhong1 +0x5f79:yi4 +0x5f7a:wang2 +0x5f7b:che4 +0x5f7c:bi3 +0x5f7d:chi2 +0x5f7e:ling3 +0x5f7f:fu2 +0x5f80:wang3 +0x5f81:zheng1 +0x5f82:cu2 +0x5f83:wang3 +0x5f84:jing4 +0x5f85:dai4 +0x5f86:xi1 +0x5f87:xun4 +0x5f88:hen3 +0x5f89:yang2 +0x5f8a:huai2 +0x5f8b:lv4 +0x5f8c:hou4 +0x5f8d:wa1 +0x5f8e:cheng3 +0x5f8f:zhi4 +0x5f90:xu2 +0x5f91:jing4 +0x5f92:tu2 +0x5f93:cong2 +0x5f95:lai2 +0x5f96:cong2 +0x5f97:de2 +0x5f98:pai2 +0x5f99:xi3 +0x5f9b:qi4 +0x5f9c:chang2 +0x5f9d:zhi4 +0x5f9e:cong2 +0x5f9f:zhou1 +0x5fa0:lai2 +0x5fa1:yu4 +0x5fa2:xie4 +0x5fa3:jie4 +0x5fa4:jian4 +0x5fa5:chi2 +0x5fa6:jia3 +0x5fa7:bian4 +0x5fa8:huang2 +0x5fa9:fu4 +0x5faa:xun2 +0x5fab:wei3 +0x5fac:pang2 +0x5fad:yao2 +0x5fae:wei1 +0x5faf:xi1 +0x5fb0:zheng1 +0x5fb1:piao4 +0x5fb2:chi2 +0x5fb3:de2 +0x5fb4:zheng1 +0x5fb5:zheng1 +0x5fb6:bie4 +0x5fb7:de2 +0x5fb8:chong1 +0x5fb9:che4 +0x5fba:jiao3 +0x5fbb:wei4 +0x5fbc:jiao4 +0x5fbd:hui1 +0x5fbe:mei2 +0x5fbf:long4 +0x5fc0:xiang1 +0x5fc1:bao4 +0x5fc2:qu2 +0x5fc3:xin1 +0x5fc5:bi4 +0x5fc6:yi4 +0x5fc7:le4 +0x5fc8:ren2 +0x5fc9:dao1 +0x5fca:ding4 +0x5fcb:gai3 +0x5fcc:ji4 +0x5fcd:ren3 +0x5fce:ren2 +0x5fcf:chan4 +0x5fd0:tan3 +0x5fd1:te4 +0x5fd2:te4 +0x5fd3:gan1 +0x5fd4:qi4 +0x5fd5:shi4 +0x5fd6:cun3 +0x5fd7:zhi4 +0x5fd8:wang4 +0x5fd9:mang2 +0x5fda:xi1 +0x5fdb:fan2 +0x5fdc:ying1 +0x5fdd:tian3 +0x5fde:min2 +0x5fdf:min2 +0x5fe0:zhong1 +0x5fe1:chong1 +0x5fe2:wu4 +0x5fe3:ji2 +0x5fe4:wu3 +0x5fe5:xi4 +0x5fe6:ye4 +0x5fe7:you1 +0x5fe8:wan4 +0x5fe9:cong1 +0x5fea:zhong1 +0x5feb:kuai4 +0x5fec:yu4 +0x5fed:bian4 +0x5fee:zhi4 +0x5fef:qi2 +0x5ff0:cui4 +0x5ff1:chen2 +0x5ff2:tai4 +0x5ff3:tun2 +0x5ff4:qian2 +0x5ff5:nian4 +0x5ff6:hun2 +0x5ff7:xiong1 +0x5ff8:niu3 +0x5ff9:wang3 +0x5ffa:xian1 +0x5ffb:xin1 +0x5ffc:kang1 +0x5ffd:hu1 +0x5ffe:kai4 +0x5fff:fen4 +0x6000:huai2 +0x6001:tai4 +0x6002:song3 +0x6003:wu3 +0x6004:ou4 +0x6005:chang4 +0x6006:chuang4 +0x6007:ju4 +0x6008:yi4 +0x6009:bao3 +0x600a:chao1 +0x600b:min2 +0x600c:pei1 +0x600d:zuo4 +0x600e:zen3 +0x600f:yang4 +0x6010:kou4 +0x6011:ban4 +0x6012:nu4 +0x6013:nao2 +0x6014:zheng1 +0x6015:pa4 +0x6016:bu4 +0x6017:tie1 +0x6018:gu4 +0x6019:hu4 +0x601a:ju4 +0x601b:da2 +0x601c:lian2 +0x601d:si1 +0x601e:chou1 +0x601f:di4 +0x6020:dai4 +0x6021:yi2 +0x6022:tu2 +0x6023:you2 +0x6024:fu1 +0x6025:ji2 +0x6026:peng1 +0x6027:xing4 +0x6028:yuan4 +0x6029:ni2 +0x602a:guai4 +0x602b:fu2 +0x602c:xi4 +0x602d:bi4 +0x602e:you1 +0x602f:qie4 +0x6030:xuan4 +0x6031:cong1 +0x6032:bing3 +0x6033:huang3 +0x6034:xu4 +0x6035:chu4 +0x6036:pi1 +0x6037:xi1 +0x6038:xi1 +0x6039:tan1 +0x603b:zong3 +0x603c:dui4 +0x603f:yi4 +0x6040:chi3 +0x6041:ren4 +0x6042:xun2 +0x6043:shi4 +0x6044:xi4 +0x6045:lao3 +0x6046:heng2 +0x6047:kuang1 +0x6048:mu2 +0x6049:zhi3 +0x604a:xie2 +0x604b:lian4 +0x604c:tiao1 +0x604d:huang3 +0x604e:die2 +0x604f:hao3 +0x6050:kong3 +0x6051:gui3 +0x6052:heng2 +0x6053:xi1 +0x6054:xiao4 +0x6055:shu4 +0x6057:kua3 +0x6058:qiu1 +0x6059:yang4 +0x605a:hui4 +0x605b:hui2 +0x605c:chi4 +0x605d:jia2 +0x605e:yi2 +0x605f:xiong1 +0x6060:guai4 +0x6061:lin4 +0x6062:hui1 +0x6063:zi4 +0x6064:xu4 +0x6065:chi3 +0x6066:xiang4 +0x6067:nv4 +0x6068:hen4 +0x6069:en1 +0x606a:ke4 +0x606b:tong1 +0x606c:tian2 +0x606d:gong1 +0x606e:quan2 +0x606f:xi1 +0x6070:qia4 +0x6071:yue4 +0x6072:peng1 +0x6073:ken3 +0x6074:de2 +0x6075:hui4 +0x6076:e4 +0x6078:tong4 +0x6079:yan4 +0x607a:kai3 +0x607b:ce4 +0x607c:nao3 +0x607d:yun4 +0x607e:mang2 +0x607f:yong3 +0x6080:yong3 +0x6081:yuan1 +0x6082:pi1 +0x6083:kun3 +0x6084:qiao3 +0x6085:yue4 +0x6086:yu4 +0x6087:yu4 +0x6088:jie4 +0x6089:xi1 +0x608a:zhe2 +0x608b:lin4 +0x608c:ti4 +0x608d:han4 +0x608e:hao4 +0x608f:qie4 +0x6090:ti4 +0x6091:bu4 +0x6092:yi4 +0x6093:qian4 +0x6094:hui3 +0x6095:xi1 +0x6096:bei4 +0x6097:man2 +0x6098:yi1 +0x6099:heng1 +0x609a:song3 +0x609b:quan1 +0x609c:cheng3 +0x609d:kui1 +0x609e:wu4 +0x609f:wu4 +0x60a0:you1 +0x60a1:li2 +0x60a2:liang4 +0x60a3:huan4 +0x60a4:cong1 +0x60a5:yi4 +0x60a6:yue4 +0x60a7:li4 +0x60a8:nin2 +0x60a9:nao3 +0x60aa:e4 +0x60ab:que4 +0x60ac:xuan2 +0x60ad:qian1 +0x60ae:wu4 +0x60af:min3 +0x60b0:cong2 +0x60b1:fei3 +0x60b2:bei1 +0x60b3:duo2 +0x60b4:cui4 +0x60b5:chang4 +0x60b6:men4 +0x60b7:li4 +0x60b8:ji4 +0x60b9:guan4 +0x60ba:guan4 +0x60bb:xing4 +0x60bc:dao4 +0x60bd:qi1 +0x60be:kong1 +0x60bf:tian3 +0x60c0:lun2 +0x60c1:xi1 +0x60c2:kan3 +0x60c3:kun1 +0x60c4:ni4 +0x60c5:qing2 +0x60c6:chou2 +0x60c7:dun1 +0x60c8:guo3 +0x60c9:chan1 +0x60ca:liang2 +0x60cb:wan3 +0x60cc:yuan1 +0x60cd:jin1 +0x60ce:ji4 +0x60cf:lin2 +0x60d0:yu4 +0x60d1:huo4 +0x60d2:he2 +0x60d3:quan2 +0x60d4:tan2 +0x60d5:ti4 +0x60d6:ti4 +0x60d7:nie1 +0x60d8:wang3 +0x60d9:chuo4 +0x60da:hu1 +0x60db:hun1 +0x60dc:xi1 +0x60dd:chang3 +0x60de:xin1 +0x60df:wei2 +0x60e0:hui4 +0x60e1:e4 +0x60e2:rui3 +0x60e3:zong3 +0x60e4:jian1 +0x60e5:yong3 +0x60e6:dian4 +0x60e7:ju4 +0x60e8:can3 +0x60e9:cheng2 +0x60ea:de2 +0x60eb:bei4 +0x60ec:qie4 +0x60ed:can2 +0x60ee:dan4 +0x60ef:guan4 +0x60f0:duo4 +0x60f1:nao3 +0x60f2:yun4 +0x60f3:xiang3 +0x60f4:zhui4 +0x60f5:die4 +0x60f6:huang2 +0x60f7:chun3 +0x60f8:qiong2 +0x60f9:re3 +0x60fa:xing1 +0x60fb:ce4 +0x60fc:bian3 +0x60fd:hun1 +0x60fe:zong1 +0x60ff:ti2 +0x6100:qiao3 +0x6101:chou2 +0x6102:bei4 +0x6103:xuan1 +0x6104:wei1 +0x6105:ge2 +0x6106:qian1 +0x6107:wei3 +0x6108:yu4 +0x6109:yu2 +0x610a:bi4 +0x610b:xuan1 +0x610c:huan4 +0x610d:min3 +0x610e:bi4 +0x610f:yi4 +0x6110:mian3 +0x6111:yong3 +0x6112:kai4 +0x6113:dang4 +0x6114:yin1 +0x6115:e4 +0x6116:chen2 +0x6117:mou4 +0x6118:ke4 +0x6119:ke4 +0x611a:yu2 +0x611b:ai4 +0x611c:qie4 +0x611d:yan3 +0x611e:nuo4 +0x611f:gan3 +0x6120:yun4 +0x6121:zong3 +0x6122:sai1 +0x6123:leng4 +0x6124:fen4 +0x6126:kui4 +0x6127:kui4 +0x6128:que4 +0x6129:gong1 +0x612a:yun2 +0x612b:su4 +0x612c:su4 +0x612d:qi2 +0x612e:yao2 +0x612f:song3 +0x6130:huang3 +0x6131:ji2 +0x6132:gu3 +0x6133:ju4 +0x6134:chuang4 +0x6135:ni4 +0x6136:xie2 +0x6137:kai3 +0x6138:zheng3 +0x6139:yong3 +0x613a:cao3 +0x613b:sun4 +0x613c:shen4 +0x613d:bo2 +0x613e:kai4 +0x613f:yuan4 +0x6140:xie2 +0x6141:hun4 +0x6142:yong3 +0x6143:yang3 +0x6144:li4 +0x6145:sao1 +0x6146:tao1 +0x6147:yin1 +0x6148:ci2 +0x6149:xu4 +0x614a:qian4 +0x614b:tai4 +0x614c:huang1 +0x614d:yun4 +0x614e:shen4 +0x614f:ming3 +0x6151:she4 +0x6152:cong2 +0x6153:piao4 +0x6154:mo4 +0x6155:mu4 +0x6156:guo2 +0x6157:chi4 +0x6158:can3 +0x6159:can2 +0x615a:can2 +0x615b:cui2 +0x615c:min3 +0x615d:te4 +0x615e:zhang1 +0x615f:tong4 +0x6160:ao4 +0x6161:shuang3 +0x6162:man4 +0x6163:guan4 +0x6164:que4 +0x6165:zao4 +0x6166:jiu4 +0x6167:hui4 +0x6168:kai3 +0x6169:lian2 +0x616a:ou4 +0x616b:song3 +0x616c:jin3 +0x616d:yin4 +0x616e:lv4 +0x616f:shang1 +0x6170:wei4 +0x6171:tuan2 +0x6172:man2 +0x6173:qian1 +0x6174:she4 +0x6175:yong1 +0x6176:qing4 +0x6177:kang1 +0x6178:di4 +0x6179:zhi2 +0x617a:lou2 +0x617b:juan4 +0x617c:qi1 +0x617d:qi1 +0x617e:yu4 +0x617f:ping2 +0x6180:liao2 +0x6181:cong1 +0x6182:you1 +0x6183:chong1 +0x6184:zhi4 +0x6185:tong4 +0x6186:cheng1 +0x6187:qi4 +0x6188:qu1 +0x6189:peng2 +0x618a:bei4 +0x618b:bie1 +0x618c:chun2 +0x618d:jiao1 +0x618e:zeng1 +0x618f:chi4 +0x6190:lian2 +0x6191:ping2 +0x6192:kui4 +0x6193:hui4 +0x6194:qiao2 +0x6195:cheng2 +0x6196:yin4 +0x6197:yin4 +0x6198:xi3 +0x6199:xi3 +0x619a:dan4 +0x619b:tan2 +0x619c:duo3 +0x619d:dui4 +0x619e:dui4 +0x619f:su4 +0x61a0:jue2 +0x61a1:ce4 +0x61a2:xiao1 +0x61a3:fan2 +0x61a4:fen4 +0x61a5:lao2 +0x61a6:lao4 +0x61a7:chong1 +0x61a8:han1 +0x61a9:qi4 +0x61aa:xian2 +0x61ab:min3 +0x61ac:jing3 +0x61ad:liao3 +0x61ae:wu3 +0x61af:can3 +0x61b0:jue2 +0x61b1:cu4 +0x61b2:xian4 +0x61b3:tan3 +0x61b4:sheng2 +0x61b5:pi1 +0x61b6:yi4 +0x61b7:chu3 +0x61b8:xian1 +0x61b9:nao2 +0x61ba:dan4 +0x61bb:tan3 +0x61bc:jing3 +0x61bd:song1 +0x61be:han4 +0x61bf:jiao1 +0x61c0:wai4 +0x61c1:huan2 +0x61c2:dong3 +0x61c3:qin2 +0x61c4:qin2 +0x61c5:qu2 +0x61c6:cao3 +0x61c7:ken3 +0x61c8:xie4 +0x61c9:ying1 +0x61ca:ao4 +0x61cb:mao4 +0x61cc:yi4 +0x61cd:lin3 +0x61ce:se4 +0x61cf:jun4 +0x61d0:huai2 +0x61d1:men4 +0x61d2:lan3 +0x61d3:ai4 +0x61d4:lin3 +0x61d5:yan1 +0x61d6:gua1 +0x61d7:xia4 +0x61d8:chi4 +0x61d9:yu3 +0x61da:yin4 +0x61db:dai1 +0x61dc:meng4 +0x61dd:ai4 +0x61de:meng2 +0x61df:dui4 +0x61e0:qi2 +0x61e1:mo3 +0x61e2:lan2 +0x61e3:men4 +0x61e4:chou2 +0x61e5:zhi4 +0x61e6:nuo4 +0x61e7:nuo4 +0x61e8:yan1 +0x61e9:yang3 +0x61ea:bo2 +0x61eb:zhi2 +0x61ec:kuang4 +0x61ed:kuang4 +0x61ee:you3 +0x61ef:fu1 +0x61f0:liu2 +0x61f1:mie4 +0x61f2:cheng2 +0x61f4:chan4 +0x61f5:meng3 +0x61f6:lan3 +0x61f7:huai2 +0x61f8:xuan2 +0x61f9:rang4 +0x61fa:chan4 +0x61fb:ji4 +0x61fc:ju4 +0x61fd:huan1 +0x61fe:she4 +0x61ff:yi4 +0x6200:lian4 +0x6201:nan3 +0x6202:mi2 +0x6203:tang3 +0x6204:jue2 +0x6205:gang4 +0x6206:gang4 +0x6207:gang4 +0x6208:ge1 +0x6209:yue4 +0x620a:wu4 +0x620b:jian1 +0x620c:xu1 +0x620d:shu4 +0x620e:rong2 +0x620f:xi4 +0x6210:cheng2 +0x6211:wo3 +0x6212:jie4 +0x6213:ge1 +0x6214:jian1 +0x6215:qiang1 +0x6216:huo4 +0x6217:qiang1 +0x6218:zhan4 +0x6219:dong4 +0x621a:qi1 +0x621b:jia2 +0x621c:die2 +0x621d:zei2 +0x621e:jia2 +0x621f:ji3 +0x6220:shi4 +0x6221:kan1 +0x6222:ji2 +0x6223:kui2 +0x6224:gai4 +0x6225:deng3 +0x6226:zhan4 +0x6227:chuang1 +0x6228:ge1 +0x6229:jian3 +0x622a:jie2 +0x622b:yu4 +0x622c:jian3 +0x622d:yan3 +0x622e:lu4 +0x622f:xi4 +0x6230:zhan4 +0x6231:xi4 +0x6232:xi4 +0x6233:chuo1 +0x6234:dai4 +0x6235:qu2 +0x6236:hu4 +0x6237:hu4 +0x6238:hu4 +0x6239:e4 +0x623a:shi4 +0x623b:li4 +0x623c:mao3 +0x623d:hu4 +0x623e:li4 +0x623f:fang2 +0x6240:suo3 +0x6241:bian3 +0x6242:dian4 +0x6243:jiong1 +0x6244:shang3 +0x6245:yi2 +0x6246:yi3 +0x6247:shan4 +0x6248:hu4 +0x6249:fei1 +0x624a:yan3 +0x624b:shou3 +0x624d:cai2 +0x624e:zha1 +0x624f:qiu2 +0x6250:le4 +0x6251:pu1 +0x6252:ba1 +0x6253:da3 +0x6254:reng1 +0x6255:fu2 +0x6257:zai4 +0x6258:tuo1 +0x6259:zhang4 +0x625a:diao1 +0x625b:kang2 +0x625c:yu1 +0x625d:ku1 +0x625e:han4 +0x625f:shen1 +0x6260:cha1 +0x6261:yi3 +0x6262:gu3 +0x6263:kou4 +0x6264:wu4 +0x6265:tuo1 +0x6266:qian1 +0x6267:zhi2 +0x6268:ren4 +0x6269:kuo4 +0x626a:men2 +0x626b:sao3 +0x626c:yang2 +0x626d:niu3 +0x626e:ban4 +0x626f:che3 +0x6270:rao3 +0x6271:xi1 +0x6272:qian2 +0x6273:ban1 +0x6274:jia2 +0x6275:yu2 +0x6276:fu2 +0x6277:ao4 +0x6278:xi1 +0x6279:pi1 +0x627a:zhi3 +0x627b:zi4 +0x627c:e4 +0x627d:dun4 +0x627e:zhao3 +0x627f:cheng2 +0x6280:ji4 +0x6281:yan3 +0x6282:kuang2 +0x6283:bian4 +0x6284:chao1 +0x6285:ju1 +0x6286:wen4 +0x6287:hu2 +0x6288:yue4 +0x6289:jue2 +0x628a:ba3 +0x628b:qin4 +0x628c:zhen3 +0x628d:zheng3 +0x628e:yun3 +0x628f:wan2 +0x6290:nu4 +0x6291:yi4 +0x6292:shu1 +0x6293:zhua1 +0x6294:pou2 +0x6295:tou2 +0x6296:dou3 +0x6297:kang4 +0x6298:zhe2 +0x6299:pou2 +0x629a:fu3 +0x629b:pao1 +0x629c:ba2 +0x629d:ao3 +0x629e:ze2 +0x629f:tuan2 +0x62a0:kou1 +0x62a1:lun2 +0x62a2:qiang3 +0x62a4:hu4 +0x62a5:bao4 +0x62a6:bing3 +0x62a7:zhi3 +0x62a8:peng1 +0x62a9:tan1 +0x62aa:pu1 +0x62ab:pi1 +0x62ac:tai2 +0x62ad:yao3 +0x62ae:zhen3 +0x62af:zha1 +0x62b0:yang3 +0x62b1:bao4 +0x62b2:he1 +0x62b3:ni3 +0x62b4:yi4 +0x62b5:di3 +0x62b6:chi4 +0x62b7:pi1 +0x62b8:za1 +0x62b9:mo3 +0x62ba:mei4 +0x62bb:shen4 +0x62bc:ya1 +0x62bd:chou1 +0x62be:qu1 +0x62bf:min3 +0x62c0:chu4 +0x62c1:jia1 +0x62c2:fu2 +0x62c3:zhan3 +0x62c4:zhu3 +0x62c5:dan4 +0x62c6:chai1 +0x62c7:mu3 +0x62c8:nian2 +0x62c9:la1 +0x62ca:fu3 +0x62cb:pao1 +0x62cc:ban4 +0x62cd:pai1 +0x62ce:ling1 +0x62cf:na2 +0x62d0:guai3 +0x62d1:qian2 +0x62d2:ju4 +0x62d3:tuo4 +0x62d4:ba2 +0x62d5:tuo1 +0x62d6:tuo1 +0x62d7:ao3 +0x62d8:ju1 +0x62d9:zhuo2 +0x62da:pan4 +0x62db:zhao1 +0x62dc:bai4 +0x62dd:bai4 +0x62de:di3 +0x62df:ni3 +0x62e0:ju4 +0x62e1:kuo4 +0x62e2:long3 +0x62e3:jian3 +0x62e5:yong3 +0x62e6:lan2 +0x62e7:ning2 +0x62e8:bo1 +0x62e9:ze2 +0x62ea:qian1 +0x62eb:hen2 +0x62ec:kuo4 +0x62ed:shi4 +0x62ee:jie2 +0x62ef:zheng3 +0x62f0:nin3 +0x62f1:gong3 +0x62f2:gong3 +0x62f3:quan2 +0x62f4:shuan1 +0x62f5:cun2 +0x62f6:zan3 +0x62f7:kao3 +0x62f8:chi3 +0x62f9:xie2 +0x62fa:ce4 +0x62fb:hui1 +0x62fc:pin1 +0x62fd:ye4 +0x62fe:shi2 +0x62ff:na2 +0x6300:bo4 +0x6301:chi2 +0x6302:gua4 +0x6303:zhi4 +0x6304:kuo4 +0x6305:duo3 +0x6306:duo3 +0x6307:zhi3 +0x6308:qie4 +0x6309:an4 +0x630a:nong4 +0x630b:zhen4 +0x630c:ge2 +0x630d:jiao4 +0x630e:ku1 +0x630f:dong4 +0x6310:ru2 +0x6311:tiao1 +0x6312:lie4 +0x6313:zha1 +0x6314:lv3 +0x6315:die2 +0x6316:wa1 +0x6317:jue2 +0x6319:ju3 +0x631a:zhi4 +0x631b:luan2 +0x631c:ya4 +0x631d:zhua1 +0x631e:ta4 +0x631f:xie2 +0x6320:nao2 +0x6321:dang3 +0x6322:jiao3 +0x6323:zheng1 +0x6324:ji3 +0x6325:hui1 +0x6326:xun2 +0x6328:ai1 +0x6329:tuo1 +0x632a:nuo2 +0x632b:cuo4 +0x632c:bo2 +0x632d:geng3 +0x632e:ti3 +0x632f:zhen4 +0x6330:cheng2 +0x6331:suo1 +0x6332:suo1 +0x6333:keng1 +0x6334:mei3 +0x6335:long4 +0x6336:ju2 +0x6337:peng2 +0x6338:jian3 +0x6339:yi4 +0x633a:ting3 +0x633b:shan1 +0x633c:nuo4 +0x633d:wan3 +0x633e:xie2 +0x633f:cha1 +0x6340:feng1 +0x6341:jiao3 +0x6342:wu3 +0x6343:jun4 +0x6344:jiu4 +0x6345:tong3 +0x6346:kun3 +0x6347:huo4 +0x6348:tu2 +0x6349:zhuo1 +0x634a:pou2 +0x634b:le4 +0x634c:ba1 +0x634d:han4 +0x634e:shao1 +0x634f:nie1 +0x6350:juan1 +0x6351:ze2 +0x6352:song3 +0x6353:ye2 +0x6354:jue2 +0x6355:bu3 +0x6356:huan2 +0x6357:bu4 +0x6358:zun4 +0x6359:yi4 +0x635a:zhai1 +0x635b:lv3 +0x635c:sou1 +0x635d:tuo1 +0x635e:lao1 +0x635f:sun3 +0x6360:bang1 +0x6361:jian3 +0x6362:huan4 +0x6363:dao3 +0x6365:wan4 +0x6366:qin2 +0x6367:peng3 +0x6368:she3 +0x6369:lie4 +0x636a:min2 +0x636b:men2 +0x636c:fu3 +0x636d:bai3 +0x636e:ju4 +0x636f:dao3 +0x6370:wo3 +0x6371:ai2 +0x6372:juan3 +0x6373:yue4 +0x6374:zong3 +0x6375:chen3 +0x6376:chui2 +0x6377:jie2 +0x6378:tu1 +0x6379:ben4 +0x637a:na4 +0x637b:nian3 +0x637c:nuo2 +0x637d:zu2 +0x637e:wo4 +0x637f:xi1 +0x6380:xian1 +0x6381:cheng2 +0x6382:dian1 +0x6383:sao3 +0x6384:lun1 +0x6385:qing4 +0x6386:gang1 +0x6387:duo2 +0x6388:shou4 +0x6389:diao4 +0x638a:pou2 +0x638b:di3 +0x638c:zhang3 +0x638d:gun3 +0x638e:ji3 +0x638f:tao1 +0x6390:qia1 +0x6391:qi2 +0x6392:pai2 +0x6393:shu2 +0x6394:qian1 +0x6395:ling4 +0x6396:ye4 +0x6397:ya4 +0x6398:jue2 +0x6399:zheng1 +0x639a:liang3 +0x639b:gua4 +0x639c:yi3 +0x639d:huo4 +0x639e:shan4 +0x639f:zheng3 +0x63a0:lve4 +0x63a1:cai3 +0x63a2:tan4 +0x63a3:che4 +0x63a4:bing1 +0x63a5:jie1 +0x63a6:ti4 +0x63a7:kong4 +0x63a8:tui1 +0x63a9:yan3 +0x63aa:cuo4 +0x63ab:zou1 +0x63ac:ju2 +0x63ad:tian4 +0x63ae:qian2 +0x63af:ken4 +0x63b0:bai1 +0x63b1:shou3 +0x63b2:jie1 +0x63b3:lu3 +0x63b4:guo2 +0x63b7:zhi2 +0x63b8:dan3 +0x63ba:xian1 +0x63bb:sao1 +0x63bc:guan4 +0x63bd:peng4 +0x63be:yuan4 +0x63bf:nuo4 +0x63c0:jian3 +0x63c1:zhen1 +0x63c2:jiu1 +0x63c3:jian1 +0x63c4:yu2 +0x63c5:yan2 +0x63c6:kui2 +0x63c7:nan3 +0x63c8:hong1 +0x63c9:rou2 +0x63ca:pi4 +0x63cb:wei1 +0x63cc:sai1 +0x63cd:zou4 +0x63ce:xuan1 +0x63cf:miao2 +0x63d0:ti2 +0x63d1:nie1 +0x63d2:cha1 +0x63d3:shi4 +0x63d4:zong3 +0x63d5:zhen4 +0x63d6:yi1 +0x63d7:shun3 +0x63d8:heng2 +0x63d9:bian4 +0x63da:yang2 +0x63db:huan4 +0x63dc:yan3 +0x63dd:zuan4 +0x63de:an3 +0x63df:xu1 +0x63e0:ya4 +0x63e1:wo4 +0x63e2:ke4 +0x63e3:chuai3 +0x63e4:ji2 +0x63e5:ti4 +0x63e6:la2 +0x63e7:la4 +0x63e8:cheng2 +0x63e9:kai1 +0x63ea:jiu1 +0x63eb:jiu1 +0x63ec:tu2 +0x63ed:jie1 +0x63ee:hui1 +0x63ef:geng1 +0x63f0:chong4 +0x63f1:shuo4 +0x63f2:she2 +0x63f3:xie4 +0x63f4:yuan2 +0x63f5:qian2 +0x63f6:ye2 +0x63f7:cha1 +0x63f8:zha1 +0x63f9:bei1 +0x63fa:yao2 +0x63fd:lan3 +0x63fe:wen4 +0x63ff:qin4 +0x6400:chan1 +0x6401:ge1 +0x6402:lou3 +0x6403:zong3 +0x6404:geng1 +0x6405:jiao3 +0x6406:gou4 +0x6407:qin4 +0x6408:yong3 +0x6409:que4 +0x640a:chou1 +0x640b:chi3 +0x640c:zhan3 +0x640d:sun3 +0x640e:sun1 +0x640f:bo2 +0x6410:chu4 +0x6411:rong3 +0x6412:beng4 +0x6413:cuo1 +0x6414:sao1 +0x6415:ke4 +0x6416:yao2 +0x6417:dao3 +0x6418:zhi1 +0x6419:nu4 +0x641a:xie2 +0x641b:jian1 +0x641c:sou1 +0x641d:qiu3 +0x641e:gao3 +0x641f:xian3 +0x6420:shuo4 +0x6421:sang3 +0x6422:jin4 +0x6423:mie4 +0x6424:e4 +0x6425:chui2 +0x6426:nuo4 +0x6427:shan1 +0x6428:ta4 +0x6429:jie2 +0x642a:tang2 +0x642b:pan2 +0x642c:ban1 +0x642d:da1 +0x642e:li4 +0x642f:tao1 +0x6430:hu2 +0x6431:zhi4 +0x6432:wa1 +0x6433:xia2 +0x6434:qian1 +0x6435:wen4 +0x6436:qiang3 +0x6437:tian2 +0x6438:zhen1 +0x6439:e4 +0x643a:xi1 +0x643b:nuo4 +0x643c:quan2 +0x643d:cha2 +0x643e:zha4 +0x643f:ge2 +0x6440:wu3 +0x6441:en4 +0x6442:she4 +0x6443:kang2 +0x6444:she4 +0x6445:shu1 +0x6446:bai3 +0x6447:yao2 +0x6448:bin4 +0x6449:sou1 +0x644a:tan1 +0x644b:sa4 +0x644c:chan3 +0x644d:suo1 +0x644e:liao2 +0x644f:chong1 +0x6450:chuang1 +0x6451:guo2 +0x6452:bing4 +0x6453:feng2 +0x6454:shuai1 +0x6455:di4 +0x6456:qi4 +0x6458:zhai1 +0x6459:lian3 +0x645a:tang2 +0x645b:chi1 +0x645c:guan4 +0x645d:lu4 +0x645e:luo4 +0x645f:lou3 +0x6460:zong3 +0x6461:gai4 +0x6462:hu4 +0x6463:zha1 +0x6464:chuang3 +0x6465:tang4 +0x6466:hua4 +0x6467:cui1 +0x6468:nai2 +0x6469:mo2 +0x646a:jiang1 +0x646b:gui1 +0x646c:ying4 +0x646d:zhi2 +0x646e:ao2 +0x646f:zhi4 +0x6470:nie4 +0x6471:man2 +0x6472:shan4 +0x6473:kou1 +0x6474:shu1 +0x6475:suo3 +0x6476:tuan2 +0x6477:jiao3 +0x6478:mo1 +0x6479:mo2 +0x647a:zhe2 +0x647b:shan3 +0x647c:keng1 +0x647d:piao1 +0x647e:jiang4 +0x647f:yin1 +0x6480:gou4 +0x6481:qian1 +0x6482:liao4 +0x6483:ji2 +0x6484:ying1 +0x6485:jue1 +0x6486:pie1 +0x6487:pie1 +0x6488:lao1 +0x6489:dun1 +0x648a:xian4 +0x648b:ruan2 +0x648c:kui4 +0x648d:zan3 +0x648e:yi4 +0x648f:xun2 +0x6490:cheng1 +0x6491:cheng1 +0x6492:sa1 +0x6493:nao2 +0x6494:heng4 +0x6495:si1 +0x6496:qian3 +0x6497:huang2 +0x6498:da1 +0x6499:zun3 +0x649a:nian3 +0x649b:lin3 +0x649c:zheng3 +0x649d:hui1 +0x649e:zhuang4 +0x649f:jiao3 +0x64a0:ji3 +0x64a1:cao1 +0x64a2:dan3 +0x64a3:dan3 +0x64a4:che4 +0x64a5:bo1 +0x64a6:che3 +0x64a7:jue2 +0x64a8:xiao1 +0x64a9:liao1 +0x64aa:ben4 +0x64ab:fu3 +0x64ac:qiao4 +0x64ad:bo1 +0x64ae:cuo1 +0x64af:zhuo2 +0x64b0:zhuan4 +0x64b1:tuo3 +0x64b2:pu1 +0x64b3:qin4 +0x64b4:dun1 +0x64b5:nian3 +0x64b7:xie2 +0x64b8:lu3 +0x64b9:jiao3 +0x64ba:cuan1 +0x64bb:ta4 +0x64bc:han4 +0x64bd:qiao4 +0x64be:zhua1 +0x64bf:jian3 +0x64c0:gan3 +0x64c1:yong1 +0x64c2:lei2 +0x64c3:kuo3 +0x64c4:lu3 +0x64c5:shan4 +0x64c6:zhuo2 +0x64c7:ze2 +0x64c8:pu1 +0x64c9:chuo4 +0x64ca:ji1 +0x64cb:dang3 +0x64cc:suo3 +0x64cd:cao1 +0x64ce:qing2 +0x64cf:jing4 +0x64d0:huan4 +0x64d1:jie1 +0x64d2:qin2 +0x64d3:kuai3 +0x64d4:dan1 +0x64d5:xi1 +0x64d6:ge3 +0x64d7:pi4 +0x64d8:bo4 +0x64d9:ao4 +0x64da:ju4 +0x64db:ye4 +0x64de:sou3 +0x64df:mi2 +0x64e0:ji3 +0x64e1:tai2 +0x64e2:zhuo2 +0x64e3:dao3 +0x64e4:xing3 +0x64e5:lan3 +0x64e6:ca1 +0x64e7:ju3 +0x64e8:ye2 +0x64e9:ru3 +0x64ea:ye4 +0x64eb:ye4 +0x64ec:ni3 +0x64ed:wo4 +0x64ee:ji2 +0x64ef:bin4 +0x64f0:ning2 +0x64f1:ge1 +0x64f2:zhi4 +0x64f3:jie2 +0x64f4:kuo4 +0x64f5:mo2 +0x64f6:jian4 +0x64f7:xie2 +0x64f8:lie4 +0x64f9:tan1 +0x64fa:bai3 +0x64fb:sou3 +0x64fc:lu3 +0x64fd:lve4 +0x64fe:rao3 +0x64ff:zhi2 +0x6500:pan1 +0x6501:yang3 +0x6502:lei4 +0x6503:sa4 +0x6504:shu1 +0x6505:zan3 +0x6506:nian3 +0x6507:xian3 +0x6508:jun4 +0x6509:huo4 +0x650a:li4 +0x650b:la4 +0x650c:han4 +0x650d:ying2 +0x650e:lu2 +0x650f:long3 +0x6510:qian1 +0x6511:qian1 +0x6512:zan3 +0x6513:qian1 +0x6514:lan2 +0x6515:san1 +0x6516:ying1 +0x6517:mei2 +0x6518:rang4 +0x6519:chan1 +0x651b:cuan1 +0x651c:xie2 +0x651d:she4 +0x651e:luo3 +0x651f:jun4 +0x6520:mi2 +0x6521:li2 +0x6522:zan3 +0x6523:luan2 +0x6524:tan1 +0x6525:zuan4 +0x6526:li4 +0x6527:dian1 +0x6528:wa1 +0x6529:dang3 +0x652a:jiao3 +0x652b:jue2 +0x652c:lan3 +0x652d:li4 +0x652e:nang3 +0x652f:zhi1 +0x6530:gui4 +0x6531:gui3 +0x6532:qi1 +0x6533:xin2 +0x6534:pu1 +0x6535:sui1 +0x6536:shou1 +0x6537:kao3 +0x6538:you1 +0x6539:gai3 +0x653a:yi3 +0x653b:gong1 +0x653c:gan1 +0x653d:ban1 +0x653e:fang4 +0x653f:zheng4 +0x6540:bo2 +0x6541:dian1 +0x6542:kou4 +0x6543:min3 +0x6544:wu4 +0x6545:gu4 +0x6546:he2 +0x6547:ce4 +0x6548:xiao4 +0x6549:mi3 +0x654a:chu4 +0x654b:ge2 +0x654c:di2 +0x654d:xu4 +0x654e:jiao4 +0x654f:min3 +0x6550:chen2 +0x6551:jiu4 +0x6552:zhen4 +0x6553:duo2 +0x6554:yu3 +0x6555:chi4 +0x6556:ao2 +0x6557:bai4 +0x6558:xu4 +0x6559:jiao4 +0x655a:duo2 +0x655b:lian4 +0x655c:nie4 +0x655d:bi4 +0x655e:chang3 +0x655f:dian3 +0x6560:duo2 +0x6561:yi4 +0x6562:gan3 +0x6563:san4 +0x6564:ke3 +0x6565:yan4 +0x6566:dun1 +0x6567:qi3 +0x6568:dou3 +0x6569:xiao4 +0x656a:duo2 +0x656b:jiao4 +0x656c:jing4 +0x656d:yang2 +0x656e:xia2 +0x656f:min2 +0x6570:shu4 +0x6571:ai2 +0x6572:qiao1 +0x6573:ai2 +0x6574:zheng3 +0x6575:di2 +0x6576:zhen4 +0x6577:fu1 +0x6578:shu4 +0x6579:liao2 +0x657a:qu1 +0x657b:xiong4 +0x657c:xi3 +0x657d:jiao3 +0x657f:jiao3 +0x6580:zhuo2 +0x6581:yi4 +0x6582:lian3 +0x6583:bi4 +0x6584:li4 +0x6585:xiao4 +0x6586:xiao4 +0x6587:wen2 +0x6588:xue2 +0x6589:qi2 +0x658a:qi2 +0x658b:zhai1 +0x658c:bin1 +0x658d:jue2 +0x658e:zhai1 +0x6590:fei3 +0x6591:ban1 +0x6592:ban1 +0x6593:lan2 +0x6594:yu3 +0x6595:lan2 +0x6596:wei3 +0x6597:dou3 +0x6598:sheng1 +0x6599:liao4 +0x659a:jia3 +0x659b:hu2 +0x659c:xie2 +0x659d:jia3 +0x659e:yu3 +0x659f:zhen1 +0x65a0:jiao4 +0x65a1:wo4 +0x65a2:tou3 +0x65a3:chu4 +0x65a4:jin1 +0x65a5:chi4 +0x65a6:yin2 +0x65a7:fu3 +0x65a8:qiang1 +0x65a9:zhan3 +0x65aa:qu2 +0x65ab:zhuo2 +0x65ac:zhan3 +0x65ad:duan4 +0x65ae:zhuo2 +0x65af:si1 +0x65b0:xin1 +0x65b1:zhuo2 +0x65b2:zhuo2 +0x65b3:qin2 +0x65b4:lin2 +0x65b5:zhuo2 +0x65b6:chu4 +0x65b7:duan4 +0x65b8:zhu3 +0x65b9:fang1 +0x65ba:xie4 +0x65bb:hang2 +0x65bc:yu2 +0x65bd:shi1 +0x65be:pei4 +0x65bf:you2 +0x65c1:pang2 +0x65c2:qi2 +0x65c3:zhan1 +0x65c4:mao2 +0x65c5:lv3 +0x65c6:pei4 +0x65c7:pi1 +0x65c8:liu2 +0x65c9:fu1 +0x65ca:fang3 +0x65cb:xuan2 +0x65cc:jing1 +0x65cd:jing1 +0x65ce:ni3 +0x65cf:zu2 +0x65d0:zhao4 +0x65d1:yi3 +0x65d2:liu2 +0x65d3:shao1 +0x65d4:jian4 +0x65d6:yi3 +0x65d7:qi2 +0x65d8:zhi4 +0x65d9:fan1 +0x65da:piao1 +0x65db:fan1 +0x65dc:zhan1 +0x65dd:guai4 +0x65de:sui4 +0x65df:yu2 +0x65e0:wu2 +0x65e1:ji4 +0x65e2:ji4 +0x65e3:ji4 +0x65e4:huo4 +0x65e5:ri4 +0x65e6:dan4 +0x65e7:jiu4 +0x65e8:zhi3 +0x65e9:zao3 +0x65ea:xie2 +0x65eb:tiao1 +0x65ec:xun2 +0x65ed:xu4 +0x65ee:xu4 +0x65ef:xu4 +0x65f0:gan4 +0x65f1:han4 +0x65f2:tai2 +0x65f3:di4 +0x65f4:xu1 +0x65f5:chan3 +0x65f6:shi2 +0x65f7:kuang4 +0x65f8:yang2 +0x65f9:shi2 +0x65fa:wang4 +0x65fb:min2 +0x65fc:min2 +0x65fd:tun1 +0x65fe:chun1 +0x65ff:wu3 +0x6600:yun2 +0x6601:bei4 +0x6602:ang2 +0x6603:ze4 +0x6604:ban3 +0x6605:jie2 +0x6606:kun1 +0x6607:sheng1 +0x6608:hu4 +0x6609:fang3 +0x660a:hao4 +0x660b:gui4 +0x660c:chang1 +0x660d:xuan1 +0x660e:ming2 +0x660f:hun1 +0x6610:fen1 +0x6611:qin3 +0x6612:hu1 +0x6613:yi4 +0x6614:xi1 +0x6615:xin1 +0x6616:yan2 +0x6617:ze4 +0x6618:fang3 +0x6619:tan2 +0x661a:shen4 +0x661b:ju4 +0x661c:yang2 +0x661d:zan3 +0x661e:bing3 +0x661f:xing1 +0x6620:ying4 +0x6621:xuan4 +0x6622:pei3 +0x6623:zhen3 +0x6624:ling1 +0x6625:chun1 +0x6626:hao4 +0x6627:mei4 +0x6628:zuo2 +0x6629:mo4 +0x662a:bian4 +0x662b:xu3 +0x662c:hun1 +0x662d:zhao1 +0x662e:zong4 +0x662f:shi4 +0x6630:shi4 +0x6631:yu4 +0x6632:fei4 +0x6633:die2 +0x6634:mao3 +0x6635:ni4 +0x6636:chang3 +0x6637:wen1 +0x6638:dong1 +0x6639:ai3 +0x663a:bing3 +0x663b:ang2 +0x663c:zhou4 +0x663d:long2 +0x663e:xian3 +0x663f:kuang4 +0x6640:tiao3 +0x6641:chao2 +0x6642:shi2 +0x6643:huang3 +0x6644:huang3 +0x6645:xuan1 +0x6646:kui2 +0x6647:xu1 +0x6648:jiao3 +0x6649:jin4 +0x664a:zhi3 +0x664b:jin4 +0x664c:shang3 +0x664d:tong2 +0x664e:hong3 +0x664f:yan4 +0x6650:gai1 +0x6651:xiang3 +0x6652:shai4 +0x6653:xiao3 +0x6654:ye1 +0x6655:yun1 +0x6656:hui1 +0x6657:han2 +0x6658:han4 +0x6659:jun4 +0x665a:wan3 +0x665b:xian4 +0x665c:kun1 +0x665d:zhou4 +0x665e:xi1 +0x665f:sheng4 +0x6660:sheng2 +0x6661:bu1 +0x6662:zhe2 +0x6663:zhe1 +0x6664:wu4 +0x6665:han4 +0x6666:hui4 +0x6667:hao4 +0x6668:chen2 +0x6669:wan3 +0x666a:tian3 +0x666b:zhuo2 +0x666c:zui4 +0x666d:zhou3 +0x666e:pu3 +0x666f:jing3 +0x6670:xi1 +0x6671:shan3 +0x6672:yi3 +0x6673:xi4 +0x6674:qing2 +0x6675:qi3 +0x6676:jing1 +0x6677:gui3 +0x6678:zhen3 +0x6679:yi4 +0x667a:zhi4 +0x667b:an3 +0x667c:wan3 +0x667d:lin2 +0x667e:liang4 +0x667f:chang1 +0x6680:wang3 +0x6681:xiao3 +0x6682:zan4 +0x6684:xuan1 +0x6685:xuan3 +0x6686:yi2 +0x6687:xia2 +0x6688:yun1 +0x6689:hui1 +0x668a:fu3 +0x668b:min3 +0x668c:kui2 +0x668d:he4 +0x668e:ying4 +0x668f:du3 +0x6690:wei3 +0x6691:shu3 +0x6692:qing2 +0x6693:mao4 +0x6694:nan2 +0x6695:jian3 +0x6696:nuan3 +0x6697:an4 +0x6698:yang2 +0x6699:chun1 +0x669a:yao2 +0x669b:suo3 +0x669c:jin4 +0x669d:ming2 +0x669e:jiao3 +0x669f:kai3 +0x66a0:gao3 +0x66a1:weng3 +0x66a2:chang4 +0x66a3:qi4 +0x66a4:hao4 +0x66a5:yan4 +0x66a6:li4 +0x66a7:ai4 +0x66a8:ji4 +0x66a9:gui4 +0x66aa:men3 +0x66ab:zan4 +0x66ac:xie4 +0x66ad:hao4 +0x66ae:mu4 +0x66af:mo4 +0x66b0:cong1 +0x66b1:ni4 +0x66b2:zhang1 +0x66b3:hui4 +0x66b4:bao4 +0x66b5:han4 +0x66b6:xuan2 +0x66b7:chuan2 +0x66b8:liao2 +0x66b9:xian1 +0x66ba:dan4 +0x66bb:jing3 +0x66bc:pie1 +0x66bd:lin2 +0x66be:tun1 +0x66bf:xi3 +0x66c0:yi4 +0x66c1:ji4 +0x66c2:huang4 +0x66c3:tai4 +0x66c4:ye4 +0x66c5:ye4 +0x66c6:li4 +0x66c7:tan2 +0x66c8:tong2 +0x66c9:xiao3 +0x66ca:fei4 +0x66cb:qin3 +0x66cc:zhao4 +0x66cd:hao4 +0x66ce:yi4 +0x66cf:xiang4 +0x66d0:xing1 +0x66d1:sen1 +0x66d2:jiao3 +0x66d3:bao4 +0x66d4:jing4 +0x66d5:yan4 +0x66d6:ai4 +0x66d7:ye4 +0x66d8:ru2 +0x66d9:shu4 +0x66da:meng2 +0x66db:xun1 +0x66dc:yao4 +0x66dd:pu4 +0x66de:li4 +0x66df:chen2 +0x66e0:kuang4 +0x66e1:die2 +0x66e3:yan4 +0x66e4:huo4 +0x66e5:lu2 +0x66e6:xi1 +0x66e7:rong2 +0x66e8:long2 +0x66e9:nang3 +0x66ea:luo3 +0x66eb:luan2 +0x66ec:shai4 +0x66ed:tang3 +0x66ee:yan3 +0x66ef:chu2 +0x66f0:yue1 +0x66f1:yue1 +0x66f2:qu1 +0x66f3:ye4 +0x66f4:geng4 +0x66f5:ye4 +0x66f6:hu1 +0x66f7:he2 +0x66f8:shu1 +0x66f9:cao2 +0x66fa:cao2 +0x66fc:man4 +0x66fd:ceng1 +0x66fe:ceng2 +0x66ff:ti4 +0x6700:zui4 +0x6701:can3 +0x6702:xu4 +0x6703:hui4 +0x6704:yin4 +0x6705:qie4 +0x6706:fen1 +0x6707:pi2 +0x6708:yue4 +0x6709:you3 +0x670a:ruan3 +0x670b:peng2 +0x670c:ban1 +0x670d:fu2 +0x670e:ling2 +0x670f:fei3 +0x6710:qu2 +0x6712:nv4 +0x6713:tiao4 +0x6714:shuo4 +0x6715:zhen4 +0x6716:lang3 +0x6717:lang3 +0x6718:juan1 +0x6719:ming2 +0x671a:huang1 +0x671b:wang4 +0x671c:tun1 +0x671d:zhao1 +0x671e:ji1 +0x671f:qi1 +0x6720:ying1 +0x6721:zong1 +0x6722:wang4 +0x6723:tong2 +0x6724:lang3 +0x6726:meng2 +0x6727:long2 +0x6728:mu4 +0x6729:deng3 +0x672a:wei4 +0x672b:mo4 +0x672c:ben3 +0x672d:zha2 +0x672e:shu4 +0x672f:zhu2 +0x6731:zhu1 +0x6732:ren2 +0x6733:ba1 +0x6734:po4 +0x6735:duo3 +0x6736:duo3 +0x6737:dao1 +0x6738:li4 +0x6739:qiu2 +0x673a:ji1 +0x673b:jiu1 +0x673c:bi3 +0x673d:xiu3 +0x673e:ting2 +0x673f:ci4 +0x6740:sha1 +0x6742:za2 +0x6743:quan2 +0x6744:qian1 +0x6745:yu2 +0x6746:gan1 +0x6747:wu1 +0x6748:cha1 +0x6749:shan1 +0x674a:xun2 +0x674b:fan1 +0x674c:wu4 +0x674d:zi3 +0x674e:li3 +0x674f:xing4 +0x6750:cai2 +0x6751:cun1 +0x6752:ren4 +0x6753:shao2 +0x6754:tuo1 +0x6755:di4 +0x6756:zhang4 +0x6757:mang2 +0x6758:chi4 +0x6759:yi4 +0x675a:gu3 +0x675b:gong1 +0x675c:du4 +0x675d:yi2 +0x675e:qi3 +0x675f:shu4 +0x6760:gang1 +0x6761:tiao2 +0x6765:lai2 +0x6767:mang2 +0x6768:yang2 +0x6769:ma4 +0x676a:miao3 +0x676b:si4 +0x676c:yuan2 +0x676d:hang2 +0x676e:fei4 +0x676f:bei1 +0x6770:jie2 +0x6771:dong1 +0x6772:gao3 +0x6773:yao3 +0x6774:xian1 +0x6775:chu3 +0x6776:chun1 +0x6777:pa2 +0x6778:shu1 +0x6779:hua4 +0x677a:xin1 +0x677b:chou3 +0x677c:zhu4 +0x677d:chou3 +0x677e:song1 +0x677f:ban3 +0x6780:song1 +0x6781:ji2 +0x6782:yue4 +0x6783:jin4 +0x6784:gou1 +0x6785:ji1 +0x6786:mao2 +0x6787:pi2 +0x6788:bi4 +0x6789:wang3 +0x678a:ang4 +0x678b:fang1 +0x678c:fen2 +0x678d:yi4 +0x678e:fu2 +0x678f:nan2 +0x6790:xi1 +0x6791:hu4 +0x6792:ya2 +0x6793:dou3 +0x6794:xun2 +0x6795:zhen3 +0x6796:yao1 +0x6797:lin2 +0x6798:rui4 +0x6799:e3 +0x679a:mei2 +0x679b:zhao4 +0x679c:guo3 +0x679d:zhi1 +0x679e:cong1 +0x679f:yun4 +0x67a1:dou3 +0x67a2:shu1 +0x67a3:zao3 +0x67a5:li4 +0x67a7:jian4 +0x67a8:cheng2 +0x67aa:qiang1 +0x67ab:feng1 +0x67ac:nan2 +0x67ad:xiao1 +0x67ae:xian1 +0x67af:ku1 +0x67b0:ping2 +0x67b1:yi2 +0x67b2:xi3 +0x67b3:zhi1 +0x67b4:guai3 +0x67b5:xiao1 +0x67b6:jia4 +0x67b7:jia1 +0x67b8:ju3 +0x67b9:fu1 +0x67ba:mo4 +0x67bb:yi4 +0x67bc:ye4 +0x67bd:ye4 +0x67be:shi4 +0x67bf:nie4 +0x67c0:bi3 +0x67c1:duo4 +0x67c2:yi2 +0x67c3:ling2 +0x67c4:bing3 +0x67c5:ni3 +0x67c6:la1 +0x67c7:he2 +0x67c8:pan2 +0x67c9:fan2 +0x67ca:zhong1 +0x67cb:dai4 +0x67cc:ci2 +0x67cd:yang1 +0x67ce:fu1 +0x67cf:bai3 +0x67d0:mou3 +0x67d1:gan1 +0x67d2:qi1 +0x67d3:ran3 +0x67d4:rou2 +0x67d5:mao4 +0x67d6:zhao1 +0x67d7:song1 +0x67d8:zhe4 +0x67d9:xia2 +0x67da:you4 +0x67db:shen1 +0x67dc:gui4 +0x67dd:tuo4 +0x67de:zuo4 +0x67df:nan2 +0x67e0:ning2 +0x67e1:yong3 +0x67e2:di3 +0x67e3:zhi2 +0x67e4:zha1 +0x67e5:cha2 +0x67e6:dan4 +0x67e7:gu1 +0x67e9:jiu4 +0x67ea:ao1 +0x67eb:fu2 +0x67ec:jian3 +0x67ed:bo1 +0x67ee:duo4 +0x67ef:ke1 +0x67f0:nai4 +0x67f1:zhu4 +0x67f2:bi4 +0x67f3:liu3 +0x67f4:chai2 +0x67f5:zha4 +0x67f6:si4 +0x67f7:zhu4 +0x67f8:pei1 +0x67f9:shi4 +0x67fa:guai3 +0x67fb:cha2 +0x67fc:yao3 +0x67fd:jue2 +0x67fe:jiu4 +0x67ff:shi4 +0x6800:zhi1 +0x6801:liu3 +0x6802:mei2 +0x6804:rong2 +0x6805:zha4 +0x6807:biao1 +0x6808:zhan4 +0x6809:jie2 +0x680a:long2 +0x680b:dong4 +0x680c:lu2 +0x680e:li4 +0x680f:lan2 +0x6810:yong3 +0x6811:shu4 +0x6812:xun2 +0x6813:shuan1 +0x6814:qi4 +0x6815:zhen1 +0x6816:qi1 +0x6817:li4 +0x6818:yi3 +0x6819:xiang2 +0x681a:zhen4 +0x681b:li4 +0x681c:su4 +0x681d:gua1 +0x681e:kan1 +0x681f:bing1 +0x6820:ren3 +0x6821:xiao4 +0x6822:bo2 +0x6823:ren3 +0x6824:bing4 +0x6825:zi1 +0x6826:chou2 +0x6827:yi4 +0x6828:jie2 +0x6829:xu3 +0x682a:zhu1 +0x682b:jian4 +0x682c:zui4 +0x682d:er2 +0x682e:er3 +0x682f:you3 +0x6830:fa2 +0x6831:gong3 +0x6832:kao3 +0x6833:lao3 +0x6834:zhan1 +0x6835:li4 +0x6837:yang2 +0x6838:he2 +0x6839:gen1 +0x683a:zhi3 +0x683b:shi4 +0x683c:ge2 +0x683d:zai1 +0x683e:luan2 +0x683f:fu2 +0x6840:jie2 +0x6841:heng2 +0x6842:gui4 +0x6843:tao2 +0x6844:guang4 +0x6845:wei2 +0x6846:kuang4 +0x6847:ru2 +0x6848:an4 +0x6849:an1 +0x684a:juan4 +0x684b:yi2 +0x684c:zhuo1 +0x684d:ku1 +0x684e:zhi4 +0x684f:qiong2 +0x6850:tong2 +0x6851:sang1 +0x6852:sang1 +0x6853:huan2 +0x6854:jie2 +0x6855:jiu4 +0x6856:xue4 +0x6857:duo4 +0x6858:zhui4 +0x6859:yu2 +0x685a:zan3 +0x685c:ying1 +0x685f:zhan4 +0x6860:ya2 +0x6861:nao2 +0x6862:zhen1 +0x6863:dang3 +0x6864:qi1 +0x6865:qiao2 +0x6866:hua4 +0x6867:kuai4 +0x6868:jiang3 +0x6869:zhuang1 +0x686a:xun2 +0x686b:suo1 +0x686c:sha1 +0x686d:zhen1 +0x686e:bei1 +0x686f:ting1 +0x6870:gua1 +0x6871:jing4 +0x6872:bo2 +0x6873:ben4 +0x6874:fu2 +0x6875:rui3 +0x6876:tong3 +0x6877:jue2 +0x6878:xi1 +0x6879:lang2 +0x687a:liu3 +0x687b:feng1 +0x687c:qi1 +0x687d:wen3 +0x687e:jun1 +0x687f:gan3 +0x6880:cu4 +0x6881:liang2 +0x6882:qiu2 +0x6883:ting3 +0x6884:you3 +0x6885:mei2 +0x6886:bang1 +0x6887:long4 +0x6888:peng1 +0x6889:zhuang1 +0x688a:di4 +0x688b:xuan1 +0x688c:tu2 +0x688d:zao4 +0x688e:ao1 +0x688f:gu4 +0x6890:bi4 +0x6891:di2 +0x6892:han2 +0x6893:zi3 +0x6894:zhi1 +0x6895:ren4 +0x6896:bei4 +0x6897:geng3 +0x6898:jian4 +0x6899:huan4 +0x689a:wan3 +0x689b:nuo2 +0x689c:jia2 +0x689d:tiao2 +0x689e:ji4 +0x689f:xiao1 +0x68a0:lv3 +0x68a1:hun2 +0x68a2:shao1 +0x68a3:cen2 +0x68a4:fen2 +0x68a5:song1 +0x68a6:meng4 +0x68a7:wu2 +0x68a8:li2 +0x68a9:li2 +0x68aa:dou4 +0x68ab:cen1 +0x68ac:ying3 +0x68ad:suo1 +0x68ae:ju2 +0x68af:ti1 +0x68b0:xie4 +0x68b1:kun3 +0x68b2:zhuo2 +0x68b3:shu1 +0x68b4:chan1 +0x68b5:fan4 +0x68b6:wei3 +0x68b7:jing4 +0x68b8:li2 +0x68b9:bing1 +0x68bc:tao2 +0x68bd:zhi4 +0x68be:lai2 +0x68bf:lian2 +0x68c0:jian3 +0x68c1:zhuo2 +0x68c2:ling2 +0x68c3:li2 +0x68c4:qi4 +0x68c5:bing4 +0x68c6:zhun1 +0x68c7:cong1 +0x68c8:qian4 +0x68c9:mian2 +0x68ca:qi2 +0x68cb:qi2 +0x68cc:cai3 +0x68cd:gun4 +0x68ce:chan2 +0x68cf:te4 +0x68d0:fei3 +0x68d1:pai2 +0x68d2:bang4 +0x68d3:pou3 +0x68d4:hun1 +0x68d5:zong1 +0x68d6:cheng2 +0x68d7:zao3 +0x68d8:ji2 +0x68d9:li4 +0x68da:peng2 +0x68db:yu4 +0x68dc:yu4 +0x68dd:gu4 +0x68de:hun2 +0x68df:dong4 +0x68e0:tang2 +0x68e1:gang1 +0x68e2:wang3 +0x68e3:di4 +0x68e4:xi2 +0x68e5:fan2 +0x68e6:cheng1 +0x68e7:zhan4 +0x68e8:qi3 +0x68e9:yuan1 +0x68ea:yan3 +0x68eb:yu4 +0x68ec:quan1 +0x68ed:yi4 +0x68ee:sen1 +0x68ef:ren3 +0x68f0:chui2 +0x68f1:leng2 +0x68f2:qi1 +0x68f3:zhuo2 +0x68f4:fu2 +0x68f5:ke1 +0x68f6:lai2 +0x68f7:zou1 +0x68f8:zou1 +0x68f9:zhuo1 +0x68fa:guan1 +0x68fb:fen2 +0x68fc:fen2 +0x68fd:chen1 +0x68fe:qiong2 +0x68ff:nie4 +0x6900:wan3 +0x6901:guo3 +0x6902:lu4 +0x6903:hao2 +0x6904:jie1 +0x6905:yi3 +0x6906:chou2 +0x6907:ju3 +0x6908:ju2 +0x6909:cheng2 +0x690a:zuo2 +0x690b:liang2 +0x690c:qiang1 +0x690d:zhi2 +0x690e:zhui1 +0x690f:ya1 +0x6910:ju1 +0x6911:bei1 +0x6912:jiao1 +0x6913:zhuo2 +0x6914:zi1 +0x6915:bin1 +0x6916:peng2 +0x6917:ding4 +0x6918:chu3 +0x691c:jian3 +0x691d:gui1 +0x691e:xi4 +0x691f:du2 +0x6920:qian4 +0x6924:luo2 +0x6925:zhi1 +0x692a:peng4 +0x692b:zhan3 +0x692d:tuo3 +0x692e:sen1 +0x692f:duo2 +0x6930:ye2 +0x6931:fou4 +0x6932:wei3 +0x6933:wei1 +0x6934:duan4 +0x6935:jia3 +0x6936:zong1 +0x6937:jian1 +0x6938:yi2 +0x6939:shen4 +0x693a:xi2 +0x693b:yan4 +0x693c:yan3 +0x693d:chuan2 +0x693e:zhan4 +0x693f:chun1 +0x6940:yu3 +0x6941:he2 +0x6942:zha1 +0x6943:wo4 +0x6944:pian2 +0x6945:bi4 +0x6946:yao1 +0x6947:huo4 +0x6948:xu1 +0x6949:ruo4 +0x694a:yang2 +0x694b:la4 +0x694c:yan2 +0x694d:ben3 +0x694e:hun2 +0x694f:kui2 +0x6950:jie4 +0x6951:kui2 +0x6952:si1 +0x6953:feng1 +0x6954:xie1 +0x6955:tuo3 +0x6956:zhi4 +0x6957:jian4 +0x6958:mu4 +0x6959:mao4 +0x695a:chu3 +0x695b:hu4 +0x695c:hu2 +0x695d:lian4 +0x695e:leng2 +0x695f:ting2 +0x6960:nan2 +0x6961:yu2 +0x6962:you2 +0x6963:mei2 +0x6964:song3 +0x6965:xuan4 +0x6966:xuan4 +0x6967:ying1 +0x6968:zhen1 +0x6969:pian2 +0x696a:ye4 +0x696b:ji2 +0x696c:jie2 +0x696d:ye4 +0x696e:chu3 +0x696f:shun3 +0x6970:yu2 +0x6971:cou4 +0x6972:wei1 +0x6973:mei2 +0x6974:di4 +0x6975:ji2 +0x6976:jie2 +0x6977:kai3 +0x6978:qiu1 +0x6979:ying2 +0x697a:rou2 +0x697b:heng2 +0x697c:lou2 +0x697d:le4 +0x6980:pin3 +0x6982:gai4 +0x6983:tan2 +0x6984:lan3 +0x6985:yun2 +0x6986:yu2 +0x6987:chen4 +0x6988:lv2 +0x6989:ju3 +0x698d:xie4 +0x698e:jia3 +0x698f:yi4 +0x6990:zhan3 +0x6991:fu4 +0x6992:nai4 +0x6993:mi4 +0x6994:lang2 +0x6995:rong2 +0x6996:gu3 +0x6997:jian4 +0x6998:ju3 +0x6999:ta3 +0x699a:yao3 +0x699b:zhen1 +0x699c:bang3 +0x699d:sha1 +0x699e:yuan2 +0x699f:zi3 +0x69a0:ming2 +0x69a1:su4 +0x69a2:jia4 +0x69a3:yao2 +0x69a4:jie2 +0x69a5:huang3 +0x69a6:gan4 +0x69a7:fei3 +0x69a8:zha4 +0x69a9:qian2 +0x69aa:ma4 +0x69ab:sun3 +0x69ac:yuan2 +0x69ad:xie4 +0x69ae:rong2 +0x69af:shi2 +0x69b0:zhi1 +0x69b1:cui1 +0x69b2:yun2 +0x69b3:ting2 +0x69b4:liu2 +0x69b5:rong2 +0x69b6:tang2 +0x69b7:que4 +0x69b8:zhai1 +0x69b9:si1 +0x69ba:sheng4 +0x69bb:ta4 +0x69bc:ke4 +0x69bd:xi1 +0x69be:gu4 +0x69bf:qi1 +0x69c0:kao3 +0x69c1:gao3 +0x69c2:sun1 +0x69c3:pan2 +0x69c4:tao1 +0x69c5:ge2 +0x69c6:xun2 +0x69c7:dian1 +0x69c8:nou4 +0x69c9:ji2 +0x69ca:shuo4 +0x69cb:gou4 +0x69cc:chui2 +0x69cd:qiang1 +0x69ce:cha2 +0x69cf:qian3 +0x69d0:huai2 +0x69d1:mei2 +0x69d2:xu4 +0x69d3:gang4 +0x69d4:gao1 +0x69d5:zhuo2 +0x69d6:tuo4 +0x69d8:yang4 +0x69d9:dian1 +0x69da:jia3 +0x69db:jian4 +0x69dc:zui4 +0x69df:bin1 +0x69e0:zhu1 +0x69e2:xi2 +0x69e3:qi3 +0x69e4:lian2 +0x69e5:hui4 +0x69e6:yong2 +0x69e7:qian4 +0x69e8:guo3 +0x69e9:gai4 +0x69ea:gai4 +0x69eb:tuan2 +0x69ec:hua4 +0x69ed:cu4 +0x69ee:sen1 +0x69ef:cui1 +0x69f0:beng4 +0x69f1:you3 +0x69f2:hu2 +0x69f3:jiang3 +0x69f4:hu4 +0x69f5:huan4 +0x69f6:kui4 +0x69f7:yi4 +0x69f8:nie4 +0x69f9:gao1 +0x69fa:kang1 +0x69fb:gui1 +0x69fc:gui1 +0x69fd:cao2 +0x69fe:man2 +0x69ff:jin3 +0x6a00:di4 +0x6a01:zhuang1 +0x6a02:le4 +0x6a03:lang2 +0x6a04:chen2 +0x6a05:cong1 +0x6a06:li2 +0x6a07:xiu1 +0x6a08:qing2 +0x6a09:shuang3 +0x6a0a:fan2 +0x6a0b:tong1 +0x6a0c:guan4 +0x6a0d:ji1 +0x6a0e:suo1 +0x6a0f:lei3 +0x6a10:lu3 +0x6a11:liang2 +0x6a12:mi4 +0x6a13:lou2 +0x6a14:chao2 +0x6a15:su4 +0x6a16:ke1 +0x6a17:chu1 +0x6a18:tang2 +0x6a19:biao1 +0x6a1a:lu4 +0x6a1b:jiu1 +0x6a1c:shu4 +0x6a1d:zha1 +0x6a1e:shu1 +0x6a1f:zhang1 +0x6a20:men2 +0x6a21:mo2 +0x6a22:niao3 +0x6a23:yang4 +0x6a24:tiao2 +0x6a25:peng2 +0x6a26:zhu4 +0x6a27:sha1 +0x6a28:xi1 +0x6a29:quan2 +0x6a2a:heng2 +0x6a2b:jian1 +0x6a2c:cong1 +0x6a2f:qiang2 +0x6a31:ying1 +0x6a32:er4 +0x6a33:xin2 +0x6a34:zhi2 +0x6a35:qiao2 +0x6a36:zui1 +0x6a37:cong1 +0x6a38:pu2 +0x6a39:shu4 +0x6a3a:hua4 +0x6a3b:kui4 +0x6a3c:zhen1 +0x6a3d:zun1 +0x6a3e:yue4 +0x6a3f:zhan3 +0x6a40:xi1 +0x6a41:xun2 +0x6a42:dian4 +0x6a43:fa1 +0x6a44:gan3 +0x6a45:mo2 +0x6a46:wu3 +0x6a47:qiao1 +0x6a48:nao2 +0x6a49:lin4 +0x6a4a:liu2 +0x6a4b:qiao2 +0x6a4c:xian4 +0x6a4d:run4 +0x6a4e:fan2 +0x6a4f:zhan3 +0x6a50:tuo2 +0x6a51:lao3 +0x6a52:yun2 +0x6a53:shun4 +0x6a54:tui2 +0x6a55:cheng1 +0x6a56:tang2 +0x6a57:meng2 +0x6a58:ju2 +0x6a59:cheng2 +0x6a5a:su4 +0x6a5b:jue2 +0x6a5c:jue2 +0x6a5d:tan1 +0x6a5e:hui4 +0x6a5f:ji1 +0x6a60:nuo3 +0x6a61:xiang4 +0x6a62:tuo3 +0x6a63:ning3 +0x6a64:rui3 +0x6a65:zhu1 +0x6a66:chuang2 +0x6a67:zeng1 +0x6a68:fen2 +0x6a69:qiong2 +0x6a6a:ran3 +0x6a6b:heng2 +0x6a6c:cen2 +0x6a6d:gu1 +0x6a6e:liu3 +0x6a6f:lao4 +0x6a70:gao1 +0x6a71:chu2 +0x6a76:ji2 +0x6a77:dou1 +0x6a79:lu3 +0x6a7c:yuan2 +0x6a7d:ta4 +0x6a7e:shu1 +0x6a7f:jiang1 +0x6a80:tan2 +0x6a81:lin3 +0x6a82:nong2 +0x6a83:yin3 +0x6a84:xi2 +0x6a85:sui4 +0x6a86:shan1 +0x6a87:zui4 +0x6a88:xuan2 +0x6a89:cheng1 +0x6a8a:gan4 +0x6a8b:ju1 +0x6a8c:zui4 +0x6a8d:yi4 +0x6a8e:qin2 +0x6a8f:pu3 +0x6a90:yan2 +0x6a91:lei2 +0x6a92:feng1 +0x6a93:hui3 +0x6a94:dang4 +0x6a95:ji4 +0x6a96:sui4 +0x6a97:bo4 +0x6a98:bi4 +0x6a99:ding3 +0x6a9a:chu3 +0x6a9b:zhua1 +0x6a9c:gui4 +0x6a9d:ji2 +0x6a9e:jie3 +0x6a9f:jia3 +0x6aa0:qing2 +0x6aa1:zhe4 +0x6aa2:jian3 +0x6aa3:qiang2 +0x6aa4:dao4 +0x6aa5:yi3 +0x6aa6:biao3 +0x6aa7:song1 +0x6aa8:she1 +0x6aa9:lin3 +0x6aab:cha2 +0x6aac:meng2 +0x6aad:yin2 +0x6aae:tao2 +0x6aaf:tai2 +0x6ab0:mian2 +0x6ab1:qi2 +0x6ab3:bin1 +0x6ab4:huo4 +0x6ab5:ji4 +0x6ab6:qian1 +0x6ab7:mi2 +0x6ab8:ning2 +0x6ab9:yi1 +0x6aba:gao3 +0x6abb:jian4 +0x6abc:yin4 +0x6abd:er2 +0x6abe:qing3 +0x6abf:yan3 +0x6ac0:qi2 +0x6ac1:mi4 +0x6ac2:zhao4 +0x6ac3:gui4 +0x6ac4:chun1 +0x6ac5:ji1 +0x6ac6:kui2 +0x6ac7:po2 +0x6ac8:deng4 +0x6ac9:chu2 +0x6acb:mian2 +0x6acc:you1 +0x6acd:zhi4 +0x6ace:guang4 +0x6acf:qian1 +0x6ad0:lei3 +0x6ad1:lei3 +0x6ad2:sa4 +0x6ad3:lu3 +0x6ad4:li4 +0x6ad5:cuan2 +0x6ad6:lv2 +0x6ad7:mie4 +0x6ad8:hui4 +0x6ad9:ou1 +0x6ada:lv2 +0x6adb:jie2 +0x6adc:gao1 +0x6add:du2 +0x6ade:yuan2 +0x6adf:li4 +0x6ae0:fei4 +0x6ae1:zhuo2 +0x6ae2:sou3 +0x6ae3:lian2 +0x6ae5:chu2 +0x6ae7:zhu1 +0x6ae8:lu2 +0x6ae9:yan2 +0x6aea:li4 +0x6aeb:zhu1 +0x6aec:chen4 +0x6aed:jie2 +0x6aee:e4 +0x6aef:su1 +0x6af0:huai2 +0x6af1:nie4 +0x6af2:yu4 +0x6af3:long2 +0x6af4:lai4 +0x6af6:xian3 +0x6af8:ju3 +0x6af9:xiao1 +0x6afa:ling2 +0x6afb:ying1 +0x6afc:jian1 +0x6afd:yin3 +0x6afe:you2 +0x6aff:ying2 +0x6b00:xiang1 +0x6b01:nong2 +0x6b02:bo2 +0x6b03:chan2 +0x6b04:lan2 +0x6b05:ju3 +0x6b06:shuang1 +0x6b07:she4 +0x6b08:wei2 +0x6b09:cong4 +0x6b0a:quan2 +0x6b0b:qu2 +0x6b0e:yu4 +0x6b0f:luo2 +0x6b10:li3 +0x6b11:zan4 +0x6b12:luan2 +0x6b13:dang3 +0x6b14:jue2 +0x6b16:lan3 +0x6b17:lan2 +0x6b18:zhu3 +0x6b19:lei2 +0x6b1a:li3 +0x6b1b:ba4 +0x6b1c:nang2 +0x6b1d:yu4 +0x6b1e:ling2 +0x6b20:qian4 +0x6b21:ci4 +0x6b22:huan1 +0x6b23:xin1 +0x6b24:yu2 +0x6b25:yu4 +0x6b26:qian1 +0x6b27:ou1 +0x6b28:xu1 +0x6b29:chao1 +0x6b2a:chu4 +0x6b2b:chi1 +0x6b2c:kai4 +0x6b2d:yi4 +0x6b2e:jue2 +0x6b2f:xi2 +0x6b30:xu1 +0x6b31:xia4 +0x6b32:yu4 +0x6b33:kuai4 +0x6b34:lang2 +0x6b35:kuan3 +0x6b36:shuo4 +0x6b37:xi1 +0x6b38:ai3 +0x6b39:yi1 +0x6b3a:qi1 +0x6b3b:xu1 +0x6b3c:chi3 +0x6b3d:qin1 +0x6b3e:kuan3 +0x6b3f:kan3 +0x6b40:kuan3 +0x6b41:kan3 +0x6b42:chuan2 +0x6b43:sha4 +0x6b45:yin1 +0x6b46:xin1 +0x6b47:xie1 +0x6b48:yu2 +0x6b49:qian4 +0x6b4a:xiao1 +0x6b4b:yi2 +0x6b4c:ge1 +0x6b4d:wu1 +0x6b4e:tan4 +0x6b4f:jin4 +0x6b50:ou1 +0x6b51:hu1 +0x6b52:ti4 +0x6b53:huan1 +0x6b54:xu1 +0x6b55:pen1 +0x6b56:xi1 +0x6b57:xiao4 +0x6b58:xu1 +0x6b59:xi1 +0x6b5b:han1 +0x6b5c:chu4 +0x6b5d:yi4 +0x6b5e:kan3 +0x6b5f:yu2 +0x6b60:chuo4 +0x6b61:huan1 +0x6b62:zhi3 +0x6b63:zheng4 +0x6b64:ci3 +0x6b65:bu4 +0x6b66:wu3 +0x6b67:qi2 +0x6b68:bu4 +0x6b69:bu4 +0x6b6a:wai1 +0x6b6b:ju4 +0x6b6c:qian2 +0x6b6d:chi2 +0x6b6e:se4 +0x6b6f:chi3 +0x6b70:se4 +0x6b71:zhong3 +0x6b72:sui4 +0x6b73:sui4 +0x6b74:li4 +0x6b75:cuo4 +0x6b76:yu2 +0x6b77:li4 +0x6b78:gui1 +0x6b79:dai3 +0x6b7a:dai3 +0x6b7b:si3 +0x6b7c:jian1 +0x6b7d:zhe2 +0x6b7e:mo4 +0x6b7f:mo4 +0x6b80:yao3 +0x6b81:mo4 +0x6b82:cu2 +0x6b83:yang1 +0x6b84:tian3 +0x6b85:sheng1 +0x6b86:dai4 +0x6b87:shang1 +0x6b88:xu4 +0x6b89:xun4 +0x6b8a:shu1 +0x6b8b:can2 +0x6b8c:jue2 +0x6b8d:piao3 +0x6b8e:qia4 +0x6b8f:qiu4 +0x6b90:su4 +0x6b91:qing2 +0x6b92:yun3 +0x6b93:lian4 +0x6b94:yi4 +0x6b95:fou3 +0x6b96:zhi2 +0x6b97:ye4 +0x6b98:can2 +0x6b99:hun1 +0x6b9a:dan1 +0x6b9b:ji2 +0x6b9c:ye4 +0x6b9e:yun3 +0x6b9f:wen1 +0x6ba0:chou4 +0x6ba1:bin4 +0x6ba2:ti4 +0x6ba3:jin4 +0x6ba4:shang1 +0x6ba5:yin2 +0x6ba6:diao1 +0x6ba7:cu4 +0x6ba8:hui4 +0x6ba9:cuan4 +0x6baa:yi4 +0x6bab:dan1 +0x6bac:du4 +0x6bad:jiang1 +0x6bae:lian4 +0x6baf:bin4 +0x6bb0:du2 +0x6bb2:jian1 +0x6bb3:shu1 +0x6bb4:ou1 +0x6bb5:duan4 +0x6bb6:zhu4 +0x6bb7:yin1 +0x6bb8:qing4 +0x6bb9:yi4 +0x6bba:sha1 +0x6bbb:que4 +0x6bbc:ke2 +0x6bbd:yao2 +0x6bbe:jun4 +0x6bbf:dian4 +0x6bc0:hui3 +0x6bc1:hui3 +0x6bc2:gu3 +0x6bc3:que4 +0x6bc4:ji1 +0x6bc5:yi4 +0x6bc6:ou1 +0x6bc7:hui3 +0x6bc8:duan4 +0x6bc9:yi1 +0x6bca:xiao1 +0x6bcb:wu2 +0x6bcc:guan4 +0x6bcd:mu3 +0x6bce:mei3 +0x6bcf:mei3 +0x6bd0:ai3 +0x6bd1:zuo3 +0x6bd2:du2 +0x6bd3:yu4 +0x6bd4:bi3 +0x6bd5:bi4 +0x6bd6:bi4 +0x6bd7:pi2 +0x6bd8:pi2 +0x6bd9:bi4 +0x6bda:chan2 +0x6bdb:mao2 +0x6bde:pu2 +0x6be0:jia1 +0x6be1:zhan1 +0x6be2:sai1 +0x6be3:mu4 +0x6be4:tuo4 +0x6be5:xun2 +0x6be6:er4 +0x6be7:rong2 +0x6be8:xian3 +0x6be9:ju2 +0x6bea:mu2 +0x6beb:hao2 +0x6bec:qiu2 +0x6bed:dou4 +0x6bef:tan3 +0x6bf0:pei2 +0x6bf1:ju2 +0x6bf2:duo2 +0x6bf3:cui4 +0x6bf4:bi1 +0x6bf5:san1 +0x6bf7:mao4 +0x6bf8:sui1 +0x6bf9:shu1 +0x6bfa:yu1 +0x6bfb:tuo4 +0x6bfc:he2 +0x6bfd:jian4 +0x6bfe:ta4 +0x6bff:san1 +0x6c00:lv2 +0x6c01:mu2 +0x6c02:mao2 +0x6c03:tong2 +0x6c04:rong3 +0x6c05:chang3 +0x6c06:pu3 +0x6c07:luo2 +0x6c08:zhan1 +0x6c09:sao4 +0x6c0a:zhan1 +0x6c0b:meng2 +0x6c0c:luo2 +0x6c0d:qu2 +0x6c0e:die2 +0x6c0f:shi4 +0x6c10:di3 +0x6c11:min2 +0x6c12:jue2 +0x6c13:mang2 +0x6c14:qi4 +0x6c15:pie1 +0x6c16:nai3 +0x6c17:qi4 +0x6c18:dao1 +0x6c19:xian1 +0x6c1a:chuan1 +0x6c1b:fen1 +0x6c1c:ri4 +0x6c1d:nei4 +0x6c1f:fu2 +0x6c20:shen1 +0x6c21:dong1 +0x6c22:qing1 +0x6c23:qi4 +0x6c24:yin1 +0x6c25:xi1 +0x6c26:hai4 +0x6c27:yang3 +0x6c28:an1 +0x6c29:ya4 +0x6c2a:ke4 +0x6c2b:qing1 +0x6c2c:ya4 +0x6c2d:dong1 +0x6c2e:dan4 +0x6c2f:lv4 +0x6c30:qing1 +0x6c31:yang3 +0x6c32:yun1 +0x6c33:yun1 +0x6c34:shui3 +0x6c36:zheng3 +0x6c37:bing1 +0x6c38:yong3 +0x6c39:dang4 +0x6c3b:le4 +0x6c3c:ni4 +0x6c3d:tun3 +0x6c3e:fan4 +0x6c3f:gui3 +0x6c40:ting1 +0x6c41:zhi1 +0x6c42:qiu2 +0x6c43:bin1 +0x6c44:ze4 +0x6c45:mian3 +0x6c46:cuan1 +0x6c47:hui4 +0x6c48:diao1 +0x6c49:han4 +0x6c4a:cha4 +0x6c4b:zhuo2 +0x6c4c:chuan4 +0x6c4d:wan2 +0x6c4e:fan4 +0x6c4f:dai4 +0x6c50:xi4 +0x6c51:tuo1 +0x6c52:mang2 +0x6c53:qiu2 +0x6c54:qi4 +0x6c55:shan4 +0x6c56:pai4 +0x6c57:han4 +0x6c58:qian1 +0x6c59:wu1 +0x6c5a:wu1 +0x6c5b:xun4 +0x6c5c:si4 +0x6c5d:ru3 +0x6c5e:gong3 +0x6c5f:jiang1 +0x6c60:chi2 +0x6c61:wu1 +0x6c64:tang1 +0x6c65:zhi1 +0x6c66:chi2 +0x6c67:qian1 +0x6c68:mi4 +0x6c69:gu3 +0x6c6a:wang1 +0x6c6b:qing4 +0x6c6c:jing3 +0x6c6d:rui4 +0x6c6e:jun1 +0x6c6f:hong2 +0x6c70:tai4 +0x6c71:quan3 +0x6c72:ji2 +0x6c73:bian4 +0x6c74:bian4 +0x6c75:gan4 +0x6c76:wen4 +0x6c77:zhong1 +0x6c78:fang1 +0x6c79:xiong1 +0x6c7a:jue2 +0x6c7b:hang3 +0x6c7d:qi4 +0x6c7e:fen2 +0x6c7f:xu4 +0x6c80:xu4 +0x6c81:qin4 +0x6c82:yi2 +0x6c83:wo4 +0x6c84:yun2 +0x6c85:yuan2 +0x6c86:hang2 +0x6c87:yan3 +0x6c88:chen2 +0x6c89:chen2 +0x6c8a:dan4 +0x6c8b:you2 +0x6c8c:dun4 +0x6c8d:hu4 +0x6c8e:huo4 +0x6c8f:qi1 +0x6c90:mu4 +0x6c91:rou2 +0x6c92:mei2 +0x6c93:ta4 +0x6c94:mian3 +0x6c95:wu4 +0x6c96:chong1 +0x6c97:tian1 +0x6c98:bi3 +0x6c99:sha1 +0x6c9a:zhi3 +0x6c9b:pei4 +0x6c9c:pan4 +0x6c9d:zhui3 +0x6c9e:za1 +0x6c9f:gou1 +0x6ca0:liu2 +0x6ca1:mei2 +0x6ca2:ze2 +0x6ca3:feng1 +0x6ca4:ou4 +0x6ca5:li4 +0x6ca6:lun2 +0x6ca7:cang1 +0x6ca8:feng2 +0x6ca9:wei2 +0x6caa:hu4 +0x6cab:mo4 +0x6cac:mei4 +0x6cad:shu4 +0x6cae:ju1 +0x6caf:zan3 +0x6cb0:tuo1 +0x6cb1:tuo2 +0x6cb2:tuo2 +0x6cb3:he2 +0x6cb4:li4 +0x6cb5:mi3 +0x6cb6:yi2 +0x6cb7:fa1 +0x6cb8:fei4 +0x6cb9:you2 +0x6cba:tian2 +0x6cbb:zhi4 +0x6cbc:zhao3 +0x6cbd:gu1 +0x6cbe:zhan1 +0x6cbf:yan2 +0x6cc0:si1 +0x6cc1:kuang4 +0x6cc2:jiong3 +0x6cc3:ju4 +0x6cc4:xie4 +0x6cc5:qiu2 +0x6cc6:yi1 +0x6cc7:jia1 +0x6cc8:zhong1 +0x6cc9:quan2 +0x6cca:bo2 +0x6ccb:hui4 +0x6ccc:mi4 +0x6ccd:ben1 +0x6cce:zhuo2 +0x6ccf:chu4 +0x6cd0:le4 +0x6cd1:you3 +0x6cd2:gu1 +0x6cd3:hong2 +0x6cd4:gan1 +0x6cd5:fa3 +0x6cd6:mao3 +0x6cd7:si4 +0x6cd8:hu1 +0x6cd9:ping2 +0x6cda:ci3 +0x6cdb:fan4 +0x6cdc:chi2 +0x6cdd:su4 +0x6cde:ning4 +0x6cdf:cheng1 +0x6ce0:ling2 +0x6ce1:pao4 +0x6ce2:bo1 +0x6ce3:qi4 +0x6ce4:si4 +0x6ce5:ni2 +0x6ce6:ju2 +0x6ce7:yue4 +0x6ce8:zhu4 +0x6ce9:sheng1 +0x6cea:lei4 +0x6ceb:xuan4 +0x6cec:xue4 +0x6ced:fu1 +0x6cee:pan4 +0x6cef:min3 +0x6cf0:tai4 +0x6cf1:yang1 +0x6cf2:ji3 +0x6cf3:yong3 +0x6cf4:guan4 +0x6cf5:beng4 +0x6cf6:xue2 +0x6cf7:long2 +0x6cf8:lu2 +0x6cfa:bo2 +0x6cfb:xie4 +0x6cfc:po1 +0x6cfd:ze2 +0x6cfe:jing1 +0x6cff:yin2 +0x6d00:zhou1 +0x6d01:ji2 +0x6d02:yi4 +0x6d03:hui1 +0x6d04:hui2 +0x6d05:zui3 +0x6d06:cheng2 +0x6d07:yin1 +0x6d08:wei2 +0x6d09:hou4 +0x6d0a:jian4 +0x6d0b:yang2 +0x6d0c:lie4 +0x6d0d:si4 +0x6d0e:ji4 +0x6d0f:er2 +0x6d10:xing2 +0x6d11:fu2 +0x6d12:sa3 +0x6d13:suo3 +0x6d14:zhi3 +0x6d15:yin1 +0x6d16:wu2 +0x6d17:xi3 +0x6d18:kao3 +0x6d19:zhu1 +0x6d1a:jiang4 +0x6d1b:luo4 +0x6d1d:an4 +0x6d1e:dong4 +0x6d1f:yi2 +0x6d20:mou2 +0x6d21:lei3 +0x6d22:yi1 +0x6d23:mi3 +0x6d24:quan2 +0x6d25:jin1 +0x6d26:mo4 +0x6d27:wei3 +0x6d28:xiao2 +0x6d29:xie4 +0x6d2a:hong2 +0x6d2b:xu4 +0x6d2c:shuo4 +0x6d2d:kuang1 +0x6d2e:tao2 +0x6d2f:qie4 +0x6d30:ju4 +0x6d31:er3 +0x6d32:zhou1 +0x6d33:ru4 +0x6d34:ping2 +0x6d35:xun2 +0x6d36:xiong1 +0x6d37:zhi4 +0x6d38:guang1 +0x6d39:huan2 +0x6d3a:ming2 +0x6d3b:huo2 +0x6d3c:wa1 +0x6d3d:qia4 +0x6d3e:pai4 +0x6d3f:wu1 +0x6d40:qu3 +0x6d41:liu2 +0x6d42:yi4 +0x6d43:jia2 +0x6d44:jing4 +0x6d45:qian3 +0x6d46:jiang1 +0x6d47:jiao1 +0x6d48:cheng2 +0x6d49:shi1 +0x6d4a:zhuo2 +0x6d4b:ce4 +0x6d4d:kuai4 +0x6d4e:ji4 +0x6d4f:liu2 +0x6d50:chan3 +0x6d51:hun2 +0x6d52:hu3 +0x6d53:nong2 +0x6d54:xun2 +0x6d55:jin4 +0x6d56:lie4 +0x6d57:qiu2 +0x6d58:wei3 +0x6d59:zhe4 +0x6d5a:jun4 +0x6d5b:han4 +0x6d5c:bang1 +0x6d5d:mang2 +0x6d5e:zhuo2 +0x6d5f:you2 +0x6d60:xi1 +0x6d61:bo2 +0x6d62:dou4 +0x6d63:wan3 +0x6d64:hong2 +0x6d65:yi4 +0x6d66:pu3 +0x6d67:ying3 +0x6d68:lan3 +0x6d69:hao4 +0x6d6a:lang4 +0x6d6b:han3 +0x6d6c:li3 +0x6d6d:geng1 +0x6d6e:fu2 +0x6d6f:wu2 +0x6d70:lian4 +0x6d71:chun2 +0x6d72:feng2 +0x6d73:yi4 +0x6d74:yu4 +0x6d75:tong2 +0x6d76:lao2 +0x6d77:hai3 +0x6d78:jin4 +0x6d79:jia2 +0x6d7a:chong1 +0x6d7b:weng3 +0x6d7c:mei3 +0x6d7d:sui1 +0x6d7e:cheng1 +0x6d7f:pei4 +0x6d80:xian4 +0x6d81:shen4 +0x6d82:tu2 +0x6d83:kun4 +0x6d84:pin1 +0x6d85:nie4 +0x6d86:han4 +0x6d87:jing1 +0x6d88:xiao1 +0x6d89:she4 +0x6d8a:nian3 +0x6d8b:tu1 +0x6d8c:yong3 +0x6d8d:xiao4 +0x6d8e:xian2 +0x6d8f:ting3 +0x6d90:e2 +0x6d91:su4 +0x6d92:tun1 +0x6d93:juan1 +0x6d94:cen2 +0x6d95:ti4 +0x6d96:li4 +0x6d97:shui4 +0x6d98:si4 +0x6d99:lei4 +0x6d9a:shui4 +0x6d9b:tao1 +0x6d9c:du2 +0x6d9d:lao4 +0x6d9e:lai2 +0x6d9f:lian2 +0x6da0:wei2 +0x6da1:wo1 +0x6da2:yun2 +0x6da3:huan4 +0x6da4:di2 +0x6da6:run4 +0x6da7:jian4 +0x6da8:zhang3 +0x6da9:se4 +0x6daa:fu2 +0x6dab:guan4 +0x6dac:xing4 +0x6dad:shou4 +0x6dae:shuan4 +0x6daf:ya2 +0x6db0:chuo4 +0x6db1:zhang4 +0x6db2:ye4 +0x6db3:kong1 +0x6db4:wo4 +0x6db5:han2 +0x6db6:tuo1 +0x6db7:dong1 +0x6db8:he2 +0x6db9:wo1 +0x6dba:ju1 +0x6dbb:gan4 +0x6dbc:liang2 +0x6dbd:hun1 +0x6dbe:ta4 +0x6dbf:zhuo1 +0x6dc0:dian4 +0x6dc1:qie4 +0x6dc2:de2 +0x6dc3:juan4 +0x6dc4:zi1 +0x6dc5:xi1 +0x6dc6:yao2 +0x6dc7:qi2 +0x6dc8:gu3 +0x6dc9:guo3 +0x6dca:han4 +0x6dcb:lin2 +0x6dcc:tang3 +0x6dcd:zhou1 +0x6dce:peng3 +0x6dcf:hao4 +0x6dd0:chang1 +0x6dd1:shu2 +0x6dd2:qi1 +0x6dd3:fang1 +0x6dd4:chi4 +0x6dd5:lu4 +0x6dd6:nao4 +0x6dd7:ju2 +0x6dd8:tao2 +0x6dd9:cong2 +0x6dda:lei4 +0x6ddb:zhi4 +0x6ddc:peng2 +0x6ddd:fei2 +0x6dde:song1 +0x6ddf:tian3 +0x6de0:pi4 +0x6de1:dan4 +0x6de2:yu4 +0x6de3:ni2 +0x6de4:yu1 +0x6de5:lu4 +0x6de6:gan4 +0x6de7:mi4 +0x6de8:jing4 +0x6de9:ling2 +0x6dea:lun2 +0x6deb:yin2 +0x6dec:cui4 +0x6ded:qu2 +0x6dee:huai2 +0x6def:yu4 +0x6df0:nian3 +0x6df1:shen1 +0x6df2:piao2 +0x6df3:chun2 +0x6df4:wa4 +0x6df5:yuan1 +0x6df6:lai2 +0x6df7:hun4 +0x6df8:qing1 +0x6df9:yan1 +0x6dfa:qian3 +0x6dfb:tian1 +0x6dfc:miao3 +0x6dfd:zhi3 +0x6dfe:yin3 +0x6dff:mi4 +0x6e00:ben1 +0x6e01:yuan1 +0x6e02:wen4 +0x6e03:re4 +0x6e04:fei1 +0x6e05:qing1 +0x6e06:yuan1 +0x6e07:ke3 +0x6e08:ji4 +0x6e09:she4 +0x6e0a:yuan1 +0x6e0c:lu4 +0x6e0d:zi4 +0x6e0e:du2 +0x6e10:jian4 +0x6e11:min3 +0x6e12:pi4 +0x6e14:yu2 +0x6e15:yuan1 +0x6e16:shen3 +0x6e17:shen4 +0x6e18:rou2 +0x6e19:huan4 +0x6e1a:zhu3 +0x6e1b:jian3 +0x6e1c:nuan3 +0x6e1d:yu2 +0x6e1e:qiu2 +0x6e1f:ting2 +0x6e20:qu2 +0x6e21:du4 +0x6e22:feng2 +0x6e23:zha1 +0x6e24:bo2 +0x6e25:wo4 +0x6e26:wo1 +0x6e27:di4 +0x6e28:wei1 +0x6e29:wen1 +0x6e2a:ru2 +0x6e2b:xie4 +0x6e2c:ce4 +0x6e2d:wei4 +0x6e2e:ge1 +0x6e2f:gang3 +0x6e30:yan3 +0x6e31:hong2 +0x6e32:xuan4 +0x6e33:mi3 +0x6e34:ke3 +0x6e35:mao2 +0x6e36:ying1 +0x6e37:yan3 +0x6e38:you2 +0x6e39:hong1 +0x6e3a:miao3 +0x6e3b:xing3 +0x6e3c:mei3 +0x6e3d:zai1 +0x6e3e:hun2 +0x6e3f:nai4 +0x6e40:kui2 +0x6e41:shi2 +0x6e42:e4 +0x6e43:pai4 +0x6e44:mei2 +0x6e45:lian4 +0x6e46:qi4 +0x6e47:qi4 +0x6e48:mei2 +0x6e49:tian2 +0x6e4a:cou4 +0x6e4b:wei2 +0x6e4c:can1 +0x6e4d:tuan1 +0x6e4e:mian3 +0x6e4f:hui4 +0x6e50:mo4 +0x6e51:xu3 +0x6e52:ji2 +0x6e53:pen2 +0x6e54:jian1 +0x6e55:jian3 +0x6e56:hu2 +0x6e57:feng4 +0x6e58:xiang1 +0x6e59:yi4 +0x6e5a:yin4 +0x6e5b:zhan4 +0x6e5c:shi2 +0x6e5d:jie1 +0x6e5e:cheng2 +0x6e5f:huang2 +0x6e60:tan4 +0x6e61:yu2 +0x6e62:bi4 +0x6e63:min3 +0x6e64:shi1 +0x6e65:tu2 +0x6e66:sheng1 +0x6e67:yong3 +0x6e68:qu4 +0x6e69:zhong4 +0x6e6b:jiao3 +0x6e6c:jiao3 +0x6e6e:yin1 +0x6e6f:tang1 +0x6e70:long2 +0x6e71:huo4 +0x6e72:yuan2 +0x6e73:nan3 +0x6e74:ban4 +0x6e75:you3 +0x6e76:quan2 +0x6e77:chui2 +0x6e78:liang4 +0x6e79:chan2 +0x6e7a:yan2 +0x6e7b:chun2 +0x6e7c:nie4 +0x6e7d:zi1 +0x6e7e:wan1 +0x6e7f:shi1 +0x6e80:man3 +0x6e81:ying2 +0x6e83:kui4 +0x6e85:jian4 +0x6e86:xu4 +0x6e87:lv3 +0x6e88:gui1 +0x6e89:gai4 +0x6e8c:po1 +0x6e8d:jin4 +0x6e8e:gui4 +0x6e8f:tang2 +0x6e90:yuan2 +0x6e91:suo3 +0x6e92:yuan2 +0x6e93:lian2 +0x6e94:yao3 +0x6e95:meng4 +0x6e96:zhun3 +0x6e97:sheng2 +0x6e98:ke4 +0x6e99:tai4 +0x6e9a:da2 +0x6e9b:wa1 +0x6e9c:liu1 +0x6e9d:gou1 +0x6e9e:sao1 +0x6e9f:ming2 +0x6ea0:zha4 +0x6ea1:shi2 +0x6ea2:yi4 +0x6ea3:lun2 +0x6ea4:ma3 +0x6ea5:pu3 +0x6ea6:wei2 +0x6ea7:li4 +0x6ea8:cai2 +0x6ea9:wu4 +0x6eaa:xi1 +0x6eab:wen1 +0x6eac:qiang1 +0x6ead:ze2 +0x6eae:shi1 +0x6eaf:su4 +0x6eb0:yi1 +0x6eb1:zhen1 +0x6eb2:sou1 +0x6eb3:yun2 +0x6eb4:xiu4 +0x6eb5:yin1 +0x6eb6:rong2 +0x6eb7:hun4 +0x6eb8:su4 +0x6eb9:su4 +0x6eba:ni4 +0x6ebb:ta4 +0x6ebc:shi1 +0x6ebd:ru4 +0x6ebe:wei1 +0x6ebf:pan4 +0x6ec0:chu4 +0x6ec1:chu2 +0x6ec2:pang1 +0x6ec3:weng3 +0x6ec4:cang1 +0x6ec5:mie4 +0x6ec6:he2 +0x6ec7:dian1 +0x6ec8:hao4 +0x6ec9:huang3 +0x6eca:xi4 +0x6ecb:zi1 +0x6ecc:di2 +0x6ecd:zhi3 +0x6ece:xing2 +0x6ecf:fu3 +0x6ed0:jie2 +0x6ed1:hua2 +0x6ed2:ge1 +0x6ed3:zi3 +0x6ed4:tao1 +0x6ed5:teng2 +0x6ed6:sui1 +0x6ed7:bi3 +0x6ed8:jiao4 +0x6ed9:hui4 +0x6eda:gun3 +0x6edb:yin2 +0x6edc:gao1 +0x6edd:long2 +0x6ede:zhi4 +0x6edf:yan4 +0x6ee0:she4 +0x6ee1:man3 +0x6ee2:ying4 +0x6ee3:chun2 +0x6ee4:lv4 +0x6ee5:lan4 +0x6ee6:luan2 +0x6ee8:bin1 +0x6ee9:tan1 +0x6eea:yu4 +0x6eeb:sou3 +0x6eec:hu4 +0x6eed:bi4 +0x6eee:biao1 +0x6eef:zhi4 +0x6ef0:jiang3 +0x6ef1:kou4 +0x6ef2:shen4 +0x6ef3:shang1 +0x6ef4:di1 +0x6ef5:mi4 +0x6ef6:ao2 +0x6ef7:lu3 +0x6ef8:hu3 +0x6ef9:hu1 +0x6efa:you2 +0x6efb:chan3 +0x6efc:fan4 +0x6efd:yong2 +0x6efe:gun3 +0x6eff:man3 +0x6f00:qing4 +0x6f01:yu2 +0x6f02:piao1 +0x6f03:ji2 +0x6f04:ya2 +0x6f05:jiao3 +0x6f06:qi1 +0x6f07:xi3 +0x6f08:ji4 +0x6f09:lu4 +0x6f0a:lv3 +0x6f0b:long2 +0x6f0c:jin3 +0x6f0d:guo2 +0x6f0e:cong2 +0x6f0f:lou4 +0x6f10:zhi2 +0x6f11:gai4 +0x6f12:qiang2 +0x6f13:li2 +0x6f14:yan3 +0x6f15:cao2 +0x6f16:jiao4 +0x6f17:cong1 +0x6f18:chun2 +0x6f19:tuan2 +0x6f1a:ou4 +0x6f1b:teng2 +0x6f1c:ye3 +0x6f1d:xi2 +0x6f1e:mi4 +0x6f1f:tang2 +0x6f20:mo4 +0x6f21:shang1 +0x6f22:han4 +0x6f23:lian2 +0x6f24:lan3 +0x6f25:wa1 +0x6f26:li2 +0x6f27:qian2 +0x6f28:feng2 +0x6f29:xuan2 +0x6f2a:yi1 +0x6f2b:man4 +0x6f2c:zi4 +0x6f2d:mang3 +0x6f2e:kang1 +0x6f2f:ta4 +0x6f30:peng1 +0x6f31:shu4 +0x6f32:zhang3 +0x6f33:zhang1 +0x6f34:chong2 +0x6f35:xu4 +0x6f36:huan4 +0x6f37:kuo4 +0x6f38:jian4 +0x6f39:yan1 +0x6f3a:chuang3 +0x6f3b:liao2 +0x6f3c:cui3 +0x6f3d:ti2 +0x6f3e:yang4 +0x6f3f:jiang1 +0x6f40:cong2 +0x6f41:ying3 +0x6f42:hong2 +0x6f43:xun2 +0x6f44:shu4 +0x6f45:guan4 +0x6f46:ying2 +0x6f47:xiao1 +0x6f4a:xu4 +0x6f4b:lian4 +0x6f4c:zhi4 +0x6f4d:wei2 +0x6f4e:pi4 +0x6f4f:jue2 +0x6f50:jiao4 +0x6f51:po1 +0x6f52:dang4 +0x6f53:hui4 +0x6f54:jie2 +0x6f55:wu3 +0x6f56:pa2 +0x6f57:ji2 +0x6f58:pan1 +0x6f59:gui2 +0x6f5a:xiao1 +0x6f5b:qian2 +0x6f5c:qian2 +0x6f5d:xi1 +0x6f5e:lu4 +0x6f5f:xi4 +0x6f60:sun4 +0x6f61:dun4 +0x6f62:huang2 +0x6f63:min3 +0x6f64:run4 +0x6f65:su4 +0x6f66:lao3 +0x6f67:zhen1 +0x6f68:zhong1 +0x6f69:yi4 +0x6f6a:di2 +0x6f6b:wan1 +0x6f6c:dan4 +0x6f6d:tan2 +0x6f6e:chao2 +0x6f6f:xun2 +0x6f70:kui4 +0x6f72:shao4 +0x6f73:tu2 +0x6f74:zhu1 +0x6f75:san4 +0x6f76:hei1 +0x6f77:bi3 +0x6f78:shan1 +0x6f79:chan2 +0x6f7a:chan2 +0x6f7b:shu3 +0x6f7c:tong2 +0x6f7d:pu3 +0x6f7e:lin2 +0x6f7f:wei2 +0x6f80:se4 +0x6f81:se4 +0x6f82:cheng2 +0x6f83:jiong4 +0x6f84:cheng2 +0x6f85:hua4 +0x6f86:jiao1 +0x6f87:lao4 +0x6f88:che4 +0x6f89:gan3 +0x6f8a:cun1 +0x6f8b:heng4 +0x6f8c:si1 +0x6f8d:shu4 +0x6f8e:peng2 +0x6f8f:han4 +0x6f90:yun2 +0x6f91:liu4 +0x6f92:hong4 +0x6f93:fu2 +0x6f94:hao4 +0x6f95:he2 +0x6f96:xian1 +0x6f97:jian4 +0x6f98:shan1 +0x6f99:xi4 +0x6f9c:lan2 +0x6f9e:yu2 +0x6f9f:lin3 +0x6fa0:mian3 +0x6fa1:zao3 +0x6fa2:dang1 +0x6fa3:huan3 +0x6fa4:ze2 +0x6fa5:xie4 +0x6fa6:yu4 +0x6fa7:li3 +0x6fa8:shi4 +0x6fa9:xue2 +0x6faa:ling2 +0x6fab:man4 +0x6fac:zi1 +0x6fad:yong1 +0x6fae:kuai4 +0x6faf:can4 +0x6fb0:lian4 +0x6fb1:dian4 +0x6fb2:ye4 +0x6fb3:ao4 +0x6fb4:huan2 +0x6fb5:zhen1 +0x6fb6:chan2 +0x6fb7:man4 +0x6fb8:dan3 +0x6fb9:dan4 +0x6fba:yi4 +0x6fbb:sui4 +0x6fbc:pi4 +0x6fbd:ju4 +0x6fbe:ta4 +0x6fbf:qin2 +0x6fc0:ji1 +0x6fc1:zhuo2 +0x6fc2:lian2 +0x6fc3:nong2 +0x6fc4:guo1 +0x6fc5:jin4 +0x6fc6:fen2 +0x6fc7:se4 +0x6fc8:ji2 +0x6fc9:sui1 +0x6fca:hui4 +0x6fcb:chu3 +0x6fcc:ta4 +0x6fcd:song1 +0x6fce:ding3 +0x6fd0:zhu3 +0x6fd1:lai4 +0x6fd2:bin1 +0x6fd3:lian2 +0x6fd4:mi3 +0x6fd5:shi1 +0x6fd6:shu4 +0x6fd7:mi4 +0x6fd8:ning4 +0x6fd9:ying2 +0x6fda:ying2 +0x6fdb:meng2 +0x6fdc:jin4 +0x6fdd:qi2 +0x6fde:pi4 +0x6fdf:ji4 +0x6fe0:hao2 +0x6fe1:ru2 +0x6fe2:zui3 +0x6fe3:wo4 +0x6fe4:tao1 +0x6fe5:yin4 +0x6fe6:yin3 +0x6fe7:dui4 +0x6fe8:ci2 +0x6fe9:huo4 +0x6fea:jing4 +0x6feb:lan4 +0x6fec:jun4 +0x6fed:ai4 +0x6fee:pu2 +0x6fef:zhuo2 +0x6ff0:wei2 +0x6ff1:bin1 +0x6ff2:gu3 +0x6ff3:qian2 +0x6ff4:xing2 +0x6ff6:kuo4 +0x6ff7:fei4 +0x6ffa:jian4 +0x6ffb:wei3 +0x6ffc:luo4 +0x6ffd:zan4 +0x6ffe:lv4 +0x6fff:li4 +0x7000:you1 +0x7001:yang4 +0x7002:lu3 +0x7003:si4 +0x7004:jie2 +0x7005:ying4 +0x7006:du2 +0x7007:wang3 +0x7008:hui1 +0x7009:xie4 +0x700a:pan2 +0x700b:shen3 +0x700c:biao1 +0x700d:chan2 +0x700e:mo4 +0x700f:liu2 +0x7010:jian1 +0x7011:pu4 +0x7012:se4 +0x7013:cheng2 +0x7014:gu3 +0x7015:bin1 +0x7016:huo4 +0x7017:xian4 +0x7018:lu2 +0x7019:qin1 +0x701a:han4 +0x701b:ying2 +0x701c:yong1 +0x701d:li4 +0x701e:jing4 +0x701f:xiao1 +0x7020:ying2 +0x7021:sui3 +0x7022:wei2 +0x7023:xie4 +0x7024:huai2 +0x7025:hao4 +0x7026:zhu1 +0x7027:long2 +0x7028:lai4 +0x7029:dui4 +0x702a:fan2 +0x702b:hu2 +0x702c:lai4 +0x702f:ying2 +0x7030:mi2 +0x7031:ji4 +0x7032:lian4 +0x7033:jian4 +0x7034:ying3 +0x7035:fen4 +0x7036:lin2 +0x7037:yi4 +0x7038:jian1 +0x7039:yue4 +0x703a:chan2 +0x703b:dai4 +0x703c:rang2 +0x703d:jian3 +0x703e:lan2 +0x703f:fan2 +0x7040:shuang4 +0x7041:yuan1 +0x7042:zhuo2 +0x7043:feng1 +0x7044:she4 +0x7045:lei3 +0x7046:lan2 +0x7047:cong2 +0x7048:qu2 +0x7049:yong1 +0x704a:qian2 +0x704b:fa3 +0x704c:guan4 +0x704d:que4 +0x704e:yan4 +0x704f:hao4 +0x7051:sa3 +0x7052:zan4 +0x7053:luan2 +0x7054:yan4 +0x7055:li2 +0x7056:mi3 +0x7057:shan4 +0x7058:tan1 +0x7059:dang3 +0x705a:jiao3 +0x705b:chan3 +0x705d:hao4 +0x705e:ba4 +0x705f:zhu2 +0x7060:lan3 +0x7061:lan2 +0x7062:nang3 +0x7063:wan1 +0x7064:luan2 +0x7065:xun2 +0x7066:xian3 +0x7067:yan4 +0x7068:gan3 +0x7069:yan4 +0x706a:yu4 +0x706b:huo3 +0x706c:biao1 +0x706d:mie4 +0x706e:guang1 +0x706f:deng1 +0x7070:hui1 +0x7071:xiao1 +0x7072:xiao1 +0x7074:hong2 +0x7075:ling2 +0x7076:zao4 +0x7077:zhuan4 +0x7078:jiu3 +0x7079:zha4 +0x707a:xie4 +0x707b:chi4 +0x707c:zhuo2 +0x707d:zai1 +0x707e:zai1 +0x707f:can4 +0x7080:yang2 +0x7081:qi4 +0x7082:zhong1 +0x7083:fen2 +0x7084:niu3 +0x7085:jiong3 +0x7086:wen2 +0x7087:po4 +0x7088:yi4 +0x7089:lu2 +0x708a:chui1 +0x708b:pi1 +0x708c:kai4 +0x708d:pan4 +0x708e:yan2 +0x708f:kai4 +0x7090:pang4 +0x7091:mu4 +0x7092:chao3 +0x7093:liao4 +0x7094:gui4 +0x7095:kang4 +0x7096:tun2 +0x7097:guang1 +0x7098:xin1 +0x7099:zhi4 +0x709b:guang1 +0x709c:wei3 +0x709d:qiang4 +0x709f:da2 +0x70a0:xia2 +0x70a1:zheng1 +0x70a2:zhu2 +0x70a3:ke3 +0x70a4:zhao4 +0x70a5:fu2 +0x70a6:ba2 +0x70a7:duo4 +0x70a8:duo4 +0x70a9:ling4 +0x70aa:zhuo2 +0x70ab:xuan4 +0x70ac:ju4 +0x70ad:tan4 +0x70ae:pao4 +0x70af:jiong3 +0x70b0:pao2 +0x70b1:tai2 +0x70b2:tai2 +0x70b3:bing3 +0x70b4:yang3 +0x70b5:tong1 +0x70b6:han1 +0x70b7:zhu4 +0x70b8:zha4 +0x70b9:dian3 +0x70ba:wei4 +0x70bb:shi2 +0x70bc:lian4 +0x70bd:chi4 +0x70be:huang3 +0x70c0:hu1 +0x70c1:shuo4 +0x70c2:lan4 +0x70c3:jing3 +0x70c4:jiao3 +0x70c5:xu4 +0x70c6:xing2 +0x70c7:quan4 +0x70c8:lie4 +0x70c9:huan4 +0x70ca:yang2 +0x70cb:xiao1 +0x70cc:xiu1 +0x70cd:xian3 +0x70ce:yin2 +0x70cf:wu1 +0x70d0:zhou1 +0x70d1:yao2 +0x70d2:shi4 +0x70d3:wei1 +0x70d4:tong2 +0x70d5:xue4 +0x70d6:zai1 +0x70d7:kai4 +0x70d8:hong1 +0x70d9:luo4 +0x70da:xia2 +0x70db:zhu2 +0x70dc:xuan3 +0x70dd:zheng1 +0x70de:po4 +0x70df:yan1 +0x70e0:hui3 +0x70e1:guang1 +0x70e2:zhe4 +0x70e3:hui1 +0x70e4:kao3 +0x70e6:fan2 +0x70e7:shao1 +0x70e8:ye4 +0x70e9:hui4 +0x70eb:tang4 +0x70ec:jin4 +0x70ed:re4 +0x70ef:xi1 +0x70f0:fu2 +0x70f1:jiong3 +0x70f2:che4 +0x70f3:pu3 +0x70f4:jing3 +0x70f5:zhuo2 +0x70f6:ting3 +0x70f7:wan2 +0x70f8:hai3 +0x70f9:peng1 +0x70fa:lang3 +0x70fb:shan1 +0x70fc:hu1 +0x70fd:feng1 +0x70fe:chi4 +0x70ff:rong2 +0x7100:hu2 +0x7102:shu2 +0x7103:he4 +0x7104:xun1 +0x7105:ku4 +0x7106:jue2 +0x7107:xiao1 +0x7108:xi1 +0x7109:yan1 +0x710a:han4 +0x710b:zhuang4 +0x710c:jun4 +0x710d:di4 +0x710e:xie4 +0x710f:ji2 +0x7110:wu4 +0x7113:han2 +0x7114:yan4 +0x7115:huan4 +0x7116:men4 +0x7117:ju2 +0x7118:chou2 +0x7119:bei4 +0x711a:fen2 +0x711b:lin4 +0x711c:kun1 +0x711d:hun4 +0x711e:tun1 +0x711f:xi2 +0x7120:cui4 +0x7121:wu2 +0x7122:hong1 +0x7123:ju4 +0x7124:fu3 +0x7125:wo4 +0x7126:jiao1 +0x7127:cong1 +0x7128:feng4 +0x7129:ping1 +0x712a:qiong1 +0x712b:ruo4 +0x712c:xi2 +0x712d:qiong2 +0x712e:xin4 +0x712f:zhuo2 +0x7130:yan4 +0x7131:yan4 +0x7132:yi4 +0x7133:jue2 +0x7134:yu4 +0x7135:gang4 +0x7136:ran2 +0x7137:pi2 +0x7138:gu3 +0x713a:sheng1 +0x713b:chang4 +0x713c:shao1 +0x713f:geng1 +0x7141:chen2 +0x7142:he4 +0x7143:kui3 +0x7144:zhong1 +0x7145:duan4 +0x7146:xia1 +0x7147:hui1 +0x7148:feng4 +0x7149:lian4 +0x714a:xuan1 +0x714b:xing1 +0x714c:huang2 +0x714d:jiao3 +0x714e:jian1 +0x714f:bi4 +0x7150:ying1 +0x7151:zhu3 +0x7152:wei3 +0x7153:tuan1 +0x7154:tian4 +0x7155:xi1 +0x7156:nuan3 +0x7157:nuan3 +0x7158:chan2 +0x7159:yan1 +0x715a:jiong3 +0x715b:jiong3 +0x715c:yu4 +0x715d:mei4 +0x715e:sha1 +0x715f:wei4 +0x7160:ye4 +0x7161:xin4 +0x7162:qiong2 +0x7163:rou3 +0x7164:mei2 +0x7165:huan4 +0x7166:xu3 +0x7167:zhao4 +0x7168:wei1 +0x7169:fan2 +0x716a:qiu2 +0x716b:sui4 +0x716c:yang2 +0x716d:lie4 +0x716e:zhu3 +0x7170:gao4 +0x7171:gua1 +0x7172:bao1 +0x7173:hu2 +0x7174:yun1 +0x7175:xia1 +0x7178:bian1 +0x7179:gou4 +0x717a:tui4 +0x717b:tang2 +0x717c:chao3 +0x717d:shan1 +0x717e:en1 +0x717f:bo2 +0x7180:huang3 +0x7181:xie2 +0x7182:xi4 +0x7183:wu4 +0x7184:xi2 +0x7185:yun4 +0x7186:he2 +0x7187:he4 +0x7188:xi1 +0x7189:yun2 +0x718a:xiong2 +0x718b:nai2 +0x718c:shan4 +0x718e:yao4 +0x718f:xun1 +0x7190:mi4 +0x7191:lian2 +0x7192:ying2 +0x7193:wu3 +0x7194:rong2 +0x7197:qiang4 +0x7198:liu1 +0x7199:xi1 +0x719a:bi4 +0x719b:biao1 +0x719c:zong3 +0x719d:lu4 +0x719e:jian1 +0x719f:shu2 +0x71a0:yi4 +0x71a1:lou2 +0x71a2:feng1 +0x71a3:sui1 +0x71a4:yi4 +0x71a5:tong1 +0x71a6:jue2 +0x71a7:zong1 +0x71a8:yun4 +0x71a9:hu4 +0x71aa:yi2 +0x71ab:zhi4 +0x71ac:ao2 +0x71ad:wei4 +0x71ae:liao2 +0x71af:han4 +0x71b0:ou1 +0x71b1:re4 +0x71b2:jiong3 +0x71b3:man4 +0x71b5:shang1 +0x71b6:cuan4 +0x71b7:zeng1 +0x71b8:jian1 +0x71b9:xi1 +0x71ba:xi1 +0x71bb:xi1 +0x71bc:yi4 +0x71bd:xiao4 +0x71be:chi4 +0x71bf:huang2 +0x71c0:chan3 +0x71c1:ye4 +0x71c2:qian2 +0x71c3:ran2 +0x71c4:yan4 +0x71c5:xian2 +0x71c6:qiao2 +0x71c7:zun4 +0x71c8:deng1 +0x71c9:dun4 +0x71ca:shen1 +0x71cb:jiao1 +0x71cc:fen2 +0x71cd:si1 +0x71ce:liao3 +0x71cf:yu4 +0x71d0:lin2 +0x71d1:tong2 +0x71d2:shao1 +0x71d3:fen1 +0x71d4:fan2 +0x71d5:yan4 +0x71d6:xun2 +0x71d7:lan4 +0x71d8:mei3 +0x71d9:tang4 +0x71da:yi1 +0x71db:jing3 +0x71dc:men4 +0x71df:ying2 +0x71e0:yu4 +0x71e1:yi4 +0x71e2:xue2 +0x71e3:lan2 +0x71e4:tai4 +0x71e5:zao4 +0x71e6:can4 +0x71e7:sui4 +0x71e8:xi1 +0x71e9:que4 +0x71ea:cong1 +0x71eb:lian2 +0x71ec:hui3 +0x71ed:zhu2 +0x71ee:xie4 +0x71ef:ling2 +0x71f0:wei1 +0x71f1:yi4 +0x71f2:xie2 +0x71f3:zhao4 +0x71f4:hui4 +0x71f7:lan2 +0x71f8:ru2 +0x71f9:xian3 +0x71fa:kao3 +0x71fb:xun1 +0x71fc:jin4 +0x71fd:chou2 +0x71fe:dao4 +0x71ff:yao4 +0x7200:he4 +0x7201:lan4 +0x7202:biao1 +0x7203:rong2 +0x7204:li4 +0x7205:mo4 +0x7206:bao4 +0x7207:ruo4 +0x7208:lv2 +0x7209:la4 +0x720a:ao2 +0x720b:xun4 +0x720c:kuang4 +0x720d:shuo4 +0x720f:li4 +0x7210:lu2 +0x7211:jue2 +0x7212:liao4 +0x7213:yan4 +0x7214:xi1 +0x7215:xie4 +0x7216:long2 +0x7217:ye4 +0x7219:rang3 +0x721a:yue4 +0x721b:lan4 +0x721c:cong2 +0x721d:jue2 +0x721e:tong2 +0x721f:guan4 +0x7221:che4 +0x7222:mi2 +0x7223:tang3 +0x7224:lan4 +0x7225:zhu2 +0x7227:ling2 +0x7228:cuan4 +0x7229:yu4 +0x722a:zhua3 +0x722c:pa2 +0x722d:zheng1 +0x722e:pao2 +0x722f:cheng1 +0x7230:yuan2 +0x7231:ai4 +0x7232:wei4 +0x7234:jue2 +0x7235:jue2 +0x7236:fu4 +0x7237:ye2 +0x7238:ba4 +0x7239:die1 +0x723a:ye2 +0x723b:yao2 +0x723c:zu3 +0x723d:shuang3 +0x723e:er3 +0x723f:qiang2 +0x7240:chuang2 +0x7241:ge1 +0x7242:zang1 +0x7243:die2 +0x7244:qiang1 +0x7245:yong2 +0x7246:qiang2 +0x7247:pian4 +0x7248:ban3 +0x7249:pan4 +0x724a:shao2 +0x724b:jian1 +0x724c:pai2 +0x724d:du2 +0x724e:chuang1 +0x724f:tou2 +0x7250:zha2 +0x7251:bian1 +0x7252:die2 +0x7253:bang3 +0x7254:bo2 +0x7255:chuang1 +0x7256:you3 +0x7258:du2 +0x7259:ya2 +0x725a:cheng4 +0x725b:niu2 +0x725d:pin4 +0x725e:jiu1 +0x725f:mou2 +0x7260:tuo2 +0x7261:mu3 +0x7262:lao2 +0x7263:ren4 +0x7264:mang2 +0x7265:fang1 +0x7266:mao2 +0x7267:mu4 +0x7268:gang1 +0x7269:wu4 +0x726a:yan4 +0x726b:ge1 +0x726c:bei4 +0x726d:si4 +0x726e:jian4 +0x726f:gu3 +0x7270:you4 +0x7271:ge1 +0x7272:sheng1 +0x7273:mu3 +0x7274:di3 +0x7275:qian1 +0x7276:quan4 +0x7277:quan2 +0x7278:zi4 +0x7279:te4 +0x727a:xi1 +0x727b:mang2 +0x727c:keng1 +0x727d:qian1 +0x727e:wu2 +0x727f:gu4 +0x7280:xi1 +0x7281:li2 +0x7282:li2 +0x7283:pou3 +0x7284:ji1 +0x7285:gang1 +0x7286:zhi2 +0x7287:ben1 +0x7288:quan2 +0x7289:run2 +0x728a:du2 +0x728b:ju4 +0x728c:jia1 +0x728d:jian1 +0x728e:feng1 +0x728f:pian1 +0x7290:ke1 +0x7291:ju2 +0x7292:kao4 +0x7293:chu2 +0x7294:xi4 +0x7295:bei4 +0x7296:luo4 +0x7297:jie4 +0x7298:ma2 +0x7299:san1 +0x729a:wei4 +0x729b:li2 +0x729c:dun1 +0x729d:tong2 +0x729f:jiang4 +0x72a1:li4 +0x72a2:du2 +0x72a3:lie4 +0x72a4:pi2 +0x72a5:piao3 +0x72a6:bao4 +0x72a7:xi1 +0x72a8:chou1 +0x72a9:wei4 +0x72aa:kui2 +0x72ab:chou1 +0x72ac:quan3 +0x72ae:ba2 +0x72af:fan4 +0x72b0:qiu2 +0x72b1:ji3 +0x72b2:cai2 +0x72b3:chuo2 +0x72b4:an4 +0x72b5:ge1 +0x72b6:zhuang4 +0x72b7:guang3 +0x72b8:ma4 +0x72b9:you2 +0x72ba:kang4 +0x72bb:bo2 +0x72bc:hou3 +0x72bd:ya2 +0x72be:yin2 +0x72bf:huan1 +0x72c0:zhuang4 +0x72c1:yun3 +0x72c2:kuang2 +0x72c3:niu3 +0x72c4:di2 +0x72c5:qing1 +0x72c6:zhong4 +0x72c7:mu4 +0x72c8:bei4 +0x72c9:pi1 +0x72ca:ju2 +0x72cb:ni2 +0x72cc:sheng1 +0x72cd:pao2 +0x72ce:xia2 +0x72cf:tuo2 +0x72d0:hu2 +0x72d1:ling2 +0x72d2:fei4 +0x72d3:pi1 +0x72d4:ni3 +0x72d5:ao3 +0x72d6:you4 +0x72d7:gou3 +0x72d8:yue4 +0x72d9:ju1 +0x72da:dan4 +0x72db:po4 +0x72dc:gu3 +0x72dd:xian3 +0x72de:ning2 +0x72df:huan2 +0x72e0:hen3 +0x72e1:jiao3 +0x72e2:he2 +0x72e3:zhao4 +0x72e4:ji2 +0x72e5:xun4 +0x72e6:shan1 +0x72e7:ta4 +0x72e8:rong2 +0x72e9:shou4 +0x72ea:tong1 +0x72eb:lao3 +0x72ec:du2 +0x72ed:xia2 +0x72ee:shi1 +0x72ef:hua2 +0x72f0:zheng1 +0x72f1:yu4 +0x72f2:sun1 +0x72f3:yu2 +0x72f4:bi4 +0x72f5:mang2 +0x72f6:xi3 +0x72f7:juan4 +0x72f8:li2 +0x72f9:xia2 +0x72fa:yin2 +0x72fb:suan1 +0x72fc:lang2 +0x72fd:bei4 +0x72fe:zhi4 +0x72ff:yan2 +0x7300:sha1 +0x7301:li4 +0x7302:han4 +0x7303:xian3 +0x7304:jing1 +0x7305:pai2 +0x7306:fei1 +0x7307:yao2 +0x7308:ba4 +0x7309:qi2 +0x730a:ni2 +0x730b:biao1 +0x730c:yin4 +0x730d:lai2 +0x730e:xi2 +0x730f:jian1 +0x7310:qiang1 +0x7311:kun1 +0x7312:yan1 +0x7313:guo3 +0x7314:zong4 +0x7315:mi2 +0x7316:chang1 +0x7317:yi1 +0x7318:zhi4 +0x7319:zheng1 +0x731a:ya2 +0x731b:meng3 +0x731c:cai1 +0x731d:cu4 +0x731e:she4 +0x7321:luo2 +0x7322:hu2 +0x7323:zong1 +0x7324:ji4 +0x7325:wei3 +0x7326:feng1 +0x7327:wo1 +0x7328:yuan2 +0x7329:xing1 +0x732a:zhu1 +0x732b:mao1 +0x732c:wei4 +0x732d:yuan2 +0x732e:xian4 +0x732f:tuan1 +0x7330:ya4 +0x7331:nao2 +0x7332:xie1 +0x7333:jia1 +0x7334:hou2 +0x7335:bian1 +0x7336:you2 +0x7337:you2 +0x7338:mei2 +0x7339:zha1 +0x733a:yao2 +0x733b:sun1 +0x733c:bo2 +0x733d:ming2 +0x733e:hua2 +0x733f:yuan2 +0x7340:sou1 +0x7341:ma4 +0x7342:yuan2 +0x7343:dai1 +0x7344:yu4 +0x7345:shi1 +0x7346:hao2 +0x7348:yi4 +0x7349:zhen1 +0x734a:chuang4 +0x734b:hao2 +0x734c:man4 +0x734d:jing4 +0x734e:jiang3 +0x734f:mu2 +0x7350:zhang1 +0x7351:chan2 +0x7352:ao2 +0x7353:ao2 +0x7354:hao2 +0x7355:cui1 +0x7356:fen2 +0x7357:jue2 +0x7358:bi4 +0x7359:bi4 +0x735a:huang2 +0x735b:pu2 +0x735c:lin2 +0x735d:yu4 +0x735e:tong2 +0x735f:yao4 +0x7360:liao2 +0x7361:shuo4 +0x7362:xiao1 +0x7365:xi2 +0x7366:ge2 +0x7367:juan4 +0x7368:du2 +0x7369:hui4 +0x736a:kuai4 +0x736b:xian3 +0x736c:xie4 +0x736d:ta4 +0x736e:xian3 +0x736f:xun1 +0x7370:ning2 +0x7371:pin2 +0x7372:huo4 +0x7373:nou4 +0x7374:meng2 +0x7375:lie4 +0x7376:nao2 +0x7377:guang3 +0x7378:shou4 +0x7379:lu2 +0x737a:ta3 +0x737b:xian4 +0x737c:mi2 +0x737d:rang2 +0x737e:huan1 +0x737f:nao2 +0x7380:luo2 +0x7381:xian3 +0x7382:qi2 +0x7383:jue2 +0x7384:xuan2 +0x7385:miao4 +0x7386:zi1 +0x7387:lv4 +0x7388:lu2 +0x7389:yu4 +0x738a:su4 +0x738b:wang2 +0x738c:qiu2 +0x738d:ga3 +0x738e:ding1 +0x738f:le4 +0x7390:ba1 +0x7391:ji1 +0x7392:hong2 +0x7393:di4 +0x7394:chuan4 +0x7395:gan1 +0x7396:jiu3 +0x7397:yu2 +0x7398:ji3 +0x7399:yu2 +0x739a:yang2 +0x739b:ma3 +0x739c:gong1 +0x739d:wu3 +0x739e:fu1 +0x739f:min2 +0x73a0:jie4 +0x73a1:ya4 +0x73a2:bin1 +0x73a3:bian4 +0x73a4:bang4 +0x73a5:yue4 +0x73a6:jue2 +0x73a7:yun3 +0x73a8:jue2 +0x73a9:wan2 +0x73aa:jian1 +0x73ab:mei2 +0x73ac:dan3 +0x73ad:pi2 +0x73ae:wei3 +0x73af:huan2 +0x73b0:xian4 +0x73b1:qiang1 +0x73b2:ling2 +0x73b3:dai4 +0x73b4:yi4 +0x73b5:an2 +0x73b6:ping2 +0x73b7:dian4 +0x73b8:fu2 +0x73b9:xuan2 +0x73ba:xi3 +0x73bb:bo1 +0x73bc:ci3 +0x73bd:gou3 +0x73be:jia3 +0x73bf:shao2 +0x73c0:po4 +0x73c1:ci2 +0x73c2:ke1 +0x73c3:ran3 +0x73c4:sheng1 +0x73c5:shen1 +0x73c6:yi2 +0x73c7:zu3 +0x73c8:jia1 +0x73c9:min2 +0x73ca:shan1 +0x73cb:liu3 +0x73cc:bi4 +0x73cd:zhen1 +0x73ce:zhen1 +0x73cf:jue2 +0x73d0:fa4 +0x73d1:long2 +0x73d2:jin1 +0x73d3:jiao4 +0x73d4:jian4 +0x73d5:li4 +0x73d6:guang1 +0x73d7:xian1 +0x73d8:zhou1 +0x73d9:gong3 +0x73da:yan1 +0x73db:xiu4 +0x73dc:yang2 +0x73dd:xu3 +0x73de:luo4 +0x73df:su4 +0x73e0:zhu1 +0x73e1:qin2 +0x73e2:ken4 +0x73e3:xun2 +0x73e4:bao3 +0x73e5:er3 +0x73e6:xiang4 +0x73e7:yao2 +0x73e8:xia2 +0x73e9:heng2 +0x73ea:gui1 +0x73eb:chong1 +0x73ec:xu4 +0x73ed:ban1 +0x73ee:pei4 +0x73f0:dang1 +0x73f2:hun2 +0x73f3:wen2 +0x73f4:e2 +0x73f5:cheng2 +0x73f6:di4 +0x73f7:wu3 +0x73f8:wu2 +0x73f9:cheng2 +0x73fa:jun4 +0x73fb:mei2 +0x73fc:bei4 +0x73fd:ting3 +0x73fe:xian4 +0x73ff:chuo4 +0x7400:han2 +0x7401:xuan2 +0x7402:yan2 +0x7403:qiu2 +0x7404:quan3 +0x7405:lang2 +0x7406:li3 +0x7407:xiu4 +0x7408:fu2 +0x7409:liu2 +0x740a:ye2 +0x740b:xi1 +0x740c:ling2 +0x740d:li4 +0x740e:jin4 +0x740f:lian2 +0x7410:suo3 +0x7413:wan2 +0x7414:dian4 +0x7415:pin2 +0x7416:zhan3 +0x7417:cui4 +0x7418:min2 +0x7419:yu4 +0x741a:ju1 +0x741b:chen1 +0x741c:lai2 +0x741d:wen2 +0x741e:sheng4 +0x741f:wei2 +0x7420:dian3 +0x7421:chu4 +0x7422:zhuo2 +0x7423:pei3 +0x7424:cheng1 +0x7425:hu3 +0x7426:qi2 +0x7427:e4 +0x7428:kun1 +0x7429:chang1 +0x742a:qi2 +0x742b:beng3 +0x742c:wan3 +0x742d:lu4 +0x742e:cong2 +0x742f:guan3 +0x7430:yan3 +0x7431:diao1 +0x7432:bei4 +0x7433:lin2 +0x7434:qin2 +0x7435:pi2 +0x7436:pa2 +0x7437:que4 +0x7438:zhuo2 +0x7439:qin2 +0x743a:fa4 +0x743c:qiong2 +0x743d:du3 +0x743e:jie4 +0x743f:hun2 +0x7440:yu3 +0x7441:mao4 +0x7442:mei2 +0x7444:xuan1 +0x7445:ti2 +0x7446:xing1 +0x7447:dai4 +0x7448:rou2 +0x7449:min2 +0x744a:zhen1 +0x744b:wei3 +0x744c:ruan3 +0x744d:huan4 +0x744e:jie1 +0x744f:chuan1 +0x7450:jian3 +0x7451:zhuan4 +0x7452:yang2 +0x7453:lian4 +0x7454:quan2 +0x7455:xia2 +0x7456:duan4 +0x7457:yuan4 +0x7458:ye2 +0x7459:nao3 +0x745a:hu2 +0x745b:ying1 +0x745c:yu2 +0x745d:huang2 +0x745e:rui4 +0x745f:se4 +0x7460:liu2 +0x7462:rong2 +0x7463:suo3 +0x7464:yao2 +0x7465:wen1 +0x7466:wu1 +0x7467:jin1 +0x7468:jin4 +0x7469:ying2 +0x746a:ma3 +0x746b:tao1 +0x746c:liu2 +0x746d:tang2 +0x746e:li4 +0x746f:lang2 +0x7470:gui1 +0x7471:tian4 +0x7472:qiang1 +0x7473:cuo3 +0x7474:jue2 +0x7475:zhao3 +0x7476:yao2 +0x7477:ai4 +0x7478:bin1 +0x7479:tu2 +0x747a:chang2 +0x747b:kun1 +0x747c:zhuan1 +0x747d:cong1 +0x747e:jin3 +0x747f:yi1 +0x7480:cui3 +0x7481:cong1 +0x7482:qi2 +0x7483:li2 +0x7484:ying3 +0x7485:suo3 +0x7486:qiu2 +0x7487:xuan2 +0x7488:ao2 +0x7489:lian2 +0x748a:men2 +0x748b:zhang1 +0x748c:yin2 +0x748e:ying1 +0x748f:zhi4 +0x7490:lu4 +0x7491:wu2 +0x7492:deng1 +0x7494:zeng1 +0x7495:xun2 +0x7496:qu2 +0x7497:dang4 +0x7498:lin2 +0x7499:liao2 +0x749a:qiong2 +0x749b:su4 +0x749c:huang2 +0x749d:gui1 +0x749e:pu2 +0x749f:jing3 +0x74a0:fan2 +0x74a1:jin4 +0x74a2:liu2 +0x74a3:ji1 +0x74a5:jing3 +0x74a6:ai4 +0x74a7:bi4 +0x74a8:can4 +0x74a9:qu2 +0x74aa:zao3 +0x74ab:dang1 +0x74ac:jiao3 +0x74ad:gun4 +0x74ae:tan3 +0x74af:hui4 +0x74b0:huan2 +0x74b1:se4 +0x74b2:sui4 +0x74b3:tian2 +0x74b5:yu2 +0x74b6:jin4 +0x74b7:lu2 +0x74b8:bin1 +0x74b9:shou4 +0x74ba:wen4 +0x74bb:zui3 +0x74bc:lan2 +0x74bd:xi3 +0x74be:ji4 +0x74bf:xuan2 +0x74c0:ruan3 +0x74c1:huo4 +0x74c2:gai4 +0x74c3:lei2 +0x74c4:du2 +0x74c5:li4 +0x74c6:zhi2 +0x74c7:rou2 +0x74c8:li2 +0x74c9:zan4 +0x74ca:qiong2 +0x74cb:zhe2 +0x74cc:gui1 +0x74cd:sui4 +0x74ce:la4 +0x74cf:long2 +0x74d0:lu2 +0x74d1:li4 +0x74d2:zan4 +0x74d3:lan4 +0x74d4:ying1 +0x74d5:mi2 +0x74d6:xiang1 +0x74d7:xi1 +0x74d8:guan4 +0x74d9:dao4 +0x74da:zan4 +0x74db:huan2 +0x74dc:gua1 +0x74dd:bo2 +0x74de:die2 +0x74df:bao2 +0x74e0:hu4 +0x74e1:zhi2 +0x74e2:piao2 +0x74e3:ban4 +0x74e4:rang2 +0x74e5:li4 +0x74e6:wa3 +0x74e8:jiang1 +0x74ea:fan3 +0x74eb:pen2 +0x74ec:fang3 +0x74ed:dan3 +0x74ee:weng4 +0x74ef:ou1 +0x74f3:hu2 +0x74f4:ling2 +0x74f5:yi2 +0x74f6:ping2 +0x74f7:ci2 +0x74f9:juan4 +0x74fa:chang2 +0x74fb:chi1 +0x74fd:dang4 +0x74fe:meng3 +0x74ff:pou3 +0x7500:zhui4 +0x7501:ping2 +0x7502:bian1 +0x7503:zhou4 +0x7504:zhen1 +0x7506:ci2 +0x7507:ying1 +0x7508:qi4 +0x7509:xian2 +0x750a:lou3 +0x750b:di4 +0x750c:ou1 +0x750d:meng2 +0x750e:zhuan1 +0x750f:peng4 +0x7510:lin2 +0x7511:zeng4 +0x7512:wu3 +0x7513:pi4 +0x7514:dan1 +0x7515:weng4 +0x7516:ying1 +0x7517:yan3 +0x7518:gan1 +0x7519:dai4 +0x751a:shen2 +0x751b:tian2 +0x751c:tian2 +0x751d:han1 +0x751e:chang2 +0x751f:sheng1 +0x7520:qing2 +0x7521:shen1 +0x7522:chan3 +0x7523:chan3 +0x7524:rui2 +0x7525:sheng1 +0x7526:su1 +0x7527:sen1 +0x7528:yong4 +0x7529:shuai3 +0x752a:lu4 +0x752b:fu3 +0x752c:yong3 +0x752d:beng2 +0x752e:feng4 +0x752f:ning2 +0x7530:tian2 +0x7531:you2 +0x7532:jia3 +0x7533:shen1 +0x7534:zha2 +0x7535:dian4 +0x7536:fu2 +0x7537:nan2 +0x7538:dian4 +0x7539:ping2 +0x753a:ting3 +0x753b:hua4 +0x753c:ting3 +0x753d:quan3 +0x753e:zi1 +0x753f:meng2 +0x7540:bi4 +0x7541:qi2 +0x7542:liu4 +0x7543:xun2 +0x7544:liu2 +0x7545:chang4 +0x7546:mu3 +0x7547:yun2 +0x7548:fan4 +0x7549:fu2 +0x754a:geng1 +0x754b:tian2 +0x754c:jie4 +0x754d:jie4 +0x754e:quan3 +0x754f:wei4 +0x7550:fu2 +0x7551:tian2 +0x7552:mu3 +0x7554:pan4 +0x7555:jiang1 +0x7556:wa1 +0x7557:da2 +0x7558:nan2 +0x7559:liu2 +0x755a:ben3 +0x755b:zhen3 +0x755c:chu4 +0x755d:mu3 +0x755e:mu3 +0x755f:ce4 +0x7561:gai1 +0x7562:bi4 +0x7563:da2 +0x7564:zhi4 +0x7565:lve4 +0x7566:qi2 +0x7567:lve4 +0x7568:pan1 +0x756a:fan1 +0x756b:hua4 +0x756c:yu2 +0x756d:yu2 +0x756e:mu3 +0x756f:jun4 +0x7570:yi4 +0x7571:liu2 +0x7572:yu2 +0x7573:die2 +0x7574:chou2 +0x7575:hua4 +0x7576:dang1 +0x7577:chuo4 +0x7578:ji1 +0x7579:wan3 +0x757a:jiang1 +0x757b:sheng2 +0x757c:chang4 +0x757d:tuan3 +0x757e:lei2 +0x757f:ji1 +0x7580:cha1 +0x7581:liu2 +0x7583:tuan3 +0x7584:lin2 +0x7585:jiang1 +0x7586:jiang1 +0x7587:chou2 +0x7588:bo4 +0x7589:die2 +0x758a:die2 +0x758b:pi3 +0x758c:nie4 +0x758d:dan4 +0x758e:shu1 +0x758f:shu1 +0x7590:zhi4 +0x7591:yi2 +0x7592:chuang2 +0x7593:nai3 +0x7594:ding1 +0x7595:bi3 +0x7596:jie2 +0x7597:liao2 +0x7598:gang1 +0x7599:ge1 +0x759a:jiu4 +0x759b:zhou3 +0x759c:xia4 +0x759d:shan4 +0x759e:xu1 +0x759f:nve4 +0x75a0:li4 +0x75a1:yang2 +0x75a2:chen4 +0x75a3:you2 +0x75a4:ba1 +0x75a5:jie4 +0x75a6:jue2 +0x75a7:zhi1 +0x75a8:xia1 +0x75a9:cui4 +0x75aa:bi4 +0x75ab:yi4 +0x75ac:li4 +0x75ad:zong4 +0x75ae:chuang1 +0x75af:feng1 +0x75b0:zhu4 +0x75b1:pao4 +0x75b2:pi2 +0x75b3:gan1 +0x75b4:ke1 +0x75b5:ci1 +0x75b6:xie4 +0x75b7:qi2 +0x75b8:dan3 +0x75b9:zhen3 +0x75ba:fa2 +0x75bb:zhi3 +0x75bc:teng2 +0x75bd:ju1 +0x75be:ji2 +0x75bf:fei4 +0x75c0:qu2 +0x75c1:dian4 +0x75c2:jia1 +0x75c3:xian2 +0x75c4:zha4 +0x75c5:bing4 +0x75c6:ni4 +0x75c7:zheng4 +0x75c8:yong1 +0x75c9:jing4 +0x75ca:quan2 +0x75cb:chong2 +0x75cc:tong1 +0x75cd:yi2 +0x75ce:kai1 +0x75cf:wei3 +0x75d0:hui2 +0x75d1:duo3 +0x75d2:yang3 +0x75d3:chi4 +0x75d4:zhi4 +0x75d5:hen2 +0x75d6:ya3 +0x75d7:mei4 +0x75d8:dou4 +0x75d9:jing4 +0x75da:xiao1 +0x75db:tong4 +0x75dc:tu1 +0x75dd:mang2 +0x75de:pi3 +0x75df:xiao1 +0x75e0:suan1 +0x75e1:pu1 +0x75e2:li4 +0x75e3:zhi4 +0x75e4:cuo2 +0x75e5:duo2 +0x75e6:wu4 +0x75e7:sha1 +0x75e8:lao2 +0x75e9:shou4 +0x75ea:huan4 +0x75eb:xian2 +0x75ec:yi4 +0x75ed:peng2 +0x75ee:zhang4 +0x75ef:guan3 +0x75f0:tan2 +0x75f1:fei4 +0x75f2:ma2 +0x75f3:lin2 +0x75f4:chi1 +0x75f5:ji4 +0x75f6:dian3 +0x75f7:an1 +0x75f8:chi4 +0x75f9:bi4 +0x75fa:bi4 +0x75fb:min2 +0x75fc:gu4 +0x75fd:dui1 +0x75fe:e1 +0x75ff:wei3 +0x7600:yu1 +0x7601:cui4 +0x7602:ya3 +0x7603:zhu2 +0x7604:cu4 +0x7605:dan4 +0x7606:shen4 +0x7607:zhong3 +0x7608:ji4 +0x7609:yu4 +0x760a:hou2 +0x760b:feng1 +0x760c:la4 +0x760d:yang2 +0x760e:shen4 +0x760f:tu2 +0x7610:yu3 +0x7611:gua1 +0x7612:wen2 +0x7613:huan4 +0x7614:ku4 +0x7615:jia3 +0x7616:yin1 +0x7617:yi4 +0x7618:lv2 +0x7619:sao1 +0x761a:jue2 +0x761b:chi4 +0x761c:xi2 +0x761d:guan1 +0x761e:yi4 +0x761f:wen1 +0x7620:ji2 +0x7621:chuang1 +0x7622:ban1 +0x7623:lei3 +0x7624:liu2 +0x7625:chai4 +0x7626:shou4 +0x7627:nve4 +0x7628:dian1 +0x7629:da5 +0x762a:pie1 +0x762b:tan1 +0x762c:zhang4 +0x762d:biao1 +0x762e:shen4 +0x762f:cu4 +0x7630:luo3 +0x7631:yi4 +0x7632:zong4 +0x7633:chou1 +0x7634:zhang4 +0x7635:zhai4 +0x7636:sou4 +0x7637:suo3 +0x7638:que2 +0x7639:diao4 +0x763a:lou4 +0x763b:lv2 +0x763c:mo4 +0x763d:jin4 +0x763e:yin3 +0x763f:ying3 +0x7640:huang2 +0x7641:fu2 +0x7642:liao2 +0x7643:long2 +0x7644:qiao2 +0x7645:liu2 +0x7646:lao2 +0x7647:xian2 +0x7648:fei4 +0x7649:dan4 +0x764a:yin4 +0x764b:he4 +0x764c:ai2 +0x764d:ban1 +0x764e:xian2 +0x764f:guan1 +0x7650:guai4 +0x7651:nong2 +0x7652:yu4 +0x7653:wei2 +0x7654:yi4 +0x7655:yong1 +0x7656:pi3 +0x7657:lei3 +0x7658:li4 +0x7659:shu3 +0x765a:dan4 +0x765b:lin3 +0x765c:dian4 +0x765d:lin3 +0x765e:lai4 +0x765f:bie3 +0x7660:ji4 +0x7661:chi1 +0x7662:yang3 +0x7663:xian3 +0x7664:jie2 +0x7665:zheng1 +0x7667:li4 +0x7668:huo4 +0x7669:lai4 +0x766b:dian1 +0x766c:xuan3 +0x766d:ying3 +0x766e:yin3 +0x766f:qu2 +0x7670:yong1 +0x7671:tan1 +0x7672:dian1 +0x7673:luo3 +0x7674:luan2 +0x7675:luan2 +0x7676:bo1 +0x7678:gui3 +0x7679:po1 +0x767a:fa1 +0x767b:deng1 +0x767c:fa1 +0x767d:bai2 +0x767e:bai3 +0x767f:qie2 +0x7680:bi1 +0x7681:zao4 +0x7682:zao4 +0x7683:mao4 +0x7684:de5 +0x7685:pa1 +0x7686:jie1 +0x7687:huang2 +0x7688:gui1 +0x7689:ci3 +0x768a:ling2 +0x768b:gao1 +0x768c:mo4 +0x768d:ji2 +0x768e:jiao3 +0x768f:peng3 +0x7690:gao1 +0x7691:ai2 +0x7692:e2 +0x7693:hao4 +0x7694:han4 +0x7695:bi1 +0x7696:wan3 +0x7697:chou2 +0x7698:qian4 +0x7699:xi1 +0x769a:ai2 +0x769b:jiong3 +0x769c:hao4 +0x769d:huang3 +0x769e:hao4 +0x769f:ze2 +0x76a0:cui3 +0x76a1:hao4 +0x76a2:xiao3 +0x76a3:ye4 +0x76a4:po2 +0x76a5:hao4 +0x76a6:jiao3 +0x76a7:ai4 +0x76a8:xing1 +0x76a9:huang4 +0x76aa:li4 +0x76ab:piao3 +0x76ac:he4 +0x76ad:jiao4 +0x76ae:pi2 +0x76af:gan3 +0x76b0:pao4 +0x76b1:zhou4 +0x76b2:jun1 +0x76b3:qiu2 +0x76b4:cun1 +0x76b5:que4 +0x76b6:zha1 +0x76b7:gu3 +0x76b8:jun1 +0x76b9:jun1 +0x76ba:zhou4 +0x76bb:zha1 +0x76bc:gu3 +0x76bd:zhan3 +0x76be:du2 +0x76bf:min3 +0x76c0:qi3 +0x76c1:ying2 +0x76c2:yu2 +0x76c3:bei1 +0x76c4:zhao1 +0x76c5:zhong1 +0x76c6:pen2 +0x76c7:he2 +0x76c8:ying2 +0x76c9:he2 +0x76ca:yi4 +0x76cb:bo1 +0x76cc:wan3 +0x76cd:he2 +0x76ce:ang4 +0x76cf:zhan3 +0x76d0:yan2 +0x76d1:jian1 +0x76d2:he2 +0x76d3:yu1 +0x76d4:kui1 +0x76d5:fan4 +0x76d6:gai4 +0x76d7:dao4 +0x76d8:pan2 +0x76d9:fu3 +0x76da:qiu2 +0x76db:sheng4 +0x76dc:dao4 +0x76dd:lu4 +0x76de:zhan3 +0x76df:meng2 +0x76e0:li3 +0x76e1:jin4 +0x76e2:xu4 +0x76e3:jian1 +0x76e4:pan2 +0x76e5:guan4 +0x76e6:an1 +0x76e7:lu2 +0x76e8:shu3 +0x76e9:zhou1 +0x76ea:dang4 +0x76eb:an1 +0x76ec:gu3 +0x76ed:li4 +0x76ee:mu4 +0x76ef:ding1 +0x76f0:gan3 +0x76f1:xu1 +0x76f2:mang2 +0x76f3:mang2 +0x76f4:zhi2 +0x76f5:qi4 +0x76f6:ruan3 +0x76f7:tian2 +0x76f8:xiang1 +0x76f9:dun3 +0x76fa:xin1 +0x76fb:xi4 +0x76fc:pan4 +0x76fd:feng1 +0x76fe:dun4 +0x76ff:min2 +0x7700:ming2 +0x7701:sheng3 +0x7702:shi4 +0x7703:yun2 +0x7704:mian3 +0x7705:pan1 +0x7706:fang3 +0x7707:miao3 +0x7708:dan1 +0x7709:mei2 +0x770a:mao4 +0x770b:kan4 +0x770c:xian4 +0x770d:ou1 +0x770e:shi4 +0x770f:yang1 +0x7710:zheng1 +0x7711:yao3 +0x7712:shen4 +0x7713:huo4 +0x7714:da4 +0x7715:zhen3 +0x7716:kuang4 +0x7717:ju1 +0x7718:shen4 +0x7719:chi4 +0x771a:sheng3 +0x771b:mei4 +0x771c:mo4 +0x771d:zhu4 +0x771e:zhen1 +0x771f:zhen1 +0x7720:mian2 +0x7721:di1 +0x7722:yuan1 +0x7723:die2 +0x7724:yi2 +0x7725:zi4 +0x7726:zi4 +0x7727:chao3 +0x7728:zha3 +0x7729:xuan4 +0x772a:bing3 +0x772b:mi3 +0x772c:long2 +0x772d:sui1 +0x772e:dong4 +0x772f:mi3 +0x7730:die2 +0x7731:yi2 +0x7732:er4 +0x7733:ming3 +0x7734:xuan4 +0x7735:chi1 +0x7736:kuang4 +0x7737:juan4 +0x7738:mou2 +0x7739:zhen4 +0x773a:tiao4 +0x773b:yang2 +0x773c:yan3 +0x773d:mo4 +0x773e:zhong4 +0x773f:mai4 +0x7740:zhao2 +0x7741:zheng1 +0x7742:mei2 +0x7743:jun4 +0x7744:shao4 +0x7745:han4 +0x7746:huan3 +0x7747:di4 +0x7748:cheng3 +0x7749:cuo1 +0x774a:juan4 +0x774b:e2 +0x774c:wan3 +0x774d:xian4 +0x774e:xi1 +0x774f:kun4 +0x7750:lai4 +0x7751:jian3 +0x7752:shan3 +0x7753:tian3 +0x7754:hun3 +0x7755:wan3 +0x7756:ling2 +0x7757:shi4 +0x7758:qiong2 +0x7759:lie4 +0x775a:yai2 +0x775b:jing1 +0x775c:zheng1 +0x775d:li2 +0x775e:lai4 +0x775f:sui4 +0x7760:juan4 +0x7761:shui4 +0x7762:sui1 +0x7763:du1 +0x7764:bi4 +0x7765:bi4 +0x7766:mu4 +0x7767:hun1 +0x7768:ni4 +0x7769:lu4 +0x776a:yi4 +0x776b:jie2 +0x776c:cai3 +0x776d:zhou3 +0x776e:yu2 +0x776f:hun1 +0x7770:ma4 +0x7771:xia4 +0x7772:xing3 +0x7773:xi1 +0x7774:gun4 +0x7776:chun3 +0x7777:jian1 +0x7778:mei4 +0x7779:du3 +0x777a:hou2 +0x777b:xuan1 +0x777c:ti4 +0x777d:kui2 +0x777e:gao1 +0x777f:rui4 +0x7780:mao4 +0x7781:xu4 +0x7782:fa1 +0x7783:wen1 +0x7784:miao2 +0x7785:chou3 +0x7786:kui4 +0x7787:mi1 +0x7788:weng3 +0x7789:kou4 +0x778a:dang4 +0x778b:chen1 +0x778c:ke1 +0x778d:sou3 +0x778e:xia1 +0x778f:qiong2 +0x7790:mao4 +0x7791:ming2 +0x7792:man2 +0x7793:shui4 +0x7794:ze2 +0x7795:zhang4 +0x7796:yi4 +0x7797:diao1 +0x7798:ou1 +0x7799:mo4 +0x779a:shun4 +0x779b:cong1 +0x779c:lou1 +0x779d:chi1 +0x779e:man2 +0x779f:piao3 +0x77a0:cheng1 +0x77a1:ji4 +0x77a2:meng2 +0x77a4:run2 +0x77a5:pie1 +0x77a6:xi1 +0x77a7:qiao2 +0x77a8:pu2 +0x77a9:zhu3 +0x77aa:deng4 +0x77ab:shen3 +0x77ac:shun4 +0x77ad:liao3 +0x77ae:che4 +0x77af:xian2 +0x77b0:kan4 +0x77b1:ye4 +0x77b2:xu4 +0x77b3:tong2 +0x77b4:mou2 +0x77b5:lin2 +0x77b6:kui4 +0x77b7:xian2 +0x77b8:ye4 +0x77b9:ai4 +0x77ba:hui4 +0x77bb:zhan1 +0x77bc:jian3 +0x77bd:gu3 +0x77be:zhao4 +0x77bf:ju4 +0x77c0:wei2 +0x77c1:chou3 +0x77c2:sao4 +0x77c3:ning3 +0x77c4:xun1 +0x77c5:yao4 +0x77c6:huo4 +0x77c7:meng2 +0x77c8:mian2 +0x77c9:bin1 +0x77ca:mian2 +0x77cb:li4 +0x77cc:kuang4 +0x77cd:jue2 +0x77ce:xuan1 +0x77cf:mian2 +0x77d0:huo4 +0x77d1:lu2 +0x77d2:meng2 +0x77d3:long2 +0x77d4:guan4 +0x77d5:man3 +0x77d6:xi3 +0x77d7:chu4 +0x77d8:tang3 +0x77d9:kan4 +0x77da:zhu3 +0x77db:mao2 +0x77dc:jin1 +0x77dd:lin2 +0x77de:yu4 +0x77df:shuo4 +0x77e0:ce4 +0x77e1:jue2 +0x77e2:shi3 +0x77e3:yi3 +0x77e4:shen3 +0x77e5:zhi1 +0x77e6:hou2 +0x77e7:shen3 +0x77e8:ying3 +0x77e9:ju3 +0x77ea:zhou1 +0x77eb:jiao3 +0x77ec:cuo2 +0x77ed:duan3 +0x77ee:ai3 +0x77ef:jiao3 +0x77f0:zeng1 +0x77f1:huo4 +0x77f2:bai3 +0x77f3:shi2 +0x77f4:ding4 +0x77f5:qi4 +0x77f6:ji1 +0x77f7:zi3 +0x77f8:gan1 +0x77f9:wu4 +0x77fa:tuo1 +0x77fb:ku4 +0x77fc:qiang1 +0x77fd:xi4 +0x77fe:fan2 +0x77ff:kuang4 +0x7800:dang4 +0x7801:ma3 +0x7802:sha1 +0x7803:dan1 +0x7804:jue2 +0x7805:li4 +0x7806:fu1 +0x7807:min2 +0x7808:nuo3 +0x7809:huo4 +0x780a:kang4 +0x780b:zhi3 +0x780c:qi4 +0x780d:kan3 +0x780e:jie4 +0x780f:fen1 +0x7810:e4 +0x7811:ya4 +0x7812:pi1 +0x7813:zhe2 +0x7814:yan2 +0x7815:sui4 +0x7816:zhuan1 +0x7817:che1 +0x7818:dun4 +0x7819:pan1 +0x781a:yan4 +0x781c:feng1 +0x781d:fa2 +0x781e:mo4 +0x781f:zha4 +0x7820:qu1 +0x7821:yu4 +0x7822:luo3 +0x7823:tuo2 +0x7824:tuo2 +0x7825:di3 +0x7826:zhai4 +0x7827:zhen1 +0x7828:ai4 +0x7829:fei4 +0x782a:mu3 +0x782b:zhu3 +0x782c:li4 +0x782d:bian1 +0x782e:nu3 +0x782f:ping1 +0x7830:peng1 +0x7831:ling2 +0x7832:pao4 +0x7833:le4 +0x7834:po4 +0x7835:bo1 +0x7836:po4 +0x7837:shen1 +0x7838:za2 +0x7839:nuo3 +0x783a:li4 +0x783b:long2 +0x783c:tong2 +0x783e:li4 +0x7840:chu3 +0x7841:keng1 +0x7842:quan2 +0x7843:zhu1 +0x7844:kuang1 +0x7845:gui1 +0x7846:e4 +0x7847:nao2 +0x7848:jia2 +0x7849:lu4 +0x784a:wei3 +0x784b:ai4 +0x784c:luo4 +0x784d:ken4 +0x784e:xing2 +0x784f:yan2 +0x7850:tong2 +0x7851:peng1 +0x7852:xi1 +0x7854:hong2 +0x7855:shuo4 +0x7856:xia2 +0x7857:qiao1 +0x7859:wei4 +0x785a:qiao2 +0x785c:keng1 +0x785d:xiao1 +0x785e:que4 +0x785f:chan4 +0x7860:lang3 +0x7861:hong2 +0x7862:yu2 +0x7863:xiao1 +0x7864:xia2 +0x7865:mang3 +0x7866:long4 +0x7867:yong3 +0x7868:che1 +0x7869:che4 +0x786a:e2 +0x786b:liu2 +0x786c:ying4 +0x786d:mang2 +0x786e:que4 +0x786f:yan4 +0x7870:sha1 +0x7871:kun3 +0x7872:yu4 +0x7875:lu3 +0x7876:chen3 +0x7877:jian3 +0x7878:nve4 +0x7879:song1 +0x787a:zhuo2 +0x787b:keng1 +0x787c:peng2 +0x787d:yan3 +0x787e:zhui4 +0x787f:kong1 +0x7880:ceng2 +0x7881:qi2 +0x7882:zong4 +0x7883:qing4 +0x7884:lin2 +0x7885:jun1 +0x7886:bo1 +0x7887:ding4 +0x7888:min2 +0x7889:diao1 +0x788a:jian1 +0x788b:he4 +0x788c:lu4 +0x788d:ai4 +0x788e:sui4 +0x788f:que4 +0x7890:ling2 +0x7891:bei1 +0x7892:yin2 +0x7893:dui4 +0x7894:wu3 +0x7895:qi2 +0x7896:lun4 +0x7897:wan3 +0x7898:dian3 +0x7899:gang1 +0x789a:bei4 +0x789b:qi4 +0x789c:chen3 +0x789d:ruan3 +0x789e:yan2 +0x789f:die2 +0x78a0:ding4 +0x78a1:du2 +0x78a2:tuo2 +0x78a3:jie2 +0x78a4:ying1 +0x78a5:bian3 +0x78a6:ke4 +0x78a7:bi4 +0x78a8:wei1 +0x78a9:shuo4 +0x78aa:zhen1 +0x78ab:duan4 +0x78ac:xia2 +0x78ad:dang4 +0x78ae:ti2 +0x78af:nao3 +0x78b0:peng4 +0x78b1:jian3 +0x78b2:di4 +0x78b3:tan4 +0x78b4:cha2 +0x78b6:qi4 +0x78b8:feng1 +0x78b9:xuan4 +0x78ba:que4 +0x78bb:que4 +0x78bc:ma3 +0x78bd:gong1 +0x78be:nian3 +0x78bf:su4 +0x78c0:e2 +0x78c1:ci2 +0x78c2:liu4 +0x78c3:si1 +0x78c4:tang2 +0x78c5:bang4 +0x78c6:hua2 +0x78c7:pi1 +0x78c8:wei3 +0x78c9:sang3 +0x78ca:lei3 +0x78cb:cuo1 +0x78cc:zhen1 +0x78cd:xia2 +0x78ce:qi1 +0x78cf:lian2 +0x78d0:pan2 +0x78d1:wei4 +0x78d2:yun3 +0x78d3:dui1 +0x78d4:zhe2 +0x78d5:ke1 +0x78d6:la1 +0x78d8:qing4 +0x78d9:gun3 +0x78da:zhuan1 +0x78db:chan2 +0x78dc:qi4 +0x78dd:ao2 +0x78de:peng1 +0x78df:lu4 +0x78e0:lu3 +0x78e1:kan4 +0x78e2:qiang3 +0x78e3:chen3 +0x78e4:yin3 +0x78e5:lei3 +0x78e6:biao1 +0x78e7:qi4 +0x78e8:mo2 +0x78e9:qi1 +0x78ea:cui1 +0x78eb:zong1 +0x78ec:qing4 +0x78ed:chuo4 +0x78ef:ji1 +0x78f0:shan4 +0x78f1:lao2 +0x78f2:qu2 +0x78f3:zeng1 +0x78f4:deng4 +0x78f5:jian4 +0x78f6:xi4 +0x78f7:lin2 +0x78f8:ding4 +0x78f9:dian4 +0x78fa:huang2 +0x78fb:pan2 +0x78fc:za2 +0x78fd:qiao1 +0x78fe:di1 +0x78ff:li4 +0x7901:jiao1 +0x7903:zhang3 +0x7904:qiao2 +0x7905:dun1 +0x7906:xian3 +0x7907:yu4 +0x7908:zhui4 +0x7909:he2 +0x790a:huo4 +0x790b:zhai2 +0x790c:lei4 +0x790d:ke3 +0x790e:chu3 +0x790f:ji2 +0x7910:que4 +0x7911:dang4 +0x7912:yi3 +0x7913:jiang1 +0x7914:pi4 +0x7915:pi1 +0x7916:yu4 +0x7917:pin1 +0x7918:qi4 +0x7919:ai4 +0x791a:kai4 +0x791b:jian1 +0x791c:yu4 +0x791d:ruan3 +0x791e:meng2 +0x791f:pao4 +0x7920:ci2 +0x7921:bo2 +0x7923:mie4 +0x7924:ca3 +0x7925:xian2 +0x7926:kuang4 +0x7927:lei4 +0x7928:lei3 +0x7929:zhi4 +0x792a:li4 +0x792b:li4 +0x792c:fan2 +0x792d:que4 +0x792e:pao4 +0x792f:ying1 +0x7930:li4 +0x7931:long2 +0x7932:long2 +0x7933:mo4 +0x7934:bo2 +0x7935:shuang1 +0x7936:guan4 +0x7937:lan2 +0x7938:zan3 +0x7939:yan2 +0x793a:shi4 +0x793b:shi4 +0x793c:li3 +0x793d:reng2 +0x793e:she4 +0x793f:yue4 +0x7940:si4 +0x7941:qi2 +0x7942:ta1 +0x7943:ma4 +0x7944:xie4 +0x7945:yao1 +0x7946:xian1 +0x7947:qi2 +0x7948:qi2 +0x7949:zhi3 +0x794a:beng1 +0x794b:dui4 +0x794c:zhong4 +0x794e:yi1 +0x794f:shi2 +0x7950:you4 +0x7951:zhi4 +0x7952:tiao2 +0x7953:fu2 +0x7954:fu4 +0x7955:mi4 +0x7956:zu3 +0x7957:zhi1 +0x7958:suan4 +0x7959:mei4 +0x795a:zuo4 +0x795b:qu1 +0x795c:hu4 +0x795d:zhu4 +0x795e:shen2 +0x795f:sui4 +0x7960:ci2 +0x7961:chai2 +0x7962:mi2 +0x7963:lv3 +0x7964:yu3 +0x7965:xiang2 +0x7966:wu2 +0x7967:tiao1 +0x7968:piao4 +0x7969:zhu1 +0x796a:gui3 +0x796b:xia2 +0x796c:zhi1 +0x796d:ji4 +0x796e:gao4 +0x796f:zhen1 +0x7970:gao4 +0x7971:shui4 +0x7972:jin1 +0x7973:chen3 +0x7974:gai1 +0x7975:kun3 +0x7976:di4 +0x7977:dao3 +0x7978:huo4 +0x7979:tao2 +0x797a:qi2 +0x797b:gu4 +0x797c:guan4 +0x797d:zui4 +0x797e:ling2 +0x797f:lu4 +0x7980:bing3 +0x7981:jin4 +0x7982:dao3 +0x7983:zhi2 +0x7984:lu4 +0x7985:shan4 +0x7986:bei1 +0x7987:zhe3 +0x7988:hui1 +0x7989:you3 +0x798a:xi4 +0x798b:yin1 +0x798c:zi1 +0x798d:huo4 +0x798e:zhen1 +0x798f:fu2 +0x7990:yuan4 +0x7991:wu2 +0x7992:xian3 +0x7993:yang2 +0x7994:ti2 +0x7995:yi1 +0x7996:mei2 +0x7997:si1 +0x7998:di4 +0x799a:zhuo2 +0x799b:zhen1 +0x799c:yong3 +0x799d:ji2 +0x799e:gao4 +0x799f:tang2 +0x79a0:si1 +0x79a1:ma4 +0x79a2:ta1 +0x79a4:xuan1 +0x79a5:qi2 +0x79a6:yu4 +0x79a7:xi3 +0x79a8:ji1 +0x79a9:si4 +0x79aa:chan2 +0x79ab:tan3 +0x79ac:kuai4 +0x79ad:sui4 +0x79ae:li3 +0x79af:nong2 +0x79b0:ni3 +0x79b1:dao3 +0x79b2:li4 +0x79b3:rang2 +0x79b4:yue4 +0x79b5:ti2 +0x79b6:zan3 +0x79b7:lei4 +0x79b8:rou2 +0x79b9:yu3 +0x79ba:yu2 +0x79bb:li2 +0x79bc:xie4 +0x79bd:qin2 +0x79be:he2 +0x79bf:tu1 +0x79c0:xiu4 +0x79c1:si1 +0x79c2:ren2 +0x79c3:tu1 +0x79c4:zi3 +0x79c5:cha2 +0x79c6:gan3 +0x79c7:yi4 +0x79c8:xian1 +0x79c9:bing3 +0x79ca:nian2 +0x79cb:qiu1 +0x79cc:qiu1 +0x79cd:zhong3 +0x79ce:fen2 +0x79cf:hao4 +0x79d0:yun2 +0x79d1:ke1 +0x79d2:miao3 +0x79d3:zhi1 +0x79d4:geng1 +0x79d5:bi3 +0x79d6:zhi1 +0x79d7:yu4 +0x79d8:mi4 +0x79d9:ku4 +0x79da:ban4 +0x79db:pi1 +0x79dc:ni2 +0x79dd:li4 +0x79de:you2 +0x79df:zu1 +0x79e0:pi1 +0x79e1:ba2 +0x79e2:ling2 +0x79e3:mo4 +0x79e4:cheng4 +0x79e5:nian2 +0x79e6:qin2 +0x79e7:yang1 +0x79e8:zuo2 +0x79e9:zhi4 +0x79ea:zhi1 +0x79eb:shu2 +0x79ec:ju4 +0x79ed:zi3 +0x79ee:huo2 +0x79ef:ji1 +0x79f0:cheng1 +0x79f1:tong2 +0x79f2:zhi4 +0x79f3:huo2 +0x79f4:he2 +0x79f5:yin1 +0x79f6:zi1 +0x79f7:zhi2 +0x79f8:jie1 +0x79f9:ren3 +0x79fa:du4 +0x79fb:yi2 +0x79fc:zhu1 +0x79fd:hui4 +0x79fe:nong2 +0x79ff:fu3 +0x7a00:xi1 +0x7a01:kao3 +0x7a02:lang2 +0x7a03:fu1 +0x7a04:ze4 +0x7a05:shui4 +0x7a06:lv3 +0x7a07:kun3 +0x7a08:gan3 +0x7a09:geng1 +0x7a0a:ti2 +0x7a0b:cheng2 +0x7a0c:tu2 +0x7a0d:shao1 +0x7a0e:shui4 +0x7a0f:ya4 +0x7a10:lun3 +0x7a11:lu4 +0x7a12:gu4 +0x7a13:zuo2 +0x7a14:ren3 +0x7a15:zhun4 +0x7a16:bang4 +0x7a17:bai4 +0x7a18:ji1 +0x7a19:zhi2 +0x7a1a:zhi4 +0x7a1b:kun3 +0x7a1c:leng2 +0x7a1d:peng2 +0x7a1e:ke1 +0x7a1f:bing3 +0x7a20:chou2 +0x7a21:zu2 +0x7a22:yu4 +0x7a23:su1 +0x7a24:lve4 +0x7a26:yi1 +0x7a27:xi4 +0x7a28:bian1 +0x7a29:ji4 +0x7a2a:fu4 +0x7a2b:bi1 +0x7a2c:nuo4 +0x7a2d:jie1 +0x7a2e:zhong3 +0x7a2f:zong1 +0x7a30:xu1 +0x7a31:cheng1 +0x7a32:dao4 +0x7a33:wen3 +0x7a34:lian2 +0x7a35:zi1 +0x7a36:yu4 +0x7a37:ji4 +0x7a38:xu4 +0x7a39:zhen3 +0x7a3a:zhi4 +0x7a3b:dao4 +0x7a3c:jia4 +0x7a3d:ji1 +0x7a3e:gao3 +0x7a3f:gao3 +0x7a40:gu3 +0x7a41:rong2 +0x7a42:sui4 +0x7a44:ji4 +0x7a45:kang1 +0x7a46:mu4 +0x7a47:shan1 +0x7a48:men2 +0x7a49:zhi4 +0x7a4a:ji4 +0x7a4b:lu4 +0x7a4c:su1 +0x7a4d:ji1 +0x7a4e:ying3 +0x7a4f:wen3 +0x7a50:qiu1 +0x7a51:se4 +0x7a53:yi4 +0x7a54:huang2 +0x7a55:qie4 +0x7a56:ji3 +0x7a57:sui4 +0x7a58:xiao1 +0x7a59:pu2 +0x7a5a:jiao1 +0x7a5b:zhuo1 +0x7a5c:tong2 +0x7a5e:lv3 +0x7a5f:sui4 +0x7a60:nong2 +0x7a61:se4 +0x7a62:hui4 +0x7a63:rang2 +0x7a64:nuo4 +0x7a65:yu4 +0x7a67:ji4 +0x7a68:tui2 +0x7a69:wen3 +0x7a6a:cheng1 +0x7a6b:huo4 +0x7a6c:gong3 +0x7a6d:lv3 +0x7a6e:biao1 +0x7a70:rang2 +0x7a71:zhuo1 +0x7a72:li2 +0x7a73:zan4 +0x7a74:xue2 +0x7a75:wa1 +0x7a76:jiu1 +0x7a77:qiong2 +0x7a78:xi4 +0x7a79:qiong2 +0x7a7a:kong1 +0x7a7b:yu1 +0x7a7c:sen1 +0x7a7d:jing3 +0x7a7e:yao4 +0x7a7f:chuan1 +0x7a80:zhun1 +0x7a81:tu1 +0x7a82:lao2 +0x7a83:qie4 +0x7a84:zhai3 +0x7a85:yao3 +0x7a86:bian3 +0x7a87:bao2 +0x7a88:yao3 +0x7a89:bing3 +0x7a8a:wa1 +0x7a8b:zhu2 +0x7a8c:jiao4 +0x7a8d:qiao4 +0x7a8e:diao4 +0x7a8f:wu1 +0x7a90:gui1 +0x7a91:yao2 +0x7a92:zhi4 +0x7a93:chuang1 +0x7a94:yao3 +0x7a95:tiao3 +0x7a96:jiao4 +0x7a97:chuang1 +0x7a98:jiong3 +0x7a99:xiao1 +0x7a9a:cheng2 +0x7a9b:kou4 +0x7a9c:cuan4 +0x7a9d:wo1 +0x7a9e:dan4 +0x7a9f:ku1 +0x7aa0:ke1 +0x7aa1:zhui4 +0x7aa2:xu4 +0x7aa3:su4 +0x7aa5:kui1 +0x7aa6:dou4 +0x7aa8:yin4 +0x7aa9:wo1 +0x7aaa:wa1 +0x7aab:ya4 +0x7aac:yu2 +0x7aad:ju4 +0x7aae:qiong2 +0x7aaf:yao2 +0x7ab0:yao2 +0x7ab1:tiao4 +0x7ab2:chao2 +0x7ab3:yu3 +0x7ab4:tian2 +0x7ab5:diao4 +0x7ab6:ju4 +0x7ab7:liao2 +0x7ab8:xi1 +0x7ab9:wu4 +0x7aba:kui1 +0x7abb:chuang1 +0x7abc:zhao1 +0x7abe:kuan3 +0x7abf:long2 +0x7ac0:cheng1 +0x7ac1:cui4 +0x7ac2:piao2 +0x7ac3:zao4 +0x7ac4:cuan4 +0x7ac5:qiao4 +0x7ac6:qiong2 +0x7ac7:dou4 +0x7ac8:zao4 +0x7ac9:long3 +0x7aca:qie4 +0x7acb:li4 +0x7acc:chu4 +0x7ace:fou4 +0x7ad0:chu4 +0x7ad1:hong2 +0x7ad2:qi2 +0x7ad6:shu4 +0x7ad7:miao4 +0x7ad8:ju3 +0x7ad9:zhan4 +0x7ada:zhu4 +0x7adb:ling2 +0x7adc:long2 +0x7add:bing4 +0x7ade:jing4 +0x7adf:jing4 +0x7ae0:zhang1 +0x7ae2:si4 +0x7ae3:jun4 +0x7ae4:hong2 +0x7ae5:tong2 +0x7ae6:song3 +0x7ae7:jing4 +0x7ae8:diao4 +0x7ae9:yi4 +0x7aea:shu4 +0x7aeb:jing4 +0x7aec:qu3 +0x7aed:jie2 +0x7aee:ping2 +0x7aef:duan1 +0x7af0:shao2 +0x7af1:zhuan3 +0x7af2:ceng2 +0x7af3:deng1 +0x7af4:cui1 +0x7af5:huai1 +0x7af6:jing4 +0x7af7:kan4 +0x7af8:jing4 +0x7af9:zhu2 +0x7afa:zhu2 +0x7afb:le4 +0x7afc:peng2 +0x7afd:yu2 +0x7afe:chi2 +0x7aff:gan1 +0x7b00:mang2 +0x7b01:zhu2 +0x7b03:du3 +0x7b04:ji1 +0x7b05:xiao2 +0x7b06:ba1 +0x7b07:suan4 +0x7b08:ji2 +0x7b09:zhen3 +0x7b0a:zhao4 +0x7b0b:sun3 +0x7b0c:ya2 +0x7b0d:zhui4 +0x7b0e:yuan2 +0x7b0f:hu4 +0x7b10:gang1 +0x7b11:xiao4 +0x7b12:cen2 +0x7b13:pi2 +0x7b14:bi3 +0x7b15:jian3 +0x7b16:yi3 +0x7b17:dong1 +0x7b18:shan1 +0x7b19:sheng1 +0x7b1a:xia2 +0x7b1b:di2 +0x7b1c:zhu2 +0x7b1d:na4 +0x7b1e:chi1 +0x7b1f:gu1 +0x7b20:li4 +0x7b21:qie4 +0x7b22:min3 +0x7b23:bao1 +0x7b24:tiao2 +0x7b25:si4 +0x7b26:fu2 +0x7b27:ce4 +0x7b28:ben4 +0x7b29:pei4 +0x7b2a:da2 +0x7b2b:zi3 +0x7b2c:di4 +0x7b2d:ling2 +0x7b2e:ze2 +0x7b2f:nu2 +0x7b30:fu2 +0x7b31:gou3 +0x7b32:fan2 +0x7b33:jia1 +0x7b34:ge3 +0x7b35:fan4 +0x7b36:shi3 +0x7b37:mao3 +0x7b38:po3 +0x7b3a:jian1 +0x7b3b:qiong2 +0x7b3c:long2 +0x7b3e:bian1 +0x7b3f:luo4 +0x7b40:gui4 +0x7b41:qu3 +0x7b42:chi2 +0x7b43:yin1 +0x7b44:yao4 +0x7b45:xian3 +0x7b46:bi3 +0x7b47:qiong2 +0x7b48:gua1 +0x7b49:deng3 +0x7b4a:jiao3 +0x7b4b:jin1 +0x7b4c:quan2 +0x7b4d:sun3 +0x7b4e:ru2 +0x7b4f:fa2 +0x7b50:kuang1 +0x7b51:zhu2 +0x7b52:tong3 +0x7b53:ji1 +0x7b54:da2 +0x7b55:xing2 +0x7b56:ce4 +0x7b57:zhong4 +0x7b58:kou4 +0x7b59:lai2 +0x7b5a:bi4 +0x7b5b:shai1 +0x7b5c:dang1 +0x7b5d:zheng1 +0x7b5e:ce4 +0x7b5f:fu1 +0x7b60:yun2 +0x7b61:tu2 +0x7b62:pa2 +0x7b63:li4 +0x7b64:lang2 +0x7b65:ju3 +0x7b66:guan3 +0x7b67:jian3 +0x7b68:han2 +0x7b69:tong3 +0x7b6a:xia2 +0x7b6b:zhi4 +0x7b6c:cheng2 +0x7b6d:suan4 +0x7b6e:shi4 +0x7b6f:zhu4 +0x7b70:zuo2 +0x7b71:xiao3 +0x7b72:shao1 +0x7b73:ting2 +0x7b74:ce4 +0x7b75:yan2 +0x7b76:gao3 +0x7b77:kuai4 +0x7b78:gan1 +0x7b79:chou2 +0x7b7b:gang4 +0x7b7c:yun2 +0x7b7e:qian1 +0x7b7f:xiao3 +0x7b80:jian3 +0x7b81:pu2 +0x7b82:lai2 +0x7b83:zou1 +0x7b84:bi4 +0x7b85:bi4 +0x7b86:bi4 +0x7b87:ge4 +0x7b88:chi2 +0x7b89:guai3 +0x7b8a:yu1 +0x7b8b:jian1 +0x7b8c:zhao4 +0x7b8d:gu1 +0x7b8e:chi2 +0x7b8f:zheng1 +0x7b90:jing1 +0x7b91:sha4 +0x7b92:zhou3 +0x7b93:lu4 +0x7b94:bo2 +0x7b95:ji1 +0x7b96:lin2 +0x7b97:suan4 +0x7b98:jun4 +0x7b99:fu2 +0x7b9a:zha2 +0x7b9b:gu1 +0x7b9c:kong1 +0x7b9d:qian2 +0x7b9e:quan1 +0x7b9f:jun4 +0x7ba0:chui2 +0x7ba1:guan3 +0x7ba2:yuan1 +0x7ba3:ce4 +0x7ba4:ju2 +0x7ba5:bo3 +0x7ba6:ze2 +0x7ba7:qie4 +0x7ba8:tuo4 +0x7ba9:luo2 +0x7baa:dan1 +0x7bab:xiao1 +0x7bac:ruo4 +0x7bad:jian4 +0x7baf:bian1 +0x7bb0:sun3 +0x7bb1:xiang1 +0x7bb2:xian3 +0x7bb3:ping2 +0x7bb4:zhen1 +0x7bb5:sheng3 +0x7bb6:hu2 +0x7bb7:shi1 +0x7bb8:zhu4 +0x7bb9:yue1 +0x7bba:chun3 +0x7bbb:lv4 +0x7bbc:wu1 +0x7bbd:dong3 +0x7bbe:shuo4 +0x7bbf:ji2 +0x7bc0:jie2 +0x7bc1:huang2 +0x7bc2:xing1 +0x7bc3:mei2 +0x7bc4:fan4 +0x7bc5:chui2 +0x7bc6:zhuan4 +0x7bc7:pian1 +0x7bc8:feng1 +0x7bc9:zhu2 +0x7bca:hong2 +0x7bcb:qie4 +0x7bcc:hou2 +0x7bcd:qiu1 +0x7bce:miao3 +0x7bcf:qian4 +0x7bd1:kui4 +0x7bd3:lou3 +0x7bd4:yun2 +0x7bd5:he2 +0x7bd6:tang2 +0x7bd7:yue4 +0x7bd8:chou1 +0x7bd9:gao1 +0x7bda:fei3 +0x7bdb:ruo4 +0x7bdc:zheng1 +0x7bdd:gou1 +0x7bde:nie4 +0x7bdf:qian4 +0x7be0:xiao3 +0x7be1:cuan4 +0x7be2:gong1 +0x7be3:pang2 +0x7be4:du3 +0x7be5:li4 +0x7be6:bi4 +0x7be7:zhuo2 +0x7be8:chu2 +0x7be9:shai1 +0x7bea:chi2 +0x7beb:zhu2 +0x7bec:qiang1 +0x7bed:long2 +0x7bee:lan2 +0x7bef:jian1 +0x7bf0:bu4 +0x7bf1:li2 +0x7bf2:hui4 +0x7bf3:bi4 +0x7bf4:di2 +0x7bf5:cong1 +0x7bf6:yan1 +0x7bf7:peng2 +0x7bf8:sen1 +0x7bf9:zhuan4 +0x7bfa:pai2 +0x7bfb:piao4 +0x7bfc:dou1 +0x7bfd:yu3 +0x7bfe:mie4 +0x7bff:zhuan1 +0x7c00:ze2 +0x7c01:xi3 +0x7c02:guo2 +0x7c03:yi2 +0x7c04:hu4 +0x7c05:chan3 +0x7c06:kou4 +0x7c07:cu4 +0x7c08:ping2 +0x7c09:chou4 +0x7c0a:ji1 +0x7c0b:gui3 +0x7c0c:su4 +0x7c0d:lou3 +0x7c0e:zha4 +0x7c0f:lu4 +0x7c10:nian3 +0x7c11:suo1 +0x7c12:cuan4 +0x7c14:suo1 +0x7c15:le4 +0x7c16:duan4 +0x7c18:xiao1 +0x7c19:bo2 +0x7c1a:mi4 +0x7c1b:si1 +0x7c1c:dang4 +0x7c1d:liao2 +0x7c1e:dan1 +0x7c1f:dian4 +0x7c20:fu3 +0x7c21:jian3 +0x7c22:min3 +0x7c23:kui4 +0x7c24:dai4 +0x7c25:jiao1 +0x7c26:deng1 +0x7c27:huang2 +0x7c28:sun3 +0x7c29:lao2 +0x7c2a:zan1 +0x7c2b:xiao1 +0x7c2c:lu4 +0x7c2d:shi4 +0x7c2e:zan1 +0x7c30:pai2 +0x7c32:pai2 +0x7c33:gan4 +0x7c34:ju4 +0x7c35:du4 +0x7c36:lu4 +0x7c37:yan2 +0x7c38:bo4 +0x7c39:dang1 +0x7c3a:sai4 +0x7c3b:ke1 +0x7c3c:long2 +0x7c3d:qian1 +0x7c3e:lian2 +0x7c3f:bu4 +0x7c40:zhou4 +0x7c41:lai4 +0x7c43:lan2 +0x7c44:kui4 +0x7c45:yu2 +0x7c46:yue4 +0x7c47:hao2 +0x7c48:zhen1 +0x7c49:tai2 +0x7c4a:ti4 +0x7c4b:mi2 +0x7c4c:chou2 +0x7c4d:ji2 +0x7c50:teng2 +0x7c51:zhuan4 +0x7c52:zhou4 +0x7c53:fan1 +0x7c54:sou3 +0x7c55:zhou4 +0x7c57:zhuo2 +0x7c58:teng2 +0x7c59:lu4 +0x7c5a:lu2 +0x7c5b:jian1 +0x7c5c:tuo4 +0x7c5d:ying2 +0x7c5e:yu4 +0x7c5f:lai4 +0x7c60:long2 +0x7c62:lian2 +0x7c63:lan2 +0x7c64:qian1 +0x7c65:yue4 +0x7c66:zhong1 +0x7c67:qu2 +0x7c68:lian2 +0x7c69:bian1 +0x7c6a:duan4 +0x7c6b:zuan3 +0x7c6c:li2 +0x7c6d:si1 +0x7c6e:luo2 +0x7c6f:ying2 +0x7c70:yue4 +0x7c71:zhuo2 +0x7c72:yu4 +0x7c73:mi3 +0x7c74:di2 +0x7c75:fan2 +0x7c76:shen1 +0x7c77:zhe2 +0x7c78:shen1 +0x7c79:nv3 +0x7c7a:xie2 +0x7c7b:lei4 +0x7c7c:xian1 +0x7c7d:zi3 +0x7c7e:ni2 +0x7c7f:cun4 +0x7c81:qian1 +0x7c83:bi3 +0x7c84:ban3 +0x7c85:wu4 +0x7c86:sha1 +0x7c87:kang1 +0x7c88:rou3 +0x7c89:fen3 +0x7c8a:bi4 +0x7c8b:cui4 +0x7c8d:li2 +0x7c8e:chi3 +0x7c91:ba1 +0x7c92:li4 +0x7c93:gan1 +0x7c94:ju4 +0x7c95:po4 +0x7c96:mo4 +0x7c97:cu1 +0x7c98:nian2 +0x7c99:zhou4 +0x7c9a:li2 +0x7c9b:su4 +0x7c9c:tiao4 +0x7c9d:li4 +0x7c9e:xi1 +0x7c9f:su4 +0x7ca0:hong2 +0x7ca1:tong2 +0x7ca2:zi1 +0x7ca3:ce4 +0x7ca4:yue4 +0x7ca5:zhou1 +0x7ca6:lin4 +0x7ca7:zhuang1 +0x7ca8:bai3 +0x7caa:fen4 +0x7cae:liang2 +0x7caf:xian4 +0x7cb0:fu2 +0x7cb1:liang2 +0x7cb2:can4 +0x7cb3:geng1 +0x7cb4:li3 +0x7cb5:yue4 +0x7cb6:lu4 +0x7cb7:ju2 +0x7cb8:qi2 +0x7cb9:cui4 +0x7cba:bai4 +0x7cbb:zhang1 +0x7cbc:lin2 +0x7cbd:zong4 +0x7cbe:jing1 +0x7cbf:guo3 +0x7cc1:san1 +0x7cc2:san3 +0x7cc3:tang2 +0x7cc4:bian1 +0x7cc5:rou3 +0x7cc6:mian4 +0x7cc7:hou2 +0x7cc8:xu3 +0x7cc9:zong4 +0x7cca:hu2 +0x7ccb:jian4 +0x7ccc:zan2 +0x7ccd:ci2 +0x7cce:li2 +0x7ccf:xie4 +0x7cd0:fu1 +0x7cd1:ni4 +0x7cd2:bei4 +0x7cd3:gu3 +0x7cd4:xiu3 +0x7cd5:gao1 +0x7cd6:tang2 +0x7cd7:qiu3 +0x7cd9:cao1 +0x7cda:zhuang1 +0x7cdb:tang2 +0x7cdc:mi2 +0x7cdd:san3 +0x7cde:fen4 +0x7cdf:zao1 +0x7ce0:kang1 +0x7ce1:jiang4 +0x7ce2:mo2 +0x7ce3:san3 +0x7ce4:san3 +0x7ce5:nuo4 +0x7ce6:xi1 +0x7ce7:liang2 +0x7ce8:jiang4 +0x7ce9:kuai4 +0x7cea:bo2 +0x7ceb:huan2 +0x7ced:zong4 +0x7cee:xian4 +0x7cef:nuo4 +0x7cf0:tuan2 +0x7cf1:nie4 +0x7cf2:li4 +0x7cf3:zuo4 +0x7cf4:di2 +0x7cf5:nie4 +0x7cf6:tiao4 +0x7cf7:lan2 +0x7cf8:mi4 +0x7cf9:si1 +0x7cfa:jiu1 +0x7cfb:xi4 +0x7cfc:gong1 +0x7cfd:zheng3 +0x7cfe:jiu1 +0x7cff:you4 +0x7d00:ji4 +0x7d01:cha4 +0x7d02:zhou4 +0x7d03:xun2 +0x7d04:yue1 +0x7d05:hong2 +0x7d06:yu1 +0x7d07:he2 +0x7d08:wan2 +0x7d09:ren4 +0x7d0a:wen4 +0x7d0b:wen2 +0x7d0c:qiu2 +0x7d0d:na4 +0x7d0e:zi1 +0x7d0f:tou3 +0x7d10:niu3 +0x7d11:fou2 +0x7d12:jie4 +0x7d13:shu1 +0x7d14:chun2 +0x7d15:pi1 +0x7d16:yin3 +0x7d17:sha1 +0x7d18:hong2 +0x7d19:zhi3 +0x7d1a:ji2 +0x7d1b:fen1 +0x7d1c:yun2 +0x7d1d:ren4 +0x7d1e:dan3 +0x7d1f:jin1 +0x7d20:su4 +0x7d21:fang3 +0x7d22:suo3 +0x7d23:cui4 +0x7d24:jiu3 +0x7d25:zha2 +0x7d27:jin3 +0x7d28:fu4 +0x7d29:zhi4 +0x7d2a:ci3 +0x7d2b:zi3 +0x7d2c:chou2 +0x7d2d:hong2 +0x7d2e:za1 +0x7d2f:lei4 +0x7d30:xi4 +0x7d31:fu2 +0x7d32:xie4 +0x7d33:shen1 +0x7d34:bei4 +0x7d35:zhu4 +0x7d36:qu3 +0x7d37:ling2 +0x7d38:zhu4 +0x7d39:shao4 +0x7d3a:gan4 +0x7d3b:yang1 +0x7d3c:fu2 +0x7d3d:tuo2 +0x7d3e:zhen3 +0x7d3f:dai4 +0x7d40:chu4 +0x7d41:shi1 +0x7d42:zhong1 +0x7d43:xian2 +0x7d44:zu3 +0x7d45:jiong3 +0x7d46:ban4 +0x7d47:ju4 +0x7d48:mo4 +0x7d49:shu4 +0x7d4a:zui4 +0x7d4c:jing1 +0x7d4d:ren2 +0x7d4e:heng4 +0x7d4f:xie4 +0x7d50:jie2 +0x7d51:zhu1 +0x7d52:chou2 +0x7d53:gua4 +0x7d54:bai3 +0x7d55:jue2 +0x7d56:kuang4 +0x7d57:hu2 +0x7d58:ci4 +0x7d59:geng1 +0x7d5a:geng1 +0x7d5b:tao1 +0x7d5c:xie2 +0x7d5d:ku4 +0x7d5e:jiao3 +0x7d5f:quan1 +0x7d60:gai3 +0x7d61:luo4 +0x7d62:xuan4 +0x7d63:bing1 +0x7d64:xian4 +0x7d65:fu2 +0x7d66:gei3 +0x7d67:tong2 +0x7d68:rong2 +0x7d69:tiao4 +0x7d6a:yin1 +0x7d6b:lei3 +0x7d6c:xie4 +0x7d6d:quan4 +0x7d6e:xu4 +0x7d6f:gai1 +0x7d70:die2 +0x7d71:tong3 +0x7d72:si1 +0x7d73:jiang4 +0x7d74:xiang2 +0x7d75:hui4 +0x7d76:jue2 +0x7d77:zhi2 +0x7d78:jian3 +0x7d79:juan4 +0x7d7a:chi1 +0x7d7b:mian3 +0x7d7c:zhen3 +0x7d7d:lv3 +0x7d7e:cheng2 +0x7d7f:qiu2 +0x7d80:shu1 +0x7d81:bang3 +0x7d82:tong3 +0x7d83:xiao1 +0x7d84:wan4 +0x7d85:qin1 +0x7d86:geng3 +0x7d87:xiu3 +0x7d88:ti2 +0x7d89:xiu4 +0x7d8a:xie2 +0x7d8b:hong2 +0x7d8c:xi4 +0x7d8d:fu2 +0x7d8e:ting1 +0x7d8f:sui1 +0x7d90:dui4 +0x7d91:kun3 +0x7d92:fu1 +0x7d93:jing1 +0x7d94:hu4 +0x7d95:zhi1 +0x7d96:yan2 +0x7d97:jiong3 +0x7d98:feng2 +0x7d99:ji4 +0x7d9c:zong1 +0x7d9d:lin2 +0x7d9e:duo3 +0x7d9f:li4 +0x7da0:lv4 +0x7da1:liang2 +0x7da2:chou2 +0x7da3:quan3 +0x7da4:shao4 +0x7da5:qi4 +0x7da6:qi2 +0x7da7:zhun3 +0x7da8:qi2 +0x7da9:wan3 +0x7daa:qian4 +0x7dab:xian4 +0x7dac:shou4 +0x7dad:wei2 +0x7dae:qi3 +0x7daf:tao2 +0x7db0:wan3 +0x7db1:gang1 +0x7db2:wang3 +0x7db3:beng1 +0x7db4:zhui4 +0x7db5:cai3 +0x7db6:guo3 +0x7db7:cui4 +0x7db8:lun2 +0x7db9:liu3 +0x7dba:qi3 +0x7dbb:zhan4 +0x7dbc:bei1 +0x7dbd:chuo4 +0x7dbe:ling2 +0x7dbf:mian2 +0x7dc0:qi1 +0x7dc1:qie4 +0x7dc2:tan1 +0x7dc3:zong1 +0x7dc4:gun3 +0x7dc5:zou1 +0x7dc6:yi4 +0x7dc7:zi1 +0x7dc8:xing4 +0x7dc9:liang3 +0x7dca:jin3 +0x7dcb:fei1 +0x7dcc:rui2 +0x7dcd:min2 +0x7dce:yu4 +0x7dcf:zong3 +0x7dd0:fan2 +0x7dd1:lv4 +0x7dd2:xu4 +0x7dd3:ying1 +0x7dd4:zhang4 +0x7dd6:xu4 +0x7dd7:xiang1 +0x7dd8:jian1 +0x7dd9:ke4 +0x7dda:xian4 +0x7ddb:ruan3 +0x7ddc:mian2 +0x7ddd:ji1 +0x7dde:duan4 +0x7ddf:zhong4 +0x7de0:di4 +0x7de1:min2 +0x7de2:miao2 +0x7de3:yuan2 +0x7de4:xie4 +0x7de5:bao3 +0x7de6:si1 +0x7de7:qiu1 +0x7de8:bian1 +0x7de9:huan3 +0x7dea:geng1 +0x7deb:cong1 +0x7dec:mian3 +0x7ded:wei4 +0x7dee:fu4 +0x7def:wei3 +0x7df0:yu2 +0x7df1:gou1 +0x7df2:miao3 +0x7df3:xie2 +0x7df4:lian4 +0x7df5:zong1 +0x7df6:bian4 +0x7df7:yun4 +0x7df8:yin1 +0x7df9:ti2 +0x7dfa:gua1 +0x7dfb:zhi4 +0x7dfc:yun1 +0x7dfd:cheng1 +0x7dfe:chan2 +0x7dff:dai4 +0x7e00:xia2 +0x7e01:yuan2 +0x7e02:zong3 +0x7e03:xu1 +0x7e06:geng1 +0x7e08:ying2 +0x7e09:jin4 +0x7e0a:yi4 +0x7e0b:zhui4 +0x7e0c:ni4 +0x7e0d:bang1 +0x7e0e:gu3 +0x7e0f:pan2 +0x7e10:zhou4 +0x7e11:jian1 +0x7e12:cuo3 +0x7e13:quan3 +0x7e14:shuang3 +0x7e15:yun1 +0x7e16:xia2 +0x7e17:cui1 +0x7e18:xi1 +0x7e19:rong2 +0x7e1a:tao1 +0x7e1b:fu2 +0x7e1c:yun2 +0x7e1d:chen1 +0x7e1e:gao3 +0x7e1f:ru4 +0x7e20:hu2 +0x7e21:zai3 +0x7e22:teng2 +0x7e23:xian4 +0x7e24:su4 +0x7e25:zhen3 +0x7e26:zong4 +0x7e27:tao1 +0x7e29:cai4 +0x7e2a:bi4 +0x7e2b:feng2 +0x7e2c:cu4 +0x7e2d:li2 +0x7e2e:suo1 +0x7e2f:yin3 +0x7e30:xi3 +0x7e31:zong4 +0x7e32:lei2 +0x7e33:zhuan4 +0x7e34:qian1 +0x7e35:man4 +0x7e36:zhi2 +0x7e37:lv3 +0x7e38:mo4 +0x7e39:piao3 +0x7e3a:lian2 +0x7e3b:mi2 +0x7e3c:xuan4 +0x7e3d:zong3 +0x7e3e:ji1 +0x7e3f:shan1 +0x7e40:sui4 +0x7e41:fan2 +0x7e42:shuai4 +0x7e43:beng1 +0x7e44:yi1 +0x7e45:sao1 +0x7e46:mou2 +0x7e47:yao2 +0x7e48:qiang3 +0x7e49:hun2 +0x7e4b:xi4 +0x7e4d:xiu4 +0x7e4e:ran2 +0x7e4f:xuan4 +0x7e50:sui4 +0x7e51:qiao1 +0x7e52:zeng1 +0x7e53:zuo3 +0x7e54:zhi1 +0x7e55:shan4 +0x7e56:san3 +0x7e57:lin2 +0x7e58:yu4 +0x7e59:fan1 +0x7e5a:liao2 +0x7e5b:chuo4 +0x7e5c:zun1 +0x7e5d:jian4 +0x7e5e:rao4 +0x7e5f:chan3 +0x7e60:rui3 +0x7e61:xiu4 +0x7e62:hui4 +0x7e63:hua4 +0x7e64:zuan3 +0x7e65:xi1 +0x7e66:qiang3 +0x7e68:da2 +0x7e69:sheng2 +0x7e6a:hui4 +0x7e6b:xi4 +0x7e6c:se4 +0x7e6d:jian3 +0x7e6e:jiang1 +0x7e6f:huan2 +0x7e70:zao3 +0x7e71:cong1 +0x7e72:jie4 +0x7e73:jiao3 +0x7e74:bo4 +0x7e75:chan2 +0x7e76:yi4 +0x7e77:nao2 +0x7e78:sui4 +0x7e79:yi4 +0x7e7a:shai3 +0x7e7b:xu1 +0x7e7c:ji4 +0x7e7d:bin1 +0x7e7e:qian3 +0x7e7f:lan2 +0x7e80:pu2 +0x7e81:xun1 +0x7e82:zuan3 +0x7e83:qi2 +0x7e84:peng2 +0x7e85:li4 +0x7e86:mo4 +0x7e87:lei4 +0x7e88:xie2 +0x7e89:zuan3 +0x7e8a:kuang4 +0x7e8b:you1 +0x7e8c:xu4 +0x7e8d:lei2 +0x7e8e:xian1 +0x7e8f:chan2 +0x7e91:lu2 +0x7e92:chan2 +0x7e93:ying1 +0x7e94:cai2 +0x7e95:xiang1 +0x7e96:xian1 +0x7e97:zui1 +0x7e98:zuan3 +0x7e99:luo4 +0x7e9a:xi3 +0x7e9b:dao4 +0x7e9c:lan4 +0x7e9d:lei2 +0x7e9e:lian4 +0x7e9f:si1 +0x7ea0:jiu1 +0x7ea1:yu1 +0x7ea2:hong2 +0x7ea3:zhou4 +0x7ea4:xian1 +0x7ea5:he2 +0x7ea6:yue1 +0x7ea7:ji2 +0x7ea8:wan2 +0x7ea9:kuang4 +0x7eaa:ji4 +0x7eab:ren4 +0x7eac:wei3 +0x7ead:yun2 +0x7eae:hong2 +0x7eaf:chun2 +0x7eb0:pi2 +0x7eb1:sha1 +0x7eb2:gang1 +0x7eb3:na4 +0x7eb4:ren2 +0x7eb5:zong4 +0x7eb6:lun2 +0x7eb7:fen1 +0x7eb8:zhi3 +0x7eb9:wen2 +0x7eba:fang3 +0x7ebb:zhu4 +0x7ebc:yin3 +0x7ebd:niu3 +0x7ebe:shu1 +0x7ebf:xian4 +0x7ec0:gan4 +0x7ec1:xie4 +0x7ec2:fu2 +0x7ec3:lian4 +0x7ec4:zu3 +0x7ec5:shen1 +0x7ec6:xi4 +0x7ec7:zhi1 +0x7ec8:zhong1 +0x7ec9:zhou4 +0x7eca:ban4 +0x7ecb:fu2 +0x7ecc:zhuo2 +0x7ecd:shao4 +0x7ece:yi4 +0x7ecf:jing1 +0x7ed0:dai4 +0x7ed1:bang3 +0x7ed2:rong2 +0x7ed3:jie2 +0x7ed4:ku4 +0x7ed5:rao4 +0x7ed6:die2 +0x7ed7:heng4 +0x7ed8:hui4 +0x7ed9:gei3 +0x7eda:xuan4 +0x7edb:jiang4 +0x7edc:luo4 +0x7edd:jue2 +0x7ede:jiao3 +0x7edf:tong3 +0x7ee0:geng3 +0x7ee1:xiao1 +0x7ee2:juan4 +0x7ee3:xiu4 +0x7ee4:xi4 +0x7ee5:sui1 +0x7ee6:tao1 +0x7ee7:ji4 +0x7ee8:ti2 +0x7ee9:ji1 +0x7eea:xu4 +0x7eeb:ling2 +0x7eec:ying1 +0x7eed:xu4 +0x7eee:qi3 +0x7eef:fei1 +0x7ef0:chuo4 +0x7ef1:zhang3 +0x7ef2:gun3 +0x7ef3:sheng2 +0x7ef4:wei2 +0x7ef5:mian2 +0x7ef6:shou4 +0x7ef7:beng1 +0x7ef8:chou2 +0x7ef9:tao2 +0x7efa:liu3 +0x7efb:quan3 +0x7efc:zong4 +0x7efd:zhan4 +0x7efe:wan3 +0x7eff:lv4 +0x7f00:zhui4 +0x7f01:zi1 +0x7f02:ke4 +0x7f03:xiang1 +0x7f04:jian1 +0x7f05:mian3 +0x7f06:lan4 +0x7f07:ti2 +0x7f08:miao3 +0x7f09:qi4 +0x7f0a:yun1 +0x7f0b:hui4 +0x7f0c:si1 +0x7f0d:duo3 +0x7f0e:duan4 +0x7f0f:bian4 +0x7f10:xian4 +0x7f11:gou1 +0x7f12:zhui4 +0x7f13:huan3 +0x7f14:di4 +0x7f15:lv3 +0x7f16:bian1 +0x7f17:min2 +0x7f18:yuan2 +0x7f19:jin4 +0x7f1a:fu2 +0x7f1b:ru4 +0x7f1c:zhen1 +0x7f1d:feng2 +0x7f1e:shuai1 +0x7f1f:gao3 +0x7f20:chan2 +0x7f21:li2 +0x7f22:yi4 +0x7f23:jian1 +0x7f24:bin1 +0x7f25:piao3 +0x7f26:man4 +0x7f27:lei2 +0x7f28:ying1 +0x7f29:suo1 +0x7f2a:mou2 +0x7f2b:sao1 +0x7f2c:xie2 +0x7f2d:liao2 +0x7f2e:shan4 +0x7f2f:zeng1 +0x7f30:jiang1 +0x7f31:qian3 +0x7f32:zao3 +0x7f33:huan2 +0x7f34:jiao3 +0x7f35:zuan3 +0x7f36:fou3 +0x7f37:xie4 +0x7f38:gang1 +0x7f39:fou3 +0x7f3a:que1 +0x7f3b:fou3 +0x7f3d:bo1 +0x7f3e:ping2 +0x7f3f:hou4 +0x7f41:gang1 +0x7f42:ying1 +0x7f43:ying1 +0x7f44:qing4 +0x7f45:xia4 +0x7f46:guan4 +0x7f47:zun1 +0x7f48:tan2 +0x7f4a:qi4 +0x7f4b:weng4 +0x7f4c:ying1 +0x7f4d:lei2 +0x7f4e:tan2 +0x7f4f:lu2 +0x7f50:guan4 +0x7f51:wang3 +0x7f52:wang3 +0x7f53:gang1 +0x7f54:wang3 +0x7f55:han3 +0x7f57:luo1 +0x7f58:fu2 +0x7f59:mi2 +0x7f5a:fa2 +0x7f5b:gu1 +0x7f5c:zhu3 +0x7f5d:ju1 +0x7f5e:mao2 +0x7f5f:gu3 +0x7f60:min2 +0x7f61:gang1 +0x7f62:ba4 +0x7f63:gua4 +0x7f64:ti2 +0x7f65:juan4 +0x7f66:fu2 +0x7f67:lin2 +0x7f68:yan3 +0x7f69:zhao4 +0x7f6a:zui4 +0x7f6b:gua4 +0x7f6c:zhuo2 +0x7f6d:yu4 +0x7f6e:zhi4 +0x7f6f:an3 +0x7f70:fa2 +0x7f71:nan3 +0x7f72:shu3 +0x7f73:si1 +0x7f74:pi2 +0x7f75:ma4 +0x7f76:liu3 +0x7f77:ba4 +0x7f78:fa2 +0x7f79:li2 +0x7f7a:chao1 +0x7f7b:wei4 +0x7f7c:bi4 +0x7f7d:ji4 +0x7f7e:zeng1 +0x7f7f:tong2 +0x7f80:liu3 +0x7f81:ji1 +0x7f82:juan4 +0x7f83:mi4 +0x7f84:zhao4 +0x7f85:luo2 +0x7f86:pi2 +0x7f87:ji1 +0x7f88:ji1 +0x7f89:luan2 +0x7f8a:yang2 +0x7f8b:mi3 +0x7f8c:qiang1 +0x7f8d:ta4 +0x7f8e:mei3 +0x7f8f:yang2 +0x7f90:you3 +0x7f91:you3 +0x7f92:fen2 +0x7f93:ba1 +0x7f94:gao1 +0x7f95:yang4 +0x7f96:gu3 +0x7f97:qiang1 +0x7f98:zang1 +0x7f99:gao1 +0x7f9a:ling2 +0x7f9b:yi4 +0x7f9c:zhu4 +0x7f9d:di1 +0x7f9e:xiu1 +0x7f9f:qian1 +0x7fa0:yi2 +0x7fa1:xian4 +0x7fa2:rong2 +0x7fa3:qun2 +0x7fa4:qun2 +0x7fa5:qiang3 +0x7fa6:huan2 +0x7fa7:suo1 +0x7fa8:xian4 +0x7fa9:yi4 +0x7fab:qiang1 +0x7fac:xian2 +0x7fad:yu2 +0x7fae:geng1 +0x7faf:jie2 +0x7fb0:tang1 +0x7fb1:yuan2 +0x7fb2:xi1 +0x7fb3:fan2 +0x7fb4:shan1 +0x7fb5:fen3 +0x7fb6:shan1 +0x7fb7:lian3 +0x7fb8:lei2 +0x7fb9:geng1 +0x7fba:nou2 +0x7fbb:qiang4 +0x7fbc:chan4 +0x7fbd:yu3 +0x7fbe:gong4 +0x7fbf:yi4 +0x7fc0:chong1 +0x7fc1:weng1 +0x7fc2:fen1 +0x7fc3:hong2 +0x7fc4:chi4 +0x7fc5:chi4 +0x7fc6:cui4 +0x7fc7:fu2 +0x7fc8:xia2 +0x7fc9:pen3 +0x7fca:yi4 +0x7fcb:la1 +0x7fcc:yi4 +0x7fcd:pi1 +0x7fce:ling2 +0x7fcf:liu4 +0x7fd0:zhi4 +0x7fd1:qu2 +0x7fd2:xi2 +0x7fd3:xie2 +0x7fd4:xiang2 +0x7fd5:xi4 +0x7fd6:xi4 +0x7fd7:qi2 +0x7fd8:qiao2 +0x7fd9:hui4 +0x7fda:hui1 +0x7fdb:xiao1 +0x7fdc:se4 +0x7fdd:hong2 +0x7fde:jiang1 +0x7fdf:di2 +0x7fe0:cui4 +0x7fe1:fei3 +0x7fe2:tao1 +0x7fe3:sha4 +0x7fe4:chi4 +0x7fe5:zhu4 +0x7fe6:jian3 +0x7fe7:xuan1 +0x7fe8:shi4 +0x7fe9:pian1 +0x7fea:zong1 +0x7feb:wan4 +0x7fec:hui1 +0x7fed:hou2 +0x7fee:he2 +0x7fef:he4 +0x7ff0:han4 +0x7ff1:ao2 +0x7ff2:piao1 +0x7ff3:yi4 +0x7ff4:lian2 +0x7ff5:qu2 +0x7ff7:lin2 +0x7ff8:pen3 +0x7ff9:qiao2 +0x7ffa:ao2 +0x7ffb:fan1 +0x7ffc:yi4 +0x7ffd:hui4 +0x7ffe:xuan1 +0x7fff:dao4 +0x8000:yao4 +0x8001:lao3 +0x8003:kao3 +0x8004:mao4 +0x8005:zhe3 +0x8006:qi2 +0x8007:gou3 +0x8008:gou3 +0x8009:gou3 +0x800a:die4 +0x800b:die4 +0x800c:er2 +0x800d:shua3 +0x800e:ruan3 +0x800f:er2 +0x8010:nai4 +0x8011:zhuan1 +0x8012:lei3 +0x8013:ting1 +0x8014:zi3 +0x8015:geng1 +0x8016:chao4 +0x8017:hao4 +0x8018:yun2 +0x8019:ba4 +0x801a:pi1 +0x801b:chi2 +0x801c:si4 +0x801d:chu2 +0x801e:jia1 +0x801f:ju4 +0x8020:he2 +0x8021:chu2 +0x8022:lao4 +0x8023:lun3 +0x8024:ji2 +0x8025:tang3 +0x8026:ou3 +0x8027:lou2 +0x8028:nou4 +0x8029:jiang3 +0x802a:pang3 +0x802b:ze2 +0x802c:lou2 +0x802d:ji1 +0x802e:lao4 +0x802f:huo4 +0x8030:you1 +0x8031:mo4 +0x8032:huai2 +0x8033:er3 +0x8034:zhe2 +0x8035:ting1 +0x8036:ye2 +0x8037:da1 +0x8038:song3 +0x8039:qin2 +0x803a:yun2 +0x803b:chi3 +0x803c:dan1 +0x803d:dan1 +0x803e:hong2 +0x803f:geng3 +0x8040:zhi2 +0x8042:nie4 +0x8043:dan1 +0x8044:zhen3 +0x8045:che4 +0x8046:ling2 +0x8047:zheng1 +0x8048:you3 +0x8049:wa1 +0x804a:liao2 +0x804b:long2 +0x804c:zhi2 +0x804d:ning2 +0x804e:tiao1 +0x804f:er2 +0x8050:ya4 +0x8051:die2 +0x8052:gua1 +0x8054:lian2 +0x8055:hao4 +0x8056:sheng4 +0x8057:lie4 +0x8058:pin4 +0x8059:jing1 +0x805a:ju4 +0x805b:bi4 +0x805c:di3 +0x805d:guo2 +0x805e:wen2 +0x805f:xu4 +0x8060:ping2 +0x8061:cong1 +0x8064:ting2 +0x8065:yu3 +0x8066:cong1 +0x8067:kui2 +0x8069:kui4 +0x806a:cong1 +0x806b:lian2 +0x806c:weng3 +0x806d:kui4 +0x806e:lian2 +0x806f:lian2 +0x8070:cong1 +0x8071:ao2 +0x8072:sheng1 +0x8073:song3 +0x8074:ting1 +0x8075:kui4 +0x8076:nie4 +0x8077:zhi2 +0x8078:dan1 +0x8079:ning2 +0x807b:ji1 +0x807c:ting1 +0x807d:ting1 +0x807e:long2 +0x807f:yu4 +0x8080:yu4 +0x8081:zhao4 +0x8082:si4 +0x8083:su4 +0x8084:yi4 +0x8085:su4 +0x8086:si4 +0x8087:zhao4 +0x8088:zhao4 +0x8089:rou4 +0x808a:yi4 +0x808b:lei4 +0x808c:ji1 +0x808d:qiu2 +0x808e:ken3 +0x808f:cao4 +0x8090:ge1 +0x8091:di4 +0x8092:huan2 +0x8093:huang1 +0x8094:yi3 +0x8095:ren4 +0x8096:xiao4 +0x8097:ru3 +0x8098:zhou3 +0x8099:yuan1 +0x809a:du4 +0x809b:gang1 +0x809c:rong2 +0x809d:gan1 +0x809e:cha1 +0x809f:wo4 +0x80a0:chang2 +0x80a1:gu3 +0x80a2:zhi1 +0x80a3:han2 +0x80a4:fu1 +0x80a5:fei2 +0x80a6:fen2 +0x80a7:pei1 +0x80a8:pang4 +0x80a9:jian1 +0x80aa:fang2 +0x80ab:zhun1 +0x80ac:you2 +0x80ad:na4 +0x80ae:hang2 +0x80af:ken3 +0x80b0:ran2 +0x80b1:gong1 +0x80b2:yu4 +0x80b3:wen3 +0x80b4:yao2 +0x80b5:jin4 +0x80b6:pi2 +0x80b7:qian1 +0x80b8:xi4 +0x80b9:xi1 +0x80ba:fei4 +0x80bb:ken3 +0x80bc:jing3 +0x80bd:tai4 +0x80be:shen4 +0x80bf:zhong3 +0x80c0:zhang4 +0x80c1:xie2 +0x80c2:shen1 +0x80c3:wei4 +0x80c4:zhou4 +0x80c5:die2 +0x80c6:dan3 +0x80c7:fei4 +0x80c8:ba2 +0x80c9:bo2 +0x80ca:qu2 +0x80cb:tian2 +0x80cc:bei4 +0x80cd:gua1 +0x80ce:tai1 +0x80cf:zi3 +0x80d0:ku1 +0x80d1:zhi1 +0x80d2:ni4 +0x80d3:ping2 +0x80d4:zi4 +0x80d5:fu4 +0x80d6:pang4 +0x80d7:zhen1 +0x80d8:xian2 +0x80d9:zuo4 +0x80da:pei1 +0x80db:jia3 +0x80dc:sheng4 +0x80dd:zhi1 +0x80de:bao1 +0x80df:mu3 +0x80e0:qu1 +0x80e1:hu2 +0x80e2:ke1 +0x80e3:yi3 +0x80e4:yin4 +0x80e5:xu1 +0x80e6:yang1 +0x80e7:long2 +0x80e8:dong4 +0x80e9:ka3 +0x80ea:lu2 +0x80eb:jing4 +0x80ec:nu3 +0x80ed:yan1 +0x80ee:pang2 +0x80ef:kua4 +0x80f0:yi2 +0x80f1:guang1 +0x80f2:hai3 +0x80f3:ge1 +0x80f4:dong4 +0x80f5:zhi4 +0x80f6:xiao2 +0x80f7:xiong1 +0x80f8:xiong1 +0x80f9:er2 +0x80fa:e4 +0x80fb:xing2 +0x80fc:pian2 +0x80fd:neng2 +0x80fe:zi4 +0x8100:cheng2 +0x8101:tiao4 +0x8102:zhi1 +0x8103:cui4 +0x8104:mei2 +0x8105:xie2 +0x8106:cui4 +0x8107:xie2 +0x8108:mai4 +0x8109:mai4 +0x810a:ji2 +0x810d:kuai4 +0x810e:sa4 +0x810f:zang1 +0x8110:qi2 +0x8111:nao3 +0x8112:mi3 +0x8113:nong2 +0x8114:luan2 +0x8115:wan3 +0x8116:bo2 +0x8117:wen3 +0x8118:guan3 +0x8119:qiu2 +0x811a:jiao3 +0x811b:jing4 +0x811c:rou2 +0x811d:heng1 +0x811e:cuo3 +0x811f:lie4 +0x8120:shan1 +0x8121:ting3 +0x8122:mei2 +0x8123:chun2 +0x8124:shen4 +0x8125:qian3 +0x8126:te4 +0x8127:zui1 +0x8128:cu4 +0x8129:xiu1 +0x812a:xin4 +0x812b:tuo1 +0x812c:pao1 +0x812d:cheng2 +0x812e:nei3 +0x812f:fu3 +0x8130:dou4 +0x8131:tuo1 +0x8132:niao4 +0x8134:pi3 +0x8135:gu3 +0x8136:gua1 +0x8137:li4 +0x8138:lian3 +0x8139:zhang4 +0x813a:cui4 +0x813b:jie2 +0x813c:liang3 +0x813d:zhou1 +0x813e:pi2 +0x813f:biao1 +0x8140:lun2 +0x8141:pian2 +0x8142:guo4 +0x8143:kui4 +0x8144:chui2 +0x8145:dan4 +0x8146:tian3 +0x8147:nei3 +0x8148:jing1 +0x8149:jie1 +0x814a:la4 +0x814b:yi4 +0x814c:yan1 +0x814d:ren3 +0x814e:shen4 +0x814f:chuo4 +0x8150:fu3 +0x8151:fu3 +0x8152:ju1 +0x8153:fei2 +0x8154:qiang1 +0x8155:wan4 +0x8156:dong4 +0x8157:pi2 +0x8158:guo2 +0x8159:zong1 +0x815a:ding4 +0x815b:wu1 +0x815c:mei2 +0x815d:ruan3 +0x815e:zhuan4 +0x815f:zhi4 +0x8160:cou4 +0x8161:gua1 +0x8162:ou3 +0x8163:di4 +0x8164:an1 +0x8165:xing1 +0x8166:nao3 +0x8167:yu2 +0x8168:chuan3 +0x8169:nan3 +0x816a:yun4 +0x816b:zhong3 +0x816c:rou2 +0x816d:e4 +0x816e:sai1 +0x816f:tu2 +0x8170:yao1 +0x8171:jian4 +0x8172:wei3 +0x8173:jiao3 +0x8174:yu2 +0x8175:jia1 +0x8176:duan4 +0x8177:bi4 +0x8178:chang2 +0x8179:fu4 +0x817a:xian4 +0x817b:ni4 +0x817c:mian3 +0x817d:wa4 +0x817e:teng2 +0x817f:tui3 +0x8180:bang3 +0x8181:qian1 +0x8182:lv3 +0x8183:wa4 +0x8184:sou4 +0x8185:tang2 +0x8186:su4 +0x8187:zhui4 +0x8188:ge2 +0x8189:yi4 +0x818a:bo2 +0x818b:liao2 +0x818c:ji2 +0x818d:pi2 +0x818e:xie2 +0x818f:gao1 +0x8190:lv3 +0x8191:bin4 +0x8193:chang2 +0x8194:lu4 +0x8195:guo2 +0x8196:pang1 +0x8197:chuai2 +0x8198:piao3 +0x8199:jiang3 +0x819a:fu1 +0x819b:tang2 +0x819c:mo4 +0x819d:xi1 +0x819e:zhuan1 +0x819f:lv4 +0x81a0:jiao1 +0x81a1:ying4 +0x81a2:lv2 +0x81a3:zhi4 +0x81a5:chun1 +0x81a6:lian3 +0x81a7:tong2 +0x81a8:peng2 +0x81a9:ni4 +0x81aa:zha4 +0x81ab:liao2 +0x81ac:cui4 +0x81ad:gui1 +0x81ae:xiao1 +0x81af:teng1 +0x81b0:fan2 +0x81b1:zhi2 +0x81b2:jiao1 +0x81b3:shan4 +0x81b4:hu1 +0x81b5:cui4 +0x81b6:run4 +0x81b7:xiang1 +0x81b8:sui3 +0x81b9:fen4 +0x81ba:ying1 +0x81bb:dan4 +0x81bc:zhua1 +0x81bd:dan3 +0x81be:kuai4 +0x81bf:nong2 +0x81c0:tun2 +0x81c1:lian2 +0x81c2:bi4 +0x81c3:yong3 +0x81c4:jue2 +0x81c5:chu4 +0x81c6:yi4 +0x81c7:juan3 +0x81c8:la4 +0x81c9:lian3 +0x81ca:sao1 +0x81cb:tun2 +0x81cc:gu3 +0x81cd:qi2 +0x81ce:cui4 +0x81cf:bin4 +0x81d0:xun1 +0x81d1:ru2 +0x81d2:huo4 +0x81d3:zang4 +0x81d4:xian4 +0x81d5:biao1 +0x81d6:xing4 +0x81d7:kuan1 +0x81d8:la4 +0x81d9:yan1 +0x81da:lu2 +0x81db:huo4 +0x81dc:zang1 +0x81dd:luo3 +0x81de:qu2 +0x81df:zang4 +0x81e0:luan2 +0x81e1:ni2 +0x81e2:zang1 +0x81e3:chen2 +0x81e4:qian1 +0x81e5:wo4 +0x81e6:guang4 +0x81e7:zang1 +0x81e8:lin2 +0x81e9:guang4 +0x81ea:zi4 +0x81eb:jiao3 +0x81ec:nie4 +0x81ed:chou4 +0x81ee:ji4 +0x81ef:gao1 +0x81f0:chou4 +0x81f1:mian2 +0x81f2:nie4 +0x81f3:zhi4 +0x81f4:zhi4 +0x81f5:ge2 +0x81f6:jian4 +0x81f7:die2 +0x81f8:zhi4 +0x81f9:xiu1 +0x81fa:tai2 +0x81fb:zhen1 +0x81fc:jiu4 +0x81fd:xian4 +0x81fe:yu2 +0x81ff:cha1 +0x8200:yao3 +0x8201:yu2 +0x8202:chong1 +0x8203:xi4 +0x8204:xi4 +0x8205:jiu4 +0x8206:yu2 +0x8207:yu3 +0x8208:xing1 +0x8209:ju3 +0x820a:jiu4 +0x820b:xin4 +0x820c:she2 +0x820d:she4 +0x820f:jiu3 +0x8210:shi4 +0x8211:tan1 +0x8212:shu1 +0x8213:shi4 +0x8214:tian3 +0x8215:dan4 +0x8216:pu4 +0x8217:pu4 +0x8218:guan3 +0x8219:hua4 +0x821a:tan1 +0x821b:chuan3 +0x821c:shun4 +0x821d:xia2 +0x821e:wu3 +0x821f:zhou1 +0x8220:dao1 +0x8221:gang1 +0x8222:shan1 +0x8223:yi3 +0x8225:pa1 +0x8226:tai4 +0x8227:fan2 +0x8228:ban3 +0x8229:chuan2 +0x822a:hang2 +0x822b:fang3 +0x822c:ban1 +0x822d:que4 +0x822f:zhong1 +0x8230:jian4 +0x8231:cang1 +0x8232:ling2 +0x8233:zhu2 +0x8234:ze2 +0x8235:duo4 +0x8236:bo2 +0x8237:xian2 +0x8238:ge3 +0x8239:chuan2 +0x823a:xia2 +0x823b:lu3 +0x823c:hong2 +0x823d:pang2 +0x823e:xi1 +0x8240:fu2 +0x8241:zao4 +0x8242:feng2 +0x8243:li2 +0x8244:shao1 +0x8245:yu2 +0x8246:lang2 +0x8247:ting3 +0x8249:wei3 +0x824a:bo2 +0x824b:meng3 +0x824c:nian4 +0x824d:ju1 +0x824e:huang2 +0x824f:shou3 +0x8250:zong1 +0x8251:bian4 +0x8252:mao4 +0x8253:die2 +0x8255:bang4 +0x8256:cha1 +0x8257:yi4 +0x8258:sao1 +0x8259:cang1 +0x825a:cao2 +0x825b:lou2 +0x825c:dai4 +0x825e:yao4 +0x825f:tong2 +0x8261:dang1 +0x8262:tan2 +0x8263:lu3 +0x8264:yi3 +0x8265:jie4 +0x8266:jian4 +0x8267:huo4 +0x8268:meng2 +0x8269:qi2 +0x826a:lu3 +0x826b:lu2 +0x826c:chan2 +0x826d:shuang1 +0x826e:gen4 +0x826f:liang2 +0x8270:jian1 +0x8271:jian1 +0x8272:se4 +0x8273:yan4 +0x8274:fu2 +0x8275:ping2 +0x8276:yan4 +0x8277:yan4 +0x8278:cao3 +0x827a:yi4 +0x827b:le4 +0x827c:ting1 +0x827d:qiu2 +0x827e:ai4 +0x827f:nai3 +0x8280:tiao2 +0x8281:jiao1 +0x8282:jie2 +0x8283:peng2 +0x8284:wan2 +0x8285:yi4 +0x8286:chai1 +0x8287:mian2 +0x8288:mie1 +0x8289:gan1 +0x828a:qian1 +0x828b:yu4 +0x828c:yu4 +0x828d:shao2 +0x828e:qiong1 +0x828f:tu3 +0x8290:xia4 +0x8291:qi3 +0x8292:mang2 +0x8293:zi3 +0x8294:hui3 +0x8295:sui1 +0x8296:zhi4 +0x8297:xiang1 +0x8298:pi2 +0x8299:fu2 +0x829a:tun2 +0x829b:wei3 +0x829c:wu2 +0x829d:zhi1 +0x829e:qi3 +0x829f:shan1 +0x82a0:wen2 +0x82a1:qian4 +0x82a2:ren2 +0x82a3:fu2 +0x82a4:kou1 +0x82a5:jie4 +0x82a6:lu2 +0x82a7:xu4 +0x82a8:ji2 +0x82a9:qin2 +0x82aa:qi2 +0x82ab:yuan2 +0x82ac:fen1 +0x82ad:ba1 +0x82ae:rui4 +0x82af:xin1 +0x82b0:ji4 +0x82b1:hua1 +0x82b2:hua1 +0x82b3:fang1 +0x82b4:wu4 +0x82b5:jue2 +0x82b6:gou1 +0x82b7:zhi3 +0x82b8:yun2 +0x82b9:qin2 +0x82ba:ao3 +0x82bb:chu2 +0x82bc:mao4 +0x82bd:ya2 +0x82be:fei4 +0x82bf:reng4 +0x82c0:hang2 +0x82c1:cong1 +0x82c2:yin2 +0x82c3:you3 +0x82c4:bian4 +0x82c5:yi4 +0x82c7:wei3 +0x82c8:li4 +0x82c9:pi3 +0x82ca:e4 +0x82cb:xian4 +0x82cc:chang2 +0x82cd:cang1 +0x82ce:meng2 +0x82cf:su1 +0x82d0:yi2 +0x82d1:yuan4 +0x82d2:ran3 +0x82d3:ling2 +0x82d4:tai2 +0x82d5:tiao2 +0x82d6:di3 +0x82d7:miao2 +0x82d8:qiong3 +0x82d9:li4 +0x82da:yong4 +0x82db:ke1 +0x82dc:mu4 +0x82dd:pei4 +0x82de:bao1 +0x82df:gou3 +0x82e0:min2 +0x82e1:yi3 +0x82e2:yi3 +0x82e3:ju4 +0x82e4:pi1 +0x82e5:ruo4 +0x82e6:ku3 +0x82e7:zhu4 +0x82e8:ni3 +0x82e9:bo2 +0x82ea:bing3 +0x82eb:shan1 +0x82ec:qiu2 +0x82ed:yao3 +0x82ee:xian1 +0x82ef:ben3 +0x82f0:hong2 +0x82f1:ying1 +0x82f2:zha3 +0x82f3:dong1 +0x82f4:ju1 +0x82f5:die2 +0x82f6:nie2 +0x82f7:gan1 +0x82f8:hu1 +0x82f9:ping2 +0x82fa:mei2 +0x82fb:fu2 +0x82fc:sheng1 +0x82fd:gu1 +0x82fe:bi4 +0x82ff:wei4 +0x8300:fu2 +0x8301:zhuo2 +0x8302:mao4 +0x8303:fan4 +0x8304:qie2 +0x8305:mao2 +0x8306:mao3 +0x8307:ba2 +0x8308:zi3 +0x8309:mo4 +0x830a:zi1 +0x830b:di3 +0x830c:chi2 +0x830d:ji4 +0x830e:jing1 +0x830f:long2 +0x8311:niao3 +0x8313:xue2 +0x8314:ying2 +0x8315:qiong2 +0x8316:ge2 +0x8317:ming2 +0x8318:li4 +0x8319:rong2 +0x831a:yin4 +0x831b:gen4 +0x831c:qian4 +0x831d:chai3 +0x831e:chen2 +0x831f:yu4 +0x8320:xiu1 +0x8321:zi4 +0x8322:lie4 +0x8323:wu2 +0x8324:ji4 +0x8325:gui1 +0x8326:ce4 +0x8327:chong2 +0x8328:ci2 +0x8329:gou3 +0x832a:guang1 +0x832b:mang2 +0x832c:chi2 +0x832d:jiao1 +0x832e:jiao1 +0x832f:fu2 +0x8330:yu2 +0x8331:zhu1 +0x8332:zi1 +0x8333:jiang1 +0x8334:hui2 +0x8335:yin1 +0x8336:cha2 +0x8337:fa2 +0x8338:rong2 +0x8339:ru2 +0x833a:chong1 +0x833b:mang3 +0x833c:tong2 +0x833d:zhong4 +0x833f:zhu2 +0x8340:xun2 +0x8341:huan2 +0x8342:kua1 +0x8343:quan2 +0x8344:gai1 +0x8345:da1 +0x8346:jing1 +0x8347:xing4 +0x8348:chuan3 +0x8349:cao3 +0x834a:jing1 +0x834b:er2 +0x834c:an4 +0x834d:shou1 +0x834e:chi2 +0x834f:ren3 +0x8350:jian4 +0x8351:ti2 +0x8352:huang1 +0x8353:ping2 +0x8354:li4 +0x8355:jin1 +0x8356:lao3 +0x8357:shu4 +0x8358:zhuang1 +0x8359:da2 +0x835a:jia2 +0x835b:rao2 +0x835c:bi4 +0x835d:ze2 +0x835e:qiao2 +0x835f:hui4 +0x8360:qi2 +0x8361:dang4 +0x8363:rong2 +0x8364:hun1 +0x8365:ying2 +0x8366:luo4 +0x8367:ying2 +0x8368:xun2 +0x8369:jin4 +0x836a:sun1 +0x836b:yin4 +0x836c:mai3 +0x836d:hong2 +0x836e:zhou4 +0x836f:yao4 +0x8370:du4 +0x8371:wei3 +0x8372:chu4 +0x8373:dou4 +0x8374:fu1 +0x8375:ren3 +0x8376:yin2 +0x8377:he2 +0x8378:bi2 +0x8379:bu4 +0x837a:yun2 +0x837b:di2 +0x837c:tu2 +0x837d:sui1 +0x837e:sui1 +0x837f:cheng2 +0x8380:chen2 +0x8381:wu2 +0x8382:bie2 +0x8383:xi1 +0x8384:geng3 +0x8385:li4 +0x8386:fu3 +0x8387:zhu4 +0x8388:mo4 +0x8389:li4 +0x838a:zhuang1 +0x838b:ji2 +0x838c:duo2 +0x838d:qiu2 +0x838e:sha1 +0x838f:suo1 +0x8390:chen2 +0x8391:feng1 +0x8392:ju3 +0x8393:mei2 +0x8394:meng2 +0x8395:xing4 +0x8396:jing1 +0x8397:che1 +0x8398:shen1 +0x8399:jun1 +0x839a:yan2 +0x839b:ting2 +0x839c:diao4 +0x839d:cuo4 +0x839e:guan1 +0x839f:han4 +0x83a0:you3 +0x83a1:cuo4 +0x83a2:jia2 +0x83a3:wang2 +0x83a4:you2 +0x83a5:niu3 +0x83a6:shao1 +0x83a7:xian4 +0x83a8:lang2 +0x83a9:fu2 +0x83aa:e2 +0x83ab:mo4 +0x83ac:wen4 +0x83ad:jie2 +0x83ae:nan2 +0x83af:mu4 +0x83b0:kan3 +0x83b1:lai2 +0x83b2:lian2 +0x83b3:shi2 +0x83b4:wo1 +0x83b6:lian3 +0x83b7:huo4 +0x83b8:you2 +0x83b9:ying2 +0x83ba:ying1 +0x83bc:chun2 +0x83bd:mang3 +0x83be:mang3 +0x83bf:ci4 +0x83c0:wan3 +0x83c1:jing1 +0x83c2:di1 +0x83c3:qu2 +0x83c4:dong1 +0x83c5:jian1 +0x83c6:zou1 +0x83c7:gu1 +0x83c8:la1 +0x83c9:lu4 +0x83ca:ju2 +0x83cb:wei4 +0x83cc:jun1 +0x83cd:nie4 +0x83ce:kun1 +0x83cf:he2 +0x83d0:pu2 +0x83d1:zi1 +0x83d2:gao3 +0x83d3:guo3 +0x83d4:fu2 +0x83d5:lun2 +0x83d6:chang1 +0x83d7:chou2 +0x83d8:song1 +0x83d9:chui2 +0x83da:zhan4 +0x83db:men2 +0x83dc:cai4 +0x83dd:ba2 +0x83de:li2 +0x83df:tu4 +0x83e0:bo1 +0x83e1:han4 +0x83e2:bao4 +0x83e3:qin4 +0x83e4:juan3 +0x83e5:xi1 +0x83e6:qin2 +0x83e7:di3 +0x83e8:jie1 +0x83e9:pu2 +0x83ea:dang4 +0x83eb:jin3 +0x83ec:zhao3 +0x83ed:tai2 +0x83ee:geng1 +0x83ef:hua2 +0x83f0:gu1 +0x83f1:ling2 +0x83f2:fei1 +0x83f3:jin1 +0x83f4:an1 +0x83f5:wang3 +0x83f6:beng3 +0x83f7:zhou3 +0x83f8:yan1 +0x83f9:ju1 +0x83fa:jian1 +0x83fb:lin3 +0x83fc:tan3 +0x83fd:shu2 +0x83fe:tian2 +0x83ff:dao4 +0x8400:hu3 +0x8401:qi2 +0x8402:he2 +0x8403:cui4 +0x8404:tao2 +0x8405:chun1 +0x8406:pi4 +0x8407:chang2 +0x8408:huan2 +0x8409:fei2 +0x840a:lai2 +0x840b:qi1 +0x840c:meng2 +0x840d:ping2 +0x840e:wei1 +0x840f:dan4 +0x8410:sha4 +0x8411:huan2 +0x8412:yan3 +0x8413:yi2 +0x8414:tiao2 +0x8415:qi2 +0x8416:wan3 +0x8417:ce4 +0x8418:nai4 +0x841a:tuo4 +0x841b:jiu1 +0x841c:tie1 +0x841d:luo2 +0x8420:meng2 +0x8424:ying2 +0x8425:ying2 +0x8426:ying2 +0x8427:xiao1 +0x8428:sa4 +0x8429:qiu1 +0x842a:ke1 +0x842b:xiang4 +0x842c:wan4 +0x842d:yu3 +0x842e:yu4 +0x842f:fu4 +0x8430:lian4 +0x8431:xuan1 +0x8432:yuan2 +0x8433:nan2 +0x8434:ze2 +0x8435:wo1 +0x8436:chun3 +0x8437:xiao1 +0x8438:yu2 +0x8439:pian1 +0x843a:mao4 +0x843b:an1 +0x843c:e4 +0x843d:luo4 +0x843e:ying2 +0x843f:huo2 +0x8440:gua1 +0x8441:jiang1 +0x8442:mian3 +0x8443:zuo2 +0x8444:zuo4 +0x8445:ju1 +0x8446:bao3 +0x8447:rou2 +0x8448:xi3 +0x8449:ye4 +0x844a:an1 +0x844b:qu2 +0x844c:jian1 +0x844d:fu2 +0x844e:lv4 +0x844f:jing1 +0x8450:pen2 +0x8451:feng1 +0x8452:hong2 +0x8453:hong2 +0x8454:hou2 +0x8455:yan2 +0x8456:tu2 +0x8457:zhu4 +0x8458:zi1 +0x8459:xiang1 +0x845a:shen4 +0x845b:ge2 +0x845c:jie2 +0x845d:jing4 +0x845e:mi3 +0x845f:huang2 +0x8460:shen1 +0x8461:pu2 +0x8462:gai4 +0x8463:dong3 +0x8464:zhou4 +0x8465:qian2 +0x8466:wei3 +0x8467:bo2 +0x8468:wei1 +0x8469:pa1 +0x846a:ji4 +0x846b:hu2 +0x846c:zang4 +0x846d:jia1 +0x846e:duan4 +0x846f:yao4 +0x8470:jun4 +0x8471:cong1 +0x8472:quan2 +0x8473:wei1 +0x8474:zhen1 +0x8475:kui2 +0x8476:ting2 +0x8477:hun1 +0x8478:xi3 +0x8479:shi1 +0x847a:qi4 +0x847b:lan2 +0x847c:zong1 +0x847d:yao1 +0x847e:yuan1 +0x847f:mei2 +0x8480:yun1 +0x8481:shu4 +0x8482:di4 +0x8483:zhuan4 +0x8484:guan1 +0x8486:xue1 +0x8487:chan3 +0x8488:kai3 +0x8489:kui4 +0x848b:jiang3 +0x848c:lou2 +0x848d:wei2 +0x848e:pai4 +0x8490:sou1 +0x8491:yin1 +0x8492:shi1 +0x8493:chun2 +0x8494:shi2 +0x8495:yun1 +0x8496:zhen1 +0x8497:lang4 +0x8498:nu2 +0x8499:meng2 +0x849a:he2 +0x849b:que1 +0x849c:suan4 +0x849d:yuan2 +0x849e:li4 +0x849f:ju3 +0x84a0:xi2 +0x84a1:bang4 +0x84a2:chu2 +0x84a3:xu2 +0x84a4:tu2 +0x84a5:liu2 +0x84a6:wo4 +0x84a7:zhen1 +0x84a8:qian4 +0x84a9:zu1 +0x84aa:po4 +0x84ab:cuo1 +0x84ac:yuan1 +0x84ad:chu2 +0x84ae:yu4 +0x84af:kuai3 +0x84b0:pan2 +0x84b1:pu2 +0x84b2:pu2 +0x84b3:na4 +0x84b4:shuo4 +0x84b5:xi1 +0x84b6:fen2 +0x84b7:yun2 +0x84b8:zheng1 +0x84b9:jian1 +0x84ba:ji2 +0x84bb:ruo4 +0x84bc:cang1 +0x84bd:en1 +0x84be:mi2 +0x84bf:hao1 +0x84c0:sun1 +0x84c1:zhen1 +0x84c2:ming2 +0x84c3:huo4 +0x84c4:xu4 +0x84c5:liu2 +0x84c6:xi2 +0x84c7:gu3 +0x84c8:lang2 +0x84c9:rong2 +0x84ca:weng3 +0x84cb:gai4 +0x84cc:cuo4 +0x84cd:shi1 +0x84ce:tang2 +0x84cf:luo3 +0x84d0:ru4 +0x84d1:suo1 +0x84d2:xian1 +0x84d3:bei4 +0x84d4:yao3 +0x84d5:gui4 +0x84d6:bi4 +0x84d7:zong3 +0x84d8:gun3 +0x84da:xiu1 +0x84db:ce4 +0x84dd:lan2 +0x84df:ji4 +0x84e0:li2 +0x84e1:can1 +0x84e2:lang2 +0x84e3:yu4 +0x84e5:ying4 +0x84e6:mo4 +0x84e7:diao4 +0x84e8:tiao1 +0x84e9:mao4 +0x84ea:tong1 +0x84eb:zhu2 +0x84ec:peng2 +0x84ed:an1 +0x84ee:lian2 +0x84ef:cong1 +0x84f0:xi3 +0x84f1:ping2 +0x84f2:qiu1 +0x84f3:jin4 +0x84f4:chun2 +0x84f5:jie2 +0x84f6:wei3 +0x84f7:tui1 +0x84f8:cao2 +0x84f9:yu3 +0x84fa:yi4 +0x84fb:ji2 +0x84fc:liao3 +0x84fd:bi4 +0x84fe:lu3 +0x84ff:su4 +0x8500:bu4 +0x8501:zhang1 +0x8502:luo2 +0x8503:jiang4 +0x8504:man4 +0x8505:yan2 +0x8506:ling2 +0x8507:ji4 +0x8508:piao3 +0x8509:gun3 +0x850a:han3 +0x850b:di2 +0x850c:su4 +0x850d:lu4 +0x850e:she4 +0x850f:shang1 +0x8510:di2 +0x8511:mie4 +0x8512:xun1 +0x8513:man4 +0x8514:bo5 +0x8515:di4 +0x8516:cuo2 +0x8517:zhe4 +0x8518:sen1 +0x8519:xuan4 +0x851a:wei4 +0x851b:hu2 +0x851c:ao2 +0x851d:mi3 +0x851e:lou2 +0x851f:cu4 +0x8520:zhong1 +0x8521:cai4 +0x8522:po2 +0x8523:jiang3 +0x8524:mi4 +0x8525:cong1 +0x8526:niao3 +0x8527:hui4 +0x8528:jun4 +0x8529:yin2 +0x852a:jian4 +0x852b:yan1 +0x852c:shu1 +0x852d:yin4 +0x852e:kui4 +0x852f:chen2 +0x8530:hu4 +0x8531:sha1 +0x8532:kou4 +0x8533:qian4 +0x8534:ma2 +0x8535:zang1 +0x8537:qiang2 +0x8538:dou1 +0x8539:lian4 +0x853a:lin4 +0x853b:kou4 +0x853c:ai3 +0x853d:bi4 +0x853e:li2 +0x853f:wei2 +0x8540:ji2 +0x8541:xun2 +0x8542:sheng4 +0x8543:fan2 +0x8544:meng2 +0x8545:ou3 +0x8546:chan3 +0x8547:dian3 +0x8548:xun4 +0x8549:jiao1 +0x854a:rui3 +0x854b:rui3 +0x854c:lei3 +0x854d:yu2 +0x854e:qiao2 +0x854f:chu2 +0x8550:hua2 +0x8551:jian1 +0x8552:mai3 +0x8553:yun2 +0x8554:bao1 +0x8555:you2 +0x8556:qu2 +0x8557:lu4 +0x8558:rao2 +0x8559:hui4 +0x855a:e4 +0x855b:teng2 +0x855c:fei3 +0x855d:jue2 +0x855e:zui4 +0x855f:fa4 +0x8560:ru2 +0x8561:fen2 +0x8562:kui4 +0x8563:shun4 +0x8564:rui2 +0x8565:ya3 +0x8566:xu1 +0x8567:fu4 +0x8568:jue2 +0x8569:dang4 +0x856a:wu2 +0x856b:tong2 +0x856c:si1 +0x856d:xiao1 +0x856e:xi4 +0x856f:long2 +0x8570:yun4 +0x8572:qi2 +0x8573:jian1 +0x8574:yun4 +0x8575:sun1 +0x8576:ling2 +0x8577:yu4 +0x8578:xia2 +0x8579:yong1 +0x857a:ji2 +0x857b:hong4 +0x857c:si4 +0x857d:nong2 +0x857e:lei3 +0x857f:xuan1 +0x8580:yun4 +0x8581:yu4 +0x8582:xi2 +0x8583:hao4 +0x8584:bo2 +0x8585:hao1 +0x8586:ai4 +0x8587:wei2 +0x8588:hui4 +0x8589:wei4 +0x858a:ji4 +0x858b:ci1 +0x858c:xiang1 +0x858d:luan4 +0x858e:mie4 +0x858f:yi4 +0x8590:leng2 +0x8591:jiang1 +0x8592:can4 +0x8593:shen1 +0x8594:qiang2 +0x8595:lian2 +0x8596:ke1 +0x8597:yuan2 +0x8598:da2 +0x8599:ti4 +0x859a:tang2 +0x859b:xue1 +0x859c:bi4 +0x859d:zhan2 +0x859e:sun1 +0x859f:lian3 +0x85a0:fan2 +0x85a1:ding3 +0x85a2:jie1 +0x85a3:gu3 +0x85a4:xie4 +0x85a5:shu3 +0x85a6:jian4 +0x85a7:kao3 +0x85a8:hong1 +0x85a9:sa4 +0x85aa:xin1 +0x85ab:xun1 +0x85ac:yao4 +0x85ae:sou3 +0x85af:shu3 +0x85b0:xun1 +0x85b1:dui4 +0x85b2:pin2 +0x85b3:wei3 +0x85b4:neng2 +0x85b5:chou2 +0x85b6:mai2 +0x85b7:ru2 +0x85b8:piao1 +0x85b9:tai2 +0x85ba:ci2 +0x85bb:zao3 +0x85bc:chen2 +0x85bd:zhen1 +0x85be:er3 +0x85bf:ni3 +0x85c0:ying2 +0x85c1:gao3 +0x85c2:cong4 +0x85c3:xiao1 +0x85c4:qi2 +0x85c5:fa2 +0x85c6:jian3 +0x85c7:xu4 +0x85c8:kui1 +0x85c9:jie4 +0x85ca:bian3 +0x85cb:diao4 +0x85cc:mi4 +0x85cd:lan2 +0x85ce:jin4 +0x85cf:cang2 +0x85d0:miao3 +0x85d1:qiong2 +0x85d2:qie4 +0x85d3:xian3 +0x85d5:ou3 +0x85d6:xian2 +0x85d7:su4 +0x85d8:lv2 +0x85d9:yi4 +0x85da:xu4 +0x85db:xie3 +0x85dc:li2 +0x85dd:yi4 +0x85de:la3 +0x85df:lei3 +0x85e0:xiao4 +0x85e1:di2 +0x85e2:zhi3 +0x85e3:bei1 +0x85e4:teng2 +0x85e5:yao4 +0x85e6:mo4 +0x85e7:huan3 +0x85e8:biao1 +0x85e9:fan2 +0x85ea:sou3 +0x85eb:tan2 +0x85ec:tui1 +0x85ed:qiong2 +0x85ee:qiao2 +0x85ef:wei4 +0x85f0:liu2 +0x85f1:hui4 +0x85f3:gao3 +0x85f4:yun4 +0x85f6:li4 +0x85f7:shu3 +0x85f8:chu2 +0x85f9:ai3 +0x85fa:lin4 +0x85fb:zao3 +0x85fc:xuan1 +0x85fd:chen4 +0x85fe:lai4 +0x85ff:huo4 +0x8600:tuo4 +0x8601:wu4 +0x8602:rui3 +0x8603:rui3 +0x8604:qi2 +0x8605:heng2 +0x8606:lu2 +0x8607:su1 +0x8608:tui2 +0x8609:mang2 +0x860a:yun4 +0x860b:pin2 +0x860c:yu3 +0x860d:xun1 +0x860e:ji4 +0x860f:jiong1 +0x8610:xian1 +0x8611:mo2 +0x8613:su1 +0x8614:jiong1 +0x8616:nie4 +0x8617:bo4 +0x8618:rang2 +0x8619:yi4 +0x861a:xian3 +0x861b:yu2 +0x861c:ju2 +0x861d:lian4 +0x861e:lian4 +0x861f:yin3 +0x8620:qiang2 +0x8621:ying1 +0x8622:long2 +0x8623:tong4 +0x8624:wei3 +0x8625:yue4 +0x8626:ling2 +0x8627:qu2 +0x8628:yao2 +0x8629:fan2 +0x862a:mi2 +0x862b:lan2 +0x862c:kui1 +0x862d:lan2 +0x862e:ji4 +0x862f:dang4 +0x8631:lei4 +0x8632:lei2 +0x8633:hua3 +0x8634:feng1 +0x8635:zhi2 +0x8636:wei4 +0x8637:kui2 +0x8638:zhan4 +0x8639:huai4 +0x863a:li2 +0x863b:ji4 +0x863c:mi2 +0x863d:lei3 +0x863e:huai4 +0x863f:luo2 +0x8640:ji1 +0x8641:kui2 +0x8642:lu4 +0x8643:jian1 +0x8646:lei2 +0x8647:quan3 +0x8648:xiao1 +0x8649:yi4 +0x864a:luan2 +0x864b:men2 +0x864c:bie1 +0x864d:hu1 +0x864e:hu3 +0x864f:lu3 +0x8650:nve4 +0x8651:lv4 +0x8652:si1 +0x8653:xiao1 +0x8654:qian2 +0x8655:chu4 +0x8656:hu1 +0x8657:xu1 +0x8658:cuo2 +0x8659:fu2 +0x865a:xu1 +0x865b:xu1 +0x865c:lu3 +0x865d:hu3 +0x865e:yu2 +0x865f:hao4 +0x8660:jiao3 +0x8661:ju4 +0x8662:guo2 +0x8663:bao4 +0x8664:yan2 +0x8665:zhan4 +0x8666:zhan4 +0x8667:kui1 +0x8668:ban1 +0x8669:xi4 +0x866a:shu2 +0x866b:chong2 +0x866c:qiu2 +0x866d:diao1 +0x866e:ji1 +0x866f:qiu2 +0x8670:cheng2 +0x8671:shi1 +0x8673:di4 +0x8674:zhe2 +0x8675:she2 +0x8676:yu1 +0x8677:gan1 +0x8678:zi3 +0x8679:hong2 +0x867a:hui3 +0x867b:meng2 +0x867c:ge4 +0x867d:sui1 +0x867e:xia1 +0x867f:chai4 +0x8680:shi2 +0x8681:yi3 +0x8682:ma3 +0x8683:xiang4 +0x8684:fang1 +0x8685:e4 +0x8686:pa1 +0x8687:chi3 +0x8688:qian1 +0x8689:wen2 +0x868a:wen2 +0x868b:rui4 +0x868c:bang4 +0x868d:bi3 +0x868e:yue4 +0x868f:yue4 +0x8690:jun1 +0x8691:qi2 +0x8692:tong2 +0x8693:yin3 +0x8694:qi2 +0x8695:can2 +0x8696:yuan2 +0x8697:jue2 +0x8698:hui2 +0x8699:qin2 +0x869a:qi2 +0x869b:zhong4 +0x869c:ya2 +0x869d:ci4 +0x869e:mu4 +0x869f:wang2 +0x86a0:fen2 +0x86a1:fen2 +0x86a2:hang2 +0x86a3:gong1 +0x86a4:zao3 +0x86a5:fu3 +0x86a6:ran2 +0x86a7:jie4 +0x86a8:fu2 +0x86a9:chi1 +0x86aa:dou3 +0x86ab:piao2 +0x86ac:xian4 +0x86ad:ni2 +0x86ae:te4 +0x86af:qiu1 +0x86b0:you2 +0x86b1:zha4 +0x86b2:ping2 +0x86b3:chi2 +0x86b4:you3 +0x86b5:he2 +0x86b6:han1 +0x86b7:ju4 +0x86b8:li4 +0x86b9:fu4 +0x86ba:ran2 +0x86bb:zha2 +0x86bc:gou3 +0x86bd:pi2 +0x86be:bo3 +0x86bf:xian2 +0x86c0:zhu4 +0x86c1:diao1 +0x86c2:bie3 +0x86c3:bing3 +0x86c4:gu1 +0x86c5:ran2 +0x86c6:qu1 +0x86c7:she2 +0x86c8:tie4 +0x86c9:ling2 +0x86ca:gu3 +0x86cb:dan4 +0x86cc:gu3 +0x86cd:ying2 +0x86ce:li4 +0x86cf:cheng1 +0x86d0:qu1 +0x86d1:mou2 +0x86d2:ge2 +0x86d3:ci4 +0x86d4:hui2 +0x86d5:hui2 +0x86d6:mang2 +0x86d7:fu4 +0x86d8:yang2 +0x86d9:wa1 +0x86da:lie4 +0x86db:zhu1 +0x86dc:yi1 +0x86dd:xian2 +0x86de:kuo4 +0x86df:jiao1 +0x86e0:li4 +0x86e1:yi4 +0x86e2:ping2 +0x86e3:jie2 +0x86e4:ha2 +0x86e5:she2 +0x86e6:yi2 +0x86e7:wang3 +0x86e8:mo4 +0x86e9:qiong2 +0x86ea:qie4 +0x86eb:gui3 +0x86ec:gong3 +0x86ed:zhi4 +0x86ee:man2 +0x86f0:zhi2 +0x86f1:jia2 +0x86f2:rao2 +0x86f3:si1 +0x86f4:qi2 +0x86f5:xing1 +0x86f6:lie4 +0x86f7:qiu2 +0x86f8:shao1 +0x86f9:yong3 +0x86fa:jia2 +0x86fb:tui4 +0x86fc:che1 +0x86fd:bai4 +0x86fe:e2 +0x86ff:han4 +0x8700:shu3 +0x8701:xuan2 +0x8702:feng1 +0x8703:shen4 +0x8704:zhen4 +0x8705:fu3 +0x8706:xian4 +0x8707:zhe2 +0x8708:wu2 +0x8709:fu2 +0x870a:li2 +0x870b:lang2 +0x870c:bi4 +0x870d:chu2 +0x870e:yuan1 +0x870f:you3 +0x8710:jie2 +0x8711:dan4 +0x8712:yan2 +0x8713:ting2 +0x8714:dian4 +0x8715:shui4 +0x8716:hui2 +0x8717:gua1 +0x8718:zhi1 +0x8719:song1 +0x871a:fei1 +0x871b:ju1 +0x871c:mi4 +0x871d:qi2 +0x871e:qi2 +0x871f:yu4 +0x8720:jun3 +0x8721:la4 +0x8722:meng3 +0x8723:qiang1 +0x8724:si1 +0x8725:xi1 +0x8726:lun2 +0x8727:li4 +0x8728:die2 +0x8729:tiao2 +0x872a:tao1 +0x872b:kun1 +0x872c:gan1 +0x872d:han4 +0x872e:yu4 +0x872f:bang4 +0x8730:fei2 +0x8731:pi2 +0x8732:wei3 +0x8733:dun1 +0x8734:yi4 +0x8735:yuan1 +0x8736:su4 +0x8737:quan2 +0x8738:qian3 +0x8739:rui4 +0x873a:ni2 +0x873b:qing1 +0x873c:wei4 +0x873d:liang3 +0x873e:guo3 +0x873f:wan1 +0x8740:dong1 +0x8741:e4 +0x8742:ban3 +0x8743:di4 +0x8744:wang3 +0x8745:can2 +0x8746:yang3 +0x8747:ying2 +0x8748:guo1 +0x8749:chan2 +0x874b:la4 +0x874c:ke1 +0x874d:ji2 +0x874e:he2 +0x874f:ting2 +0x8750:mai4 +0x8751:xu1 +0x8752:mian2 +0x8753:yu2 +0x8754:jie1 +0x8755:shi2 +0x8756:xuan1 +0x8757:huang2 +0x8758:yan3 +0x8759:bian1 +0x875a:rou2 +0x875b:wei1 +0x875c:fu4 +0x875d:yuan2 +0x875e:mei4 +0x875f:wei4 +0x8760:fu2 +0x8761:ruan3 +0x8762:xie2 +0x8763:you2 +0x8764:qiu2 +0x8765:mao2 +0x8766:xia1 +0x8767:ying1 +0x8768:shi1 +0x8769:chong2 +0x876a:tang1 +0x876b:zhu1 +0x876c:zong1 +0x876d:ti2 +0x876e:fu4 +0x876f:yuan2 +0x8770:hui3 +0x8771:meng2 +0x8772:la4 +0x8773:du2 +0x8774:hu2 +0x8775:qiu1 +0x8776:die2 +0x8777:li4 +0x8778:gua1 +0x8779:yun1 +0x877a:ju3 +0x877b:nan3 +0x877c:lou2 +0x877d:qun3 +0x877e:rong2 +0x877f:ying2 +0x8780:jiang1 +0x8782:lang2 +0x8783:pang2 +0x8784:si1 +0x8785:xi1 +0x8786:ci4 +0x8787:xi1 +0x8788:yuan2 +0x8789:weng1 +0x878a:lian2 +0x878b:sou1 +0x878c:ban1 +0x878d:rong2 +0x878e:rong2 +0x878f:ji2 +0x8790:wu1 +0x8791:qiu4 +0x8792:han4 +0x8793:qin2 +0x8794:yi2 +0x8795:bi1 +0x8796:hua2 +0x8797:tang2 +0x8798:yi3 +0x8799:du4 +0x879a:nai4 +0x879b:he2 +0x879c:hu2 +0x879d:hui4 +0x879e:ma3 +0x879f:ming2 +0x87a0:yi4 +0x87a1:wen2 +0x87a2:ying2 +0x87a3:teng2 +0x87a4:yu3 +0x87a5:cang1 +0x87a8:man3 +0x87aa:shang1 +0x87ab:shi4 +0x87ac:cao2 +0x87ad:chi1 +0x87ae:di4 +0x87af:ao2 +0x87b0:lu4 +0x87b1:wei4 +0x87b2:zhi4 +0x87b3:tang2 +0x87b4:chen2 +0x87b5:piao1 +0x87b6:qu2 +0x87b7:pi2 +0x87b8:yu2 +0x87b9:jian4 +0x87ba:luo2 +0x87bb:lou2 +0x87bc:qin3 +0x87bd:zhong1 +0x87be:yin3 +0x87bf:jiang1 +0x87c0:shuai4 +0x87c1:wen2 +0x87c2:jiao1 +0x87c3:wan4 +0x87c4:zhe2 +0x87c5:zhe4 +0x87c6:ma2 +0x87c7:ma2 +0x87c8:guo1 +0x87c9:liu2 +0x87ca:mao2 +0x87cb:xi1 +0x87cc:cong1 +0x87cd:li2 +0x87ce:man3 +0x87cf:xiao1 +0x87d1:zhang1 +0x87d2:mang3 +0x87d3:xiang4 +0x87d4:mo4 +0x87d5:zui1 +0x87d6:si1 +0x87d7:qiu1 +0x87d8:te4 +0x87d9:zhi2 +0x87da:peng2 +0x87db:peng2 +0x87dc:jiao3 +0x87dd:qu2 +0x87de:bie2 +0x87df:liao2 +0x87e0:pan2 +0x87e1:gui3 +0x87e2:xi3 +0x87e3:ji3 +0x87e4:zhuan1 +0x87e5:huang2 +0x87e6:fei4 +0x87e7:lao2 +0x87e8:jue2 +0x87e9:jue2 +0x87ea:hui4 +0x87eb:yin2 +0x87ec:chan2 +0x87ed:jiao1 +0x87ee:shan4 +0x87ef:rao2 +0x87f0:xiao1 +0x87f1:mou2 +0x87f2:chong2 +0x87f3:xun2 +0x87f4:si1 +0x87f6:cheng1 +0x87f7:dang1 +0x87f8:li3 +0x87f9:xie4 +0x87fa:shan4 +0x87fb:yi3 +0x87fc:jing3 +0x87fd:da2 +0x87fe:chan2 +0x87ff:qi4 +0x8800:ci1 +0x8801:xiang4 +0x8802:she4 +0x8803:luo3 +0x8804:qin2 +0x8805:ying2 +0x8806:chai4 +0x8807:li4 +0x8808:ze2 +0x8809:xuan1 +0x880a:lian2 +0x880b:zhu2 +0x880c:ze2 +0x880d:xie1 +0x880e:mang3 +0x880f:xie4 +0x8810:qi2 +0x8811:rong2 +0x8812:jian3 +0x8813:meng3 +0x8814:hao2 +0x8815:ru2 +0x8816:huo4 +0x8817:zhuo2 +0x8818:jie2 +0x8819:bin1 +0x881a:he4 +0x881b:mie4 +0x881c:fan2 +0x881d:lei2 +0x881e:jie2 +0x881f:la4 +0x8820:mi4 +0x8821:li3 +0x8822:chun3 +0x8823:li4 +0x8824:qiu1 +0x8825:nie4 +0x8826:lu2 +0x8827:du4 +0x8828:xiao1 +0x8829:zhu1 +0x882a:long2 +0x882b:li4 +0x882c:long2 +0x882d:feng1 +0x882e:ye1 +0x882f:beng4 +0x8830:shang4 +0x8831:gu3 +0x8832:juan1 +0x8833:ying1 +0x8835:xi1 +0x8836:can2 +0x8837:qu2 +0x8838:quan2 +0x8839:du4 +0x883a:can2 +0x883b:man2 +0x883c:jue2 +0x883d:jie2 +0x883e:zhu2 +0x883f:zha2 +0x8840:xie3 +0x8841:huang1 +0x8842:niu4 +0x8843:pei1 +0x8844:nv4 +0x8845:xin4 +0x8846:zhong4 +0x8847:mo4 +0x8848:er4 +0x8849:ke4 +0x884a:mie4 +0x884b:xi4 +0x884c:xing2 +0x884d:yan3 +0x884e:kan4 +0x884f:yuan4 +0x8851:ling2 +0x8852:xuan4 +0x8853:shu4 +0x8854:xian2 +0x8855:tong4 +0x8856:long4 +0x8857:jie1 +0x8858:xian2 +0x8859:ya2 +0x885a:hu2 +0x885b:wei4 +0x885c:dao4 +0x885d:chong1 +0x885e:wei4 +0x885f:dao4 +0x8860:zhun1 +0x8861:heng2 +0x8862:qu2 +0x8863:yi1 +0x8865:bu3 +0x8866:gan3 +0x8867:yu2 +0x8868:biao3 +0x8869:cha4 +0x886a:yi3 +0x886b:shan1 +0x886c:chen4 +0x886d:fu1 +0x886e:gun3 +0x886f:fen1 +0x8870:shuai1 +0x8871:jie2 +0x8872:na4 +0x8873:zhong1 +0x8874:dan3 +0x8875:ri4 +0x8876:zhong4 +0x8877:zhong1 +0x8878:xie4 +0x8879:qi2 +0x887a:xie2 +0x887b:ran2 +0x887c:zhi1 +0x887d:ren4 +0x887e:qin1 +0x887f:jin1 +0x8880:jun1 +0x8881:yuan2 +0x8882:mei4 +0x8883:chai4 +0x8884:ao3 +0x8885:niao3 +0x8886:hui1 +0x8887:ran2 +0x8888:jia1 +0x8889:tuo2 +0x888a:ling3 +0x888b:dai4 +0x888c:bao4 +0x888d:pao2 +0x888e:yao4 +0x888f:zuo4 +0x8890:bi4 +0x8891:shao4 +0x8892:tan3 +0x8893:ju3 +0x8894:he4 +0x8895:shu4 +0x8896:xiu4 +0x8897:zhen3 +0x8898:yi2 +0x8899:pa4 +0x889a:bo1 +0x889b:di1 +0x889c:wa4 +0x889d:fu4 +0x889e:gun3 +0x889f:zhi4 +0x88a0:zhi4 +0x88a1:ran2 +0x88a2:pan4 +0x88a3:yi4 +0x88a4:mao4 +0x88a6:na4 +0x88a7:kou1 +0x88a8:xian4 +0x88a9:chan1 +0x88aa:qu1 +0x88ab:bei4 +0x88ac:gun3 +0x88ad:xi2 +0x88af:bo2 +0x88b1:fu2 +0x88b2:yi2 +0x88b3:chi3 +0x88b4:ku4 +0x88b5:ren4 +0x88b6:jiang4 +0x88b7:jia2 +0x88b8:cun2 +0x88b9:mo4 +0x88ba:jie2 +0x88bb:er2 +0x88bc:luo4 +0x88bd:ru2 +0x88be:zhu1 +0x88bf:gui1 +0x88c0:yin1 +0x88c1:cai2 +0x88c2:lie4 +0x88c5:zhuang1 +0x88c6:dang1 +0x88c8:kun1 +0x88c9:ken4 +0x88ca:niao3 +0x88cb:shu4 +0x88cc:jia2 +0x88cd:kun3 +0x88ce:cheng2 +0x88cf:li3 +0x88d0:juan1 +0x88d1:shen1 +0x88d2:pou2 +0x88d3:ge2 +0x88d4:yi4 +0x88d5:yu4 +0x88d6:zhen3 +0x88d7:liu2 +0x88d8:qiu2 +0x88d9:qun2 +0x88da:ji4 +0x88db:yi4 +0x88dc:bu3 +0x88dd:zhuang1 +0x88de:shui4 +0x88df:sha1 +0x88e0:qun2 +0x88e1:li3 +0x88e2:lian2 +0x88e3:lian4 +0x88e4:ku4 +0x88e5:jian3 +0x88e6:fou2 +0x88e7:chan1 +0x88e8:bi4 +0x88e9:gun1 +0x88ea:tao2 +0x88eb:yuan4 +0x88ec:ling2 +0x88ed:chi3 +0x88ee:chang1 +0x88ef:chou2 +0x88f0:duo2 +0x88f1:biao3 +0x88f2:liang3 +0x88f3:chang2 +0x88f4:pei2 +0x88f5:pei2 +0x88f6:fei1 +0x88f7:yuan1 +0x88f8:luo3 +0x88f9:guo3 +0x88fa:yan3 +0x88fb:du3 +0x88fc:xi2 +0x88fd:zhi4 +0x88fe:ju1 +0x88ff:qi3 +0x8900:ji4 +0x8901:zhi2 +0x8902:gua4 +0x8903:ken4 +0x8905:ti4 +0x8906:ti2 +0x8907:fu4 +0x8908:chong2 +0x8909:xie1 +0x890a:bian3 +0x890b:die2 +0x890c:kun1 +0x890d:duan1 +0x890e:xiu4 +0x890f:xiu4 +0x8910:he2 +0x8911:yuan4 +0x8912:bao1 +0x8913:bao3 +0x8914:fu4 +0x8915:yu2 +0x8916:tuan4 +0x8917:yan3 +0x8918:hui1 +0x8919:bei4 +0x891a:chu3 +0x891b:lv3 +0x891e:yun3 +0x891f:da2 +0x8920:gou1 +0x8921:da1 +0x8922:huai2 +0x8923:rong2 +0x8924:yuan4 +0x8925:ru4 +0x8926:nai4 +0x8927:jiong3 +0x8928:suo3 +0x8929:ban1 +0x892a:tun4 +0x892b:chi3 +0x892c:sang3 +0x892d:niao3 +0x892e:ying1 +0x892f:jie4 +0x8930:qian1 +0x8931:huai2 +0x8932:ku4 +0x8933:lian2 +0x8934:bao3 +0x8935:li2 +0x8936:zhe2 +0x8937:shi1 +0x8938:lv3 +0x8939:yi4 +0x893a:die2 +0x893b:xie4 +0x893c:xian1 +0x893d:wei4 +0x893e:biao3 +0x893f:cao2 +0x8940:ji1 +0x8941:jiang3 +0x8942:sen1 +0x8943:bao1 +0x8944:xiang1 +0x8946:pu2 +0x8947:jian3 +0x8948:zhuan4 +0x8949:jian4 +0x894a:zui4 +0x894b:ji2 +0x894c:dan1 +0x894d:za2 +0x894e:fan2 +0x894f:bo2 +0x8950:xiang4 +0x8951:xin2 +0x8952:bie2 +0x8953:rao2 +0x8954:man3 +0x8955:lan2 +0x8956:ao3 +0x8957:duo2 +0x8958:gui4 +0x8959:cao4 +0x895a:sui4 +0x895b:nong2 +0x895c:chan1 +0x895d:lian4 +0x895e:bi4 +0x895f:jin1 +0x8960:dang1 +0x8961:shu2 +0x8962:tan3 +0x8963:bi4 +0x8964:lan2 +0x8965:pu2 +0x8966:ru2 +0x8967:zhi3 +0x8969:shu3 +0x896a:wa4 +0x896b:shi4 +0x896c:bai3 +0x896d:xie2 +0x896e:bo2 +0x896f:chen4 +0x8970:lai4 +0x8971:long2 +0x8972:xi2 +0x8973:xian1 +0x8974:lan2 +0x8975:zhe2 +0x8976:dai4 +0x8978:zan4 +0x8979:shi1 +0x897a:jian3 +0x897b:pan4 +0x897c:yi4 +0x897e:ya4 +0x897f:xi1 +0x8980:xi1 +0x8981:yao4 +0x8982:feng3 +0x8983:tan2 +0x8985:biao4 +0x8986:fu4 +0x8987:ba4 +0x8988:he2 +0x8989:ji1 +0x898a:ji1 +0x898b:jian4 +0x898c:guan1 +0x898d:bian4 +0x898e:yan4 +0x898f:gui1 +0x8990:jue2 +0x8991:pian3 +0x8992:mao2 +0x8993:mi4 +0x8994:mi4 +0x8995:mie4 +0x8996:shi4 +0x8997:si1 +0x8998:zhan1 +0x8999:luo2 +0x899a:jue2 +0x899b:mi4 +0x899c:tiao4 +0x899d:lian2 +0x899e:yao4 +0x899f:zhi4 +0x89a0:jun1 +0x89a1:xi2 +0x89a2:shan3 +0x89a3:wei1 +0x89a4:xi4 +0x89a5:tian3 +0x89a6:yu2 +0x89a7:lan3 +0x89a8:e4 +0x89a9:du3 +0x89aa:qin1 +0x89ab:pang3 +0x89ac:ji4 +0x89ad:ming2 +0x89ae:ying2 +0x89af:gou4 +0x89b0:qu4 +0x89b1:zhan4 +0x89b2:jin3 +0x89b3:guan1 +0x89b4:deng1 +0x89b5:jian4 +0x89b6:luo2 +0x89b7:qu4 +0x89b8:jian4 +0x89b9:wei2 +0x89ba:jue2 +0x89bb:qu4 +0x89bc:luo2 +0x89bd:lan3 +0x89be:shen3 +0x89bf:di2 +0x89c0:guan1 +0x89c1:jian4 +0x89c2:guan1 +0x89c3:yan4 +0x89c4:gui1 +0x89c5:mi4 +0x89c6:shi4 +0x89c7:zhan1 +0x89c8:lan3 +0x89c9:jue2 +0x89ca:ji4 +0x89cb:xi2 +0x89cc:di2 +0x89cd:tian3 +0x89ce:yu2 +0x89cf:gou4 +0x89d0:jin3 +0x89d1:qu4 +0x89d2:jiao3 +0x89d3:jiu1 +0x89d4:jin1 +0x89d5:cu1 +0x89d6:jue2 +0x89d7:zhi4 +0x89d8:chao4 +0x89d9:ji2 +0x89da:gu1 +0x89db:dan4 +0x89dc:zi1 +0x89dd:di3 +0x89de:shang1 +0x89df:hua4 +0x89e0:quan2 +0x89e1:ge2 +0x89e2:chi4 +0x89e3:jie3 +0x89e4:gui3 +0x89e5:gong1 +0x89e6:chu4 +0x89e7:jie3 +0x89e8:hun4 +0x89e9:qiu2 +0x89ea:xing1 +0x89eb:su4 +0x89ec:ni2 +0x89ed:ji1 +0x89ee:lu4 +0x89ef:zhi4 +0x89f0:zha1 +0x89f1:bi4 +0x89f2:xing1 +0x89f3:hu2 +0x89f4:shang1 +0x89f5:gong1 +0x89f6:zhi4 +0x89f7:xue2 +0x89f8:chu4 +0x89f9:xi1 +0x89fa:yi2 +0x89fb:lu4 +0x89fc:jue2 +0x89fd:xi1 +0x89fe:yan4 +0x89ff:xi1 +0x8a00:yan2 +0x8a02:ding4 +0x8a03:fu4 +0x8a04:qiu2 +0x8a05:qiu2 +0x8a06:jiao4 +0x8a07:hong1 +0x8a08:ji4 +0x8a09:fan4 +0x8a0a:xun4 +0x8a0b:diao4 +0x8a0c:hong2 +0x8a0d:cha4 +0x8a0e:tao3 +0x8a0f:xu1 +0x8a10:jie2 +0x8a11:yi2 +0x8a12:ren4 +0x8a13:xun4 +0x8a14:yin2 +0x8a15:shan4 +0x8a16:qi4 +0x8a17:tuo1 +0x8a18:ji4 +0x8a19:xun4 +0x8a1a:yin2 +0x8a1b:e2 +0x8a1c:fen1 +0x8a1d:ya4 +0x8a1e:yao1 +0x8a1f:song4 +0x8a20:shen3 +0x8a21:yin2 +0x8a22:xin1 +0x8a23:jue2 +0x8a24:xiao2 +0x8a25:ne4 +0x8a26:chen2 +0x8a27:you2 +0x8a28:zhi3 +0x8a29:xiong1 +0x8a2a:fang3 +0x8a2b:xin4 +0x8a2c:chao1 +0x8a2d:she4 +0x8a2e:xian1 +0x8a2f:sha3 +0x8a30:tun2 +0x8a31:xu3 +0x8a32:yi4 +0x8a33:yi4 +0x8a34:su4 +0x8a35:chi1 +0x8a36:he1 +0x8a37:shen1 +0x8a38:he2 +0x8a39:xu4 +0x8a3a:zhen3 +0x8a3b:zhu4 +0x8a3c:zheng4 +0x8a3d:gou4 +0x8a3e:zi3 +0x8a3f:zi3 +0x8a40:zhan1 +0x8a41:gu3 +0x8a42:fu4 +0x8a43:quan3 +0x8a44:die2 +0x8a45:ling2 +0x8a46:di3 +0x8a47:yang4 +0x8a48:li4 +0x8a49:nao2 +0x8a4a:pan4 +0x8a4b:zhou4 +0x8a4c:gan4 +0x8a4d:yi4 +0x8a4e:ju4 +0x8a4f:ao4 +0x8a50:zha4 +0x8a51:tuo2 +0x8a52:yi2 +0x8a53:qu3 +0x8a54:zhao4 +0x8a55:ping2 +0x8a56:bi4 +0x8a57:xiong4 +0x8a58:qu1 +0x8a59:ba2 +0x8a5a:da2 +0x8a5b:zu3 +0x8a5c:tao1 +0x8a5d:zhu3 +0x8a5e:ci2 +0x8a5f:zhe2 +0x8a60:yong3 +0x8a61:xu3 +0x8a62:xun2 +0x8a63:yi4 +0x8a64:huang3 +0x8a65:he2 +0x8a66:shi4 +0x8a67:cha2 +0x8a68:jiao1 +0x8a69:shi1 +0x8a6a:hen3 +0x8a6b:cha4 +0x8a6c:gou4 +0x8a6d:gui3 +0x8a6e:quan2 +0x8a6f:hui4 +0x8a70:jie2 +0x8a71:hua4 +0x8a72:gai1 +0x8a73:xiang2 +0x8a74:wei1 +0x8a75:shen1 +0x8a76:chou2 +0x8a77:tong2 +0x8a78:mi2 +0x8a79:zhan1 +0x8a7a:ming4 +0x8a7b:e4 +0x8a7c:hui1 +0x8a7d:yan2 +0x8a7e:xiong1 +0x8a7f:gua4 +0x8a80:er4 +0x8a81:beng3 +0x8a82:tiao3 +0x8a83:chi3 +0x8a84:lei3 +0x8a85:zhu1 +0x8a86:kuang1 +0x8a87:kua1 +0x8a88:wu2 +0x8a89:yu4 +0x8a8a:teng2 +0x8a8b:ji4 +0x8a8c:zhi4 +0x8a8d:ren4 +0x8a8e:su4 +0x8a8f:lang3 +0x8a90:e2 +0x8a91:kuang2 +0x8a92:e4 +0x8a93:shi4 +0x8a94:ting3 +0x8a95:dan4 +0x8a96:bo2 +0x8a97:chan2 +0x8a98:you4 +0x8a99:heng2 +0x8a9a:qiao4 +0x8a9b:qin1 +0x8a9c:shua4 +0x8a9d:an1 +0x8a9e:yu3 +0x8a9f:xiao4 +0x8aa0:cheng2 +0x8aa1:jie4 +0x8aa2:xian4 +0x8aa3:wu1 +0x8aa4:wu4 +0x8aa5:gao4 +0x8aa6:song4 +0x8aa7:pu3 +0x8aa8:hui4 +0x8aa9:jing4 +0x8aaa:shuo1 +0x8aab:zhen4 +0x8aac:shuo1 +0x8aad:du2 +0x8aaf:chang4 +0x8ab0:shui2 +0x8ab1:jie2 +0x8ab2:ke4 +0x8ab3:qu1 +0x8ab4:cong2 +0x8ab5:xiao2 +0x8ab6:sui4 +0x8ab7:wang3 +0x8ab8:xuan2 +0x8ab9:fei3 +0x8aba:chi1 +0x8abb:ta4 +0x8abc:yi4 +0x8abd:na2 +0x8abe:yin2 +0x8abf:diao4 +0x8ac0:pi3 +0x8ac1:chuo4 +0x8ac2:chan3 +0x8ac3:chen1 +0x8ac4:zhun1 +0x8ac5:ji1 +0x8ac6:qi1 +0x8ac7:tan2 +0x8ac8:zhui4 +0x8ac9:wei3 +0x8aca:ju2 +0x8acb:qing3 +0x8acc:jian4 +0x8acd:zheng1 +0x8ace:ze2 +0x8acf:zou1 +0x8ad0:qian1 +0x8ad1:zhuo2 +0x8ad2:liang4 +0x8ad3:jian4 +0x8ad4:zhu4 +0x8ad5:hao2 +0x8ad6:lun4 +0x8ad7:shen3 +0x8ad8:biao3 +0x8ad9:huai4 +0x8ada:pian2 +0x8adb:yu2 +0x8adc:die2 +0x8add:xu3 +0x8ade:pian3 +0x8adf:shi4 +0x8ae0:xuan1 +0x8ae1:shi4 +0x8ae2:hun4 +0x8ae3:hua4 +0x8ae4:e4 +0x8ae5:zhong4 +0x8ae6:di4 +0x8ae7:xie2 +0x8ae8:fu2 +0x8ae9:pu3 +0x8aea:ting2 +0x8aeb:jian4 +0x8aec:qi3 +0x8aed:yu4 +0x8aee:zi1 +0x8aef:chuan2 +0x8af0:xi3 +0x8af1:hui4 +0x8af2:yin1 +0x8af3:an1 +0x8af4:xian2 +0x8af5:nan2 +0x8af6:chen2 +0x8af7:feng3 +0x8af8:zhu1 +0x8af9:yang2 +0x8afa:yan4 +0x8afb:heng1 +0x8afc:xuan1 +0x8afd:ge2 +0x8afe:nuo4 +0x8aff:qi4 +0x8b00:mou2 +0x8b01:ye4 +0x8b02:wei4 +0x8b04:teng2 +0x8b05:zou1 +0x8b06:shan4 +0x8b07:jian3 +0x8b08:bo2 +0x8b0a:huang3 +0x8b0b:huo4 +0x8b0c:ge1 +0x8b0d:ying2 +0x8b0e:mi2 +0x8b0f:xiao3 +0x8b10:mi4 +0x8b11:xi4 +0x8b12:qiang1 +0x8b13:chen1 +0x8b14:nve4 +0x8b15:ti2 +0x8b16:su4 +0x8b17:bang4 +0x8b18:chi2 +0x8b19:qian1 +0x8b1a:shi4 +0x8b1b:jiang3 +0x8b1c:yuan4 +0x8b1d:xie4 +0x8b1e:xue4 +0x8b1f:tao1 +0x8b20:yao2 +0x8b21:yao2 +0x8b23:yu2 +0x8b24:biao1 +0x8b25:cong4 +0x8b26:qing4 +0x8b27:li2 +0x8b28:mo2 +0x8b29:mo4 +0x8b2a:shang1 +0x8b2b:zhe2 +0x8b2c:miu4 +0x8b2d:jian3 +0x8b2e:ze2 +0x8b2f:jie1 +0x8b30:lian2 +0x8b31:lou2 +0x8b32:can1 +0x8b33:ou1 +0x8b34:guan4 +0x8b35:xi2 +0x8b36:zhuo2 +0x8b37:ao2 +0x8b38:ao2 +0x8b39:jin3 +0x8b3a:zhe2 +0x8b3b:yi2 +0x8b3c:hu4 +0x8b3d:jiang4 +0x8b3e:man2 +0x8b3f:chao2 +0x8b40:han4 +0x8b41:hua2 +0x8b42:chan3 +0x8b43:xu1 +0x8b44:zeng1 +0x8b45:se4 +0x8b46:xi1 +0x8b47:she1 +0x8b48:dui4 +0x8b49:zheng4 +0x8b4a:nao2 +0x8b4b:lan2 +0x8b4c:e2 +0x8b4d:ying4 +0x8b4e:jue2 +0x8b4f:ji1 +0x8b50:zun3 +0x8b51:jiao3 +0x8b52:bo4 +0x8b53:hui4 +0x8b54:zhuan4 +0x8b55:mu2 +0x8b56:zen4 +0x8b57:zha2 +0x8b58:shi5 +0x8b59:qiao2 +0x8b5a:tan2 +0x8b5b:zen4 +0x8b5c:pu3 +0x8b5d:sheng2 +0x8b5e:xuan1 +0x8b5f:zao4 +0x8b60:tan1 +0x8b61:dang3 +0x8b62:sui4 +0x8b63:qian1 +0x8b64:ji1 +0x8b65:jiao4 +0x8b66:jing3 +0x8b67:lian2 +0x8b68:nou2 +0x8b69:yi1 +0x8b6a:ai4 +0x8b6b:zhan1 +0x8b6c:pi4 +0x8b6d:hui3 +0x8b6e:hua4 +0x8b6f:yi4 +0x8b70:yi4 +0x8b71:shan4 +0x8b72:rang4 +0x8b73:nou4 +0x8b74:qian3 +0x8b75:zhui4 +0x8b76:ta4 +0x8b77:hu4 +0x8b78:zhou1 +0x8b79:hao2 +0x8b7a:ye4 +0x8b7b:ying1 +0x8b7c:jian4 +0x8b7d:yu4 +0x8b7e:jian3 +0x8b7f:hui4 +0x8b80:du2 +0x8b81:zhe2 +0x8b82:xuan4 +0x8b83:zan4 +0x8b84:lei3 +0x8b85:shen3 +0x8b86:wei4 +0x8b87:chan3 +0x8b88:li4 +0x8b89:yi2 +0x8b8a:bian4 +0x8b8b:zhe2 +0x8b8c:yan4 +0x8b8d:e4 +0x8b8e:chou2 +0x8b8f:wei4 +0x8b90:chou2 +0x8b91:yao4 +0x8b92:chan2 +0x8b93:rang4 +0x8b94:yin3 +0x8b95:lan2 +0x8b96:chen4 +0x8b97:huo4 +0x8b98:zhe2 +0x8b99:huan1 +0x8b9a:zan4 +0x8b9b:yi4 +0x8b9c:dang3 +0x8b9d:zhan1 +0x8b9e:yan4 +0x8b9f:du2 +0x8ba0:yan2 +0x8ba1:ji4 +0x8ba2:ding4 +0x8ba3:fu4 +0x8ba4:ren4 +0x8ba5:ji1 +0x8ba6:jie2 +0x8ba7:hong2 +0x8ba8:tao3 +0x8ba9:rang4 +0x8baa:shan4 +0x8bab:qi4 +0x8bac:tuo1 +0x8bad:xun4 +0x8bae:yi4 +0x8baf:xun4 +0x8bb0:ji4 +0x8bb1:ren4 +0x8bb2:jiang3 +0x8bb3:hui4 +0x8bb4:ou1 +0x8bb5:ju4 +0x8bb6:ya4 +0x8bb7:ne4 +0x8bb8:xu3 +0x8bb9:e2 +0x8bba:lun4 +0x8bbb:xiong1 +0x8bbc:song4 +0x8bbd:feng1 +0x8bbe:she4 +0x8bbf:fang3 +0x8bc0:jue2 +0x8bc1:zheng4 +0x8bc2:gu3 +0x8bc3:he1 +0x8bc4:ping2 +0x8bc5:zu3 +0x8bc6:shi4 +0x8bc7:xiong4 +0x8bc8:zha4 +0x8bc9:su4 +0x8bca:zhen3 +0x8bcb:di3 +0x8bcc:zou1 +0x8bcd:ci2 +0x8bce:qu4 +0x8bcf:zhao4 +0x8bd0:bi4 +0x8bd1:yi4 +0x8bd2:yi2 +0x8bd3:kuang1 +0x8bd4:lei3 +0x8bd5:shi4 +0x8bd6:gua4 +0x8bd7:shi1 +0x8bd8:jie2 +0x8bd9:hui1 +0x8bda:cheng2 +0x8bdb:zhu1 +0x8bdc:shen1 +0x8bdd:hua4 +0x8bde:dan4 +0x8bdf:gou4 +0x8be0:quan2 +0x8be1:gui3 +0x8be2:xun2 +0x8be3:yi4 +0x8be4:zheng1 +0x8be5:gai1 +0x8be6:xiang2 +0x8be7:cha4 +0x8be8:hun4 +0x8be9:xu3 +0x8bea:zhou1 +0x8beb:jie4 +0x8bec:wu2 +0x8bed:yu3 +0x8bee:qiao4 +0x8bef:wu4 +0x8bf0:gao4 +0x8bf1:you4 +0x8bf2:hui4 +0x8bf3:kuang2 +0x8bf4:shuo1 +0x8bf5:song4 +0x8bf6:ai1 +0x8bf7:qing3 +0x8bf8:zhu1 +0x8bf9:zou1 +0x8bfa:nuo4 +0x8bfb:du2 +0x8bfc:zhuo2 +0x8bfd:fei3 +0x8bfe:ke4 +0x8bff:wei3 +0x8c00:yu2 +0x8c01:shui2 +0x8c02:shen3 +0x8c03:diao4 +0x8c04:chan3 +0x8c05:liang4 +0x8c06:zhun1 +0x8c07:sui4 +0x8c08:tan2 +0x8c09:shen3 +0x8c0a:yi2 +0x8c0b:mou2 +0x8c0c:chen2 +0x8c0d:die2 +0x8c0e:huang3 +0x8c0f:jian4 +0x8c10:xie2 +0x8c11:nve4 +0x8c12:ye4 +0x8c13:wei4 +0x8c14:e4 +0x8c15:yu4 +0x8c16:xuan1 +0x8c17:chan2 +0x8c18:zi1 +0x8c19:an1 +0x8c1a:yan4 +0x8c1b:di4 +0x8c1c:mi2 +0x8c1d:pian2 +0x8c1e:xu3 +0x8c1f:mo2 +0x8c20:dang3 +0x8c21:su4 +0x8c22:xie4 +0x8c23:yao2 +0x8c24:bang4 +0x8c25:shi4 +0x8c26:qian1 +0x8c27:mi4 +0x8c28:jin3 +0x8c29:man2 +0x8c2a:zhe2 +0x8c2b:jian3 +0x8c2c:miu4 +0x8c2d:tan2 +0x8c2e:zen4 +0x8c2f:qiao2 +0x8c30:lan2 +0x8c31:pu3 +0x8c32:jue2 +0x8c33:yan4 +0x8c34:qian3 +0x8c35:zhan1 +0x8c36:chen4 +0x8c37:gu3 +0x8c38:qian1 +0x8c39:hong2 +0x8c3a:xia1 +0x8c3b:jue2 +0x8c3c:hong2 +0x8c3d:han1 +0x8c3e:hong1 +0x8c3f:xi1 +0x8c40:xi1 +0x8c41:huo1 +0x8c42:liao2 +0x8c43:han3 +0x8c44:du2 +0x8c45:long2 +0x8c46:dou4 +0x8c47:jiang1 +0x8c48:qi3 +0x8c49:chi3 +0x8c4a:li3 +0x8c4b:deng1 +0x8c4c:wan1 +0x8c4d:bi1 +0x8c4e:shu4 +0x8c4f:xian4 +0x8c50:feng1 +0x8c51:zhi4 +0x8c52:zhi4 +0x8c53:yan4 +0x8c54:yan4 +0x8c55:shi3 +0x8c56:chu4 +0x8c57:hui1 +0x8c58:tun2 +0x8c59:yi4 +0x8c5a:tun2 +0x8c5b:yi4 +0x8c5c:jian1 +0x8c5d:ba1 +0x8c5e:hou4 +0x8c5f:e4 +0x8c60:cu2 +0x8c61:xiang4 +0x8c62:huan4 +0x8c63:jian1 +0x8c64:ken3 +0x8c65:gai1 +0x8c66:qu2 +0x8c67:fu1 +0x8c68:xi1 +0x8c69:bin1 +0x8c6a:hao2 +0x8c6b:yu4 +0x8c6c:zhu1 +0x8c6d:jia1 +0x8c6e:fen2 +0x8c6f:xi1 +0x8c70:bo2 +0x8c71:wen1 +0x8c72:huan2 +0x8c73:bin1 +0x8c74:di2 +0x8c75:zong1 +0x8c76:fen2 +0x8c77:yi4 +0x8c78:zhi4 +0x8c79:bao4 +0x8c7a:chai2 +0x8c7b:an4 +0x8c7c:pi2 +0x8c7d:na4 +0x8c7e:pi1 +0x8c7f:gou3 +0x8c80:na4 +0x8c81:you4 +0x8c82:diao1 +0x8c83:mo4 +0x8c84:si4 +0x8c85:xiu1 +0x8c86:huan2 +0x8c87:kun1 +0x8c88:he2 +0x8c89:he2 +0x8c8a:mo4 +0x8c8b:han4 +0x8c8c:mao4 +0x8c8d:li2 +0x8c8e:ni2 +0x8c8f:bi3 +0x8c90:yu3 +0x8c91:jia1 +0x8c92:tuan1 +0x8c93:mao1 +0x8c94:pi2 +0x8c95:xi1 +0x8c96:e4 +0x8c97:ju4 +0x8c98:mo4 +0x8c99:chu1 +0x8c9a:tan2 +0x8c9b:huan1 +0x8c9c:jue2 +0x8c9d:bei4 +0x8c9e:zhen1 +0x8c9f:yuan2 +0x8ca0:fu4 +0x8ca1:cai2 +0x8ca2:gong4 +0x8ca3:te4 +0x8ca4:yi2 +0x8ca5:hang2 +0x8ca6:wan4 +0x8ca7:pin2 +0x8ca8:huo4 +0x8ca9:fan4 +0x8caa:tan1 +0x8cab:guan4 +0x8cac:ze2 +0x8cad:zhi2 +0x8cae:er4 +0x8caf:zhu3 +0x8cb0:shi4 +0x8cb1:bi4 +0x8cb2:zi1 +0x8cb3:er4 +0x8cb4:gui4 +0x8cb5:pian3 +0x8cb6:bian3 +0x8cb7:mai3 +0x8cb8:dai4 +0x8cb9:sheng4 +0x8cba:kuang4 +0x8cbb:fei4 +0x8cbc:tie1 +0x8cbd:yi2 +0x8cbe:chi2 +0x8cbf:mao4 +0x8cc0:he4 +0x8cc1:bi4 +0x8cc2:lu4 +0x8cc3:lin4 +0x8cc4:hui4 +0x8cc5:gai1 +0x8cc6:pian2 +0x8cc7:zi1 +0x8cc8:jia3 +0x8cc9:xu4 +0x8cca:zei2 +0x8ccb:jiao3 +0x8ccc:gai4 +0x8ccd:zang1 +0x8cce:jian4 +0x8ccf:ying4 +0x8cd0:xun4 +0x8cd1:zhen4 +0x8cd2:she1 +0x8cd3:bin1 +0x8cd4:bin1 +0x8cd5:qiu2 +0x8cd6:she1 +0x8cd7:chuan4 +0x8cd8:zang1 +0x8cd9:zhou1 +0x8cda:lai4 +0x8cdb:zan4 +0x8cdc:ci4 +0x8cdd:chen1 +0x8cde:shang3 +0x8cdf:tian3 +0x8ce0:pei2 +0x8ce1:geng1 +0x8ce2:xian2 +0x8ce3:mai4 +0x8ce4:jian4 +0x8ce5:sui4 +0x8ce6:fu4 +0x8ce7:tan4 +0x8ce8:cong2 +0x8ce9:cong2 +0x8cea:zhi4 +0x8ceb:ji1 +0x8cec:zhang4 +0x8ced:du3 +0x8cee:jin4 +0x8cef:xiong1 +0x8cf0:shun3 +0x8cf1:yun3 +0x8cf2:bao3 +0x8cf3:zai1 +0x8cf4:lai4 +0x8cf5:feng4 +0x8cf6:cang4 +0x8cf7:ji1 +0x8cf8:sheng4 +0x8cf9:ai4 +0x8cfa:zhuan4 +0x8cfb:fu4 +0x8cfc:gou4 +0x8cfd:sai4 +0x8cfe:ze2 +0x8cff:liao2 +0x8d00:wei4 +0x8d01:bai4 +0x8d02:chen3 +0x8d03:zhuan4 +0x8d04:zhi4 +0x8d05:zhui4 +0x8d06:biao1 +0x8d07:yun1 +0x8d08:zeng4 +0x8d09:tan3 +0x8d0a:zan4 +0x8d0b:yan4 +0x8d0d:shan4 +0x8d0e:wan4 +0x8d0f:ying2 +0x8d10:jin4 +0x8d11:gan3 +0x8d12:xian2 +0x8d13:zang1 +0x8d14:bi4 +0x8d15:du2 +0x8d16:shu2 +0x8d17:yan4 +0x8d19:xuan4 +0x8d1a:long4 +0x8d1b:gan4 +0x8d1c:zang1 +0x8d1d:bei4 +0x8d1e:zhen1 +0x8d1f:fu4 +0x8d20:yuan2 +0x8d21:gong4 +0x8d22:cai2 +0x8d23:ze2 +0x8d24:xian2 +0x8d25:bai4 +0x8d26:zhang4 +0x8d27:huo4 +0x8d28:zhi2 +0x8d29:fan4 +0x8d2a:tan1 +0x8d2b:pin2 +0x8d2c:bian3 +0x8d2d:gou4 +0x8d2e:zhu3 +0x8d2f:guan4 +0x8d30:er4 +0x8d31:jian4 +0x8d32:bi4 +0x8d33:shi4 +0x8d34:tie1 +0x8d35:gui4 +0x8d36:kuang4 +0x8d37:dai4 +0x8d38:mao4 +0x8d39:fei4 +0x8d3a:he4 +0x8d3b:yi2 +0x8d3c:zei2 +0x8d3d:zhi4 +0x8d3e:jia3 +0x8d3f:hui4 +0x8d40:zi1 +0x8d41:ren4 +0x8d42:lu4 +0x8d43:zang1 +0x8d44:zi1 +0x8d45:gai1 +0x8d46:jin4 +0x8d47:qiu2 +0x8d48:zhen4 +0x8d49:lai4 +0x8d4a:she1 +0x8d4b:fu4 +0x8d4c:du3 +0x8d4d:ji1 +0x8d4e:shu2 +0x8d4f:shang3 +0x8d50:si4 +0x8d51:bi4 +0x8d52:zhou1 +0x8d53:geng1 +0x8d54:pei2 +0x8d55:tan4 +0x8d56:lai4 +0x8d57:feng4 +0x8d58:zhui4 +0x8d59:fu4 +0x8d5a:zhuan4 +0x8d5b:sai4 +0x8d5c:ze2 +0x8d5d:yan4 +0x8d5e:zan4 +0x8d5f:yun1 +0x8d60:zeng4 +0x8d61:shan4 +0x8d62:ying2 +0x8d63:gan4 +0x8d64:chi4 +0x8d65:xi4 +0x8d66:she4 +0x8d67:nan3 +0x8d68:xiong2 +0x8d69:xi4 +0x8d6a:cheng1 +0x8d6b:he4 +0x8d6c:cheng1 +0x8d6d:zhe3 +0x8d6e:xia2 +0x8d6f:tang2 +0x8d70:zou3 +0x8d71:zou3 +0x8d72:li4 +0x8d73:jiu3 +0x8d74:fu4 +0x8d75:zhao4 +0x8d76:gan3 +0x8d77:qi3 +0x8d78:shan4 +0x8d79:qiong2 +0x8d7a:qin2 +0x8d7b:xian3 +0x8d7c:ci1 +0x8d7d:jue2 +0x8d7e:qin3 +0x8d7f:chi2 +0x8d80:ci1 +0x8d81:chen4 +0x8d82:chen4 +0x8d83:die2 +0x8d84:ju1 +0x8d85:chao1 +0x8d86:di1 +0x8d87:se4 +0x8d88:zhan1 +0x8d89:zhu2 +0x8d8a:yue4 +0x8d8b:qu1 +0x8d8c:jie2 +0x8d8d:chi2 +0x8d8e:chu2 +0x8d8f:gua1 +0x8d90:xue4 +0x8d91:ci1 +0x8d92:tiao2 +0x8d93:duo3 +0x8d94:lie4 +0x8d95:gan3 +0x8d96:suo1 +0x8d97:cu4 +0x8d98:xi2 +0x8d99:zhao4 +0x8d9a:su4 +0x8d9b:yin3 +0x8d9c:ju2 +0x8d9d:jian4 +0x8d9e:que4 +0x8d9f:tang4 +0x8da0:chuo4 +0x8da1:cui3 +0x8da2:lu4 +0x8da3:qu4 +0x8da4:dang4 +0x8da5:qiu1 +0x8da6:zi1 +0x8da7:ti2 +0x8da8:qu1 +0x8da9:chi4 +0x8daa:huang2 +0x8dab:qiao2 +0x8dac:qiao2 +0x8dad:yao4 +0x8dae:zao4 +0x8daf:ti4 +0x8db1:zan3 +0x8db2:zan3 +0x8db3:zu2 +0x8db4:pa1 +0x8db5:bao4 +0x8db6:ku4 +0x8db7:ke1 +0x8db8:dun3 +0x8db9:jue2 +0x8dba:fu1 +0x8dbb:chen3 +0x8dbc:jian3 +0x8dbd:fang4 +0x8dbe:zhi3 +0x8dbf:sa4 +0x8dc0:yue4 +0x8dc1:pa2 +0x8dc2:qi2 +0x8dc3:yue4 +0x8dc4:qiang1 +0x8dc5:tuo4 +0x8dc6:tai2 +0x8dc7:yi4 +0x8dc8:nian3 +0x8dc9:ling2 +0x8dca:mei4 +0x8dcb:ba2 +0x8dcc:die1 +0x8dcd:ku1 +0x8dce:tuo2 +0x8dcf:jia1 +0x8dd0:ci3 +0x8dd1:pao3 +0x8dd2:qia3 +0x8dd3:zhu4 +0x8dd4:ju1 +0x8dd5:die2 +0x8dd6:zhi2 +0x8dd7:fu1 +0x8dd8:pan2 +0x8dd9:ju3 +0x8dda:shan1 +0x8ddb:bo3 +0x8ddc:ni2 +0x8ddd:ju4 +0x8dde:li4 +0x8ddf:gen1 +0x8de0:yi2 +0x8de1:ji1 +0x8de2:dai4 +0x8de3:xian3 +0x8de4:jiao1 +0x8de5:duo4 +0x8de6:zhu1 +0x8de7:quan2 +0x8de8:kua4 +0x8de9:zhuai3 +0x8dea:gui4 +0x8deb:qiong2 +0x8dec:kui3 +0x8ded:xiang2 +0x8dee:chi4 +0x8def:lu4 +0x8df0:beng4 +0x8df1:zhi4 +0x8df2:jia2 +0x8df3:tiao4 +0x8df4:cai3 +0x8df5:jian4 +0x8df6:ta4 +0x8df7:qiao1 +0x8df8:bi4 +0x8df9:xian1 +0x8dfa:duo4 +0x8dfb:ji1 +0x8dfc:ju2 +0x8dfd:ji4 +0x8dfe:shu2 +0x8dff:tu2 +0x8e00:chu4 +0x8e01:jing4 +0x8e02:nie4 +0x8e03:xiao1 +0x8e04:bo2 +0x8e05:chi4 +0x8e06:qun1 +0x8e07:mou3 +0x8e08:shu1 +0x8e09:lang2 +0x8e0a:yong3 +0x8e0b:jiao3 +0x8e0c:chou2 +0x8e0d:qiao1 +0x8e0f:ta4 +0x8e10:jian4 +0x8e11:qi2 +0x8e12:wo1 +0x8e13:wei3 +0x8e14:zhuo2 +0x8e15:jie2 +0x8e16:ji2 +0x8e17:nie1 +0x8e18:ju2 +0x8e19:ju1 +0x8e1a:lun2 +0x8e1b:lu4 +0x8e1c:leng4 +0x8e1d:huai2 +0x8e1e:ju4 +0x8e1f:chi2 +0x8e20:wan3 +0x8e21:quan2 +0x8e22:ti1 +0x8e23:bo2 +0x8e24:zu2 +0x8e25:qie4 +0x8e26:ji3 +0x8e27:cu4 +0x8e28:zong1 +0x8e29:cai3 +0x8e2a:zong1 +0x8e2b:peng4 +0x8e2c:zhi4 +0x8e2d:zheng1 +0x8e2e:dian3 +0x8e2f:zhi2 +0x8e30:yu2 +0x8e31:duo4 +0x8e32:dun4 +0x8e33:chun3 +0x8e34:yong3 +0x8e35:zhong3 +0x8e36:di4 +0x8e37:zhe3 +0x8e38:chen3 +0x8e39:chuai4 +0x8e3a:jian4 +0x8e3b:gua1 +0x8e3c:tang2 +0x8e3d:ju3 +0x8e3e:fu2 +0x8e3f:zu2 +0x8e40:die2 +0x8e41:pian2 +0x8e42:rou2 +0x8e43:nuo4 +0x8e44:ti2 +0x8e45:cha3 +0x8e46:tui3 +0x8e47:jian3 +0x8e48:dao3 +0x8e49:cuo1 +0x8e4a:xi1 +0x8e4b:ta4 +0x8e4c:qiang1 +0x8e4d:zhan3 +0x8e4e:dian1 +0x8e4f:ti2 +0x8e50:ji2 +0x8e51:nie4 +0x8e52:man2 +0x8e53:liu1 +0x8e54:zhan4 +0x8e55:bi4 +0x8e56:chong1 +0x8e57:lu4 +0x8e58:liao2 +0x8e59:cu4 +0x8e5a:tang1 +0x8e5b:dai4 +0x8e5c:suo1 +0x8e5d:xi3 +0x8e5e:kui3 +0x8e5f:ji1 +0x8e60:zhi2 +0x8e61:qiang1 +0x8e62:di2 +0x8e63:pan2 +0x8e64:zong1 +0x8e65:lian2 +0x8e66:beng4 +0x8e67:zao1 +0x8e68:nian3 +0x8e69:bie2 +0x8e6a:tui2 +0x8e6b:ju2 +0x8e6c:deng4 +0x8e6d:ceng4 +0x8e6e:xian1 +0x8e6f:fan2 +0x8e70:chu2 +0x8e71:zhong1 +0x8e72:dun1 +0x8e73:bo1 +0x8e74:cu4 +0x8e75:zu2 +0x8e76:jue2 +0x8e77:jue2 +0x8e78:lin4 +0x8e79:ta4 +0x8e7a:qiao1 +0x8e7b:qiao1 +0x8e7c:pu2 +0x8e7d:liao1 +0x8e7e:dun1 +0x8e7f:cuan1 +0x8e80:kuang4 +0x8e81:zao4 +0x8e82:ta4 +0x8e83:bi4 +0x8e84:bi4 +0x8e85:zhu2 +0x8e86:ju4 +0x8e87:chu2 +0x8e88:qiao4 +0x8e89:dun3 +0x8e8a:chou2 +0x8e8b:ji1 +0x8e8c:wu3 +0x8e8d:yue4 +0x8e8e:nian3 +0x8e8f:lin4 +0x8e90:lie4 +0x8e91:zhi2 +0x8e92:li4 +0x8e93:zhi4 +0x8e94:chan2 +0x8e95:chu2 +0x8e96:duan4 +0x8e97:wei4 +0x8e98:long2 +0x8e99:lin4 +0x8e9a:xian1 +0x8e9b:wei4 +0x8e9c:zuan1 +0x8e9d:lan2 +0x8e9e:xie4 +0x8e9f:rang2 +0x8ea0:xie3 +0x8ea1:nie4 +0x8ea2:ta4 +0x8ea3:qu2 +0x8ea4:jie4 +0x8ea5:cuan1 +0x8ea6:zuan1 +0x8ea7:xi3 +0x8ea8:kui2 +0x8ea9:jue2 +0x8eaa:lin4 +0x8eab:shen1 +0x8eac:gong1 +0x8ead:dan1 +0x8eaf:qu1 +0x8eb0:ti3 +0x8eb1:duo3 +0x8eb2:duo3 +0x8eb3:gong1 +0x8eb4:lang2 +0x8eb6:luo3 +0x8eb7:ai3 +0x8eb8:ji1 +0x8eb9:ju2 +0x8eba:tang3 +0x8ebd:yan3 +0x8ebf:kang1 +0x8ec0:qu1 +0x8ec1:lou2 +0x8ec2:lao4 +0x8ec3:tuo3 +0x8ec4:zhi2 +0x8ec6:ti3 +0x8ec7:dao4 +0x8ec9:yu4 +0x8eca:che1 +0x8ecb:ya4 +0x8ecc:gui3 +0x8ecd:jun1 +0x8ece:wei4 +0x8ecf:yue4 +0x8ed0:xin4 +0x8ed1:di4 +0x8ed2:xuan1 +0x8ed3:fan4 +0x8ed4:ren4 +0x8ed5:shan1 +0x8ed6:qiang2 +0x8ed7:shu1 +0x8ed8:tun2 +0x8ed9:chen2 +0x8eda:dai4 +0x8edb:e4 +0x8edc:na4 +0x8edd:qi2 +0x8ede:mao2 +0x8edf:ruan3 +0x8ee0:ren4 +0x8ee1:fan3 +0x8ee2:zhuan3 +0x8ee3:hong1 +0x8ee4:hu1 +0x8ee5:qu2 +0x8ee6:huang4 +0x8ee7:di3 +0x8ee8:ling2 +0x8ee9:dai4 +0x8eea:ao1 +0x8eeb:zhen3 +0x8eec:fan4 +0x8eed:kuang1 +0x8eee:ang3 +0x8eef:peng1 +0x8ef0:bei4 +0x8ef1:gu1 +0x8ef2:ku1 +0x8ef3:pao2 +0x8ef4:zhu4 +0x8ef5:rong3 +0x8ef6:e4 +0x8ef7:ba2 +0x8ef8:zhou2 +0x8ef9:zhi3 +0x8efa:yao2 +0x8efb:ke1 +0x8efc:yi4 +0x8efd:qing1 +0x8efe:shi4 +0x8eff:ping2 +0x8f00:er2 +0x8f01:qiong2 +0x8f02:ju2 +0x8f03:jiao4 +0x8f04:guang1 +0x8f05:lu4 +0x8f06:kai3 +0x8f07:quan2 +0x8f08:zhou1 +0x8f09:zai4 +0x8f0a:zhi4 +0x8f0b:she1 +0x8f0c:liang4 +0x8f0d:yu4 +0x8f0e:shao1 +0x8f0f:you2 +0x8f10:huan3 +0x8f11:yun3 +0x8f12:zhe2 +0x8f13:wan3 +0x8f14:fu3 +0x8f15:qing1 +0x8f16:zhou1 +0x8f17:ni2 +0x8f18:ling2 +0x8f19:zhe2 +0x8f1a:zhan4 +0x8f1b:liang4 +0x8f1c:zi1 +0x8f1d:hui1 +0x8f1e:wang3 +0x8f1f:chuo4 +0x8f20:guo3 +0x8f21:kan3 +0x8f22:yi3 +0x8f23:peng2 +0x8f24:qian4 +0x8f25:gun3 +0x8f26:nian3 +0x8f27:pian2 +0x8f28:guan3 +0x8f29:bei4 +0x8f2a:lun2 +0x8f2b:pai2 +0x8f2c:liang2 +0x8f2d:ruan3 +0x8f2e:rou2 +0x8f2f:ji2 +0x8f30:yang2 +0x8f31:xian2 +0x8f32:chuan2 +0x8f33:cou4 +0x8f34:chun1 +0x8f35:ge2 +0x8f36:you2 +0x8f37:hong1 +0x8f38:shu1 +0x8f39:fu4 +0x8f3a:zi1 +0x8f3b:fu2 +0x8f3c:wen1 +0x8f3d:ben4 +0x8f3e:zhan3 +0x8f3f:yu2 +0x8f40:wen1 +0x8f41:tao1 +0x8f42:gu3 +0x8f43:zhen1 +0x8f44:xia2 +0x8f45:yuan2 +0x8f46:lu4 +0x8f47:jiu1 +0x8f48:chao2 +0x8f49:zhuan3 +0x8f4a:wei4 +0x8f4b:hun2 +0x8f4d:che4 +0x8f4e:jiao4 +0x8f4f:zhan4 +0x8f50:pu2 +0x8f51:lao3 +0x8f52:fen2 +0x8f53:fan1 +0x8f54:lin2 +0x8f55:ge2 +0x8f56:se4 +0x8f57:kan3 +0x8f58:huan4 +0x8f59:yi3 +0x8f5a:ji2 +0x8f5b:dui4 +0x8f5c:er2 +0x8f5d:yu2 +0x8f5e:xian4 +0x8f5f:hong1 +0x8f60:lei3 +0x8f61:pei4 +0x8f62:li4 +0x8f63:li4 +0x8f64:lu2 +0x8f65:lin4 +0x8f66:che1 +0x8f67:ya4 +0x8f68:gui3 +0x8f69:xuan1 +0x8f6a:di4 +0x8f6b:ren4 +0x8f6c:zhuan3 +0x8f6d:e4 +0x8f6e:lun2 +0x8f6f:ruan3 +0x8f70:hong1 +0x8f71:ku1 +0x8f72:ke1 +0x8f73:lu2 +0x8f74:zhou2 +0x8f75:zhi3 +0x8f76:yi4 +0x8f77:hu1 +0x8f78:zhen3 +0x8f79:li4 +0x8f7a:yao2 +0x8f7b:qing1 +0x8f7c:shi4 +0x8f7d:zai4 +0x8f7e:zhi4 +0x8f7f:jiao4 +0x8f80:zhou1 +0x8f81:quan2 +0x8f82:lu4 +0x8f83:jiao4 +0x8f84:zhe2 +0x8f85:fu3 +0x8f86:liang4 +0x8f87:nian3 +0x8f88:bei4 +0x8f89:hui1 +0x8f8a:gun3 +0x8f8b:wang3 +0x8f8c:liang2 +0x8f8d:chuo4 +0x8f8e:zi1 +0x8f8f:cou4 +0x8f90:fu2 +0x8f91:ji2 +0x8f92:wen1 +0x8f93:shu1 +0x8f94:pei4 +0x8f95:yuan2 +0x8f96:xia2 +0x8f97:zhan3 +0x8f98:lu4 +0x8f99:che4 +0x8f9a:lin2 +0x8f9b:xin1 +0x8f9c:gu1 +0x8f9d:ci2 +0x8f9e:ci2 +0x8f9f:pi4 +0x8fa0:zui4 +0x8fa1:bian4 +0x8fa2:la4 +0x8fa3:la4 +0x8fa4:ci2 +0x8fa5:xue1 +0x8fa6:ban4 +0x8fa7:bian4 +0x8fa8:bian4 +0x8fa9:bian4 +0x8fab:bian4 +0x8fac:ban1 +0x8fad:ci2 +0x8fae:bian4 +0x8faf:bian4 +0x8fb0:chen2 +0x8fb1:ru3 +0x8fb2:nong2 +0x8fb3:nong2 +0x8fb4:zhen3 +0x8fb5:chuo4 +0x8fb6:chuo4 +0x8fb8:reng2 +0x8fb9:bian1 +0x8fba:bian1 +0x8fbd:liao2 +0x8fbe:da2 +0x8fbf:chan1 +0x8fc0:gan1 +0x8fc1:qian1 +0x8fc2:yu1 +0x8fc3:yu1 +0x8fc4:qi4 +0x8fc5:xun4 +0x8fc6:yi3 +0x8fc7:guo4 +0x8fc8:mai4 +0x8fc9:qi2 +0x8fca:za1 +0x8fcb:wang4 +0x8fcd:zhun1 +0x8fce:ying2 +0x8fcf:ti4 +0x8fd0:yun4 +0x8fd1:jin4 +0x8fd2:hang2 +0x8fd3:ya4 +0x8fd4:fan3 +0x8fd5:wu4 +0x8fd6:da2 +0x8fd7:e2 +0x8fd8:huan2 +0x8fd9:zhe4 +0x8fdb:jin4 +0x8fdc:yuan3 +0x8fdd:wei2 +0x8fde:lian2 +0x8fdf:chi2 +0x8fe0:che4 +0x8fe1:ni4 +0x8fe2:tiao2 +0x8fe3:zhi4 +0x8fe4:yi3 +0x8fe5:jiong3 +0x8fe6:jia1 +0x8fe7:chen2 +0x8fe8:dai4 +0x8fe9:er3 +0x8fea:di2 +0x8feb:po4 +0x8fec:wang3 +0x8fed:die2 +0x8fee:ze2 +0x8fef:tao2 +0x8ff0:shu4 +0x8ff1:tuo2 +0x8ff3:jing4 +0x8ff4:hui2 +0x8ff5:tong2 +0x8ff6:you4 +0x8ff7:mi2 +0x8ff8:beng4 +0x8ff9:ji1 +0x8ffa:nai3 +0x8ffb:yi2 +0x8ffc:jie2 +0x8ffd:zhui1 +0x8ffe:lie4 +0x8fff:xun4 +0x9000:tui4 +0x9001:song4 +0x9002:shi4 +0x9003:tao2 +0x9004:pang2 +0x9005:hou4 +0x9006:ni4 +0x9007:dun4 +0x9008:jiong3 +0x9009:xuan3 +0x900a:xun4 +0x900b:bu1 +0x900c:you2 +0x900d:xiao1 +0x900e:qiu2 +0x900f:tou4 +0x9010:zhu2 +0x9011:qiu2 +0x9012:di4 +0x9013:di4 +0x9014:tu2 +0x9015:jing4 +0x9016:ti4 +0x9017:dou4 +0x9018:yi3 +0x9019:zhe4 +0x901a:tong1 +0x901b:guang4 +0x901c:wu4 +0x901d:shi4 +0x901e:cheng3 +0x901f:su4 +0x9020:zao4 +0x9021:qun1 +0x9022:feng2 +0x9023:lian2 +0x9024:suo4 +0x9025:hui2 +0x9026:li3 +0x9028:lai2 +0x9029:ben4 +0x902a:cuo4 +0x902b:jue2 +0x902c:beng4 +0x902d:huan4 +0x902e:dai4 +0x902f:lu4 +0x9030:you2 +0x9031:zhou1 +0x9032:jin4 +0x9033:yu4 +0x9034:chuo4 +0x9035:kui2 +0x9036:wei1 +0x9037:ti4 +0x9038:yi4 +0x9039:da2 +0x903a:yuan3 +0x903b:luo2 +0x903c:bi1 +0x903d:nuo4 +0x903e:yu2 +0x903f:dang4 +0x9040:sui2 +0x9041:dun4 +0x9042:sui4 +0x9043:yan3 +0x9044:chuan2 +0x9045:chi2 +0x9046:ti2 +0x9047:yu4 +0x9048:shi2 +0x9049:zhen1 +0x904a:you2 +0x904b:yun4 +0x904c:e4 +0x904d:bian4 +0x904e:guo4 +0x904f:e4 +0x9050:xia2 +0x9051:huang2 +0x9052:qiu2 +0x9053:dao4 +0x9054:da2 +0x9055:wei2 +0x9057:yi2 +0x9058:gou4 +0x9059:yao2 +0x905a:chu4 +0x905b:liu2 +0x905c:xun4 +0x905d:ta4 +0x905e:di4 +0x905f:chi2 +0x9060:yuan3 +0x9061:su4 +0x9062:ta4 +0x9063:qian3 +0x9065:yao2 +0x9066:guan4 +0x9067:zhang1 +0x9068:ao2 +0x9069:shi4 +0x906a:ce4 +0x906b:chi4 +0x906c:su4 +0x906d:zao1 +0x906e:zhe1 +0x906f:dun4 +0x9070:di4 +0x9071:lou2 +0x9072:chi2 +0x9073:cuo1 +0x9074:lin2 +0x9075:zun1 +0x9076:rao4 +0x9077:qian1 +0x9078:xuan3 +0x9079:yu4 +0x907a:yi2 +0x907b:wu4 +0x907c:liao2 +0x907d:ju4 +0x907e:shi4 +0x907f:bi4 +0x9080:yao1 +0x9081:mai4 +0x9082:xie4 +0x9083:sui4 +0x9084:huan2 +0x9085:zhan1 +0x9086:teng2 +0x9087:er3 +0x9088:miao3 +0x9089:bian1 +0x908a:bian1 +0x908b:la2 +0x908c:li2 +0x908d:yuan2 +0x908e:yao2 +0x908f:luo2 +0x9090:li3 +0x9091:yi4 +0x9092:ting2 +0x9093:deng4 +0x9094:qi3 +0x9095:yong1 +0x9096:shan1 +0x9097:han2 +0x9098:yu2 +0x9099:mang2 +0x909a:ru2 +0x909b:qiong2 +0x909d:kuang4 +0x909e:fu1 +0x909f:kang4 +0x90a0:bin1 +0x90a1:fang1 +0x90a2:xing2 +0x90a3:na4 +0x90a5:shen3 +0x90a6:bang1 +0x90a7:yuan2 +0x90a8:cun1 +0x90a9:huo3 +0x90aa:xie2 +0x90ab:bang1 +0x90ac:wu1 +0x90ad:ju4 +0x90ae:you2 +0x90af:han2 +0x90b0:tai2 +0x90b1:qiu1 +0x90b2:bi4 +0x90b3:pei2 +0x90b4:bing3 +0x90b5:shao4 +0x90b6:bei4 +0x90b7:wa3 +0x90b8:di3 +0x90b9:zou1 +0x90ba:ye4 +0x90bb:lin2 +0x90bc:kuang1 +0x90bd:gui1 +0x90be:zhu1 +0x90bf:shi1 +0x90c0:ku1 +0x90c1:yu4 +0x90c2:gai1 +0x90c3:he2 +0x90c4:xi4 +0x90c5:zhi4 +0x90c6:ji2 +0x90c7:xun2 +0x90c8:hou4 +0x90c9:xing2 +0x90ca:jiao1 +0x90cb:xi2 +0x90cc:gui1 +0x90cd:nuo2 +0x90ce:lang2 +0x90cf:jia2 +0x90d0:kuai4 +0x90d1:zheng4 +0x90d3:yun4 +0x90d4:yan2 +0x90d5:cheng2 +0x90d6:dou1 +0x90d7:chi1 +0x90d8:lv3 +0x90d9:fu3 +0x90da:wu2 +0x90db:fu2 +0x90dc:gao4 +0x90dd:hao3 +0x90de:lang2 +0x90df:jia2 +0x90e0:geng3 +0x90e1:jun4 +0x90e2:ying3 +0x90e3:bo2 +0x90e4:xi4 +0x90e5:bei4 +0x90e6:li4 +0x90e7:yun2 +0x90e8:bu4 +0x90e9:xiao2 +0x90ea:qi1 +0x90eb:pi2 +0x90ec:qing1 +0x90ed:guo1 +0x90ef:tan2 +0x90f0:zou1 +0x90f1:ping2 +0x90f2:lai2 +0x90f3:ni2 +0x90f4:chen1 +0x90f5:you2 +0x90f6:bu4 +0x90f7:xiang1 +0x90f8:dan1 +0x90f9:ju2 +0x90fa:yong1 +0x90fb:qiao1 +0x90fc:yi1 +0x90fd:du1 +0x90fe:yan3 +0x90ff:mei2 +0x9100:ruo4 +0x9101:bei4 +0x9102:e4 +0x9103:yu2 +0x9104:juan4 +0x9105:yu3 +0x9106:yun4 +0x9107:hou4 +0x9108:kui2 +0x9109:xiang1 +0x910a:xiang1 +0x910b:sou1 +0x910c:tang2 +0x910d:ming2 +0x910e:xi4 +0x910f:ru4 +0x9110:chu4 +0x9111:zi1 +0x9112:zou1 +0x9113:ju2 +0x9114:wu1 +0x9115:xiang1 +0x9116:yun2 +0x9117:hao4 +0x9118:yong1 +0x9119:bi3 +0x911a:mo4 +0x911b:chao2 +0x911c:fu1 +0x911d:liao3 +0x911e:yin2 +0x911f:zhuan1 +0x9120:hu4 +0x9121:qiao1 +0x9122:yan1 +0x9123:zhang1 +0x9124:man4 +0x9125:qiao1 +0x9126:xu3 +0x9127:deng4 +0x9128:bi4 +0x9129:xin2 +0x912a:bi4 +0x912b:ceng2 +0x912c:wei2 +0x912d:zheng4 +0x912e:mao4 +0x912f:shan4 +0x9130:lin2 +0x9131:po2 +0x9132:dan1 +0x9133:meng2 +0x9134:ye4 +0x9135:cao1 +0x9136:kuai4 +0x9137:feng1 +0x9138:meng2 +0x9139:zou1 +0x913a:kuang4 +0x913b:lian3 +0x913c:zan4 +0x913d:chan2 +0x913e:you1 +0x913f:qi2 +0x9140:yan1 +0x9141:chan2 +0x9142:zan4 +0x9143:ling2 +0x9144:huan1 +0x9145:xi1 +0x9146:feng1 +0x9147:zan4 +0x9148:li4 +0x9149:you3 +0x914a:ding3 +0x914b:qiu2 +0x914c:zhuo2 +0x914d:pei4 +0x914e:zhou4 +0x914f:yi2 +0x9150:hang4 +0x9151:yu3 +0x9152:jiu3 +0x9153:yan3 +0x9154:zui4 +0x9155:mao2 +0x9156:dan1 +0x9157:xu4 +0x9158:tou2 +0x9159:zhen1 +0x915a:fen1 +0x915d:yun4 +0x915e:tai4 +0x915f:tian1 +0x9160:qia3 +0x9161:tuo2 +0x9162:zuo4 +0x9163:han1 +0x9164:gu1 +0x9165:su1 +0x9166:po4 +0x9167:chou2 +0x9168:zai4 +0x9169:ming2 +0x916a:lao4 +0x916b:chuo4 +0x916c:chou2 +0x916d:you4 +0x916e:tong2 +0x916f:zhi3 +0x9170:xian1 +0x9171:jiang4 +0x9172:cheng2 +0x9173:yin4 +0x9174:tu2 +0x9175:jiao4 +0x9176:mei2 +0x9177:ku4 +0x9178:suan1 +0x9179:lei4 +0x917a:pu2 +0x917b:zui4 +0x917c:hai3 +0x917d:yan4 +0x917e:xi3 +0x917f:niang4 +0x9180:wei2 +0x9181:lu4 +0x9182:lan3 +0x9183:yan1 +0x9184:tao2 +0x9185:pei1 +0x9186:zhan3 +0x9187:chun2 +0x9188:tan2 +0x9189:zui4 +0x918a:chuo4 +0x918b:cu4 +0x918c:kun1 +0x918d:ti2 +0x918e:mian2 +0x918f:du1 +0x9190:hu2 +0x9191:xu3 +0x9192:xing3 +0x9193:tan3 +0x9194:jiu1 +0x9195:chun2 +0x9196:yun4 +0x9197:po4 +0x9198:ke4 +0x9199:sou1 +0x919a:mi2 +0x919b:quan2 +0x919c:chou3 +0x919d:cuo2 +0x919e:yun4 +0x919f:yong4 +0x91a0:ang4 +0x91a1:zha4 +0x91a2:hai3 +0x91a3:tang2 +0x91a4:jiang4 +0x91a5:piao3 +0x91a6:shan3 +0x91a7:yu4 +0x91a8:li2 +0x91a9:zao2 +0x91aa:lao2 +0x91ab:yi1 +0x91ac:jiang4 +0x91ad:bu2 +0x91ae:jiao4 +0x91af:xi1 +0x91b0:tan2 +0x91b1:po4 +0x91b2:nong2 +0x91b3:yi4 +0x91b4:li3 +0x91b5:ju4 +0x91b6:jiao4 +0x91b7:yi4 +0x91b8:niang4 +0x91b9:ru2 +0x91ba:xun1 +0x91bb:chou2 +0x91bc:yan4 +0x91bd:ling2 +0x91be:mi2 +0x91bf:mi2 +0x91c0:niang4 +0x91c1:xin4 +0x91c2:jiao4 +0x91c3:xi3 +0x91c4:mi2 +0x91c5:yan4 +0x91c6:bian4 +0x91c7:cai3 +0x91c8:shi4 +0x91c9:you4 +0x91ca:shi4 +0x91cb:shi4 +0x91cc:li3 +0x91cd:zhong4 +0x91ce:ye3 +0x91cf:liang4 +0x91d0:li2 +0x91d1:jin1 +0x91d3:ga2 +0x91d4:yi3 +0x91d5:liao3 +0x91d6:dao1 +0x91d7:zhao1 +0x91d8:ding1 +0x91d9:po4 +0x91da:qiu2 +0x91db:he2 +0x91dc:fu3 +0x91dd:zhen1 +0x91de:zhi2 +0x91df:ba1 +0x91e0:luan4 +0x91e1:fu3 +0x91e2:nai2 +0x91e3:diao4 +0x91e4:shan4 +0x91e5:qiao3 +0x91e6:kou4 +0x91e7:chuan4 +0x91e8:zi3 +0x91e9:fan2 +0x91ea:yu2 +0x91eb:hua2 +0x91ec:han4 +0x91ed:gang1 +0x91ee:qi2 +0x91ef:mang2 +0x91f0:ri4 +0x91f1:di4 +0x91f2:si4 +0x91f3:xi4 +0x91f4:yi4 +0x91f5:chai1 +0x91f6:shi1 +0x91f7:tu3 +0x91f8:xi4 +0x91f9:nv3 +0x91fa:qian1 +0x91fc:jian4 +0x91fd:pi1 +0x91fe:ye2 +0x91ff:yin2 +0x9200:ba3 +0x9201:fang1 +0x9202:chen2 +0x9203:xing2 +0x9204:dou3 +0x9205:yue4 +0x9206:yan2 +0x9207:fu1 +0x9208:pi1 +0x9209:na4 +0x920a:xin1 +0x920b:e2 +0x920c:jue2 +0x920d:dun4 +0x920e:gou1 +0x920f:yin3 +0x9210:qian2 +0x9211:ban3 +0x9212:ji2 +0x9213:ren2 +0x9214:chao1 +0x9215:niu3 +0x9216:fen1 +0x9217:yun3 +0x9218:ji3 +0x9219:qin2 +0x921a:pi2 +0x921b:guo1 +0x921c:hong2 +0x921d:yin2 +0x921e:jun1 +0x921f:shi1 +0x9220:yi4 +0x9221:zhong1 +0x9222:nie1 +0x9223:gai4 +0x9224:ri4 +0x9225:huo3 +0x9226:tai4 +0x9227:kang4 +0x922c:duo2 +0x922d:zi1 +0x922e:ni2 +0x922f:tu2 +0x9230:shi4 +0x9231:min2 +0x9232:gu1 +0x9233:ke1 +0x9234:ling2 +0x9235:bing4 +0x9236:yi2 +0x9237:gu3 +0x9238:bo2 +0x9239:pi1 +0x923a:yu4 +0x923b:si4 +0x923c:zuo2 +0x923d:bu4 +0x923e:you2 +0x923f:dian4 +0x9240:jia3 +0x9241:zhen1 +0x9242:shi3 +0x9243:shi4 +0x9244:tie3 +0x9245:ju4 +0x9246:chan1 +0x9247:shi1 +0x9248:shi1 +0x9249:xuan4 +0x924a:zhao1 +0x924b:bao4 +0x924c:he2 +0x924d:bi4 +0x924e:sheng1 +0x924f:chu2 +0x9250:shi2 +0x9251:bo2 +0x9252:zhu4 +0x9253:chi4 +0x9254:za1 +0x9255:po1 +0x9256:tong2 +0x9257:qian2 +0x9258:fu2 +0x9259:zhai3 +0x925a:liu3 +0x925b:qian1 +0x925c:fu2 +0x925d:li4 +0x925e:yue4 +0x925f:pi1 +0x9260:yang1 +0x9261:ban4 +0x9262:bo1 +0x9263:jie2 +0x9264:gou1 +0x9265:shu4 +0x9266:zheng1 +0x9267:mu3 +0x9268:ni3 +0x9269:nie1 +0x926a:di4 +0x926b:jia1 +0x926c:mu4 +0x926d:dan4 +0x926e:shen1 +0x926f:yi3 +0x9270:si1 +0x9271:kuang4 +0x9272:ka3 +0x9273:bei3 +0x9274:jian4 +0x9275:tong2 +0x9276:xing2 +0x9277:hong2 +0x9278:jiao3 +0x9279:chi3 +0x927a:er3 +0x927b:ge4 +0x927c:bing3 +0x927d:shi4 +0x927e:mou2 +0x927f:ha1 +0x9280:yin2 +0x9281:jun1 +0x9282:zhou1 +0x9283:chong4 +0x9284:shang4 +0x9285:tong2 +0x9286:mo4 +0x9287:lei4 +0x9288:ji1 +0x9289:yu4 +0x928a:xu4 +0x928b:ren2 +0x928c:zun4 +0x928d:zhi4 +0x928e:qiong1 +0x928f:shan4 +0x9290:chi4 +0x9291:xian3 +0x9292:xing2 +0x9293:quan2 +0x9294:pi1 +0x9295:tie3 +0x9296:zhu1 +0x9297:hou2 +0x9298:ming2 +0x9299:kua3 +0x929a:yao2 +0x929b:xian1 +0x929c:xian2 +0x929d:xiu1 +0x929e:jun1 +0x929f:cha1 +0x92a0:lao3 +0x92a1:ji2 +0x92a2:pi3 +0x92a3:ru2 +0x92a4:mi3 +0x92a5:yi1 +0x92a6:yin1 +0x92a7:guang1 +0x92a8:an3 +0x92a9:diu1 +0x92aa:you3 +0x92ab:se4 +0x92ac:kao4 +0x92ad:qian2 +0x92ae:luan2 +0x92b0:ai1 +0x92b1:diao4 +0x92b2:han4 +0x92b3:rui4 +0x92b4:shi4 +0x92b5:keng1 +0x92b6:qiu2 +0x92b7:xiao1 +0x92b8:zhe2 +0x92b9:xiu4 +0x92ba:zang4 +0x92bb:ti1 +0x92bc:cuo4 +0x92bd:gua1 +0x92be:gong3 +0x92bf:zhong1 +0x92c0:dou4 +0x92c1:lv3 +0x92c2:mei2 +0x92c3:lang2 +0x92c4:wan3 +0x92c5:xin1 +0x92c6:yun2 +0x92c7:bei4 +0x92c8:wu4 +0x92c9:su4 +0x92ca:yu4 +0x92cb:chan2 +0x92cc:ting3 +0x92cd:bo2 +0x92ce:han4 +0x92cf:jia2 +0x92d0:hong2 +0x92d1:cuan1 +0x92d2:feng1 +0x92d3:chan1 +0x92d4:wan3 +0x92d5:zhi4 +0x92d6:si1 +0x92d7:xuan1 +0x92d8:wu2 +0x92d9:wu2 +0x92da:tiao2 +0x92db:gong3 +0x92dc:zhuo2 +0x92dd:lve4 +0x92de:xing2 +0x92df:qian1 +0x92e0:shen4 +0x92e1:han2 +0x92e2:lve4 +0x92e3:xie2 +0x92e4:chu2 +0x92e5:zheng4 +0x92e6:ju1 +0x92e7:xian4 +0x92e8:tie3 +0x92e9:mang2 +0x92ea:pu1 +0x92eb:li2 +0x92ec:pan4 +0x92ed:rui4 +0x92ee:cheng2 +0x92ef:gao4 +0x92f0:li3 +0x92f1:te4 +0x92f3:zhu4 +0x92f5:tu1 +0x92f6:liu3 +0x92f7:zui4 +0x92f8:ju4 +0x92f9:chang3 +0x92fa:yuan1 +0x92fb:jian4 +0x92fc:gang1 +0x92fd:diao4 +0x92fe:tao2 +0x92ff:chang2 +0x9300:lun2 +0x9301:guo3 +0x9302:ling2 +0x9303:bei1 +0x9304:lu4 +0x9305:li2 +0x9306:qiang1 +0x9307:pou2 +0x9308:juan4 +0x9309:min2 +0x930a:zui4 +0x930b:peng2 +0x930c:an4 +0x930d:pi2 +0x930e:xian4 +0x930f:ya4 +0x9310:zhui1 +0x9311:lei4 +0x9312:a1 +0x9313:kong1 +0x9314:ta4 +0x9315:kun1 +0x9316:du3 +0x9317:wei4 +0x9318:chui2 +0x9319:zi1 +0x931a:zheng1 +0x931b:ben1 +0x931c:nie1 +0x931d:cong2 +0x931e:dui4 +0x931f:tan2 +0x9320:ding4 +0x9321:qi2 +0x9322:qian2 +0x9323:zhuo2 +0x9324:qi2 +0x9325:yu4 +0x9326:jin3 +0x9327:guan3 +0x9328:mao2 +0x9329:chang1 +0x932a:tian3 +0x932b:xi2 +0x932c:lian4 +0x932d:tao2 +0x932e:gu4 +0x932f:cuo4 +0x9330:shu4 +0x9331:zhen1 +0x9332:lu4 +0x9333:meng3 +0x9334:lu4 +0x9335:hua1 +0x9336:biao3 +0x9337:ga2 +0x9338:lai2 +0x9339:ken3 +0x933c:nai4 +0x933d:wan3 +0x933e:zan4 +0x9340:de2 +0x9341:xian1 +0x9343:huo1 +0x9344:liang4 +0x9346:men2 +0x9347:kai3 +0x9348:ying1 +0x9349:di1 +0x934a:lian4 +0x934b:guo1 +0x934c:xian3 +0x934d:du4 +0x934e:tu2 +0x934f:wei2 +0x9350:cong1 +0x9351:fu4 +0x9352:rou2 +0x9353:ji2 +0x9354:e4 +0x9355:rou2 +0x9356:chen3 +0x9357:ti2 +0x9358:zha2 +0x9359:hong4 +0x935a:yang2 +0x935b:duan4 +0x935c:xia1 +0x935d:yu2 +0x935e:keng1 +0x935f:xing1 +0x9360:huang2 +0x9361:wei3 +0x9362:fu4 +0x9363:zhao1 +0x9364:cha2 +0x9365:qie4 +0x9366:she2 +0x9367:hong1 +0x9368:kui2 +0x9369:tian3 +0x936a:mou2 +0x936b:qiao1 +0x936c:qiao1 +0x936d:hou2 +0x936e:tou1 +0x936f:cong1 +0x9370:huan2 +0x9371:ye4 +0x9372:min2 +0x9373:jian4 +0x9374:duan1 +0x9375:jian4 +0x9376:si1 +0x9377:kui1 +0x9378:hu2 +0x9379:xuan1 +0x937a:zhe3 +0x937b:jie2 +0x937c:zhen1 +0x937d:bian1 +0x937e:zhong1 +0x937f:zi1 +0x9380:xiu1 +0x9381:ye2 +0x9382:mei3 +0x9383:pai4 +0x9384:ai1 +0x9385:jie4 +0x9387:mei2 +0x9388:chuo1 +0x9389:ta4 +0x938a:bang4 +0x938b:xia2 +0x938c:lian2 +0x938d:suo3 +0x938e:xi4 +0x938f:liu2 +0x9390:zu2 +0x9391:ye4 +0x9392:nou4 +0x9393:weng1 +0x9394:rong2 +0x9395:tang2 +0x9396:suo3 +0x9397:qiang1 +0x9398:ge2 +0x9399:shuo4 +0x939a:chui2 +0x939b:bo2 +0x939c:pan2 +0x939d:sa4 +0x939e:bi4 +0x939f:sang3 +0x93a0:gang1 +0x93a1:zi1 +0x93a2:wu1 +0x93a3:ying4 +0x93a4:huang3 +0x93a5:tiao2 +0x93a6:liu2 +0x93a7:kai3 +0x93a8:sun3 +0x93a9:sha1 +0x93aa:sou1 +0x93ab:wan4 +0x93ac:hao4 +0x93ad:zhen4 +0x93ae:zhen4 +0x93af:luo3 +0x93b0:yi4 +0x93b1:yuan2 +0x93b2:tang3 +0x93b3:nie4 +0x93b4:xi2 +0x93b5:jia1 +0x93b6:ge1 +0x93b7:ma3 +0x93b8:juan1 +0x93bb:suo3 +0x93bf:na2 +0x93c0:lu3 +0x93c1:suo3 +0x93c2:ou1 +0x93c3:zu2 +0x93c4:tuan2 +0x93c5:xiu1 +0x93c6:guan4 +0x93c7:xuan4 +0x93c8:lian4 +0x93c9:shou4 +0x93ca:ao2 +0x93cb:man3 +0x93cc:mo4 +0x93cd:luo2 +0x93ce:bi4 +0x93cf:wei4 +0x93d0:liu2 +0x93d1:di2 +0x93d2:qiao1 +0x93d3:cong1 +0x93d4:yi2 +0x93d5:lu4 +0x93d6:ao2 +0x93d7:keng1 +0x93d8:qiang1 +0x93d9:cui1 +0x93da:qi4 +0x93db:chang2 +0x93dc:tang1 +0x93dd:man4 +0x93de:yong1 +0x93df:chan3 +0x93e0:feng1 +0x93e1:jing4 +0x93e2:biao1 +0x93e3:shu4 +0x93e4:lou4 +0x93e5:xiu4 +0x93e6:cong1 +0x93e7:long2 +0x93e8:zan4 +0x93e9:jian4 +0x93ea:cao2 +0x93eb:li2 +0x93ec:xia4 +0x93ed:xi1 +0x93ee:kang1 +0x93f0:beng4 +0x93f3:zheng1 +0x93f4:lu4 +0x93f5:hua2 +0x93f6:ji2 +0x93f7:pu2 +0x93f8:hui4 +0x93f9:qiang1 +0x93fa:po1 +0x93fb:lin2 +0x93fc:suo3 +0x93fd:xiu4 +0x93fe:san3 +0x93ff:cheng1 +0x9400:kui4 +0x9401:si1 +0x9402:liu4 +0x9403:nao2 +0x9404:heng2 +0x9405:pie3 +0x9406:sui4 +0x9407:fan2 +0x9408:qiao2 +0x9409:quan1 +0x940a:yang2 +0x940b:tang4 +0x940c:xiang4 +0x940d:jue2 +0x940e:jiao1 +0x940f:zun1 +0x9410:liao2 +0x9411:jie2 +0x9412:lao2 +0x9413:dui4 +0x9414:tan2 +0x9415:zan1 +0x9416:ji1 +0x9417:jian3 +0x9418:zhong1 +0x9419:deng4 +0x941a:ya4 +0x941b:ying4 +0x941c:dui4 +0x941d:jue2 +0x941e:nou4 +0x941f:ti4 +0x9420:pu3 +0x9421:tie3 +0x9424:ding3 +0x9425:shan4 +0x9426:kai1 +0x9427:jian3 +0x9428:fei4 +0x9429:sui4 +0x942a:lu3 +0x942b:juan1 +0x942c:hui4 +0x942d:yu4 +0x942e:lian2 +0x942f:zhuo2 +0x9430:qiao1 +0x9431:qian1 +0x9432:zhuo2 +0x9433:lei2 +0x9434:bi4 +0x9435:tie3 +0x9436:huan2 +0x9437:ye4 +0x9438:duo2 +0x9439:guo3 +0x943a:dang1 +0x943b:ju4 +0x943c:fen2 +0x943d:da2 +0x943e:bei4 +0x943f:yi4 +0x9440:ai4 +0x9441:zong1 +0x9442:xun4 +0x9443:diao4 +0x9444:zhu4 +0x9445:heng2 +0x9446:zhui4 +0x9447:ji1 +0x9448:nie1 +0x9449:ta4 +0x944a:huo4 +0x944b:qing4 +0x944c:bin1 +0x944d:ying1 +0x944e:kui4 +0x944f:ning2 +0x9450:xu1 +0x9451:jian4 +0x9452:jian4 +0x9454:cha3 +0x9455:zhi4 +0x9456:mie4 +0x9457:li2 +0x9458:lei2 +0x9459:ji1 +0x945a:zuan4 +0x945b:kuang4 +0x945c:shang4 +0x945d:peng2 +0x945e:la4 +0x945f:du2 +0x9460:shuo4 +0x9461:chuo4 +0x9462:lv4 +0x9463:biao1 +0x9464:bao4 +0x9465:lu3 +0x9468:long2 +0x9469:e4 +0x946a:lu2 +0x946b:xin1 +0x946c:jian4 +0x946d:lan2 +0x946e:bo2 +0x946f:jian1 +0x9470:yao4 +0x9471:chan2 +0x9472:xiang1 +0x9473:jian4 +0x9474:xi1 +0x9475:guan4 +0x9476:cang2 +0x9477:nie4 +0x9478:lei3 +0x9479:cuan4 +0x947a:qu2 +0x947b:pan4 +0x947c:luo2 +0x947d:zuan1 +0x947e:luan2 +0x947f:zao2 +0x9480:nie4 +0x9481:jue2 +0x9482:tang3 +0x9483:shu3 +0x9484:lan2 +0x9485:jin1 +0x9486:qiu2 +0x9487:yi3 +0x9488:zhen1 +0x9489:ding1 +0x948a:zhao1 +0x948b:po4 +0x948c:diao3 +0x948d:tu3 +0x948e:qian1 +0x948f:chuan4 +0x9490:shan4 +0x9491:ji2 +0x9492:fan2 +0x9493:diao4 +0x9494:men2 +0x9495:nv3 +0x9496:xi2 +0x9497:chai1 +0x9498:xing2 +0x9499:gai4 +0x949a:bu4 +0x949b:tai4 +0x949c:ju4 +0x949d:dun4 +0x949e:chao1 +0x949f:zhong1 +0x94a0:na4 +0x94a1:bei4 +0x94a2:gang1 +0x94a3:ban3 +0x94a4:qian2 +0x94a5:yao4 +0x94a6:qin1 +0x94a7:jun1 +0x94a8:wu4 +0x94a9:gou1 +0x94aa:kang4 +0x94ab:fang1 +0x94ac:huo2 +0x94ad:dou3 +0x94ae:niu3 +0x94af:ba3 +0x94b0:yu4 +0x94b1:qian2 +0x94b2:zheng1 +0x94b3:qian2 +0x94b4:gu1 +0x94b5:bo1 +0x94b6:e1 +0x94b7:po1 +0x94b8:bu4 +0x94b9:ba2 +0x94ba:yue4 +0x94bb:zuan4 +0x94bc:mu4 +0x94bd:dan4 +0x94be:jia3 +0x94bf:dian4 +0x94c0:you2 +0x94c1:tie3 +0x94c2:bo2 +0x94c3:ling2 +0x94c4:shuo4 +0x94c5:qian1 +0x94c6:liu3 +0x94c7:bao4 +0x94c8:shi4 +0x94c9:xuan4 +0x94ca:she2 +0x94cb:bi4 +0x94cc:ni3 +0x94cd:pi1 +0x94ce:duo2 +0x94cf:xing2 +0x94d0:kao4 +0x94d1:lao3 +0x94d2:er4 +0x94d3:mang2 +0x94d4:ya4 +0x94d5:you3 +0x94d6:cheng2 +0x94d7:jia2 +0x94d8:ye2 +0x94d9:nao2 +0x94da:zhi4 +0x94db:dang1 +0x94dc:tong2 +0x94dd:lv3 +0x94de:diao4 +0x94df:yin1 +0x94e0:kai3 +0x94e1:zha2 +0x94e2:zhu1 +0x94e3:xian3 +0x94e4:ting3 +0x94e5:diu1 +0x94e6:xian1 +0x94e7:hua2 +0x94e8:quan2 +0x94e9:sha1 +0x94ea:jia2 +0x94eb:yao2 +0x94ec:ge4 +0x94ed:ming2 +0x94ee:zheng1 +0x94ef:se4 +0x94f0:jiao3 +0x94f1:yi3 +0x94f2:chan3 +0x94f3:chong4 +0x94f4:tang4 +0x94f5:an1 +0x94f6:yin2 +0x94f7:ru3 +0x94f8:zhu4 +0x94f9:lao2 +0x94fa:pu1 +0x94fb:wu2 +0x94fc:lai2 +0x94fd:te4 +0x94fe:lian4 +0x94ff:keng1 +0x9500:xiao1 +0x9501:suo3 +0x9502:li3 +0x9503:zheng4 +0x9504:chu2 +0x9505:guo1 +0x9506:gao4 +0x9507:tie3 +0x9508:xiu4 +0x9509:cuo4 +0x950a:lve4 +0x950b:feng1 +0x950c:xin1 +0x950d:liu3 +0x950e:kai1 +0x950f:jian3 +0x9510:rui4 +0x9511:ti4 +0x9512:lang2 +0x9513:qian1 +0x9514:ju2 +0x9515:a1 +0x9516:qiang1 +0x9517:duo3 +0x9518:tian3 +0x9519:cuo4 +0x951a:mao2 +0x951b:ben1 +0x951c:qi2 +0x951d:de2 +0x951e:kua3 +0x951f:kun1 +0x9520:chang1 +0x9521:xi2 +0x9522:gu4 +0x9523:luo2 +0x9524:chui2 +0x9525:zhui1 +0x9526:jin3 +0x9527:zhi4 +0x9528:xian1 +0x9529:juan4 +0x952a:huo1 +0x952b:pou2 +0x952c:tan2 +0x952d:ding4 +0x952e:jian4 +0x952f:ju4 +0x9530:meng3 +0x9531:zi1 +0x9532:qie4 +0x9533:ying1 +0x9534:kai3 +0x9535:qiang1 +0x9536:song1 +0x9537:e4 +0x9538:cha2 +0x9539:qiao1 +0x953a:zhong1 +0x953b:duan4 +0x953c:sou1 +0x953d:huang2 +0x953e:huan2 +0x953f:ai1 +0x9540:du4 +0x9541:mei3 +0x9542:lou4 +0x9543:zi1 +0x9544:fei4 +0x9545:mei2 +0x9546:mo4 +0x9547:zhen4 +0x9548:bo2 +0x9549:ge2 +0x954a:nie4 +0x954b:tang3 +0x954c:juan1 +0x954d:nie4 +0x954e:na2 +0x954f:liu2 +0x9550:hao4 +0x9551:bang4 +0x9552:yi4 +0x9553:jia1 +0x9554:bin1 +0x9555:rong2 +0x9556:biao1 +0x9557:tang1 +0x9558:man4 +0x9559:luo2 +0x955a:beng4 +0x955b:yong1 +0x955c:jing4 +0x955d:di2 +0x955e:zu2 +0x955f:xuan4 +0x9560:liu2 +0x9561:tan2 +0x9562:jue2 +0x9563:liao2 +0x9564:pu2 +0x9565:lu3 +0x9566:dui4 +0x9567:lan4 +0x9568:pu3 +0x9569:cuan4 +0x956a:qiang1 +0x956b:deng1 +0x956c:huo4 +0x956d:lei2 +0x956e:huan2 +0x956f:zhuo2 +0x9570:lian2 +0x9571:yi4 +0x9572:cha3 +0x9573:biao1 +0x9574:la4 +0x9575:chan2 +0x9576:xiang1 +0x9577:chang2 +0x9578:chang2 +0x9579:jiu3 +0x957a:ao3 +0x957b:die2 +0x957c:qu1 +0x957d:liao3 +0x957e:mi2 +0x957f:chang2 +0x9580:men2 +0x9581:ma4 +0x9582:shuan1 +0x9583:shan3 +0x9584:huo4 +0x9585:men2 +0x9586:yan2 +0x9587:bi4 +0x9588:han4 +0x9589:bi4 +0x958b:kai1 +0x958c:kang4 +0x958d:beng1 +0x958e:hong2 +0x958f:run4 +0x9590:san4 +0x9591:xian2 +0x9592:xian2 +0x9593:jian1 +0x9594:min3 +0x9595:xia1 +0x9597:dou4 +0x9598:zha2 +0x9599:nao4 +0x959b:peng1 +0x959c:xia3 +0x959d:ling2 +0x959e:bian4 +0x959f:bi4 +0x95a0:run4 +0x95a1:he2 +0x95a2:guan1 +0x95a3:ge2 +0x95a4:ge2 +0x95a5:fa2 +0x95a6:chu4 +0x95a7:hong4 +0x95a8:gui1 +0x95a9:min3 +0x95ab:kun3 +0x95ac:lang3 +0x95ad:lv2 +0x95ae:ting2 +0x95af:sha4 +0x95b0:ju2 +0x95b1:yue4 +0x95b2:yue4 +0x95b3:chan3 +0x95b4:qu4 +0x95b5:lin4 +0x95b6:chang1 +0x95b7:shai4 +0x95b8:kun3 +0x95b9:yan1 +0x95ba:wen2 +0x95bb:yan2 +0x95bc:e4 +0x95bd:hun1 +0x95be:yu4 +0x95bf:wen2 +0x95c0:xiang4 +0x95c1:bao1 +0x95c2:xiang4 +0x95c3:qu4 +0x95c4:yao3 +0x95c5:wen2 +0x95c6:ban3 +0x95c7:an4 +0x95c8:wei2 +0x95c9:yin1 +0x95ca:kuo4 +0x95cb:que4 +0x95cc:lan2 +0x95cd:du1 +0x95d0:tian2 +0x95d1:nie4 +0x95d2:ta4 +0x95d3:kai3 +0x95d4:he2 +0x95d5:que4 +0x95d6:chuang3 +0x95d7:guan1 +0x95d8:dou4 +0x95d9:qi3 +0x95da:kui1 +0x95db:tang2 +0x95dc:guan1 +0x95dd:piao2 +0x95de:kan4 +0x95df:xi4 +0x95e0:hui4 +0x95e1:chan3 +0x95e2:pi4 +0x95e3:dang4 +0x95e4:huan2 +0x95e5:ta4 +0x95e6:wen2 +0x95e8:men2 +0x95e9:shuan1 +0x95ea:shan3 +0x95eb:yan4 +0x95ec:han4 +0x95ed:bi4 +0x95ee:wen4 +0x95ef:chuang3 +0x95f0:run4 +0x95f1:wei2 +0x95f2:xian2 +0x95f3:hong2 +0x95f4:jian1 +0x95f5:min3 +0x95f6:kang4 +0x95f7:men4 +0x95f8:zha2 +0x95f9:nao4 +0x95fa:gui1 +0x95fb:wen2 +0x95fc:ta4 +0x95fd:min3 +0x95fe:lv2 +0x95ff:kai3 +0x9600:fa2 +0x9601:ge2 +0x9602:he2 +0x9603:kun3 +0x9604:jiu1 +0x9605:yue4 +0x9606:lang3 +0x9607:du1 +0x9608:yu4 +0x9609:yan1 +0x960a:chang1 +0x960b:xi4 +0x960c:wen2 +0x960d:hun1 +0x960e:yan2 +0x960f:e4 +0x9610:chan3 +0x9611:lan2 +0x9612:qu4 +0x9613:hui4 +0x9614:kuo4 +0x9615:que4 +0x9616:ge2 +0x9617:tian2 +0x9618:ta4 +0x9619:que4 +0x961a:kan4 +0x961b:huan2 +0x961c:fu4 +0x961d:fu4 +0x961e:le4 +0x961f:dui4 +0x9620:xin4 +0x9621:qian1 +0x9622:wu4 +0x9623:yi4 +0x9624:tuo2 +0x9625:yin1 +0x9626:yang2 +0x9627:dou3 +0x9628:e4 +0x9629:sheng1 +0x962a:ban3 +0x962b:pei2 +0x962c:keng1 +0x962d:yun3 +0x962e:ruan3 +0x962f:zhi3 +0x9630:pi2 +0x9631:jing3 +0x9632:fang2 +0x9633:yang2 +0x9634:yin1 +0x9635:zhen4 +0x9636:jie1 +0x9637:cheng1 +0x9638:e4 +0x9639:qu1 +0x963a:di3 +0x963b:zu3 +0x963c:zuo4 +0x963d:dian4 +0x963e:ling3 +0x963f:a1 +0x9640:tuo2 +0x9641:tuo2 +0x9642:bei1 +0x9643:bing3 +0x9644:fu4 +0x9645:ji4 +0x9646:lu4 +0x9647:long3 +0x9648:chen2 +0x9649:xing2 +0x964a:duo4 +0x964b:lou4 +0x964c:mo4 +0x964d:jiang4 +0x964e:shu1 +0x964f:duo4 +0x9650:xian4 +0x9651:er2 +0x9652:gui3 +0x9653:yu1 +0x9654:gai1 +0x9655:shan3 +0x9656:xun4 +0x9657:qiao4 +0x9658:xing2 +0x9659:chun2 +0x965a:fu4 +0x965b:bi4 +0x965c:xia2 +0x965d:shan3 +0x965e:sheng1 +0x965f:zhi4 +0x9660:pu1 +0x9661:dou3 +0x9662:yuan4 +0x9663:zhen4 +0x9664:chu2 +0x9665:xian4 +0x9667:nie4 +0x9668:yun3 +0x9669:xian3 +0x966a:pei2 +0x966b:pei2 +0x966c:zou1 +0x966d:yi1 +0x966e:dui3 +0x966f:lun2 +0x9670:yin1 +0x9671:ju1 +0x9672:chui2 +0x9673:chen2 +0x9674:pi2 +0x9675:ling2 +0x9676:tao2 +0x9677:xian4 +0x9678:lu4 +0x967a:xian3 +0x967b:yin1 +0x967c:zhu3 +0x967d:yang2 +0x967e:reng2 +0x967f:shan3 +0x9680:chong2 +0x9681:yan4 +0x9682:yin1 +0x9683:yu2 +0x9684:di1 +0x9685:yu2 +0x9686:long2 +0x9687:wei1 +0x9688:wei1 +0x9689:nie4 +0x968a:dui4 +0x968b:sui2 +0x968c:an3 +0x968d:huang2 +0x968e:jie1 +0x968f:sui2 +0x9690:yin3 +0x9691:gai1 +0x9692:yan3 +0x9693:hui1 +0x9694:ge2 +0x9695:yun3 +0x9696:wu4 +0x9697:wei3 +0x9698:ai4 +0x9699:xi4 +0x969a:tang2 +0x969b:ji4 +0x969c:zhang4 +0x969d:dao3 +0x969e:ao2 +0x969f:xi4 +0x96a0:yin3 +0x96a2:rao4 +0x96a3:lin2 +0x96a4:tui2 +0x96a5:deng4 +0x96a6:pi3 +0x96a7:sui4 +0x96a8:sui2 +0x96a9:yu4 +0x96aa:xian3 +0x96ab:fen1 +0x96ac:ni3 +0x96ad:er2 +0x96ae:ji1 +0x96af:dao3 +0x96b0:xi2 +0x96b1:yin3 +0x96b2:e2 +0x96b3:hui1 +0x96b4:long3 +0x96b5:xi1 +0x96b6:li4 +0x96b7:li4 +0x96b8:li4 +0x96b9:zhui1 +0x96ba:he4 +0x96bb:zhi1 +0x96bc:zhun3 +0x96bd:jun4 +0x96be:nan2 +0x96bf:yi4 +0x96c0:que4 +0x96c1:yan4 +0x96c2:qin2 +0x96c3:ya3 +0x96c4:xiong2 +0x96c5:ya3 +0x96c6:ji2 +0x96c7:gu4 +0x96c8:huan2 +0x96c9:zhi4 +0x96ca:gou4 +0x96cb:jun4 +0x96cc:ci2 +0x96cd:yong1 +0x96ce:ju1 +0x96cf:chu2 +0x96d0:hu1 +0x96d1:za2 +0x96d2:luo4 +0x96d3:yu2 +0x96d4:chou2 +0x96d5:diao1 +0x96d6:sui1 +0x96d7:han4 +0x96d8:huo4 +0x96d9:shuang1 +0x96da:guan4 +0x96db:chu2 +0x96dc:za2 +0x96dd:yong1 +0x96de:ji1 +0x96df:xi1 +0x96e0:chou2 +0x96e1:liu4 +0x96e2:li2 +0x96e3:nan2 +0x96e4:xue2 +0x96e5:za2 +0x96e6:ji2 +0x96e7:ji2 +0x96e8:yu3 +0x96e9:yu2 +0x96ea:xue3 +0x96eb:na3 +0x96ec:fou3 +0x96ed:se4 +0x96ee:mu4 +0x96ef:wen2 +0x96f0:fen1 +0x96f1:pang2 +0x96f2:yun2 +0x96f3:li4 +0x96f4:li4 +0x96f5:ang3 +0x96f6:ling2 +0x96f7:lei2 +0x96f8:an2 +0x96f9:bao2 +0x96fa:meng2 +0x96fb:dian4 +0x96fc:dang4 +0x96fd:xing2 +0x96fe:wu4 +0x96ff:zhao4 +0x9700:xu1 +0x9701:ji4 +0x9702:mu4 +0x9703:chen2 +0x9704:xiao1 +0x9705:zha2 +0x9706:ting2 +0x9707:zhen4 +0x9708:pei4 +0x9709:mei2 +0x970a:ling2 +0x970b:qi1 +0x970c:chou1 +0x970d:huo4 +0x970e:sha4 +0x970f:fei1 +0x9710:weng1 +0x9711:zhan1 +0x9712:yin1 +0x9713:ni2 +0x9714:zhu4 +0x9715:tun2 +0x9716:lin2 +0x9718:dong4 +0x9719:ying1 +0x971a:wu4 +0x971b:ling2 +0x971c:shuang1 +0x971d:ling2 +0x971e:xia2 +0x971f:hong2 +0x9720:yin1 +0x9721:mo4 +0x9722:mai4 +0x9723:yun3 +0x9724:liu4 +0x9725:meng4 +0x9726:bin1 +0x9727:wu4 +0x9728:wei4 +0x9729:huo4 +0x972a:yin2 +0x972b:xi2 +0x972c:yi4 +0x972d:ai3 +0x972e:dan4 +0x972f:deng4 +0x9730:xian4 +0x9731:yu4 +0x9732:lu4 +0x9733:long2 +0x9734:dai4 +0x9735:ji2 +0x9736:pang2 +0x9737:yang2 +0x9738:ba4 +0x9739:pi1 +0x973a:wei2 +0x973c:xi3 +0x973d:ji4 +0x973e:mai2 +0x973f:meng4 +0x9740:meng2 +0x9741:lei2 +0x9742:li4 +0x9743:huo4 +0x9744:ai3 +0x9745:fei4 +0x9746:dai4 +0x9747:long2 +0x9748:ling2 +0x9749:ai4 +0x974a:feng1 +0x974b:li4 +0x974c:bao3 +0x974e:he4 +0x974f:he4 +0x9750:bing4 +0x9751:qing1 +0x9752:qing1 +0x9753:jing4 +0x9754:tian1 +0x9755:zhen1 +0x9756:jing4 +0x9757:cheng4 +0x9758:qing4 +0x9759:jing4 +0x975a:jing4 +0x975b:dian4 +0x975c:jing4 +0x975d:tian1 +0x975e:fei1 +0x975f:fei1 +0x9760:kao4 +0x9761:mi3 +0x9762:mian4 +0x9763:mian4 +0x9764:pao4 +0x9765:ye4 +0x9766:tian3 +0x9767:hui4 +0x9768:ye4 +0x9769:ge2 +0x976a:ding1 +0x976b:cha1 +0x976c:jian1 +0x976d:ren4 +0x976e:di2 +0x976f:du4 +0x9770:wu4 +0x9771:ren4 +0x9772:qin2 +0x9773:jin4 +0x9774:xue1 +0x9775:niu3 +0x9776:ba3 +0x9777:yin3 +0x9778:sa3 +0x9779:na4 +0x977a:mo4 +0x977b:zu3 +0x977c:da2 +0x977d:ban4 +0x977e:yi4 +0x977f:yao4 +0x9780:tao2 +0x9781:tuo2 +0x9782:jia2 +0x9783:hong2 +0x9784:pao2 +0x9785:yang3 +0x9787:yin1 +0x9788:jia2 +0x9789:tao2 +0x978a:ji2 +0x978b:xie2 +0x978c:an1 +0x978d:an1 +0x978e:hen2 +0x978f:gong3 +0x9791:da2 +0x9792:qiao1 +0x9793:ting1 +0x9794:wan3 +0x9795:ying4 +0x9796:sui1 +0x9797:tiao2 +0x9798:qiao4 +0x9799:xuan4 +0x979a:kong4 +0x979b:beng3 +0x979c:ta4 +0x979d:zhang3 +0x979e:bing3 +0x979f:kuo4 +0x97a0:ju1 +0x97a1:la5 +0x97a2:xie4 +0x97a3:rou2 +0x97a4:bang1 +0x97a5:yi4 +0x97a6:qiu1 +0x97a7:qiu1 +0x97a8:he2 +0x97a9:xiao4 +0x97aa:mu4 +0x97ab:ju2 +0x97ac:jian1 +0x97ad:bian1 +0x97ae:di1 +0x97af:jian1 +0x97b1:tao1 +0x97b2:gou1 +0x97b3:ta4 +0x97b4:bei4 +0x97b5:xie2 +0x97b6:pan2 +0x97b7:ge2 +0x97b8:bi4 +0x97b9:kuo4 +0x97bb:lou2 +0x97bc:gui4 +0x97bd:qiao2 +0x97be:xue1 +0x97bf:ji1 +0x97c0:jian1 +0x97c1:jiang1 +0x97c2:chan4 +0x97c3:da2 +0x97c4:huo4 +0x97c5:xian3 +0x97c6:qian1 +0x97c7:du2 +0x97c8:wa4 +0x97c9:jian1 +0x97ca:lan2 +0x97cb:wei2 +0x97cc:ren4 +0x97cd:fu2 +0x97ce:mei4 +0x97cf:juan4 +0x97d0:ge2 +0x97d1:wei3 +0x97d2:qiao4 +0x97d3:han2 +0x97d4:chang4 +0x97d6:rou2 +0x97d7:xun4 +0x97d8:she4 +0x97d9:wei3 +0x97da:ge2 +0x97db:bei4 +0x97dc:tao1 +0x97dd:gou1 +0x97de:yun4 +0x97e0:bi4 +0x97e1:wei3 +0x97e2:hui4 +0x97e3:du2 +0x97e4:wa4 +0x97e5:du2 +0x97e6:wei2 +0x97e7:ren4 +0x97e8:fu2 +0x97e9:han2 +0x97ea:wei3 +0x97eb:yun4 +0x97ec:tao1 +0x97ed:jiu3 +0x97ee:jiu3 +0x97ef:xian1 +0x97f0:xie4 +0x97f1:xian1 +0x97f2:ji1 +0x97f3:yin1 +0x97f4:za2 +0x97f5:yun4 +0x97f6:shao2 +0x97f7:le4 +0x97f8:peng2 +0x97f9:heng2 +0x97fa:ying1 +0x97fb:yun4 +0x97fc:peng2 +0x97fd:yin1 +0x97fe:yin1 +0x97ff:xiang3 +0x9800:hu4 +0x9801:ye4 +0x9802:ding3 +0x9803:qing3 +0x9804:kui2 +0x9805:xiang4 +0x9806:shun4 +0x9807:han1 +0x9808:xu1 +0x9809:yi2 +0x980a:xu4 +0x980b:gu4 +0x980c:song4 +0x980d:kui3 +0x980e:qi2 +0x980f:hang2 +0x9810:yu4 +0x9811:wan2 +0x9812:ban1 +0x9813:dun4 +0x9814:di2 +0x9815:dan1 +0x9816:pan4 +0x9817:po1 +0x9818:ling3 +0x9819:ce4 +0x981a:jing3 +0x981b:lei3 +0x981c:he2 +0x981d:qiao1 +0x981e:e4 +0x981f:e2 +0x9820:wei3 +0x9821:jie2 +0x9822:gua1 +0x9823:shen3 +0x9824:yi2 +0x9825:shen3 +0x9826:hai2 +0x9827:dui1 +0x9828:pian1 +0x9829:ping1 +0x982a:lei4 +0x982b:fu3 +0x982c:jia2 +0x982d:tou2 +0x982e:hui4 +0x982f:kui2 +0x9830:jia2 +0x9831:le4 +0x9832:ting3 +0x9833:cheng1 +0x9834:ying3 +0x9835:jun1 +0x9836:hu2 +0x9837:han4 +0x9838:jing3 +0x9839:tui2 +0x983a:tui2 +0x983b:pin2 +0x983c:lai4 +0x983d:tui2 +0x983e:zi1 +0x983f:zi1 +0x9840:chui2 +0x9841:ding4 +0x9842:lai4 +0x9843:yan2 +0x9844:han4 +0x9845:jian1 +0x9846:ke1 +0x9847:cui4 +0x9848:jiong3 +0x9849:qin1 +0x984a:yi2 +0x984b:sai1 +0x984c:ti2 +0x984d:e2 +0x984e:e4 +0x984f:yan2 +0x9850:hun2 +0x9851:kan3 +0x9852:yong2 +0x9853:zhuan1 +0x9854:yan2 +0x9855:xian3 +0x9856:xin4 +0x9857:yi3 +0x9858:yuan4 +0x9859:sang3 +0x985a:dian1 +0x985b:dian1 +0x985c:jiang3 +0x985d:ku1 +0x985e:lei4 +0x985f:liao2 +0x9860:piao4 +0x9861:yi4 +0x9862:man2 +0x9863:qi1 +0x9864:rao4 +0x9865:hao4 +0x9866:qiao2 +0x9867:gu4 +0x9868:xun4 +0x9869:qian1 +0x986a:hui1 +0x986b:zhan4 +0x986c:ru2 +0x986d:hong1 +0x986e:bin1 +0x986f:xian3 +0x9870:pin2 +0x9871:lu2 +0x9872:lan3 +0x9873:nie4 +0x9874:quan2 +0x9875:ye4 +0x9876:ding3 +0x9877:qing3 +0x9878:han1 +0x9879:xiang4 +0x987a:shun4 +0x987b:xu1 +0x987c:xu4 +0x987d:wan2 +0x987e:gu4 +0x987f:dun4 +0x9880:qi2 +0x9881:ban1 +0x9882:song4 +0x9883:hang2 +0x9884:yu4 +0x9885:lu2 +0x9886:ling3 +0x9887:po3 +0x9888:jing3 +0x9889:jie2 +0x988a:jia2 +0x988b:tian5 +0x988c:han4 +0x988d:ying3 +0x988e:jiong3 +0x988f:hai2 +0x9890:yi2 +0x9891:pin2 +0x9892:hui4 +0x9893:tui2 +0x9894:han4 +0x9895:ying3 +0x9896:ying3 +0x9897:ke1 +0x9898:ti2 +0x9899:yong2 +0x989a:e4 +0x989b:zhuan1 +0x989c:yan2 +0x989d:e2 +0x989e:nie4 +0x989f:man2 +0x98a0:dian1 +0x98a1:sang3 +0x98a2:hao4 +0x98a3:lei4 +0x98a4:zhan4 +0x98a5:ru2 +0x98a6:pin2 +0x98a7:quan2 +0x98a8:feng1 +0x98a9:biao1 +0x98ab:fu2 +0x98ac:xia1 +0x98ad:zhan3 +0x98ae:biao1 +0x98af:sa4 +0x98b0:ba2 +0x98b1:tai2 +0x98b2:lie4 +0x98b3:gua1 +0x98b4:xuan4 +0x98b5:shao4 +0x98b6:ju4 +0x98b7:bi1 +0x98b8:si1 +0x98b9:wei3 +0x98ba:yang2 +0x98bb:yao2 +0x98bc:sou1 +0x98bd:kai3 +0x98be:sao1 +0x98bf:fan2 +0x98c0:liu2 +0x98c1:xi2 +0x98c2:liao2 +0x98c3:piao1 +0x98c4:piao1 +0x98c5:liu2 +0x98c6:biao1 +0x98c7:biao1 +0x98c8:biao3 +0x98c9:liao2 +0x98cb:se4 +0x98cc:feng1 +0x98cd:biao1 +0x98ce:feng1 +0x98cf:yang2 +0x98d0:zhan3 +0x98d1:biao1 +0x98d2:sa4 +0x98d3:ju4 +0x98d4:si1 +0x98d5:sou1 +0x98d6:yao2 +0x98d7:liu2 +0x98d8:piao1 +0x98d9:biao1 +0x98da:biao1 +0x98db:fei1 +0x98dc:fan1 +0x98dd:fei1 +0x98de:fei1 +0x98df:shi2 +0x98e0:shi2 +0x98e1:can1 +0x98e2:ji1 +0x98e3:ding4 +0x98e4:si4 +0x98e5:tuo1 +0x98e6:zhan1 +0x98e7:sun1 +0x98e8:xiang3 +0x98e9:tun2 +0x98ea:ren4 +0x98eb:yu4 +0x98ec:juan4 +0x98ed:chi4 +0x98ee:yin3 +0x98ef:fan4 +0x98f0:fan4 +0x98f1:sun1 +0x98f2:yin3 +0x98f3:zhu4 +0x98f4:yi2 +0x98f5:zhai3 +0x98f6:bi4 +0x98f7:jie3 +0x98f8:tao1 +0x98f9:liu3 +0x98fa:ci2 +0x98fb:tie4 +0x98fc:si4 +0x98fd:bao3 +0x98fe:shi4 +0x98ff:duo4 +0x9900:hai4 +0x9901:ren4 +0x9902:tian3 +0x9903:jiao3 +0x9904:jia2 +0x9905:bing3 +0x9906:yao2 +0x9907:tong2 +0x9908:ci2 +0x9909:xiang3 +0x990a:yang3 +0x990b:yang3 +0x990c:er3 +0x990d:yan4 +0x990e:le5 +0x990f:yi1 +0x9910:can1 +0x9911:bo1 +0x9912:nei3 +0x9913:e4 +0x9914:bu1 +0x9915:jun4 +0x9916:dou4 +0x9917:su4 +0x9918:yu2 +0x9919:shi4 +0x991a:yao2 +0x991b:hun2 +0x991c:guo3 +0x991d:shi4 +0x991e:jian4 +0x991f:zhui4 +0x9920:bing3 +0x9921:xian4 +0x9922:bu4 +0x9923:ye4 +0x9924:tan2 +0x9925:fei3 +0x9926:zhang1 +0x9927:wei4 +0x9928:guan3 +0x9929:e4 +0x992a:nuan3 +0x992b:hun2 +0x992c:hu2 +0x992d:huang2 +0x992e:tie4 +0x992f:hui4 +0x9930:jian1 +0x9931:hou2 +0x9932:he2 +0x9933:xing2 +0x9934:fen1 +0x9935:wei4 +0x9936:gu3 +0x9937:cha1 +0x9938:song4 +0x9939:tang2 +0x993a:bo2 +0x993b:gao1 +0x993c:xi4 +0x993d:kui4 +0x993e:liu4 +0x993f:sou1 +0x9940:tao2 +0x9941:ye4 +0x9942:yun2 +0x9943:mo2 +0x9944:tang2 +0x9945:man2 +0x9946:bi4 +0x9947:yu4 +0x9948:xiu1 +0x9949:jin3 +0x994a:san3 +0x994b:kui4 +0x994c:zhuan4 +0x994d:shan4 +0x994e:chi4 +0x994f:dan4 +0x9950:yi4 +0x9951:ji1 +0x9952:rao2 +0x9953:cheng1 +0x9954:yong1 +0x9955:tao1 +0x9956:hui4 +0x9957:xiang3 +0x9958:zhan1 +0x9959:fen1 +0x995a:hai4 +0x995b:meng2 +0x995c:yan4 +0x995d:mo2 +0x995e:chan2 +0x995f:xiang3 +0x9960:luo2 +0x9961:zuan4 +0x9962:nang3 +0x9963:shi2 +0x9964:ding4 +0x9965:ji1 +0x9966:tuo1 +0x9967:xing2 +0x9968:tun2 +0x9969:xi4 +0x996a:ren4 +0x996b:yu4 +0x996c:chi4 +0x996d:fan4 +0x996e:yin3 +0x996f:jian4 +0x9970:shi4 +0x9971:bao3 +0x9972:si4 +0x9973:duo4 +0x9974:yi2 +0x9975:er3 +0x9976:rao2 +0x9977:xiang3 +0x9978:jia2 +0x9979:le5 +0x997a:jiao3 +0x997b:yi1 +0x997c:bing3 +0x997d:bo2 +0x997e:dou4 +0x997f:e4 +0x9980:yu2 +0x9981:nei3 +0x9982:jun4 +0x9983:guo3 +0x9984:hun2 +0x9985:xian4 +0x9986:guan3 +0x9987:cha1 +0x9988:kui4 +0x9989:gu3 +0x998a:sou1 +0x998b:chan2 +0x998c:ye4 +0x998d:mo2 +0x998e:bo2 +0x998f:liu4 +0x9990:xiu1 +0x9991:jin3 +0x9992:man2 +0x9993:san3 +0x9994:zhuan4 +0x9995:nang3 +0x9996:shou3 +0x9997:kui2 +0x9998:guo2 +0x9999:xiang1 +0x999a:fen2 +0x999b:ba2 +0x999c:ni3 +0x999d:bi4 +0x999e:bo2 +0x999f:tu2 +0x99a0:han1 +0x99a1:fei1 +0x99a2:jian1 +0x99a3:an1 +0x99a4:ai3 +0x99a5:fu4 +0x99a6:xian1 +0x99a7:wen1 +0x99a8:xin1 +0x99a9:fen2 +0x99aa:bin1 +0x99ab:xing1 +0x99ac:ma3 +0x99ad:yu4 +0x99ae:feng2 +0x99af:han4 +0x99b0:di4 +0x99b1:tuo2 +0x99b2:tuo1 +0x99b3:chi2 +0x99b4:xun2 +0x99b5:zhu4 +0x99b6:zhi1 +0x99b7:pei4 +0x99b8:xin4 +0x99b9:ri4 +0x99ba:sa4 +0x99bb:yin3 +0x99bc:wen2 +0x99bd:zhi2 +0x99be:dan4 +0x99bf:lv2 +0x99c0:you2 +0x99c1:bo2 +0x99c2:bao3 +0x99c3:kuai4 +0x99c4:tuo2 +0x99c5:yi4 +0x99c6:qu1 +0x99c8:qu1 +0x99c9:jiong1 +0x99ca:bo3 +0x99cb:zhao1 +0x99cc:yuan1 +0x99cd:peng1 +0x99ce:zhou4 +0x99cf:ju4 +0x99d0:zhu4 +0x99d1:nu2 +0x99d2:ju1 +0x99d3:pi1 +0x99d4:zang3 +0x99d5:jia4 +0x99d6:ling2 +0x99d7:zhen1 +0x99d8:tai2 +0x99d9:fu4 +0x99da:yang3 +0x99db:shi3 +0x99dc:bi4 +0x99dd:tuo2 +0x99de:tuo2 +0x99df:si4 +0x99e0:liu2 +0x99e1:ma4 +0x99e2:pian2 +0x99e3:tao2 +0x99e4:zhi4 +0x99e5:rong2 +0x99e6:teng2 +0x99e7:dong4 +0x99e8:xun2 +0x99e9:quan2 +0x99ea:shen1 +0x99eb:jiong1 +0x99ec:er3 +0x99ed:hai4 +0x99ee:bo2 +0x99f0:yin1 +0x99f1:luo4 +0x99f3:dan4 +0x99f4:xie4 +0x99f5:liu2 +0x99f6:ju2 +0x99f7:song3 +0x99f8:qin1 +0x99f9:mang2 +0x99fa:liang2 +0x99fb:han4 +0x99fc:tu2 +0x99fd:xuan4 +0x99fe:tui4 +0x99ff:jun4 +0x9a00:e2 +0x9a01:cheng3 +0x9a02:xing1 +0x9a03:ai2 +0x9a04:lu4 +0x9a05:zhui1 +0x9a06:zhou1 +0x9a07:she3 +0x9a08:pian2 +0x9a09:kun1 +0x9a0a:tao2 +0x9a0b:lai2 +0x9a0c:zong1 +0x9a0d:ke4 +0x9a0e:qi2 +0x9a0f:qi2 +0x9a10:yan4 +0x9a11:fei1 +0x9a12:sao1 +0x9a13:yan3 +0x9a14:jie2 +0x9a15:yao3 +0x9a16:wu4 +0x9a17:pian4 +0x9a18:cong1 +0x9a19:pian4 +0x9a1a:qian2 +0x9a1b:fei1 +0x9a1c:huang2 +0x9a1d:jian1 +0x9a1e:huo4 +0x9a1f:yu4 +0x9a20:ti2 +0x9a21:quan2 +0x9a22:xia2 +0x9a23:zong1 +0x9a24:kui2 +0x9a25:rou2 +0x9a26:si1 +0x9a27:gua1 +0x9a28:tuo2 +0x9a29:kui4 +0x9a2a:sou1 +0x9a2b:qian1 +0x9a2c:cheng2 +0x9a2d:zhi4 +0x9a2e:liu2 +0x9a2f:pang2 +0x9a30:teng2 +0x9a31:xi1 +0x9a32:cao3 +0x9a33:du2 +0x9a34:yan4 +0x9a35:yuan2 +0x9a36:zou1 +0x9a37:sao1 +0x9a38:shan4 +0x9a39:li2 +0x9a3a:zhi4 +0x9a3b:shuang3 +0x9a3c:lu4 +0x9a3d:xi2 +0x9a3e:luo2 +0x9a3f:zhang1 +0x9a40:mo4 +0x9a41:ao4 +0x9a42:can1 +0x9a43:piao4 +0x9a44:cong1 +0x9a45:qu1 +0x9a46:bi4 +0x9a47:zhi4 +0x9a48:yu4 +0x9a49:xu1 +0x9a4a:hua2 +0x9a4b:bo1 +0x9a4c:su4 +0x9a4d:xiao1 +0x9a4e:lin2 +0x9a4f:chan3 +0x9a50:dun1 +0x9a51:liu2 +0x9a52:tuo2 +0x9a53:zeng1 +0x9a54:tan2 +0x9a55:jiao1 +0x9a56:tie3 +0x9a57:yan4 +0x9a58:luo2 +0x9a59:zhan1 +0x9a5a:jing1 +0x9a5b:yi4 +0x9a5c:ye4 +0x9a5d:tuo1 +0x9a5e:bin1 +0x9a5f:zou4 +0x9a60:yan4 +0x9a61:peng2 +0x9a62:lv2 +0x9a63:teng2 +0x9a64:xiang1 +0x9a65:ji4 +0x9a66:shuang1 +0x9a67:ju2 +0x9a68:xi1 +0x9a69:huan1 +0x9a6a:li2 +0x9a6b:biao1 +0x9a6c:ma3 +0x9a6d:yu4 +0x9a6e:tuo2 +0x9a6f:xun2 +0x9a70:chi2 +0x9a71:qu1 +0x9a72:ri4 +0x9a73:bo2 +0x9a74:lv2 +0x9a75:zang3 +0x9a76:shi3 +0x9a77:si4 +0x9a78:fu4 +0x9a79:ju1 +0x9a7a:zou1 +0x9a7b:zhu4 +0x9a7c:tuo2 +0x9a7d:nu2 +0x9a7e:jia4 +0x9a7f:yi4 +0x9a80:tai2 +0x9a81:xiao1 +0x9a82:ma4 +0x9a83:yin1 +0x9a84:jiao1 +0x9a85:hua2 +0x9a86:luo4 +0x9a87:hai4 +0x9a88:pian2 +0x9a89:biao1 +0x9a8a:li2 +0x9a8b:cheng3 +0x9a8c:yan4 +0x9a8d:xin1 +0x9a8e:qin1 +0x9a8f:jun4 +0x9a90:qi2 +0x9a91:qi2 +0x9a92:ke4 +0x9a93:zhui1 +0x9a94:zong1 +0x9a95:su4 +0x9a96:can1 +0x9a97:pian4 +0x9a98:zhi4 +0x9a99:kui2 +0x9a9a:sao1 +0x9a9b:wu4 +0x9a9c:ao2 +0x9a9d:liu2 +0x9a9e:qian1 +0x9a9f:shan4 +0x9aa0:piao4 +0x9aa1:luo2 +0x9aa2:cong1 +0x9aa3:chan3 +0x9aa4:zou4 +0x9aa5:ji4 +0x9aa6:shuang1 +0x9aa7:xiang1 +0x9aa8:gu3 +0x9aa9:wei3 +0x9aaa:wei3 +0x9aab:wei3 +0x9aac:yu2 +0x9aad:gan4 +0x9aae:yi4 +0x9aaf:ang1 +0x9ab0:tou2 +0x9ab1:xie4 +0x9ab2:bao1 +0x9ab3:bi4 +0x9ab4:chi1 +0x9ab5:ti3 +0x9ab6:di3 +0x9ab7:ku1 +0x9ab8:hai2 +0x9ab9:qiao1 +0x9aba:gou4 +0x9abb:kua4 +0x9abc:ge2 +0x9abd:tui3 +0x9abe:geng3 +0x9abf:pian2 +0x9ac0:bi4 +0x9ac1:ke1 +0x9ac2:ka4 +0x9ac3:yu2 +0x9ac4:sui3 +0x9ac5:lou2 +0x9ac6:bo2 +0x9ac7:xiao1 +0x9ac8:pang2 +0x9ac9:bo1 +0x9aca:ci1 +0x9acb:kuan1 +0x9acc:bin4 +0x9acd:mo2 +0x9ace:liao2 +0x9acf:lou2 +0x9ad0:nao2 +0x9ad1:du2 +0x9ad2:zang1 +0x9ad3:sui3 +0x9ad4:ti3 +0x9ad5:bin4 +0x9ad6:kuan1 +0x9ad7:lu2 +0x9ad8:gao1 +0x9ad9:gao1 +0x9ada:qiao4 +0x9adb:kao1 +0x9adc:qiao1 +0x9add:lao4 +0x9ade:zao4 +0x9adf:biao1 +0x9ae0:kun1 +0x9ae1:kun1 +0x9ae2:ti4 +0x9ae3:fang3 +0x9ae4:xiu1 +0x9ae5:ran2 +0x9ae6:mao2 +0x9ae7:dan4 +0x9ae8:kun1 +0x9ae9:bin4 +0x9aea:fa4 +0x9aeb:tiao2 +0x9aec:pi1 +0x9aed:zi1 +0x9aee:fa4 +0x9aef:ran2 +0x9af0:ti4 +0x9af1:pao4 +0x9af2:pi1 +0x9af3:mao2 +0x9af4:fu2 +0x9af5:er2 +0x9af6:rong2 +0x9af7:qu1 +0x9af9:xiu1 +0x9afa:gua4 +0x9afb:ji4 +0x9afc:peng2 +0x9afd:zhua1 +0x9afe:shao1 +0x9aff:sha1 +0x9b00:ti4 +0x9b01:li4 +0x9b02:bin4 +0x9b03:zong1 +0x9b04:ti4 +0x9b05:peng2 +0x9b06:song1 +0x9b07:zheng1 +0x9b08:quan2 +0x9b09:zong1 +0x9b0a:shun4 +0x9b0b:jian1 +0x9b0c:duo3 +0x9b0d:hu2 +0x9b0e:la4 +0x9b0f:jiu1 +0x9b10:qi2 +0x9b11:lian2 +0x9b12:zhen3 +0x9b13:bin4 +0x9b14:peng2 +0x9b15:mo4 +0x9b16:san1 +0x9b17:man4 +0x9b18:man2 +0x9b19:seng1 +0x9b1a:xu1 +0x9b1b:lie4 +0x9b1c:qian1 +0x9b1d:qian1 +0x9b1e:nong2 +0x9b1f:huan2 +0x9b20:kuai4 +0x9b21:ning2 +0x9b22:bin4 +0x9b23:lie4 +0x9b24:rang2 +0x9b25:dou4 +0x9b26:dou4 +0x9b27:nao4 +0x9b28:hong4 +0x9b29:xi4 +0x9b2a:dou4 +0x9b2b:han3 +0x9b2c:dou4 +0x9b2d:dou4 +0x9b2e:jiu1 +0x9b2f:chang4 +0x9b30:yu4 +0x9b31:yu4 +0x9b32:li4 +0x9b33:juan4 +0x9b34:fu3 +0x9b35:qian2 +0x9b36:gui1 +0x9b37:zong1 +0x9b38:liu4 +0x9b39:gui1 +0x9b3a:shang1 +0x9b3b:yu4 +0x9b3c:gui3 +0x9b3d:mei4 +0x9b3e:ji4 +0x9b3f:qi2 +0x9b40:jie4 +0x9b41:kui2 +0x9b42:hun2 +0x9b43:ba2 +0x9b44:po4 +0x9b45:mei4 +0x9b46:xu4 +0x9b47:yan3 +0x9b48:xiao1 +0x9b49:liang3 +0x9b4a:yu4 +0x9b4b:tui2 +0x9b4c:qi1 +0x9b4d:wang3 +0x9b4e:liang3 +0x9b4f:wei4 +0x9b50:jian1 +0x9b51:chi1 +0x9b52:piao1 +0x9b53:bi4 +0x9b54:mo2 +0x9b55:ji3 +0x9b56:xu1 +0x9b57:chou3 +0x9b58:yan3 +0x9b59:zhan3 +0x9b5a:yu2 +0x9b5b:dao1 +0x9b5c:ren2 +0x9b5d:ji4 +0x9b5f:gong1 +0x9b60:tuo2 +0x9b61:diao4 +0x9b62:ji3 +0x9b63:xu4 +0x9b64:e2 +0x9b65:e4 +0x9b66:sha1 +0x9b67:hang2 +0x9b68:tun2 +0x9b69:mo4 +0x9b6a:jie4 +0x9b6b:shen3 +0x9b6c:fan3 +0x9b6d:yuan2 +0x9b6e:bi2 +0x9b6f:lu3 +0x9b70:wen2 +0x9b71:hu2 +0x9b72:lu2 +0x9b73:za2 +0x9b74:fang2 +0x9b75:fen2 +0x9b76:na4 +0x9b77:you2 +0x9b7a:he2 +0x9b7b:xia2 +0x9b7c:qu1 +0x9b7d:han1 +0x9b7e:pi2 +0x9b7f:ling2 +0x9b80:tuo2 +0x9b81:bo1 +0x9b82:qiu2 +0x9b83:ping2 +0x9b84:fu2 +0x9b85:bi4 +0x9b86:ji4 +0x9b87:wei4 +0x9b88:ju1 +0x9b89:diao1 +0x9b8a:bo2 +0x9b8b:you2 +0x9b8c:gun3 +0x9b8d:pi1 +0x9b8e:nian2 +0x9b8f:xing1 +0x9b90:tai2 +0x9b91:bao4 +0x9b92:fu4 +0x9b93:zha3 +0x9b94:ju4 +0x9b95:gu1 +0x9b99:ta4 +0x9b9a:jie2 +0x9b9b:shu4 +0x9b9c:hou4 +0x9b9d:xiang3 +0x9b9e:er2 +0x9b9f:an4 +0x9ba0:wei2 +0x9ba1:tiao1 +0x9ba2:zhu1 +0x9ba3:yin4 +0x9ba4:lie4 +0x9ba5:luo4 +0x9ba6:tong2 +0x9ba7:yi2 +0x9ba8:qi2 +0x9ba9:bing4 +0x9baa:wei3 +0x9bab:jiao1 +0x9bac:bu4 +0x9bad:gui1 +0x9bae:xian1 +0x9baf:ge2 +0x9bb0:hui2 +0x9bb3:kao3 +0x9bb5:duo2 +0x9bb6:jun1 +0x9bb7:ti2 +0x9bb8:mian3 +0x9bb9:xiao1 +0x9bba:za3 +0x9bbb:sha1 +0x9bbc:qin1 +0x9bbd:yu2 +0x9bbe:nei3 +0x9bbf:zhe2 +0x9bc0:gun3 +0x9bc1:geng3 +0x9bc3:wu2 +0x9bc4:qiu2 +0x9bc5:ting2 +0x9bc6:fu3 +0x9bc7:wan3 +0x9bc8:tiao2 +0x9bc9:li3 +0x9bca:sha1 +0x9bcb:sha1 +0x9bcc:gao4 +0x9bcd:meng2 +0x9bd2:yong3 +0x9bd3:ni2 +0x9bd4:zi1 +0x9bd5:qi2 +0x9bd6:qing1 +0x9bd7:xiang3 +0x9bd8:nei3 +0x9bd9:chun2 +0x9bda:ji4 +0x9bdb:diao1 +0x9bdc:qie4 +0x9bdd:gu4 +0x9bde:zhou3 +0x9bdf:dong1 +0x9be0:lai2 +0x9be1:fei1 +0x9be2:ni2 +0x9be3:yi4 +0x9be4:kun1 +0x9be5:lu4 +0x9be6:jiu4 +0x9be7:chang1 +0x9be8:jing1 +0x9be9:lun2 +0x9bea:ling2 +0x9beb:zou1 +0x9bec:li2 +0x9bed:meng3 +0x9bee:zong1 +0x9bef:zhi4 +0x9bf0:nian2 +0x9bf4:shi1 +0x9bf5:shen1 +0x9bf6:hun3 +0x9bf7:shi4 +0x9bf8:hou2 +0x9bf9:xing1 +0x9bfa:zhu1 +0x9bfb:la4 +0x9bfc:zong1 +0x9bfd:ji4 +0x9bfe:bian1 +0x9bff:bian1 +0x9c00:huan4 +0x9c01:quan2 +0x9c02:ze2 +0x9c03:wei1 +0x9c04:wei1 +0x9c05:yu2 +0x9c06:qun1 +0x9c07:rou2 +0x9c08:die2 +0x9c09:huang2 +0x9c0a:lian4 +0x9c0b:yan3 +0x9c0c:qiu2 +0x9c0d:qiu1 +0x9c0e:jian4 +0x9c0f:bi4 +0x9c10:e4 +0x9c11:yang2 +0x9c12:fu4 +0x9c13:sai1 +0x9c14:jian3 +0x9c15:xia2 +0x9c16:tuo3 +0x9c17:hu2 +0x9c19:ruo4 +0x9c1b:wen1 +0x9c1c:jian1 +0x9c1d:hao4 +0x9c1e:wu1 +0x9c1f:fang2 +0x9c20:sao1 +0x9c21:liu2 +0x9c22:ma3 +0x9c23:shi2 +0x9c24:shi1 +0x9c25:guan1 +0x9c27:teng2 +0x9c28:ta4 +0x9c29:yao2 +0x9c2a:ge2 +0x9c2b:rong2 +0x9c2c:qian2 +0x9c2d:qi2 +0x9c2e:wen1 +0x9c2f:ruo4 +0x9c31:lian2 +0x9c32:ao2 +0x9c33:le4 +0x9c34:hui1 +0x9c35:min3 +0x9c36:ji4 +0x9c37:tiao2 +0x9c38:qu1 +0x9c39:jian1 +0x9c3a:sao1 +0x9c3b:man2 +0x9c3c:xi2 +0x9c3d:qiu2 +0x9c3e:biao4 +0x9c3f:ji1 +0x9c40:ji4 +0x9c41:zhu2 +0x9c42:jiang1 +0x9c43:qiu1 +0x9c44:zhuan1 +0x9c45:yong2 +0x9c46:zhang1 +0x9c47:kang1 +0x9c48:xue3 +0x9c49:bie1 +0x9c4a:jue2 +0x9c4b:qu1 +0x9c4c:xiang4 +0x9c4d:bo1 +0x9c4e:jiao3 +0x9c4f:xun2 +0x9c50:su4 +0x9c51:huang2 +0x9c52:zun4 +0x9c53:shan4 +0x9c54:shan4 +0x9c55:fan1 +0x9c56:gui4 +0x9c57:lin2 +0x9c58:xun2 +0x9c59:miao2 +0x9c5a:xi3 +0x9c5d:fen4 +0x9c5e:guan1 +0x9c5f:hou4 +0x9c60:kuai4 +0x9c61:zei2 +0x9c62:sao1 +0x9c63:zhan1 +0x9c64:gan3 +0x9c65:gui4 +0x9c66:sheng2 +0x9c67:li3 +0x9c68:chang2 +0x9c6c:ru2 +0x9c6d:ji4 +0x9c6e:xu4 +0x9c6f:huo4 +0x9c71:li4 +0x9c72:lie4 +0x9c73:li4 +0x9c74:mie4 +0x9c75:zhen1 +0x9c76:xiang3 +0x9c77:e4 +0x9c78:lu2 +0x9c79:guan4 +0x9c7a:li2 +0x9c7b:xian1 +0x9c7c:yu2 +0x9c7d:dao1 +0x9c7e:ji3 +0x9c7f:you2 +0x9c80:tun2 +0x9c81:lu3 +0x9c82:fang2 +0x9c83:ba1 +0x9c84:he2 +0x9c85:bo1 +0x9c86:ping2 +0x9c87:nian2 +0x9c88:lu2 +0x9c89:you2 +0x9c8a:zha3 +0x9c8b:fu4 +0x9c8c:bo2 +0x9c8d:bao4 +0x9c8e:hou4 +0x9c8f:pi1 +0x9c90:tai2 +0x9c91:gui1 +0x9c92:jie2 +0x9c93:kao3 +0x9c94:wei3 +0x9c95:er2 +0x9c96:tong2 +0x9c97:ze2 +0x9c98:hou4 +0x9c99:kuai4 +0x9c9a:ji4 +0x9c9b:jiao3 +0x9c9c:xian1 +0x9c9d:za3 +0x9c9e:xiang3 +0x9c9f:xun2 +0x9ca0:geng3 +0x9ca1:li2 +0x9ca2:lian2 +0x9ca3:jian1 +0x9ca4:li3 +0x9ca5:shi2 +0x9ca6:tiao2 +0x9ca7:gun3 +0x9ca8:sha1 +0x9ca9:wan3 +0x9caa:jun1 +0x9cab:ji4 +0x9cac:yong3 +0x9cad:qing1 +0x9cae:ling2 +0x9caf:qi2 +0x9cb0:zou1 +0x9cb1:fei1 +0x9cb2:kun1 +0x9cb3:chang1 +0x9cb4:gu4 +0x9cb5:ni2 +0x9cb6:nian2 +0x9cb7:diao1 +0x9cb8:jing1 +0x9cb9:shen1 +0x9cba:shi1 +0x9cbb:zi1 +0x9cbc:fen4 +0x9cbd:die2 +0x9cbe:bi4 +0x9cbf:chang2 +0x9cc0:shi4 +0x9cc1:wen1 +0x9cc2:wei1 +0x9cc3:sai1 +0x9cc4:e4 +0x9cc5:qiu1 +0x9cc6:fu4 +0x9cc7:huang2 +0x9cc8:quan2 +0x9cc9:jiang1 +0x9cca:bian1 +0x9ccb:sao1 +0x9ccc:ao2 +0x9ccd:qi2 +0x9cce:ta4 +0x9ccf:yin2 +0x9cd0:yao2 +0x9cd1:fang2 +0x9cd2:jian1 +0x9cd3:le4 +0x9cd4:biao4 +0x9cd5:xue3 +0x9cd6:bie1 +0x9cd7:man2 +0x9cd8:min3 +0x9cd9:yong2 +0x9cda:wei4 +0x9cdb:xi2 +0x9cdc:jue2 +0x9cdd:shan4 +0x9cde:lin2 +0x9cdf:zun4 +0x9ce0:huo4 +0x9ce1:gan3 +0x9ce2:li3 +0x9ce3:zhan1 +0x9ce4:guan3 +0x9ce5:niao3 +0x9ce6:yi3 +0x9ce7:fu2 +0x9ce8:li4 +0x9ce9:jiu1 +0x9cea:bu3 +0x9ceb:yan4 +0x9cec:fu2 +0x9ced:diao1 +0x9cee:ji1 +0x9cef:feng4 +0x9cf1:gan1 +0x9cf2:shi1 +0x9cf3:feng4 +0x9cf4:ming2 +0x9cf5:bao3 +0x9cf6:yuan1 +0x9cf7:zhi1 +0x9cf8:hu4 +0x9cf9:qin2 +0x9cfa:fu1 +0x9cfb:fen1 +0x9cfc:wen2 +0x9cfd:jian1 +0x9cfe:shi1 +0x9cff:yu4 +0x9d00:fou3 +0x9d01:yao1 +0x9d02:jue4 +0x9d03:jue2 +0x9d04:pi1 +0x9d05:huan1 +0x9d06:zhen4 +0x9d07:bao3 +0x9d08:yan4 +0x9d09:ya1 +0x9d0a:zheng4 +0x9d0b:fang1 +0x9d0c:feng4 +0x9d0d:wen2 +0x9d0e:ou1 +0x9d0f:te4 +0x9d10:jia1 +0x9d11:nu2 +0x9d12:ling2 +0x9d13:mie4 +0x9d14:fu2 +0x9d15:tuo2 +0x9d16:wen2 +0x9d17:li4 +0x9d18:bian4 +0x9d19:zhi4 +0x9d1a:ge1 +0x9d1b:yuan1 +0x9d1c:zi1 +0x9d1d:qu2 +0x9d1e:xiao1 +0x9d1f:chi1 +0x9d20:dan4 +0x9d21:ju1 +0x9d22:you4 +0x9d23:gu1 +0x9d24:zhong1 +0x9d25:yu4 +0x9d26:yang1 +0x9d27:rong4 +0x9d28:ya1 +0x9d29:tie3 +0x9d2a:yu4 +0x9d2c:ying1 +0x9d2d:zhui1 +0x9d2e:wu1 +0x9d2f:er2 +0x9d30:gua1 +0x9d31:ai4 +0x9d32:zhi1 +0x9d33:yan4 +0x9d34:heng2 +0x9d35:jiao1 +0x9d36:ji2 +0x9d37:lie4 +0x9d38:zhu1 +0x9d39:ren2 +0x9d3a:yi2 +0x9d3b:hong2 +0x9d3c:luo4 +0x9d3d:ru2 +0x9d3e:mou2 +0x9d3f:ge1 +0x9d40:ren4 +0x9d41:jiao1 +0x9d42:xiu1 +0x9d43:zhou1 +0x9d44:zhi1 +0x9d45:luo4 +0x9d49:luan2 +0x9d4a:jia2 +0x9d4b:ji4 +0x9d4c:yu2 +0x9d4d:huan1 +0x9d4e:tuo3 +0x9d4f:bu1 +0x9d50:wu2 +0x9d51:juan1 +0x9d52:yu4 +0x9d53:bo2 +0x9d54:xun4 +0x9d55:xun4 +0x9d56:bi4 +0x9d57:xi1 +0x9d58:jun4 +0x9d59:ju2 +0x9d5a:tu2 +0x9d5b:jing1 +0x9d5c:ti2 +0x9d5d:e2 +0x9d5e:e2 +0x9d5f:kuang2 +0x9d60:hu2 +0x9d61:wu3 +0x9d62:shen1 +0x9d63:lai4 +0x9d66:lu4 +0x9d67:ping2 +0x9d68:shu1 +0x9d69:fu2 +0x9d6a:an1 +0x9d6b:zhao4 +0x9d6c:peng2 +0x9d6d:qin2 +0x9d6e:qian1 +0x9d6f:bei1 +0x9d70:diao1 +0x9d71:lu4 +0x9d72:que4 +0x9d73:jian1 +0x9d74:ju2 +0x9d75:tu4 +0x9d76:ya1 +0x9d77:yuan1 +0x9d78:qi2 +0x9d79:li2 +0x9d7a:ye4 +0x9d7b:zhui1 +0x9d7c:kong1 +0x9d7d:zhui4 +0x9d7e:kun1 +0x9d7f:sheng1 +0x9d80:qi2 +0x9d81:jing1 +0x9d82:yi4 +0x9d83:yi4 +0x9d84:jing1 +0x9d85:zi1 +0x9d86:lai2 +0x9d87:dong1 +0x9d88:qi1 +0x9d89:chun2 +0x9d8a:geng1 +0x9d8b:ju1 +0x9d8c:qu1 +0x9d8f:ji1 +0x9d90:shu4 +0x9d92:chi4 +0x9d93:miao2 +0x9d94:rou2 +0x9d95:an1 +0x9d96:qiu1 +0x9d97:ti2 +0x9d98:hu2 +0x9d99:ti2 +0x9d9a:e4 +0x9d9b:jie1 +0x9d9c:mao2 +0x9d9d:fu2 +0x9d9e:chun1 +0x9d9f:tu2 +0x9da0:yan3 +0x9da1:he2 +0x9da2:yuan2 +0x9da3:pian1 +0x9da4:yun4 +0x9da5:mei2 +0x9da6:hu2 +0x9da7:ying1 +0x9da8:dun4 +0x9da9:wu4 +0x9daa:ju2 +0x9dac:cang1 +0x9dad:fang3 +0x9dae:gu4 +0x9daf:ying1 +0x9db0:yuan2 +0x9db1:xuan1 +0x9db2:weng1 +0x9db3:shi1 +0x9db4:he4 +0x9db5:chu2 +0x9db6:tang2 +0x9db7:xia4 +0x9db8:ruo4 +0x9db9:liu2 +0x9dba:ji2 +0x9dbb:gu2 +0x9dbc:jian1 +0x9dbd:zhun3 +0x9dbe:han4 +0x9dbf:zi1 +0x9dc0:zi1 +0x9dc1:ni4 +0x9dc2:yao4 +0x9dc3:yan4 +0x9dc4:ji1 +0x9dc5:li4 +0x9dc6:tian2 +0x9dc7:kou4 +0x9dc8:ti1 +0x9dc9:ti1 +0x9dca:ni4 +0x9dcb:tu2 +0x9dcc:ma3 +0x9dcd:jiao1 +0x9dce:gao1 +0x9dcf:tian2 +0x9dd0:chen2 +0x9dd1:li4 +0x9dd2:zhuan1 +0x9dd3:zhe4 +0x9dd4:ao2 +0x9dd5:yao3 +0x9dd6:yi1 +0x9dd7:ou1 +0x9dd8:chi4 +0x9dd9:zhi4 +0x9dda:liao2 +0x9ddb:rong2 +0x9ddc:lou2 +0x9ddd:bi4 +0x9dde:shuang1 +0x9ddf:zhuo2 +0x9de0:yu2 +0x9de1:wu2 +0x9de2:jue2 +0x9de3:yin2 +0x9de4:quan2 +0x9de5:si1 +0x9de6:jiao1 +0x9de7:yi4 +0x9de8:hua1 +0x9de9:bi4 +0x9dea:ying1 +0x9deb:su4 +0x9dec:huang2 +0x9ded:fan2 +0x9dee:jiao1 +0x9def:liao2 +0x9df0:yan4 +0x9df1:kao1 +0x9df2:jiu4 +0x9df3:xian2 +0x9df4:xian2 +0x9df5:tu2 +0x9df6:mai3 +0x9df7:zun1 +0x9df8:yu4 +0x9df9:ying1 +0x9dfa:lu4 +0x9dfb:tuan2 +0x9dfc:xian2 +0x9dfd:xue2 +0x9dfe:yi4 +0x9dff:pi4 +0x9e00:shu2 +0x9e01:luo2 +0x9e02:qi1 +0x9e03:yi2 +0x9e04:ji2 +0x9e05:zhe2 +0x9e06:yu2 +0x9e07:zhan1 +0x9e08:ye4 +0x9e09:yang2 +0x9e0a:pi4 +0x9e0b:ning2 +0x9e0c:huo4 +0x9e0d:mi2 +0x9e0e:ying1 +0x9e0f:meng2 +0x9e10:di2 +0x9e11:yue4 +0x9e12:yu2 +0x9e13:lei3 +0x9e14:bao4 +0x9e15:lu2 +0x9e16:he4 +0x9e17:long2 +0x9e18:shuang1 +0x9e19:yue4 +0x9e1a:ying1 +0x9e1b:guan4 +0x9e1c:qu2 +0x9e1d:li2 +0x9e1e:luan2 +0x9e1f:niao3 +0x9e20:jiu1 +0x9e21:ji1 +0x9e22:yuan1 +0x9e23:ming2 +0x9e24:shi1 +0x9e25:ou1 +0x9e26:ya1 +0x9e27:cang1 +0x9e28:bao3 +0x9e29:zhen4 +0x9e2a:gu1 +0x9e2b:dong1 +0x9e2c:lu2 +0x9e2d:ya1 +0x9e2e:xiao1 +0x9e2f:yang1 +0x9e30:ling2 +0x9e31:zhi1 +0x9e32:qu2 +0x9e33:yuan1 +0x9e34:xue2 +0x9e35:tuo2 +0x9e36:si1 +0x9e37:zhi4 +0x9e38:er2 +0x9e39:gua1 +0x9e3a:xiu1 +0x9e3b:heng2 +0x9e3c:zhou1 +0x9e3d:ge1 +0x9e3e:luan2 +0x9e3f:hong2 +0x9e40:wu2 +0x9e41:bo2 +0x9e42:li2 +0x9e43:juan1 +0x9e44:hu2 +0x9e45:e2 +0x9e46:yu4 +0x9e47:xian2 +0x9e48:ti2 +0x9e49:wu3 +0x9e4a:que4 +0x9e4b:miao2 +0x9e4c:an1 +0x9e4d:kun1 +0x9e4e:bei1 +0x9e4f:peng2 +0x9e50:qian1 +0x9e51:chun2 +0x9e52:geng1 +0x9e53:yuan1 +0x9e54:su4 +0x9e55:hu2 +0x9e56:he2 +0x9e57:e4 +0x9e58:gu2 +0x9e59:qiu1 +0x9e5a:zi1 +0x9e5b:mei2 +0x9e5c:mu4 +0x9e5d:ni4 +0x9e5e:yao4 +0x9e5f:weng1 +0x9e60:liu2 +0x9e61:ji2 +0x9e62:ni4 +0x9e63:jian1 +0x9e64:he4 +0x9e65:yi1 +0x9e66:ying1 +0x9e67:zhe4 +0x9e68:liao2 +0x9e69:liao2 +0x9e6a:jiao1 +0x9e6b:jiu4 +0x9e6c:yu4 +0x9e6d:lu4 +0x9e6e:xuan2 +0x9e6f:zhan1 +0x9e70:ying1 +0x9e71:huo4 +0x9e72:meng2 +0x9e73:guan4 +0x9e74:shuang1 +0x9e75:lu3 +0x9e76:jin1 +0x9e77:ling2 +0x9e78:jian3 +0x9e79:xian2 +0x9e7a:cuo2 +0x9e7b:jian3 +0x9e7c:jian3 +0x9e7d:yan2 +0x9e7e:cuo2 +0x9e7f:lu4 +0x9e80:you1 +0x9e81:cu1 +0x9e82:ji3 +0x9e83:biao1 +0x9e84:cu1 +0x9e85:biao1 +0x9e86:zhu4 +0x9e87:jun1 +0x9e88:zhu3 +0x9e89:jian1 +0x9e8a:mi2 +0x9e8b:mi2 +0x9e8c:wu2 +0x9e8d:liu2 +0x9e8e:chen2 +0x9e8f:jun1 +0x9e90:lin2 +0x9e91:ni2 +0x9e92:qi2 +0x9e93:lu4 +0x9e94:jiu4 +0x9e95:jun1 +0x9e96:jing1 +0x9e97:li4 +0x9e98:xiang1 +0x9e99:yan2 +0x9e9a:jia1 +0x9e9b:mi2 +0x9e9c:li4 +0x9e9d:she4 +0x9e9e:zhang1 +0x9e9f:lin2 +0x9ea0:jing1 +0x9ea1:ji1 +0x9ea2:ling2 +0x9ea3:yan2 +0x9ea4:cu1 +0x9ea5:mai4 +0x9ea6:mai4 +0x9ea7:ge1 +0x9ea8:chao3 +0x9ea9:fu1 +0x9eaa:mian3 +0x9eab:mian3 +0x9eac:fu1 +0x9ead:pao4 +0x9eae:qu4 +0x9eaf:qu2 +0x9eb0:mou2 +0x9eb1:fu1 +0x9eb2:xian4 +0x9eb3:lai2 +0x9eb4:qu2 +0x9eb5:mian4 +0x9eb7:feng1 +0x9eb8:fu1 +0x9eb9:qu2 +0x9eba:mian4 +0x9ebb:ma2 +0x9ebc:me5 +0x9ebd:mo5 +0x9ebe:hui1 +0x9ec0:zou1 +0x9ec1:nen1 +0x9ec2:fen2 +0x9ec3:huang2 +0x9ec4:huang2 +0x9ec5:jin1 +0x9ec6:guang1 +0x9ec7:tian1 +0x9ec8:tou3 +0x9ec9:heng2 +0x9eca:xi1 +0x9ecb:kuang3 +0x9ecc:heng2 +0x9ecd:shu3 +0x9ece:li2 +0x9ecf:nian2 +0x9ed0:chi1 +0x9ed1:hei1 +0x9ed2:hei1 +0x9ed3:yi4 +0x9ed4:qian2 +0x9ed5:dan1 +0x9ed6:xi4 +0x9ed7:tuan3 +0x9ed8:mo4 +0x9ed9:mo4 +0x9eda:qian2 +0x9edb:dai4 +0x9edc:chu4 +0x9edd:you3 +0x9ede:dian3 +0x9edf:yi1 +0x9ee0:xia2 +0x9ee1:yan3 +0x9ee2:qu1 +0x9ee3:mei3 +0x9ee4:yan3 +0x9ee5:qing2 +0x9ee6:yu4 +0x9ee7:li2 +0x9ee8:dang3 +0x9ee9:du2 +0x9eea:can3 +0x9eeb:yin1 +0x9eec:an4 +0x9eed:yan1 +0x9eee:tan3 +0x9eef:an4 +0x9ef0:zhen3 +0x9ef1:dai4 +0x9ef2:can3 +0x9ef3:yi1 +0x9ef4:mei2 +0x9ef5:dan3 +0x9ef6:yan3 +0x9ef7:du2 +0x9ef8:lu2 +0x9ef9:zhi3 +0x9efa:fen3 +0x9efb:fu2 +0x9efc:fu3 +0x9efd:min3 +0x9efe:min3 +0x9eff:yuan2 +0x9f00:cu4 +0x9f01:qu4 +0x9f02:chao2 +0x9f03:wa1 +0x9f04:zhu1 +0x9f05:zhi1 +0x9f06:mang2 +0x9f07:ao2 +0x9f08:bie1 +0x9f09:tuo2 +0x9f0a:bi4 +0x9f0b:yuan2 +0x9f0c:chao2 +0x9f0d:tuo2 +0x9f0e:ding3 +0x9f0f:mi4 +0x9f10:nai4 +0x9f11:ding3 +0x9f12:zi1 +0x9f13:gu3 +0x9f14:gu3 +0x9f15:dong1 +0x9f16:fen2 +0x9f17:tao2 +0x9f18:yuan1 +0x9f19:pi2 +0x9f1a:chang1 +0x9f1b:gao1 +0x9f1c:qi4 +0x9f1d:yuan1 +0x9f1e:tang1 +0x9f1f:teng1 +0x9f20:shu3 +0x9f21:shu3 +0x9f22:fen2 +0x9f23:fei4 +0x9f24:wen2 +0x9f25:ba2 +0x9f26:diao1 +0x9f27:tuo2 +0x9f28:tong2 +0x9f29:qu2 +0x9f2a:sheng1 +0x9f2b:shi2 +0x9f2c:you4 +0x9f2d:shi2 +0x9f2e:ting2 +0x9f2f:wu2 +0x9f30:nian4 +0x9f31:jing1 +0x9f32:hun2 +0x9f33:ju2 +0x9f34:yan3 +0x9f35:tu2 +0x9f36:ti2 +0x9f37:xi1 +0x9f38:xian3 +0x9f39:yan3 +0x9f3a:lei2 +0x9f3b:bi2 +0x9f3c:yao3 +0x9f3d:qiu2 +0x9f3e:han1 +0x9f3f:wu1 +0x9f40:wu4 +0x9f41:hou1 +0x9f42:xi4 +0x9f43:ge2 +0x9f44:zha1 +0x9f45:xiu4 +0x9f46:weng4 +0x9f47:zha1 +0x9f48:nong2 +0x9f49:nang4 +0x9f4a:qi2 +0x9f4b:zhai1 +0x9f4c:ji4 +0x9f4d:zi1 +0x9f4e:ji1 +0x9f4f:ji1 +0x9f50:qi2 +0x9f51:ji1 +0x9f52:chi3 +0x9f53:chen4 +0x9f54:chen4 +0x9f55:he2 +0x9f56:ya2 +0x9f57:ken3 +0x9f58:xie4 +0x9f59:pao2 +0x9f5a:cuo4 +0x9f5b:shi4 +0x9f5c:zi1 +0x9f5d:chi1 +0x9f5e:nian4 +0x9f5f:ju3 +0x9f60:tiao2 +0x9f61:ling2 +0x9f62:ling2 +0x9f63:chu1 +0x9f64:quan2 +0x9f65:xie4 +0x9f66:ken3 +0x9f67:nie4 +0x9f68:jiu4 +0x9f69:yao3 +0x9f6a:chuo4 +0x9f6b:kun3 +0x9f6c:yu3 +0x9f6d:chu3 +0x9f6e:yi3 +0x9f6f:ni2 +0x9f70:cuo4 +0x9f71:zou1 +0x9f72:qu3 +0x9f73:nen3 +0x9f74:xian3 +0x9f75:ou2 +0x9f76:e4 +0x9f77:wo4 +0x9f78:yi4 +0x9f79:chuo1 +0x9f7a:zou1 +0x9f7b:dian1 +0x9f7c:chu3 +0x9f7d:jin4 +0x9f7e:ya4 +0x9f7f:chi3 +0x9f80:chen4 +0x9f81:he2 +0x9f82:ken3 +0x9f83:ju3 +0x9f84:ling2 +0x9f85:pao2 +0x9f86:tiao2 +0x9f87:zi1 +0x9f88:ken3 +0x9f89:yu3 +0x9f8a:chuo4 +0x9f8b:qu3 +0x9f8c:wo4 +0x9f8d:long2 +0x9f8e:pang2 +0x9f8f:gong1 +0x9f90:pang2 +0x9f91:yan3 +0x9f92:long2 +0x9f93:long2 +0x9f94:gong1 +0x9f95:kan1 +0x9f96:ta4 +0x9f97:ling2 +0x9f98:ta4 +0x9f99:long2 +0x9f9a:gong1 +0x9f9b:kan1 +0x9f9c:gui1 +0x9f9d:qiu1 +0x9f9e:bie1 +0x9f9f:gui1 +0x9fa0:yue4 +0x9fa1:chui4 +0x9fa2:he2 +0x9fa3:jue2 +0x9fa4:xie2 +0x9fa5:yu4 +0x9fc3:shan3 +0xf90e:la4 +0xfa0c:wu4 +0xfa0d:huo4 +0xfa10:zhong3 +0xfa12:qing2 +0xfa15:xi1 +0xfa16:zhu1 +0xfa17:yi4 +0xfa18:li3 +0xfa19:shen2 +0xfa1a:xiang2 +0xfa1b:fu2 +0xfa1c:jing4 +0xfa1d:jing1 +0xfa1e:yu3 +0xfa22:zhu1 +0xfa25:yi4 +0xfa26:du1 +0xfa2a:fan4 +0xfa2b:si4 +0xfa2c:guan3 +0xfa2d:he4 diff --git a/dde-file-manager-5.5.3/src/common/common.pri b/dde-file-manager-5.5.3/src/common/common.pri new file mode 100644 index 0000000..18d393b --- /dev/null +++ b/dde-file-manager-5.5.3/src/common/common.pri @@ -0,0 +1,107 @@ +unix { + ProjectName = dde-file-manager + PREFIX = /usr + APPSHAREDIR = $$PREFIX/share/$$ProjectName + top_srcdir = $$PWD/../ + + CONFIG(release, debug|release) { + LIB_INSTALL_DIR = $$[QT_INSTALL_LIBS] + } + + ARCH = $$QMAKE_HOST.arch + isEqual(ARCH, mips64) | isEqual(ARCH, mips32) | isEqual(ARCH, loongarch64) | isEqual(ARCH, riscv64) { + DEFINES += SPLICE_CP + + #不支持CI内存检测 + CONFIG += DISABLE_TSAN_TOOL + } + isEqual(ARCH, loongarch64){ + DEFINES += __mips__ + DEFINES += __MIPSEL__ + } + isEqual(ARCH, riscv64){ + DEFINES += __riscv + DEFINES += __LP64 + } + isEqual(ARCH, riscv32){ + DEFINES += __riscv + } + isEqual(ARCH, x86_64) | isEqual(ARCH, i686) { + message("Build arch:" $$ARCH) + + #只在release开启,方便debug时开发 + CONFIG(release, debug|release) { + message("x86 ENABLE_DAEMON") + #启用守护,当前进程退出后会接着起动一个文管后台驻留进程,提升响应速度 + DEFINES += ENABLE_DAEMON + } + #起动时,使用异步初始化,加载资源,提升起动速度 + DEFINES += ENABLE_ASYNCINIT + } else { + message("Build arch:" $$ARCH "Deepin Anything support disabled") + CONFIG += DISABLE_ANYTHING + + DEFINES += ENABLE_ASYNCINIT + } + + isEqual(ARCH, sw_64) | isEqual(ARCH, mips64) | isEqual(ARCH, mips32) | isEqual(ARCH, loongarch64) | isEqual(ARCH, riscv64) { + DEFINES += ARCH_MIPSEL ARCH_SW + + #use classical file section mode + DEFINES += CLASSICAL_SECTION + + DEFINES += LOAD_FILE_INTERVAL=150 + + DEFINES += DISABLE_COMPRESS_PREIVEW + + #启用守护,当前进程退出后会接着起动一个文管后台驻留进程,提升响应速度 + DEFINES += ENABLE_DAEMON + + #起动时,使用异步初始化,加载资源,提升起动速度 + DEFINES += ENABLE_ASYNCINIT + } else { + isEmpty(DISABLE_JEMALLOC) { + DEFINES += ENABLE_JEMALLOC + LIBS += -ljemalloc + } + } + + isEqual(ARCH, sw_64){ + DEFINES += SW_CPUINFO + QMAKE_CXXFLAGS += -mieee + } + isEqual(ARCH, aarch64){ + DEFINES += arm + DEFINES += __arm__ + } + #优化通过指定 -Wl,--as-needed 选项,链接过程中,链接器会检查所有的依赖库,没有实际被引用的库,不再写入可执行文件头。最终生成的可执行文件头中包含的都是必要的链接库信息 + QMAKE_CXX += -Wl,--as-need -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,-O1 + QMAKE_CXXFLAGS += -Wl,--as-need -fPIE -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,-O1 + QMAKE_LFLAGS += -Wl,--as-needed -pie + isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + #mips编译优化-pg是用于测试性能提升 + QMAKE_CXX += -O3 -ftree-vectorize -march=loongson3a -mhard-float -mno-micromips -mno-mips16 -flax-vector-conversions -mloongson-ext2 -mloongson-mmi #-mmsa #龙芯4000使用的编译优化参数 + QMAKE_CXXFLAGS += -O3 -ftree-vectorize -march=loongson3a -mhard-float -mno-micromips -mno-mips16 -flax-vector-conversions -mloongson-ext2 -mloongson-mmi #-mmsa #龙芯4000使用的编译优化参数 + } + + isEmpty(LIB_INSTALL_DIR) { + LIB_BASE_DIR = $$[QT_INSTALL_LIBS]/$$ProjectName + } else { + LIB_BASE_DIR = $$LIB_INSTALL_DIR/$$ProjectName + } + + PLUGINDIR = $$LIB_BASE_DIR/plugins + TOOLDIR = $$LIB_BASE_DIR/tools + + DEFINES += PLUGINDIR=\\\"$$top_srcdir/plugins:$$PLUGINDIR\\\" TOOLDIR=\\\"$$top_srcdir/tools:$$TOOLDIR\\\" + + isEmpty(VERSION) { + VERSION = 1.8.2 + } +} + +INCLUDEPATH += $$top_srcdir \ + $$top_srcdir/utils \ + $$top_srcdir/dde-file-manager-lib/interfaces \ + $$top_srcdir/dde-file-manager-lib/interfaces/plugins \ + $$top_srcdir/dde-file-manager-plugins/plugininterfaces diff --git a/dde-file-manager-5.5.3/src/dbusservices/com.deepin.dde.desktop.service b/dde-file-manager-5.5.3/src/dbusservices/com.deepin.dde.desktop.service new file mode 100644 index 0000000..b03c21c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dbusservices/com.deepin.dde.desktop.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=com.deepin.dde.desktop +Exec=/usr/bin/dde-desktop diff --git a/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/advanced-info.qrc b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/advanced-info.qrc new file mode 100644 index 0000000..d7227bb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/advanced-info.qrc @@ -0,0 +1,5 @@ + + + advanced-info.theme + + diff --git a/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/advanced-info.theme b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/advanced-info.theme new file mode 100644 index 0000000..5fa2917 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/advanced-info.theme @@ -0,0 +1,22 @@ +QListWidget::item{ + height: 24px; + padding: 0px; + margins:10px; + color: black; + background: white; +} + +QListWidget::item:selected{ + background: white; +} + +QLabel{ + font-size: 11px; +} + +QLineEdit{ + font-size: 11px; + border: 1px solid rgba(0, 0, 0, 0); + border-radius: 2px; + background: rgba(0, 40, 60, 0.1); +} diff --git a/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dadvancedinfoplugin.cpp b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dadvancedinfoplugin.cpp new file mode 100644 index 0000000..9535443 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dadvancedinfoplugin.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "dadvancedinfoplugin.h" +#include "dadvancedinfowidget.h" +DAdvancedInfoPlugin::DAdvancedInfoPlugin(QObject *parent) + : PropertyDialogExpandInfoInterface(parent) +{ + +} + +QWidget *DAdvancedInfoPlugin::expandWidget(const QString &file) +{ + return new DAdvancedInfoWidget(nullptr, file); +} + +QString DAdvancedInfoPlugin::expandWidgetTitle(const QString &file) +{ + Q_UNUSED(file); + return "Advanced info"; +} diff --git a/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dadvancedinfoplugin.h b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dadvancedinfoplugin.h new file mode 100644 index 0000000..a2772ce --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dadvancedinfoplugin.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DADVANCEDINFOPLUGIN_H +#define DADVANCEDINFOPLUGIN_H + +#include <../dde-file-manager-plugins/plugininterfaces/menu/menuinterface.h> +#include + +class QWidget; + +class DAdvancedInfoPlugin : public PropertyDialogExpandInfoInterface +{ + Q_OBJECT + Q_INTERFACES(PropertyDialogExpandInfoInterface) + Q_PLUGIN_METADATA(IID PropertyDialogExpandInfoInterface_iid FILE "dde-advanced-property-plugin.json") + +public: + explicit DAdvancedInfoPlugin(QObject *parent = nullptr); + + QWidget* expandWidget(const QString &file) override; + + QString expandWidgetTitle(const QString &file) override; +}; + +#endif // DADVANCEDINFOPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dadvancedinfowidget.cpp b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dadvancedinfowidget.cpp new file mode 100644 index 0000000..a313c33 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dadvancedinfowidget.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "dadvancedinfowidget.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "../utils/utils.h" +#include "shutil/fileutils.h" +#include "interfaces/dfileinfo.h" +#include "interfaces/dfileservices.h" +#include "models/avfsfileinfo.h" + +DAdvancedInfoWidget::DAdvancedInfoWidget(QWidget *parent, const QString &file) : + QWidget(parent), + m_url(QUrl::fromUserInput(file)) +{ + initData(); + initUI(); +} + +void DAdvancedInfoWidget::initData() +{ + const DAbstractFileInfoPointer& info = DFileService::instance()->createFileInfo(this, DUrl(m_url)); + if(!info || !info->exists()) + return; + QString realParentPath = info->parentUrl().path(); + QString realFilePath = info->filePath(); + QString realFileUri = info->fileUrl().toString(); + bool isAvfsFile = info->fileUrl().isAVFSFile(); + QProcess p; + + if(isAvfsFile){ + realParentPath = AVFSFileInfo::realFileUrl(info->fileUrl()).parentUrl().path(); + realFilePath = AVFSFileInfo::realFileUrl(info->fileUrl()).path(); + realFileUri = AVFSFileInfo::realFileUrl(info->fileUrl()).toString(); + } + + + //qio mime type + m_InfoList << QStringPair("QMimeType:", info->mimeTypeName()); + + //gio mime type + QString g_mimeType = FileUtils::getMimeTypeByGIO(realFileUri); + m_InfoList << QStringPair("GMimeType:", g_mimeType); + + //icon name + m_InfoList << QStringPair("Icon name:", info->iconName()); + + //acess + QString cmd = "/bin/bash"; + QStringList args; + args << "-c" << "ls -l " + realParentPath + "|grep " + info->fileName(); + + p.start(cmd, args); + p.waitForFinished(200); + QString access = p.readAll().constData(); + access = access.split(" ").first(); + m_InfoList << QStringPair("Access:", access); + + //size md5 + QString sizeMD5 = FileUtils::md5(QString::number(FileUtils::totalSize(info->filePath()))); + m_InfoList << QStringPair("MD5:", sizeMD5); + + //avfs real url + if(info->fileUrl().isAVFSFile()){ + QString realPath = AVFSFileInfo::realFileUrl(info->fileUrl()).path(); + m_InfoList << QStringPair("Arch reflect path:", realPath); + } + + //symlink real path + if(info->isSymLink()){ + m_InfoList << QStringPair("Sym root target:", info->rootSymLinkTarget().path()); + } +} + +void DAdvancedInfoWidget::initUI() +{ + m_listWidget = new QListWidget(this); + m_listWidget->setSpacing(2); + QVBoxLayout* mainLayout = new QVBoxLayout; + mainLayout->addWidget(m_listWidget); + setLayout(mainLayout); + + foreach (const QStringPair& pair, m_InfoList) { + QFrame *frame = nullptr; + QFormLayout *fLayout = nullptr; + QLineEdit *valLabel = nullptr; + QListWidgetItem *item = nullptr; + + valLabel = new QLineEdit(frame); + valLabel->setText(pair.second); + valLabel->setReadOnly(true); + + fLayout = new QFormLayout; + fLayout->setContentsMargins(5, 0, 5, 0); + fLayout->addRow(pair.first, valLabel); + + frame = new QFrame(this); + frame->setContentsMargins(0, 0, 0, 0); + frame->setLayout(fLayout); + + item = new QListWidgetItem; + m_listWidget->addItem(item); + m_listWidget->setItemWidget(item, frame); + } + + setFixedWidth(310); +} diff --git a/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dadvancedinfowidget.h b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dadvancedinfowidget.h new file mode 100644 index 0000000..3e1a9d6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dadvancedinfowidget.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DADVANCEDINFOWIDGET_H +#define DADVANCEDINFOWIDGET_H + +#include +#include +#include +#include +#include +#include +#include + +typedef QPair QStringPair; +class DAdvancedInfoWidget : public QWidget +{ + Q_OBJECT +public: + explicit DAdvancedInfoWidget(QWidget *parent = nullptr, const QString &file = ""); + void initData(); + void initUI(); + +signals: + +public slots: + +private: + QListWidget* m_listWidget; + QList m_InfoList; + QUrl m_url; +}; + +#endif // DADVANCEDINFOWIDGET_H diff --git a/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dde-advanced-property-plugin.json b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dde-advanced-property-plugin.json new file mode 100644 index 0000000..1e81138 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dde-advanced-property-plugin.json @@ -0,0 +1,3 @@ +{ + "Keys" : [ ] +} diff --git a/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dde-advanced-property-plugin.pro b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dde-advanced-property-plugin.pro new file mode 100644 index 0000000..41fb431 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-advanced-property-plugin/dde-advanced-property-plugin.pro @@ -0,0 +1,37 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-03-15T16:03:35 +# +#------------------------------------------------- +include(../common/common.pri) +QT += core gui widgets + +TARGET = dde-advanced-property-plugin +TEMPLATE = lib +CONFIG += plugin c++11 + +PLUGIN_INSTALL_DIR = $$PLUGINDIR/menu +message($$PLUGIN_INSTALL_DIR) + +SOURCES += \ + dadvancedinfowidget.cpp \ + dadvancedinfoplugin.cpp + +DESTDIR = ../dde-file-manager-plugins/menu + +HEADERS += \ + dadvancedinfowidget.h \ + dadvancedinfoplugin.h +DISTFILES += dde-advanced-property-plugin.json + +INCLUDEPATH += \ + ../dde-file-manager-lib \ + ../dde-file-manager-lib/interfaces + +unix { + target.path = $$PLUGIN_INSTALL_DIR + INSTALLS += target +} + +RESOURCES += \ + advanced-info.qrc diff --git a/dde-file-manager-5.5.3/src/dde-desktop/accessibility/ac-desktop-define.h b/dde-file-manager-5.5.3/src/dde-desktop/accessibility/ac-desktop-define.h new file mode 100644 index 0000000..6f65797 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/accessibility/ac-desktop-define.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DESKTOP_ACCESSIBLE_UI_DEFINE_H +#define DESKTOP_ACCESSIBLE_UI_DEFINE_H + +#include +#include +#include "accessibility/acintelfunctions.h" + + + #define AC_SCREEN_BACKGROUND "screen_background" // 设置桌面 + #define AC_CANVAS_GRID_VIEW "screen_canvas_view" // 桌面视图画布 + #define AC_WATER_MASK_FRAME "water_mask" // 桌面水印 + + #define AC_WATER_MASK_LOGO_LABEL "water_mask_logo" // 水印logo + #define AC_WATER_MASK_TEXT "water_mask_text" // 水印文字描述 + #define AC_WATER_TEXT_LABEL_NO_AUTHORIZED "Not_authorized" // 水印文字描述:无授权 + #define AC_WATER_TEXT_LABEL_IN_TRIAL "In_trial_period" // 水印文字描述:试用 + + #define AC_FILE_MENU_DESKTOP "desktop_menu" + + +#endif // DESKTOP_ACCESSIBLE_UI_DEFINE_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/accessibility/acobjectlist.h b/dde-file-manager-5.5.3/src/dde-desktop/accessibility/acobjectlist.h new file mode 100644 index 0000000..5a480f1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/accessibility/acobjectlist.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DESKTOP_ACCESSIBLE_OBJECT_LIST_H +#define DESKTOP_ACCESSIBLE_OBJECT_LIST_H + +#include "acframefunctions.h" + +// 添加accessible + +SET_FORM_ACCESSIBLE(QWidget,m_w->objectName()) + +QAccessibleInterface *accessibleFactory(const QString &classname, QObject *object) +{ + QAccessibleInterface *interface = nullptr; + USE_ACCESSIBLE(classname, QWidget); + + return interface; +} + +#endif // DESKTOP_ACCESSIBLE_OBJECT_LIST_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/config/config.cpp b/dde-file-manager-5.5.3/src/dde-desktop/config/config.cpp new file mode 100644 index 0000000..e718de8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/config/config.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +const QString Config::groupGeneral = "GeneralConfig"; +const QString Config::keyProfile = "Profile"; +const QString Config::keySortBy = "SortBy"; +const QString Config::keySortOrder = "SortOrder"; +const QString Config::keyAutoAlign = "AutoSort"; +const QString Config::keyIconLevel = "IconLevel"; +const QString Config::keyQuickHide = "QuickHide"; +const QString Config::keyAutoMerge = "AutoMerge"; +const QString Config::keyWaterMask = "WaterMaskUseJson"; + +Config::Config() +{ + auto configPath = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first(); + configPath = configPath + + "/" + QApplication::organizationName() + + "/" + QApplication::applicationName() + + "/" + QApplication::applicationName() + ".conf"; + + qDebug() << configPath; + + QFileInfo configFile(configPath); + if (!configFile.exists()) { + configFile.absoluteDir().mkpath("."); + } + //不使用DFMDesktopSettings,有几率启动崩溃 + m_settings = new QSettings(configPath,QSettings::IniFormat); + auto work = new QThread(this); + this->moveToThread(work); + work->start(); + + m_syncTimer.setSingleShot(true); + m_syncTimer.setInterval(1000); + connect(&m_syncTimer, &QTimer::timeout, this, [ = ]() { + QMutexLocker lk(&m_mtxLock); + m_settings->sync(); + }, Qt::QueuedConnection); +} + +void Config::setConfig(const QString &group, const QString &key, const QVariant &value) +{ + QMutexLocker lk(&m_mtxLock); + m_settings->beginGroup(group); + m_settings->setValue(key, value); + m_settings->endGroup(); + sync(); +} + +void Config::setConfigList(const QString &group, const QStringList &keys, const QVariantList &values) +{ + QMutexLocker lk(&m_mtxLock); + m_settings->beginGroup(group); + for (int i = 0; i < keys.length(); ++i) { + m_settings->setValue(keys.value(i), values.value(i)); + } + m_settings->endGroup(); + sync(); +} + +void Config::removeConfig(const QString &group, const QString &key) +{ + QMutexLocker lk(&m_mtxLock); + m_settings->beginGroup(group); + m_settings->remove(key); + m_settings->endGroup(); + sync(); +} + +void Config::removeConfigList(const QString &group, const QStringList &keys) +{ + QMutexLocker lk(&m_mtxLock); + m_settings->beginGroup(group); + for (int i = 0; i < keys.length(); ++i) { + m_settings->remove(keys.value(i)); + } + m_settings->endGroup(); + sync(); +} + +void Config::sync() +{ + metaObject()->invokeMethod(&m_syncTimer,"start",Q_ARG(int,1000)); +} + +QVariant Config::getConfig(const QString &group, const QString &key, const QVariant &defaultValue) +{ + QMutexLocker lk(&m_mtxLock); + m_settings->beginGroup(group); + QVariant result = m_settings->value(key, defaultValue); + m_settings->endGroup(); + return result; +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/config/config.h b/dde-file-manager-5.5.3/src/dde-desktop/config/config.h new file mode 100644 index 0000000..06d5532 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/config/config.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include +#include +#include +#include "../global/singleton.h" + +class Config: public QObject, public DDEDesktop::Singleton +{ + Q_OBJECT +public: + inline QMutex *mutex() {return &m_mtxLock;} + inline QSettings *settings() {return m_settings;} + QVariant getConfig(const QString &group, const QString &key, const QVariant &defaultValue = QVariant()); + + static const QString groupGeneral; + static const QString keyProfile; + static const QString keySortBy; + static const QString keySortOrder; + static const QString keyAutoAlign; + static const QString keyIconLevel; + static const QString keyQuickHide; + static const QString keyAutoMerge; + static const QString keyWaterMask; + +public slots: + void setConfig(const QString &group, const QString &key, const QVariant &value); + void removeConfig(const QString &group, const QString &key); + void setConfigList(const QString &group, const QStringList &keys, const QVariantList &values); + void removeConfigList(const QString &group, const QStringList &keys); + void sync(); +private: + explicit Config(); + Config(const Config &) = delete; + Config &operator=(const Config &) = delete; + friend class DDEDesktop::Singleton; + + QMutex m_mtxLock; + QSettings *m_settings = nullptr; + QTimer m_syncTimer; +}; diff --git a/dde-file-manager-5.5.3/src/dde-desktop/config/profile.cpp b/dde-file-manager-5.5.3/src/dde-desktop/config/profile.cpp new file mode 100644 index 0000000..12c16b3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/config/profile.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "profile.h" + +class ProfilePrivate +{ +public: + explicit ProfilePrivate(Profile *parent) : q_ptr(parent){} + + Profile *q_ptr; + Q_DECLARE_PUBLIC(Profile) +}; + +Profile::Profile(QObject *parent) : + QObject(parent), d_ptr(new ProfilePrivate(this)) +{ + +} + +Profile::~Profile() +{ + +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/data/applications/dde-computer.desktop b/dde-file-manager-5.5.3/src/dde-desktop/data/applications/dde-computer.desktop new file mode 100644 index 0000000..7a2ff03 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/data/applications/dde-computer.desktop @@ -0,0 +1,169 @@ +[Desktop Entry] +Categories=System; +Comment=Show basic info of the computer. +Exec=gio open computer:/// +GenericName=Computer +Icon=computer +Name=Computer +OnlyShowIn=Deepin; +Terminal=false +Type=Application +X-AppStream-Ignore=true +X-Deepin-AppID=dde-computer + +# Translations: +# Do not manually modify! +Comment[am_ET]=መሰረታዊ መረጃ ስለ ኮምፒዩተር ማሳያ +Comment[ar]=إظهار المعلومات الأساسية للحاسوب +Comment[ast]=Amuesa la información básica del ordenador. +Comment[az]=Kompyuterin baza məlumatlarını göstərmək +Comment[bg]=Покажи основна информация на компютъра. +Comment[bn]=কম্পিউটারটির প্রাথমিক তথ্যগুলি দেখান +Comment[bo]=རྩིས་འཁོར་གྱི་གཞི་རྩའི་ཆ་འཕྲིན་མངོན་སྟོན་བྱེད། +Comment[ca]=Mostra informació bàsica de l'ordinador. +Comment[cs]=Zobrazit základní údaje o počítači. +Comment[da]=Vis grundlæggende info om computeren. +Comment[de]=Grundlegende Informationen über diesen Rechner anzeigen +Comment[el]=Εμφάνιση βασικών πληροφοριών του υπολογιστή. +Comment[es]=Mostrar información básica del equipo. +Comment[fa]=نمایش اطلاعات اولیه رایانه. +Comment[fi]=Näytä tietokoneen perustiedot. +Comment[fr]=Afficher les informations de base de l'ordinateur. +Comment[gl_ES]=Amosar información básica do computador. +Comment[hi_IN]=कंप्यूटर संबंधी सामान्य जानकारी दिखाएँ। +Comment[hr]=Pokaži osnovne podatke o računalu. +Comment[hu]=A számítógép alapvető információinak megjelenítése. +Comment[id]=Tampilkan informasi dasar dari komputer +Comment[it]=Mostra le informazioni base del computer. +Comment[ja]=コンピューターの基本情報を表示します。 +Comment[kab]=Sken-d taɣult tagejdant n uselkim. +Comment[km_KH]=បង្ហាញព័ត៌មានមូលដ្ឋានរបស់កុំព្យូទ័រ។ +Comment[ko]=컴퓨터의 기본 정보 표시 +Comment[lt]=Rodyti pagrindinę kompiuterio informaciją. +Comment[mn]=Компьютерийн үндсэн мэдээлэл харах. +Comment[ms]=Tunjuk maklumat umum komputer. +Comment[nb]=Vis grunnleggende informasjon om datamaskinen: +Comment[ne]=कम्प्युटरको आधारभूत जानकारी देखाउनुहोस्। +Comment[nl]=Toon algemene informatie over deze computer +Comment[pa]=ਕੰਪਿਊਟਰ ਦੀ ਮੁੱਢਲੀ ਜਾਣਕਾਰੀ ਵੇਖਾਓ +Comment[pl]=Wyświetl podstawowe informacje o komputerze. +Comment[pt]=Mostrar informação básica do computador. +Comment[pt_BR]=Exibir informações básicas do computador. +Comment[ro]=Afișează informațiile de bază ale calculatorului. +Comment[ru]=Показать основную информацию о компьютере. +Comment[si]=පරිගණකයේ මූලික තොරතුරු පෙන්වන්න. +Comment[sk]=Zobraziť základné informácie počítača. +Comment[sl]=Pokaži osnovne informacije tega računalnika. +Comment[sq]=Shfaqni të dhëna elementare të kompjuterit. +Comment[sr]=Прикажи основне податке о рачунару. +Comment[sv]=Visa simpel information om datorn. +Comment[ta]=கணினி அடிப்படை தகவல் காட்டு. +Comment[tr]=Bilgisayarın temel bilgilerini göster. +Comment[ug]=كومپيوتېرنىڭ ئاساسلىق ئۇچۇرلىرىنى كۆرسىتىش +Comment[uk]=Показати базову інформаціїю про компʼютер +Comment[zh_CN]=显示计算机的基本信息 +Comment[zh_HK]=顯示計算機的基本訊息 +Comment[zh_TW]=顯示這台電腦的基本資訊。 +GenericName[am_ET]=ኮምፒዩተር +GenericName[ar]=الحاسوب +GenericName[ast]=Ordenador +GenericName[az]=Kompyuter +GenericName[bg]=Компютър +GenericName[bn]=কম্পিউটার +GenericName[bo]=རྩིས་འཁོར། +GenericName[ca]=Ordinador +GenericName[cs]=Počítač +GenericName[da]=Computer +GenericName[de]=Computer +GenericName[el]=Υπολογιστής +GenericName[es]=Equipo +GenericName[fa]=رایانه +GenericName[fi]=Tietokone +GenericName[fr]=Ordinateur +GenericName[gl_ES]=Computador +GenericName[hi_IN]=कंप्यूटर +GenericName[hr]=Računalo +GenericName[hu]=Számítógép +GenericName[id]=Komputer +GenericName[it]=Computer +GenericName[ja]=コンピューター +GenericName[kab]=Aselkim +GenericName[km_KH]=កំុព្យូទ័រ +GenericName[ko]=컴퓨터 +GenericName[lt]=Kompiuteris +GenericName[mn]=Компьютер +GenericName[ms]=Komputer +GenericName[nb]=Datamaskin +GenericName[ne]=कम्प्युटर +GenericName[nl]=Computer +GenericName[pa]=ਕੰਪਿਊਟਰ +GenericName[pl]=Komputer +GenericName[pt]=Computador +GenericName[pt_BR]=Computador +GenericName[ro]=Calculator +GenericName[ru]=Компьютер +GenericName[si]=පරිගණකය +GenericName[sk]=Počítač +GenericName[sl]=Računalnik +GenericName[sq]=Kompjuter +GenericName[sr]=Рачунар +GenericName[sv]=Dator +GenericName[ta]=கணினி +GenericName[tr]=Bilgisayar +GenericName[ug]=كومپيوتېر +GenericName[uk]=Комп'ютер +GenericName[zh_CN]=计算机 +GenericName[zh_HK]=計算機 +GenericName[zh_TW]=電腦 +Name[am_ET]=ኮምፒዩተር +Name[ar]=الحاسوب +Name[ast]=Ordenador +Name[az]=Kompyuter +Name[bg]=Компютър +Name[bn]=কম্পিউটার +Name[bo]=རྩིས་འཁོར། +Name[ca]=Ordinador +Name[cs]=Počítač +Name[da]=Computer +Name[de]=Computer +Name[el]=Υπολογιστής +Name[es]=Equipo +Name[fa]=رایانه +Name[fi]=Tietokone +Name[fr]=Ordinateur +Name[gl_ES]=Computador +Name[hi_IN]=कंप्यूटर +Name[hr]=Računalo +Name[hu]=Számítógép +Name[id]=Komputer +Name[it]=Computer +Name[ja]=コンピューター +Name[kab]=Aselkim +Name[km_KH]=កំុព្យូទ័រ +Name[ko]=컴퓨터 +Name[lt]=Kompiuteris +Name[mn]=Компьютер +Name[ms]=Komputer +Name[nb]=Datamaskin +Name[ne]=कम्प्युटर +Name[nl]=Computer +Name[pa]=ਕੰਪਿਊਟਰ +Name[pl]=Komputer +Name[pt]=Computador +Name[pt_BR]=Computador +Name[ro]=Calculator +Name[ru]=Компьютер +Name[si]=පරිගණකය +Name[sk]=Počítač +Name[sl]=Računalnik +Name[sq]=Kompjuter +Name[sr]=Рачунар +Name[sv]=Dator +Name[ta]=கணினி +Name[tr]=Bilgisayar +Name[ug]=كومپيوتېر +Name[uk]=Комп'ютер +Name[zh_CN]=计算机 +Name[zh_HK]=計算機 +Name[zh_TW]=電腦 + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/data/applications/dde-home.desktop b/dde-file-manager-5.5.3/src/dde-desktop/data/applications/dde-home.desktop new file mode 100644 index 0000000..ed2d14f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/data/applications/dde-home.desktop @@ -0,0 +1,122 @@ +[Desktop Entry] +Categories=System; +Comment=Open home directory +Exec=/usr/bin/dde-file-manager -O -n +GenericName=Home +Icon=user-home +Name=Home +OnlyShowIn=Deepin; +Terminal=false +Type=Application +X-AppStream-Ignore=true +X-Deepin-AppID=dde-file-manager +X-Deepin-Vendor=deepin + +# Translations: +# Do not manually modify! +Comment[ar]=افتح الدليل الرئيسي +Comment[az]=Ev qovluğunu açmaq +Comment[bo]=དཀར་ཆག་གཙོ་བོ་ཁ་འབྱེད། +Comment[ca]=Obre la carpeta de l'usuari +Comment[cs]=Otevřít domovskou složku +Comment[de]=Home-Verzeichnis öffnen +Comment[es]=Abrir carpeta personal +Comment[et]=Ava kodukaust +Comment[fi]=Avaa kotikansio +Comment[fr]=Ouvrir le répertoire personnel +Comment[gl_ES]=Abrir o inicio do directorio +Comment[hr]=Otvori osobni direktorij +Comment[hu]=Saját mappa megnyitása +Comment[it]=Apri la Home +Comment[ja]=ホームディレクトリを開きます +Comment[kab]=Ldi akaram agejdan +Comment[ko]=홈 디렉토리 열기 +Comment[lt]=Atverti namų katalogą +Comment[ms]=Buka direktori rumah +Comment[nl]=Open je persoonlijke map +Comment[pl]=Otwórz katalog domowy +Comment[pt]=Abrir diretório da Pasta Pessoal +Comment[pt_BR]=Abrir a pasta pessoal +Comment[ro]=Deschide directorul acasă +Comment[ru]=Открыть домашний каталог +Comment[sk]=Otvoriť domovský adresár +Comment[sl]=Odpri domačo mapo +Comment[sq]=Hapni drejtorinë shtëpi +Comment[sr]=Отвори лични директоријум +Comment[tr]=Ev dizinini aç +Comment[ug]=باش مۇندەرىجىنى ئېچىش +Comment[uk]=Відкрити домашній каталог +Comment[zh_CN]=打开主目录 +Comment[zh_HK]=打開主目錄 +Comment[zh_TW]=打開主目錄 +GenericName[ar]=المنزل +GenericName[az]=Ev +GenericName[bo]=དཀར་ཆག་གཙོ་བོ། +GenericName[ca]=Carpeta de l'usuari +GenericName[cs]=Domovská složka +GenericName[de]=Home +GenericName[es]=Carpeta personal +GenericName[et]=Kodu +GenericName[fi]=Koti +GenericName[fr]=Accueil +GenericName[gl_ES]=Inicio +GenericName[hr]=Osobna mapa +GenericName[hu]=Saját mappa +GenericName[it]=Home +GenericName[ja]=ホーム +GenericName[kab]=Agejdan +GenericName[ko]=홈 +GenericName[lt]=Namai +GenericName[ms]=Rumah +GenericName[nl]=Persoonlijke map +GenericName[pl]=Katalog domowy +GenericName[pt]=Pasta Pessoal +GenericName[pt_BR]=Pasta Pessoal +GenericName[ro]=Acasă +GenericName[ru]=Домашняя папка +GenericName[sk]=Domov +GenericName[sl]=Dom +GenericName[sq]=Shtëpia +GenericName[sr]=Лично +GenericName[tr]=Ev +GenericName[ug]=باش مۇندەرىجە +GenericName[uk]=Домівка +GenericName[zh_CN]=主目录 +GenericName[zh_HK]=主目錄 +GenericName[zh_TW]=主資料夾 +Name[ar]=المنزل +Name[az]=Ev +Name[bo]=དཀར་ཆག་གཙོ་བོ། +Name[ca]=Carpeta de l'usuari +Name[cs]=Domovská složka +Name[de]=Home +Name[es]=Carpeta personal +Name[et]=Kodu +Name[fi]=Koti +Name[fr]=Accueil +Name[gl_ES]=Inicio +Name[hr]=Osobna mapa +Name[hu]=Saját mappa +Name[it]=Home +Name[ja]=ホーム +Name[kab]=Agejdan +Name[ko]=홈 +Name[lt]=Namai +Name[ms]=Rumah +Name[nl]=Persoonlijke map +Name[pl]=Katalog domowy +Name[pt]=Pasta Pessoal +Name[pt_BR]=Pasta Pessoal +Name[ro]=Acasă +Name[ru]=Домашняя папка +Name[sk]=Domov +Name[sl]=Dom +Name[sq]=Shtëpia +Name[sr]=Лично +Name[tr]=Ev +Name[ug]=باش مۇندەرىجە +Name[uk]=Домівка +Name[zh_CN]=主目录 +Name[zh_HK]=主目錄 +Name[zh_TW]=主資料夾 + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/data/applications/dde-trash.desktop b/dde-file-manager-5.5.3/src/dde-desktop/data/applications/dde-trash.desktop new file mode 100644 index 0000000..ab05b23 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/data/applications/dde-trash.desktop @@ -0,0 +1,165 @@ +[Desktop Entry] +Categories=System; +Comment=Open trash. +Exec=gio open trash:/// +GenericName=Open Trash. +Icon=user-trash +Name=Trash +OnlyShowIn=Deepin; +Terminal=false +Type=Application +X-AppStream-Ignore=true +X-Deepin-AppID=dde-trash + +# Translations: +# Do not manually modify! +Comment[am_ET]=ቆሻሻ መክፈቻ +Comment[ar]=فتح سلة المحذوفات. +Comment[ast]=Abrir la papelera. +Comment[az]=Səbəti açmaq. +Comment[bg]=Отвори кофата. +Comment[bn]=ট্র্যাশ খুলুন +Comment[bo]=སྙིགས་སྣོད་ཁ་ཕྱེ། +Comment[ca]=Obre la paperera. +Comment[cs]=Otevřít koš. +Comment[da]=Åbn papirkurv. +Comment[de]=Papierkorb öffnen. +Comment[el]=Άνοιγμα Κάδου. +Comment[es]=Abrir papelera. +Comment[et]=Ava prügikast. +Comment[fa]=باز کردن زباله دان. +Comment[fi]=Avaa roskakori. +Comment[fr]=Ouvrir la corbeille. +Comment[gl_ES]=Abrir o lixo. +Comment[hr]=Otvori smeće. +Comment[hu]=Kuka megnyitása +Comment[id]=Buka tong sampah. +Comment[it]=Apri cestino. +Comment[ja]=ゴミ箱を開きます。 +Comment[kab]=Ldi taqecwalt +Comment[km_KH]=បើកធុងសំរាម។ +Comment[ko]=휴지통 열기. +Comment[lt]=Atverti šiukšlinę. +Comment[ms]=Buka tong sampah. +Comment[nb]=Åpne søppelkasse. +Comment[ne]=रद्दीटोकरी खोल्नुहोस्। +Comment[nl]=Open de prullenbak +Comment[pa]=ਰੱਦੀ ਨੂੰ ਖੋਲ੍ਹੋ। +Comment[pl]=Otwórz kosz. +Comment[pt]=Abrir o lixo. +Comment[pt_BR]=Abrir lixeira. +Comment[ro]=Deschide coș de gunoi +Comment[ru]=Открыть корзину. +Comment[sk]=Otvoriť kôš. +Comment[sl]=Odpri koš. +Comment[sq]=Hap hedhurinat. +Comment[sr]=Отвори смеће. +Comment[sv]=Öppna papperskorg. +Comment[ta]= குப்பை கோப்புகளை திற +Comment[tr]=Çöp kutusunu aç. +Comment[ug]=ئەخلەت چېلىكىنى ئېچىش +Comment[uk]=Відкрити смітник +Comment[zh_CN]=打开回收站 +Comment[zh_HK]=打開回收站 +Comment[zh_TW]=開啟回收桶。 +GenericName[am_ET]=ቆሻሻ መክፈቻ +GenericName[ar]=فتح سلة المحذوفات +GenericName[ast]=Abrir la papelera. +GenericName[az]=Səbəti açmaq. +GenericName[bg]=Отвори кофата. +GenericName[bn]=ট্র্যাশ খুলুন +GenericName[bo]=སྙིགས་སྣོད་ཁ་ཕྱེ། +GenericName[ca]=Obre la paperera. +GenericName[cs]=Otevřít koš. +GenericName[da]=Åbn papirkurv. +GenericName[de]=Papierkorb öffnen +GenericName[el]=Άνοιγμα Κάδου. +GenericName[es]=Abrir papelera. +GenericName[et]=Ava prügikast. +GenericName[fa]=باز کردن زباله دان +GenericName[fi]=Avaa roskakori. +GenericName[fr]=Ouvrir la corbeille. +GenericName[gl_ES]=Abrir o Lixo. +GenericName[hr]=Otvori smeće. +GenericName[hu]=Kuka megnyitása +GenericName[id]=Buka Tong sampah. +GenericName[it]=Apri Cestino. +GenericName[ja]=ゴミ箱を開きます。 +GenericName[kab]=Ldi taqecwalt +GenericName[km_KH]=បើកធុងសំរាម។ +GenericName[ko]=휴지통 열기. +GenericName[lt]=Atverti šiukšlinę. +GenericName[ms]=Buka Tong Sampah. +GenericName[nb]=Åpne Søppelkasse. +GenericName[ne]=रद्दीटोकरी खोल्नुहोस्। +GenericName[nl]=Prullenbak openen +GenericName[pa]=ਰੱਦੀ ਨੂੰ ਖੋਲ੍ਹੋ +GenericName[pl]=Otwórz kosz. +GenericName[pt]=Abrir o lixo. +GenericName[pt_BR]=Abrir Lixeira. +GenericName[ro]=Deschide Coș de gunoi +GenericName[ru]=Открыть Корзину. +GenericName[sk]=Otvoriť Kôš. +GenericName[sl]=Odpri koš. +GenericName[sq]=Hap Hedhurinat. +GenericName[sr]=Отвори смеће. +GenericName[sv]=Öppna Papperskorg. +GenericName[ta]= குப்பை கோப்புகளை திற +GenericName[tr]=Çöp Kutusunu Aç. +GenericName[ug]=ئەخلەت چېلىكىنى ئېچىش +GenericName[uk]=Відкрити смітник +GenericName[zh_CN]=打开回收站 +GenericName[zh_HK]=打開回收站 +GenericName[zh_TW]=開啟回收桶。 +Name[am_ET]=ቆሻሻ +Name[ar]=المحذوفات +Name[ast]=Papelera +Name[az]=Səbət +Name[bg]=Кошче +Name[bn]=ট্র্যাশ +Name[bo]=སྙིགས་སྣོད། +Name[ca]=Paperera +Name[cs]=Koš +Name[da]=Papirkurv +Name[de]=Papierkorb +Name[el]=Κάδος +Name[eo]=Korbeto +Name[es]=Papelera +Name[et]=Prügikast +Name[fa]=زباله دان +Name[fi]=Roskakori +Name[fr]=Corbeille +Name[gl_ES]=Lixo +Name[hr]=Smeće +Name[hu]=Kuka +Name[id]=Tong sampah +Name[it]=Cestino +Name[ja]=ゴミ箱 +Name[kab]=Taqecwalt +Name[km_KH]=ធុងសំរាម +Name[ko]=휴지통 +Name[lt]=Šiukšlinė +Name[ml]=ചവറ്റുകൊട്ട +Name[ms]=Tong Sampah +Name[nb]=Søppe +Name[ne]=रद्दीटोकरी +Name[nl]=Prullenbak +Name[pa]=ਰੱਦੀ +Name[pl]=Kosz +Name[pt]=Lixo +Name[pt_BR]=Lixeira +Name[ro]=Coș de gunoi +Name[ru]=Корзина +Name[sk]=Kôš +Name[sl]=Koš +Name[sq]=Hedhurina +Name[sr]=Смеће +Name[sv]=Papperskorg +Name[ta]=குப்பை கோப்பு +Name[tr]=Çöp Kutusu +Name[ug]=ئەخلەت +Name[uk]=Смітник +Name[zh_CN]=回收站 +Name[zh_HK]=回收站 +Name[zh_TW]=回收桶 + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/data/com.deepin.dde.desktop.service b/dde-file-manager-5.5.3/src/dde-desktop/data/com.deepin.dde.desktop.service new file mode 100644 index 0000000..b03c21c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/data/com.deepin.dde.desktop.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=com.deepin.dde.desktop +Exec=/usr/bin/dde-desktop diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbus.pri b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbus.pri new file mode 100644 index 0000000..7de6a4c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbus.pri @@ -0,0 +1,4 @@ +include($$PWD/filedialog/filedialog.pri) +include($$PWD/filemanager1/filemanager1.pri) + +QT += dbus diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusdisplay.cpp b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusdisplay.cpp new file mode 100644 index 0000000..5d48bbc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusdisplay.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + + +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -p DBusDisplay -c DBusDisplay com.deepin.daemon.Display.xml + * + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusdisplay.h" + +/* + * Implementation of interface class DBusDisplay + */ + +DBusDisplay::DBusDisplay(QObject *parent) + : QDBusAbstractInterface(staticServiceName(), staticObjectPath(), staticInterfaceName(), QDBusConnection::sessionBus(), parent) +{ + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + + QDBusConnection::sessionBus().connect(this->service(), this->path(), "org.freedesktop.DBus.Properties", "PropertiesChanged","sa{sv}as", this, SLOT(__propertyChanged__(QDBusMessage))); +} + +DBusDisplay::~DBusDisplay() +{ + QDBusConnection::sessionBus().disconnect(service(), path(), "org.freedesktop.DBus.Properties", "PropertiesChanged", "sa{sv}as", this, SLOT(propertyChanged(QDBusMessage))); +} + + +QDBusArgument &operator<<(QDBusArgument &argument, const DisplayRect &rect) +{ + argument.beginStructure(); + argument << rect.x << rect.y << rect.width << rect.height; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, DisplayRect &rect) +{ + argument.beginStructure(); + argument >> rect.x >> rect.y >> rect.width >> rect.height; + argument.endStructure(); + return argument; +} + +QDebug operator<<(QDebug deg, const DisplayRect &rect) +{ + qDebug() << "x:" << rect.x << "y:" << rect.y << "width:" << rect.width << "height:" << rect.height; + + return deg; +} + + +DBusAppearance::DBusAppearance(QObject *parent) + : QDBusAbstractInterface(staticServiceName(), staticObjectPath(), staticInterfaceName(), QDBusConnection::sessionBus(), parent) +{ + QDBusConnection::sessionBus().connect(this->service(), this->path(), "org.freedesktop.DBus.Properties", "PropertiesChanged","sa{sv}as", this, SLOT(__propertyChanged__(QDBusMessage))); +} + +DBusAppearance::~DBusAppearance() +{ + QDBusConnection::sessionBus().disconnect(service(), path(), "org.freedesktop.DBus.Properties", "PropertiesChanged", "sa{sv}as", this, SLOT(propertyChanged(QDBusMessage))); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusdisplay.h b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusdisplay.h new file mode 100644 index 0000000..4602761 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusdisplay.h @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -p displayinterface -c DisplayInterface com.deepin.daemon.Display.xml + * + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef DBUSDISPLAY_H +#define DBUSDISPLAY_H + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef QMap BrightnessMap; + +Q_DECLARE_METATYPE(BrightnessMap) + +struct DisplayRect { + qint16 x; + qint16 y; + quint16 width; + quint16 height; + + operator QRect() const + { + return QRect(x, y, width, height); + } +}; + +Q_DECLARE_METATYPE(DisplayRect) + +QDBusArgument &operator<<(QDBusArgument &argument, const DisplayRect &rect); +const QDBusArgument &operator>>(const QDBusArgument &argument, DisplayRect &rect); +QDebug operator<<(QDebug deg, const DisplayRect &rect); + +/* + * Proxy class for interface com.deepin.daemon.Display + */ +class DBusDisplay: public QDBusAbstractInterface +{ + Q_OBJECT + + Q_SLOT void __propertyChanged__(const QDBusMessage &msg) + { + QList arguments = msg.arguments(); + if (3 != arguments.count()) + return; + QString interfaceName = msg.arguments().at(0).toString(); + if (interfaceName != "com.deepin.daemon.Display") + return; + QVariantMap changedProps = qdbus_cast(arguments.at(1).value()); + QStringList keys = changedProps.keys(); + foreach (const QString &prop, keys) { + const QMetaObject *self = metaObject(); + for (int i = self->propertyOffset(); i < self->propertyCount(); ++i) { + QMetaProperty p = self->property(i); + if (p.name() == prop) { + Q_EMIT p.notifySignal().invoke(this); + } + } + } + } +public: + static inline const char *staticInterfaceName() + { + return "com.deepin.daemon.Display"; + } + static inline const char *staticServiceName() + { + return "com.deepin.daemon.Display"; + } + static inline const char *staticObjectPath() + { + return "/com/deepin/daemon/Display"; + } + +public: + explicit DBusDisplay(QObject *parent = nullptr); + + ~DBusDisplay(); + + Q_PROPERTY(BrightnessMap Brightness READ brightness NOTIFY BrightnessChanged) + inline BrightnessMap brightness() const + { + return qvariant_cast< BrightnessMap >(property("Brightness")); + } + + Q_PROPERTY(QDBusObjectPath BuiltinOutput READ builtinOutput NOTIFY BuiltinOutputChanged) + inline QDBusObjectPath builtinOutput() const + { + return qvariant_cast< QDBusObjectPath >(property("BuiltinOutput")); + } + + Q_PROPERTY(uchar DisplayMode READ displayMode NOTIFY DisplayModeChanged) + inline short displayMode() const + { + return qvariant_cast< uchar >(property("DisplayMode")); + } + + Q_PROPERTY(bool HasChanged READ hasChanged NOTIFY HasChangedChanged) + inline bool hasChanged() const + { + return qvariant_cast< bool >(property("HasChanged")); + } + + Q_PROPERTY(QList Monitors READ monitors NOTIFY MonitorsChanged) + inline QList monitors() const + { + return qvariant_cast< QList >(property("Monitors")); + } + + Q_PROPERTY(QString Primary READ primary NOTIFY PrimaryChanged) + inline QString primary() const + { + return qvariant_cast< QString >(property("Primary")); + } + + Q_PROPERTY(DisplayRect PrimaryRect READ primaryRect NOTIFY PrimaryRectChanged) + inline DisplayRect primaryRect() const + { + return qvariant_cast< DisplayRect >(property("PrimaryRect")); + } + + Q_PROPERTY(ushort ScreenHeight READ screenHeight NOTIFY ScreenHeightChanged) + inline ushort screenHeight() const + { + return qvariant_cast< ushort >(property("ScreenHeight")); + } + + Q_PROPERTY(ushort ScreenWidth READ screenWidth NOTIFY ScreenWidthChanged) + inline ushort screenWidth() const + { + return qvariant_cast< ushort >(property("ScreenWidth")); + } + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> Apply() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("Apply"), argumentList); + } + + inline QDBusPendingReply<> AssociateTouchScreen(const QString &in0, const QString &in1) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1); + return asyncCallWithArgumentList(QStringLiteral("AssociateTouchScreen"), argumentList); + } + + inline QDBusPendingReply<> ChangeBrightness(const QString &in0, double in1) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1); + return asyncCallWithArgumentList(QStringLiteral("ChangeBrightness"), argumentList); + } + + inline QDBusPendingReply ListOutputNames() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("ListOutputNames"), argumentList); + } + + inline QDBusPendingReply<> JoinMonitor(const QString &in0, const QString &in1) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1); + return asyncCallWithArgumentList(QStringLiteral("JoinMonitor"), argumentList); + } + + inline QDBusPendingReply QueryCurrentPlanName() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("QueryCurrentPlanName"), argumentList); + } + + inline QDBusPendingReply QueryOutputFeature(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("QueryOutputFeature"), argumentList); + } + + inline QDBusPendingReply<> Reset() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("Reset"), argumentList); + } + + inline QDBusPendingReply<> ResetBrightness(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("ResetBrightness"), argumentList); + } + + inline QDBusPendingReply<> ResetChanges() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("ResetChanges"), argumentList); + } + + inline QDBusPendingReply<> SaveChanges() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("SaveChanges"), argumentList); + } + + inline QDBusPendingReply<> SetBrightness(const QString &in0, double in1) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1); + return asyncCallWithArgumentList(QStringLiteral("SetBrightness"), argumentList); + } + + inline QDBusPendingReply<> SetPrimary(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("SetPrimary"), argumentList); + } + + inline QDBusPendingReply<> SplitMonitor(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("SplitMonitor"), argumentList); + } + + inline QDBusPendingReply<> SwitchMode(short in0, const QString &in1) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1); + return asyncCallWithArgumentList(QStringLiteral("SwitchMode"), argumentList); + } + + inline QDBusPendingReply GetRealDisplayMode() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("GetRealDisplayMode"), argumentList); + } + +Q_SIGNALS: // SIGNALS + //void PrimaryChanged(const QRect &in0); +// begin property changed signals + void BrightnessChanged(); + void BuiltinOutputChanged(); + void DisplayModeChanged(); + void HasChangedChanged(); + void MonitorsChanged(); + void PrimaryChanged(); + void PrimaryRectChanged(); + void ScreenHeightChanged(); + void ScreenWidthChanged(); +}; + +//system("qdbus --literal com.deepin.SessionManager /com/deepin/XSettings com.deepin.XSettings.GetScaleFactor > /tmp/123"); + +class DBusAppearance: public QDBusAbstractInterface +{ + Q_OBJECT + + Q_SLOT void __propertyChanged__(const QDBusMessage &msg) + { + QList arguments = msg.arguments(); + if (3 != arguments.count()) + return; + QString interfaceName = msg.arguments().at(0).toString(); +// if (interfaceName != "com.deepin.daemon.Appearance") + if (interfaceName != "com.deepin.XSettings") + return; + QVariantMap changedProps = qdbus_cast(arguments.at(1).value()); + QStringList keys = changedProps.keys(); + foreach (const QString &prop, keys) { + const QMetaObject *self = metaObject(); + for (int i = self->propertyOffset(); i < self->propertyCount(); ++i) { + QMetaProperty p = self->property(i); + if (p.name() == prop) { + Q_EMIT p.notifySignal().invoke(this); + } + } + } + } +public: + explicit DBusAppearance(QObject *parent = nullptr); + + ~DBusAppearance(); +public: + static inline const char *staticInterfaceName() + { return "com.deepin.XSettings"; } + static inline const char *staticServiceName() + { return "com.deepin.SessionManager"; } + static inline const char *staticObjectPath() + { return "/com/deepin/XSettings"; } +public Q_SLOTS: // METHODS + inline QDBusPendingReply GetScaleFactor() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("GetScaleFactor"), argumentList); + } +}; +#endif diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusdock.cpp b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusdock.cpp new file mode 100644 index 0000000..d01b3ab --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusdock.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + + +#include "dbusdock.h" + +/* + * Implementation of interface class DBusDock + */ +DBusDock::DBusDock(QObject *parent) + : QDBusAbstractInterface(staticServiceName(), staticObjectPath(), staticInterfaceName(), QDBusConnection::sessionBus(), parent) +{ + qDBusRegisterMetaType(); + QDBusConnection::sessionBus().connect(this->service(), this->path(), + "org.freedesktop.DBus.Properties", "PropertiesChanged", + this, SLOT(__propertyChanged__(QDBusMessage))); +} + +DBusDock::~DBusDock() +{ + QDBusConnection::sessionBus().disconnect(service(), path(), "org.freedesktop.DBus.Properties" + , "PropertiesChanged", this, SLOT(__propertyChanged__(QDBusMessage))); +} + +QDBusArgument &operator<<(QDBusArgument &argument, const DockRect &rect) +{ + argument.beginStructure(); + argument << rect.x << rect.y << rect.width << rect.height; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, DockRect &rect) +{ + argument.beginStructure(); + argument >> rect.x >> rect.y >> rect.width >> rect.height; + argument.endStructure(); + return argument; +} + +QDebug operator<<(QDebug deg, const DockRect &rect) +{ + qDebug() << "x:" << rect.x << "y:" << rect.y << "width:" << rect.width << "height:" << rect.height; + + return deg; +} + +DockInfo *DockInfo::ins() +{ + static DockInfo ins; + return &ins; +} + +DBusDock *DockInfo::dock() const +{ + return m_dock; +} + +DockInfo::DockInfo(QObject *parent) + : QObject (parent) +{ + m_dock = new DBusDock(this); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusdock.h b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusdock.h new file mode 100644 index 0000000..c10dd01 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusdock.h @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c DBusDock -p dbusdock com.deepin.dde.daemon.Dock.xml + * + * qdbusxml2cpp is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef DBUSDOCK_H_1465782143 +#define DBUSDOCK_H_1465782143 + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.dde.daemon.Dock + */ +struct DockRect{ + qint32 x; + qint32 y; + quint32 width; + quint32 height; + + operator QRect() const + { + return QRect(x, y, static_cast(width), static_cast(height)); + } +}; +Q_DECLARE_METATYPE(DockRect) + +QDBusArgument &operator<<(QDBusArgument &argument, const DockRect &rect); +const QDBusArgument &operator>>(const QDBusArgument &argument, DockRect &rect); +QDebug operator<<(QDebug deg, const DockRect &rect); + +class DBusDock: public QDBusAbstractInterface +{ + Q_OBJECT + +private slots: + void __propertyChanged__(const QDBusMessage& msg) + { + QList arguments = msg.arguments(); + if (3 != arguments.count()) + return; + QString interfaceName = msg.arguments().at(0).toString(); + if (interfaceName !="com.deepin.dde.daemon.Dock") + return; + QVariantMap changedProps = qdbus_cast(arguments.at(1).value()); + foreach(const QString &prop, changedProps.keys()) { + const QMetaObject* self = metaObject(); + for (int i=self->propertyOffset(); i < self->propertyCount(); ++i) { + QMetaProperty p = self->property(i); + if (p.name() == prop) { + Q_EMIT p.notifySignal().invoke(this); + } + } + } + } +public: + static inline const char *staticInterfaceName() + { return "com.deepin.dde.daemon.Dock"; } + static inline const char *staticServiceName() + { return "com.deepin.dde.daemon.Dock";} + static inline const char *staticObjectPath() + { return "/com/deepin/dde/daemon/Dock";} + +public: + explicit DBusDock(QObject *parent = nullptr); + + ~DBusDock(); + + Q_PROPERTY(uint ActiveWindow READ activeWindow NOTIFY ActiveWindowChanged) + inline uint activeWindow() const + { return qvariant_cast< uint >(property("ActiveWindow")); } + + Q_PROPERTY(QList Entries READ entries NOTIFY EntriesChanged) + inline QList entries() const + { return qvariant_cast< QList >(property("Entries")); } + + Q_PROPERTY(int DisplayMode READ displayMode WRITE setDisplayMode NOTIFY DisplayModeChanged) + inline int displayMode() const + { return int(qvariant_cast< int >(property("DisplayMode"))); } + inline void setDisplayMode(int value) + { setProperty("DisplayMode", QVariant::fromValue(int(value))); } + + Q_PROPERTY(int HideMode READ hideMode WRITE setHideMode NOTIFY HideModeChanged) + inline int hideMode() const + { return qvariant_cast< int >(property("HideMode")); } + inline void setHideMode(int value) + { setProperty("HideMode", QVariant::fromValue(value)); } + + Q_PROPERTY(int HideState READ hideState NOTIFY HideStateChanged) + inline int hideState() const + { return int(qvariant_cast< int >(property("HideState"))); } + + Q_PROPERTY(int Position READ position WRITE setPosition NOTIFY PositionChanged) + inline int position() const + { return int(qvariant_cast< int >(property("Position"))); } + inline void setPosition(int value) + { setProperty("Position", QVariant::fromValue(int(value))); } + + Q_PROPERTY(quint32 IconSize READ iconSize WRITE setIconSize NOTIFY IconSizeChanged) + inline quint32 iconSize() const + { return qvariant_cast< quint32 >(property("IconSize")); } + inline void setIconSize(quint32 value) + { setProperty("IconSize", QVariant::fromValue(value)); } + + Q_PROPERTY(quint32 ShowTimeout READ showTimeout NOTIFY ShowTimeoutChanged) + inline quint32 showTimeout() const + { return qvariant_cast< quint32 >(property("ShowTimeout")); } + + Q_PROPERTY(DockRect FrontendWindowRect READ frontendWindowRect NOTIFY FrontendWindowRectChanged) + inline DockRect frontendWindowRect() const + { return qvariant_cast< DockRect >(property("FrontendWindowRect")); } + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> ActivateWindow(uint in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("ActivateWindow"), argumentList); + } + + inline QDBusPendingReply<> CloseWindow(uint in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("CloseWindow"), argumentList); + } + + inline QDBusPendingReply GetEntryIDs() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("GetEntryIDs"), argumentList); + } + + inline QDBusPendingReply<> MoveEntry(const int oldIndex, const int newIndex) + { + QList args; + args << oldIndex << newIndex; + + return asyncCallWithArgumentList(QStringLiteral("MoveEntry"), args); + } + + inline QDBusPendingReply RequestDock(const QString &appDesktop, const int index = -1) + { + QList args; + args << appDesktop << index; + + return asyncCallWithArgumentList(QStringLiteral("RequestDock"), args); + } + + inline QDBusPendingReply IsDocked(const QString &appDesktop) + { + QList args; + args << appDesktop; + + return asyncCallWithArgumentList(QStringLiteral("IsDocked"), args); + } + + inline QDBusPendingReply IsOnDock(const QString &appDesktop) + { + QList args; + args << appDesktop; + + return asyncCallWithArgumentList(QStringLiteral("IsOnDock"), args); + } + + inline QDBusPendingReply RequestUndock(const QString &appDesktop) + { + QList args; + args << appDesktop; + + return asyncCallWithArgumentList(QStringLiteral("RequestUndock"), args); + } + + inline QDBusPendingReply<> SetFrontendWindowRect(const int x, const int y, const quint32 width, const quint32 height) + { + QList argumentList; + argumentList << QVariant::fromValue(x) << QVariant::fromValue(y) << QVariant::fromValue(width) << QVariant::fromValue(height); + return asyncCallWithArgumentList(QStringLiteral("SetFrontendWindowRect"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void EntryAdded(const QDBusObjectPath &entryPath, const int index); + void EntryRemoved(const QString &entryId); + void ServiceRestarted(); + // begin property changed signals + void ActiveWindowChanged(); + void DisplayModeChanged(); + void EntriesChanged(); + void HideModeChanged(); + void HideStateChanged(); + void PositionChanged(); + void IconSizeChanged(); + void ShowTimeoutChanged(); + void FrontendWindowRectChanged(); +}; + +#define DockInfoIns DockInfo::ins()->dock() +class DockInfo : public QObject +{ + Q_OBJECT +public: + static DockInfo *ins(); + DBusDock *dock() const; +private: + explicit DockInfo(QObject *parent = nullptr); + DBusDock *m_dock = nullptr; +}; + +namespace com { + namespace deepin { + namespace dde { + namespace daemon { + typedef ::DBusDock Dock; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusmonitor.cpp b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusmonitor.cpp new file mode 100644 index 0000000..77bf4cf --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusmonitor.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#include "dbusmonitor.h" + +DBusMonitor::DBusMonitor(const QString &objectPath,QObject *parent) + : QDBusAbstractInterface(staticServiceName(), objectPath, staticInterfaceName(), QDBusConnection::sessionBus(), parent) +{ + QDBusConnection::sessionBus().connect(this->service(), this->path(), "org.freedesktop.DBus.Properties", "PropertiesChanged","sa{sv}as", this, SLOT(__propertyChanged__(QDBusMessage))); +} + +DBusMonitor::~DBusMonitor() +{ + QDBusConnection::sessionBus().disconnect( + service(), path(), "org.freedesktop.DBus.Properties", + "PropertiesChanged", "sa{sv}as", this, SLOT(propertyChanged(QDBusMessage))); +} + +QRect DBusMonitor::rect() const +{ + return QRect(x(),y(),width(),height()); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusmonitor.h b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusmonitor.h new file mode 100644 index 0000000..d9a93e4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/dbusmonitor.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#ifndef DBUSMONITOR_H +#define DBUSMONITOR_H + +#include +#include + +class DBusMonitor : public QDBusAbstractInterface +{ + Q_OBJECT + Q_SLOT void __propertyChanged__(const QDBusMessage& msg) + { + QList arguments = msg.arguments(); + if (3 != arguments.count()) + return; + QString interfaceName = msg.arguments().at(0).toString(); + if (interfaceName !="com.deepin.daemon.Display.Monitor") + return; + QVariantMap changedProps = qdbus_cast(arguments.at(1).value()); + QStringList keys = changedProps.keys(); + foreach(const QString &prop, keys) { + const QMetaObject* self = metaObject(); + for (int i=self->propertyOffset(); i < self->propertyCount(); ++i) { + QMetaProperty p = self->property(i); + if (p.name() == prop) { + Q_EMIT p.notifySignal().invoke(this); + } + } + } + } +public: + static inline const char *staticServiceName() + { return "com.deepin.daemon.Display"; } + static inline const char *staticInterfaceName() + { return "com.deepin.daemon.Display.Monitor"; } +public: + DBusMonitor(const QString &objectPath,QObject *parent = nullptr); + ~DBusMonitor(); + + Q_PROPERTY(QString Name READ name) + inline QString name() const + { return qvariant_cast< QString >(property("Name")); } + + Q_PROPERTY(qint16 X READ x NOTIFY monitorRectChanged) + inline qint16 x() const + { return qvariant_cast< qint16 >(property("X")); } + + Q_PROPERTY(qint16 Y READ y NOTIFY monitorRectChanged) + inline qint16 y() const + { return qvariant_cast< qint16 >(property("Y") ); } + + Q_PROPERTY(quint16 Width READ width NOTIFY monitorRectChanged) + inline quint16 width() const + { return qvariant_cast< quint16 >(property("Width")); } + + Q_PROPERTY(quint16 Height READ height NOTIFY monitorRectChanged) + inline quint16 height() const + { return qvariant_cast< quint16 >(property("Height")); } + + Q_PROPERTY(bool Enabled READ enabled NOTIFY monitorEnabledChanged) + inline bool enabled() const + { return qvariant_cast< bool >(property("Enabled")); } +signals: + void monitorRectChanged(); + void monitorEnabledChanged(); +public: + QRect rect() const; +}; + +#endif // DBUSMONITOR_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialog.service b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialog.service new file mode 100644 index 0000000..e05dc6b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialog.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=com.deepin.filemanager.filedialog +Exec=/usr/bin/dde-desktop --file-dialog-only diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialog.xml b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialog.xml new file mode 100644 index 0000000..4b198ff --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialog.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialogmanager.xml b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialogmanager.xml new file mode 100644 index 0000000..47928b1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/com.deepin.filemanager.filedialogmanager.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/dbusfiledialoghandle.cpp b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/dbusfiledialoghandle.cpp new file mode 100644 index 0000000..c2b224d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/dbusfiledialoghandle.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "dbusfiledialoghandle.h" + +#include +#include + +#include + +DBusFileDialogHandle::DBusFileDialogHandle(QWidget *parent) + : DFileDialogHandle(parent) +{ + widget()->setAttribute(Qt::WA_NativeWindow); + + QWindow *window = widget()->windowHandle(); + + if (window) + connect(window, &QWindow::activeChanged, this, &DBusFileDialogHandle::windowActiveChanged); + + connect(&m_heartbeatTimer, &QTimer::timeout, this, &QObject::deleteLater); + connect(widget(), &QWidget::destroyed, this, &QObject::deleteLater); + connect(this, &DBusFileDialogHandle::currentUrlChanged, this, &DBusFileDialogHandle::directoryChanged); + connect(this, &DBusFileDialogHandle::currentUrlChanged, this, &DBusFileDialogHandle::directoryUrlChanged); + + m_heartbeatTimer.setInterval(30 * 1000); + m_heartbeatTimer.start(); +} + +DBusFileDialogHandle::~DBusFileDialogHandle() +{ + if (widget()) + widget()->close(); +} + +QString DBusFileDialogHandle::directory() const +{ + return DFileDialogHandle::directory().absolutePath(); +} + +void DBusFileDialogHandle::setDirectoryUrl(const QString &directory) +{ + QUrl dir(directory); + if (dir.scheme().isEmpty()) { + dir = QUrl::fromLocalFile(directory); + } + DFileDialogHandle::setDirectoryUrl(dir); +} + +QString DBusFileDialogHandle::directoryUrl() const +{ + return DFileDialogHandle::directoryUrl().toString(); +} + +void DBusFileDialogHandle::selectUrl(const QString &url) +{ + DFileDialogHandle::selectUrl(QUrl(url)); +} + +QStringList DBusFileDialogHandle::selectedUrls() const +{ + QStringList list; + + for (const QUrl &url : DFileDialogHandle::selectedUrls()) + list << url.toString(); + + return list; +} + +int DBusFileDialogHandle::filter() const +{ + return DFileDialogHandle::filter(); +} + +void DBusFileDialogHandle::setFilter(int filters) +{ + DFileDialogHandle::setFilter(static_cast(filters)); +} + +void DBusFileDialogHandle::setViewMode(int mode) +{ + DFileDialogHandle::setViewMode(static_cast(mode)); +} + +int DBusFileDialogHandle::viewMode() const +{ + return DFileDialogHandle::viewMode(); +} + +void DBusFileDialogHandle::setFileMode(int mode) +{ + DFileDialogHandle::setFileMode(static_cast(mode)); +} + +void DBusFileDialogHandle::setAcceptMode(int mode) +{ + DFileDialogHandle::setAcceptMode(static_cast(mode)); +} + +int DBusFileDialogHandle::acceptMode() const +{ + return DFileDialogHandle::acceptMode(); +} + +void DBusFileDialogHandle::setLabelText(int label, const QString &text) +{ + DFileDialogHandle::setLabelText(static_cast(label), text); +} + +QString DBusFileDialogHandle::labelText(int label) const +{ + return DFileDialogHandle::labelText(static_cast(label)); +} + +void DBusFileDialogHandle::setOptions(int options) +{ + DFileDialogHandle::setOptions(static_cast(options)); +} + +void DBusFileDialogHandle::setOption(int option, bool on) +{ + DFileDialogHandle::setOption(static_cast(option), on); +} + +int DBusFileDialogHandle::options() const +{ + return static_cast(DFileDialogHandle::options()); +} + +bool DBusFileDialogHandle::testOption(int option) const +{ + return DFileDialogHandle::testOption(static_cast(option)); +} + +WId DBusFileDialogHandle::winId() const +{ + return widget()->winId(); +} + +void DBusFileDialogHandle::setWindowTitle(const QString &title) +{ + widget()->setWindowTitle(title); +} + +bool DBusFileDialogHandle::windowActive() const +{ + return widget()->isActiveWindow(); +} + +void DBusFileDialogHandle::activateWindow() +{ + widget()->activateWindow(); +} + +int DBusFileDialogHandle::heartbeatInterval() const +{ + return m_heartbeatTimer.interval(); +} + +void DBusFileDialogHandle::makeHeartbeat() +{ + m_heartbeatTimer.start(); +} + +quint32 DBusFileDialogHandle::windowFlags() const +{ + return widget()->windowFlags(); +} + +void DBusFileDialogHandle::setHeartbeatInterval(int heartbeatInterval) +{ + m_heartbeatTimer.setInterval(heartbeatInterval); +} + +void DBusFileDialogHandle::setWindowFlags(quint32 windowFlags) +{ + widget()->setWindowFlags(static_cast(windowFlags)); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/dbusfiledialoghandle.h b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/dbusfiledialoghandle.h new file mode 100644 index 0000000..cf6382a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/dbusfiledialoghandle.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#ifndef DBUSFILEDIALOGHANDLE_H +#define DBUSFILEDIALOGHANDLE_H + +#include "dfiledialoghandle.h" + +#include + +class DBusFileDialogHandle : public DFileDialogHandle +{ + Q_OBJECT + + Q_PROPERTY(QString directory READ directory WRITE setDirectory NOTIFY directoryChanged) + Q_PROPERTY(QString directoryUrl READ directoryUrl WRITE setDirectoryUrl NOTIFY directoryUrlChanged) + Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters) + Q_PROPERTY(int filter READ filter WRITE setFilter) + Q_PROPERTY(int viewMode READ viewMode WRITE setViewMode) + Q_PROPERTY(int acceptMode READ acceptMode WRITE setAcceptMode) + Q_PROPERTY(bool windowActive READ windowActive NOTIFY windowActiveChanged) + Q_PROPERTY(int heartbeatInterval READ heartbeatInterval WRITE setHeartbeatInterval) + Q_PROPERTY(quint32 windowFlags READ windowFlags WRITE setWindowFlags) + Q_PROPERTY(bool hideOnAccept READ hideOnAccept WRITE setHideOnAccept) + +public: + explicit DBusFileDialogHandle(QWidget *parent = nullptr); + virtual ~DBusFileDialogHandle(); + + QString directory() const; + + void setDirectoryUrl(const QString & directory); + QString directoryUrl() const; + + void selectUrl(const QString &url); + QStringList selectedUrls() const; + + int filter() const; + void setFilter(int filters); + + void setViewMode(int mode); + int viewMode() const; + + void setFileMode(int mode); + + void setAcceptMode(int mode); + int acceptMode() const; + + void setLabelText(int label, const QString &text); + QString labelText(int label) const; + + void setOptions(int options); + void setOption(int option, bool on = true); + int options() const; + bool testOption(int option) const; + + WId winId() const; + void setWindowTitle(const QString &title); + bool windowActive() const; + + void activateWindow(); + + int heartbeatInterval() const; + void makeHeartbeat(); + + quint32 windowFlags() const; + +public slots: + void setHeartbeatInterval(int heartbeatInterval); + void setWindowFlags(quint32 windowFlags); + +signals: + void windowActiveChanged(); + void directoryChanged(); + void directoryUrlChanged(); + +private: + QTimer m_heartbeatTimer; +}; + +#endif // DBUSFILEDIALOGHANDLE_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/dbusfiledialogmanager.cpp b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/dbusfiledialogmanager.cpp new file mode 100644 index 0000000..51dcc06 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/dbusfiledialogmanager.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "dbusfiledialogmanager.h" +#include "dbusfiledialoghandle.h" +#include "dfmstandardpaths.h" +#include "filedialog_adaptor.h" +#include "app/define.h" +#include "singleton.h" +#include "interfaces/dfmstandardpaths.h" +#include "dfilewatcher.h" +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "views/windowmanager.h" +#include "dfileservices.h" +#include "bluetooth/bluetoothtransdialog.h" + +#include + +DFM_USE_NAMESPACE + +DBusFileDialogManager::DBusFileDialogManager(QObject *parent) + : QObject(parent) +{ + +} + +QDBusObjectPath DBusFileDialogManager::createDialog(QString key) +{ + if (key.isEmpty()) + key = QUuid::createUuid().toRfc4122().toHex(); + + g_isFileDialogMode = true; + + if (!initJobDone) { + DFMGlobal::initGvfsMountManager(); + DFMGlobal::initDeviceListener(); + + /*init searchHistoryManager */ + DFMGlobal::initSearchHistoryManager(); + + /*init bookmarkManager */ + DFMGlobal::initBookmarkManager(); + + /*init fileMenuManager */ + DFMGlobal::initFileMenuManager(); + + /*init fileSignalManger */ + DFMGlobal::initFileSiganlManager(); + + /*init appController */ + DFMGlobal::initAppcontroller(); + + /*init fileService */ + DFMGlobal::initFileService(); + + /*init systemPathMnager */ + DFMGlobal::initSystemPathManager(); + + /*init mimeTypeDisplayManager */ + DFMGlobal::initMimeTypeDisplayManager(); + + /*init networkManager */ + DFMGlobal::initNetworkManager(); + + /*init secretManger */ + DFMGlobal::initSecretManager(); + + /*init userShareManager */ + DFMGlobal::initUserShareManager(); + + /*init initDialogManager */ + DFMGlobal::initDialogManager(); + + /*init controllers for different scheme*/ + fileService->initHandlersByCreators(); + + WindowManager::instance(); + + initJobDone = true; + } + + DBusFileDialogHandle *handle = new DBusFileDialogHandle(); + Q_UNUSED(new FiledialogAdaptor(handle)); + + const QDBusObjectPath path("/com/deepin/filemanager/filedialog/" + key); + + if (m_dialogObjectMap.contains(path)) { + return path; + } + + if (!QDBusConnection::sessionBus().registerObject(path.path(), handle)) { + qWarning("Cannot register to the D-Bus object.\n"); + handle->deleteLater(); + + return QDBusObjectPath(); + } + + m_dialogObjectMap[path] = handle; + connect(handle, &DBusFileDialogHandle::destroyed, this, &DBusFileDialogManager::onDialogDestroy); + + return path; +} + +void DBusFileDialogManager::destroyDialog(const QDBusObjectPath &path) +{ + QObject *object = m_dialogObjectMap.value(path); + + if (object) + object->deleteLater(); +} + +QList DBusFileDialogManager::dialogs() const +{ + return m_dialogObjectMap.keys(); +} + +QString DBusFileDialogManager::errorString() const +{ + return m_errorString; +} + +bool DBusFileDialogManager::isUseFileChooserDialog() const +{ + return DFMApplication::instance()->genericAttribute(DFMApplication::GA_OverrideFileChooserDialog).toBool(); +} + +bool DBusFileDialogManager::canUseFileChooserDialog(const QString &group, const QString &executableFileName) const +{ + const QString &group_name = QStringLiteral("DBusFileDialog"); + const QVariantMap &black_map = DFMApplication::appObtuselySetting()->value(group_name, "disable").toMap(); + + return !black_map.value(group).toStringList().contains(executableFileName); +} + +QStringList DBusFileDialogManager::globPatternsForMime(const QString &mimeType) const +{ + QMimeDatabase db; + QMimeType mime(db.mimeTypeForName(mimeType)); + if (mime.isValid()) { + if (mime.isDefault()) { + return QStringList(QStringLiteral("*")); + } else { + return mime.globPatterns(); + } + } + return QStringList(); +} + +QStringList DBusFileDialogManager::monitorFiles() const +{ + return DFileWatcher::getMonitorFiles(); +} + +void DBusFileDialogManager::showBluetoothTransDialog(const QString &id, const QStringList &URIs) +{ + BluetoothTransDialog *dlg = new BluetoothTransDialog(URIs, BluetoothTransDialog::DirectlySend, id); + dlg->setAttribute(Qt::WA_DeleteOnClose); + dlg->show(); +} + +void DBusFileDialogManager::onDialogDestroy() +{ + const QDBusObjectPath &path = m_dialogObjectMap.key(QObject::sender()); + + if (!path.path().isEmpty()) + m_dialogObjectMap.remove(path); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/dbusfiledialogmanager.h b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/dbusfiledialogmanager.h new file mode 100644 index 0000000..39ab769 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/dbusfiledialogmanager.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ + +#ifndef DBUSFILEDIALOGMANAGER_H +#define DBUSFILEDIALOGMANAGER_H + +#include +#include + +class DBusFileDialogManager : public QObject +{ +public: + explicit DBusFileDialogManager(QObject *parent = nullptr); + + QDBusObjectPath createDialog(QString key); + void destroyDialog(const QDBusObjectPath &path); + QList dialogs() const; + QString errorString() const; + + bool isUseFileChooserDialog() const; + bool canUseFileChooserDialog(const QString &group, const QString &executableFileName) const; + + QStringList globPatternsForMime(const QString &mimeType) const; + QStringList monitorFiles() const; + + void showBluetoothTransDialog(const QString &id, const QStringList &URIs); + +private: + void onDialogDestroy(); + + bool initJobDone = false; + + QString m_errorString; + QMap m_dialogObjectMap; +}; + +#endif // DBUSFILEDIALOGMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/filedialog.pri b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/filedialog.pri new file mode 100644 index 0000000..3a6ae11 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filedialog/filedialog.pri @@ -0,0 +1,28 @@ +dialog.files = $$PWD/com.deepin.filemanager.filedialog.xml +dialog.header_flags += -l DBusFileDialogHandle -i $$PWD/dbusfiledialoghandle.h +dialog.source_flags += -l DBusFileDialogHandle + +manager.files = $$PWD/com.deepin.filemanager.filedialogmanager.xml +manager.header_flags += -l DBusFileDialogManager -i $$PWD/dbusfiledialogmanager.h +manager.source_flags += -l DBusFileDialogManager + +DBUS_ADAPTORS += dialog manager + +filedialog_xmls.path = /usr/share/dbus-1/interfaces +filedialog_xmls.files = $$dialog.files $$manager.files + +filedialog_service.path = /usr/share/dbus-1/services +filedialog_service.files = $$PWD/com.deepin.filemanager.filedialog.service + +#INSTALLS += filedialog_service filedialog_xmls + +HEADERS += \ + $$PWD/dbusfiledialoghandle.h \ + $$PWD/dbusfiledialogmanager.h + +SOURCES += \ + $$PWD/dbusfiledialoghandle.cpp \ + $$PWD/dbusfiledialogmanager.cpp + +INCLUDEPATH += $$PWD +DEFINES += PRO_FILE_PWD=\\\"$$_PRO_FILE_PWD_\\\" diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/dbusfilemanager1.cpp b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/dbusfilemanager1.cpp new file mode 100644 index 0000000..7e9db03 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/dbusfilemanager1.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include +#include +#include "dbusfilemanager1.h" +#include "dfilewatcher.h" +#include "dfileservices.h" +#include "app/define.h" +#include "dialogs/dialogmanager.h" +#include "../dialogs/dtaskdialog.h" +#include "../dde-file-manager-lib/vault/vaultglobaldefine.h" + + +#include + +DBusFileManager1::DBusFileManager1(QObject *parent) + : QObject(parent) +{ + // monitor screen lock event. + QDBusConnection::sessionBus().connect( + "com.deepin.SessionManager", + "/com/deepin/SessionManager", + "org.freedesktop.DBus.Properties", + "PropertiesChanged", "sa{sv}as", + this, + SLOT(lockPropertyChanged(QDBusMessage))); +} + +void DBusFileManager1::ShowFolders(const QStringList &URIs, const QString &StartupId) +{ + Q_UNUSED(StartupId) + + if (QProcess::startDetached("file-manager.sh", QStringList() << "--raw" << URIs)) + return; + + QProcess::startDetached("dde-file-manager", QStringList() << "--raw" << URIs); +} + +void DBusFileManager1::ShowItemProperties(const QStringList &URIs, const QString &StartupId) +{ + Q_UNUSED(StartupId) + + if (QProcess::startDetached("file-manager.sh", QStringList() << "--raw" << "-p" << URIs)) + return; + + QProcess::startDetached("dde-file-manager", QStringList() << "--raw" << "-p" << URIs); +} + +void DBusFileManager1::ShowItems(const QStringList &URIs, const QString &StartupId) +{ + Q_UNUSED(StartupId) + + if (QProcess::startDetached("file-manager.sh", QStringList() << "--show-item" << URIs << "--raw")) + return; + + QProcess::startDetached("dde-file-manager", QStringList() << "--show-item" << URIs << "--raw"); +} + +void DBusFileManager1::Trash(const QStringList &URIs) +{ + DUrlList urls; + foreach (const QString &path, URIs) { + DUrl tempUrl = DUrl::fromUserInput(path); + urls << tempUrl; + } + DFileService::instance()->moveToTrash(this, urls); + +} + +QStringList DBusFileManager1::GetMonitorFiles() const +{ + return DFileWatcher::getMonitorFiles(); +} + +bool DBusFileManager1::topTaskDialog() +{ + // 如果正在有保险箱的移动、粘贴操作,置顶弹出任务框 + DTaskDialog *pTaskDlg = dialogManager->taskDialog(); + if (pTaskDlg && pTaskDlg->haveNotCompletedVaultTask()) { + pTaskDlg->showDialogOnTop(); + return true; + } + return false; +} + +void DBusFileManager1::closeTask() +{ + // 如果正在有保险箱的移动、粘贴、删除操作,强行结束任务 + DTaskDialog *pTaskDlg = dialogManager->taskDialog(); + if (pTaskDlg && pTaskDlg->haveNotCompletedVaultTask()) { + pTaskDlg->stopVaultTask(); + } +} + +//! 写json文件函数 +void ChangeJson(const QString & path, const QString & gourpNamne, const QString & VauleName, const QString & vaule) +{ + QByteArray byte; + QFile file(path); + if (file.exists()) { + file.open(QIODevice::ReadOnly|QIODevice::Text); + byte = file.readAll(); + file.close(); + }else{ + qDebug() <<"openFileError"; + file.close(); + return; + } + + QJsonParseError json_error; + QJsonDocument jsonDoc(QJsonDocument::fromJson(byte, &json_error)); + if (json_error.error != QJsonParseError::NoError) { + qDebug() << " json error "; + } + + QJsonObject rootobj = jsonDoc.object(); + if (rootobj.contains(gourpNamne)) { + QJsonObject gourpObject = rootobj.value(gourpNamne).toObject(); + gourpObject[VauleName] = vaule; + rootobj[gourpNamne] = gourpObject; + + if (file.exists()) { + file.open(QIODevice::WriteOnly|QIODevice::Text); + jsonDoc.setObject(rootobj); + file.seek(0); + file.write(jsonDoc.toJson()); + file.flush(); + file.close(); + } + } +} + +void DBusFileManager1::lockPropertyChanged(const QDBusMessage &msg) +{ + QList arguments = msg.arguments(); + if (3 != arguments.count()) + return; + + QString interfaceName = msg.arguments().at(0).toString(); + if (interfaceName != "com.deepin.SessionManager") + return; + + QVariantMap changedProps = qdbus_cast(arguments.at(1).value()); + QStringList keys = changedProps.keys(); + foreach (const QString &prop, keys) { + if (prop == "Locked") { + bool bLocked = changedProps[prop].toBool(); + if (bLocked) { + char *loginUser = getlogin(); + QString user = loginUser ? loginUser : ""; + emit lockEventTriggered(user); + + char buf[512] = {0}; + FILE *cmd_pipe = popen("pidof -s dde-file-manager", "r"); + + fgets(buf, 512, cmd_pipe); + pid_t pid = static_cast(strtoul(buf, nullptr, 10)); + + if (pid == 0) { + QString umountCmd = "fusermount -zu " + VAULT_BASE_PATH + "/" + VAULT_DECRYPT_DIR_NAME; + QByteArray umountCmdBytes = umountCmd.toUtf8(); + system(umountCmdBytes.data()); + //! 记录保险箱上锁时间 + ChangeJson(VAULT_TIME_CONFIG_FILE, + QString("VaultTime"), + QString("LockTime"), + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); + } + + pclose(cmd_pipe); + } + } + } +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/dbusfilemanager1.h b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/dbusfilemanager1.h new file mode 100644 index 0000000..c89b7fb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/dbusfilemanager1.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ + +#ifndef DBUSFILEMANAGER1_H +#define DBUSFILEMANAGER1_H + +#include +#include + + +class DBusFileManager1 : public QObject +{ + Q_OBJECT + +public: + explicit DBusFileManager1(QObject *parent = nullptr); + + void ShowFolders(const QStringList &URIs, const QString &StartupId); + void ShowItemProperties(const QStringList &URIs, const QString &StartupId); + void ShowItems(const QStringList &URIs, const QString &StartupId); + void Trash(const QStringList &URIs); + + // debug function + QStringList GetMonitorFiles() const; + +signals: + /** + * @brief lockEventTriggered 锁屏信号 + * @param user + */ + void lockEventTriggered(QString user); + +public slots: + // 保险箱使用 + bool topTaskDialog(); + void closeTask(); + +private slots: + /** + * @brief lockPropertyChanged 锁屏改变事件 + * @param msg + */ + void lockPropertyChanged(const QDBusMessage &msg); +}; + +#endif // DBUSFILEMANAGER1_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/filemanager1.pri b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/filemanager1.pri new file mode 100644 index 0000000..ebe2df3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/filemanager1.pri @@ -0,0 +1,21 @@ +filemanager.files = $$PWD/org.freedesktop.FileManager1.xml +filemanager.header_flags += -l DBusFileManager1 -i $$PWD/dbusfilemanager1.h +filemanager.source_flags += -l DBusFileManager1 + +DBUS_ADAPTORS += filemanager + +filemanager_xmls.path = /usr/share/dbus-1/interfaces +filemanager_xmls.files = $$filemanager.files + +filemanager_service.path = /usr/share/dbus-1/services +filemanager_service.files = $$PWD/org.freedesktop.FileManager.service + +INSTALLS += filemanager_service #filemanager_xmls + +HEADERS += \ + $$PWD/dbusfilemanager1.h + +SOURCES += \ + $$PWD/dbusfilemanager1.cpp + +INCLUDEPATH += $$PWD diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/org.freedesktop.FileManager.service b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/org.freedesktop.FileManager.service new file mode 100644 index 0000000..4b1f820 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/org.freedesktop.FileManager.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.freedesktop.FileManager1 +Exec=/usr/bin/dde-file-manager -d diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/org.freedesktop.FileManager1.xml b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/org.freedesktop.FileManager1.xml new file mode 100644 index 0000000..301126d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/filemanager1/org.freedesktop.FileManager1.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/licenceInterface.cpp b/dde-file-manager-5.5.3/src/dde-desktop/dbus/licenceInterface.cpp new file mode 100644 index 0000000..5ae736b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/licenceInterface.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + + +#include "licenceInterface.h" +/* + * Implementation of interface class ComDeepinLicenseInterface + */ + +ComDeepinLicenseInterface::ComDeepinLicenseInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +ComDeepinLicenseInterface::~ComDeepinLicenseInterface() +{ +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dbus/licenceInterface.h b/dde-file-manager-5.5.3/src/dde-desktop/dbus/licenceInterface.h new file mode 100644 index 0000000..f016969 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dbus/licenceInterface.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -p licenseInterface.h + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + + +#ifndef LICENCEINTERFACE_H +#define LICENCEINTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.license + */ +class ComDeepinLicenseInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.license.Info"; } + +public: + ComDeepinLicenseInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~ComDeepinLicenseInterface(); + + Q_PROPERTY(int AuthorizationState READ AuthorizationState) + inline int AuthorizationState() const + { return qvariant_cast< int >(property("AuthorizationState")); } + +Q_SIGNALS: // SIGNALS + void LicenseStateChange(); + +}; + +namespace com { + namespace deepin { + namespace license { + typedef ::ComDeepinLicenseInterface Info; + } + } +} + +#endif // LICENCEINTERFACE_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dde-desktop-build.pri b/dde-file-manager-5.5.3/src/dde-desktop/dde-desktop-build.pri new file mode 100644 index 0000000..af0f557 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dde-desktop-build.pri @@ -0,0 +1,32 @@ +DEFINES += QT_MESSAGELOGCONTEXT + +EDITION=COMMUNITY +ARCH = $$QMAKE_HOST.arch +isEqual(ARCH, sw_64) | isEqual(ARCH, mips64) | isEqual(ARCH, mips32) | isEqual(ARCH, loongarch64) | isEqual(ARCH, riscv64) { + EDITION=RACCOON +} + +isEqual(EDITION, RACCOON) { + DEFINES += DDE_COMPUTER_TRASH +} + +DEFINES += DDE_DBUS_DISPLAY + +CONFIG(release, release|debug) { + PKGCONFIG += dtkwidget dtkgui dtkcore +} else { + PKGCONFIG += dtkwidget dtkgui dtkcore +} + +load(dtk_qmake) + +# add computer/trash icon on professional system +deepin_professional: DEFINES += DDE_COMPUTER_TRASH + +!isEmpty(DISABLE_SCREENSAVER) { + DEFINES += DISABLE_SCREENSAVER +} + +!isEmpty(DISABLE_WALLPAPER_CAROUSEL) { + DEFINES += DISABLE_WALLPAPER_CAROUSEL +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dde-desktop.pri b/dde-file-manager-5.5.3/src/dde-desktop/dde-desktop.pri new file mode 100644 index 0000000..a9c22fe --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dde-desktop.pri @@ -0,0 +1,99 @@ +include($$PWD/dde-desktop-build.pri) +include($$PWD/util/util.pri) +include($$PWD/dbus/dbus.pri) + +include($$PWD/../dde-wallpaper-chooser/dde-wallpaper-chooser.pri) +#无热区设置 +#include($$PWD/../dde-zone/dde-zone.pri) +DEFINES += DISABLE_ZONE + +QT += core gui widgets dbus x11extras network concurrent multimedia #multimediawidgets svg +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +greaterThan(QT_MINOR_VERSION, 7): QT += gui-private +else: QT += platformsupport-private + +CONFIG += c++11 link_pkgconfig +PKGCONFIG += xcb xcb-ewmh xcb-shape dframeworkdbus gio-qt + +INCLUDEPATH += $$PWD/../dde-file-manager-lib\ + $$PWD/../dde-file-manager-lib/interfaces \ + $$PWD/../dde-file-manager-lib/interfaces/plugins \ + $$PWD/../dde-file-manager-lib/io\ + $$PWD/../utils\ + $$PWD/view \ + $$PWD + +win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../dde-file-manager-lib/release -ldde-file-manager +else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../dde-file-manager-lib/debug -ldde-file-manager +else:unix: LIBS += -L$$OUT_PWD/../../src/dde-file-manager-lib -ldde-file-manager + +CONFIG(debug, debug|release) { + DEPENDPATH += $$PWD/../dde-file-manager-lib + unix:QMAKE_RPATHDIR += $$OUT_PWD/../../src/dde-file-manager-lib +} + +SOURCES += \ + $$PWD/config/config.cpp \ + $$PWD/desktop.cpp \ + $$PWD/view/canvasviewhelper.cpp \ + $$PWD/model/dfileselectionmodel.cpp \ + $$PWD/view/canvasgridview.cpp \ + $$PWD/presenter/apppresenter.cpp \ + $$PWD/presenter/gridmanager.cpp \ + $$PWD/dbus/dbusdisplay.cpp \ + $$PWD/presenter/dfmsocketinterface.cpp \ + $$PWD/view/watermaskframe.cpp \ + $$PWD/dbus/dbusdock.cpp \ + $$PWD/view/desktopitemdelegate.cpp \ + $$PWD/presenter/gridcore.cpp \ + $$PWD/dbus/dbusmonitor.cpp \ + $$PWD/screen/abstractscreen.cpp \ + $$PWD/screen/abstractscreenmanager.cpp \ + $$PWD/screen/screenmanager.cpp \ + $$PWD/screen/screenobject.cpp \ + $$PWD/view/backgroundmanager.cpp \ + $$PWD/screen/screenhelper.cpp \ + $$PWD/view/backgroundwidget.cpp \ + $$PWD/screen/screenmanagerwayland.cpp \ + $$PWD/screen/screenobjectwayland.cpp \ + $$PWD/dbus/licenceInterface.cpp \ + $$PWD/view/canvasviewmanager.cpp \ + $$PWD/presenter/deepinlicensehelper.cpp + + + +HEADERS += \ + $$PWD/config/config.h \ + $$PWD/desktop.h \ + $$PWD/view/canvasviewhelper.h \ + $$PWD/model/dfileselectionmodel.h \ + $$PWD/view/private/canvasviewprivate.h \ + $$PWD/global/coorinate.h \ + $$PWD/global/singleton.h \ + $$PWD/view/canvasgridview.h \ + $$PWD/presenter/apppresenter.h \ + $$PWD/presenter/gridmanager.h \ + $$PWD/dbus/dbusdisplay.h \ + $$PWD/presenter/dfmsocketinterface.h \ + $$PWD/view/watermaskframe.h \ + $$PWD/dbus/dbusdock.h \ + $$PWD/view/desktopitemdelegate.h \ + $$PWD/presenter/gridcore.h \ + $$PWD/deventfilter.h \ + $$PWD/dbus/dbusmonitor.h \ + $$PWD/dbus/licenceInterface.h \ + $$PWD/screen/abstractscreen.h \ + $$PWD/screen/abstractscreenmanager.h \ + $$PWD/screen/screenmanager.h \ + $$PWD/screen/screenobject.h \ + $$PWD/view/backgroundmanager.h \ + $$PWD/screen/screenhelper.h \ + $$PWD/view/backgroundwidget.h \ + $$PWD/screen/screenmanagerwayland.h \ + $$PWD/screen/screenobjectwayland.h \ + $$PWD/view/canvasviewmanager.h \ + $$PWD/screen/abstractscreenmanager_p.h \ + $$PWD/accessible/frameaccessibledefine.h \ + $$PWD/accessible/accessiblelist.h \ + $$PWD/presenter/deepinlicensehelper.h diff --git a/dde-file-manager-5.5.3/src/dde-desktop/dde-desktop.pro b/dde-file-manager-5.5.3/src/dde-desktop/dde-desktop.pro new file mode 100644 index 0000000..8ba3b7e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/dde-desktop.pro @@ -0,0 +1,142 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-06-24T09:14:17 +# +#------------------------------------------------- + +include($$PWD/dde-desktop-build.pri) +include($$PWD/util/util.pri) +include($$PWD/dbus/dbus.pri) + +include($$PWD/../dde-wallpaper-chooser/dde-wallpaper-chooser.pri) +# 集成测试标签 +include($$PWD/../../3rdparty/accessibility/accessibility-suite.pri) +#无热区设置 +#include($$PWD/../dde-zone/dde-zone.pri) +DEFINES += DISABLE_ZONE + +# 获取标签系统设置 +AC_FUNC_ENABLE = true +#AC_FUNC_ENABLE = $$(ENABLE_AC_FUNC) +# 检查集成测试标签 +equals( AC_FUNC_ENABLE, true ){ + DEFINES += ENABLE_ACCESSIBILITY + message("dde-desktop enabled accessibility function with set: " $$AC_FUNC_ENABLE) +} + +QT += core gui widgets dbus x11extras network concurrent multimedia #multimediawidgets svg +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +greaterThan(QT_MINOR_VERSION, 7): QT += gui-private +else: QT += platformsupport-private + +TEMPLATE = app +TARGET = dde-desktop +DESTDIR = $$BUILD_DIST +CONFIG += c++11 link_pkgconfig +PKGCONFIG += xcb xcb-ewmh xcb-shape dframeworkdbus gio-qt + +INCLUDEPATH += $$PWD/../dde-file-manager-lib\ + $$PWD/../utils \ + $$PWD/../dde-file-manager-lib/interfaces \ + $$PWD/../dde-file-manager-lib/interfaces/plugins \ + $$PWD/../dde-file-manager-lib/io + +win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../dde-file-manager-lib/release -ldde-file-manager +else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../dde-file-manager-lib/debug -ldde-file-manager +else:unix: LIBS += -L$$OUT_PWD/../dde-file-manager-lib -ldde-file-manager + +CONFIG(debug, debug|release) { + DEPENDPATH += $$PWD/../dde-file-manager-lib + unix:QMAKE_RPATHDIR += $$OUT_PWD/../dde-file-manager-lib +} + +#安全加固 +QMAKE_CXXFLAGS += -fstack-protector-all +QMAKE_LFLAGS += -z now -pie -fPIE +isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + QMAKE_LFLAGS += -z noexecstack -z relro +} + +SOURCES += \ + main.cpp \ + config/config.cpp \ + desktop.cpp \ + view/canvasviewhelper.cpp \ +# view/canvasview.cpp \ + model/dfileselectionmodel.cpp \ + view/canvasgridview.cpp \ + presenter/apppresenter.cpp \ + presenter/gridmanager.cpp \ + dbus/dbusdisplay.cpp \ + presenter/dfmsocketinterface.cpp \ + view/watermaskframe.cpp \ + dbus/dbusdock.cpp \ + view/desktopitemdelegate.cpp \ + presenter/gridcore.cpp \ + dbus/dbusmonitor.cpp \ + screen/abstractscreen.cpp \ + screen/abstractscreenmanager.cpp \ + screen/screenmanager.cpp \ + screen/screenobject.cpp \ + view/backgroundmanager.cpp \ + screen/screenhelper.cpp \ + view/backgroundwidget.cpp \ + screen/screenmanagerwayland.cpp \ + screen/screenobjectwayland.cpp \ + dbus/licenceInterface.cpp \ + view/canvasviewmanager.cpp \ + presenter/deepinlicensehelper.cpp + + + +HEADERS += \ + config/config.h \ + desktop.h \ + view/canvasviewhelper.h \ + model/dfileselectionmodel.h \ + view/private/canvasviewprivate.h \ + global/coorinate.h \ + global/singleton.h \ + view/canvasgridview.h \ + presenter/apppresenter.h \ + presenter/gridmanager.h \ + dbus/dbusdisplay.h \ + presenter/dfmsocketinterface.h \ + view/watermaskframe.h \ + dbus/dbusdock.h \ + view/desktopitemdelegate.h \ + presenter/gridcore.h \ + deventfilter.h \ + dbus/dbusmonitor.h \ + dbus/licenceInterface.h \ + screen/abstractscreen.h \ + screen/abstractscreenmanager.h \ + screen/abstractscreenmanager_p.h \ + screen/screenmanager.h \ + screen/screenobject.h \ + view/backgroundmanager.h \ + screen/screenhelper.h \ + view/backgroundwidget.h \ + screen/screenmanagerwayland.h \ + screen/screenobjectwayland.h \ + view/canvasviewmanager.h \ + accessibility/ac-desktop-define.h \ + accessibility/acobjectlist.h \ + desktopprivate.h \ + presenter/dfmsocketinterface_p.h \ + presenter/deepinlicensehelper.h + +RESOURCES += + +# Automating generation .qm files from .ts files + +CONFIG(release, debug|release) { + !system($$PWD/translate_generation.sh): error("Failed to generate translation") + !system($$PWD/translate_ts2desktop.sh): error("Failed to generate translation") +} + +TRANSLATIONS += $$PWD/translations/$${TARGET}.ts \ + $$PWD/translations/$${TARGET}_zh_CN.ts + +include($$PWD/development.pri) diff --git a/dde-file-manager-5.5.3/src/dde-desktop/desktop.cpp b/dde-file-manager-5.5.3/src/dde-desktop/desktop.cpp new file mode 100644 index 0000000..88bd65d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/desktop.cpp @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ + +#include "desktop.h" +#include +#include +#include +#include +#include +#include +#include "desktopprivate.h" +#include "screen/screenhelper.h" +#include "presenter/gridmanager.h" +#include "../util/dde/desktopinfo.h" +#include "presenter/apppresenter.h" +#include "canvasviewmanager.h" +#include "backgroundmanager.h" +#include "desktopprivate.h" + +Desktop::Desktop() + : d(new DesktopPrivate) +{ +} + +Desktop::~Desktop() +{ + +} + +void Desktop::preInit() +{ + d->m_background = new BackgroundManager; + // //5s归还一次内存 + // QTimer *releaseMem = new QTimer; + // connect(releaseMem,&QTimer::timeout,this,[](){malloc_trim(0);}); + // releaseMem->start(5000); +} + +void Desktop::loadData() +{ + Presenter::instance()->init(); +} + +void Desktop::loadView() +{ + d->m_canvas = new CanvasViewManager(d->m_background); +} + +void Desktop::showWallpaperSettings(QString name, int mode) +{ + if (name.isNull() || name.isEmpty()) { + if (ScreenHelper::screenManager()->primaryScreen() == nullptr) { + qCritical() << "get primary screen failed! stop show wallpaper"; + return; + } + + name = ScreenHelper::screenManager()->primaryScreen()->name(); + } + + if (d->wallpaperSettings) { + //防止暴力操作,高频调用接口 + if (d->wallpaperSettings->isVisible()) + return; + d->wallpaperSettings->deleteLater(); + d->wallpaperSettings = nullptr; + } + + d->wallpaperSettings = new WallpaperSettings(name, Frame::Mode(mode)); + connect(d->wallpaperSettings, &Frame::done, this, [ = ] { + d->wallpaperSettings->deleteLater(); + d->wallpaperSettings = nullptr; + }); + + + connect(d->wallpaperSettings, &Frame::backgroundChanged, this, [this] { + WallpaperSettings *setting = dynamic_cast(sender()); + if (setting && d->m_background) { + QPair screenImage = setting->desktopBackground(); + d->m_background->setBackgroundImage(screenImage.first, screenImage.second); + } + }, Qt::DirectConnection); + + d->wallpaperSettings->show(); + + //使壁纸设置窗口保持焦点 + auto autoAct = new AutoActivateWindow(d->wallpaperSettings); + autoAct->setWatched(d->wallpaperSettings); + autoAct->start(); +} + + +void Desktop::showZoneSettings() +{ +#ifndef DISABLE_ZONE + if (d->zoneSettings) { + d->zoneSettings->deleteLater(); + d->zoneSettings = nullptr; + } + + d->zoneSettings = new ZoneSettings; + connect(d->zoneSettings, &ZoneMainWindow::finished, this, [ = ] { + d->zoneSettings->deleteLater(); + d->zoneSettings = nullptr; + }); + + d->zoneSettings->show(); + d->zoneSettings->grabKeyboard(); +#else + qWarning() << "Zone is disabled"; +#endif +} + + +void Desktop::EnableUIDebug(bool enable) +{ + for (CanvasViewPointer view : d->m_canvas->canvas().values()) { + view->EnableUIDebug(enable); + view->update(); + } +} + +void Desktop::SetVisible(int screenNum, bool v) +{ + --screenNum; + QVector screens = ScreenMrg->logicScreens(); + if (screens.size() > screenNum && screenNum >= 0) { + ScreenPointer sp = screens[screenNum]; + BackgroundWidgetPointer bw = d->m_background->allbackgroundWidgets().value(sp); + if (bw) + bw->setVisible(v); + + CanvasViewPointer view = d->m_canvas->canvas().value(sp); + if (view) + view->setVisible(v); + } +} + +void Desktop::FixGeometry(int screenNum) +{ + --screenNum; + QVector screens = ScreenMrg->logicScreens(); + if (screens.size() > screenNum && screenNum >= 0) { + ScreenPointer sp = screens[screenNum]; + emit ScreenMrg->sigScreenGeometryChanged(); + } +} + +void Desktop::Reset() +{ + ScreenMrg->reset(); + if (d->m_background->isEnabled()) { + d->m_background->onBackgroundBuild(); + } else { + d->m_background->onSkipBackgroundBuild(); + } +} + +void Desktop::PrintInfo() +{ + ScreenPointer primary = ScreenMrg->primaryScreen(); + qInfo() << "**************Desktop Info" << qApp->applicationVersion() + << "*****************"; + if (primary) + qInfo() << "primary screen :" << primary->name() + << "available geometry" << primary->availableGeometry() + << "handle geometry" << primary->handleGeometry() + << "devicePixelRatio" << ScreenMrg->devicePixelRatio() + << "screen count" << ScreenMrg->screens().count(); + else + qCritical() << "primary screen error! not found"; + + qInfo() << "*****************Screens Mode " << ScreenMrg->displayMode() + << "********************"; + qInfo() << "*****************last changed Mode " << ScreenMrg->lastChangedMode() + << "********************"; + int num = 1; + for (ScreenPointer screen : ScreenMrg->logicScreens()) { + if (screen) { + qInfo() << screen.get() << "screen name " << screen->name() + << "num" << num << "geometry" << screen->geometry() + << "handle geometry" << screen->handleGeometry(); + ++num; + } else { + qCritical() << "error! empty screen pointer!"; + } + } + + qInfo() << "*****************Background Eable" << d->m_background->isEnabled() + << "**********************"; + auto backgronds = d->m_background->allbackgroundWidgets(); + for (auto iter = backgronds.begin(); iter != backgronds.end(); ++iter) { + qInfo() << "Background" << iter.value().get() << "on screen" << iter.key()->name() << iter.key().get() + << "geometry" << iter.value()->geometry() << "visable" << iter.value()->isVisible() + << "rect" << iter.value()->rect() << "background image" + << d->m_background->backgroundImages().value(iter.key()->name()) + << "pixmap" << iter.value()->pixmap(); + + if (iter.value()->windowHandle()) { + qInfo() << "window geometry" << iter.value()->windowHandle()->geometry() + << iter.value()->windowHandle()->screen()->geometry(); + } + } + + qInfo() << "*****************Canvas Grid" << "**********************"; + if (d->m_canvas) { + auto canvas = d->m_canvas->canvas(); + GridCore *core = GridManager::instance()->core(); + for (auto iter = canvas.begin(); iter != canvas.end(); ++iter) { + int screenNum = iter.value()->screenNum(); + qInfo() << "canvas" << iter.value().get() << "on screen" << iter.value()->canvansScreenName() + << "num" << screenNum << "geometry" << iter.value()->geometry() + << "background" << iter.value()->parentWidget() << "screen" << iter.key().get(); + if (core->screensCoordInfo.contains(screenNum)) { + auto coord = core->screensCoordInfo.value(screenNum); + qInfo() << "coord " << coord.first << "*" << coord.second + << "display items count" << core->itemGrids.value(screenNum).size(); + } else { + qCritical() << "Grid" << iter.value()->screenNum() << "not find coordinfo"; + } + + } + + qInfo() << "overlap items count" << core->overlapItems.size(); + delete core; + } else { + qWarning() << "not load canvasgridview"; + } + qInfo() << "************Desktop Infomation End **************"; +} + +void Desktop::Refresh() +{ + if (d->m_canvas) + for (CanvasViewPointer view : d->m_canvas->canvas().values()) { + view->Refresh(); + } +} + +void Desktop::ShowWallpaperChooser(const QString &screen) +{ + showWallpaperSettings(screen, Frame::WallpaperMode); +} + +void Desktop::ShowScreensaverChooser(const QString &screen) +{ +#ifndef DISABLE_SCREENSAVER + showWallpaperSettings(screen, Frame::ScreenSaverMode); +#endif +} + +QList Desktop::GetIconSize() +{ + QSize iconSize{0, 0}; + if (d->m_canvas && !d->m_canvas->canvas().isEmpty()) + iconSize = d->m_canvas->canvas().first()->iconSize(); + QList size{iconSize.width(), iconSize.height()}; + return size; +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/desktop.h b/dde-file-manager-5.5.3/src/dde-desktop/desktop.h new file mode 100644 index 0000000..57df115 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/desktop.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ + +#ifndef DESKTOP_H +#define DESKTOP_H + +#include +#include + +#include "global/singleton.h" + +#define DesktopServiceName "com.deepin.dde.desktop" +#define DesktopServicePath "/com/deepin/dde/desktop" +#define DesktopServiceInterface "com.deepin.dde.desktop" + +class QDBusConnection; +class CanvasGridView; +class DesktopPrivate; +class Desktop : public QObject, public DDEDesktop::Singleton +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", DesktopServiceInterface) +public: + void preInit(); + void loadData(); + void loadView(); + void showZoneSettings(); + +public slots: + void ShowWallpaperChooser(const QString &screen = QString()); + void ShowScreensaverChooser(const QString &screen = QString()); + + Q_SCRIPTABLE void EnableUIDebug(bool enable); + Q_SCRIPTABLE void SetVisible(int screenNum,bool); + Q_SCRIPTABLE void FixGeometry(int screenNum); + Q_SCRIPTABLE void Reset(); + Q_SCRIPTABLE void PrintInfo(); + Q_SCRIPTABLE void Refresh(); + Q_SCRIPTABLE QList GetIconSize(); +protected: + void showWallpaperSettings(QString name, int mode = 0); +private: + explicit Desktop(); + ~Desktop(); + friend class DDEDesktop::Singleton; + Q_DISABLE_COPY(Desktop) + + QScopedPointer d; +}; + +#endif // DESKTOP_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/desktopprivate.h b/dde-file-manager-5.5.3/src/dde-desktop/desktopprivate.h new file mode 100644 index 0000000..6055e02 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/desktopprivate.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ + +#ifndef DESKTOPPRIVATE_H +#define DESKTOPPRIVATE_H + +#include "../dde-wallpaper-chooser/frame.h" +#include "../dde-wallpaper-chooser/utils/autoactivatewindow.h" + + +#ifndef DISABLE_ZONE +#include "../dde-zone/mainwindow.h" +#endif +#include + +using WallpaperSettings = Frame; + +#ifndef DISABLE_ZONE +using ZoneSettings = ZoneMainWindow; +#endif + +class BackgroundManager; +class CanvasViewManager; +class DesktopPrivate +{ +public: + ~DesktopPrivate() + { + if (m_background) { + delete m_background; + m_background = nullptr; + } + + if (m_canvas) { + delete m_canvas; + m_canvas = nullptr; + } + + if (wallpaperSettings) { + delete wallpaperSettings; + wallpaperSettings = nullptr; + } +#ifndef DISABLE_ZONE + if (zoneSettings) { + delete zoneSettings; + zoneSettings = nullptr; + } +#endif + } + BackgroundManager *m_background = nullptr; + CanvasViewManager *m_canvas = nullptr; + WallpaperSettings *wallpaperSettings = nullptr; + +#ifndef DISABLE_ZONE + ZoneSettings *zoneSettings { nullptr }; +#endif +}; +#endif // DESKTOPPRIVATE_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/development.pri b/dde-file-manager-5.5.3/src/dde-desktop/development.pri new file mode 100755 index 0000000..d0774f9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/development.pri @@ -0,0 +1,20 @@ +isEmpty(PREFIX){ + PREFIX = /usr +} + +target.path = $${PREFIX}/bin/ + +desktop_files.path = /usr/share/applications/ +desktop_files.files = $$PWD/data/applications/* + +services.path = /usr/share/dbus-1/services +services.files = $$PWD/data/com.deepin.dde.desktop.service + +translations.path = $${PREFIX}/share/$${TARGET}/translations +translations.files = translations/*.qm + +INSTALLS += target desktop_files services translations + +GitVersion = $$system(git rev-parse HEAD) +DEFINES += GIT_VERSION=\\\"$$GitVersion\\\" + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/global/coorinate.h b/dde-file-manager-5.5.3/src/dde-desktop/global/coorinate.h new file mode 100644 index 0000000..ea48092 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/global/coorinate.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include + +class Coordinate +{ +public: + Coordinate(int _x, int _y) + { + d.x = _x; + d.y = _y; + } + + explicit Coordinate(QPoint pos) + { + d.x = pos.x(); + d.y = pos.y(); + } + + QPoint position() + { + return QPoint(d.x, d.y); + } + + Coordinate moveLeft(int offset = 1) const + { + return Coordinate(d.x - offset, d.y); + } + + Coordinate moveRight(int offset = 1) const + { + return Coordinate(d.x + offset, d.y); + } + + Coordinate moveUp(int offset = 1) const + { + return Coordinate(d.x, d.y - offset); + } + + Coordinate moveDown(int offset = 1) const + { + return Coordinate(d.x, d.y + offset); + } + +private: + union CoordinateData { + struct { /*Position*/ + int32_t x; + int32_t y; + }; +// CoordValue value; + }; + + CoordinateData d; +}; diff --git a/dde-file-manager-5.5.3/src/dde-desktop/global/singleton.h b/dde-file-manager-5.5.3/src/dde-desktop/global/singleton.h new file mode 100644 index 0000000..7968f9a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/global/singleton.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#pragma once + +namespace DDEDesktop { +template +class Singleton +{ +public: + static inline T *instance() + { + static T *_instance = new T; + return _instance; + } + +protected: + Singleton(void) {} + ~Singleton(void) {} + Singleton(const Singleton &) {} + Singleton &operator= (const Singleton &); +}; +} + + + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/main.cpp b/dde-file-manager-5.5.3/src/dde-desktop/main.cpp new file mode 100644 index 0000000..592d4e9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/main.cpp @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "util/dde/ddesession.h" +#include "config/config.h" +#include "desktop.h" +#include "view/canvasgridview.h" + +#include +#include +#include +#include + +// DBus +#include "filedialogmanager_adaptor.h" +#include "dbusfiledialogmanager.h" +#include "filemanager1_adaptor.h" +#include "dbusfilemanager1.h" +#include "util/dde/desktopinfo.h" +#include "accessibility/acobjectlist.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +DGUI_USE_NAMESPACE +DWIDGET_USE_NAMESPACE +DCORE_USE_NAMESPACE +DFM_USE_NAMESPACE + +static bool registerDialogDBus() +{ + if (!QDBusConnection::sessionBus().isConnected()) { + qWarning("Cannot connect to the D-Bus session bus.\n" + "Please check your system settings and try again.\n"); + return false; + } + + // add our D-Bus interface and connect to D-Bus + if (!QDBusConnection::sessionBus().registerService("com.deepin.filemanager.filedialog")) { + qWarning("Cannot register the \"com.deepin.filemanager.filedialog\" service.\n"); + return false; + } + + DBusFileDialogManager *manager = new DBusFileDialogManager(); + Q_UNUSED(new FiledialogmanagerAdaptor(manager)); + + if (!QDBusConnection::sessionBus().registerObject("/com/deepin/filemanager/filedialogmanager", manager)) { + qWarning("Cannot register to the D-Bus object: \"/com/deepin/filemanager/filedialogmanager\"\n"); + manager->deleteLater(); + return false; + } + + return true; +} + +static bool registerFileManager1DBus() +{ + if (!QDBusConnection::sessionBus().isConnected()) { + qWarning("Cannot connect to the D-Bus session bus.\n" + "Please check your system settings and try again.\n"); + return false; + } + + // add our D-Bus interface and connect to D-Bus + if (!QDBusConnection::sessionBus().registerService("org.freedesktop.FileManager1")) { + qWarning("Cannot register the \"org.freedesktop.FileManager1\" service.\n"); + return false; + } + + DBusFileManager1 *manager = new DBusFileManager1(); + Q_UNUSED(new FileManager1Adaptor(manager)); + + if (!QDBusConnection::sessionBus().registerObject("/org/freedesktop/FileManager1", manager)) { + qWarning("Cannot register to the D-Bus object: \"/org/freedesktop/FileManager1\"\n"); + manager->deleteLater(); + return false; + } + + return true; +} + +int main(int argc, char *argv[]) +{ + //for qt5platform-plugins load DPlatformIntegration or DPlatformIntegrationParent + if (qEnvironmentVariableIsEmpty("XDG_CURRENT_DESKTOP")){ + qputenv("XDG_CURRENT_DESKTOP", "Deepin"); + } + + // Fixed the locale codec to utf-8 + QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8")); + + DApplication app(argc, argv); + + if (DesktopInfo().waylandDectected()) { + //! 以下代码用于视频预览使用 + setenv("PULSE_PROP_media.role", "video", 1); + QSurfaceFormat format; + format.setRenderableType(QSurfaceFormat::OpenGLES); + format.setDefaultFormat(format); + } else { + //fix bug59539 向桌面拖拽文件,进度条框无法拖动 + //根因:桌面启动时窗管未完全启动,导致xcb插件fallback到不同的分支 + //方案:设置环境变量来强制指定 使用NO_TITLEBAR + qputenv("D_DXCB_FORCE_NO_TITLEBAR", "1"); + } + + // 集成测试标签 +#ifdef ENABLE_ACCESSIBILITY + QAccessible::installFactory(accessibleFactory); + QAccessible::setActive(true); +#else + QAccessible::setActive(false); +#endif + + bool preload = false; + bool fileDialogOnly = false; + for (const QString &arg : app.arguments()) { + if (arg == "--preload") { + preload = true; + break; + } + if (arg == "--file-dialog-only") { + fileDialogOnly = true; + break; + } + } + + //因bug#46452,--file-dialog-only不再判断root +// if (fileDialogOnly && getuid() != 0) { +// // --file-dialog-only should only used by `root`. +// qDebug() << "Current UID != 0, the `--file-dialog-only` argument is ignored."; +// fileDialogOnly = false; +// } + + app.setQuitOnLastWindowClosed(false); + app.loadTranslator(); + app.setOrganizationName("deepin"); + app.setApplicationDisplayName(app.translate("DesktopMain", "Desktop")); + app.setApplicationVersion(DApplication::buildVersion((GIT_VERSION))); + app.setAttribute(Qt::AA_UseHighDpiPixmaps); + + const QString logFormat = "%{time}{yyyyMMdd.HH:mm:ss.zzz}[%{type:1}][%{function:-35} %{line:-4} %{threadid} ] %{message}\n"; + DFMLogManager::setLogFormat(logFormat); + DFMLogManager::registerConsoleAppender(); + + if (!preload) + DFMLogManager::registerFileAppender(); + + DFMApplication fmApp; + Q_UNUSED(fmApp) + + qInfo() << "start " << app.applicationName() << app.applicationVersion(); + qInfo() << "pid:" << getpid() << " preload:" << preload << "fileDialogOnly:" << fileDialogOnly; + + if (!preload && !fileDialogOnly) { + QDBusConnection conn = QDBusConnection::sessionBus(); + + if (!conn.registerService(DesktopServiceName)) { + qCritical() << "registerService Failed, maybe service exist" << conn.lastError(); + exit(0x0002); + } + + auto registerOptions = QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals | QDBusConnection::ExportAllProperties; + if (!conn.registerObject(DesktopServicePath, Desktop::instance(), registerOptions)) { + qCritical() << "registerObject Failed" << conn.lastError(); + exit(0x0003); + } + } + + if (!preload) { + // Notify dde-desktop start up + if (!fileDialogOnly) + Dde::Session::RegisterDdeSession(); + + // ability to show file selection dialog + if (!registerDialogDBus()) { + qWarning() << "Register dialog dbus failed."; + if (fileDialogOnly) + return 1; + } + + if (!registerFileManager1DBus()) + qWarning() << "Register org.freedesktop.FileManager1 DBus service is failed"; + } + + // init pixmap cache size limit, 20MB * devicePixelRatio + QPixmapCache::setCacheLimit(static_cast(20 * 1024 * app.devicePixelRatio())); + QThreadPool::globalInstance()->setMaxThreadCount(MAX_THREAD_COUNT); + + if (!fileDialogOnly) { + Desktop::instance()->preInit(); + Config::instance(); + } + + DFMGlobal::installTranslator(); + if (!fileDialogOnly) + Desktop::instance()->loadData(); + + if (preload) { + QTimer::singleShot(1000, &app, &QCoreApplication::quit); + } else { + if (!fileDialogOnly) { + Desktop::instance()->loadView(); + } + } + + QTimer::singleShot(100, []() { + AppController::instance(); + DFMGlobal::autoLoadDefaultPlugins(); + DFMGlobal::initPluginManager(); + DFMGlobal::initMimesAppsManager(); + DFMGlobal::initDialogManager(); + DFMGlobal::initOperatorRevocation(); + DFMGlobal::initTagManagerConnect(); + DFMGlobal::initThumbnailConnection(); + DFMGlobal::initDeviceListener(); + DFMGlobal::initGvfsMountManager(); + DFMGlobal::initBluetoothManager(); + DFMGlobal::initRootFileManager(); + DFMGlobal::setInitAppOver(); + }); + + DFMGlobal::IsFileManagerDiloagProcess = true; // for compatibility. + int ret = app.exec(); + qInfo() << "exit: " << ret << "pid:" << getpid(); + return ret; +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/model/dfileselectionmodel.cpp b/dde-file-manager-5.5.3/src/dde-desktop/model/dfileselectionmodel.cpp new file mode 100644 index 0000000..a560be2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/model/dfileselectionmodel.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + + +#include "dfileselectionmodel.h" + +DFileSelectionModel::DFileSelectionModel(QAbstractItemModel *model) + : QItemSelectionModel(model) +{ + m_timer.setSingleShot(true); + + connect(&m_timer, &QTimer::timeout, this, &DFileSelectionModel::updateSelecteds); +} + +DFileSelectionModel::DFileSelectionModel(QAbstractItemModel *model, QObject *parent) + : QItemSelectionModel(model, parent) +{ + m_timer.setSingleShot(true); + + connect(&m_timer, &QTimer::timeout, this, &DFileSelectionModel::updateSelecteds); +} + +bool DFileSelectionModel::isSelected(const QModelIndex &index) const +{ + if (m_currentCommand != QItemSelectionModel::SelectionFlags(Current | Rows | ClearAndSelect)) + return QItemSelectionModel::isSelected(index); + + return std::any_of(m_selection.begin(), m_selection.end(), [ index ](const QItemSelectionRange & range) { + return range.contains(index); + }); +} + +int DFileSelectionModel::selectedCount() const +{ + if (m_currentCommand != QItemSelectionModel::SelectionFlags(Current | Rows | ClearAndSelect)) + return selectedIndexes().count(); + + return m_lastSelectedIndex.row() - m_firstSelectedIndex.row() + 1; +} + +QModelIndexList DFileSelectionModel::selectedIndexes() const +{ + if (m_selectedList.isEmpty()) { + if (m_currentCommand != QItemSelectionModel::SelectionFlags(Current | Rows | ClearAndSelect)) { + m_selectedList = QItemSelectionModel::selectedIndexes(); + } else { + for (const QItemSelectionRange &range : m_selection) { + for (const QModelIndex &index : range.indexes()) { + if (!m_selectedList.contains(index)) + m_selectedList << index; + } + } + } + + // remove repeated item + //m_selectedList = m_selectedList.toSet().toList(); + } + + return m_selectedList; +} + +void DFileSelectionModel::clearSelectedCaches() +{ + m_selectedList.clear(); +} + +void DFileSelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) +{ + if (!command.testFlag(NoUpdate)) + m_selectedList.clear(); + + if (command != QItemSelectionModel::SelectionFlags(Current | Rows | ClearAndSelect)) { + if (m_timer.isActive()) { + m_timer.stop(); + updateSelecteds(); + } + + m_currentCommand = command; + + QItemSelectionModel::select(selection, command); + + return; + } + + + if (selection.isEmpty()) { + m_firstSelectedIndex = QModelIndex(); + m_lastSelectedIndex = QModelIndex(); + } else { + m_firstSelectedIndex = selection.first().topLeft(); + m_lastSelectedIndex = selection.last().bottomRight(); + } + + QItemSelection newSelection(m_firstSelectedIndex, m_lastSelectedIndex); + + emitSelectionChanged(newSelection, m_selection); + + m_currentCommand = command; + m_selection = newSelection; + + m_timer.start(20); +} + +void DFileSelectionModel::updateSelecteds() +{ + QItemSelectionModel::select(m_selection, m_currentCommand); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/model/dfileselectionmodel.h b/dde-file-manager-5.5.3/src/dde-desktop/model/dfileselectionmodel.h new file mode 100644 index 0000000..204833a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/model/dfileselectionmodel.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include + +class DFileSelectionModel : public QItemSelectionModel +{ +public: + explicit DFileSelectionModel(QAbstractItemModel *model = nullptr); + explicit DFileSelectionModel(QAbstractItemModel *model, QObject *parent); + + bool isSelected(const QModelIndex &index) const; + int selectedCount() const; + + QModelIndexList selectedIndexes() const; + void clearSelectedCaches(); + +protected: + void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override; + +private: + void updateSelecteds(); + + mutable QModelIndexList m_selectedList; + + QItemSelection m_selection; + QModelIndex m_firstSelectedIndex; + QModelIndex m_lastSelectedIndex; + QItemSelectionModel::SelectionFlags m_currentCommand; + QTimer m_timer; + + friend class CanvasGridView; +}; diff --git a/dde-file-manager-5.5.3/src/dde-desktop/presenter/apppresenter.cpp b/dde-file-manager-5.5.3/src/dde-desktop/presenter/apppresenter.cpp new file mode 100644 index 0000000..4bd4a3c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/presenter/apppresenter.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + + +#include "apppresenter.h" + +#include + +#include "../config/config.h" +#include "gridmanager.h" + +Presenter::Presenter(QObject *parent) : QObject(parent) +{ +} + +void Presenter::init() +{ + connect(Presenter::instance(), &Presenter::setConfig, + Config::instance(), &Config::setConfig, Qt::QueuedConnection); + connect(Presenter::instance(), &Presenter::removeConfig, + Config::instance(), &Config::removeConfig, Qt::QueuedConnection); + connect(Presenter::instance(), &Presenter::setConfigList, + Config::instance(), &Config::setConfigList, Qt::QueuedConnection); + connect(Presenter::instance(), &Presenter::removeConfigList, + Config::instance(), &Config::removeConfigList, Qt::QueuedConnection); +} + +void Presenter::onSortRoleChanged(int role, Qt::SortOrder order) +{ + emit setConfig(Config::groupGeneral, Config::keySortBy, role); + emit setConfig(Config::groupGeneral, Config::keySortOrder, order); +} + +void Presenter::onAutoAlignToggled() +{ + GridManager::instance()->toggleArrange(); + emit setConfig(Config::groupGeneral, Config::keyAutoAlign, GridManager::instance()->autoArrange()); +} + +void Presenter::onAutoMergeToggled() +{ + emit setConfig(Config::groupGeneral, Config::keyAutoMerge, GridManager::instance()->autoMerge()); +} + +void Presenter::OnIconLevelChanged(int iconLevel) +{ + emit setConfig(Config::groupGeneral, Config::keyIconLevel, iconLevel); +} + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/presenter/apppresenter.h b/dde-file-manager-5.5.3/src/dde-desktop/presenter/apppresenter.h new file mode 100644 index 0000000..9d2ceeb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/presenter/apppresenter.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include "../global/singleton.h" + +class Presenter : public QObject, public DDEDesktop::Singleton +{ + Q_OBJECT +public: + + void init(); + +signals: + void setConfig(const QString &group, const QString &key, const QVariant &value); + void removeConfig(const QString &group, const QString &key); + void setConfigList(const QString &group, const QStringList &keys, const QVariantList &values); + void removeConfigList(const QString &group, const QStringList &keys); + +public slots: + void onSortRoleChanged(int role, Qt::SortOrder order); + void onAutoAlignToggled(); + void onAutoMergeToggled(); + void OnIconLevelChanged(int iconLevel); + +private: + Q_DISABLE_COPY(Presenter) + explicit Presenter(QObject *parent = nullptr); + friend class DDEDesktop::Singleton; +}; + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/presenter/deepinlicensehelper.cpp b/dde-file-manager-5.5.3/src/dde-desktop/presenter/deepinlicensehelper.cpp new file mode 100644 index 0000000..c87bcd7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/presenter/deepinlicensehelper.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ +#include "deepinlicensehelper.h" + +#include "dbus/licenceInterface.h" + +#include +#include + +class DeepinLicenseHelperGlobal : public DeepinLicenseHelper {}; +Q_GLOBAL_STATIC(DeepinLicenseHelperGlobal, deepinLicenseHelperGlobal) + +DeepinLicenseHelper *DeepinLicenseHelper::instance() +{ + return deepinLicenseHelperGlobal; +} + +DeepinLicenseHelper::DeepinLicenseHelper(QObject *parent) : QObject(parent) +{ + Q_ASSERT(qApp->thread() == thread()); + m_reqTimer.setInterval(500); + m_reqTimer.setSingleShot(true); + + connect(&m_reqTimer, &QTimer::timeout, this, &DeepinLicenseHelper::requetLicenseState); +} + +DeepinLicenseHelper::~DeepinLicenseHelper() +{ + m_work.waitForFinished(); + delete m_licenseInterface; + m_licenseInterface = nullptr; +} + +void DeepinLicenseHelper::init() +{ + std::call_once(initFlag, [this](){ + m_work = QtConcurrent::run(&DeepinLicenseHelper::createInterface); + }); +} + +void DeepinLicenseHelper::delayGetState() +{ + m_reqTimer.start(); +} + +void DeepinLicenseHelper::requetLicenseState() +{ + if (m_work.isRunning() || !m_licenseInterface) { + qWarning() << "requetLicenseState: interface is invalid."; + return; + } + + m_work = QtConcurrent::run(&DeepinLicenseHelper::getLicenseState, this); +} + +void DeepinLicenseHelper::initFinshed(void *interface) +{ + Q_ASSERT(interface); + Q_ASSERT(!m_licenseInterface); + m_licenseInterface = static_cast(interface); + connect(m_licenseInterface, &ComDeepinLicenseInterface::LicenseStateChange, + this, &DeepinLicenseHelper::licenseStateChanged); + m_work.waitForFinished(); + qInfo() << "interface inited"; + + requetLicenseState(); +} + +void DeepinLicenseHelper::createInterface() +{ + qInfo() << "create ComDeepinLicenseInterface..."; + auto licenseInterface = new ComDeepinLicenseInterface( + "com.deepin.license", + "/com/deepin/license/Info", + QDBusConnection::systemBus()); + licenseInterface->moveToThread(qApp->thread()); + qInfo() << "create /com/deepin/license/Info org.freedesktop.DBus.Properties..."; + QMetaObject::invokeMethod(DeepinLicenseHelper::instance(), "initFinshed", Q_ARG(void *, licenseInterface)); +} + +void DeepinLicenseHelper::getLicenseState(DeepinLicenseHelper *self) +{ + Q_ASSERT(self); + Q_ASSERT(self->m_licenseInterface); + qInfo() << "get active state from com.deepin.license.Info"; + int state = self->m_licenseInterface->AuthorizationState(); + qInfo() << "Get AuthorizationState" << state; + emit self->postLicenseState(state); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/presenter/deepinlicensehelper.h b/dde-file-manager-5.5.3/src/dde-desktop/presenter/deepinlicensehelper.h new file mode 100644 index 0000000..972df51 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/presenter/deepinlicensehelper.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ +#ifndef DEEPINLICENSEHELPER_H +#define DEEPINLICENSEHELPER_H + +#include +#include +#include + +#include + +class ComDeepinLicenseInterface; +class DeepinLicenseHelper : public QObject +{ + Q_OBJECT +public: + static DeepinLicenseHelper *instance(); + void init(); + void delayGetState(); +signals: + void licenseStateChanged(); + void postLicenseState(int); + +public slots: + +protected: + explicit DeepinLicenseHelper(QObject *parent = nullptr); + ~DeepinLicenseHelper(); + +private slots: + void requetLicenseState(); + void initFinshed(void *interface); + +private: + static void createInterface(); + static void getLicenseState(DeepinLicenseHelper *); +private: + std::once_flag initFlag; + QFuture m_work; + QTimer m_reqTimer; + ComDeepinLicenseInterface *m_licenseInterface = nullptr; +}; + +#endif // DEEPINLICENSEHELPER_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/presenter/dfmsocketinterface.cpp b/dde-file-manager-5.5.3/src/dde-desktop/presenter/dfmsocketinterface.cpp new file mode 100644 index 0000000..63c8b53 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/presenter/dfmsocketinterface.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + + +#include "dfmsocketinterface.h" +#include "dfmsocketinterface_p.h" + +#include +#include +#include +#include +#include + +class DFMSocketInterfacePrivate +{ +public: + explicit DFMSocketInterfacePrivate(DFMSocketInterface *parent) : q_ptr(parent) {} + ~DFMSocketInterfacePrivate() { + } + QLocalSocket *socket = nullptr; + + DFMSocketInterface *q_ptr; + Q_DECLARE_PUBLIC(DFMSocketInterface) +}; + +DFMSocketInterface::DFMSocketInterface(QObject *parent) : QObject(parent), d_ptr(new DFMSocketInterfacePrivate(this)) +{ + Q_D(DFMSocketInterface); + + d->socket = new QLocalSocket(); + QString socketPath = QString("/var/run/user/%1/dde-file-manager").arg(getuid()); + qInfo() << "connect to socket" << socketPath; + connect(d->socket, static_cast(&QLocalSocket::error), + this, [ = ](QLocalSocket::LocalSocketError socketError) { + //连接出错可能造成死循环,屏蔽之 + d->socket->close(); + d->socket->deleteLater(); +// d->socket = new QLocalSocket(); +// d->socket->connectToServer(socketPath); + qCritical() << "Connect error" << socketError << d->socket->errorString(); + }); + + d->socket->connectToServer(socketPath); +} + +DFMSocketInterface::~DFMSocketInterface() +{ + Q_D(DFMSocketInterface); + if (d->socket) { + d->socket->close(); + d->socket->deleteLater(); + d->socket = nullptr; + } +} + +//json="{\"paths\":[$paths],\"isShowPropertyDialogRequest\":true}"; +// echo $json |socat - $XDG_RUNTIME_DIR/dde-file-manager; +void DFMSocketInterface::showProperty(const QStringList &paths) +{ + //Q_D(DFMSocketInterface); + + DDesktopServices::showFileItemProperties(paths); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/presenter/dfmsocketinterface.h b/dde-file-manager-5.5.3/src/dde-desktop/presenter/dfmsocketinterface.h new file mode 100644 index 0000000..090a7cb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/presenter/dfmsocketinterface.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include +#include "../global/singleton.h" + +class DFMSocketInterfacePrivate; +class DFMSocketInterface : public QObject, public DDEDesktop::Singleton +{ + Q_OBJECT + friend class DDEDesktop::Singleton; +public: + explicit DFMSocketInterface(QObject *parent = nullptr); + virtual ~ DFMSocketInterface(); + +signals: + +public slots: + void showProperty(const QStringList &paths); + +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), DFMSocketInterface) +}; + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/presenter/dfmsocketinterface_p.h b/dde-file-manager-5.5.3/src/dde-desktop/presenter/dfmsocketinterface_p.h new file mode 100644 index 0000000..09b2911 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/presenter/dfmsocketinterface_p.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#ifndef DFMSOCKETINTERFACE_P_H +#define DFMSOCKETINTERFACE_P_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +DWIDGET_USE_NAMESPACE + +using namespace std; +static int getProcIdByName(const string &procName) +{ + int pid = -1; + + // Open the /proc directory + DIR *dp = opendir("/proc"); + if (dp != nullptr) { + // Enumerate all entries in directory until process found + struct dirent *dirp; + while (pid < 0 && (dirp = readdir(dp))) { + // Skip non-numeric entries + int id = atoi(dirp->d_name); + if (id > 0) { + // Read contents of virtual /proc/{pid}/cmdline file + string cmdPath = string("/proc/") + dirp->d_name + "/cmdline"; + ifstream cmdFile(cmdPath.c_str()); + string cmdLine; + getline(cmdFile, cmdLine); + if (!cmdLine.empty()) { + // Keep first cmdline item which contains the program path + size_t pos = cmdLine.find('\0'); + if (pos != string::npos) { + cmdLine = cmdLine.substr(0, pos); + } + // Keep program name only, removing the path + pos = cmdLine.rfind('/'); + if (pos != string::npos) { + cmdLine = cmdLine.substr(pos + 1); + } + // Compare against requested process name + if (procName == cmdLine) { + pid = id; + } + } + } + } + closedir(dp); + } + + return pid; +} +#endif // DFMSOCKETINTERFACE_P_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/presenter/gridcore.cpp b/dde-file-manager-5.5.3/src/dde-desktop/presenter/gridcore.cpp new file mode 100644 index 0000000..e63dcdc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/presenter/gridcore.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + + +#include "gridcore.h" + +GridCore::GridCore() +{ + +} + +QStringList GridCore::reloacle(int screenNum, GIndex targetIndex, int emptyBefore, int emptyAfter) +{ + QStringList dodgeItems; + auto end = findEmptyBackward(screenNum, targetIndex, emptyAfter); + dodgeItems << reloacleBackward(screenNum, targetIndex, end); + + auto start = findEmptyForward(screenNum, targetIndex - 1, emptyBefore); + dodgeItems << reloacleForward(screenNum, start, targetIndex - 1); + return dodgeItems; +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/presenter/gridcore.h b/dde-file-manager-5.5.3/src/dde-desktop/presenter/gridcore.h new file mode 100644 index 0000000..a325db1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/presenter/gridcore.h @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include +#include +#include +#include + +typedef QPoint GPos; +typedef qint32 GIndex; + + +inline QString positionKey(QPoint pos) +{ + return QString("%1_%2").arg(pos.x()).arg(pos.y()); +} + +/*! + * \brief qQPointLessThanKey sort by postition + * \param key1 + * \param key2 + * \return + */ +inline bool qQPointLessThanKey(const QPoint &key1, const QPoint &key2) +{ + return (key1.x() < key2.x()) || + ((key1.x() == key2.x()) && (key1.y() < key2.y())); +} + +template <> inline bool qMapLessThanKey(const QPoint &key1, const QPoint &key2) +{ + return qQPointLessThanKey(key1, key2); +} + + +// TODO: move all grid calc to GridCore +class GridCore +{ +public: + + QStringList overlapItems; + + QMap> gridItems; + QMap> itemGrids; + QMap m_screenFullStatus;//屏幕图标状态 + QMap> m_cellStatus;//> + QMap positionProfiles; + QMap> screensCoordInfo; //> + +public: + GridCore(); + + void addItem(int screenNum, GIndex index, const QString &item) + { + //bug#45219,当出现错误的index时,放入堆叠 + if (index < 0 || index >= m_cellStatus.value(screenNum).length()) { + qWarning() << "screen" << screenNum << "error index" << index << item; + if (!overlapItems.contains(item)) { + overlapItems << item; + } + return; + } + + if (!m_cellStatus.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return; + } + auto cellStatusItor = m_cellStatus.find(screenNum); + cellStatusItor.value()[index] = true; + auto position = toPos(screenNum, index); + + if (!itemGrids.contains(screenNum) + || !gridItems.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return; + } + auto tempGridItemsItor = gridItems.find(screenNum); + auto tempItemGridsItor = itemGrids.find(screenNum); + tempItemGridsItor->insert(item, position); + tempGridItemsItor->insert(position, item); + } + + void removeItem(int screenNum, GPos pos) + { + if (!gridItems.contains(screenNum) || !itemGrids.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return; + } + auto tempGridItemsItor = gridItems.find(screenNum); + auto tempItemGridsItor = itemGrids.find(screenNum); + + auto index = toIndex(screenNum, pos); + auto item = tempGridItemsItor.value().take(pos); + tempItemGridsItor.value().remove(item); + + if (!m_cellStatus.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return; + } + Q_ASSERT(index < m_cellStatus.value(screenNum).length()); + auto cellStatusItor = m_cellStatus.find(screenNum); + cellStatusItor.value()[index] = false; + } + + void removeItem(int screenNum, GIndex index) + { + if (!gridItems.contains(screenNum) || !itemGrids.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return; + } + auto tempGridItemsItor = gridItems.find(screenNum); + auto tempItemGridsItor = itemGrids.find(screenNum); + + + auto position = toPos(screenNum, index); + auto item = tempGridItemsItor.value().take(position); + tempItemGridsItor.value().remove(item); + + + if (!m_cellStatus.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return; + } + Q_ASSERT(index < m_cellStatus.value(screenNum).length()); + auto cellStatusItor = m_cellStatus.find(screenNum); + cellStatusItor.value()[index] = false; + } + + void removeItem(int screenNum, const QString &item) + { + if (!gridItems.contains(screenNum) || !itemGrids.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return; + } + auto tempGridItemsItor = gridItems.find(screenNum); + auto tempItemGridsItor = itemGrids.find(screenNum); + + auto position = tempItemGridsItor.value().take(item); + auto index = toIndex(screenNum, position); + tempGridItemsItor.value().take(position); + + if (!m_cellStatus.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return; + } + Q_ASSERT(index < m_cellStatus.value(screenNum).length()); + auto cellStatusItor = m_cellStatus.find(screenNum); + cellStatusItor.value()[index] = false; + + } + + inline GIndex toIndex(int screenNum, const GPos &pos) const + { + auto coordInfo = screensCoordInfo.value(screenNum); + return pos.x() * coordInfo.second + pos.y(); + } + + inline GPos toPos(int screenNum, GIndex index) const + { + auto coordInfo = screensCoordInfo.value(screenNum); + + auto x = index / coordInfo.second; + auto y = index % coordInfo.second; + return GPos(x, y); + } + + inline GPos pos(int screenNum, const QString &item) const + { + if (itemGrids.value(screenNum).contains(item)) { + return itemGrids.value(screenNum).value(item); + } else { + auto coordInfo = screensCoordInfo.value(screenNum); + return GPos(coordInfo.first - 1, coordInfo.second - 1); + } + } + + GIndex findEmptyForward(int screenNum, GIndex index, int emptyCount) + { + if (0 == emptyCount) { + return index; + } + if (!m_cellStatus.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return index;//return right? + } + auto cellStatusItor = m_cellStatus.find(screenNum); + + for (auto i = index; i >= 0; --i) { + if (!cellStatusItor.value()[i]) { + --emptyCount; + if (0 == emptyCount) { + return i; + } + } + } + return 0; + } + + QStringList reloacleForward(int screenNum, GIndex start, GIndex end) + { + QStringList items; + if (!gridItems.contains(screenNum) || !itemGrids.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return items; + } + auto tempGridItemsItor = gridItems.find(screenNum); + auto tempItemGridsItor = itemGrids.find(screenNum); + + for (auto i = start; i <= end; ++i) { + auto position = toPos(screenNum, i); + if (tempGridItemsItor.value().contains(position)) { + items << tempGridItemsItor.value().value(position); + tempGridItemsItor.value().remove(position); + } + } + + for (auto i = start; i < start + items.length(); ++i) { + auto position = toPos(screenNum, i); + auto item = items.value(i - start); + tempGridItemsItor.value().insert(position, item); + tempItemGridsItor.value().insert(item, position); + } + return items; + } + + GIndex findEmptyBackward(int screenNum, GIndex index, int emptyCount) + { + if (!m_cellStatus.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return index;//return right? + } + auto cellStatusItor = m_cellStatus.find(screenNum); + + if (0 == emptyCount) { + return index; + } + + for (auto i = index; i < m_cellStatus.value(screenNum).length(); ++i) { + if (!cellStatusItor.value()[i]) { + --emptyCount; + if (0 == emptyCount) { + return i; + } + } + } + return m_cellStatus.value(screenNum).length() - 1; + } + + // start < end + QStringList reloacleBackward(int screenNum, GIndex start, GIndex end) + { + QStringList items; + if (!gridItems.contains(screenNum) || !itemGrids.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return items; + } + auto tempGridItemsItor = gridItems.find(screenNum); + auto tempItemGridsItor = itemGrids.find(screenNum); + + for (auto i = end; i >= start; --i) { + auto position = toPos(screenNum, i); + if (tempGridItemsItor.value().contains(position)) { + items << tempGridItemsItor.value().value(position); + tempGridItemsItor.value().remove(position); + } + } + + for (auto i = end; i > end - items.length(); --i) { + auto position = toPos(screenNum, i); + auto item = items.value(end - i); + tempGridItemsItor.value().insert(position, item); + tempItemGridsItor.value().insert(item, position); + } + return items; + } + + QList emptyPostion(int screenNum) const + { + QList ret; + if (!m_cellStatus.contains(screenNum)) { + qDebug() << "can not find num :" << screenNum; + return ret; + } + + auto cellStatusItor = m_cellStatus.find(screenNum); + for (GIndex i = 0; i < m_cellStatus.value(screenNum).length(); ++i) { + if (!cellStatusItor.value()[i]) { + ret.append(i); + } + } + return ret; + } + + QStringList reloacle(int screenNum, GIndex targetIndex, int emptyBefore, int emptyAfter); +}; + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/presenter/gridmanager.cpp b/dde-file-manager-5.5.3/src/dde-desktop/presenter/gridmanager.cpp new file mode 100644 index 0000000..916baae --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/presenter/gridmanager.cpp @@ -0,0 +1,1561 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#include "gridmanager.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include "apppresenter.h" +#include "dfileservices.h" +#include "../config/config.h" +#include "dabstractfileinfo.h" +#include "screen/screenhelper.h" +#include "interfaces/private/mergeddesktop_common_p.h" + + +class GridManagerPrivate +{ +public: + GridManagerPrivate() + { + //新需求gsetting控制桌面部分文件 + m_desktopSettings = new DGioSettings("com.deepin.dde.filemanager.desktop", "/com/deepin/dde/filemanager/desktop/"); + QString desktopPath = QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first(); + DUrl desktopUrl = DUrl::fromLocalFile(desktopPath); + QDir dir(desktopUrl.toString()); + m_gsettings << dir.filePath("dde-home.desktop") + << dir.filePath("dde-trash.desktop") + << dir.filePath("dde-computer.desktop"); + + autoArrange = Config::instance()->getConfig(Config::groupGeneral, Config::keyAutoAlign).toBool(); +#ifdef ENABLE_AUTOMERGE //sp2需求调整,屏蔽自动整理 + autoMerge = Config::instance()->getConfig(Config::groupGeneral, Config::keyAutoMerge, false).toBool(); +#else + //取消自动整理 + autoMerge = Config::instance()->getConfig(Config::groupGeneral, Config::keyAutoMerge, false).toBool(); + //若用户开启了自动整理,则强制退出 + if (autoMerge) { + autoMerge = false; + Config::instance()->setConfig(Config::groupGeneral, Config::keyAutoMerge, false); + } +#endif +// auto settings = Config::instance()->settings(); +// settings->beginGroup(Config::groupGeneral); +// autoArrange = settings->value(Config::keyAutoAlign).toBool(); +// autoMerge = settings->value(Config::keyAutoMerge, false).toBool(); +// settings->endGroup(); + } + + GridManagerPrivate(GridManagerPrivate &) = delete; + GridManagerPrivate &operator=(GridManagerPrivate &) = delete; + + ~GridManagerPrivate() + { + if (m_desktopSettings) { + delete m_desktopSettings; + m_desktopSettings = nullptr; + } + } + inline int cellCount(int screenNum) const + { + auto coordInfo = screensCoordInfo.value(screenNum); + return coordInfo.second * coordInfo.first; + } + + void clear() + { + m_itemGrids.clear(); + m_gridItems.clear(); + m_overlapItems.clear(); + m_cellStatus.clear(); + + for (int i : screenCode()) { + + //add empty m_itemGrids + QMap gridItem; + m_gridItems.insert(i, gridItem); + + //add empty m_gridItems + QMap itemGrid; + m_itemGrids.insert(i, itemGrid); + + m_screenFullStatus.insert(i, false); + } + + auto coordkeys = screensCoordInfo.keys(); + for (auto key : coordkeys) { + //add empty coordInfo + QVector tempVector; + tempVector.resize(cellCount(key)); + m_cellStatus.insert(key, tempVector); + } + auto statusValues = m_cellStatus.values(); + for (auto &oneValue : statusValues) { + for (int i = 0; i < oneValue.length(); ++i) { + oneValue[i] = false; + } + } + } + + QStringList rangeItems(int screenNum) + { + QStringList sortItems; + + auto inUsePos = m_gridItems.value(screenNum).keys(); + qSort(inUsePos.begin(), inUsePos.end(), qQPointLessThanKey); + + for (int index = 0; index < inUsePos.length(); ++index) { + auto gridPos = inUsePos.value(index); + auto item = m_gridItems.value(screenNum).value(gridPos); + sortItems << item; + } + + sortItems << m_overlapItems; + return sortItems; + } + + QStringList rangeItems(const int screenNum, const QStringList itemList) + { + QStringList sortItems; + QList itemPosList; + QStringList unknownItemList; + foreach (auto item, itemList) { + if (m_itemGrids.contains(screenNum) && m_itemGrids.value(screenNum).contains(item)) { + itemPosList.append(m_itemGrids.value(screenNum).value(item)); + } else { + unknownItemList.append(item); + } + } + + qSort(itemPosList.begin(), itemPosList.end(), qQPointLessThanKey); + + for (int index = 0; index < itemPosList.length(); ++index) { + auto gridPos = itemPosList.value(index); + auto item = m_gridItems.value(screenNum).value(gridPos); + sortItems << item; + } + sortItems << unknownItemList; + return sortItems; + } + + void autoMergeItems(QStringList items) + { + arrange(items); + } + + void arrange(QStringList sortedItems) + { + //过滤gsetting中配置的文件 + for (auto &one : m_gsettings) { + //todo:如果开放自动整理需要转化成真是路径做处理 + DUrl tempUrl(one); + if (!GridManager::instance()->desktopFileShow(tempUrl, true)) + sortedItems.removeOne(one); + } + + auto screenOrder = screenCode(); + QTime t; + t.start(); + qDebug() << "screen count" << screenOrder.size(); + for (int screenNum : screenOrder) { + qDebug() << "arrange Num" << screenNum << sortedItems.size(); + QMap gridItems; + QMap itemGrids; + if (!sortedItems.empty()) { + auto cellStatus = m_cellStatus.value(screenNum); + int coordHeight = screensCoordInfo.value(screenNum).second; + int i = 0; + for (; i < cellStatus.size() && !sortedItems.empty(); ++i) { + QString item = sortedItems.takeFirst(); + QPoint pos(i / coordHeight, i % coordHeight); + //cellStatus[i] = true; + gridItems.insert(pos, item); + itemGrids.insert(item, pos); + setCellStatus(screenNum, i, true); + } + qDebug() << "screen" << screenNum << "put item:" << i << "cell" << cellStatus.size(); + } + m_gridItems.insert(screenNum, gridItems); + m_itemGrids.insert(screenNum, itemGrids); + } + qDebug() << "time " << t.elapsed() << "(ms) overlapItems " << sortedItems.size(); + m_overlapItems = sortedItems; + } + + void createProfile() + { + if (0 == createProfileTime) + clear(); + createProfileTime++; + } + + void loadProfile(const QStringList &orderedItems, QHash existItems) + { + QMap screenNumProfiles; + + if (m_bSingleMode) { + screenNumProfiles.insert(1, QString("SingleScreen")); + } else { + readProfiles(); + screenNumProfiles = positionProfiles; + } + + //获取个屏幕分组信息对应的图标信息 + QMap moreIcon; + QMutexLocker lk(Config::instance()->mutex()); + auto settings = Config::instance()->settings(); + for (int &screenKey : screenNumProfiles.keys()) { + settings->beginGroup(screenNumProfiles.value(screenKey)); + for (auto &key : settings->allKeys()) { + auto coords = key.split("_"); + auto x = coords.value(0).toInt(); + auto y = coords.value(1).toInt(); + QString item = settings->value(key).toString(); + if (existItems.contains(item)) { + QPoint pos{x, y}; + if (!screenCode().contains(screenKey) || m_screenFullStatus.value(screenKey) || !isValid(screenKey, pos)) { + if (moreIcon.contains(screenKey)) { + moreIcon.find(screenKey)->append(item); + } else { + moreIcon.insert(screenKey, QStringList() << item); + } + } else { + if (!add(screenKey, pos, item)) { + continue; + } + } + existItems.remove(item); + } + } + settings->endGroup(); + } + lk.unlock(); + + for (int key : moreIcon.keys()) { + foreach (QString item, moreIcon.value(key)) { + QPair emptyPos = getEmptyPos(key); + add(emptyPos.first, emptyPos.second, item); + } + } + + for (const QString &item : orderedItems) { + //已经有位子的,跳过 + if (!existItems.contains(item)) + continue; + + QPair empty_pos{ takeEmptyPos() }; + add(empty_pos.first, empty_pos.second, item); + } + } + + void syncAllProfile() + { + if (allItems().isEmpty()) + return; + + if (m_bSingleMode) { + syncProfile(1); + } else { + foreach (int screenNum, positionProfiles.keys()) { + syncProfile(screenNum); + } + + updateProfiles(); + } + } + + void readProfiles() + { + positionProfiles.clear(); + QMutexLocker lk(Config::instance()->mutex()); + auto settings = Config::instance()->settings(); + settings->beginGroup(Config::keyProfile); + for (QString &key : settings->allKeys()) { + positionProfiles.insert(key.toInt(), settings->value(key).toString()); + } + settings->endGroup(); + } + + void updateProfiles() + { + positionProfiles.clear(); + QStringList keys; + QVariantList values; + + QList screens = screenCode(); + foreach (int index, screens) { + positionProfiles.insert(index, QString("Screen_%1").arg(index)); + keys.append(QString::fromStdString(std::to_string(index))); + values.append(QString("Screen_%1").arg(index)); + } + + Config::instance()->removeConfig(Config::keyProfile, ""); + Config::instance()->setConfigList(Config::keyProfile, keys, values); + } + + inline bool isValid(int screenNum, QPoint pos) const + { + auto coordInfo = screensCoordInfo.value(screenNum); + return coordInfo.first > pos.x() && coordInfo.second > pos.y() + && pos.x() >= 0 && pos.y() >= 0; + } + + inline QPoint overlapPos(int screenNum) const + { + auto coordInfo = screensCoordInfo.value(screenNum); + return QPoint(coordInfo.first - 1, coordInfo.second - 1); + } + + inline QPoint gridPosAt(int screenNum, int index) const + { + auto coordHeight = screensCoordInfo.value(screenNum).second; + auto x = index / coordHeight; + auto y = index % coordHeight; + return QPoint(x, y); + } + + inline int indexOfGridPos(int screenNum, const QPoint &pos) const + { + //return pos.x() * coordHeight + pos.y(); + auto oneScreenCoord = screensCoordInfo.value(screenNum); + if (0 == oneScreenCoord.first) + return 0; + else { + return pos.x() * oneScreenCoord.second + pos.y(); + } + } + + QPair takeEmptyPos() + { + //返回空位屏以及编号 + QPair posPair; + //if(-1 != emptyScreenNum){ + for (int emptyScreenNum : screenCode()) { //todo 优化效率 + auto cellStatus = m_cellStatus.value(emptyScreenNum); + for (int i = 0; i < cellStatus.size(); ++i) { + if (!cellStatus[i]) { + //cellStatus[i] = true; + posPair.first = emptyScreenNum; + posPair.second = gridPosAt(emptyScreenNum, i); + return posPair; + } + } + } + + if (!m_cellStatus.isEmpty()) { + posPair.first = screenCode().last(); + posPair.second = overlapPos(posPair.first); + } + return posPair; + } + + QPair getEmptyPos(int screenNum) + { + QPair emptyPosPair; + if (screenNum <= 0) { + return emptyPosPair; + } + + if (getEmptyPos(screenNum, false, emptyPosPair.second)) { + emptyPosPair.first = screenNum; + return emptyPosPair; + } + + for (int screenIndex = screenNum - 1; screenIndex > 0; --screenIndex) { + if (getEmptyPos(screenIndex, true, emptyPosPair.second)) { + emptyPosPair.first = screenIndex; + return emptyPosPair; + } + } + + for (int screenIndex = screenNum + 1; screenIndex <= screenCode().size(); ++screenIndex) { + if (getEmptyPos(screenIndex, false, emptyPosPair.second)) { + emptyPosPair.first = screenIndex; + return emptyPosPair; + } + } + + if (!m_cellStatus.isEmpty()) { + emptyPosPair.first = screenCode().last(); + emptyPosPair.second = overlapPos(screenCode().last()); + } + return emptyPosPair; + } + + bool getEmptyPos(int screenNum, bool isRightTop, QPoint &resultPos) + { + if (!m_screenFullStatus.contains(screenNum) || m_screenFullStatus.value(screenNum) + || !m_cellStatus.contains(screenNum) || !screensCoordInfo.contains(screenNum)) { + return false; + } + + auto cellStatus = m_cellStatus.value(screenNum); + + if (isRightTop) { + QPair screenSize = screensCoordInfo.value(screenNum); + for (int xIndex = screenSize.first - 1; xIndex >= 0; --xIndex) { + for (int yIndex = 0; yIndex < screenSize.second; ++yIndex) { + int rightTopIndex = xIndex * screenSize.second + yIndex; + if (rightTopIndex < cellStatus.size() && !cellStatus[rightTopIndex]) { + resultPos = QPoint(xIndex, yIndex); + return true; + } + } + } + } else { + for (int index = 0; index < cellStatus.size(); ++index) { + if (!cellStatus[index]) { + resultPos = gridPosAt(screenNum, index); + return true; + } + } + } + + return false; + } + + bool setCellStatus(int screenNum, int index, bool state) + { + if (!m_cellStatus.contains(screenNum)) + return false; + + if (m_cellStatus.value(screenNum).length() <= index || index < 0) { + return false; + } + + auto cellStatusItor = m_cellStatus.find(screenNum); + cellStatusItor.value()[index] = state; + + updateScreenFullStatus(screenNum); + return true; + } + + void updateScreenFullStatus(int screenNum) + { + auto cellStatus = m_cellStatus.value(screenNum); + for (int index = 0; index < cellStatus.size(); ++index) { + if (!cellStatus[index]) { + m_screenFullStatus.find(screenNum).value() = false; + return; + } + } + + m_screenFullStatus.find(screenNum).value() = true; + } + + bool add(int screenNum, QPoint pos, const QString &itemId) + { + if (itemId.isEmpty()) { + qCritical() << "add empty item"; // QVector.value() may retruen an empty QString + return false; + } else if (m_itemGrids.value(screenNum).contains(itemId)) { + qCritical() << "add" << itemId << "failed." + << m_itemGrids.value(screenNum).value(itemId) << "grid exist item"; + return false; + } + + if (m_gridItems.value(screenNum).contains(pos)) { + if (pos != overlapPos(screenNum)) { + qCritical() << "add" << itemId << "failed." + << pos << "grid exist item in screenNun " << screenNum << "-" << m_gridItems.value(screenNum).value(pos); + return false; + } else { + if (!m_overlapItems.contains(itemId)) { + m_overlapItems << itemId; + return true; + } + return false; + } + } + + if (!isValid(screenNum, pos)) { + return false; + } + + if (m_gridItems.end() != m_gridItems.find(screenNum)) { + m_gridItems.find(screenNum)->insert(pos, itemId); + } + if (m_itemGrids.end() != m_itemGrids.find(screenNum)) { + m_itemGrids.find(screenNum)->insert(itemId, pos); + } + + int index = indexOfGridPos(screenNum, pos); + return setCellStatus(screenNum, index, true); + } + + QPair generateProfileConfigVariable(int screenNum) + { + //根据屏幕编号获取对应屏幕图标信息 + QStringList keyList; + QVariantList valueList; + QMap onceScreenGridItems = m_gridItems.value(screenNum); + for (auto pos : onceScreenGridItems.keys()) { + keyList << positionKey(pos); + valueList << onceScreenGridItems.value(pos); + } + + return QPair(keyList, valueList); + } + + void syncProfile(int screenNum) + { + QPair kvList = generateProfileConfigVariable(screenNum); + //positionProfile需要调整一下,添加上屏幕编号 :Position_%1_%2x%3 + QString screenPositionProfile; + if (m_bSingleMode) { + screenPositionProfile = QString("SingleScreen");//单一桌面模式和扩展桌面模式需要独立保存桌面项目位置配置文件,以便两种模式互相切换时仍然完好如初 + } else { + screenPositionProfile = QString("Screen_%1").arg(screenNum); + } + + Config::instance()->removeConfig(screenPositionProfile, ""); + Config::instance()->setConfigList(screenPositionProfile, kvList.first, kvList.second); + } + + bool remove(int screenNum, QPoint pos, const QString &id) + { + //m_overlapItems 重叠items + m_overlapItems.removeAll(id); + if (!m_itemGrids.value(screenNum).contains(id)) { + qDebug() << "can not remove" << pos << id; + return false; + } + + auto tempGridItemsItor = m_gridItems.find(screenNum); + auto tempItemGridsItor = m_itemGrids.find(screenNum); + tempGridItemsItor->remove(pos); + tempItemGridsItor->remove(id); + + auto usageIndex = indexOfGridPos(screenNum, pos); + + if (!m_cellStatus.contains(screenNum)) + return false; + + setCellStatus(screenNum, usageIndex, false); + return true; + } + + void resetGridSize(int screenNum, int w, int h) + { + if (!screensCoordInfo.contains(screenNum)) + return; + + auto coordInfo = screensCoordInfo.find(screenNum); + Q_ASSERT(!(coordInfo.value().second == h && coordInfo.value().first == w)); + coordInfo.value().first = w; + coordInfo.value().second = h; + + createProfile(); + } + + inline void setWhetherShowHiddenFiles(bool value)noexcept + { + m_whetherShowHiddenFiles.store(value, std::memory_order_release); + } + + inline bool getWhetherShowHiddenFiles()noexcept + { + return m_whetherShowHiddenFiles.load(std::memory_order_consume); + } + + inline QList screenCode() const + { + QList screenOrder = screensCoordInfo.keys(); + qSort(screenOrder.begin(), screenOrder.end()); + return screenOrder; + } + + //必须在screensCoordInfo改变前获取,即resetGridSize前获取 + QStringList allItems() const + { + QStringList items; + auto screens = screenCode(); + for (int num : screens) { + auto cells = m_cellStatus.value(num); + auto gridItems = m_gridItems.value(num); + for (int i = 0; i < cells.size(); ++i) { + if (cells.value(i)) { + QPoint pos = gridPosAt(num, i); + const QString &item = gridItems.value(pos); + items << item; + } + } + } + items << m_overlapItems; + return items; + } + + void reAutoArrage() + { + QStringList items = allItems(); + clear(); + arrange(items); + } +public: + QStringList m_overlapItems; + QList m_allItems; + QMap> m_gridItems; + QMap> m_itemGrids; + //newer + QMap m_screenFullStatus;//屏幕图标状态 + QMap> m_cellStatus;//> + QMap positionProfiles; + QMap> screensCoordInfo; //> + bool autoArrange; + bool autoMerge = false; + int createProfileTime{0}; + std::atomic m_whetherShowHiddenFiles{ false }; + bool m_bSingleMode = true; + bool m_doneInit{false}; + DUrl m_currentVirtualUrl{""};//保留当前屏幕上的扩展情况,用于插拔屏和分辨率变化等重新刷新图标位置 + DGioSettings *m_desktopSettings{nullptr}; + QStringList m_gsettings; +}; + +GridManager::GridManager(): d(new GridManagerPrivate) +{ + bool showHidden = DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowedHiddenFiles).toBool(); + setWhetherShowHiddenFiles(showHidden); + //gsetting配置发生变化 + connect(d->m_desktopSettings, &DGioSettings::valueChanged, this, [this](const QString & key, const QVariant & value) { + Q_UNUSED(value) + QStringList desktopIconKey{"desktop-computer", "desktop-trash", "desktop-home-directory"}; + if (desktopIconKey.contains(key)) + emit this->sigSyncOperation(soGsettingUpdate); + }); +} + +GridManager::~GridManager() +{ + +} + +DUrl GridManager::getInitRootUrl() +{ + setAutoMerge(d->autoMerge); + if (d->autoMerge) { + //刷新虚拟路径时是先查看是否已有展开状态,即使是初始化也得先检查 + DUrl virtualExpandUrl = GridManager::instance()->getCurrentVirtualExpandUrl(); + if (virtualExpandUrl.fragment().isEmpty()) { + return DUrl(DFMMD_ROOT MERGEDDESKTOP_FOLDER); + } else { + return virtualExpandUrl; + } + + } else { + // sa + QString desktopPath = QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first(); + DUrl desktopUrl = DUrl::fromLocalFile(desktopPath); + + if (!QDir(desktopPath).exists()) { + QDir::home().mkpath(desktopPath); + } + + return desktopUrl; + } +} + +void GridManager::initGridItemsInfos() +{ + DUrl fileUrl = getInitRootUrl(); + QScopedPointer tempModel(new DFileSystemModel(nullptr)); + + //设置是否显示隐藏文件 + auto filters = tempModel->filters(); + filters = GridManager::instance()->getWhetherShowHiddenFiles() ? + filters | QDir::Hidden : filters & ~QDir::Hidden; + tempModel->setFilters(filters); + qDebug() << "desktop init filters " << filters; + + QList infoList = DFileService::instance()->getChildren(this, fileUrl, QStringList(), tempModel->filters()); + d->clear(); + + //设置排序 + DFileSystemModel::Roles sortRole = static_cast(Config::instance()->getConfig(Config::groupGeneral, Config::keySortBy, DFileSystemModel::FileMimeTypeRole).toInt()); + Qt::SortOrder sortOrder = Config::instance()->getConfig(Config::groupGeneral, Config::keySortOrder).toInt() == Qt::AscendingOrder ? + Qt::AscendingOrder : Qt::DescendingOrder; + + qDebug() << "sort rules" << sortRole << sortOrder; + { + QPoint sort(sortRole, sortOrder); + emit sigSyncOperation(soSort, sort); + } + + if (!d->m_doneInit) { + d->m_doneInit = true; + //todo:考虑用此变量做刷新时的自动整理优化的,不太理想,后续优化看能否有更好的方式 + //d->m_allItems = infoList; + } + if (GridManager::instance()->autoMerge()) { + GridManager::instance()->initAutoMerge(infoList); + } +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + else if (GridManager::instance()->autoArrange()) { + QModelIndex index = tempModel->setRootUrl(fileUrl); + DAbstractFileInfoPointer root = tempModel->fileInfo(index); + QTime t; + if (root != nullptr) { + DAbstractFileInfo::CompareFunction sortFun = root->compareFunByColumn(sortRole); + qDebug() << "DAbstractFileInfo::CompareFunction " << (sortFun != nullptr); + t.start(); + if (sortFun) { + qSort(infoList.begin(), infoList.end(), [sortFun, sortOrder](const DAbstractFileInfoPointer & node1, const DAbstractFileInfoPointer & node2) { + return sortFun(node1, node2, sortOrder); + }); + } + qDebug() << "sort complete time " << t.elapsed(); + } + QStringList list; + for (const DAbstractFileInfoPointer &df : infoList) { + list << df->fileUrl().toString(); + } + qDebug() << "sorted desktop items num" << list.size() << " time " << t.elapsed(); + initArrage(list); + } +#endif + else { + QModelIndex index = tempModel->setRootUrl(fileUrl); + DAbstractFileInfoPointer root = tempModel->fileInfo(index); + QTime t; + if (root != nullptr) { + DAbstractFileInfo::CompareFunction sortFun = root->compareFunByColumn(sortRole); + qDebug() << "DAbstractFileInfo::CompareFunction " << (sortFun != nullptr); + t.start(); + if (sortFun) { + qSort(infoList.begin(), infoList.end(), [sortFun, sortOrder](const DAbstractFileInfoPointer & node1, const DAbstractFileInfoPointer & node2) { + return sortFun(node1, node2, sortOrder); + }); + } + qDebug() << "sort complete time " << t.elapsed(); + } + + //顺序 + QStringList list; + //加载配置文件位置信息,此加载应当加载所有,通过add来将不同屏幕图标信息加载到m_gridItems和m_itemGrids + QHash indexHash; + + for (const DAbstractFileInfoPointer &df : infoList) { + auto path = df->fileUrl(); + if (!GridManager::instance()->desktopFileShow(path, true)) + continue; + list << path.toString(); + indexHash.insert(path.toString(), false); + } + sortMainDesktopFile(list, sortRole, sortOrder); //按类型排序的特殊处理 + qDebug() << "sorted desktop items num" << list.size() << " time " << t.elapsed(); + + //初始化Profile,用实际地址的文件去匹配图标位置(自动整理则图标顺延展开,自定义则按照配置文件对应顺序) + d->createProfile(); + d->loadProfile(list, indexHash); +#ifndef USE_SP2_AUTOARRAGE + if (GridManager::instance()->autoArrange()) { + d->arrange(d->allItems()); + } +#endif + delaySyncAllProfile(); + } + //fixbug81490 栅格数据更新完成后,需要更新扩展显示图标的区域 + emit sigSyncOperation(soExpandItemUpdate); +} + +void GridManager::initAutoMerge(const QList &items) +{ + d->clear(); + QStringList list; + for (const DAbstractFileInfoPointer &df : items) { + list << df->fileUrl().toString(); + } + d->autoMergeItems(list); + emit sigSyncOperation(soUpdate); +} + + +void GridManager::initArrage(const QStringList &items) +{ + d->clear(); + d->arrange(items); + if (m_needRenameItem.isEmpty()) //经过排序后,需要打开重命名 + emit sigSyncOperation(soUpdate); + else { + emit sigSyncOperation(soUpdate); + emit sigSyncOperation(soRename, m_needRenameItem); + m_needRenameItem.clear(); //处理后清除 + } +} + +void GridManager::initCustom(const QStringList &orderedItems, const QHash &indexHash) +{ + clear(); + d->loadProfile(orderedItems, indexHash); + delaySyncAllProfile(); +} + +void GridManager::initCustom(QStringList &items) +{ + for (auto &one : d->m_gsettings) { + DUrl tempUrl(one); + if (!GridManager::instance()->desktopFileShow(tempUrl, true)) + items.removeOne(one); + } + + QHash indexHash; + for (const QString &item : items) { + indexHash.insert(item, false); + } + + initCustom(items, indexHash); +} + +bool GridManager::add(int screenNum, const QString &id) +{ + Q_UNUSED(screenNum) + DUrl tempUrl(id); + if (!GridManager::instance()->desktopFileShow(tempUrl, true)) + return true; + for (int screenNum : d->screenCode()) { + if (d->m_itemGrids.value(screenNum).contains(id)) { + qWarning() << "item exist item" << screenNum << id; + return false; + } + } + + QPair posPair{ d->takeEmptyPos() }; + return add(posPair.first, posPair.second, id); +} + +bool GridManager::add(int screenNum, QPoint pos, const QString &id) +{ + qDebug() << "add" << pos << id; + auto ret = d->add(screenNum, pos, id); +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + if (ret && !autoMerge() && !autoArrange()) { +#else + if (ret && !autoMerge()) { +#endif + d->syncProfile(screenNum); + } + + return ret; +} +bool GridManager::move(int screenNum, const QStringList &selecteds, const QString ¤t, int x, int y) +{ + auto currentPos = d->m_itemGrids.value(screenNum).value(current); + auto destPos = QPoint(x, y); + auto offset = destPos - currentPos; + + QList originPosList; + QList destPosList; + // check dest is empty; + auto destPosMap = d->m_gridItems[screenNum]; + auto destUsedGrids = d->m_cellStatus[screenNum]; + for (auto &id : selecteds) { + auto oldPos = d->m_itemGrids.value(screenNum).value(id); + originPosList << oldPos; + destPosMap.remove(oldPos); + destUsedGrids[d->indexOfGridPos(screenNum, oldPos)] = false; + auto tempDestPos = oldPos + offset; + destPosList << tempDestPos; + } + + bool conflict = false; + for (auto pos : destPosList) { + if (destPosMap.contains(pos) || !d->isValid(screenNum, pos)) { + conflict = true; + break; + } + } + + // no need to resize + if (conflict) { + auto selectedHeadCount = selecteds.indexOf(current); + // find free grid before destPos + auto destIndex = d->indexOfGridPos(screenNum, destPos); + + QList emptyIndexList; + + for (int i = 0; i < d->cellCount(screenNum); ++i) { + if (false == destUsedGrids.value(i)) { + emptyIndexList << i; + } + } + auto destGridHeadCount = emptyIndexList.indexOf(destIndex); + + Q_ASSERT(emptyIndexList.length() >= selecteds.length()); + + auto startIndex = emptyIndexList.indexOf(destIndex) - selectedHeadCount; + if (destGridHeadCount < selectedHeadCount) { + startIndex = 0; + } + auto destTailCount = emptyIndexList.length() - destGridHeadCount; + auto selectedTailCount = selecteds.length() - selectedHeadCount; + if (destTailCount <= selectedTailCount) { + startIndex = emptyIndexList.length() - selecteds.length(); + } + + destPosList.clear(); + + startIndex = emptyIndexList.value(startIndex); + for (int i = startIndex; i < d->cellCount(screenNum); ++i) { + if (false == destUsedGrids.value(i)) { + destPosList << d->gridPosAt(screenNum, i); + } + } + } + + for (int i = 0; i < selecteds.length(); ++i) { + if (contains(screenNum, selecteds.value(i))) { + remove(screenNum, selecteds.value(i)); + } + } + for (int i = 0; i < selecteds.length(); ++i) { + QPoint point{ destPosList.value(i) }; + bool ret = add(screenNum, point, selecteds.value(i)); + if (!ret) { + d->m_overlapItems << selecteds.value(i); +// auto fPos = forwardFindEmpty(screenNum,point); +// add(fPos.first, fPos.second, selecteds.value(i)); + } + } + + return true; +} + +bool GridManager::move(int fromScreen, int toScreen, const QStringList &selectedIds, const QString &itemId, int x, int y) +{ + QPoint currentPos = d->m_itemGrids.value(fromScreen).value(itemId); + QPoint destPos = QPoint(x, y); + QPoint offset = destPos - currentPos; + + QList originPosList; + QList destPosList; + // check dest is empty; + QMap &destPosMap = d->m_gridItems[toScreen]; + + //源 + QMap &orgPosMap = d->m_gridItems[fromScreen]; + QMap &orgItemMap = d->m_itemGrids[fromScreen]; + QVector &orgUsedGrids = d->m_cellStatus[fromScreen]; + + QStringList overflowItemList; + QStringList sortItems = d->rangeItems(fromScreen, selectedIds); + //移除源 + for (const QString &id : sortItems) { + QPoint oldPos = orgItemMap.value(id); + originPosList << oldPos; + orgPosMap.remove(oldPos); + orgItemMap.remove(id); + orgUsedGrids[d->indexOfGridPos(fromScreen, oldPos)] = false; + + auto tempDestPos = oldPos + offset; + destPosList << tempDestPos; + } + + bool conflict = false; + for (auto pos : destPosList) { + if (destPosMap.contains(pos) || !d->isValid(toScreen, pos)) { + conflict = true; + break; + } + } + + // no need to resize + if (conflict) { + QVector &destUsedGrids = d->m_cellStatus[toScreen]; + auto selectedHeadCount = sortItems.indexOf(itemId); + // find free grid before destPos + auto destIndex = d->indexOfGridPos(toScreen, destPos); + + QList emptyIndexList; + + for (int i = 0; i < d->cellCount(toScreen); ++i) { + if (false == destUsedGrids.value(i)) { + emptyIndexList << i; + } + } + auto destGridHeadCount = emptyIndexList.indexOf(destIndex); + + if (emptyIndexList.length() < sortItems.length()) { + int overflowCnt = sortItems.length() - emptyIndexList.length(); + for (int index = 0; index < overflowCnt; ++index) { + overflowItemList.append(sortItems.takeLast()); + } + } + + Q_ASSERT(emptyIndexList.length() >= sortItems.length()); + auto startIndex = emptyIndexList.indexOf(destIndex) - selectedHeadCount; + if (destGridHeadCount < selectedHeadCount) { + startIndex = 0; + } + auto destTailCount = emptyIndexList.length() - destGridHeadCount; + auto selectedTailCount = sortItems.length() - selectedHeadCount; + if (destTailCount <= selectedTailCount) { + startIndex = emptyIndexList.length() - sortItems.length(); + } + + destPosList.clear(); + + startIndex = emptyIndexList.value(startIndex); + for (int i = startIndex; i < d->cellCount(toScreen); ++i) { + if (false == destUsedGrids.value(i)) { + destPosList << d->gridPosAt(toScreen, i); + } + } + } + + for (int i = 0; i < sortItems.length(); ++i) { + if (contains(toScreen, sortItems.value(i))) { + remove(toScreen, sortItems.value(i)); + } + } + + for (int i = 0; i < sortItems.length(); ++i) { + QPoint point{ destPosList.value(i) }; + add(toScreen, point, sortItems.value(i)); + } + + for (int i = 0; i < overflowItemList.length(); ++i) { + add(toScreen, overflowItemList.value(i)); + } + + + //保存源屏配置 +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + if (!autoMerge() && !autoArrange()) { +#else + if (!autoMerge()) { +#endif + d->syncProfile(fromScreen); + } + + emit sigSyncOperation(soHideEditing); + return true; +} + + +bool GridManager::remove(int screenNum, const QString &id) +{ + if (d->m_itemGrids.value(screenNum).contains(id)) { + auto pos = d->m_itemGrids.value(screenNum).value(id); + bool ret = remove(screenNum, pos, id); + qDebug() << screenNum << id << pos << ret; + return ret; + } else if (d->m_overlapItems.contains(id)) { + d->m_overlapItems.removeAll(id); + qDebug() << screenNum << id << "overlapItems" << true; + return true; + } + return false; +} + +void GridManager::popOverlap() +{ + if (!d->m_overlapItems.isEmpty()) { + auto itemId = d->m_overlapItems.takeFirst(); + auto pos = d->takeEmptyPos(); + add(pos.first, pos.second, itemId); + } +} + +int GridManager::addToOverlap(const QString &itemId) +{ + if (d->m_overlapItems.contains(itemId)) + return 1; + + for (auto coor : d->m_itemGrids.values()) { + if (coor.contains(itemId)) + return -1; + } + + d->m_overlapItems << itemId; + return 0; +} + +int GridManager::emptyPostionCount(int screenNum) const +{ + return d->m_cellStatus.value(screenNum).size() - d->m_gridItems.value(screenNum).size(); +} + +bool GridManager::remove(int screenNum, QPoint pos, const QString &id) +{ + auto ret = d->remove(screenNum, pos, id); +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + if (ret && !(autoMerge() || autoArrange())) { +#else + if (ret && !autoMerge()) { +#endif + d->syncProfile(screenNum); + } + return ret; +} + +bool GridManager::clear() +{ + d->clear(); + return true; +} + +void GridManager::restCoord() +{ + d->screensCoordInfo.clear(); + d->m_gridItems.clear(); + d->m_itemGrids.clear(); + d->m_cellStatus.clear(); + d->m_overlapItems.clear(); + d->m_screenFullStatus.clear(); +} + +void GridManager::addCoord(int screenNum, QPair coordInfo) +{ + qDebug() << "add screen" << screenNum << coordInfo; + //todo:若在add的时候存在了对应的num,考虑要不要直接更新value,而不是return + if (d->screensCoordInfo.contains(screenNum)) + return; + //初始化栅格 + d->screensCoordInfo.insert(screenNum, coordInfo); + if (!d->m_gridItems.contains(screenNum)) { + QMap gridItem; + d->m_gridItems.insert(screenNum, gridItem); + } + if (!d->m_itemGrids.contains(screenNum)) { + QMap itemGrid; + d->m_itemGrids.insert(screenNum, itemGrid); + } +// if(!d->m_cellStatus.contains(screenNum)){ +// QVector cellStatus; +// cellStatus.resize(coordInfo.first * coordInfo.second); +// d->m_cellStatus.insert(screenNum, cellStatus); +// } +} + +QString GridManager::firstItemId(int screenNum) +{ + for (int i = 0; i < d->m_cellStatus.value(screenNum).length(); ++i) { + if (d->m_cellStatus.value(screenNum).value(i)) { + auto pos = d->gridPosAt(screenNum, i); + return itemId(screenNum, pos); + } + } + return ""; +} + +QString GridManager::lastItemId(int screenNum) +{ + auto len = d->m_cellStatus.value(screenNum).length(); + for (int i = 0; i < len; ++i) { + if (d->m_cellStatus.value(screenNum).value(len - 1 - i)) { + auto pos = d->gridPosAt(screenNum, len - 1 - i); + return itemId(screenNum, pos); + } + } + return ""; +} + +QString GridManager::lastItemTop(int screenNum) +{ + auto len = d->m_cellStatus.value(screenNum).length(); + for (int i = 0; i < len; ++i) { + if (d->m_cellStatus.value(screenNum).value(len - 1 - i)) { + auto pos = d->gridPosAt(screenNum, len - 1 - i); + return itemTop(screenNum, pos); + } + } + return ""; +} + +QStringList GridManager::itemIds(int screenNum) +{ + QStringList ids; + for (int i = 0; i < d->m_cellStatus.value(screenNum).length(); ++i) { + if (d->m_cellStatus.value(screenNum).value(i)) { + auto pos = d->gridPosAt(screenNum, i); + ids.append(itemId(screenNum, pos)); + } + } + if (screenNum == d->screenCode().last()) + ids << d->m_overlapItems; + return ids; +} + +QStringList GridManager::allItems() const +{ + return d->allItems(); +} + +bool GridManager::contains(int screebNum, const QString &id) +{ + return d->m_itemGrids.value(screebNum).contains(id) || + (d->screenCode().last() == screebNum && d->m_overlapItems.contains(id)); +} + +QPoint GridManager::position(int screenNum, const QString &id) +{ + if (!d->m_itemGrids.value(screenNum).contains(id)) { + return d->overlapPos(screenNum); + } + + return d->m_itemGrids.value(screenNum).value(id); +} + +bool GridManager::find(const QString &itemId, QPair &pos) +{ + bool ret = false; + auto screenOrder = d->screenCode(); + auto iter = std::find_if(screenOrder.begin(), screenOrder.end(), [this, itemId](const int &screen) { + return contains(screen, itemId); + }); + + if (iter != screenOrder.end()) { + pos.first = *iter; + pos.second = position(*iter, itemId); + ret = true; + } + + return ret; +} + +QString GridManager::itemId(int screenNum, int x, int y) +{ + return d->m_gridItems.value(screenNum).value(QPoint(x, y)); +} + +QString GridManager::itemId(int screenNum, QPoint pos) +{ + return d->m_gridItems.value(screenNum).value(pos); +} + +QString GridManager::itemTop(int screenNum, int x, int y) +{ + return itemTop(screenNum, QPoint(x, y)); +} + +QString GridManager::itemTop(int screenNum, QPoint pos) +{ + if (screenNum == d->screenCode().last() + && pos == d->overlapPos(screenNum) + && !d->m_overlapItems.isEmpty()) { + return d->m_overlapItems.last(); + } + + return itemId(screenNum, pos); +} + +bool GridManager::isEmpty(int screenNum, int x, int y) +{ + auto cellStatus = d->m_cellStatus.value(screenNum); + int pos = d->indexOfGridPos(screenNum, QPoint(x, y)); + if (pos >= cellStatus.size() || pos < 0) + return false; + + return !cellStatus.value(pos); +} + +QStringList GridManager::overlapItems(int screen) const +{ + if (!d->screenCode().empty() && screen == d->screenCode().last()) + return d->m_overlapItems; + + return QStringList(); +} + +bool GridManager::shouldArrange() const +{ + return d->autoArrange || d->autoMerge; +} + +bool GridManager::autoArrange() const +{ + return d->autoArrange; +} + +bool GridManager::autoMerge() const +{ + return d->autoMerge; +} + +bool GridManager::doneInit() const +{ + return d->m_doneInit; +} + +void GridManager::toggleArrange() +{ + d->autoArrange = !d->autoArrange; +} + +void GridManager::setAutoMerge(bool enable) +{ + if (d->autoMerge == enable) return; + d->autoMerge = enable; +} + +void GridManager::toggleAutoMerge() +{ + setAutoMerge(!d->autoMerge); +} + +void GridManager::reArrange() +{ + if (shouldArrange()) { + d->reAutoArrage(); + emit sigSyncOperation(soUpdate); + return; + } +} + +int GridManager::gridCount() const +{ + auto screens = d->screensCoordInfo.values(); + int totalCount = std::accumulate(screens.begin(), screens.end(), 0, [](int total, const QPair &coordInfo) { + return total += coordInfo.first * coordInfo.second; + }); + + return totalCount; +} + +int GridManager::gridCount(int screenNum) const +{ + int totalCount = 0; + if (d->screensCoordInfo.contains(screenNum)) { + auto coordInfo = d->screensCoordInfo.value(screenNum); + totalCount = coordInfo.first * coordInfo.second; + } + return totalCount; +} + +QPair GridManager::forwardFindEmpty(int screenNum, QPoint start) const +{ + QPair emptyPos; + auto size = gridSize(screenNum); + for (int j = start.y(); j < size.height(); ++j) { + if (GridManager::instance()->isEmpty(screenNum, start.x(), j)) { + emptyPos.first = screenNum; + emptyPos.second = QPoint(start.x(), j); + return emptyPos; + } + } + + for (int i = start.x() + 1; i < size.width(); ++i) { + for (int j = 0; j < size.height(); ++j) { + if (GridManager::instance()->isEmpty(screenNum, i, j)) { + emptyPos.first = screenNum; + emptyPos.second = QPoint(i, j); + return emptyPos; + } + } + } + return d->takeEmptyPos(); +} + +QList GridManager::allScreenNum() +{ + return d->screensCoordInfo.keys(); +} + +QSize GridManager::gridSize(int screenNum) const +{ + auto coordInfo = d->screensCoordInfo.value(screenNum); + return QSize(coordInfo.first, coordInfo.second); +} + +void GridManager::updateGridSize(int screenNum, int w, int h) +{ + auto coordInfo = d->screensCoordInfo.value(screenNum); + if (coordInfo.second == h && coordInfo.first == w) { + return; + } + + if (0 == coordInfo.first && 0 == coordInfo.second) { + d->resetGridSize(screenNum, w, h); + return; + } + + QStringList items = d->allItems(); //必须在resetGridSize前获取 + d->resetGridSize(screenNum, w, h); + + if (shouldArrange()) { + d->clear(); + d->arrange(items); +#ifndef USE_SP2_AUTOARRAGE //sp3需求改动 + if (autoArrange()) { + d->syncAllProfile(); + } +#endif + } else { + initCustom(items); + } + emit sigSyncOperation(soUpdate); +} + +GridCore *GridManager::core() +{ + auto core = new GridCore; + core->overlapItems = d->m_overlapItems; + core->gridItems = d->m_gridItems; + core->itemGrids = d->m_itemGrids; + core->m_cellStatus = d->m_cellStatus; + core->screensCoordInfo = d->screensCoordInfo; + return core; +} + +void GridManager::setWhetherShowHiddenFiles(bool value) noexcept +{ + d->setWhetherShowHiddenFiles(value); +} + +bool GridManager::getWhetherShowHiddenFiles() noexcept +{ + return d->getWhetherShowHiddenFiles(); +} + +bool GridManager::getCanvasFullStatus(int screenId) +{ + return d->m_screenFullStatus.value(screenId); +} + +void GridManager::dump() +{ + for (auto key : d->m_gridItems.keys()) { + qDebug() << key << d->m_gridItems.value(key); + } + + for (auto key : d->m_itemGrids.keys()) { + qDebug() << key << d->m_itemGrids.value(key); + } +} + +void GridManager::sortMainDesktopFile(QStringList &list, int role, Qt::SortOrder order) +{ + if (role != DFileSystemModel::FileMimeTypeRole) + return; + QString desktopPath = QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first(); + DUrl desktopUrl = DUrl::fromLocalFile(desktopPath); + QDir dir(desktopUrl.toString()); + + QList> mainDesktop = {{dir.filePath("dde-home.desktop"), false}, + {dir.filePath("dde-trash.desktop"), false}, + {dir.filePath("dde-computer.desktop"), false} + }; + for (auto it = mainDesktop.begin(); it != mainDesktop.end(); ++it) { + if (list.removeOne(it->first)) { + it->second = true; + } + } + + for (auto it = mainDesktop.begin(); it != mainDesktop.end(); ++it) { + if (it->second) { + //升序 + if (order == Qt::AscendingOrder) { + list.push_front(it->first); + }//降序 + else { + list.push_back(it->first); + } + } + } +} + +void GridManager::setDisplayMode(bool single) +{ + d->m_bSingleMode = single; +} + +void GridManager::delaySyncAllProfile(int ms) +{ + static QTimer *syncTimer = nullptr; + qDebug() << "delaySyncAllProfile" << QThread::currentThread() << qApp->thread(); + if (syncTimer != nullptr) { + qDebug() << "reset timer" << syncTimer; + syncTimer->stop(); + delete syncTimer; + syncTimer = nullptr; + } + if (ms < 1) { + d->syncAllProfile(); + } + + syncTimer = new QTimer; + syncTimer->setSingleShot(true); + connect(syncTimer, &QTimer::timeout, this, [ = ]() { + syncTimer->stop(); + d->syncAllProfile(); + }); + syncTimer->start(ms); +} + +void GridManager::setCurrentVirtualExpandUrl(const DUrl url) +{ + d->m_currentVirtualUrl = url; +} + +DUrl GridManager::getCurrentVirtualExpandUrl() +{ + return d->m_currentVirtualUrl; +} + +void GridManager::setCurrentAllItems(const QList &infoList) +{ + d->m_allItems = infoList; +} + +QVariant GridManager::isGsettingShow(const QString &targetkey, const QVariant defaultValue) +{ + if (!d->m_desktopSettings->keys().contains(targetkey)) + return defaultValue; + QVariant tempValue = d->m_desktopSettings->value(targetkey); + if (!tempValue.isValid()) + return defaultValue; + return tempValue.toBool(); +} + +bool GridManager::desktopFileShow(const DUrl &url, const bool defaultValue) +{ + if (!url.isValid()) + return defaultValue; + if (0 == url.fileName().localeAwareCompare("dde-computer.desktop")) { + auto tempComputer = isGsettingShow("desktop-computer", QVariant()); + if (!tempComputer.isValid()) + return defaultValue; + return tempComputer.toBool(); + } + if (0 == url.fileName().localeAwareCompare("dde-trash.desktop")) { + auto tempTrash = isGsettingShow("desktop-trash", QVariant()); + if (!tempTrash.isValid()) + return defaultValue; + return tempTrash.toBool(); + } + if (0 == url.fileName().localeAwareCompare("dde-home.desktop")) { + auto tempHome = isGsettingShow("desktop-home-directory", QVariant()); + if (!tempHome.isValid()) + return defaultValue; + return tempHome.toBool(); + } + return defaultValue; +} + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/presenter/gridmanager.h b/dde-file-manager-5.5.3/src/dde-desktop/presenter/gridmanager.h new file mode 100644 index 0000000..2e97f61 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/presenter/gridmanager.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include +#include +#include +#include + +#include "gridcore.h" +#include "dabstractfileinfo.h" + +#include "../global/coorinate.h" +#include "../global/singleton.h" + +class GridCore; +class GridManagerPrivate; +class GridManager: public QObject, public DDEDesktop::Singleton +{ + Q_OBJECT +public: + enum SyncOperation {soAutoMerge, soRename, soIconSize, soSort + , soHideEditing, soUpdate, soAutoMergeUpdate + , soHidenSwitch, soGsettingUpdate, soExpandItemUpdate + }; + DUrl getInitRootUrl(); + void initGridItemsInfos(); + void initAutoMerge(const QList &items); + void initArrage(const QStringList &items); + void initCustom(QStringList &items); + void initCustom(const QStringList &orderedItems, const QHash &indexHash); + + bool add(int screenNum, QPoint pos, const QString &id); + bool add(int screenNum, const QString &id); + bool move(int screenNum, const QStringList &selecteds, const QString ¤t, int x, int y); + bool move(int fromScreen, int toScreen, const QStringList &selectedIds, const QString &itemId, int x, int y); + bool remove(int screenNum, const QString &id); + void popOverlap(); //弹出堆叠 + int addToOverlap(const QString &itemId); + int emptyPostionCount(int screenNum) const; + + bool clear(); + void restCoord(); + + void addCoord(int screenNum, QPair coordInfo); + QString firstItemId(int screenNum); + QString lastItemId(int screenNum); + QString lastItemTop(int screenNum); + QStringList itemIds(int screenNum); + QStringList allItems() const; + + bool contains(int screebNum, const QString &id); + QPoint position(int screenNum, const QString &id); + bool find(const QString &itemId, QPair &pos); + QString itemId(int screenNum, int x, int y); + QString itemId(int screenNum, QPoint pos); + QString itemTop(int screenNum, int x, int y); //调整显示方式,如果是堆叠,则将最后一个pos的换成堆叠的最后一个项目 + QString itemTop(int screenNum, QPoint pos); + bool isEmpty(int screenNum, int x, int y); + + QStringList overlapItems(int screen) const; + bool shouldArrange() const; + bool autoArrange() const; + bool autoMerge() const; + bool doneInit()const; + void toggleArrange(); + void setAutoMerge(bool enable = true); + void toggleAutoMerge(); + void reArrange(); + + int gridCount() const; + int gridCount(int screenNum) const; + QPair forwardFindEmpty(int screenNum, QPoint start) const; + QList allScreenNum(); + QSize gridSize(int screenNum) const; + void updateGridSize(int screenNum, int w, int h); + + GridCore *core(); + + void setWhetherShowHiddenFiles(bool value)noexcept; + bool getWhetherShowHiddenFiles()noexcept; + + bool getCanvasFullStatus(int screenId); + + void setDisplayMode(bool single); + void delaySyncAllProfile(int ms = 100); + + void setCurrentVirtualExpandUrl(const DUrl url); + DUrl getCurrentVirtualExpandUrl(); + void setCurrentAllItems(const QList &infoList); + QVariant isGsettingShow(const QString &targetkey, const QVariant defaultValue); + bool desktopFileShow(const DUrl &url, const bool defaultValue); + +public: + void dump(); + static void sortMainDesktopFile(QStringList &list, int role, Qt::SortOrder order); + QString m_needRenameItem; //用于排完顺序后打开编辑框 +signals: + void sigSyncOperation(int so, QVariant var = QVariant()); + void sigSyncSelection(class CanvasGridView *, DUrlList url); +protected: + //bool remove(int screenNum, int x, int y, const QString &itemId); + bool remove(int screenNum, QPoint pos, const QString &id); + + friend class DDEDesktop::Singleton; + + GridManager(); + ~GridManager(); + + QScopedPointer d; +}; diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreen.cpp b/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreen.cpp new file mode 100644 index 0000000..6e599f7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreen.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ + +#include "abstractscreen.h" + +AbstractScreen::AbstractScreen(QObject *parent) : QObject(parent) +{ + +} + +AbstractScreen::~AbstractScreen() +{ + +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreen.h b/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreen.h new file mode 100644 index 0000000..6d5a986 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreen.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ + +#ifndef ABSTRACTSCREEN_H +#define ABSTRACTSCREEN_H + +#include +#include + +class AbstractScreen : public QObject +{ + Q_OBJECT +public: + explicit AbstractScreen(QObject *parent = nullptr); + virtual ~AbstractScreen(); + virtual QString name() const = 0; + virtual QRect geometry() const = 0; + virtual QRect availableGeometry() const = 0; + virtual QRect handleGeometry() const = 0; +signals: + void sigGeometryChanged(const QRect &); + void sigAvailableGeometryChanged(const QRect &); +public slots: +private: + Q_DISABLE_COPY(AbstractScreen) +}; + +typedef QSharedPointer ScreenPointer; +#endif // ABSTRACTSCREEN_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreenmanager.cpp b/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreenmanager.cpp new file mode 100644 index 0000000..78fc71c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreenmanager.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "abstractscreenmanager.h" +#include "abstractscreenmanager_p.h" + +#include + +ScreenManagerPrivate::ScreenManagerPrivate(AbstractScreenManager *p): q(p) +{ + QObject::connect(&m_eventShot, &QTimer::timeout, q, [=]() { + q->processEvent(); + m_events.clear(); + }); +} + +ScreenManagerPrivate::~ScreenManagerPrivate() +{ +} + +void ScreenManagerPrivate::readyShot(int wait) +{ + m_eventShot.stop(); + qDebug() << "shotting later " << wait; + + if (wait < 1) { + wait = 1; + } + + m_eventShot.setSingleShot(true); + m_eventShot.start(wait); +} + +AbstractScreenManager::AbstractScreenManager(QObject *parent) + : QObject(parent) + ,d(new ScreenManagerPrivate(this)) +{ + +} + +AbstractScreenManager::~AbstractScreenManager() +{ + delete d; +} + +void AbstractScreenManager::appendEvent(AbstractScreenManager::Event e) +{ + qDebug() << "append event" << e << "current size" << (d->m_events.size() + 1); + //收集短时间内爆发出的事件,合并处理,优化响应速度 + d->m_events.insert(e,0); + d->readyShot(100); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreenmanager.h b/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreenmanager.h new file mode 100644 index 0000000..3f90952 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreenmanager.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#ifndef ABSTRACTSCREENMANAGER_H +#define ABSTRACTSCREENMANAGER_H + +#include "abstractscreen.h" +#include +#include + +class ScreenManagerPrivate; +class AbstractScreenManager : public QObject +{ + Q_OBJECT + friend class ScreenManagerPrivate; +public: + enum DisplayMode{Custom = 0,Duplicate,Extend,Showonly}; //显示模式 + enum Event{Screen,Mode,Geometry,AvailableGeometry}; //事件类型 +public: + explicit AbstractScreenManager(QObject *parent = nullptr); + virtual ~AbstractScreenManager(); + virtual ScreenPointer primaryScreen() = 0; + virtual QVector screens() const = 0; //按接入顺序 + virtual QVector logicScreens() const = 0; //主屏第一,其他按接入顺序 + virtual ScreenPointer screen(const QString &name) const = 0; + virtual qreal devicePixelRatio() const = 0; + virtual DisplayMode displayMode() const = 0; //从dbus获取后台最新mode + virtual DisplayMode lastChangedMode() const = 0; //最后接收到改变后的mode + virtual void reset() = 0; +protected: + void appendEvent(Event); //添加屏幕事件 + virtual void processEvent() = 0; +signals: + void sigScreenChanged(); //屏幕接入,移除 + void sigDisplayModeChanged(); //显示模式改变 + void sigScreenGeometryChanged(); //屏幕分辨率改变 + void sigScreenAvailableGeometryChanged(); //屏幕可用区改变 +protected: + int m_lastMode = -1; + ScreenManagerPrivate *d; +}; + +#endif // ABSTRACTSCREENMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreenmanager_p.h b/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreenmanager_p.h new file mode 100644 index 0000000..0b818f4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/abstractscreenmanager_p.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ + +#ifndef SCREENMANAGER_P_H +#define SCREENMANAGER_P_H + +#include "abstractscreenmanager.h" + +#include +#include + +class ScreenManagerPrivate +{ +public: + explicit ScreenManagerPrivate(AbstractScreenManager *p); + ~ScreenManagerPrivate(); + void readyShot(int wait = 50); +public: + QTimer m_eventShot; //延迟处理定时器 + QMultiMap m_events; //事件池 + AbstractScreenManager *q; +}; + +#endif // SCREENMANAGER_P_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/screenhelper.cpp b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenhelper.cpp new file mode 100644 index 0000000..5b62273 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenhelper.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "screenhelper.h" +#include "util/dde/desktopinfo.h" +#include "screenmanager.h" +#include "screenmanagerwayland.h" + +AbstractScreenManager *ScreenHelper::screenManager() +{ + if (DesktopInfo().waylandDectected()){ + static ScreenManagerWayland ins; + return &ins; + } + else { + static ScreenManager ins; + return &ins; + } +} + +ScreenHelper::ScreenHelper() +{ + +} + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/screenhelper.h b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenhelper.h new file mode 100644 index 0000000..4d3768e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenhelper.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ + +#ifndef SCREENHELPER_H +#define SCREENHELPER_H + +#include "abstractscreenmanager.h" + +#define ScreenMrg ScreenHelper::screenManager() +class ScreenHelper +{ +public: + static AbstractScreenManager *screenManager(); +private: + ScreenHelper(); +}; + +#endif // SCREENHELPER_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/screenmanager.cpp b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenmanager.cpp new file mode 100644 index 0000000..f6c8894 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenmanager.cpp @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "screenmanager.h" +#include "screenobject.h" +#include "abstractscreenmanager_p.h" +#include "dbus/dbusdisplay.h" +#include "dbus/dbusdock.h" + + +#include + +#define SCREENOBJECT(screen) dynamic_cast(screen) + + +static bool validPrimaryChanged(const ScreenManager *screenManager) +{ + /*! + * fix bug65195、bug88250 处理只有一个屏幕时,主屏发生改变的情况 + * 拔掉VGA连接线后不会触发该槽函数,通过dbus获取到的主屏名字仍然是VGA,但是Qt会创建虚拟屏幕,名字会是 :0.0 等。 + * 插上HDMI连接线会触发该槽函数,通过dbus获取到主屏的名字是HDMI,通过Qt获取到的也是HDMI, + * 说明Qt已经从虚拟屏幕转换为真实屏幕,再配合屏幕数量只有1个,来发出屏幕改变事件。 + */ + static int times = 0; + if (Q_LIKELY(qApp->screens().count() == 1)) { + // 偶现,通过Qt获取到的屏幕名称可能是虚拟屏幕名称:0.0,需要延迟几百毫秒后才会获取到正确的名称(例如HDMI) + // 规避方案:延迟100毫秒重复获取,超过10秒则放弃获取 + if (Q_UNLIKELY(QString(":0.0") == qApp->primaryScreen()->name())) { + qWarning() << " The screen name obtained by Qt is :0.0, which is re obtained after a delay of 100 milliseconds." + "Current times:" << times; + times++; + if (Q_LIKELY(times < 100)) { + QTimer::singleShot(100, screenManager, &ScreenManager::onPrimaryChanged); + } else { + qCritical() << "Can not get the correct primary name.Current primary name is " << qApp->primaryScreen()->name(); + times = 0; + } + return false; + } else { + qInfo() << "Primary screen changed, the screen name obtained by Qt is " << qApp->primaryScreen()->name() <<".Current times:" << times; + times = 0; + return true; + } + } else { + // 多屏由其余正常逻辑处理,不在本特殊处理范围内 + times = 0; + return false; + } +} + + +ScreenManager::ScreenManager(QObject *parent) + : AbstractScreenManager(parent) +{ + m_display = new DBusDisplay(this); + init(); +} + +ScreenManager::~ScreenManager() +{ + +} + +void ScreenManager::onScreenAdded(QScreen *screen) +{ + if (screen == nullptr || m_screens.contains(screen)) + return; + + ScreenObjectPointer psc(new ScreenObject(screen)); + m_screens.insert(screen, psc); + connectScreen(psc); + + qInfo() << "add screen:" << screen->name(); + //emit sigScreenChanged(); + appendEvent(Screen); +} + +void ScreenManager::onScreenRemoved(QScreen *screen) +{ + auto psc = m_screens.take(screen); + if (psc.get() != nullptr) { + disconnectScreen(psc); + qInfo() << "del screen:" << screen->name(); + //emit sigScreenChanged(); + appendEvent(Screen); + } +} + +void ScreenManager::onPrimaryChanged() +{ + if (validPrimaryChanged(this)) + appendEvent(Screen); +} + +void ScreenManager::onScreenGeometryChanged(const QRect &rect) +{ + Q_UNUSED(rect) + appendEvent(AbstractScreenManager::Geometry); +} + +void ScreenManager::onScreenAvailableGeometryChanged(const QRect &rect) +{ + Q_UNUSED(rect) + appendEvent(AbstractScreenManager::AvailableGeometry); +} + +void ScreenManager::onDockChanged() +{ +// int dockHideMode = DockInfoIns->hideMode(); +// if (3 != dockHideMode) //只处理智能隐藏 +// return ; +#ifdef UNUSED_SMARTDOCK + auto primary = primaryScreen(); + if (primary == nullptr) { + qCritical() << "get primary screen failed"; + return; + } else { + emit sigScreenAvailableGeometryChanged(primary, primary->availableGeometry()); + } +#else + //新增动态dock区功能,dock区不再只是在主屏幕,随鼠标移动 + appendEvent(AbstractScreenManager::AvailableGeometry); +#endif +} + +void ScreenManager::init() +{ + connect(qApp, &QGuiApplication::screenAdded, this, &ScreenManager::onScreenAdded); + connect(qApp, &QGuiApplication::screenRemoved, this, &ScreenManager::onScreenRemoved); + + /*! + * fix bug65195 临时方案。当Qt提供了屏幕名字改变信号后,应该删除该逻辑,改为监听该信号来同步屏幕名称 + * 根因:当只存在一个屏幕时,拔插连接线(VGA和HDMI)时,不会收到Qt的屏幕添加删除信号(Qt会创建虚拟屏幕),桌面不会进行重建。 + * 但是屏幕对象返回的名字已经发生了变化,而Qt暂时没有提供屏幕名字改变的信号,导致程序中通过屏幕名字判断的逻辑都会出现问题。 + * 该bug就是由于画布中保存的名字没有更新,调用显示壁纸屏保设置界面后,找不到对应的屏幕,从而导致位置校正错误。 + */ + connect(m_display, &DBusDisplay::PrimaryChanged, this, &ScreenManager::onPrimaryChanged); + connect(qApp, &QGuiApplication::primaryScreenChanged, this, [this]() { + this->appendEvent(Screen); + }); + + //dock区处理 + connect(DockInfoIns, &DBusDock::FrontendWindowRectChanged, this, &ScreenManager::onDockChanged); + connect(DockInfoIns, &DBusDock::HideModeChanged, this, &ScreenManager::onDockChanged); + //connect(DockInfoIns,&DBusDock::PositionChanged,this, &ScreenManager::onDockChanged); 不关心位子改变,有bug#25148,全部由区域改变触发 + + m_screens.clear(); + for (QScreen *sc : qApp->screens()) { + ScreenPointer psc(new ScreenObject(sc)); + m_screens.insert(sc, psc); + connectScreen(psc); + } + + //依赖现有屏幕数据,必须在屏幕对象初始化后调用 + m_lastMode = displayMode(); +} + +void ScreenManager::connectScreen(ScreenPointer psc) +{ + connect(psc.get(), &AbstractScreen::sigGeometryChanged, this, + &ScreenManager::onScreenGeometryChanged); +//为了解决bug33117, +//在dock时尚模式下,去切换dock位置后,会先触发QScreen的sigAvailableGeometryChanged,此时去获取 +//dock的区域不正确,继而导致桌面栅格计算不正确从而导致自定义下记录的桌面图标无法恢复而异常位置。先暂时屏蔽之。 +//至于此处信号会影响什么地方暂时不可追溯(目前在x86单双屏切换dock均未发现有何影响)。 + +// connect(psc.get(),&AbstractScreen::sigAvailableGeometryChanged,this, +// &ScreenManager::onScreenAvailableGeometryChanged); +} + + +void ScreenManager::disconnectScreen(ScreenPointer psc) +{ + disconnect(psc.get(), &AbstractScreen::sigGeometryChanged, this, + &ScreenManager::onScreenGeometryChanged); + disconnect(psc.get(), &AbstractScreen::sigAvailableGeometryChanged, this, + &ScreenManager::onScreenAvailableGeometryChanged); +} + +ScreenPointer ScreenManager::primaryScreen() +{ + QScreen *primary = qApp->primaryScreen(); + ScreenPointer ret = m_screens.value(primary); + //Q_ASSERT(ret.get() != nullptr); + return ret; +} + +QVector ScreenManager::screens() const +{ + QVector order; + for (QScreen *sc : qApp->screens()) { + if (m_screens.contains(sc)) { + if (sc->geometry().size() == QSize(0, 0)) + qCritical() << "screen error. does it is closed?"; + order.append(m_screens.value(sc)); + } + } + return order; +} + +QVector ScreenManager::logicScreens() const +{ + QVector order; + auto screens = qApp->screens(); + + //调整主屏幕到第一 + QScreen *primary = qApp->primaryScreen(); + screens.removeOne(primary); + screens.push_front(primary); + + for (QScreen *sc : screens) { + if (m_screens.contains(sc)) + order.append(m_screens.value(sc)); + } + return order; +} + +ScreenPointer ScreenManager::screen(const QString &name) const +{ + ScreenPointer ret; + auto screens = m_screens.values(); + auto iter = std::find_if(screens.begin(), screens.end(), [name](const ScreenPointer & sp) { + return sp->name() == name; + }); + + if (iter != screens.end()) { + ret = *iter; + } + + return ret; +} + +qreal ScreenManager::devicePixelRatio() const +{ + return qApp->primaryScreen()->devicePixelRatio(); +} + +AbstractScreenManager::DisplayMode ScreenManager::displayMode() const +{ + QVector allScreen = screens(); + if (allScreen.isEmpty()) + return AbstractScreenManager::Custom; + + if (allScreen.size() == 1) { + return AbstractScreenManager::Showonly; + } else { + //存在两个屏幕坐标不一样则视为扩展,只有所有屏幕坐标相等发生重叠时才视为复制 + const ScreenPointer &screen = allScreen.at(0); + for (int i = 1; i < allScreen.size(); ++i) { + const ScreenPointer &screen2 = allScreen.at(i); + if (screen->geometry().topLeft() != screen2->geometry().topLeft()) { + return AbstractScreenManager::Extend; + } + } + + //所有屏幕的都重叠,则视为复制 + return AbstractScreenManager::Duplicate; + } +} + +AbstractScreenManager::DisplayMode ScreenManager::lastChangedMode() const +{ + return static_cast(m_lastMode); +} + +void ScreenManager::reset() +{ + if (m_display) { + delete m_display; + m_display = nullptr; + } + + m_display = new DBusDisplay(this); + init(); +} + +void ScreenManager::processEvent() +{ + //x11下通过屏幕数据计算显示模式 + //因此需要在每次屏幕变化时计算当前的显示模式 + int mode = displayMode(); + qInfo() << "current mode" << mode << "lastmode" << m_lastMode; + + if (mode != m_lastMode) { + m_lastMode = mode; + d->m_events.insert(AbstractScreenManager::Mode, 0); + } + + //事件优先级。由上往下,背景和画布模块在处理上层的事件已经处理过下层事件的涉及的改变,因此直接忽略 + if (d->m_events.contains(AbstractScreenManager::Mode)) { + emit sigDisplayModeChanged(); + } + else if (d->m_events.contains(AbstractScreenManager::Screen)) { + emit sigScreenChanged(); + } + else if (d->m_events.contains(AbstractScreenManager::Geometry)) { + emit sigScreenGeometryChanged(); + } + else if (d->m_events.contains(AbstractScreenManager::AvailableGeometry)) { + emit sigScreenAvailableGeometryChanged(); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/screenmanager.h b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenmanager.h new file mode 100644 index 0000000..22cace1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenmanager.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#ifndef SCREENMANAGER_H +#define SCREENMANAGER_H + +#include "abstractscreenmanager.h" +#include +#include + +class QScreen; +class ScreenObject; +class DBusDisplay; +class ScreenManager : public AbstractScreenManager +{ + Q_OBJECT +public: + explicit ScreenManager(QObject *parent = nullptr); + ~ScreenManager() override; + ScreenPointer primaryScreen() override; + QVector screens() const override; + QVector logicScreens() const override; + ScreenPointer screen(const QString &name) const override; + qreal devicePixelRatio() const override; + DisplayMode displayMode() const override; + DisplayMode lastChangedMode() const override; + void reset() override; +public slots: + void onPrimaryChanged(); +protected: + void processEvent() override; +protected slots: + void onScreenAdded(QScreen *screen); + void onScreenRemoved(QScreen *screen); + void onScreenGeometryChanged(const QRect &); + void onScreenAvailableGeometryChanged(const QRect &); + void onDockChanged(); +private: + void init(); + void connectScreen(ScreenPointer); + void disconnectScreen(ScreenPointer); +protected: + QMap m_screens; + DBusDisplay *m_display = nullptr; +}; + +#endif // SCREENMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/screenmanagerwayland.cpp b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenmanagerwayland.cpp new file mode 100644 index 0000000..4562608 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenmanagerwayland.cpp @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "screenmanagerwayland.h" +#include "screenobjectwayland.h" +#include "abstractscreenmanager_p.h" +#include "dbus/dbusdisplay.h" +#include "dbus/dbusdock.h" +#include "dbus/dbusmonitor.h" + +#include +#include + +#define SCREENOBJECT(screen) dynamic_cast(screen) +ScreenManagerWayland::ScreenManagerWayland(QObject *parent) + : AbstractScreenManager(parent) +{ + m_display = new DBusDisplay(this); + init(); +} + +ScreenManagerWayland::~ScreenManagerWayland() +{ + if (m_display) { + m_display->deleteLater(); + m_display = nullptr; + } +} + +ScreenPointer ScreenManagerWayland::primaryScreen() +{ + QString primaryName = m_display->primary(); + if (primaryName.isEmpty()) + qCritical() << "get primary name failed"; + + ScreenPointer ret; + for (ScreenPointer sp : m_screens.values()) { + if (sp->name() == primaryName) { + ret = sp; + break; + } + } + if (ret.isNull()) + qWarning() << "get primary from dbus:" < ScreenManagerWayland::screens() const +{ + QVector order; + for (const QDBusObjectPath &path : m_display->monitors()) { + if (m_screens.contains(path.path())) { + ScreenPointer sp = m_screens.value(path.path()); + ScreenObjectWayland *screen = SCREENOBJECT(sp.data()); + if (screen) { + if (screen->enabled()) + order.append(sp); + } else + order.append(sp); + } else { + qWarning() << "unknow monitor:" << path.path() << ".save monitors:" << m_screens.keys(); + } + } + return order; +} + +QVector ScreenManagerWayland::logicScreens() const +{ + QVector order; + QString primaryName = m_display->primary(); + if (primaryName.isEmpty()) + qCritical() << "get primary name failed"; + + //调整主屏幕到第一 + for (const QDBusObjectPath &path : m_display->monitors()) { + if (path.path().isEmpty()) { + qWarning() << "monitor: QDBusObjectPath is empty"; + continue; + } + + if (m_screens.contains(path.path())) { + ScreenPointer sp = m_screens.value(path.path()); + if (sp == nullptr) { + qCritical() << "get scrreen failed path" << path.path(); + continue; + } + if (sp->name() == primaryName) { + order.push_front(sp); + } else { + ScreenObjectWayland *screen = SCREENOBJECT(sp.data()); + if (screen) { + if (screen->enabled()) + order.push_back(sp); + } else + order.push_back(sp); + } + } + } + return order; +} + +ScreenPointer ScreenManagerWayland::screen(const QString &name) const +{ + ScreenPointer ret; + auto screens = m_screens.values(); + auto iter = std::find_if(screens.begin(), screens.end(), [name](const ScreenPointer & sp) { + return sp->name() == name; + }); + + if (iter != screens.end()) { + ret = *iter; + } + + return ret; +} + +qreal ScreenManagerWayland::devicePixelRatio() const +{ + //dbus获取的缩放不是应用值而是设置值,目前还是使用QT来获取 + return qApp->primaryScreen()->devicePixelRatio(); +} + +AbstractScreenManager::DisplayMode ScreenManagerWayland::displayMode() const +{ + auto pending = m_display->GetRealDisplayMode(); + pending.waitForFinished(); + if (pending.isError()) { + qWarning() << "Display GetRealDisplayMode Error:" << pending.error().name() << pending.error().message(); + AbstractScreenManager::DisplayMode ret = AbstractScreenManager::DisplayMode(m_display->displayMode()); + return ret; + } else { + /* + DisplayModeMirror: 1 + DisplayModeExtend: 2 + DisplayModeOnlyOne: 3 + DisplayModeUnknow: 4 + */ + int mode = pending.argumentAt(0).toInt(); + qDebug() << "GetRealDisplayMode resulet" << mode; + if (mode > 0 && mode < 4) + return static_cast(mode); + else + return AbstractScreenManager::Custom; + } +} + +AbstractScreenManager::DisplayMode ScreenManagerWayland::lastChangedMode() const +{ + return static_cast(m_lastMode); +} + +void ScreenManagerWayland::reset() +{ + if (m_display) { + delete m_display; + m_display = nullptr; + } + + m_display = new DBusDisplay(this); + init(); +} + +void ScreenManagerWayland::processEvent() +{ + //事件优先级。由上往下,背景和画布模块在处理上层的事件已经处理过下层事件的涉及的改变,因此直接忽略 + if (d->m_events.contains(AbstractScreenManager::Mode)) { + emit sigDisplayModeChanged(); + } + else if (d->m_events.contains(AbstractScreenManager::Screen)) { + emit sigScreenChanged(); + } + else if (d->m_events.contains(AbstractScreenManager::Geometry)) { + emit sigScreenGeometryChanged(); + } + else if (d->m_events.contains(AbstractScreenManager::AvailableGeometry)) { + emit sigScreenAvailableGeometryChanged(); + } +} + +void ScreenManagerWayland::onMonitorChanged() +{ + QStringList monitors; + //检查新增的屏幕 + for (auto objectPath : m_display->monitors()) { + QString path = objectPath.path(); + if (path.isEmpty()) { + qWarning() << "get monitor path is empty from display"; + continue; + } + + //新增的 + if (!m_screens.contains(path)) { + ScreenPointer sp(new ScreenObjectWayland(new DBusMonitor(path))); + m_screens.insert(path, sp); + connectScreen(sp); + qInfo() << "add monitor:" << path; + } + monitors << path; + } + qDebug() << "get monitors:" << monitors; + + //检查移除的屏幕 + for (const QString &path : m_screens.keys()) { + if (!monitors.contains(path)) { + ScreenPointer sp = m_screens.take(path); + disconnectScreen(sp); + qInfo() << "del monitor:" << path; + } + } + qDebug() << "save monitors:" << m_screens.keys(); + appendEvent(Screen); +} + +void ScreenManagerWayland::onDockChanged() +{ +#ifdef UNUSED_SMARTDOCK + auto screen = primaryScreen(); + if (screen == nullptr) { + qCritical() << "primaryScreen() return nullptr!!!"; + return; + } + emit sigScreenAvailableGeometryChanged(screen, screen->availableGeometry()); +#else + //新增动态dock区功能,dock区不再只是在主屏幕,随鼠标移动 + //emit sigScreenAvailableGeometryChanged(nullptr, QRect()); + appendEvent(AvailableGeometry); +#endif +} + +void ScreenManagerWayland::onScreenGeometryChanged(const QRect &rect) +{ + Q_UNUSED(rect) + appendEvent(Geometry); + + //fix wayland下切换合并/拆分,当主屏的geometry在合并拆分前后没有改变时,不会发送PrimaryRectChanged,而在主线能发送出来。 + //这导致没法判断到显示模式改变,这里补充触发 + emit m_display->PrimaryRectChanged(); +} + +void ScreenManagerWayland::init() +{ + m_screens.clear(); + + //先尝试使用Qt信号,若有问题再使用DBUS的信号 + connect(qApp, &QGuiApplication::screenAdded, this, &ScreenManagerWayland::onMonitorChanged); + connect(m_display, &DBusDisplay::MonitorsChanged, this, &ScreenManagerWayland::onMonitorChanged); + connect(m_display, &DBusDisplay::PrimaryChanged, this, [this]() { + this->appendEvent(Screen); + }); +#ifdef UNUSE_TEMP + connect(m_display, &DBusDisplay::DisplayModeChanged, this, &AbstractScreenManager::sigDisplayModeChanged); +#else + //临时方案, + connect(m_display, &DBusDisplay::DisplayModeChanged, this, [this]() { + //emit sigDisplayModeChanged(); + int mode = m_display->GetRealDisplayMode(); + qInfo() << "deal display mode changed " << mode; + if (m_lastMode == mode) + return; + m_lastMode = mode; + this->appendEvent(Mode); + }); + + //临时方案,使用PrimaryRectChanged信号作为拆分/合并信号 + connect(m_display, &DBusDisplay::PrimaryRectChanged, this, [this]() { + int mode = m_display->GetRealDisplayMode(); + qInfo() << "deal merge and split" << mode << m_lastMode; + if (m_lastMode == mode) + return; + m_lastMode = mode; + //emit sigDisplayModeChanged(); + this->appendEvent(Mode); + }); + + m_lastMode = m_display->GetRealDisplayMode(); +#endif + + //dock区处理 + connect(DockInfoIns, &DBusDock::FrontendWindowRectChanged, this, &ScreenManagerWayland::onDockChanged); + connect(DockInfoIns, &DBusDock::HideModeChanged, this, &ScreenManagerWayland::onDockChanged); + //connect(DockInfoIns,&DBusDock::PositionChanged,this, &ScreenManagerWayland::onDockChanged);不关心位子改变,有bug#25148,全部由区域改变触发 + + //初始化屏幕 + for (auto objectPath : m_display->monitors()) { + const QString path = objectPath.path(); + ScreenPointer sp(new ScreenObjectWayland(new DBusMonitor(path))); + m_screens.insert(path, sp); + connectScreen(sp); + } +} + +void ScreenManagerWayland::connectScreen(ScreenPointer sp) +{ + connect(sp.get(), &AbstractScreen::sigGeometryChanged, this, + &ScreenManagerWayland::onScreenGeometryChanged); +} + +void ScreenManagerWayland::disconnectScreen(ScreenPointer sp) +{ + disconnect(sp.get(), &AbstractScreen::sigGeometryChanged, this, + &ScreenManagerWayland::onScreenGeometryChanged); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/screenmanagerwayland.h b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenmanagerwayland.h new file mode 100644 index 0000000..cab370b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenmanagerwayland.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#ifndef SCREENMANAGERWAYLAND_H +#define SCREENMANAGERWAYLAND_H + +#include "abstractscreenmanager.h" +#include +#include + +class DBusDisplay; +class ScreenManagerWayland : public AbstractScreenManager +{ + Q_OBJECT +public: + explicit ScreenManagerWayland(QObject *parent = nullptr); + ~ScreenManagerWayland() override; + ScreenPointer primaryScreen() override; + QVector screens() const override; + QVector logicScreens() const override; + ScreenPointer screen(const QString &name) const override; + qreal devicePixelRatio() const override; + DisplayMode displayMode() const override; + DisplayMode lastChangedMode() const override; + void reset() override; +protected: + void processEvent() override; +protected slots: + void onMonitorChanged(); + void onDockChanged(); + void onScreenGeometryChanged(const QRect &rect); +private: + void init(); + void connectScreen(ScreenPointer); + void disconnectScreen(ScreenPointer); +protected: + QMap m_screens; //dbus-path - screen + DBusDisplay *m_display = nullptr; +}; + +#endif // SCREENMANAGERWAYLAND_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/screenobject.cpp b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenobject.cpp new file mode 100644 index 0000000..1be7acd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenobject.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "screenobject.h" +#include "dbus/dbusdock.h" + + +#include +#include +#include + +static QRect dealRectRatio(QRect orgRect) +{ + //处理缩放,先不考虑高分屏的特殊处理 + qreal ratio = qApp->primaryScreen()->devicePixelRatio(); + if (ratio != 1.0) + orgRect = QRect(orgRect.x(), orgRect.y() + , static_cast(orgRect.width() / ratio) + , static_cast(orgRect.height() / ratio)); + return orgRect; +} + +ScreenObject::ScreenObject(QScreen *sc, QObject *parent) + : AbstractScreen(parent) + ,m_screen(sc) +{ + init(); +} + +ScreenObject::~ScreenObject() +{ + +} + +QString ScreenObject::name() const +{ + return m_screen->name(); +} + +QRect ScreenObject::geometry() const +{ + return m_screen->geometry(); +} + +QRect ScreenObject::availableGeometry() const +{ + //!QScreen::availableGeometry在刚启动时返回的值是错的,需要拖到下dock区才能正确显示 + //return m_screen->availableGeometry(); + //end + + QRect ret = geometry(); //已经缩放过 + + int dockHideMode = DockInfoIns->hideMode(); + if ( 1 == dockHideMode) {//隐藏 + qInfo() << "dock is Hidden"; + return ret; + } + + DockRect dockrectI = DockInfoIns->frontendWindowRect(); //原始dock大小 + QRect dockrect = dealRectRatio(dockrectI.operator QRect()); //缩放处理 + +#ifndef UNUSED_SMARTDOCK + qreal ratio = qApp->primaryScreen()->devicePixelRatio(); + //bug 52241 + QRect t_rect = handleGeometry(); + + if (!t_rect.contains(dockrectI)) { //使用原始大小判断的dock区所在的屏幕 + qDebug() << "screen:" << name() << " handleGeometry:" << t_rect << " dockrectI:" << dockrectI; + return ret; + } +#endif + + qDebug() << "frontendWindowRect: dockrectI " << QRect(dockrectI); + qDebug() << "dealRectRatio dockrect " << dockrect; + qDebug() << "ScreenObject ret " << ret << name(); + switch (DockInfoIns->position()) { + case 0: //上 + ret.setY(dockrect.bottom()); + qDebug() << "dock on top, availableGeometry" << ret; + break; + case 1: //右 + { + int w = dockrect.left() - ret.left(); + if (w >= 0) + ret.setWidth(static_cast(w / ratio)); //原始大小计算的宽,需缩放处理 + else { + qCritical() << "dockrect.left() - ret.left() is invaild" << w; + } + qDebug() << "dock on right,availableGeometry" << ret; + } + break; + case 2: //下 + { + int h = dockrect.top() - ret.top(); + if (h >= 0) + ret.setHeight(static_cast(h / ratio)); //原始大小计算的高,需缩放处理 + else { + qCritical() << "dockrect.top() - ret.top() is invaild" << h; + } + qDebug() << "dock on bottom,availableGeometry" << ret; + break; + } + case 3: //左 + ret.setX(dockrect.right()); + qDebug() << "dock on left,availableGeometry" << ret; + break; + default: + qCritical() << "dock postion error!" << "and handleGeometry:" << t_rect << " dockrectI:" << dockrectI; + break; + } + return ret; +} + +QRect ScreenObject::handleGeometry() const +{ + return m_screen->handle()->geometry(); +} + +QScreen *ScreenObject::screen() const +{ + return m_screen; +} + +void ScreenObject::init() +{ + connect(m_screen,SIGNAL(geometryChanged(const QRect &)),this,SIGNAL(sigGeometryChanged(const QRect &))); + connect(m_screen,SIGNAL(availableGeometryChanged(const QRect &)),this,SIGNAL(sigAvailableGeometryChanged(const QRect &))); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/screenobject.h b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenobject.h new file mode 100644 index 0000000..2ba9537 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenobject.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#ifndef SCREENOBJECT_H +#define SCREENOBJECT_H + +#include "abstractscreen.h" +#include + +class ScreenObject : public AbstractScreen +{ +public: + ScreenObject(QScreen *sc, QObject *parent = nullptr); + ~ScreenObject() override; + QString name() const override; + QRect geometry() const override; + QRect availableGeometry() const override; + QRect handleGeometry() const override; +public: + QScreen *screen() const; +private: + void init(); +private: + QScreen *m_screen = nullptr; +}; + +typedef QSharedPointer ScreenObjectPointer; +#endif // SCREENOBJECT_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/screenobjectwayland.cpp b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenobjectwayland.cpp new file mode 100644 index 0000000..9d6ae49 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenobjectwayland.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "screenobjectwayland.h" +#include "dbus/dbusmonitor.h" +#include "dbus/dbusdock.h" + +#include +#include + +static QRect dealRectRatio(QRect orgRect) +{ + //处理缩放,先不考虑高分屏的特殊处理 + qreal ratio = qApp->primaryScreen()->devicePixelRatio(); + if (ratio != 1.0) + orgRect = QRect(orgRect.x(), orgRect.y() + , static_cast(orgRect.width() / ratio) + , static_cast(orgRect.height() / ratio)); + return orgRect; +} + +ScreenObjectWayland::ScreenObjectWayland(DBusMonitor *monitor,QObject *parent) + : AbstractScreen(parent) + , m_monitor(monitor) +{ + init(); +} + +ScreenObjectWayland::~ScreenObjectWayland() +{ + if (m_monitor){ + m_monitor->deleteLater(); + m_monitor = nullptr; + } +} + +QString ScreenObjectWayland::name() const +{ + return m_monitor->name(); +} + +QRect ScreenObjectWayland::geometry() const +{ + QRect orgRect = m_monitor->rect(); + orgRect = dealRectRatio(orgRect); + return orgRect; +} + +QRect ScreenObjectWayland::availableGeometry() const +{ + QRect ret = geometry(); //已经缩放过 + + int dockHideMode = DockInfoIns->hideMode(); + if ( 1 == dockHideMode){ //隐藏 + qInfo() << "dock is Hidden"; + return ret; + } + + //DockGeoIns->getGeometry(); //经过缩放处理后的docks,有问题 + DockRect dockrectI = DockInfoIns->frontendWindowRect(); //原始dock大小 + QRect dockrect = dealRectRatio(dockrectI.operator QRect()); //缩放处理 + +#ifndef UNUSED_SMARTDOCK + qreal ratio = qApp->primaryScreen()->devicePixelRatio(); + //fix bug52241 + //当缩放比例为小数时,获得的缩放rect会向下整失去精度,缩放推算原始大小修改为直接获取 + QRect t_rect = handleGeometry(); //原始geometry大小 + + if (!t_rect.contains(dockrectI)) { //使用原始大小判断的dock区所在的屏幕 + qDebug() << "screen:" << name() << " handleGeometry:" << t_rect << " dockrectI:" << dockrectI; + return ret; + } +#endif + + qDebug() << "frontendWindowRect: dockrectI " << QRect(dockrectI); + qDebug() << "dealRectRatio dockrect " << dockrect; + qDebug() << "ScreenObject ret " << ret << name(); + switch (DockInfoIns->position()) { + case 0: //上 + ret.setY(dockrect.bottom()); + qDebug() << "dock on top, availableGeometry" << ret; + break; + case 1: //右 + { + int w = dockrect.left() - ret.left(); + if (w >= 0) + ret.setWidth(static_cast(w / ratio)); + else { + qCritical() << "dockrect.left() - ret.left() is invaild" << w; + } + qDebug() << "dock on right,availableGeometry" << ret; + } + break; + case 2: //下 + { + int h = dockrect.top() - ret.top(); + if (h >= 0) + ret.setHeight(static_cast(h / ratio)); + else { + qCritical() << "dockrect.top() - ret.top() is invaild" << h; + } + qDebug() << "dock on bottom,availableGeometry" << ret; + break; + } + case 3: //左 + ret.setX(dockrect.right()); + qDebug() << "dock on left,availableGeometry" << ret; + break; + default: + qCritical() << "dock postion error!" << "and handleGeometry:" << t_rect << " dockrectI:" << dockrectI; + break; + } + return ret; +} + +QRect ScreenObjectWayland::handleGeometry() const +{ + return m_monitor->rect(); +} + +QString ScreenObjectWayland::path() const +{ + return m_monitor->path(); +} + +bool ScreenObjectWayland::enabled() const +{ + return m_monitor->enabled(); +} + +void ScreenObjectWayland::init() +{ + connect(m_monitor,&DBusMonitor::monitorRectChanged, this, [this](){ + emit sigGeometryChanged(geometry()); + }); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/screen/screenobjectwayland.h b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenobjectwayland.h new file mode 100644 index 0000000..9936ec6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/screen/screenobjectwayland.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#ifndef SCREENOBJECTWAYLAND_H +#define SCREENOBJECTWAYLAND_H + +#include "abstractscreen.h" + +class DBusMonitor; +class ScreenObjectWayland : public AbstractScreen +{ +public: + ScreenObjectWayland(DBusMonitor *monitor, QObject *parent = nullptr); + ~ScreenObjectWayland() override; + QString name() const override; + QRect geometry() const override; + QRect availableGeometry() const override; + QRect handleGeometry() const override; + QString path() const; + bool enabled() const; +private: + void init(); +private: + DBusMonitor *m_monitor = nullptr; +}; + +#endif // SCREENOBJECTWAYLAND_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translate_desktop2ts.sh b/dde-file-manager-5.5.3/src/dde-desktop/translate_desktop2ts.sh new file mode 100755 index 0000000..b67cda8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translate_desktop2ts.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +DESKTOP_COMPUTER_SOURCE_FILE=data/applications/dde-computer.desktop +DESKTOP_COMPUTER_TS_DIR=translations/dde-computer-desktop/ + +/usr/bin/deepin-desktop-ts-convert desktop2ts $DESKTOP_COMPUTER_SOURCE_FILE $DESKTOP_COMPUTER_TS_DIR + + +DESKTOP_TRASH_SOURCE_FILE=data/applications/dde-trash.desktop +DESKTOP_TRASH_TS_DIR=translations/dde-trash-desktop/ + +/usr/bin/deepin-desktop-ts-convert desktop2ts $DESKTOP_TRASH_SOURCE_FILE $DESKTOP_TRASH_TS_DIR + +DESKTOP_HOME_SOURCE_FILE=data/applications/dde-home.desktop +DESKTOP_HOME_TS_DIR=translations/dde-home-desktop/ + +/usr/bin/deepin-desktop-ts-convert desktop2ts $DESKTOP_HOME_SOURCE_FILE $DESKTOP_HOME_TS_DIR diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translate_generation.sh b/dde-file-manager-5.5.3/src/dde-desktop/translate_generation.sh new file mode 100755 index 0000000..c908092 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translate_generation.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# this file is used to auto-generate .qm file from .ts file. +# author: shibowen at linuxdeepin.com + +ts_list=(`ls translations/*.ts`) + +for ts in "${ts_list[@]}" +do + printf "\nprocess ${ts}\n" + lrelease "${ts}" +done diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translate_ts2desktop.sh b/dde-file-manager-5.5.3/src/dde-desktop/translate_ts2desktop.sh new file mode 100755 index 0000000..fcda3ce --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translate_ts2desktop.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +DESKTOP_COMPUTER_TEMP_FILE=data/applications/dde-computer.desktop.tmp +DESKTOP_COMPUTER_FILE=data/applications/dde-computer.desktop +DESKTOP_COMPUTER_TS_DIR=translations/dde-computer-desktop/ + +/usr/bin/deepin-desktop-ts-convert ts2desktop $DESKTOP_COMPUTER_FILE $DESKTOP_COMPUTER_TS_DIR $DESKTOP_COMPUTER_TEMP_FILE +mv $DESKTOP_COMPUTER_TEMP_FILE $DESKTOP_COMPUTER_FILE + + +DESKTOP_TRASH_TEMP_FILE=data/applications/dde-trash.desktop.tmp +DESKTOP_TRASH_FILE=data/applications/dde-trash.desktop +DESKTOP_TRASH_TS_DIR=translations/dde-trash-desktop/ + +/usr/bin/deepin-desktop-ts-convert ts2desktop $DESKTOP_TRASH_FILE $DESKTOP_TRASH_TS_DIR $DESKTOP_TRASH_TEMP_FILE +mv $DESKTOP_TRASH_TEMP_FILE $DESKTOP_TRASH_FILE + +DESKTOP_HOME_TEMP_FILE=data/applications/dde-home.desktop.tmp +DESKTOP_HOME_FILE=data/applications/dde-home.desktop +DESKTOP_HOME_TS_DIR=translations/dde-home-desktop/ + +/usr/bin/deepin-desktop-ts-convert ts2desktop $DESKTOP_HOME_FILE $DESKTOP_HOME_TS_DIR $DESKTOP_HOME_TEMP_FILE +mv $DESKTOP_HOME_TEMP_FILE $DESKTOP_HOME_FILE diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop.ts new file mode 100644 index 0000000..b375192 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop.ts @@ -0,0 +1 @@ +desktopComputerComputerShow basic info of the computer.Show basic info of the computer. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_am_ET.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_am_ET.ts new file mode 100644 index 0000000..d4315c7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_am_ET.ts @@ -0,0 +1 @@ +desktopComputerኮምፒዩተርShow basic info of the computer.መሰረታዊ መረጃ ስለ ኮምፒዩተር ማሳያ \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ar.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ar.ts new file mode 100644 index 0000000..329e029 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ar.ts @@ -0,0 +1 @@ +desktopComputerالحاسوبShow basic info of the computer.إظهار المعلومات الأساسية للحاسوب \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ast.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ast.ts new file mode 100644 index 0000000..f4533ff --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ast.ts @@ -0,0 +1 @@ +desktopComputerOrdenadorShow basic info of the computer.Amuesa la información básica del ordenador. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_az.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_az.ts new file mode 100644 index 0000000..1d31188 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_az.ts @@ -0,0 +1 @@ +desktopComputerKompyuterShow basic info of the computer.Kompyuterin baza məlumatlarını göstərmək \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_bg.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_bg.ts new file mode 100644 index 0000000..6afe75c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_bg.ts @@ -0,0 +1 @@ +desktopComputerКомпютърShow basic info of the computer.Покажи основна информация на компютъра. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_bn.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_bn.ts new file mode 100644 index 0000000..f135da1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_bn.ts @@ -0,0 +1 @@ +desktopComputerকম্পিউটারShow basic info of the computer.কম্পিউটারটির প্রাথমিক তথ্যগুলি দেখান \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_bo.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_bo.ts new file mode 100644 index 0000000..0829787 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_bo.ts @@ -0,0 +1 @@ +desktopComputerརྩིས་འཁོར།Show basic info of the computer.རྩིས་འཁོར་གྱི་གཞི་རྩའི་ཆ་འཕྲིན་མངོན་སྟོན་བྱེད། \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ca.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ca.ts new file mode 100644 index 0000000..592ad74 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ca.ts @@ -0,0 +1 @@ +desktopComputerOrdinadorShow basic info of the computer.Mostra informació bàsica de l'ordinador. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_cs.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_cs.ts new file mode 100644 index 0000000..2ddfe0f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_cs.ts @@ -0,0 +1 @@ +desktopComputerPočítačShow basic info of the computer.Zobrazit základní údaje o počítači. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_da.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_da.ts new file mode 100644 index 0000000..6da2257 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_da.ts @@ -0,0 +1 @@ +desktopComputerComputerShow basic info of the computer.Vis grundlæggende info om computeren. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_de.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_de.ts new file mode 100644 index 0000000..ff017a2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_de.ts @@ -0,0 +1 @@ +desktopComputerComputerShow basic info of the computer.Grundlegende Informationen über diesen Rechner anzeigen \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_el.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_el.ts new file mode 100644 index 0000000..558f94f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_el.ts @@ -0,0 +1 @@ +desktopComputerΥπολογιστήςShow basic info of the computer.Εμφάνιση βασικών πληροφοριών του υπολογιστή. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_es.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_es.ts new file mode 100644 index 0000000..e71ddd5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_es.ts @@ -0,0 +1 @@ +desktopComputerEquipoShow basic info of the computer.Mostrar información básica del equipo. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_fa.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_fa.ts new file mode 100644 index 0000000..079eaf5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_fa.ts @@ -0,0 +1 @@ +desktopComputerرایانهShow basic info of the computer.نمایش اطلاعات اولیه رایانه. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_fi.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_fi.ts new file mode 100644 index 0000000..dda818d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_fi.ts @@ -0,0 +1 @@ +desktopComputerTietokoneShow basic info of the computer.Näytä tietokoneen perustiedot. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_fr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_fr.ts new file mode 100644 index 0000000..2fa52f5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_fr.ts @@ -0,0 +1 @@ +desktopComputerOrdinateurShow basic info of the computer.Afficher les informations de base de l'ordinateur. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_gl_ES.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_gl_ES.ts new file mode 100644 index 0000000..4e5b9c6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_gl_ES.ts @@ -0,0 +1 @@ +desktopComputerComputadorShow basic info of the computer.Amosar información básica do computador. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_hi_IN.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_hi_IN.ts new file mode 100644 index 0000000..c728ff8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_hi_IN.ts @@ -0,0 +1 @@ +desktopComputerकंप्यूटरShow basic info of the computer.कंप्यूटर संबंधी सामान्य जानकारी दिखाएँ। \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_hr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_hr.ts new file mode 100644 index 0000000..81cc545 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_hr.ts @@ -0,0 +1 @@ +desktopComputerRačunaloShow basic info of the computer.Pokaži osnovne podatke o računalu. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_hu.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_hu.ts new file mode 100644 index 0000000..cac1e8a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_hu.ts @@ -0,0 +1 @@ +desktopComputerSzámítógépShow basic info of the computer.A számítógép alapvető információinak megjelenítése. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_id.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_id.ts new file mode 100644 index 0000000..f4e6c08 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_id.ts @@ -0,0 +1 @@ +desktopComputerKomputerShow basic info of the computer.Tampilkan informasi dasar dari komputer \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_it.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_it.ts new file mode 100644 index 0000000..039b335 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_it.ts @@ -0,0 +1 @@ +desktopComputerComputerShow basic info of the computer.Mostra le informazioni base del computer. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ja.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ja.ts new file mode 100644 index 0000000..a0615e4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ja.ts @@ -0,0 +1 @@ +desktopComputerコンピューターShow basic info of the computer.コンピューターの基本情報を表示します。 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_kab.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_kab.ts new file mode 100644 index 0000000..92e72c6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_kab.ts @@ -0,0 +1 @@ +desktopComputerAselkimShow basic info of the computer.Sken-d taɣult tagejdant n uselkim. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_km_KH.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_km_KH.ts new file mode 100644 index 0000000..3138fe1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_km_KH.ts @@ -0,0 +1 @@ +desktopComputerកំុព្យូទ័រShow basic info of the computer.បង្ហាញព័ត៌មានមូលដ្ឋានរបស់កុំព្យូទ័រ។ \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ko.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ko.ts new file mode 100644 index 0000000..076deb8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ko.ts @@ -0,0 +1 @@ +desktopComputer컴퓨터Show basic info of the computer.컴퓨터의 기본 정보 표시 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_lt.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_lt.ts new file mode 100644 index 0000000..1481ef2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_lt.ts @@ -0,0 +1 @@ +desktopComputerKompiuterisShow basic info of the computer.Rodyti pagrindinę kompiuterio informaciją. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_mn.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_mn.ts new file mode 100644 index 0000000..0eb1e30 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_mn.ts @@ -0,0 +1 @@ +desktopComputerКомпьютерShow basic info of the computer.Компьютерийн үндсэн мэдээлэл харах. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ms.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ms.ts new file mode 100644 index 0000000..307aab9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ms.ts @@ -0,0 +1 @@ +desktopComputerKomputerShow basic info of the computer.Tunjuk maklumat umum komputer. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_nb.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_nb.ts new file mode 100644 index 0000000..2320bc0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_nb.ts @@ -0,0 +1 @@ +desktopComputerDatamaskinShow basic info of the computer.Vis grunnleggende informasjon om datamaskinen: \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ne.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ne.ts new file mode 100644 index 0000000..d5c320b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ne.ts @@ -0,0 +1 @@ +desktopComputerकम्प्युटरShow basic info of the computer.कम्प्युटरको आधारभूत जानकारी देखाउनुहोस्। \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_nl.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_nl.ts new file mode 100644 index 0000000..f559938 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_nl.ts @@ -0,0 +1 @@ +desktopComputerComputerShow basic info of the computer.Toon algemene informatie over deze computer \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_pa.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_pa.ts new file mode 100644 index 0000000..9041684 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_pa.ts @@ -0,0 +1 @@ +desktopComputerਕੰਪਿਊਟਰShow basic info of the computer.ਕੰਪਿਊਟਰ ਦੀ ਮੁੱਢਲੀ ਜਾਣਕਾਰੀ ਵੇਖਾਓ \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_pl.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_pl.ts new file mode 100644 index 0000000..368dbf1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_pl.ts @@ -0,0 +1 @@ +desktopComputerKomputerShow basic info of the computer.Wyświetl podstawowe informacje o komputerze. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_pt.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_pt.ts new file mode 100644 index 0000000..6b84a8d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_pt.ts @@ -0,0 +1 @@ +desktopComputerComputadorShow basic info of the computer.Mostrar informação básica do computador. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_pt_BR.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_pt_BR.ts new file mode 100644 index 0000000..a391316 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_pt_BR.ts @@ -0,0 +1 @@ +desktopComputerComputadorShow basic info of the computer.Exibir informações básicas do computador. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ro.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ro.ts new file mode 100644 index 0000000..c5e25c5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ro.ts @@ -0,0 +1 @@ +desktopComputerCalculatorShow basic info of the computer.Afișează informațiile de bază ale calculatorului. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ru.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ru.ts new file mode 100644 index 0000000..52b71f5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ru.ts @@ -0,0 +1 @@ +desktopComputerКомпьютерShow basic info of the computer.Показать основную информацию о компьютере. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_si.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_si.ts new file mode 100644 index 0000000..b7790de --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_si.ts @@ -0,0 +1 @@ +desktopComputerපරිගණකයShow basic info of the computer.පරිගණකයේ මූලික තොරතුරු පෙන්වන්න. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sk.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sk.ts new file mode 100644 index 0000000..c891a14 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sk.ts @@ -0,0 +1 @@ +desktopComputerPočítačShow basic info of the computer.Zobraziť základné informácie počítača. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sl.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sl.ts new file mode 100644 index 0000000..1ae2499 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sl.ts @@ -0,0 +1 @@ +desktopComputerRačunalnikShow basic info of the computer.Pokaži osnovne informacije tega računalnika. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sq.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sq.ts new file mode 100644 index 0000000..d8a8cdc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sq.ts @@ -0,0 +1 @@ +desktopComputerKompjuterShow basic info of the computer.Shfaqni të dhëna elementare të kompjuterit. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sr.ts new file mode 100644 index 0000000..acbd050 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sr.ts @@ -0,0 +1 @@ +desktopComputerРачунарShow basic info of the computer.Прикажи основне податке о рачунару. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sv.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sv.ts new file mode 100644 index 0000000..441a421 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_sv.ts @@ -0,0 +1 @@ +desktopComputerDatorShow basic info of the computer.Visa simpel information om datorn. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ta.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ta.ts new file mode 100644 index 0000000..f62f759 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ta.ts @@ -0,0 +1 @@ +desktopComputerகணினிShow basic info of the computer.கணினி அடிப்படை தகவல் காட்டு. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_tr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_tr.ts new file mode 100644 index 0000000..f9a8a51 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_tr.ts @@ -0,0 +1 @@ +desktopComputerBilgisayarShow basic info of the computer.Bilgisayarın temel bilgilerini göster. \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ug.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ug.ts new file mode 100644 index 0000000..2b95b83 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_ug.ts @@ -0,0 +1 @@ +desktopComputerكومپيوتېرShow basic info of the computer.كومپيوتېرنىڭ ئاساسلىق ئۇچۇرلىرىنى كۆرسىتىش \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_uk.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_uk.ts new file mode 100644 index 0000000..d7cc4f8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_uk.ts @@ -0,0 +1 @@ +desktopComputerКомп'ютерShow basic info of the computer.Показати базову інформаціїю про компʼютер \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_zh_CN.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_zh_CN.ts new file mode 100644 index 0000000..aff312b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_zh_CN.ts @@ -0,0 +1 @@ +desktopComputer计算机Show basic info of the computer.显示计算机的基本信息 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_zh_HK.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_zh_HK.ts new file mode 100644 index 0000000..b28d90a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_zh_HK.ts @@ -0,0 +1 @@ +desktopComputer計算機Show basic info of the computer.顯示計算機的基本訊息 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_zh_TW.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_zh_TW.ts new file mode 100644 index 0000000..2cd6ef6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-computer-desktop/desktop_zh_TW.ts @@ -0,0 +1 @@ +desktopComputer電腦Show basic info of the computer.顯示這台電腦的基本資訊。 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop.ts new file mode 100644 index 0000000..e3c3337 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Icon size + + + + Auto merge + Auto merge + + + + Auto arrange + Auto arrange + + + + Corner Settings + Corner Settings + + + + + Set Wallpaper + Set Wallpaper + + + + Wallpaper and Screensaver + Wallpaper and Screensaver + + + + Properties + Properties + + + + Display Settings + Display Settings + + + + DesktopItemDelegate + + + Tiny + Tiny + + + + Small + Small + + + + Medium + Medium + + + + Large + Large + + + + Super large + Super large + + + + DesktopMain + + + Desktop + Desktop + + + + Frame + + + Wallpaper Slideshow + Wallpaper Slideshow + + + + When login + When login + + + + When wakeup + When wakeup + + + + Require a password on wakeup + Require a password on wakeup + + + + Never + Never + + + + Wait: + Wait: + + + + Wallpaper + Wallpaper + + + + Screensaver + Screensaver + + + + Loading wallpapers... + Loading wallpapers... + + + + Loading screensavers... + Loading screensavers... + + + + Desktop + button + Desktop + + + + Lock Screen + button + Lock Screen + + + + Both + Both + + + + Apply + button + Apply + + + + WaterMaskFrame + + + + Not authorized + Not authorized + + + + + In trial period + In trial period + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_am_ET.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_am_ET.ts new file mode 100644 index 0000000..0946880 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_am_ET.ts @@ -0,0 +1,176 @@ + + + CanvasGridView + + + Icon size + የ ምልክት መጠን + + + + Auto merge + + + + + Auto arrange + በራሱ ማስተካከያ + + + + Set Wallpaper + የ ግድግዳ ወረቀት ማሰናጃ + + + + Wallpaper and Screensaver + + + + + Properties + ባህሪዎች + + + + Display Settings + ማሰናጃ ማሳያ + + + + Corner Settings + ጠርዝ ማሰናጃ + + + + DesktopItemDelegate + + + Tiny + በጣም ትንሽ + + + + Small + ትንሽ + + + + Medium + መካከለኛ + + + + Large + ትልቅ + + + + Super large + በጣም ትልቅ + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + + + + + When login + + + + + When wakeup + + + + + Require a password on wakeup + + + + + Never + + + + + Wait: + + + + + Wallpaper + + + + + Screensaver + + + + + Only desktop + ዴስክቶፕ ብቻ + + + + Only lock screen + መመልከቻ ብቻ መቆለፊያ + + + + Apply + + + + + ZoneMainWindow + + + Fast Screen Off + በፍጥነት መመልከቻ ማጥፊያ + + + Control Center + መቆጣጠሪያ ማእከል + + + + All Windows + ሁሉንም መስኮቶች + + + + Launcher + ማስጀመሪያ + + + + Desktop + ዴስክቶፕ + + + + None + ምንም + + + + Close Window + መስኮት መዝጊያ + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ar.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ar.ts new file mode 100644 index 0000000..1871082 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ar.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + حجم الأيقونة + + + + Auto merge + دمج تلقائى + + + + Auto arrange + ترتيب تلقائي + + + + Corner Settings + إعدادات التنقل الزاوي + + + + + Set Wallpaper + إعداد كخلفية + + + + Wallpaper and Screensaver + الخلفيات و شاشة التوقف + + + + Properties + الخصائص + + + + Display Settings + إعدادات العرض + + + + DesktopItemDelegate + + + Tiny + صغير جداً + + + + Small + صغير + + + + Medium + متوسط + + + + Large + كبير + + + + Super large + كبير جداً + + + + DesktopMain + + + Desktop + سطح المكتب + + + + Frame + + + Wallpaper Slideshow + عرض الخلفيات + + + + When login + عند تسجيل الدخول + + + + When wakeup + عند الإيقاظ + + + + Require a password on wakeup + يلزم كلمة مرور عند الإيقاظ + + + + Never + أبداً + + + + Wait: + انتظر: + + + + Wallpaper + خلفية + + + + Screensaver + شاشة التوقف + + + + Loading wallpapers... + تحميل الخلفيات ... + + + + Loading screensavers... + تحميل شاشات التوقف ... + + + + Desktop + button + سطح المكتب + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + طبِّق + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + قيد التجربة + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ast.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ast.ts new file mode 100644 index 0000000..ebdb64e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ast.ts @@ -0,0 +1,176 @@ + + + CanvasGridView + + + Icon size + Tamañu d'iconos + + + + Auto merge + + + + + Auto arrange + Auto-ordenar + + + + Set Wallpaper + Afitar fondu de pantalla + + + + Wallpaper and Screensaver + + + + + Properties + Propiedaes + + + + Display Settings + Axustes de pantalla + + + + Corner Settings + Axustes d'esquines + + + + DesktopItemDelegate + + + Tiny + Nanu + + + + Small + Pequeñu + + + + Medium + Mediu + + + + Large + Grande + + + + Super large + Escomanáu + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + + + + + When login + + + + + When wakeup + + + + + Require a password on wakeup + + + + + Never + + + + + Wait: + + + + + Wallpaper + + + + + Screensaver + + + + + Only desktop + Namái escritoriu + + + + Only lock screen + Namái pantalla de bloquéu + + + + Apply + + + + + ZoneMainWindow + + + Fast Screen Off + Pantalla rápida desactivada + + + Control Center + Centru de control + + + + All Windows + Toles ventanes + + + + Launcher + Llanzador + + + + Desktop + Escritoriu + + + + None + Dengún + + + + Close Window + Zarrar ventana + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_az.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_az.ts new file mode 100644 index 0000000..8ffc904 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_az.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Nişan ölçüsü + + + + Auto merge + Avtomatik birləşdirmə + + + + Auto arrange + Avtomatik tənzimləmə + + + + Corner Settings + Künc ayarları + + + + + Set Wallpaper + Divar kağızını təyin etmək + + + + Wallpaper and Screensaver + Divar kağızı və Ekran şəkli + + + + Properties + Tərcihlər + + + + Display Settings + Ekran ayarları + + + + DesktopItemDelegate + + + Tiny + İncə + + + + Small + Kiçik + + + + Medium + Orta + + + + Large + Geniş + + + + Super large + Çox geniş + + + + DesktopMain + + + Desktop + İş Masası + + + + Frame + + + Wallpaper Slideshow + Divar kağızları slaydı + + + + When login + Daxil oduqda + + + + When wakeup + Oyandıqda + + + + Require a password on wakeup + Oyatmaq üçün şifrə tələb olunur + + + + Never + Heç vaxt + + + + Wait: + Gözləmək: + + + + Wallpaper + Divar kağızı + + + + Screensaver + Ekran şəkli + + + + Loading wallpapers... + Divar kağızları yüklənir... + + + + Loading screensavers... + Ekran şəkilləri yüklənir + + + + Desktop + button + İş Masası + + + + Lock Screen + button + Kilid ekranı + + + + Both + Hər ikisi + + + + Apply + button + Tətbiq etmək + + + + WaterMaskFrame + + + + Not authorized + Səlahiyyət verilməyib + + + + + In trial period + Sınaq müddətində + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_bg.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_bg.ts new file mode 100644 index 0000000..86a3c60 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_bg.ts @@ -0,0 +1,168 @@ + + + CanvasGridView + + + Icon size + Размер на икона + + + + Auto merge + Автоматична обедини + + + + Auto arrange + Автоматична подредба + + + + Corner Settings + Настройки на ъглите + + + + + Set Wallpaper + Задай тапет + + + + Wallpaper and Screensaver + Тапет и предпазител на екрана + + + + Properties + Свойства + + + + Display Settings + Найстройки на екрана + + + + DesktopItemDelegate + + + Tiny + Тясна + + + + Small + Малка + + + + Medium + Средна + + + + Large + Голяма + + + + Super large + Много голям + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + Слайдшоу на тапети + + + + When login + При влизане + + + + When wakeup + При събуждане + + + + Require a password on wakeup + Поискай парола при събуждане + + + + Never + Никога + + + + Wait: + Чакай: + + + + Wallpaper + Тапет + + + + Screensaver + Предпазител на екрана + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Only desktop + button + Само десктоп + + + + Only lock screen + button + Само заключи екрана + + + + Apply + button + Приложи + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_bn.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_bn.ts new file mode 100644 index 0000000..9e1e5f6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_bn.ts @@ -0,0 +1,176 @@ + + + CanvasGridView + + + Icon size + আইকনের আকার + + + + Auto merge + + + + + Auto arrange + স্বয়ংক্রিয়ভাবে সাজান + + + + Set Wallpaper + ওয়ালপেপার সেট করুন + + + + Wallpaper and Screensaver + + + + + Properties + বৈশিষ্ট্যসমূহ + + + + Display Settings + ডিসপ্লে সেটিংস + + + + Corner Settings + কোনা সেটিংস + + + + DesktopItemDelegate + + + Tiny + অতি ক্ষুদ্র + + + + Small + ছোট + + + + Medium + মধ্যম + + + + Large + বড় + + + + Super large + অতি বৃহৎ + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + + + + + When login + + + + + When wakeup + + + + + Require a password on wakeup + + + + + Never + + + + + Wait: + + + + + Wallpaper + + + + + Screensaver + + + + + Only desktop + শুধুমাত্র ডেস্কটপ + + + + Only lock screen + শুধুমাত্র লক স্ক্রিন + + + + Apply + + + + + ZoneMainWindow + + + Fast Screen Off + দ্রুত স্ক্রিন বন্ধ + + + Control Center + কন্ট্রোল সেন্টার + + + + All Windows + সকল উইন্ডো সমূহ + + + + Launcher + লঞ্চার + + + + Desktop + ডেস্কটপ + + + + None + কোনোটিই নয় + + + + Close Window + উইন্ডো বন্ধ করুন + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_bo.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_bo.ts new file mode 100644 index 0000000..9f43a59 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_bo.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + རྟགས་རིས་ཆེ་ཆུང་། + + + + Auto merge + རང་འགུལ་ལེགས་སྒྲིག + + + + Auto arrange + སྟར་རང་སྒྲིག + + + + Corner Settings + ཚ་གནས་སྒྲིག་འགོད། + + + + + Set Wallpaper + རྒྱབ་ཤོག་སྒྲིག་འགོད། + + + + Wallpaper and Screensaver + རྒྱབ་ཤོག་དང་འཆར་སྲུང་། + + + + Properties + ངོ་བོ། + + + + Display Settings + སྒྲིག་འགོད་མངོན་སྟོན། + + + + DesktopItemDelegate + + + Tiny + ཆུང་ཤོས། + + + + Small + ཆུང་། + + + + Medium + འབྲིང་། + + + + Large + ཆེ། + + + + Super large + ཆེ་ཤོས། + + + + DesktopMain + + + Desktop + ཅོག་ངོས། + + + + Frame + + + Wallpaper Slideshow + རྒྱབ་ཤོག་རང་འགུལ་གྱིས་བརྗེ་བ། + + + + When login + ཐོ་འཇུག་སྐབས། + + + + When wakeup + གཉིད་སད་སྐབས། + + + + Require a password on wakeup + སོར་ཆུད་སྐབས་གསང་ཨང་དགོས། + + + + Never + གཏན་ནས་མིན། + + + + Wait: + རང་དགར་འཇོག་པའི་དུས་ཚོད། + + + + Wallpaper + རྒྱབ་ཤོག + + + + Screensaver + འཆར་སྲུང་། + + + + Loading wallpapers... + རྒྱབ་ཤོག་སྣོན་འཇུག་བྱེད་བཞིན་པ། + + + + Loading screensavers... + བརྙན་སྲུང་སྣོན་འཇུག་བྱེད་བཞིན་པ། + + + + Desktop + button + ཅོག་ངོས་མངོན་སྟོན། + + + + Lock Screen + button + སྒོ་ལྕགས་རྒྱག་པ། + + + + Both + མཉམ་དུ་སྒྲིག་འགོད་བྱེད་པ། + + + + Apply + button + འཆར་སྲུང་སྒྲིག་འགོད། + + + + WaterMaskFrame + + + + Not authorized + དབང་བརྩལ་མེད། + + + + + In trial period + ཚོད་སྤྱོད་དུས་ཡུན། + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ca.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ca.ts new file mode 100644 index 0000000..422a3af --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ca.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Mida de la icona + + + + Auto merge + Fusió automàtica + + + + Auto arrange + Arranjament automàtic + + + + Corner Settings + Paràmetres dels cantons + + + + + Set Wallpaper + Estableix el fons de pantalla + + + + Wallpaper and Screensaver + Fons i protector de pantalla + + + + Properties + Propietats + + + + Display Settings + Paràmetres de la pantalla + + + + DesktopItemDelegate + + + Tiny + Molt petita + + + + Small + Petita + + + + Medium + Mitjana + + + + Large + Grossa + + + + Super large + Molt grossa + + + + DesktopMain + + + Desktop + Escriptori + + + + Frame + + + Wallpaper Slideshow + Presentació de fons de pantalla + + + + When login + En entrar + + + + When wakeup + En despertar + + + + Require a password on wakeup + Demana una contrasenya en despertar + + + + Never + Mai + + + + Wait: + Espera: + + + + Wallpaper + Fons de pantalla + + + + Screensaver + Protector de pantalla + + + + Loading wallpapers... + Es carreguen els fons de pantalla... + + + + Loading screensavers... + Es carreguen els estalvis de pantalla... + + + + Desktop + button + Escriptori + + + + Lock Screen + button + Bloca la pantalla + + + + Both + Amdós + + + + Apply + button + Aplica + + + + WaterMaskFrame + + + + Not authorized + Sense autorització + + + + + In trial period + En període de prova + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_cs.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_cs.ts new file mode 100644 index 0000000..0445204 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_cs.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Velikost ikon + + + + Auto merge + Seskupovat automaticky + + + + Auto arrange + Uspořádávat automaticky + + + + Corner Settings + Nastavení rohů + + + + + Set Wallpaper + Nastavit pozadí + + + + Wallpaper and Screensaver + Pozadí plochy a spořič obrazovky + + + + Properties + Vlastnosti + + + + Display Settings + Zobrazit nastavení + + + + DesktopItemDelegate + + + Tiny + Drobné + + + + Small + Malé + + + + Medium + Střední + + + + Large + Velké + + + + Super large + Opravdu velké + + + + DesktopMain + + + Desktop + Plocha + + + + Frame + + + Wallpaper Slideshow + Měnit pozadí plochy + + + + When login + Při přihlášení + + + + When wakeup + Při probuzení + + + + Require a password on wakeup + Vyžadovat heslo při probuzení + + + + Never + Nespouštět + + + + Wait: + Prodleva: + + + + Wallpaper + Pozadí + + + + Screensaver + Spořič obrazovky + + + + Loading wallpapers... + Nahrávají se pozadí… + + + + Loading screensavers... + Nahrávají se šetřiče obrazovky… + + + + Desktop + button + Plocha + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + Použít + + + + WaterMaskFrame + + + + Not authorized + Nepověřeno + + + + + In trial period + Ve zkušebním období + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_da.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_da.ts new file mode 100644 index 0000000..cbf832b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_da.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Ikonstørrelse + + + + Auto merge + Automatisk sammenlægning + + + + Auto arrange + Placér automatisk + + + + Corner Settings + Hjørneindstillinger + + + + + Set Wallpaper + Sæt tapet + + + + Wallpaper and Screensaver + Tapet og pauseskærm + + + + Properties + Egenskaber + + + + Display Settings + Skærmindstillinger + + + + DesktopItemDelegate + + + Tiny + Meget lille + + + + Small + Lille + + + + Medium + Medium + + + + Large + Stor + + + + Super large + Meget stor + + + + DesktopMain + + + Desktop + Skrivebord + + + + Frame + + + Wallpaper Slideshow + Tapet-diasshow + + + + When login + Ved indlogning + + + + When wakeup + Ved opvågning + + + + Require a password on wakeup + Kræv en adgangskode ved opvågning + + + + Never + Aldrig + + + + Wait: + Vent: + + + + Wallpaper + Tapet + + + + Screensaver + Pauseskærm + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Desktop + button + Skrivebord + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + Anvend + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_de.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_de.ts new file mode 100644 index 0000000..a2aa3e9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_de.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Symbolgröße + + + + Auto merge + Automatisch zusammenführen + + + + Auto arrange + Automatisch sortieren + + + + Corner Settings + Eckeneinstellungen + + + + + Set Wallpaper + Hintergrundbild festlegen + + + + Wallpaper and Screensaver + Hintergrundbild und Bildschirmschoner + + + + Properties + Eigenschaften + + + + Display Settings + Anzeigeeinstellungen + + + + DesktopItemDelegate + + + Tiny + Sehr klein + + + + Small + Klein + + + + Medium + Mittel + + + + Large + Groß + + + + Super large + Sehr groß + + + + DesktopMain + + + Desktop + Desktop + + + + Frame + + + Wallpaper Slideshow + Hintergrundbild-Slideshow + + + + When login + Bei der Anmeldung + + + + When wakeup + Beim Aufwachen + + + + Require a password on wakeup + Erfordert ein Kennwort beim Aufwecken + + + + Never + Nie + + + + Wait: + Warten: + + + + Wallpaper + Hintergrundbild + + + + Screensaver + Bildschirmschoner + + + + Loading wallpapers... + Hintergrundbilder werden geladen ... + + + + Loading screensavers... + Bildschirmschoner werden geladen ... + + + + Desktop + button + Desktop + + + + Lock Screen + button + Sperrbildschirm + + + + Both + Beide + + + + Apply + button + Anwenden + + + + WaterMaskFrame + + + + Not authorized + Nicht autorisiert + + + + + In trial period + In der Testphase + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_el.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_el.ts new file mode 100644 index 0000000..870a4dd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_el.ts @@ -0,0 +1,168 @@ + + + CanvasGridView + + + Icon size + Μέγεθος εικονιδίων + + + + Auto merge + Αυτόματη συγχώνευση + + + + Auto arrange + Αυτόματη στοίχιση + + + + Corner Settings + Ρυθμίσεις Γωνίας + + + + + Set Wallpaper + Ορισμός Ταπετσαρίας + + + + Wallpaper and Screensaver + Wallpaper και Screensaver + + + + Properties + Ιδιότητες + + + + Display Settings + Ρυθμίσεις Εμφάνισης + + + + DesktopItemDelegate + + + Tiny + Μικρούλικο + + + + Small + Μικρό + + + + Medium + Μεσσαίο + + + + Large + Μεγάλο + + + + Super large + Τεράστιο + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + Wallpaper Slideshow + + + + When login + Στη σύνδεση + + + + When wakeup + Στην αφύπνιση + + + + Require a password on wakeup + Απαίτηση κωδικού πρόσβασης κατά την αφύπνιση + + + + Never + Ποτέ + + + + Wait: + Αναμονή: + + + + Wallpaper + Wallpaper + + + + Screensaver + Screensaver + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Only desktop + button + Μόνο η επιφάνεια εργασίας + + + + Only lock screen + button + Μόνο το κλείδωμα οθόνης + + + + Apply + button + Εφαρμογή + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_en_AU.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_en_AU.ts new file mode 100644 index 0000000..3898bc0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_en_AU.ts @@ -0,0 +1,169 @@ + + + CanvasGridView + + + Icon size + Icon size + + + + Auto merge + Auto merge + + + + Auto arrange + Auto arrange + + + + Corner Settings + Corner Settings + + + + + Set Wallpaper + Set Wallpaper + + + + Wallpaper and Screensaver + Wallpaper and Screensaver + + + + Properties + Properties + + + + Display Settings + Display Settings + + + + DesktopItemDelegate + + + Tiny + Tiny + + + + Small + Small + + + + Medium + Medium + + + + Large + Large + + + + Super large + Extra large + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + Wallpaper Slideshow + + + + When login + When login + + + + When wakeup + When wake up + + + + Require a password on wakeup + Password-required on wake up + + + + + Never + Never + + + + Wait: + Wait: + + + + Wallpaper + Wallpaper + + + + Screensaver + Screensaver + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Only desktop + button + Desktop only + + + + Only lock screen + button + Lock screen only + + + + Apply + button + Apply + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_es.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_es.ts new file mode 100644 index 0000000..68122b6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_es.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Tamaño de icono + + + + Auto merge + Agrupar automáticamente + + + + Auto arrange + Organizar automáticamente + + + + Corner Settings + Ajustes de esquinas + + + + + Set Wallpaper + Establecer fondo de pantalla + + + + Wallpaper and Screensaver + Fondo de pantalla y salvapantallas + + + + Properties + Propiedades + + + + Display Settings + Ajustes de pantalla + + + + DesktopItemDelegate + + + Tiny + Minúsculo + + + + Small + Pequeño + + + + Medium + Mediano + + + + Large + Grande + + + + Super large + Enorme + + + + DesktopMain + + + Desktop + Escritorio + + + + Frame + + + Wallpaper Slideshow + Cambiar fondos automáticamente + + + + When login + Cuando inicie sesión + + + + When wakeup + Cuando se reactive + + + + Require a password on wakeup + Solicitar contraseña para desbloquear + + + + Never + Nunca + + + + Wait: + Esperar: + + + + Wallpaper + Fondo de pantalla + + + + Screensaver + Salvapantallas + + + + Loading wallpapers... + Descargando fondos de pantalla... + + + + Loading screensavers... + Descargando salvapantallas... + + + + Desktop + button + Escritorio + + + + Lock Screen + button + Pantalla de bloqueo + + + + Both + Ambos + + + + Apply + button + Aplicar + + + + WaterMaskFrame + + + + Not authorized + No autorizado + + + + + In trial period + En periodo de prueba + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_fa.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_fa.ts new file mode 100644 index 0000000..b7d7654 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_fa.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + اندازه آیکون + + + + Auto merge + ادغام خودکار + + + + Auto arrange + ترتیب خودکار + + + + Corner Settings + تنظیمات گوشه + + + + + Set Wallpaper + تنظیم پس زمینه + + + + Wallpaper and Screensaver + تصویر زمینه و محافظ صفحه + + + + Properties + خصوصیات + + + + Display Settings + تنظیمات نمایشگر + + + + DesktopItemDelegate + + + Tiny + ریز + + + + Small + کوچک + + + + Medium + متوسط + + + + Large + بزرگ + + + + Super large + خیلی بزرگ + + + + DesktopMain + + + Desktop + دسکتاپ + + + + Frame + + + Wallpaper Slideshow + نمایش پرده ای تصاویر پس زمینه + + + + When login + هنگام ورود + + + + When wakeup + هنگام بیدار شدن + + + + Require a password on wakeup + در هنگام بیداری به یک رمز عبور احتیاج دارید + + + + Never + هرگز + + + + Wait: + صبر کنید: + + + + Wallpaper + پس زمینه + + + + Screensaver +  محافظ صفحه + + + + Loading wallpapers... + بارگذاری پس زمینه ها... + + + + Loading screensavers... + بارگذاری اسکرین سیور ها... + + + + Desktop + button + دسکتاپ + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + اعمال + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_fi.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_fi.ts new file mode 100644 index 0000000..9204c36 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_fi.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Kuvakkeen koko + + + + Auto merge + Liitä automaattisesti + + + + Auto arrange + Järjestä automaattisesti + + + + Corner Settings + Kulmien asetukset + + + + + Set Wallpaper + Aseta taustakuva + + + + Wallpaper and Screensaver + Tausta ja näytönsäästäjä + + + + Properties + Ominaisuudet + + + + Display Settings + Näytön asetukset + + + + DesktopItemDelegate + + + Tiny + Pienin + + + + Small + Pieni + + + + Medium + Keskikoko + + + + Large + Suuri + + + + Super large + Suurin + + + + DesktopMain + + + Desktop + Työpöytä + + + + Frame + + + Wallpaper Slideshow + Kuvien esitysväli + + + + When login + Kirjautuessa + + + + When wakeup + Herätessä + + + + Require a password on wakeup + Vaadi salasana herätyksen jälkeen + + + + Never + Ei koskaan + + + + Wait: + Odota: + + + + Wallpaper + Taustakuva + + + + Screensaver + Näytönsäästäjä + + + + Loading wallpapers... + Ladataan taustakuvia... + + + + Loading screensavers... + Ladataan näytönsäästäjät... + + + + Desktop + button + Työpöytä + + + + Lock Screen + button + Lukitusnäyttö + + + + Both + Molemmat + + + + Apply + button + Käytä + + + + WaterMaskFrame + + + + Not authorized + Ei hyväksytty + + + + + In trial period + Koeaika + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_fr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_fr.ts new file mode 100644 index 0000000..2f2d942 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_fr.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Taille des icônes + + + + Auto merge + Fusionner automatiquement les icônes + + + + Auto arrange + Réorganiser automatiquement les icônes + + + + Corner Settings + Paramétrer les coins + + + + + Set Wallpaper + Définir le fond d'écran + + + + Wallpaper and Screensaver + Fond et économiseur d'écran + + + + Properties + Propriétés + + + + Display Settings + Paramètres d'affichage + + + + DesktopItemDelegate + + + Tiny + Très petit + + + + Small + Petit + + + + Medium + Moyen + + + + Large + Grand + + + + Super large + Très grand + + + + DesktopMain + + + Desktop + Bureau + + + + Frame + + + Wallpaper Slideshow + Diaporama de fonds d'écran + + + + When login + Lors de la connexion + + + + When wakeup + À la sortie de veille + + + + Require a password on wakeup + Demander un mot de passe à la sortie de veille + + + + Never + Jamais + + + + Wait: + Attendre: + + + + Wallpaper + Fond d'écran + + + + Screensaver + Économiseur d'écran + + + + Loading wallpapers... + Chargement des fonds d'écran... + + + + Loading screensavers... + Chargement des économiseurs d'écran... + + + + Desktop + button + Bureau + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + Appliquer + + + + WaterMaskFrame + + + + Not authorized + Non autorisé + + + + + In trial period + En période d'essai + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_gl_ES.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_gl_ES.ts new file mode 100644 index 0000000..78882db --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_gl_ES.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Tamaño da icona + + + + Auto merge + Fusión automática + + + + Auto arrange + Disposición automática + + + + Corner Settings + Axustes das esquinas + + + + + Set Wallpaper + Definir o fondo de pantalla + + + + Wallpaper and Screensaver + Fondo de pantalla e Salvapantalla + + + + Properties + Propiedades + + + + Display Settings + Axustes da pantalla + + + + DesktopItemDelegate + + + Tiny + Moi pequeno + + + + Small + Pequeno + + + + Medium + Normal + + + + Large + Grande + + + + Super large + Moi Grande + + + + DesktopMain + + + Desktop + Escritorio + + + + Frame + + + Wallpaper Slideshow + Presentación de diapositivas do fondo de pantalla + + + + When login + Cando inicie sesión + + + + When wakeup + Ao espertar + + + + Require a password on wakeup + Esixir un contrasinal ao activar + + + + Never + Nunca + + + + Wait: + Espere: + + + + Wallpaper + Fondo de pantalla + + + + Screensaver + Salvapantallas + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Desktop + button + Escritorio + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + Confirmar + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_hi_IN.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_hi_IN.ts new file mode 100644 index 0000000..94548ba --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_hi_IN.ts @@ -0,0 +1,168 @@ + + + CanvasGridView + + + Icon size + आइकन का आकार + + + + Auto merge + स्वतः विलय + + + + Auto arrange + स्वतः क्रमबद्ध + + + + Corner Settings + स्क्रीन के कोनों की सेटिंग्स + + + + + Set Wallpaper + वॉलपेपर सेट करें + + + + Wallpaper and Screensaver + वॉलपेपर व स्क्रीनसेवर + + + + Properties + विशेषताएँ + + + + Display Settings + डिस्प्ले सेटिंग्स + + + + DesktopItemDelegate + + + Tiny + बहुत छोटा + + + + Small + छोटा + + + + Medium + मध्यम + + + + Large + बड़ा + + + + Super large + बहुत बड़ा + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + वॉलपेपर स्लाइड शो + + + + When login + लॉगिन के समय + + + + When wakeup + चालू होते समय + + + + Require a password on wakeup + चालू होने पर कूटशब्द अनिवार्य करें + + + + Never + कभी नहीं + + + + Wait: + प्रतीक्षा : + + + + Wallpaper + वॉलपेपर + + + + Screensaver + स्क्रीनसेवर + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Only desktop + button + केवल डेस्कटॉप + + + + Only lock screen + button + केवल लॉक स्क्रीन + + + + Apply + button + लागू करें + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_hr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_hr.ts new file mode 100644 index 0000000..f10a6c0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_hr.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Veličina ikone + + + + Auto merge + + + + + Auto arrange + Samouređivanje + + + + Corner Settings + Postavke kutova + + + + + Set Wallpaper + Postavi tapetu + + + + Wallpaper and Screensaver + Tapeta i čuvar zaslona + + + + Properties + Svojstva + + + + Display Settings + Postavke prikaza + + + + DesktopItemDelegate + + + Tiny + + + + + Small + Malo + + + + Medium + Srednje + + + + Large + Veliko + + + + Super large + Izuzetno veliko + + + + DesktopMain + + + Desktop + Radna površina + + + + Frame + + + Wallpaper Slideshow + Klizni prikaz tapete + + + + When login + Prilikom prijave + + + + When wakeup + Prilikom buđenja + + + + Require a password on wakeup + Potrebna je lozinka kod buđenja + + + + Never + Nikada + + + + Wait: + Pričekajte: + + + + Wallpaper + Tapeta + + + + Screensaver + Čuvar zaslona + + + + Loading wallpapers... + Učitavam tapete... + + + + Loading screensavers... + Učitavam čuvare zaslona... + + + + Desktop + button + Radna površina + + + + Lock Screen + button + Zaključaj zaslon + + + + Both + + + + + Apply + button + Primjeni + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + U probnom periodu + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_hu.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_hu.ts new file mode 100644 index 0000000..eee244d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_hu.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Ikon méret + + + + Auto merge + Automatikus összefűzés + + + + Auto arrange + Automatikus elrendezés + + + + Corner Settings + Sarkok beállításai + + + + + Set Wallpaper + Beállítás háttérképként + + + + Wallpaper and Screensaver + Háttérkép és Képernyővédő + + + + Properties + Tulajdonságok + + + + Display Settings + Megjelenítési beállítások + + + + DesktopItemDelegate + + + Tiny + Nagyon kicsi + + + + Small + Kicsi + + + + Medium + Közepes + + + + Large + Nagy + + + + Super large + Nagyon nagy + + + + DesktopMain + + + Desktop + Asztal + + + + Frame + + + Wallpaper Slideshow + Háttérkép diavetítése + + + + When login + Bejelentkezéskor + + + + When wakeup + Felébresztéskor + + + + Require a password on wakeup + Felébresztés után jelszó szükséges a belépéshez + + + + Never + Soha + + + + Wait: + Várakozás: + + + + Wallpaper + Háttérkép + + + + Screensaver + Képernyővédő + + + + Loading wallpapers... + Háttérképek betöltése... + + + + Loading screensavers... + Képernyővédők betöltése... + + + + Desktop + button + Asztal + + + + Lock Screen + button + Zárolási képernyő + + + + Both + Mindkettő + + + + Apply + button + Alkalmaz + + + + WaterMaskFrame + + + + Not authorized + Nem engedélyezett + + + + + In trial period + A próbaidőszakban + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_id.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_id.ts new file mode 100644 index 0000000..1e76c11 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_id.ts @@ -0,0 +1,168 @@ + + + CanvasGridView + + + Icon size + Ukuran ikon + + + + Auto merge + Auto Gabung + + + + Auto arrange + Atur otomatis + + + + Corner Settings + Pengaturan Sudut + + + + + Set Wallpaper + Setel Wallpaper + + + + Wallpaper and Screensaver + Wallpaper dan Screensaver + + + + Properties + Properti + + + + Display Settings + Pengaturan Tampilan + + + + DesktopItemDelegate + + + Tiny + Mungil + + + + Small + Kecil + + + + Medium + Media + + + + Large + Besar + + + + Super large + Besar sekali + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + Penampil Wallpaper + + + + When login + Ketika login + + + + When wakeup + Ketika bangun + + + + Require a password on wakeup + Membutuhkan password saat bangun + + + + Never + Tidak pernah + + + + Wait: + Tunggu: + + + + Wallpaper + Wallpaper + + + + Screensaver + Screensaver + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Only desktop + button + Hanya desktop + + + + Only lock screen + button + Hanya kunci layar + + + + Apply + button + Terapkan + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_it.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_it.ts new file mode 100644 index 0000000..7c39dc6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_it.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Dimensione icone + + + + Auto merge + Organizza automaticamente + + + + Auto arrange + Disponi automaticamente + + + + Corner Settings + Impostazioni angoli di navigazione + + + + + Set Wallpaper + Imposta sfondo + + + + Wallpaper and Screensaver + Sfondi e screensaver + + + + Properties + Proprietà + + + + Display Settings + Impostazioni visualizzazione + + + + DesktopItemDelegate + + + Tiny + Molto piccole + + + + Small + Piccole + + + + Medium + Medie + + + + Large + Grandi + + + + Super large + Molto grandi + + + + DesktopMain + + + Desktop + Desktop + + + + Frame + + + Wallpaper Slideshow + Slideshow sfondi + + + + When login + Al Login + + + + When wakeup + Al risveglio + + + + Require a password on wakeup + Richiedi la password per risvegliare + + + + Never + Mai + + + + Wait: + Attesa: + + + + Wallpaper + Sfondi + + + + Screensaver + Screensaver + + + + Loading wallpapers... + Caricamento sfondi... + + + + Loading screensavers... + Caricamento salvaschermo... + + + + Desktop + button + Desktop + + + + Lock Screen + button + Lock Screen + + + + Both + Entrambe + + + + Apply + button + Applica + + + + WaterMaskFrame + + + + Not authorized + Nessuna autorizzazione + + + + + In trial period + Periodo di prova + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ja.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ja.ts new file mode 100644 index 0000000..dea0eda --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ja.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + アイコンサイズ + + + + Auto merge + 自動的にまとめる + + + + Auto arrange + 自動整列 + + + + Corner Settings + コーナーの設定 + + + + + Set Wallpaper + 壁紙を設定 + + + + Wallpaper and Screensaver + 壁紙とスクリーンセーバー + + + + Properties + プロパティ + + + + Display Settings + ディスプレイの設定 + + + + DesktopItemDelegate + + + Tiny + 最小 + + + + Small + + + + + Medium + + + + + Large + + + + + Super large + 最大 + + + + DesktopMain + + + Desktop + デスクトップ + + + + Frame + + + Wallpaper Slideshow + 壁紙をスライドショーにする + + + + When login + ログイン時 + + + + When wakeup + サスペンド復帰時 + + + + Require a password on wakeup + サスペンド復帰時にパスワードを必要とする + + + + Never + 使用しない + + + + Wait: + 開始まで: + + + + Wallpaper + 壁紙 + + + + Screensaver + スクリーンセーバー + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Desktop + button + デスクトップ + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + 適用 + + + + WaterMaskFrame + + + + Not authorized + 未認証 + + + + + In trial period + トライアル期間 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_km_KH.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_km_KH.ts new file mode 100644 index 0000000..c001bf4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_km_KH.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + ទំហំIcon + + + + Auto merge + បញ្ចូលគ្នាស្វ័យប្រវត្តិ + + + + Auto arrange + រៀបចំស្វ័យប្រវត្តិ + + + + Corner Settings + ការកំណត់ជ្រុង + + + + + Set Wallpaper + កំណត់ផ្ទាំងរូបភាព + + + + Wallpaper and Screensaver + ផ្ទាំងរូបភាពនិងរូបថតអេក្រង់ + + + + Properties + Properties + + + + Display Settings + កំណត់ការបង្ហាញ + + + + DesktopItemDelegate + + + Tiny + តូចល្អិត + + + + Small + តូច + + + + Medium + មធ្យម + + + + Large + ធំ + + + + Super large + ធំខ្លាំង + + + + DesktopMain + + + Desktop + ផ្ទៃតុ + + + + Frame + + + Wallpaper Slideshow + ការបញ្ចាំងផ្ទាំងរូបភាព + + + + When login + ពេលចូលប្រើ + + + + When wakeup + នៅពេលបើកម្តងទៀត + + + + Require a password on wakeup + ទាមទារពាក្យសំងាត់នៅពេលបើកម្តងទៀត + + + + Never + មិនដែល + + + + Wait: + រងចំា: + + + + Wallpaper + ផ្ទាំង​រូបភាព + + + + Screensaver + Screensaver + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Desktop + button + ផ្ទៃតុ + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + អនុវត្ត + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ko.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ko.ts new file mode 100644 index 0000000..37a477a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ko.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + 아이콘 크기 + + + + Auto merge + 자동 병합 + + + + Auto arrange + 자동 정렬 + + + + Corner Settings + 모서리 설정 + + + + + Set Wallpaper + 배경화면 설정 + + + + Wallpaper and Screensaver + 배경화면 및 화면보호기 + + + + Properties + 속성 + + + + Display Settings + 화면 설정 + + + + DesktopItemDelegate + + + Tiny + 초소형 + + + + Small + 소형 + + + + Medium + 중형 + + + + Large + 대형 + + + + Super large + 초대형 + + + + DesktopMain + + + Desktop + 바탕화면 + + + + Frame + + + Wallpaper Slideshow + 배경화면 슬라이드쇼 + + + + When login + 로그인 시 + + + + When wakeup + 절전모드 해제 시 + + + + Require a password on wakeup + 절전모드 해제 시 비밀번호 필요 + + + + Never + 없음 + + + + Wait: + 대기: + + + + Wallpaper + 배경화면 + + + + Screensaver + 화면보호기 + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Desktop + button + 바탕화면 + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + 적용 + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_lt.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_lt.ts new file mode 100644 index 0000000..4a97dc8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_lt.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Piktogramų dydis + + + + Auto merge + Automatiškai sulieti + + + + Auto arrange + Automatiškai išdėstyti + + + + Corner Settings + Kampų nustatymai + + + + + Set Wallpaper + Nustatyti darbalaukio foną + + + + Wallpaper and Screensaver + Darbalaukio fonas ir ekrano užsklanda + + + + Properties + Savybės + + + + Display Settings + Ekrano nustatymai + + + + DesktopItemDelegate + + + Tiny + Mažytis + + + + Small + Mažas + + + + Medium + Vidutinis + + + + Large + Didelis + + + + Super large + Didžiulis + + + + DesktopMain + + + Desktop + Darbalaukis + + + + Frame + + + Wallpaper Slideshow + Darbalaukio fono skaidrių rodymas + + + + When login + Prisijungus + + + + When wakeup + Pažadinus kompiuterį + + + + Require a password on wakeup + Pažadinus, reikalauti slaptažodžio + + + + Never + Niekada + + + + Wait: + Laukti: + + + + Wallpaper + Darbalaukio fonas + + + + Screensaver + Ekrano užsklanda + + + + Loading wallpapers... + Įkeliami darbalaukio fonai... + + + + Loading screensavers... + Įkeliamos ekrano užsklandos... + + + + Desktop + button + Darbalaukis + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + Taikyti + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ml.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ml.ts new file mode 100644 index 0000000..169c40a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ml.ts @@ -0,0 +1,176 @@ + + + CanvasGridView + + + Icon size + + + + + Auto merge + + + + + Auto arrange + + + + + Set Wallpaper + + + + + Wallpaper and Screensaver + + + + + Properties + സവിശേഷതകൾ + + + + Display Settings + + + + + Corner Settings + + + + + DesktopItemDelegate + + + Tiny + + + + + Small + + + + + Medium + + + + + Large + + + + + Super large + + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + + + + + When login + + + + + When wakeup + + + + + Require a password on wakeup + + + + + Never + + + + + Wait: + + + + + Wallpaper + + + + + Screensaver + + + + + Only desktop + + + + + Only lock screen + + + + + Apply + + + + + ZoneMainWindow + + + Fast Screen Off + + + + Control Center + + + + + All Windows + + + + + Launcher + + + + + Desktop + ഡെസ്ക്ടോപ്പ് + + + + None + + + + + Close Window + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_mn.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_mn.ts new file mode 100644 index 0000000..f23ceee --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_mn.ts @@ -0,0 +1,168 @@ + + + CanvasGridView + + + Icon size + Таних тэмдэгийн хэмжээ + + + + Auto merge + Автоматаар нэгтгэх + + + + Auto arrange + Автоматаар зохион байгуулах + + + + Corner Settings + Булангийн тохируулга + + + + + Set Wallpaper + Фон зургийг тохируулах + + + + Wallpaper and Screensaver + Фон зураг болон дэлгэц амраагч + + + + Properties + Төлөв байдал + + + + Display Settings + Дэлгэцийн тохируулга + + + + DesktopItemDelegate + + + Tiny + Жижигхэн + + + + Small + Жижиг + + + + Medium + Дунд + + + + Large + Том + + + + Super large + Маш том + + + + DesktopMain + + + Desktop + Ажлын тавцан + + + + Frame + + + Wallpaper Slideshow + + + + + When login + Нэвтрэх үед + + + + When wakeup + Сэргэх үед + + + + Require a password on wakeup + Сэргэх үед нууц үг шаардах + + + + Never + Хэзээ ч үгүй + + + + Wait: + Хүлээх: + + + + Wallpaper + Дэлгэцийн зураг + + + + Screensaver + Дэлгэц амраагч + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Only desktop + button + Зөвхөн ажлын тавцан + + + + Only lock screen + button + Зөвхөн түгжээний дэлгэц + + + + Apply + button + Бататгах + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ms.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ms.ts new file mode 100644 index 0000000..e7b0082 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ms.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Saiz ikon + + + + Auto merge + Auto gabung + + + + Auto arrange + Auto susun + + + + Corner Settings + Tetapan Bucu + + + + + Set Wallpaper + Tetapkan Kertas Dinding + + + + Wallpaper and Screensaver + Kertas Dinding dan Penyelamat Skrin + + + + Properties + Sifat + + + + Display Settings + Tetapan Paparan + + + + DesktopItemDelegate + + + Tiny + Sangat kecil + + + + Small + Kecil + + + + Medium + Sederhana + + + + Large + Besar + + + + Super large + Sangat besar + + + + DesktopMain + + + Desktop + Atas Meja + + + + Frame + + + Wallpaper Slideshow + Paparan Slaid Kertas Dinding + + + + When login + Bila daftar masuk + + + + When wakeup + Bila bangun + + + + Require a password on wakeup + Perlukan kata laluan ketika bangun + + + + Never + Tidak Sesekali + + + + Wait: + Tunggu: + + + + Wallpaper + Kertas Dinding + + + + Screensaver + Penyelamat Skrin + + + + Loading wallpapers... + Memuatkan kertas dinding... + + + + Loading screensavers... + Memuatkan penyelamat skrin... + + + + Desktop + button + Atas Meja + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + Laksana + + + + WaterMaskFrame + + + + Not authorized + Tidak dibenarkan + + + + + In trial period + Masih dalam percubaan + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_nb.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_nb.ts new file mode 100644 index 0000000..fd06436 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_nb.ts @@ -0,0 +1,181 @@ + + + CanvasGridView + + + Icon size + Ikonstørrelse + + + + Auto merge + + + + + Auto arrange + Ordne automatisk + + + + + Set Wallpaper + Sett Bakgrunnsbilde + + + + Wallpaper and Screensaver + Bakgrunnsbilde og Skjermsparer + + + + Properties + Innstillinger + + + + Display Settings + Skjerinnstillinger + + + + DesktopItemDelegate + + + Tiny + Kjempeliten + + + + Small + Liten + + + + Medium + Middels + + + + Large + Stor + + + + Super large + Kjempestor + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + Bakgrunnsbilde Lysbildefremvisning + + + + When login + Når du logger inn + + + + When wakeup + Når datamaskinen våkner + + + + Require a password on wakeup + + + + + Never + Aldri + + + + Wait: + Vent: + + + + Wallpaper + Bakgrunnsbilde + + + + Screensaver + Skjermsparer + + + + Only desktop + Bare skrivebord + + + + Only lock screen + Bare låseskjerm + + + + Apply + Bruk + + + + WaterMaskFrame + + + Not authorized + + + + + In trial period + + + + + ZoneMainWindow + + + Fast Screen Off + Rask Skjerm Av + + + + All Windows + Alle Vindu + + + + Launcher + Launcher + + + + Desktop + Skrivebord + + + + None + Ingen + + + + Close Window + Lukk Vindu + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_nl.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_nl.ts new file mode 100644 index 0000000..e1e4862 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_nl.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Pictogramgrootte + + + + Auto merge + Automatisch samenvoegen + + + + Auto arrange + Automatisch schikken + + + + Corner Settings + Hoekinstellingen + + + + + Set Wallpaper + Achtergrond instellen + + + + Wallpaper and Screensaver + Achtergrond en schermbeveiliging + + + + Properties + Eigenschappen + + + + Display Settings + Beeldscherminstellingen + + + + DesktopItemDelegate + + + Tiny + Extra klein + + + + Small + Klein + + + + Medium + Normaal + + + + Large + Groot + + + + Super large + Extra groot + + + + DesktopMain + + + Desktop + Bureaublad + + + + Frame + + + Wallpaper Slideshow + Diavoorstelling + + + + When login + Bij inloggen + + + + When wakeup + Bij ontwaken + + + + Require a password on wakeup + Wachtwoord vereisen bij ontwaken + + + + Never + Nooit + + + + Wait: + Wachten: + + + + Wallpaper + Bureaubladachtergrond + + + + Screensaver + Schermbeveiliging + + + + Loading wallpapers... + Bezig met laden van achtergronden… + + + + Loading screensavers... + Bezig met laden van schermbeveiligingen… + + + + Desktop + button + Bureaublad + + + + Lock Screen + button + Vergrendelscherm + + + + Both + Beide + + + + Apply + button + Instellen + + + + WaterMaskFrame + + + + Not authorized + Niet toegestaan + + + + + In trial period + In proefperiode + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_pa.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_pa.ts new file mode 100644 index 0000000..06081d3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_pa.ts @@ -0,0 +1,176 @@ + + + CanvasGridView + + + Icon size + + + + + Auto merge + + + + + Auto arrange + ਆਪੇ ਇੰਤਜ਼ਾਮ ਕਰੋ + + + + Set Wallpaper + + + + + Wallpaper and Screensaver + + + + + Properties + + + + + Display Settings + ਡਿਸਪਲੇਅ ਸੈਟਿੰਗਾਂ + + + + Corner Settings + ਕੋਨਾ ਸੈਟਿੰਗਾਂ + + + + DesktopItemDelegate + + + Tiny + + + + + Small + + + + + Medium + + + + + Large + + + + + Super large + + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + + + + + When login + + + + + When wakeup + + + + + Require a password on wakeup + + + + + Never + + + + + Wait: + + + + + Wallpaper + + + + + Screensaver + + + + + Only desktop + + + + + Only lock screen + + + + + Apply + + + + + ZoneMainWindow + + + Fast Screen Off + + + + Control Center + + + + + All Windows + + + + + Launcher + + + + + Desktop + + + + + None + + + + + Close Window + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_pl.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_pl.ts new file mode 100644 index 0000000..783bc3c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_pl.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Rozmiar ikon + + + + Auto merge + Automatyczne łączenie + + + + Auto arrange + Automatyczne sortowanie + + + + Corner Settings + Ustawienia narożników + + + + + Set Wallpaper + Ustaw tapetę pulpitu + + + + Wallpaper and Screensaver + Tapeta pulpitu i wygaszacz ekranu + + + + Properties + Właściwości + + + + Display Settings + Ustawienia ekranu + + + + DesktopItemDelegate + + + Tiny + Maleńki + + + + Small + Mały + + + + Medium + Średni + + + + Large + Duży + + + + Super large + Bardzo duży + + + + DesktopMain + + + Desktop + Pulpit + + + + Frame + + + Wallpaper Slideshow + Pokaz slajdów z tapetami + + + + When login + Podczas logowania + + + + When wakeup + Kiedy się budzę + + + + Require a password on wakeup + Wymagaj hasła podczas budzenia + + + + Never + Nigdy + + + + Wait: + Odczekaj: + + + + Wallpaper + Tapeta pulpitu + + + + Screensaver + Wygaszacz ekranu + + + + Loading wallpapers... + Wczytywanie tapet... + + + + Loading screensavers... + Wczytywanie wygaszaczy ekranu... + + + + Desktop + button + Pulpit + + + + Lock Screen + button + Ekran blokady + + + + Both + Oba + + + + Apply + button + Zastosuj + + + + WaterMaskFrame + + + + Not authorized + Nieautoryzowany + + + + + In trial period + W okresie próbnym + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_pt.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_pt.ts new file mode 100644 index 0000000..104b4b8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_pt.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Tamanho do ícone + + + + Auto merge + Agrupar automaticamente + + + + Auto arrange + Organizar automaticamente + + + + Corner Settings + Definições de cantos + + + + + Set Wallpaper + Definir papel de parede + + + + Wallpaper and Screensaver + Papel de parede e Protector de ecrã + + + + Properties + Propriedades + + + + Display Settings + Definições de visualização + + + + DesktopItemDelegate + + + Tiny + Minúsculo + + + + Small + Pequeno + + + + Medium + Médio + + + + Large + Grande + + + + Super large + Enorme + + + + DesktopMain + + + Desktop + Ambiente de trabalho + + + + Frame + + + Wallpaper Slideshow + Apresentação de diapositivos de papel de parede + + + + When login + Quando iniciar sessão + + + + When wakeup + Quando retomar sessão + + + + Require a password on wakeup + Requer palavra-passe ao retomar sessão + + + + Never + Nunca + + + + Wait: + Aguarde: + + + + Wallpaper + Papel de parede + + + + Screensaver + Protector de ecrã + + + + Loading wallpapers... + A carregar papéis de parede... + + + + Loading screensavers... + A carregar protetores de ecrã... + + + + Desktop + button + Ambiente de trabalho + + + + Lock Screen + button + Ecrã de bloqueio + + + + Both + Ambos + + + + Apply + button + Aplicar + + + + WaterMaskFrame + + + + Not authorized + Não autorizado + + + + + In trial period + Em período experimental + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_pt_BR.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_pt_BR.ts new file mode 100644 index 0000000..55daea6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_pt_BR.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Tamanho do ícone + + + + Auto merge + Agrupar automaticamente + + + + Auto arrange + Organizar automaticamente + + + + Corner Settings + Configurações dos Cantos + + + + + Set Wallpaper + Definir Papel de Parede + + + + Wallpaper and Screensaver + Papel de Parede e Protetor de Tela + + + + Properties + Propriedades + + + + Display Settings + Configurações da Tela + + + + DesktopItemDelegate + + + Tiny + Muito Pequeno + + + + Small + Pequeno + + + + Medium + Médio + + + + Large + Grande + + + + Super large + Super Grande + + + + DesktopMain + + + Desktop + Área de Trabalho + + + + Frame + + + Wallpaper Slideshow + Alternar o papel de parede automaticamente + + + + When login + Quando fizer login + + + + When wakeup + Quando acordar + + + + Require a password on wakeup + Solicitar senha ao acordar + + + + Never + Nunca + + + + Wait: + Intervalo: + + + + Wallpaper + Papel de Parede + + + + Screensaver + Protetor de Tela + + + + Loading wallpapers... + Carregando os papéis de parede... + + + + Loading screensavers... + Carregando os protetores de tela... + + + + Desktop + button + Área de Trabalho + + + + Lock Screen + button + Tela de bloqueio + + + + Both + Ambos + + + + Apply + button + Aplicar + + + + WaterMaskFrame + + + + Not authorized + Não autorizado + + + + + In trial period + Em período de testes + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ro.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ro.ts new file mode 100644 index 0000000..b436782 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ro.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Dimensiune pictogramă + + + + Auto merge + Îmbinare automată + + + + Auto arrange + Aranjare automată + + + + Corner Settings + Setări Colţuri + + + + + Set Wallpaper + Setează Imagine de fundal + + + + Wallpaper and Screensaver + Imagine de fundal şi economisitor de ecran + + + + Properties + Proprietăți + + + + Display Settings + Setări Afișare + + + + DesktopItemDelegate + + + Tiny + Minuscul + + + + Small + Mic + + + + Medium + Mediu + + + + Large + Mare + + + + Super large + Super mare + + + + DesktopMain + + + Desktop + Spațiul de lucru + + + + Frame + + + Wallpaper Slideshow + Diapozitiv Imagini de fundal + + + + When login + La logare + + + + When wakeup + La trezire + + + + Require a password on wakeup + Solicită parola la trezire + + + + Never + Niciodată + + + + Wait: + Aşteaptă: + + + + Wallpaper + Imagine de fundal + + + + Screensaver + Economisitor de ecran + + + + Loading wallpapers... + Încărcare imagini de fundal... + + + + Loading screensavers... + Încărcare economisitori de ecran... + + + + Desktop + button + Spațiul de lucru + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + Aplică + + + + WaterMaskFrame + + + + Not authorized + Nu este autorizat + + + + + In trial period + Perioada de grație + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ru.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ru.ts new file mode 100644 index 0000000..3690c0d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ru.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Размер значка + + + + Auto merge + Автоматическое объединение + + + + Auto arrange + Автоматическое размещение + + + + Corner Settings + Угловая Навигация + + + + + Set Wallpaper + Установить в Качестве Обоев + + + + Wallpaper and Screensaver + Обои и Заставка рабочего стола + + + + Properties + Свойства + + + + Display Settings + Настройки Экрана + + + + DesktopItemDelegate + + + Tiny + Крошечный + + + + Small + Маленький + + + + Medium + Средний + + + + Large + Большой + + + + Super large + Очень большой + + + + DesktopMain + + + Desktop + Рабочий Стол + + + + Frame + + + Wallpaper Slideshow + Слайд-шоу Обоев рабочего стола + + + + When login + При входе + + + + When wakeup + При пробуждении + + + + Require a password on wakeup + Требовать пароль при пробуждении + + + + Never + Никогда + + + + Wait: + Задержка: + + + + Wallpaper + Обои Рабочего стола + + + + Screensaver + Заставка Рабочего стола + + + + Loading wallpapers... + Загрузка обоев... + + + + Loading screensavers... + Загрузка заставок... + + + + Desktop + button + Рабочий Стол + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + Применить + + + + WaterMaskFrame + + + + Not authorized + Не авторизован + + + + + In trial period + Пробный период + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sk.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sk.ts new file mode 100644 index 0000000..05f8d48 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sk.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Veľkosť ikony + + + + Auto merge + Automaticky zlúčiť + + + + Auto arrange + Automaticky usporiadať + + + + Corner Settings + Nastavenia rohov + + + + + Set Wallpaper + Nastaviť pozadie + + + + Wallpaper and Screensaver + Pozadie a šetrič obrazovky + + + + Properties + Vlastnosti + + + + Display Settings + Nastavenie zobrazenia + + + + DesktopItemDelegate + + + Tiny + Maličké + + + + Small + Malé + + + + Medium + Stredné + + + + Large + Veľké + + + + Super large + Veľmi veľké + + + + DesktopMain + + + Desktop + Plocha + + + + Frame + + + Wallpaper Slideshow + Slideshow pozadia + + + + When login + Pri prihlasovaní + + + + When wakeup + Pri prebudení + + + + Require a password on wakeup + Vyžadovať heslo pri prebudení + + + + Never + Nikdy + + + + Wait: + Čakajte: + + + + Wallpaper + Pozadie + + + + Screensaver + Šetrič obrazovky + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Desktop + button + Plocha + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + Vykonať + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sl.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sl.ts new file mode 100644 index 0000000..86813dd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sl.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Velikost ikone + + + + Auto merge + Samodejno združevanje + + + + Auto arrange + Samodejno razporedi + + + + Corner Settings + Nastavitve roba + + + + + Set Wallpaper + Nastavi ozadje + + + + Wallpaper and Screensaver + Ozadje in ohranjevalnik zaslona + + + + Properties + Lastnosti + + + + Display Settings + Nastavitve zaslona + + + + DesktopItemDelegate + + + Tiny + Drobno + + + + Small + Majhno + + + + Medium + Srednje + + + + Large + Veliko + + + + Super large + Zelo veliko + + + + DesktopMain + + + Desktop + Namizje + + + + Frame + + + Wallpaper Slideshow + Diaprojekcija ozadji + + + + When login + Ob prijavi + + + + When wakeup + Ob bujenju + + + + Require a password on wakeup + Ob bujenju zahtevaj geslo + + + + Never + Nikoli + + + + Wait: + Počakaj: + + + + Wallpaper + Ozadje + + + + Screensaver + Ohranjevalnik zaslona + + + + Loading wallpapers... + Nalaganje ozadji... + + + + Loading screensavers... + Nalaganje ohranjevalnikov... + + + + Desktop + button + Namizje + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + Uporabi + + + + WaterMaskFrame + + + + Not authorized + Ni overjeno + + + + + In trial period + Preizkusna doba + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sq.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sq.ts new file mode 100644 index 0000000..8625852 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sq.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Madhësi ikonash + + + + Auto merge + Vetëpërzieji + + + + Auto arrange + Vetësistemim + + + + Corner Settings + Rregullime Këndi + + + + + Set Wallpaper + Caktoni Sfond + + + + Wallpaper and Screensaver + Sfond dhe Ekrankursyes + + + + Properties + Veti + + + + Display Settings + Rregullime Ekrani + + + + DesktopItemDelegate + + + Tiny + Të vockla + + + + Small + Të vogla + + + + Medium + Mesatare + + + + Large + Të mëdha + + + + Super large + Super të mëdha + + + + DesktopMain + + + Desktop + Desktop + + + + Frame + + + Wallpaper Slideshow + Parakalim Sfondesh + + + + When login + Gjatë hyrjes + + + + When wakeup + Gjatë zgjimesh + + + + Require a password on wakeup + Gjatë zgjimi kërko doemos fjalëkalim + + + + Never + Kurrë + + + + Wait: + Pritni: + + + + Wallpaper + Sfond + + + + Screensaver + Ekrankursyes + + + + Loading wallpapers... + Po ngarkohen sfonde… + + + + Loading screensavers... + Po ngarkohen ekrankursyes… + + + + Desktop + button + Desktop + + + + Lock Screen + button + Kyçe Ekranin + + + + Both + Që të dyja + + + + Apply + button + Zbatoje + + + + WaterMaskFrame + + + + Not authorized + E paautorizuar + + + + + In trial period + Në periudhë prove + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sr.ts new file mode 100644 index 0000000..2438cbc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sr.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Величина иконица + + + + Auto merge + Аутоматски сврстај + + + + Auto arrange + Аутоматски сложи + + + + Corner Settings + Подешавање углова + + + + + Set Wallpaper + Постави позадину + + + + Wallpaper and Screensaver + Позадина и чувар екрана + + + + Properties + Својства + + + + Display Settings + Подешавање приказа + + + + DesktopItemDelegate + + + Tiny + Сићушне + + + + Small + Мале + + + + Medium + Средње + + + + Large + Велике + + + + Super large + Огромне + + + + DesktopMain + + + Desktop + Радна површина + + + + Frame + + + Wallpaper Slideshow + Самостална промена позадине + + + + When login + При пријави + + + + When wakeup + При буђењу + + + + Require a password on wakeup + Лозинка при буђењу + + + + Never + Никад + + + + Wait: + Након: + + + + Wallpaper + Позадина + + + + Screensaver + Чувар екрана + + + + Loading wallpapers... + Учитавање позадина... + + + + Loading screensavers... + Учитавање чувара екрана... + + + + Desktop + button + Радна површина + + + + Lock Screen + button + + + + + Both + + + + + Apply + button + Примени + + + + WaterMaskFrame + + + + Not authorized + Није овлашћен + + + + + In trial period + Пробни период + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sv.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sv.ts new file mode 100644 index 0000000..6c5888c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_sv.ts @@ -0,0 +1,168 @@ + + + CanvasGridView + + + Icon size + Ikonstorlek + + + + Auto merge + Autosammanfogning + + + + Auto arrange + Autoarrangera + + + + Corner Settings + Kantinställningar + + + + + Set Wallpaper + Ange som bakgrundsbild + + + + Wallpaper and Screensaver + Bakgrundsbild och skärmsläckare + + + + Properties + Egenskaper + + + + Display Settings + Skärminställningar + + + + DesktopItemDelegate + + + Tiny + Pytteliten + + + + Small + Liten + + + + Medium + Medium + + + + Large + Stor + + + + Super large + Superstor + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + Bakgrundsbildsbildspel + + + + When login + Vid inloggning + + + + When wakeup + Vid väckning + + + + Require a password on wakeup + Kräv ett lösenord vid väckning + + + + Never + Aldrig + + + + Wait: + Vänta: + + + + Wallpaper + Bakgrundsbild + + + + Screensaver + Skärmsläckare + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Only desktop + button + Bara skrivbord + + + + Only lock screen + button + Bara låsskärm + + + + Apply + button + Tillämpa + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ta.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ta.ts new file mode 100644 index 0000000..2bf1c3b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ta.ts @@ -0,0 +1,168 @@ + + + CanvasGridView + + + Icon size + ஐகான் அளவு + + + + Auto merge + தானாக இணை + + + + Auto arrange + தானாக ஒழுங்குபடுத்து + + + + Corner Settings + கார்னர் அமைப்புகள் + + + + + Set Wallpaper + வால்பேப்பராக அமைக்கவும் + + + + Wallpaper and Screensaver + வால்பேப்பர் மற்றும் ஸ்கிரீன்சேவர்கள் + + + + Properties + பண்புகள் + + + + Display Settings + காட்சி அமைப்புகள் + + + + DesktopItemDelegate + + + Tiny + மிக சிறிய + + + + Small + சிறிய + + + + Medium + நடுத்தரம் + + + + Large + பெரிய + + + + Super large + மிகப்பெரிய + + + + DesktopMain + + + Desktop + + + + + Frame + + + Wallpaper Slideshow + வால்பேப்பர் ஸ்லைடுஷோ + + + + When login + உள்நுழையும் போது + + + + When wakeup + விழிப்புணர்வு போது + + + + Require a password on wakeup + விழிப்பூட்டலில் கடவுச்சொல் தேவை + + + + Never + ஒருபோதும் + + + + Wait: + காத்திரு: + + + + Wallpaper + வால்பேப்பர் + + + + Screensaver + ஸ்கிரீன்சேவர்கள் + + + + Loading wallpapers... + + + + + Loading screensavers... + + + + + Only desktop + button + டெஸ்க்டாப்பில் மட்டும் + + + + Only lock screen + button + திரையை மட்டுமே பூட்டு + + + + Apply + button + உபயோகி + + + + WaterMaskFrame + + + + Not authorized + + + + + + In trial period + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_tr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_tr.ts new file mode 100644 index 0000000..696bdbd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_tr.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Simge boyutu + + + + Auto merge + Otomatik birleştir + + + + Auto arrange + Otomatik hizala + + + + Corner Settings + Köşe Ayarları + + + + + Set Wallpaper + Duvar Kağıdını Ayarla + + + + Wallpaper and Screensaver + Duvar Kağıdı ve Ekran Koruyucu + + + + Properties + Özellikler + + + + Display Settings + Görüntü Ayarları + + + + DesktopItemDelegate + + + Tiny + Çok küçük + + + + Small + Küçük + + + + Medium + Orta + + + + Large + Büyük + + + + Super large + Çok büyük + + + + DesktopMain + + + Desktop + Masaüstü + + + + Frame + + + Wallpaper Slideshow + Duvar Kağıdı Slayt Gösterisi + + + + When login + Oturum açıldığında + + + + When wakeup + Uykudan uyanıldığında + + + + Require a password on wakeup + Uyanıldığında parola sor + + + + Never + Asla + + + + Wait: + Bekleme: + + + + Wallpaper + Duvar Kağıdı + + + + Screensaver + Ekran Koruyucu + + + + Loading wallpapers... + Duvar kağıtları yükleniyor... + + + + Loading screensavers... + Ekran koruyucular yükleniyor... + + + + Desktop + button + Masaüstü + + + + Lock Screen + button + Kilit Ekranı + + + + Both + Her ikisi de + + + + Apply + button + Uygula + + + + WaterMaskFrame + + + + Not authorized + Yetkili değil + + + + + In trial period + Deneme döneminde + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ug.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ug.ts new file mode 100644 index 0000000..a73d1eb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_ug.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + سىن بەلگە چوڭ-كىچكلىكى + + + + Auto merge + ئاپتوماتىك بىرلەشتۈرۈش + + + + Auto arrange + ئاپتۇماتىك تىزىش + + + + Corner Settings + بۇلۇڭ تەڭشىكى + + + + + Set Wallpaper + تەگلىك بەلگىلەش + + + + Wallpaper and Screensaver + تام قەغىزى ۋە ئېكران قوغدىغۇچ + + + + Properties + خاسلىقلار + + + + Display Settings + ئېكران تەڭشىكى + + + + DesktopItemDelegate + + + Tiny + كىچىك + + + + Small + كىچىك + + + + Medium + ئوتتۇرا + + + + Large + چوڭ + + + + Super large + ئالاھىدە چوڭ + + + + DesktopMain + + + Desktop + ئۈستەليۈزى + + + + Frame + + + Wallpaper Slideshow + تام قەغىزى تام تەسۋىرى + + + + When login + كىرگەندە + + + + When wakeup + ئويغانغاندا + + + + Require a password on wakeup + ئويغانغاندا پارول تەلەپ قىلسۇن + + + + Never + ئىشلەتمەسلىك + + + + Wait: + ساقلاش: + + + + Wallpaper + تەگلىك رەسىم + + + + Screensaver + ئېكران قوغدىغۇچ + + + + Loading wallpapers... + تەگلىك رەسىم يۈكلىنىۋاتىدۇ... + + + + Loading screensavers... + ئىكران قوغدىغۇچ يۈكلىنىۋاتىدۇ... + + + + Desktop + button + ئۈستەليۈزى + + + + Lock Screen + button + ئېكران قۇلۇپى + + + + Both + تەڭلا تەڭشەش + + + + Apply + button + قوللىنىش + + + + WaterMaskFrame + + + + Not authorized + ئىجازەتسىز + + + + + In trial period + سىناق مۇددىتى + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_uk.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_uk.ts new file mode 100644 index 0000000..160f60e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_uk.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + Розмір іконки + + + + Auto merge + Автоматичне обєднання + + + + Auto arrange + Автоматичне розміщення + + + + Corner Settings + Налаштування кутів + + + + + Set Wallpaper + Встановити шпалери + + + + Wallpaper and Screensaver + Шпалери і зберігач екрана + + + + Properties + Властивості + + + + Display Settings + Налаштування дисплею + + + + DesktopItemDelegate + + + Tiny + Крихітний + + + + Small + Малий + + + + Medium + Середній + + + + Large + Великий + + + + Super large + Супер великий + + + + DesktopMain + + + Desktop + Стільниця + + + + Frame + + + Wallpaper Slideshow + Показ слайдів із зображень тла + + + + When login + Під час входу + + + + When wakeup + Під час пробудження + + + + Require a password on wakeup + Вимагати пароль при пробудженні + + + + Never + Ніколи + + + + Wait: + Очікування: + + + + Wallpaper + Шпалери + + + + Screensaver + Зберігач екрана + + + + Loading wallpapers... + Завантажуємо шпалери… + + + + Loading screensavers... + Завантажуємо зберігачі екрана… + + + + Desktop + button + Стільниця + + + + Lock Screen + button + Заблокувати екран + + + + Both + Обидва + + + + Apply + button + Застосувати + + + + WaterMaskFrame + + + + Not authorized + Не уповноважено + + + + + In trial period + Період тестування + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_zh_CN.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_zh_CN.ts new file mode 100644 index 0000000..a39fd0f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_zh_CN.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + 图标大小 + + + + Auto merge + 自动整理 + + + + Auto arrange + 自动排列 + + + + Corner Settings + 热区设置 + + + + + Set Wallpaper + 设置壁纸 + + + + Wallpaper and Screensaver + 壁纸与屏保 + + + + Properties + 属性 + + + + Display Settings + 显示设置 + + + + DesktopItemDelegate + + + Tiny + 极小 + + + + Small + + + + + Medium + + + + + Large + + + + + Super large + 极大 + + + + DesktopMain + + + Desktop + 桌面 + + + + Frame + + + Wallpaper Slideshow + 自动更换壁纸 + + + + When login + 登录时 + + + + When wakeup + 唤醒时 + + + + Require a password on wakeup + 恢复时需要密码 + + + + Never + 从不 + + + + Wait: + 闲置时间: + + + + Wallpaper + 壁纸 + + + + Screensaver + 屏保 + + + + Loading wallpapers... + 壁纸加载中… + + + + Loading screensavers... + 屏保加载中… + + + + Desktop + button + 桌面 + + + + Lock Screen + button + 锁屏 + + + + Both + 同时设置 + + + + Apply + button + 设置屏保 + + + + WaterMaskFrame + + + + Not authorized + 未授权 + + + + + In trial period + 试用期 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_zh_HK.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_zh_HK.ts new file mode 100644 index 0000000..5c04841 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_zh_HK.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + 圖標大小 + + + + Auto merge + 自動整理 + + + + Auto arrange + 自動排列 + + + + Corner Settings + 熱區設置 + + + + + Set Wallpaper + 設置壁紙 + + + + Wallpaper and Screensaver + 壁紙與屏保 + + + + Properties + 屬性 + + + + Display Settings + 顯示設置 + + + + DesktopItemDelegate + + + Tiny + 極小 + + + + Small + + + + + Medium + + + + + Large + + + + + Super large + 極大 + + + + DesktopMain + + + Desktop + 桌面 + + + + Frame + + + Wallpaper Slideshow + 自動更換壁紙 + + + + When login + 登錄時 + + + + When wakeup + 喚醒時 + + + + Require a password on wakeup + 恢復時需要密碼 + + + + Never + 從不 + + + + Wait: + 閒置時間: + + + + Wallpaper + 壁紙 + + + + Screensaver + 屏保 + + + + Loading wallpapers... + 壁紙加載中… + + + + Loading screensavers... + 屏保加載中… + + + + Desktop + button + 桌面 + + + + Lock Screen + button + 鎖屏 + + + + Both + 同時設置 + + + + Apply + button + 設置屏保 + + + + WaterMaskFrame + + + + Not authorized + 未經授權 + + + + + In trial period + 試用期 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_zh_TW.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_zh_TW.ts new file mode 100644 index 0000000..5747949 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-desktop_zh_TW.ts @@ -0,0 +1,173 @@ + + + CanvasGridView + + + Icon size + 圖示大小 + + + + Auto merge + 自動整理 + + + + Auto arrange + 自動排列 + + + + Corner Settings + 螢幕熱點設定 + + + + + Set Wallpaper + 設定桌布 + + + + Wallpaper and Screensaver + 桌布和螢幕保護程式 + + + + Properties + 屬性 + + + + Display Settings + 顯示設定 + + + + DesktopItemDelegate + + + Tiny + 極小 + + + + Small + + + + + Medium + + + + + Large + + + + + Super large + 超大 + + + + DesktopMain + + + Desktop + 桌面 + + + + Frame + + + Wallpaper Slideshow + 自動切換桌布 + + + + When login + 登入時 + + + + When wakeup + 喚醒時 + + + + Require a password on wakeup + 喚醒時需要密碼 + + + + Never + 永不 + + + + Wait: + 等待時間: + + + + Wallpaper + 桌布 + + + + Screensaver + 螢幕保護程式 + + + + Loading wallpapers... + 壁紙加載中… + + + + Loading screensavers... + 屏保加載中… + + + + Desktop + button + 桌面 + + + + Lock Screen + button + 鎖定畫面 + + + + Both + 同時設定 + + + + Apply + button + 套 用 + + + + WaterMaskFrame + + + + Not authorized + 未授權 + + + + + In trial period + 試用期 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop.ts new file mode 100644 index 0000000..4170c8d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop.ts @@ -0,0 +1 @@ +desktopHomeHomeOpen home directoryOpen home directory \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ar.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ar.ts new file mode 100644 index 0000000..6a51e7e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ar.ts @@ -0,0 +1,2 @@ +desktopHomeالمنزلOpen home directoryافتح الدليل الرئيسي + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_az.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_az.ts new file mode 100644 index 0000000..3747a22 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_az.ts @@ -0,0 +1 @@ +desktopHomeEvOpen home directoryEv qovluğunu açmaq \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_bo.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_bo.ts new file mode 100644 index 0000000..4fff658 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_bo.ts @@ -0,0 +1 @@ +desktopHomeདཀར་ཆག་གཙོ་བོ།Open home directoryདཀར་ཆག་གཙོ་བོ་ཁ་འབྱེད། \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ca.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ca.ts new file mode 100644 index 0000000..72204bd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ca.ts @@ -0,0 +1 @@ +desktopHomeCarpeta de l'usuariOpen home directoryObre la carpeta de l'usuari \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_cs.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_cs.ts new file mode 100644 index 0000000..efe7fb2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_cs.ts @@ -0,0 +1 @@ +desktopHomeDomovská složkaOpen home directoryOtevřít domovskou složku \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_de.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_de.ts new file mode 100644 index 0000000..e98aab4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_de.ts @@ -0,0 +1 @@ +desktopHomeHomeOpen home directoryHome-Verzeichnis öffnen \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_es.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_es.ts new file mode 100644 index 0000000..2bbef6f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_es.ts @@ -0,0 +1 @@ +desktopHomeCarpeta personalOpen home directoryAbrir carpeta personal \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_et.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_et.ts new file mode 100644 index 0000000..7c8dd33 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_et.ts @@ -0,0 +1 @@ +desktopHomeKoduOpen home directoryAva kodukaust \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_fi.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_fi.ts new file mode 100644 index 0000000..630e496 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_fi.ts @@ -0,0 +1 @@ +desktopHomeKotiOpen home directoryAvaa kotikansio \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_fr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_fr.ts new file mode 100644 index 0000000..554618b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_fr.ts @@ -0,0 +1 @@ +desktopHomeAccueilOpen home directoryOuvrir le répertoire personnel \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_gl_ES.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_gl_ES.ts new file mode 100644 index 0000000..bcae9a6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_gl_ES.ts @@ -0,0 +1 @@ +desktopHomeInicioOpen home directoryAbrir o inicio do directorio \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_hr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_hr.ts new file mode 100644 index 0000000..6e60e13 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_hr.ts @@ -0,0 +1 @@ +desktopHomeOsobna mapaOpen home directoryOtvori osobni direktorij \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_hu.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_hu.ts new file mode 100644 index 0000000..4a2490c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_hu.ts @@ -0,0 +1 @@ +desktopHomeSaját mappaOpen home directorySaját mappa megnyitása \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_it.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_it.ts new file mode 100644 index 0000000..835a7f0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_it.ts @@ -0,0 +1 @@ +desktopHomeHomeOpen home directoryApri la Home \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ja.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ja.ts new file mode 100644 index 0000000..d31c2aa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ja.ts @@ -0,0 +1 @@ +desktopHomeホームOpen home directoryホームディレクトリを開きます \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_kab.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_kab.ts new file mode 100644 index 0000000..ed269bc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_kab.ts @@ -0,0 +1 @@ +desktopHomeAgejdanOpen home directoryLdi akaram agejdan \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ko.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ko.ts new file mode 100644 index 0000000..83280bd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ko.ts @@ -0,0 +1 @@ +desktopHomeOpen home directory홈 디렉토리 열기 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_lt.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_lt.ts new file mode 100644 index 0000000..ebf13f2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_lt.ts @@ -0,0 +1 @@ +desktopHomeNamaiOpen home directoryAtverti namų katalogą \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ms.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ms.ts new file mode 100644 index 0000000..7aca812 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ms.ts @@ -0,0 +1 @@ +desktopHomeRumahOpen home directoryBuka direktori rumah \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_nl.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_nl.ts new file mode 100644 index 0000000..0e27f53 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_nl.ts @@ -0,0 +1 @@ +desktopHomePersoonlijke mapOpen home directoryOpen je persoonlijke map \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_pl.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_pl.ts new file mode 100644 index 0000000..1f12684 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_pl.ts @@ -0,0 +1 @@ +desktopHomeKatalog domowyOpen home directoryOtwórz katalog domowy \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_pt.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_pt.ts new file mode 100644 index 0000000..54c64f3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_pt.ts @@ -0,0 +1 @@ +desktopHomePasta PessoalOpen home directoryAbrir diretório da Pasta Pessoal \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_pt_BR.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_pt_BR.ts new file mode 100644 index 0000000..ce65fc1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_pt_BR.ts @@ -0,0 +1 @@ +desktopHomePasta PessoalOpen home directoryAbrir a pasta pessoal \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ro.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ro.ts new file mode 100644 index 0000000..88f5e9d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ro.ts @@ -0,0 +1 @@ +desktopHomeAcasăOpen home directoryDeschide directorul acasă \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ru.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ru.ts new file mode 100644 index 0000000..00d5b44 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ru.ts @@ -0,0 +1 @@ +desktopHomeДомашняя папкаOpen home directoryОткрыть домашний каталог \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_sk.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_sk.ts new file mode 100644 index 0000000..6e65a48 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_sk.ts @@ -0,0 +1 @@ +desktopHomeDomovOpen home directoryOtvoriť domovský adresár \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_sl.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_sl.ts new file mode 100644 index 0000000..c51b5f0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_sl.ts @@ -0,0 +1 @@ +desktopHomeDomOpen home directoryOdpri domačo mapo \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_sq.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_sq.ts new file mode 100644 index 0000000..2662ae1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_sq.ts @@ -0,0 +1 @@ +desktopHomeShtëpiaOpen home directoryHapni drejtorinë shtëpi \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_sr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_sr.ts new file mode 100644 index 0000000..78c9ef2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_sr.ts @@ -0,0 +1 @@ +desktopHomeЛичноOpen home directoryОтвори лични директоријум \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_tr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_tr.ts new file mode 100644 index 0000000..27ca08d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_tr.ts @@ -0,0 +1 @@ +desktopHomeEvOpen home directoryEv dizinini aç \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ug.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ug.ts new file mode 100644 index 0000000..9ad8677 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_ug.ts @@ -0,0 +1 @@ +desktopHomeباش مۇندەرىجەOpen home directoryباش مۇندەرىجىنى ئېچىش \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_uk.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_uk.ts new file mode 100644 index 0000000..0e5b831 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_uk.ts @@ -0,0 +1 @@ +desktopHomeДомівкаOpen home directoryВідкрити домашній каталог \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_zh_CN.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_zh_CN.ts new file mode 100644 index 0000000..604548c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_zh_CN.ts @@ -0,0 +1 @@ +desktopHome主目录Open home directory打开主目录 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_zh_HK.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_zh_HK.ts new file mode 100644 index 0000000..a973f1b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_zh_HK.ts @@ -0,0 +1 @@ +desktopHome主目錄Open home directory打開主目錄 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_zh_TW.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_zh_TW.ts new file mode 100644 index 0000000..126699f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-home-desktop/desktop_zh_TW.ts @@ -0,0 +1 @@ +desktopHome主資料夾Open home directory打開主目錄 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop.ts new file mode 100644 index 0000000..85c42d0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop.ts @@ -0,0 +1 @@ +desktopOpen Trash.Open Trash.Open trash.Open trash.TrashTrash \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_am_ET.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_am_ET.ts new file mode 100644 index 0000000..3f7ec9f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_am_ET.ts @@ -0,0 +1 @@ +desktopOpen Trash.ቆሻሻ መክፈቻOpen trash.ቆሻሻ መክፈቻTrashቆሻሻ \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ar.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ar.ts new file mode 100644 index 0000000..c1643f1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ar.ts @@ -0,0 +1 @@ +desktopOpen Trash.فتح سلة المحذوفاتOpen trash.فتح سلة المحذوفات.Trashالمحذوفات \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ast.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ast.ts new file mode 100644 index 0000000..d96332a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ast.ts @@ -0,0 +1 @@ +desktopOpen Trash.Abrir la papelera.Open trash.Abrir la papelera.TrashPapelera \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_az.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_az.ts new file mode 100644 index 0000000..2d6e81d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_az.ts @@ -0,0 +1 @@ +desktopOpen Trash.Səbəti açmaq.Open trash.Səbəti açmaq.TrashSəbət \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_bg.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_bg.ts new file mode 100644 index 0000000..7d058a3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_bg.ts @@ -0,0 +1 @@ +desktopOpen Trash.Отвори кофата.Open trash.Отвори кофата.TrashКошче \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_bn.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_bn.ts new file mode 100644 index 0000000..8a40e4d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_bn.ts @@ -0,0 +1 @@ +desktopOpen Trash.ট্র্যাশ খুলুনOpen trash.ট্র্যাশ খুলুনTrashট্র্যাশ \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_bo.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_bo.ts new file mode 100644 index 0000000..d464214 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_bo.ts @@ -0,0 +1 @@ +desktopOpen Trash.སྙིགས་སྣོད་ཁ་ཕྱེ།Open trash.སྙིགས་སྣོད་ཁ་ཕྱེ།Trashསྙིགས་སྣོད། \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ca.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ca.ts new file mode 100644 index 0000000..22c6aae --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ca.ts @@ -0,0 +1 @@ +desktopOpen Trash.Obre la paperera.Open trash.Obre la paperera.TrashPaperera \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_cs.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_cs.ts new file mode 100644 index 0000000..b228593 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_cs.ts @@ -0,0 +1 @@ +desktopOpen Trash.Otevřít koš.Open trash.Otevřít koš.TrashKoš \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_da.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_da.ts new file mode 100644 index 0000000..3ee6c70 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_da.ts @@ -0,0 +1 @@ +desktopOpen Trash.Åbn papirkurv.Open trash.Åbn papirkurv.TrashPapirkurv \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_de.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_de.ts new file mode 100644 index 0000000..30db3f1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_de.ts @@ -0,0 +1 @@ +desktopOpen Trash.Papierkorb öffnenOpen trash.Papierkorb öffnen.TrashPapierkorb \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_el.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_el.ts new file mode 100644 index 0000000..386bc5a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_el.ts @@ -0,0 +1 @@ +desktopOpen Trash.Άνοιγμα Κάδου.Open trash.Άνοιγμα Κάδου.TrashΚάδος \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_eo.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_eo.ts new file mode 100644 index 0000000..1a15d99 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_eo.ts @@ -0,0 +1,3 @@ + + +desktopOpen Trash.Open trash.TrashKorbeto diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_es.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_es.ts new file mode 100644 index 0000000..d839188 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_es.ts @@ -0,0 +1 @@ +desktopOpen Trash.Abrir papelera.Open trash.Abrir papelera.TrashPapelera \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_et.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_et.ts new file mode 100644 index 0000000..f46725a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_et.ts @@ -0,0 +1 @@ +desktopOpen Trash.Ava prügikast.Open trash.Ava prügikast.TrashPrügikast \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_fa.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_fa.ts new file mode 100644 index 0000000..8cde5ba --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_fa.ts @@ -0,0 +1 @@ +desktopOpen Trash.باز کردن زباله دانOpen trash.باز کردن زباله دان.Trashزباله دان \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_fi.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_fi.ts new file mode 100644 index 0000000..d151ce1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_fi.ts @@ -0,0 +1 @@ +desktopOpen Trash.Avaa roskakori.Open trash.Avaa roskakori.TrashRoskakori \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_fr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_fr.ts new file mode 100644 index 0000000..8e02b8e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_fr.ts @@ -0,0 +1 @@ +desktopOpen Trash.Ouvrir la corbeille.Open trash.Ouvrir la corbeille.TrashCorbeille \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_gl_ES.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_gl_ES.ts new file mode 100644 index 0000000..25ec4b1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_gl_ES.ts @@ -0,0 +1 @@ +desktopOpen Trash.Abrir o Lixo.Open trash.Abrir o lixo.TrashLixo \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_hr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_hr.ts new file mode 100644 index 0000000..539b83b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_hr.ts @@ -0,0 +1 @@ +desktopOpen Trash.Otvori smeće.Open trash.Otvori smeće.TrashSmeće \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_hu.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_hu.ts new file mode 100644 index 0000000..d288f26 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_hu.ts @@ -0,0 +1 @@ +desktopOpen Trash.Kuka megnyitásaOpen trash.Kuka megnyitásaTrashKuka \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_id.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_id.ts new file mode 100644 index 0000000..d8e840b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_id.ts @@ -0,0 +1 @@ +desktopOpen Trash.Buka Tong sampah.Open trash.Buka tong sampah.TrashTong sampah \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_it.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_it.ts new file mode 100644 index 0000000..c99e5c6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_it.ts @@ -0,0 +1 @@ +desktopOpen Trash.Apri Cestino.Open trash.Apri cestino.TrashCestino \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ja.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ja.ts new file mode 100644 index 0000000..e4e34c5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ja.ts @@ -0,0 +1 @@ +desktopOpen Trash.ゴミ箱を開きます。Open trash.ゴミ箱を開きます。Trashゴミ箱 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_kab.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_kab.ts new file mode 100644 index 0000000..877fe32 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_kab.ts @@ -0,0 +1 @@ +desktopOpen Trash.Ldi taqecwaltOpen trash.Ldi taqecwaltTrashTaqecwalt \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_km_KH.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_km_KH.ts new file mode 100644 index 0000000..9caf5d5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_km_KH.ts @@ -0,0 +1 @@ +desktopOpen Trash.បើកធុងសំរាម។Open trash.បើកធុងសំរាម។Trashធុងសំរាម \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ko.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ko.ts new file mode 100644 index 0000000..ba2d283 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ko.ts @@ -0,0 +1 @@ +desktopOpen Trash.휴지통 열기.Open trash.휴지통 열기.Trash휴지통 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_lt.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_lt.ts new file mode 100644 index 0000000..933e629 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_lt.ts @@ -0,0 +1 @@ +desktopOpen Trash.Atverti šiukšlinę.Open trash.Atverti šiukšlinę.TrashŠiukšlinė \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ml.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ml.ts new file mode 100644 index 0000000..8b0e08f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ml.ts @@ -0,0 +1,3 @@ + + +desktopOpen Trash.Open trash.Trashചവറ്റുകൊട്ട diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ms.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ms.ts new file mode 100644 index 0000000..9e7b68a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ms.ts @@ -0,0 +1 @@ +desktopOpen Trash.Buka Tong Sampah.Open trash.Buka tong sampah.TrashTong Sampah \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_nb.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_nb.ts new file mode 100644 index 0000000..605829d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_nb.ts @@ -0,0 +1 @@ +desktopOpen Trash.Åpne Søppelkasse.Open trash.Åpne søppelkasse.TrashSøppe \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ne.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ne.ts new file mode 100644 index 0000000..e0e9a3f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ne.ts @@ -0,0 +1 @@ +desktopOpen Trash.रद्दीटोकरी खोल्नुहोस्।Open trash.रद्दीटोकरी खोल्नुहोस्।Trashरद्दीटोकरी \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_nl.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_nl.ts new file mode 100644 index 0000000..348bec9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_nl.ts @@ -0,0 +1 @@ +desktopOpen Trash.Prullenbak openenOpen trash.Open de prullenbakTrashPrullenbak \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_pa.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_pa.ts new file mode 100644 index 0000000..cf63181 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_pa.ts @@ -0,0 +1 @@ +desktopOpen Trash.ਰੱਦੀ ਨੂੰ ਖੋਲ੍ਹੋOpen trash.ਰੱਦੀ ਨੂੰ ਖੋਲ੍ਹੋ।Trashਰੱਦੀ \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_pl.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_pl.ts new file mode 100644 index 0000000..c8351be --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_pl.ts @@ -0,0 +1 @@ +desktopOpen Trash.Otwórz kosz.Open trash.Otwórz kosz.TrashKosz \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_pt.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_pt.ts new file mode 100644 index 0000000..9ee0c8d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_pt.ts @@ -0,0 +1 @@ +desktopOpen Trash.Abrir o lixo.Open trash.Abrir o lixo.TrashLixo \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_pt_BR.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_pt_BR.ts new file mode 100644 index 0000000..7521270 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_pt_BR.ts @@ -0,0 +1 @@ +desktopOpen Trash.Abrir Lixeira.Open trash.Abrir lixeira.TrashLixeira \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ro.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ro.ts new file mode 100644 index 0000000..5f52737 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ro.ts @@ -0,0 +1 @@ +desktopOpen Trash.Deschide Coș de gunoiOpen trash.Deschide coș de gunoiTrashCoș de gunoi \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ru.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ru.ts new file mode 100644 index 0000000..92127a8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ru.ts @@ -0,0 +1 @@ +desktopOpen Trash.Открыть Корзину.Open trash.Открыть корзину.TrashКорзина \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sk.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sk.ts new file mode 100644 index 0000000..76d2442 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sk.ts @@ -0,0 +1 @@ +desktopOpen Trash.Otvoriť Kôš.Open trash.Otvoriť kôš.TrashKôš \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sl.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sl.ts new file mode 100644 index 0000000..501e0f9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sl.ts @@ -0,0 +1 @@ +desktopOpen Trash.Odpri koš.Open trash.Odpri koš.TrashKoš \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sq.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sq.ts new file mode 100644 index 0000000..7513cf0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sq.ts @@ -0,0 +1 @@ +desktopOpen Trash.Hap Hedhurinat.Open trash.Hap hedhurinat.TrashHedhurina \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sr.ts new file mode 100644 index 0000000..9e684dc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sr.ts @@ -0,0 +1 @@ +desktopOpen Trash.Отвори смеће.Open trash.Отвори смеће.TrashСмеће \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sv.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sv.ts new file mode 100644 index 0000000..8a0a14f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_sv.ts @@ -0,0 +1 @@ +desktopOpen Trash.Öppna Papperskorg.Open trash.Öppna papperskorg.TrashPapperskorg \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ta.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ta.ts new file mode 100644 index 0000000..d3bb20e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ta.ts @@ -0,0 +1 @@ +desktopOpen Trash. குப்பை கோப்புகளை திறOpen trash. குப்பை கோப்புகளை திறTrashகுப்பை கோப்பு \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_tr.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_tr.ts new file mode 100644 index 0000000..f4aedd0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_tr.ts @@ -0,0 +1 @@ +desktopOpen Trash.Çöp Kutusunu Aç.Open trash.Çöp kutusunu aç.TrashÇöp Kutusu \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ug.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ug.ts new file mode 100644 index 0000000..e108efa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_ug.ts @@ -0,0 +1 @@ +desktopOpen Trash.ئەخلەت چېلىكىنى ئېچىشOpen trash.ئەخلەت چېلىكىنى ئېچىشTrashئەخلەت \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_uk.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_uk.ts new file mode 100644 index 0000000..4d4272b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_uk.ts @@ -0,0 +1 @@ +desktopOpen Trash.Відкрити смітникOpen trash.Відкрити смітникTrashСмітник \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_zh_CN.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_zh_CN.ts new file mode 100644 index 0000000..f62a755 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_zh_CN.ts @@ -0,0 +1 @@ +desktopOpen Trash.打开回收站Open trash.打开回收站Trash回收站 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_zh_HK.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_zh_HK.ts new file mode 100644 index 0000000..b2ba217 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_zh_HK.ts @@ -0,0 +1 @@ +desktopOpen Trash.打開回收站Open trash.打開回收站Trash回收站 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_zh_TW.ts b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_zh_TW.ts new file mode 100644 index 0000000..f19a483 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/translations/dde-trash-desktop/desktop_zh_TW.ts @@ -0,0 +1 @@ +desktopOpen Trash.開啟回收桶。Open trash.開啟回收桶。Trash回收桶 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-desktop/update_translations.sh b/dde-file-manager-5.5.3/src/dde-desktop/update_translations.sh new file mode 100755 index 0000000..f0e2661 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/update_translations.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# this file is used to auto update ts file. + +lupdate -ts translations/dde-desktop.ts -no-obsolete +lupdate -ts translations/dde-desktop_zh_CN.ts -no-obsolete diff --git a/dde-file-manager-5.5.3/src/dde-desktop/util/dde/ddesession.cpp b/dde-file-manager-5.5.3/src/dde-desktop/util/dde/ddesession.cpp new file mode 100644 index 0000000..64f4d40 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/util/dde/ddesession.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "ddesession.h" + +#include +#include + +void Dde::Session::RegisterDdeSession() +{ + const char *envName = "DDE_SESSION_PROCESS_COOKIE_ID"; + QByteArray cookie = qgetenv(envName); + qunsetenv(envName); + + if (!cookie.isEmpty()) { + QDBusInterface iface("com.deepin.SessionManager", + "/com/deepin/SessionManager", + "com.deepin.SessionManager", + QDBusConnection::sessionBus()); + iface.call("Register", QString(cookie)); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/util/dde/ddesession.h b/dde-file-manager-5.5.3/src/dde-desktop/util/dde/ddesession.h new file mode 100644 index 0000000..7168bc2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/util/dde/ddesession.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#pragma once + +namespace Dde +{ +namespace Session +{ +void RegisterDdeSession(); +} +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/util/dde/desktopinfo.cpp b/dde-file-manager-5.5.3/src/dde-desktop/util/dde/desktopinfo.cpp new file mode 100644 index 0000000..d811482 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/util/dde/desktopinfo.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "desktopinfo.h" + +#include +#include + +DesktopInfo::DesktopInfo() +{ + auto e = QProcessEnvironment::systemEnvironment(); + XDG_CURRENT_DESKTOP = e.value(QStringLiteral("XDG_CURRENT_DESKTOP")); + XDG_SESSION_TYPE = e.value(QStringLiteral("XDG_SESSION_TYPE")); + WAYLAND_DISPLAY = e.value(QStringLiteral("WAYLAND_DISPLAY")); + KDE_FULL_SESSION = e.value(QStringLiteral("KDE_FULL_SESSION")); + GNOME_DESKTOP_SESSION_ID = e.value(QStringLiteral("GNOME_DESKTOP_SESSION_ID")); + DESKTOP_SESSION = e.value(QStringLiteral("DESKTOP_SESSION")); +} + +bool DesktopInfo::waylandDectected() +{ + //! 该函数只能在QApplication之后调用才能返回有效的值,在此之前会返回空值 + Q_ASSERT(qApp); + return QApplication::platformName() == "wayland"; +} + +DesktopInfo::WM DesktopInfo::windowManager() +{ + DesktopInfo::WM res = DesktopInfo::OTHER; + if (XDG_CURRENT_DESKTOP.contains(QLatin1String("GNOME"), Qt::CaseInsensitive) || + !GNOME_DESKTOP_SESSION_ID.isEmpty()) { + res = DesktopInfo::GNOME; + } else if (!KDE_FULL_SESSION.isEmpty() || DESKTOP_SESSION == QLatin1String("kde-plasma")) { + res = DesktopInfo::KDE; + } + return res; +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/util/dde/desktopinfo.h b/dde-file-manager-5.5.3/src/dde-desktop/util/dde/desktopinfo.h new file mode 100644 index 0000000..a888ae8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/util/dde/desktopinfo.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#ifndef DESKTOPINFO_H +#define DESKTOPINFO_H + +#include + +class DesktopInfo +{ +public: + DesktopInfo(); + + enum WM { + GNOME, + KDE, + OTHER + }; + + bool waylandDectected(); + WM windowManager(); + +private: + QString XDG_CURRENT_DESKTOP; + QString XDG_SESSION_TYPE; + QString WAYLAND_DISPLAY; + QString KDE_FULL_SESSION; + QString GNOME_DESKTOP_SESSION_ID; + QString GDMSESSION; + QString DESKTOP_SESSION; +}; + +#endif // DESKTOPINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/util/util.cpp b/dde-file-manager-5.5.3/src/dde-desktop/util/util.cpp new file mode 100644 index 0000000..0a19325 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/util/util.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ + +#include "util.h" +#include "dde/desktopinfo.h" +#include +#include +#include +#include +#include +#include +#include + +//#include +//for xcb +#include + +namespace DesktopUtil +{ +void set_desktop_window(QWidget *w) +{ + if (!w) + return; + + w->winId(); //must be called + QWindow *window = w->windowHandle(); + if (!window){ + qWarning() << w << "windowHandle is null"; + return; + } + + if (DesktopInfo().waylandDectected()) { + qDebug() << "wayland set desktop"; + w->setWindowFlags(Qt::FramelessWindowHint); + w->setAttribute(Qt::WA_NativeWindow); + window->setProperty("_d_dwayland_window-type","desktop"); + } else { + QXcbWindowFunctions::setWmWindowType(window, QXcbWindowFunctions::Desktop); + } +} + +#if 0 +QCursor *loadQCursorFromX11Cursor(const char* theme, const char* cursorName, int cursorSize) +{ + if (theme == nullptr || cursorName == nullptr || cursorSize <= 0) + return nullptr; + + XcursorImages *images = XcursorLibraryLoadImages(cursorName, theme, cursorSize); + if (images == nullptr || images->images[0] == nullptr) { + qWarning() << "loadCursorFalied, theme =" << theme << ", cursorName=" << cursorName; + return nullptr; + } + + const int imgW = images->images[0]->width; + const int imgH = images->images[0]->height; + QImage img((const uchar*)images->images[0]->pixels, imgW, imgH, QImage::Format_ARGB32); + QPixmap pixmap = QPixmap::fromImage(img); + QCursor *cursor = new QCursor(pixmap, images->images[0]->xhot, images->images[0]->yhot); + delete images; + return cursor; +} +#endif + +void set_prview_window(QWidget *w) +{ + if (!w) + return; + + w->setWindowFlags(w->windowFlags() | Qt::BypassWindowManagerHint | Qt::WindowDoesNotAcceptFocus); + if (DesktopInfo().waylandDectected()) { + w->winId(); //must be called + QWindow *window = w->windowHandle(); + if (!window){ + qWarning() << w << "windowHandle is null"; + return; + } + qDebug() << "wayland set role dock"; + window->setProperty("_d_dwayland_window-type","wallpaper"); + } +} +} + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/util/util.h b/dde-file-manager-5.5.3/src/dde-desktop/util/util.h new file mode 100644 index 0000000..fbbbb6e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/util/util.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * + * 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 + * 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 . + */ + +#pragma once +#include + +class QWidget; +namespace DesktopUtil +{ + //根据主题加载系统中的x11光标为QCursor,桌面走wayland不需要从x11获取光标 + //QCursor *loadQCursorFromX11Cursor(const char* theme, const char* cursorName, int cursorSize); + void set_desktop_window(QWidget *); + void set_prview_window(QWidget *w); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/util/util.pri b/dde-file-manager-5.5.3/src/dde-desktop/util/util.pri new file mode 100644 index 0000000..76c95fb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/util/util.pri @@ -0,0 +1,9 @@ +HEADERS += \ + $$PWD/dde/ddesession.h \ + $$PWD/util.h \ + $$PWD/dde/desktopinfo.h + +SOURCES += \ + $$PWD/dde/ddesession.cpp \ + $$PWD/util.cpp \ + $$PWD/dde/desktopinfo.cpp diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/backgroundmanager.cpp b/dde-file-manager-5.5.3/src/dde-desktop/view/backgroundmanager.cpp new file mode 100644 index 0000000..663743b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/backgroundmanager.cpp @@ -0,0 +1,505 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "backgroundmanager.h" +#include "screen/screenhelper.h" +#include "util/util.h" + +#include +#include + +BackgroundManager::BackgroundManager(bool preview, QObject *parent) + : QObject(parent) + , windowManagerHelper(DWindowManagerHelper::instance()) + , m_preview(preview) +{ + init(); + QDBusConnection::sessionBus().connect("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged", this, SLOT(onWmDbusStarted(QString, QString, QString))); +} + +BackgroundManager::~BackgroundManager() +{ + if (gsettings) { + gsettings->deleteLater(); + gsettings = nullptr; + } + + if (wmInter) { + wmInter->deleteLater(); + wmInter = nullptr; + } + + windowManagerHelper = nullptr; + + m_backgroundMap.clear(); + QDBusConnection::sessionBus().disconnect("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged", this, SLOT(onWmDbusStarted(QString, QString, QString))); +} + +void BackgroundManager::onRestBackgroundManager() +{ + //判断是否需要绘制背景,如果是窗口绘制背景则桌面isEnable返回false,即桌面不绘制背景 + if (m_preview || isEnabled()) { + if (wmInter) { + return; + } + + wmInter = new WMInter("com.deepin.wm", "/com/deepin/wm", QDBusConnection::sessionBus(), this); + gsettings = new DGioSettings("com.deepin.dde.appearance", "", this); + + if (!m_preview) { + connect(wmInter, &WMInter::WorkspaceSwitched, this, [this] (int, int to) { + currentWorkspaceIndex = to; + pullImageSettings(); + onResetBackgroundImage(); + }); + + connect(gsettings, &DGioSettings::valueChanged, this, [this] (const QString & key, const QVariant & value) { + Q_UNUSED(value); + if (key == "background-uris") { + pullImageSettings(); + onResetBackgroundImage(); + } + }); + } + + //屏幕改变 + connect(ScreenHelper::screenManager(), &AbstractScreenManager::sigScreenChanged, + this, &BackgroundManager::onBackgroundBuild); + disconnect(ScreenHelper::screenManager(), &AbstractScreenManager::sigScreenChanged, + this, &BackgroundManager::onSkipBackgroundBuild); + + //显示模式改变 + connect(ScreenHelper::screenManager(), &AbstractScreenManager::sigDisplayModeChanged, + this, &BackgroundManager::onBackgroundBuild); + disconnect(ScreenHelper::screenManager(), &AbstractScreenManager::sigDisplayModeChanged, + this, &BackgroundManager::onSkipBackgroundBuild); + + //屏幕大小改变 + connect(ScreenHelper::screenManager(), &AbstractScreenManager::sigScreenGeometryChanged, + this, &BackgroundManager::onScreenGeometryChanged); + + //可用区改变,背景不用处理可用区改变 +// connect(ScreenHelper::screenManager(), &AbstractScreenManager::sigScreenAvailableGeometryChanged, +// this, &BackgroundManager::onScreenGeometryChanged); + + //创建背景 + pullImageSettings(); + onBackgroundBuild(); + } else { + + // 清理数据 + if (gsettings) { + gsettings->deleteLater(); + gsettings = nullptr; + } + + if (wmInter) { + wmInter->deleteLater(); + wmInter = nullptr; + } + + currentWorkspaceIndex = 0; + + //屏幕改变 + connect(ScreenHelper::screenManager(), &AbstractScreenManager::sigScreenChanged, + this, &BackgroundManager::onSkipBackgroundBuild); + disconnect(ScreenHelper::screenManager(), &AbstractScreenManager::sigScreenChanged, + this, &BackgroundManager::onBackgroundBuild); + + //显示模式改变 + connect(ScreenHelper::screenManager(), &AbstractScreenManager::sigDisplayModeChanged, + this, &BackgroundManager::onSkipBackgroundBuild); + disconnect(ScreenHelper::screenManager(), &AbstractScreenManager::sigDisplayModeChanged, + this, &BackgroundManager::onBackgroundBuild); + + //没有背景所以不用关心 + disconnect(ScreenHelper::screenManager(), &AbstractScreenManager::sigScreenGeometryChanged, + this, &BackgroundManager::onScreenGeometryChanged); + disconnect(ScreenHelper::screenManager(), &AbstractScreenManager::sigScreenAvailableGeometryChanged, + this, &BackgroundManager::onScreenGeometryChanged); + + //销毁窗口 + m_backgroundMap.clear(); + + //不创建背景 + onSkipBackgroundBuild(); + } +} + +void BackgroundManager::onScreenGeometryChanged() +{ + bool changed = false; + for (ScreenPointer sp : m_backgroundMap.keys()) { + BackgroundWidgetPointer bw = m_backgroundMap.value(sp); + qDebug() << "screen geometry change:" << sp.get() << bw.get(); + if (bw.get() != nullptr) { + //bw->windowHandle()->handle()->setGeometry(sp->handleGeometry()); //不能设置,设置了widget的geometry会被乱改 + //fix bug32166 bug32205 + if (bw->geometry() == sp->geometry()) { + qDebug() << "background geometry is equal to screen geometry,and discard changes" << bw->geometry(); + continue; + } + qInfo() << "background geometry change from" << bw->geometry() << "to" << sp->geometry() + << "screen name" << sp->name(); + bw->setGeometry(sp->geometry()); + changed = true; + } + } + + //背景处理 + if (changed) + onResetBackgroundImage(); +} + +void BackgroundManager::init() +{ + if (!m_preview) { + connect(windowManagerHelper, &DWindowManagerHelper::windowManagerChanged, + this, &BackgroundManager::onRestBackgroundManager); + connect(windowManagerHelper, &DWindowManagerHelper::hasCompositeChanged, + this, &BackgroundManager::onRestBackgroundManager); + } + + onRestBackgroundManager(); +} + +void BackgroundManager::pullImageSettings() +{ + m_backgroundImagePath.clear(); + for (ScreenPointer sc : ScreenMrg->logicScreens()) { + QString path = getBackgroundFromWm(sc->name()); + m_backgroundImagePath.insert(sc->name(), path); + } +} + +QString BackgroundManager::getBackgroundFromWm(const QString &screen) +{ + QString ret; + if (!screen.isEmpty() && wmInter) { + + // 1.从窗管获取壁纸 + int retry = 5; + static const int timeOut = 200; + int oldTimeOut = wmInter->timeout(); + wmInter->setTimeout(timeOut); + + while (retry--) { + qInfo() << "Get background by wm GetCurrentWorkspaceBackgroundForMonitor and sc:" << screen; + QDBusPendingReply reply = wmInter->GetCurrentWorkspaceBackgroundForMonitor(screen); + reply.waitForFinished(); + + if (reply.error().type() != QDBusError::NoError) { + qWarning() << "Get background failed by wmDBus and times:" << (5-retry) + << reply.error().type() << reply.error().name() << reply.error().message(); + } else { + ret = reply.argumentAt<0>(); + qInfo() << "Get background path succeed:" << ret << "screen" << screen << " times:" << (5 - retry); + break; + } + } + wmInter->setTimeout(oldTimeOut); + + if (ret.isEmpty() || !QFile::exists(QUrl(ret).toLocalFile())) { + + // 2.从配置文件解析壁纸 + ret = getBackgroundFromWmConfig(screen); + if (ret.isEmpty() || !QFile::exists(QUrl(ret).toLocalFile())) { + + // 3.使用默认壁纸 + ret = getDefaultBackground(); + qCritical() << "get background fail path :" << ret << "screen" << screen + << "use default:" << ret; + } else { + qCritical() << "get background fail path :" << ret << "screen" << screen + << "use wm config file:" << ret; + } + } else { + qInfo() << "getBackgroundFromWm GetCurrentWorkspaceBackgroundForMonitor path :" << ret << "screen" << screen; + } + } else { + qInfo() << "Get background path terminated screen:" << screen << wmInter; + } + + return ret; +} + +QString BackgroundManager::getBackgroundFromWmConfig(const QString &screen) +{ + QString imagePath; + + QString homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first(); + QFile wmFile(homePath + "/.config/deepinwmrc"); + if (wmFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + + // 根据工作区和屏幕名称查找对应的壁纸 + while (!wmFile.atEnd()) { + QString line = wmFile.readLine(); + int index = line.indexOf("@"); + int indexEQ = line.indexOf("="); + if (index <= 0 || indexEQ <= index+1) { + continue; + } + + int workspaceIndex = line.left(index).toInt(); + QString screenName = line.mid(index+1, indexEQ-index-1); + if (workspaceIndex != currentWorkspaceIndex || screenName != screen) { + continue; + } + + imagePath = line.mid(indexEQ+1).trimmed(); + break; + } + + wmFile.close(); + } + + return imagePath; +} + +QString BackgroundManager::getDefaultBackground() const +{ + //获取默认壁纸 + QString defaultPath; + if (gsettings) { + for (const QString &path : gsettings->value("background-uris").toStringList()){ + if (path.isEmpty() || !QFile::exists(QUrl(path).toLocalFile())) { + continue; + } + else { + defaultPath = path; + qInfo() << "default background path:" << path; + break; + } + } + } + // 设置默认壁纸 + if (defaultPath.isEmpty()) { + defaultPath = QString("file:///usr/share/backgrounds/default_background.jpg"); + } + return defaultPath; +} + +BackgroundWidgetPointer BackgroundManager::createBackgroundWidget(ScreenPointer screen) +{ + BackgroundWidgetPointer bwp(new BackgroundWidget); + bwp->setAccessableInfo(screen->name()); + bwp->setProperty("isPreview", m_preview); + bwp->setProperty("myScreen", screen->name()); // assert screen->name is unique + //bwp->createWinId(); //不创建,4k下有bug + //bwp->windowHandle()->handle()->setGeometry(screen->handleGeometry()); //不能设置,设置了widget的geometry会被乱改//分辨率原始大小 + bwp->setGeometry(screen->geometry()); //经过缩放的区域 + qDebug() << "screen name" << screen->name() << "geometry" << screen->geometry() << bwp.get(); + + if (m_preview) { + DesktopUtil::set_prview_window(bwp.data()); + } else { + DesktopUtil::set_desktop_window(bwp.data()); + } + + return bwp; +} + +bool BackgroundManager::isEnabled() const +{ + // 只支持kwin,或未开启混成的桌面环境 +// return windowManagerHelper->windowManagerName() == DWindowManagerHelper::KWinWM || !windowManagerHelper->hasComposite(); + return m_backgroundEnable; +} + +void BackgroundManager::setVisible(bool visible) +{ + m_visible = visible; + for (BackgroundWidgetPointer w : m_backgroundMap.values()) { + w->setVisible(visible); + } +} + +bool BackgroundManager::isVisible() const +{ + return m_visible; +} + +BackgroundWidgetPointer BackgroundManager::backgroundWidget(ScreenPointer sp) const +{ + return m_backgroundMap.value(sp); +} + +void BackgroundManager::setBackgroundImage(const QString &screen, const QString &path) +{ + if (screen.isEmpty() || path.isEmpty()) + return; + + m_backgroundImagePath[screen] = path; + onResetBackgroundImage(); +} + + +void BackgroundManager::onBackgroundBuild() +{ + //屏幕模式判断 + AbstractScreenManager::DisplayMode mode = ScreenMrg->lastChangedMode(); + qInfo() << "screen mode" << mode << "screen count" << ScreenMrg->screens().size(); + + //实际是单屏 + if ((AbstractScreenManager::Showonly == mode) || (AbstractScreenManager::Duplicate == mode) //仅显示和复制 + || (ScreenMrg->screens().count() == 1)) { //单屏模式 + + ScreenPointer primary = ScreenMrg->primaryScreen(); + if (primary == nullptr) { + qCritical() << "get primary screen failed return"; + //清空并通知view重建 + m_backgroundMap.clear(); + emit sigBackgroundBuilded(mode); + return; + } + + BackgroundWidgetPointer bwp = m_backgroundMap.value(primary); + m_backgroundMap.clear(); + if (!bwp.isNull()) { + if (bwp->geometry() != primary->geometry()) + bwp->setGeometry(primary->geometry()); + } else { + bwp = createBackgroundWidget(primary); + } + + m_backgroundMap.insert(primary, bwp); + + //设置壁纸 + onResetBackgroundImage(); + + if (m_visible) + bwp->show(); + else + qWarning() << "Disable show the background widget, of screen:" << primary->name() << primary->geometry(); + } else { //多屏 + auto screes = ScreenMrg->logicScreens(); + for (auto sp : m_backgroundMap.keys()) { + if (!screes.contains(sp)) { + auto rmd = m_backgroundMap.take(sp); + qInfo() << "screen:" << rmd->property("myScreen") << "is invalid, delete it."; + } + } + for (ScreenPointer sc : screes) { + BackgroundWidgetPointer bwp = m_backgroundMap.value(sc); + if (!bwp.isNull()) { + if (bwp->geometry() != sc->geometry()) + bwp->setGeometry(sc->geometry()); + } else { + qInfo() << "screen:" << sc->name() << " added, create it."; + bwp = createBackgroundWidget(sc); + m_backgroundMap.insert(sc, bwp); + } + + if (m_visible) + bwp->show(); + else + qWarning() << "Disable show the background widget, of screen:" << sc->name() << sc->geometry(); + } + + onResetBackgroundImage(); + } + + //通知view重建 + emit sigBackgroundBuilded(mode); +} + +void BackgroundManager::onSkipBackgroundBuild() +{ + //通知view重建 + emit sigBackgroundBuilded(ScreenMrg->lastChangedMode()); +} + +void BackgroundManager::onResetBackgroundImage() +{ + auto getPix = [](const QString & path, const QPixmap & defalutPixmap)->QPixmap{ + if (path.isEmpty()) + return defalutPixmap; + + QString currentWallpaper = path.startsWith("file:") ? QUrl(path).toLocalFile() : path; + QPixmap backgroundPixmap(currentWallpaper); + // fix whiteboard shows when a jpeg file with filename xxx.png + // content formart not epual to extension + if (backgroundPixmap.isNull()) { + QImageReader reader(currentWallpaper); + reader.setDecideFormatFromContent(true); + backgroundPixmap = QPixmap::fromImage(reader.read()); + } + return backgroundPixmap.isNull() ? defalutPixmap : backgroundPixmap; + }; + + QPixmap defaultImage; + + QMap recorder; //记录有效的壁纸 + for (ScreenPointer sp : m_backgroundMap.keys()) { + QString userPath; + if (!m_backgroundImagePath.contains(sp->name())) { + userPath = getBackgroundFromWm(sp->name()); + } else { + userPath = m_backgroundImagePath.value(sp->name()); + } + + if (!userPath.isEmpty()) + recorder.insert(sp->name(), userPath); + + QPixmap backgroundPixmap = getPix(userPath, defaultImage); + if (backgroundPixmap.isNull()) { + qCritical() << "screen " << sp->name() << "backfround path" << userPath + << "can not read!"; + continue; + } + + BackgroundWidgetPointer bw = m_backgroundMap.value(sp); + QSize trueSize = sp->handleGeometry().size(); //使用屏幕缩放前的分辨率 + auto pix = backgroundPixmap.scaled(trueSize, + Qt::KeepAspectRatioByExpanding, + Qt::SmoothTransformation); + + if (pix.width() > trueSize.width() || pix.height() > trueSize.height()) { + pix = pix.copy(QRect(static_cast((pix.width() - trueSize.width()) / 2.0), + static_cast((pix.height() - trueSize.height()) / 2.0), + trueSize.width(), + trueSize.height())); + } + + qDebug() << sp->name() << "background path" << userPath << "truesize" << trueSize << "devicePixelRatio" + << bw->devicePixelRatioF() << pix << "widget" << bw.get(); + pix.setDevicePixelRatio(bw->devicePixelRatioF()); + bw->setPixmap(pix); + } + + //更新壁纸 + m_backgroundImagePath = recorder; +} + +void BackgroundManager::onWmDbusStarted(QString name, QString oldOwner, QString newOwner) +{ + Q_UNUSED(oldOwner) + Q_UNUSED(newOwner) + //窗管服务注销也会进入该函数,因此需要判断服务是否已注册 + if (name == QString("com.deepin.wm") && QDBusConnection::sessionBus().interface()->isServiceRegistered("com.deepin.wm")) { + qInfo() << "dbus server com.deepin.wm started."; + pullImageSettings(); + onResetBackgroundImage(); + + QDBusConnection::sessionBus().disconnect("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged", this, SLOT(onWmDbusStarted(QString, QString, QString))); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/backgroundmanager.h b/dde-file-manager-5.5.3/src/dde-desktop/view/backgroundmanager.h new file mode 100644 index 0000000..ba04291 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/backgroundmanager.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#ifndef BACKGROUNDMANAGER_H +#define BACKGROUNDMANAGER_H + +#include "backgroundwidget.h" +#include "screen/abstractscreen.h" + +#include +#include +#include + +#include +#include + +using WMInter = com::deepin::wm; + +DGUI_USE_NAMESPACE +class AbstractScreen; +class BackgroundManager : public QObject +{ + Q_OBJECT +public: + explicit BackgroundManager(bool preview = false,QObject *parent = nullptr); + ~BackgroundManager(); + bool isEnabled() const; + void setVisible(bool visible); + bool isVisible() const; + BackgroundWidgetPointer backgroundWidget(ScreenPointer) const; + inline QMap allbackgroundWidgets() const{return m_backgroundMap;} + void setBackgroundImage(const QString &screen,const QString &path); + inline QMap backgroundImages() const {return m_backgroundImagePath;} +signals: + void sigBackgroundBuilded(int mode); //通知canvasview +public slots: + void onBackgroundBuild(); //创建背景窗口 + void onSkipBackgroundBuild(); //不创建背景窗口,直接发完成信号 + void onResetBackgroundImage(); + void onWmDbusStarted(QString name, QString oldOwner, QString newOwner); //窗管dbus服务启动完成 +protected slots: + void onRestBackgroundManager(); //重置背景,响应窗管改变 + void onScreenGeometryChanged(); //响应屏幕大小改变 +private: + void init(); + void pullImageSettings(); + QString getBackgroundFromWm(const QString &screen); + QString getBackgroundFromWmConfig(const QString &screen); + QString getDefaultBackground() const; + BackgroundWidgetPointer createBackgroundWidget(ScreenPointer); +protected: + DGioSettings *gsettings = nullptr; + WMInter *wmInter = nullptr; + DWindowManagerHelper* windowManagerHelper = nullptr; +private: + bool m_preview = false; //壁纸预览 + bool m_visible = true; + int currentWorkspaceIndex = 1; + bool m_backgroundEnable = true; + + QMap m_backgroundMap; + + //记录设置的背景的壁纸 + QMap m_backgroundImagePath; +}; + +#endif // BACKGROUNDMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/backgroundwidget.cpp b/dde-file-manager-5.5.3/src/dde-desktop/view/backgroundwidget.cpp new file mode 100644 index 0000000..a8a3712 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/backgroundwidget.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "backgroundwidget.h" +#include "canvasgridview.h" +#include "accessibility/ac-desktop-define.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BackgroundWidget::BackgroundWidget(QWidget *parent) + : QWidget(parent) +{ + AC_SET_OBJECT_NAME( this, AC_SCREEN_BACKGROUND); + AC_SET_ACCESSIBLE_NAME( this, AC_SCREEN_BACKGROUND); +} + +BackgroundWidget::~BackgroundWidget() +{ + if (m_view.get() != nullptr){ + m_view->setParent(nullptr); + m_view = nullptr; + } +} + +void BackgroundWidget::setPixmap(const QPixmap &pixmap) +{ + m_pixmap = pixmap; + m_noScalePixmap = pixmap; + m_noScalePixmap.setDevicePixelRatio(1); + update(); +} + +void BackgroundWidget::paintEvent(QPaintEvent *event) +{ + qreal scale = devicePixelRatioF(); + if (scale > 1.0 && event->rect() == rect()) { + if (backingStore()->handle()->paintDevice()->devType() != QInternal::Image) { + return; + } + + QImage *image = static_cast(backingStore()->handle()->paintDevice()); + QPainter pa(image); + pa.drawPixmap(0, 0, m_noScalePixmap); + return; + } + + QPainter pa(this); + pa.drawPixmap(event->rect().topLeft(), m_pixmap, QRectF(QPointF(event->rect().topLeft()) * scale, QSizeF(event->rect().size()) * scale)); +} + +void BackgroundWidget::setView(const QSharedPointer &v) +{ + if (v.get() != nullptr) + v->setParent(this); + m_view = v; +} + +void BackgroundWidget::setAccessableInfo(const QString& info) +{ + if(info.isEmpty()) + return; + + AC_SET_OBJECT_NAME( this, info); + AC_SET_ACCESSIBLE_NAME( this, info); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/backgroundwidget.h b/dde-file-manager-5.5.3/src/dde-desktop/view/backgroundwidget.h new file mode 100644 index 0000000..23fe683 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/backgroundwidget.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#ifndef BACKGROUNDWIDGET_H +#define BACKGROUNDWIDGET_H + +#include +#include +#include + +class CanvasGridView; +class BackgroundWidget : public QWidget +{ + Q_OBJECT +public: + explicit BackgroundWidget(QWidget *parent = nullptr); + ~BackgroundWidget() override; + void setPixmap(const QPixmap &pixmap); + void paintEvent(QPaintEvent *event) override; + void setView(const QSharedPointer &); + inline QPixmap pixmap() const {return m_pixmap;} + void setAccessableInfo(const QString& info); +private: + QPixmap m_pixmap; + QPixmap m_noScalePixmap; + QSharedPointer m_view; //保有view的指针,防止背景释放时,连带一起释放view +}; + +typedef QSharedPointer BackgroundWidgetPointer; +#endif // BACKGROUNDWIDGET_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/canvasgridview.cpp b/dde-file-manager-5.5.3/src/dde-desktop/view/canvasgridview.cpp new file mode 100644 index 0000000..ebb2ee6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/canvasgridview.cpp @@ -0,0 +1,3784 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: wangchunlin + * + * Maintainer: wangchunlin + * + * 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 + * 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 . + */ + +#include "canvasgridview.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//dfmlib singleton +#include <../utils/singleton.h> +#include + +#include "../util/dde/desktopinfo.h" +#include "../model/dfileselectionmodel.h" +#include "../presenter/gridmanager.h" +#include "../presenter/apppresenter.h" +#include "../presenter/dfmsocketinterface.h" +#include "../desktop.h" +#include "../config/config.h" +#include "screen/screenhelper.h" +#include "../models/desktopfileinfo.h" + +#include "interfaces/private/mergeddesktop_common_p.h" +#include "private/canvasviewprivate.h" +#include "canvasviewhelper.h" +#include "watermaskframe.h" +#include "desktopitemdelegate.h" + +#include "app/define.h" +#include "controllers/mergeddesktopcontroller.h" +#include "../dde-wallpaper-chooser/screensavercontrol.h" + +#include "accessibility/ac-desktop-define.h" + +#define DESKTOP_CAN_SCREENSAVER "DESKTOP_CAN_SCREENSAVER" +#define DRAGICON_SIZE 128 //拖拽聚合默认icon边长 +#define DRAGICON_OUTLINE 30 //增加外圈范围,防止旋转后部分图片的角绘制不到 +#define DRAGICON_MAX 4 //拖拽聚合最多绘制icon数量 +#define DRAGICON_ROTATE 10.0 //拖拽聚合旋转角度 +#define DRAGICON_OPACITY 0.1 //拖拽聚合透明度梯度 +#define DRAGICON_MAX_COUNT 99 //最大显示计数 + +QMap CanvasGridView::virtualEntryExpandState; + +static const QMap kSortActions = {{MenuAction::Name, DFileSystemModel::FileDisplayNameRole} + , {MenuAction::Size, DFileSystemModel::FileSizeRole} + , {MenuAction::Type, DFileSystemModel::FileMimeTypeRole} + , {MenuAction::LastModifiedDate, DFileSystemModel::FileLastModifiedRole} +}; + +DWIDGET_USE_NAMESPACE + +//candrop十分耗时,在不关心Qt::ItemDropEnable的调用时ignoreDropFlag为true,不调用candrop,节省时间,bug#10926 +namespace { + class IgnoreDropFlag + { + public: + explicit IgnoreDropFlag(DFileSystemModel *m) : model(m) + { + if (model) + model->ignoreDropFlag = true; + } + ~IgnoreDropFlag() + { + if (model) + model->ignoreDropFlag = false; + } + private: + DFileSystemModel *model = nullptr; + }; + + static void setMenuActionsFilter() + { + DFileMenuManager::setActionWhitelist(QSet()); + DFileMenuManager::setActionBlacklist(QSet()); + } + // end +} + +CanvasGridView::CanvasGridView(const QString &screen, QWidget *parent) + : QAbstractItemView(parent) + , d(new CanvasViewPrivate) + , m_screenName(screen) + , m_currentTargetUrl(DUrl()) +{ + AC_SET_OBJECT_NAME(this, AC_CANVAS_GRID_VIEW); + AC_SET_ACCESSIBLE_NAME(this, AC_CANVAS_GRID_VIEW); + initUI(); + initConnection(); +} + +CanvasGridView::~CanvasGridView() +{ + +} + +QRect CanvasGridView::visualRect(const QModelIndex &index) const +{ + auto url = model()->getUrlByIndex(index); + auto gridPos = GridManager::instance()->position(m_screenNum, url.toString()); + + auto x = gridPos.x() * d->cellWidth + d->viewMargins.left(); + auto y = gridPos.y() * d->cellHeight + d->viewMargins.top(); + return QRect(x, y, d->cellWidth, d->cellHeight); +} + +QModelIndex CanvasGridView::indexAt(const QPoint &point) const +{ + QPoint gridPos = gridAt(point); + //如果本屏有堆叠就,并且point为堆叠点,那么修改点击的项目为堆叠项目的最后一个 for优先在最后一个网格显示堆叠的最后一个项目 + QString localFile = GridManager::instance()->itemTop(m_screenNum, gridPos.x(), gridPos.y()); + //GridManager::instance()->itemId(m_screenNum, gridPos.x(), gridPos.y()); + + QModelIndex rowIndex = model()->index(DUrl(localFile)); + QPoint pos = QPoint(point.x() + horizontalOffset(), point.y() + verticalOffset()); + auto list = itemPaintGeomertys(rowIndex); + + + for (QModelIndex &index : itemDelegate()->hasWidgetIndexs()) { + if (index == itemDelegate()->editingIndex()) { + QWidget *widget = itemDelegate()->editingIndexWidget(); + if (widget && widget->isVisible() && widget->geometry().contains(point)) { + return index; + } + continue; + } + + QWidget *widget = indexWidget(index); + + if (widget && widget->isVisible() && widget->geometry().contains(point)) { + return index; + } + } + + auto ret = std::any_of(list.begin(), list.end(), [pos](const QRect & rect) { + return rect.contains(pos); + }); + + if (ret) + return rowIndex; + + return QModelIndex(); +} + +void CanvasGridView::scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint hint) +{ + Q_UNUSED(hint); + QRect area = viewport()->rect(); + QRect rect = visualRect(index); + + if (rect.left() < area.left()) { + horizontalScrollBar()->setValue( + horizontalScrollBar()->value() + rect.left() - area.left()); + } else if (rect.right() > area.right()) { + horizontalScrollBar()->setValue( + horizontalScrollBar()->value() + qMin( + rect.right() - area.right(), rect.left() - area.left())); + } + + if (rect.top() < area.top()) { + verticalScrollBar()->setValue( + verticalScrollBar()->value() + rect.top() - area.top()); + } else if (rect.bottom() > area.bottom()) { + verticalScrollBar()->setValue( + verticalScrollBar()->value() + qMin( + rect.bottom() - area.bottom(), rect.top() - area.top())); + } + + update(); +} + +QModelIndex CanvasGridView::moveCursorGrid(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) +{ + Q_UNUSED(modifiers); +// qDebug() << modifiers << d->currentCursorIndex; + + auto selectionModel = this->selectionModel(); + auto headIndex = firstIndex(); + auto tailIndex = lastIndex(); + + QModelIndex current = d->currentCursorIndex; + if (!current.isValid() || !selectionModel->isSelected(current)) { + return headIndex; + } + auto url = model()->getUrlByIndex(current); + + auto pos = GridManager::instance()->position(m_screenNum, url.toString()); + auto newCoord = Coordinate(pos); + + switch (cursorAction) { + case MoveLeft: + while (pos.x() >= 0) { + newCoord = newCoord.moveLeft(); + pos = newCoord.position(); + if (!GridManager::instance()->isEmpty(m_screenNum, pos.x(), pos.y())) { + break; + } + } + break; + case MoveRight: + while (pos.x() < d->colCount) { + newCoord = newCoord.moveRight(); + pos = newCoord.position(); + if (!GridManager::instance()->isEmpty(m_screenNum, pos.x(), pos.y())) { + break; + } + } + break; + case MovePrevious: + case MoveUp: + while (pos.y() >= 0 && pos.x() >= 0) { + newCoord = newCoord.moveUp(); + pos = newCoord.position(); + if (pos.y() < 0) { + newCoord = Coordinate(pos.x() - 1, d->rowCount - 1); + pos = newCoord.position(); + } + if (!GridManager::instance()->isEmpty(m_screenNum, pos.x(), pos.y())) { + break; + } + } + break; + case MoveNext: + case MoveDown: + while (pos.y() < d->rowCount && pos.x() < d->colCount) { + newCoord = newCoord.moveDown(); + pos = newCoord.position(); + if (pos.y() >= d->rowCount) { + newCoord = Coordinate(pos.x() + 1, 0); + pos = newCoord.position(); + } + if (!GridManager::instance()->isEmpty(m_screenNum, pos.x(), pos.y())) { + break; + } + } + break; + case MoveHome: + case MovePageUp: { + if (modifiers == Qt::ShiftModifier) { + QItemSelection selection; + while (pos.y() >= 0 && pos.x() >= 0) { + newCoord = newCoord.moveUp(); + pos = newCoord.position(); + if (pos.y() < 0) { + newCoord = Coordinate(pos.x() - 1, d->rowCount - 1); + pos = newCoord.position(); + } + if (!GridManager::instance()->isEmpty(m_screenNum, pos.x(), pos.y())) { + auto localFile = GridManager::instance()->itemTop(m_screenNum, pos.x(), pos.y()); + //GridManager::instance()->itemId(m_screenNum, pos.x(), pos.y()); + auto index = model()->index(DUrl(localFile)); + + QItemSelectionRange selectionRange(index); + selection.push_back(selectionRange); + } + } + QAbstractItemView::selectionModel()->select(selection, QItemSelectionModel::Select); + } + return headIndex; + } + case MoveEnd: + case MovePageDown: { + if (modifiers == Qt::ShiftModifier) { + QItemSelection selection; + while (pos.y() < d->rowCount && pos.x() < d->colCount) { + newCoord = newCoord.moveDown(); + pos = newCoord.position(); + if (pos.y() >= d->rowCount) { + newCoord = Coordinate(pos.x() + 1, 0); + pos = newCoord.position(); + } + if (!GridManager::instance()->isEmpty(m_screenNum, pos.x(), pos.y())) { + auto localFile = GridManager::instance()->itemTop(m_screenNum, pos.x(), pos.y()); + //GridManager::instance()->itemId(m_screenNum, pos.x(), pos.y()); + auto index = model()->index(DUrl(localFile)); + + QItemSelectionRange selectionRange(index); + selection.push_back(selectionRange); + } + } + + QAbstractItemView::selectionModel()->select(selection, QItemSelectionModel::Select); + } + return tailIndex; + } + } + + if (!d->isVaildCoordinate(newCoord)) { + return current; + } + + auto localFile = GridManager::instance()->itemTop(m_screenNum, pos.x(), pos.y()); + //GridManager::instance()->itemId(m_screenNum, pos.x(), pos.y()); + auto newIndex = model()->index(DUrl(localFile)); + if (newIndex.isValid()) { + return newIndex; + } + + //qDebug() << selectedUrls(); + return current; +} + +void CanvasGridView::updateHiddenItems() +{ + itemDelegate()->hideAllIIndexWidget(); + clearSelection(); + + auto filters = model()->filters(); + filters = GridManager::instance()->getWhetherShowHiddenFiles() ? + filters | QDir::Hidden : filters & ~QDir::Hidden; + qDebug() << "current filters" << GridManager::instance()->getWhetherShowHiddenFiles() + << filters << m_screenName << m_screenNum; + model()->setFilters(filters); + delayModelRefresh(0); + return; +} + +void CanvasGridView::updateExpandItemGeometry() +{ + updateEditorGeometries(); +} + +void CanvasGridView::setGeometry(const QRect &rect) +{ + //!防止获取到的屏幕区域是0x0的时候崩溃 + if (rect.size().width() < 1 || rect.size().height() < 1) { + return; + } else { + QAbstractItemView::setGeometry(rect); + updateCanvas(); + if (d->waterMaskFrame) + d->waterMaskFrame->updatePosition(); + } +} + +bool CanvasGridView::fetchDragEventUrlsFromSharedMemory() +{ + QSharedMemory sm; + sm.setKey(DRAG_EVENT_URLS); + + if (!sm.isAttached()) { + if (!sm.attach()) { + qWarning() << "FQSharedMemory detach failed."; + return false; + } + } + + QBuffer buffer; + QDataStream in(&buffer); + + sm.lock(); + //用缓冲区得到共享内存关联后得到的数据和数据大小 + +// buffer.setData((char*)sm.constData(), sm.size());//解决警告采用下方方式 + buffer.setData(static_cast(const_cast(sm.constData())), sm.size()); + + buffer.open(QBuffer::ReadOnly); //设置读取模式 + in >> m_urlsForDragEvent; //使用数据流从缓冲区获得共享内存的数据,然后输出到字符串中 + sm.unlock(); //解锁 + sm.detach();//与共享内存空间分离 + + return true; +} + +void CanvasGridView::setTargetUrlToApp(const QMimeData *data, const DUrl &url) +{ + //仅当target改变的时候才调用DFileDragClient::setTargetUrl + if (!m_currentTargetUrl.isValid() || m_currentTargetUrl.path() != url.path()) { + m_currentTargetUrl = url; + DFileDragClient::setTargetUrl(data, url); + } +} + +void CanvasGridView::delayModelRefresh(int ms) +{ + if (m_refreshTimer != nullptr) { + m_refreshTimer->stop(); + delete m_refreshTimer; + m_refreshTimer = nullptr; + qDebug() << "reset refresh timer" << m_screenNum; + } + + if (ms < 1) { + qDebug() << "now refresh " << m_refreshTimer << m_screenNum; + m_rt.start(); + model()->refresh(); + return; + } + + m_refreshTimer = new QTimer(this); + connect(m_refreshTimer, &QTimer::timeout, this, [ = ]() { + m_refreshTimer->stop(); + qDebug() << "beging refresh " << m_refreshTimer << m_screenNum; + m_rt.start(); + model()->refresh(); + }); + + m_refreshTimer->start(ms); +} + +void CanvasGridView::delayArrage(int ms) +{ + static QTimer *arrangeTimer = nullptr; + if (arrangeTimer != nullptr) { + arrangeTimer->stop(); + delete arrangeTimer; + arrangeTimer = nullptr; + qDebug() << "reset timer" << m_screenNum; + } +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + if (ms < 1) { + d->bReloadItem = true; + qDebug() << "beging sort " << arrangeTimer << m_screenNum; + model()->setEnabledSort(true); + model()->sort(); + return; + } + + arrangeTimer = new QTimer; + connect(arrangeTimer, &QTimer::timeout, this, [ = ]() { + arrangeTimer->stop(); + d->bReloadItem = true; + qDebug() << "beging sort " << arrangeTimer << m_screenNum; + model()->setEnabledSort(true); + model()->sort(); + }); +#else + if (ms < 1) { + qDebug() << "beging arrage " << arrangeTimer << m_screenNum; + auto list = GridManager::instance()->allItems(); + qDebug() << "initArrage file count" << list.size(); + GridManager::instance()->initArrage(list); + GridManager::instance()->delaySyncAllProfile(); + + emit GridManager::instance()->sigSyncOperation(GridManager::soUpdate); + return; + } + + arrangeTimer = new QTimer; + connect(arrangeTimer, &QTimer::timeout, this, [ = ]() { + arrangeTimer->stop(); + auto list = GridManager::instance()->allItems(); + qDebug() << "initArrage file count" << list.size(); + GridManager::instance()->initArrage(list); + GridManager::instance()->delaySyncAllProfile(); + + emit GridManager::instance()->sigSyncOperation(GridManager::soUpdate); + }); +#endif + arrangeTimer->start(ms); +} + +void CanvasGridView::delayCustom(int ms) +{ +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + if (GridManager::instance()->shouldArrange()) { +#else + if (GridManager::instance()->autoMerge()) { +#endif + return; + } + + static QTimer *arrangeTimer = nullptr; + if (arrangeTimer != nullptr) { + arrangeTimer->stop(); + delete arrangeTimer; + arrangeTimer = nullptr; + qDebug() << "reset Custom timer" << m_screenNum; + } + + if (ms < 1) { + QStringList list; + for (int i = 0; i < model()->rowCount(); ++i) { + auto index = model()->index(i, 0); + auto localFile = model()->getUrlByIndex(index).toString(); + list << localFile; + } + qDebug() << "initCustom file count" << list.size(); + GridManager::sortMainDesktopFile(list, model()->sortRole(), model()->sortOrder()); + GridManager::instance()->initCustom(list); +#ifndef USE_SP2_AUTOARRAGE //sp3需求改动 + if (GridManager::instance()->autoArrange()) { + delayArrage(0); + } +#endif + emit GridManager::instance()->sigSyncOperation(GridManager::soUpdate); + return; + } + + arrangeTimer = new QTimer; + connect(arrangeTimer, &QTimer::timeout, this, [ = ]() { + arrangeTimer->stop(); + QStringList list; + for (int i = 0; i < model()->rowCount(); ++i) { + auto index = model()->index(i, 0); + auto localFile = model()->getUrlByIndex(index).toString(); + list << localFile; + } + GridManager::sortMainDesktopFile(list, model()->sortRole(), model()->sortOrder()); + auto oriItems = GridManager::instance()->allItems(); + qDebug() << "initCustom file count" << list.size() << " and oriItems count " << oriItems.count(); + GridManager::instance()->initCustom(list); +#ifndef USE_SP2_AUTOARRAGE //sp3需求改动 + if (GridManager::instance()->autoArrange()) { + delayArrage(0); + } +#endif + + //fix bug #32527 + if (list.isEmpty() && !oriItems.isEmpty()) { + delayModelRefresh(500); + } + + emit GridManager::instance()->sigSyncOperation(GridManager::soUpdate); + }); + arrangeTimer->start(ms); +} + +void CanvasGridView::delayAutoMerge(int ms) +{ + if (!GridManager::instance()->autoMerge()) { + return; + } + + static QTimer *arrangeTimer = nullptr; + if (arrangeTimer != nullptr) { + arrangeTimer->stop(); + delete arrangeTimer; + arrangeTimer = nullptr; + qDebug() << "reset autoMerge timer" << m_screenNum; + } + + if (ms < 1) { + QStringList list; + for (int i = 0; i < model()->rowCount(); ++i) { + auto index = model()->index(i, 0); + auto localFile = model()->getUrlByIndex(index).toString(); + list << localFile; + } + qDebug() << "now initArrage file count" << list.size() + << "expend" << currentUrl().fragment(); + GridManager::instance()->initArrage(list); + return; + } + + arrangeTimer = new QTimer; + connect(arrangeTimer, &QTimer::timeout, this, [ = ]() { + arrangeTimer->stop(); + QStringList list; + for (int i = 0; i < model()->rowCount(); ++i) { + auto index = model()->index(i, 0); + auto localFile = model()->getUrlByIndex(index).toString(); + list << localFile; + } + qDebug() << "initArrage file count" << list.size() + << "expend" << currentUrl().fragment() << "screen" << m_screenNum; + GridManager::instance()->initArrage(list); + }); + arrangeTimer->start(ms); +} + +DUrl CanvasGridView::currentCursorFile() const +{ + DUrl ret; + DAbstractFileInfoPointer fp = model()->fileInfo(d->currentCursorIndex); + if (fp) { + ret = fp->fileUrl(); + } + return ret; +} + +void CanvasGridView::syncIconLevel(int level) +{ + if (itemDelegate()->iconSizeLevel() == level) { + return; + } + + itemDelegate()->setIconSizeByIconSizeLevel(level); + updateCanvas(); +} + +WId CanvasGridView::winId() const +{ + if (isTopLevel()) { + return QAbstractItemView::winId(); + } else { + return topLevelWidget()->winId(); + } +} + +void CanvasGridView::setAutoMerge(bool enabled) +{ + GridManager::instance()->setAutoMerge(enabled); + if (enabled) { + //this->setRootUrl(DUrl(DFMMD_ROOT MERGEDDESKTOP_FOLDER)); + //刷新虚拟路径时是先查看是否已有展开状态 + DUrl virtualExpandUrl = GridManager::instance()->getCurrentVirtualExpandUrl(); + if (virtualExpandUrl.fragment().isEmpty()) { + this->setRootUrl(DUrl(DFMMD_ROOT MERGEDDESKTOP_FOLDER)); + } else { + this->setRootUrl(virtualExpandUrl); + } + } else { + // sa + QString desktopPath = QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first(); + DUrl desktopUrl = DUrl::fromLocalFile(desktopPath); + + if (!QDir(desktopPath).exists()) { + QDir::home().mkpath(desktopPath); + } + + //复位成未展开的状态 + DUrl clearUrl; + GridManager::instance()->setCurrentVirtualExpandUrl(DUrl(QUrl())); + this->setRootUrl(desktopUrl); + } +} + +// please make sure the passed \a url argument is a valid virtual entry url. +void CanvasGridView::toggleEntryExpandedState(const DUrl &url) +{ + // just some simple check + if (!url.isValid() || url.scheme() != DFMMD_SCHEME) { + return; + } + + clearSelection(); + + // toggle expand state + DMD_TYPES toggleType = MergedDesktopController::entryTypeByName(url.fileName()); + virtualEntryExpandState[toggleType] = !virtualEntryExpandState[toggleType]; + bool isExpand = virtualEntryExpandState[toggleType]; + + // construct fragment which indicated the expanded entries + QStringList expandedEntries; + int possibleChildCount = 0; + + bool onlyExpandShowClickedEntry = false; + for (unsigned int i = DMD_FIRST_TYPE; i <= DMD_ALL_TYPE; i++) { + DMD_TYPES oneType = static_cast(i); + if (oneType != DMD_FOLDER && virtualEntryExpandState[oneType]) { + expandedEntries.append(MergedDesktopController::entryNameByEnum(oneType)); + } + + // check if icon cound is greater than desktop grid count + possibleChildCount += 1; // 1: the virtual entry icon + if (isExpand && virtualEntryExpandState[oneType]) { + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, MergedDesktopController::getVirtualEntryPath(oneType)); + if (info) { + possibleChildCount += info->filesCount(); + } + } + } + if (possibleChildCount > GridManager::instance()->gridCount()) { + onlyExpandShowClickedEntry = true; + } + + // prepare root url + DUrl targetUrl(DFMMD_ROOT MERGEDDESKTOP_FOLDER); + + if (!expandedEntries.isEmpty()) { + targetUrl.setFragment(onlyExpandShowClickedEntry ? MergedDesktopController::entryNameByEnum(toggleType) : expandedEntries.join(',')); + } + + // set root url (which will update the view) + this->setRootUrl(targetUrl); + //更新其他canvas的model自动整理数据。 todo:考虑优化没有扩展到的不用刷新 + QMap mergeUpInfo; + mergeUpInfo.insert(m_screenName, targetUrl); + emit GridManager::instance()->sigSyncOperation(GridManager::soAutoMergeUpdate, QVariant::fromValue(mergeUpInfo)); + +} + +void CanvasGridView::updateEntryExpandedState(const DUrl &url) +{ + this->setRootUrl(url); +} + +QModelIndex CanvasGridView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers) +{ + // Do not allow move when hold ctrl + if (modifiers == Qt::ControlModifier) { + return d->currentCursorIndex; + } + + auto current = d->currentCursorIndex; + if (!current.isValid()) { + current = firstIndex(); + d->currentCursorIndex = current; + d->m_oldCursorIndex = current; + return current; + } + + if (rectForIndex(current).isEmpty()) { + qCritical() << "current never empty" << current; + d->currentCursorIndex = firstIndex(); + d->m_oldCursorIndex = current; + return d->currentCursorIndex; + } + + QModelIndex index = moveCursorGrid(cursorAction, modifiers); + + if (index.isValid()) { + d->currentCursorIndex = index; + if (!DFMGlobal::keyShiftIsPressed()) + d->m_oldCursorIndex = index; + return index; + } + + d->currentCursorIndex = current; + return current; +} + +int CanvasGridView::horizontalOffset() const +{ + return horizontalScrollBar()->value(); +} + +int CanvasGridView::verticalOffset() const +{ + return verticalScrollBar()->value(); +} + +bool CanvasGridView::isIndexHidden(const QModelIndex &index) const +{ + Q_UNUSED(index); + return false; +} + +void CanvasGridView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command) +{ + setSelection(rect, command, false); +} + +QRegion CanvasGridView::visualRegionForSelection(const QItemSelection &selection) const +{ + QRegion region; + auto selectedList = selection.indexes(); + for (auto &index : selectedList) { + region = region.united(QRegion(visualRect(index))); + } + return region; +} + +void CanvasGridView::mouseMoveEvent(QMouseEvent *event) +{ + //不关心Dropflag,节省时间,bug#10926 + IgnoreDropFlag idf(model()); + + if (event->buttons() != Qt::LeftButton) { + event->ignore(); + return; + } + + QAbstractItemView::mouseMoveEvent(event); + + auto curPos = event->pos(); + QRect selectRect; + + if (d->showSelectRect) { + selectRect.setLeft(qMin(curPos.x(), d->lastPos.x())); + selectRect.setTop(qMin(curPos.y(), d->lastPos.y())); + selectRect.setRight(qMax(curPos.x(), d->lastPos.x())); + selectRect.setBottom(qMax(curPos.y(), d->lastPos.y())); + d->selectRect = selectRect.normalized(); + } + + if (d->showSelectRect) { + update(); + setState(DragSelectingState); + auto command = QItemSelectionModel::Current | QItemSelectionModel::ClearAndSelect; + setSelection(selectRect, command, true); + } +} + +void CanvasGridView::mousePressEvent(QMouseEvent *event) +{ + auto index = indexAt(event->pos()); + + d->mousePressed = true; + + if (index.isValid()) { + d->currentCursorIndex = index; + //shift 开始index无效时更新无当前点击项,未按下shift点击时更新为当前点击项 + if (!d->m_oldCursorIndex.isValid() || !DFMGlobal::keyShiftIsPressed()) + d->m_oldCursorIndex = index; + } + + bool leftButtonPressed = event->button() == Qt::LeftButton; + bool showSelectFrame = leftButtonPressed; + showSelectFrame &= !index.isValid(); + d->showSelectRect = showSelectFrame; + d->lastPos = event->pos(); + + //如果是触摸屏,就开启200ms计时,再响应drag + //当事件source为MouseEventSynthesizedByQt,认为此事件为TouchBegin转换而来 + if ((event->source() == Qt::MouseEventSynthesizedByQt) && leftButtonPressed) { + //读取dde配置的按压时长 + static QObject *theme_settings = reinterpret_cast(qvariant_cast(qApp->property("_d_theme_settings_object"))); + QVariant touchFlickBeginMoveDelay; + if (theme_settings) { + touchFlickBeginMoveDelay = theme_settings->property("touchFlickBeginMoveDelay"); + } + //若dde配置了则使用dde的配置,若没有则使用默认的200ms + d->touchTimer.setInterval(touchFlickBeginMoveDelay.isValid() ? touchFlickBeginMoveDelay.toInt() : 200); + d->touchTimer.start(); + } else { + d->touchTimer.stop(); + } + + bool isEmptyArea = !index.isValid(); + if (index.isValid() && itemDelegate()->editingIndex() == index) { + //如果当前点击的是正在编辑的项目 + //不关闭编辑框,fix#bug25523 桌面文件进行重命名操作,在重命名输入框中右键,自动退出重命名状态 + } else + itemDelegate()->commitDataAndCloseActiveEditor(); + + if (isEmptyArea) { + if (!DFMGlobal::keyCtrlIsPressed() && !DFMGlobal::keyShiftIsPressed()) { + itemDelegate()->hideNotEditingIndexWidget(); + QAbstractItemView::setCurrentIndex(QModelIndex()); + clearSelection(); + d->currentCursorIndex = QModelIndex(); + d->m_oldCursorIndex = QModelIndex(); + } + } + + d->beforeMoveSelection = selectionModel()->selection(); + //auto selectedIndexes = selectionModel()->selectedIndexes(); + bool isselected = isSelected(index); +// QAbstractItemView::mousePressEvent(event); + //fix 修改ctrl+左键取消选中状态导致所有选中文件被取消选中的问题。 + if (leftButtonPressed && isselected && event->modifiers() == Qt::ControlModifier) { +#if 0 //反选功能 暂不清楚是否需要,不开启 + selectedIndexes.removeOne(index); + QItemSelection selection; + for (const QModelIndex &mi : selectedIndexes) { + selection << QItemSelectionRange(mi); + } + d->beforeMoveSelection = selection; + selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect); +#else + setProperty("lastPressedIndex", index); + + //fixbug39610:必须先取出已选择列表,再调用mousePressEvent(不调用会导致不能连续拖拽复制),再设置选中列表为获取的项 + QItemSelection selection; + for (const QModelIndex &mi : selectedIndexes()) { + selection << QItemSelectionRange(mi); + } + + QAbstractItemView::mousePressEvent(event); + + selectionModel()->select(selection, QItemSelectionModel::Select); +#endif + } else { + QAbstractItemView::mousePressEvent(event); + } + + if (leftButtonPressed) { + d->m_currentMousePressIndex = index; + if (!isEmptyArea) { + const DUrl &url = model()->getUrlByIndex(index); + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, url); + if (info && info->isVirtualEntry()) { + toggleEntryExpandedState(url); + } + } + } + + update(); +} + +void CanvasGridView::mouseReleaseEvent(QMouseEvent *event) +{ + QAbstractItemView::mouseReleaseEvent(event); + d->mousePressed = false; + if (d->showSelectRect && d->selectRect.isValid()) { + d->showSelectRect = false; + d->selectRect = QRect(); + + auto releaseIndex = indexAt(event->pos()); + if (releaseIndex.isValid()) { + //按照产品要求,框选时鼠标释放位置若为有效index时,设置该index为焦点index, + //若释放时位置的index无效,则会在moveCursor中默认为左上角第一个 + d->currentCursorIndex = releaseIndex; + d->m_oldCursorIndex = releaseIndex; + } + } + + QModelIndex index = property("lastPressedIndex").toModelIndex(); + if (index.isValid() && DFMGlobal::keyCtrlIsPressed() && index == indexAt(event->pos()) && isSelected(index)) { + //fix 修改ctrl+左键取消选中状态导致所有选中文件被取消选中的问题。 + selectionModel()->select(QItemSelection(index, index), QItemSelectionModel::Deselect); + setProperty("lastPressedIndex", QModelIndex()); + } + + update(); +} + +void CanvasGridView::mouseDoubleClickEvent(QMouseEvent *event) +{ + auto pos = event->pos(); + QModelIndex index = indexAt(pos); + + //bug59277桌面修改文件夹名称,双击进入文件夹,会进入桌面目录 + //若在编辑中则直接完成编辑,并在重名完成后使用新的名称发送doubleClicked信号 + if (itemDelegate()->editingIndexWidget() && (index == itemDelegate()->editingIndex())) { + //结束重名 + itemDelegate()->commitDataAndCloseActiveEditor(); + QTimer::singleShot(200,this,[this,pos]() { + //因为重名后原有的index会改变,但所处位置pos不变,因此使用pos重新获取index + emit doubleClicked(indexAt(pos)); + }); + return; + } + + QPersistentModelIndex persistent = index; + emit doubleClicked(persistent); + if ((event->button() == Qt::LeftButton) && !edit(persistent, DoubleClicked, event) + && !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, nullptr, this)) { + emit activated(persistent); + } +} + +void CanvasGridView::wheelEvent(QWheelEvent *event) +{ + if (DFMGlobal::keyCtrlIsPressed()) { + if (event->angleDelta().y() > 0) { + increaseIcon(); + } else { + decreaseIcon(); + } + //QThread::msleep(100); + event->accept(); + } +} + +void CanvasGridView::keyPressEvent(QKeyEvent *event) +{ + if (Q_UNLIKELY(DFMApplication::appObtuselySetting()->value("ApplicationAttribute", "DisableDesktopShortcuts", false).toBool())) { + bool specialShortcut = false; + if (event->modifiers() == Qt::NoModifier || event->modifiers() == Qt::KeypadModifier) { + switch (event->key()) { + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Enter: + case Qt::Key_Return: + specialShortcut = true; + break; + default: + return; + } + } + + if (!specialShortcut) { + return; + } + } + + QMap selectUrlsMap; + auto rootUrl = model()->rootUrl(); + bool canDeleted = true; + for (const QModelIndex &index : selectionModel()->selectedIndexes()) { + auto url = model()->getUrlByIndex(index); + if (url.isEmpty()) { + canDeleted = false; + continue; + } + const DAbstractFileInfoPointer fileInfo = model()->fileInfo(index); + if (fileInfo && !fileInfo->isVirtualEntry()) { + selectUrlsMap.insert(url.toString(), url); + } + } + selectUrlsMap.remove(rootUrl.toString()); + + const DUrlList &selectUrls = selectUrlsMap.values(); + + switch (event->modifiers()) { + case Qt::NoModifier: + switch (event->key()) { + case Qt::Key_F1: { + class PublicApplication : public DApplication + { + public: + using DApplication::handleHelpAction; + }; + + QString app_name = qApp->applicationName(); + qApp->setApplicationName("dde"); + reinterpret_cast(DApplication::instance())->handleHelpAction(); + qApp->setApplicationName(app_name); + break; + } + case Qt::Key_Tab: { + this->selectionModel()->clear(); + QKeyEvent downKey(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier); + QCoreApplication::sendEvent(this, &downKey); + break; + } + case Qt::Key_Escape: { + auto tmpUrl = DFMGlobal::instance()->fetchUrlsFromClipboard(); + auto homePath = QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first(); + if (tmpUrl.size() > 0) { + DAbstractFileInfoPointer tempInfo = DFileService::instance()->createFileInfo(nullptr, MergedDesktopController::convertToRealPath(DUrl(tmpUrl.first()))); + if (tempInfo->path() == homePath) + DFMGlobal::instance()->clearClipboard(); + } + break; + } + default: + break; + } + // fall through + //为解决fall through警告而添加的下面一句 + Q_FALLTHROUGH(); + case Qt::KeypadModifier: + switch (event->key()) { + case Qt::Key_Return: + case Qt::Key_Enter: + if (!itemDelegate()->editingIndex().isValid()) { + DUrlList lst; + for (const DUrl &url : selectUrlsMap) { + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, url); + if (!info || info->isVirtualEntry()) { + // we do expand the virtual entry on single click, so no longer need to do that here. + // toggleEntryExpandedState(url); + continue; + } + lst << url; + } + if (1 == lst.count()) { + DFileService::instance()->openFile(this, lst.first()); + } else { + DFileService::instance()->openFiles(this, lst, true); + } + return; + } + break; + case Qt::Key_F5: + Refresh(); + return; + case Qt::Key_Delete: + if (canDeleted && !selectUrlsMap.contains(rootUrl.toString()) && !selectUrls.isEmpty()) { + DFileService::instance()->moveToTrash(this, selectUrls); + } + break; + case Qt::Key_Space: { + QStringList urls = GridManager::instance()->itemIds(m_screenNum); + DUrlList entryUrls; + foreach (QString url, urls) { + entryUrls << DUrl(url); + } + DUrlList selectUrlsActual = MergedDesktopController::convertToRealPaths(selectUrls); + DFMGlobal::showFilePreviewDialog(selectUrlsActual, entryUrls); + } + break; + default: + break; + } + break; + + case Qt::ShiftModifier: + if (event->key() == Qt::Key_Delete) { + if (!canDeleted || selectUrls.isEmpty()) { + return; + } + + DFileService::instance()->deleteFiles(this, selectUrls); + + return; + } else if (event->key() == Qt::Key_T) { +// Open appController->actionOpenInTerminal(fmevent); + return; + } + break; + + case Qt::ControlModifier: + switch (event->key()) { + case Qt::Key_Minus: + decreaseIcon(); + return; + case Qt::Key_Equal: + increaseIcon(); + return; + case Qt::Key_H: { + //更改显示隐藏状态 + bool whetherShowHiddenFiles{ GridManager::instance()->getWhetherShowHiddenFiles() }; + GridManager::instance()->setWhetherShowHiddenFiles(!whetherShowHiddenFiles); + + //同步刷新,交由GridViewManager调用updateHiddenItems + emit GridManager::instance()->sigSyncOperation(GridManager::soHidenSwitch); + return; + } + case Qt::Key_I: + DFMGlobal::showPropertyDialog(nullptr, selectUrls); + return; + + default: + break; + } + break; + + case Qt::ControlModifier | Qt::ShiftModifier: + + if (event->key() == Qt::Key_N) { + if (itemDelegate()->editingIndex().isValid()) { + return; + } +// clearSelection(); +// appController->actionNewFolder(fmevent); + return; + } + + if (event->key() == Qt::Key_Question) { +// appController->actionShowHotkeyHelp(fmevent); + return; + } + if (event->key() == Qt::Key_Plus) { + increaseIcon(); + return; + } + break; + + case Qt::AltModifier: + if (event->key() == Qt::Key_M) { + //新需求gesetting控制右键菜单隐藏功能,和产品确认调整为gsetting高于本身配置文件,即gsetting有相关配置后本身的json相关配置失效 + auto tempGsetting = GridManager::instance()->isGsettingShow("context-menu", QVariant()); + if (tempGsetting.isValid()) { + if (!tempGsetting.toBool()) + return; + } else { + auto tempConfig = DFMApplication::appObtuselySetting()->value("ApplicationAttribute", "DisableDesktopContextMenu", QVariant()); + if (tempConfig.isValid()) + if (!tempConfig.toBool()) + return; + } + + QModelIndexList indexList = selectionModel()->selectedIndexes(); + bool isEmptyArea = indexList.empty(); + Qt::ItemFlags flags; + + if (isEmptyArea) { + flags = model()->flags(rootIndex()); + + if (!flags.testFlag(Qt::ItemIsEnabled)) { + return; + } + } else { + const QModelIndex &index = indexList.first(); + flags = model()->flags(index); + + if (!flags.testFlag(Qt::ItemIsEnabled)) { + isEmptyArea = true; + flags = rootIndex().flags(); + } + } + + // fix bug94233 在桌面右键,右键菜单缺少选项 + if (!DFileMenuManager::actionWhitelist().isEmpty() || !DFileMenuManager::actionBlacklist().isEmpty()) { + //! set menu actions filter + setMenuActionsFilter(); + } + + if (isEmptyArea) { + itemDelegate()->hideNotEditingIndexWidget(); + clearSelection(); + showEmptyAreaMenu(flags); + } else { + const QModelIndex &index = indexList.first(); + showNormalMenu(index, flags); + } + return; + } + break; + + default: + break; + } + + QAbstractItemView::keyPressEvent(event); + +// DUtil::TimerSingleShot(10, [this]() { +// auto index = d->currentCursorIndex; +// auto marginWidth = d->cellHeight; +// auto rect = visualRect(index).marginsAdded(QMargins(marginWidth, marginWidth, marginWidth, marginWidth)); +// repaint(rect); +// }); + update(); +} + +void CanvasGridView::dragEnterEvent(QDragEnterEvent *event) +{ + // 修复bug-65773 + m_currentTargetUrl.clear(); + if (DFileDragClient::checkMimeData(event->mimeData())) { + event->acceptProposedAction(); + setTargetUrlToApp(event->mimeData(), currentUrl()); + return; + } +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + if (event->source()) { +#else + if (!GridManager::instance()->autoMerge()) { +#endif + //从非桌面拖入时,不启动让位动画(同步dragMoveEvent的处理方式),否则将导致桌面已选择的图标在绘制时被隐藏 + CanvasGridView *view = dynamic_cast(event->source()); + if (view && event->mimeData()) { + //拖拽复制时,不做让位处理 + if (!GridManager::instance()->shouldArrange() && !DFMGlobal::keyCtrlIsPressed()) { + d->startDodge = true; + } + } + itemDelegate()->hideNotEditingIndexWidget(); + } + + //由于普通用户无法访问root用户的共享内存,跨用户的情况使用从mimedata中取url的方式 + bool sameUser = DFMGlobal::isMimeDatafromCurrentUser(event->mimeData()); + if (sameUser) { + fetchDragEventUrlsFromSharedMemory(); + } else { + m_urlsForDragEvent = event->mimeData()->urls(); + } + + d->fileViewHelper->preproccessDropEvent(event, m_urlsForDragEvent); + + if (event->mimeData()->hasFormat("XdndDirectSave0")) { + event->setDropAction(Qt::CopyAction); + event->acceptProposedAction(); + return; + } + + update(); // bug 23351: while draging it, refresh it ASAP to remove the older icon + QAbstractItemView::dragEnterEvent(event); +} + +void CanvasGridView::dragMoveEvent(QDragMoveEvent *event) +{ + d->dodgeDelayTimer.stop(); + d->dragTargetGrid = QPoint(-1, -1); + + auto pos = event->pos(); + auto hoverIndex = indexAt(event->pos()); + + auto startDodgeAnimation = [ = ]() { + d->dragTargetGrid.setX((pos.x() - d->viewMargins.left()) / d->cellWidth); + d->dragTargetGrid.setY((pos.y() - d->viewMargins.top()) / d->cellHeight); + + // FIXME: out of border??? + auto localeFile = GridManager::instance()->itemId(m_screenNum, d->dragTargetGrid); + if (!localeFile.isEmpty() && !d->dodgeAnimationing) { + d->dodgeDelayTimer.start(); + } + + d->fileViewHelper->preproccessDropEvent(event, m_urlsForDragEvent); + if (!hoverIndex.isValid()) { + if (DFileDragClient::checkMimeData(event->mimeData())) { + event->acceptProposedAction(); + setTargetUrlToApp(event->mimeData(), currentUrl()); + } else { + event->accept(); + } + } + }; + + if (hoverIndex.isValid()) { + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(hoverIndex); + CanvasGridView *view = dynamic_cast(event->source()); + if (fileInfo) { + if (view && !DFMGlobal::keyCtrlIsPressed()) { + event->setDropAction(Qt::MoveAction); + } + + bool canDrop = fileInfo->canDrop(); + canDrop = fileInfo->isDir() && !fileInfo->isWritable(); + canDrop = fileInfo->supportedDropActions().testFlag(event->dropAction()); + //解决未使用警告,不清楚是否能直接删除上方canDrop相关,故采用宏 + Q_UNUSED(canDrop) + if (!fileInfo->canDrop() || (fileInfo->isDir() && !fileInfo->isWritable()) || + !fileInfo->supportedDropActions().testFlag(event->dropAction())) { + // not support drag + event->ignore(); + } else { + if (DFileDragClient::checkMimeData(event->mimeData())) { + event->acceptProposedAction(); + setTargetUrlToApp(event->mimeData(), fileInfo->fileUrl()); + } else { + event->accept(); + } + // 当为追加压缩时 + if (fileInfo->canDrop() && fileInfo->canDragCompress()) { + // 设置当拖拽gvfs文件时,不支持追加压缩 + if (!m_urlsForDragEvent.isEmpty()) { + event->setDropAction(Qt::CopyAction); + const DAbstractFileInfoPointer &dragfileInfo = DFileService::instance()->createFileInfo(this, DUrl(m_urlsForDragEvent.first())); + if (dragfileInfo->isGvfsMountFile()) { + event->setDropAction(Qt::MoveAction); + return event->ignore(); + } + } + } + update(); + return; + } + } + } + +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + if (!GridManager::instance()->shouldArrange()) { //自定义 +#else + //fixbug39610 区分图标拖拽移动和拖拽复制操作 + if (!GridManager::instance()->autoMerge() && !DFMGlobal::keyCtrlIsPressed()) { //自定义 +#endif + CanvasGridView *view = dynamic_cast(event->source()); + if (view && event->mimeData()) { + QPair orgpos; + //找项目源 + auto urls = event->mimeData()->urls(); + if (!urls.isEmpty() && GridManager::instance()->find(urls.first().toString(), orgpos)) { + if (orgpos.first == m_screenNum) { //同屏 + startDodgeAnimation(); + update(); + return; + } //跨屏拖动,空间不足时先禁止拖动,todo 寻找更好的解决办法 + else if (GridManager::instance()->emptyPostionCount(m_screenNum) >= urls.size()) { + startDodgeAnimation(); + update(); + return; + } + } else { + qWarning() << "not found items" << urls; + } + } + //end + } + + { + //自动整理(sp2自动排列)以及不触发让位的drag处理 + d->fileViewHelper->preproccessDropEvent(event, m_urlsForDragEvent); + if (!hoverIndex.isValid()) { + if (DFileDragClient::checkMimeData(event->mimeData())) { + event->acceptProposedAction(); + setTargetUrlToApp(event->mimeData(), currentUrl()); + } else { + event->accept(); + } + } + } + update(); +} + +void CanvasGridView::dragLeaveEvent(QDragLeaveEvent *event) +{ + d->dodgeDelayTimer.stop(); + d->startDodge = false; + d->dragTargetGrid = QPoint(-1, -1); + QAbstractItemView::dragLeaveEvent(event); + update(); +} + +void CanvasGridView::dropEvent(QDropEvent *event) +{ + d->dodgeDelayTimer.stop(); + d->startDodge = false; + d->dragTargetGrid = QPoint(-1, -1); + + QModelIndex targetIndex = indexAt(event->pos()); + + //list保持顺序 + QList selectLocalFiles; + //辅助selectLocalFiles做查找,判断是否重复 + QHash selectLocalFileMap; + + auto selects = selectionModel()->selectedIndexes(); + bool dropOnSelf = false; + for (auto index : selects) { + auto info = model()->fileInfo(index); + + if (!info) { + continue; + } + + if (targetIndex == index) { + dropOnSelf = true; + } + + const QString fileUrl = info->fileUrl().toString(); + //重复的不再添加 + if (!selectLocalFileMap.contains(fileUrl)) { + selectLocalFiles << fileUrl; + selectLocalFileMap.insert(fileUrl, 0); + } + + } + + qDebug() << "selectLocalFiles urls:" << selectLocalFiles; + DAbstractFileInfoPointer targetInfo = model()->fileInfo(indexAt(event->pos())); + if (!targetInfo || dropOnSelf) { + targetInfo = model()->fileInfo(rootIndex()); + } + + //防止桌面的计算机/回收站/主目录被拖拽复制到其他目录中 + if (indexAt(event->pos()).isValid() && + (targetInfo->isDir() || + targetInfo->fileUrl() == DesktopFileInfo::homeDesktopFileUrl())) { + for (QUrl url : m_urlsForDragEvent) { + DUrl durl(url); + if ((DesktopFileInfo::computerDesktopFileUrl() == durl) || + (DesktopFileInfo::trashDesktopFileUrl() == durl) || + (DesktopFileInfo::homeDesktopFileUrl() == durl)) { + event->setDropAction(Qt::IgnoreAction); + return; + } + } + } + + CanvasGridView *sourceView = dynamic_cast(event->source()); + if (sourceView && !DFMGlobal::keyCtrlIsPressed()) { + event->setDropAction(Qt::MoveAction); + } else { + d->fileViewHelper->preproccessDropEvent(event); + } + + if (event->mimeData()->property("IsDirectSaveMode").toBool()) { + event->setDropAction(Qt::CopyAction); + + const QModelIndex &index = indexAt(event->pos()); + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(index.isValid() ? index : rootIndex()); + + if (fileInfo && fileInfo->fileUrl().isLocalFile()) { + if (fileInfo->isDir()) { + const_cast(event->mimeData())->setProperty("DirectSaveUrl", fileInfo->fileUrl()); + } else { + const_cast(event->mimeData())->setProperty("DirectSaveUrl", fileInfo->parentUrl()); + } + } + + event->accept(); // yeah! we've done with XDS so stop Qt from further event propagation. + } else { + if (event->dropAction() == Qt::MoveAction) { + QModelIndex dropIndex = indexAt(gridRectAt(event->pos()).center()); + if (sourceView && (!dropIndex.isValid() || dropOnSelf)) { +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + //自动排列和自动整理不允许屏幕间拖动 + if (GridManager::instance()->shouldArrange()) { +#else + //自动整理不允许屏幕间拖动 + if (GridManager::instance()->autoMerge()) { +#endif + return; + } + + auto point = event->pos(); + auto row = (point.x() - d->viewMargins.left()) / d->cellWidth; + auto col = (point.y() - d->viewMargins.top()) / d->cellHeight; + + QList urls = event->mimeData()->urls(); + qDebug() << "event urls:" << urls; + for (auto url : urls) { + const QString fielUrl = url.toString(); + if (!selectLocalFileMap.contains(fielUrl)) { + selectLocalFiles << fielUrl; + selectLocalFileMap.insert(fielUrl, 0); + } + } + + qDebug() << "selectLocalFiles2222 urls:" << selectLocalFiles; + QPair orgpos; + //找项目源 + if (!selectLocalFiles.isEmpty() + && GridManager::instance()->find(*selectLocalFiles.begin(), orgpos)) { + if (orgpos.first == m_screenNum) { //同屏 + //获取焦点 + QString current = sourceView->currentCursorFile().toString(); + qDebug() << "move " << m_screenNum << "focus" << current << "count" << selectLocalFiles.size(); + GridManager::instance()->move(m_screenNum, selectLocalFiles, current, row, col); + } else { //跨屏 + //获取源屏幕的焦点 + QString current = sourceView->currentCursorFile().toString(); + qDebug() << "move form" << orgpos.first << "to" << m_screenNum + << "focus" << current << selectLocalFiles.size(); + GridManager::instance()->move(orgpos.first, m_screenNum, selectLocalFiles, current, row, col); + } + } + + setState(NoState); + itemDelegate()->hideNotEditingIndexWidget(); +#ifndef USE_SP2_AUTOARRAGE //sp3需求改动 + if (GridManager::instance()->autoArrange()) { + delayArrage(0); + } +#endif + emit GridManager::instance()->sigSyncOperation(GridManager::soUpdate); + return; + } else if (sourceView && !targetIndex.isValid()) { //桌面窗口上互相拖动到有文件的格子上,drop到的targetIndex无效时直接返回 + qInfo() << "drop on invaild target, skip. drop:" << dropIndex.row() << dropIndex.column(); + return; + } + } + + if (!targetIndex.isValid()) { + targetIndex = rootIndex(); + } + + if (model()->supportedDropActions() & event->dropAction() && model()->flags(targetIndex) & Qt::ItemIsDropEnabled) { + const Qt::DropAction action = event->dropAction(); + if (model()->dropMimeData(event->mimeData(), action, targetIndex.row(), targetIndex.column(), targetIndex)) { + if (action != event->dropAction()) { + event->setDropAction(action); + event->accept(); + } else { + event->acceptProposedAction(); + } + } + } + + setState(NoState); + viewport()->update(); + } + //fix bug 24478,在drop事件完成时,设置当前窗口为激活窗口,crtl+z就能找到正确的回退 + QWidget *parentptr = parentWidget(); + QWidget *curwindow = nullptr; + while (parentptr) { + curwindow = parentptr; + parentptr = parentptr->parentWidget(); + } + if (curwindow) { + qApp->setActiveWindow(curwindow); + } + if (DFileDragClient::checkMimeData(event->mimeData())) { + event->acceptProposedAction(); + setTargetUrlToApp(event->mimeData(), model()->getUrlByIndex(targetIndex)); + + // DFileDragClient deletelater() will be called after connection destroyed + DFileDragClient *c = new DFileDragClient(event->mimeData()); + DUrlList urlList = DUrl::fromQUrlList(event->mimeData()->urls()); + connect(c, &DFileDragClient::stateChanged, this, [this, urlList](DFileDragState state) { + if (state == Finished) { + select(urlList); + } + }); + } +} + +void CanvasGridView::paintEvent(QPaintEvent *event) +{ + //不关心Dropflag,节省时间,bug#10926 + IgnoreDropFlag idf(model()); + + QPainter painter(viewport()); + auto repaintRect = event->rect(); + painter.setRenderHints(QPainter::HighQualityAntialiasing); + + auto option = viewOptions(); + option.textElideMode = Qt::ElideMiddle; + + const QModelIndex current = d->currentCursorIndex; + const QAbstractItemModel *itemModel = this->model(); + const DFileSelectionModel *selections = this->selectionModel(); + const bool focusEnabled = false; + const bool focus = (hasFocus() || viewport()->hasFocus()) && current.isValid() && focusEnabled; + const QStyle::State state = option.state; + const QAbstractItemView::State viewState = this->state(); + const bool enabled = (state & QStyle::State_Enabled) != 0; + + painter.setBrush(QColor(255, 0, 0, 0)); + + if (d->_debug_show_grid) { + painter.save(); + if (model()) { + for (int i = 0; i < d->colCount * d->rowCount; ++i) { + auto pos = d->indexCoordinate(i).position(); + auto x = pos.x() * d->cellWidth + d->viewMargins.left(); + auto y = pos.y() * d->cellHeight + d->viewMargins.top(); + + auto rect = QRect(x, y, d->cellWidth, d->cellHeight); + + int rowMode = pos.x() % 2; + int colMode = pos.y() % 2; + auto color = (colMode == rowMode) ? QColor(0, 0, 255, 32) : QColor(255, 0, 0, 32); + painter.fillRect(rect, color); + + if (pos == d->dragTargetGrid) { + painter.fillRect(rect, Qt::green); + } + painter.setPen(QPen(Qt::red, 2)); + painter.drawText(rect, QString("%1-%2").arg(pos.x()).arg(pos.y())); + + //为测试开启debug模式下鼠标框选热区 + QMargins margins(10, 10, 10, 10); + rect = rect.marginsRemoved(margins); + painter.setPen(Qt::red); + painter.drawRect(rect); + } + } + painter.restore(); + } + + DUrlList selecteds; + if (d->dodgeAnimationing || d->startDodge) { + selecteds = selectedUrls(); + } + +// qDebug() << d->dragIn << d->dodgeAnimationing; + if (d->startDodge) { + auto currentMousePos = mapFromGlobal(QCursor::pos()); + auto hoverIndex = indexAt(currentMousePos); + auto url = model()->getUrlByIndex(hoverIndex); + + if (selecteds.contains(url) + || (d->dodgeAnimationing && d->dodgeItems.contains(url.toString()))) { + + } else { + if (hoverIndex.isValid() && hoverIndex != d->currentCursorIndex) { + QPainterPath path; + auto lastRect = visualRect(hoverIndex); + path.addRoundRect(lastRect, 4, 4); + painter.fillPath(path, QColor(43, 167, 248, 255 * 3 / 10)); + painter.strokePath(path, QColor(30, 126, 255, 255 * 2 / 10)); + } + } + } + + QStringList repaintLocalFiles; + if (d->fileViewHelper->isPaintFile()) { + for (int x = 0; x < d->colCount; ++x) { + for (int y = 0; y < d->rowCount; ++y) { + auto localFile = GridManager::instance()->itemId(m_screenNum, x, y); + if (!localFile.isEmpty()) { + repaintLocalFiles << localFile; + } + } + } + + //放入堆叠 + auto overlayItems = GridManager::instance()->overlapItems(m_screenNum); + for (int i = 0; i < overlayItems.length(); ++i) { + auto localFile = overlayItems.value(i); + if (!localFile.isEmpty()) { + repaintLocalFiles << localFile; + } + } + } + +// int drawCount = 0; + for (auto &localFile : repaintLocalFiles) { + auto url = DUrl(localFile); + + /* 按照产品要求,拖拽时,展示拖拽源位置图片 + // hide selected if draw animation + //拖拽复制时,原图标保持 + if ((d->dodgeAnimationing || d->startDodge) && selecteds.contains(url) && !DFMGlobal::keyCtrlIsPressed()) { +// qDebug() << "skip drag select" << url; + continue; + } + */ + + + if (d->dodgeAnimationing && d->dodgeItems.contains(localFile)) { +// qDebug() << "skip dragMoveItems" << localFile; + continue; + } + + auto index = model()->index(url); + if (!index.isValid()) { +// qDebug() << "skip index.isValid"; + continue; + } + option.rect = visualRect(index); + + bool needflash = false; + for (auto &rr : event->region().rects()) + if (rr.intersects(option.rect)) { + needflash = true; + } + + if (!needflash) { +// qDebug() << "skip !needflash"; + continue; + } + + + if (!repaintRect.intersects(option.rect)) { +// qDebug() << "skip !repaintRect.intersects(option.rect)"; + continue; + } + + option.rect = option.rect.marginsRemoved(d->cellMargins); + option.state = state; + if (selections && selections->isSelected(index)) { + option.state |= QStyle::State_Selected; + } + if (enabled) { + QPalette::ColorGroup cg; + if ((itemModel->flags(index) & Qt::ItemIsEnabled) == 0) { + option.state &= ~QStyle::State_Enabled; + cg = QPalette::Disabled; + } else { + cg = QPalette::Normal; + } + option.palette.setCurrentColorGroup(cg); + } + if (focus && current == index) { + option.state |= QStyle::State_HasFocus; + if (viewState == EditingState) { + option.state |= QStyle::State_Editing; + } + } + option.state &= ~QStyle::State_MouseOver; + + painter.save(); + if (d->_debug_show_grid) { + for (auto rect : itemPaintGeomertys(index)) { + painter.setPen(Qt::red); + painter.drawRect(rect); + } + } + + this->itemDelegate()->paint(&painter, option, index); + DAbstractFileInfoPointer info = model()->fileInfo(index); + if (info && info->scheme() == DFMMD_SCHEME && info->isVirtualEntry()) { + DMD_TYPES oneType = MergedDesktopController::entryTypeByName(info->fileName()); + if (virtualEntryExpandState[oneType]) { + // do draw mask here + static QIcon expandMaskIcon = QIcon::fromTheme("folder-stack-mask"); + const QRect itemRect = itemIconGeomerty(index); + QPixmap pixmap = DFMStyledItemDelegate::getIconPixmap(expandMaskIcon, itemRect.size(), devicePixelRatioF()); + painter.drawPixmap(itemRect.topLeft(), pixmap); + } + } + painter.restore(); + } + + // draw select rect copy from QListView::paintEvent + if (d->showSelectRect && d->selectRect.isValid()) { + QStyleOptionRubberBand opt; + opt.initFrom(this); + opt.shape = QRubberBand::Rectangle; + opt.opaque = false; + opt.rect = d->selectRect; + painter.save(); + style()->drawControl(QStyle::CE_RubberBand, &opt, &painter); + painter.restore(); + } + +// draw dragMove animation + if (d->dodgeAnimationing) { + for (auto animatingItem : d->dodgeItems) { + auto localFile = animatingItem; + auto index = model()->index(DUrl(localFile)); + if (index.isValid()) { + option.rect = visualRect(index).marginsRemoved(d->cellMargins); + } + + auto gridPos = d->dodgeTargetGrid->pos(m_screenNum, localFile); + auto x = gridPos.x() * d->cellWidth + d->viewMargins.left(); + auto y = gridPos.y() * d->cellHeight + d->viewMargins.top(); + + QRect end = QRect(x, y, d->cellWidth, d->cellHeight).marginsRemoved(d->cellMargins); + + auto tempCurrent = dodgeDuration(); + auto nx = option.rect.x() + (end.x() - option.rect.x()) * tempCurrent; + auto ny = option.rect.y() + (end.y() - option.rect.y()) * tempCurrent; + option.rect.setX(static_cast(nx)); + option.rect.setY(static_cast(ny)); + option.rect.setSize(end.size()); + painter.save(); + itemDelegate()->paint(&painter, option, index); + painter.restore(); + } + } +} + +void CanvasGridView::focusInEvent(QFocusEvent *event) +{ + QAbstractItemView::focusInEvent(event); + itemDelegate()->commitDataAndCloseActiveEditor(); + + /// set menu actions filter + setMenuActionsFilter(); +} + +void CanvasGridView::focusOutEvent(QFocusEvent *event) +{ + QAbstractItemView::focusOutEvent(event); + d->startDodge = false; +} + +void CanvasGridView::contextMenuEvent(QContextMenuEvent *event) +{ + // fix bug94233 在桌面右键,右键菜单缺少选项 + if (!DFileMenuManager::actionWhitelist().isEmpty() || !DFileMenuManager::actionBlacklist().isEmpty()) { + //! set menu actions filter + setMenuActionsFilter(); + } + + //fix bug39609 选中桌面文件夹,进行右键操作,例如打开、重命名,然后再按快捷键home、left、right无效 + d->mousePressed = false; + + //新需求gesetting控制右键菜单隐藏功能,和产品确认调整为gsetting高于本身配置文件,即gsetting有相关配置后本身的json相关配置失效 + auto tempGsetting = GridManager::instance()->isGsettingShow("context-menu", QVariant()); + if (tempGsetting.isValid()) { + if (!tempGsetting.toBool()) + return; + } else { + auto tempConfig = DFMApplication::appObtuselySetting()->value("ApplicationAttribute", "DisableDesktopContextMenu", QVariant()); + if (tempConfig.isValid()) + if (!tempConfig.toBool()) + return; + } + + //关闭编辑框 + itemDelegate()->hideAllIIndexWidget(); + + //fix buf#202007010011,忽略drop判断,提升响应速度 + IgnoreDropFlag idf(model()); + + const QModelIndex &index = indexAt(event->pos()); + bool indexIsSelected = selectionModel()->isSelected(index); + bool isEmptyArea = d->fileViewHelper->isEmptyArea(event->pos()) && !indexIsSelected; + Qt::ItemFlags flags; + + if (isEmptyArea) { + flags = model()->flags(rootIndex()); + + if (!flags.testFlag(Qt::ItemIsEnabled)) { + return; + } + } else { + flags = model()->flags(index); + + if (!flags.testFlag(Qt::ItemIsEnabled)) { + isEmptyArea = true; + flags = rootIndex().flags(); + } + } + + if (isEmptyArea) { + itemDelegate()->hideNotEditingIndexWidget(); + clearSelection(); + //*d->lastMenuPos() = qMakePair(m_screenNum,gridAt(event->pos())); + d->lastMenuPos = event->pos(); + showEmptyAreaMenu(flags); + } else { + if (!selectionModel()->isSelected(index)) { + setCurrentIndex(index); + } + + showNormalMenu(index, flags); + } +} + +bool CanvasGridView::event(QEvent *event) +{ + if (event->type() == QEvent::FontChange) { + updateCanvas(); + } + + return QAbstractItemView::event(event); +} + +void CanvasGridView::rowsInserted(const QModelIndex &parent, int first, int last) +{ + QAbstractItemView::rowsInserted(parent, first, last); + + for (int index = first; index <= last; ++index) { + const QModelIndex &child = parent.child(index, 0); + DAbstractFileInfoPointer info = model()->fileInfo(child); + if (info) { + info->makeToActive(); + } else { + qCritical() << "CanvasGridView::rowsInserted(): Create file info failed!!!!!!!!!!!!!" << index; + } + } + + update(); +} + +void CanvasGridView::keyboardSearch(const QString &search) +{ + if (search.isEmpty()) + return; + + d->fileViewHelper->keyboardSearch(search.toLocal8Bit().at(0)); +} + +QPixmap CanvasGridView::renderToPixmap(const QModelIndexList &indexes) const +{ + qreal scale = 1; + QWidget *window = this->window(); + if (window) { + QWindow *windowHandle = window->windowHandle(); + if (windowHandle) + scale = windowHandle->devicePixelRatio(); + } + + //将当前按住的index剔除 + QModelIndexList indexesWithoutPressed = indexes; + auto needRemove = [=](const QModelIndex &index) { + return index.row() == d->m_currentMousePressIndex.row(); + }; + indexesWithoutPressed.erase(std::remove_if(indexesWithoutPressed.begin(), indexesWithoutPressed.end(), needRemove), + indexesWithoutPressed.end()); + //拖拽聚合图标可绘制区域大小 + QRect pixRect(0, 0, DRAGICON_SIZE + DRAGICON_OUTLINE * 2, DRAGICON_SIZE + DRAGICON_OUTLINE * 2); + QPixmap pixmap(pixRect.size() * scale); + pixmap.setDevicePixelRatio(scale); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + QStyleOptionViewItem option = this->viewOptions(); + option.state |= QStyle::State_Selected; + option.rect = option.rect.translated(DRAGICON_OUTLINE, DRAGICON_OUTLINE); + + qreal offsetX = pixRect.width() / 2; + qreal offsetY = pixRect.height() / 2; + for (int i = qMin(DRAGICON_MAX - 1, indexesWithoutPressed.length() - 1); i >= 0 ; --i) { + //计算旋转角度 + qreal rotate = DRAGICON_ROTATE * (ceil((i + 1.0) / 2.0) / 2.0 + 1.0) * (i % 2 == 1 ? -1 : 1); + //设置透明度 50% 40% 30% 20% + painter.setOpacity(1.0 - (i + 5) * DRAGICON_OPACITY); + + //旋转 + painter.translate(offsetX, offsetY); //让图片的中心作为旋转的中心 + painter.rotate(rotate); + painter.translate(-offsetX, -offsetY); //使原点复原 + + //绘制icon + this->itemDelegate()->paintDragIcon(&painter, option, indexesWithoutPressed.at(i), QSize(DRAGICON_SIZE, DRAGICON_SIZE)); + + //旋转回原角度 + painter.translate(offsetX, offsetY); + painter.rotate(-rotate); + painter.translate(-offsetX, -offsetY); + } + + //绘制当前按住的icon,顶层icon80%透明度 + painter.setOpacity(0.8); + this->itemDelegate()->paintDragIcon(&painter, option, d->m_currentMousePressIndex, QSize(DRAGICON_SIZE, DRAGICON_SIZE)); + QSize iconSize = this->itemDelegate()->getIndexIconSize(option, d->m_currentMousePressIndex, QSize(DRAGICON_SIZE, DRAGICON_SIZE)); + + //绘制数量提示原点,大于99个文件显示为99+ + int length = indexes.length() > DRAGICON_MAX_COUNT ? 28 : 24; //原点直径:1到2个字符直径为24,3个字符直径为28 + int x = DRAGICON_OUTLINE + (DRAGICON_SIZE + iconSize.width() - length) / 2; + int y = DRAGICON_OUTLINE + (DRAGICON_SIZE + iconSize.height() - length) / 2; + + QColor pointColor(244, 74, 74); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setOpacity(1); + painter.setPen(pointColor); + painter.setBrush(pointColor); + painter.drawEllipse(x, y, length, length); + + painter.setPen(Qt::white); + //按照设计的要求设置字体:Arial,12大小,粗体 + QFont ft("Arial"); + ft.setPixelSize(12); + ft.setBold(true); + painter.setFont(ft); + QString countStr = indexes.length() > DRAGICON_MAX_COUNT ? QString::number(DRAGICON_MAX_COUNT).append("+") : QString::number(indexes.length()); + painter.drawText(QRect(x, y, length, length), Qt::AlignCenter, countStr); + + return pixmap; +} + +QString CanvasGridView::canvansScreenName() const +{ + return m_screenName; +} + +QRect CanvasGridView::rectForIndex(const QModelIndex &index) const +{ + return visualRect(index); +} + +DUrl CanvasGridView::currentUrl() const +{ + return model()->getUrlByIndex(rootIndex()); +} + +DFileSystemModel *CanvasGridView::model() const +{ + return qobject_cast(QAbstractItemView::model()); +} + +DFileSelectionModel *CanvasGridView::selectionModel() const +{ + return static_cast(QAbstractItemView::selectionModel()); +} + +DesktopItemDelegate *CanvasGridView::itemDelegate() const +{ + return qobject_cast(QAbstractItemView::itemDelegate()); +} + +void CanvasGridView::setItemDelegate(DesktopItemDelegate *delegate) +{ + QAbstractItemDelegate *dg = QAbstractItemView::itemDelegate(); + + if (dg) { + dg->deleteLater(); + } + + QAbstractItemView::setItemDelegate(delegate); +} + +double CanvasGridView::dodgeDuration() const +{ + return d->dodgeDuration; +} + +QMargins CanvasGridView::cellMargins() const +{ + return d->cellMargins; +} + +QSize CanvasGridView::cellSize() const +{ + return QSize(d->cellWidth, d->cellHeight); +} + +void CanvasGridView::openUrl(const DUrl &url) +{ + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, url); + if (!info || info->isVirtualEntry()) { + // we do expand the virtual entry on single click, so no longer need to do that here. + // toggleEntryExpandedState(url); + return; + } + + DFileService::instance()->openFile(this, url); +} + +void CanvasGridView::openUrls(const QList &urls) +{ + if (urls.isEmpty()) + return; + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, urls.at(0)); + if (!info || info->isVirtualEntry()) { + return; + } + + DFileService::instance()->openFiles(this, urls); +} + +bool CanvasGridView::setCurrentUrl(const DUrl &url) +{ + DUrl fileUrl = url; + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, fileUrl); + if (!info) { + qWarning() << "This scheme isn't support"; + return false; + } + + const DUrl &checkUrl = currentUrl(); + + if (checkUrl == fileUrl) { + return false; + } + + QModelIndex index = model()->setRootUrl(fileUrl); + setRootIndex(index); + + if (focusWidget() && focusWidget()->window() == window() && fileUrl.isLocalFile()) { + QDir::setCurrent(fileUrl.toLocalFile()); + } + + QAbstractItemView::setCurrentIndex(QModelIndex()); + + model()->setFilters(model()->filters()); + + if (d->filesystemWatcher) { + disconnect(d->filesystemWatcher, nullptr, this, nullptr); + d->filesystemWatcher->deleteLater(); + } + + if (!model()->canFetchMore(index)) { + + // TODO: updateContentLabel + qDebug() << "TODO: updateContentLabel()"; + } else { //if (GridManager::instance()->autoMerge()){ + m_rt.restart(); + model()->refresh(); + qDebug() << "refresh" << m_screenNum << fileUrl; + } + + d->filesystemWatcher = model()->fileWatcher(); + +#if 0 //!由于model中已做了刷新,故无需下面代码 task#40201 + //fix bug#30019 当.hidden文件改变时刷新model,用于实时更新隐藏文件 + connect(d->filesystemWatcher, &DAbstractFileWatcher::fileModified, this, [this](const DUrl & url) { + if (url.fileName() == ".hidden" && !(model()->filters() & QDir::Hidden)) + delayModelRefresh(); + }); + //end +#endif + + connect(d->filesystemWatcher, &DAbstractFileWatcher::subfileCreated, + this, [ = ](const DUrl & url) { + Q_EMIT itemCreated(url); + update(); + }); + + connect(d->filesystemWatcher, &DAbstractFileWatcher::fileDeleted, + this, [ = ](const DUrl & url) { + Q_EMIT itemDeleted(url); + update(); + }); + + connect(d->filesystemWatcher, &DAbstractFileWatcher::fileMoved, + this, [ = ](const DUrl & oriUrl, const DUrl & dstUrl) { + + bool findOldPos = false; + QPoint oldPos = QPoint(-1, -1); + + if (GridManager::instance()->contains(m_screenNum, oriUrl.toString()) && !oriUrl.fileName().isEmpty()) { + oldPos = GridManager::instance()->position(m_screenNum, oriUrl.toString()); + findOldPos = true; + } + + bool findNewPos = false; + if (dstUrl.parentUrl() == oriUrl.parentUrl() && !dstUrl.fileName().isEmpty()) { + findNewPos = true; + } + + findNewPos &= !GridManager::instance()->contains(m_screenNum, dstUrl.toString()); + + if (!findNewPos) { + Q_EMIT itemDeleted(oriUrl); + } else { + if (findOldPos) { + GridManager::instance()->remove(m_screenNum, oriUrl.toString()); + + //文件被重名后变成隐藏文件 + DAbstractFileInfoPointer file = fileService->createFileInfo(nullptr, dstUrl); + //判断文件是否为隐藏文件,当前若不显示隐藏文件,则跳过 + if (file && file->isHidden() && !(model()->filters() & QDir::Hidden)) { + qDebug() << dstUrl << "is hidden file,do not show"; + + //变成隐藏文件,出现了空位,需要执行一次排列 + if (GridManager::instance()->autoArrange()) + this->delayArrage(); + } else + GridManager::instance()->add(m_screenNum, oldPos, dstUrl.toString()); + + if (GridManager::instance()->autoMerge()) + this->delayModelRefresh(); +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + else if (GridManager::instance()->autoArrange()) + this->delayArrage(); +#endif + } else { + //在多屏情况下,该信号会导致文件改名后被移动位置(原因是每个画布对象都有一个watcher,文件改名时每个画布都会处理,从而非文件所在的画布就会发送该信号) + //同步,查找old文件名所在屏和所在位置,仅在old名图标所在的屏处理,避免重命名时被非old名图标所在屏处理 + QPair pos; + bool isFound = GridManager::instance()->find(oriUrl.toString(), pos); + if (isFound && pos.first != m_screenNum) { + qDebug() << QString("item: %1 is found, but it doesn't belong to %2 %3, it's belong %4"). + arg(oriUrl.toString()). + arg(m_screenNum). + arg(m_screenName). + arg(pos.first) + << pos.second; + return ; + } else { + auto screenNumbers = GridManager::instance()->allScreenNum(); + for (auto num : screenNumbers) { + if (num < m_screenNum && !GridManager::instance()->getCanvasFullStatus(num)) { + qDebug() << QString("The previous Canvas(%1)is not full!!! so, current Canvas(%2) don't emit itemCreated signal !"). + arg(num). + arg(m_screenNum); + return; + } + } + } + Q_EMIT itemCreated(dstUrl); + qDebug() << QString("%1 isFound = %2 ,findOldPos = %3, findNewPos = %4, emit itemCreated signal!"). + arg(oriUrl.toString()). + arg(isFound). + arg(findOldPos). + arg(findNewPos); + } + } + + update(); + }); + return true; +} + +void CanvasGridView::initRootUrl() +{ + setAutoMerge(GridManager::instance()->autoMerge()); +} + +bool CanvasGridView::setRootUrl(const DUrl &url) +{ + if (url.isEmpty()) { + return false; + } + + if (url.scheme() == DFMMD_SCHEME) { + for (unsigned int oneType = DMD_PICTURE; oneType <= DMD_OTHER; oneType++) { + virtualEntryExpandState[static_cast(oneType)] = false; + } + + QString frag = url.fragment(); + if (!frag.isEmpty()) { + QStringList entryNameList = frag.split(',', QString::SkipEmptyParts); + for (const QString &oneEntry : entryNameList) { + virtualEntryExpandState[MergedDesktopController::entryTypeByName(oneEntry)] = true; + } + } + //虚拟路径展开后立即保存 + if (GridManager::instance()->doneInit()) + GridManager::instance()->setCurrentVirtualExpandUrl(url); + } + + itemDelegate()->hideAllIIndexWidget(); + + clearSelection(); + + return setCurrentUrl(url); +} + +const DUrlList CanvasGridView::autoMergeSelectedUrls() const +{ + auto selects = selectionModel()->selectedIndexes(); + DUrlList urls; + for (auto index : selects) { + auto info = model()->fileInfo(index); + + //为了满足自定义模式下对多个文件的重命名时的replaceText里的判断 + //这里提前改成对应的Durl + if (info && !info->isVirtualEntry()) { + if (GridManager::instance()->autoMerge()) { + if (!info) + continue ; + QString fileBaseName{ info->baseName() }; + const QString &suffix = info->suffix().isEmpty() ? QString() : QString(".") + info->suffix(); + if (fileBaseName.trimmed().isEmpty()) { + qWarning() << "replace fileBaseName(not include suffix) trimmed is empty string"; + continue; + } + int max_length = MAX_FILE_NAME_CHAR_COUNT - suffix.toLocal8Bit().size(); + if (fileBaseName.toLocal8Bit().size() > max_length) { + fileBaseName = DFMGlobal::cutString(fileBaseName, max_length, QTextCodec::codecForLocale()); + } + DUrl vUrl{ info->getUrlByNewFileName(fileBaseName + suffix) }; + urls << vUrl; + } + } + } + return urls; +} + +const DUrlList CanvasGridView::selectedUrls() const +{ + auto selects = selectionModel()->selectedIndexes(); + DUrlList urls; + for (auto index : selects) { + auto info = model()->fileInfo(index); + if (info && !info->isVirtualEntry()) { + urls << info->fileUrl(); + } + } + return urls; +} + +void CanvasGridView::viewSelectedUrls(DUrlList &validSel, QModelIndexList &validIndexes) +{ + auto selects = selectionModel()->selectedIndexes(); + for (auto index : selects) { + auto info = model()->fileInfo(index); + if (info && !info->isVirtualEntry() && GridManager::instance()->contains(m_screenNum, info->fileUrl().toString())) { + validSel << info->fileUrl(); + validIndexes << index; + } + } +} + +void CanvasGridView::setScreenNum(int num) +{ + m_screenNum = num; +} + +void CanvasGridView::setScreenName(const QString &name) +{ + m_screenName = name; +} + +bool CanvasGridView::isSelected(const QModelIndex &index) const +{ + return static_cast(selectionModel())->isSelected(index); +} + +void CanvasGridView::select(const QList &list) +{ + //不关心Dropflag,节省时间 bug#202007010011 + IgnoreDropFlag idf(model()); + + QModelIndex lastIndex; + QItemSelection selection; + + clearSelection(); + + for (auto &url : list) { + auto index = model()->index(url); + QItemSelectionRange selectionRange(index); + if (!selection.contains(index)) { + selection.push_back(selectionRange); + } + lastIndex = index; + } + + if (!selection.isEmpty()) { + auto selectModel = static_cast(selectionModel()); + selectModel->select(selection, QItemSelectionModel::Select); + } + + if (lastIndex.isValid()) { + selectionModel()->setCurrentIndex(lastIndex, QItemSelectionModel::Select); + + //fix #bug100789 根据产品要求,在粘贴导致原有选中项中的焦点项被取消选中状态时,已粘贴后的扩展方向的最后一个为焦点 + d->currentCursorIndex = lastIndex; + d->m_oldCursorIndex = lastIndex; + } +} + +int CanvasGridView::selectedIndexCount() const +{ + return static_cast(selectionModel())->selectedCount(); +} + +bool CanvasGridView::edit(const QModelIndex &index, QAbstractItemView::EditTrigger trigger, QEvent *event) +{ + DUrl fileUrl = model()->getUrlByIndex(index); + //解决自动整理只包含一个有效图标时全选重命名无效问题 + auto validSelectCount = selectedUrls().size(); +// if (fileUrl.isEmpty() || selectedIndexCount() > 1 || (trigger == SelectedClicked && DFMGlobal::keyShiftIsPressed())) { + if (fileUrl.isEmpty() || validSelectCount > 1 || (trigger == SelectedClicked && DFMGlobal::keyShiftIsPressed())) { + return false; + } + + if (trigger == SelectedClicked) { + QStyleOptionViewItem option = viewOptions(); + + option.rect = visualRect(index).marginsRemoved(d->cellMargins); + + const QRect &file_name_rect = itemDelegate()->fileNameRect(option, index); + + if (!file_name_rect.contains(static_cast(event)->pos())) { + return false; + } + } + + if (QWidget *w = indexWidget(index)) { + Qt::ItemFlags flags = model()->flags(index); + if (((flags & Qt::ItemIsEditable) == 0) || ((flags & Qt::ItemIsEnabled) == 0)) { + return false; + } + if (state() == QAbstractItemView::EditingState) { + return false; + } + if (trigger == QAbstractItemView::AllEditTriggers) { // force editing + d->fileViewHelper->triggerEdit(index); + return true; + } + if ((trigger & editTriggers()) == QAbstractItemView::SelectedClicked + && !selectionModel()->isSelected(index)) { + return false; + } + + if (trigger & editTriggers()) { + w->setFocus(); + d->fileViewHelper->triggerEdit(index); + return true; + } + } + bool tmp = QAbstractItemView::edit(index, trigger, event); + if (tmp) { + d->fileViewHelper->triggerEdit(index); + } + + return tmp; +} + +void CanvasGridView::setDodgeDuration(double dodgeDuration) +{ + if (qFuzzyCompare(d->dodgeDuration, dodgeDuration)) { + return; + } + + d->dodgeDuration = dodgeDuration; + emit dodgeDurationChanged(d->dodgeDuration); +} + +void CanvasGridView::selectAll() +{ + //全选按桌面显示顺序对文件进行选择 + DUrlList all = DUrl::fromStringList(GridManager::instance()->allItems()); + select(all); +} + +void CanvasGridView::onRefreshFinished() +{ + qDebug() << "fresh ending spend " << m_rt.elapsed() << m_screenNum; + model()->setEnabledSort(false); + if (GridManager::instance()->autoMerge()) { + delayAutoMerge(); + } +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + else if (GridManager::instance()->autoArrange()) { + delayArrage(); + } +#endif + else { //自定义 + delayCustom(); + } +} + +void CanvasGridView::EnableUIDebug(bool enable) +{ + d->_debug_log = enable; + d->_debug_show_grid = enable; +} + +QString CanvasGridView::Size() +{ + QBuffer buffer; + buffer.open(QBuffer::ReadWrite); + QDataStream debug(&buffer); + + debug << GridManager::instance()->gridSize(m_screenNum); + + return QString::fromUtf8(buffer.buffer()); +} + +QString CanvasGridView::Dump() +{ + GridManager::instance()->dump(); + return ""; +} + +#include + +QString CanvasGridView::DumpPos(qint32 x, qint32 y) +{ + QJsonObject debug; + + auto px = x * d->cellWidth + d->cellWidth / 2 + d->viewMargins.left(); + auto py = y * d->cellHeight + d->cellHeight / 2 + d->viewMargins.top(); + + QModelIndex index = indexAt(QPoint(px, py)); + + debug.insert("checkPoint:", QJsonValue::fromVariant(QList({px, py}))); + debug.insert("index", QJsonValue::fromVariant(QList({index.row(), index.column()}))); + debug.insert("url", model()->getUrlByIndex(index).toString()); + debug.insert("grid content", GridManager::instance()->itemTop(m_screenNum, x, y)); + + return QJsonDocument(debug).toJson(); +} + +void CanvasGridView::Refresh() +{ + d->fileViewHelper->viewFlicker(); +} + +void CanvasGridView::initUI() +{ +#ifdef QT_DEBUG + EnableUIDebug(true); +#endif + + setAttribute(Qt::WA_TranslucentBackground); + viewport()->setAttribute(Qt::WA_TranslucentBackground); + viewport()->setAutoFillBackground(false); + setFrameShape(QFrame::NoFrame); // TODO: using QWidget instead of QFrame? + + setSelectionMode(QAbstractItemView::ExtendedSelection); + setAcceptDrops(true); + setDragDropMode(QAbstractItemView::DragDrop); + setEditTriggers(QAbstractItemView::EditKeyPressed | QAbstractItemView::SelectedClicked); + setDefaultDropAction(Qt::CopyAction); + + d->fileViewHelper = new CanvasViewHelper(this); + d->fileViewHelper->setProperty("isCanvasViewHelper", true); + + setModel(new DFileSystemModel(d->fileViewHelper)); + model()->isDesktop = true;//紧急修复,由于修复bug#33209添加了一次事件循环的处理,导致桌面的自动排列在删除,恢复文件时显示异常 + + //默认按类型排序 + model()->setSortRole(DFileSystemModel::FileMimeTypeRole); + model()->setEnabledSort(true); + + //设置是否显示隐藏文件 + auto filters = model()->filters(); + filters = GridManager::instance()->getWhetherShowHiddenFiles() ? + filters | QDir::Hidden : filters & ~QDir::Hidden; + model()->setFilters(filters); + + setSelectionModel(new DFileSelectionModel(model(), this)); + auto delegate = new DesktopItemDelegate(d->fileViewHelper); + delegate->setEnabledTextShadow(true); + delegate->setFocusTextBackgroundBorderColor(Qt::white); + setItemDelegate(delegate); + + QVariant iconSizeLevel = 1; + iconSizeLevel = Config::instance()->getConfig(Config::groupGeneral, Config::keyIconLevel, iconSizeLevel); + itemDelegate()->setIconSizeByIconSizeLevel(iconSizeLevel.toInt()); + qDebug() << "current icon size level" << itemDelegate()->iconSizeLevel(); + + DFMSocketInterface::instance(); + DGioSettings desktopSettings("com.deepin.dde.filemanager.desktop", "/com/deepin/dde/filemanager/desktop/"); + if (desktopSettings.keys().contains("water-mask") && desktopSettings.value("water-mask").toBool()) { + d->waterMaskFrame = new WaterMaskFrame("/usr/share/deepin/dde-desktop-watermask.json", this); + d->waterMaskFrame->lower(); + d->waterMaskFrame->updatePosition(); + } +} + + +void CanvasGridView::initConnection() +{ + connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, + [this](const QItemSelection & selected, const QItemSelection & deselected) { + + Q_UNUSED(selected) + QModelIndex index = property("lastPressedIndex").toModelIndex(); + if (index.isValid() && deselected.contains(index)) { + setProperty("lastPressedIndex", QModelIndex()); + } + + //同步选择状态 + emit GridManager::instance()->sigSyncSelection(this, selectedUrls()); + }); + + connect(&d->dodgeDelayTimer, &QTimer::timeout, + this, [ = ]() { +// qDebug() << "start animation"; + d->dodgeAnimationing = true; + auto animation = new QPropertyAnimation(this, "dodgeDuration"); + animation->setDuration(300); + animation->setEasingCurve(QEasingCurve::InOutCubic); + animation->setStartValue(0.0); + animation->setEndValue(1.0); + + connect(animation, &QPropertyAnimation::valueChanged, + this, [ = ]() { + update(); + }); + + connect(animation, &QPropertyAnimation::finished, + this, [ = ]() { + DUrlList selecteds = selectedUrls(); + QMap> removed; //记录移除的 + for (auto relocateItem : selecteds) { + auto localFile = relocateItem.toString(); + QPair pos; + bool ret = GridManager::instance()->find(localFile, pos); + //处理跨屏,如果是跨屏的remove失败,后面就无需再add + if (ret && GridManager::instance()->remove(pos.first, localFile)) + removed.insert(relocateItem, pos); + } + + // commit dodgeTargetGrid + for (auto relocateItem : d->dodgeItems) { + QPoint orgPos = GridManager::instance()->position(m_screenNum, relocateItem); + bool rmRet = GridManager::instance()->remove(m_screenNum, relocateItem); + auto pos = d->dodgeTargetGrid->pos(m_screenNum, relocateItem); + bool addRet = GridManager::instance()->add(m_screenNum, pos, relocateItem); + //add失败,还原。修复bug#21943 + if (!addRet && rmRet) { + qWarning() << "error move!!!" << relocateItem << "from" << orgPos + << "to" << pos << "fail." << "put it on" << orgPos; + bool ret = GridManager::instance()->add(m_screenNum, orgPos, relocateItem); + if (!ret) { + qWarning() << "error resotre " << relocateItem << " to" << orgPos << "fail."; + } + } + } + + //只有被remove的才add。用于处理跨屏拖动 + for (auto relocateItem : removed.keys()) { + QString localFile = relocateItem.toString(); + QPoint tarPos = d->dodgeTargetGrid->pos(m_screenNum, localFile); + bool ret = GridManager::instance()->add(m_screenNum, tarPos, localFile); + //用于修复drag在多屏之间拖动触发动画后的bug + if (!ret) { + auto orgPos = removed.value(relocateItem); + qWarning() << "error move!!!" << localFile << "from" << orgPos + << "to" << tarPos << "fail." << "put it on" << orgPos; + ret = GridManager::instance()->add(orgPos.first, orgPos.second, localFile); + //还原失败,放入堆叠 + if (!ret) { + int iret = GridManager::instance()->addToOverlap(localFile); + qWarning() << "error put " << localFile << " on" << orgPos << "fail. move to overlaps" << iret; + } + } + } + d->dodgeAnimationing = false; + delete d->dodgeTargetGrid; + d->dodgeTargetGrid = nullptr; + + //隐藏选中框 + emit GridManager::instance()->sigSyncOperation(GridManager::soHideEditing); + }); + animation->start(); + d->dodgeDelayTimer.stop(); + + auto selURLs = selectedUrls(); + QStringList selLocalFiles; + + d->dodgeTargetGrid = GridManager::instance()->core(); + auto grid = d->dodgeTargetGrid; + + int emptyBefore = 0; + int emptyAfter = 0; + GIndex targetIndex = grid->toIndex(m_screenNum, d->dragTargetGrid); + + //获取所有的空位 + QList empty = grid->emptyPostion(m_screenNum); + auto sortIndex = [targetIndex](const GIndex & i1, const GIndex & i2) ->bool{ + return qAbs(i1 - targetIndex) < qAbs(i2 - targetIndex); + }; + qSort(empty.begin(), empty.end(), sortIndex); + GIndex index = 0; + for (auto sel : selURLs) { + QString localFile = sel.toString(); + selLocalFiles << localFile; + //抓取的项目在本屏 + if (GridManager::instance()->contains(m_screenNum, localFile)) { + GPos pos = grid->pos(m_screenNum, localFile); + index = grid->toIndex(m_screenNum, pos); + grid->removeItem(m_screenNum, localFile); + } else { //跨屏 + if (!empty.isEmpty()) + index = empty.takeFirst(); + } + + if (index < targetIndex) { + ++emptyBefore; + } else { + ++emptyAfter; + } + } + + if (0 == emptyAfter) { + ++targetIndex; + } + + d->dodgeItems = grid->reloacle(m_screenNum, targetIndex, emptyBefore, emptyAfter); + for (auto i = 0; i < selLocalFiles.length(); ++i) { + grid->addItem(m_screenNum, targetIndex - emptyBefore + i, selLocalFiles.value(i)); + } + }); + + //model刷新完毕 + connect(model(), &DFileSystemModel::sigJobFinished, this, &CanvasGridView::onRefreshFinished); + connect(model(), &DFileSystemModel::requestSelectFiles,this,[this](const QList &urls){ + //fix bug39609 选中桌面文件夹,通过按键F2重命名,然后再按快捷键home、left、right均变为桌面第一个图标为选中 + //重设当前新文件名的index为当前index + if (!urls.isEmpty()) { + d->currentCursorIndex = model()->index(urls.first()); + d->m_oldCursorIndex = d->currentCursorIndex; + } + d->fileViewHelper->onRequestSelectFiles(urls); + }); + + connect(this->model(), &DFileSystemModel::newFileByInternal, + this, [ = ](const DUrl & fileUrl) { +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + if (GridManager::instance()->shouldArrange()) { +#else + if (GridManager::instance()->autoMerge()) { +#endif + //排完序后交由GridManager::initArrage触发重命名 + GridManager::instance()->m_needRenameItem = fileUrl.toString(); + return ; + } +#ifndef USE_SP2_AUTOARRAGE //sp3需求改动 + else if (GridManager::instance()->autoArrange()) { + //开启编辑框 + emit GridManager::instance()->sigSyncOperation(GridManager::soRename, fileUrl.toString()); + return; + } +#endif + + QString localFile = fileUrl.toString(); + int itemScreen; + QPair orgPos; + if (GridManager::instance()->find(localFile, orgPos)) { + itemScreen = orgPos.first; + } else { + qCritical() << "cannot find item" << localFile << "screen" << m_screenNum; + return ; + } + + qDebug() << "newFileByInternal item" << localFile << "screen" << itemScreen + << "pos" << orgPos.second << "to screen" << m_screenNum; + + QPair gridPos; + gridPos.first = m_screenNum; + gridPos.second = gridAt(d->lastMenuPos); + if (d->lastMenuNewFilepath == localFile) { + if (gridPos == orgPos) { + //开启编辑框 + goto openEditor; + } + } + + gridPos = GridManager::instance()->forwardFindEmpty(m_screenNum, gridPos.second); + + //无需move + if (gridPos == orgPos) { + goto openEditor; + } + + //目标位置在当前屏才move + if (gridPos.first == m_screenNum) { + //同屏 + if (m_screenNum == itemScreen) { + GridManager::instance()->move(m_screenNum, QStringList() << localFile, + localFile, gridPos.second.x(), gridPos.second.y()); + } else { //跨屏 + GridManager::instance()->move(itemScreen, m_screenNum, QStringList() << localFile, + localFile, gridPos.second.x(), gridPos.second.y()); + } + } + //else{} //目标位置无法在m_screenNum放下,就不处理 + + openEditor: + emit GridManager::instance()->sigSyncOperation(GridManager::soRename, fileUrl.toString()); + return ; + }); + + connect(this, &CanvasGridView::itemCreated, this, [ = ](const DUrl & url) { + qDebug() << "CanvasGridView::itemCreated" << url << m_screenNum; + d->lastMenuNewFilepath = url.toString(); + //!在这里add会导致自动整理在快速创建文件时crash,与DAbstractFileInfoPrivate中 + //! 的cache机制 urlToFileInfoMap 在异步时有关 关联bug#24855 + //GridManager::instance()->add(m_screenNum, d->lastMenuNewFilepath); + //!end + + //创建或者粘贴时保持之前的状态 + if (GridManager::instance()->autoMerge()) { + this->delayModelRefresh(100); + return ; + } + + //判断文件是否为隐藏文件,当前若不显示隐藏文件,则跳过 + DAbstractFileInfoPointer file = fileService->createFileInfo(nullptr, url); + if (file && file->isHidden() && !(model()->filters() & QDir::Hidden)) { + qDebug() << url << "is hidden file,do not show"; + return; + } + + GridManager::instance()->add(m_screenNum, d->lastMenuNewFilepath); +#ifdef USE_SP2_AUTOARRAGE //sp3需求改动 + if (GridManager::instance()->autoArrange()) { //重新排列 + this->delayArrage(); + } +#endif + }); + + connect(this, &CanvasGridView::itemDeleted, this, [ = ](const DUrl & url) { + auto index = model()->index(url); + //当选中的文件中有文件被移除时就清空所有选中项 + if (d->currentCursorIndex == index || selectionModel()->selectedIndexes().contains(index)) { + d->currentCursorIndex = QModelIndex(); + selectionModel()->setCurrentIndex(QModelIndex(), QItemSelectionModel::Clear); + setCurrentIndex(QModelIndex()); + } + //fix bug55930 桌面新建文本文件和文件夹,选中文本文件剪切到文件夹 ,重命名新的文件夹 ,弹出重命名窗口 + //clear cache selected items,because index data updated + selectionModel()->clearSelectedCaches(); + + if (!GridManager::instance()->remove(m_screenNum, url.toString())) + return; + + //自动整理 + if (GridManager::instance()->autoMerge()) { + delayModelRefresh(); + } else if (GridManager::instance()->autoArrange()) { //重新排列 + this->delayArrage(); + } else { + GridManager::instance()->popOverlap(); //弹出堆叠 + } + }); + + connect(this->model(), &DFileSystemModel::requestSelectFiles, + d->fileViewHelper, &CanvasViewHelper::onRequestSelectFiles); + + connect(this->model(), &QAbstractItemModel::dataChanged, + this, [ = ](const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector &roles) { + qDebug() << "dataChanged" << roles << d->bReloadItem; + if (d->bReloadItem) { + d->bReloadItem = false; + qDebug() << "dataChanged" << topLeft << bottomRight << roles; + qDebug() << "resort desktop icons "; + model()->setEnabledSort(false); + + QStringList list; + for (int i = 0; i < model()->rowCount(); ++i) { + auto index = model()->index(i, 0); + auto localFile = model()->getUrlByIndex(index).toString(); + list << localFile; + } + + GridManager::sortMainDesktopFile(list, model()->sortRole(), model()->sortOrder()); +#ifdef USE_SP2_AUTOARRAGE + //自动排列和整理 + if (GridManager::instance()->shouldArrange()) { + GridManager::instance()->initArrage(list); + return ; + } + + GridManager::instance()->clear(); + //自定义 + for (auto lf : list) { + GridManager::instance()->add(m_screenNum, lf); + } +#else + GridManager::instance()->initArrage(list); + + //自动整理 + if (GridManager::instance()->autoMerge()) { + return ; + } + + GridManager::instance()->delaySyncAllProfile(); +#endif + } + }); + + connect(this, &CanvasGridView::doubleClicked, this, [this](const QModelIndex &index) { + DUrl url = model()->getUrlByIndex(index); + openUrl(url); + }, Qt::QueuedConnection); + + + connect(this, &CanvasGridView::autoAlignToggled, this, [this]() { + Presenter::instance()->onAutoAlignToggled(); + if (GridManager::instance()->autoArrange()) { + this->delayArrage(); + } else { + GridManager::instance()->delaySyncAllProfile(0); + } + }); + +#ifdef ENABLE_AUTOMERGE //sp2需求调整,屏蔽自动整理 + connect(this, &CanvasGridView::autoMergeToggled, this, []() { + bool enable = !GridManager::instance()->autoMerge(); + GridManager::instance()->setAutoMerge(enable); + Presenter::instance()->onAutoMergeToggled(); + + emit GridManager::instance()->sigSyncOperation(GridManager::soAutoMerge, enable); + }); +#endif + + connect(this, &CanvasGridView::sortRoleChanged, + Presenter::instance(), &Presenter::onSortRoleChanged); + connect(this, &CanvasGridView::changeIconLevel, + Presenter::instance(), &Presenter::OnIconLevelChanged); + + connect(this, &CanvasGridView::changeIconLevel, this, + [](int level) { + emit GridManager::instance()->sigSyncOperation(GridManager::soIconSize, level); + }); + + connect(this, &CanvasGridView::sortRoleChanged, this, + [](int role, Qt::SortOrder order) { + QPoint sort(role, order); + emit GridManager::instance()->sigSyncOperation(GridManager::soSort, sort); + }); + + connect(DFMApplication::instance(), &DFMApplication::showedHiddenFilesChanged, this, [ = ](bool isShowedHiddenFile) { + GridManager::instance()->setWhetherShowHiddenFiles(isShowedHiddenFile); + updateHiddenItems(); + }); + + connect(DFMApplication::instance(), &DFMApplication::previewAttributeChanged, this->model(), &DFileSystemModel::update); +} + +void CanvasGridView::updateCanvas() +{ + //todo计算margin + itemDelegate()->updateItemSizeHint(); + auto itemSize = itemDelegate()->sizeHint(QStyleOptionViewItem(), QModelIndex()); + QMargins geometryMargins = QMargins(0, 0, 0, 0); + d->updateCanvasSize(this->geometry().size(), this->geometry().size(), geometryMargins, itemSize); + + GridManager::instance()->updateGridSize(m_screenNum, d->colCount, d->rowCount); + + auto expandedWidget = reinterpret_cast(itemDelegate()->expandedIndexWidget()); + if (expandedWidget) { + int offset = -1 * ((d->cellWidth - itemSize.width()) % 2); + QMargins margins(offset, d->cellMargins.top(), 0, 0); + expandedWidget->setContentsMargins(margins); + } + + //需在expandedWidget->setContentsMargins(margins)之后在更新,否则在计算时没有将Margins纳入计算,导致显示错误 + updateEditorGeometries(); + update(); +} + +void CanvasGridView::setIconByLevel(int level) +{ + if (itemDelegate()->iconSizeLevel() == level) { + return; + } + itemDelegate()->setIconSizeByIconSizeLevel(level); + emit this->changeIconLevel(itemDelegate()->iconSizeLevel()); + updateCanvas(); +} + +void CanvasGridView::increaseIcon() +{ + // TODO: 3 is 128*128, 0,1,2,3 + if (itemDelegate()->iconSizeLevel() >= 4) { + return; + } + itemDelegate()->increaseIcon(); + emit this->changeIconLevel(itemDelegate()->iconSizeLevel()); + updateCanvas(); +} + +void CanvasGridView::decreaseIcon() +{ + itemDelegate()->decreaseIcon(); + emit this->changeIconLevel(itemDelegate()->iconSizeLevel()); + updateCanvas(); +} + +inline QPoint CanvasGridView::gridAt(const QPoint &pos) const +{ + auto row = (pos.x() - d->viewMargins.left()) / d->cellWidth; + auto col = (pos.y() - d->viewMargins.top()) / d->cellHeight; + return QPoint(row, col); +} + +inline QRect CanvasGridView::gridRectAt(const QPoint &pos) const +{ + auto row = (pos.x() - d->viewMargins.left()) / d->cellWidth; + auto col = (pos.y() - d->viewMargins.top()) / d->cellHeight; + + auto x = row * d->cellWidth + d->viewMargins.left(); + auto y = col * d->cellHeight + d->viewMargins.top(); + return QRect(x, y, d->cellWidth, d->cellHeight).marginsRemoved(d->cellMargins); +} + +inline QList CanvasGridView::itemPaintGeomertys(const QModelIndex &index) const +{ + QStyleOptionViewItem option = viewOptions(); + option.rect = visualRect(index).marginsRemoved(d->cellMargins); + return itemDelegate()->paintGeomertys(option, index); +} + +inline QRect CanvasGridView::itemIconGeomerty(const QModelIndex &index) const +{ + QStyleOptionViewItem option = viewOptions(); + option.rect = visualRect(index).marginsRemoved(d->cellMargins); + auto rects = itemDelegate()->paintGeomertys(option, index); + if (rects.isEmpty()) { + return option.rect; + } + + return rects.value(0); +} + + +inline QModelIndex CanvasGridView::firstIndex() +{ + auto localFile = GridManager::instance()->firstItemId(m_screenNum); + return model()->index(DUrl(localFile)); +} + +inline QModelIndex CanvasGridView::lastIndex() +{ + //使用堆叠 + auto localFile = GridManager::instance()->lastItemTop(m_screenNum);//lastItemId(m_screenNum); + return model()->index(DUrl(localFile)); +} + +void CanvasGridView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command, bool byIconRect) +{ + Q_UNUSED(byIconRect) + + auto selectRect = rect.normalized(); + auto topLeftGridPos = gridAt(selectRect.topLeft()); + auto bottomRightGridPos = gridAt(selectRect.bottomRight()); + + QItemSelection oldSelection; + // keep old selection if mouse press + bool ctrlShiftPress = DFMGlobal::keyShiftIsPressed() || DFMGlobal::keyCtrlIsPressed(); + if (ctrlShiftPress) { + oldSelection = selectionModel()->selection(); + if (0 == selectionModel()->selection().indexes().size() && DFMGlobal::keyShiftIsPressed()) + d->beginPos = topLeftGridPos; + } else { + d->beginPos = QPoint(-1, -1); + } + // select by key board, so mouse not pressed + if (!d->mousePressed && d->currentCursorIndex.isValid() && !ctrlShiftPress) { + QItemSelectionRange selectionRange(d->currentCursorIndex); + if (!oldSelection.contains(d->currentCursorIndex)) { + oldSelection.push_back(selectionRange); + } + QAbstractItemView::selectionModel()->select(oldSelection, command); + return; + } + + //get current Point + QPoint currentPoint(-1, -1); + if (d->mousePressed) { + auto clickIndex = indexAt(d->lastPos); + if (clickIndex.isValid() && !d->showSelectRect) { //如果在框选就不进去 + QPoint tempClickIndex = visualRect(clickIndex).center(); + QPoint tempLastPoint = visualRect(d->currentCursorIndex).center(); + if (!d->currentCursorIndex.isValid()) + tempLastPoint = tempClickIndex + QPoint(1, 1); + selectRect = QRect(tempClickIndex, tempLastPoint); + + topLeftGridPos = gridAt(selectRect.topLeft()); + bottomRightGridPos = gridAt(selectRect.bottomRight()); + currentPoint = topLeftGridPos; + if (QPoint(-1, -1) == currentPoint) + return; + } else { + // TODO: what? + if (!d->showSelectRect) { + return; + } + oldSelection = d->beforeMoveSelection; + topLeftGridPos = gridAt(d->selectRect.topLeft()); + bottomRightGridPos = gridAt(d->selectRect.bottomRight()); + + QItemSelection rectSelection; + QMargins margins(10, 10, 10, 10); + for (auto x = topLeftGridPos.x(); x <= bottomRightGridPos.x(); ++x) { + for (auto y = topLeftGridPos.y(); y <= bottomRightGridPos.y(); ++y) { + auto localFile = GridManager::instance()->itemTop(m_screenNum, x, y); + //GridManager::instance()->itemId(m_screenNum, x, y); + if (localFile.isEmpty()) { + continue; + } + auto index = model()->index(DUrl(localFile)); + + //需求,桌面图标向内收缩10个像素为框选触发范围 + auto tempVr = visualRect(index); + tempVr = tempVr.marginsRemoved(margins); + if (tempVr.intersects(selectRect)) { + QItemSelectionRange selectionRange(index); + if (!rectSelection.contains(index)) { + rectSelection.push_back(selectionRange); + } + } + } + } + if (command != QItemSelectionModel::Deselect) { + QItemSelection lastAllSelection; + if (DFMGlobal::keyShiftIsPressed()) { + //shitf键增量 + for (auto &sel : rectSelection) { + for (auto &index : sel.indexes()) + if (!oldSelection.contains(index)) { + oldSelection.push_back(sel); + } + } + lastAllSelection.merge(oldSelection, QItemSelectionModel::Select); + } else { + // Remove dump select + auto tempNewSelection = rectSelection; + auto tempOldSelection = oldSelection; + for (auto &sel : rectSelection) { + for (auto &index : sel.indexes()) + if (oldSelection.contains(index)) { + //bug87509,产品要求按住ctrl鼠标框选效果与文管保持一直 + tempNewSelection.removeOne(sel); + tempOldSelection.removeOne(sel); + } + } + // merge + lastAllSelection.merge(tempNewSelection, QItemSelectionModel::Select); + lastAllSelection.merge(tempOldSelection, QItemSelectionModel::Select); + } + + QAbstractItemView::selectionModel()->select(lastAllSelection, command); + } else { + QAbstractItemView::selectionModel()->select(rectSelection, command); + } + return; + } + } + + if (DFMGlobal::keyShiftIsPressed()) { + QModelIndexList needSelectIndex; + QModelIndexList selectIndexs; + QSize coordSize = GridManager::instance()->gridSize(m_screenNum); + + QItemSelection rectSelection; + DUrl oldRet; + DAbstractFileInfoPointer oldFp = model()->fileInfo(d->m_oldCursorIndex); + if (!oldFp) + return; + oldRet = oldFp->fileUrl(); + QPair oldPosInfo; + GridManager::instance()->find(oldRet.toString(), oldPosInfo); + + DUrl currentRet; + DAbstractFileInfoPointer currentFp = model()->fileInfo(d->currentCursorIndex); + if (currentFp) { + currentRet = currentFp->fileUrl(); + } + QPair currentPosInfo; + GridManager::instance()->find(currentRet.toString(), currentPosInfo); + + topLeftGridPos = oldPosInfo.second; + bottomRightGridPos = currentPosInfo.second; + + QPoint temp; + if (topLeftGridPos.y() > bottomRightGridPos.y() + || (topLeftGridPos.x() > bottomRightGridPos.x() + && topLeftGridPos.y() == bottomRightGridPos.y())) { + temp = topLeftGridPos; + topLeftGridPos = bottomRightGridPos; + bottomRightGridPos = temp; + } + + int rowBegin = topLeftGridPos.y(); + int rowEnd = bottomRightGridPos.y(); + QPoint nextItem; + for (; rowBegin <= rowEnd; ++ rowBegin) { + nextItem.setX(0); + nextItem.setY(rowBegin); + while (nextItem != bottomRightGridPos) { + if (nextItem.y() == topLeftGridPos.y() && nextItem.x() < topLeftGridPos.x()) { + nextItem = QPoint((nextItem.x() + 1), rowBegin); + continue; + } + + auto nextUrl = GridManager::instance()->itemTop(m_screenNum, nextItem.x(), nextItem.y()); + auto nextIndex = model()->index(nextUrl); + QItemSelectionRange selectionRange(nextIndex); + rectSelection.append(selectionRange); + nextItem = QPoint((nextItem.x() + 1), rowBegin); + bool inLayoutX = 0 <= nextItem.x() && nextItem.x() <= (coordSize.width() - 1); + if (!inLayoutX) { + break; + } + } + auto nextUrl = GridManager::instance()->itemTop(m_screenNum, nextItem.x(), nextItem.y()); + auto nextIndex = model()->index(nextUrl); + QItemSelectionRange selectionRange(nextIndex); + rectSelection.append(selectionRange); + } + + QAbstractItemView::selectionModel()->clear(); + QAbstractItemView::selectionModel()->select(rectSelection, command); + } else if (DFMGlobal::keyCtrlIsPressed()) { + //just Ctrl + auto localFile = GridManager::instance()->itemTop(m_screenNum, topLeftGridPos.x(), topLeftGridPos.y()); + //GridManager::instance()->itemId(m_screenNum, topLeftGridPos.x(), topLeftGridPos.y()); + if (localFile.isEmpty()) { + return; + } + auto index = model()->index(DUrl(localFile)); + QItemSelectionRange selectionRange(index); + if (!oldSelection.contains(index)) { + oldSelection.push_back(selectionRange); + } else { + oldSelection.removeOne(selectionRange); + } + QAbstractItemView::selectionModel()->select(oldSelection, command); + d->beginPos = topLeftGridPos; + } else { + //just click or mouseleft select + auto localFile = GridManager::instance()->itemTop(m_screenNum, topLeftGridPos.x(), topLeftGridPos.y()); + //GridManager::instance()->itemId(m_screenNum, topLeftGridPos.x(), topLeftGridPos.y()); + if (localFile.isEmpty()) { + return; + } + auto index = model()->index(DUrl(localFile)); + + //end + QItemSelectionRange selectionRange(index); + QItemSelection rectSelection; + rectSelection.push_back(selectionRange); + QAbstractItemView::selectionModel()->select(rectSelection, command); + d->beginPos = topLeftGridPos; + } +} + +void CanvasGridView::handleContextMenuAction(int action) +{ + bool changeSort = false; + + switch (action) { + case DisplaySettings: { + QDBusInterface interface("com.deepin.dde.ControlCenter","/com/deepin/dde/ControlCenter","com.deepin.dde.ControlCenter"); + interface.asyncCall("ShowModule",QVariant::fromValue(QString("display"))); + break; + } + case CornerSettings: + Desktop::instance()->showZoneSettings(); + break; + case WallpaperSettings: + Desktop::instance()->ShowWallpaperChooser(m_screenName); + break; + case MenuAction::SelectAll: + this->selectAll(); + break; +// case FileManagerProperty: { +// QStringList localFiles; +// localFiles << currentUrl().toLocalFile(); +// qDebug() << localFiles; +// DFMSocketInterface::instance()->showProperty(localFiles); +// break; +// } + case AutoMerge: + emit autoMergeToggled(); + break; + case AutoSort: + emit autoAlignToggled(); + break; + case IconSize0: + case IconSize1: + case IconSize2: + case IconSize3: + case IconSize4: + setIconByLevel(action - IconSize0); + break; + + case MenuAction::Name: + case MenuAction::Size: + case MenuAction::Type: + case MenuAction::LastModifiedDate: + changeSort = true; + break; + + default: + qInfo() << action; + } + + if (changeSort) { + model()->setEnabledSort(true); + d->bReloadItem = true; +// QMap sortActions; +// sortActions.insert(MenuAction::Name, DFileSystemModel::FileDisplayNameRole); +// sortActions.insert(MenuAction::Size, DFileSystemModel::FileSizeRole); +// sortActions.insert(MenuAction::Type, DFileSystemModel::FileMimeTypeRole); +// sortActions.insert(MenuAction::LastModifiedDate, DFileSystemModel::FileLastModifiedRole); + + int sortRole = kSortActions.value(action); + Qt::SortOrder sortOrder = model()->sortOrder(); + //若排序模式一样,则改变升降 + if (sortRole == model()->sortRole()) + sortOrder = sortOrder == Qt::AscendingOrder ? Qt::DescendingOrder : Qt::AscendingOrder; + + model()->setSortRole(sortRole, sortOrder); + model()->sort(); + Q_EMIT sortRoleChanged(sortRole, sortOrder); + } +} + +void CanvasGridView::showEmptyAreaMenu(const Qt::ItemFlags &/*indexFlags*/) +{ + const QModelIndex &index = rootIndex(); + const DAbstractFileInfoPointer &info = model()->fileInfo(index); + QVector actions; + actions << MenuAction::NewFolder << MenuAction::NewDocument; + if (!GridManager::instance()->autoMerge()) { + actions << MenuAction::SortBy; + } + actions << MenuAction::Paste + << MenuAction::SelectAll << MenuAction::OpenInTerminal; + // 右键刷新 + { + static const DGioSettings menuSwitch("com.deepin.dde.filemanager.contextmenu", + "/com/deepin/dde/filemanager/contextmenu/"); + auto showRefreh = menuSwitch.value("Refresh"); + if (showRefreh.isValid() && showRefreh.toBool()) + actions << MenuAction::RefreshView; + } + + actions << MenuAction::Property << MenuAction::Separator; + if (actions.isEmpty()) { + return; + } + + const QMap > &subActions = info->subMenuActionList(); + + QSet disableList = DFileMenuManager::getDisableActionList(model()->getUrlByIndex(index)); + + if (model()->state() != DFileSystemModel::Idle) { + disableList << MenuAction::SortBy; + } + if (!model()->rowCount()) { + disableList << MenuAction::SelectAll; + } + + DFileMenu *menu = DFileMenuManager::genereteMenuByKeys(actions, disableList, true, subActions); + if (!menu) { + return; + } + + auto *pasteAction = menu->actionAt(DFileMenuManager::getActionString(MenuAction::Paste)); + + DFileMenu iconSizeMenu; + + for (int i = itemDelegate()->minimumIconSizeLevel(); i <= itemDelegate()->maximumIconSizeLevel(); ++i) { + auto iconSize = new QAction(&iconSizeMenu); + iconSize->setText(itemDelegate()->iconSizeLevelDescription(i)); + iconSize->setData(IconSize + i); + iconSize->setCheckable(true); + iconSize->setChecked(i == itemDelegate()->iconSizeLevel()); + iconSizeMenu.addAction(iconSize); + } + //图标大小排列 + QAction iconSizeAction(menu); + iconSizeAction.setText(tr("Icon size")); + iconSizeAction.setData(IconSize); + iconSizeAction.setMenu(&iconSizeMenu); + menu->insertAction(pasteAction, &iconSizeAction); + +#ifdef ENABLE_AUTOMERGE //sp2需求调整,屏蔽自动整理 + //自动整理 + QAction menuAutoMerge(menu); + menuAutoMerge.setText(tr("Auto merge")); + menuAutoMerge.setData(AutoMerge); + menuAutoMerge.setCheckable(true); + menuAutoMerge.setChecked(GridManager::instance()->autoMerge()); + DGioSettings settings("com.deepin.dde.filemanager.desktop", "/com/deepin/dde/filemanager/desktop/"); + if (settings.value("auto-merge").toBool()) { + menu->insertAction(pasteAction, &menuAutoMerge); + } +#endif + + //自动排序 + QAction autoSort(menu); + autoSort.setText(tr("Auto arrange")); + autoSort.setData(AutoSort); + autoSort.setCheckable(true); + autoSort.setChecked(GridManager::instance()->autoArrange()); + if (!GridManager::instance()->autoMerge()) + menu->insertAction(pasteAction, &autoSort); + + //DFileView中会修改排序项的选中属性,需重设状态。 + if (QAction *sortAction = menu->actionAt(DFileMenuManager::getActionString(MenuAction::SortBy))) { + if (QMenu *roleMenu = sortAction->menu()) { + for (QAction *action : roleMenu->actions()) { + action->setCheckable(false); + action->setChecked(false); + } + } + } + + auto *propertyAction = menu->actionAt(DFileMenuManager::getActionString(MenuAction::Property)); + QList pluginActions = DFileMenuManager::loadEmptyAreaPluginMenu(menu, model()->rootUrl(), true); + + if (pluginActions.count() > 0) { + QAction *separator = new QAction(menu); + separator->setSeparator(true); + menu->insertAction(pluginActions.at(0), separator); + } + + //显示设置 + QAction display(menu); + display.setText(tr("Display Settings")); + display.setData(DisplaySettings); + menu->addAction(&display); + + //热区设置,新版无热区设置需求 +#ifndef DISABLE_ZONE + QAction corner(menu); + DGioSettings gsetting("com.deepin.dde.desktop", "/com/deepin/dde/desktop/"); + if (gsetting.keys().contains("enable-hotzone-settings") && gsetting.value("enable-hotzone-settings").toBool()) { + corner.setText(tr("Corner Settings")); + corner.setData(CornerSettings); + menu->addAction(&corner); + } +#endif + + //壁纸和屏保设置 + QAction wallpaper(menu); +#ifdef DISABLE_SCREENSAVER + wallpaper.setText(tr("Set Wallpaper")); +#else + if (ScreenSaverCtrlFunction::needShowScreensaver()) { + wallpaper.setText(tr("Wallpaper and Screensaver")); + } else { + wallpaper.setText(tr("Set Wallpaper")); + } +#endif + wallpaper.setData(WallpaperSettings); + menu->addAction(&wallpaper); + + menu->removeAction(propertyAction); + menu->setEventData(model()->rootUrl(), selectedUrls(), winId(), this); + + //扩展菜单 + DFileMenuManager::extendCustomMenu(menu, false, currentUrl() , {}, {}, true); + + connect(menu, &DFileMenu::triggered, this, [ = ](QAction * action) { + qDebug() << "trigger action" << action->data(); + if (!action->data().isValid()) { + return; + } + handleContextMenuAction(action->data().toInt()); + }); + + d->fileViewHelper->handleMenu(menu); + + if (DesktopInfo().waylandDectected()) { + + QPoint t_tmpPoint = QCursor::pos(); + QRect t_tmpRect; + if (parentWidget()) + t_tmpRect = parentWidget()->geometry(); + else { + auto screen = ScreenMrg->primaryScreen(); + if (screen) + t_tmpRect = screen->geometry(); + else { + qCritical() << "get primary geometry fail" << m_screenName << m_screenNum; + menu->exec(); + menu->deleteLater(); + return; + } + } + + if (t_tmpPoint.x() + menu->sizeHint().width() > t_tmpRect.right()) + t_tmpPoint.setX(t_tmpPoint.x() - menu->sizeHint().width()); + + if (t_tmpPoint.y() + menu->sizeHint().height() > t_tmpRect.bottom()) + t_tmpPoint.setY(t_tmpPoint.y() - menu->sizeHint().height()); +// menu->exec(t_tmpPoint); + QEventLoop eventLoop; + d->menuLoop = &eventLoop; + connect(menu, &QMenu::aboutToHide, this, [ = ] { + if (d->menuLoop) + d->menuLoop->exit(); + }); + menu->popup(t_tmpPoint); + menu->setGeometry(t_tmpPoint.x(), t_tmpPoint.y(), menu->sizeHint().width(), menu->sizeHint().height()); + eventLoop.exec(); + d->menuLoop = nullptr; + menu->deleteLater(); + return; + } + //fix bug 33305 在用右键菜单复制大量文件时,在复制过程中,关闭窗口这时this释放了,在关闭拷贝menu的exec退出,menu的deleteLater崩溃 + QPointer me = this; + menu->exec(); + menu->deleteLater(me); +} + +void CanvasGridView::showNormalMenu(const QModelIndex &index, const Qt::ItemFlags &indexFlags) +{ + if (!index.isValid()) { + return; + } + + const DUrlList list = selectedUrls(); + const DAbstractFileInfoPointer &info = model()->fileInfo(index); + if (!info || info->isVirtualEntry()) { + return; + } + + QSet disableList; + QSet unusedList; + + // blumia: when touching this part, do the same change in dfileview.cpp + if (list.size() == 1) { + if (!info->isReadable() && !info->isSymLink()) { + disableList << MenuAction::Copy; + } + + if (!info->isWritable() && !info->isFile() && !info->isSymLink()) { + disableList << MenuAction::Delete; + } + + if (!indexFlags.testFlag(Qt::ItemIsEditable)) { + disableList << MenuAction::Rename; + } + } + + if (list.length() == 1) { + unusedList << MenuAction::OpenInNewWindow + << MenuAction::OpenInNewTab + << MenuAction::SendToDesktop + << MenuAction::AddToBookMark; + } else { + unusedList << MenuAction::SendToDesktop; + } + + /********************************************/ + //桌面的菜单action有些是通过filemanager lis管理的 + //里面的判断都是i基于真实路径,所以在自动整理的虚拟路径就不适用 + //故重新更改成真实路径传递,可能对action后续的操作是否有影响 + auto curUrl = info->fileUrl(); + DUrlList realList; + DFileMenu *menu = nullptr; + + //是否显示自定义菜单 + bool customMenu = true; + + auto dirUrl = currentUrl(); + if (curUrl.scheme() == DFMMD_SCHEME) { + curUrl = MergedDesktopController::convertToRealPath(curUrl); + dirUrl = MergedDesktopController::convertToRealPath(dirUrl); + + //判断计算机 回收站 主目录 + const DUrl &computerDesktopFile = DesktopFileInfo::computerDesktopFileUrl(); + const DUrl &trashDesktopFile = DesktopFileInfo::trashDesktopFileUrl(); + const DUrl &homeDesktopFile = DesktopFileInfo::homeDesktopFileUrl(); + + for (const DUrl &url : list) { + auto cUrl = MergedDesktopController::convertToRealPath(url); + realList.append(cUrl); + //多选文件中包含以下文件时 则不展示扩展菜单项 + if (customMenu && (cUrl == computerDesktopFile + || cUrl == trashDesktopFile + || cUrl == homeDesktopFile)) { + customMenu = false; + } + } + menu = DFileMenuManager::createNormalMenu(curUrl, realList, disableList, unusedList, static_cast(winId()), true); + } else { + //realList给后面的扩展菜单使用 + realList = list; + + //判断计算机 回收站 主目录 + const DUrl &computerDesktopFile = DesktopFileInfo::computerDesktopFileUrl(); + const DUrl &trashDesktopFile = DesktopFileInfo::trashDesktopFileUrl(); + const DUrl &homeDesktopFile = DesktopFileInfo::homeDesktopFileUrl(); + + //多选文件中包含以下文件时 则不展示扩展菜单项 + for (const DUrl &cUrl : realList) { + if (cUrl == computerDesktopFile + || cUrl == trashDesktopFile + || cUrl == homeDesktopFile) { + customMenu = false; + break; + } + } + menu = DFileMenuManager::createNormalMenu(info->fileUrl(), list, disableList, unusedList, static_cast(winId()), true); + } + + if (!menu) { + return; + } + + //totally use dde file manager libs for menu actions + // auto *menu = DFileMenuManager::createNormalMenu(info->fileUrl(), list, disableList, unusedList, winId(), true); + /********************************************/ + + QSet ignoreActions; + ignoreActions << MenuAction::Open; + menu->setIgnoreMenuActions(ignoreActions); + menu->setAccessibleInfo(AC_FILE_MENU_DESKTOP); + + auto *propertyAction = menu->actionAt(DFileMenuManager::getActionString(MenuAction::Property)); + if (propertyAction) { + menu->removeAction(propertyAction); + } + + QAction *property = new QAction(menu); + property->setText(tr("Properties")); + property->setData(FileManagerProperty); + menu->addAction(property); + + menu->setEventData(model()->rootUrl(), selectedUrls(), winId(), this, index); + + //扩展菜单 + if (customMenu) + DFileMenuManager::extendCustomMenu(menu, true, dirUrl, curUrl, realList, true); + + //断开连接,桌面优先处理 + //为了保证自动整理下右键菜单标记信息(需要虚拟路径)与右键取消共享文件夹(需要真是路径)无有冲突, + //故在connect(menu, &DFileMenu::triggered, this, [ = ](QAction * action) {}相应之后再相应actionTriggered的连接 + //所以这里先断开 + disconnect(menu, &DFileMenu::triggered, fileMenuManger, &DFileMenuManager::actionTriggered); + connect(menu, &DFileMenu::triggered, this, [ = ](QAction * action) { + if (!action->data().isValid()) { + return; + } + switch (action->data().toInt()) { + case MenuAction::Open: { +// for (auto &url : list) { +// openUrl(url); +// } + qDebug() << "open urls" << list; + openUrls(list); + } + break; + case FileManagerProperty: { + //解决自动整理修改文件属性不生效问题 + QList selectedUrlLst{}; + if (GridManager::instance()->autoMerge()) { + QList t_selectedUrls{}; + t_selectedUrls = this->autoMergeSelectedUrls(); + for (auto temp : t_selectedUrls) { + if (DFMMD_SCHEME == temp.scheme()) + selectedUrlLst.append(MergedDesktopController::convertToRealPath(temp)); + } + } else { + selectedUrlLst = this->selectedUrls(); + } + + DFMGlobal::showPropertyDialog(this, selectedUrlLst); + //DFMGlobal::showPropertyDialog(this, this->selectedUrls()); + break; + } + case MenuAction::Rename: { + if (list.size() == 1) { + QAbstractItemView::edit(index); //###: select one file on desktop. + + } else { //###: select more than one files. + QList selectedUrls{}; + if (GridManager::instance()->autoMerge()) { + selectedUrls = this->autoMergeSelectedUrls(); + } else { + selectedUrls = this->selectedUrls(); + } + DFMGlobal::showMultiFilesRenameDialog(selectedUrls); + } + break; + } + //为了保证自动整理下右键菜单标记信息(需要虚拟路径)与右键取消共享文件夹(需要真是路径)无有冲突 + //将取消共享文件夹的选中路径提到里面 + case MenuAction::Share: { + if (info->fileUrl().scheme() == DFMMD_SCHEME) { + menu->setEventData(curUrl, realList, winId(), this, index); + } else { + menu->setEventData(model()->rootUrl(), selectedUrls(), winId(), this, index); + } + break; + } + + default: + break; + } + }, Qt::QueuedConnection); + + //使用队列连接,防止menu的exec无法退出 + //为了保证自动整理下右键菜单标记信息(需要虚拟路径)与右键取消共享文件夹(需要真是路径)无有冲突, + //故在connect(menu, &DFileMenu::triggered, this, [ = ](QAction * action) {}相应之后再相应actionTriggered的连接 + //这里再重新连接保证在triggered之后相应 + connect(menu, &DFileMenu::triggered, fileMenuManger, &DFileMenuManager::actionTriggered, Qt::QueuedConnection); + d->fileViewHelper->handleMenu(menu); + + if (DesktopInfo().waylandDectected()) { + + QPoint t_tmpPoint = QCursor::pos(); + QRect t_tmpRect; + if (parentWidget()) + t_tmpRect = parentWidget()->geometry(); + else { + auto screen = ScreenMrg->primaryScreen(); + if (screen) + t_tmpRect = screen->geometry(); + else { + qCritical() << "get primary geometry fail" << m_screenName << m_screenNum; + menu->exec(); + menu->deleteLater(); + return; + } + } + + if (t_tmpPoint.x() + menu->sizeHint().width() > t_tmpRect.right()) + t_tmpPoint.setX(t_tmpPoint.x() - menu->sizeHint().width()); + + if (t_tmpPoint.y() + menu->sizeHint().height() > t_tmpRect.bottom()) + t_tmpPoint.setY(t_tmpPoint.y() - menu->sizeHint().height()); +// menu->exec(t_tmpPoint); + QEventLoop eventLoop; + d->menuLoop = &eventLoop; + connect(menu, &QMenu::aboutToHide, this, [ = ] { + if (d->menuLoop) + d->menuLoop->exit(); + }); + menu->popup(t_tmpPoint); + menu->setGeometry(t_tmpPoint.x(), t_tmpPoint.y(), menu->sizeHint().width(), menu->sizeHint().height()); + eventLoop.exec(); + d->menuLoop = nullptr; + menu->deleteLater(); + return; + } + //fix bug 33305 在用右键菜单复制大量文件时,在复制过程中,关闭窗口这时this释放了,在关闭拷贝menu的exec退出,menu的deleteLater崩溃 + QPointer me = this; + menu->exec(); + menu->deleteLater(me); + //断连,防止menu没有释放再次触发信号 + disconnect(menu, nullptr, this, nullptr); +} + +void CanvasGridView::startDrag(Qt::DropActions supportedActions) +{ + // 在定时器期间收到鼠标move事件低于配置时间,不触发drag + if (d->touchTimer.isActive()) + return; + //drop后该变量依然为true,先将其置为false + d->mousePressed = false; + + //drag优化,只抓起本屏幕上的图标 + DUrlList validSel; + QModelIndexList validIndexes; + viewSelectedUrls(validSel, validIndexes); + select(validSel); + itemDelegate()->hideAllIIndexWidget(); + + //数量大于1, 聚合图标 + if (validIndexes.count() > 1) { + QMimeData *data = model()->mimeData(validIndexes); + if (!data) + return; + + QPixmap pixmap = this->renderToPixmap(validIndexes); + QDrag *drag = new QDrag(this); + drag->setPixmap(pixmap); + drag->setMimeData(data); + drag->setHotSpot(QPoint(static_cast(pixmap.size().width() / (2 * pixmap.devicePixelRatio())), + static_cast(pixmap.size().height() / (2 * pixmap.devicePixelRatio())))); + Qt::DropAction dropAction = Qt::IgnoreAction; + Qt::DropAction defaultDropAction = QAbstractItemView::defaultDropAction(); + if (defaultDropAction != Qt::IgnoreAction && (supportedActions & defaultDropAction)) + dropAction = defaultDropAction; + else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove) + dropAction = Qt::CopyAction; + drag->exec(supportedActions, dropAction); + } else { + QAbstractItemView::startDrag(supportedActions); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/canvasgridview.h b/dde-file-manager-5.5.3/src/dde-desktop/view/canvasgridview.h new file mode 100644 index 0000000..371e36b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/canvasgridview.h @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#ifndef CANVASGRIDVIEW_H +#define CANVASGRIDVIEW_H + +#include +#include +#include +#include + +#define DesktopCanvasPath "/com/deepin/dde/desktop/canvas" +#define DesktopCanvasInterface "com.deepin.dde.desktop.Canvas" + +enum DMD_TYPES : unsigned int; +class DUrl; +class DesktopItemDelegate; +class DFileSystemModel; +class DFileSelectionModel; +class CanvasViewPrivate; +class CanvasGridView: public QAbstractItemView +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", DesktopCanvasInterface) + + Q_PROPERTY(double dodgeDuration READ dodgeDuration WRITE setDodgeDuration NOTIFY dodgeDurationChanged) +public: + static QMap virtualEntryExpandState; + + explicit CanvasGridView(const QString &screen, QWidget *parent = Q_NULLPTR); + ~CanvasGridView() override; + + + enum ContextMenuAction { + DisplaySettings = MenuAction::UserMenuAction + 1, + CornerSettings, + WallpaperSettings, + + FileManagerProperty, + + AutoMerge, + AutoSort, + + IconSize, + IconSize0 = IconSize, + IconSize1 = IconSize + 1, + IconSize2 = IconSize + 2, + IconSize3 = IconSize + 3, + IconSize4 = IconSize + 4, + }; + Q_ENUM(ContextMenuAction) + + // inherint prue virtual function of QAbstractItemView + virtual QRect visualRect(const QModelIndex &index) const override; + virtual QModelIndex indexAt(const QPoint &point) const override; + virtual void scrollTo(const QModelIndex &index, + ScrollHint hint = EnsureVisible) override; + virtual QModelIndex moveCursor(CursorAction cursorAction, + Qt::KeyboardModifiers modifiers) override; + virtual int horizontalOffset() const override; + virtual int verticalOffset() const override; + virtual bool isIndexHidden(const QModelIndex &index) const override; + virtual void setSelection(const QRect &rect, + QItemSelectionModel::SelectionFlags command) override; + virtual QRegion visualRegionForSelection(const QItemSelection &selection) const override; + + // event override + void mouseMoveEvent(QMouseEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void mouseDoubleClickEvent(QMouseEvent *event) override; + void wheelEvent(QWheelEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void dragEnterEvent(QDragEnterEvent *event) override; + void dragMoveEvent(QDragMoveEvent *event) override; + void dragLeaveEvent(QDragLeaveEvent *event) override; + void dropEvent(QDropEvent *event) override; + void paintEvent(QPaintEvent *) override; + //void resizeEvent(QResizeEvent *event) override; + void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + void contextMenuEvent(QContextMenuEvent *event) override; + + bool event(QEvent *event) override; + + virtual void rowsInserted(const QModelIndex &parent, int first, int last) override; + virtual void keyboardSearch(const QString &search) override; + +#if QT_CONFIG(draganddrop) + virtual void startDrag(Qt::DropActions supportedActions) override; +#endif + QPixmap renderToPixmap(const QModelIndexList &indexes) const; + QString canvansScreenName() const; + QRect rectForIndex(const QModelIndex &index) const; + DUrl currentUrl() const; + bool setCurrentUrl(const DUrl &url); + void initRootUrl(); + bool setRootUrl(const DUrl &url); + const DUrlList autoMergeSelectedUrls() const; + const DUrlList selectedUrls() const; + void viewSelectedUrls(DUrlList &validSel, QModelIndexList &validIndexes); + void setScreenNum(int num); + void setScreenName(const QString &name); + inline QString screenName() const {return m_screenName;} + bool isSelected(const QModelIndex &index) const; + void select(const QList &list); + int selectedIndexCount() const; + + DFileSystemModel *model() const; + DFileSelectionModel *selectionModel() const; + DesktopItemDelegate *itemDelegate() const; + void setItemDelegate(DesktopItemDelegate *delegate); + + double dodgeDuration() const; + + void openUrl(const DUrl &url); + void openUrls(const QList &urls); + + QMargins cellMargins() const; + QSize cellSize() const; + + WId winId() const; + void setAutoMerge(bool enabled = false); + void toggleEntryExpandedState(const DUrl &url); + void updateEntryExpandedState(const DUrl &url); + void setGeometry(const QRect &rect); + void delayModelRefresh(int ms = 50); + DUrl currentCursorFile() const; + inline int screenNum() const {return m_screenNum;} + void syncIconLevel(int level); + void updateHiddenItems(); + void updateExpandItemGeometry(); +signals: + void sortRoleChanged(int role, Qt::SortOrder order); + void autoAlignToggled(); + void autoMergeToggled(); + void changeIconLevel(int iconLevel); + void dodgeDurationChanged(double dodgeDuration); + +signals: + void itemDeleted(const DUrl &url); + void itemCreated(const DUrl &url); + +public slots: + bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event) override; + void setDodgeDuration(double dodgeDuration); + virtual void selectAll() override; +protected slots: + void onRefreshFinished(); +// Debug interface +public Q_SLOTS: + Q_SCRIPTABLE void EnableUIDebug(bool enable); + Q_SCRIPTABLE QString Size(); + Q_SCRIPTABLE QString Dump(); + Q_SCRIPTABLE QString DumpPos(qint32 x, qint32 y); + Q_SCRIPTABLE void Refresh(); // 刷新桌面图标 +protected: + void delayAutoMerge(int ms = 50); + void delayArrage(int ms = 50); + void delayCustom(int ms = 50); +private: + Q_DISABLE_COPY(CanvasGridView) + + friend class DEventFilter; + + void initUI(); + void initConnection(); + void updateCanvas(); + + void setIconByLevel(int level); + void increaseIcon(); + void decreaseIcon(); + + inline QPoint gridAt(const QPoint &pos) const; + inline QRect gridRectAt(const QPoint &pos) const; + inline QList itemPaintGeomertys(const QModelIndex &index) const; + inline QRect itemIconGeomerty(const QModelIndex &index) const; + + inline QModelIndex firstIndex(); + inline QModelIndex lastIndex(); + + void setSelection(const QRect &rect, + QItemSelectionModel::SelectionFlags command, + bool byIconRect); + + void handleContextMenuAction(int action); + + void showEmptyAreaMenu(const Qt::ItemFlags &indexFlags); + void showNormalMenu(const QModelIndex &index, const Qt::ItemFlags &indexFlags); + bool isIndexEmpty(); + QModelIndex moveCursorGrid(CursorAction cursorAction, Qt::KeyboardModifiers modifiers); + + void setGeometry(int, int, int, int) = delete; + bool fetchDragEventUrlsFromSharedMemory(); + + /** + * @brief setTargetUrlToApp 为其他应用设置目标Url + * 仅当被拖拽行为是DFileDrag时会被调用 + * @param data mimeData + * @param url 目标Url + */ + void setTargetUrlToApp(const QMimeData *data, const DUrl &url); + + QScopedPointer d; + double m_dragMoveTime; + QList m_urlsForDragEvent; + + QString m_screenName; + int m_screenNum{1}; + + QTimer *m_refreshTimer = nullptr; + QTime m_rt; //刷新计时,可以删除 + + DUrl m_currentTargetUrl; //缓存当前目标Url +}; + + +#endif // CANVASGRIDVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/canvasviewhelper.cpp b/dde-file-manager-5.5.3/src/dde-desktop/view/canvasviewhelper.cpp new file mode 100644 index 0000000..23a7359 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/canvasviewhelper.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: wangchunlin + * + * Maintainer: wangchunlin + * + * 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 + * 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 . + */ + +#include "canvasviewhelper.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "canvasgridview.h" +#include "desktopitemdelegate.h" + +CanvasViewHelper::CanvasViewHelper(CanvasGridView *parent): DFileViewHelper(parent) +{ + connect(fileSignalManager, &FileSignalManager::requestSelectFile, + this, &CanvasViewHelper::handleSelectEvent); + + //交由CanvasView处理,修复项目经过自动排列后编辑框显示问题 + disconnect(fileSignalManager, SIGNAL(requestSelectRenameFile(DFMUrlBaseEvent)), + this, SLOT(_q_selectAndRename(DFMUrlBaseEvent))); +} + +CanvasGridView *CanvasViewHelper::parent() const +{ + return qobject_cast(DFileViewHelper::parent()); +} + +quint64 CanvasViewHelper::windowId() const +{ + return parent()->winId(); +} + +const DAbstractFileInfoPointer CanvasViewHelper::fileInfo(const QModelIndex &index) const +{ + return parent()->model()->fileInfo(index); +} + +DFMStyledItemDelegate *CanvasViewHelper::itemDelegate() const +{ + return qobject_cast(parent()->itemDelegate()); +} + +DFileSystemModel *CanvasViewHelper::model() const +{ + return parent()->model(); +} + +const DUrlList CanvasViewHelper::selectedUrls() const +{ + return parent()->selectedUrls(); +} + +void CanvasViewHelper::select(const QList &list) +{ + return parent()->select(list); +} + +void CanvasViewHelper::edit(const DFMEvent &event) +{ + if (event.windowId() != windowId() || event.fileUrlList().isEmpty()) { + return; + } + + DUrl fileUrl = event.fileUrlList().first(); + + if (fileUrl.isEmpty()) { + return; + } + + const QModelIndex &index = model()->index(fileUrl); + + parent()->edit(index, QAbstractItemView::EditKeyPressed, nullptr); +} + +void CanvasViewHelper::onRequestSelectFiles(const QList &urls) +{ + select(urls); +} + +void CanvasViewHelper::handleSelectEvent(const DFMUrlListBaseEvent &event) +{ + // TODO: should check fileSignalManager->requestSelectFile() and ensure sender correct. + if (event.sender() != this->parent() + && event.sender() != this->model()) { + return; + } + + select(event.urlList()); +} + +void CanvasViewHelper::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const +{ + if (isSelected(index)) { + option->state |= QStyle::State_Selected; + } else { + option->state &= QStyle::StateFlag(~QStyle::State_Selected); + } + + option->palette.setColor(QPalette::Text, QColor("white")); + option->palette.setColor(QPalette::Disabled, QPalette::Text, QColor("#797979")); + if ((option->state & QStyle::State_Selected) && option->showDecorationSelected) { + option->palette.setColor(QPalette::Inactive, QPalette::Text, QColor("#e9e9e9")); + } else { + option->palette.setColor(QPalette::Inactive, QPalette::Text, QColor("#797979")); + } + option->palette.setColor(QPalette::BrightText, Qt::white); + option->palette.setBrush(QPalette::Shadow, QColor(0, 0, 0, 178)); + + bool transp = isTransparent(index); + + if (transp) { + option->backgroundBrush = QColor("#BFE4FC"); + } + + if ((option->state & QStyle::State_HasFocus) && option->showDecorationSelected && selectedIndexsCount() > 1) { + option->palette.setColor(QPalette::Background, QColor("#0076F9")); + + if (!transp) + option->backgroundBrush = QColor("#0076F9"); + } else { + option->palette.setColor(QPalette::Background, QColor("#2da6f7")); + + if (!transp) + option->backgroundBrush = QColor("#2da6f7"); + } + + option->textElideMode = Qt::ElideLeft; +} + +int CanvasViewHelper::selectedIndexsCount() const +{ + return parent()->selectedIndexCount(); +} + +bool CanvasViewHelper::isSelected(const QModelIndex &index) const +{ + return parent()->isSelected(index); +} + +void CanvasViewHelper::viewFlicker() +{ + auto fileModel = model(); + auto view = parent(); + if (fileModel && view) { + //刷新时的闪烁效果 + m_paintFile = false; + view->repaint(); //依赖Qt重绘ui,若本次repaint不进入paintevent,则不会闪烁 + view->update(); + m_paintFile = true; + + //刷新model + fileModel->refresh(); + } +} + +bool CanvasViewHelper::isPaintFile() const +{ + return m_paintFile; +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/canvasviewhelper.h b/dde-file-manager-5.5.3/src/dde-desktop/view/canvasviewhelper.h new file mode 100644 index 0000000..942ac75 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/canvasviewhelper.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include + +class DFMEvent; +class CanvasGridView; +class CanvasViewHelper : public DFileViewHelper +{ + Q_OBJECT +public: + explicit CanvasViewHelper(CanvasGridView *parent); + + CanvasGridView *parent() const; + + virtual quint64 windowId() const override; + virtual const DAbstractFileInfoPointer fileInfo(const QModelIndex &index) const override; + virtual DFMStyledItemDelegate *itemDelegate() const override; + virtual DFileSystemModel *model() const override; + virtual const DUrlList selectedUrls() const override; + virtual void select(const QList &list) override; + virtual void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override; + virtual int selectedIndexsCount() const override; + virtual bool isSelected(const QModelIndex &index) const override; + virtual void viewFlicker() override; + bool isPaintFile() const; + +public slots: + void edit(const DFMEvent &event); + void onRequestSelectFiles(const QList &urls); + void handleSelectEvent(const DFMUrlListBaseEvent &event); +private: + bool m_paintFile = true; +}; diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/canvasviewmanager.cpp b/dde-file-manager-5.5.3/src/dde-desktop/view/canvasviewmanager.cpp new file mode 100644 index 0000000..ba01f7a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/canvasviewmanager.cpp @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#include "canvasviewmanager.h" +#include "screen/screenhelper.h" +#include "presenter/gridmanager.h" +#include "desktopitemdelegate.h" +#include "dfilesystemmodel.h" +#include "util/util.h" +#include "util/dde/desktopinfo.h" + +#include + +static const char * const PROPERTY_VIEW_INITED = "view_inited"; +inline QRect relativeRect(const QRect &avRect,const QRect &geometry) +{ + QPoint relativePos = avRect.topLeft() - geometry.topLeft(); + + return QRect(relativePos,avRect.size()); +} + +inline void initView(CanvasViewPointer view){ + if (view && !view->property(PROPERTY_VIEW_INITED).toBool()){ + view->setProperty(PROPERTY_VIEW_INITED,true); + view->initRootUrl(); + } +} + +CanvasViewManager::CanvasViewManager(BackgroundManager *bmrg, QObject *parent) + : QObject(parent) + , m_background(bmrg) +{ + init(); +} + +CanvasViewManager::~CanvasViewManager() +{ + m_background = nullptr; + m_canvasMap.clear(); +} + +void CanvasViewManager::onCanvasViewBuild(int imode) +{ + //在画布创建时做保护先判断背景,无背景信息,清空画布 + if (m_background->allbackgroundWidgets().isEmpty() && m_background->isEnabled()){ + m_canvasMap.clear(); + qWarning() << "not get background.....,current mode: "<< imode; + return; + } + + //屏幕模式判断 + AbstractScreenManager::DisplayMode mode = static_cast(imode); + + GridManager::instance()->restCoord(); + //实际是单屏 + if ((AbstractScreenManager::Showonly == mode) || (AbstractScreenManager::Duplicate == mode) //仅显示和复制 + || (ScreenMrg->screens().count() == 1)){ + + ScreenPointer primary = ScreenMrg->primaryScreen(); + if (primary == nullptr) { + m_canvasMap.clear(); + qCritical() << "get primary screen failed return"; + return; + } + + CanvasViewPointer mView = m_canvasMap.value(primary); + + //删除其他 + m_canvasMap.clear(); + + if (mView.get() == nullptr){ + mView = CanvasViewPointer(new CanvasGridView(primary->name())); + mView->setScreenNum(1); + //设置未初始化 + mView->setProperty(PROPERTY_VIEW_INITED,false); + GridManager::instance()->addCoord(1, {0,0}); + } + else { + mView->setScreenNum(1); + mView->setScreenName(primary->name()); + mView->clearSelection(); + /*! + * 在DIconItemDelegate::paint中,通过setEditorData将expandedItem和index产生关联, + * 只执行clearSelection无法清除QAbstractItemView的数据editorIndexHash,导致执行 + * updateEditorGeometries时,将不存在的expandedItem显示到错误的地方 + */ + mView->itemDelegate()->hideNotEditingIndexWidget(); + GridManager::instance()->addCoord(1, {0,0}); + } + + GridManager::instance()->setDisplayMode(true); + m_canvasMap.insert(primary, mView); + + qDebug() << "mode" << mode << "inited" << mView->property(PROPERTY_VIEW_INITED).toBool() + << primary << primary->name() << "num" << 1 + << "devicePixelRatio" << ScreenMrg->devicePixelRatio(); + } + else { + auto currentScreens = ScreenMrg->logicScreens(); + int screenNum = 0; + //检查新增的屏幕 + for (const ScreenPointer &sp : currentScreens){ + ++screenNum; + CanvasViewPointer mView = m_canvasMap.value(sp); + + //新增 + if (mView.get() == nullptr){ + mView = CanvasViewPointer(new CanvasGridView(sp->name())); + mView->setScreenNum(screenNum); + //设置未初始化 + mView->setProperty(PROPERTY_VIEW_INITED,false); + GridManager::instance()->addCoord(screenNum, {0,0}); + m_canvasMap.insert(sp, mView); + } + else { + GridManager::instance()->addCoord(screenNum, {0,0}); + mView->setScreenNum(screenNum); + mView->setScreenName(sp->name()); + mView->clearSelection(); + mView->itemDelegate()->hideNotEditingIndexWidget(); + } + + qDebug() << "mode" << mode << "inited" << mView->property(PROPERTY_VIEW_INITED).toBool() + << sp << sp->name() << "num" << screenNum << mView->screenName() + << "devicePixelRatio" << ScreenMrg->devicePixelRatio(); + } + + //检查移除的屏幕 + for (const ScreenPointer &sp : m_canvasMap.keys()){ + if (!currentScreens.contains(sp)){ + auto rmd = m_canvasMap.take(sp); + qDebug() << "mode" << mode << "removed" << rmd->screenName(); + } + } + GridManager::instance()->setDisplayMode(false); + } + + onBackgroundEnableChanged(); +} + +void CanvasViewManager::onBackgroundEnableChanged() +{ + if (m_background->isEnabled()) { + for (const ScreenPointer &sp : m_canvasMap.keys()){ + CanvasViewPointer mView = m_canvasMap.value(sp); + BackgroundWidgetPointer bw = m_background->backgroundWidget(sp); + //fix bug52928 主屏数据不同步导致桌面崩溃(插上扩展屏后模式切换为复制模式,背景管理类中获取主屏为VGA,画布管理类中再次获取变成了HDMI) + if (bw == nullptr) { + auto datas = m_background->allbackgroundWidgets(); + for (auto bsp : datas.keys()) { + qWarning() << "BackgroundManager give screen:" << bsp->name(); + } + qWarning() << "CanvasViewManager give screen:" << sp->name(); + m_canvasMap.clear(); + qCritical() << "ERROR!! The screen data obtained by CanvasViewManager is inconsistent with that obtained by BackGroundManager."; + return; + } + + QRect avRect; + QRect screenAvaRect = sp->availableGeometry(); +#ifndef UNUSED_SMARTDOCK + avRect = relativeRect(screenAvaRect,sp->geometry()); +#else + if (sp == ScreenMrg->primaryScreen()){ + avRect = relativeRect(sp->availableGeometry(),sp->geometry()); + } + else { + avRect = relativeRect(sp->geometry(),sp->geometry()); + } +#endif + // fix bug105508 获取到屏幕数据为空导致卡死。创建时屏幕数据错误,则直接放弃创建。 + if (avRect.size().width() < 1 || avRect.size().height() < 1) { + m_canvasMap.clear(); + qCritical() << "ERROR!! The screen data obtained by CanvasViewManager is invalid." + << "Screen name:" << sp->name() << " geometry:" << sp->geometry(); + for(auto w : m_background->allbackgroundWidgets().values()) { + // 清空已经设置过的view + w->setView(nullptr); + } + + return; + } + + mView->setAttribute(Qt::WA_NativeWindow, false); + bw->setView(mView); + + mView->setGeometry(avRect); + mView->show(); + + initView(mView); + qDebug() << "canvas" << mView << "availableGeometry" << avRect + << "inited" << mView->property(PROPERTY_VIEW_INITED).toBool() + << "screen" << sp->name() << sp->geometry() << screenAvaRect; + } + } + else { + for (const ScreenPointer &sp : m_canvasMap.keys()){ + + QRect avRect; +#ifndef UNUSED_SMARTDOCK + avRect = sp->availableGeometry(); +#else + avRect = sp == ScreenMrg->primaryScreen() ? sp->availableGeometry() : sp->geometry(); +#endif + // fix bug105508 获取到屏幕数据为空导致卡死。创建时屏幕数据错误,则直接放弃创建。 + if (avRect.size().width() < 1 || avRect.size().height() < 1) { + m_canvasMap.clear(); + qCritical() << "ERROR!! The screen data obtained by CanvasViewManager is invalid." + << "Screen name:" << sp->name() << " geometry:" << sp->geometry() << sp->availableGeometry(); + return; + } + + CanvasViewPointer mView = m_canvasMap.value(sp); + mView->setParent(nullptr); + mView->setWindowFlag(Qt::FramelessWindowHint, true); + + DesktopUtil::set_desktop_window(mView.data()); + mView->setGeometry(avRect); + mView->show(); + initView(mView); + qDebug() << "no background. primaryScreen" << ScreenMrg->primaryScreen()->name() + << "canvas geo" << mView->geometry() << "inited" << mView->property(PROPERTY_VIEW_INITED).toBool() + << "canvas's screen"<< sp->name() << sp->geometry() << "availableGeometry" << avRect; + } + } + GridManager::instance()->initGridItemsInfos(); +} + +void CanvasViewManager::onScreenGeometryChanged() +{ +#ifdef UNUSED_SMARTDOCK + CanvasViewPointer mView = m_canvasMap.value(sp); + if (mView.get() != nullptr){ + QRect avRect; + if (m_background->isEnabled()) { + if (sp == ScreenMrg->primaryScreen()){ + avRect = relativeRect(sp->availableGeometry(), sp->geometry()); + } + else { + avRect = relativeRect(sp->geometry(), sp->geometry()); + } + } + else { + avRect = sp == ScreenMrg->primaryScreen() ? sp->availableGeometry() : sp->geometry(); + } + + qDebug() << "primary Screen" << ScreenMrg->primaryScreen()->name() + << "view geometry change from" << mView->geometry() << "to" << avRect + << "view screen" << sp->name() << sp->geometry() << sp->availableGeometry(); + //fix bug32166 bug32205 + if (mView->geometry() == avRect) { + qDebug() << "view geometry is equal to rect,and discard changes"; + return; + } + mView->setGeometry(avRect); + } +#else + for (const ScreenPointer &sp : m_canvasMap.keys()) { + CanvasViewPointer mView = m_canvasMap.value(sp); + if (mView == nullptr) + continue; + + QRect avRect; + if (m_background->isEnabled()) { + avRect = relativeRect(sp->availableGeometry(), sp->geometry()); + } + else { + avRect = sp->availableGeometry(); + } + + //fix bug32166 bug32205 + if (mView->geometry() == avRect) { + qDebug() << "view geometry is equal to rect,and discard changes" << avRect; + continue; + } + + qDebug() << "view geometry change from" << mView->geometry() << "to" << avRect + << "view screen" << sp->name() << sp->geometry() << sp->availableGeometry(); + mView->setGeometry(avRect); + } +#endif +} + +void CanvasViewManager::onSyncOperation(int so,QVariant var) +{ + GridManager::SyncOperation type = static_cast(so); + qDebug() << "sync type" << type << "data" << var; + + switch (type) { + case GridManager::soAutoMerge:{ + bool enable = var.toBool(); + for (CanvasViewPointer view : m_canvasMap.values()){ + view->setAutoMerge(enable); + } + + if (!enable) + GridManager::instance()->initGridItemsInfos(); + break; + } + case GridManager::soRename:{ //处理自动排列时右键新建文件,编辑框显示问题 + QString file = var.toString(); + arrageEditDeal(file); + break; + } + case GridManager::soIconSize:{ //处理图标大小 + int level = var.toInt(); + for (CanvasViewPointer view : m_canvasMap.values()){ + view->syncIconLevel(level); + /*! + * #bug102678:在DIconItemDelegate::paint中,通过setEditorData将expandedItem和index产生关联, + * 只执行clearSelection无法清除QAbstractItemView的数据editorIndexHash,导致执行 + * updateEditorGeometries时,将不存在的expandedItem显示到错误的地方 + */ + view->itemDelegate()->hideNotEditingIndexWidget(); + } + break; + } + case GridManager::soSort:{ + QPoint sort = var.toPoint(); + for (CanvasViewPointer view : m_canvasMap.values()){ + view->model()->setSortRole(sort.x(),static_cast(sort.y())); + view->update(); + } + break; + } + case GridManager::soHideEditing:{ //隐藏文件移动后留下编辑框 + for (CanvasViewPointer view : m_canvasMap.values()){ + view->itemDelegate()->hideNotEditingIndexWidget(); + view->update(); + } + break; + } + case GridManager::soUpdate:{ + for (CanvasViewPointer view : m_canvasMap.values()){ + view->update(); + } + break; + } + case GridManager::soAutoMergeUpdate:{ + qDebug() << "update when canvas folder expand changed"; + auto mergeMap = var.value>(); + if(mergeMap.isEmpty()) + return; + auto one = mergeMap.begin(); + + for (CanvasViewPointer view : m_canvasMap.values()){ + if(one.key() == view->canvansScreenName()) + continue; + view->updateEntryExpandedState(one.value()); + } + break; + } + case GridManager::soHidenSwitch:{ + for (CanvasViewPointer view : m_canvasMap.values()){ + view->updateHiddenItems(); + } + break; + } + case GridManager::soGsettingUpdate:{ + for (CanvasViewPointer view : m_canvasMap.values()){ + view->delayModelRefresh(); + } + break; + } + case GridManager::soExpandItemUpdate: { + for (CanvasViewPointer view : m_canvasMap.values()) { + view->updateExpandItemGeometry(); + } + break; + } + //default处会报警告:"warning: default label in switch which covers all enumeration values" + //这里是全量case,因此为解决警告删除default + } +} + +void CanvasViewManager::onSyncSelection(CanvasGridView *v, DUrlList selected) +{ + disconnect(GridManager::instance(), &GridManager::sigSyncSelection, + this,&CanvasViewManager::onSyncSelection); + //qDebug() << "sync selection " << v->canvansScreenName() << selected.size(); + for (CanvasViewPointer view : m_canvasMap.values()) { + if (view == v) + continue; + view->select(selected); + view->update(); + } + connect(GridManager::instance(), &GridManager::sigSyncSelection, + this,&CanvasViewManager::onSyncSelection,Qt::DirectConnection); +} + +void CanvasViewManager::arrageEditDeal(const QString &file) +{ + QPair orgPos; + //找文件在哪个屏上 + if (GridManager::instance()->find(file,orgPos)){ + for (CanvasViewPointer view : m_canvasMap.values()) { + //绘制屏上,打开编辑框 + if (view->screenNum() == orgPos.first){ + //已有editor,跳过 + if (view->itemDelegate()->editingIndexWidget()){ + qDebug() << "has editor" << view->itemDelegate()->editingIndex(); + continue; + } + + //激活编辑框 + DUrl fileUrl(file); + auto index = view->model()->index(fileUrl); + view->select(QList() << fileUrl); + bool bEdit = view->edit(index,QAbstractItemView::EditKeyPressed,nullptr); + Q_UNUSED(bEdit) + QWidget *editor = view->itemDelegate()->editingIndexWidget(); + if (editor) + editor->activateWindow(); + } + } + } +} + +void CanvasViewManager::init() +{ + //屏幕增删,模式改变 + connect(m_background,&BackgroundManager::sigBackgroundBuilded + , this,&CanvasViewManager::onCanvasViewBuild); + + //屏幕大小改变 + connect(ScreenHelper::screenManager(), &AbstractScreenManager::sigScreenGeometryChanged, + this, &CanvasViewManager::onScreenGeometryChanged); + + //可用区改变 + connect(ScreenHelper::screenManager(), &AbstractScreenManager::sigScreenAvailableGeometryChanged, + this, &CanvasViewManager::onScreenGeometryChanged); + + //grid改变 + connect(GridManager::instance(), &GridManager::sigSyncOperation, + this, &CanvasViewManager::onSyncOperation,Qt::QueuedConnection); + + //同步选中状态 + connect(GridManager::instance(), &GridManager::sigSyncSelection, + this,&CanvasViewManager::onSyncSelection,Qt::DirectConnection); + + onCanvasViewBuild(ScreenMrg->lastChangedMode()); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/canvasviewmanager.h b/dde-file-manager-5.5.3/src/dde-desktop/view/canvasviewmanager.h new file mode 100644 index 0000000..28d121a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/canvasviewmanager.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * + * 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 + * 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 . + */ + +#ifndef CANVASVIEWMANAGER_H +#define CANVASVIEWMANAGER_H + +#include "backgroundmanager.h" +#include "canvasgridview.h" +#include + +typedef QSharedPointer CanvasViewPointer; + +class CanvasViewManager : public QObject +{ + Q_OBJECT +public: + explicit CanvasViewManager(BackgroundManager *bmrg,QObject *parent = nullptr); + ~CanvasViewManager(); + inline QMap canvas() const{return m_canvasMap;} +signals: +public slots: + void onCanvasViewBuild(int mode); +private slots: + void onBackgroundEnableChanged(); + void onScreenGeometryChanged(); + void onSyncOperation(int so, QVariant var); + void onSyncSelection(CanvasGridView *v, DUrlList selected); +private: + void init(); + void arrageEditDeal(const QString &); +private: + BackgroundManager *m_background = nullptr; + QMap m_canvasMap; +}; + +#endif // CANVASVIEWMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/desktopitemdelegate.cpp b/dde-file-manager-5.5.3/src/dde-desktop/view/desktopitemdelegate.cpp new file mode 100644 index 0000000..b0804ee --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/desktopitemdelegate.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: wangchunlin + * + * Maintainer: wangchunlin + * + * 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 + * 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 . + */ + +#include "desktopitemdelegate.h" + +#include +#include + +#include "private/dstyleditemdelegate_p.h" +#include "canvasgridview.h" +#include "canvasviewhelper.h" + +#include + +DesktopItemDelegate::DesktopItemDelegate(DFileViewHelper *parent) : + DIconItemDelegate(parent) +{ + iconSizes << 32 << 48 << 64 << 96 << 128; + iconSizeDescriptions << tr("Tiny") + << tr("Small") + << tr("Medium") + << tr("Large") + << tr("Super large"); +} + +DesktopItemDelegate::~DesktopItemDelegate() +{ + +} + +QWidget *DesktopItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &opt, const QModelIndex &index) const +{ + auto widget = DIconItemDelegate::createEditor(parent, opt, index); + FileIconItem *item = static_cast(widget); + connect(item, &FileIconItem::inputFocusOut, this, &DesktopItemDelegate::commitDataAndCloseActiveEditor); + auto helper = qobject_cast(this->parent()); + auto itemSize = sizeHint(QStyleOptionViewItem(), QModelIndex()); + auto cellSize = helper->parent()->cellSize(); + int offset = -1 * ((cellSize.width() - itemSize.width()) % 2); + widget->setContentsMargins(offset, helper->parent()->cellMargins().top(), 0, 0); + return widget; +} + +QString DesktopItemDelegate::iconSizeLevelDescription(int i) const +{ + return iconSizeDescriptions.at(i); +} + +int DesktopItemDelegate::iconSizeLevel() const +{ + return currentIconSizeIndex; +} + +int DesktopItemDelegate::minimumIconSizeLevel() const +{ + return 0; +} + +int DesktopItemDelegate::maximumIconSizeLevel() const +{ + return iconSizes.count() - 1; +} + +int DesktopItemDelegate::increaseIcon() +{ + return setIconSizeByIconSizeLevel(currentIconSizeIndex + 1); + +} + +int DesktopItemDelegate::decreaseIcon() +{ + return setIconSizeByIconSizeLevel(currentIconSizeIndex - 1); +} + +int DesktopItemDelegate::setIconSizeByIconSizeLevel(int level) +{ + if (level == currentIconSizeIndex) { + return level; + } + + if (level >= minimumIconSizeLevel() && level <= maximumIconSizeLevel()) { + currentIconSizeIndex = level; + + parent()->parent()->setIconSize(iconSizeByIconSizeLevel()); + + return currentIconSizeIndex; + } + + return -1; +} + +QSize DesktopItemDelegate::iconSizeByIconSizeLevel() const +{ + int size = iconSizes.at(currentIconSizeIndex); + return QSize(size, size); +} + +void DesktopItemDelegate::updateItemSizeHint() +{ + DIconItemDelegate::updateItemSizeHint(); + int width = parent()->parent()->iconSize().width() * 17 / 10; + int height = parent()->parent()->iconSize().height() + + 10 + 2 * d_ptr->textLineHeight; + + d_ptr->itemSizeHint = QSize(width, height); +} + +void DesktopItemDelegate::hideAllIIndexWidget() +{ + //父类的hideAllIIndexWidget不会立即隐藏editor,这里做特殊处理 + auto editor = editingIndexWidget(); + DIconItemDelegate::hideAllIIndexWidget(); + + if (editor) + editor->hide(); +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/desktopitemdelegate.h b/dde-file-manager-5.5.3/src/dde-desktop/view/desktopitemdelegate.h new file mode 100644 index 0000000..b3499fe --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/desktopitemdelegate.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#pragma once + +#include + +class DesktopItemDelegate : public DIconItemDelegate +{ + Q_OBJECT +public: + explicit DesktopItemDelegate(DFileViewHelper *parent); + virtual ~DesktopItemDelegate() override; + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const override; + QString iconSizeLevelDescription(int i) const; + int iconSizeLevel() const override; + int minimumIconSizeLevel() const override; + int maximumIconSizeLevel() const override; + + int increaseIcon() override; + int decreaseIcon() override; + int setIconSizeByIconSizeLevel(int level) override; + QSize iconSizeByIconSizeLevel() const; + + void updateItemSizeHint() override; + void hideAllIIndexWidget() override; +private: + QStringList iconSizeDescriptions; + QList iconSizes; + // default icon size is 48px. + int currentIconSizeIndex = -1; +}; + diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/private/canvasviewprivate.h b/dde-file-manager-5.5.3/src/dde-desktop/view/private/canvasviewprivate.h new file mode 100644 index 0000000..3a851e2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/private/canvasviewprivate.h @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * wangchunlin + * liqiang + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../global/coorinate.h" +#include "../../dbus/dbusdock.h" +#include "../canvasgridview.h" + +class QFrame; +class CanvasViewHelper; +class WaterMaskFrame; +class GridCore; +class DAbstractFileWatcher; + +class CanvasViewPrivate +{ +private: + inline void updateCellMargins(const QSize &szItem, const QSize &szCell) + { + auto horizontalMargin = (szCell.width() - szItem.width()); + auto verticalMargin = (szCell.height() - szItem.height()); + auto leftMargin = horizontalMargin / 2; + auto rightMargin = horizontalMargin - leftMargin; + auto topMargin = verticalMargin / 2; + auto bottom = verticalMargin - topMargin; + + cellMargins = QMargins(leftMargin, topMargin, rightMargin, bottom); + } + +public: + CanvasViewPrivate() + { + mousePressed = false; + bReloadItem = false; + dodgeDelayTimer.setInterval(200); + + touchTimer.setTimerType(Qt::PreciseTimer); + QObject::connect(&touchTimer, &QTimer::timeout, &touchTimer, &QTimer::stop); + + if (qgetenv("_DDE_DESKTOP_DEBUG_SHOW_GRID") == "TRUE") { + _debug_log = true; + _debug_show_grid = true; + } + + if (qgetenv("_DDE_DESKTOP_DEBUG_PROFILER") == "TRUE") { + _debug_profiler = true; + } + } + + void updateCanvasSize(const QSize &szSceeen, const QSize &szCanvas, const QMargins &geometryMargins, const QSize &szItem) + { + qInfo() << "screen size" << szSceeen << "canvas" << szCanvas << "item size" << szItem; + QMargins miniMargin = QMargins(2, 2, 2, 2); + auto miniCellWidth = szItem.width() + miniMargin.left() + miniMargin.right(); + colCount = (szSceeen.width() - dockReserveArea.width()) / miniCellWidth; + + if (colCount < 1) { + qCritical() << "!!!!! colCount is 0!!! set it 1 and set cellWidth to " << szCanvas.width(); + cellWidth = szCanvas.width(); + colCount = 1; + } else { + cellWidth = szCanvas.width() / colCount; + } + if (cellWidth < 1) + cellWidth = 1; + + auto miniCellHeigh = szItem.height() + miniMargin.top() + miniMargin.bottom(); + rowCount = (szSceeen.height() - dockReserveArea.height()) / miniCellHeigh; + if (rowCount < 1) { + qCritical() << "!!!!! rowCount is 0!!! set it and set cellHeight to" << szCanvas.height(); + cellHeight = szCanvas.height(); + rowCount = 1; + } else { + cellHeight = szCanvas.height() / rowCount; + } + + if (cellHeight < 1) + cellHeight = 1; + + updateCellMargins(szItem, QSize(cellWidth, cellHeight)); + + auto horizontalMargin = (szCanvas.width() - cellWidth * colCount); + auto verticalMargin = (szCanvas.height() - cellHeight * rowCount); + auto leftMargin = horizontalMargin / 2; + auto rightMargin = horizontalMargin - leftMargin; + auto topMargin = verticalMargin / 2; + auto bottom = verticalMargin - topMargin; + viewMargins = geometryMargins + QMargins(leftMargin, topMargin, rightMargin, bottom); + } + + Coordinate indexCoordinate(int index) + { + return Coordinate(index / rowCount, index % rowCount); + } + + int coordinateIndex(Coordinate coord) + { + return coord.position().x() * rowCount + coord.position().y(); + } + + bool isVaildCoordinate(Coordinate coord) + { + return (coord.position().x() >= 0 && coord.position().x() < colCount) + && (coord.position().y() >= 0 && coord.position().y() < rowCount); + } + +// static QPair *lastMenuPos() +// { +// static QPair pos = qMakePair(0,QPoint(0,0)); +// return &pos; +// } + +public: + QRect dockReserveArea = QRect(0, 0, 80, 80); + QMargins viewMargins; + QMargins cellMargins = QMargins(2, 2, 2, 2); + + bool hideItems = false; + + int rowCount = 0; + int colCount = 0; + int cellWidth = 0; + int cellHeight = 0; + + QTimer dodgeDelayTimer; + QStringList dodgeItems; + bool dodgeAnimationing = false; + double dodgeDuration = 0; + GridCore *dodgeTargetGrid = nullptr; + bool startDodge = false; + QPoint dragTargetGrid = QPoint(-1, -1); + + // currentCursorIndex is not the mouse, it's the position move by keybord + QModelIndex currentCursorIndex; + //当前鼠标按下的index,currentCursorIndex是键盘移动选中的index + //currentCursorIndex在使用上已经被多次误用了,所以这里使用新的变量,区分减小影响 + QModelIndex m_currentMousePressIndex; + + //记录首次光标首次所在位置索引 + QModelIndex m_oldCursorIndex; + + QPoint lastMenuPos; + QString lastMenuNewFilepath; + + QPoint lastPos; + QPoint beginPos{QPoint(-1, -1)}; + + QItemSelection beforeMoveSelection; + bool showSelectRect = false; + QRect selectRect = QRect(-1, -1, 1, 1); + + bool mousePressed; + + QRect canvasRect; + CanvasViewHelper *fileViewHelper = nullptr; + + bool bReloadItem; + + // secice system up +// QTimer *syncTimer = nullptr; +// qint64 lastRepaintTime = 0; + DAbstractFileWatcher *filesystemWatcher = nullptr; + WaterMaskFrame *waterMaskFrame = nullptr; + + //DBusDock *dbusDock = nullptr; + QEventLoop *menuLoop = nullptr; + + // debug + bool _debug_log = false; + bool _debug_show_grid = false; + bool _debug_profiler = false; + + // 用于实现触屏拖拽手指在屏幕上按下短时间200ms后响应 + QTimer touchTimer; +}; diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/watermaskframe.cpp b/dde-file-manager-5.5.3/src/dde-desktop/view/watermaskframe.cpp new file mode 100644 index 0000000..a4d6683 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/watermaskframe.cpp @@ -0,0 +1,409 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: liqiang + * + * Maintainer: liqiang + * wangchunlin + * + * 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 + * 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 . + */ + +#include "watermaskframe.h" +#include "../config/config.h" +#include "presenter/deepinlicensehelper.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "accessibility/ac-desktop-define.h" + +DCORE_USE_NAMESPACE + +WaterMaskFrame::WaterMaskFrame(const QString &fileName, QWidget *parent) : + QFrame(parent), + m_configFile(fileName) +{ + AC_SET_OBJECT_NAME( this, AC_WATER_MASK_FRAME); + AC_SET_ACCESSIBLE_NAME( this, AC_WATER_MASK_FRAME); + setAttribute(Qt::WA_TransparentForMouseEvents, true); + + DeepinLicenseHelper::instance()->init(); + // 授权状态改变 + connect(DeepinLicenseHelper::instance(), &DeepinLicenseHelper::licenseStateChanged, + this, &WaterMaskFrame::updateAuthorizationState); + + // 获取到当前授权状态 + connect(DeepinLicenseHelper::instance(), &DeepinLicenseHelper::postLicenseState, + this, &WaterMaskFrame::onChangeAuthorizationLabel); + + //todo + m_logoLabel = new QLabel(this); + m_textLabel = new QLabel(this); + + AC_SET_OBJECT_NAME( m_logoLabel, AC_WATER_MASK_LOGO_LABEL); + AC_SET_ACCESSIBLE_NAME( m_logoLabel, AC_WATER_MASK_LOGO_LABEL); + AC_SET_OBJECT_NAME( m_textLabel, AC_WATER_MASK_TEXT); + AC_SET_ACCESSIBLE_NAME( m_textLabel, AC_WATER_MASK_TEXT); + + bool isConfigFileExist = checkConfigFile(m_configFile); + if (isConfigFileExist) { + loadConfig(m_configFile); + } else { + hide(); + } +} + +WaterMaskFrame::~WaterMaskFrame() +{ + if(m_logoLabel){ + m_logoLabel->deleteLater(); + m_logoLabel = nullptr; + } + + if(m_textLabel){ + m_textLabel->deleteLater(); + m_textLabel = nullptr; + } + + if (m_mainLayout) { + m_mainLayout->deleteLater(); + m_mainLayout = nullptr; + } +} + +bool WaterMaskFrame::checkConfigFile(const QString &fileName) +{ + if (QFile(fileName).exists()) { + return true; + } else { + return false; + } +} + +void WaterMaskFrame::loadConfig(const QString &fileName) +{ + QFile file(fileName); + if (!file.open(QFile::ReadOnly)) { + qWarning() << "WaterMask config file doesn't exist!"; + } + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error); + if (error.error == QJsonParseError::NoError) { + m_configs = QJsonObject::fromVariantMap(doc.toVariant().toMap()); + initUI(); + } else { + qCritical() << error.errorString(); + } + +} + +void WaterMaskFrame::initUI() +{ + if (m_configs.contains("isMaskAlwaysOn")) { + m_isMaskAlwaysOn = m_configs.value("isMaskAlwaysOn").toBool(); + } + + bool useJosn = Config::instance()->getConfig(Config::groupGeneral,Config::keyWaterMask, true).toBool(); + QString maskLogoUri; + if(useJosn){ + if (m_configs.contains("maskLogoUri")) { + maskLogoUri = m_configs.value("maskLogoUri").toString(); + } else { + maskLogoUri.clear(); + } + } + else { + maskLogoUri = DSysInfo::distributionOrgLogo(DSysInfo::OrgType::Distribution, DSysInfo::LogoType::Transparent); + } + + if (maskLogoUri.startsWith("~/")) { + maskLogoUri.replace(0, 1, QDir::homePath()); + } + +// QString maskLogoLayoutAlign; +// if (m_configs.contains("maskLogoLayoutAlign")) { +// maskLogoLayoutAlign = m_configs.value("maskLogoLayoutAlign").toString(); +// } else { +// maskLogoLayoutAlign = "left"; +// } + + int maskLogoWidth; + if (m_configs.contains("maskLogoWidth")) { + maskLogoWidth = m_configs.value("maskLogoWidth").toInt(); + } else { + maskLogoWidth = 128; + } + + int maskLogoHeight; + if (m_configs.contains("maskLogoHeight")) { + maskLogoHeight = m_configs.value("maskLogoHeight").toInt(); + } else { + maskLogoHeight = 48; + } + +// QString maskText; +// if (m_configs.contains("maskText")) { +// maskText = m_configs.value("maskText").toString(); +// } else { +// maskText = ""; +// } + +// QString maskTextLayoutAlign; +// if (m_configs.contains("maskTextLayoutAlign")) { +// maskTextLayoutAlign = m_configs.value("maskTextLayoutAlign").toString(); +// } else { +// maskTextLayoutAlign = "right"; +// } + +// QString maskTextColor; +// if (m_configs.contains("maskTextColor")) { +// maskTextColor = m_configs.value("maskTextColor").toString(); +// } else { +// maskTextColor = "rgba(245,245,245,245.130)"; +// } + +// QString maskTextFontSize; +// if (m_configs.contains("maskTextFontSize")) { +// maskTextFontSize = m_configs.value("maskTextFontSize").toString(); +// } else { +// maskTextFontSize = "12px"; +// } + + +// int maskTextWidth; +// if (m_configs.contains("maskTextWidth")) { +// maskTextWidth = m_configs.value("maskTextWidth").toInt(); +// } else { +// maskTextWidth = 100; +// } + +// int maskTextHeight; +// if (m_configs.contains("maskTextHeight")) { +// maskTextHeight = m_configs.value("maskTextHeight").toInt(); +// } else { +// maskTextHeight = 30; +// } + +// QString maskTextAlign; +// if (m_configs.contains("maskTextAlign")) { +// maskTextAlign = m_configs.value("maskTextAlign").toString(); +// } else { +// maskTextAlign = "left"; +// } + + int maskLogoTextSpacing; + if (m_configs.contains("maskLogoTextSpacing")) { + maskLogoTextSpacing = m_configs.value("maskLogoTextSpacing").toInt(); + } else { + maskLogoTextSpacing = 0; + } + +// if (m_configs.contains("maskWidth")) { +// m_maskWidth = m_configs.value("maskWidth").toInt(); +// } else { +// m_maskWidth = 228; +// } + + if (m_configs.contains("maskHeight")) { + m_maskHeight = m_configs.value("maskHeight").toInt(); + } else { + m_maskHeight = 48; + } + + if (m_configs.contains("xRightBottom")) { + m_xRightBottom = m_configs.value("xRightBottom").toInt(); + } else { + m_xRightBottom = 50; + } + + if (m_configs.contains("yRightBottom")) { + m_yRightBottom = m_configs.value("yRightBottom").toInt(); + } else { + m_yRightBottom = 98; + } + + QString maskLogoLayoutAlign = "left"; + QString maskTextLayoutAlign = "right"; + QString maskTextColor = "rgba(245,245,245,245.120)"; + QString maskTextFontSize = "12px"; + int maskTextWidth = 100; + int maskTextHeight = 30; + QString maskTextAlign = "left"; + m_maskWidth = maskLogoWidth + maskTextWidth; + + { + QImageReader mask_image_reader(maskLogoUri); + const QSize &mask_size = QSize(maskLogoWidth, maskLogoHeight) * m_logoLabel->devicePixelRatioF(); + const QSize &mask_image_size = mask_image_reader.size(); + + if (maskLogoUri.endsWith(".svg") || (mask_image_size.width() >= mask_size.width() + && mask_image_size.height() >= mask_size.height())) { + mask_image_reader.setScaledSize(mask_size); + } else { + mask_image_reader.setScaledSize(QSize(maskLogoWidth, maskLogoHeight)); + } + + QPixmap mask_pixmap = QPixmap::fromImage(mask_image_reader.read()); + mask_pixmap.setDevicePixelRatio(m_logoLabel->devicePixelRatioF()); + + m_logoLabel->setPixmap(mask_pixmap); + } + + if (isNeedState()) { + qInfo() << "delayGetState"; + DeepinLicenseHelper::instance()->delayGetState(); + qInfo() << "called delayGetState"; + } else { + m_textLabel->setText(""); + } + + m_textLabel->setFixedSize(maskTextWidth, maskTextHeight); + + if (maskTextAlign == "left") { + m_textLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); + } else if (maskTextAlign == "right") { + m_textLabel->setAlignment(Qt::AlignRight | Qt::AlignBottom); + } else if (maskTextAlign == "center") { + m_textLabel->setAlignment(Qt::AlignCenter); + } + + m_mainLayout = new QHBoxLayout(); + m_mainLayout->setSpacing(0); + m_mainLayout->addStretch(); + + if (maskLogoUri.length() != 0) { + if (maskLogoLayoutAlign == "left") { + m_mainLayout->addWidget(m_logoLabel, 0, Qt::AlignLeft | Qt::AlignVCenter); + } else if (maskLogoLayoutAlign == "right") { + m_mainLayout->addWidget(m_logoLabel, 0, Qt::AlignRight | Qt::AlignVCenter); + } else if (maskLogoLayoutAlign == "center") { + m_mainLayout->addWidget(m_logoLabel, 0, Qt::AlignCenter); + } + } + + m_mainLayout->addSpacing(maskLogoTextSpacing); + + if (isNeedState()) { + if (maskTextLayoutAlign == "left") { + m_mainLayout->addWidget(m_textLabel, 0, Qt::AlignLeft | Qt::AlignVCenter); + } else if (maskTextLayoutAlign == "right") { + m_mainLayout->addWidget(m_textLabel, 0, Qt::AlignRight | Qt::AlignVCenter); + } else if (maskTextLayoutAlign == "center") { + m_mainLayout->addWidget(m_textLabel, 0, Qt::AlignCenter); + } + } + m_mainLayout->addStretch(); + m_mainLayout->setContentsMargins(0, 0, 0, 0); + + /*initUI会new一个QHBoxLayout,WaterMaskFrame构造时已经调用了一次, + * 后续多次同一对象调用initUI会导致泄露,由于updateAuthorizationState会间接调用到initUI, + * 因此需要删掉之前的布局之后再调用*/ + auto tempLayout = this->layout(); + if (tempLayout) { + delete tempLayout; + tempLayout = nullptr; + } + setLayout(m_mainLayout); + setFixedSize(m_maskWidth, m_maskHeight); + QString color(maskTextColor); + QString fontsize(maskTextFontSize); + QString style = QString("QLabel {color: %1; font-size: %2}").arg(color, fontsize); + setStyleSheet(style); +} + +bool WaterMaskFrame::isNeedState() +{ + DSysInfo::DeepinType deepinType = DSysInfo::deepinType(); + DSysInfo::UosEdition uosEdition = DSysInfo::uosEditionType(); + qInfo() << "deepinType" << deepinType << "uosEditionType" << uosEdition; + + bool ret = (DSysInfo::DeepinType::DeepinProfessional == deepinType + || DSysInfo::DeepinType::DeepinPersonal == deepinType + || DSysInfo::DeepinType::DeepinServer == deepinType); + +#if (DTK_VERSION >= DTK_VERSION_CHECK(5, 4, 7, 0)) + // 教育版不需要水印 + ret = ret || DSysInfo::UosEdition::UosEducation == uosEdition; + qInfo() << "check uos Edition" << ret; +#endif + + return ret; +} + +bool WaterMaskFrame::parseJson(QString key) +{ + if(key.isNull() || key.isEmpty() || (!m_configs.contains(key))){ + qWarning() << key <<"WaterMask load Config fail"; + return false; + } + else { + m_configs = m_configs.value(key).toObject(); + return true; + } +} + +void WaterMaskFrame::updatePosition() +{ + int x = static_cast(parent())->width() - m_xRightBottom - m_maskWidth; + int y = static_cast(parent())->height() - m_yRightBottom - m_maskHeight; + move(x, y); +} + +void WaterMaskFrame::updateAuthorizationState() +{ + qInfo() << "received com.deepin.license.Info::LicenseStateChange."; + bool isConfigFileExist = checkConfigFile(m_configFile); + qInfo() << "isConfigFileExist:" << isConfigFileExist << " configFile:" << m_configFile; + if (isConfigFileExist) { + loadConfig(m_configFile); + } +} + +void WaterMaskFrame::onChangeAuthorizationLabel(int stateType) +{ + qInfo() << "reply ActiveState is" << stateType << this; + + switch (stateType) { + case Unauthorized: + case AuthorizedLapse: + case TrialExpired: { + m_textLabel->setText(tr("Not authorized")); + m_textLabel->setObjectName(tr("Not authorized")); + AC_SET_ACCESSIBLE_NAME(m_textLabel, AC_WATER_TEXT_LABEL_NO_AUTHORIZED); + } + break; + case Authorized: + //2020-07-06 需求变更,已授权不显示 + //m_textLabel->setText(tr("authorized")); + m_textLabel->setText(""); + break; + case TrialAuthorized:{ + m_textLabel->setText(tr("In trial period")); + m_textLabel->setObjectName(tr("In trial period")); + AC_SET_ACCESSIBLE_NAME(m_textLabel, AC_WATER_TEXT_LABEL_IN_TRIAL); + } + break; + default: + qWarning() << "unkown active state:" << stateType; + } +} diff --git a/dde-file-manager-5.5.3/src/dde-desktop/view/watermaskframe.h b/dde-file-manager-5.5.3/src/dde-desktop/view/watermaskframe.h new file mode 100644 index 0000000..bbf4e67 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-desktop/view/watermaskframe.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: liqiang + * + * Maintainer: liqiang + * wangchunlin + * + * + * 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 + * 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 . + */ + + +#ifndef WATERMASKFRAME_H +#define WATERMASKFRAME_H + +#include +#include +#include + +enum ActiveState { + Unauthorized = 0, //未授权 + Authorized, //已授权 + AuthorizedLapse, //授权失效 + TrialAuthorized, //试用期已授权 + TrialExpired //试用期已过期 +}; + +class QHBoxLayout; +class WaterMaskFrame : public QFrame +{ + Q_OBJECT +public: + explicit WaterMaskFrame(const QString& fileName, QWidget *parent = nullptr); + ~WaterMaskFrame(); + bool checkConfigFile(const QString& fileName); + void loadConfig(const QString& fileName); + void initUI(); + +private: + bool isNeedState(); + bool parseJson(QString key); + +public slots: + void updatePosition(); + void updateAuthorizationState(); +private slots: + void onChangeAuthorizationLabel(int); +private: + QString m_configFile; + QJsonObject m_configs; + QLabel* m_logoLabel = nullptr; + QLabel* m_textLabel = nullptr; + QHBoxLayout *m_mainLayout = nullptr; + bool m_isMaskAlwaysOn = false; + int m_xRightBottom; + int m_yRightBottom; + int m_maskWidth; + int m_maskHeight; +}; + +#endif // WATERMASKFRAME_H diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/dde-dock-plugins.pro b/dde-file-manager-5.5.3/src/dde-dock-plugins/dde-dock-plugins.pro new file mode 100644 index 0000000..46d76ae --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/dde-dock-plugins.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs + +SUBDIRS += disk-mount diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/com.deepin.dde.dock.module.disk-mount.gschema.xml b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/com.deepin.dde.dock.module.disk-mount.gschema.xml new file mode 100644 index 0000000..57fbb24 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/com.deepin.dde.dock.module.disk-mount.gschema.xml @@ -0,0 +1,49 @@ + + + + + + + + false + Blocking event + + Blocking mouse events + + + + true + Module Enable + + Control Module Enable + + + + + true + Able to integration with file manager app + + If enabled, it's able to integrate with file manager. + If disabled, will not try to open up file manager in any case. + + + + + true + Hide the item and do not allowed eject or unmount if mount point is not under /media + + If enabled, mounts which not mounted under /media will not allowed to eject or unmount. + + + + + true + Hide the item and do not allowed eject or unmount if the mount device provided root (/) mount point + + If enabled, mounts which on the same device as root (/) mount will not allowed to eject or unmount. + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattacheddeviceinterface.cpp b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattacheddeviceinterface.cpp new file mode 100644 index 0000000..4bec6fe --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattacheddeviceinterface.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "dattacheddeviceinterface.h" + +DAttachedDeviceInterface::~DAttachedDeviceInterface() +{ +} diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattacheddeviceinterface.h b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattacheddeviceinterface.h new file mode 100644 index 0000000..abd0a1e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattacheddeviceinterface.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DATTACHEDDEVICEINTERFACE_H +#define DATTACHEDDEVICEINTERFACE_H + +#include +#include +#include + +class DAttachedDeviceInterface +{ +public: + virtual bool isValid() = 0; // is device valid and useable + virtual bool detachable() = 0; // can be unmounted / removable or not. + virtual void detach() = 0; // do unmount, also do eject if possible. + virtual QString displayName() = 0; // device display name. + virtual bool deviceUsageValid() = 0; // storage valid / available or not. + virtual QPair deviceUsage() = 0; // used / total, in bytes. + virtual QString iconName() = 0; // device icon (theme) name. + virtual QUrl mountpointUrl() = 0; // path to the device mount point. + virtual QUrl accessPointUrl() = 0; // path to the open filemanger. + virtual ~DAttachedDeviceInterface() = 0; +}; + +#endif // DATTACHEDDEVICEINTERFACE_H diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattachedudisks2device.cpp b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattachedudisks2device.cpp new file mode 100644 index 0000000..d77e98d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattachedudisks2device.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "dattachedudisks2device.h" +#include "diskcontrolitem.h" +#include "diskcontrolwidget.h" +#include "interfaces/dumountmanager.h" + +#include +#include +#include +#include +#include + +DFM_USE_NAMESPACE + +ErrorHandleInfc::~ErrorHandleInfc() +{ +} + + +/*! + * \class DAttachedUdisks2Device + * + * \brief An attached (mounted) block device (partition) + */ + +DAttachedUdisks2Device::DAttachedUdisks2Device(const DBlockDevice *blockDevicePointer) +{ + QByteArrayList mountPoints = blockDevicePointer->mountPoints(); + mountPoint = mountPoints.isEmpty() ? "" : mountPoints.first(); + deviceDBusId = blockDevicePointer->path(); + c_blockDevice.reset(DDiskManager::createBlockDevice(deviceDBusId)); // not take the ownership of the passed pointer. +} + +bool DAttachedUdisks2Device::isValid() +{ + return !c_blockDevice.isNull(); +} + +bool DAttachedUdisks2Device::detachable() +{ + QScopedPointer diskDev(DDiskManager::createDiskDevice(blockDevice()->drive())); + return diskDev->removable(); +} + +void DAttachedUdisks2Device::detach() +{ + DBlockDevice *blkDevice = blockDevice(); + if (!blkDevice) { + qWarning() << "blockDevice() got null!"; + return; + } + const QString &path = blkDevice->path(); + QtConcurrent::run([path]() { + DUMountManager umountManager; + const QString &drive = umountManager.getDriveName(path); + if (!umountManager.ejectDrive(drive)) + DiskControlWidget::NotifyMsg(umountManager.getErrorMsg()); + }); +} + +QString DAttachedUdisks2Device::displayName() +{ + static QMap i18nMap { + {"data", "Data Disk"} + }; + + QStorageInfo storage_info(mountPoint); + QString result; + + if (blockDevice()->isValid()) { + QString devName = blockDevice()->idLabel(); + if (devName.isEmpty()) { + devName = qApp->translate("DeepinStorage", "%1 Volume").arg(DiskControlItem::formatDiskSize(blockDevice()->size())); + } + + // Deepin i10n Label text (_dde_text): + if (devName.startsWith(ddeI18nSym)) { + QString i18nKey = devName.mid(ddeI18nSym.size(), devName.size() - ddeI18nSym.size()); + devName = qApp->translate("DeepinStorage", i18nMap.value(i18nKey, i18nKey.toUtf8().constData())); + } + + result = devName; + } else if (storage_info.isValid()) { + qint64 bytesTotal = storage_info.bytesTotal(); + result = qApp->translate("DeepinStorage", "%1 Volume").arg(DiskControlItem::formatDiskSize(static_cast(bytesTotal))); + } + + return result; +} + +bool DAttachedUdisks2Device::deviceUsageValid() +{ + QStorageInfo storage_info(mountPoint); + return storage_info.isValid(); +} + +QPair DAttachedUdisks2Device::deviceUsage() +{ + QStorageInfo storage_info(mountPoint); + + if (storage_info.isValid()) { + quint64 bytesTotal = blockDevice()->size(); + qint64 bytesFree = storage_info.bytesAvailable(); + return QPair(static_cast(bytesFree), static_cast(bytesTotal)); + } + + return QPair(0, 0); +} + +QString DAttachedUdisks2Device::iconName() +{ + QScopedPointer diskDev(DDiskManager::createDiskDevice(blockDevice()->drive())); + + bool isDvd = diskDev->optical(); + bool isRemovable = diskDev->removable(); + QString iconName = QStringLiteral("drive-harddisk"); + + if (isRemovable) { + iconName = QStringLiteral("drive-removable-media-usb"); + } + + if (isDvd) { + iconName = QStringLiteral("media-optical"); + } + + return iconName; +} + +QUrl DAttachedUdisks2Device::mountpointUrl() +{ + return QUrl::fromLocalFile(mountPoint); +} + +QUrl DAttachedUdisks2Device::accessPointUrl() +{ + QUrl url = mountpointUrl(); + auto blk = blockDevice(); + if (blk) { + QScopedPointer drv(DDiskManager::createDiskDevice(blk->drive())); + if (drv && drv->optical()) { + url = DUrl::fromBurnFile(QString(blk->device()) + "/" + BURN_SEG_ONDISC + "/"); + } + } + return url; +} + +DBlockDevice *DAttachedUdisks2Device::blockDevice() +{ + return c_blockDevice.data(); +} diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattachedudisks2device.h b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattachedudisks2device.h new file mode 100644 index 0000000..7c42fe3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattachedudisks2device.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DATTACHEDUDISKS2DEVICE_H +#define DATTACHEDUDISKS2DEVICE_H + +#include "dattacheddeviceinterface.h" + +#include +class ErrorHandleInfc +{ +public: + virtual void onError(DAttachedDeviceInterface *device) = 0; + virtual ~ErrorHandleInfc() = 0; +}; + +class DBlockDevice; + +class DAttachedUdisks2Device : public DAttachedDeviceInterface +{ +public: + explicit DAttachedUdisks2Device(const DBlockDevice *blockDevicePointer); + virtual ~DAttachedUdisks2Device() override {} + bool isValid() override; + bool detachable() override; + void detach() override; + QString displayName() override; + bool deviceUsageValid() override; + QPair deviceUsage() override; + QString iconName() override; + QUrl mountpointUrl() override; + QUrl accessPointUrl() override; + + DBlockDevice *blockDevice(); + void setErrorHandler(ErrorHandleInfc *handle) + { + errhandle = handle; + } + +private: + QScopedPointer c_blockDevice; + QString deviceDBusId; + QString mountPoint; + ErrorHandleInfc *errhandle = nullptr; + + const QString ddeI18nSym = QStringLiteral("_dde_"); +}; + +#endif // DATTACHEDUDISKS2DEVICE_H diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattachedvfsdevice.cpp b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattachedvfsdevice.cpp new file mode 100644 index 0000000..2ad3c03 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattachedvfsdevice.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include +#include +#include +#include "diskcontrolwidget.h" + +#include "dattachedvfsdevice.h" +#include +#include + +namespace { +void unmount_done_cb(GObject *object, GAsyncResult *res, gpointer user_data) +{ + Q_UNUSED(user_data); + + gboolean succeeded; + GError *error = nullptr; + succeeded = g_mount_unmount_with_operation_finish (G_MOUNT (object), res, &error); + + if (!succeeded) { + qWarning()<<"can't umount the device for error code:" << error->code << ", error message:" << error->code; + DiskControlWidget::NotifyMsg(DiskControlWidget::tr("Cannot unmount the device"), DiskControlWidget::tr("") ); + } + g_object_unref (G_MOUNT (object)); +} + +void unmount_mounted(const QString &mount_path) +{ + if (mount_path.isEmpty()) + return; + + qInfo()<<"umount the device:" << mount_path ; + GFile *file = g_file_new_for_path(QFile::encodeName(mount_path)); + if (file == nullptr) + return; + + GError *error = nullptr; + GMount *mount = g_file_find_enclosing_mount (file, nullptr, &error); + if (mount == nullptr) { + bool no_permission = false; + + QFileInfo fileInfo(QUrl(mount_path).toLocalFile()); + + while (!fileInfo.exists() && fileInfo.fileName() != QDir::rootPath() && !fileInfo.absolutePath().isEmpty()) { + fileInfo.setFile(fileInfo.absolutePath()); + } + + if (fileInfo.exists()) { + if (getuid() == fileInfo.ownerId()) { + if (!fileInfo.permission(QFile::ReadOwner | QFile::ExeOwner)) + no_permission = true; + } else if (getgid() == fileInfo.groupId()) { + if (!fileInfo.permission(QFile::ReadGroup | QFile::ExeGroup)) + no_permission = true; + } else if (!fileInfo.permission(QFile::ReadOther | QFile::ExeOther)) { + no_permission = true; + } + } + + if (no_permission) { + QString user_name = fileInfo.owner(); + + if (fileInfo.absoluteFilePath().startsWith("/media/")) { + user_name = fileInfo.baseName(); + } + DiskControlWidget::NotifyMsg(DiskControlWidget::tr("The disk is mounted by user \"%1\", you cannot unmount it."), DiskControlWidget::tr("") ); + return; + } + + DiskControlWidget::NotifyMsg(DiskControlWidget::tr("Cannot find the mounted device"), DiskControlWidget::tr("") ); + return; + } + + GMountOperation *mount_op = g_mount_operation_new (); + GMountUnmountFlags flags = G_MOUNT_UNMOUNT_FORCE; + GAsyncReadyCallback callback = unmount_done_cb; + g_mount_unmount_with_operation(mount, flags, mount_op, nullptr, callback, nullptr); + g_object_unref (mount_op); + g_object_unref (file); +} +} + +/*! + * \class DAttachedVfsDevice + * + * \brief An attached (mounted) virtual filesystem device from gio + */ +DAttachedVfsDevice::DAttachedVfsDevice(const QString &mountpointPath) +{ + m_dgioMount.reset(DGioMount::createFromPath(mountpointPath)); + m_mountpointPath = mountpointPath; +} + +bool DAttachedVfsDevice::isValid() +{ + return !m_dgioMount.isNull(); +} + +bool DAttachedVfsDevice::detachable() +{ + return m_dgioMount->canUnmount(); +} + +void DAttachedVfsDevice::detach() +{ + //使用dgioMount->unmount()不能提供失败警告,需要替换为一个有状态返回的卸载方式。 BUG 51596 + //m_dgioMount->unmount(); + unmount_mounted(m_mountpointPath); +} + +QString DAttachedVfsDevice::displayName() +{ + return m_dgioMount ? m_dgioMount->name() : QStringLiteral("-"); +} + +bool DAttachedVfsDevice::deviceUsageValid() +{ + if (m_dgioMount.isNull()) + return false; + + QExplicitlySharedDataPointer file = m_dgioMount->getRootFile(); + if (file) { + QExplicitlySharedDataPointer fi = file->createFileInfo("*", FILE_QUERY_INFO_NONE, 500); + // 直接取createFileInfo数据有误,createFileSystemInfo数据才准确, createFileInfo仅用来判断文件是否可访问 + // 这里逻辑与计算机页面保持一致 + if (fi && fi->fileType() == DGioFileType::FILE_TYPE_DIRECTORY) { + return file->createFileSystemInfo(); + } + } + + return false; +} + +QPair DAttachedVfsDevice::deviceUsage() +{ + QExplicitlySharedDataPointer file = m_dgioMount->getRootFile(); + if (file) { + QExplicitlySharedDataPointer fi = file->createFileInfo("*", FILE_QUERY_INFO_NONE, 500); + // 直接取createFileInfo数据有误,createFileSystemInfo数据才准确, createFileInfo仅用来判断文件是否可访问 + // 这里逻辑与计算机页面保持一致 + if (fi && fi->fileType() == DGioFileType::FILE_TYPE_DIRECTORY) { + QExplicitlySharedDataPointer fsInfo = file->createFileSystemInfo(); + if (fsInfo) + return QPair(fsInfo->fsFreeBytes(), fsInfo->fsTotalBytes()); + } + } + + return QPair(0, 0); +} + +QString DAttachedVfsDevice::iconName() +{ + QStringList iconList = m_dgioMount ? m_dgioMount->themedIconNames() : QStringList(); + + if (iconList.empty()) { + return QStringLiteral("drive-network"); + } + + return iconList.first(); +} + +QUrl DAttachedVfsDevice::mountpointUrl() +{ + QExplicitlySharedDataPointer file = m_dgioMount->getRootFile(); + return QUrl::fromLocalFile(file->path()); +} + +QUrl DAttachedVfsDevice::accessPointUrl() +{ + return mountpointUrl(); +} diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattachedvfsdevice.h b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattachedvfsdevice.h new file mode 100644 index 0000000..f6c560a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/dattachedvfsdevice.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DATTACHEDVFSDEVICE_H +#define DATTACHEDVFSDEVICE_H + +#include "dattacheddeviceinterface.h" + +#include +#include + +#include +#include + +class DAttachedVfsDevice : public DAttachedDeviceInterface +{ +public: + explicit DAttachedVfsDevice(const QString &mountpointPath); + virtual ~DAttachedVfsDevice() override {} + bool isValid() override; + bool detachable() override; + void detach() override; + QString displayName() override; + bool deviceUsageValid() override; + QPair deviceUsage() override; + QString iconName() override; + QUrl mountpointUrl() override; + QUrl accessPointUrl() override; + +private: + QScopedPointer m_dgioMount; + QString m_mountpointPath; +}; + +#endif // DATTACHEDVFSDEVICE_H diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/disk-mount.json b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/disk-mount.json new file mode 100644 index 0000000..ad498ee --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/disk-mount.json @@ -0,0 +1,3 @@ +{ + "api": "1.1.1" +} diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/disk-mount.pro b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/disk-mount.pro new file mode 100644 index 0000000..e357891 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/disk-mount.pro @@ -0,0 +1,50 @@ +PREFIX = /usr +QT += core widgets concurrent dbus +TEMPLATE = lib +CONFIG += plugin c++11 link_pkgconfig +PKGCONFIG += dtkwidget gio-qt udisks2-qt5 + +INCLUDEPATH += /usr/include/dde-dock +INCLUDEPATH += $$PWD/../../dde-file-manager-lib/interfaces \ + $$PWD/../../dde-file-manager-lib + +TARGET = $$qtLibraryTarget(dde-disk-mount-plugin) +DESTDIR = $$_PRO_FILE_PWD_/../ +DISTFILES += disk-mount.json + +DEFINES += QT_MESSAGELOGCONTEXT DFM_NO_FILE_WATCHER + +#unix: LIBS += -L$$OUT_PWD/../../dde-file-manager-lib -ldde-file-manager + +include(src.pri) + +TRANSLATIONS += $$PWD/translations/$${TARGET}.ts \ + $$PWD/translations/$${TARGET}_zh_CN.ts +TR_EXCLUDE += $$PWD/../../dde-file-manager-lib/configure/* + +# Automating generation .qm files from .ts files +CONFIG(release, debug|release) { + !system($$PWD/../../dde-file-manager-lib/generate_translations.sh): error("Failed to generate translation") +# DEFINES += QT_NO_DEBUG_OUTPUT +} + +#安全加固 +QMAKE_CXXFLAGS += -fstack-protector-all +QMAKE_LFLAGS += -z now -fPIC +isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + QMAKE_LFLAGS += -z noexecstack -z relro +} + +gschema.path = $${PREFIX}/share/glib-2.0/schemas +gschema.files = *.gschema.xml + +translations.path = $${PREFIX}/share/$${TARGET}/translations +translations.files = translations/*.qm + +target.path = $${PREFIX}/lib/dde-dock/plugins/system-trays/ +INSTALLS += target gschema translations + +RESOURCES += \ + resources.qrc \ + resources/theme-icons.qrc \ + $$PWD/../../dde-file-manager-lib/configure.qrc diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskcontrolitem.cpp b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskcontrolitem.cpp new file mode 100644 index 0000000..b9043bd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskcontrolitem.cpp @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "diskcontrolitem.h" +#include "dattachedudisks2device.h" + +#include "dfmglobal.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +//fix: 设置光盘容量属性 +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE +DGUI_USE_NAMESPACE + +DFM_USE_NAMESPACE + +Q_GLOBAL_STATIC_WITH_ARGS(DFMSettings, gsGlobal, ("deepin/dde-file-manager", DFMSettings::GenericConfig)) + +// it takes the ownership of \a attachedDevicePtr. +DiskControlItem::DiskControlItem(DAttachedDeviceInterface *attachedDevicePtr, QWidget *parent) + : QFrame(parent), + + m_unknowIcon(":/icons/resources/unknown.svg"), + + m_diskIcon(new QPushButton(this)), + m_diskName(new QLabel), + m_diskCapacity(new QLabel), + m_capacityValueBar(new QProgressBar), + m_unmountButton(new DIconButton(this)) +{ + int colorValue = Dtk::Gui::DGuiApplicationHelper::instance()->themeType() == Dtk::Gui::DGuiApplicationHelper::LightType + ? 0 + : 1; + + attachedDevice.reset(attachedDevicePtr); + + m_diskName->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + m_diskName->setTextFormat(Qt::PlainText); + + QFont f = m_diskName->font(); + f.setPixelSize(14); + f.setWeight(QFont::Medium); + m_diskName->setFont(f); + QPalette pal = m_diskName->palette(); + pal.setColor(QPalette::WindowText, QColor::fromRgbF(colorValue, colorValue, colorValue, 0.8)); + m_diskName->setPalette(pal); + + f = m_diskCapacity->font(); + f.setPixelSize(12); + f.setWeight(QFont::Normal); + m_diskCapacity->setFont(f); + pal = m_diskCapacity->palette(); + pal.setColor(QPalette::WindowText, QColor::fromRgbF(colorValue, colorValue, colorValue, 0.6)); + m_diskCapacity->setPalette(pal); + + m_capacityValueBar->setTextVisible(false); + m_capacityValueBar->setFixedHeight(2); + + m_unmountButton->setFixedSize(20, 20); + m_unmountButton->setIconSize({20, 20}); + m_unmountButton->setFlat(true); + + QVBoxLayout *leftLay = new QVBoxLayout; + leftLay->addWidget(m_diskIcon); + leftLay->setContentsMargins(10, 8, 0, 8); + leftLay->setSpacing(0); + + QWidget *info = new QWidget(this); + QVBoxLayout *centLay = new QVBoxLayout; + QVBoxLayout *subCentLay = new QVBoxLayout; + subCentLay->setSpacing(2); + subCentLay->setContentsMargins(0, 0, 0, 0); + subCentLay->addWidget(m_diskName); + subCentLay->addWidget(m_diskCapacity); + centLay->addItem(subCentLay); + centLay->addWidget(m_capacityValueBar); + info->setLayout(centLay); + centLay->setSpacing(5); + centLay->setContentsMargins(10, 11, 0, 10); + + + QVBoxLayout *rigtLay = new QVBoxLayout; + rigtLay->addWidget(m_unmountButton); + rigtLay->setContentsMargins(19, 22, 12, 22); + + QHBoxLayout *mainLay = new QHBoxLayout; + mainLay->addLayout(leftLay); + mainLay->addWidget(info); + mainLay->addLayout(rigtLay); + mainLay->setContentsMargins(10, 8, 8, 12); + mainLay->setMargin(0); + mainLay->setSpacing(0); + + setLayout(mainLay); + setObjectName("DiskItem"); + + connect(m_unmountButton, &DIconButton::clicked, this, [this]() { + emit umountClicked(this); + }); + + if (gsGlobal->value("GenericAttribute", "DisableNonRemovableDeviceUnmount", false).toBool() && !attachedDevice->detachable()) { + m_unmountButton->hide(); + } + + m_diskIcon->setFlat(true); + m_diskIcon->setIcon(QIcon::fromTheme(attachedDevice->iconName(), m_unknowIcon)); + m_diskIcon->setIconSize(QSize(48, 48)); + m_diskIcon->setAttribute(Qt::WA_TransparentForMouseEvents); + m_diskIcon->setStyleSheet("padding: 0;"); + m_diskName->setText(QStringLiteral("OwO")); // blumia: correct text should be set in DiskControlItem::showEvent() + m_capacityValueBar->setMinimum(0); + m_capacityValueBar->setMaximum(100); + + connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, &DiskControlItem::refreshIcon); + refreshIcon(); +} + +DiskControlItem::~DiskControlItem() +{ +} + +void DiskControlItem::refreshIcon() +{ + m_unmountButton->setIcon(QIcon::fromTheme("dfm_unmount")); +} + +void DiskControlItem::detachDevice() +{ + attachedDevice->detach(); +} + +QString DiskControlItem::driveName() +{ + DAttachedUdisks2Device *device = dynamic_cast(attachedDevice.data()); + if (device && device->blockDevice()) + return device->blockDevice()->drive(); + return ""; +} + +QString DiskControlItem::tagName() const +{ + return m_tagName; +} + +void DiskControlItem::setTagName(const QString &tagName) +{ + m_tagName = tagName; +} + +QUrl DiskControlItem::mountPointUrl() +{ + return attachedDevice->mountpointUrl(); +} + +QString DiskControlItem::sizeString(const QString &str) +{ + int begin_pos = str.indexOf('.'); + + if (begin_pos < 0) + return str; + + QString size = str; + + while (size.count() - 1 > begin_pos) { + if (!size.endsWith('0')) + return size; + + size = size.left(size.count() - 1); + } + + return size.left(size.count() - 1); +} + +QString DiskControlItem::formatDiskSize(const quint64 num) +{ + QStringList list {" B", " KB", " MB", " GB", " TB"}; + qreal fileSize(num); + + QStringListIterator i(list); + QString unit = i.next(); + + int index = 0; + while (i.hasNext()) { + if (fileSize < 1024) { + break; + } + + unit = i.next(); + fileSize /= 1024; + index++; + } + return QString("%1%2").arg(sizeString(QString::number(fileSize, 'f', 1)), unit); +} + +void DiskControlItem::mouseReleaseEvent(QMouseEvent *e) +{ + QWidget::mouseReleaseEvent(e); + + DGioSettings gsettings("com.deepin.dde.dock.module.disk-mount", "/com/deepin/dde/dock/module/disk-mount/"); + if (gsettings.value("filemanager-integration").toBool()) { + // 光盘文件系统剥离 RockRidge 后,udisks 的默认挂载权限为 500,为遵从 linux 权限限制,在这里添加访问目录的权限校验 + DUrl mountPoint = DUrl(attachedDevice->mountpointUrl()); + QFile f(mountPoint.path()); + if (f.exists() && !f.permissions().testFlag(QFile::ExeUser)) { + DDialog *d = new DDialog(QObject::tr("Access denied"), QObject::tr("You do not have permission to access this folder")); + d->setAttribute(Qt::WA_DeleteOnClose); + Qt::WindowFlags flags = d->windowFlags(); + d->setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint); + d->setIcon(QIcon::fromTheme("dialog-error")); + d->addButton(QObject::tr("Confirm","button"), true, DDialog::ButtonRecommend); + d->setMaximumWidth(640); + d->show(); + return; + } + + DUrl url = DUrl(attachedDevice->accessPointUrl()); + if (url.scheme() == BURN_SCHEME) { + // 1. 当前熊默认文件管理器为 dde-file-manager 时,使用它打开光盘 + // 2. 默认文件管理器为其他时,依然采用打开挂载点的方式 + if (!QStandardPaths::findExecutable(QStringLiteral("dde-file-manager")).isEmpty()) { + QString &&path = url.path(); + QString opticalPath = QString("burn://%1").arg(path); + qDebug() << "open optical path =>" << opticalPath; + QProcess::startDetached(QStringLiteral("dde-file-manager"), {opticalPath}); + } else { + url = DUrl(attachedDevice->mountpointUrl()); + DDesktopServices::showFolder(url); + } + } else { + DDesktopServices::showFolder(url); + } + } +} + +void DiskControlItem::showEvent(QShowEvent *e) +{ + m_diskName->setText(attachedDevice->displayName()); + QString name = attachedDevice->displayName(); + QFont f = m_diskName->font(); + QFontMetrics fm(f); + QString elideText = fm.elidedText(name, Qt::ElideRight, m_diskName->width()); + m_diskName->setText(elideText); + + if (attachedDevice->deviceUsageValid()) { + QString iconName = attachedDevice->iconName(); + QPair freeAndTotal = attachedDevice->deviceUsage(); + quint64 bytesFree = freeAndTotal.first; + quint64 bytesTotal = freeAndTotal.second; + + if (iconName.simplified().toLower() == "media-optical") { // 光驱无法读取容量 + //fix: 设置光盘容量属性 + quint64 burnCapacityTotalSize = 0; + quint64 burnCapacityUsedSize = 0; + int burnStatus = 0;//光盘容量状态:0,光驱弹出状态 1,光驱弹入处于添加未挂载状态 2,光驱弹入处于添加后并挂载的状态 + int burnExt = 0; + QFile burnCapacityFile(QString("%1/.config/deepin/dde-file-manager.json").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation))); + if (!burnCapacityFile.open(QIODevice::ReadOnly)) { + qDebug() << "Couldn't open dde-file-manager.json burnCapacityFile!"; + return; + } + QByteArray burnCapacityData = burnCapacityFile.readAll(); + burnCapacityFile.close(); + + QJsonParseError parseJsonErr; + QJsonDocument jsonDoc(QJsonDocument::fromJson(burnCapacityData, &parseJsonErr)); + if (!(parseJsonErr.error == QJsonParseError::NoError)) { + qDebug() << "decode json file error!"; + return; + } + QJsonObject tempBurnObjs = jsonDoc.object(); + qDebug() << "tempBurnObjs==" << tempBurnObjs; + if (tempBurnObjs.contains(QStringLiteral("BurnCapacityAttribute"))) { + QJsonValue jsonBurnValueList = tempBurnObjs.value(QStringLiteral("BurnCapacityAttribute")); + QJsonObject tagItem = jsonBurnValueList.toObject(); + if (tagItem.contains(m_tagName)) { + QJsonObject burnItem = tagItem[m_tagName].toObject(); + burnCapacityTotalSize = static_cast(burnItem["BurnCapacityTotalSize"].toDouble()); + burnCapacityUsedSize = static_cast(burnItem["BurnCapacityUsedSize"].toDouble()); + burnStatus = burnItem["BurnCapacityStatus"].toInt(); + burnExt = burnItem["BurnCapacityExt"].toInt(); + } + } + Q_UNUSED(burnExt)//解决未用警告 + bytesFree = burnCapacityTotalSize - burnCapacityUsedSize; + bytesTotal = burnCapacityTotalSize; + if (burnStatus == 2) { + m_diskCapacity->setText(QString("%1 / %2") + .arg(formatDiskSize(burnCapacityUsedSize)) + .arg(formatDiskSize(burnCapacityTotalSize))); + } else { + m_diskCapacity->setText(tr("Unknown")); + } + } else { + m_diskCapacity->setText(QString("%1 / %2") + .arg(formatDiskSize(bytesTotal - bytesFree)) + .arg(formatDiskSize(bytesTotal))); + } + + if (bytesTotal > 0) { + m_capacityValueBar->setValue(static_cast(100 * (bytesTotal - bytesFree) / bytesTotal)); + } + } + + QFrame::showEvent(e); +} + +DFMSettings *getGsGlobal() +{ + return gsGlobal; +} diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskcontrolitem.h b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskcontrolitem.h new file mode 100644 index 0000000..344560c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskcontrolitem.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DISKCONTROLITEM_H +#define DISKCONTROLITEM_H + +#include +#include +#include +#include +#include +#include "dattacheddeviceinterface.h" +#include "dtkwidget_global.h" + +DFM_BEGIN_NAMESPACE +class DFMSettings; +DFM_END_NAMESPACE + +DWIDGET_BEGIN_NAMESPACE +class DIconButton; +DWIDGET_END_NAMESPACE + +DWIDGET_USE_NAMESPACE + +class DiskControlItem : public QFrame +{ + Q_OBJECT + +public: + explicit DiskControlItem(DAttachedDeviceInterface *attachedDevicePtr, QWidget *parent = nullptr); + ~DiskControlItem() override; + + static QString formatDiskSize(const quint64 num); + void detachDevice(); + QString driveName(); + QString tagName() const; + void setTagName(const QString &tagName); + QUrl mountPointUrl(); + +signals: + void umountClicked(DiskControlItem *item); + +private slots: + static QString sizeString(const QString &str); + +private: + void mouseReleaseEvent(QMouseEvent *e) override; + void showEvent(QShowEvent *e) override; + void refreshIcon(); + +private: + QIcon m_unknowIcon; + + QPushButton *m_diskIcon; + QLabel *m_diskName; + QLabel *m_diskCapacity; + QProgressBar *m_capacityValueBar; + DIconButton *m_unmountButton; + QScopedPointer attachedDevice; + + QString m_tagName; +}; + +DFM_NAMESPACE::DFMSettings* getGsGlobal(); + +#endif // DISKCONTROLITEM_H diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskcontrolwidget.cpp b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskcontrolwidget.cpp new file mode 100644 index 0000000..0e477d4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskcontrolwidget.cpp @@ -0,0 +1,635 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "diskcontrolwidget.h" +#include "diskcontrolitem.h" +#include "dattachedudisks2device.h" +#include "dattachedvfsdevice.h" +#include "models/dfmrootfileinfo.h" +#include "interfaces/dumountmanager.h" +#include "diskglobal.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#define WIDTH 300 + +DWIDGET_BEGIN_NAMESPACE +class DDialog; +DWIDGET_END_NAMESPACE +DWIDGET_USE_NAMESPACE + +DFM_USE_NAMESPACE + +DiskControlWidget::DiskControlWidget(QWidget *parent) + : QScrollArea(parent), + m_centralLayout(new QVBoxLayout), + m_centralWidget(new QWidget) +{ + this->setObjectName("DiskControlWidget-QScrollArea"); + + m_centralWidget->setLayout(m_centralLayout); + m_centralWidget->setFixedWidth(WIDTH); + + m_centralLayout->setMargin(0); + m_centralLayout->setSpacing(0); + + m_vfsManager.reset(new DGioVolumeManager); + + setWidget(m_centralWidget); + setFixedWidth(WIDTH); + setFrameShape(QFrame::NoFrame); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + verticalScrollBar()->setSingleStep(7); + m_centralWidget->setAutoFillBackground(false); + viewport()->setAutoFillBackground(false); + + m_diskManager = new DDiskManager(this); + m_umountManager.reset(new DUMountManager(this)); + + initConnect(); +} + +DiskControlWidget::~DiskControlWidget() +{ + +} + +void DiskControlWidget::initConnect() +{ + connect(m_diskManager, &DDiskManager::diskDeviceAdded, this, &DiskControlWidget::onDriveConnected); + connect(m_diskManager, &DDiskManager::blockDeviceAdded, this, &DiskControlWidget::onBlockDeviceAdded); + connect(m_diskManager, &DDiskManager::diskDeviceRemoved, this, &DiskControlWidget::onDriveDisconnected); + connect(m_diskManager, &DDiskManager::mountAdded, this, &DiskControlWidget::onMountAdded); + connect(m_diskManager, &DDiskManager::mountRemoved, this, &DiskControlWidget::onMountRemoved); + connect(m_diskManager, &DDiskManager::fileSystemAdded, this, &DiskControlWidget::onVolumeAdded); + connect(m_diskManager, &DDiskManager::fileSystemRemoved, this, &DiskControlWidget::onVolumeRemoved); + + connect(m_vfsManager.data(), &DGioVolumeManager::mountAdded, this, &DiskControlWidget::onVfsMountChanged); +// connect(m_vfsManager.data(), &DGioVolumeManager::mountChanged, this, &DiskControlWidget::onVfsMountChanged); + connect(m_vfsManager.data(), &DGioVolumeManager::mountRemoved, this, &DiskControlWidget::onVfsMountChanged); + + // 系统主题改变,重新刷新控件列表以适应新主题下的文字颜色 + connect(Dtk::Gui::DGuiApplicationHelper::instance(), &Dtk::Gui::DGuiApplicationHelper::themeTypeChanged, + this, [this]{ this->onDiskListChanged(); }); +} + +DDiskManager* DiskControlWidget::startMonitor() +{ + m_diskManager->setWatchChanges(true); + onDiskListChanged(); + return m_diskManager; +} + +/* + * + * TODO: move this thing into dtkcore or somewhere... + * There is also a FileUtils::getKernelParameters() in dde-file-manager. + * blumia: for writing unit test, try validate the result with `tr ' ' '\n' < /proc/cmdline` + */ +QMap getKernelParameters() +{ + QFile cmdline("/proc/cmdline"); + cmdline.open(QIODevice::ReadOnly); + QByteArray content = cmdline.readAll(); + + QByteArrayList paraList(content.split(' ')); + + QMap result; + result.insert("_ori_proc_cmdline", content); + + for (const QByteArray &onePara : paraList) { + int equalsIdx = onePara.indexOf('='); + QString key = equalsIdx == -1 ? onePara.trimmed() : onePara.left(equalsIdx).trimmed(); + QString value = equalsIdx == -1 ? QString() : onePara.right(equalsIdx).trimmed(); + result.insert(key, value); + } + + return result; +} + +void DiskControlWidget::doStartupAutoMount() +{ + // check if we are in live system, don't do auto mount if we are in live system. + static QMap cmdline = getKernelParameters(); + if (cmdline.value("boot", "") == QStringLiteral("live")) { + m_isInLiveSystem = true; + return; + } + + // 插件启动的时候判定是否挂载所有块设备 + m_autoMountEnable = getGsGlobal()->value("GenericAttribute", "AutoMount", false).toBool(); + if (!m_autoMountEnable) { + return; + } + + QStringList blDevList = m_diskManager->blockDevices({}); + for (const QString &blDevStr : blDevList) { + QScopedPointer blDev(DDiskManager::createBlockDevice(blDevStr)); + + if (blDev->isEncrypted()) continue; + // 已经解锁一次的加密盘,在重新挂载时就不需要秘钥了,如果这时重启dock就会自动挂载上,所以这里扔需要排除加密明文设备 + if (blDev->cryptoBackingDevice().length() > 1) continue; + if (blDev->hintIgnore()) continue; + + QList mountPoints = blDev->mountPoints(); + if (blDev->hasFileSystem() && blDev->mountPoints().isEmpty()) { + blDev->mount({{"auth.no_user_interaction", true}}); + } + } +} + +bool isProtectedDevice(DBlockDevice *blk) +{ + DGioSettings gsettings("com.deepin.dde.dock.module.disk-mount", "/com/deepin/dde/dock/module/disk-mount/"); + if (gsettings.value("protect-non-media-mounts").toBool()) { + QList mountPoints = blk->mountPoints(); + for (auto &mountPoint : mountPoints) { + if (!mountPoint.startsWith("/media/")) { + return true; + } + } + } + + if (gsettings.value("protect-root-device-mounts").toBool()) { + QStorageInfo qsi("/"); + QStringList rootDevNodes = DDiskManager::resolveDeviceNode(qsi.device(), {}); + if (!rootDevNodes.isEmpty()) { + if (DDiskManager::createBlockDevice(rootDevNodes.first())->drive() == blk->drive()) { + return true; + } + } + } + + return false; +} + +// onStop 为用户选择 Stop 后的回调 +void DiskControlWidget::popQueryScanningDialog(QObject *object, std::function onStop) +{ + DDialog *d = new DDialog; + d->setTitle(QObject::tr("Scanning the device, stop it?")); // 正在扫描当前设备,是否终止扫描? + d->setAttribute(Qt::WA_DeleteOnClose); + Qt::WindowFlags flags = d->windowFlags(); + d->setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint); + d->setIcon(QIcon::fromTheme("dialog-warning")); + d->addButton(QObject::tr("Cancel","button")); + d->addButton(QObject::tr("Stop","button"), true, DDialog::ButtonWarning); // 终止 + d->setMaximumWidth(640); + d->show(); + + QPointer pobject = object; + QObject::connect(d, &DDialog::buttonClicked, d, [=](int index, const QString &text){ + qInfo() << "index:" << index << ", Text:" << text; + // 用户点击终止扫描 + if (index == 1) { + qInfo() << "user click \'Stop\'."; + if (pobject) { + onStop(); + } + } + }); +} + +void DiskControlWidget::unmountAll() +{ + if (m_umountManager && m_umountManager->isScanningDrive()) { + popQueryScanningDialog(this, [this]() { + if (!m_umountManager) { + qWarning() << "m_umountManager is null!"; + return; + } + + if (m_umountManager->stopScanAllDrive()) + doUnMountAll(); + else + NotifyMsg(tr("The device was not safely removed"), tr("Click \"Safely Remove\" and then disconnect it next time") ); + }); + return; + } + doUnMountAll(); +} + +void DiskControlWidget::doUnMountAll() +{ + QStringList blockDevices = m_diskManager->blockDevices({}); + + QtConcurrent::run([blockDevices]() { + for (const QString &blDevStr : blockDevices) { + QScopedPointer blDev(DDiskManager::createBlockDevice(blDevStr)); + if (isProtectedDevice(blDev.data())) continue; + if (blDev->hasFileSystem() /* && DFMSetting*/ && !blDev->mountPoints().isEmpty() && !blDev->hintIgnore() && !blDev->hintSystem()) { + QScopedPointer diskDev(DDiskManager::createDiskDevice(blDev->drive())); + blDev->unmount({}); + qDebug() << "unmountAll" << "removable" << diskDev->removable() << + "optical" << diskDev->optical() << + "canPowerOff" << diskDev->canPowerOff() << + "ejectable" << diskDev->ejectable(); + + if (diskDev->removable()) { + diskDev->eject({}); + qDebug() << "unmountAll"; + if (diskDev->lastError().isValid()) { + qWarning() << diskDev->lastError().name() << blockDevices; + NotifyMsg(tr("The device was not safely removed"), tr("Click \"Safely Remove\" and then disconnect it next time") ); + continue; + } + } + if (diskDev->optical()) { // is optical + if (diskDev->ejectable()) { + diskDev->eject({}); + if (diskDev->lastError().isValid()) { + qWarning() << diskDev->lastError().name() << blockDevices; + NotifyMsg(tr("The device was not safely removed"), tr("Click \"Safely Remove\" and then disconnect it next time") ); + } + continue; // fix bug#16936 在 dock 上选择了卸载全部后,还会有U盘未被卸载 + } + } + + if (diskDev->canPowerOff()) { + diskDev->powerOff({}); + } + } + } + }); + + QList > vfsMounts = getVfsMountList(); + for (auto mount : vfsMounts) { + if (mount->isShadowed()) { + continue; + } + QExplicitlySharedDataPointer rootFile = mount->getRootFile(); + QString path = rootFile->path(); + DAttachedVfsDevice *dad = new DAttachedVfsDevice(path); + if (dad->isValid()) { + dad->detach(); + } else { + qDebug() << "dad->isValid()" << mount->name(); + } + } +} + +const QList > DiskControlWidget::getVfsMountList() +{ + QList > result; + const QList > mounts = m_vfsManager->getMounts(); + for (auto mount : mounts) { + QExplicitlySharedDataPointer file = mount->getRootFile(); + QString uriStr = file->uri(); + QUrl url(uriStr); + +#ifdef QT_DEBUG + if (!url.isValid()) { + qWarning() << "Gio uri is not a vaild QUrl!" << uriStr; + //qFatal("See the above warning for reason"); + } +#endif // QT_DEBUG + + if (url.scheme() == "file") continue; + + result.append(mount); + } + + return result; +} + +void DiskControlWidget::onDiskListChanged() +{ + auto addSeparateLine = [this](int width = 1){ + QFrame *line = new QFrame(this); + line->setLineWidth(width); + line->setFrameStyle(QFrame::HLine); + line->setFrameShadow(QFrame::Plain); + m_centralLayout->addWidget(line); + }; + + while (QLayoutItem *item = m_centralLayout->takeAt(0)) { + delete item->widget(); + delete item; + } + + QVBoxLayout *headerLay = new QVBoxLayout(this); + QWidget *header = new QWidget(this); + header->setLayout(headerLay); + headerLay->setSpacing(0); + headerLay->setContentsMargins(20, 9, 0, 8); + QLabel *headerTitle = new QLabel(tr("Disks"), this); + QFont f = headerTitle->font(); + f.setPixelSize(20); + f.setWeight(QFont::Medium); + headerTitle->setFont(f); + QPalette pal = headerTitle->palette(); + QColor color = Dtk::Gui::DGuiApplicationHelper::instance()->themeType() == Dtk::Gui::DGuiApplicationHelper::LightType + ? Qt::black + : Qt::white; + pal.setColor(QPalette::WindowText, color); + headerTitle->setPalette(pal); + + headerLay->addWidget(headerTitle); + m_centralLayout->addWidget(header); + addSeparateLine(2); + + int mountedCount = 0; + + QStringList blDevList = DDiskManager::blockDevices({}); + for (const QString &blDevStr : blDevList) { + QScopedPointer blDev(DDiskManager::createBlockDevice(blDevStr)); + if (blDev->hasFileSystem() && !blDev->mountPoints().isEmpty() && !blDev->hintSystem() && !blDev->hintIgnore()) { + if (isProtectedDevice(blDev.data())) continue; + mountedCount++; + QStringList blDevStrArray = blDevStr.split(QDir::separator()); + QString tagName = blDevStrArray.isEmpty() ? "" : blDevStrArray.last(); + DAttachedUdisks2Device *dad = new DAttachedUdisks2Device(blDev.data()); + qDebug() << "create new item, tagname is" << tagName; + DiskControlItem *item = new DiskControlItem(dad, this); + item->setTagName(tagName); + + class ErrHandle : public ErrorHandleInfc, public QObject + { + public: + explicit ErrHandle(QObject *parent): QObject(parent) {} + virtual void onError(DAttachedDeviceInterface *device) + { + DAttachedUdisks2Device *drv = dynamic_cast(device); + if (drv) { + qWarning() << drv->blockDevice()->lastError().name() << device->displayName(); + NotifyMsg(DiskControlWidget::tr("The device was not safely removed"), tr("Click \"Safely Remove\" and then disconnect it next time")); + } + } + }; + dad->setErrorHandler(new ErrHandle(item)); + + m_centralLayout->addWidget(item); + addSeparateLine(1); + + connect(item, &DiskControlItem::umountClicked, this, &DiskControlWidget::onItemUmountClicked); + } + } + + const QList > mounts = getVfsMountList(); + for (auto mount : mounts) { + if (mount->isShadowed()) { + continue; + } + QExplicitlySharedDataPointer rootFile = mount->getRootFile(); + QString path = rootFile->path(); + DAttachedVfsDevice *dad = new DAttachedVfsDevice(path); + if (dad->isValid()) { + mountedCount++; + DiskControlItem *item = new DiskControlItem(dad, this); + m_centralLayout->addWidget(item); + addSeparateLine(1); + + connect(item, &DiskControlItem::umountClicked, this, &DiskControlWidget::onItemUmountClicked); + } else { + delete dad; + dad = nullptr; //指针指空 防止野指针崩溃不好找 + } + } + + // 移除最下面的分割线 + QLayoutItem *last = m_centralLayout->takeAt(m_centralLayout->count() - 1); + if (last) { + delete last->widget(); + delete last; + } + + emit diskCountChanged(mountedCount); + + const int contentHeight = mountedCount * 70 + 46; + const int maxHeight = std::min(contentHeight, 70 * 6); + + m_centralWidget->setFixedHeight(contentHeight); + setFixedHeight(maxHeight); + + verticalScrollBar()->setPageStep(maxHeight); + verticalScrollBar()->setMaximum(contentHeight - maxHeight); +} + +void DiskControlWidget::onDriveConnected(const QString &deviceId) +{ + QScopedPointer diskDevice(DDiskManager::createDiskDevice(deviceId)); + if (diskDevice->removable()) { + DDesktopServices::playSystemSoundEffect(DDesktopServices::SSE_DeviceAdded); + } +} + +void DiskControlWidget::onDriveDisconnected() +{ + qDebug() << "changed from drive_disconnected"; + NotifyMsg(QObject::tr("The device has been safely removed")); + DDesktopServices::playSystemSoundEffect(DDesktopServices::SSE_DeviceRemoved); + onDiskListChanged(); +} + +void DiskControlWidget::onMountAdded() +{ + qDebug() << "changed from mount_add"; + onDiskListChanged(); +} + +void DiskControlWidget::onMountRemoved(const QString &blockDevicePath, const QByteArray &mountPoint) +{ + Q_UNUSED(mountPoint); + qDebug() << "changed from mount_remove:" << blockDevicePath; + QScopedPointer blDev(DDiskManager::createBlockDevice(blockDevicePath)); + if (blDev) { + QScopedPointer diskDev(DDiskManager::createDiskDevice(blDev->drive())); + if (diskDev && diskDev->removable()) { + qDebug() << "removable device" << blockDevicePath;// << mountPoint; + //return; // removable device emit onDiskListChanged too + } + } + + qDebug() << "unmounted," << mountPoint; + onDiskListChanged(); +} + +void DiskControlWidget::onVolumeAdded() +{ + qDebug() << "changed from volume_add"; + onDiskListChanged(); +} + +void DiskControlWidget::onVolumeRemoved() +{ + qDebug() << "changed from volume_remove"; + onDiskListChanged(); +} + +void DiskControlWidget::onVfsMountChanged(QExplicitlySharedDataPointer mount) +{ + qDebug() << "changed from VfsMount"; + QExplicitlySharedDataPointer file = mount->getRootFile(); + QString uriStr = file->uri(); + QUrl url(uriStr); + +#ifdef QT_DEBUG + if (!url.isValid()) { + qWarning() << "Gio uri is not a vaild QUrl!" << uriStr; + //qFatal("See the above warning for reason"); + } +#endif // QT_DEBUG + + if (url.scheme() == "file") return; + + onDiskListChanged(); +} + +void DiskControlWidget::onBlockDeviceAdded(const QString &path) +{ + static const QString msg = "device add canceld: "; + // 刷新一次配置信息当有新的设备接入时,保证每次都是最新的配置生效 + getGsGlobal()->reload(); + m_autoMountEnable = getGsGlobal()->value("GenericAttribute", "AutoMount", false).toBool(); + m_autoMountAndOpenEnable = getGsGlobal()->value("GenericAttribute", "AutoMountAndOpen", false).toBool(); + + if (m_isInLiveSystem || !m_autoMountEnable) { + qDebug() << msg + "isInLiveSys-" << m_isInLiveSystem << "\tautoMountEnable-" << m_autoMountEnable; + return; + } + // 以前的逻辑,应该是判定当前用户是否是激活状态(登录系统状态) + QDBusInterface loginManager("org.freedesktop.login1", + "/org/freedesktop/login1/user/self", + "org.freedesktop.login1.User", + QDBusConnection::systemBus()); + QVariant replay = loginManager.property(("State")); + if (replay.isValid()) { + QString state = replay.toString(); + if (state != "active") { + qDebug() << msg + "user state is not active"; + return; + } + } + + qInfo() << "try to convert blkdev from path: " << path ; + + QScopedPointer blkDev(DDiskManager::createBlockDevice(path)); + + // 如果已经在 onDriveConnected 函数中挂载上了的设备直接忽略 + if (!blkDev || !blkDev->mountPoints().isEmpty()) return; + // 以下皆是以前的逻辑 + if (isProtectedDevice(blkDev.data())) return; + if (blkDev->isEncrypted()) return; + // 加密盘解锁后 dock先挂载 会触发文管挂载时提示重复挂载 bugid: 77010 + if (blkDev->cryptoBackingDevice().length() > 1) return; + if (blkDev->hintIgnore()) return; + if (!blkDev->hasFileSystem()) return; + + QString mountPoint = blkDev->mount({}); + + if (mountPoint.isEmpty() || blkDev->lastError().type() != QDBusError::NoError) { + qDebug() << "auto mount error: " << blkDev->lastError().type() << blkDev->lastError().message(); + qDebug() << msg + "mount error occured"; + return; + } + + qInfo() << "auto mount drive[ " << blkDev->drive() << " ] with path[" << path << " ] on point:" << mountPoint; + + if (m_autoMountAndOpenEnable) { + if (!QStandardPaths::findExecutable(QStringLiteral("dde-file-manager")).isEmpty()) { + QString mountUrlStr = DFMROOT_ROOT + QFileInfo(blkDev->device()).fileName() + "." SUFFIX_UDISKS; + QProcess::startDetached(QStringLiteral("dde-file-manager"), {mountUrlStr}); + qDebug() << "open by dde-file-manager: " << mountUrlStr; + return; + } + DDesktopServices::showFolder(QUrl::fromLocalFile(mountPoint)); + } +} + +void DiskControlWidget::onItemUmountClicked(DiskControlItem *item) +{ + if (!item) { + qWarning() << "DiskControlWidget, item is null."; + return; + } + + // 弹出某个设备,需要停止该分区对应设备的所有其它分区 + const QString &driveName = item->driveName(); + if (m_umountManager && !driveName.isNull() && !driveName.isEmpty() && m_umountManager->isScanningDrive(driveName)) { + popQueryScanningDialog(item, [this, driveName, item]() { + if (!m_umountManager) { + qWarning() << "m_umountManager is null!"; + return; + } + if (m_umountManager->stopScanDrive(driveName)) + item->detachDevice(); + else + NotifyMsg(tr("The device was not safely removed"), tr("Click \"Safely Remove\" and then disconnect it next time")); + }); + return; + } + item->detachDevice(); +} + +void DiskControlWidget::NotifyMsg(QString msg) +{ + DDBusSender() + .service("org.freedesktop.Notifications") + .path("/org/freedesktop/Notifications") + .interface("org.freedesktop.Notifications") + .method(QString("Notify")) + .arg(tr("dde-file-manager")) + .arg(static_cast(0)) + .arg(QString("media-eject")) + .arg(msg) + .arg(QString()) + .arg(QStringList()) + .arg(QVariantMap()) + .arg(5000).call(); +} + +void DiskControlWidget::NotifyMsg(QString title, QString msg) +{ + DDBusSender() + .service("org.freedesktop.Notifications") + .path("/org/freedesktop/Notifications") + .interface("org.freedesktop.Notifications") + .method(QString("Notify")) + .arg(tr("dde-file-manager")) + .arg(static_cast(0)) + .arg(QString("media-eject")) + .arg(title) + .arg(msg) + .arg(QStringList()) + .arg(QVariantMap()) + .arg(5000).call(); +} diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskcontrolwidget.h b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskcontrolwidget.h new file mode 100644 index 0000000..dee81b5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskcontrolwidget.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DISKCONTROLWIDGET_H +#define DISKCONTROLWIDGET_H + +#include +#include +#include +#include + +class DDiskManager; +DFM_BEGIN_NAMESPACE +class DFMSettings; +class DFMVfsManager; +DFM_END_NAMESPACE + +class DGioVolumeManager; +class DUMountManager; +class DiskControlItem; + +class DiskControlWidget : public QScrollArea +{ + Q_OBJECT + +public: + explicit DiskControlWidget(QWidget *parent = nullptr); + ~DiskControlWidget() override; + void initConnect(); + + DDiskManager* startMonitor(); + void doStartupAutoMount(); + void unmountAll(); + void doUnMountAll(); + + const QList > getVfsMountList(); + static void NotifyMsg(QString msg); + static void NotifyMsg(QString title, QString msg); + +signals: + void diskCountChanged(const int count) const; + +private: + void popQueryScanningDialog(QObject *object, std::function onStop); + +private slots: + void onDriveConnected(const QString &deviceId); + void onDiskListChanged(); + void onDriveDisconnected(); + void onMountAdded(); + void onMountRemoved(const QString &blockDevicePath, const QByteArray &mountPoint); + void onVolumeAdded(); + void onVolumeRemoved(); + void onVfsMountChanged(QExplicitlySharedDataPointer mount); + void onBlockDeviceAdded(const QString &path); + void onItemUmountClicked(DiskControlItem *item); + +private: + QVBoxLayout *m_centralLayout; + QWidget *m_centralWidget; + bool m_isInLiveSystem = false; // 当处于 liveSys 的时候禁用自动挂载(以前的逻辑) + bool m_autoMountEnable = false; // 配置项中的自动挂载 + bool m_autoMountAndOpenEnable = false; // 配置项中的挂载并打开 + + DDiskManager *m_diskManager; + QScopedPointer m_umountManager; + QScopedPointer m_vfsManager; +}; + +#endif // DISKCONTROLWIDGET_H diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskglobal.cpp b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskglobal.cpp new file mode 100644 index 0000000..fdd6e30 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskglobal.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "diskglobal.h" +#include +#include + +DiskGlobal::DiskGlobal(QObject * parent):QObject (parent) +{ + +} + +bool DiskGlobal::isWayLand() +{ + //! 该函数只能在QApplication之后调用才能返回有效的值,在此之前会返回空值 + Q_ASSERT(qApp); + return QApplication::platformName() == "wayland"; +} diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskglobal.h b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskglobal.h new file mode 100644 index 0000000..14a7f95 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskglobal.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DISKGLOBAL_H +#define DISKGLOBAL_H +#include +#include + +class DiskGlobal : public QObject +{ +public: + explicit DiskGlobal(QObject *parent = nullptr); + + static bool isWayLand(); +}; + +#endif // DFMGLOBAL_H diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskmountplugin.cpp b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskmountplugin.cpp new file mode 100644 index 0000000..6c247e5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskmountplugin.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "diskmountplugin.h" + +#include +#include + +#define OPEN "open" +#define UNMOUNT_ALL "unmount_all" + +DWIDGET_USE_NAMESPACE + +DiskMountPlugin::DiskMountPlugin(QObject *parent) + : QObject(parent), + + m_pluginAdded(false), + m_pluginLoaded(false), + m_usingAppLoader(true), + + m_tipsLabel(new TipsWidget), + m_diskPluginItem(new DiskPluginItem), + m_diskControlApplet(nullptr) +{ + qDebug() << "===============init============="; + m_diskPluginItem->setVisible(false); + + m_tipsLabel->setObjectName("diskmount"); + m_tipsLabel->setVisible(false); + m_tipsLabel->setText(tr("Disk")); +} + +DiskMountPlugin::DiskMountPlugin(bool usingAppLoader, QObject *parent) + : QObject(parent), + + m_pluginAdded(false), + m_pluginLoaded(false), + m_usingAppLoader(usingAppLoader), + + m_tipsLabel(new TipsWidget), + m_diskPluginItem(new DiskPluginItem), + m_diskControlApplet(nullptr) +{ + qDebug() << "===============init============="; + m_diskPluginItem->setVisible(false); + + m_tipsLabel->setObjectName("diskmount"); + m_tipsLabel->setVisible(false); + m_tipsLabel->setText(tr("Disk")); +} + +const QString DiskMountPlugin::pluginName() const +{ + return "disk-mount"; +} + +void DiskMountPlugin::init(PluginProxyInterface *proxyInter) +{ + // blumia: we are using i10n translation from DFM so... qApp->loadTranslator(); + QString applicationName = qApp->applicationName(); + qApp->setApplicationName("dde-disk-mount-plugin"); + if(m_usingAppLoader){ + qDebug() << qApp->loadTranslator(); + } + qApp->setApplicationName(applicationName); + qDebug() << "===============init==proxyInter==========="; + m_proxyInter = proxyInter; + + if (m_pluginLoaded) { + qDebug() << "disk mount plugin has been loaded! return"; + return; + } + + m_pluginLoaded = true; + + initCompoments(); + m_diskPluginItem->setDockDisplayMode(displayMode()); +} + +QWidget *DiskMountPlugin::itemWidget(const QString &itemKey) +{ + Q_UNUSED(itemKey); + + return m_diskPluginItem; +} + +QWidget *DiskMountPlugin::itemTipsWidget(const QString &itemKey) +{ + Q_UNUSED(itemKey); + + return m_tipsLabel; +} + +QWidget *DiskMountPlugin::itemPopupApplet(const QString &itemKey) +{ + Q_UNUSED(itemKey); + + return m_diskControlApplet; +} + +const QString DiskMountPlugin::itemContextMenu(const QString &itemKey) +{ + Q_UNUSED(itemKey); + + QList items; + items.reserve(2); + + DGioSettings gsettings("com.deepin.dde.dock.module.disk-mount", "/com/deepin/dde/dock/module/disk-mount/"); + + if (gsettings.value("filemanager-integration").toBool()) { + QMap open; + open["itemId"] = OPEN; + open["itemText"] = tr("Open"); + open["isActive"] = true; + items.push_back(open); + } + + QMap unmountAll; + unmountAll["itemId"] = UNMOUNT_ALL; + unmountAll["itemText"] = tr("Eject all"); + unmountAll["isActive"] = true; + items.push_back(unmountAll); + + QMap menu; + menu["items"] = items; + menu["checkableMenu"] = false; + menu["singleCheck"] = false; + + return QJsonDocument::fromVariant(menu).toJson(); +} + +void DiskMountPlugin::invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked) +{ + Q_UNUSED(itemKey) + Q_UNUSED(checked) + + if (menuId == OPEN) + QProcess::startDetached("gio", QStringList() << "open" << "computer:///"); + else if (menuId == UNMOUNT_ALL) + m_diskControlApplet->unmountAll(); +} + +int DiskMountPlugin::itemSortKey(const QString &itemKey) +{ + const QString &key = QString("pos_%1_%2").arg(itemKey).arg(Dock::Efficient); + int ret = m_proxyInter->getValue(this, key, 0).toInt(); // dde-dock默认设置为0 + qDebug() << "itemSortKey [key:" << key << "," << ret << "] for :" << itemKey; + return ret; +} + +void DiskMountPlugin::setSortKey(const QString &itemKey, const int order) +{ + const QString &key = QString("pos_%1_%2").arg(itemKey).arg(Dock::Efficient); + m_proxyInter->saveValue(this, key, order); + qDebug() << "setSortKey [key:" << key << "," << order << "] for :" << itemKey; +} + +void DiskMountPlugin::refreshIcon(const QString &itemKey) +{ + if (itemKey == DISK_MOUNT_KEY) { + m_diskPluginItem->updateIcon(); + } +} + +void DiskMountPlugin::initCompoments() +{ + m_diskControlApplet = new DiskControlWidget; + m_diskControlApplet->setObjectName("disk-mount"); + m_diskControlApplet->setVisible(false); + + connect(m_diskControlApplet, &DiskControlWidget::diskCountChanged, this, &DiskMountPlugin::diskCountChanged); + m_diskControlApplet->doStartupAutoMount(); + m_diskControlApplet->startMonitor(); +} + +void DiskMountPlugin::displayModeChanged(const Dock::DisplayMode mode) +{ + m_diskPluginItem->setDockDisplayMode(mode); +} + +void DiskMountPlugin::diskCountChanged(const int count) +{ + qDebug() << count << m_pluginAdded; + if (m_pluginAdded == bool(count)) + return; + + m_pluginAdded = bool(count); + + if (m_pluginAdded) + m_proxyInter->itemAdded(this, DISK_MOUNT_KEY); + else + m_proxyInter->itemRemoved(this, DISK_MOUNT_KEY); +} diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskmountplugin.h b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskmountplugin.h new file mode 100644 index 0000000..ac44616 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskmountplugin.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DISKMOUNTPLUGIN_H +#define DISKMOUNTPLUGIN_H + +#include +#include + +#include "pluginsiteminterface.h" +#include "diskcontrolwidget.h" +#include "diskpluginitem.h" + +// TipsWidget from dde-dock. +// TODO: move the disk mount plugin to dde-dock project. +class TipsWidget : public QFrame +{ + Q_OBJECT +public: + explicit TipsWidget(QWidget *parent = nullptr) : QFrame(parent) {} + + void setText(const QString &text) + { + m_text = text; + setFixedSize(fontMetrics().width(text) + 6, fontMetrics().height()); + update(); + } + + void refreshFont() + { + setFixedSize(fontMetrics().width(m_text) + 6, fontMetrics().height()); + update(); + } + +protected: + void paintEvent(QPaintEvent *event) override + { + QFrame::paintEvent(event); + refreshFont(); + QPainter painter(this); + painter.setPen(QPen(palette().brightText(), 1)); + QTextOption option; + option.setAlignment(Qt::AlignCenter); + painter.drawText(rect(), m_text, option); + } + +private: + QString m_text; +}; + + +class DiskMountPlugin : public QObject, PluginsItemInterface +{ + Q_OBJECT + Q_INTERFACES(PluginsItemInterface) + Q_PLUGIN_METADATA(IID "com.deepin.dock.PluginsItemInterface" FILE "disk-mount.json") + +public: + explicit DiskMountPlugin(QObject *parent = nullptr); + explicit DiskMountPlugin(bool usingAppLoader, QObject *parent = nullptr); + + const QString pluginName() const override; + void init(PluginProxyInterface *proxyInter) override; + + QWidget *itemWidget(const QString &itemKey) override; + QWidget *itemTipsWidget(const QString &itemKey) override; + QWidget *itemPopupApplet(const QString &itemKey) override; + + const QString itemContextMenu(const QString &itemKey) override; + void invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked) override; + + int itemSortKey(const QString &itemKey) override; + void setSortKey(const QString &itemKey, const int order) override; + + void refreshIcon(const QString &itemKey) override; + +private: + void initCompoments(); + + void displayModeChanged(const Dock::DisplayMode mode) override; + +private slots: + void diskCountChanged(const int count); + +private: + bool m_pluginAdded; + bool m_pluginLoaded; + bool m_usingAppLoader; + + TipsWidget *m_tipsLabel; + DiskPluginItem *m_diskPluginItem; + DiskControlWidget *m_diskControlApplet; +}; + +#endif // DISKMOUNTPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskpluginitem.cpp b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskpluginitem.cpp new file mode 100644 index 0000000..a9e4246 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskpluginitem.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "diskpluginitem.h" + +#include +#include +#include +#include +#include +#include +#include + +DGUI_USE_NAMESPACE + +DiskPluginItem::DiskPluginItem(QWidget *parent) + : QWidget(parent), + m_displayMode(Dock::Efficient) +{ + connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, [ = ] { + updateIcon(); + }); +} + +void DiskPluginItem::setDockDisplayMode(const Dock::DisplayMode mode) +{ + m_displayMode = mode; + + updateIcon(); +} + +void DiskPluginItem::paintEvent(QPaintEvent *e) +{ + QWidget::paintEvent(e); + + QPainter painter(this); + const QRectF &rf = QRectF(rect()); + const QRectF &rfp = QRectF(m_icon.rect()); + painter.drawPixmap(rf.center() - rfp.center() / qApp->devicePixelRatio(), m_icon); +} + +void DiskPluginItem::resizeEvent(QResizeEvent *e) +{ + QWidget::resizeEvent(e); + + // 修复bug-89675 切换模式时,diskpluginitem大小会变化,导致了绘制位置不对 + // 于是出现了切换模式时,图标不见了。 + // 保持diskpluginitem横纵比 + const Dock::Position position = qApp->property(PROP_POSITION).value(); + if (position == Dock::Bottom || position == Dock::Top) { + setMaximumWidth(height()); + setMaximumHeight(QWIDGETSIZE_MAX); + } else { + setMaximumHeight(width()); + setMaximumWidth(QWIDGETSIZE_MAX); + } + + updateIcon(); +} + +QSize DiskPluginItem::sizeHint() const +{ + return QSize(26, 26); +} + +void DiskPluginItem::updateIcon() +{ +// if (m_displayMode == Dock::Efficient) +// m_icon = QIcon::fromTheme("drive-removable-dock-symbolic").pixmap(16 * qApp->devicePixelRatio(), 16 * qApp->devicePixelRatio()); +// else +// m_icon = QIcon::fromTheme("drive-removable-dock").pixmap(std::min(width(), height()) * 0.8 * qApp->devicePixelRatio(), std::min(width(), height()) * 0.8 * qApp->devicePixelRatio()); + + // fashion mode icons are no longer needed + + QString iconName = "drive-removable-dock-symbolic"; + if (height() <= PLUGIN_BACKGROUND_MIN_SIZE && DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) + iconName.append(PLUGIN_MIN_ICON_NAME); + + m_icon = QIcon::fromTheme(iconName, QIcon(QString(":/icons/resources/%1.svg").arg(iconName))).pixmap(static_cast(16 * qApp->devicePixelRatio()), static_cast(16 * qApp->devicePixelRatio())); + m_icon.setDevicePixelRatio(qApp->devicePixelRatio()); + update(); +} diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskpluginitem.h b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskpluginitem.h new file mode 100644 index 0000000..c2358ee --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/diskpluginitem.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DISKPLUGINITEM_H +#define DISKPLUGINITEM_H + +#include "constants.h" + +#include +#include + +#define DISK_MOUNT_KEY "mount-item-key" + +class DiskPluginItem : public QWidget +{ + Q_OBJECT + +public: + explicit DiskPluginItem(QWidget *parent = nullptr); + +public slots: + void setDockDisplayMode(const Dock::DisplayMode mode); + void updateIcon(); + +protected: + void paintEvent(QPaintEvent *e); + void resizeEvent(QResizeEvent *e); + QSize sizeHint() const; + +private: + Dock::DisplayMode m_displayMode; + + QPixmap m_icon; +}; + +#endif // DISKPLUGINITEM_H diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources.qrc b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources.qrc new file mode 100644 index 0000000..33ccacd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources.qrc @@ -0,0 +1,15 @@ + + + resources/icon-small.svg + resources/icon.svg + resources/unknown.svg + resources/unmount-hover.svg + resources/unmount-normal.svg + resources/unmount-press.svg + resources/unmount-normal-dark.svg + resources/unmount-hover-dark.svg + resources/unmount-press-dark.svg + resources/drive-removable-dock-symbolic-dark.svg + resources/drive-removable-dock-symbolic.svg + + diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/drive-removable-dock-symbolic-dark.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/drive-removable-dock-symbolic-dark.svg new file mode 100644 index 0000000..0d14feb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/drive-removable-dock-symbolic-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/drive-removable-dock-symbolic.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/drive-removable-dock-symbolic.svg new file mode 100644 index 0000000..11b67d3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/drive-removable-dock-symbolic.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/icon-small.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/icon-small.svg new file mode 100644 index 0000000..549ca8a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/icon-small.svg @@ -0,0 +1,13 @@ + + + + drive_harddisk_usb_symbolic_active_16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/icon.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/icon.svg new file mode 100644 index 0000000..952b644 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/icon.svg @@ -0,0 +1,28 @@ + + + + 磁盘挂载-48px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/icons/deepin/builtin/dark/icons/dfm_unmount_20px.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/icons/deepin/builtin/dark/icons/dfm_unmount_20px.svg new file mode 100644 index 0000000..663fa9c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/icons/deepin/builtin/dark/icons/dfm_unmount_20px.svg @@ -0,0 +1,10 @@ + + + + 卸载normal + Created with Sketch. + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/icons/deepin/builtin/light/icons/dfm_unmount_20px.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/icons/deepin/builtin/light/icons/dfm_unmount_20px.svg new file mode 100644 index 0000000..9cce128 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/icons/deepin/builtin/light/icons/dfm_unmount_20px.svg @@ -0,0 +1,10 @@ + + + + 卸载normal + Created with Sketch. + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/theme-icons.qrc b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/theme-icons.qrc new file mode 100644 index 0000000..68634a9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/theme-icons.qrc @@ -0,0 +1,6 @@ + + + icons/deepin/builtin/dark/icons/dfm_unmount_20px.svg + icons/deepin/builtin/light/icons/dfm_unmount_20px.svg + + diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unknown.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unknown.svg new file mode 100644 index 0000000..8156620 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unknown.svg @@ -0,0 +1,40 @@ + + + + drive-unknown + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-hover-dark.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-hover-dark.svg new file mode 100644 index 0000000..d6ef1e4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-hover-dark.svg @@ -0,0 +1,10 @@ + + + + 卸载hover + Created with Sketch. + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-hover.png b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-hover.png new file mode 100644 index 0000000..863e17a Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-hover.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-hover.svg new file mode 100644 index 0000000..61f2bd0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-hover.svg @@ -0,0 +1,10 @@ + + + + 卸载hover + Created with Sketch. + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-normal-dark.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-normal-dark.svg new file mode 100644 index 0000000..7d5f445 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-normal-dark.svg @@ -0,0 +1,10 @@ + + + + 卸载normal + Created with Sketch. + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-normal.png b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-normal.png new file mode 100644 index 0000000..77feec2 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-normal.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-normal.svg new file mode 100644 index 0000000..7fe4816 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-normal.svg @@ -0,0 +1,10 @@ + + + + 卸载normal + Created with Sketch. + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-press-dark.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-press-dark.svg new file mode 100644 index 0000000..258497b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-press-dark.svg @@ -0,0 +1,10 @@ + + + + 卸载press + Created with Sketch. + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-press.png b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-press.png new file mode 100644 index 0000000..a3e0692 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-press.svg b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-press.svg new file mode 100644 index 0000000..30ccb29 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/resources/unmount-press.svg @@ -0,0 +1,10 @@ + + + + 卸载press + Created with Sketch. + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/src.pri b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/src.pri new file mode 100644 index 0000000..1e83613 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/src.pri @@ -0,0 +1,39 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-06-24T09:14:17 +# +#------------------------------------------------- + +INCLUDEPATH += $$PWD + + +HEADERS += \ + $$PWD/diskmountplugin.h \ + $$PWD/diskcontrolwidget.h \ + $$PWD/diskpluginitem.h \ + $$PWD/diskcontrolitem.h \ + $$PWD/diskglobal.h \ + $$PWD/dattacheddeviceinterface.h \ + $$PWD/dattachedudisks2device.h \ + $$PWD/dattachedvfsdevice.h \ + $$PWD/../../dde-file-manager-lib/interfaces/dfmsettings.h \ + $$PWD/../../dde-file-manager-lib/interfaces/dfmstandardpaths.h \ + $$PWD/../../dde-file-manager-lib/interfaces/durl.h \ + $$PWD/../../dde-file-manager-lib/interfaces/defenderinterface.h \ + $$PWD/../../dde-file-manager-lib/interfaces/dumountmanager.h \ + +SOURCES += \ + $$PWD/diskmountplugin.cpp \ + $$PWD/diskcontrolwidget.cpp \ + $$PWD/diskpluginitem.cpp \ + $$PWD/diskcontrolitem.cpp \ + $$PWD/diskglobal.cpp \ + $$PWD/dattachedudisks2device.cpp \ + $$PWD/dattachedvfsdevice.cpp \ + $$PWD/../../dde-file-manager-lib/interfaces/dfmsettings.cpp \ + $$PWD/../../dde-file-manager-lib/interfaces/dfmstandardpaths.cpp \ + $$PWD/../../dde-file-manager-lib/interfaces/durl.cpp \ + $$PWD/../../dde-file-manager-lib/interfaces/defenderinterface.cpp \ + $$PWD/../../dde-file-manager-lib/interfaces/dumountmanager.cpp \ + $$PWD/dattacheddeviceinterface.cpp + diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin.ts new file mode 100644 index 0000000..5b3a7b2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Authentication timed out + + + Disk is busy, cannot unmount now + Disk is busy, cannot unmount now + + + Disk is busy, cannot eject now + Disk is busy, cannot eject now + + + The device is busy, cannot eject now + The device is busy, cannot eject now + + + The device is busy, cannot remove now + The device is busy, cannot remove now + + + + DeepinStorage + + %1 Volume + %1 Volume + + + + DiskControlItem + + Unknown + Unknown + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + The device was not safely removed + + + Click "Safely Remove" and then disconnect it next time + Click "Safely Remove" and then disconnect it next time + + + Cannot unmount the device + Cannot unmount the device + + + The disk is mounted by user "%1", you cannot unmount it. + The disk is mounted by user "%1", you cannot unmount it. + + + Cannot find the mounted device + Cannot find the mounted device + + + Disks + Disks + + + + DiskMountPlugin + + Disk + Disk + + + Open + Open + + + Eject all + Eject all + + + + QObject + + The device has been safely removed + The device has been safely removed + + + Access denied + Access denied + + + You do not have permission to access this folder + You do not have permission to access this folder + + + Scanning the device, stop it? + Scanning the device, stop it? + + + Confirm + button + Confirm + + + Cancel + button + Cancel + + + Stop + button + Stop + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ar.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ar.ts new file mode 100644 index 0000000..dba3a51 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ar.ts @@ -0,0 +1,101 @@ + + + DeepinStorage + + %1 Volume + %1 مستوى الصوت + + + + DiskControlItem + + Unknown + غير معروف + + + + DiskControlWidget + + dde-file-manager + مدير ملفات ديبين + + + The device was not safely removed + لم يتم إزالة الجهاز بأمان + + + Click "Safely Remove" and then disconnect it next time + + + + The device is busy, cannot eject now + + + + The device is busy, cannot remove now + + + + Cannot unmount the device + لا يمكن فصل الجهاز + + + The disk is mounted by user "%1", you cannot unmount it. + القرص متصل بالمستخدم "%1"، لا يمكنك فصله. + + + Cannot find the mounted device + + + + Disks + الأقراص + + + + DiskMountPlugin + + Disk + القرص + + + Open + فتح + + + Eject all + إخراج الكل + + + + QObject + + The device has been safely removed + تمت إزالة الجهاز بأمان + + + Access denied + تم رفض الوصول + + + You do not have permission to access this folder + ليس لديك صلاحيات للوصول إلى هذا المجلد + + + Confirm + تأكيد + + + Scanning the device, stop it? + يتم فحص الجهاز ... هل تريد إيقافه ؟ + + + Cancel + إلغاء + + + Stop + إيقاف + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_az.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_az.ts new file mode 100644 index 0000000..6e9771b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_az.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Doğrulama vaxtı bitdi + + + Disk is busy, cannot unmount now + Disk məşğuldur, indi ayrıla bilməz + + + Disk is busy, cannot eject now + Disk məşğuldur, indi çıxarıla bilməz + + + The device is busy, cannot eject now + Cihaz məşğuldur, indi çıxarıla bilməz + + + The device is busy, cannot remove now + Cihaz məşğuldur, indi ayrıla bilməz + + + + DeepinStorage + + %1 Volume + %1 disk tutumu + + + + DiskControlItem + + Unknown + Naməlum + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Cihaz təhlükəsiz şəkildə çıxarılmadı + + + Click "Safely Remove" and then disconnect it next time + Növbəti dəfə "Təhlükəsiz Çıxartmaq" vurun və sonra çıxardın + + + Cannot unmount the device + Cihazı ayırmaq mümkün deyil + + + The disk is mounted by user "%1", you cannot unmount it. + Disk "%1" istifadəçisi tərəfindən qoşulub, siz onu ayıra bilməzsiniz. + + + Cannot find the mounted device + Qoşulmuş cihazı tapmaq olmur + + + Disks + Disklər + + + + DiskMountPlugin + + Disk + Disk + + + Open + Açmaq + + + Eject all + Hamısını çıxartmaq + + + + QObject + + The device has been safely removed + Bu cihaz təhlükəsiz çıxarıldı + + + Access denied + İcazə verilmədi + + + You do not have permission to access this folder + Bu qovluğa girməniz üçün icazəniz yoxdur + + + Scanning the device, stop it? + Cihazlar aşkarlanır, dayandırılsın? + + + Confirm + button + Tədiqləmək + + + Cancel + button + İmtina + + + Stop + button + Dayandırmaq + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_bg.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_bg.ts new file mode 100644 index 0000000..764643d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_bg.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + %1 обем + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + Диск + + + + Open + Отваряне + + + + Unmount all + Демонтиране на всичко + + + + QObject + + + Device has been removed + Устройство беше премахнато + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_bo.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_bo.ts new file mode 100644 index 0000000..293cb69 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_bo.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + དཔང་དཔྱད་དུས་བརྒལ། + + + Disk is busy, cannot unmount now + སྡུད་སྡེར་ཡིག་ཆ་གཞན་གྱིས་བཟུང་ཡོད་པས། བཤིག་འདོན་བྱེད་ཐབས་བྲལ། + + + Disk is busy, cannot eject now + སྡུད་སྡེར་ཡིག་ཆ་གཞན་གྱིས་བཟུང་ཡོད་པས། ཕྱིར་དོན་ཐབས་བྲལ། + + + The device is busy, cannot eject now + འོད་སྡེར་བྲེལ་བཞིན་འདུག་པས། ཕྱིར་བཏོན་ཐབས་བྲལ། + + + The device is busy, cannot remove now + འོད་སྡེར་བྲེལ་བཞིན་འདུག་པས། བདེ་འཇགས་ངང་ཕྱིར་བཏོན་ཐབས་བྲལ། + + + + DeepinStorage + + %1 Volume + བམ་པོ་%1  + + + + DiskControlItem + + Unknown + མི་ཤེས་པ། + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + སྒྲིག་ཆས་རྒྱུན་གཏན་ངང་སྤོ་འབུད་བྱས་མེད། + + + Click "Safely Remove" and then disconnect it next time + “བདེ་འཇགས་སྤོ་འབུད་”མནན་རྗེས། མུ་མཐུད་འབྲེལ་མཐུད་བྱེད་མཚམས་འཇོག་རྒྱུ། + + + Cannot unmount the device + སྒྲིག་ཆས་བཤིག་འདོན་བྱེད་ཐབས་བྲལ། + + + The disk is mounted by user "%1", you cannot unmount it. + སྡུད་སྡེར་ནི་སྤྱོད་མཁན་“%1”གྱིས་བཅུག་པས། ཁྱོད་ལ་བཤིག་འདོན་བྱེད་དབང་མེད། + + + Cannot find the mounted device + བབ་མཚུངས་ཀྱི་འགེལ་ཆས་རྙེད་མ་བྱུང་། + + + Disks + སྡུད་སྡེར། + + + + DiskMountPlugin + + Disk + སྡུད་སྡེར། + + + Open + ཁ་འབྱེད་པ། + + + Eject all + ཚང་མ་ཕྱིར་འདོན་བྱེད་པ། + + + + QObject + + The device has been safely removed + སྒྲིག་ཆས་བདེ་འཇགས་ངང་སྤོ་འབུད་བྱས་སོང་། + + + Access denied + ཀློག་མི་རུང་བ་དང་འབྲི་མི་རུང་བ། + + + You do not have permission to access this folder + ཁྱོད་ལ་ཡིག་ཁུག་འདི་ཀློག་དབང་མེད། + + + Scanning the device, stop it? + མིག་སྔའི་སྒྲིག་ཆས་བཤར་འབེབས་བཞིན་ཡོད་པས། བཤེར་འབེབས་མཚམས་འཇོག་རྒྱུ་ཡིན་ནམ། + + + Confirm + button + ཆོག + + + Cancel + button + འདོར་བ། + + + Stop + button + མཚམས་འཇོགས། + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ca.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ca.ts new file mode 100644 index 0000000..7faf547 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ca.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + S'ha esgotat el temps d'espera de l'autenticació. + + + Disk is busy, cannot unmount now + El disc està ocupat. No es pot desmuntar ara. + + + Disk is busy, cannot eject now + El disc està ocupat. No es pot extreure ara. + + + The device is busy, cannot eject now + El dispositiu està ocupat. No es pot extreure ara. + + + The device is busy, cannot remove now + El dispositiu està ocupat. No es pot suprimir ara. + + + + DeepinStorage + + %1 Volume + Volum: %1 + + + + DiskControlItem + + Unknown + Desconegut + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + El dispositiu no s'ha extret amb seguretat. + + + Click "Safely Remove" and then disconnect it next time + A la propera, cliqueu a "Extreu-lo amb seguretat" i després desconnecteu-lo. + + + Cannot unmount the device + No es pot desmuntar el dispositiu. + + + The disk is mounted by user "%1", you cannot unmount it. + El disc està muntat per l'usuari %1, no podeu desmuntar-lo. + + + Cannot find the mounted device + No es pot trobar el dispositiu muntat. + + + Disks + Discs + + + + DiskMountPlugin + + Disk + Disc + + + Open + Obre + + + Eject all + Extreu-ho tot + + + + QObject + + The device has been safely removed + El dispositiu s'ha extret amb seguretat. + + + Access denied + Accés denegat + + + You do not have permission to access this folder + No teniu permís per accedir a aquesta carpeta. + + + Scanning the device, stop it? + S'escaneja el dispositiu. Voleu interrompre-ho? + + + Confirm + button + Confirmeu-ho + + + Cancel + button + Cancel·la + + + Stop + button + Interromp + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_cs.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_cs.ts new file mode 100644 index 0000000..e259a4a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_cs.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Překročen časový limit pro ověření se + + + Disk is busy, cannot unmount now + Disk je zaneprázdněn, nyní ho proto nelze odpojit + + + Disk is busy, cannot eject now + Disk je zaneprázdněn, nyní ho proto nelze vysunout + + + The device is busy, cannot eject now + Zařízení je něčím využíváno, proto ho nyní není možné vysunout + + + The device is busy, cannot remove now + Zařízení je něčím využíváno, proto ho není možné nyní odebrat + + + + DeepinStorage + + %1 Volume + %1 svazek + + + + DiskControlItem + + Unknown + Neznámý + + + + DiskControlWidget + + dde-file-manager + Správce souborů + + + The device was not safely removed + Zařízení nebylo bezpečně odebráno + + + Click "Safely Remove" and then disconnect it next time + Příště klepněte na „Bezpečně odebrat“, a až pak odpojte + + + Cannot unmount the device + Zařízení se nedaří odpojit + + + The disk is mounted by user "%1", you cannot unmount it. + Disk je připojený (mount) uživatelem „%1“ – vy ho odpojit nemůžete. + + + Cannot find the mounted device + Nedaří se nalézt připojené zařízení + + + Disks + Disky + + + + DiskMountPlugin + + Disk + Disk + + + Open + Otevřít + + + Eject all + Vysunout vše + + + + QObject + + The device has been safely removed + Zařízení je možné bezpečně odebrat + + + Access denied + Přístup odepřen + + + You do not have permission to access this folder + Nemáte oprávnění pro přistupování k této složce + + + Scanning the device, stop it? + Prohledává se zařízení. Zastavit? + + + Confirm + button + Potvrdit + + + Cancel + button + Zrušit + + + Stop + button + Zastavit + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_da.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_da.ts new file mode 100644 index 0000000..186df47 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_da.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + %1-diskområde + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + Disken er i brug. Kan ikke skubbe ud nu + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + Disk + + + + Open + Åbn + + + + Unmount all + Afmontér alle + + + + QObject + + + Device has been removed + Enheden er blevet fjernet + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_de.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_de.ts new file mode 100644 index 0000000..a5be43a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_de.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Zeitüberschreitung bei der Authentifizierung + + + Disk is busy, cannot unmount now + Laufwerk wird verwendet, es kann jetzt nicht ausgehängt werden + + + Disk is busy, cannot eject now + Datenträger wird verwendet, er kann jetzt nicht ausgeworfen werden + + + The device is busy, cannot eject now + Das Gerät ist beschäftigt, kann jetzt nicht ausgeworfen werden + + + The device is busy, cannot remove now + Das Gerät ist beschäftigt, kann jetzt nicht entfernt werden + + + + DeepinStorage + + %1 Volume + %1 Laufwerk + + + + DiskControlItem + + Unknown + Unbekannt + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Das Gerät wurde nicht sicher entfernt + + + Click "Safely Remove" and then disconnect it next time + Klicke auf „Sicher entfernen“ und trenne die Verbindung dann beim nächsten Mal + + + Cannot unmount the device + Kann das Gerät nicht aushängen + + + The disk is mounted by user "%1", you cannot unmount it. + Das Laufwerk ist vom Benutzer „%1“ eingehängt, Sie können es nicht aushängen. + + + Cannot find the mounted device + Kann das eingehängte Gerät nicht finden + + + Disks + Laufwerke + + + + DiskMountPlugin + + Disk + Laufwerk + + + Open + Öffnen + + + Eject all + Alle auswerfen + + + + QObject + + The device has been safely removed + Das Gerät wurde sicher entfernt + + + Access denied + Zugriff verweigert + + + You do not have permission to access this folder + Sie haben keine Berechtigung, um auf diesen Ordner zuzugreifen + + + Scanning the device, stop it? + + + + Confirm + button + Bestätigen + + + Cancel + button + Abbrechen + + + Stop + button + Stopp + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_el.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_el.ts new file mode 100644 index 0000000..aae5d86 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_el.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + %1 Ένταση + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + Δίσκος + + + + Open + Άνοιγμα + + + + Unmount all + Αποχώρηση όλων + + + + QObject + + + Device has been removed + Η συσκευή έχει αφαιρεθεί + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_es.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_es.ts new file mode 100644 index 0000000..b7f3a6f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_es.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + El tiempo para autenticarse agotado + + + Disk is busy, cannot unmount now + El disco está en uso, no se puede desmontar ahora + + + Disk is busy, cannot eject now + El disco está en uso, no se puede expulsar ahora + + + The device is busy, cannot eject now + El disco está ocupado, no se puede expulsar ahora + + + The device is busy, cannot remove now + El dispositivo está ocupado, no se puede quitar ahora + + + + DeepinStorage + + %1 Volume + Volumen %1 + + + + DiskControlItem + + Unknown + Desconocido + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + El dispositivo no fue retirado de forma segura + + + Click "Safely Remove" and then disconnect it next time + Clic en «Extraer del equipo» y luego desconéctelo + + + Cannot unmount the device + No se puede desmontar el dispositivo + + + The disk is mounted by user "%1", you cannot unmount it. + El disco fue montado por el usuario «%1», no puedes desmontarlo. + + + Cannot find the mounted device + No puedo encontrar el dispositivo montado + + + Disks + Discos + + + + DiskMountPlugin + + Disk + Disco + + + Open + Abrir + + + Eject all + Expulsar todo + + + + QObject + + The device has been safely removed + El dispositivo ha sido retirado de forma segura + + + Access denied + Acceso denegado + + + You do not have permission to access this folder + No tienes permiso para acceder a esta carpeta + + + Scanning the device, stop it? + Disco bajo escaneo, ¿desea detenerlo? + + + Confirm + button + Confirmar + + + Cancel + button + Cancelar + + + Stop + button + Detener + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_fa.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_fa.ts new file mode 100644 index 0000000..d0481b2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_fa.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + %1 حجم + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + دیسک + + + + Open + باز کردن + + + + Unmount all + لغو همه + + + + QObject + + + Device has been removed + دستگاه حذف شده است + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_fi.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_fi.ts new file mode 100644 index 0000000..59d1e7c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_fi.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Todennus aikakatkaistiin + + + Disk is busy, cannot unmount now + Levy on varattu, ei voi irrottaa + + + Disk is busy, cannot eject now + Levy varattu, ei voi poistaa nyt + + + The device is busy, cannot eject now + Laite on varattu, eikä sitä voi avata + + + The device is busy, cannot remove now + Laite on varattu, eikä sitä voi poistaa + + + + DeepinStorage + + %1 Volume + %1 Asema + + + + DiskControlItem + + Unknown + Tuntematon + + + + DiskControlWidget + + dde-file-manager + dde-file-manager-tiedosto-hallinta + + + The device was not safely removed + Laitetta ei poistettu turvallisesti + + + Click "Safely Remove" and then disconnect it next time + Napsauta ensin "Poista turvallisesti" ja irrota se sitten + + + Cannot unmount the device + Laitteen irrottaminen ei onnistu + + + The disk is mounted by user "%1", you cannot unmount it. + Levyä käyttää käyttäjä "%1", et voi irrottaa sitä. + + + Cannot find the mounted device + Liitettyä laitetta ei löydy + + + Disks + Levyt + + + + DiskMountPlugin + + Disk + Levy + + + Open + Avaa + + + Eject all + Irroita kaikki + + + + QObject + + The device has been safely removed + Laite on poistettu turvallisesti + + + Access denied + Pääsy evätty + + + You do not have permission to access this folder + Sinulla ei ole oikeutta käyttää tätä kansiota + + + Scanning the device, stop it? + Skannaa laitetta, pysäytä se? + + + Confirm + button + Vahvista + + + Cancel + button + Peruuta + + + Stop + button + Seis + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_fr.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_fr.ts new file mode 100644 index 0000000..ddc3ef7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_fr.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + L'authentification a expiré + + + Disk is busy, cannot unmount now + Le disque est occupé, et ne peut donc pas être démonté maintenant + + + Disk is busy, cannot eject now + Le disque est occupé, impossible de l'éjecter maintenant + + + The device is busy, cannot eject now + L'appareil est occupé et ne peut pas être éjecté maintenant + + + The device is busy, cannot remove now + L'appareil est occupé et ne peut pas être retiré maintenant + + + + DeepinStorage + + %1 Volume + %1 Volume + + + + DiskControlItem + + Unknown + Inconnu + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Le périphérique n'a pas été retiré en toute sécurité + + + Click "Safely Remove" and then disconnect it next time + Cliquez sur "Supprimer en toute sécurité" et ensuite déconnectez-le + + + Cannot unmount the device + Impossible de démonter l'appareil + + + The disk is mounted by user "%1", you cannot unmount it. + Le disque est monté par l'utilisateur "% 1", vous ne pouvez pas le démonter. + + + Cannot find the mounted device + Impossible de trouver le périphérique monté + + + Disks + Disques + + + + DiskMountPlugin + + Disk + Disque + + + Open + Ouvrir + + + Eject all + Tout éjecter + + + + QObject + + The device has been safely removed + L'appareil a été retiré en toute sécurité + + + Access denied + Accès refusé + + + You do not have permission to access this folder + Vous n'êtes pas autorisé à accéder à ce dossier + + + Scanning the device, stop it? + Scanner l'appareil, l'arrêter ? + + + Confirm + button + Confirmer + + + Cancel + button + Annuler + + + Stop + button + Arrêter + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_hi_IN.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_hi_IN.ts new file mode 100644 index 0000000..6d36911 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_hi_IN.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + %1 वॉल्यूम + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + डिस्क + + + + Open + खोलें + + + + Unmount all + सभी को माउंट से हटाएँ + + + + QObject + + + Device has been removed + डिवाइस को हटा दिया गया है + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_hr.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_hr.ts new file mode 100644 index 0000000..fb3527d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_hr.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + + + + Disk is busy, cannot unmount now + Disk je zauzet, ne mogu sada odmontirati + + + Disk is busy, cannot eject now + Disk je zauzet, ne mogu sada izbaciti + + + The device is busy, cannot eject now + Uređaj je zauzet, ne mogu sada izbaciti + + + The device is busy, cannot remove now + Uređaj je zauzet, ne mogu sada ukloniti + + + + DeepinStorage + + %1 Volume + + + + + DiskControlItem + + Unknown + Nepoznato + + + + DiskControlWidget + + dde-file-manager + dde-upravitelj-datotekama + + + The device was not safely removed + Uređaj nije sigurno uklonjen + + + Click "Safely Remove" and then disconnect it next time + Klikni "Sigurno ukloni" i odspoji ga slijedeći put + + + Cannot unmount the device + Ne mogu odmontirati uređaj + + + The disk is mounted by user "%1", you cannot unmount it. + Disk je montirao korisnik "%1", vi ga ne možete odmontirati. + + + Cannot find the mounted device + Ne mogu naći montirani uređaj + + + Disks + Diskovi + + + + DiskMountPlugin + + Disk + Disk + + + Open + Otvori + + + Eject all + Izbaci sve + + + + QObject + + The device has been safely removed + Uređaj je sigurno uklonjen + + + Access denied + Pristup odbijen + + + You do not have permission to access this folder + Nemate dozvole za pristup ovoj mapi + + + Scanning the device, stop it? + Skeniram uređaj, prestati? + + + Confirm + button + Potvrdi + + + Cancel + button + Otkaži + + + Stop + button + Zaustavi + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_hu.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_hu.ts new file mode 100644 index 0000000..9892511 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_hu.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + A hitelesítés lejárt + + + Disk is busy, cannot unmount now + A lemez használatban van, jelenleg nem választható le + + + Disk is busy, cannot eject now + A lemez használatban van, jelenleg nem választható le + + + The device is busy, cannot eject now + Az eszköz használatban van, jelenleg nem választható le + + + The device is busy, cannot remove now + Az eszköz használatban van, jelenleg nem távolítható el + + + + DeepinStorage + + %1 Volume + %1 kötet + + + + DiskControlItem + + Unknown + Ismeretlen + + + + DiskControlWidget + + dde-file-manager + dde-fájlkezelő + + + The device was not safely removed + Az eszközt nem sikerült biztonságosan eltávolítani + + + Click "Safely Remove" and then disconnect it next time + Kattintson a "Biztonságos eltávolítás" gombra, majd csatlakoztassa le később + + + Cannot unmount the device + Eszköz nem leválasztható + + + The disk is mounted by user "%1", you cannot unmount it. + A lemez "%1" felhasználó által felcsatolva, a leválasztása nem lehetséges. + + + Cannot find the mounted device + Nem található a csatlakoztatott eszköz + + + Disks + Lemezek + + + + DiskMountPlugin + + Disk + Lemez + + + Open + Megnyitás + + + Eject all + Az összes kiadása + + + + QObject + + The device has been safely removed + Az eszköz biztonságosan eltávolítva + + + Access denied + Hozzáférés megtagadva + + + You do not have permission to access this folder + Nincs jogosultsága a mappához való hozzáféréséhez + + + Scanning the device, stop it? + Az eszköz ellenőrzése, biztos benne hogy leállítja? + + + Confirm + button + Megerősítés + + + Cancel + button + Mégsem + + + Stop + button + Leállítás + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_id.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_id.ts new file mode 100644 index 0000000..19d412e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_id.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + 1% Volume + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + Diska + + + + Open + Buka + + + + Unmount all + Lepaskan semua + + + + QObject + + + Device has been removed + Piranti telah dilepas + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_it.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_it.ts new file mode 100644 index 0000000..00f2d04 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_it.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Autenticazione scaduta + + + Disk is busy, cannot unmount now + Disco occupato, impossibile smontare + + + Disk is busy, cannot eject now + Disco occupato, impossibile espellerlo ora + + + The device is busy, cannot eject now + Disco occupato, impossibile espellerlo ora + + + The device is busy, cannot remove now + Disco occupato, impossibile espellerlo ora + + + + DeepinStorage + + %1 Volume + %1 Volume + + + + DiskControlItem + + Unknown + Sconosciuto + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Il dispositivo non è stato rimosso in sicurezza + + + Click "Safely Remove" and then disconnect it next time + Clicca su "Rimozione sicura" e rimuovilo solo successivamente + + + Cannot unmount the device + Impossibile smontare il dispositivo + + + The disk is mounted by user "%1", you cannot unmount it. + Il disco è stato montato dall'utente "%1", non puoi smontarlo. + + + Cannot find the mounted device + Impossibile trovare il dispositivo montato + + + Disks + Dischi + + + + DiskMountPlugin + + Disk + Disco + + + Open + Apri + + + Eject all + Espelli tutto + + + + QObject + + The device has been safely removed + Il dispositivo è stato rimosso in sicurezza + + + Access denied + Accesso negato + + + You do not have permission to access this folder + Non hai i permessi per accedere a questa cartella + + + Scanning the device, stop it? + Scansione del dispositivo in corso, interromperla? + + + Confirm + button + Conferma + + + Cancel + button + Annulla + + + Stop + button + Stop + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ja.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ja.ts new file mode 100644 index 0000000..03af2b7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ja.ts @@ -0,0 +1,89 @@ + + + DeepinStorage + + %1 Volume + %1 ボリューム + + + + DiskControlItem + + Unknown + 不明 + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + デバイスが安全に取り外されませんでした + + + Click "Safely Remove" and then disconnect it next time + 次回は "安全に取り出す" をクリックしてから切断してください + + + The device is busy, cannot eject now + + + + The device is busy, cannot remove now + + + + Cannot unmount the device + デバイスのマウントを解除できません + + + The disk is mounted by user "%1", you cannot unmount it. + ディスクがユーザー "%1" によってマウントされているため、マウントを解除することができません。 + + + Cannot find the mounted device + + + + Disks + ディスク + + + + DiskMountPlugin + + Disk + ディスク + + + Open + 開く + + + Eject all + すべて取り出す + + + + QObject + + The device has been safely removed + デバイスが安全に取り出されました + + + Access denied + アクセス拒否 + + + You do not have permission to access this folder + このフォルダーにアクセスする権限がありません + + + Confirm + 確定 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_km_KH.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_km_KH.ts new file mode 100644 index 0000000..447b5e4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_km_KH.ts @@ -0,0 +1,49 @@ + + + DeepinStorage + + %1 Volume + %1 កម្រិតសំឡេង + + + + DiskControlItem + + Unknown + + + + + DiskControlWidget + + Disk is busy, cannot eject now + ថាសបានជាប់រវល់, មិនអាចដកចេញឥឡូវបានទេ + + + dde-file-manager + dde-កម្មវិធី​គ្រប់​គ្រង​ឯកសារ + + + + DiskMountPlugin + + Disk + ថាស + + + Open + បើក + + + Unmount all + Unmount ទំាងអស់ + + + + QObject + + Device has been removed + ឧបករណ៍ត្រូវបានដកចេញ + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ko.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ko.ts new file mode 100644 index 0000000..905cc49 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ko.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + %1 볼륨 + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + 디스크 + + + + Open + 열기 + + + + Unmount all + 모두 마운트 해제 + + + + QObject + + + Device has been removed + 장치가 제거됨 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_lt.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_lt.ts new file mode 100644 index 0000000..24e63d1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_lt.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + %1 tomas + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + Diskas yra užimtas, dabar negalima išstumti + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + Diskas + + + + Open + Atverti + + + + Unmount all + Atjungti visus + + + + QObject + + + Device has been removed + Įrenginys pašalintas + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ms.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ms.ts new file mode 100644 index 0000000..c0c2a22 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ms.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Pengesahihan telah tamat masa + + + Disk is busy, cannot unmount now + Cakera sibuk, tidak dapat ditanggalkan sekarang + + + Disk is busy, cannot eject now + Cakera sibuk, tidak dapat ditanggalkan sekarang + + + The device is busy, cannot eject now + Peranti masih sibuk, tidak dapat lentingkan sekarang + + + The device is busy, cannot remove now + Peranti masih sibuk, tidak dapat tanggalkan sekarang + + + + DeepinStorage + + %1 Volume + Volum %1 + + + + DiskControlItem + + Unknown + Tidak diketahui + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Peranti masih tidak selamat ditanggalkan + + + Click "Safely Remove" and then disconnect it next time + Klik "Tanggal secara Selamat" dan kemudian putuskannya di lain masa + + + Cannot unmount the device + Tidak dapat menanggalkan peranti + + + The disk is mounted by user "%1", you cannot unmount it. + Cakera dilekap oleh pengguna "%1", anda tidak dapat menyahlekapkannya. + + + Cannot find the mounted device + Tidak dapat cari peranti dilekap + + + Disks + Cakera-Cakera + + + + DiskMountPlugin + + Disk + Cakera + + + Open + Buka + + + Eject all + Lenting semua + + + + QObject + + The device has been safely removed + Peranti telah selamat ditanggalkan + + + Access denied + Capaian dinafikan + + + You do not have permission to access this folder + Anda tidak mempunyai keizinan untuk mencapai folder ini + + + Scanning the device, stop it? + Mengimbas peranti, hentikannya? + + + Confirm + button + Sahkan + + + Cancel + button + Batal + + + Stop + button + Henti + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_nb.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_nb.ts new file mode 100644 index 0000000..a6337b5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_nb.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + %1 Volume + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + Disk + + + + Open + Åpne + + + + Unmount all + Avmonter alle + + + + QObject + + + Device has been removed + Enheten har blitt fjernet + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ne.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ne.ts new file mode 100644 index 0000000..4d00f40 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ne.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + % 1 खण्ड + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + डिस्क व्यस्त छ, भर्खरै निकाल्न सक्दैन + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + डिस्क + + + + Open + खोल्नुहोस् + + + + Unmount all + सबै अनमाउन्ट गर्नुहोस् + + + + QObject + + + Device has been removed + उपकरण हटाईएको छ + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_nl.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_nl.ts new file mode 100644 index 0000000..b0e4e65 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_nl.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + De authenticatie is verlopen + + + Disk is busy, cannot unmount now + Schijf is in gebruik; je kunt nu niet afkoppelen + + + Disk is busy, cannot eject now + Schijf is in gebruik; je kunt nu niet uitwerpen + + + The device is busy, cannot eject now + Schijf is in gebruik; je kunt nu niet uitwerpen + + + The device is busy, cannot remove now + Schijf is in gebruik; je kunt nu niet afkoppelen + + + + DeepinStorage + + %1 Volume + Volume %1 + + + + DiskControlItem + + Unknown + Onbekend + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Het apparaat is niet veilig verwijderd + + + Click "Safely Remove" and then disconnect it next time + Klik voortaan op ‘Veilig verwijderen’ voordat je het apparaat loskoppelt + + + Cannot unmount the device + Kan apparaat niet afkoppelen + + + The disk is mounted by user "%1", you cannot unmount it. + De schijf is aangekoppeld door gebruiker "%1". Je kunt deze daarom niet afkoppelen. + + + Cannot find the mounted device + Het aangekoppelde apparaat is niet aangetroffen + + + Disks + Schijven + + + + DiskMountPlugin + + Disk + Schijf + + + Open + Openen + + + Eject all + Alles uitwerpen + + + + QObject + + The device has been safely removed + Het apparaat is veilig verwijderd + + + Access denied + Toegang geweigerd + + + You do not have permission to access this folder + Je bent niet bevoegd om deze map te openen + + + Scanning the device, stop it? + Wil je het doorzoeken van het apparaat afbreken? + + + Confirm + button + Oké + + + Cancel + button + Annuleren + + + Stop + button + Afbreken + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_pl.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_pl.ts new file mode 100644 index 0000000..16936f9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_pl.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Upłynął limit czasu uwierzytelniania + + + Disk is busy, cannot unmount now + Dysk jest zajęty, nie można teraz odmontować + + + Disk is busy, cannot eject now + Dysk jest zajęty, nie można go teraz wysunąć + + + The device is busy, cannot eject now + Urządzenie jest zajęte, nie można go teraz wysunąć + + + The device is busy, cannot remove now + Urządzenie jest zajęte, nie można go teraz wyjąć + + + + DeepinStorage + + %1 Volume + Volumen %1 + + + + DiskControlItem + + Unknown + Nieznany + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Urządzenie nie zostało bezpiecznie usunięte + + + Click "Safely Remove" and then disconnect it next time + Kliknij „Bezpieczne usuwanie”, a następnie odłącz go następnym razem + + + Cannot unmount the device + Nie można odmontować urządzenia + + + The disk is mounted by user "%1", you cannot unmount it. + Dysk został zamontowany przez użytkownika "%1", nie możesz go wymontować. + + + Cannot find the mounted device + Nie można odnaleźć podpiętego urządzenia + + + Disks + Dyski + + + + DiskMountPlugin + + Disk + Dysk + + + Open + Otwórz + + + Eject all + Wyrzuć wszystko + + + + QObject + + The device has been safely removed + Urządzenie zostało bezpiecznie usunięte + + + Access denied + Zakaz dostępu + + + You do not have permission to access this folder + Nie masz uprawnień do dostępu do tego katalogu + + + Scanning the device, stop it? + Skanowanie urządzenia, zatrzymać? + + + Confirm + button + Potwierdź + + + Cancel + button + Anuluj + + + Stop + button + Stop + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_pt.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_pt.ts new file mode 100644 index 0000000..831dda7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_pt.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Autenticação expirou + + + Disk is busy, cannot unmount now + O disco está ocupado, não pode ser desmontado agora + + + Disk is busy, cannot eject now + O disco está ocupado, não pode ser ejectado agora + + + The device is busy, cannot eject now + O dispositivo está ocupado, não é possível ejectar agora + + + The device is busy, cannot remove now + O dispositivo está ocupado, não é possível remover agora + + + + DeepinStorage + + %1 Volume + %1 Volume + + + + DiskControlItem + + Unknown + Desconhecido + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + O dispositivo não foi removido em segurança + + + Click "Safely Remove" and then disconnect it next time + Clique em "Remover em segurança" e retire-o da próxima vez + + + Cannot unmount the device + Não é possível desmontar o dispositivo + + + The disk is mounted by user "%1", you cannot unmount it. + O disco foi montado pelo utilizador "%1", não o pode desmontar. + + + Cannot find the mounted device + Não é possível localizar o dispositivo montado + + + Disks + Discos + + + + DiskMountPlugin + + Disk + Disco + + + Open + Abrir + + + Eject all + Ejectar tudo + + + + QObject + + The device has been safely removed + O dispositivo foi removido com segurança + + + Access denied + Acesso negado + + + You do not have permission to access this folder + Não tem autorização para aceder a esta pasta + + + Scanning the device, stop it? + A analisar o dispositivo, interromper? + + + Confirm + button + Confirmar + + + Cancel + button + Cancelar + + + Stop + button + Parar + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_pt_BR.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_pt_BR.ts new file mode 100644 index 0000000..a5aa4f1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_pt_BR.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + A autenticação expirou + + + Disk is busy, cannot unmount now + O disco está ocupado; impossível desmontá-lo + + + Disk is busy, cannot eject now + O disco está ocupado; impossível ejetá-lo + + + The device is busy, cannot eject now + O dispositivo está ocupado; impossível ejetá-lo + + + The device is busy, cannot remove now + O dispositivo está ocupado; impossível removê-lo + + + + DeepinStorage + + %1 Volume + Volume de %1 + + + + DiskControlItem + + Unknown + Desconhecido + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + O dispositivo não foi removido com segurança + + + Click "Safely Remove" and then disconnect it next time + Clique em "Remover com segurança" e então desconecte-o na próxima vez + + + Cannot unmount the device + Impossível desmontar o dispositivo + + + The disk is mounted by user "%1", you cannot unmount it. + O disco foi montado pelo usuário "%1"; e você não pode desmontá-lo. + + + Cannot find the mounted device + Impossível encontrar o dispositivo montado + + + Disks + Dispositivos + + + + DiskMountPlugin + + Disk + Disco + + + Open + Abrir + + + Eject all + Ejetar tudo + + + + QObject + + The device has been safely removed + O dispositivo foi removido com segurança + + + Access denied + Acesso negado + + + You do not have permission to access this folder + Você não tem permissão para acessar esta pasta + + + Scanning the device, stop it? + Verificando o dispositivo, parar? + + + Confirm + button + Confirmar + + + Cancel + button + Cancelar + + + Stop + button + Parar + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ro.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ro.ts new file mode 100644 index 0000000..586e8ac --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ro.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Timpul de autentificare a expirat + + + Disk is busy, cannot unmount now + Disc ocupat, nu poate fi demontat la moment + + + Disk is busy, cannot eject now + Disc ocupat, nu poate fi eliminat acum + + + The device is busy, cannot eject now + Dispozitivul este ocupat, nu poate fi scos acum + + + The device is busy, cannot remove now + Dispozitivul este ocupat, nu poate fi eliminat acum + + + + DeepinStorage + + %1 Volume + %1 Volum + + + + DiskControlItem + + Unknown + Necunoscut + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Dispozitivul nu a fost deconectat în mod sigur + + + Click "Safely Remove" and then disconnect it next time + Clic pe „Eliminare sigură” și apoi deconectați data viitoare + + + Cannot unmount the device + Dispozitivul nu poate fi deconectat + + + The disk is mounted by user "%1", you cannot unmount it. + Discul este montat de către utilizatorul „%1”, dvs. nu îl puteți demonta. + + + Cannot find the mounted device + Nu se poate găsi dispozitivul montat + + + Disks + Discuri + + + + DiskMountPlugin + + Disk + Disc + + + Open + Deschide + + + Eject all + Scoateți toate + + + + QObject + + The device has been safely removed + Dispozitivul a fost îndepărtat în mod sigur + + + Access denied + Acces interzis + + + You do not have permission to access this folder + Nu aveți permisiunea de a accesa acest directoriu + + + Scanning the device, stop it? + Scanarea dispozitivului, oprire? + + + Confirm + button + Confirmare + + + Cancel + button + Anulare + + + Stop + button + Oprire + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ru.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ru.ts new file mode 100644 index 0000000..429bdc3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ru.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Истекло время аутентификации + + + Disk is busy, cannot unmount now + Диск занят, не могу отмонтировать сейчас + + + Disk is busy, cannot eject now + Диск занят и не может быть извлечён сейчас + + + The device is busy, cannot eject now + Устройство занято и не может быть извлечено сейчас + + + The device is busy, cannot remove now + Устройство занято, сейчас извлечь нельзя + + + + DeepinStorage + + %1 Volume + %1 Объём + + + + DiskControlItem + + Unknown + Неизвестно + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Устройство не было безопасно извлечено + + + Click "Safely Remove" and then disconnect it next time + В следующий раз сначала нажмите "Безопасное извлечение", а затем отключите устройство + + + Cannot unmount the device + Невозможно отключить устройство + + + The disk is mounted by user "%1", you cannot unmount it. + Диск смонтирован пользователем "%1", вы не сможете его размонтировать. + + + Cannot find the mounted device + Не удается найти подключенное устройство + + + Disks + Диски + + + + DiskMountPlugin + + Disk + Диск + + + Open + Открыть + + + Eject all + Извлечь все + + + + QObject + + The device has been safely removed + Устройство было безопасно извлечено + + + Access denied + Доступ запрещен + + + You do not have permission to access this folder + У вас нет права доступа к этой папке + + + Scanning the device, stop it? + Сканирование устройства, остановить его? + + + Confirm + button + Подтвердить + + + Cancel + button + Отмена + + + Stop + button + Стоп + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sk.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sk.ts new file mode 100644 index 0000000..0ae57a2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sk.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + %1 oddiel + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + Disk + + + + Open + Otvoriť + + + + Unmount all + Odpojiť všetko + + + + QObject + + + Device has been removed + Zariadenie bolo odstránené + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sl.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sl.ts new file mode 100644 index 0000000..ec58756 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sl.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Čas za overitev je potekel + + + Disk is busy, cannot unmount now + Disk je v rabi. Trenutno ga ni mogoče odklopiti + + + Disk is busy, cannot eject now + Disk deluje in ga trenutno ni mogoče varno odstraniti + + + The device is busy, cannot eject now + Naprava je v rabi in je trenutno ni mogoče izvreči + + + The device is busy, cannot remove now + Naprava je v rabi n je trenutno ni mogoče odstraniti + + + + DeepinStorage + + %1 Volume + %1 Glasnost + + + + DiskControlItem + + Unknown + Neznano + + + + DiskControlWidget + + dde-file-manager + dde-upravitelj-datotek + + + The device was not safely removed + Naprava ni bila varno odstranjena + + + Click "Safely Remove" and then disconnect it next time + Klikni "Varno odstrani" in nato odstranite + + + Cannot unmount the device + Naprave ni mogoče odklopiti + + + The disk is mounted by user "%1", you cannot unmount it. + Disk je priklopil uporabnik "%1", ne morete ga odklopiti. + + + Cannot find the mounted device + Priklopljene naprave ni mogoče najti + + + Disks + Diski + + + + DiskMountPlugin + + Disk + Disk + + + Open + Odpri + + + Eject all + Izvrzi vse + + + + QObject + + The device has been safely removed + Naprava je bila varno odstranjena + + + Access denied + Zavrnjen dostop + + + You do not have permission to access this folder + Nimate dovoljenja za dostopanje do te mape + + + Scanning the device, stop it? + Preverjanje naprave. Zaustavim? + + + Confirm + button + Potrdi + + + Cancel + button + Prekini + + + Stop + button + Zaustavi + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sq.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sq.ts new file mode 100644 index 0000000..466aef2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sq.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Mirëfilltësimit i mbaroi koha + + + Disk is busy, cannot unmount now + Disku është i zënë, s’mund të çmontohet tani + + + Disk is busy, cannot eject now + Disku është i zënë, s’mund të nxirret + + + The device is busy, cannot eject now + Pajisja është e zënë, s’mund të nxirret tani + + + The device is busy, cannot remove now + Pajisja është e zënë, s’mund të hiqet tani + + + + DeepinStorage + + %1 Volume + Vëllim %1 + + + + DiskControlItem + + Unknown + I panjohur + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Pajisja s’u hoq në mënyrë të parrezik + + + Click "Safely Remove" and then disconnect it next time + Herës tjetër klikoni mbi “Hiqe Në Mënyrë të Parrezik” dhe mandej shkëputeni + + + Cannot unmount the device + Nuk çmontohet dot pajisja + + + The disk is mounted by user "%1", you cannot unmount it. + Disku është montuar nga përdoruesi "%1", s’mund ta çmontoni. + + + Cannot find the mounted device + S’gjendet pajisje e montuar + + + Disks + Disqe + + + + DiskMountPlugin + + Disk + Disk + + + Open + Hap + + + Eject all + Nxirri krejt + + + + QObject + + The device has been safely removed + Pajisja u hoq në mënyrë të parrezik + + + Access denied + Hyrja u mohua + + + You do not have permission to access this folder + S’keni leje të hyni te kjo dosje + + + Scanning the device, stop it? + Po skanohet pajisja, të ndalet? + + + Confirm + button + Ripohojeni + + + Cancel + button + Anuloje + + + Stop + button + Ndale + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sr.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sr.ts new file mode 100644 index 0000000..a3f5631 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sr.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Време за идентификацију је истекло + + + Disk is busy, cannot unmount now + Диск је у употреби, тренутно се не може демонтирати + + + Disk is busy, cannot eject now + Диск је у употреби, тренутно се не може избацити + + + The device is busy, cannot eject now + Уређај је заузет, не може се избацити + + + The device is busy, cannot remove now + Уређај је заузет, не може се уклонити + + + + DeepinStorage + + %1 Volume + %1 Логички диск + + + + DiskControlItem + + Unknown + Непознато + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Уређај није безбедно уклоњен + + + Click "Safely Remove" and then disconnect it next time + Следећи пут, кликните на "Безбедно уклони", затим уклоните уређај + + + Cannot unmount the device + Не могу да демонтирам уређај + + + The disk is mounted by user "%1", you cannot unmount it. + Диск је монтирао корисник "%1", не можете га демонтирати. + + + Cannot find the mounted device + Не могу да пронађем монтирани уређај + + + Disks + Дискови + + + + DiskMountPlugin + + Disk + Диск + + + Open + Отвори + + + Eject all + Избаци све + + + + QObject + + The device has been safely removed + Уређај је безбедно уклоњен + + + Access denied + Забрањен приступ + + + You do not have permission to access this folder + Немате дозволу да приступите овој фасцикли + + + Scanning the device, stop it? + Проверавање уређаја, зауставити? + + + Confirm + button + Потврди + + + Cancel + button + Откажи + + + Stop + button + Заустави + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sv.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sv.ts new file mode 100644 index 0000000..1c71b93 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_sv.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + %1 volym + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + Disk + + + + Open + Öppna + + + + Unmount all + Avmontera alla + + + + QObject + + + Device has been removed + Enheten har tagits bort + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ta.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ta.ts new file mode 100644 index 0000000..b4c2e49 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ta.ts @@ -0,0 +1,53 @@ + + + DeepinStorage + + + + %1 Volume + % 1 தொகுதி + + + + DiskControlWidget + + + + + + Disk is busy, cannot eject now + + + + + dde-file-manager + + + + + DiskMountPlugin + + + Disk + வட்டத் தகடு + + + + Open + திற + + + + Unmount all + அனைத்தையும் விலக்கு + + + + QObject + + + Device has been removed + சாதனம் அகற்றப்பட்டது + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_tr.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_tr.ts new file mode 100644 index 0000000..83d80d5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_tr.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Kimlik doğrulama zaman aşımı + + + Disk is busy, cannot unmount now + Disk meşgul olduğundan şu anda ayrılamıyor + + + Disk is busy, cannot eject now + Disk meşgul, şimdi çıkartılamıyor + + + The device is busy, cannot eject now + Aygıt meşgul, şimdi çıkarılamıyor + + + The device is busy, cannot remove now + Aygıt meşgul, şimdi çıkarılamaz + + + + DeepinStorage + + %1 Volume + %1 Birim + + + + DiskControlItem + + Unknown + Bilinmiyor + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Cihaz güvenli bir şekilde kaldırılmadı + + + Click "Safely Remove" and then disconnect it next time + Bir daha ki sefer "Güvenle Kaldıra" tıklayın bağlantısını kesin + + + Cannot unmount the device + Aygıtın bağı ayrılamadı + + + The disk is mounted by user "%1", you cannot unmount it. + Diski "%1" kullanıcısı bağlamış, siz bu bağı ayıramazsınız. + + + Cannot find the mounted device + Takılı aygıt bulunamıyor + + + Disks + Diskler + + + + DiskMountPlugin + + Disk + Disk + + + Open + + + + Eject all + Tümünü çıkar + + + + QObject + + The device has been safely removed + Cihaz güvenli bir şekilde kaldırıldı + + + Access denied + Erişim reddedildi + + + You do not have permission to access this folder + Bu klasöre erişme izniniz yok + + + Scanning the device, stop it? + Cihaz taranıyor, durdurulsun mu? + + + Confirm + button + Onayla + + + Cancel + button + İptal + + + Stop + button + Durdur + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ug.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ug.ts new file mode 100644 index 0000000..fe80e7b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_ug.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + دەلىللەش ۋاقتى ئۆتۈپ كەتتى + + + Disk is busy, cannot unmount now + دىسكا ھۆججىتى ئىگىلىۋېلىندى ، ئۆچۈرگىلى بولمايدۇ + + + Disk is busy, cannot eject now + دىسكا ئالدىراش ، ھازىر چىقىرىۋېتەلمەيدۇ + + + The device is busy, cannot eject now + دىسكا ئالدىراش ، ھازىر چىقىرىۋېتەلمەيدۇ + + + The device is busy, cannot remove now + دىسكا ئالدىراش ، ھازىر بىخەتەر چىقىرىۋېتەلمەيدۇ + + + + DeepinStorage + + %1 Volume + %1 رايۇن + + + + DiskControlItem + + Unknown + نامەلۇم + + + + DiskControlWidget + + dde-file-manager + ھۆججەت باشقۇرغۇچ + + + The device was not safely removed + ئۈسكۈنە نورمال ئۆچۈرۈلمىدى + + + Click "Safely Remove" and then disconnect it next time + «بىخەتەر ئۆچۈرۈش» نى باسقاندىن كېيىن ئۇلىنىشنى ئۈزۈڭ + + + Cannot unmount the device + ئۈسكۈنىنى چىقىرالمىدى + + + The disk is mounted by user "%1", you cannot unmount it. + دىسكىغا “%1” ئىشلەتكۈچى ئاغدۇرۇلغان، ئۆچۈرۈش ھوقۇقىڭىز يوق. + + + Cannot find the mounted device + ماس ئاغدۇرۇش ئۈسكۈنىسى تېپىلمىدى + + + Disks + دىسكا + + + + DiskMountPlugin + + Disk + دىسكا + + + Open + ئېچىش + + + Eject all + ھەممىسىنى چىقىرىش + + + + QObject + + The device has been safely removed + ئۈسكۈنە بىخەتەر ئۆچۈرۈلدى + + + Access denied + ئوقۇغىلى، يازغىلى بولمايدۇ + + + You do not have permission to access this folder + بۇ ھۆججەتنى ئوقۇش ھوقۇقىڭىز يوق + + + Scanning the device, stop it? + ئۈسكۈنە سايىلىنىۋاتىدۇ، سايىلەشنى توختىتامسىز؟ + + + Confirm + button + جەزملەشتۈرۈش + + + Cancel + button + بىكار قىلىش + + + Stop + button + توختىتىمەن + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_uk.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_uk.ts new file mode 100644 index 0000000..f1e7ef7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_uk.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + Перевищено час очікування на розпізнавання + + + Disk is busy, cannot unmount now + Диск зайнятий, його неможливо розмонтувати зараз + + + Disk is busy, cannot eject now + Диск зайнятий, зараз його неможливо вийняти + + + The device is busy, cannot eject now + Пристрій зайнято, його не можна виштовхнути зараз + + + The device is busy, cannot remove now + Пристрій зайнято, зараз вилучення неможливе + + + + DeepinStorage + + %1 Volume + Том %1 + + + + DiskControlItem + + Unknown + Невідомо + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + Пристрій не було безпечно вилучено + + + Click "Safely Remove" and then disconnect it next time + Наступного разу натисніть кнопку «Вилучити безпечно», а вже потім від'єднуйте пристрій + + + Cannot unmount the device + Не вдалося демонтувати пристрій + + + The disk is mounted by user "%1", you cannot unmount it. + Диск змонтовано користувачем %1, ви не можете розмонтувати його. + + + Cannot find the mounted device + Не вдалося знайти змонтований пристрій + + + Disks + Диски + + + + DiskMountPlugin + + Disk + Диск + + + Open + Відкрити + + + Eject all + Виштовхнути усі + + + + QObject + + The device has been safely removed + Пристрій було безпечно вилучено + + + Access denied + Доступ заборонено + + + You do not have permission to access this folder + У вас немає дозволу на доступ до цієї теки + + + Scanning the device, stop it? + Скануємо пристрій. Припинити? + + + Confirm + button + Підтвердити + + + Cancel + button + Скасувати + + + Stop + button + Припинити + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_zh_CN.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_zh_CN.ts new file mode 100644 index 0000000..a08fb22 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_zh_CN.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + 认证超时 + + + Disk is busy, cannot unmount now + 磁盘文件被占用,无法卸载 + + + Disk is busy, cannot eject now + 磁盘文件被占用,无法弹出 + + + The device is busy, cannot eject now + 光驱正忙,无法弹出 + + + The device is busy, cannot remove now + 设备正忙,无法安全移除 + + + + DeepinStorage + + %1 Volume + %1 卷 + + + + DiskControlItem + + Unknown + 未知 + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + 设备没有正常移除 + + + Click "Safely Remove" and then disconnect it next time + 请点击“安全移除”后,再断开连接 + + + Cannot unmount the device + 无法卸载设备 + + + The disk is mounted by user "%1", you cannot unmount it. + 磁盘由用户“%1”挂载,您没有卸载权限。 + + + Cannot find the mounted device + 找不到对应的挂载设备 + + + Disks + 磁盘列表 + + + + DiskMountPlugin + + Disk + 磁盘 + + + Open + 打开 + + + Eject all + 全部弹出 + + + + QObject + + The device has been safely removed + 设备已被安全移除 + + + Access denied + 禁止访问 + + + You do not have permission to access this folder + 您没有权限访问该文件夹 + + + Scanning the device, stop it? + 正在扫描当前设备,是否终止扫描? + + + Confirm + button + 确 定 + + + Cancel + button + 取 消 + + + Stop + button + 终 止 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_zh_HK.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_zh_HK.ts new file mode 100644 index 0000000..3b9268d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_zh_HK.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + 認證超時 + + + Disk is busy, cannot unmount now + 磁盤文件被佔用,無法卸載 + + + Disk is busy, cannot eject now + 磁盤文件被佔用,無法彈出 + + + The device is busy, cannot eject now + 光驅正忙,無法彈出 + + + The device is busy, cannot remove now + 設備正忙,無法安全移除 + + + + DeepinStorage + + %1 Volume + %1 卷 + + + + DiskControlItem + + Unknown + 未知 + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + 設備沒有正常移除 + + + Click "Safely Remove" and then disconnect it next time + 請點擊“安全移除”後,再斷開連接 + + + Cannot unmount the device + 無法卸載設備 + + + The disk is mounted by user "%1", you cannot unmount it. + 磁盤由用戶“%1”掛載,您沒有卸載權限。 + + + Cannot find the mounted device + 找不到對應的掛載設備 + + + Disks + 磁盤列表 + + + + DiskMountPlugin + + Disk + 磁盤 + + + Open + 打開 + + + Eject all + 全部彈出 + + + + QObject + + The device has been safely removed + 設備已被安全移除 + + + Access denied + 禁止訪問 + + + You do not have permission to access this folder + 您沒有權限讀取此文件夾 + + + Scanning the device, stop it? + 正在掃描當前設備,是否終止掃描? + + + Confirm + button + 確 定 + + + Cancel + button + 取 消 + + + Stop + button + 終 止 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_zh_TW.ts b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_zh_TW.ts new file mode 100644 index 0000000..d2f24cb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/translations/dde-disk-mount-plugin_zh_TW.ts @@ -0,0 +1,119 @@ + + + DUMountManager + + Authentication timed out + 認證超時 + + + Disk is busy, cannot unmount now + 磁碟忙碌中,現無法卸載 + + + Disk is busy, cannot eject now + 磁碟忙碌,現在無法退出 + + + The device is busy, cannot eject now + 光碟機正忙,無法彈出 + + + The device is busy, cannot remove now + 裝置正忙,無法安全移除 + + + + DeepinStorage + + %1 Volume + %1 磁碟區 + + + + DiskControlItem + + Unknown + 未知 + + + + DiskControlWidget + + dde-file-manager + dde-file-manager + + + The device was not safely removed + 裝置沒有正常移除 + + + Click "Safely Remove" and then disconnect it next time + 請點擊「安全移除」後,再斷開連接 + + + Cannot unmount the device + 無法卸載裝置 + + + The disk is mounted by user "%1", you cannot unmount it. + 此磁碟已被「%1」給掛載,你無法移除它。 + + + Cannot find the mounted device + 找不到掛載裝置 + + + Disks + 磁碟列表 + + + + DiskMountPlugin + + Disk + 磁碟 + + + Open + 開啟 + + + Eject all + 全部彈出 + + + + QObject + + The device has been safely removed + 裝置已被安全移除 + + + Access denied + 權限被拒 + + + You do not have permission to access this folder + 無權進入資料夾 + + + Scanning the device, stop it? + 正在掃描目前裝置,是否終止掃描? + + + Confirm + button + 確 定 + + + Cancel + button + 取 消 + + + Stop + button + 終 止 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/update_translations.sh b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/update_translations.sh new file mode 100755 index 0000000..1222baf --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-dock-plugins/disk-mount/update_translations.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# this file is used to auto update ts file. + +lupdate -ts translations/dde-disk-mount-plugin.ts -no-obsolete +lupdate -ts translations/dde-disk-mount-plugin_zh_CN.ts -no-obsolete diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/accesscontrol/accesscontrolmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/accesscontrol/accesscontrolmanager.cpp new file mode 100644 index 0000000..13a5386 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/accesscontrol/accesscontrolmanager.cpp @@ -0,0 +1,742 @@ +/* + * Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: zhangsheng + * + * 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 + * 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 . + */ + +#include "accesscontrolmanager.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dfilesystemwatcher.h" + +#include "app/policykithelper.h" +#include "dbusservice/dbusadaptor/accesscontrol_adaptor.h" + +#define KEY_INVOKER "invoker" +#define KEY_TYPE "type" +#define KEY_DEVICE "device" +#define KEY_POLICY "policy" +#define KEY_TSTAMP "timestamp" +#define KEY_GLOBAL "global" + +#define KEY_ERRSTR "errstr" +#define KEY_ERRNO "errno" + +#define POLICYTYPE "policytype" +#define VAULTHIDESTATE "vaulthidestate" +#define POLICYSTATE "policystate" + +#define TYPE_INVALID 0x00 +#define TYPE_BLOCK 0x01 +#define TYPE_OPTICAL 0x02 +#define TYPE_PROTOCOL 0x04 + +#define POLICY_DISABLE 0 +#define POLICY_RONLY 1 +#define POLICY_RW 2 + +#define MAX_RETRY 5 + +QString AccessControlManager::ObjectPath = "/com/deepin/filemanager/daemon/AccessControlManager"; +QString AccessControlManager::PolicyKitActionId = "com.deepin.filemanager.daemon.AccessControlManager"; + +AccessControlManager::AccessControlManager(QObject *parent) + : QObject(parent) + , QDBusContext(), + m_watcher(new DFileSystemWatcher(this)) +{ + if (!QDBusConnection::systemBus().registerObject(ObjectPath, this)) { + qFatal("AccessControlManager Register Object Failed."); + } + new AccessControlAdaptor(this); // 注册接口,无需自己释放内存 + m_diskMnanager = new DDiskManager(this); + m_diskMnanager->setWatchChanges(true); + + m_whiteProcess << "/usr/bin/dmcg" << "/usr/bin/dde-file-manager"; + m_configPath = "/etc/deepin/devAccessConfig.json"; + m_vaultConfigPath = "/etc/deepin/vaultAccessConfig.json"; + loadPolicy(); + loadVaultPolicy(); + changeMountedOnInit(); + + m_errMsg.insert(NoError, ""); + m_errMsg.insert(InvalidArgs, tr("Invalid args")); + m_errMsg.insert(InvalidInvoker, tr("Invalid invoker")); + + m_watcher->addPath("/home"); + onFileCreated("/home", "root"); + initConnect(); +} + +AccessControlManager::~AccessControlManager() +{ + +} + +void AccessControlManager::initConnect() +{ + connect(m_diskMnanager, &DDiskManager::mountAdded, this, &AccessControlManager::chmodMountpoints); + connect(m_watcher, &DFileSystemWatcher::fileCreated, this, &AccessControlManager::onFileCreated); + connect(m_diskMnanager, &DDiskManager::diskDeviceAdded, this, &AccessControlManager::disconnOpticalDev); +} + +bool AccessControlManager::checkAuthentication() +{ + bool ret = false; + qint64 pid = 0; + QDBusConnection c = QDBusConnection::connectToBus(QDBusConnection::SystemBus, "org.freedesktop.DBus"); + if(c.isConnected()) { + pid = c.interface()->servicePid(message().service()).value(); + } + + if (pid){ + ret = PolicyKitHelper::instance()->checkAuthorization(PolicyKitActionId, pid); + } + + if (!ret) { + qWarning() << "Authentication failed !!"; + qWarning() << "failed pid: " << pid; + qWarning() << "failed policy id:" << PolicyKitActionId; + } + return ret; +} + +QString AccessControlManager::SetAccessPolicy(const QVariantMap &policy) +{ + QVariantMap sigInfo; + // 0. 接口访问权限 + uint invokerPid = connection().interface()->servicePid(message().service()).value(); + QString invokerPath; + if (!isValidInvoker(invokerPid, invokerPath)) { + sigInfo = policy; + sigInfo.insert(KEY_ERRNO, InvalidInvoker); + sigInfo.insert(KEY_ERRSTR, m_errMsg.value(InvalidInvoker)); + emit AccessPolicySetFinished(sigInfo); + qDebug() << invokerPath << " is not allowed to invoke this function"; + return invokerPath + " is not allowed"; + } + + // 1. 校验策略有效性 + if (!isValidPolicy(policy, invokerPath)) { + sigInfo = policy; + sigInfo.insert(KEY_ERRNO, InvalidArgs); + sigInfo.insert(KEY_ERRSTR, m_errMsg.value(InvalidArgs)); + emit AccessPolicySetFinished(sigInfo); + qDebug() << "policy is not valid"; + return QString("policy is not valid"); + } + + // 2. 写入配置文件 + savePolicy(policy); + + // 2.5 加载最新的策略到内存 + loadPolicy(); + + // 2.5.5 发送信号通知策略已完成修改 + sigInfo.insert(KEY_INVOKER, invokerPath); + sigInfo.insert(KEY_TYPE, policy.value(KEY_TYPE)); + sigInfo.insert(KEY_POLICY, policy.value(KEY_POLICY)); + sigInfo.insert(KEY_ERRNO, NoError); + sigInfo.insert(KEY_ERRSTR, ""); + emit AccessPolicySetFinished(sigInfo); + QVariantList sigInfos; + QMapIterator> iter(m_globalPolicies); + while (iter.hasNext()) { + iter.next(); + QVariantMap item; + item.insert(KEY_TYPE, iter.key()); + item.insert(KEY_POLICY, iter.value().second); + sigInfos << item; + } + emit DeviceAccessPolicyChanged(sigInfos); + + // 3. 改变已挂载设备的访问权限;现阶段不接入此功能; +// changeMountedPolicy(policy); + return "OK"; +} + +QVariantList AccessControlManager::QueryAccessPolicy() +{ + QVariantList ret; + QVariantMap item; + QMapIterator> iter(m_globalPolicies); + while (iter.hasNext()) { + iter.next(); + item.clear(); + item.insert(KEY_TYPE, iter.key()); + item.insert(KEY_POLICY, iter.value().second); + item.insert(KEY_INVOKER, iter.value().first); + ret << item; + } + return ret; +} + +/** + * @brief AccessControlManager::SetVaultAccessPolicy + * @param policy POLICYTYPE 1表示保险箱, VAULTHIDESTATE 1表示隐藏保险箱 2表示显示保险箱, POLICYSTATE 1表示策略执行 2表示策略不执行 + * @return 返回执行结果 + */ +QString AccessControlManager::SetVaultAccessPolicy(const QVariantMap &policy) +{ + QVariantMap sigInfo; + // 0. 接口访问权限 + uint invokerPid = connection().interface()->servicePid(message().service()).value(); + QString invokerPath; + if (!isValidInvoker(invokerPid, invokerPath)) { + sigInfo = policy; + sigInfo.insert(KEY_ERRNO, InvalidInvoker); + sigInfo.insert(KEY_ERRSTR, m_errMsg.value(InvalidInvoker)); + emit AccessPolicySetFinished(sigInfo); + qInfo() << invokerPath << " is not allowed to invoke this function"; + return invokerPath + " is not allowed"; + } + + // 1. 校验策略有效性 + if (!isValidVaultPolicy(policy)) { + sigInfo = policy; + sigInfo.insert(KEY_ERRNO, InvalidArgs); + sigInfo.insert(KEY_ERRSTR, m_errMsg.value(InvalidArgs)); + emit AccessPolicySetFinished(sigInfo); + qDebug() << "policy is not valid"; + return QString("policy is not valid"); + } + + saveVaultPolicy(policy); + + loadVaultPolicy(); + + if(m_VaultHidePolicies.isEmpty()) + return QString(""); + + // 2.5.5 发送信号通知策略已完成修改 + sigInfo.insert(POLICYTYPE, policy.value(POLICYTYPE)); + sigInfo.insert(VAULTHIDESTATE, policy.value(VAULTHIDESTATE)); + sigInfo.insert(POLICYSTATE, policy.value(POLICYSTATE)); + sigInfo.insert(KEY_ERRNO, NoError); + sigInfo.insert(KEY_ERRSTR, ""); + emit AccessPolicySetFinished(sigInfo); + + emit AccessVaultPolicyNotify(); + + return QString("OK"); +} + +QVariantList AccessControlManager::QueryVaultAccessPolicy() +{ + QVariantList ret; + QVariantMap item; + QMapIterator iter(m_VaultHidePolicies); + while (iter.hasNext()) { + iter.next(); + item.insert(iter.key(), iter.value()); + } + ret << QVariant::fromValue(item); + return ret; +} + +int AccessControlManager::QueryVaultAccessPolicyVisible() +{ + if(m_VaultHidePolicies.value(POLICYSTATE) == 1) + return m_VaultHidePolicies.value(VAULTHIDESTATE); + else + return 0; +} + +QString AccessControlManager::FileManagerReply(int policystate) +{ + QVariantList listMap = QueryVaultAccessPolicy(); + QVariantMap map = listMap.at(0).toMap(); + map.insert(POLICYSTATE, policystate); + SetVaultAccessPolicy(map); + return "OK"; +} + +/** + * @brief 设备挂载后,为挂载路径添加写权限 + * 一些设备被 root 挂载,对其他用户没写权限,导致无法正常操作(相关 bug-60788) + * @param blockDevicePath + * @param mountPoint + */ +void AccessControlManager::chmodMountpoints(const QString &blockDevicePath, const QByteArray &mountPoint) +{ + qDebug() << "blockDevicePath: " << blockDevicePath; + QScopedPointer blk(m_diskMnanager->createBlockDevice(blockDevicePath)); + if (m_globalPolicies.contains(TYPE_BLOCK) && blk) { + QString devDesc = blk->device(); + int mode = accessMode(mountPoint); + QString source = m_globalPolicies.value(TYPE_BLOCK).first; + int policy = m_globalPolicies.value(TYPE_BLOCK).second; + QString fs = blk->idType(); + if (mode != policy) { + if (policy == POLICY_DISABLE) { + // unmount + } else { + // remount + QtConcurrent::run([devDesc, mountPoint, fs, policy, source](){ + int ret = mount(devDesc.toLocal8Bit().data(), + mountPoint.data(), + fs.toLocal8Bit().data(), + MS_REMOUNT | (policy == POLICY_RONLY ? MS_RDONLY : 0), + nullptr); + if (ret == 0) + qDebug() << "remount with policy " << policy << " from " << source; + else + qDebug() << "remount with policy " << policy << " failed, errno: " << errno << ", errstr: " << strerror(errno); + }); + } + } + if (policy != POLICY_RW) // 当格式化后,挂载点属组变为了 root 且权限变为了 755,其他用户变得无权限访问设备,因此这里在控制权限为 RW 的时候,继续执行后续变更挂载点权限的代码; + return; + } + + qInfo() << "chmod ==>" << mountPoint; + struct stat fileStat; + stat(mountPoint.data(), &fileStat); + chmod(mountPoint.data(), (fileStat.st_mode | S_IWUSR | S_IWGRP | S_IWOTH)); +} + +void AccessControlManager::disconnOpticalDev(const QString &drivePath) +{ + QSharedPointer drv(DDiskManager::createDiskDevice(drivePath)); + if (!drv || !drv->canPowerOff() || drv->connectionBus() != "usb") // 不能断电的通常为内置光驱 + return; + // note: drv->optical 设备接入时此字段为 false,不能用于判断是否是光驱 + const QStringList &compatibility = drv->mediaCompatibility(); + if (compatibility.count() == 0 || !compatibility.first().contains("optical")) + return; + if (!m_globalPolicies.contains(TYPE_OPTICAL)) { + return; + } + + int policy = m_globalPolicies.value(TYPE_OPTICAL).second; + qDebug() << drv << drv->optical() << m_globalPolicies.contains(TYPE_OPTICAL) << policy; + if (policy == POLICY_DISABLE) { + QtConcurrent::run([drv](){ + int retry = 0; + do { + retry++; + drv->powerOff({}); + QDBusError err = drv->lastError(); + if (err.type() == QDBusError::NoError || retry == MAX_RETRY) + break; + else + qDebug() << "poweroff device: " << drv->lastError().message(); + QThread::msleep(500); + } while (1); + }); + } +} + +bool AccessControlManager::isValidPolicy(const QVariantMap &policy, const QString &realInvoker) +{ + // invoker must not be empty + // type must in (0, 7] + // policy must in [0, 2] + // device is optional + return policy.contains(KEY_INVOKER) && !policy.value(KEY_INVOKER).toString().isEmpty() + && policy.contains(KEY_TYPE) && policy.value(KEY_TYPE).toInt() > TYPE_INVALID && policy.value(KEY_TYPE).toInt() <= (TYPE_BLOCK | TYPE_OPTICAL | TYPE_PROTOCOL) + && policy.contains(KEY_POLICY) && policy.value(KEY_POLICY).toInt() >= POLICY_DISABLE && policy.value(KEY_POLICY).toInt() <= POLICY_RW + && policy.value(KEY_INVOKER).toString() == realInvoker; +} + +void AccessControlManager::savePolicy(const QVariantMap &policy) +{ + // 1. if file does not exist then create it + QFile config(m_configPath); + if (!config.open(QIODevice::ReadWrite)) { + qDebug() << "config open failed"; + return; + } + config.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner); + + int inGlobal = (!policy.contains(KEY_DEVICE) || policy.value(KEY_DEVICE).toString().isEmpty()) + ? 1 : 0; + int inType = policy.value(KEY_TYPE).toInt(); + int inPolicy = policy.value(KEY_POLICY).toInt(); + QString inDevice = inGlobal ? "" : policy.value(KEY_DEVICE).toString(); + QString inInvoker = policy.value(KEY_INVOKER).toString(); + + // 2. append/replace config to configFile + bool foundExist = false; + QJsonParseError err; + QJsonDocument doc = QJsonDocument::fromJson(config.readAll(), &err); + QJsonArray newArr; + if (doc.isArray()) { + QJsonArray arr = doc.array(); + foreach (auto obj, arr) { + if (!obj.isObject()) + continue; + QJsonObject objInfo = obj.toObject(); + int global = objInfo.contains(KEY_GLOBAL) ? objInfo.value(KEY_GLOBAL).toInt() : 0; + QString src = objInfo.contains(KEY_INVOKER) ? objInfo.value(KEY_INVOKER).toString() : ""; + int type = objInfo.contains(KEY_TYPE) ? objInfo.value(KEY_TYPE).toInt() : 0; + QString timestamp = objInfo.contains(KEY_TSTAMP) ? objInfo.value(KEY_TSTAMP).toString() : ""; + QString dev = objInfo.contains(KEY_DEVICE) ? objInfo.value(KEY_DEVICE).toString() : ""; + QString invoker = objInfo.contains(KEY_INVOKER) ? objInfo.value(KEY_INVOKER).toString() : ""; + + if (inGlobal == global && inType == type && inDevice == dev && inInvoker == invoker) { + foundExist = true; + objInfo.insert(KEY_POLICY, inPolicy); + objInfo.insert(KEY_TSTAMP, QString::number(QDateTime::currentSecsSinceEpoch())); + qDebug() << "found exist policy, just updtae it"; + } + + newArr.append(objInfo); + } + } + if (!foundExist) { + QJsonObject obj; + obj.insert(KEY_GLOBAL, inGlobal ? 1: 0); + obj.insert(KEY_INVOKER, inInvoker); + obj.insert(KEY_TYPE, inType); + obj.insert(KEY_POLICY, inPolicy); + obj.insert(KEY_TSTAMP, QString::number(QDateTime::currentSecsSinceEpoch())); + if (inGlobal == 0) + obj.insert(KEY_DEVICE, inDevice); + newArr.append(obj); + qDebug() << "append new policy"; + } + doc.setArray(newArr); + config.close(); + config.open(QIODevice::Truncate | QIODevice::ReadWrite); // overwrite the config file + config.write(doc.toJson()); + config.close(); +} + +void AccessControlManager::changeMountedPolicy(const QVariantMap &policy) +{ + int type = policy.value(KEY_TYPE).toInt(); + int mode = policy.value(KEY_POLICY).toInt(); + QString device = policy.value(KEY_DEVICE).toString(); + qDebug() << "type = " << type << "\t" << "policy = " << mode; + if (type & TYPE_BLOCK) { + changeMountedBlock(mode, device); + } + if (type & TYPE_OPTICAL) { + changeMountedOptical(mode, device); + } + if (type & TYPE_PROTOCOL) { + changeMountedProtocol(mode, device); + } +} + +bool AccessControlManager::isValidInvoker(uint pid, QString &invokerPath) +{ + QFileInfo f(QString("/proc/%1/exe").arg(pid)); + if (!f.exists()) + return false; + invokerPath = f.canonicalFilePath(); + return m_whiteProcess.contains(invokerPath); +} + +void AccessControlManager::changeMountedBlock(int mode, const QString &device) +{ + Q_UNUSED(device) + + const QStringList &blocks = m_diskMnanager->blockDevices({}); + QList waitToHandle; + foreach (auto block, blocks) { + QScopedPointer blkDev(DDiskManager::createBlockDevice(block)); + if (!blkDev || !blkDev->hasFileSystem() || blkDev->mountPoints().isEmpty()) + continue; + + QScopedPointer drvDev(DDiskManager::createDiskDevice(blkDev->drive())); + if (!drvDev || !drvDev->removable() || drvDev->optical()) + continue; + + QString mps = blkDev->mountPoints().first(); + // 0. 检查是否是目标设备 + + // 1. 检查设备是否在白名单内 + + // 2. 检查挂载点权限是否与策略一致,不一致则需要更改 + int mountedMode = accessMode(mps); + if (mountedMode == mode) + continue; + + // 3. 需要重载或卸载 + const QString &devDesc = blkDev->device(); // 设备描述符 + MountArgs args; + args.devDesc = devDesc; + args.mountPoint = mps; + args.fileSystem = blkDev->idType(); + waitToHandle.append(args); + } + + // 4. 开启线程处理重载/卸载任务 + if (waitToHandle.count() > 0) { + QtConcurrent::run([waitToHandle, mode](){ + foreach(auto dev, waitToHandle) { + if (mode == 0) { // unmount + int ret = umount(dev.mountPoint.toLocal8Bit().data()); + } else { // remount + int ret = mount(dev.devDesc.toLocal8Bit().data(), + dev.mountPoint.toLocal8Bit().data(), + dev.fileSystem.toLocal8Bit().data(), + MS_REMOUNT | (mode == POLICY_RONLY ? MS_RDONLY : 0), + nullptr); + if (ret < 0) + qDebug() << "remount " << dev.devDesc << " failed: " << errno << ": " << strerror(errno); + } + } + }); + } +} + +void AccessControlManager::changeMountedOptical(int mode, const QString &device) +{ + Q_UNUSED(device) + // 只能主动关闭,不能主动打开;光驱只负责 DISABLE / RW + if (mode != POLICY_DISABLE) + return; + const QStringList &blocks = DDiskManager::blockDevices({}); + const QStringList &disks = m_diskMnanager->diskDevices(); + QMap> opticalDrv; + foreach (auto drvPath, disks) { // 获取系统所有 USB 光驱设备对象 + QSharedPointer drv(DDiskManager::createDiskDevice(drvPath)); + if (!drv) + continue; + const QStringList &compatibility = drv->mediaCompatibility(); + if (compatibility.count() == 0 || !compatibility.first().contains("optical") || drv->connectionBus() != "usb") + continue; + opticalDrv.insert(drvPath, drv); + } + + QtConcurrent::run([blocks, opticalDrv]{ + foreach (auto blkPath, blocks) { + QSharedPointer blk(DDiskManager::createBlockDevice(blkPath)); + if (!blk || !opticalDrv.contains(blk->drive())) + continue; + + // unmount first + if (blk->mountPoints().count() > 0) { + blk->unmount({}); + if (blk->lastError().type() != QDBusError::NoError) { + qDebug() << "Error occured while unmount optical device: " << blk->lastError().message(); + continue; + } + } + QThread::msleep(500); + // poweroff it + QSharedPointer drv = opticalDrv.value(blk->drive()); + if (drv) { + int retry = 0; + do { + retry++; + drv->powerOff({}); + QDBusError err = drv->lastError(); + if (err.type() == QDBusError::NoError || retry == MAX_RETRY) + break; + else + qDebug() << "Error occured while poweroff optical device: " << drv->lastError().message(); + QThread::msleep(500); + } while (1); + } + } + }); +} + +void AccessControlManager::changeMountedProtocol(int mode, const QString &device) +{ + Q_UNUSED(mode) + Q_UNUSED(device) +} + +void AccessControlManager::changeMountedOnInit() +{ + qDebug() << "start change access on init..."; + if (m_globalPolicies.contains(TYPE_BLOCK)) + changeMountedBlock(m_globalPolicies.value(TYPE_BLOCK).second, ""); + if (m_globalPolicies.contains(TYPE_OPTICAL)) + changeMountedOptical(m_globalPolicies.value(TYPE_OPTICAL).second, ""); + if (m_globalPolicies.contains(TYPE_PROTOCOL)) + changeMountedProtocol(m_globalPolicies.value(TYPE_PROTOCOL).second, ""); + qDebug() << "end change access on init..."; +} + +int AccessControlManager::accessMode(const QString &mps) +{ + if (mps.isEmpty()) + return POLICY_DISABLE; + char *path = mps.toLocal8Bit().data(); + if (access(path, W_OK) == 0) + return POLICY_RW; + if (access(path, R_OK) == 0) + return POLICY_RONLY; + return POLICY_DISABLE; +} + +void AccessControlManager::loadPolicy() +{ + QFile config(m_configPath); + if (!config.open(QIODevice::ReadOnly)) + return; + QJsonParseError err; + QJsonDocument doc = QJsonDocument::fromJson(config.readAll(), &err); + config.close(); + + if (doc.isArray()) { + m_globalPolicies.clear(); + QJsonArray arr = doc.array(); + foreach (auto item, arr) { + if (!item.isObject()) + continue; + + QJsonObject obj = item.toObject(); + int global = obj.contains(KEY_GLOBAL) ? obj.value(KEY_GLOBAL).toInt() : -1; + if (global != 1) { + // load black/white policy + ; + } else { + // load default/general policy + int type = obj.contains(KEY_TYPE) ? obj.value(KEY_TYPE).toInt() : TYPE_INVALID; + int policy = obj.contains(KEY_POLICY) ? obj.value(KEY_POLICY).toInt() : POLICY_RW; + QString source = obj.contains(KEY_INVOKER) ? obj.value(KEY_INVOKER).toString() : ""; + if (!m_globalPolicies.contains(type) || 1) // 1: 新读取到的数据源优先级大于之前读取到的,则刷新原有的 + m_globalPolicies.insert(type, QPair(source, policy)); + } + } + } + + qDebug() << "loaded policy: " << m_globalPolicies; +} + +void AccessControlManager::decodeConfig() +{ + +} + +void AccessControlManager::encodeConfig() +{ + +} + +bool AccessControlManager::isValidVaultPolicy(const QVariantMap &policy) +{ + if(policy.value(POLICYTYPE).toInt() < 0 || policy.value(VAULTHIDESTATE).toInt() < 0) + return false; + return true; +} + +void AccessControlManager::saveVaultPolicy(const QVariantMap &policy) +{ + // 1. if file does not exist then create it + QFile config(m_vaultConfigPath); + if (!config.open(QIODevice::ReadWrite)) { + qDebug() << "config open failed"; + config.close(); + return; + } + config.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner); + + QJsonParseError err; + QJsonDocument doc = QJsonDocument::fromJson(config.readAll(), &err); + config.close(); + + QJsonArray newArr; + + QJsonObject obj; + obj.insert(POLICYTYPE, policy.value(POLICYTYPE).toInt()); + obj.insert(VAULTHIDESTATE, policy.value(VAULTHIDESTATE).toInt()); + obj.insert(POLICYSTATE, policy.value(POLICYSTATE).toInt()); + newArr.append(obj); + qDebug() << "append new policy"; + doc.setArray(newArr); + config.open(QIODevice::Truncate | QIODevice::ReadWrite); // overwrite the config file + config.write(doc.toJson()); + config.close(); +} + +void AccessControlManager::loadVaultPolicy() +{ + QFile config(m_vaultConfigPath); + if (!config.open(QIODevice::ReadOnly)) + return; + QJsonParseError err; + QJsonDocument doc = QJsonDocument::fromJson(config.readAll(), &err); + config.close(); + + if (doc.isArray()) { + m_VaultHidePolicies.clear(); + QJsonArray arr = doc.array(); + foreach (auto item, arr) { + if (!item.isObject()) + continue; + + QJsonObject obj = item.toObject(); + + // load default/general policy + int policytype = obj.contains(POLICYTYPE) ? obj.value(POLICYTYPE).toInt() : -1; + int vaulthidestate = obj.contains(VAULTHIDESTATE) ? obj.value(VAULTHIDESTATE).toInt() : -1; + int policystate = obj.contains(POLICYSTATE) ? obj.value(POLICYSTATE).toInt() : -1; + m_VaultHidePolicies.insert(POLICYTYPE, policytype); + m_VaultHidePolicies.insert(VAULTHIDESTATE, vaulthidestate); + m_VaultHidePolicies.insert(POLICYSTATE, policystate); + } + } + + qDebug() << "loaded policy: " << m_VaultHidePolicies; +} + +void AccessControlManager::onFileCreated(const QString &path, const QString &name) +{ + Q_UNUSED(path) + Q_UNUSED(name) + + QDir homeDir("/home"); + QStringList dirNames = homeDir.entryList(QDir::NoDotAndDotDot | QDir::Dirs); + dirNames.append("root"); // root 用户不在/home下,但设备会挂载到/media/root + for (const QString &dirName : dirNames) { + // /media/[UserName] 为默认挂载的基路径,预先从创建此目录,目的是为了确保该路径其他用户能够访问 + QString mountBaseName = QString("/media/%1").arg(dirName); + QDir mountDir(mountBaseName); + if (!mountDir.exists()) { + qInfo() << mountBaseName << "not exists"; + if (QDir().mkpath(mountBaseName)) { + qInfo() << "create" << mountBaseName << "success"; + struct stat fileStat; + QByteArray nameBytes(mountBaseName.toUtf8()); + stat(nameBytes.data(), &fileStat); + chmod(nameBytes.data(), (fileStat.st_mode | S_IRUSR | S_IRGRP | S_IROTH)); + } + } + // ACL + QString aclCmd = QString("setfacl -m o:rx %1").arg(mountBaseName); + QProcess::execute(aclCmd); + qInfo() << "acl:" << aclCmd; + } + +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/accesscontrol/accesscontrolmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/accesscontrol/accesscontrolmanager.h new file mode 100644 index 0000000..3c198fe --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/accesscontrol/accesscontrolmanager.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: zhangsheng + * + * 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 + * 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 . + */ + +#ifndef ACCESSCONTROLMANAGER_H +#define ACCESSCONTROLMANAGER_H + +#include +#include + +class AccessControlAdaptor; +class DDiskManager; +class DFileSystemWatcher; + +class AccessControlManager : public QObject, public QDBusContext +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface","com.deepin.filemanager.daemon.AccessControlManager") + + enum ErrCode{ + NoError = 0, + InvalidArgs, + InvalidInvoker, + }; + + struct MountArgs{ + QString devDesc; + QString mountPoint; + QString fileSystem; + }; + +public: + explicit AccessControlManager(QObject *parent = nullptr); + ~AccessControlManager(); + + void initConnect(); + + static QString ObjectPath; + static QString PolicyKitActionId; + +protected: + bool checkAuthentication(); + +public slots: + QString SetAccessPolicy(const QVariantMap &policy); + QVariantList QueryAccessPolicy(); + + QString SetVaultAccessPolicy(const QVariantMap &policy); + QVariantList QueryVaultAccessPolicy(); + int QueryVaultAccessPolicyVisible(); + QString FileManagerReply(int policystate); + +signals: + void AccessPolicySetFinished(const QVariantMap &policy); + void DeviceAccessPolicyChanged(const QVariantList &policy); + + void AccessVaultPolicyNotify(); + +private slots: + void onFileCreated(const QString &path, const QString &name); + void chmodMountpoints(const QString &blockDevicePath, const QByteArray &mountPoint); + void disconnOpticalDev(const QString &drivePath); + + bool isValidPolicy(const QVariantMap &policy, const QString &realInvoker); + bool isValidInvoker(uint pid, QString &invokerPath); + + void changeMountedPolicy(const QVariantMap &policy); + void changeMountedBlock(int mode, const QString &device = ""); + void changeMountedOptical(int mode, const QString &device = ""); + void changeMountedProtocol(int mode, const QString &device = ""); + + // 在启动系统的时候对已挂载的设备执行一次策略变更(设备的接入先于 daemon 的启动) + void changeMountedOnInit(); + + int accessMode(const QString &mps); // 获取挂载点访问权限 + + void savePolicy(const QVariantMap &policy); + void loadPolicy(); + void decodeConfig(); + void encodeConfig(); + + bool isValidVaultPolicy(const QVariantMap &policy); + + void saveVaultPolicy(const QVariantMap &policy); + void loadVaultPolicy(); + +private: + AccessControlAdaptor *m_accessControlAdaptor = nullptr; + DDiskManager *m_diskMnanager = nullptr; + DFileSystemWatcher *m_watcher = nullptr; + + QString m_configPath; + QStringList m_whiteProcess; + + QMap> m_globalPolicies; + QMap m_errMsg; + + QString m_vaultConfigPath; + QMap m_VaultHidePolicies; +}; + +#endif // ACCESSCONTROLMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/filemanagerdaemon.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/filemanagerdaemon.cpp new file mode 100644 index 0000000..9f8adab --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/filemanagerdaemon.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "filemanagerdaemon.h" +#include "controllers/appcontroller.h" + +FileManagerDaemon::FileManagerDaemon(QObject *parent) : QObject(parent) +{ + initControllers(); + initConnect(); +} + +FileManagerDaemon::~FileManagerDaemon() +{ + +} + +void FileManagerDaemon::initControllers() +{ + m_appController = new AppController(this); +} + +void FileManagerDaemon::initConnect() +{ + +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/filemanagerdaemon.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/filemanagerdaemon.h new file mode 100644 index 0000000..f72e441 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/filemanagerdaemon.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef FILEMANAGERDAEMON_H +#define FILEMANAGERDAEMON_H + +#include + +class AppController; + +class FileManagerDaemon : public QObject +{ + Q_OBJECT +public: + explicit FileManagerDaemon(QObject *parent = nullptr); + ~FileManagerDaemon(); + + void initControllers(); + void initConnect(); + +signals: + +public slots: + +private: + AppController* m_appController = nullptr; +}; + +#endif // FILEMANAGERDAEMON_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/global.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/global.h new file mode 100644 index 0000000..6e61437 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/global.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef GLOBAL +#define GLOBAL + +#include + +static const QString DaemonServicePath = "com.deepin.filemanager.daemon"; + +#endif // GLOBAL + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/policykithelper.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/policykithelper.cpp new file mode 100644 index 0000000..0f46ffe --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/policykithelper.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "policykithelper.h" + +bool PolicyKitHelper::checkAuthorization(const QString& actionId, qint64 applicationPid) +{ + Authority::Result result; + result = Authority::instance()->checkAuthorizationSync(actionId, UnixProcessSubject(applicationPid), /// 第一个参数是需要验证的action,和规则文件写的保持一致 + Authority::AllowUserInteraction); + if (result == Authority::Yes) { + return true; + }else { + return false; + } +} + +PolicyKitHelper::PolicyKitHelper() +{ + +} + +PolicyKitHelper::~PolicyKitHelper() +{ + +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/policykithelper.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/policykithelper.h new file mode 100644 index 0000000..ec4645d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/app/policykithelper.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef POLICYKITHELPER_H +#define POLICYKITHELPER_H + +#include +#include +#include + +using namespace PolkitQt1; + +class PolicyKitHelper +{ + +public: + inline static PolicyKitHelper* instance(){ + static PolicyKitHelper instance; + return &instance; + } + + bool checkAuthorization(const QString& actionId, qint64 applicationPid); + + +private: + PolicyKitHelper(); + ~PolicyKitHelper(); + + Q_DISABLE_COPY(PolicyKitHelper) +}; + +#endif // POLICYKITHELPER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/client/filemanagerclient.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/client/filemanagerclient.cpp new file mode 100644 index 0000000..3042973 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/client/filemanagerclient.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "filemanagerclient.h" +#include "app/global.h" +#include "dbusservice/dbustype/dbusinforet.h" +#include "dbusservice/dbusinterface/renamejob_interface.h" +#include +#include + +FileManagerClient::FileManagerClient(QObject *parent) : QObject(parent) +{ + DBusInfoRet::registerMetaType(); + QString objectPath = "/com/deepin/filemanager/daemon/Operations"; + m_fileOperationInterface = new FileOperationInterface(DaemonServicePath, objectPath, QDBusConnection::systemBus()); + testNewNameJob("11111", "222222222"); +} + +FileManagerClient::~FileManagerClient() +{ + +} + +void FileManagerClient::testNewNameJob(const QString &oldFile, const QString &newFile) +{ + QDBusPendingReply reply = m_fileOperationInterface->NewRenameJob(oldFile, newFile); + reply.waitForFinished(); + if (reply.isFinished()){ + DBusInfoRet result = qdbus_cast(reply.argumentAt(0)); + qDebug() << result; + RenameJobInterface* renamejobInterface = new RenameJobInterface(result.ServicePath, result.InterfacePath.path(), QDBusConnection::systemBus()); + renamejobInterface->Execute(); + }else{ + + } +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/client/filemanagerclient.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/client/filemanagerclient.h new file mode 100644 index 0000000..fc4ddbe --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/client/filemanagerclient.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef FILEMANAGERCLIENT_H +#define FILEMANAGERCLIENT_H + +#include + +#include "dbusservice/dbusinterface/fileoperation_interface.h" + +class FileManagerClient : public QObject +{ + Q_OBJECT +public: + explicit FileManagerClient(QObject *parent = nullptr); + ~FileManagerClient(); + +signals: + +public slots: + void testNewNameJob(const QString &oldFile, const QString &newFile); + +private: + FileOperationInterface* m_fileOperationInterface = nullptr; + +}; + +#endif // FILEMANAGERCLIENT_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/controllers/appcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/controllers/appcontroller.cpp new file mode 100644 index 0000000..6711d58 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/controllers/appcontroller.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "app/global.h" +#include "appcontroller.h" +#include "fileoperation.h" +#include "tag/tagmanagerdaemon.h" +#include "usershare/usersharemanager.h" +#include "accesscontrol/accesscontrolmanager.h" +#include "vault/vaultmanager.h" +#include "revocation/revocationmanager.h" +#include "vault/vaultbruteforceprevention.h" + +AppController::AppController(QObject *parent) : QObject(parent) +{ + initControllers(); + initConnect(); +} + +AppController::~AppController() +{ + +} + +void AppController::initControllers() +{ + m_accessController = new AccessControlManager(this); + m_userShareManager = new UserShareManager(this); + m_tagManagerDaemon = new TagManagerDaemon{ this }; + m_vaultManager = new VaultManager(this); + m_revocationManager = new RevocationManager(this); + m_vaultForce = new VaultBruteForcePrevention(this); +} + +void AppController::initConnect() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/controllers/appcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/controllers/appcontroller.h new file mode 100644 index 0000000..6558eef --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/controllers/appcontroller.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef APPCONTROLLER_H +#define APPCONTROLLER_H + +#include + +class FileOperation; +class UserShareManager; +class UsbFormatter; +class CommandManager; +class DeviceInfoManager; +class TagManagerDaemon; +class AccessControlManager; +class VaultManager; +class RevocationManager; +class VaultBruteForcePrevention; + +class AppController : public QObject +{ + Q_OBJECT +public: + explicit AppController(QObject *parent = nullptr); + ~AppController(); + + void initControllers(); + void initConnect(); + +signals: + +public slots: + +private: + UserShareManager *m_userShareManager = nullptr; + TagManagerDaemon *m_tagManagerDaemon = nullptr; + AccessControlManager *m_accessController = nullptr; + VaultManager *m_vaultManager = nullptr; + RevocationManager *m_revocationManager = nullptr; + VaultBruteForcePrevention *m_vaultForce = nullptr; +}; + +#endif // APPCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/controllers/fileoperation.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/controllers/fileoperation.cpp new file mode 100644 index 0000000..1b57354 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/controllers/fileoperation.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "fileoperation.h" +#include "dbusservice/dbusadaptor/fileoperation_adaptor.h" + +#include "fileoperationjob/copyjob.h" +#include "fileoperationjob/movejob.h" +#include "fileoperationjob/createfolderjob.h" +#include "fileoperationjob/createtemplatefilejob.h" +#include "fileoperationjob/renamejob.h" +#include "fileoperationjob/deletejob.h" + +#include +#include +#include + +QString FileOperation::ObjectPath = "/com/deepin/filemanager/daemon/Operations"; + +FileOperation::FileOperation(const QString &servicePath, QObject *parent) : + QObject(parent) +{ + DBusInfoRet::registerMetaType(); + m_servicePath = servicePath; + QDBusConnection::systemBus().registerObject(ObjectPath, this); + m_fileOperationAdaptor = new FileOperationAdaptor(this); +} + +FileOperation::~FileOperation() +{ + +} + +DBusInfoRet FileOperation::NewCreateFolderJob(const QString &fabspath) +{ + DBusInfoRet result; + qDebug() << fabspath; + CreateFolderJob* job = new CreateFolderJob(fabspath); + if (job->registerObject()){ + result.ServicePath = m_servicePath; + result.InterfacePath = QDBusObjectPath(job->objectPath()); + } + qDebug() << result; + return result; +} + +DBusInfoRet FileOperation::NewCreateTemplateFileJob(const QString &templateFile, const QString &targetDir) +{ + DBusInfoRet result; + qDebug() << templateFile << targetDir; + CreateTemplateFileJob* job = new CreateTemplateFileJob(templateFile, targetDir); + if (job->registerObject()){ + result.ServicePath = m_servicePath; + result.InterfacePath = QDBusObjectPath(job->objectPath()); + } + qDebug() << result; + return result; +} + +DBusInfoRet FileOperation::NewCopyJob(const QStringList &filelist, const QString &targetDir) +{ + DBusInfoRet result; + qDebug() << filelist << targetDir; + CopyJob* job = new CopyJob(filelist, targetDir); + if (job->registerObject()){ + result.ServicePath = m_servicePath; + result.InterfacePath = QDBusObjectPath(job->objectPath()); + } + qDebug() << result; + return result; +} + +DBusInfoRet FileOperation::NewMoveJob(const QStringList &filelist, const QString &targetDir) +{ + DBusInfoRet result; + qDebug() << filelist << targetDir; + MoveJob* job = new MoveJob(filelist, targetDir); + if (job->registerObject()){ + result.ServicePath = m_servicePath; + result.InterfacePath = QDBusObjectPath(job->objectPath()); + } + qDebug() << result; + return result; +} + +DBusInfoRet FileOperation::NewRenameJob(const QString &oldFile, const QString &newFile) +{ + DBusInfoRet result; + qDebug() << oldFile << newFile << QDBusConnection::systemBus().name(); + RenameJob* job = new RenameJob(oldFile, newFile); + if (job->registerObject()){ + result.ServicePath = m_servicePath; + result.InterfacePath = QDBusObjectPath(job->objectPath()); + } + qDebug() << result; + return result; +} + +DBusInfoRet FileOperation::NewDeleteJob(const QStringList &filelist) +{ + DBusInfoRet result; + qDebug() << filelist; + DeleteJob* job = new DeleteJob(filelist); + if (job->registerObject()){ + result.ServicePath = m_servicePath; + result.InterfacePath = QDBusObjectPath(job->objectPath()); + } + qDebug() << result; + return result; +} + +QString FileOperation::test(const QString &oldFile, const QString &newFile, QDBusObjectPath &result2, bool &result3) +{ + Q_UNUSED(oldFile) + Q_UNUSED(newFile) + + result2.setPath("m_renameJobBasePath"); + result3 = true; + + qDebug() << result2.path() << result3; + + return "1111111111111"; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/controllers/fileoperation.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/controllers/fileoperation.h new file mode 100644 index 0000000..0eec3b9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/controllers/fileoperation.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef FILEOPERATION_H +#define FILEOPERATION_H + +#include +#include +#include "dbusservice/dbustype/dbusinforet.h" + + +class FileOperationAdaptor; + +class FileOperation : public QObject ,protected QDBusContext +{ + Q_OBJECT + +public: + explicit FileOperation(const QString& servicePath, QObject *parent = nullptr); + ~FileOperation(); + + static QString ObjectPath; + +signals: + +public slots: + DBusInfoRet NewCreateFolderJob(const QString &fabspath); + DBusInfoRet NewCreateTemplateFileJob(const QString &templateFile, const QString &targetDir); + DBusInfoRet NewCopyJob(const QStringList &filelist, const QString &targetDir); + DBusInfoRet NewMoveJob(const QStringList &filelist, const QString &targetDir); + DBusInfoRet NewRenameJob(const QString &oldFile, const QString &newFile); + DBusInfoRet NewDeleteJob(const QStringList &filelist); + QString test(const QString &oldFile, const QString &newFile, QDBusObjectPath &result2, bool &result3); + +private: + QString m_servicePath; + FileOperationAdaptor* m_fileOperationAdaptor; +}; + +typedef QMap StringMap; + +Q_DECLARE_METATYPE(StringMap) + +#endif // FILEOPERATION_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/acesscontrol.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/acesscontrol.xml new file mode 100644 index 0000000..8b1eaad --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/acesscontrol.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/com.deepin.filemanager.daemon.conf b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/com.deepin.filemanager.daemon.conf new file mode 100644 index 0000000..f6c2b7b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/com.deepin.filemanager.daemon.conf @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/com.deepin.filemanager.daemon.policy b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/com.deepin.filemanager.daemon.policy new file mode 100644 index 0000000..91f9c52 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/com.deepin.filemanager.daemon.policy @@ -0,0 +1,64 @@ + + + + + + + User share manager + Authentication is required to change your user share data + 修改您的共享信息需要认证 + folder + + no + no + auth_admin_keep + + + + access control manager + Authentication is required to get admin permission + 获取文件管理权限需要认证 + folder + + no + no + auth_admin_keep + + + + vault manager + Authentication is required to create a file vault + 创建文件保险箱需要认证 + folder + + no + no + auth_admin_keep + + + + vault manager + Authentication is required to delete the file vault + 删除文件保险箱需要认证 + folder + + no + no + auth_admin_keep + + + + Retrieve Password + Authentication is required to retrieve the vault password + 找回保险箱密码需要认证 + folder + + no + no + auth_admin_keep + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/com.deepin.filemanager.daemon.service b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/com.deepin.filemanager.daemon.service new file mode 100644 index 0000000..1d10173 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/com.deepin.filemanager.daemon.service @@ -0,0 +1,6 @@ +[D-BUS Service] +Name=com.deepin.filemanager.daemon +Exec=/usr/bin/dde-file-manager-daemon +User=root +SystemdService=dde-filemanager-daemon.service + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/copyjob.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/copyjob.xml new file mode 100644 index 0000000..6db1d33 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/copyjob.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/createfolderjob.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/createfolderjob.xml new file mode 100644 index 0000000..5cbe310 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/createfolderjob.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/createtemplatefilejob.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/createtemplatefilejob.xml new file mode 100644 index 0000000..f06a669 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/createtemplatefilejob.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/accesscontrol_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/accesscontrol_adaptor.cpp new file mode 100644 index 0000000..8811a2b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/accesscontrol_adaptor.cpp @@ -0,0 +1,71 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i accesscontrol/accesscontrolmanager.h -c AccessControlAdaptor -l AccessControlManager -a dbusadaptor/accesscontrol_adaptor acesscontrol.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "dbusadaptor/accesscontrol_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class AccessControlAdaptor + */ + +AccessControlAdaptor::AccessControlAdaptor(AccessControlManager *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +AccessControlAdaptor::~AccessControlAdaptor() +{ + // destructor +} + +QString AccessControlAdaptor::FileManagerReply(int policystate) +{ + // handle method call com.deepin.filemanager.daemon.AccessControlManager.FileManagerReply + return parent()->FileManagerReply(policystate); +} + +QVariantList AccessControlAdaptor::QueryAccessPolicy() +{ + // handle method call com.deepin.filemanager.daemon.AccessControlManager.QueryAccessPolicy + return parent()->QueryAccessPolicy(); +} + +QVariantList AccessControlAdaptor::QueryVaultAccessPolicy() +{ + // handle method call com.deepin.filemanager.daemon.AccessControlManager.QueryVaultAccessPolicy + return parent()->QueryVaultAccessPolicy(); +} + +int AccessControlAdaptor::QueryVaultAccessPolicyVisible() +{ + // handle method call com.deepin.filemanager.daemon.AccessControlManager.QueryVaultAccessPolicyVisible + return parent()->QueryVaultAccessPolicyVisible(); +} + +QString AccessControlAdaptor::SetAccessPolicy(const QVariantMap &policy) +{ + // handle method call com.deepin.filemanager.daemon.AccessControlManager.SetAccessPolicy + return parent()->SetAccessPolicy(policy); +} + +QString AccessControlAdaptor::SetVaultAccessPolicy(const QVariantMap &policy) +{ + // handle method call com.deepin.filemanager.daemon.AccessControlManager.SetVaultAccessPolicy + return parent()->SetVaultAccessPolicy(policy); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/accesscontrol_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/accesscontrol_adaptor.h new file mode 100644 index 0000000..bb2780f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/accesscontrol_adaptor.h @@ -0,0 +1,90 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i accesscontrol/accesscontrolmanager.h -c AccessControlAdaptor -l AccessControlManager -a dbusadaptor/accesscontrol_adaptor acesscontrol.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef ACCESSCONTROL_ADAPTOR_H +#define ACCESSCONTROL_ADAPTOR_H + +#include +#include +#include "accesscontrol/accesscontrolmanager.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.AccessControlManager + */ +class AccessControlAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.AccessControlManager") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + AccessControlAdaptor(AccessControlManager *parent); + virtual ~AccessControlAdaptor(); + + inline AccessControlManager *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + QString FileManagerReply(int policystate); + QVariantList QueryAccessPolicy(); + QVariantList QueryVaultAccessPolicy(); + int QueryVaultAccessPolicyVisible(); + QString SetAccessPolicy(const QVariantMap &policy); + QString SetVaultAccessPolicy(const QVariantMap &policy); +Q_SIGNALS: // SIGNALS + void AccessPolicySetFinished(const QVariantMap &policy); + void AccessVaultPolicyNotify(); + void DeviceAccessPolicyChanged(const QVariantList &policy); +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/acesscontrol_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/acesscontrol_adaptor.cpp new file mode 100644 index 0000000..6cea439 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/acesscontrol_adaptor.cpp @@ -0,0 +1,19 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i acesscontrol/acesscontrolmanager.h -c AcessControlAdaptor -l AcessControlManager -a dbusadaptor/acesscontrol_adaptor acesscontrol.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "dbusadaptor/acesscontrol_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/acesscontrol_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/acesscontrol_adaptor.h new file mode 100644 index 0000000..f79a66d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/acesscontrol_adaptor.h @@ -0,0 +1,27 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i acesscontrol/acesscontrolmanager.h -c AcessControlAdaptor -l AcessControlManager -a dbusadaptor/acesscontrol_adaptor acesscontrol.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef ACESSCONTROL_ADAPTOR_H +#define ACESSCONTROL_ADAPTOR_H + +#include +#include +#include "acesscontrol/acesscontrolmanager.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/copyjob_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/copyjob_adaptor.cpp new file mode 100644 index 0000000..6a9f74f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/copyjob_adaptor.cpp @@ -0,0 +1,41 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i fileoperationjob/copyjob.h -c CopyJobAdaptor -l CopyJob -a dbusadaptor/copyjob_adaptor copyjob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "dbusadaptor/copyjob_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class CopyJobAdaptor + */ + +CopyJobAdaptor::CopyJobAdaptor(CopyJob *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +CopyJobAdaptor::~CopyJobAdaptor() +{ + // destructor +} + +void CopyJobAdaptor::Execute() +{ + // handle method call com.deepin.filemanager.daemon.CopyJob.Execute + parent()->Execute(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/copyjob_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/copyjob_adaptor.h new file mode 100644 index 0000000..42e850b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/copyjob_adaptor.h @@ -0,0 +1,56 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i fileoperationjob/copyjob.h -c CopyJobAdaptor -l CopyJob -a dbusadaptor/copyjob_adaptor copyjob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef COPYJOB_ADAPTOR_H +#define COPYJOB_ADAPTOR_H + +#include +#include +#include "fileoperationjob/copyjob.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.CopyJob + */ +class CopyJobAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.CopyJob") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + CopyJobAdaptor(CopyJob *parent); + virtual ~CopyJobAdaptor(); + + inline CopyJob *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + void Execute(); +Q_SIGNALS: // SIGNALS + void Done(const QString &in0); +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/createfolderjob_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/createfolderjob_adaptor.cpp new file mode 100644 index 0000000..43d5e8c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/createfolderjob_adaptor.cpp @@ -0,0 +1,41 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i fileoperationjob/createfolderjob.h -c CreateFolderJobAdaptor -l CreateFolderJob -a dbusadaptor/createfolderjob_adaptor createfolderjob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "dbusadaptor/createfolderjob_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class CreateFolderJobAdaptor + */ + +CreateFolderJobAdaptor::CreateFolderJobAdaptor(CreateFolderJob *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +CreateFolderJobAdaptor::~CreateFolderJobAdaptor() +{ + // destructor +} + +void CreateFolderJobAdaptor::Execute() +{ + // handle method call com.deepin.filemanager.daemon.CreateFolderJob.Execute + parent()->Execute(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/createfolderjob_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/createfolderjob_adaptor.h new file mode 100644 index 0000000..9dda6c7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/createfolderjob_adaptor.h @@ -0,0 +1,56 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i fileoperationjob/createfolderjob.h -c CreateFolderJobAdaptor -l CreateFolderJob -a dbusadaptor/createfolderjob_adaptor createfolderjob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef CREATEFOLDERJOB_ADAPTOR_H +#define CREATEFOLDERJOB_ADAPTOR_H + +#include +#include +#include "fileoperationjob/createfolderjob.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.CreateFolderJob + */ +class CreateFolderJobAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.CreateFolderJob") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + CreateFolderJobAdaptor(CreateFolderJob *parent); + virtual ~CreateFolderJobAdaptor(); + + inline CreateFolderJob *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + void Execute(); +Q_SIGNALS: // SIGNALS + void Done(const QString &in0); +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/createtemplatefilejob_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/createtemplatefilejob_adaptor.cpp new file mode 100644 index 0000000..815684d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/createtemplatefilejob_adaptor.cpp @@ -0,0 +1,41 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i fileoperationjob/createtemplatefilejob.h -c CreateTemplateFileAdaptor -l CreateTemplateFileJob -a dbusadaptor/createtemplatefilejob_adaptor createtemplatefilejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "dbusadaptor/createtemplatefilejob_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class CreateTemplateFileAdaptor + */ + +CreateTemplateFileAdaptor::CreateTemplateFileAdaptor(CreateTemplateFileJob *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +CreateTemplateFileAdaptor::~CreateTemplateFileAdaptor() +{ + // destructor +} + +void CreateTemplateFileAdaptor::Execute() +{ + // handle method call com.deepin.filemanager.daemon.CreateTemplateFileJob.Execute + parent()->Execute(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/createtemplatefilejob_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/createtemplatefilejob_adaptor.h new file mode 100644 index 0000000..c817c66 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/createtemplatefilejob_adaptor.h @@ -0,0 +1,56 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i fileoperationjob/createtemplatefilejob.h -c CreateTemplateFileAdaptor -l CreateTemplateFileJob -a dbusadaptor/createtemplatefilejob_adaptor createtemplatefilejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef CREATETEMPLATEFILEJOB_ADAPTOR_H +#define CREATETEMPLATEFILEJOB_ADAPTOR_H + +#include +#include +#include "fileoperationjob/createtemplatefilejob.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.CreateTemplateFileJob + */ +class CreateTemplateFileAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.CreateTemplateFileJob") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + CreateTemplateFileAdaptor(CreateTemplateFileJob *parent); + virtual ~CreateTemplateFileAdaptor(); + + inline CreateTemplateFileJob *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + void Execute(); +Q_SIGNALS: // SIGNALS + void Done(const QString &in0); +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/deletejob_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/deletejob_adaptor.cpp new file mode 100644 index 0000000..5e148b9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/deletejob_adaptor.cpp @@ -0,0 +1,41 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i fileoperationjob/deletejob.h -c DeleteJobAdaptor -l DeleteJob -a dbusadaptor/deletejob_adaptor deletejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "dbusadaptor/deletejob_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class DeleteJobAdaptor + */ + +DeleteJobAdaptor::DeleteJobAdaptor(DeleteJob *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +DeleteJobAdaptor::~DeleteJobAdaptor() +{ + // destructor +} + +void DeleteJobAdaptor::Execute() +{ + // handle method call com.deepin.filemanager.daemon.DeleteJob.Execute + parent()->Execute(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/deletejob_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/deletejob_adaptor.h new file mode 100644 index 0000000..afe05bd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/deletejob_adaptor.h @@ -0,0 +1,56 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i fileoperationjob/deletejob.h -c DeleteJobAdaptor -l DeleteJob -a dbusadaptor/deletejob_adaptor deletejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef DELETEJOB_ADAPTOR_H +#define DELETEJOB_ADAPTOR_H + +#include +#include +#include "fileoperationjob/deletejob.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.DeleteJob + */ +class DeleteJobAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.DeleteJob") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + DeleteJobAdaptor(DeleteJob *parent); + virtual ~DeleteJobAdaptor(); + + inline DeleteJob *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + void Execute(); +Q_SIGNALS: // SIGNALS + void Done(const QString &in0); +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/fileoperation_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/fileoperation_adaptor.cpp new file mode 100644 index 0000000..99966c4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/fileoperation_adaptor.cpp @@ -0,0 +1,77 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i controllers/fileoperation.h -i dbusservice/dbustype/dbusinforet.h -c FileOperationAdaptor -l FileOperation -a dbusadaptor/fileoperation_adaptor fileoperation.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "dbusadaptor/fileoperation_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class FileOperationAdaptor + */ + +FileOperationAdaptor::FileOperationAdaptor(FileOperation *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +FileOperationAdaptor::~FileOperationAdaptor() +{ + // destructor +} + +DBusInfoRet FileOperationAdaptor::NewCopyJob(const QStringList &filelist, const QString &targetDir) +{ + // handle method call com.deepin.filemanager.daemon.Operations.NewCopyJob + return parent()->NewCopyJob(filelist, targetDir); +} + +DBusInfoRet FileOperationAdaptor::NewCreateFolderJob(const QString &fabspath) +{ + // handle method call com.deepin.filemanager.daemon.Operations.NewCreateFolderJob + return parent()->NewCreateFolderJob(fabspath); +} + +DBusInfoRet FileOperationAdaptor::NewCreateTemplateFileJob(const QString &templateFile, const QString &targetDir) +{ + // handle method call com.deepin.filemanager.daemon.Operations.NewCreateTemplateFileJob + return parent()->NewCreateTemplateFileJob(templateFile, targetDir); +} + +DBusInfoRet FileOperationAdaptor::NewDeleteJob(const QStringList &filelist) +{ + // handle method call com.deepin.filemanager.daemon.Operations.NewDeleteJob + return parent()->NewDeleteJob(filelist); +} + +DBusInfoRet FileOperationAdaptor::NewMoveJob(const QStringList &filelist, const QString &targetDir) +{ + // handle method call com.deepin.filemanager.daemon.Operations.NewMoveJob + return parent()->NewMoveJob(filelist, targetDir); +} + +DBusInfoRet FileOperationAdaptor::NewRenameJob(const QString &oldFile, const QString &newFile) +{ + // handle method call com.deepin.filemanager.daemon.Operations.NewRenameJob + return parent()->NewRenameJob(oldFile, newFile); +} + +QString FileOperationAdaptor::test(const QString &oldFile, const QString &newFile, QDBusObjectPath &result2, bool &result3) +{ + // handle method call com.deepin.filemanager.daemon.Operations.test + return parent()->test(oldFile, newFile, result2, result3); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/fileoperation_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/fileoperation_adaptor.h new file mode 100644 index 0000000..fee6088 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/fileoperation_adaptor.h @@ -0,0 +1,99 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i controllers/fileoperation.h -i dbusservice/dbustype/dbusinforet.h -c FileOperationAdaptor -l FileOperation -a dbusadaptor/fileoperation_adaptor fileoperation.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef FILEOPERATION_ADAPTOR_H +#define FILEOPERATION_ADAPTOR_H + +#include +#include +#include "controllers/fileoperation.h" +#include "dbusservice/dbustype/dbusinforet.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.Operations + */ +class FileOperationAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.Operations") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + FileOperationAdaptor(FileOperation *parent); + virtual ~FileOperationAdaptor(); + + inline FileOperation *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + DBusInfoRet NewCopyJob(const QStringList &filelist, const QString &targetDir); + DBusInfoRet NewCreateFolderJob(const QString &fabspath); + DBusInfoRet NewCreateTemplateFileJob(const QString &templateFile, const QString &targetDir); + DBusInfoRet NewDeleteJob(const QStringList &filelist); + DBusInfoRet NewMoveJob(const QStringList &filelist, const QString &targetDir); + DBusInfoRet NewRenameJob(const QString &oldFile, const QString &newFile); + QString test(const QString &oldFile, const QString &newFile, QDBusObjectPath &result2, bool &result3); +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/movejob_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/movejob_adaptor.cpp new file mode 100644 index 0000000..5bb4844 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/movejob_adaptor.cpp @@ -0,0 +1,41 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i fileoperationjob/movejob.h -c MoveJobAdaptor -l MoveJob -a dbusadaptor/movejob_adaptor movejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "dbusadaptor/movejob_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class MoveJobAdaptor + */ + +MoveJobAdaptor::MoveJobAdaptor(MoveJob *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +MoveJobAdaptor::~MoveJobAdaptor() +{ + // destructor +} + +void MoveJobAdaptor::Execute() +{ + // handle method call com.deepin.filemanager.daemon.RenameJob.Execute + parent()->Execute(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/movejob_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/movejob_adaptor.h new file mode 100644 index 0000000..17eb0d4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/movejob_adaptor.h @@ -0,0 +1,56 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i fileoperationjob/movejob.h -c MoveJobAdaptor -l MoveJob -a dbusadaptor/movejob_adaptor movejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef MOVEJOB_ADAPTOR_H +#define MOVEJOB_ADAPTOR_H + +#include +#include +#include "fileoperationjob/movejob.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.RenameJob + */ +class MoveJobAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.RenameJob") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + MoveJobAdaptor(MoveJob *parent); + virtual ~MoveJobAdaptor(); + + inline MoveJob *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + void Execute(); +Q_SIGNALS: // SIGNALS + void Done(const QString &in0); +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/partitionmanager_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/partitionmanager_adaptor.cpp new file mode 100644 index 0000000..abb6074 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/partitionmanager_adaptor.cpp @@ -0,0 +1,41 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i ../partman/partitionmanager.h -c PartitionManagerAdaptor -l PartitionManager -a dbusadaptor/partitionmanager_adaptor partitionmanager.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "dbusadaptor/partitionmanager_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class PartitionManagerAdaptor + */ + +PartitionManagerAdaptor::PartitionManagerAdaptor(PartitionManager *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +PartitionManagerAdaptor::~PartitionManagerAdaptor() +{ + // destructor +} + +bool PartitionManagerAdaptor::mkfs(const QString &path, const QString &fstype, const QString &label) +{ + // handle method call com.deepin.filemanager.daemon.PartitionManager.mkfs + return parent()->mkfs(path, fstype, label); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/partitionmanager_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/partitionmanager_adaptor.h new file mode 100644 index 0000000..5e4c7d1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/partitionmanager_adaptor.h @@ -0,0 +1,57 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i ../partman/partitionmanager.h -c PartitionManagerAdaptor -l PartitionManager -a dbusadaptor/partitionmanager_adaptor partitionmanager.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef PARTITIONMANAGER_ADAPTOR_H +#define PARTITIONMANAGER_ADAPTOR_H + +#include +#include +#include "../partman/partitionmanager.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.PartitionManager + */ +class PartitionManagerAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.PartitionManager") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + PartitionManagerAdaptor(PartitionManager *parent); + virtual ~PartitionManagerAdaptor(); + + inline PartitionManager *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + bool mkfs(const QString &path, const QString &fstype, const QString &label); +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/renamejob_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/renamejob_adaptor.cpp new file mode 100644 index 0000000..4c231dc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/renamejob_adaptor.cpp @@ -0,0 +1,41 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i fileoperationjob/renamejob.h -c RenameJobAdaptor -l RenameJob -a dbusadaptor/renamejob_adaptor renamejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "dbusadaptor/renamejob_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class RenameJobAdaptor + */ + +RenameJobAdaptor::RenameJobAdaptor(RenameJob *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +RenameJobAdaptor::~RenameJobAdaptor() +{ + // destructor +} + +void RenameJobAdaptor::Execute() +{ + // handle method call com.deepin.filemanager.daemon.RenameJob.Execute + parent()->Execute(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/renamejob_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/renamejob_adaptor.h new file mode 100644 index 0000000..3adfc2c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/renamejob_adaptor.h @@ -0,0 +1,56 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i fileoperationjob/renamejob.h -c RenameJobAdaptor -l RenameJob -a dbusadaptor/renamejob_adaptor renamejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef RENAMEJOB_ADAPTOR_H +#define RENAMEJOB_ADAPTOR_H + +#include +#include +#include "fileoperationjob/renamejob.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.RenameJob + */ +class RenameJobAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.RenameJob") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + RenameJobAdaptor(RenameJob *parent); + virtual ~RenameJobAdaptor(); + + inline RenameJob *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + void Execute(); +Q_SIGNALS: // SIGNALS + void Done(const QString &in0); +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/revocationmgr_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/revocationmgr_adaptor.cpp new file mode 100644 index 0000000..8109a9c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/revocationmgr_adaptor.cpp @@ -0,0 +1,47 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i ../revocation/revocationmanager.h -c RevocationMgrAdaptor -l RevocationManager -a ../dbusservice/dbusadaptor/revocationmgr_adaptor revocation.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "../dbusservice/dbusadaptor/revocationmgr_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class RevocationMgrAdaptor + */ + +RevocationMgrAdaptor::RevocationMgrAdaptor(RevocationManager *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +RevocationMgrAdaptor::~RevocationMgrAdaptor() +{ + // destructor +} + +int RevocationMgrAdaptor::popEvent() +{ + // handle method call com.deepin.filemanager.daemon.RevocationManager.popEvent + return parent()->popEvent(); +} + +void RevocationMgrAdaptor::pushEvent(int event, const QString &user) +{ + // handle method call com.deepin.filemanager.daemon.RevocationManager.pushEvent + parent()->pushEvent(event, user); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/revocationmgr_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/revocationmgr_adaptor.h new file mode 100644 index 0000000..9acf0ac --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/revocationmgr_adaptor.h @@ -0,0 +1,67 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i ../revocation/revocationmanager.h -c RevocationMgrAdaptor -l RevocationManager -a ../dbusservice/dbusadaptor/revocationmgr_adaptor revocation.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef REVOCATIONMGR_ADAPTOR_H +#define REVOCATIONMGR_ADAPTOR_H + +#include +#include +#include "../revocation/revocationmanager.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.RevocationManager + */ +class RevocationMgrAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.RevocationManager") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + RevocationMgrAdaptor(RevocationManager *parent); + virtual ~RevocationMgrAdaptor(); + + inline RevocationManager *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + int popEvent(); + void pushEvent(int event, const QString &user); +Q_SIGNALS: // SIGNALS + void deskRevocationAction(const QString &user); + void fmgrRevocationAction(const QString &user); +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/tagmanagerdaemon_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/tagmanagerdaemon_adaptor.cpp new file mode 100644 index 0000000..e0f5353 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/tagmanagerdaemon_adaptor.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dbusadaptor/tagmanagerdaemon_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class TagManagerDaemonAdaptor + */ + +TagManagerDaemonAdaptor::TagManagerDaemonAdaptor(QObject *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +TagManagerDaemonAdaptor::~TagManagerDaemonAdaptor() +{ + // destructor +} + +QDBusVariant TagManagerDaemonAdaptor::disposeClientData(const QVariantMap &filesAndTags, qulonglong type) +{ + // handle method call com.deepin.filemanager.daemon.TagManagerDaemon.disposeClientData + QDBusVariant result; + QMetaObject::invokeMethod(parent(), "disposeClientData", Q_RETURN_ARG(QDBusVariant, result), Q_ARG(QVariantMap, filesAndTags), Q_ARG(qulonglong, type)); + return result; +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/tagmanagerdaemon_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/tagmanagerdaemon_adaptor.h new file mode 100644 index 0000000..45fbafe --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/tagmanagerdaemon_adaptor.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef TAGMANAGERDAEMON_ADAPTOR_H +#define TAGMANAGERDAEMON_ADAPTOR_H + +#include +#include +#include "tag/tagmanagerdaemon.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.TagManagerDaemon + */ +class TagManagerDaemonAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.TagManagerDaemon") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + TagManagerDaemonAdaptor(QObject *parent); + virtual ~TagManagerDaemonAdaptor(); + +public: // PROPERTIES +public Q_SLOTS: // METHODS + QDBusVariant disposeClientData(const QVariantMap &filesAndTags, qulonglong type); +Q_SIGNALS: // SIGNALS + void addNewTags(const QDBusVariant &new_tags); + void changeTagColor(const QVariantMap &old_and_new_color); + void changeTagName(const QVariantMap &old_and_new_name); + void deleteTags(const QDBusVariant &be_deleted_tags); + void filesWereTagged(const QVariantMap &tagged_files); + void untagFiles(const QVariantMap &file_be_removed_tags); +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/usershare_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/usershare_adaptor.cpp new file mode 100644 index 0000000..6423a32 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/usershare_adaptor.cpp @@ -0,0 +1,59 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i usershare/usersharemanager.h -c UserShareAdaptor -l UserShareManager -a dbusadaptor/usershare_adaptor usershare.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "dbusadaptor/usershare_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class UserShareAdaptor + */ + +UserShareAdaptor::UserShareAdaptor(UserShareManager *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +UserShareAdaptor::~UserShareAdaptor() +{ + // destructor +} + +bool UserShareAdaptor::addGroup(const QString &groupName) +{ + // handle method call com.deepin.filemanager.daemon.UserShareManager.addGroup + return parent()->addGroup(groupName); +} + +bool UserShareAdaptor::closeSmbShareByShareName(const QString &sharename, bool bshow) +{ + // handle method call com.deepin.filemanager.daemon.UserShareManager.closeSmbShareByShareName + return parent()->closeSmbShareByShareName(sharename, bshow); +} + +bool UserShareAdaptor::createShareLinkFile() +{ + // handle method call com.deepin.filemanager.daemon.UserShareManager.createShareLinkFile + return parent()->createShareLinkFile(); +} + +bool UserShareAdaptor::setUserSharePassword(const QString &username, const QString &passward) +{ + // handle method call com.deepin.filemanager.daemon.UserShareManager.setUserSharePassword + return parent()->setUserSharePassword(username, passward); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/usershare_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/usershare_adaptor.h new file mode 100644 index 0000000..3e08747 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/usershare_adaptor.h @@ -0,0 +1,71 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i usershare/usersharemanager.h -c UserShareAdaptor -l UserShareManager -a dbusadaptor/usershare_adaptor usershare.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef USERSHARE_ADAPTOR_H +#define USERSHARE_ADAPTOR_H + +#include +#include +#include "usershare/usersharemanager.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.UserShareManager + */ +class UserShareAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.UserShareManager") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + UserShareAdaptor(UserShareManager *parent); + virtual ~UserShareAdaptor(); + + inline UserShareManager *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + bool addGroup(const QString &groupName); + bool closeSmbShareByShareName(const QString &sharename, bool bshow); + bool createShareLinkFile(); + bool setUserSharePassword(const QString &username, const QString &passward); +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/vault_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/vault_adaptor.cpp new file mode 100644 index 0000000..30b7f77 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/vault_adaptor.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "../dbusservice/dbusadaptor/vault_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class VaultAdaptor + */ + +VaultAdaptor::VaultAdaptor(VaultManager *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +VaultAdaptor::~VaultAdaptor() +{ + // destructor +} + +bool VaultAdaptor::checkAuthentication(const QString &type) +{ + // handle method call com.deepin.filemanager.daemon.VaultManager.checkAuthentication + return parent()->checkAuthentication(type); +} + +void VaultAdaptor::clearLockEvent() +{ + // handle method call com.deepin.filemanager.daemon.VaultManager.clearLockEvent + parent()->clearLockEvent(); +} + +qulonglong VaultAdaptor::getLastestTime() +{ + // handle method call com.deepin.filemanager.daemon.VaultManager.getLastestTime + return parent()->getLastestTime(); +} + +qulonglong VaultAdaptor::getSelfTime() +{ + // handle method call com.deepin.filemanager.daemon.VaultManager.getSelfTime + return parent()->getSelfTime(); +} + +bool VaultAdaptor::isLockEventTriggered() +{ + // handle method call com.deepin.filemanager.daemon.VaultManager.isLockEventTriggered + return parent()->isLockEventTriggered(); +} + +void VaultAdaptor::setRefreshTime(qulonglong time) +{ + // handle method call com.deepin.filemanager.daemon.VaultManager.setRefreshTime + parent()->setRefreshTime(time); +} + +void VaultAdaptor::sysUserChanged(const QString &curUser) +{ + // handle method call com.deepin.filemanager.daemon.VaultManager.sysUserChanged + parent()->sysUserChanged(curUser); +} + +void VaultAdaptor::triggerLockEvent() +{ + // handle method call com.deepin.filemanager.daemon.VaultManager.triggerLockEvent + parent()->triggerLockEvent(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/vault_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/vault_adaptor.h new file mode 100644 index 0000000..bd5f77d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/vault_adaptor.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef VAULT_ADAPTOR_H +#define VAULT_ADAPTOR_H + +#include +#include +#include "../vault/vaultmanager.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.VaultManager + */ +class VaultAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.VaultManager") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + VaultAdaptor(VaultManager *parent); + virtual ~VaultAdaptor(); + + inline VaultManager *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + bool checkAuthentication(const QString &type); + void clearLockEvent(); + qulonglong getLastestTime(); + qulonglong getSelfTime(); + bool isLockEventTriggered(); + void setRefreshTime(qulonglong time); + void sysUserChanged(const QString &curUser); + void triggerLockEvent(); +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/vaultbruteforceprevention_adaptor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/vaultbruteforceprevention_adaptor.cpp new file mode 100644 index 0000000..9e19b5e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/vaultbruteforceprevention_adaptor.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "../dbusservice/dbusadaptor/vaultbruteforceprevention_adaptor.h" +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class VaultBruteForcePreventionAdaptor + */ + +VaultBruteForcePreventionAdaptor::VaultBruteForcePreventionAdaptor(VaultBruteForcePrevention *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +VaultBruteForcePreventionAdaptor::~VaultBruteForcePreventionAdaptor() +{ + // destructor +} + +int VaultBruteForcePreventionAdaptor::getLeftoverErrorInputTimes(int userID) +{ + // handle method call com.deepin.filemanager.daemon.VaultManager2.getLeftoverErrorInputTimes + return parent()->getLeftoverErrorInputTimes(userID); +} + +int VaultBruteForcePreventionAdaptor::getNeedWaitMinutes(int userID) +{ + // handle method call com.deepin.filemanager.daemon.VaultManager2.getNeedWaitMinutes + return parent()->getNeedWaitMinutes(userID); +} + +void VaultBruteForcePreventionAdaptor::leftoverErrorInputTimesMinusOne(int userID) +{ + // handle method call com.deepin.filemanager.daemon.VaultManager2.leftoverErrorInputTimesMinusOne + parent()->leftoverErrorInputTimesMinusOne(userID); +} + +void VaultBruteForcePreventionAdaptor::restoreLeftoverErrorInputTimes(int userID) +{ + // handle method call com.deepin.filemanager.daemon.VaultManager2.restoreLeftoverErrorInputTimes + parent()->restoreLeftoverErrorInputTimes(userID); +} + +void VaultBruteForcePreventionAdaptor::restoreNeedWaitMinutes(int userID) +{ + // handle method call com.deepin.filemanager.daemon.VaultManager2.restoreNeedWaitMinutes + parent()->restoreNeedWaitMinutes(userID); +} + +void VaultBruteForcePreventionAdaptor::startTimerOfRestorePasswordInput(int userID) +{ + // handle method call com.deepin.filemanager.daemon.VaultManager2.startTimerOfRestorePasswordInput + parent()->startTimerOfRestorePasswordInput(userID); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/vaultbruteforceprevention_adaptor.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/vaultbruteforceprevention_adaptor.h new file mode 100644 index 0000000..09cdf0f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusadaptor/vaultbruteforceprevention_adaptor.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef VAULTBRUTEFORCEPREVENTION_ADAPTOR_H +#define VAULTBRUTEFORCEPREVENTION_ADAPTOR_H + +#include +#include +#include "../vault/vaultbruteforceprevention.h" +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.filemanager.daemon.VaultManager2 + */ +class VaultBruteForcePreventionAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.daemon.VaultManager2") + Q_CLASSINFO("D-Bus Introspection", "" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" + "") +public: + VaultBruteForcePreventionAdaptor(VaultBruteForcePrevention *parent); + virtual ~VaultBruteForcePreventionAdaptor(); + + inline VaultBruteForcePrevention *parent() const + { return static_cast(QObject::parent()); } + +public: // PROPERTIES +public Q_SLOTS: // METHODS + int getLeftoverErrorInputTimes(int userID); + int getNeedWaitMinutes(int userID); + void leftoverErrorInputTimesMinusOne(int userID); + void restoreLeftoverErrorInputTimes(int userID); + void restoreNeedWaitMinutes(int userID); + void startTimerOfRestorePasswordInput(int userID); +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/accesscontrol_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/accesscontrol_interface.cpp new file mode 100644 index 0000000..f832b54 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/accesscontrol_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c AccessControlInterface -p dbusinterface/accesscontrol_interface acesscontrol.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/accesscontrol_interface.h" + +/* + * Implementation of interface class AccessControlInterface + */ + +AccessControlInterface::AccessControlInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +AccessControlInterface::~AccessControlInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/accesscontrol_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/accesscontrol_interface.h new file mode 100644 index 0000000..22ab37a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/accesscontrol_interface.h @@ -0,0 +1,93 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c AccessControlInterface -p dbusinterface/accesscontrol_interface acesscontrol.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef ACCESSCONTROL_INTERFACE_H +#define ACCESSCONTROL_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.AccessControlManager + */ +class AccessControlInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.AccessControlManager"; } + +public: + AccessControlInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~AccessControlInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply FileManagerReply(int policystate) + { + QList argumentList; + argumentList << QVariant::fromValue(policystate); + return asyncCallWithArgumentList(QStringLiteral("FileManagerReply"), argumentList); + } + + inline QDBusPendingReply QueryAccessPolicy() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("QueryAccessPolicy"), argumentList); + } + + inline QDBusPendingReply QueryVaultAccessPolicy() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("QueryVaultAccessPolicy"), argumentList); + } + + inline QDBusPendingReply QueryVaultAccessPolicyVisible() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("QueryVaultAccessPolicyVisible"), argumentList); + } + + inline QDBusPendingReply SetAccessPolicy(const QVariantMap &policy) + { + QList argumentList; + argumentList << QVariant::fromValue(policy); + return asyncCallWithArgumentList(QStringLiteral("SetAccessPolicy"), argumentList); + } + + inline QDBusPendingReply SetVaultAccessPolicy(const QVariantMap &policy) + { + QList argumentList; + argumentList << QVariant::fromValue(policy); + return asyncCallWithArgumentList(QStringLiteral("SetVaultAccessPolicy"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void AccessPolicySetFinished(const QVariantMap &policy); + void AccessVaultPolicyNotify(); + void DeviceAccessPolicyChanged(const QVariantList &policy); +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::AccessControlInterface AccessControlManager; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/acesscontrol_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/acesscontrol_interface.cpp new file mode 100644 index 0000000..922ce0d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/acesscontrol_interface.cpp @@ -0,0 +1,13 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c AcessControlInterface -p dbusinterface/acesscontrol_interface acesscontrol.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/acesscontrol_interface.h" + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/acesscontrol_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/acesscontrol_interface.h new file mode 100644 index 0000000..bdc56c3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/acesscontrol_interface.h @@ -0,0 +1,23 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c AcessControlInterface -p dbusinterface/acesscontrol_interface acesscontrol.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef ACESSCONTROL_INTERFACE_H +#define ACESSCONTROL_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/copyjob_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/copyjob_interface.cpp new file mode 100644 index 0000000..cbbbefc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/copyjob_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c CopyJobInterface -p dbusinterface/copyjob_interface copyjob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/copyjob_interface.h" + +/* + * Implementation of interface class CopyJobInterface + */ + +CopyJobInterface::CopyJobInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +CopyJobInterface::~CopyJobInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/copyjob_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/copyjob_interface.h new file mode 100644 index 0000000..a685494 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/copyjob_interface.h @@ -0,0 +1,58 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c CopyJobInterface -p dbusinterface/copyjob_interface copyjob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef COPYJOB_INTERFACE_H +#define COPYJOB_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.CopyJob + */ +class CopyJobInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.CopyJob"; } + +public: + CopyJobInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~CopyJobInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> Execute() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("Execute"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void Done(const QString &in0); +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::CopyJobInterface CopyJob; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/createfolderjob_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/createfolderjob_interface.cpp new file mode 100644 index 0000000..f5bd73d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/createfolderjob_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c CreateFolderJobInterface -p dbusinterface/createfolderjob_interface createfolderjob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/createfolderjob_interface.h" + +/* + * Implementation of interface class CreateFolderJobInterface + */ + +CreateFolderJobInterface::CreateFolderJobInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +CreateFolderJobInterface::~CreateFolderJobInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/createfolderjob_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/createfolderjob_interface.h new file mode 100644 index 0000000..7c9462a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/createfolderjob_interface.h @@ -0,0 +1,58 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c CreateFolderJobInterface -p dbusinterface/createfolderjob_interface createfolderjob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef CREATEFOLDERJOB_INTERFACE_H +#define CREATEFOLDERJOB_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.CreateFolderJob + */ +class CreateFolderJobInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.CreateFolderJob"; } + +public: + CreateFolderJobInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~CreateFolderJobInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> Execute() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("Execute"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void Done(const QString &in0); +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::CreateFolderJobInterface CreateFolderJob; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/createtemplatefilejob_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/createtemplatefilejob_interface.cpp new file mode 100644 index 0000000..c104df9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/createtemplatefilejob_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c CreateTemplateFileInterface -p dbusinterface/createtemplatefilejob_interface createtemplatefilejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/createtemplatefilejob_interface.h" + +/* + * Implementation of interface class CreateTemplateFileInterface + */ + +CreateTemplateFileInterface::CreateTemplateFileInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +CreateTemplateFileInterface::~CreateTemplateFileInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/createtemplatefilejob_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/createtemplatefilejob_interface.h new file mode 100644 index 0000000..2471d3d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/createtemplatefilejob_interface.h @@ -0,0 +1,58 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c CreateTemplateFileInterface -p dbusinterface/createtemplatefilejob_interface createtemplatefilejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef CREATETEMPLATEFILEJOB_INTERFACE_H +#define CREATETEMPLATEFILEJOB_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.CreateTemplateFileJob + */ +class CreateTemplateFileInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.CreateTemplateFileJob"; } + +public: + CreateTemplateFileInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~CreateTemplateFileInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> Execute() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("Execute"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void Done(const QString &in0); +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::CreateTemplateFileInterface CreateTemplateFileJob; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/deletejob_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/deletejob_interface.cpp new file mode 100644 index 0000000..4ef8754 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/deletejob_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c DeleteJobInterface -p dbusinterface/deletejob_interface deletejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/deletejob_interface.h" + +/* + * Implementation of interface class DeleteJobInterface + */ + +DeleteJobInterface::DeleteJobInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +DeleteJobInterface::~DeleteJobInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/deletejob_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/deletejob_interface.h new file mode 100644 index 0000000..594d7b4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/deletejob_interface.h @@ -0,0 +1,58 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c DeleteJobInterface -p dbusinterface/deletejob_interface deletejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef DELETEJOB_INTERFACE_H +#define DELETEJOB_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.DeleteJob + */ +class DeleteJobInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.DeleteJob"; } + +public: + DeleteJobInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~DeleteJobInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> Execute() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("Execute"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void Done(const QString &in0); +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::DeleteJobInterface DeleteJob; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/fileoperation_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/fileoperation_interface.cpp new file mode 100644 index 0000000..0f3f5c6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/fileoperation_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i dbusservice/dbustype/dbusinforet.h -c FileOperationInterface -p dbusinterface/fileoperation_interface fileoperation.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/fileoperation_interface.h" + +/* + * Implementation of interface class FileOperationInterface + */ + +FileOperationInterface::FileOperationInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +FileOperationInterface::~FileOperationInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/fileoperation_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/fileoperation_interface.h new file mode 100644 index 0000000..74f4f4f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/fileoperation_interface.h @@ -0,0 +1,112 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i dbusservice/dbustype/dbusinforet.h -c FileOperationInterface -p dbusinterface/fileoperation_interface fileoperation.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef FILEOPERATION_INTERFACE_H +#define FILEOPERATION_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "dbusservice/dbustype/dbusinforet.h" + +/* + * Proxy class for interface com.deepin.filemanager.daemon.Operations + */ +class FileOperationInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.Operations"; } + +public: + FileOperationInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~FileOperationInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply NewCopyJob(const QStringList &filelist, const QString &targetDir) + { + QList argumentList; + argumentList << QVariant::fromValue(filelist) << QVariant::fromValue(targetDir); + return asyncCallWithArgumentList(QStringLiteral("NewCopyJob"), argumentList); + } + + inline QDBusPendingReply NewCreateFolderJob(const QString &fabspath) + { + QList argumentList; + argumentList << QVariant::fromValue(fabspath); + return asyncCallWithArgumentList(QStringLiteral("NewCreateFolderJob"), argumentList); + } + + inline QDBusPendingReply NewCreateTemplateFileJob(const QString &templateFile, const QString &targetDir) + { + QList argumentList; + argumentList << QVariant::fromValue(templateFile) << QVariant::fromValue(targetDir); + return asyncCallWithArgumentList(QStringLiteral("NewCreateTemplateFileJob"), argumentList); + } + + inline QDBusPendingReply NewDeleteJob(const QStringList &filelist) + { + QList argumentList; + argumentList << QVariant::fromValue(filelist); + return asyncCallWithArgumentList(QStringLiteral("NewDeleteJob"), argumentList); + } + + inline QDBusPendingReply NewMoveJob(const QStringList &filelist, const QString &targetDir) + { + QList argumentList; + argumentList << QVariant::fromValue(filelist) << QVariant::fromValue(targetDir); + return asyncCallWithArgumentList(QStringLiteral("NewMoveJob"), argumentList); + } + + inline QDBusPendingReply NewRenameJob(const QString &oldFile, const QString &newFile) + { + QList argumentList; + argumentList << QVariant::fromValue(oldFile) << QVariant::fromValue(newFile); + return asyncCallWithArgumentList(QStringLiteral("NewRenameJob"), argumentList); + } + + inline QDBusPendingReply test(const QString &oldFile, const QString &newFile) + { + QList argumentList; + argumentList << QVariant::fromValue(oldFile) << QVariant::fromValue(newFile); + return asyncCallWithArgumentList(QStringLiteral("test"), argumentList); + } + inline QDBusReply test(const QString &oldFile, const QString &newFile, QDBusObjectPath &result2, bool &result3) + { + QList argumentList; + argumentList << QVariant::fromValue(oldFile) << QVariant::fromValue(newFile); + QDBusMessage reply = callWithArgumentList(QDBus::Block, QStringLiteral("test"), argumentList); + if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 3) { + result2 = qdbus_cast(reply.arguments().at(1)); + result3 = qdbus_cast(reply.arguments().at(2)); + } + return reply; + } + +Q_SIGNALS: // SIGNALS +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::FileOperationInterface Operations; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/movejob_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/movejob_interface.cpp new file mode 100644 index 0000000..5f4f8f1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/movejob_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c MoveJobInterface -p dbusinterface/movejob_interface movejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/movejob_interface.h" + +/* + * Implementation of interface class MoveJobInterface + */ + +MoveJobInterface::MoveJobInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +MoveJobInterface::~MoveJobInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/movejob_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/movejob_interface.h new file mode 100644 index 0000000..93f2826 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/movejob_interface.h @@ -0,0 +1,58 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c MoveJobInterface -p dbusinterface/movejob_interface movejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef MOVEJOB_INTERFACE_H +#define MOVEJOB_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.RenameJob + */ +class MoveJobInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.RenameJob"; } + +public: + MoveJobInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~MoveJobInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> Execute() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("Execute"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void Done(const QString &in0); +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::MoveJobInterface RenameJob; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/partitionmanager_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/partitionmanager_interface.cpp new file mode 100644 index 0000000..560e3d6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/partitionmanager_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c PartitionManagerInterface -p dbusinterface/partitionmanager_interface partitionmanager.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/partitionmanager_interface.h" + +/* + * Implementation of interface class PartitionManagerInterface + */ + +PartitionManagerInterface::PartitionManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +PartitionManagerInterface::~PartitionManagerInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/partitionmanager_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/partitionmanager_interface.h new file mode 100644 index 0000000..f692533 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/partitionmanager_interface.h @@ -0,0 +1,58 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c PartitionManagerInterface -p dbusinterface/partitionmanager_interface partitionmanager.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef PARTITIONMANAGER_INTERFACE_H +#define PARTITIONMANAGER_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.PartitionManager + */ +class PartitionManagerInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.PartitionManager"; } + +public: + PartitionManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~PartitionManagerInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply mkfs(const QString &path, const QString &fstype, const QString &label) + { + QList argumentList; + argumentList << QVariant::fromValue(path) << QVariant::fromValue(fstype) << QVariant::fromValue(label); + return asyncCallWithArgumentList(QStringLiteral("mkfs"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::PartitionManagerInterface PartitionManager; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/renamejob_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/renamejob_interface.cpp new file mode 100644 index 0000000..2cbd5dd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/renamejob_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c RenameJobInterface -p dbusinterface/renamejob_interface renamejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/renamejob_interface.h" + +/* + * Implementation of interface class RenameJobInterface + */ + +RenameJobInterface::RenameJobInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +RenameJobInterface::~RenameJobInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/renamejob_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/renamejob_interface.h new file mode 100644 index 0000000..088cf1c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/renamejob_interface.h @@ -0,0 +1,58 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c RenameJobInterface -p dbusinterface/renamejob_interface renamejob.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef RENAMEJOB_INTERFACE_H +#define RENAMEJOB_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.RenameJob + */ +class RenameJobInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.RenameJob"; } + +public: + RenameJobInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~RenameJobInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> Execute() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("Execute"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void Done(const QString &in0); +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::RenameJobInterface RenameJob; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/revocationmgr_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/revocationmgr_interface.cpp new file mode 100644 index 0000000..8a49efd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/revocationmgr_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c RevocationMgrInterface -p ../dbusservice/dbusinterface/revocationmgr_interface revocation.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "../dbusservice/dbusinterface/revocationmgr_interface.h" + +/* + * Implementation of interface class RevocationMgrInterface + */ + +RevocationMgrInterface::RevocationMgrInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +RevocationMgrInterface::~RevocationMgrInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/revocationmgr_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/revocationmgr_interface.h new file mode 100644 index 0000000..bacf9e1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/revocationmgr_interface.h @@ -0,0 +1,66 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c RevocationMgrInterface -p ../dbusservice/dbusinterface/revocationmgr_interface revocation.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef REVOCATIONMGR_INTERFACE_H +#define REVOCATIONMGR_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.RevocationManager + */ +class RevocationMgrInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.RevocationManager"; } + +public: + RevocationMgrInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~RevocationMgrInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply popEvent() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("popEvent"), argumentList); + } + + inline QDBusPendingReply<> pushEvent(int event, const QString &user) + { + QList argumentList; + argumentList << QVariant::fromValue(event) << QVariant::fromValue(user); + return asyncCallWithArgumentList(QStringLiteral("pushEvent"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void deskRevocationAction(const QString &user); + void fmgrRevocationAction(const QString &user); +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::RevocationMgrInterface RevocationManager; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/usbformatter_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/usbformatter_interface.cpp new file mode 100644 index 0000000..988349e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/usbformatter_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c UsbFormatterInterface -p dbusinterface/usbformatter_interface usbformatter.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/usbformatter_interface.h" + +/* + * Implementation of interface class UsbFormatterInterface + */ + +UsbFormatterInterface::UsbFormatterInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +UsbFormatterInterface::~UsbFormatterInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/usbformatter_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/usbformatter_interface.h new file mode 100644 index 0000000..9d739d8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/usbformatter_interface.h @@ -0,0 +1,58 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c UsbFormatterInterface -p dbusinterface/usbformatter_interface usbformatter.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef USBFORMATTER_INTERFACE_H +#define USBFORMATTER_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.UsbFormatter + */ +class UsbFormatterInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.UsbFormatter"; } + +public: + UsbFormatterInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~UsbFormatterInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply mkfs(const QString &path, const QString &fstype, const QString &label) + { + QList argumentList; + argumentList << QVariant::fromValue(path) << QVariant::fromValue(fstype) << QVariant::fromValue(label); + return asyncCallWithArgumentList(QStringLiteral("mkfs"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::UsbFormatterInterface UsbFormatter; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/usershare_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/usershare_interface.cpp new file mode 100644 index 0000000..0741bff --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/usershare_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c UserShareInterface -p dbusinterface/usershare_interface usershare.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/usershare_interface.h" + +/* + * Implementation of interface class UserShareInterface + */ + +UserShareInterface::UserShareInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +UserShareInterface::~UserShareInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/usershare_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/usershare_interface.h new file mode 100644 index 0000000..a6ed892 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/usershare_interface.h @@ -0,0 +1,78 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c UserShareInterface -p dbusinterface/usershare_interface usershare.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef USERSHARE_INTERFACE_H +#define USERSHARE_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.UserShareManager + */ +class UserShareInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.UserShareManager"; } + +public: + UserShareInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~UserShareInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply addGroup(const QString &groupName) + { + QList argumentList; + argumentList << QVariant::fromValue(groupName); + return asyncCallWithArgumentList(QStringLiteral("addGroup"), argumentList); + } + + inline QDBusPendingReply closeSmbShareByShareName(const QString &sharename, bool bshow) + { + QList argumentList; + argumentList << QVariant::fromValue(sharename) << QVariant::fromValue(bshow); + return asyncCallWithArgumentList(QStringLiteral("closeSmbShareByShareName"), argumentList); + } + + inline QDBusPendingReply createShareLinkFile() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("createShareLinkFile"), argumentList); + } + + inline QDBusPendingReply setUserSharePassword(const QString &username, const QString &passward) + { + QList argumentList; + argumentList << QVariant::fromValue(username) << QVariant::fromValue(passward); + return asyncCallWithArgumentList(QStringLiteral("setUserSharePassword"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::UserShareInterface UserShareManager; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/vault_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/vault_interface.cpp new file mode 100644 index 0000000..f8ea1c0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/vault_interface.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "../dbusservice/dbusinterface/vault_interface.h" + +/* + * Implementation of interface class VaultInterface + */ + +VaultInterface::VaultInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +VaultInterface::~VaultInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/vault_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/vault_interface.h new file mode 100644 index 0000000..c6393ed --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/vault_interface.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef VAULT_INTERFACE_H +#define VAULT_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.VaultManager + */ +class VaultInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.VaultManager"; } + +public: + VaultInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~VaultInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply checkAuthentication(const QString &type) + { + QList argumentList; + argumentList << QVariant::fromValue(type); + return asyncCallWithArgumentList(QStringLiteral("checkAuthentication"), argumentList); + } + + inline QDBusPendingReply<> clearLockEvent() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("clearLockEvent"), argumentList); + } + + inline QDBusPendingReply getLastestTime() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("getLastestTime"), argumentList); + } + + inline QDBusPendingReply getSelfTime() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("getSelfTime"), argumentList); + } + + inline QDBusPendingReply isLockEventTriggered() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("isLockEventTriggered"), argumentList); + } + + inline QDBusPendingReply<> setRefreshTime(qulonglong time) + { + QList argumentList; + argumentList << QVariant::fromValue(time); + return asyncCallWithArgumentList(QStringLiteral("setRefreshTime"), argumentList); + } + + inline QDBusPendingReply<> sysUserChanged(const QString &curUser) + { + QList argumentList; + argumentList << QVariant::fromValue(curUser); + return asyncCallWithArgumentList(QStringLiteral("sysUserChanged"), argumentList); + } + + inline QDBusPendingReply<> triggerLockEvent() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("triggerLockEvent"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::VaultInterface VaultManager; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/vaultbruteforceprevention_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/vaultbruteforceprevention_interface.cpp new file mode 100644 index 0000000..86af4c6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/vaultbruteforceprevention_interface.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "../dbusservice/dbusinterface/vaultbruteforceprevention_interface.h" + +/* + * Implementation of interface class VaultBruteForcePreventionInterface + */ + +VaultBruteForcePreventionInterface::VaultBruteForcePreventionInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +VaultBruteForcePreventionInterface::~VaultBruteForcePreventionInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/vaultbruteforceprevention_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/vaultbruteforceprevention_interface.h new file mode 100644 index 0000000..e61a297 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbusinterface/vaultbruteforceprevention_interface.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef VAULTBRUTEFORCEPREVENTION_INTERFACE_H +#define VAULTBRUTEFORCEPREVENTION_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.VaultManager2 + */ +class VaultBruteForcePreventionInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.VaultManager2"; } + +public: + VaultBruteForcePreventionInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~VaultBruteForcePreventionInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply getLeftoverErrorInputTimes(int userID) + { + QList argumentList; + argumentList << QVariant::fromValue(userID); + return asyncCallWithArgumentList(QStringLiteral("getLeftoverErrorInputTimes"), argumentList); + } + + inline QDBusPendingReply getNeedWaitMinutes(int userID) + { + QList argumentList; + argumentList << QVariant::fromValue(userID); + return asyncCallWithArgumentList(QStringLiteral("getNeedWaitMinutes"), argumentList); + } + + inline QDBusPendingReply<> leftoverErrorInputTimesMinusOne(int userID) + { + QList argumentList; + argumentList << QVariant::fromValue(userID); + return asyncCallWithArgumentList(QStringLiteral("leftoverErrorInputTimesMinusOne"), argumentList); + } + + inline QDBusPendingReply<> restoreLeftoverErrorInputTimes(int userID) + { + QList argumentList; + argumentList << QVariant::fromValue(userID); + return asyncCallWithArgumentList(QStringLiteral("restoreLeftoverErrorInputTimes"), argumentList); + } + + inline QDBusPendingReply<> restoreNeedWaitMinutes(int userID) + { + QList argumentList; + argumentList << QVariant::fromValue(userID); + return asyncCallWithArgumentList(QStringLiteral("restoreNeedWaitMinutes"), argumentList); + } + + inline QDBusPendingReply<> startTimerOfRestorePasswordInput(int userID) + { + QList argumentList; + argumentList << QVariant::fromValue(userID); + return asyncCallWithArgumentList(QStringLiteral("startTimerOfRestorePasswordInput"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::VaultBruteForcePreventionInterface VaultManager2; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbustype/dbusinforet.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbustype/dbusinforet.cpp new file mode 100644 index 0000000..c154527 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbustype/dbusinforet.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "dbusinforet.h" + +DBusInfoRet::DBusInfoRet() +{ + +} + +DBusInfoRet::~DBusInfoRet() +{ + +} + +QDBusArgument &operator<<(QDBusArgument &argument, const DBusInfoRet &obj) +{ + argument.beginStructure(); + argument << obj.ServicePath << obj.InterfacePath; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, DBusInfoRet &obj) +{ + argument.beginStructure(); + argument >> obj.ServicePath >> obj.InterfacePath; + argument.endStructure(); + return argument; +} + +QDebug operator<<(QDebug dbg, const DBusInfoRet &obj) +{ + dbg.nospace() << "{ "; + dbg.nospace() << "ServicePath :" << obj.ServicePath << ", "; + dbg.nospace() << "InterfacePath :" << obj.InterfacePath.path(); + dbg.nospace() << " }"; + return dbg; +} + +void DBusInfoRet::registerMetaType() +{ + qRegisterMetaType(QT_STRINGIFY(DBusInfoRet)); + qDBusRegisterMetaType(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbustype/dbusinforet.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbustype/dbusinforet.h new file mode 100644 index 0000000..0e74858 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dbustype/dbusinforet.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DBUSINFORET_H +#define DBUSINFORET_H + +#include +#include + + +class DBusInfoRet +{ +public: + + QString ServicePath; + QDBusObjectPath InterfacePath; + + DBusInfoRet(); + ~DBusInfoRet(); + + friend QDBusArgument &operator<<(QDBusArgument &argument, const DBusInfoRet &obj); + + friend const QDBusArgument &operator>>(const QDBusArgument &argument, DBusInfoRet &obj); + + friend QDebug operator<<(QDebug dbg, const DBusInfoRet &obj); + + static void registerMetaType(); +}; + +Q_DECLARE_METATYPE(DBusInfoRet) + +#endif // DBUSINFORET_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dde-filemanager-daemon.service b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dde-filemanager-daemon.service new file mode 100644 index 0000000..83e87c5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/dde-filemanager-daemon.service @@ -0,0 +1,10 @@ +[Unit] +Description=DDE File Manager Daemon + +[Service] +Type=dbus +BusName=com.deepin.filemanager.daemon +ExecStart=/usr/bin/dde-file-manager-daemon + +[Install] +WantedBy=multi-user.target diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/deletejob.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/deletejob.xml new file mode 100644 index 0000000..e9f9a43 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/deletejob.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/fileoperation.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/fileoperation.xml new file mode 100644 index 0000000..7cd90a6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/fileoperation.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/help.sh b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/help.sh new file mode 100755 index 0000000..72d5899 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/help.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +echo "=====fileoperation=====" +qdbusxml2cpp -i controllers/fileoperation.h -i dbusservice/dbustype/dbusinforet.h -c FileOperationAdaptor -l FileOperation -a dbusadaptor/fileoperation_adaptor fileoperation.xml +qdbusxml2cpp -i dbusservice/dbustype/dbusinforet.h -c FileOperationInterface -p dbusinterface/fileoperation_interface fileoperation.xml + + +echo "=====createfolderjob=====" +qdbusxml2cpp -i fileoperationjob/createfolderjob.h -c CreateFolderJobAdaptor -l CreateFolderJob -a dbusadaptor/createfolderjob_adaptor createfolderjob.xml +qdbusxml2cpp -c CreateFolderJobInterface -p dbusinterface/createfolderjob_interface createfolderjob.xml + + +echo "=====createtemplatefilejob=====" +qdbusxml2cpp -i fileoperationjob/createtemplatefilejob.h -c CreateTemplateFileAdaptor -l CreateTemplateFileJob -a dbusadaptor/createtemplatefilejob_adaptor createtemplatefilejob.xml +qdbusxml2cpp -c CreateTemplateFileInterface -p dbusinterface/createtemplatefilejob_interface createtemplatefilejob.xml + + +echo "=====copyjob=====" +qdbusxml2cpp -i fileoperationjob/copyjob.h -c CopyJobAdaptor -l CopyJob -a dbusadaptor/copyjob_adaptor copyjob.xml +qdbusxml2cpp -c CopyJobInterface -p dbusinterface/copyjob_interface copyjob.xml + + +echo "=====movejob=====" +qdbusxml2cpp -i fileoperationjob/movejob.h -c MoveJobAdaptor -l MoveJob -a dbusadaptor/movejob_adaptor movejob.xml +qdbusxml2cpp -c MoveJobInterface -p dbusinterface/movejob_interface movejob.xml + + +echo "=====renamejob=====" +qdbusxml2cpp -i fileoperationjob/renamejob.h -c RenameJobAdaptor -l RenameJob -a dbusadaptor/renamejob_adaptor renamejob.xml +qdbusxml2cpp -c RenameJobInterface -p dbusinterface/renamejob_interface renamejob.xml + +echo "=====deletejob=====" +qdbusxml2cpp -i fileoperationjob/deletejob.h -c DeleteJobAdaptor -l DeleteJob -a dbusadaptor/deletejob_adaptor deletejob.xml +qdbusxml2cpp -c DeleteJobInterface -p dbusinterface/deletejob_interface deletejob.xml + + +echo "=====usershare=====" +qdbusxml2cpp -i usershare/usersharemanager.h -c UserShareAdaptor -l UserShareManager -a dbusadaptor/usershare_adaptor usershare.xml +qdbusxml2cpp -c UserShareInterface -p dbusinterface/usershare_interface usershare.xml + +echo "=====accesscontrol=====" +#qdbuscpp2xml -M -S ../accesscontrol/accesscontrolmanager.h -o acesscontrol.xml +qdbusxml2cpp -i accesscontrol/accesscontrolmanager.h -c AccessControlAdaptor -l AccessControlManager -a dbusadaptor/accesscontrol_adaptor acesscontrol.xml +qdbusxml2cpp -c AccessControlInterface -p dbusinterface/accesscontrol_interface acesscontrol.xml + +echo "=====usbformatter=====" +qdbusxml2cpp -i usbformatter/usbformatter.h -c UsbFormatterAdaptor -l UsbFormatter -a dbusadaptor/usbformatter_adaptor usbformatter.xml +qdbusxml2cpp -c UsbFormatterInterface -p dbusinterface/usbformatter_interface usbformatter.xml + +echo "=====commandmanager=====" +qdbusxml2cpp -i commandmanager/commandmanager.h -c CommandManagerAdaptor -l CommandManager -a dbusadaptor/commandmanager_adaptor commandmanager.xml +qdbusxml2cpp -c CommandManagerInterface -p dbusinterface/commandmanager_interface commandmanager.xml + +echo "=====deviceinfomanager=====" +qdbusxml2cpp -i deviceinfo/deviceinfomanager.h -c DeviceInfoManagerAdaptor -l DeviceInfoManager -a dbusadaptor/deviceinfomanager_adaptor deviceinfo.xml +qdbusxml2cpp -i ../partman/partition.h -c DeviceInfoManagerInterface -p dbusinterface/deviceinfomanager_interface deviceinfo.xml + +echo "====tagmanagerdaemon====" +qdbusxml2cpp -i tag/tagmanagerdaemon.h -c TagManagerDaemonAdaptor -a dbusadaptor/tagmanagerdaemon_adaptor tagmanagerdaemon.xml + +echo notice that: the xxx_interface.h/cpp files were put into 'dde-file-manager-lib' not 'dde-file-manager-daemon'. +qdbusxml2cpp -c TagManagerDaemonInterface -p ../../dde-file-manager-lib/controllers/interface/tagmanagerdaemon_interface tagmanagerdaemon.xml + +echo "====quicksearchdaemon====" +qdbusxml2cpp -i quicksearch/quicksearchdaemon.h -c QuickSearchDaemonAdaptor -a dbusadaptor/quicksearchdaemon_adaptor quicksearchdaemon.xml + +echo notice that: the xxx_interface.h/cpp files were put into 'dde-file-manager-lib' not 'dde-file-manager-daemon'. +qdbusxml2cpp -c QuickSearchDaemonInterface -p ../../dde-file-manger-lib/interface/quicksearchdaemon_interface quicksearchdaemon.xml diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/movejob.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/movejob.xml new file mode 100644 index 0000000..7a521ef --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/movejob.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/renamejob.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/renamejob.xml new file mode 100644 index 0000000..7a521ef --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/renamejob.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/revocation.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/revocation.xml new file mode 100644 index 0000000..c477433 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/revocation.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/revocationmgr.sh b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/revocationmgr.sh new file mode 100755 index 0000000..de54b80 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/revocationmgr.sh @@ -0,0 +1,8 @@ +#!/bin/bash + + +echo "=====revocationmanager=====" +#qdbuscpp2xml -M -S ../revocation/revocationmanager.h -o revocation.xml +qdbusxml2cpp -i ../revocation/revocationmanager.h -c RevocationMgrAdaptor -l RevocationManager -a ../dbusservice/dbusadaptor/revocationmgr_adaptor revocation.xml +qdbusxml2cpp -c RevocationMgrInterface -p ../dbusservice/dbusinterface/revocationmgr_interface revocation.xml + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/tagmanagerdaemon.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/tagmanagerdaemon.xml new file mode 100644 index 0000000..8edede4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/tagmanagerdaemon.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/usershare.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/usershare.xml new file mode 100644 index 0000000..7f4d60c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/usershare.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/vault.sh b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/vault.sh new file mode 100755 index 0000000..b20386a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/vault.sh @@ -0,0 +1,13 @@ +#!/bin/bash + + +echo "=====vault=====" +#qdbuscpp2xml -M -S ../vault/vaultmanager.h -o vault.xml +qdbusxml2cpp -i ../vault/vaultmanager.h -c VaultAdaptor -l VaultManager -a ../dbusservice/dbusadaptor/vault_adaptor vault.xml +qdbusxml2cpp -c VaultInterface -p ../dbusservice/dbusinterface/vault_interface vault.xml + + +#qdbuscpp2xml -M -S ../vault/vaultbruteforceprevention.h -o vaultbruteforceprevention.xml +qdbusxml2cpp -i ../vault/vaultbruteforceprevention.h -c VaultBruteForcePreventionAdaptor -l VaultBruteForcePrevention -a ../dbusservice/dbusadaptor/vaultbruteforceprevention_adaptor vaultbruteforceprevention.xml +qdbusxml2cpp -c VaultBruteForcePreventionInterface -p ../dbusservice/dbusinterface/vaultbruteforceprevention_interface vaultbruteforceprevention.xml + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/vault.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/vault.xml new file mode 100644 index 0000000..4a86245 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/vault.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/vaultbruteforceprevention.xml b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/vaultbruteforceprevention.xml new file mode 100644 index 0000000..4c07f91 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dbusservice/vaultbruteforceprevention.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dde-file-manager-daemon.pro b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dde-file-manager-daemon.pro new file mode 100644 index 0000000..7359228 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/dde-file-manager-daemon.pro @@ -0,0 +1,72 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2016-08-02T13:45:46 +# +#------------------------------------------------- + +QT += core dbus concurrent + +QT -= gui + +TARGET = dde-file-manager-daemon +CONFIG += console +CONFIG -= app_bundle + +PKGCONFIG += x11 polkit-agent-1 polkit-qt5-1 udisks2-qt5 +CONFIG(release, release|debug) { + PKGCONFIG += dtkwidget +} else { + PKGCONFIG += dtkwidget +} +CONFIG += c++11 link_pkgconfig + +LIBS += -L$$OUT_PWD/../dde-file-manager-lib -ldde-file-manager -lKF5Codecs + +CONFIG(debug, debug|release) { + DEPENDPATH += $$PWD/../dde-file-manager-lib + unix:QMAKE_RPATHDIR += $$OUT_PWD/../dde-file-manager-lib +} + +TEMPLATE = app + +#include(../utils/utils.pri) +#include(../fileoperations/fileoperations.pri) + +INCLUDEPATH += dbusservice +INCLUDEPATH += $$PWD/../dde-file-manager-lib $$PWD/.. \ + $$PWD/../utils \ + $$PWD/../dde-file-manager-lib/interfaces \ + $$PWD/../dde-file-manager-lib/shutil + +DEFINES += QT_MESSAGELOGCONTEXT + +#安全加固 +QMAKE_CXXFLAGS += -fstack-protector-all +QMAKE_LFLAGS += -z now -pie -fPIE +isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + QMAKE_LFLAGS += -z noexecstack -z relro +} + +include(src.pri) +SOURCES += \ + main.cpp + +target.path = /usr/bin + +poliktpolicy.path = $$PREFIX/share/polkit-1/actions +poliktpolicy.files = dbusservice/com.deepin.filemanager.daemon.policy + +systembusconf.path = /etc/dbus-1/system.d +systembusconf.files = dbusservice/com.deepin.filemanager.daemon.conf + +services.path = $$PREFIX/share/dbus-1/system-services +services.files = dbusservice/com.deepin.filemanager.daemon.service + +systemd_service.files = dbusservice/dde-filemanager-daemon.service +systemd_service.path = $$PREFIX/lib/systemd/system + +INSTALLS += target poliktpolicy systembusconf services systemd_service + +DISTFILES += \ + dbusservice/fileoperation.xml \ + dbusservice/renamejob.xml diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/basejob.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/basejob.cpp new file mode 100644 index 0000000..b9a449c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/basejob.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "basejob.h" +#include "app/policykithelper.h" +#include +#include +#include + +BaseJob::BaseJob(QObject *parent) : QObject(parent) +{ + +} + +BaseJob::~BaseJob() +{ + QDBusConnection::systemBus().unregisterObject(m_objectPath); +} + +qint64 BaseJob::getClientPid() +{ + qint64 pid = 0; + QDBusConnection c = QDBusConnection::connectToBus(QDBusConnection::SystemBus, "org.freedesktop.DBus"); + if(c.isConnected()) + { + pid = c.interface()->servicePid(message().service()).value(); + } + return pid; +} + +bool BaseJob::checkAuthorization(const QString &actionId, qint64 applicationPid) +{ + bool isAuthenticationSucceeded(false); + qint64 pid = getClientPid(); + if (pid){ + isAuthenticationSucceeded = PolicyKitHelper::instance()->checkAuthorization(actionId, applicationPid); + } + return isAuthenticationSucceeded; +} + +QString BaseJob::objectPath() const +{ + return m_objectPath; +} + +void BaseJob::setObjectPath(const QString &objectPath) +{ + m_objectPath = objectPath; +} + +bool BaseJob::registerObject() +{ + bool result = QDBusConnection::systemBus().registerObject(objectPath(), this); + if (!result){ + deleteLater(); + } + return result; +} + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/basejob.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/basejob.h new file mode 100644 index 0000000..6e47248 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/basejob.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef BASEJOB_H +#define BASEJOB_H + +#include +#include + +class BaseJob : public QObject, public QDBusContext +{ + Q_OBJECT +public: + explicit BaseJob(QObject *parent = nullptr); + ~BaseJob(); + + + qint64 getClientPid(); + bool checkAuthorization(const QString& actionId, qint64 applicationPid); + + QString objectPath() const; + void setObjectPath(const QString &objectPath); + + bool registerObject(); + +signals: + +public slots: + +private: + QString m_objectPath; +}; + +#endif // BASEJOB_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/copyjob.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/copyjob.cpp new file mode 100644 index 0000000..f887114 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/copyjob.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "copyjob.h" +#include "dbusadaptor/copyjob_adaptor.h" + +QString CopyJob::BaseObjectPath = "/com/deepin/filemanager/daemon/CreateCopyJob"; +QString CopyJob::PolicyKitActionId = "com.deepin.filemanager.daemon.NewCopyJob"; +int CopyJob::JobId = 0; + +CopyJob::CopyJob(const QStringList &filelist, const QString &targetDir, QObject *parent) : + BaseJob(parent), + m_filelist(filelist), + m_targetDir(targetDir) +{ + JobId += 1; + m_jobId = JobId; + setObjectPath(QString("%1%2").arg(BaseObjectPath, QString::number(m_jobId))); + m_adaptor = new CopyJobAdaptor(this); +} + +CopyJob::~CopyJob() +{ + +} + +void CopyJob::Execute() +{ + qDebug() << "CreateFolderJob execute"; + qDebug() << PolicyKitActionId; + bool isAuthenticationSucceeded = checkAuthorization(PolicyKitActionId, getClientPid()); + if (isAuthenticationSucceeded){ + qDebug() << "CreateFolderJob executing"; + } + deleteLater(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/copyjob.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/copyjob.h new file mode 100644 index 0000000..056ce12 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/copyjob.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef COPYJOB_H +#define COPYJOB_H + +#include +#include "basejob.h" + +class CopyJobAdaptor; + +class CopyJob : public BaseJob +{ + Q_OBJECT +public: + explicit CopyJob(const QStringList &filelist, const QString &targetDir, QObject *parent = nullptr); + ~CopyJob(); + + static QString BaseObjectPath; + static QString PolicyKitActionId; + static int JobId; + +signals: + void Done(const QString& message); + +public slots: + void Execute(); + +private: + QStringList m_filelist; + QString m_targetDir; + int m_jobId = 0; + + CopyJobAdaptor* m_adaptor; +}; + +#endif // COPYJOB_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/createfolderjob.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/createfolderjob.cpp new file mode 100644 index 0000000..c3315b0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/createfolderjob.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "createfolderjob.h" +#include "dbusadaptor/createfolderjob_adaptor.h" + +QString CreateFolderJob::BaseObjectPath = "/com/deepin/filemanager/daemon/CreateFolderJob"; +QString CreateFolderJob::PolicyKitActionId = "com.deepin.filemanager.daemon.NewCreateFolderJob"; +int CreateFolderJob::JobId = 0; + +CreateFolderJob::CreateFolderJob(const QString &fabspath, QObject *parent) : + BaseJob(parent), + m_fabspath(fabspath) +{ + JobId += 1; + m_jobId = JobId; + setObjectPath(QString("%1%2").arg(BaseObjectPath, QString::number(m_jobId))); + m_adaptor = new CreateFolderJobAdaptor(this); +} + +CreateFolderJob::~CreateFolderJob() +{ + +} + +void CreateFolderJob::Execute() +{ + qDebug() << "CreateFolderJob execute"; + qDebug() << PolicyKitActionId; + bool isAuthenticationSucceeded = checkAuthorization(PolicyKitActionId, getClientPid()); + if (isAuthenticationSucceeded){ + qDebug() << "CreateFolderJob executing"; + } + deleteLater(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/createfolderjob.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/createfolderjob.h new file mode 100644 index 0000000..0afafa7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/createfolderjob.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef CREATEFOLDERJOB_H +#define CREATEFOLDERJOB_H + +#include +#include "basejob.h" + +class CreateFolderJobAdaptor; + +class CreateFolderJob : public BaseJob +{ + Q_OBJECT +public: + explicit CreateFolderJob(const QString& fabspath, QObject *parent = nullptr); + ~CreateFolderJob(); + + static QString BaseObjectPath; + static QString PolicyKitActionId; + static int JobId; + +signals: + void Done(const QString& message); + +public slots: + void Execute(); + +private: + QString m_fabspath; + int m_jobId = 0; + + CreateFolderJobAdaptor* m_adaptor; +}; + +#endif // CREATEFOLDERJOB_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/createtemplatefilejob.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/createtemplatefilejob.cpp new file mode 100644 index 0000000..af0824c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/createtemplatefilejob.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "createtemplatefilejob.h" +#include "dbusadaptor/createtemplatefilejob_adaptor.h" + +QString CreateTemplateFileJob::BaseObjectPath = "/com/deepin/filemanager/daemon/CreateTemplateFileJob"; +QString CreateTemplateFileJob::PolicyKitActionId = "com.deepin.filemanager.daemon.NewCreateTempleFileJob"; +int CreateTemplateFileJob::JobId = 0; + +CreateTemplateFileJob::CreateTemplateFileJob(const QString &templateFile, const QString &targetDir, QObject *parent) : + BaseJob(parent), + m_templateFile(templateFile), + m_targetDir(targetDir) +{ + JobId += 1; + m_jobId = JobId; + setObjectPath(QString("%1%2").arg(BaseObjectPath, QString::number(m_jobId))); + m_adaptor = new CreateTemplateFileAdaptor(this); +} + +CreateTemplateFileJob::~CreateTemplateFileJob() +{ + +} + +void CreateTemplateFileJob::Execute() +{ + qDebug() << "CreateTemplateFileJob execute"; + qDebug() << PolicyKitActionId; + bool isAuthenticationSucceeded = checkAuthorization(PolicyKitActionId, getClientPid()); + if (isAuthenticationSucceeded){ + qDebug() << "CreateTemplateFileJob executing"; + } + deleteLater(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/createtemplatefilejob.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/createtemplatefilejob.h new file mode 100644 index 0000000..2973a8d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/createtemplatefilejob.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef CREATETEMPLATEFILEJOB_H +#define CREATETEMPLATEFILEJOB_H + +#include +#include "basejob.h" + +class CreateTemplateFileAdaptor; + +class CreateTemplateFileJob : public BaseJob +{ + Q_OBJECT +public: + explicit CreateTemplateFileJob(const QString &templateFile, const QString &targetDir, QObject *parent = nullptr); + ~CreateTemplateFileJob(); + + static QString BaseObjectPath; + static QString PolicyKitActionId; + static int JobId; + +signals: + void Done(const QString& message); + +public slots: + void Execute(); + +private: + QString m_templateFile; + QString m_targetDir; + int m_jobId = 0; + + CreateTemplateFileAdaptor* m_adaptor; +}; + +#endif // CREATETEMPLATEFILEJOB_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/deletejob.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/deletejob.cpp new file mode 100644 index 0000000..358fca5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/deletejob.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "deletejob.h" +#include "dbusadaptor/deletejob_adaptor.h" + +QString DeleteJob::BaseObjectPath = "/com/deepin/filemanager/daemon/DeleteJob"; +QString DeleteJob::PolicyKitActionId = "com.deepin.filemanager.daemon.NewDeleteJob"; +int DeleteJob::JobId = 0; + + +DeleteJob::DeleteJob(const QStringList &filelist, QObject *parent) : + BaseJob(parent), + m_filelist(filelist) +{ + JobId += 1; + m_jobId = JobId; + setObjectPath(QString("%1%2").arg(BaseObjectPath, QString::number(m_jobId))); + m_adaptor = new DeleteJobAdaptor(this); +} + +DeleteJob::~DeleteJob() +{ + +} + +void DeleteJob::Execute() +{ + qDebug() << "DeleteJob execute"; + qDebug() << PolicyKitActionId; + bool isAuthenticationSucceeded = checkAuthorization(PolicyKitActionId, getClientPid()); + if (isAuthenticationSucceeded){ + qDebug() << "DeleteJob executing"; + } + deleteLater(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/deletejob.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/deletejob.h new file mode 100644 index 0000000..4a3574c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/deletejob.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DELETEJOB_H +#define DELETEJOB_H + +#include +#include "basejob.h" + +class DeleteJobAdaptor; + +class DeleteJob : public BaseJob +{ + Q_OBJECT +public: + explicit DeleteJob(const QStringList& filelist, QObject *parent = nullptr); + ~DeleteJob(); + + static QString BaseObjectPath; + static QString PolicyKitActionId; + static int JobId; + +signals: + void Done(const QString& message); + +public slots: + void Execute(); + +private: + QStringList m_filelist; + int m_jobId = 0; + + DeleteJobAdaptor* m_adaptor; + +}; + +#endif // DELETEJOB_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/movejob.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/movejob.cpp new file mode 100644 index 0000000..824fdea --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/movejob.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "movejob.h" +#include "dbusadaptor/movejob_adaptor.h" + +QString MoveJob::BaseObjectPath = "/com/deepin/filemanager/daemon/MoveJob"; +QString MoveJob::PolicyKitActionId = "com.deepin.filemanager.daemon.NewMoveJob"; +int MoveJob::JobId = 0; + +MoveJob::MoveJob(const QStringList &filelist, const QString &targetDir, QObject *parent) : + BaseJob(parent), + m_filelist(filelist), + m_targetDir(targetDir) +{ + JobId += 1; + m_jobId = JobId; + setObjectPath(QString("%1%2").arg(BaseObjectPath, QString::number(m_jobId))); + m_adaptor = new MoveJobAdaptor(this); +} + +MoveJob::~MoveJob() +{ + +} + +void MoveJob::Execute() +{ + qDebug() << "MoveJob execute"; + qDebug() << PolicyKitActionId; + bool isAuthenticationSucceeded = checkAuthorization(PolicyKitActionId, getClientPid()); + if (isAuthenticationSucceeded){ + qDebug() << "MoveJob executing"; + } + deleteLater(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/movejob.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/movejob.h new file mode 100644 index 0000000..a05dac3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/movejob.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef MOVEJOB_H +#define MOVEJOB_H + +#include +#include "basejob.h" + +class MoveJobAdaptor; + +class MoveJob : public BaseJob +{ + Q_OBJECT +public: + explicit MoveJob(const QStringList &filelist, const QString &targetDir, QObject *parent = nullptr); + ~MoveJob(); + + static QString BaseObjectPath; + static QString PolicyKitActionId; + static int JobId; + +signals: + void Done(const QString& message); + +public slots: + void Execute(); + +private: + QStringList m_filelist; + QString m_targetDir; + int m_jobId = 0; + + MoveJobAdaptor* m_adaptor; +}; + +#endif // MOVEJOB_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/renamejob.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/renamejob.cpp new file mode 100644 index 0000000..26cc659 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/renamejob.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "renamejob.h" +#include "dbusservice/dbusadaptor/renamejob_adaptor.h" +#include +#include + + +QString RenameJob::BaseObjectPath = "/com/deepin/filemanager/daemon/RenameJob"; +QString RenameJob::PolicyKitActionId = "com.deepin.filemanager.daemon.NewRenameJob"; +int RenameJob::JobId = 0; + +RenameJob::RenameJob(const QString &oldFile, + const QString &newFile, + QObject *parent) : + + BaseJob(parent), + m_oldFile(oldFile), + m_newFile(newFile) +{ + JobId += 1; + m_jobId = JobId; + setObjectPath(QString("%1%2").arg(BaseObjectPath, QString::number(m_jobId))); + m_adaptor = new RenameJobAdaptor(this); +} + +RenameJob::~RenameJob() +{ + +} + +void RenameJob::Execute() +{ + qDebug() << "RenameJob execute"; + qDebug() << PolicyKitActionId; + bool isAuthenticationSucceeded = checkAuthorization(PolicyKitActionId, getClientPid()); + if (isAuthenticationSucceeded){ + qDebug() << "RenameJob executing"; + } + deleteLater(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/renamejob.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/renamejob.h new file mode 100644 index 0000000..6d04703 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/fileoperationjob/renamejob.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef RENAMEJOB_H +#define RENAMEJOB_H + +#include +#include "basejob.h" + + +class RenameJobAdaptor; + +class RenameJob : public BaseJob +{ + Q_OBJECT +public: + explicit RenameJob(const QString&oldFile, + const QString &newFile, + QObject *parent = nullptr); + ~RenameJob(); + + static QString BaseObjectPath; + static QString PolicyKitActionId; + static int JobId; + +signals: + void Done(const QString& message); + +public slots: + void Execute(); + +private: + QString m_oldFile; + QString m_newFile; + int m_jobId = 0; + RenameJobAdaptor* m_adaptor; +}; + +#endif // RENAMEJOB_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/main.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/main.cpp new file mode 100644 index 0000000..a5d4774 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/main.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include "app/global.h" +#include "app/filemanagerdaemon.h" +#include "client/filemanagerclient.h" +#include "log/dfmLogManager.h" + +#include "ddiskmanager.h" + +#include +#include +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + ///###: why? + ///###: when dbus invoke a daemon the variants in the environment of daemon(s) are empty. + ///###: So we need to set them. + if (!qEnvironmentVariableIsSet("LANG")) { + qputenv("LANG", "en_US.UTF8"); + } + + if (!qEnvironmentVariableIsSet("LANGUAGE")) { + qputenv("LANGUAGE", "en_US"); + } + + if (!qEnvironmentVariableIsSet("HOME")) { + qputenv("HOME", getpwuid(getuid())->pw_dir); + } + + QCoreApplication a(argc, argv); + + a.setOrganizationName("deepin"); + + QString logPath = "/var/log/" + QCoreApplication::organizationName() + QLatin1Char('/') + + QCoreApplication::applicationName() + QLatin1Char('/'); + QDir logDir(logPath); + if (!logDir.exists()) { + QDir().mkpath(logPath); + } + + QDBusConnection connection = QDBusConnection::systemBus(); + DFM_NAMESPACE::DFMLogManager::setlogFilePath(logPath + QCoreApplication::applicationName() + ".log"); + DFM_NAMESPACE::DFMLogManager::registerConsoleAppender(); + DFM_NAMESPACE::DFMLogManager::registerFileAppender(); + + if (!connection.interface()->isServiceRegistered(DaemonServicePath)){ + qDebug() << connection.registerService(DaemonServicePath) << "register" << DaemonServicePath << "success"; + FileManagerDaemon* daemon = new FileManagerDaemon(); + qDebug() << daemon; + return a.exec(); + }else{ + qDebug() << "dde-file-manager-daemon is running"; + FileManagerClient* client = new FileManagerClient(); + qDebug() << client << QCoreApplication::applicationPid(); + return a.exec(); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/revocation/revocationmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/revocation/revocationmanager.cpp new file mode 100644 index 0000000..8eec947 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/revocation/revocationmanager.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 Deepin Technology Co., Ltd. + * + * Author: Lu Zhen + * + * Maintainer: Lu Zhen + * + * 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 + * 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 . + */ + +#include "revocationmanager.h" +#include "dfmglobal.h" +#include +#include "dbusadaptor/revocationmgr_adaptor.h" + +QString RevocationManager::ObjectPath = "/com/deepin/filemanager/daemon/RevocationManager"; + +RevocationManager::RevocationManager(QObject *parent) + : QObject(parent) + , QDBusContext() +{ + QDBusConnection::systemBus().registerObject(ObjectPath, this); + m_adaptor = new RevocationMgrAdaptor(this); +} + +RevocationManager::~RevocationManager() +{ +} + +void RevocationManager::pushEvent(int event, const QString & user) +{ + if (REVOCATION_TIMES == m_eventStack.size()) { + m_eventStack.pop_front(); + } + RevocationEvent evtTypeUser; + evtTypeUser.eventType = static_cast(event); + evtTypeUser.user = user; + m_eventStack.push(evtTypeUser); +} + +int RevocationManager::popEvent() +{ + if (m_eventStack.isEmpty()) + return DFM_NO_EVENT; + + RevocationEvent event = m_eventStack.pop(); + switch (event.eventType) { + case DFM_FILE_MGR: + emit fmgrRevocationAction(event.user); + break; + case DFM_DESKTOP: + emit deskRevocationAction(event.user); + break; + case DFM_NO_EVENT: + break; + } + return event.eventType; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/revocation/revocationmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/revocation/revocationmanager.h new file mode 100644 index 0000000..b9bb5d6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/revocation/revocationmanager.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2020 Deepin Technology Co., Ltd. + * + * Author: Lu Zhen + * + * Maintainer: Lu Zhen + * + * 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 + * 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 . + */ + + +#ifndef REVOCATIONMANAGER_H +#define REVOCATIONMANAGER_H + +#include +#include +#include + +class RevocationMgrAdaptor; +/** + * @brief The RevocationManager class + */ +class RevocationManager : public QObject, public QDBusContext +{ + Q_OBJECT +public: + enum RevocationEventType + { + DFM_NO_EVENT = -1, + DFM_FILE_MGR = 0, + DFM_DESKTOP = 1 + }; + + struct RevocationEvent{ + RevocationEventType eventType; + QString user; + }; + + + explicit RevocationManager(QObject *parent = nullptr); + ~RevocationManager(); + + static QString ObjectPath; + +public slots: + /** + * @brief pushEvent 入栈事件 + * @param event 0:filemgr 1:desktop + * @param1 user 事件执行用户 + */ + void pushEvent(int event, const QString& user); + + /** + * @brief popEvent 弹出最新事件 + * @returns 事件 0:filemgr 1:desktop + */ + int popEvent(); + +signals: + /** + * @brief fmgrRevocationAction 发送给文管的撤销动作(处理文管) + * @param user 撤销动作的执行者 + */ + void fmgrRevocationAction(const QString& user); + + /** + * @brief deskRevocationAction 发送给桌面的撤销动作(处理桌面) + * @param user 撤销动作的执行者 + */ + void deskRevocationAction(const QString& user); + +private: + RevocationMgrAdaptor* m_adaptor = nullptr; + QStack m_eventStack; +}; + +#endif // REVOCATIONMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/src.pri b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/src.pri new file mode 100644 index 0000000..8290121 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/src.pri @@ -0,0 +1,104 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-06-24T09:14:17 +# +#------------------------------------------------- + +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/app/filemanagerdaemon.h \ + $$PWD/controllers/appcontroller.h \ + $$PWD/app/global.h \ + $$PWD/controllers/fileoperation.h \ + $$PWD/fileoperationjob/renamejob.h \ + $$PWD/dbusservice/dbusadaptor/fileoperation_adaptor.h \ + $$PWD/dbusservice/dbusadaptor/renamejob_adaptor.h \ + $$PWD/dbusservice/dbusinterface/fileoperation_interface.h \ + $$PWD/dbusservice/dbusinterface/renamejob_interface.h \ + $$PWD/client/filemanagerclient.h \ + $$PWD/dbusservice/dbustype/dbusinforet.h \ + $$PWD/app/policykithelper.h \ + $$PWD/fileoperationjob/basejob.h \ + $$PWD/fileoperationjob/createfolderjob.h \ + $$PWD/fileoperationjob/createtemplatefilejob.h \ + $$PWD/fileoperationjob/movejob.h \ + $$PWD/fileoperationjob/copyjob.h \ + $$PWD/fileoperationjob/deletejob.h \ + $$PWD/dbusservice/dbusadaptor/copyjob_adaptor.h \ + $$PWD/dbusservice/dbusadaptor/createfolderjob_adaptor.h \ + $$PWD/dbusservice/dbusadaptor/createtemplatefilejob_adaptor.h \ + $$PWD/dbusservice/dbusadaptor/deletejob_adaptor.h \ + $$PWD/dbusservice/dbusadaptor/movejob_adaptor.h \ + $$PWD/dbusservice/dbusinterface/copyjob_interface.h \ + $$PWD/dbusservice/dbusinterface/createfolderjob_interface.h \ + $$PWD/dbusservice/dbusinterface/createtemplatefilejob_interface.h \ + $$PWD/dbusservice/dbusinterface/deletejob_interface.h \ + $$PWD/dbusservice/dbusinterface/movejob_interface.h \ + $$PWD/usershare/usersharemanager.h \ + $$PWD/dbusservice/dbusadaptor/usershare_adaptor.h \ + $$PWD/dbusservice/dbusinterface/usershare_interface.h \ + $$PWD/dbusservice/dbusinterface/usbformatter_interface.h \ + $$PWD/tag/tagmanagerdaemon.h \ + $$PWD/dbusservice/dbusadaptor/tagmanagerdaemon_adaptor.h \ + $$PWD/accesscontrol/accesscontrolmanager.h \ + $$PWD/dbusservice/dbusadaptor/accesscontrol_adaptor.h \ + $$PWD/dbusservice/dbusinterface/accesscontrol_interface.h \ + $$PWD/vault/vaultmanager.h \ + $$PWD/dbusservice/dbusadaptor/vault_adaptor.h \ + $$PWD/dbusservice/dbusinterface/vault_interface.h \ + $$PWD/vault/vaultclock.h \ + $$PWD/revocation/revocationmanager.h \ + $$PWD/dbusservice/dbusadaptor/revocationmgr_adaptor.h \ + $$PWD/dbusservice/dbusinterface/revocationmgr_interface.h \ + $$PWD/vault/vaultbruteforceprevention.h \ + $$PWD/dbusservice/dbusadaptor/vaultbruteforceprevention_adaptor.h \ + $$PWD/dbusservice/dbusinterface/vaultbruteforceprevention_interface.h + +SOURCES += \ + $$PWD/app/filemanagerdaemon.cpp \ + $$PWD/controllers/appcontroller.cpp \ + $$PWD/controllers/fileoperation.cpp \ + $$PWD/fileoperationjob/renamejob.cpp \ + $$PWD/dbusservice/dbusadaptor/fileoperation_adaptor.cpp \ + $$PWD/dbusservice/dbusadaptor/renamejob_adaptor.cpp \ + $$PWD/dbusservice/dbusinterface/fileoperation_interface.cpp \ + $$PWD/dbusservice/dbusinterface/renamejob_interface.cpp \ + $$PWD/client/filemanagerclient.cpp \ + $$PWD/dbusservice/dbustype/dbusinforet.cpp \ + $$PWD/app/policykithelper.cpp \ + $$PWD/fileoperationjob/basejob.cpp \ + $$PWD/fileoperationjob/createfolderjob.cpp \ + $$PWD/fileoperationjob/createtemplatefilejob.cpp \ + $$PWD/fileoperationjob/movejob.cpp \ + $$PWD/fileoperationjob/copyjob.cpp \ + $$PWD/fileoperationjob/deletejob.cpp \ + $$PWD/dbusservice/dbusadaptor/copyjob_adaptor.cpp \ + $$PWD/dbusservice/dbusadaptor/createfolderjob_adaptor.cpp \ + $$PWD/dbusservice/dbusadaptor/createtemplatefilejob_adaptor.cpp \ + $$PWD/dbusservice/dbusadaptor/deletejob_adaptor.cpp \ + $$PWD/dbusservice/dbusadaptor/movejob_adaptor.cpp \ + $$PWD/dbusservice/dbusinterface/copyjob_interface.cpp \ + $$PWD/dbusservice/dbusinterface/createfolderjob_interface.cpp \ + $$PWD/dbusservice/dbusinterface/createtemplatefilejob_interface.cpp \ + $$PWD/dbusservice/dbusinterface/deletejob_interface.cpp \ + $$PWD/dbusservice/dbusinterface/movejob_interface.cpp \ + $$PWD/usershare/usersharemanager.cpp \ + $$PWD/dbusservice/dbusadaptor/usershare_adaptor.cpp \ + $$PWD/dbusservice/dbusinterface/usershare_interface.cpp \ + $$PWD/dbusservice/dbusinterface/usbformatter_interface.cpp \ + $$PWD/tag/tagmanagerdaemon.cpp \ + $$PWD/dbusservice/dbusadaptor/tagmanagerdaemon_adaptor.cpp \ + $$PWD/accesscontrol/accesscontrolmanager.cpp \ + $$PWD/dbusservice/dbusadaptor/accesscontrol_adaptor.cpp \ + $$PWD/dbusservice/dbusinterface/accesscontrol_interface.cpp \ + $$PWD/vault/vaultmanager.cpp \ + $$PWD/dbusservice/dbusadaptor/vault_adaptor.cpp \ + $$PWD/dbusservice/dbusinterface/vault_interface.cpp \ + $$PWD/vault/vaultclock.cpp \ + $$PWD/revocation/revocationmanager.cpp \ + $$PWD/dbusservice/dbusadaptor/revocationmgr_adaptor.cpp \ + $$PWD/dbusservice/dbusinterface/revocationmgr_interface.cpp \ + $$PWD/vault/vaultbruteforceprevention.cpp \ + $$PWD/dbusservice/dbusadaptor/vaultbruteforceprevention_adaptor.cpp \ + $$PWD/dbusservice/dbusinterface/vaultbruteforceprevention_interface.cpp diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/tag/tagmanagerdaemon.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/tag/tagmanagerdaemon.cpp new file mode 100644 index 0000000..30abc66 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/tag/tagmanagerdaemon.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "app/define.h" +#include "tag/tagutil.h" +#include "tagmanagerdaemon.h" +#include "shutil/dsqlitehandle.h" +#include "dbusadaptor/tagmanagerdaemon_adaptor.h" + +#include + + +static constexpr const char *ObjectPath{"/com/deepin/filemanager/daemon/TagManagerDaemon"}; + +std::atomic counter{ 0 }; + + +TagManagerDaemon::TagManagerDaemon(QObject *const parent) + : QObject{ parent }, + adaptor{ new TagManagerDaemonAdaptor{ this } }, +m_anything_monitor{ new DAnythingMonitorFilter{this} } +{ + + this->init_connection(); + + if (!QDBusConnection::systemBus().registerObject(ObjectPath, this)) { + qFatal("Failed to register object."); //###: log! + } +} + +QDBusVariant TagManagerDaemon::disposeClientData(const QMap &filesAndTags, const unsigned long long &type) +{ + QDBusVariant dbusVar{}; + + if (!filesAndTags.isEmpty()) { + QMap::const_iterator cbeg{ filesAndTags.cbegin() }; + QMap::const_iterator cend{ filesAndTags.cend() }; + QMap> filesAndTagsName{}; + + for (; cbeg != cend; ++cbeg) { + QString key{ Tag::escaping_en_skim(cbeg.key()) }; + QList values{}; + + auto lst = cbeg.value().toStringList(); + std::transform(lst.begin(), lst.end(), std::back_inserter(values), [](const QString & qstr) { + return Tag::escaping_en_skim(qstr); + }); + + filesAndTagsName[key] = values; + } + + QVariant var{ DSqliteHandle::instance()->disposeClientData(filesAndTagsName, type) }; + dbusVar.setVariant(var); + } + + return dbusVar; +} + +void TagManagerDaemon::onAddNewTags(const QVariant &new_tags)noexcept +{ + emit addNewTags(QDBusVariant{new_tags}); +} + +void TagManagerDaemon::onDeleteTags(const QVariant &be_deleted_tags)noexcept +{ + emit deleteTags(QDBusVariant{be_deleted_tags}); +} + +void TagManagerDaemon::onFileWereTagged(const QVariantMap &files_were_tagged)noexcept +{ + emit filesWereTagged(files_were_tagged); +} + +void TagManagerDaemon::onUntagFiles(const QVariantMap &tag_beg_removed_files)noexcept +{ + emit untagFiles(tag_beg_removed_files); +} + +void TagManagerDaemon::onChangeTagColor(const QVariantMap &old_and_new_color)noexcept +{ + emit changeTagColor(old_and_new_color); +} + +void TagManagerDaemon::onChangeTagName(const QVariantMap &old_and_new_name)noexcept +{ + emit changeTagName(old_and_new_name); +} + + +void TagManagerDaemon::init_connection()noexcept +{ + if (adaptor) { + QObject::connect(DSqliteHandle::instance(), &DSqliteHandle::addNewTags, this, &TagManagerDaemon::onAddNewTags); + QObject::connect(DSqliteHandle::instance(), &DSqliteHandle::deleteTags, this, &TagManagerDaemon::onDeleteTags); + QObject::connect(DSqliteHandle::instance(), &DSqliteHandle::changeTagColor, this, &TagManagerDaemon::onChangeTagColor); + QObject::connect(DSqliteHandle::instance(), &DSqliteHandle::changeTagName, this, &TagManagerDaemon::onChangeTagName); + QObject::connect(DSqliteHandle::instance(), &DSqliteHandle::filesWereTagged, this, &TagManagerDaemon::onFileWereTagged); + QObject::connect(DSqliteHandle::instance(), &DSqliteHandle::untagFiles, this, &TagManagerDaemon::onUntagFiles); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/tag/tagmanagerdaemon.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/tag/tagmanagerdaemon.h new file mode 100644 index 0000000..1937764 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/tag/tagmanagerdaemon.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef TAGMANAGERDAEMON_H +#define TAGMANAGERDAEMON_H + +#include + +#include +#include +#include + + +#include "deviceinfo/udisklistener.h" +#include "deviceinfo/udiskdeviceinfo.h" +#include "shutil/danythingmonitorfilter.h" + +class TagManagerDaemonAdaptor; +class TagManagerDaemon : public QObject +{ + Q_OBJECT +public: + explicit TagManagerDaemon(QObject *const parent); + virtual ~TagManagerDaemon() = default; + TagManagerDaemon(const TagManagerDaemon &other) = delete; + TagManagerDaemon &operator=(const TagManagerDaemon &other) = delete; + + Q_INVOKABLE QDBusVariant disposeClientData(const QMap &filesAndTags, const unsigned long long &type); + +signals: + void addNewTags(const QDBusVariant &new_tags); + void deleteTags(const QDBusVariant &be_deleted_tags); + void changeTagColor(const QVariantMap &old_and_new_color); + void changeTagName(const QVariantMap &old_and_new_name); + void filesWereTagged(const QVariantMap &files_were_tagged); + void untagFiles(const QVariantMap &tag_beg_removed_files); + + + +private slots: + void onAddNewTags(const QVariant &new_tags)noexcept; + void onDeleteTags(const QVariant &be_deleted_tags)noexcept; + void onFileWereTagged(const QVariantMap &files_were_tagged)noexcept; + void onUntagFiles(const QVariantMap &tag_beg_removed_files)noexcept; + void onChangeTagColor(const QVariantMap &old_and_new_color)noexcept; + void onChangeTagName(const QVariantMap &old_and_new_name)noexcept; + +private: + void init_connection()noexcept; + + TagManagerDaemonAdaptor *adaptor{ nullptr }; + DAnythingMonitorFilter *m_anything_monitor{ nullptr }; +}; +#endif // TAGMANAGERDAEMON_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/usershare/usersharemanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/usershare/usersharemanager.cpp new file mode 100644 index 0000000..27119bd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/usershare/usersharemanager.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "usersharemanager.h" +#include "dbusservice/dbusadaptor/usershare_adaptor.h" +#include +#include +#include +#include +#include "app/policykithelper.h" + +QString UserShareManager::ObjectPath = "/com/deepin/filemanager/daemon/UserShareManager"; +QString UserShareManager::PolicyKitActionId = "com.deepin.filemanager.daemon.UserShareManager"; + +UserShareManager::UserShareManager(QObject *parent) + : QObject(parent) + , QDBusContext() +{ + QDBusConnection::systemBus().registerObject(ObjectPath, this); + m_userShareAdaptor = new UserShareAdaptor(this); +} + +UserShareManager::~UserShareManager() +{ + +} + +bool UserShareManager::checkAuthentication() +{ + bool ret = false; + qint64 pid = 0; + QDBusConnection c = QDBusConnection::connectToBus(QDBusConnection::SystemBus, "org.freedesktop.DBus"); + if (c.isConnected()) { + pid = c.interface()->servicePid(message().service()).value(); + } + + if (pid) { + ret = PolicyKitHelper::instance()->checkAuthorization(PolicyKitActionId, pid); + } + + if (!ret) { + qDebug() << "Authentication failed !!"; + } + return ret; +} + +bool UserShareManager::addGroup(const QString &groupName) +{ + if (!checkAuthentication()) { + qDebug() << "addGroup failed" << groupName; + return false; + } + + QStringList args; + args << groupName; + bool ret = QProcess::startDetached("/usr/sbin/groupadd", args); + qDebug() << "groupadd" << groupName << ret; + return ret; +} + +bool UserShareManager::setUserSharePassword(const QString &username, const QString &passward) +{ + if (!checkAuthentication()) { + qDebug() << "setUserSharePassword failed" << username; + return false; + } + + qDebug() << username;// << passward; // log password? + QStringList args; + args << "-a" << username << "-s"; + QProcess p; + p.start("smbpasswd", args); + p.write(passward.toStdString().c_str()); + p.write("\n"); + p.write(passward.toStdString().c_str()); + p.closeWriteChannel(); + bool ret = p.waitForFinished(); + qDebug() << p.readAll() << p.readAllStandardError() << p.readAllStandardOutput(); + return ret; +} + +bool UserShareManager::closeSmbShareByShareName(const QString &sharename, const bool bshow) +{ + if (!bshow) { + return true; + } +// if (!checkAuthentication()) { +// qDebug() << "closeSmbShareByShareName failed" << sharename; +// return false; +// } + unsigned int suid = 0; + QDBusConnection c = QDBusConnection::connectToBus(QDBusConnection::SystemBus, "org.freedesktop.DBus"); + if (!c.isConnected()) { + qDebug() << "连接DBus失败"; + return false; + } + suid = c.interface()->serviceUid(message().service()).value(); //获取调用总线进程属主 + + QString filename = sharename.toLower(); //文件名小写 + QFileInfo info("/var/lib/samba/usershares/" + filename); + if (suid != info.ownerId() && suid != 0) { //对比文件属主与调用总线进程属主 + qDebug() << "非属主用户" << info.path(); + return false; + } + + QProcess p; + //取得所有连击的pid + QString cmd = QString("smbcontrol smbd close-share %1").arg(sharename); + qDebug() << "cmd==========" << cmd; + p.start(cmd); + bool ret = p.waitForFinished(); + + qDebug() << p.readAll() << p.readAllStandardError() << p.readAllStandardOutput(); + return ret; +} + +bool UserShareManager::createShareLinkFile() +{ + // 创建链接文件之前已经提权了 这里就不需要再次判断权限了 + /*if (!checkAuthentication()) { + qDebug() << "createShareLinkFile"; + return false; + }*/ + + QProcess sh; + sh.start("ln -sf /lib/systemd/system/smbd.service /etc/systemd/system/multi-user.target.wants/smbd.service"); + auto ret = sh.waitForFinished(); + return ret; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/usershare/usersharemanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/usershare/usersharemanager.h new file mode 100644 index 0000000..ebeb2d3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/usershare/usersharemanager.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef USERSHAREDAEMONMANAGER_H +#define USERSHAREDAEMONMANAGER_H + +#include +#include + +class UserShareAdaptor; + +class UserShareManager : public QObject, public QDBusContext +{ + Q_OBJECT +public: + explicit UserShareManager(QObject *parent = nullptr); + ~UserShareManager(); + +public: + static QString ObjectPath; + static QString PolicyKitActionId; + +protected: + bool checkAuthentication(); + +signals: + +public slots: + bool addGroup(const QString &groupName); + bool setUserSharePassword(const QString &username, const QString &passward); + bool closeSmbShareByShareName(const QString &sharename,const bool bshow); + bool createShareLinkFile(); + +private: + UserShareAdaptor* m_userShareAdaptor = nullptr; +}; + +#endif // USERSHAREDAEMONMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultbruteforceprevention.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultbruteforceprevention.cpp new file mode 100644 index 0000000..085b03e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultbruteforceprevention.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "vaultbruteforceprevention.h" +#include "dbusadaptor/vaultbruteforceprevention_adaptor.h" + +QString VaultBruteForcePrevention::ObjectPath = "/com/deepin/filemanager/daemon/VaultManager2"; + +VaultBruteForcePrevention::VaultBruteForcePrevention(QObject *parent) : QObject(parent) +{ + QDBusConnection::systemBus().registerObject(ObjectPath, this); + m_vaultAdaptor = new VaultBruteForcePreventionAdaptor(this); +} + +int VaultBruteForcePrevention::getLeftoverErrorInputTimes(int userID) +{ + if (!isValidInvoker()) + return -1; + if (!m_mapLeftoverInputTimes.contains(userID)) + m_mapLeftoverInputTimes[userID] = ERROR_INPUT_TIMES; + return m_mapLeftoverInputTimes[userID]; +} + +void VaultBruteForcePrevention::leftoverErrorInputTimesMinusOne(int userID) +{ + if (!isValidInvoker()) + return; + if (!m_mapLeftoverInputTimes.contains(userID)) + m_mapLeftoverInputTimes[userID] = ERROR_INPUT_TIMES; + --m_mapLeftoverInputTimes[userID]; +} + +void VaultBruteForcePrevention::restoreLeftoverErrorInputTimes(int userID) +{ + if (!isValidInvoker()) + return; + m_mapLeftoverInputTimes[userID] = ERROR_INPUT_TIMES; +} + +void VaultBruteForcePrevention::startTimerOfRestorePasswordInput(int userID) +{ + if (!isValidInvoker()) + return; + m_mapTimer.insert(startTimer(TIMER_OUT_TIME), userID); +} + +int VaultBruteForcePrevention::getNeedWaitMinutes(int userID) +{ + if (!isValidInvoker()) + return 100; + if (!m_mapNeedMinutes.contains(userID)) + m_mapNeedMinutes[userID] = TOTAL_WAIT_TIME; + return m_mapNeedMinutes[userID]; +} + +void VaultBruteForcePrevention::restoreNeedWaitMinutes(int userID) +{ + if (!isValidInvoker()) + return; + m_mapNeedMinutes[userID] = TOTAL_WAIT_TIME; +} + +void VaultBruteForcePrevention::timerEvent(QTimerEvent *event) +{ + int timerID = event->timerId(); + if (m_mapTimer.contains(timerID)) { + int userID = m_mapTimer[timerID]; + if (!m_mapNeedMinutes.contains(userID)) + m_mapNeedMinutes[userID] = TOTAL_WAIT_TIME; + --m_mapNeedMinutes[userID]; + if (m_mapNeedMinutes[userID] < 1) { + killTimer(timerID); + m_mapTimer.remove(timerID); + // 密码剩余输入次数还原,需要等待的分钟数还原 + restoreLeftoverErrorInputTimes(userID); + restoreNeedWaitMinutes(userID); + } + } +} + +bool VaultBruteForcePrevention::isValidInvoker() +{ +#if 0 + // 暂时屏蔽,后期优化 + // 1. 该白名单方案会造成调试运行保险箱,保险箱进程不再白名单内,导致无法开锁 + // 2. 该写法存在逻辑问题,导致了bug#103685 + static QStringList VaultwhiteProcess = {"/usr/bin/dde-file-manager", "/usr/bin/dde-desktop", "/usr/bin/dde-select-dialog-wayland", "/usr/bin/dde-select-dialog-x11"}; + uint pid = connection().interface()->servicePid(message().service()).value(); + QFileInfo f(QString("/proc/%1/exe").arg(pid)); + if (!f.exists()) + return false; + return VaultwhiteProcess.contains(f.canonicalFilePath()); +#endif + return true; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultbruteforceprevention.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultbruteforceprevention.h new file mode 100644 index 0000000..e1a5f3d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultbruteforceprevention.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef VAULTBRUTEFORCEPREVENTION_H +#define VAULTBRUTEFORCEPREVENTION_H + +#define ERROR_INPUT_TIMES 6 // 错误次数 +#define TIMER_OUT_TIME 60*1000 // 计时器超时时间/ms +#define TOTAL_WAIT_TIME 10 // 需要等待的分钟数 + +#include +#include +#include +#include + +class VaultBruteForcePreventionAdaptor; + +class VaultBruteForcePrevention : public QObject, public QDBusContext +{ + Q_OBJECT +public: + explicit VaultBruteForcePrevention(QObject *parent = nullptr); + + static QString ObjectPath; + +public slots: + /** + * @brief getLeftoverErrorInputTimes 获得保险箱剩余错误密码输入次数 + * @return + */ + int getLeftoverErrorInputTimes(int userID); + + /** + * @brief leftoverErrorInputTimesMinusOne 保险箱剩余错误密码输入次数减1 + */ + void leftoverErrorInputTimesMinusOne(int userID); + + /** + * @brief restoreLeftoverErrorInputTimes 保险箱剩余错误密码输入次数还原 + */ + void restoreLeftoverErrorInputTimes(int userID); + + /** + * @brief startTimerOfRestorePasswordInput 开启恢复密码输入定时器 + */ + void startTimerOfRestorePasswordInput(int userID); + + /** + * @brief getNeedWaitMinutes 获得保险箱再次输入密码需要等待的分钟数 + * @return + */ + int getNeedWaitMinutes(int userID); + + /** + * @brief restoreNeedWaitMinutes 保险箱再次输入密码的等待分钟数还原 + */ + void restoreNeedWaitMinutes(int userID); + +protected: + void timerEvent(QTimerEvent *event) override; + +private: + /** + * @brief isValidInvoker 判断调用者是否是白名单进程 + * @return + */ + bool isValidInvoker(); + +private: + // 记录保险箱剩余的错误密码输入次数 + QMap m_mapLeftoverInputTimes {}; + + // 剩余时间定时器,key:定时器ID value:用户ID + QMap m_mapTimer {}; + + // 记录恢复密码输入还需要的分钟数 + QMap m_mapNeedMinutes {}; + + VaultBruteForcePreventionAdaptor *m_vaultAdaptor {nullptr}; +}; + +#endif // VAULTBRUTEFORCEPREVENTION_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultclock.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultclock.cpp new file mode 100644 index 0000000..337acd0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultclock.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "vault/vaultclock.h" +#include "dbusservice/dbusadaptor/vault_adaptor.h" +#include +#include +#include +#include +#include + +VaultClock::VaultClock(QObject *parent) + : QObject(parent) + , m_selfTime(0) +{ + // Create self clock. + connect(&m_selfTimer, &QTimer::timeout, this, &VaultClock::tick); + m_selfTimer.setInterval(1000); + m_selfTimer.start(); +} + +VaultClock::~VaultClock() +{ + m_selfTimer.stop(); +} + +void VaultClock::setRefreshTime(quint64 time) +{ + m_lastestTime = time; +} + +quint64 VaultClock::getLastestTime() const +{ + return m_lastestTime; +} + +quint64 VaultClock::getSelfTime() const +{ + return m_selfTime; +} + +void VaultClock::addTickTime(qint64 seconds) +{ + m_selfTime += static_cast(seconds); +} + +bool VaultClock::isLockEventTriggered() const +{ + return m_isLockEventTriggerd; +} + +void VaultClock::triggerLockEvent() +{ + m_isLockEventTriggerd = true; +} + +void VaultClock::clearLockEvent() +{ + m_isLockEventTriggerd = false; +} + +void VaultClock::tick() +{ + m_selfTime++; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultclock.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultclock.h new file mode 100644 index 0000000..2ee34f5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultclock.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef VAULTCLOCK_H +#define VAULTCLOCK_H + +#include +#include + +/** + * @brief The VaultClock class + */ +class VaultClock : public QObject +{ + Q_OBJECT +public: + explicit VaultClock(QObject *parent = nullptr); + ~VaultClock(); + +public slots: + /** + * @brief setRefreshTime 设置保险箱刷新时间 + * @param time + */ + void setRefreshTime(quint64 time); + + /** + * @brief getLastestTime 获取保险柜计时 + * @return + */ + quint64 getLastestTime() const; + + /** + * @brief getSelfTime 获取自定义时间 + * @return + */ + quint64 getSelfTime() const; + + /** + * @brief isLockEventTriggered 是否存在已触发的锁定事件 + * @return + */ + bool isLockEventTriggered() const; + + /** + * @brief triggerLockEvent 触发锁定事件 + */ + void triggerLockEvent(); + + /** + * @brief clearLockEvent 清除锁定事件 + */ + void clearLockEvent(); + + /** + * @brief addTickTime 增加时钟 + * @param seconds + */ + void addTickTime(qint64 seconds); + +protected: + /** + * @brief tick 秒针 + */ + void tick(); + +private: + quint64 m_lastestTime = 0; // latest time + + QTimer m_selfTimer; + quint64 m_selfTime; + + bool m_isLockEventTriggerd = false; +}; + +#endif // VAULTCLOCK_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultmanager.cpp new file mode 100644 index 0000000..de0ace7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultmanager.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "vaultmanager.h" +#include "dbusadaptor/vault_adaptor.h" +#include "app/policykithelper.h" +#include "vaultclock.h" + +#include +#include +#include +#include +#include +#include + + +QString VaultManager::ObjectPath = "/com/deepin/filemanager/daemon/VaultManager"; +QString VaultManager::PolicyKitCreateActionId = "com.deepin.filemanager.daemon.VaultManager.Create"; +QString VaultManager::PolicyKitRemoveActionId = "com.deepin.filemanager.daemon.VaultManager.Remove"; + +VaultManager::VaultManager(QObject *parent) + : QObject(parent) + , QDBusContext() + , m_curVaultClock(nullptr) + , m_pcTime(0) +{ + QDBusConnection::systemBus().registerObject(ObjectPath, this); + m_vaultAdaptor = new VaultAdaptor(this); + + // create a default vault clock. + m_curVaultClock = new VaultClock(this); + m_curUser = getCurrentUser(); + m_mapUserClock.insert(m_curUser, m_curVaultClock); + + // monitor system user changed. + QDBusConnection::systemBus().connect( + "com.deepin.dde.LockService", + "/com/deepin/dde/LockService", + "com.deepin.dde.LockService", + "UserChanged", + this, + SLOT(sysUserChanged(QString))); + + QDBusConnection::systemBus().connect( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "PrepareForSleep", + this, + SLOT(computerSleep(bool))); +} + +VaultManager::~VaultManager() +{ +} + +void VaultManager::sysUserChanged(const QString &curUser) +{ + if (m_curUser != curUser) { + m_curUser = curUser; + bool bContain = m_mapUserClock.contains(m_curUser); + if (bContain) { + m_curVaultClock = m_mapUserClock[m_curUser]; + } else { + m_curVaultClock = new VaultClock(this); + m_mapUserClock.insert(m_curUser, m_curVaultClock); + } + } +} + +void VaultManager::setRefreshTime(quint64 time) +{ + m_curVaultClock->setRefreshTime(time); +} + +quint64 VaultManager::getLastestTime() const +{ + return m_curVaultClock->getLastestTime(); +} + +quint64 VaultManager::getSelfTime() const +{ + return m_curVaultClock->getSelfTime(); +} + +bool VaultManager::checkAuthentication(QString type) +{ + bool ret = false; + qint64 pid = 0; + QDBusConnection c = QDBusConnection::connectToBus(QDBusConnection::SystemBus, "org.freedesktop.DBus"); + if(c.isConnected()) { + pid = c.interface()->servicePid(message().service()).value(); + } + + if (pid){ + if (type.compare("Create") == 0) { + ret = PolicyKitHelper::instance()->checkAuthorization(PolicyKitCreateActionId, pid); + }else if (type.compare("Remove") == 0){ + ret = PolicyKitHelper::instance()->checkAuthorization(PolicyKitRemoveActionId, pid); + } + } + + if (!ret) { + qDebug() << "Authentication failed !!"; + } + return ret; +} + +bool VaultManager::isLockEventTriggered() const +{ + return m_curVaultClock->isLockEventTriggered(); +} + +void VaultManager::triggerLockEvent() +{ + m_curVaultClock->triggerLockEvent(); +} + +void VaultManager::clearLockEvent() +{ + m_curVaultClock->clearLockEvent(); +} + +void VaultManager::computerSleep(bool bSleep) +{ + if (bSleep) { + m_pcTime = QDateTime::currentSecsSinceEpoch(); + } else { + qint64 diffTime = QDateTime::currentSecsSinceEpoch() - m_pcTime; + if (diffTime > 0) { + for (auto key : m_mapUserClock.keys()) { + VaultClock *vaultClock = m_mapUserClock.value(key); + if (vaultClock) { + vaultClock->addTickTime(diffTime); + } + } + } + } +} + +QString VaultManager::getCurrentUser() const +{ + QString user = m_curUser; + + QDBusInterface sessionManagerIface("com.deepin.dde.LockService", + "/com/deepin/dde/LockService", + "com.deepin.dde.LockService", + QDBusConnection::systemBus()); + + if (sessionManagerIface.isValid()) { + QDBusPendingCall call = sessionManagerIface.asyncCall("CurrentUser"); + call.waitForFinished(); + if (!call.isError()) { + QDBusReply reply = call.reply(); + user = reply.value(); + } + } + + return user; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultmanager.h new file mode 100644 index 0000000..de5cf8b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-daemon/vault/vaultmanager.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + + +#ifndef VAULTMANAGER_H +#define VAULTMANAGER_H + +#include +#include +#include + +class VaultAdaptor; +class VaultClock; + +/** + * @brief The VaultManager class 保险箱管理类 + */ +class VaultManager : public QObject, public QDBusContext +{ + Q_OBJECT +public: + explicit VaultManager(QObject *parent = nullptr); + ~VaultManager(); + + static QString ObjectPath; + static QString PolicyKitCreateActionId; + static QString PolicyKitRemoveActionId; + +public slots: + /** + * @brief slotUserChanged 用户切换槽函数 + * @param curUser + */ + void sysUserChanged(const QString& curUser); + + /** + * @brief setRefreshTime 设置保险箱刷新时间 + * @param time + */ + void setRefreshTime(quint64 time); + + /** + * @brief getLastestTime 获取保险柜计时 + * @return + */ + quint64 getLastestTime() const; + + /** + * @brief getSelfTime 获取自定义时间 + * @return + */ + quint64 getSelfTime() const; + + /** + * @brief checkAuthentication 权限验证 + * @param type + * @return + */ + bool checkAuthentication(QString type); + + /** + * @brief isLockEventTriggered 是否存在已触发的锁定事件 + * @return + */ + bool isLockEventTriggered() const; + + /** + * @brief triggerLockEvent 触发锁定事件 + */ + void triggerLockEvent(); + + /** + * @brief clearLockEvent 清除锁定事件 + */ + void clearLockEvent(); + + /** + * @brief computerSleep 通过dbus接口获取电脑休眠状态 + * 该函数将主机休眠时间记录到时钟 + * @param bSleep true为正要进入休眠,false为进入唤醒状态 + */ + void computerSleep(bool bSleep); + +private: + /** + * @brief getCurrentUser 获取当前用户 + * @return + */ + QString getCurrentUser() const; + + VaultAdaptor* m_vaultAdaptor = nullptr; + + QMap m_mapUserClock; // map user and timer. + VaultClock *m_curVaultClock; // current user clock. + QString m_curUser; // current system user. + qint64 m_pcTime; // 主机时间 +}; + +#endif // VAULTMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/accessibility/ac-lib-file-manager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/accessibility/ac-lib-file-manager.h new file mode 100644 index 0000000..5730ac0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/accessibility/ac-lib-file-manager.h @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef LIB_FRAME_ACCESSIBLE_DEFINE_H +#define LIB_FRAME_ACCESSIBLE_DEFINE_H + +#include +#include +#include "acintelfunctions.h" + + #define AC_FILE_MENU_DEFAULT "default_file_menu" //默认菜单 + #define AC_FILE_MENU_DEFAULT_SIDEBAR "default_sidebar_menu" //侧边栏默认菜单 + #define AC_FILE_MENU_SIDEBAR_TAGITEM "sidebar_tagitem_menu" //侧边栏标签菜单 + #define AC_FILE_MENU_SIDEBAR_DEVICE_ITEM "sidebar_deviceitem_menu"//侧边栏设备菜单 + #define AC_FILE_MENU_SIDEBAR_VAULT_ITEM "sidebar_vaultitem_menu"//侧边栏保险箱菜单 + #define AC_FILE_MENU_SIDEBAR_BOOK_MARK "sidebar_bookmark_menu" //侧边栏书签菜单 + #define AC_FILE_MENU_USER_SHARE "user_share_menu" //用户共享菜单 + #define AC_FILE_MENU_TOOLBAR_SEETINGS "toolbar_seetings_menu"//工具栏菜单 + #define AC_FILE_MENU_VAULT "vault_menu" //保险箱菜单 + #define AC_FILE_MENU_FILEVIEW "fileview_menu"//视图菜单 + #define AC_FILE_MENU_CRUMB_BAR "crumb_bar_menu"//面包屑菜单 + + #define AC_COMPUTER_VIEW "computer_view" // 计算视图 + #define AC_COMPUTER_LIST_VIEW "computer_list_view"//计算机列表视图 + #define AC_COMPUTER_MIAN_WINDOW "computer_window"//计算机窗口 + + #define AC_COMPUTER_TITLE_BAR "computer_title_bar"//计算机标题栏 + #define AC_COMPUTER_CUSTOM_TITLE_BAR "custom_title_bar"//自定义标题栏 + #define AC_COMPUTER_TITLE_BAR_ADRESS "AddressToolBar"//地址输入框 + #define AC_COMPUTER_TITLE_BAR_BACK_BTN "back_button"//回退按钮 + #define AC_COMPUTER_TITLE_BAR_FORWARD_BTN "forword_button" //前进按钮 + #define AC_COMPUTER_TITLE_BAR_BTN_BOX "button_box" //按钮区域 + #define AC_COMPUTER_TITLE_BAR_SERACH_BTN "search_button" //查询按钮 + #define AC_COMPUTER_TITLE_BAR_DETAIL_BTN "detail_button" //详细按钮 + #define AC_COMPUTER_TITLE_BAR_CONTOLLER_TOOL_BAR "ContollerToolBar" //控制区域 + #define AC_COMPUTER_TITLE_BAR_CRUMB_SERACH_FRAME "crumb_search_frame" //面包屑区域 + + #define AC_COMPUTER_STATUS_BAR "status_bar" //计算机状态栏 + #define AC_COMPUTER_STATUS_BAR_LOADING_INDICATOR "loadingIndicator" //加载指示器 + #define AC_COMPUTER_STATUS_BAR_SCALE_SLIDER "scale_slider" + #define AC_COMPUTER_STATUS_BAR_ACCEPT_BUTTON "accept_button" //接收按钮 + #define AC_COMPUTER_STATUS_BAR_REJECT_BUTTON "reject_button" // 拒绝按钮 + #define AC_COMPUTER_STATUS_BAR_LINE_EDIT "line_edit" //编辑区域 + + #define AC_COMPUTER_RENAME_BAR "rename_bar" //重命名 + #define AC_COMPUTER_RENAME_BAR_SELECT_TYPE "rename_types" //重命名类型 + #define AC_COMPUTER_RENAME_BAR_STACK_WIDGET "stack_widget" //栈面板 + + #define AC_COMPUTER_CRUMB_BAR "crumb_bar" //面包屑指示栏 + #define AC_COMPUTER_CRUMB_BAR_LEFT_ARROW "left_arrow" //左箭头 + #define AC_COMPUTER_CRUMB_BAR_RIGHT_ARROW "right_arrow" //右箭头 + #define AC_COMPUTER_CRUMB_BAR_LIST_VIEW "crumb_list_view" //列表 + #define AC_COMPUTER_CRUMB_BAR_SCROLL_BAR "scroll_bar" //滑动模块 + + #define AC_COMPUTER_COMPLETER_LIST_VIEW "CompleterListView" + + #define AC_FILE_VIEW "file_view" //文件视图 + #define AC_FM_VIEW_MANAGER "fm_view_manager" //文件视图管理 + #define AC_DM_SIDE_BAR "left_side_bar" //左边栏 + #define AC_DM_SIDE_BAR_VIEW "side_bar_view" //左边栏视图 + #define AC_DM_TOOLBAR "DM_ToolBar" //工具栏 + #define AC_DM_RIGHT_VIEW "right_view" // 右边栏 + #define AC_DM_RIGHT_VIEW_TRASH_LABEL "trash_label" //回收站标签 + #define AC_DM_RIGHT_VIEW_TRASH_HOLDER "trash_holder" //回收站 + #define AC_DM_RIGHT_VIEW_TRASH_SPLIT_LINE "trash_split_line" //回收站隔离线 + #define AC_DM_RIGHT_VIEW_EMPTY_TRASH_BUTTON "EmptyTrashButton" //清空回收站 + #define AC_DM_RIGHT_VIEW_HOLDER "rightviewHolder" //右视图 + #define AC_DM_RIGHT_VIEW_DETAIL_VLINE "rightDetailVLine" //右视图隔离线 + #define AC_DM_RIGHT_VIEW_DETAIL_VIEW "right-detail-view" //有视图详情 + #define AC_DM_RIGHT_VIEW_MAIN_FRAME "main_frame" //主窗口 + #define AC_DM_RIGHT_VIEW_MAIN_FRAME_ICON_LABEL "frame_icon"//主窗口图标 + #define AC_DM_RIGHT_VIEW_MAIN_FRAME_LINE "frame_line" //主窗口隔离线 + #define AC_DM_RIGHT_VIEW_MAIN_FRAME_SCROLLAREA "DFMRightDetailView-QScrollArea" //滑动区域 + + #define AC_TAG_WIDGET "tag-widget" //标签面板 + + #define AC_COMPUTER_CENTRAL_WIDGET "CentralWidget" //计算机中心区域 + #define AC_DM_SPLITTER "dm_splitter" //隔离线 + #define AC_VIEW_MID_WIDGET "mid_wiget" //中间区域 + + #define AC_VIEW_TAB_BAR "TabBar" //标签栏 + #define AC_VIEW_TAB_BAR_NEW_BUTTON "NewTabButton" //标签栏按钮 + #define AC_VIEW_TAB_BAR_TOP_LINE "top_line" //标签栏上线 + #define AC_VIEW_TAB_BAR_BOTTOM_LINE "bottom_line" //标签栏下线 + + #define AC_CLOSE_ALL_DLG_INDICATOR "dialogs_close_all_dialog_indicator" + #define AC_CLOSE_ALL_DLG_INDICATOR_MSG_LABEL "dialog_indicator_message_label" + #define AC_CLOSE_ALL_DLG_INDICATOR_CLOSE_BUTTON "dialog_indicator_message_all_close_button" + + #define AC_TASK_DLG "d_task_dialog" //任务对话框 + #define AC_TASK_DLG_TITLE_BAR "d_task_dialog_title_bars" //标题栏 + #define AC_TASK_DLG_TASK_LIST_WIDGET "task_dialog_task_list_widget" //任务列表面板 + #define AC_TASK_DLG_TASK_LIST_ITEM "task_dialog_task_list_item" // 任务列表 + #define AC_TASK_DLG_TASK_JOB_ITEM "task_dialog_task_job_item" //任务 + + #define AC_FD_STATUS_BAR "dlg_status_bar" // 文件对话框状态栏 + #define AC_FD_STATUS_BAR_INTEL "statusBar" // 状态栏 + #define AC_FD_STATUS_BAR_FILE_NAME_EDIT "file_name_edit" //文件名 + #define AC_FD_STATUS_BAR_FILTERS "filters" //过滤 + #define AC_FD_STATUS_BAR_TITLE_LABEL "title_label" //标题标签 + #define AC_FD_STATUS_BAR_TITLE_CONTENT_LABEL "content_label" //内容标签 + #define AC_FD_STATUS_BAR_TITLE_CONTENT_EDIT "content_edit" //内容框 + #define AC_FD_STATUS_BAR_TITLE_CONTENT_BOX "content_box" //内容列表 + + #define AC_TAG_LABLE "tag_label" //tag 标签 + #define AC_TAG_LEFT_LABLE "tag_left_label" //tag 左标签 + #define AC_TAG_ACTION_WIDGET "tag_action_widget" //tag 面板 + #define AC_TAG_ACTION_WIDGET_TOOL_TIP "tag_action_tool_tip" //tag 面板 提示 + #define AC_TAG_CRUMB_EDIT "tag_crumb_edit" //tag 编辑区域 + + #define AC_VAULT_ACTIVE_WIDGET "vault_active_widget" // 保险箱激活页面 + #define AC_VAULT_ACTIVE_STACK "vault_active_stack" // 保险箱激活 功能页面容器 + #define AC_VAULT_ACTIVE_START_WIDGET "vault_active_start_widget" // 保险箱激活 开始页面 + #define AC_VAULT_ACTIVE_START_TITLE_LABEL "vault_active_start_title" // 保险箱激活 开始页面 标题 + #define AC_VAULT_ACTIVE_START_CONTENT_LABEL "vault_active_start_content" // 保险箱激活 开始页面 内容 + #define AC_VAULT_ACTIVE_START_PICTURE "vault_active_start_picture" // 保险箱激活 开始页面 图片 + #define AC_VAULT_ACTIVE_START_BUTTON "vault_active_start_button" // 保险箱激活 开始页面 开启按钮 + #define AC_VAULT_ACTIVE_SET_PASSWORD_WIDGET "vault_active_set_password_widget" // 保险箱激活 设置密码页面 + #define AC_VAULT_ACTIVE_SET_PASSWORD_TITLE "vault_active_set_password_title" // 保险箱激活 设置密码页面 标题 + #define AC_VAULT_ACTIVE_SET_PASSWORD_TYPE_LABEL "vault_active_set_password_type_label" // 保险箱激活 设置密码页面 类型 标签 + #define AC_VAULT_ACTIVE_SET_PASSWORD_TYPE_COMBOX "vault_active_set_password_type_combox" // 保险箱激活 设置密码页面 类型 组合框 + #define AC_VAULT_ACTIVE_SET_PASSWORD_PASSWORD_LABEL "vault_active_set_password_password_label" // 保险箱激活 设置密码页面 设置密码 标签 + #define AC_VAULT_ACTIVE_SET_PASSWORD_PASSWORD_EDIT "vault_active_set_password_password_edit" // 保险箱激活 设置密码页面 设置密码 编辑框 + #define AC_VAULT_ACTIVE_SET_PASSWORD_REPASSWORD_LABEL "vault_active_set_password_repassword_lable" // 保险箱激活 设置密码页面 重复密码 标签 + #define AC_VAULT_ACTIVE_SET_PASSWORD_REPASSWORD_EDIT "vault_active_set_password_repassword_edit" // 保险箱激活 设置密码页面 重复密码 编辑框 + #define AC_VAULT_ACTIVE_SET_PASSWORD_HINT_LABEL "vault_active_set_password_hint_label" // 保险箱激活 设置密码页面 提示 标签 + #define AC_VAULT_ACTIVE_SET_PASSWORD_HINT_EDIT "vault_active_set_password_hint_edit" // 保险箱激活 设置密码页面 提示 编辑框 + #define AC_VAULT_ACTIVE_SET_PASSWORD_NEXT_BUTTON "vault_active_set_password_next_button" // 保险箱激活 设置密码页面 下一步 按钮 + #define AC_VAULT_ACTIVE_KEY_WIDGET "vault_active_key_widget" // 保险箱激活 密钥页面 + #define AC_VAULT_ACTIVE_KEY_TITLE "vault_active_key_title" // 保险箱激活 密钥页面 标题 + #define AC_VAULT_ACTIVE_KEY_CONTENT "vault_active_key_content" // 保险箱激活 密钥页面 内容 + #define AC_VAULT_ACTIVE_KEY_KEY_BUTTON "vault_active_key_key_button" // 保险箱激活 密钥页面 密钥 按钮 + #define AC_VAULT_ACTIVE_KEY_KEY_EDIT "vault_active_key_key_edit" // 保险箱激活 密钥页面 密钥 编辑器框 + #define AC_VAULT_ACTIVE_KEY_QRCODE_BUTTON "vault_active_key_qrcode_button" // 保险箱激活 密钥页面 二维码 按钮 + #define AC_VAULT_ACTIVE_KEY_QRCODE_IMAGE "vault_active_key_qrcode_image" // 保险箱激活 密钥页面 二维码 图片 + #define AC_VAULT_ACTIVE_KEY_QRCODE_HINT "vault_active_key_qrcode_hint" // 保险箱激活 密钥页面 二维码 提示 + #define AC_VAULT_ACTIVE_KEY_NEXT_BUTTON "vault_active_key_next_button" // 保险箱激活 密钥页面 下一步 按钮 + #define AC_VAULT_DEFAULT_PATH_RADIOBTN "vault_default_path_radiobtn" // 保险箱激活 密钥保存页面 默认保存路径单选按钮 + #define AC_VAULT_OTHER_PATH_RADIOBTN "vault_other_path_radiobtn" // 保险箱激活 密钥保存页面 用户自定义保存路径单选按钮 + #define AC_VAULT_SELECT_FILE_SAVE_PATH_EDIT "vault_select_file_save_path_edit" // 保险箱激活 密钥保存页面 用户选择保存的路径编辑框 + #define AC_VAULT_ACTIVE_ENCRYPT_WIDGET "vault_active_encrypy_widget" // 保险箱激活 加密页面 + #define AC_VAULT_ACTIVE_ENCRYPT_TITLE "vault_active_encrypy_title" // 保险箱激活 加密页面 标题 + #define AC_VAULT_ACTIVE_ENCRYPT_CONTENT "vault_active_encrypy_content" // 保险箱激活 加密页面 内容 + #define AC_VAULT_ACTIVE_ENCRYPT_IMAGE "vault_active_encrypy_image" // 保险箱激活 加密页面 图片 + #define AC_VAULT_ACTIVE_ENCRYPT_PROGRESS "vault_active_encrypy_progress" // 保险箱激活 加密页面 进度条 + #define AC_VAULT_ACTIVE_ENCRYPT_PROGRESS_HINT "vault_active_encrypy_progress_hint" // 保险箱激活 加密页面 进度条提示 + #define AC_VAULT_ACTIVE_ENCRYPT_FINISH_IMAGE "vault_active_encrypy_finish_image" // 保险箱激活 加密页面 加密完成图片 + #define AC_VAULT_ACTIVE_ENCRYPT_FINISH_HINT "vault_active_encrypy_finish_hint" // 保险箱激活 加密页面 加密完成提示 + #define AC_VAULT_ACTIVE_ENCRYPT_BUTTON "vault_active_encrypy_button" // 保险箱激活 加密页面 按钮 + #define AC_VAULT_PASSWORD_UNLOCK_WIDGET "vault_password_unlock_widget" // 保险箱解锁 密码解锁页面 + #define AC_VAULT_PASSWORD_UNLOCK_TITLE "vault_password_unlock_title" // 保险箱解锁 密码解锁页面 标题 + #define AC_VAULT_PASSWORD_UNLOCK_CONTENT "vault_password_unlock_content" // 保险箱解锁 密码解锁页面 内容 + #define AC_VAULT_PASSWORD_UNLOCK_EDIT "vault_password_unlock_edit" // 保险箱解锁 密码解锁页面 编辑框 + #define AC_VAULT_PASSWORD_UNLOCK_HINT_BUTTON "vault_password_unlock_hint_button" // 保险箱解锁 密码解锁页面 密码提示按钮 + #define AC_VAULT_PASSWORD_UNLOCK_FORGETPASSWORD_BUTTON "vault_password_unlock_forgetpassword_button" // 保险箱解锁 密码解锁页面 密码找回 + #define AC_VAULT_PASSWORD_UNLOCK_CANCEL_BUTTON "vault_password_unlock_cancel_button" // 保险箱解锁 密码解锁页面 取消按钮 + #define AC_VAULT_PASSWORD_UNLOCK_OK_BUTTON "vault_password_unlock_ok_button" // 保险箱解锁 密码解锁页面 确认按钮 + #define AC_VAULT_KEY_UNLOCK_WIDGET "vault_key_unlock_widget" // 保险箱解锁 密钥解锁页面 + #define AC_VAULT_KEY_UNLOCK_TITLE "vault_key_unlock_title" // 保险箱解锁 密钥解锁页面 标题 + #define AC_VAULT_KEY_UNLOCK_EDIT "vault_key_unlock_edit" // 保险箱解锁 密钥解锁页面 编辑框 + #define AC_VAULT_KEY_UNLOCK_CANCEL_BUTTON "vault_key_unlock_cancel_button" // 保险箱解锁 密钥解锁页面 取消按钮 + #define AC_VAULT_KEY_UNLOCK_OK_BUTTON "vault_key_unlock_ok_button" // 保险箱解锁 密钥解锁页面 确认按钮 + #define AC_VAULT_DELETE_WIDGET "vault_delete_widget" // 保险箱删除 删除页面 + #define AC_VAULT_DELETE_TITLE "vault_delete_title" // 保险箱删除 删除页面 标题 + #define AC_VAULT_DELETE_CONTENT "vault_delete_content" // 保险箱删除 删除页面 内容 + #define AC_VAULT_DELETE_CANCEL_BUTTON "vault_delete_cancel_button" // 保险箱删除 删除页面 取消按钮 + #define AC_VAULT_DELETE_CHANGE_BUTTON "vault_delete_change_button" // 保险箱删除 删除页面 切换按钮 + #define AC_VAULT_DELETE_DELETE_BUTTON "vault_delete_delete_button" // 保险箱删除 删除页面 删除按钮 + #define AC_VAULT_DELETE_PASSWORD_EDIT "vault_delete_password_edit" // 保险箱删除 删除页面 密码编辑框 + #define AC_VAULT_DELETE_HINT_BUTTON "vault_delete_hint_button" // 保险箱删除 删除页面 密码提示按钮 + #define AC_VAULT_DELETE_KEY_EDIT "vault_delete_key_edit" // 保险箱删除 删除页面 密钥编辑框 + #define AC_VAULT_DELETE_PROGRESS "vault_delete_progress" // 保险箱删除 删除页面 删除操作进度条 + #define AC_VAULT_SAVE_PATH_TYPE_COMBOBOX "vault_save_path_type_combobox" // 保险箱解锁 密码找回页面 密钥保存方式 + #define AC_VAULT_SAVE_PUBKEY_FILE_EDIT "vault_save_pubkey_file_edit" // 保险箱解锁 密码找回页面 选择密钥文件路径 + #define AC_VAULT_RETURN_UNLOCK_PAGE_BTN "vault_return_unlock_page_btn" // 保险箱解锁 密码找回页面 返回解锁页面 + #define AC_VAULT_VERIFY_PUKEY_FILE_BTN "vault_verify_pubkey_file_btn" // 保险箱解锁 密码找回页面 验证密钥 + +#endif // LIB_FRAME_ACCESSIBLE_DEFINE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/accessibility/acintelfunctions.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/accessibility/acintelfunctions.h new file mode 100644 index 0000000..9872374 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/accessibility/acintelfunctions.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef ACCESSIBLE_INTERNAL_FUNCTIONS_H +#define ACCESSIBLE_INTERNAL_FUNCTIONS_H + +//#define AC_SET_OBJECT_NAME(classObj,objectname) classObj->setObjectName(objectname); + +#ifdef ENABLE_ACCESSIBILITY + #define AC_SET_ACCESSIBLE_NAME(classObj,accessiblename) classObj->setAccessibleName(accessiblename); + #define AC_SET_OBJECT_NAME(classObj,objectname) +#else + #define AC_SET_ACCESSIBLE_NAME(classObj,accessiblename) + #define AC_SET_OBJECT_NAME(classObj,objectname) +#endif + +#endif // ACCESSIBLE_INTERNAL_FUNCTIONS_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/app/define.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/app/define.cpp new file mode 100644 index 0000000..6a2b32e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/app/define.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "define.h" + +#include + +#include "dialogs/dialogmanager.h" +#include "gvfs/gvfsmountmanager.h" +#include "deviceinfo/udisklistener.h" +#include "disomaster.h" + +Q_GLOBAL_STATIC(DialogManager, gsDialogManager) +Q_GLOBAL_STATIC(GvfsMountManager, gsGvfsMountManager) +Q_GLOBAL_STATIC(UDiskListener, gsUDiskListener) +Q_GLOBAL_STATIC(DISOMasterNS::DISOMaster, gsDISOMaster) + +static QMutex odmutex; + +bool g_isFileDialogMode = false; + +DialogManager *getDialogManager(bool doConstruct) +{ + if (doConstruct) { + if (!gsDialogManager.exists() && qApp) { + gsDialogManager->moveToThread(qApp->thread()); + } + + return gsDialogManager(); + } + return gsDialogManager.exists() ? gsDialogManager() : nullptr; +} + +GvfsMountManager *getGvfsMountManager(bool doConstruct) +{ + if (doConstruct) { + if (!gsGvfsMountManager.exists() && qApp) { + gsGvfsMountManager->moveToThread(qApp->thread()); + } + + return gsGvfsMountManager(); + } + return gsGvfsMountManager.exists() ? gsGvfsMountManager() : nullptr; +} + +UDiskListener *getUDiskListener(bool doConstruct) +{ + if (doConstruct) { + if (!gsUDiskListener.exists() && qApp) { + gsUDiskListener->moveToThread(qApp->thread()); + } + + return gsUDiskListener(); + } + return gsUDiskListener.exists() ? gsUDiskListener() : nullptr; +} + +DISOMasterNS::DISOMaster *getDISOMaster(bool doConstruct) +{ + if (doConstruct) { + if (!gsDISOMaster.exists() && qApp) { + gsDISOMaster->moveToThread(qApp->thread()); + } + + return gsDISOMaster(); + } + return gsDISOMaster.exists() ? gsDISOMaster() : nullptr; +} + +QMutex *getOpticalDriveMutex() +{ + return &odmutex; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/app/define.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/app/define.h new file mode 100644 index 0000000..6eb2f62 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/app/define.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef GLOBAL_H +#define GLOBAL_H + +class DialogManager; +class GvfsMountManager; +class UDiskListener; +class QMutex; +namespace DISOMasterNS { +class DISOMaster; +} + +DialogManager *getDialogManager(bool doConstruct = false); +GvfsMountManager *getGvfsMountManager(bool doConstruct = false); +UDiskListener *getUDiskListener(bool doConstruct = false); +DISOMasterNS::DISOMaster *getDISOMaster(bool doContruct = false); +QMutex *getOpticalDriveMutex(); + +#define bluetoothManager BluetoothManager::instance() +#define searchHistoryManager Singleton::instance() +#define bookmarkManager Singleton::instance() +#define fileMenuManger Singleton::instance() +#define fileSignalManager Singleton::instance() +#define dialogManager getDialogManager(true) +#define appController AppController::instance() +#define fileService DFileService::instance() +#define rootFileManager DRootFileManager::instance() +#define deviceListener getUDiskListener(true) +#define mimeAppsManager Singleton::instance() +#define systemPathManager Singleton::instance() +#define mimeTypeDisplayManager Singleton::instance() +#define networkManager Singleton::instance() +#define gvfsMountManager getGvfsMountManager(true) +#define secretManager Singleton::instance() +#define userShareManager Singleton::instance() +#define ISOMaster getDISOMaster(true) + +// begin file item global define +#define TEXT_PADDING 4 +#define ICON_MODE_ICON_SPACING 5 +#define COLUMU_PADDING 10 +#define LEFT_PADDING 10 +#define RIGHT_PADDING 10 +// end + +// begin file view global define +#define LIST_MODE_LEFT_MARGIN 10 +#define LIST_MODE_RIGHT_MARGIN 10 +// end + + +#define MAX_PROPERTY_DIALOG_NUMBER 16 + +#define DISCBURN_STAGING "discburn" +#define DISCBURN_CACHE_MID_PATH "/.cache/deepin/discburn/_dev_" + +#define VAULT_CREATE "com.deepin.filemanager.daemon.VaultManager.Create" +#define VAULT_REMOVE "com.deepin.filemanager.daemon.VaultManager.Remove" + +#define IPHONE_STAGING "Apple_Inc" +#define MOBILE_ROOT_PATH "/run/user" +#define NETWORK_REDIRECT_SCHEME_EX "-all-network" + +// root 用户下 挂载路径为 /.gvfs/mtp:host=", 所以这里去掉/ +#define MTP_STAGING "gvfs/mtp:host=" + +extern bool g_isFileDialogMode; + +#endif // GLOBAL_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/app/filesignalmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/app/filesignalmanager.cpp new file mode 100644 index 0000000..b678c2c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/app/filesignalmanager.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "filesignalmanager.h" + +#include "dfmevent.h" +#include "dabstractfileinfo.h" +#include "durl.h" +#include + + +FileSignalManager::FileSignalManager(QObject *parent): + QObject(parent) +{ + qRegisterMetaType(QT_STRINGIFY(DFMEvent)); + qRegisterMetaType(QT_STRINGIFY(DFMUrlListBaseEvent)); + qRegisterMetaType(QT_STRINGIFY(QDir::Filters)); + qRegisterMetaType>(QT_STRINGIFY(QList)); + qRegisterMetaType(QT_STRINGIFY(DUrl)); + qRegisterMetaType(); + qRegisterMetaType(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/app/filesignalmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/app/filesignalmanager.h new file mode 100644 index 0000000..cf43cb6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/app/filesignalmanager.h @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef FILESIGNALMANAGER_H +#define FILESIGNALMANAGER_H + +#include + +class DFileInfo; +class DFMEvent; +class DFMUrlBaseEvent; +class DFMUrlListBaseEvent; +class DAbstractFileInfo; +class DeviceInfo; +class DUrl; + +typedef QList DUrlList; + + + +class FileSignalManager : public QObject +{ + Q_OBJECT + +public: + explicit FileSignalManager(QObject *parent = nullptr); + +signals: + /* emit usershare status changed*/ + void userShareCountChanged(const int count); + + // 在共享信息刷新后,请求刷新页面 + void requestRefreshFileModel(const DUrl &url); + + /* request close current tab*/ + void requestCloseCurrentTab(quint64 winId); + + // 请求关闭窗口的所有保险箱的标签 + void requestCloseAllTabOfVault(quint64 winId); + + /* request fetch network nodes*/ + void requestFetchNetworks(const DFMUrlBaseEvent &event); + + /*request choose smb mounted file*/ + void requestChooseSmbMountedFile(const DFMUrlBaseEvent &event); + + /* current display url changed*/ + // DEPRECATED: use DFileManagerWindow::currentUrlChanged() instead + void Q_DECL_DEPRECATED currentUrlChanged(const DFMUrlBaseEvent &event); + + /* file icon*/ + void requestIcon(const DUrl &url) const; + void iconChanged(const DUrl &url, const QIcon &icon) const; + + /*add copy/move/delete job to taskdialog when copy/move/delete job created*/ + void jobAdded(const QMap &jobDetail); + + /*remove copy/move/delete job to taskdialog when copy/move/delete job finished*/ + void jobRemoved(const QMap &jobDetail); + + /*update copy/move/delete job taskdialog ui*/ + void jobDataUpdated(const QMap &jobDetail, + const QMap &data); + + /*abort copy/move/delete job taskdialog from ui*/ + void abortTask(const QMap &jobDetail); + + /*copy/move job conflict dialog show */ + void conflictDialogShowed(const QMap &jobDetail); + + /*request rename to DFileView*/ + void requestRename(const DFMUrlBaseEvent &event); + + /*request to rename multi files */ + void requestMultiFilesRename(const DFMUrlListBaseEvent &event); + + /* view select all */ + void requestViewSelectAll(int windowId); + + /*requst open new window by given url*/ + void requestOpenNewWindowByUrl(const DUrl &url, bool isAlwaysOpen); + + /*request active window*/ + void requestActiveWindow(); + + /*request show url wrong dialog*/ + void requestShowUrlWrongDialog(const DUrl &url); + + /*request show PropertyDialog*/ + void requestShowOpenWithDialog(const DFMEvent &event); + + /*request show OpenFiles PropertyDialog*/ + void requestShowOpenFilesWithDialog(const DFMUrlListBaseEvent &event); + + /*request show PropertyDialog*/ + void requestShowPropertyDialog(const DFMUrlListBaseEvent &event); + + /*request show PropertyDialog*/ + void requestShowShareOptionsInPropertyDialog(const DFMUrlListBaseEvent &event); + + /*request show TrashPropertyDialog*/ + void requestShowTrashPropertyDialog(const DFMEvent &event); + + /*request show ComputerPropertyDialog*/ + void requestShowComputerPropertyDialog(const DFMEvent &event); + + /*request show PropertyDialog*/ + void requestShowDevicePropertyDialog(const DFMEvent &event); + + /* request select file view item*/ + void requestSelectFile(const DFMUrlListBaseEvent &event); + + /* request select file view item and rename*/ + void requestSelectRenameFile(const DFMUrlBaseEvent &event); + + /*request update mime cache*/ + void requestUpdateMimeAppsCache(); + + /*close last active window */ + void aboutToCloseLastActivedWindow(int winId); + + /*sort role changed*/ + void requestCacheSortState(); + + /* error dialog from disk listener*/ + void showDiskErrorDialog(const QString &id, const QString &errorText); + + /* status bar items count */ + void statusBarItemsCounted(const DFMEvent &event, int number); + void statusBarItemsSelected(const DFMEvent &event, int number); + + /* request of renaming bookmark*/ + void requestBookmarkRename(const DFMEvent &event); + + /*book mark rename*/ + void bookmarkRenamed(const QString &newname, const DFMUrlBaseEvent &event); + + /*focus back to DFileView*/ + void requestFoucsOnFileView(quint64 winId); + + /*ctrl + F*/ + void requestSearchCtrlF(quint64 winId); + + /*ctrl + L*/ + void requestSearchCtrlL(quint64 winId); + + /*request cache samba login data*/ + void requsetCacheLoginData(const QJsonObject &obj); + + /*quit application if taskdialog close*/ + void requestQuitApplication(); + + /*request fresh file view*/ + void requestFreshFileView(quint64 winId); + void requestFreshAllFileView(); + /*request fresh desktop view*/ + void requestFreshAllDesktop(); + + /*request abort copy/move job*/ + void requestAbortJob(const DUrl &url); + + /*request abort copy/move job for DFileCopyMoveJob*/ + void requestAsynAbortJob(const DUrl &url); + + /*request start file job task update timer*/ + void requestStartUpdateJobTimer(); + + void requestStopUpdateJobTimer(); + + /*icon size changed by setting dialog*/ + void requestChangeIconSizeBySizeIndex(const int &sizeIndex); + + /*trash state changed when trash is empty or is filled*/ + void trashStateChanged(); + + /*show file preview dialog*/ + void requestShowFilePreviewDialog(const DUrlList &selectUrls, const DUrlList &entryUrls); + + /*show 4G warning dialog if file copy to removal devicve which type is fat32*/ + void requestShow4GFat32Dialog(); + + /*show restore failed dialog for tagart removed*/ + void requestShowRestoreFailedDialog(const DUrlList &urlList); + + /*show retore failed dialog for permission*/ + void requestShowRestoreFailedPerssionDialog(const QString &srcPath, const QString &targetPath); + + /*show restore failed dialog for ource file does not exist*/ + void requestShowRestoreFailedSourceNotExist(const DUrlList &urlList); + + /*show dialog for no permission operation*/ + void requestShowNoPermissionDialog(const DFMUrlListBaseEvent &event); + + /*show add user share failed dialog for share name same as system uername*/ + void requestShowAddUserShareFailedDialog(const QString &sharePath); + + void requestShowErrorDialog(const QString &title, const QString &message); + + /*rename a tag*/ + void requestRenameTag(const DUrl &oldTagUrl); + + /*stop cd scan timer,擦除光盘、刻录光盘时停止定时器*/ + void stopCdScanTimer(const QString &strDevice); + + // 在擦除光盘完成后重启定时器 + void restartCdScanTimer(const QString &strDevice); + + // 激活任务进度对话框 + void activeTaskDlg(); + + // 强制刷新计算机页面 + void requestUpdateComputerView(); + + // 请求重定向tab页 + void requestRedirectTabUrl(const DUrl &tabRootUrl, const DUrl &newUrl); + + // 请求关闭tab页 + void requestCloseTab(const DUrl &tabRootUrl); + + //隐藏系统盘状态发生改变消息 + void requestHideSystemPartition(bool ishide); + + //手动发送文件移动信号 gio专用 + void fileMoved(const QString &from, const QString &fname, const QString &to, const QString &tname); + + //移除最近访问中的包含当前路径的文件 + void requestRemoveRecentFile(const QString &path); + + // 通过信号进入目录,目前与DFileManagerWindow::cd 关联 + bool cdFolder(const DUrl &folderUrl); + + // 请求关闭本地监听端口 + void requestCloseListen(); + + // 请求停止mediainfo的获取 + void requestCloseMediaInfo(const QString path); + + // 请求忽略当前鼠标拖拽事件 + void requestIgnoreDragEvent(); + + /*request show smb url mounted all window*/ + void requestShowNewWindows(); + + /*mounted failed and remove need open windows*/ + void requestRemoveSmbUrl(const DUrl &url); + +#ifdef SW_LABEL + /*copy/move/delete fail job show */ + void jobFailed(int nRet, const QString &jobType, const QString &srcFileName); +#endif +}; + +#endif // FILESIGNALMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothadapter.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothadapter.cpp new file mode 100644 index 0000000..a583129 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothadapter.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "bluetoothadapter.h" + +BluetoothAdapter::BluetoothAdapter(QObject *parent) + : QObject(parent), + m_id(""), + m_name(""), + m_powered(false) +{ + +} + +void BluetoothAdapter::setId(const QString &id) +{ + m_id = id; +} + +void BluetoothAdapter::setName(const QString &name) +{ + if (name != m_name) { + m_name = name; + Q_EMIT nameChanged(name); + } +} + +void BluetoothAdapter::setPowered(bool powered) +{ + if (powered != m_powered) { + m_powered = powered; + Q_EMIT poweredChanged(powered); + } +} + +QMap BluetoothAdapter::devices() const +{ + return m_devices; +} + +const BluetoothDevice *BluetoothAdapter::deviceById(const QString &id) const +{ + return m_devices.keys().contains(id) ? m_devices[id] : nullptr; +} + +void BluetoothAdapter::addDevice(const BluetoothDevice *device) +{ + if (!deviceById(device->id())) { + m_devices[device->id()] = device; + Q_EMIT deviceAdded(device); + } +} + +void BluetoothAdapter::removeDevice(const QString &deviceId) +{ + const BluetoothDevice *device = nullptr; + + device = deviceById(deviceId); + if (device) { + m_devices.remove(deviceId); + Q_EMIT deviceRemoved(deviceId); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothadapter.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothadapter.h new file mode 100644 index 0000000..27a9d22 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothadapter.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef BLUETOOTHADAPTER_H +#define BLUETOOTHADAPTER_H + +#include "bluetooth/bluetoothdevice.h" + +#include +#include + +/** + * @brief 蓝牙模块适配器,管理终端的蓝牙设备,是一对多的关系 + */ +class BluetoothAdapter : public QObject +{ + Q_OBJECT +public: + explicit BluetoothAdapter(QObject *parent = nullptr); + + inline QString id() const { return m_id; } + void setId(const QString &id); + + inline QString name() const { return m_name; } + void setName(const QString &name); + + inline bool powered() const { return m_powered; } + void setPowered(bool powered); + + QMap devices() const; + const BluetoothDevice *deviceById(const QString &id) const; + +public Q_SLOTS: + void addDevice(const BluetoothDevice *device); + void removeDevice(const QString &deviceId); + +Q_SIGNALS: + void deviceAdded(const BluetoothDevice *device) const; + void deviceRemoved(const QString &deviceId) const; + void nameChanged(const QString &name) const; + void poweredChanged(const bool &powered) const; + +private: + QString m_id; + QString m_name; + bool m_powered; + QMap m_devices; +}; + +#endif // BLUETOOTHADAPTER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothdevice.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothdevice.cpp new file mode 100644 index 0000000..cc5cc93 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothdevice.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "bluetoothdevice.h" + +BluetoothDevice::BluetoothDevice(QObject *parent) : QObject(parent),m_paired(false),m_trusted(false),m_state(StateUnavailable) +{ + +} + +void BluetoothDevice::setId(const QString &id) +{ + m_id = id; +} + +void BluetoothDevice::setName(const QString &name) +{ + if (name != m_name) { + m_name = name; + Q_EMIT nameChanged(name); + } +} + +void BluetoothDevice::setAlias(const QString &alias) +{ + if (alias != m_alias) { + m_alias = alias; + Q_EMIT aliasChanged(alias); + } +} + +void BluetoothDevice::setIcon(const QString &icon) +{ + m_icon = icon; +} + +void BluetoothDevice::setPaired(bool paired) +{ + if (paired != m_paired) { + m_paired = paired; + Q_EMIT pairedChanged(paired); + } +} + +void BluetoothDevice::setTrusted(bool trusted) +{ + if (trusted != m_trusted) { + m_trusted = trusted; + Q_EMIT trustedChanged(trusted); + } +} + +void BluetoothDevice::setState(const BluetoothDevice::State &state) +{ + if (state != m_state) { + m_state = state; + Q_EMIT stateChanged(state); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothdevice.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothdevice.h new file mode 100644 index 0000000..dd07a72 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothdevice.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef BLUETOOTHDEVICE_H +#define BLUETOOTHDEVICE_H + +#include + +/** + * @brief 蓝牙连接的终端设备,例如含有蓝牙模块的手机/电脑 + */ +class BluetoothDevice : public QObject +{ + Q_OBJECT + +public: + enum State { + StateUnavailable = 0, // 未连接 + StateAvailable = 1, // 可链接 + StateConnected = 2 // 完成连接 + }; + Q_ENUM(State) + + explicit BluetoothDevice(QObject *parent = nullptr); + + inline QString id() const { return m_id; } + void setId(const QString &id); + + inline QString name() const { return m_name; } + void setName(const QString &name); + + inline QString alias() const { return m_alias; } + void setAlias(const QString &alias); + + inline QString icon() const { return m_icon; } + void setIcon(const QString &icon); + + inline bool paired() const { return m_paired; } + void setPaired(bool paired); + + inline bool trusted() const { return m_trusted; } + void setTrusted(bool trusted); + + inline State state() const { return m_state; } + void setState(const State &state); + +Q_SIGNALS: + void nameChanged(const QString &name) const; + void aliasChanged(const QString &alias) const; + void pairedChanged(const bool &paired) const; + void stateChanged(const State &state) const; + void trustedChanged(const bool trusted) const; + +private: + QString m_id; + QString m_name; + QString m_alias; + QString m_icon; // phone/computer + bool m_paired; // 是否配对 + bool m_trusted; // 是否信任该设备 + State m_state; +}; + +#endif // BLUETOOTHDEVICE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmanager.cpp new file mode 100644 index 0000000..c81a886 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmanager.cpp @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "bluetoothmanager_p.h" +#include "bluetooth/bluetoothmodel.h" + +#include +#include +#include + +#define BluetoothService "com.deepin.daemon.Bluetooth" +#define BluetoothPath "/com/deepin/daemon/Bluetooth" +#define BlutoothInterface "com.deepin.daemon.Bluetooth" + +#define BluetoothPage "bluetooth" +#define ControlcenterService "com.deepin.dde.ControlCenter" +#define ControlcenterPath "/com/deepin/dde/ControlCenter" + +BluetoothManagerPrivate::BluetoothManagerPrivate(BluetoothManager *qq) + : q_ptr(qq), + m_model(new BluetoothModel(qq)) +{ + Q_Q(BluetoothManager); + // initialize dbus interface + m_bluetoothInter = new DBusBluetooth(BluetoothService, BluetoothPath, + QDBusConnection::sessionBus(), q); + m_controlcenterInter = new DBusControlcenter(ControlcenterService, ControlcenterPath, + QDBusConnection::sessionBus(), q); + + initConnects(); +} + +void BluetoothManagerPrivate::resolve(const QDBusReply &req) +{ + Q_Q(BluetoothManager); + const QString replyStr = req.value(); + qInfo() << replyStr; + static int maxRetry = 3; + // GetAdapter method, if there has no adapter, the method returns an emtpy json [], but if the method is not ready, + // returns a null string. if null, retry + if (replyStr.isEmpty() && maxRetry > 0) { + qInfo() << "retry to get bluetooth adapters..." << maxRetry; + QTimer::singleShot(500, q, [q]{ + q->refresh(); + }); + maxRetry--; + return; + } + QJsonDocument doc = QJsonDocument::fromJson(replyStr.toUtf8()); + QJsonArray arr = doc.array(); + for (QJsonValue val : arr) { + BluetoothAdapter *adapter = new BluetoothAdapter(m_model); + inflateAdapter(adapter, val.toObject()); + m_model->addAdapter(adapter); + } +} + +void BluetoothManagerPrivate::initConnects() +{ + Q_Q(BluetoothManager); + + QObject::connect(m_bluetoothInter, &DBusBluetooth::serviceValidChanged, q, [q](bool valid){ + if (valid) { + qInfo() << "bluetooth service is valid now..."; + QTimer::singleShot(1000, q, [q]{ q->refresh(); }); + } + }); + + // adapter added + QObject::connect(m_bluetoothInter, &DBusBluetooth::AdapterAdded, q, [=](const QString & json) { + QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); + QJsonObject obj = doc.object(); + + BluetoothAdapter *adapter = new BluetoothAdapter(m_model); + inflateAdapter(adapter, obj); + m_model->addAdapter(adapter); + }); + + // adapter removed + QObject::connect(m_bluetoothInter, &DBusBluetooth::AdapterRemoved, q, [=](const QString & json) { + QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); + QJsonObject obj = doc.object(); + const QString id = obj["Path"].toString(); + + const BluetoothAdapter *result = m_model->removeAdapater(id); + BluetoothAdapter *adapter = const_cast(result); + if (adapter) { + adapter->deleteLater(); + } + }); + + // adapter changed + QObject::connect(m_bluetoothInter, &DBusBluetooth::AdapterPropertiesChanged, q, [=](const QString & json) { + const QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); + const QJsonObject obj = doc.object(); + const QString id = obj["Path"].toString(); + + BluetoothAdapter *adapter = const_cast(m_model->adapterById(id)); + if (adapter) { + inflateAdapter(adapter, obj); + } + }); + + // device added + QObject::connect(m_bluetoothInter, &DBusBluetooth::DeviceAdded, q, [=](const QString & json) { + QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); + QJsonObject obj = doc.object(); + const QString adapterId = obj["AdapterPath"].toString(); + const QString id = obj["Path"].toString(); + + const BluetoothAdapter *result = m_model->adapterById(adapterId); + BluetoothAdapter *adapter = const_cast(result); + if (adapter) { + const BluetoothDevice *result1 = adapter->deviceById(id); + BluetoothDevice *device = const_cast(result1); + if (!device) { + device = new BluetoothDevice(adapter); + } + inflateDevice(device, obj); + adapter->addDevice(device); + } + }); + + // deivce removeed + QObject::connect(m_bluetoothInter, &DBusBluetooth::DeviceRemoved, q, [=](const QString & json) { + QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); + QJsonObject obj = doc.object(); + const QString adapterId = obj["AdapterPath"].toString(); + const QString id = obj["Path"].toString(); + + const BluetoothAdapter *result = m_model->adapterById(adapterId); + BluetoothAdapter *adapter = const_cast(result); + if (adapter) { + adapter->removeDevice(id); + } + }); + + // device changed + QObject::connect(m_bluetoothInter, &DBusBluetooth::DevicePropertiesChanged, q, [this](const QString & json) { + const QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); + const QJsonObject obj = doc.object(); + const QString id = obj["Path"].toString(); + for (const BluetoothAdapter *adapter : m_model->adapters()) { + BluetoothDevice *device = const_cast(adapter->deviceById(id)); + if (device) { + inflateDevice(device, obj); + } + } + }); + + QObject::connect(m_bluetoothInter, &DBusBluetooth::TransferCreated, q, [=](const QString & file, const QDBusObjectPath & transferPath, const QDBusObjectPath & sessionPath) { + qDebug() << file << transferPath.path() << sessionPath.path(); + }); + + QObject::connect(m_bluetoothInter, &DBusBluetooth::TransferRemoved, q, [=](const QString & file, const QDBusObjectPath & transferPath, const QDBusObjectPath & sessionPath, bool done) { + Q_UNUSED(transferPath) + Q_Q(BluetoothManager); + if (!done) { + Q_EMIT q->transferCancledByRemote(sessionPath.path()); + } else { + Q_EMIT q->fileTransferFinished(sessionPath.path(), file); + } + }); + + QObject::connect(m_bluetoothInter, &DBusBluetooth::ObexSessionCreated, q, [=](const QDBusObjectPath & sessionPath) { + qDebug() << sessionPath.path(); + }); + + QObject::connect(m_bluetoothInter, &DBusBluetooth::ObexSessionRemoved, q, [=](const QDBusObjectPath & sessionPath) { + qDebug() << sessionPath.path(); + }); + + QObject::connect(m_bluetoothInter, &DBusBluetooth::ObexSessionProgress, q, [=](const QDBusObjectPath & sessionPath, qulonglong totalSize, qulonglong transferred, int currentIdx) { + Q_Q(BluetoothManager); + Q_EMIT q->transferProgressUpdated(sessionPath.path(), totalSize, transferred, currentIdx); + }); + + QObject::connect(m_bluetoothInter, &DBusBluetooth::TransferFailed, q, [=](const QString & file, const QDBusObjectPath & sessionPath, const QString & errInfo) { + Q_Q(BluetoothManager); + Q_EMIT q->transferFailed(sessionPath.path(), file, errInfo); + }); +} + +void BluetoothManagerPrivate::inflateAdapter(BluetoothAdapter *adapter, const QJsonObject &adapterObj) +{ + Q_Q(BluetoothManager); + + const QString path = adapterObj["Path"].toString(); + const QString alias = adapterObj["Alias"].toString(); + const bool powered = adapterObj["Powered"].toBool(); + qDebug() << "resolve adapter path:" << path; + + adapter->setId(path); + adapter->setName(alias); + adapter->setPowered(powered); + + QPointer adapterPointer(adapter); + + // 异步获取适配器的所有设备 + QDBusObjectPath dPath(path); + QDBusPendingCall call = m_bluetoothInter->GetDevices(dPath); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, q, [this, watcher, adapterPointer, call] { + if (!adapterPointer) { + qDebug() << "adapterPointer released!"; + watcher->deleteLater(); + return; + } + BluetoothAdapter *adapter = adapterPointer.data(); + if (!call.isError()) { + QStringList tmpList; + + QDBusReply reply = call.reply(); + const QString replyStr = reply.value(); + QJsonDocument doc = QJsonDocument::fromJson(replyStr.toUtf8()); + QJsonArray arr = doc.array(); + + for (QJsonValue val : arr) { + const QString id = val.toObject()["Path"].toString(); + const BluetoothDevice *result = adapter->deviceById(id); + BluetoothDevice *device = const_cast(result); + if (device == nullptr) { + device = new BluetoothDevice(adapter); + } + // 存储设备数据 + inflateDevice(device, val.toObject()); + adapter->addDevice(device); + + tmpList << id; + } + + // 适配器设备去重 + for (const BluetoothDevice *device : adapter->devices()) { + if (!tmpList.contains(device->id())) { + adapter->removeDevice(device->id()); + + BluetoothDevice *target = const_cast(device); + if (target) { + target->deleteLater(); + } + } + } + } else { + qWarning() << call.error().message(); + } + + watcher->deleteLater(); + }); +} + +void BluetoothManagerPrivate::inflateDevice(BluetoothDevice *device, const QJsonObject &deviceObj) +{ + const QString &id = deviceObj["Path"].toString(); + const QString &name = deviceObj["Name"].toString(); + const QString &alias = deviceObj["Alias"].toString(); + const QString &icon = deviceObj["Icon"].toString(); + const bool paired = deviceObj["Paired"].toBool(); + const bool trusted = deviceObj["Trusted"].toBool(); + const BluetoothDevice::State state = BluetoothDevice::State(deviceObj["State"].toInt()); + + device->setId(id); + device->setName(name); + device->setAlias(alias); + device->setIcon(icon); + device->setPaired(paired); + device->setTrusted(trusted); + device->setState(state); +} + +/** + * @brief This is BluetoothManager implement + */ +BluetoothManager::BluetoothManager(QObject *parent) + : QObject(parent), + d_ptr(new BluetoothManagerPrivate(this)) +{ + refresh(); +} + + +BluetoothManager *BluetoothManager::instance() +{ + static BluetoothManager bluetooth; + return &bluetooth; +} + + +void BluetoothManager::refresh() +{ + Q_D(BluetoothManager); + + if (!d->m_bluetoothInter->isValid()) { + qCritical() << "bluetooth interface is not valid!!!"; + return; + } + + // 获取蓝牙设备 + QDBusPendingCall call = d->m_bluetoothInter->GetAdapters(); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call); + connect(watcher, &QDBusPendingCallWatcher::finished, [ = ] { + if (!call.isError()) + { + QDBusReply reply = call.reply(); + d->resolve(reply); + } else + { + qWarning() << call.error().message(); + } + watcher->deleteLater(); + }); +} + +BluetoothModel *BluetoothManager::model() +{ + Q_D(BluetoothManager); + + return d->m_model; +} + +bool BluetoothManager::hasAdapter() +{ + return model()->adapters().count() > 0; +} + +bool BluetoothManager::bluetoothSendEnable() +{ + QDBusInterface btIface(BluetoothService, BluetoothPath, BlutoothInterface, QDBusConnection::sessionBus()); + if (!btIface.isValid()) { + qWarning() << "bluetooth interface is not valid"; + return false; + } + auto canSendFile = btIface.property("CanSendFile"); + if (!canSendFile.isValid()) { + qWarning() << "bluetooth interface has no 'CanSendFile' property"; + return true; // if there is no this property, then we do not disable bluetooth transfer. + } + return canSendFile.toBool(); +} + +void BluetoothManager::showBluetoothSettings() +{ + Q_D(BluetoothManager); + + d->m_controlcenterInter->ShowModule(BluetoothPage); +} + +void BluetoothManager::sendFiles(const QString &id, const QStringList &filePath, const QString &senderToken) +{ + Q_D(BluetoothManager); + + // /org/bluez/hci0/dev_90_63_3B_DA_5A_4C --》 90:63:3B:DA:5A:4C + QString deviceAddress = id; + deviceAddress.remove(QRegularExpression("/org/bluez/hci[0-9]*/dev_")).replace("_", ":"); + + QFuture> future = QtConcurrent::run([this, deviceAddress, filePath] { + Q_D(BluetoothManager); + QDBusPendingReply reply = d->m_bluetoothInter->SendFiles(deviceAddress, filePath); + reply.waitForFinished(); + return qMakePair(reply.value().path(), reply.error().message()); + }); + + if (d->m_watcher) { + if (d->m_watcher->isRunning()) + d->m_watcher->future().cancel(); + delete d->m_watcher; + d->m_watcher = nullptr; + } + + // 此处 watcher 在 run 完成之后会 delete,但无法在传输对话框关闭后立即 delete + d->m_watcher = new QFutureWatcher>(); + d->m_watcher->setFuture(future); + connect(d->m_watcher, &QFutureWatcher::finished, this, [d, senderToken, this]{ + emit transferEstablishFinish(d->m_watcher->result().first, d->m_watcher->result().second, senderToken); + delete d->m_watcher; + d->m_watcher = nullptr; + }); +} + +bool BluetoothManager::cancelTransfer(const QString &sessionPath) +{ + Q_D(BluetoothManager); + d->m_bluetoothInter->CancelTransferSession(QDBusObjectPath(sessionPath)); + qDebug() << sessionPath; + return true; +} + +bool BluetoothManager::canSendBluetoothRequest() +{ + Q_D(BluetoothManager); + return d->m_bluetoothInter->transportable(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmanager.h new file mode 100644 index 0000000..740cd40 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmanager.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef BLUETOOTHMANAGER_H +#define BLUETOOTHMANAGER_H + +#include + +#include "dfmglobal.h" + +class BluetoothModel; +class BluetoothDevice; +class BluetoothAdapter; +class BluetoothManagerPrivate; + +/** + * @brief This is singleton class. + * you should `#include "app/define.h"` and `"bluetooth/bluetoothmanager.h"`, + * then use the macro `bluetoothManager` call method + */ +class BluetoothManager : public QObject +{ + Q_OBJECT + +public: + static BluetoothManager *instance(); + + /** + * @brief 返回数据模型 + * @return + */ + BluetoothModel *model(); + + bool hasAdapter(); + + static bool bluetoothSendEnable(); + + +public Q_SLOTS: + /** + * @brief 异步接口:调用刷新蓝牙模块,初始化数据 + */ + void refresh(); + + /** + * @brief 打开控制中心的‘蓝牙’界面 + */ + void showBluetoothSettings(); + + /** + * @brief sendFiles 向设备发送文件 + * @param id 蓝牙设备 ID + * @param filePath 文件路径列表 + * @param senderToken 发起该次传输请求的对话框唯一标识符 + */ + void sendFiles(const QString &id, const QStringList &filePath, const QString &senderToken); + + /** + * @brief cancleTransfer 取消某个传输会话 + * @param sessionPath + * @return + */ + bool cancelTransfer(const QString &sessionPath); + + bool canSendBluetoothRequest(); + +Q_SIGNALS: + + /** + * @brief transferProcessUpdated 当前传输会话进度更新 + * @param sessionPath 用来标识当前传输进程的会话id + * @param total 当前传输列表的总bytes + * @param transferred 当前已传输的 bytes + * @param currFileIndex 当前传输文件的序号 + */ + void transferProgressUpdated(const QString &sessionPath, qulonglong total, qulonglong transferred, int currFileIndex); + + /** + * @brief transferCancledByRemote + * @param sessionPath + */ + void transferCancledByRemote(const QString &sessionPath); + + void fileTransferFinished(const QString &sessionPath, const QString &filePath); + void transferFailed(const QString &sessionPath, const QString &filePath, const QString &errMsg); + void transferEstablishFinish(const QString &sessionPath, const QString &errMsg, const QString &senderToken); + +private: + explicit BluetoothManager(QObject *parent = nullptr); + BluetoothManager(const BluetoothManager &) = delete; + BluetoothManager &operator = (const BluetoothManager &) = delete; + + QSharedPointer d_ptr; + + Q_DECLARE_PRIVATE(BluetoothManager) +}; + +#endif // BLUETOOTHMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmanager_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmanager_p.h new file mode 100644 index 0000000..ae5789f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmanager_p.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef BLUETOOTHMANAGER_P_H +#define BLUETOOTHMANAGER_P_H + +#include "bluetoothmanager.h" + +#include + +#include +#include + + +using DBusBluetooth = com::deepin::daemon::Bluetooth; +using DBusControlcenter = com::deepin::dde::ControlCenter; + +template +class QFutureWatcher; + +class BluetoothManagerPrivate +{ +public: + explicit BluetoothManagerPrivate(BluetoothManager *qq); + + BluetoothManagerPrivate(BluetoothManagerPrivate &) = delete; + BluetoothManagerPrivate &operator=(BluetoothManagerPrivate &) = delete; + /** + * @brief 解析蓝牙设备, 获取适配器和设备信息 + * @param req + */ + void resolve(const QDBusReply &req); + + /** + * @brief 蓝牙 dbus 信号的处理 + */ + void initConnects(); + + /** + * @brief 获取适配器信息 + * @param adapter + * @param adapterObj + */ + void inflateAdapter(BluetoothAdapter *adapter, const QJsonObject &adapterObj); + + /** + * @brief 获取设备信息 + * @param device + * @param deviceObj + */ + void inflateDevice(BluetoothDevice *device, const QJsonObject &deviceObj); + +public: + BluetoothManager *q_ptr {nullptr}; + BluetoothModel *m_model {nullptr}; + DBusBluetooth *m_bluetoothInter {nullptr}; + DBusControlcenter *m_controlcenterInter {nullptr}; + QFutureWatcher> *m_watcher {nullptr}; + + Q_DECLARE_PUBLIC(BluetoothManager) +}; + +#endif // BLUETOOTHMANAGER_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmodel.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmodel.cpp new file mode 100644 index 0000000..f53ae30 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmodel.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "bluetoothmodel.h" + +BluetoothModel::BluetoothModel(QObject *parent) : QObject(parent) +{ + m_adapters.clear(); +} + +QMap BluetoothModel::adapters() const +{ + return m_adapters; +} + +const BluetoothAdapter *BluetoothModel::adapterById(const QString &id) +{ + return m_adapters.keys().contains(id) ? m_adapters[id] : nullptr; +} + +void BluetoothModel::addAdapter(BluetoothAdapter *adapter) +{ + if (!adapterById(adapter->id())) { + m_adapters[adapter->id()] = adapter; + Q_EMIT adapterAdded(adapter); + return; + } + adapter->deleteLater(); +} + +const BluetoothAdapter *BluetoothModel::removeAdapater(const QString &adapterId) +{ + const BluetoothAdapter *adapter = nullptr; + + adapter = adapterById(adapterId); + if (adapter) { + m_adapters.remove(adapterId); + Q_EMIT adapterRemoved(adapter); + } + + return adapter; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmodel.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmodel.h new file mode 100644 index 0000000..58a7998 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothmodel.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef BLUETOOTHMODEL_H +#define BLUETOOTHMODEL_H + +#include "bluetooth/bluetoothadapter.h" + +#include + +/** + * @brief 蓝牙模块数据模型,管理所有的适配器,是一对多关系 + */ +class BluetoothModel : public QObject +{ + Q_OBJECT +public: + explicit BluetoothModel(QObject *parent = nullptr); + + /** + * @brief 返回所有蓝牙 adapter_id - adapter + * @return + */ + QMap adapters() const; + + /** + * @brief 通过 adapter_id_id 返回 adapter + * @param id + * @return + */ + const BluetoothAdapter *adapterById(const QString &id); + +public Q_SLOTS: + void addAdapter(BluetoothAdapter *adapter); + const BluetoothAdapter *removeAdapater(const QString &adapterId); + +Q_SIGNALS: + void adapterAdded(const BluetoothAdapter *adapter) const; + void adapterRemoved(const BluetoothAdapter *adapter) const; + +private: + QMap m_adapters; + +}; + +#endif // BLUETOOTHMODEL_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothtransdialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothtransdialog.cpp new file mode 100644 index 0000000..81d3b50 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothtransdialog.cpp @@ -0,0 +1,810 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "bluetoothtransdialog.h" +#include "dguiapplicationhelper.h" +#include "bluetooth/bluetoothmanager.h" +#include "bluetooth/bluetoothadapter.h" +#include "bluetooth/bluetoothmodel.h" +#include "app/define.h" +#include "dfileservices.h" +#include "dialogs/dialogmanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TITLE_BT_TRANS_FILE BluetoothTransDialog::tr("Bluetooth File Transfer") +#define TITLE_BT_TRANS_SUCC BluetoothTransDialog::tr("File Transfer Successful") +#define TITLE_BT_TRANS_FAIL BluetoothTransDialog::tr("File Transfer Failed") + +#define TXT_SENDING_FILE BluetoothTransDialog::tr("Sending files to \"%1\"") +#define TXT_SENDING_FAIL BluetoothTransDialog::tr("Failed to send files to \"%1\"") +#define TXT_SENDING_SUCC BluetoothTransDialog::tr("Sent to \"%1\" successfully") +#define TXT_SELECT_DEVIC BluetoothTransDialog::tr("Select a Bluetooth device to receive files") +#define TXT_NO_DEV_FOUND BluetoothTransDialog::tr("Cannot find the connected Bluetooth device") +#define TXT_WAIT_FOR_RCV BluetoothTransDialog::tr("Waiting to be received...") +#define TXT_GOTO_BT_SETS BluetoothTransDialog::tr("Go to Bluetooth Settings") +#define TXT_SEND_PROGRES BluetoothTransDialog::tr("%1/%2 Sent") +#define TXT_ERROR_REASON BluetoothTransDialog::tr("Error: the Bluetooth device is disconnected") +#define TXT_FILE_OVERSIZ BluetoothTransDialog::tr("Unable to send the file more than 2 GB") +#define TXT_FILE_ZEROSIZ BluetoothTransDialog::tr("Unable to send 0 KB files") +#define TXT_FILE_NOEXIST BluetoothTransDialog::tr("File doesn't exist") + +#define TXT_NEXT BluetoothTransDialog::tr("Next","button") +#define TXT_CANC BluetoothTransDialog::tr("Cancel","button") +#define TXT_DONE BluetoothTransDialog::tr("Done","button") +#define TXT_RTRY BluetoothTransDialog::tr("Retry","button") +#define TXT_OKAY BluetoothTransDialog::tr("OK","button") + +static const QString ICON_CONNECT = "notification-bluetooth-connected"; +static const QString ICON_DISCONN = "notification-bluetooth-disconnected"; + +static const QString lightIcon = ":/icons/deepin/builtin/light/icons/bluetooth_"; +static const QString darkIcon = ":/icons/deepin/builtin/dark/icons/bluetooth_"; + +static const QString PXMP_NO_DEV_LIGHT = "://icons/deepin/builtin/light/icons/dfm_bluetooth_empty_light.svg"; +static const QString PXMP_NO_DEV_DARKY = "://icons/deepin/builtin/dark/icons/dfm_bluetooth_empty_dark.svg"; + +static const qint64 FILE_TRANSFER_LIMITS = 2147483648; // 2GB = 2 * 1024 * 1024 * 1024 Bytes + +BluetoothTransDialog::BluetoothTransDialog(const QStringList &urls, BluetoothTransDialog::TransferMode mode, QString targetDevId, QWidget *parent) + : DDialog(parent) + , m_urls(urls) + , m_token(QUuid::createUuid().toString()) +{ + initUI(); + initConn(); + m_stack->setCurrentIndex(NoneDevicePage); // 初始界面为空界面 + + updateDeviceList(); // 打开多个窗口的时候蓝牙设备不一定任何更新操作,因此这时依靠蓝牙状态的变更去更新列表不可取,手动获取一次列表 + bluetoothManager->refresh(); + + if (mode == DirectlySend) + sendFilesToDevice(targetDevId); + + // 调试布局 + // setStyleSheet("border: 1px solid blue;"); +} + +void BluetoothTransDialog::sendFilesToDevice(const QString &devId) +{ + const BluetoothDevice *dev = nullptr; + QMapIterator iter(bluetoothManager->model()->adapters()); + while (iter.hasNext()) { + iter.next(); + dev = (iter.value()->deviceById(devId)); + if (dev) + break; + } + + if (!dev) { + qDebug() << "can not find device: " << devId; + } else { + m_selectedDevice = dev->alias(); + m_selectedDeviceId = devId; + sendFiles(); + } +} + +void BluetoothTransDialog::changeLabelTheme(QLabel *obj, bool isTitle) +{ + if (!obj) + return; + + double alpha = isTitle ? 0.9 : 0.7; + connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, + obj, [obj, alpha](DGuiApplicationHelper::ColorType themeType) { + QPalette pal = obj->palette(); + pal.setColor(QPalette::WindowText, themeType == DGuiApplicationHelper::DarkType + ? QColor::fromRgbF(1, 1, 1, alpha) + : QColor::fromRgbF(0, 0, 0, alpha)); + obj->setPalette(pal); + }); +} + +void BluetoothTransDialog::setObjTextStyle(QWidget *obj, int size, bool bold) +{ + if (!obj) + return; + QFont f = obj->font(); + f.setFamily("SourceHanSansSC"); + f.setPixelSize(size); + f.setWeight(bold ? QFont::Medium : QFont::Normal); + f.setStyle(QFont::StyleNormal); + obj->setFont(f); +} + +QString BluetoothTransDialog::humanizedStrOfObexErrMsg(const QString &msg) +{ + if (msg.contains("Timed out")) { + return tr("File sending request timed out"); + } else if (msg.contains("0x53")) { + return tr("The service is busy and unable to process the request"); + } else { // ...TO BE CONTINUE + return msg; + } +} + +bool BluetoothTransDialog::canSendFiles() +{ + return bluetoothManager->canSendBluetoothRequest(); +} + +void BluetoothTransDialog::initUI() +{ + setIcon(QIcon::fromTheme(ICON_CONNECT)); + setFixedSize(381, 271); + layout()->setMargin(0); + layout()->setSpacing(0); + + // main structure + QFrame *mainFrame = new QFrame(this); + QVBoxLayout *pLayout = new QVBoxLayout; + pLayout->setSpacing(0); + pLayout->setMargin(0); + mainFrame->setLayout(pLayout); + + addContent(mainFrame); + + // public title + m_titleOfDialog = new DLabel(TITLE_BT_TRANS_FILE, this); + m_titleOfDialog->setAlignment(Qt::AlignCenter); + setObjTextStyle(m_titleOfDialog, 14, true); + changeLabelTheme(m_titleOfDialog, true); + pLayout->addWidget(m_titleOfDialog); + + // stacked area + m_stack = new QStackedWidget(this); + m_stack->layout()->setMargin(0); + m_stack->layout()->setSpacing(0); + + pLayout->addWidget(m_stack); + + // 以下顺序固定以便进行枚举遍历 + m_stack->addWidget(initDeviceSelectorPage()); + m_stack->addWidget(initNonDevicePage()); + m_stack->addWidget(initWaitForRecvPage()); + m_stack->addWidget(initTranferingPage()); + m_stack->addWidget(initFailedPage()); + m_stack->addWidget(initSuccessPage()); + + setOnButtonClickedClose(false); + + // 防止窗口初始化的时候字体颜色不更改,手动触发一次该信号 + emit DGuiApplicationHelper::instance()->themeTypeChanged(DGuiApplicationHelper::instance()->themeType()); +} + +void BluetoothTransDialog::initConn() +{ + QMap adapters = bluetoothManager->model()->adapters(); + QMapIterator iter(adapters); + while (iter.hasNext()) { + iter.next(); + const BluetoothAdapter *adapter = iter.value(); + connectAdapter(adapter); + } + + connect(m_stack, &QStackedWidget::currentChanged, this, &BluetoothTransDialog::onPageChagned); + connect(this, &BluetoothTransDialog::buttonClicked, this, &BluetoothTransDialog::onBtnClicked); + + connect(m_devicesList, &DListView::clicked, this, [this](const QModelIndex & curr) { + for (int i = 0; i < m_devModel->rowCount(); i++) { + DStandardItem *item = dynamic_cast(m_devModel->item(i)); + if (!item) + continue; + if (i == curr.row()) { + item->setCheckState(Qt::Checked); + m_selectedDevice = item->text(); + m_selectedDeviceId = item->data(DevIdRole).toString(); + } else + item->setCheckState(Qt::Unchecked); + } + }); + + connect(bluetoothManager->model(), &BluetoothModel::adapterAdded, this, [this](const BluetoothAdapter *adapter) { + connectAdapter(adapter); + }); + + connect(bluetoothManager->model(), &BluetoothModel::adapterRemoved, this, [this](const BluetoothAdapter *adapter) { + if (!adapter) + return; + if (m_connectedAdapter.contains(adapter->id())) + m_connectedAdapter.removeAll(adapter->id()); + + adapter->disconnect(); + QMap devices = adapter->devices(); + QMapIterator it(devices); + while (it.hasNext()) { + it.next(); + it.value()->disconnect(); + } + }); + + connect(bluetoothManager, &BluetoothManager::transferProgressUpdated, this, [this](const QString &sessionPath, qulonglong total, qulonglong transferred, int currFileIndex) { + if (sessionPath != m_currSessionPath) + return; + + if (transferred > total) // 过滤异常数据 + return; + + if (m_progressUpdateShouldBeIgnore) { + m_firstTransSize = transferred; // fix bug 45296 记录被忽略的第一次的请求头的数据段长度,如果之后信号触发依然是这个数据长度则认为未接收传输请求。 + m_progressUpdateShouldBeIgnore = false; + return; + } + if (m_firstTransSize == transferred) + return; + + if (m_stack->currentIndex() != TransferPage && m_stack->currentIndex() != FailedPage) + m_stack->setCurrentIndex(TransferPage); + + m_sendingStatus->setText(TXT_SEND_PROGRES.arg(currFileIndex - 1).arg(m_urls.count())); + m_progressBar->setMaximum(static_cast(total)); + m_progressBar->setValue(static_cast(transferred)); + + if (total == transferred && m_stack->currentIndex() == TransferPage) { + m_sendingStatus->setText(TXT_SEND_PROGRES.arg(currFileIndex).arg(m_urls.count())); + QPointer stack(m_stack); + QTimer::singleShot(1000, nullptr, [stack] { // 这里留一秒的时间用于显示完整的进度,避免进度满就直接跳转页面了 + if (!stack) + return; + qDebug() << "delay switch page on trans success"; + stack->setCurrentIndex(SuccessPage); + }); + } + }); + + connect(bluetoothManager, &BluetoothManager::transferCancledByRemote, this, [this](const QString &sessionPath) { + if (sessionPath != m_currSessionPath) + return; + m_stack->setCurrentIndex(FailedPage); + bluetoothManager->cancelTransfer(sessionPath); + }); + + connect(bluetoothManager, &BluetoothManager::transferFailed, this, [this](const QString &sessionPath, const QString &filePath, const QString &errMsg) { + if (sessionPath != m_currSessionPath) + return; + m_stack->setCurrentIndex(FailedPage); + bluetoothManager->cancelTransfer(sessionPath); + qDebug() << "filePath: " << filePath + << "\nerrorMsg: " << errMsg; + }); + + connect(bluetoothManager, &BluetoothManager::fileTransferFinished, this, [this](const QString &sessionPath, const QString &filePath) { + if (sessionPath != m_currSessionPath) + return; + m_finishedUrls << filePath; + if (m_finishedUrls.count() == m_urls.count()) { + m_stack->setCurrentIndex(SuccessPage); + } + }); + + connect(bluetoothManager, &BluetoothManager::transferEstablishFinish, this, [this](const QString &sessionPath, const QString &errMsg, const QString &senderToken){ + if (m_token != senderToken) + return; + + m_currSessionPath = sessionPath; + if (!sessionPath.isEmpty()) + return; + + if (m_devModel->rowCount() != 0) + m_stack->setCurrentIndex(SelectDevicePage); + else + m_stack->setCurrentIndex(NoneDevicePage); + + dialogManager->showErrorDialog(TITLE_BT_TRANS_FAIL, humanizedStrOfObexErrMsg(errMsg)); + }); +} + +QWidget *BluetoothTransDialog::initDeviceSelectorPage() +{ + // device selector page + QWidget *w = new QWidget(this); + QVBoxLayout *pLayout = new QVBoxLayout(w); + pLayout->setSpacing(0); + pLayout->setMargin(0); + w->setLayout(pLayout); + // w->setStyleSheet("border: 1px solid red;"); + + DLabel *statusTxt = new DLabel(TXT_SELECT_DEVIC, this); + statusTxt->setAlignment(Qt::AlignCenter); + setObjTextStyle(statusTxt, 14, false); + changeLabelTheme(statusTxt); + pLayout->addWidget(statusTxt); + + m_devicesList = new DListView(this); + m_devModel = new QStandardItemModel(this); + m_devicesList->setFixedHeight(88); + m_devicesList->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); + m_devicesList->setEditTriggers(QListView::NoEditTriggers); + m_devicesList->setIconSize(QSize(32, 32)); + m_devicesList->setResizeMode(QListView::Adjust); + m_devicesList->setMovement(QListView::Static); + m_devicesList->setSelectionMode(QListView::NoSelection); + m_devicesList->setFrameShape(QFrame::NoFrame); + m_devicesList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_devicesList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_devicesList->setBackgroundType(DStyledItemDelegate::BackgroundType::ClipCornerBackground); + m_devicesList->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding); + m_devicesList->setViewportMargins(0, 0, 0, 0); + m_devicesList->setItemSpacing(1); + m_devicesList->setModel(m_devModel); + + pLayout->addWidget(m_devicesList); + DCommandLinkButton *linkBtn = new DCommandLinkButton(TXT_GOTO_BT_SETS, this); + setObjTextStyle(linkBtn, 12, true); + connect(linkBtn, &DCommandLinkButton::clicked, this, &BluetoothTransDialog::showBluetoothSetting); + QHBoxLayout *pLay = new QHBoxLayout(this); + pLay->setMargin(0); + pLay->setSpacing(0); + pLay->addStretch(1); + pLay->addWidget(linkBtn); + pLayout->addLayout(pLay); + pLayout->setStretch(1, 1); + + return w; +} + +QWidget *BluetoothTransDialog::initNonDevicePage() +{ + QWidget *w = new QWidget(this); + QVBoxLayout *pLay = new QVBoxLayout(w); + pLay->setSpacing(0); + pLay->setMargin(0); + w->setLayout(pLay); + + DLabel *statusTxt = new DLabel(TXT_NO_DEV_FOUND, this); + statusTxt->setAlignment(Qt::AlignCenter); + setObjTextStyle(statusTxt, 14, false); + changeLabelTheme(statusTxt); + pLay->addWidget(statusTxt); + + DCommandLinkButton *linkBtn = new DCommandLinkButton(TXT_GOTO_BT_SETS, this); + setObjTextStyle(linkBtn, 12, true); + connect(linkBtn, &DCommandLinkButton::clicked, this, &BluetoothTransDialog::showBluetoothSetting); + QHBoxLayout *pHLay = new QHBoxLayout(w); + pHLay->addStretch(1); + pHLay->addWidget(linkBtn); + pHLay->addStretch(1); + pLay->addLayout(pHLay); + + QSvgWidget *pIconWid = new QSvgWidget(this); + pIconWid->setFixedSize(80, 80); + QWidget *pIconWidContainer = new QWidget(this); + QHBoxLayout *iconLay = new QHBoxLayout(pIconWidContainer); + iconLay->addStretch(1); + iconLay->addWidget(pIconWid); + iconLay->addStretch(1); + iconLay->setMargin(0); + iconLay->setSpacing(0); + pLay->addWidget(pIconWidContainer); + + connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, [pIconWid](DGuiApplicationHelper::ColorType t) { + switch (t) { + case DGuiApplicationHelper::UnknownType: + case DGuiApplicationHelper::LightType: + pIconWid->load(PXMP_NO_DEV_LIGHT); + break; + case DGuiApplicationHelper::DarkType: + pIconWid->load(PXMP_NO_DEV_DARKY); + break; + } + }); + + return w; +} + +QWidget *BluetoothTransDialog::initWaitForRecvPage() +{ + QWidget *w = new QWidget(this); + QVBoxLayout *pLay = new QVBoxLayout(w); + pLay->setSpacing(0); + pLay->setContentsMargins(0, 6, 0, 16); + w->setLayout(pLay); + // w->setStyleSheet("border: 1px solid red;"); + + m_subTitleForWaitPage = new DLabel("Sending files to ..."); + m_subTitleForWaitPage->setAlignment(Qt::AlignCenter); + m_subTitleForWaitPage->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); + setObjTextStyle(m_subTitleForWaitPage, 14, false); + changeLabelTheme(m_subTitleForWaitPage); + pLay->addWidget(m_subTitleForWaitPage); + + QVBoxLayout *spinnerLayout = new QVBoxLayout; + m_spinner = new DSpinner(this); + m_spinner->setFixedHeight(48); + spinnerLayout->addStretch(1); + spinnerLayout->addWidget(m_spinner); + spinnerLayout->addStretch(1); + pLay->addLayout(spinnerLayout); + + DLabel *txt2 = new DLabel(TXT_WAIT_FOR_RCV, this); + txt2->setAlignment(Qt::AlignCenter); + txt2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); + setObjTextStyle(txt2, 12, false); + changeLabelTheme(txt2); + pLay->addWidget(txt2); + + return w; +} + +QWidget *BluetoothTransDialog::initTranferingPage() +{ + QWidget *w = new QWidget(this); + QVBoxLayout *pLay = new QVBoxLayout(w); + w->setLayout(pLay); + + m_subTitleOfTransPage = new DLabel("Sending files to ..."); + m_subTitleOfTransPage->setAlignment(Qt::AlignCenter); + setObjTextStyle(m_subTitleOfTransPage, 14, false); + changeLabelTheme(m_subTitleOfTransPage); + pLay->addWidget(m_subTitleOfTransPage); + + m_progressBar = new DProgressBar(this); + m_progressBar->setValue(0); + m_progressBar->setMaximum(100); + m_progressBar->setMaximumHeight(8); + pLay->addWidget(m_progressBar); + + m_sendingStatus = new DLabel(TXT_SEND_PROGRES, this); + m_sendingStatus->setAlignment(Qt::AlignCenter); + setObjTextStyle(m_sendingStatus, 12, false); + changeLabelTheme(m_sendingStatus); + pLay->addWidget(m_sendingStatus); + + return w; +} + +QWidget *BluetoothTransDialog::initFailedPage() +{ + QWidget *w = new QWidget(this); + QVBoxLayout *pLay = new QVBoxLayout(w); + pLay->setSpacing(0); + pLay->setMargin(0); + // w->setStyleSheet("border: 1px solid red;"); + w->setLayout(pLay); + + m_subTitleOfFailedPage = new DLabel("Failed to send files to ..."); + m_subTitleOfFailedPage->setAlignment(Qt::AlignCenter); + m_subTitleOfFailedPage->setContentsMargins(0, 46, 0, 10); + setObjTextStyle(m_subTitleOfFailedPage, 14, false); + changeLabelTheme(m_subTitleOfFailedPage); + pLay->addWidget(m_subTitleOfFailedPage); + + DLabel *txt2 = new DLabel(TXT_ERROR_REASON, this); + txt2->setMargin(0); + txt2->setAlignment(Qt::AlignCenter); + setObjTextStyle(txt2, 12, false); + changeLabelTheme(txt2); + pLay->addWidget(txt2); + pLay->addStretch(1); + + return w; +} + +QWidget *BluetoothTransDialog::initSuccessPage() +{ + QWidget *w = new QWidget(this); + QVBoxLayout *pLay = new QVBoxLayout(w); + w->setLayout(pLay); + + m_subTitleOfSuccessPage = new DLabel("Sent to ... successfully"); + m_subTitleOfSuccessPage->setAlignment(Qt::AlignCenter); + setObjTextStyle(m_subTitleOfSuccessPage, 14, false); + changeLabelTheme(m_subTitleOfSuccessPage); + pLay->addWidget(m_subTitleOfSuccessPage); + + return w; +} + +DStandardItem *BluetoothTransDialog::getStyledItem(const BluetoothDevice *dev) +{ + // 只有已配对、状态为已连接的设备才显示在设备列表中 + if (!dev || !(dev->paired() && dev->state() == BluetoothDevice::StateConnected)) + return nullptr; + + if (findItemByIdRole(dev)) // 列表中已有此设备 + return nullptr; + + DViewItemActionList actLst; + DViewItemAction *act = new DViewItemAction(Qt::AlignVCenter | Qt::AlignLeft, QSize(22, 22), QSize(), false); + actLst.append(act); + + connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, + act, [act, dev](DGuiApplicationHelper::ColorType themeType) { + QString iconPath = QString("%1%2%3").arg(themeType == DGuiApplicationHelper::DarkType ? darkIcon : lightIcon) + .arg(dev->icon()) + .arg(themeType == DGuiApplicationHelper::DarkType ? "_dark.svg" : "_light.svg"); + act->setIcon(QIcon(iconPath)); + }); + + // 初始化一次主题变更以添加图标 + emit DGuiApplicationHelper::instance()->themeTypeChanged(DGuiApplicationHelper::instance()->themeType()); + + + DStandardItem *item = new DStandardItem(); + item->setData(dev->id(), DevIdRole); + item->setText(dev->alias()); + item->setActionList(Qt::LeftEdge, actLst); + QFont f = item->font(); + f.setPixelSize(12); + item->setFont(f); + return item; +} + +DStandardItem *BluetoothTransDialog::findItemByIdRole(const BluetoothDevice *dev) +{ + return dev ? findItemByIdRole(dev->id()) : nullptr; +} + +DStandardItem *BluetoothTransDialog::findItemByIdRole(const QString &devId) +{ + const QString &id = devId; + for (int i = 0; i < m_devModel->rowCount(); i++) { + if (id == m_devModel->data(m_devModel->index(i, 0), DevIdRole).toString()) + return dynamic_cast(m_devModel->item(i)); + } + return nullptr; +} + +void BluetoothTransDialog::updateDeviceList() +{ + if (!m_devicesList) + return; + + QMap adapters = bluetoothManager->model()->adapters(); + QMapIterator iter(adapters); + while (iter.hasNext()) { + iter.next(); + const BluetoothAdapter *adapter = iter.value(); + QMap devices = adapter->devices(); + QMapIterator iterOfDev(devices); + while (iterOfDev.hasNext()) { + iterOfDev.next(); + const BluetoothDevice *dev = iterOfDev.value(); + connectDevice(dev); + addDevice(dev); + } + } +} + +void BluetoothTransDialog::addDevice(const BluetoothDevice *dev) +{ + if (!dev) + return; + // 根据设备的 uuid 或 icon 要对可接收文件的设备进行过滤 + static const QStringList deviceCanRecvFile {"computer", "phone"}; + if (!deviceCanRecvFile.contains(dev->icon())) // 暂时根据 icon 进行判定,以后或可根据 uuid 是否包含 obex 传输服务来判定设备能否接收文件 + return; + + DStandardItem *item = getStyledItem(dev); + if (!item) + return; + + m_devModel->appendRow(item); + if (m_stack->currentIndex() == NoneDevicePage) // 仅当页面位于无设备页面时执行跳转 + m_stack->setCurrentIndex(SelectDevicePage); +} + +void BluetoothTransDialog::removeDevice(const BluetoothDevice *dev) +{ + if (!dev) + return; + removeDevice(dev->id()); +} + +void BluetoothTransDialog::removeDevice(const QString &id) +{ + for (int i = 0; i < m_devModel->rowCount(); i++) { + if (m_devModel->data(m_devModel->index(i, 0), DevIdRole).toString() == id) { + m_devModel->removeRow(i); + if (m_devModel->rowCount() == 0 && m_stack->currentIndex() == SelectDevicePage) + m_stack->setCurrentIndex(NoneDevicePage); + return; + } + } +} + +void BluetoothTransDialog::sendFiles() +{ + foreach (auto path, m_finishedUrls) { // 针对失败重试:之前已经发送成功的文件不再次发送 + m_urls.removeAll(path); + } + m_finishedUrls.clear(); + + if (m_urls.count() == 0 || m_selectedDeviceId.isEmpty()) + return; + + // 无法发送文件尺寸大于 2GB 以及尺寸为 0 的文件,若包含则中止发送行为,文件不存在也一样 + foreach (auto u, m_urls) { + DUrl url = DUrl::fromLocalFile(u); + if (!url.isValid()) + continue; + DAbstractFileInfoPointer info = fileService->createFileInfo(nullptr, url); + if (info && !info->exists()) { + dialogManager->showMessageDialog(DialogManager::msgErr, TXT_FILE_NOEXIST, "", TXT_OKAY); + close(); // 与产品经理沟通后,为避免文件不存在时的retry可能引起的一系列问题,当用户点击retry的确认时,直接终止流程 + return; + } + if (info && info->size() > FILE_TRANSFER_LIMITS) { + dialogManager->showMessageDialog(DialogManager::msgInfo, TXT_FILE_OVERSIZ, "", TXT_OKAY); + return; + } else if (info && info->size() == 0) { + dialogManager->showMessageDialog(DialogManager::msgInfo, TXT_FILE_ZEROSIZ, "", TXT_OKAY); + return; + } + } + + m_subTitleForWaitPage->setText(TXT_SENDING_FILE.arg(m_selectedDevice)); + m_subTitleOfTransPage->setText(TXT_SENDING_FILE.arg(m_selectedDevice)); + m_subTitleOfFailedPage->setText(TXT_SENDING_FAIL.arg(m_selectedDevice)); + m_subTitleOfSuccessPage->setText(TXT_SENDING_SUCC.arg(m_selectedDevice)); + + m_progressUpdateShouldBeIgnore = true; + m_firstTransSize = 0; + m_progressBar->setValue(0); // retry 时需要重置进度 + + bluetoothManager->sendFiles(m_selectedDeviceId, m_urls, m_token); + + m_stack->setCurrentIndex(WaitForRecvPage); + m_spinner->start(); +} + +void BluetoothTransDialog::closeEvent(QCloseEvent *event) +{ + DDialog::closeEvent(event); + + if ((m_stack->currentIndex() == WaitForRecvPage + || m_stack->currentIndex() == TransferPage + || m_stack->currentIndex() == FailedPage) + && !m_currSessionPath.isEmpty()) { + bluetoothManager->cancelTransfer(m_currSessionPath); + } +} + +void BluetoothTransDialog::showBluetoothSetting() +{ + bluetoothManager->showBluetoothSettings(); +} + +void BluetoothTransDialog::onBtnClicked(const int &nIdx) +{ + static qint64 lastTriggerTime = 0; + if (QDateTime::currentMSecsSinceEpoch() - lastTriggerTime <= 200) // 间隔 200ms 触发一次操作,限制操作频率 + return; + + Page currpage = static_cast(m_stack->currentIndex()); + switch (currpage) { + case SelectDevicePage: + if (m_selectedDevice.isEmpty() && nIdx == 1) + return; + if (nIdx != 1) { // 点击取消 + close(); + return; + } + + if (canSendFiles()) { + sendFiles(); + } else { + dialogManager->showMessageDialog(DialogManager::messageType::msgInfo, DialogManager::tr("Sending files now, please try later")); + } + + break; + case FailedPage: + if (nIdx == 1) + sendFiles(); + else + close(); + break; + case WaitForRecvPage: + case NoneDevicePage: + case TransferPage: + case SuccessPage: + close(); + break; + } + lastTriggerTime = QDateTime::currentMSecsSinceEpoch(); +} + +void BluetoothTransDialog::onPageChagned(const int &nIdx) +{ + if (!m_titleOfDialog || !m_spinner) + return; + m_spinner->stop(); + setIcon(QIcon::fromTheme(ICON_CONNECT)); + m_titleOfDialog->setText(TITLE_BT_TRANS_FILE); + clearButtons(); + + Page currpage = static_cast(nIdx); + switch (currpage) { + case SelectDevicePage: + addButton(TXT_CANC); + addButton(TXT_NEXT, true, ButtonType::ButtonRecommend); + break; + case NoneDevicePage: + case WaitForRecvPage: + case TransferPage: + addButton(TXT_CANC); + break; + case FailedPage: + m_titleOfDialog->setText(TITLE_BT_TRANS_FAIL); + setIcon(QIcon::fromTheme(ICON_DISCONN)); + addButton(TXT_CANC); + addButton(TXT_RTRY, true, ButtonType::ButtonRecommend); + break; + case SuccessPage: + m_titleOfDialog->setText(TITLE_BT_TRANS_SUCC); + addButton(TXT_DONE); + break; + } +} + +void BluetoothTransDialog::connectAdapter(const BluetoothAdapter *adapter) +{ + if (!adapter || m_connectedAdapter.contains(adapter->id())) + return; + m_connectedAdapter.append(adapter->id()); + + connect(adapter, &BluetoothAdapter::deviceAdded, this, [this](const BluetoothDevice * dev) { + addDevice(dev); + connectDevice(dev); + }); + + connect(adapter, &BluetoothAdapter::deviceRemoved, this, [this](const QString & deviceId) { + removeDevice(deviceId); + }); +} + +void BluetoothTransDialog::connectDevice(const BluetoothDevice *dev) +{ + if (!dev) + return; + connect(dev, &BluetoothDevice::stateChanged, this, [this](const BluetoothDevice::State & state) { + BluetoothDevice *device = dynamic_cast(sender()); + if (!device) + return; + + switch (state) { + case BluetoothDevice::StateConnected: + addDevice(device); + break; + default: + removeDevice(device); + break; + } + }); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothtransdialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothtransdialog.h new file mode 100644 index 0000000..6e18cdb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/bluetooth/bluetoothtransdialog.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef BluetoothTransDialog_H +#define BluetoothTransDialog_H + +#include +#include +#include + +DWIDGET_BEGIN_NAMESPACE +class DLabel; +class DCommandLinkButton; +class DListView; +class DProgressBar; +class DStandardItem; +class DSpinner; +DWIDGET_END_NAMESPACE +DWIDGET_USE_NAMESPACE + +QT_BEGIN_NAMESPACE +class QStandardItemModel; +class QStackedWidget; +QT_END_NAMESPACE + +class BluetoothDevice; +class BluetoothAdapter; +class BluetoothTransDialog : public DDialog +{ + Q_OBJECT +public: + enum TransferMode { + Default = 0, // 先选择设备再发送 + DirectlySend // 直接发送到指定设备 + }; + + BluetoothTransDialog(const QStringList &urls, TransferMode mode = Default, QString targetDevId = QString(), QWidget *parent = nullptr); + + static bool canSendFiles(); + +protected: + void closeEvent(QCloseEvent *event) override; + +private: + void initUI(); + void initConn(); + QWidget *initDeviceSelectorPage(); + QWidget *initNonDevicePage(); + QWidget *initWaitForRecvPage(); + QWidget *initTranferingPage(); + QWidget *initFailedPage(); + QWidget *initSuccessPage(); + + /** + * @brief getStyledItem 根据蓝牙设备对象获取一个处理后的列表 item + * @param dev 蓝牙设备对象 + * @return 返回一个列表 item 用于添加到列表中 + */ + DStandardItem *getStyledItem(const BluetoothDevice *dev); + + /** + * @brief findItemByIdRole 从列表中获取对应蓝牙设备的 item + * @param dev + * @return + */ + DStandardItem *findItemByIdRole(const BluetoothDevice *dev); + DStandardItem *findItemByIdRole(const QString &devId); + + /** + * @brief updateDeviceList 初始化加载设备列表 + */ + void updateDeviceList(); + + /** + * @brief addDevice 添加设备到设备列表 + * @param dev 蓝牙设备对象 + */ + void addDevice(const BluetoothDevice *dev); + + /** + * @brief removeDevice 从列表中移除相应设备 + * @param dev 蓝牙设备对象 + */ + void removeDevice(const BluetoothDevice *dev); + void removeDevice(const QString &id); + + void sendFiles(); + + /** + * @brief sendFilesToDevice 直接发送文件到指定设备 + * @param devId 接收方id + */ + void sendFilesToDevice(const QString &devId); + + /** + * @brief changeLabelTheme 跟随主题变换对话框部分字体文案的颜色 + * @param obj 需要控制颜色的QLabel对象 + * @param isTitle 是否是主标题,主标题的透明度与其他文案有差别 + */ + void changeLabelTheme(QLabel *obj, bool isTitle = false); + + /** + * @brief setObjTextStyle 设置各控件的字体属性 + * @param obj 目标控件 + * @param size 字体尺寸 + * @param bold 字体加粗 + */ + void setObjTextStyle(QWidget *obj, int size, bool bold); + + /** + * @brief humanizedStrOfObexErrMsg 处理 obex 的错误信息 + * @param msg obex 返回的错误信息 + * @return 可读性处理后的字符串 + */ + QString humanizedStrOfObexErrMsg(const QString &msg); + +private Q_SLOTS: + void showBluetoothSetting(); + + /** + * @brief onBtnClicked 对话框按钮槽函数,根据页面及触发按钮的索引执行页面间的跳转 + * @param nIdx 按钮的索引 + */ + void onBtnClicked(const int &nIdx); + + /** + * @brief onPageChagned 处理页面跳转后界面按钮的更新等操作 + * @param nIdx 页面的索引,索引值与枚举 Page 一致 + */ + void onPageChagned(const int &nIdx); + + /** + * @brief connectAdapter 连接每个 adapter 的信号 + */ + void connectAdapter(const BluetoothAdapter *); + + /** + * @brief connectDevice 连接每个设备的信号 + */ + void connectDevice(const BluetoothDevice *); + +private: + enum Page { + SelectDevicePage, + NoneDevicePage, + WaitForRecvPage, + TransferPage, + FailedPage, + SuccessPage, + }; + + enum DeviceRoles { + DevNameRole = Qt::UserRole + 100, + DevIdRole, + }; + + DLabel *m_titleOfDialog = nullptr; + QStackedWidget *m_stack = nullptr; // 多页面容器 + DListView *m_devicesList = nullptr; // 设备列表 + QStandardItemModel *m_devModel = nullptr; // 列表的 model + DLabel *m_subTitleForWaitPage = nullptr; + DLabel *m_subTitleOfTransPage = nullptr; + DLabel *m_subTitleOfFailedPage = nullptr; + DLabel *m_subTitleOfSuccessPage = nullptr; + DLabel *m_sendingStatus = nullptr; + DProgressBar *m_progressBar = nullptr; + DSpinner *m_spinner = nullptr; + +private: + QStringList m_urls; // 待发送文件 + QStringList m_finishedUrls; + QString m_selectedDevice; + QString m_selectedDeviceId; + QString m_currSessionPath; // 当前发送进程的 obex 会话路径,用于取消当前传输会话 + bool m_progressUpdateShouldBeIgnore = true; // 忽略每次调用 sendFile 发送过来的第一次更新进度的信号,此时接收方还未同意接收文件,信号被触发可能是因为创建链路的时候携带有部分请求信息导致 transferred 数据的更新 + qulonglong m_firstTransSize = 0; + + QStringList m_connectedAdapter; + + QString m_token; // 用于标识当前对话框ID +}; + +#endif // BluetoothTransDialog_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure.qrc new file mode 100644 index 0000000..67b254f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure.qrc @@ -0,0 +1,19 @@ + + + configure/global-setting-template.js + configure/global-setting-template-pro.js + configure/global-setting-template-fedora.js + + + configure/dde-file-manager.default.json + configure/dde-file-manager.obtusely.default.json + + + configure/dde-file-manager.default.json + configure/dde-file-manager.obtusely.default.json + + + configure/dde-file-manager.default.json + configure/dde-file-manager.obtusely.default.json + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/dde-file-manager.default.json b/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/dde-file-manager.default.json new file mode 100644 index 0000000..7dd4b0d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/dde-file-manager.default.json @@ -0,0 +1,46 @@ +{ + "ApplicationAttribute": { + "AllwayOpenOnNewWindow": false, + "IconSizeLevel": 1, + "ViewMode": 1, + "ViewSizeAdjustable": true, + "ViewComppactMode": false, + "ViewAutoCompace": false, + "OpenFileMode": 1, + "UrlOfNewWindow": "computer:///", + "UrlOfNewTab": "", + "ThemeName": "light" + }, + "GenericAttribute": { + "IndexInternal": true, + "IndexExternal": false, + "PreviewCompressFile": false, + "PreviewTextFile": true, + "PreviewDocumentFile": true, + "PreviewImage": true, + "PreviewVideo": true, + "AutoMount": true, + "AutoMountAndOpen": false, + "OverrideFileChooserDialog": true, + "ShowedHiddenOnSearch": true, + "ShowedHiddenFiles": false, + "ShowRecentFileEntry": true, + "ShowedFileSuffixOnRename": true, + "DisableNonRemovableDeviceUnmount": false, + "HiddenSystemPartition": false, + "AlwaysShowOfflineRemoteConnections": true + }, + "AnythingMonitorFilterPath": { + "WhiteList":[ + "/media", + "/home" + ], + "BlackList": [ + "~/.local/share/Trash" + ] + }, + "QuickSearchFilter": { + "__annotation":"///You can fill it with regex(grep grammar)", + "BlackList":[] + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/dde-file-manager.obtusely.default.json b/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/dde-file-manager.obtusely.default.json new file mode 100644 index 0000000..9b52a29 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/dde-file-manager.obtusely.default.json @@ -0,0 +1,33 @@ +{ + "DBusFileDialog": { + "disable": { + "gtk2": ["xarchiver", "gpick", "libreoffice", "handbrake", "ghb"], + "gtk3": ["libreoffice", "handbrake", "ghb"] + } + }, + "FileViewState": { + "standard://downloads": { + "sortOrder": 1, + "sortRole": 262, + "viewMode": 2 + }, + "recent:///": { + "sortOrder": 0, + "sortRole": 263, + "viewMode": 2 + } + }, + "WindowManager": { + "WindowState": { + "width": 1100, + "height": 700 + }, + "ViewColumnState": { + "265": 300 + } + }, + "FileName": { + "non-allowableCharacters": "(^\\s+|[/\\\\:*\"'?<>\\[\\]|\r\n\t])", + "non-allowableEmptyCharactersOfEnd": true + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/global-setting-template-fedora.js b/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/global-setting-template-fedora.js new file mode 100644 index 0000000..dba43eb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/global-setting-template-fedora.js @@ -0,0 +1,310 @@ +{ + "groups": [ + { + "key": "base", + "name": qsTranslate("GenerateSettingTranslate", "Basic"), + "groups": [ + { + "key": "open_action", + "name": qsTranslate("GenerateSettingTranslate", "Open behavior"), + "options": [ + { + "key": "allways_open_on_new_window", + "type": "checkbox", + "text": qsTranslate("GenerateSettingTranslate", "Always open folder in new window"), + "default": false + }, + { + "key": "open_file_action", + "name": qsTranslate("GenerateSettingTranslate", "Open file:"), + "type": "combobox", + "items": [ + qsTranslate("GenerateSettingTranslate", "Click"), + qsTranslate("GenerateSettingTranslate", "Double click") + ], + "default": 1 + } + ] + }, + { + "key": "new_tab_windows", + "name": qsTranslate("GenerateSettingTranslate", "New window and tab"), + "options": [ + { + "key": "default_window_path", + "name": qsTranslate("GenerateSettingTranslate", "Open from default window:"), + "type": "combobox", + "items": { + "values": [ + qsTranslate("GenerateSettingTranslate", "Computer"), + qsTranslate("GenerateSettingTranslate", "Home"), + qsTranslate("GenerateSettingTranslate", "Desktop"), + qsTranslate("GenerateSettingTranslate", "Videos"), + qsTranslate("GenerateSettingTranslate", "Music"), + qsTranslate("GenerateSettingTranslate", "Pictures"), + qsTranslate("GenerateSettingTranslate", "Documents"), + qsTranslate("GenerateSettingTranslate", "Downloads") + ], + "keys": [ + "computer:///", + "standard://home", + "standard://desktop", + "standard://videos", + "standard://music", + "standard://pictures", + "standard://documents", + "standard://downloads" + ] + }, + "default": "computer:///" + }, + { + "key": "new_tab_path", + "name": qsTranslate("GenerateSettingTranslate", "Open in new tab:"), + "type": "combobox", + "items": { + "values": [ + qsTranslate("GenerateSettingTranslate", "Current Directory"), + qsTranslate("GenerateSettingTranslate", "Computer"), + qsTranslate("GenerateSettingTranslate", "Home"), + qsTranslate("GenerateSettingTranslate", "Desktop"), + qsTranslate("GenerateSettingTranslate", "Videos"), + qsTranslate("GenerateSettingTranslate", "Music"), + qsTranslate("GenerateSettingTranslate", "Pictures"), + qsTranslate("GenerateSettingTranslate", "Documents"), + qsTranslate("GenerateSettingTranslate", "Downloads") + ], + "keys": [ + "", + "computer:///", + "standard://home", + "standard://desktop", + "standard://videos", + "standard://music", + "standard://pictures", + "standard://documents", + "standard://downloads" + ] + }, + "default": "" + } + ] + }, + { + "key": "default_view", + "name": qsTranslate("GenerateSettingTranslate", "View"), + "options": [ + { + "key": "icon_size", + "name": qsTranslate("GenerateSettingTranslate", "Default size:"), + "type": "combobox", + "items": [ + qsTranslate("GenerateSettingTranslate", "Extra small"), + qsTranslate("GenerateSettingTranslate", "Small"), + qsTranslate("GenerateSettingTranslate", "Medium"), + qsTranslate("GenerateSettingTranslate", "Large"), + qsTranslate("GenerateSettingTranslate", "Extra large") + ], + "default": 1 + }, + { + "key": "view_mode", + "name": qsTranslate("GenerateSettingTranslate", "Default view:"), + "type": "combobox", + "items": { + "values": [ + qsTranslate("GenerateSettingTranslate", "Icon"), + qsTranslate("GenerateSettingTranslate", "List") + ], + "keys": [ + 1, 2 + ] + }, + "default": 1 + } + ] + }, + { + "key": "hidden_files", + "name": qsTranslate("GenerateSettingTranslate", "Hidden files"), + "options": [ + { + "key": "show_hidden", + "text": qsTranslate("GenerateSettingTranslate", "Show hidden files"), + "type": "checkbox", + "default": false + }, + { + "key": "hide_suffix", + "text": qsTranslate("GenerateSettingTranslate", "Hide file extension when rename"), + "type": "checkbox", + "default": true + }, + { + "key": "show_recent", + "text": qsTranslate("GenerateSettingTranslate", "Display recent file entry in left panel"), + "type": "checkbox", + "default": true + } + ] + } + + ] + }, + { + "key": "advance", + "name": qsTranslate("GenerateSettingTranslate", "Advanced"), + "groups": [ + { + "key": "index", + "name": qsTranslate("GenerateSettingTranslate", "Index"), + "options": [ + { + "key": "index_internal", + "text": qsTranslate("GenerateSettingTranslate", "Auto index internal disk"), + "type": "checkbox", + "default": true + }, + { + "key": "index_external", + "text": qsTranslate("GenerateSettingTranslate", "Index external storage device after connected to computer"), + "type": "checkbox", + "default": false + }, + { + "key": "index_search", + "text": qsTranslate("GenerateSettingTranslate", "Full-Text search"), + "type": "checkbox", + "default": false + } + ] + }, + { + "key": "search", + "name": "", + "options": [ + { + "key": "show_hidden", + "text": qsTranslate("GenerateSettingTranslate", "Show hidden files in search results"), + "type": "checkbox", + "default": false, + "hide": true + } + ] + }, + { + "key": "preview", + "name": qsTranslate("GenerateSettingTranslate", "Preview"), + "options": [ + { + "key": "compress_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Compress file preview"), + "type": "checkbox", + "default": false, + "hide": true + }, + { + "key": "text_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Text preview"), + "type": "checkbox", + "default": true + }, + { + "key": "document_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Document preview"), + "type": "checkbox", + "default": true + }, + { + "key": "image_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Image preview"), + "type": "checkbox", + "default": true + }, + { + "key": "video_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Video preview"), + "type": "checkbox", + "default": false, + "hide": true + } + ] + }, + { + "key": "mount", + "name": qsTranslate("GenerateSettingTranslate", "Mount"), + "options": [ + { + "key": "auto_mount", + "text": qsTranslate("GenerateSettingTranslate", "Auto mount"), + "type": "mountCheckBox", + "default": true + }, + { + "key": "auto_mount_and_open", + "text": qsTranslate("GenerateSettingTranslate", "Open after auto mount"), + "type": "openCheckBox", + "default": false + }, + { + "key": "mtp_show_bottom_info", + "text": qsTranslate("GenerateSettingTranslate", "Show item counts and sizes in the path of mounted MTP devices"), + "type": "checkbox", + "default": false + }, + { + "key": "always_show_offline_remote_connection", + "text": qsTranslate("GenerateSettingTranslate", "Keep showing the mounted Samba shares"), + "type": "checkbox", + "default": true + } + ] + }, + { + "key": "dialog", + "name": qsTranslate("GenerateSettingTranslate", "Dialog"), + "options": [ + { + "key": "default_chooser_dialog", + "text": qsTranslate("GenerateSettingTranslate", "Use the file chooser dialog of File Manager"), + "type": "checkbox", + "default": true + }, + { + "key": "delete_confirmation_dialog", + "text": qsTranslate("GenerateSettingTranslate", "Ask for my confirmation when deleting files"), + "type": "checkbox", + "default": false + } + ] + }, + { + "key": "other", + "name": qsTranslate("GenerateSettingTranslate", "Other"), + "options": [ + { + "key": "hide_system_partition", + "text": qsTranslate("GenerateSettingTranslate", "Hide system disk"), + "type": "checkbox", + "default": false + }, + { + "key": "show_crumbbar_clickable_area", + "text": "Show crumb bar clickable area", + "type": "checkbox", + "default": false, + "hide": true + }, + { + "key": "show_filesystemtag_on_diskicon", + "text": qsTranslate("GenerateSettingTranslate", "Show file system on disk icon"), + "type": "checkbox", + "default": false + } + ] + } + ] + } + + ] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/global-setting-template-pro.js b/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/global-setting-template-pro.js new file mode 100644 index 0000000..9a27dff --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/global-setting-template-pro.js @@ -0,0 +1,310 @@ +{ + "groups": [ + { + "key": "base", + "name": qsTranslate("GenerateSettingTranslate", "Basic"), + "groups": [ + { + "key": "open_action", + "name": qsTranslate("GenerateSettingTranslate", "Open behavior"), + "options": [ + { + "key": "allways_open_on_new_window", + "type": "checkbox", + "text": qsTranslate("GenerateSettingTranslate", "Always open folder in new window"), + "default": false + }, + { + "key": "open_file_action", + "name": qsTranslate("GenerateSettingTranslate", "Open file:"), + "type": "combobox", + "items": [ + qsTranslate("GenerateSettingTranslate", "Click"), + qsTranslate("GenerateSettingTranslate", "Double click") + ], + "default": 1 + } + ] + }, + { + "key": "new_tab_windows", + "name": qsTranslate("GenerateSettingTranslate", "New window and tab"), + "options": [ + { + "key": "default_window_path", + "name": qsTranslate("GenerateSettingTranslate", "Open from default window:"), + "type": "combobox", + "items": { + "values": [ + qsTranslate("GenerateSettingTranslate", "Computer"), + qsTranslate("GenerateSettingTranslate", "Home"), + qsTranslate("GenerateSettingTranslate", "Desktop"), + qsTranslate("GenerateSettingTranslate", "Videos"), + qsTranslate("GenerateSettingTranslate", "Music"), + qsTranslate("GenerateSettingTranslate", "Pictures"), + qsTranslate("GenerateSettingTranslate", "Documents"), + qsTranslate("GenerateSettingTranslate", "Downloads") + ], + "keys": [ + "computer:///", + "standard://home", + "standard://desktop", + "standard://videos", + "standard://music", + "standard://pictures", + "standard://documents", + "standard://downloads" + ] + }, + "default": "computer:///" + }, + { + "key": "new_tab_path", + "name": qsTranslate("GenerateSettingTranslate", "Open in new tab:"), + "type": "combobox", + "items": { + "values": [ + qsTranslate("GenerateSettingTranslate", "Current Directory"), + qsTranslate("GenerateSettingTranslate", "Computer"), + qsTranslate("GenerateSettingTranslate", "Home"), + qsTranslate("GenerateSettingTranslate", "Desktop"), + qsTranslate("GenerateSettingTranslate", "Videos"), + qsTranslate("GenerateSettingTranslate", "Music"), + qsTranslate("GenerateSettingTranslate", "Pictures"), + qsTranslate("GenerateSettingTranslate", "Documents"), + qsTranslate("GenerateSettingTranslate", "Downloads") + ], + "keys": [ + "", + "computer:///", + "standard://home", + "standard://desktop", + "standard://videos", + "standard://music", + "standard://pictures", + "standard://documents", + "standard://downloads" + ] + }, + "default": "" + } + ] + }, + { + "key": "default_view", + "name": qsTranslate("GenerateSettingTranslate", "View"), + "options": [ + { + "key": "icon_size", + "name": qsTranslate("GenerateSettingTranslate", "Default size:"), + "type": "combobox", + "items": [ + qsTranslate("GenerateSettingTranslate", "Extra small"), + qsTranslate("GenerateSettingTranslate", "Small"), + qsTranslate("GenerateSettingTranslate", "Medium"), + qsTranslate("GenerateSettingTranslate", "Large"), + qsTranslate("GenerateSettingTranslate", "Extra large") + ], + "default": 1 + }, + { + "key": "view_mode", + "name": qsTranslate("GenerateSettingTranslate", "Default view:"), + "type": "combobox", + "items": { + "values": [ + qsTranslate("GenerateSettingTranslate", "Icon"), + qsTranslate("GenerateSettingTranslate", "List") + ], + "keys": [ + 1, 2 + ] + }, + "default": 1 + } + ] + }, + { + "key": "hidden_files", + "name": qsTranslate("GenerateSettingTranslate", "Hidden files"), + "options": [ + { + "key": "show_hidden", + "text": qsTranslate("GenerateSettingTranslate", "Show hidden files"), + "type": "checkbox", + "default": false + }, + { + "key": "hide_suffix", + "text": qsTranslate("GenerateSettingTranslate", "Hide file extension when rename"), + "type": "checkbox", + "default": true + }, + { + "key": "show_recent", + "text": qsTranslate("GenerateSettingTranslate", "Display recent file entry in left panel"), + "type": "checkbox", + "default": true + } + + ] + } + + ] + }, + { + "key": "advance", + "name": qsTranslate("GenerateSettingTranslate", "Advanced"), + "groups": [ + { + "key": "index", + "name": qsTranslate("GenerateSettingTranslate", "Index"), + "options": [ + { + "key": "index_internal", + "text": qsTranslate("GenerateSettingTranslate", "Auto index internal disk"), + "type": "checkbox", + "default": true + }, + { + "key": "index_external", + "text": qsTranslate("GenerateSettingTranslate", "Index external storage device after connected to computer"), + "type": "checkbox", + "default": false + }, + { + "key": "index_search", + "text": qsTranslate("GenerateSettingTranslate", "Full-Text search"), + "type": "checkbox", + "default": false + } + ] + }, + { + "key": "search", + "name": "", + "options": [ + { + "key": "show_hidden", + "text": qsTranslate("GenerateSettingTranslate", "Show hidden files in search results"), + "type": "checkbox", + "default": false, + "hide": true + } + ] + }, + { + "key": "preview", + "name": qsTranslate("GenerateSettingTranslate", "Preview"), + "options": [ + { + "key": "compress_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Compress file preview"), + "type": "checkbox", + "default": false, + "hide": true + }, + { + "key": "text_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Text preview"), + "type": "checkbox", + "default": true + }, + { + "key": "document_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Document preview"), + "type": "checkbox", + "default": true + }, + { + "key": "image_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Image preview"), + "type": "checkbox", + "default": true + }, + { + "key": "video_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Video preview"), + "type": "checkbox", + "default": true + } + ] + }, + { + "key": "mount", + "name": qsTranslate("GenerateSettingTranslate", "Mount"), + "options": [ + { + "key": "auto_mount", + "text": qsTranslate("GenerateSettingTranslate", "Auto mount"), + "type": "mountCheckBox", + "default": true + }, + { + "key": "auto_mount_and_open", + "text": qsTranslate("GenerateSettingTranslate", "Open after auto mount"), + "type": "openCheckBox", + "default": false + }, + { + "key": "mtp_show_bottom_info", + "text": qsTranslate("GenerateSettingTranslate", "Show item counts and sizes in the path of mounted MTP devices"), + "type": "checkbox", + "default": false + }, + { + "key": "always_show_offline_remote_connection", + "text": qsTranslate("GenerateSettingTranslate", "Keep showing the mounted Samba shares"), + "type": "checkbox", + "default": true + } + ] + }, + { + "key": "dialog", + "name": qsTranslate("GenerateSettingTranslate", "Dialog"), + "options": [ + { + "key": "default_chooser_dialog", + "text": qsTranslate("GenerateSettingTranslate", "Use the file chooser dialog of File Manager"), + "type": "checkbox", + "default": true + }, + { + "key": "delete_confirmation_dialog", + "text": qsTranslate("GenerateSettingTranslate", "Ask for my confirmation when deleting files"), + "type": "checkbox", + "default": false + } + ] + }, + { + "key": "other", + "name": qsTranslate("GenerateSettingTranslate", "Other"), + "options": [ + { + "key": "hide_system_partition", + "text": qsTranslate("GenerateSettingTranslate", "Hide system disk"), + "type": "checkbox", + "default": false + }, + { + "key": "show_crumbbar_clickable_area", + "text": "Show crumb bar clickable area", + "type": "checkbox", + "default": false, + "hide": true + }, + { + "key": "show_filesystemtag_on_diskicon", + "text": qsTranslate("GenerateSettingTranslate", "Show file system on disk icon"), + "type": "checkbox", + "default": false + } + ] + } + ] + } + + ] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/global-setting-template.js b/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/global-setting-template.js new file mode 100644 index 0000000..e3eff40 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/configure/global-setting-template.js @@ -0,0 +1,309 @@ +{ + "groups": [ + { + "key": "base", + "name": qsTranslate("GenerateSettingTranslate", "Basic"), + "groups": [ + { + "key": "open_action", + "name": qsTranslate("GenerateSettingTranslate", "Open behavior"), + "options": [ + { + "key": "allways_open_on_new_window", + "type": "checkbox", + "text": qsTranslate("GenerateSettingTranslate", "Always open folder in new window"), + "default": false + }, + { + "key": "open_file_action", + "name": qsTranslate("GenerateSettingTranslate", "Open file:"), + "type": "combobox", + "items": [ + qsTranslate("GenerateSettingTranslate", "Click"), + qsTranslate("GenerateSettingTranslate", "Double click") + ], + "default": 1 + } + ] + }, + { + "key": "new_tab_windows", + "name": qsTranslate("GenerateSettingTranslate", "New window and tab"), + "options": [ + { + "key": "default_window_path", + "name": qsTranslate("GenerateSettingTranslate", "Open from default window:"), + "type": "combobox", + "items": { + "values": [ + qsTranslate("GenerateSettingTranslate", "Computer"), + qsTranslate("GenerateSettingTranslate", "Home"), + qsTranslate("GenerateSettingTranslate", "Desktop"), + qsTranslate("GenerateSettingTranslate", "Videos"), + qsTranslate("GenerateSettingTranslate", "Music"), + qsTranslate("GenerateSettingTranslate", "Pictures"), + qsTranslate("GenerateSettingTranslate", "Documents"), + qsTranslate("GenerateSettingTranslate", "Downloads") + ], + "keys": [ + "computer:///", + "standard://home", + "standard://desktop", + "standard://videos", + "standard://music", + "standard://pictures", + "standard://documents", + "standard://downloads" + ] + }, + "default": "computer:///" + }, + { + "key": "new_tab_path", + "name": qsTranslate("GenerateSettingTranslate", "Open in new tab:"), + "type": "combobox", + "items": { + "values": [ + qsTranslate("GenerateSettingTranslate", "Current Directory"), + qsTranslate("GenerateSettingTranslate", "Computer"), + qsTranslate("GenerateSettingTranslate", "Home"), + qsTranslate("GenerateSettingTranslate", "Desktop"), + qsTranslate("GenerateSettingTranslate", "Videos"), + qsTranslate("GenerateSettingTranslate", "Music"), + qsTranslate("GenerateSettingTranslate", "Pictures"), + qsTranslate("GenerateSettingTranslate", "Documents"), + qsTranslate("GenerateSettingTranslate", "Downloads") + ], + "keys": [ + "", + "computer:///", + "standard://home", + "standard://desktop", + "standard://videos", + "standard://music", + "standard://pictures", + "standard://documents", + "standard://downloads" + ] + }, + "default": "" + } + ] + }, + { + "key": "default_view", + "name": qsTranslate("GenerateSettingTranslate", "View"), + "options": [ + { + "key": "icon_size", + "name": qsTranslate("GenerateSettingTranslate", "Default size:"), + "type": "combobox", + "items": [ + qsTranslate("GenerateSettingTranslate", "Extra small"), + qsTranslate("GenerateSettingTranslate", "Small"), + qsTranslate("GenerateSettingTranslate", "Medium"), + qsTranslate("GenerateSettingTranslate", "Large"), + qsTranslate("GenerateSettingTranslate", "Extra large") + ], + "default": 1 + }, + { + "key": "view_mode", + "name": qsTranslate("GenerateSettingTranslate", "Default view:"), + "type": "combobox", + "items": { + "values": [ + qsTranslate("GenerateSettingTranslate", "Icon"), + qsTranslate("GenerateSettingTranslate", "List") + ], + "keys": [ + 1, 2 + ] + }, + "default": 1 + } + ] + }, + { + "key": "hidden_files", + "name": qsTranslate("GenerateSettingTranslate", "Hidden files"), + "options": [ + { + "key": "show_hidden", + "text": qsTranslate("GenerateSettingTranslate", "Show hidden files"), + "type": "checkbox", + "default": false + }, + { + "key": "hide_suffix", + "text": qsTranslate("GenerateSettingTranslate", "Hide file extension when rename"), + "type": "checkbox", + "default": true + }, + { + "key": "show_recent", + "text": qsTranslate("GenerateSettingTranslate", "Display recent file entry in left panel"), + "type": "checkbox", + "default": true + } + + ] + } + + ] + }, + { + "key": "advance", + "name": qsTranslate("GenerateSettingTranslate", "Advanced"), + "groups": [ + { + "key": "index", + "name": qsTranslate("GenerateSettingTranslate", "Index"), + "options": [ + { + "key": "index_internal", + "text": qsTranslate("GenerateSettingTranslate", "Auto index internal disk"), + "type": "checkbox", + "default": true + }, + { + "key": "index_external", + "text": qsTranslate("GenerateSettingTranslate", "Index external storage device after connected to computer"), + "type": "checkbox", + "default": false + }, + { + "key": "index_search", + "text": qsTranslate("GenerateSettingTranslate", "Full-Text search"), + "type": "checkbox", + "default": false + } + ] + }, + { + "key": "search", + "name": "", + "options": [ + { + "key": "show_hidden", + "text": qsTranslate("GenerateSettingTranslate", "Show hidden files in search results"), + "type": "checkbox", + "default": false, + "hide": true + } + ] + }, + { + "key": "preview", + "name": qsTranslate("GenerateSettingTranslate", "Preview"), + "options": [ + { + "key": "compress_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Compressed file preview"), + "type": "checkbox", + "default": false + }, + { + "key": "text_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Text preview"), + "type": "checkbox", + "default": true + }, + { + "key": "document_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Document preview"), + "type": "checkbox", + "default": true + }, + { + "key": "image_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Image preview"), + "type": "checkbox", + "default": true + }, + { + "key": "video_file_preview", + "text": qsTranslate("GenerateSettingTranslate", "Video preview"), + "type": "checkbox", + "default": true + } + ] + }, + { + "key": "mount", + "name": qsTranslate("GenerateSettingTranslate", "Mount"), + "options": [ + { + "key": "auto_mount", + "text": qsTranslate("GenerateSettingTranslate", "Auto mount"), + "type": "mountCheckBox", + "default": true + }, + { + "key": "auto_mount_and_open", + "text": qsTranslate("GenerateSettingTranslate", "Open after auto mount"), + "type": "openCheckBox", + "default": false + }, + { + "key": "mtp_show_bottom_info", + "text": qsTranslate("GenerateSettingTranslate", "Show item counts and sizes in the path of mounted MTP devices"), + "type": "checkbox", + "default": false + }, + { + "key": "always_show_offline_remote_connection", + "text": qsTranslate("GenerateSettingTranslate", "Keep showing the mounted Samba shares"), + "type": "checkbox", + "default": true + } + ] + }, + { + "key": "dialog", + "name": qsTranslate("GenerateSettingTranslate", "Dialog"), + "options": [ + { + "key": "default_chooser_dialog", + "text": qsTranslate("GenerateSettingTranslate", "Use the file chooser dialog of File Manager"), + "type": "checkbox", + "default": true + }, + { + "key": "delete_confirmation_dialog", + "text": qsTranslate("GenerateSettingTranslate", "Ask for my confirmation when deleting files"), + "type": "checkbox", + "default": false + } + ] + }, + { + "key": "other", + "name": qsTranslate("GenerateSettingTranslate", "Other"), + "options": [ + { + "key": "hide_system_partition", + "text": qsTranslate("GenerateSettingTranslate", "Hide system disk"), + "type": "checkbox", + "default": false + }, + { + "key": "show_crumbbar_clickable_area", + "text": "Show crumb bar clickable area", + "type": "checkbox", + "default": false, + "hide": true + }, + { + "key": "show_filesystemtag_on_diskicon", + "text": qsTranslate("GenerateSettingTranslate", "Show file system on disk icon"), + "type": "checkbox", + "default": false + } + ] + } + ] + } + + ] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/appcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/appcontroller.cpp new file mode 100644 index 0000000..dd70fc9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/appcontroller.cpp @@ -0,0 +1,1631 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +//fix:修正临时拷贝文件到光盘的路径问题,不是挂载目录,而是临时缓存目录 +#include "dfilemenumanager.h" + +#include "appcontroller.h" +#include "trashjobcontroller.h" +#include "deletejobcontroller.h" +#include "filecontroller.h" +#include "trashmanager.h" +#include "searchcontroller.h" +#include "sharecontroler.h" +#include "avfsfilecontroller.h" +#include "mountcontroller.h" +#include "masteredmediacontroller.h" +#include "vaultcontroller.h" +#include "bookmarkmanager.h" +#include "networkcontroller.h" +#include "mergeddesktopcontroller.h" +#include "dfmrootcontroller.h" +#include "dfmappentrycontroller.h" +#include "deviceinfo/udisklistener.h" +#include "dfileservices.h" +#include "fileoperations/filejob.h" +#include "dfmeventdispatcher.h" +#include "dfmapplication.h" +#include "disomaster.h" +#include "pathmanager.h" + +#include "app/filesignalmanager.h" +#include "dfmevent.h" +#include "app/define.h" + +#include "interfaces/dfmstandardpaths.h" +#include "interfaces/defenderinterface.h" +#include "interfaces/dumountmanager.h" +#include "shutil/fileutils.h" +#include "views/windowmanager.h" +#include "views/dfilemanagerwindow.h" +#include "views/dtagedit.h" +#include "views/dfmopticalmediawidget.h" + +#include "gvfs/networkmanager.h" +#include "gvfs/gvfsmountmanager.h" +#include "gvfs/secretmanager.h" +#include "usershare/usersharemanager.h" +#include "dialogs/dialogmanager.h" +#include "singleton.h" + +#include "tagcontroller.h" +#include "recentcontroller.h" +#include "views/drenamebar.h" +#include "shutil/filebatchprocess.h" +#include "utils.h" + +#include "../deviceinfo/udisklistener.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "tag/tagutil.h" +#include "tag/tagmanager.h" +#include "shutil/shortcut.h" +//#include "views/dbookmarkitem.h" +#include "models/desktopfileinfo.h" +#include "models/dfmrootfileinfo.h" +#include "controllers/tagmanagerdaemoncontroller.h" + +#include "dblockdevice.h" +#include "ddiskdevice.h" +#include "ddiskmanager.h" +#include "dgiovolumemanager.h" +#include "dgiofile.h" +#include "dgiomount.h" + +#ifdef SW_LABEL +#include "sw_label/filemanagerlibrary.h" +#endif + +using namespace Dtk::Widget; + +///###: be used for tag protocol. +template +using iterator = typename QList::iterator; + +template +using citerator = typename QList::const_iterator; + +const char *empty_recent_file = + R"|( + + )|"; + +QPair AppController::selectionAndRenameFile; +QPair AppController::selectionFile; +QPair, quint64> AppController::multiSelectionFilesCache; +std::atomic AppController::multiSelectionFilesCacheCounter{ 0 }; +std::atomic AppController::flagForDDesktopRenameBar{ false }; + + +class AppController_ : public AppController {}; +Q_GLOBAL_STATIC(AppController_, acGlobal) + +AppController *AppController::instance() +{ + return acGlobal; +} + +void AppController::registerUrlHandle() +{ + DFileService::dRegisterUrlHandler(FILE_SCHEME, ""); + // DFileService::dRegisterUrlHandler(TRASH_SCHEME, ""); + //sanitinizer工具检测到DFileService::setFileUrlHandler(TRASH_SCHEME, "", new TrashManager());泄露 + auto tempTrashMgr = new TrashManager(); + tempTrashMgr->setObjectName("trashMgr"); + DFileService::setFileUrlHandler(TRASH_SCHEME, "", tempTrashMgr); + DFileService::dRegisterUrlHandler(SEARCH_SCHEME, ""); + DFileService::dRegisterUrlHandler(NETWORK_SCHEME, ""); + DFileService::dRegisterUrlHandler(SMB_SCHEME, ""); + DFileService::dRegisterUrlHandler(SFTP_SCHEME, ""); + DFileService::dRegisterUrlHandler(FTP_SCHEME, ""); + DFileService::dRegisterUrlHandler(DAV_SCHEME, ""); + DFileService::dRegisterUrlHandler(USERSHARE_SCHEME, ""); + DFileService::dRegisterUrlHandler(AVFS_SCHEME, ""); + DFileService::dRegisterUrlHandler(MOUNT_SCHEME, ""); + DFileService::dRegisterUrlHandler(BURN_SCHEME, ""); + + DFileService::dRegisterUrlHandler(TAG_SCHEME, ""); + DFileService::dRegisterUrlHandler(RECENT_SCHEME, ""); + DFileService::dRegisterUrlHandler(DFMMD_SCHEME, ""); + DFileService::dRegisterUrlHandler(DFMROOT_SCHEME, ""); + DFileService::dRegisterUrlHandler(DFMVAULT_SCHEME, ""); + DFileService::dRegisterUrlHandler(APPENTRY_SCHEME, ""); +} + +void AppController::actionOpen(const QSharedPointer &event, const bool isEnter) +{ + const DUrlList &urls = event->urlList(); + if (urls.isEmpty()) { + return; + } + + if (urls.size() > 1 || DFMApplication::instance()->appAttribute(DFMApplication::AA_AllwayOpenOnNewWindow).toBool()) { + // 选择多文件打开的时候调用函数 openFiles,单文件打开调用 openFile,部分 controller 没有实现 openFiles 函数,因此在这里转换成 file:// 的 url, + // 通过 fileController 来进行打开调用 + DUrlList lstUrls; + for (DUrl u : urls) { + if (u.scheme() == RECENT_SCHEME) { + u = DUrl::fromLocalFile(u.path()); + } else if (u.scheme() == SEARCH_SCHEME) { //搜索结果也存在右键批量打卡不成功的问题,这里做类似处理 + u = u.searchedFileUrl(); + } else if (u.scheme() == BURN_SCHEME) { + DAbstractFileInfoPointer info = fileService->createFileInfo(event->sender(), u); + if (!info) + continue; + if (info->canRedirectionFileUrl()) + u = info->redirectedFileUrl(); + } + lstUrls << u; + } + + //! bug 38585 判断是不是保险箱以及是否是解锁状态,如果是就发送processEventAsync事件OpenInCurrentWindow走解锁流程 + if (VaultController::ins()->state() != VaultController::Unlocked && lstUrls.size() == 1 && lstUrls.first().isVaultFile()) { + DFMEventDispatcher::instance()->processEventAsync(event->sender(), urls, DFMOpenUrlEvent::OpenInCurrentWindow, isEnter); + } else { + DFMEventDispatcher::instance()->processEvent(event->sender(), lstUrls, DFMOpenUrlEvent::ForceOpenNewWindow, isEnter); + } + } else { + //fix bug 30506 ,异步处理网路文件很卡的情况下,快速点击会崩溃,或者卡死,使用fileinfo中的是否是gvfsmount + if (urls.size() > 0 && DFileService::instance()->createFileInfo(nullptr, urls.first())->isGvfsMountFile()/*FileUtils::isGvfsMountFile(urls.first().path())*/) { + DFMEventDispatcher::instance()->processEvent(event->sender(), urls, DFMOpenUrlEvent::OpenInCurrentWindow); + return; + } + DFMEventDispatcher::instance()->processEventAsync(event->sender(), urls, DFMOpenUrlEvent::OpenInCurrentWindow); + } +} + +void AppController::actionOpenDisk(const QSharedPointer &event) +{ + const DUrl &fileUrl = event->url(); + if (!fileUrl.isValid()) { + return; + } + + bool mounted = QStorageInfo(fileUrl.toLocalFile()).isValid(); + + DAbstractFileInfoPointer fi = fileService->createFileInfo(event->sender(), fileUrl); + if (fi && fi->scheme() == DFMROOT_SCHEME) { + mounted |= (!fi->redirectedFileUrl().isEmpty()); + } + + QScopedPointer blk(DDiskManager::createBlockDevice(fi->extraProperties()["udisksblk"].toString())); + QScopedPointer drv(DDiskManager::createDiskDevice(blk->drive())); + + if (fileUrl.path().contains("dfmroot:///sr") && blk->idUUID().isEmpty() && !drv->opticalBlank()) return; // 如果光驱的uuid为空(光盘未挂载)且不是空光盘的情况下 + + if (!mounted) { + m_fmEvent = event; + setEventKey(Open); + actionMount(event); + deviceListener->addSubscriber(this); + } else { + DUrl newUrl = fileUrl; + newUrl.setQuery(QString()); + + if (fi && fi->scheme() == DFMROOT_SCHEME) { + newUrl = fi->redirectedFileUrl(); + } + + const QSharedPointer &e = dMakeEventPointer(event->sender(), DUrlList() << newUrl); + e->setWindowId(event->windowId()); + actionOpen(e); + } +} + + +void AppController::asyncOpenDisk(const QString &path) +{ + DUrlList urls; + urls << DUrl(path); + m_fmEvent->setData(urls); + actionOpen(m_fmEvent.staticCast()); +} + +void AppController::actionOpenInNewWindow(const QSharedPointer &event) +{ + DFMEventDispatcher::instance()->processEvent(event->sender(), event->urlList(), true); +} + +void AppController::actionOpenInNewTab(const QSharedPointer &event) +{ + DFMEventDispatcher::instance()->processEvent(event->sender(), event->url()); +} + +void AppController::actionOpenDiskInNewTab(const QSharedPointer &event) +{ + const DUrl &fileUrl = event->url(); + + if (!fileUrl.isValid()) { + return; + } + + bool mounted = QStorageInfo(fileUrl.toLocalFile()).isValid(); + + DAbstractFileInfoPointer fi = fileService->createFileInfo(event->sender(), fileUrl); + if (fi && fi->scheme() == DFMROOT_SCHEME) { + mounted |= (!fi->redirectedFileUrl().isEmpty()); + } + + if (!mounted) { + m_fmEvent = event; + actionMount(event); + setEventKey(OpenNewTab); + deviceListener->addSubscriber(this); + } else { + //FIXME(zccrs): 为了菜单中能卸载/挂载U盘,url中被设置了query字段,今后应该将此字段移动到继承的FMEvent中 + DUrl newUrl = fileUrl; + + newUrl.setQuery(QString()); + + if (fi && fi->scheme() == DFMROOT_SCHEME) { + newUrl = fi->redirectedFileUrl(); + } + + actionOpenInNewTab(dMakeEventPointer(event->sender(), newUrl)); + } +} + +void AppController::asyncOpenDiskInNewTab(const QString &path) +{ + m_fmEvent->setData(DUrl(path)); + actionOpenDiskInNewTab(m_fmEvent.staticCast()); +} + +void AppController::actionOpenDiskInNewWindow(const QSharedPointer &event) +{ + const DUrl &fileUrl = event->url(); + + if (!fileUrl.isValid()) { + return; + } + + bool mounted = QStorageInfo(fileUrl.toLocalFile()).isValid(); + + DAbstractFileInfoPointer fi = fileService->createFileInfo(event->sender(), fileUrl); + if (fi && fi->scheme() == DFMROOT_SCHEME) { + mounted |= (!fi->redirectedFileUrl().isEmpty()); + } + + if (!mounted) { + m_fmEvent = event; + actionMount(event); + setEventKey(OpenNewWindow); + deviceListener->addSubscriber(this); + } else { + //FIXME(zccrs): 为了菜单中能卸载/挂载U盘,url中被设置了query字段,今后应该将此字段移动到继承的FMEvent中 + DUrl newUrl = fileUrl; + + newUrl.setQuery(QString()); + + if (fi && fi->scheme() == DFMROOT_SCHEME) { + newUrl = fi->redirectedFileUrl(); + } + + const QSharedPointer newEvent(new DFMUrlListBaseEvent(event->sender(), DUrlList() << newUrl)); + + newEvent->setWindowId(event->windowId()); + + actionOpenInNewWindow(newEvent); + } +} + +void AppController::asyncOpenDiskInNewWindow(const QString &path) +{ + DUrlList urls; + urls << DUrl(path); + m_fmEvent->setData(urls); + actionOpenInNewWindow(m_fmEvent.staticCast()); +} + +void AppController::actionOpenAsAdmin(const QSharedPointer &event) +{ + QStringList args; + // fix bug#42601 【专业版 sp3】【文件管理器】【5.2.0.21-1】搜索结果页,右键文件夹点击以管理员身份打开,新窗口未聚焦到对应文件夹 + args << event->url().toLocalFile(); + qDebug() << args; + QProcess::startDetached("dde-file-manager-pkexec", args); +} + +void AppController::actionOpenWithCustom(const QSharedPointer &event) +{ + emit fileSignalManager->requestShowOpenWithDialog(DFMUrlBaseEvent(event->sender(), event->url())); +} + +//新加app打开多个url +void AppController::actionOpenFilesWithCustom(const QSharedPointer &event) +{ + emit fileSignalManager->requestShowOpenFilesWithDialog(DFMUrlListBaseEvent(event->sender(), event->urlList())); +} + +void AppController::actionOpenFileLocation(const QSharedPointer &event) +{ + const DUrlList &urls = event->urlList(); + foreach (const DUrl &url, urls) { + fileService->openFileLocation(event->sender(), url); + } +} + + +void AppController::actionCompress(const QSharedPointer &event) +{ + fileService->compressFiles(event->sender(), event->urlList()); +} + +void AppController::actionDecompress(const QSharedPointer &event) +{ + fileService->decompressFile(event->sender(), event->urlList()); +} + +void AppController::actionDecompressHere(const QSharedPointer &event) +{ + fileService->decompressFileHere(event->sender(), event->urlList()); +} + +void AppController::actionCut(const QSharedPointer &event) +{ + fileService->writeFilesToClipboard(event->sender(), DFMGlobal::CutAction, event->urlList()); + +} + +void AppController::actionCopy(const QSharedPointer &event) +{ + fileService->writeFilesToClipboard(event->sender(), DFMGlobal::CopyAction, event->urlList()); +} + +void AppController::actionPaste(const QSharedPointer &event) +{ + // QTimer::singleshot目的: 多窗口下粘贴,右键拖动标题栏 + QTimer::singleShot(0, [event]() { + fileService->pasteFileByClipboard(event->sender(), event->url()); + }); +} + +void AppController::actionRename(const QSharedPointer &event) +{ + DUrlList urlList{ event->urlList() }; + if (urlList.size() == 1) { //###: for one file. + QSharedPointer singleFileEvent{ dMakeEventPointer(event->sender(), urlList.first()) }; + emit fileSignalManager->requestRename(*singleFileEvent); + + } else { //###: for more than one file. + emit fileSignalManager->requestMultiFilesRename(*event); + } +} + +void AppController::actionBookmarkRename(const QSharedPointer &event) +{ + emit fileSignalManager->requestBookmarkRename(*event.data()); +} + +void AppController::actionBookmarkRemove(const QSharedPointer &event) +{ + fileService->removeBookmark(event->sender(), event->url()); +} + +void AppController::actionDelete(const QSharedPointer &event) +{ + // 使用 Qtimer 避免回收站有大量文件时,异步事件处理时间过长,导致窗口不能拖动 + QTimer::singleShot(1, [event]() { + fileService->moveToTrash(event->sender(), event->urlList()); + }); +} + +void AppController::actionCompleteDeletion(const QSharedPointer &event) +{ + auto &&list = event->urlList(); + if (list.isEmpty()) + return; + + auto sender { event->sender() }; + foreach (const DUrl &url, list) { + if (systemPathManager->isSystemPath(url.toLocalFile())) { + DThreadUtil::runInMainThread(dialogManager, &DialogManager::showDeleteSystemPathWarnDialog, DFMEvent::windowIdByQObject(sender)); + return; + } + } + + bool slient { false }; + bool force { false }; + DFMEventDispatcher::instance()->processEventAsync(dMakeEventPointer(sender, list, slient, force)); +} + +void AppController::actionCreateSymlink(const QSharedPointer &event) +{ + fileService->createSymlink(event->sender(), event->url()); +} + +void AppController::actionSendToDesktop(const QSharedPointer &event) +{ + fileService->sendToDesktop(event->sender(), event->urlList()); +} + +void AppController::actionSendToBluetooth() +{ + QAction *act = dynamic_cast(sender()); + if (!act) + return; + DUrlList urlList = DUrl::fromStringList(act->property("urlList").toStringList()); + fileService->sendToBluetooth(urlList); +} + +void AppController::actionAddToBookMark(const QSharedPointer &event) +{ + fileService->addToBookmark(event->sender(), event->url()); +} + +void AppController::actionNewFolder(const QSharedPointer &event) +{ + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, event->url()); + + fileService->mkdir(event->sender(), FileUtils::newDocumentUrl(info, tr("New Folder"), QString())); +} + +void AppController::actionSelectAll(quint64 winId) +{ + emit fileSignalManager->requestViewSelectAll(static_cast(winId)); +} + +void AppController::actionClearRecent(const QSharedPointer &event) +{ + Q_UNUSED(event) +} + +void AppController::actionClearRecent() +{ + QFile f(QDir::homePath() + "/.local/share/recently-used.xbel"); + f.open(QIODevice::WriteOnly); + f.write(empty_recent_file); + f.close(); +} + +void AppController::actionClearTrash(const QObject *sender) +{ + DUrlList list; + list << DUrl::fromTrashFile("/"); + //fix bug 31324,判断当前是否是正在清空回收站,是返回,不是保存状态 + if (DFileService::instance()->getDoClearTrashState()) { + return; + } + DFileService::instance()->setDoClearTrashState(true); + + bool ret = fileService->deleteFiles(sender, list); + + if (ret) { + DDesktopServices::playSystemSoundEffect(DDesktopServices::SSE_EmptyTrash); + } +} + +void AppController::actionNewWord(const QSharedPointer &event) +{ + int windowId = event->windowId(); + bool wayland = DesktopInfo().waylandDectected(); + QString suffix = wayland ? "wps" : "doc"; + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, event->url()); + FileUtils::cpTemplateFileToTargetDir(info->toLocalFile(), QObject::tr("Document"), suffix, windowId); +} + +void AppController::actionNewExcel(const QSharedPointer &event) +{ + int windowId = event->windowId(); + bool wayland = DesktopInfo().waylandDectected(); + QString suffix = wayland ? "et" : "xls"; + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, event->url()); + FileUtils::cpTemplateFileToTargetDir(info->toLocalFile(), QObject::tr("Spreadsheet"), suffix, windowId); +} + +void AppController::actionNewPowerpoint(const QSharedPointer &event) +{ + int windowId = event->windowId(); + bool wayland = DesktopInfo().waylandDectected(); + QString suffix = wayland ? "dps" : "ppt"; + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, event->url()); + FileUtils::cpTemplateFileToTargetDir(info->toLocalFile(), QObject::tr("Presentation"), suffix, windowId); +} + +void AppController::actionNewText(const QSharedPointer &event) +{ + quint64 windowId = event->windowId(); + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, event->url()); + FileUtils::cpTemplateFileToTargetDir(info->toLocalFile(), QObject::tr("Text"), "txt", windowId); +} + +void AppController::actionMount(const QSharedPointer &event) +{ + const DUrl &fileUrl = event->url(); + + if (fileUrl.scheme() == DFMROOT_SCHEME) { + auto path = fileUrl.path(); + // mount the stashed remote connections + if (path.endsWith(SUFFIX_STASHED_REMOTE)) { + path = RemoteMountsStashManager::normalizeConnUrl(path); + auto e = dMakeEventPointer(event->sender(), path); + GvfsMountManager::instance()->mount_sync(*e); + return; + } + + DAbstractFileInfoPointer fi = fileService->createFileInfo(event->sender(), fileUrl); + QScopedPointer blk(DDiskManager::createBlockDevice(fi->extraProperties()["udisksblk"].toString())); + QScopedPointer drv(DDiskManager::createDiskDevice(blk->drive())); + + if (drv && drv->mediaCompatibility().join(" ").contains("optical") && !drv->mediaAvailable() && drv->ejectable()) { + QtConcurrent::run([](QString drvs) { + //fix:对于磁盘这块,主要由于光驱不会自动挂载,只有加载成功后鼠标左键双击才会执行此步,现在这样容易导致用户一系列误操作,故关闭。 + //QScopedPointer drv(DDiskManager::createDiskDevice(drvs)); + //drv->eject({}); + Q_UNUSED(drvs) + }, blk->drive()); + return; + } + // 断网时mount Samba无效 + if (blk->device().isEmpty()) { + dialogManager->showErrorDialog(tr("Mounting device error"), QString()); + qWarning() << "blockDevice is invalid, fileurl is " << fileUrl; + return; + } + + DUrl q; + q.setQuery(blk->device()); + const QSharedPointer &e = dMakeEventPointer(event->sender(), q); + actionMount(e); + return; + } else if (fileUrl.scheme() == APPENTRY_SCHEME) { + auto e = dMakeEventPointer(event->sender(), DUrlList() << fileUrl); + actionOpen(e); + return; + } + + QStringList deviceNode = DDiskManager::resolveDeviceNode(fileUrl.query(), {}); + if(deviceNode.isEmpty()) { + qDebug()<<"============>DeviceNode for "<< fileUrl <<"is empty"; + return; + } + QString udiskspath = deviceNode.first(); + QSharedPointer blkdev(DDiskManager::createBlockDevice(udiskspath)); + QSharedPointer drive(DDiskManager::createDiskDevice(blkdev->drive())); + if (drive->optical()) { + QtConcurrent::run([ = ] { + QMutexLocker locker(getOpticalDriveMutex()); //bug 31318 refine + + DISOMasterNS::DeviceProperty dp = ISOMaster->getDevicePropertyCached(fileUrl.query()); + if (dp.devid.length() == 0) + { + if (blkdev->mountPoints().size()) { + blkdev->unmount({}); + } + qDebug() << "============>fileUrl.query():" << fileUrl.query(); + if (!ISOMaster->acquireDevice(fileUrl.query())) { + ISOMaster->releaseDevice(); + blkdev->unmount({}); + QThread::msleep(1000); + QScopedPointer diskdev(DDiskManager::createDiskDevice(blkdev->drive())); + diskdev->eject({}); + + if (diskdev->optical()) + QMetaObject::invokeMethod(dialogManager, std::bind(&DialogManager::showErrorDialog, dialogManager, tr("The disc image was corrupted, cannot mount now, please erase the disc first"), QString()), Qt::ConnectionType::QueuedConnection); + + return; + } + dp = ISOMaster->getDeviceProperty(); + ISOMaster->releaseDevice(); + } + + if (!dp.formatted) + { + //blkdev->mount({}); + //We have to stick with 'UDisk'Listener until actionOpenDiskInNew* + //stops relying on doSubscriberAction... + deviceListener->mount(fileUrl.query()); + } + }); + return; + } + deviceListener->mount(fileUrl.query()); +} + +void AppController::actionMountImage(const QSharedPointer &event) +{ + qDebug() << "mount image:" << event->url(); + + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(this, event->url()); + + QString archiveuri = ""; + if (info && info->canRedirectionFileUrl()) { + archiveuri = "archive://" + QString(QUrl::toPercentEncoding(info->redirectedFileUrl().toString())); + qDebug() << "redirect the url to:" << info->redirectedFileUrl(); + } else { + archiveuri = "archive://" + QString(QUrl::toPercentEncoding(event->url().toString())); + } + + QStringList args; + args << "mount" << archiveuri; + + QProcess *gioproc = new QProcess; + gioproc->start("gio", args); + connect(gioproc, static_cast(&QProcess::finished), this, [ = ](int ret) { + if (ret) { + dialogManager->showErrorDialog(tr("Mount error: unsupported image format"), QString()); + } else { + QString double_encoded_uri = QUrl::toPercentEncoding(event->url().toEncoded()); + double_encoded_uri = QUrl::toPercentEncoding(double_encoded_uri); + QExplicitlySharedDataPointer f(DGioFile::createFromUri("archive://" + double_encoded_uri)); + if (f->path().length()) { + this->actionOpen(dMakeEventPointer(event->sender(), DUrlList() << DUrl::fromLocalFile(f->path()))); + } + } + gioproc->deleteLater(); + }); +} + +void AppController::popQueryScanningDialog(QObject *object, std::function onStop) +{ + QPointer pobject = object; + int code = dialogManager->showStopScanningDialog(); + // 用户选择'终止' + if (code > 0 && pobject) + onStop(); +} + +void AppController::refreshDesktop() +{ + static const QString DesktopService = "com.deepin.dde.desktop"; + static const QString DesktopPath = "/com/deepin/dde/desktop"; + DesktopInterface desktop(DesktopService, + DesktopPath, + QDBusConnection::sessionBus(), + this); + desktop.asyncCallWithArgumentList(QStringLiteral("Refresh"), QList()); +} + +void AppController::actionUnmount(const QSharedPointer &event) +{ + const DUrl &fileUrl = event->url(); + DAbstractFileInfoPointer fi = fileService->createFileInfo(event->sender(), fileUrl); + if (fi) { + const QString &blkStr = fi->extraProperties()["udisksblk"].toString(); + if (!blkStr.isNull() && !blkStr.isEmpty() && m_umountManager && m_umountManager->isScanningBlock(blkStr)) { + popQueryScanningDialog(this, [this, event, blkStr](){ + if (!m_umountManager) { + qWarning() << "m_umountManager is null."; + return; + } + if (m_umountManager->stopScanBlock(blkStr)) + doActionUnmount(event); + else + qWarning() << m_umountManager->getErrorMsg(); + }); + // 需要用户确认时弹框,提前结束卸载流程 + return; + } + } + // 其它情况直接走卸载流程 + doActionUnmount(event); +} + +void AppController::doActionUnmount(const QSharedPointer &event) +{ + const DUrl &fileUrl = event->url(); + + if (fileUrl.scheme() == DFMROOT_SCHEME) { + DAbstractFileInfoPointer fi = fileService->createFileInfo(event->sender(), fileUrl); + + // huawei 50143: 卸载时有任务,提示设备繁忙并且不能中断传输 +// emit fileSignalManager->requestAsynAbortJob(fi->redirectedFileUrl()); + + if (fi->suffix() == SUFFIX_UDISKS) { + //在主线程去调用unmount时如果弹出权限认证窗口,会导致文管界面挂起, + //在关闭窗口特效情况下,还会出现文管界面绘制不刷新出现重影的情况 + //把unmount相关操作移至子线程 + emit doUnmount(fi->extraProperties()["udisksblk"].toString()); + } else if (fi->suffix() == SUFFIX_GVFSMP) { + QString path = fi->extraProperties()["rooturi"].toString(); + if (path.isEmpty()) { + //FIXME(zccrs): 为解决,无法访问smb共享地址时,点击卸载共享目录,创建的fileinfo拿到的path为"",所有就没办法umount,临时解决方案,重Durl中获取 + QString encodePath = QUrl::fromPercentEncoding(fileUrl.path().mid(1).chopped( + QString("." SUFFIX_GVFSMP).length()).toUtf8()); + if (encodePath.contains(SMB_SCHEME) && encodePath.split(",").count() >= 2) { + path = QString("smb://"); + QStringList strlist = encodePath.split(","); + if (strlist.at(0).contains("=")) + path = path + strlist.at(0).mid(strlist.at(0).indexOf("=") + 1) + "/"; + if (strlist.at(1).contains("share=")) { + QString shareName = strlist.at(1); + path = path + shareName.replace(QString("share="), "") + "/"; + } + } + //fix bug 61610 是ftp和sftp在断网的情况下,卸载ftp或者sftp时rooturi为空,通过url去获取 + if (encodePath.contains(FTP_SCHEME)) { + path = encodePath.contains(SFTP_SCHEME) ? QString("sftp://") : QString("ftp://"); + //匹配ip,找到ip + QString Ip = encodePath.indexOf("=") >= 0 ? + encodePath.mid(encodePath.indexOf("=") + 1) : QString(); + path = path + Ip + QString("/"); + } + qInfo() << "umount path = " << path; + } + + deviceListener->unmount(path); + } + } else if (fileUrl.query().length()) { + QString dev = fileUrl.query(DUrl::FullyEncoded); + deviceListener->unmount(dev); + } +} + +void AppController::actionRestore(const QSharedPointer &event) +{ + DFileService::instance()->restoreFile(event->sender(), event->urlList()); +} + +void AppController::actionRestoreAll(const QSharedPointer &event) +{ + DFileService::instance()->restoreFile(event->sender(), DUrlList() << event->url()); +} + +void AppController::actionEject(const QSharedPointer &event) +{ + const DUrl &fileUrl = event->url(); + + if (fileUrl.scheme() == DFMROOT_SCHEME) { + DAbstractFileInfoPointer fi = fileService->createFileInfo(this, fileUrl); + + // Only optical media has eject option, should terminate all oprations while ejecting... + emit fileSignalManager->requestAsynAbortJob(fi->redirectedFileUrl()); + QtConcurrent::run([fi]() { + qDebug() << fi->fileUrl().path(); + QString strVolTag = fi->fileUrl().path().remove("/").remove(".localdisk"); // /sr0.localdisk 去头去尾取卷标 + //fix: 刻录期间误操作弹出菜单会引起一系列错误引导,规避用户误操作后引起不必要的错误信息提示 + if (strVolTag.startsWith("sr") && DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].bBurningOrErasing) { + QMetaObject::invokeMethod(dialogManager, "showErrorDialog", Qt::QueuedConnection, + Q_ARG(QString, tr("The device was not safely removed")), Q_ARG(QString, tr("Click \"Safely Remove\" and then disconnect it next time"))); + } else { + bool err = false; + QScopedPointer blk(DDiskManager::createBlockDevice(fi->extraProperties()["udisksblk"].toString())); + QScopedPointer drv(DDiskManager::createDiskDevice(blk->drive())); + QScopedPointer cbblk(DDiskManager::createBlockDevice(blk->cryptoBackingDevice())); + if (!blk->mountPoints().empty()) { + blk->unmount({}); + QDBusError lastError = blk->lastError(); + if (lastError.message().contains("target is busy")) { + QMetaObject::invokeMethod(dialogManager, "showErrorDialog", Qt::QueuedConnection, Q_ARG(QString, tr("The device was not ejected")), Q_ARG(QString, tr("Disk is busy, cannot eject now"))); + return; + } + + if (lastError.type() == QDBusError::Other) { // bug 27164, 取消 应该直接退出操作 + qDebug() << "blk action has been canceled"; + return; + } + + if (lastError.type() == QDBusError::NoReply) { // bug 29268, 用户超时操作 + qDebug() << "action timeout with noreply response"; + QMetaObject::invokeMethod(dialogManager, "showErrorDialog", Qt::QueuedConnection, Q_ARG(QString, tr("Authentication timed out")), Q_ARG(QString, "")); + //dialogManager->showErrorDialog(tr("Authentication timed out"), QString()); + return; + } + err |= blk->lastError().isValid(); + } + if (blk->cryptoBackingDevice().length() > 1) { + err |= cbblk->lastError().isValid(); + drv.reset(DDiskManager::createDiskDevice(cbblk->drive())); + } + drv->eject({}); + err |= drv->lastError().isValid(); + QDBusError dbusError = drv->lastError(); + if (err) { + // fix bug #27164 用户在操作其他用户挂载上的设备的时候需要进行提权操作,此时需要输入用户密码,如果用户点击了取消,此时返回 QDBusError::Other + // 所以暂时这样处理,处理并不友好。这个 errorType 并不能准确的反馈出用户的操作与错误直接的关系。这里笼统的处理成“设备正忙”也不准确。 + if (dbusError.isValid() && dbusError.type() != QDBusError::Other) { + qDebug() << "disc eject error: " << dbusError.message() << dbusError.name() << dbusError.type(); + QMetaObject::invokeMethod(dialogManager, "showErrorDialog", Qt::QueuedConnection, + Q_ARG(QString, tr("The device was not safely removed")), Q_ARG(QString, tr("Click \"Safely Remove\" and then disconnect it next time"))); + } + } + } + }); + } else { + deviceListener->eject(fileUrl.query(DUrl::FullyEncoded)); + } +} + +void AppController::actionSafelyRemoveDrive(const QSharedPointer &event) +{ + const DUrl &fileUrl = event->url(); + + QString driveName; + if (fileUrl.scheme() == DFMROOT_SCHEME) { + DAbstractFileInfoPointer fi = fileService->createFileInfo(this, fileUrl); + const QString &blkStr = fi->extraProperties()["udisksblk"].toString(); + if (m_umountManager) + driveName = m_umountManager->getDriveName(blkStr); + else + qWarning() << "m_umountManager is null!"; + } + + if (!driveName.isNull() && !driveName.isEmpty() && m_umountManager && m_umountManager->isScanningDrive(driveName)) { + popQueryScanningDialog(this, [this, event, driveName](){ + if (!m_umountManager) { + qWarning() << "m_umountManager is null!"; + return; + } + if (m_umountManager->stopScanDrive(driveName)) + doSafelyRemoveDrive(event); + else + qWarning() << m_umountManager->getErrorMsg(); + }); + // 需要用户确认时弹框,提前结束卸载流程 + return; + } + // 其它情况直接走卸载流程 + doSafelyRemoveDrive(event); +} + +void AppController::doSafelyRemoveDrive(const QSharedPointer &event) +{ + const DUrl &fileUrl = event->url(); + + if (fileUrl.scheme() == DFMROOT_SCHEME) { + DAbstractFileInfoPointer fi = fileService->createFileInfo(this, fileUrl); + + // bug 29419 期望在外设进行卸载,弹出时,终止复制操作 +// emit fileSignalManager->requestAsynAbortJob(fi->redirectedFileUrl()); + + //在主线程去调用unmount时如果弹出权限认证窗口,会导致文管界面挂起, + //在关闭窗口特效情况下,还会出现文管界面绘制不刷新出现重影的情况 + //把unmount相关操作移至子线程 + emit doSaveRemove(fi->extraProperties()["udisksblk"].toString()); + } else { + QString unix_device = fileUrl.query(DUrl::FullyEncoded); + QString drive_unix_device = gvfsMountManager->getDriveUnixDevice(unix_device); + if (!drive_unix_device.isEmpty()) { + gvfsMountManager->stop_device(drive_unix_device); + } + } +} + +void AppController::actionOpenInTerminal(const QSharedPointer &event) +{ + for (const DUrl &url : event->urlList()) { + fileService->openInTerminal(event->sender(), url); + } +} + +void AppController::actionProperty(const QSharedPointer &event) +{ + DUrlList urlList = event->urlList(); + + for (DUrl &url : urlList) { + DUrl realTargetUrl = url; + + //consider symlink file that links to trash/computer desktop files + const DAbstractFileInfoPointer &info = fileService->createFileInfo(event->sender(), url); + if (info && info->isSymLink()) { + realTargetUrl = info->rootSymLinkTarget(); + } + + if (info && info->scheme() == DFMROOT_SCHEME && info->suffix() == SUFFIX_USRDIR) { + url = info->redirectedFileUrl(); + } + // filx bug 60949 当共享文件夹的权限,被服务器改变去掉执行时,计算机界面选中共享文件, + // 再右键属性,选择属性,是不能显示的,调用checkGvfsMountfileBusy检查一下,弹提示。 + if (url.scheme() == DFMROOT_SCHEME && info->suffix() == SUFFIX_GVFSMP && + DFileService::instance()->checkGvfsMountfileBusy(url)) { + urlList.removeAll(url); + } + + if (url.isLocalFile()) { + QString urlSrcPath = url.path(); + QStorageInfo partition(url.path()); + if (partition.isValid() && partition.rootPath() == url.path() && !DDiskManager::resolveDeviceNode(partition.device(), {}).isEmpty()) { + QString dev(partition.device()); + QString newDev = dev.mid(dev.lastIndexOf('/') + 1); + url = DUrl(DFMROOT_ROOT + newDev + "." + SUFFIX_UDISKS); + //fix lvm分区下的逻辑目录打开属性需要对url做转换 + if (dev.contains("/mapper/")) { + QList ch = fileService->getChildren(this, DUrl(DFMROOT_ROOT), {}, nullptr); + for (auto chi : ch) { + if (chi.data()->checkMpsStr(urlSrcPath)) { + url = chi->fileUrl(); + break; + } + } + } + } + } + + DUrl gvfsmpurl; + gvfsmpurl.setScheme(DFMROOT_SCHEME); + gvfsmpurl.setPath("/" + QUrl::toPercentEncoding(url.path()) + "." SUFFIX_GVFSMP); + DAbstractFileInfoPointer fp(new DFMRootFileInfo(gvfsmpurl)); + if (fp->exists()) { + url = gvfsmpurl; + } + + if (info && info->scheme() == BURN_SCHEME && info->fileUrl().burnFilePath().contains(QRegularExpression("^/*$"))) { + url = DUrl(DFMROOT_ROOT + info->fileUrl().burnDestDevice().mid(QString("/dev/").length()) + "." + SUFFIX_UDISKS); + } + + if (realTargetUrl.toLocalFile().endsWith(QString(".") + DESKTOP_SURRIX)) { + DesktopFile df(realTargetUrl.toLocalFile()); + if (df.getDeepinId() == "dde-trash") { + dialogManager->showTrashPropertyDialog(DFMUrlBaseEvent(event->sender(), realTargetUrl)); + urlList.removeOne(url); + } else if (df.getDeepinId() == "dde-computer") { + dialogManager->showComputerPropertyDialog(); + urlList.removeOne(url); + } + } + } + + if (urlList.isEmpty()) { + return; + } + + if (urlList.first() == DUrl::fromTrashFile("/")) { + emit fileSignalManager->requestShowTrashPropertyDialog(DFMUrlBaseEvent(event->sender(), urlList.first())); + } else if (urlList.first() == DUrl::fromComputerFile("/")) { + emit fileSignalManager->requestShowComputerPropertyDialog(DFMUrlBaseEvent(event->sender(), urlList.first())); + } else { + emit fileSignalManager->requestShowPropertyDialog(DFMUrlListBaseEvent(event->sender(), urlList)); + } +} + +void AppController::actionNewWindow(const QSharedPointer &event) +{ + return actionOpenInNewWindow(event); +} + +void AppController::actionExit(quint64 winId) +{ + emit fileSignalManager->aboutToCloseLastActivedWindow(static_cast(winId)); +} + +void AppController::actionSetAsWallpaper(const QSharedPointer &event) +{ + const DUrl &fileUrl = event->url(); + + if (fileUrl.isLocalFile()) { + FileUtils::setBackground(fileUrl.toLocalFile()); + } else { + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(nullptr, fileUrl); + + if (info) { + const QString &local_file = info->toLocalFile(); + + if (!local_file.isEmpty()) { + FileUtils::setBackground(local_file); + } + } + } +} + +void AppController::actionShare(const QSharedPointer &event) +{ + emit fileSignalManager->requestShowShareOptionsInPropertyDialog(*event.data()); +} + +void AppController::actionUnShare(const QSharedPointer &event) +{ + fileService->unShareFolder(event->sender(), event->url()); +} + +void AppController::actionConnectToServer(quint64 winId) +{ + dialogManager->showConnectToServerDialog(winId); +} + +void AppController::actionSetUserSharePassword(quint64 winId) +{ + dialogManager->showUserSharePasswordSettingDialog(winId); +} + +void AppController::actionSettings(quint64 winId) +{ + dialogManager->showGlobalSettingsDialog(winId); +} + +void AppController::actionFormatDevice(const QSharedPointer &event) +{ + QWidget *w = WindowManager::getWindowById(event->windowId()); + if (!w) { + return; + } + + DAbstractFileInfoPointer info = fileService->createFileInfo(nullptr, event->url()); + if (!info) { + return; + } + + QSharedPointer blkdev(DDiskManager::createBlockDevice(info->extraProperties()["udisksblk"].toString())); + QString devicePath = blkdev->device(); + + QString cmd = "dde-device-formatter"; + QStringList args; + args << "-m=" + QString::number(event->windowId()) << devicePath; + + QProcess *process = new QProcess(this); + + connect(process, &QProcess::started, this, [w, process] { + QWidget *tmpWidget = new QWidget(w); + + tmpWidget->setWindowModality(Qt::WindowModal); + tmpWidget->setWindowFlags(Qt::Dialog); + tmpWidget->setAttribute(Qt::WA_DontShowOnScreen); + tmpWidget->show(); + + connect(process, static_cast(&QProcess::finished), + tmpWidget, &QWidget::deleteLater); + connect(process, static_cast(&QProcess::error), + tmpWidget, &QWidget::deleteLater); + }); + + connect(process, static_cast(&QProcess::finished), + process, &QProcess::deleteLater); + connect(process, static_cast(&QProcess::error), + process, &QProcess::deleteLater); + process->startDetached(cmd, args); +} + +void AppController::actionOpticalBlank(const QSharedPointer &event) +{ + if (DThreadUtil::runInMainThread(dialogManager, &DialogManager::showOpticalBlankConfirmationDialog, DFMUrlBaseEvent(event->sender(), event->url())) == DDialog::Accepted) { + QtConcurrent::run([ = ] { + QSharedPointer job(new FileJob(FileJob::OpticalBlank)); + job->moveToThread(qApp->thread()); + job->setWindowId(static_cast(event->windowId())); + dialogManager->addJob(job); + + DUrl dev(event->url()); + + job->doDiscBlank(dev); + dialogManager->removeJob(job->getJobId()); + //job->deleteLater(); + }); + } +} + +void AppController::actionRemoveStashedMount(const QSharedPointer &event) +{ + auto path = event->url().path(); // something like "/smb://1.2.3.4/shared-folder.remote" + path = RemoteMountsStashManager::normalizeConnUrl(path); + // then find the stashed key of it. + const auto &&stashedRemoteMounts = RemoteMountsStashManager::remoteMounts(); + QString key; + for (const auto &mount: stashedRemoteMounts) { + auto protocol = mount.value(REMOTE_PROTOCOL).toString(); + auto host = mount.value(REMOTE_HOST).toString(); + auto share = mount.value(REMOTE_SHARE).toString(); + if (protocol.isEmpty() || host.isEmpty()) { + qWarning() << "protocol or host is empty: " << mount; + continue; + } + + QString connPath = QString("%1://%2/%3").arg(protocol).arg(host).arg(share); + if (connPath == path) { + key = mount.value(REMOTE_KEY).toString(); + break; + } + } + if (!key.isEmpty()) { + RemoteMountsStashManager::removeRemoteMountItem(key); + } +} + +void AppController::actionctrlL(quint64 winId) +{ + emit fileSignalManager->requestSearchCtrlL(winId); +} + +void AppController::actionctrlF(quint64 winId) +{ + emit fileSignalManager->requestSearchCtrlF(winId); +} + +void AppController::actionExitCurrentWindow(quint64 winId) +{ + if (WindowManager::getWindowById(winId)) { + WindowManager::getWindowById(winId)->close(); + } +} + +void AppController::actionShowHotkeyHelp(quint64 winId) +{ + if (!WindowManager::getWindowById(winId)) { + return; + } + QRect rect = WindowManager::getWindowById(winId)->geometry(); + QPoint pos(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2); + Shortcut sc; + QStringList args; + QString param1 = "-j=" + sc.toStr(); + QString param2 = "-p=" + QString::number(pos.x()) + "," + QString::number(pos.y()); + args << param1 << param2; + QProcess::startDetached("deepin-shortcut-viewer", args); +} + +void AppController::actionBack(quint64 winId) +{ + DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(this), qobject_cast(WindowManager::getWindowById(winId))); +} + +void AppController::actionForward(quint64 winId) +{ + DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(this), qobject_cast(WindowManager::getWindowById(winId))); +} + +void AppController::actionForgetPassword(const QSharedPointer &event) +{ + QString path; + DAbstractFileInfoPointer fi = fileService->createFileInfo(event->sender(), event->url()); + if (fi && fi->suffix() == SUFFIX_GVFSMP) { + path = QUrl(fi->extraProperties()["rooturi"].toString()).toString(); + } + QJsonObject smbObj = secretManager->getLoginData(path); + + qDebug() << path << smbObj; + + if (!smbObj.empty()) { + QStringList ids = path.split("/"); + QString domain; + QString user; + QString server; + if (ids.at(2).contains(";")) { + domain = ids.at(2).split(";").at(0); + QString userIps = ids.at(2).split(";").at(1); + if (userIps.contains("@")) { + user = userIps.split("@").at(0); + server = userIps.split("@").at(1); + } + } else { + QString userIps = ids.at(2); + if (userIps.contains("@")) { + user = userIps.split("@").at(0); + server = userIps.split("@").at(1); + } else { + server = userIps; + } + } + qDebug() << smbObj << server; + QJsonObject obj; + obj.insert("user", smbObj.value("username").toString()); + obj.insert("domain", smbObj.value("domain").toString()); + obj.insert("protocol", DUrl(smbObj.value("id").toString()).scheme()); + obj.insert("server", server); + obj.insert("key", smbObj.value("key").toString()); + secretManager->clearPasswordByLoginObj(obj); + } + actionUnmount(event); + + auto stashKey = fi->extraProperties()["backer_url"].toString(); + RemoteMountsStashManager::removeRemoteMountItem(stashKey); +} + +void AppController::actionOpenFileByApp() +{ + const QAction *action = qobject_cast(sender()); + + if (!action) { + return; + } + + QString app = action->property("app").toString(); + if (action->property("urls").isValid()) { + DUrlList fileUrls = qvariant_cast(action->property("urls")); + QStringList fileUrlStrs; + for (const DUrl &url : fileUrls) { + fileUrlStrs << url.toString(); + } + FileUtils::openFilesByApp(app, fileUrlStrs); + } else { + DUrl fileUrl = qvariant_cast(action->property("url")); + fileService->openFileByApp(this, app, fileUrl); + } +} + +void AppController::actionSendToRemovableDisk() +{ + const QAction *action = qobject_cast(sender()); + + if (!action) { + return; + } + + DUrl targetUrl = DUrl(action->property("mounted_root_uri").toString()); + DUrlList urlList = DUrl::fromStringList(action->property("urlList").toStringList()); + + // 如果从光驱内发送文件到其他移动设备,将光驱路径转换成本地挂载路径 + for (DUrl &u : urlList) { + if (u.scheme() == BURN_SCHEME || u.scheme() == TAG_SCHEME || u.scheme() == SEARCH_SCHEME || u.scheme() == RECENT_SCHEME) { + DAbstractFileInfoPointer fi = fileService->createFileInfo(nullptr, u); + if (fi) + u = fi->redirectedFileUrl(); + } + } + + //fix:修正临时拷贝文件到光盘的路径问题,不是挂载目录,而是临时缓存目录 + QString blkDevice = action->property("blkDevice").toString(); + + if (blkDevice.startsWith("sr")) { // fix bug#27909 + QString &strCachePath = DFMOpticalMediaWidget::g_mapCdStatusInfo[blkDevice].cachePath; + if (strCachePath.isEmpty()) { // fix 未打开文管加载光驱时,结构中cachePath为空,此时往暂存区中发送文件会触发错误流程 + strCachePath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/" + qApp->organizationName() + "/" DISCBURN_STAGING "/_dev_" + blkDevice; + } + DUrl tempTargetUrl = DUrl::fromLocalFile(strCachePath); + fileService->pasteFile(action, DFMGlobal::CopyAction, tempTargetUrl, urlList); + } else { // other: usb storage and so on + fileService->pasteFile(action, DFMGlobal::CopyAction, targetUrl, urlList); + } +} + +void AppController::actionStageFileForBurning() +{ + const QAction *action = qobject_cast(sender()); + + if (!action) { + return; + } + + QString destdev = action->property("dest_drive").toString(); + DUrlList urlList = DUrl::fromStringList(action->property("urlList").toStringList()); + for (DUrl &u : urlList) { + DAbstractFileInfoPointer fi = fileService->createFileInfo(sender(), u); + if (fi) { // MasteredMediaFileInfo::canRedirectionFileUrl() 有问题,现在暂时不知道怎么修改 + u = fi->redirectedFileUrl(); + } + } + + QScopedPointer dev(DDiskManager::createDiskDevice(destdev)); + if (!dev->optical()) { + QtConcurrent::run([destdev]() { + QScopedPointer diskDev(DDiskManager::createDiskDevice(destdev)); + diskDev->eject({}); + }); + return; + } + + DDiskManager diskm; + for (auto &blks : diskm.blockDevices({})) { + QScopedPointer blkd(DDiskManager::createBlockDevice(blks)); + if (blkd->drive() == destdev) { + DUrl dest = DUrl::fromBurnFile(QString(blkd->device()) + "/" BURN_SEG_STAGING "/"); + fileService->pasteFile(action, DFMGlobal::CopyAction, dest, urlList); + break; + } + } +} + +QList AppController::actionGetTagsThroughFiles(const QSharedPointer &event) +{ + QList tags{}; + + if (static_cast(event) && (!event->urlList().isEmpty())) { + tags = DFileService::instance()->getTagsThroughFiles(nullptr, event->urlList()); + } + + return tags; +} + +bool AppController::actionRemoveTagsOfFile(const QSharedPointer &event) +{ + bool value{ false }; + + if (event && (event->url().isValid()) && !(event->tags().isEmpty())) { + QList tags = event->tags(); + value = DFileService::instance()->removeTagsOfFile(this, event->url(), tags); + } + + return value; +} + +void AppController::actionChangeTagColor(const QSharedPointer &event) +{ + QString tagName = event->m_tagUrl.fileName(); + QString newColor = TagManager::instance()->getColorNameByColor(event->m_newColorForTag); + TagManager::instance()->changeTagColor(tagName, newColor); +} + +void AppController::showTagEdit(const QRect &parentRect, const QPoint &globalPos, const DUrlList &fileList) +{ + DTagEdit *tagEdit = new DTagEdit(); + + auto subValue = parentRect.height() - globalPos.y(); + if (subValue < 98) { + tagEdit->setArrowDirection(DArrowRectangle::ArrowDirection::ArrowBottom); + } + + tagEdit->setBaseSize(160, 98); + tagEdit->setFilesForTagging(fileList); + tagEdit->setAttribute(Qt::WA_DeleteOnClose); + + ///###: Here, Used the position which was stored in DFileView. + tagEdit->setFocusOutSelfClosing(true); + + QList sameTagsInDiffFiles{ DFileService::instance()->getTagsThroughFiles(nullptr, fileList) }; + + tagEdit->setDefaultCrumbs(sameTagsInDiffFiles); + tagEdit->show(globalPos.x(), globalPos.y()); +} + +#ifdef SW_LABEL +void AppController::actionSetLabel(const DFMEvent &event) +{ + if (FileManagerLibrary::instance()->isCompletion()) { + std::string path = event.fileUrl().toLocalFile().toStdString(); + // auto_operation(const_cast(path.c_str()), "020100"); + FileManagerLibrary::instance()->auto_operation()(const_cast(path.c_str()), "020100"); + qDebug() << "020100" << "set label"; + } +} + +void AppController::actionViewLabel(const DFMEvent &event) +{ + if (FileManagerLibrary::instance()->isCompletion()) { + std::string path = event.fileUrl().toLocalFile().toStdString(); + // auto_operation(const_cast(path.c_str()), "010101"); + FileManagerLibrary::instance()->auto_operation()(const_cast(path.c_str()), "010101"); + qDebug() << "010101" << "view label"; + } +} + +void AppController::actionEditLabel(const DFMEvent &event) +{ + if (FileManagerLibrary::instance()->isCompletion()) { + std::string path = event.fileUrl().toLocalFile().toStdString(); + // auto_operation(const_cast(path.c_str()), "010201"); + FileManagerLibrary::instance()->auto_operation()(const_cast(path.c_str()), "010201"); + qDebug() << "010201" << "edit label"; + } +} + +void AppController::actionPrivateFileToPublic(const DFMEvent &event) +{ + if (FileManagerLibrary::instance()->isCompletion()) { + std::string path = event.fileUrl().toLocalFile().toStdString(); + // auto_operation(const_cast(path.c_str()), "010501"); + FileManagerLibrary::instance()->auto_operation()(const_cast(path.c_str()), "010501"); + qDebug() << "010501" << "private file to public"; + } +} + +void AppController::actionByIds(const DFMEvent &event, QString actionId) +{ + if (FileManagerLibrary::instance()->isCompletion()) { + std::string path = event.fileUrl().toLocalFile().toStdString(); + std::string _actionId = actionId.toStdString(); + FileManagerLibrary::instance()->auto_operation()(const_cast(path.c_str()), const_cast(_actionId.c_str())); + qDebug() << "action by" << actionId; + } +} + +#endif + + +void AppController::doSubscriberAction(const QString &path) +{ + switch (eventKey()) { + case Open: + asyncOpenDisk(path); + break; + case OpenNewWindow: + asyncOpenDiskInNewWindow(path); + break; + case OpenNewTab: + asyncOpenDiskInNewTab(path); + break; + default: + break; + } + deviceListener->removeSubscriber(this); +} + +QString AppController::createFile(const QString &sourceFile, const QString &targetDir, const QString &baseFileName, WId windowId) +{ + QFileInfo info(sourceFile); + + if (!info.exists()) { + return QString(); + } + + const QString &targetFile = FileUtils::newDocmentName(targetDir, baseFileName, info.suffix()); + // AppController::selectionAndRenameFile = qMakePair(DUrl::fromLocalFile(targetFile), windowId); + + if (DFileService::instance()->touchFile(WindowManager::getWindowById(windowId), DUrl::fromLocalFile(targetFile))) { + QFile target(targetFile); + + if (!target.open(QIODevice::WriteOnly)) { + return QString(); + } + + QFile source(sourceFile); + + if (!source.open(QIODevice::ReadOnly)) { + return QString(); + } + + target.write(source.readAll()); + + return targetFile; + } + + return QString(); +} + +AppController::AppController(QObject *parent) : QObject(parent) +{ + createGVfSManager(); + createUserShareManager(); + createDBusInterface(); + initConnect(); + registerUrlHandle(); +} + +AppController::~AppController() +{ + m_unmountThread.quit(); + m_unmountThread.wait(); +} + +void AppController::initConnect() +{ + connect(userShareManager, &UserShareManager::userShareCountChanged, + fileSignalManager, &FileSignalManager::userShareCountChanged); + + m_unmountWorker = new UnmountWorker; + m_unmountWorker->moveToThread(&m_unmountThread); + connect(&m_unmountThread, &QThread::finished, m_unmountWorker, &QObject::deleteLater); + connect(m_unmountWorker, &UnmountWorker::unmountResult, this, &AppController::showErrorDialog); + connect(this, &AppController::doUnmount, m_unmountWorker, &UnmountWorker::doUnmount); + connect(this, &AppController::doSaveRemove, m_unmountWorker, &UnmountWorker::doSaveRemove); + connect(fileSignalManager, &FileSignalManager::requestFreshAllDesktop, + this, &AppController::refreshDesktop); + + m_unmountThread.start(); + + m_umountManager.reset(new DUMountManager(this)); +} + +void AppController::createGVfSManager() +{ + networkManager; + secretManager; +} + +void AppController::createUserShareManager() +{ + userShareManager; +} + +void AppController::createDBusInterface() +{ + static const QString SessionManagerService = "com.deepin.SessionManager"; + static const QString SessionManagerPath = "/com/deepin/StartManager"; + + //创建中不再响应 + if (m_statDBusInterface == CreatingIFS ) + return; + m_statDBusInterface = CreatingIFS; + + if (!m_startManagerInterface) + m_startManagerInterface = new StartManagerInterface(SessionManagerService, + SessionManagerPath, + QDBusConnection::sessionBus(), + this); + if (!m_introspectableInterface) { + m_introspectableInterface = new IntrospectableInterface(SessionManagerService, + SessionManagerPath, + QDBusConnection::sessionBus(), + this); + m_introspectableInterface->setTimeout(1000); + } + + QtConcurrent::run(QThreadPool::globalInstance(),[this]() { + QDBusPendingReply reply = m_introspectableInterface->Introspect(); + reply.waitForFinished(); + if (!reply.isFinished() || reply.isError()) { + qWarning() << "dbus connect error" << QDBusError::errorString(reply.error().type()) << m_introspectableInterface->service(); + m_statDBusInterface = UnkownIFS; + } else { + QString xmlCode = reply.argumentAt(0).toString(); + //Introspect会返回空的接口信息,不能作为判断依据,需置为UnkownIFS再次判断 + if (xmlCode.contains("com.deepin.StartManager")) { + if (xmlCode.contains("LaunchApp")) { + m_statDBusInterface = VaildIFS; + qInfo() << "com.deepin.SessionManager : StartManager has LaunchApp interface"; + } else { + m_statDBusInterface = NoneIFS; + qWarning() << "com.deepin.SessionManager : StartManager doesn't have LaunchApp interface."; + } + } else { + qWarning() << "com.deepin.SessionManager Introspect error" << xmlCode; + m_statDBusInterface = UnkownIFS; + } + + } + return; + }); +} + +void AppController::showErrorDialog(const QString &title, const QString &content) +{ + dialogManager->showErrorDialog(title, content); +} + +bool AppController::checkLaunchAppInterface() +{ + //再次尝试获取接口状态 + qDebug() << "LaunchAppInterface state " << m_statDBusInterface; + if (m_statDBusInterface == UnkownIFS) + createDBusInterface(); + + //如果正在加载dbus接口,则稍等 + int times = 10; + while ((m_statDBusInterface == CreatingIFS) && times > 0) { + qDebug() << "LaunchAppInterface is loading..."; + QThread::msleep(100); + times--; + } + + bool ret = m_statDBusInterface == VaildIFS; + if (!ret) + qWarning() << "LaunchAppInterface is invaild, state:" << m_statDBusInterface; + return ret; +} + +StartManagerInterface *AppController::startManagerInterface() const +{ + return m_startManagerInterface; +} + +void UnmountWorker::doUnmount(const QString &blkStr) +{ + DUMountManager manager; + if (!manager.umountBlock(blkStr)) + emit unmountResult(tr("The device was not safely unmounted"), manager.getErrorMsg()); +} + +void UnmountWorker::doSaveRemove(const QString &blkStr) +{ + DUMountManager manager; + if (!manager.removeDrive(manager.getDriveName(blkStr))) + emit unmountResult(tr("The device was not safely removed"), manager.getErrorMsg()); +} + +DesktopInterface::DesktopInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +DesktopInterface::~DesktopInterface() +{ +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/appcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/appcontroller.h new file mode 100644 index 0000000..934f0fd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/appcontroller.h @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef APPCONTROLLER_H +#define APPCONTROLLER_H + +#include +#include + +#include "subscriber.h" +#include "dfmevent.h" +#include "dbusinterface/startmanager_interface.h" +#include "dbusinterface/introspectable_interface.h" + + +class FileController; +class FileMonitor; +class DRenameBar; +class FileBatchProcess; +class DUMountManager; + +/** + * @brief The UnmountWorker class 卸载操作类 用于在子线程执行卸载操作 + */ +class UnmountWorker : public QObject +{ + Q_OBJECT + +public slots: + void doUnmount(const QString &blkStr); + void doSaveRemove(const QString &blkStr); + +signals: + void unmountResult(const QString &title, const QString &msg); +}; + +class DesktopInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.dde.desktop"; } +public: + DesktopInterface(const QString &service, const QString &path, + const QDBusConnection &connection, QObject *parent = nullptr); + ~DesktopInterface(); +}; + + +class AppController : public QObject, public Subscriber +{ + Q_OBJECT + +public: + enum ActionType { + Open, + OpenNewWindow, + OpenNewTab + }; + + static AppController *instance(); + static void registerUrlHandle(); + +public slots: + void actionOpen(const QSharedPointer &event, const bool isEnter = false); + void actionOpenDisk(const QSharedPointer &event); + void asyncOpenDisk(const QString &path); + + void actionOpenInNewWindow(const QSharedPointer &event); + void actionOpenInNewTab(const QSharedPointer &event); + void actionOpenDiskInNewTab(const QSharedPointer &event); + void asyncOpenDiskInNewTab(const QString &path); + void actionOpenDiskInNewWindow(const QSharedPointer &event); + void asyncOpenDiskInNewWindow(const QString &path); + void actionOpenAsAdmin(const QSharedPointer &event); + + void actionOpenWithCustom(const QSharedPointer &event); + void actionOpenFilesWithCustom(const QSharedPointer &event); + void actionOpenFileLocation(const QSharedPointer &event); + void actionCompress(const QSharedPointer &event); + void actionDecompress(const QSharedPointer &event); + void actionDecompressHere(const QSharedPointer &event); + void actionCut(const QSharedPointer &event); + void actionCopy(const QSharedPointer &event); + void actionPaste(const QSharedPointer &event); + void actionRename(const QSharedPointer &event); + void actionBookmarkRename(const QSharedPointer &event); + void actionBookmarkRemove(const QSharedPointer &event); + void actionDelete(const QSharedPointer &event); + void actionCompleteDeletion(const QSharedPointer &event); + void actionCreateSymlink(const QSharedPointer &event); + void actionSendToDesktop(const QSharedPointer &event); + void actionSendToBluetooth(); + void actionAddToBookMark(const QSharedPointer &event); + void actionNewFolder(const QSharedPointer &event); + void actionSelectAll(quint64 winId); + void actionClearRecent(const QSharedPointer &event); + void actionClearRecent(); + void actionClearTrash(const QObject *sender = nullptr); + void actionNewWord(const QSharedPointer &event); + void actionNewExcel(const QSharedPointer &event); + void actionNewPowerpoint(const QSharedPointer &event); + void actionNewText(const QSharedPointer &event); + void actionMount(const QSharedPointer &event); + void actionMountImage(const QSharedPointer &event); + void actionUnmount(const QSharedPointer &event); + void doActionUnmount(const QSharedPointer &event); + void actionRestore(const QSharedPointer &event); + void actionRestoreAll(const QSharedPointer &event); + void actionEject(const QSharedPointer &event); + void actionSafelyRemoveDrive(const QSharedPointer &event); + void doSafelyRemoveDrive(const QSharedPointer &event); + void actionOpenInTerminal(const QSharedPointer &event); + void actionProperty(const QSharedPointer &event); + void actionNewWindow(const QSharedPointer &event); + void actionExit(quint64 winId); + void actionSetAsWallpaper(const QSharedPointer &event); + void actionShare(const QSharedPointer &event); + void actionUnShare(const QSharedPointer &event); + void actionConnectToServer(quint64 winId); + void actionSetUserSharePassword(quint64 winId); + void actionSettings(quint64 winId); + void actionFormatDevice(const QSharedPointer &event); + void actionOpticalBlank(const QSharedPointer &event); + void actionRemoveStashedMount(const QSharedPointer &event); + + + void actionctrlL(quint64 winId); + void actionctrlF(quint64 winId); + + void actionExitCurrentWindow(quint64 winId); + void actionShowHotkeyHelp(quint64 winId); + void actionBack(quint64 winId); + void actionForward(quint64 winId); + + void actionForgetPassword(const QSharedPointer &event); + + void actionOpenFileByApp(); + void actionSendToRemovableDisk(); + void actionStageFileForBurning(); + + + ///###: tag protocol + QList actionGetTagsThroughFiles(const QSharedPointer &event); + bool actionRemoveTagsOfFile(const QSharedPointer &event); + void actionChangeTagColor(const QSharedPointer &event); + void showTagEdit(const QRect &parentRect, const QPoint &globalPos, const DUrlList &fileList); + +#ifdef SW_LABEL + void actionSetLabel(const DFMEvent &event); + void actionViewLabel(const DFMEvent &event); + void actionEditLabel(const DFMEvent &event); + void actionPrivateFileToPublic(const DFMEvent &event); + void actionByIds(const DFMEvent &event, QString actionId); +#endif + + // Subscriber interface +public: + void doSubscriberAction(const QString &path) override; + + static QString createFile(const QString &sourceFile, const QString &targetDir, const QString &baseFileName, WId windowId); + +signals: + void doUnmount(const QString &blk); + void doSaveRemove(const QString &blk); + +protected: + explicit AppController(QObject *parent = nullptr); + ~AppController() override; + +private: + void initConnect(); + void createGVfSManager(); + void createUserShareManager(); + void createDBusInterface(); + void showErrorDialog(const QString &title, const QString &content); + void popQueryScanningDialog(QObject *object, std::function onStop); + void refreshDesktop(); + + QSharedPointer m_fmEvent; + static QPair selectionAndRenameFile; //###: for creating new file. + static QPair selectionFile; //###: rename a file which must be existance. + + StartManagerInterface *m_startManagerInterface = nullptr; + IntrospectableInterface *m_introspectableInterface = nullptr; + QThread m_unmountThread; + UnmountWorker *m_unmountWorker; + QScopedPointer m_umountManager; + + volatile enum {UnkownIFS,NoneIFS,CreatingIFS,VaildIFS} m_statDBusInterface = UnkownIFS; //dbus接口创建状态 + + friend class FileController; + friend class MergedDesktopController; + friend class DFileSystemModel; + friend class DFileViewHelper; + friend class DRenameBar; + friend class FileBatchProcess; + friend class VaultController; + +public: + static QPair, quint64> multiSelectionFilesCache; //###: for multi selection. + static std::atomic multiSelectionFilesCacheCounter; + static std::atomic flagForDDesktopRenameBar; + + StartManagerInterface *startManagerInterface() const; + bool checkLaunchAppInterface(); +}; + +#endif // APPCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/avfsfilecontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/avfsfilecontroller.cpp new file mode 100644 index 0000000..9603872 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/avfsfilecontroller.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "avfsfilecontroller.h" +#include "interfaces/dfileinfo.h" +#include "dfmstandardpaths.h" +#include +#include +#include "models/avfsfileinfo.h" +#include "dfileinfo.h" +#include +#include +#include "dfileservices.h" +#include "shutil/fileutils.h" +#include "dfmevent.h" + +class AVFSIterator : public DDirIterator +{ +public: + AVFSIterator(const DUrl &url, + const QStringList &nameFilters, + QDir::Filters filter, + QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags); + + ~AVFSIterator() override; + + DUrl next() override; + bool hasNext() const override; + + QString fileName() const override; + DUrl fileUrl() const override; + const DAbstractFileInfoPointer fileInfo() const override; + DUrl url() const override; + +private: + QDirIterator *iterator; + DUrl currentUrl; +}; + +AVFSIterator::AVFSIterator(const DUrl &url, const QStringList &nameFilters, QDir::Filters filter, QDirIterator::IteratorFlags flags): + DDirIterator() +{ + QString realPath = AVFSFileInfo::realDirUrl(url).toLocalFile(); + iterator = new QDirIterator(realPath, nameFilters, filter, flags); + currentUrl = url; +} + +AVFSIterator::~AVFSIterator() +{ + delete iterator; +} + +DUrl AVFSIterator::next() +{ + QString realPath = iterator->next(); + Q_UNUSED(realPath); + DUrl url = DUrl::fromAVFSFile(currentUrl.path() + "/" + fileName()); + return url; +} + +bool AVFSIterator::hasNext() const +{ + return iterator->hasNext(); +} + +QString AVFSIterator::fileName() const +{ + return fileInfo()->fileName(); +} + +DUrl AVFSIterator::fileUrl() const +{ + return fileInfo()->fileUrl(); +} + +const DAbstractFileInfoPointer AVFSIterator::fileInfo() const +{ + DUrl url = DUrl::fromAVFSFile(currentUrl.path() + "/" + iterator->fileName()); + return DAbstractFileInfoPointer(new AVFSFileInfo(url)); +} + +DUrl AVFSIterator::url() const +{ + return currentUrl; +} + +AVFSFileController::AVFSFileController(QObject *parent): + DAbstractFileController(parent) +{ + +} + +const DAbstractFileInfoPointer AVFSFileController::createFileInfo(const QSharedPointer &event) const +{ + DAbstractFileInfoPointer info(new AVFSFileInfo(event->url())); + + return info; +} + +const DDirIteratorPointer AVFSFileController::createDirIterator(const QSharedPointer &event) const +{ + return DDirIteratorPointer(new AVFSIterator(event->url(), event->nameFilters(), event->filters(), event->flags())); +} + +DAbstractFileWatcher *AVFSFileController::createFileWatcher(const QSharedPointer &event) const +{ + QString realPath = AVFSFileInfo::realDirUrl(event->url()).toLocalFile(); + + return new DFileWatcher(realPath); +} + +bool AVFSFileController::openFileLocation(const QSharedPointer &event) const +{ + return DFileService::instance()->openFileLocation(event->sender(), realUrl(event->url())); +} + +bool AVFSFileController::openFile(const QSharedPointer &event) const +{ + return DFileService::instance()->openFile(event->sender(), realUrl(event->url())); +} + +bool AVFSFileController::openFileByApp(const QSharedPointer &event) const +{ + return DFileService::instance()->openFileByApp(event->sender(), event->appName(), realUrl(event->url())); +} + +bool AVFSFileController::writeFilesToClipboard(const QSharedPointer &event) const +{ + DUrlList realUrlList; + + foreach (const DUrl &url, event->urlList()) { + realUrlList << realUrl(url); + } + + return DFileService::instance()->writeFilesToClipboard(event->sender(), event->action(), realUrlList); +} + +bool AVFSFileController::openInTerminal(const QSharedPointer &event) const +{ + return DFileService::instance()->openInTerminal(event->sender(), realUrl(event->url())); +} + +DUrl AVFSFileController::realUrl(const DUrl &url) +{ + return AVFSFileInfo::realFileUrl(url); +} + +QString AVFSFileController::findArchFileRootPath(const DUrl &url) +{ + QStringList items = url.path().split("/"); + for (int i = 0; i < items.size(); i++) { + QString path = ""; + for (int j = 0; j <= i; j++) { + path += (items.at(j) + "/"); + } + if (path.endsWith("/")) + path.chop(1); + if (FileUtils::isArchive(path)) + return path; + } + return QString(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/avfsfilecontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/avfsfilecontroller.h new file mode 100644 index 0000000..555649b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/avfsfilecontroller.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef AVFSFILECONTROLLER_H +#define AVFSFILECONTROLLER_H + +#include + +#include "dabstractfilecontroller.h" + +class AVFSFileController : public DAbstractFileController +{ + Q_OBJECT + +public: + explicit AVFSFileController(QObject *parent = nullptr); + + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + + const DDirIteratorPointer createDirIterator(const QSharedPointer &event) const override; + + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + + bool openFileLocation(const QSharedPointer &event) const override; + + bool openFile(const QSharedPointer &event) const override; + bool openFileByApp(const QSharedPointer &event) const override; + bool writeFilesToClipboard(const QSharedPointer &event) const override; + + bool openInTerminal(const QSharedPointer &event) const override; + + static DUrl realUrl(const DUrl &url); + static QString findArchFileRootPath(const DUrl &url); +private: +}; + +#endif // AVFSFILECONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/bookmarkmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/bookmarkmanager.cpp new file mode 100644 index 0000000..183c16f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/bookmarkmanager.cpp @@ -0,0 +1,448 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "bookmarkmanager.h" +#include "dfileservices.h" +#include "dfmevent.h" +#include "dabstractfilewatcher.h" +#include "private/dabstractfilewatcher_p.h" +#include "dfmapplication.h" +#include "dfmsettings.h" + +#include "app/define.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "shutil/fileutils.h" +#include "deviceinfo/udisklistener.h" + +class BookMarkFileWatcher; +class BookMarkFileWatcherPrivate : public DAbstractFileWatcherPrivate +{ +public: + explicit BookMarkFileWatcherPrivate(DAbstractFileWatcher *qq) + : DAbstractFileWatcherPrivate(qq) {} + + bool start() override + { + started = true; + + return true; + } + + bool stop() override + { + started = false; + + return true; + } +}; + +class BookMarkFileWatcher : public DAbstractFileWatcher +{ +public: + explicit BookMarkFileWatcher(const DUrl &url, QObject *parent = nullptr) + : DAbstractFileWatcher(*new BookMarkFileWatcherPrivate(this), url, parent) + { + + } +}; + +BookMarkManager::BookMarkManager(QObject *parent) + : DAbstractFileController(parent) +{ + fileService->setFileUrlHandler(BOOKMARK_SCHEME, "", this); + + connect(DFMApplication::genericSetting(), &DFMSettings::valueEdited, this, &BookMarkManager::onFileEdited); + connect(DFileService::instance(), &DFileService::fileRenamed, this, &BookMarkManager::onFileRenamed); +} + +BookMarkManager::~BookMarkManager() +{ + +} + +/*! + * \brief Check if a bookmark is exist. + * \param url a bookmark url + * + * FIXME: A workaround for the worng implement of BookMark::exists(). + * We should remove this function or make it private once we correct + * BookMark::exists() 's behavior. + * + * \return exist or not + */ +bool BookMarkManager::checkExist(const DUrl &url) +{ + return m_bookmarkDataMap.contains(url.bookmarkTargetUrl()); +// BookMarkPointer p = m_bookmarks.value(url.bookmarkTargetUrl()); +// return p; +} + +bool BookMarkManager::renameFile(const QSharedPointer &event) const +{ + DUrl from = event->fromUrl(); + DUrl new_from = from.bookmarkTargetUrl(); + DUrl to = event->toUrl(); + + BookmarkData data = findBookmarkData(event->fromUrl()); + + if (!data.m_url.isValid()) { + return false; + } + + QVariantList list = DFMApplication::genericSetting()->value("BookMark", "Items").toList(); + + for (int i = 0; i < list.count(); ++i) { + QVariantMap map = list.at(i).toMap(); + + if (map.value("name").toString() == data.m_url.bookmarkName()) { + map["name"] = event->toUrl().bookmarkName(); + list[i] = map; + + DFMApplication::genericSetting()->setValue("BookMark", "Items", list); + + data.m_url = event->toUrl(); + data.m_lastModified = QDateTime::currentDateTime(); + m_bookmarkDataMap[event->toUrl().bookmarkTargetUrl()] = data; + + BookMarkPointer item = findBookmark(event->fromUrl()); + if (item) { + BookMark *new_item = new BookMark(event->toUrl()); + QUrlQuery query(event->toUrl()); + + new_item->m_created = data.m_created; + new_item->m_lastModified = data.m_lastModified; + new_item->mountPoint = data.mountPoint;//query.queryItemValue("mount_point"); + new_item->locateUrl = map.value("locateUrl").toString();//query.queryItemValue("locate_url"); + + m_bookmarks[event->toUrl().bookmarkTargetUrl()] = new_item; + } + + break; + } + } + + DAbstractFileWatcher::ghostSignal(DUrl(BOOKMARK_ROOT), &DAbstractFileWatcher::fileMoved, event->fromUrl(), event->toUrl()); + + return true; +} + +bool BookMarkManager::deleteFiles(const QSharedPointer &event) const +{ + QVariantList list = DFMApplication::genericSetting()->value("BookMark", "Items").toList(); + + for (const DUrl &url : event->urlList()) { + + if (!m_bookmarkDataMap.contains(url.bookmarkTargetUrl())) + continue; + + m_bookmarks.remove(url.bookmarkTargetUrl()); + const BookmarkData &data = m_bookmarkDataMap.take(url.bookmarkTargetUrl()); + + for (int i = 0; i < list.count(); ++i) { + const QVariantMap &map = list.at(i).toMap(); + + if (map.value("name").toString() == data.m_url.bookmarkName()) { + list.removeAt(i); + break; + } + } + + DAbstractFileWatcher::ghostSignal(DUrl(BOOKMARK_ROOT), &DAbstractFileWatcher::fileDeleted, data.m_url); + } + + DFMApplication::genericSetting()->setValue("BookMark", "Items", list); + + return true; +} + +bool BookMarkManager::touch(const QSharedPointer &event) const +{ + //与其他书签储存逻辑保持一致,去掉url中的Query字符串 + DUrl newUrl = event->url(); + newUrl.setQuery(""); + QUrlQuery query(event->url()); + + BookmarkData bookmarkData; + bookmarkData.m_created = QDateTime::currentDateTime(); + bookmarkData.m_lastModified = bookmarkData.m_created; + bookmarkData.mountPoint = query.queryItemValue("mount_point"); + bookmarkData.locateUrl = query.queryItemValue("locate_url"); + bookmarkData.m_url = newUrl; + + m_bookmarkDataMap[newUrl.bookmarkTargetUrl()] = bookmarkData; + m_bookmarks[newUrl.bookmarkTargetUrl()] = nullptr; + + QVariantList list = DFMApplication::genericSetting()->value("BookMark", "Items").toList(); + list << QVariantMap { + {"name", bookmarkData.m_url.bookmarkName()}, + {"url", bookmarkData.m_url.bookmarkTargetUrl()}, + {"created", bookmarkData.m_created.toString(Qt::ISODate)}, + {"lastModified", bookmarkData.m_lastModified.toString(Qt::ISODate)}, + {"mountPoint", bookmarkData.mountPoint}, + {"locateUrl", bookmarkData.locateUrl} + }; + + DFMApplication::genericSetting()->setValue("BookMark", "Items", list); + DAbstractFileWatcher::ghostSignal(DUrl(BOOKMARK_ROOT), &DAbstractFileWatcher::subfileCreated, bookmarkData.m_url); + + return true; +} + +bool BookMarkManager::setPermissions(const QSharedPointer &event) const +{ + DUrl url = event->url(); + + if (!url.bookmarkTargetUrl().isEmpty()) { + return DFileService::instance()->setPermissions(event->sender(), url.bookmarkTargetUrl(), event->permissions()); + } + + return false; +} + +bool BookMarkManager::removeBookmark(const QSharedPointer &event) const +{ + return DFileService::instance()->deleteFiles(nullptr, {event->url()}, false); +} + +BookMarkPointer BookMarkManager::findBookmark(const DUrl &url) const +{ + return m_bookmarks.value(url.bookmarkTargetUrl()); +} + +BookmarkData BookMarkManager::findBookmarkData(const DUrl &url) const +{ + return m_bookmarkDataMap.value(url.bookmarkTargetUrl()); +} + +/*! + * \brief Update bookmark items by the given \a value + * + * \param value QVariant from DFMApplication::generfile:///media/wzc/asd/VM?mount_point=device:/dev/sda5&locate_url=/VMicSetting() + * + * Please notice that this is NOT updating bookmark list to local saved config file, + * instead, this is updating bookmark item list FROM local saved config file. + * + * \sa DFMSetting::valueEdited(), DFMApplication::genericSetting() + */ +void BookMarkManager::update(const QVariant &value) +{ + const QVariantList &list = value.toList(); + + DUrlList bookmarkUrlList = m_bookmarkDataMap.keys(); + for (int i = 0; i < list.count(); ++i) { + const QVariantMap &item = list.at(i).toMap(); + const QString &name = item.value("name").toString(); + const DUrl &url = DUrl::fromUserInput(item.value("url").toString()); + const QDateTime &create_time = QDateTime::fromString(item.value("created").toString(), Qt::ISODate); + const QDateTime &last_modified_time = QDateTime::fromString(item.value("lastModified").toString(), Qt::ISODate); + const QString &mount_point = item.value("mountPoint").toString(); + //兼容以前未转base64版本(sp2update2之前),先判断locateUrl,保证存入bookmark中的是base64 + QByteArray ba; + if (item.value("locateUrl").toString().startsWith("/")) { //转base64的路径不会以'/'开头 + ba = item.value("locateUrl").toString().toLocal8Bit().toBase64(); + } else { + ba = item.value("locateUrl").toString().toLocal8Bit(); + } + const QString &locate_url = QString(ba); + + BookmarkData data; + data.m_url = DUrl::fromBookMarkFile(url, name); + data.m_created = create_time; + data.m_lastModified = last_modified_time; + data.mountPoint = mount_point; + data.locateUrl = locate_url; + + if (m_bookmarkDataMap.contains(url)) { + const BookmarkData oldData = m_bookmarkDataMap.value(url); + m_bookmarkDataMap[url] = data; + + if (oldData.m_url.fragment() != name) { + DAbstractFileWatcher::ghostSignal(DUrl(BOOKMARK_ROOT), &DAbstractFileWatcher::fileMoved, oldData.m_url, data.m_url); + + } + } else { + m_bookmarkDataMap[url] = data; + DAbstractFileWatcher::ghostSignal(DUrl(BOOKMARK_ROOT), &DAbstractFileWatcher::subfileCreated, data.m_url); + } + + bookmarkUrlList.removeOne(url); + } + + for (const DUrl &url : bookmarkUrlList) { + const BookmarkData data = m_bookmarkDataMap.value(url); + m_bookmarks[url] = nullptr; + + DAbstractFileWatcher::ghostSignal(DUrl(BOOKMARK_ROOT), &DAbstractFileWatcher::fileDeleted, data.m_url); + } +} + +void BookMarkManager::onFileEdited(const QString &group, const QString &key, const QVariant &value) +{ + if (group != "BookMark" || key != "Items") + return; + + update(value); +} + +bool BookMarkManager::onFileRenamed(const DUrl &from, const DUrl &to) +{ + //采用durl标准的转bookmarkurl接口,否则转出的URL可能isValid = false + DUrl bookMarkFrom = DUrl::fromBookMarkFile(from, from.fileName()); + DUrl bookMarkTo = DUrl::fromBookMarkFile(to, to.fileName()); + + BookmarkData data = findBookmarkData(bookMarkFrom); + BookMarkPointer item = findBookmark(bookMarkFrom); + if (!item || !data.m_url.isValid()) { + return false; + } + + QVariantList list = DFMApplication::genericSetting()->value("BookMark", "Items").toList(); + for (int i = 0; i < list.count(); ++i) { + QVariantMap map = list.at(i).toMap(); + + if (map.value("name").toString() == item->getName()) { + bookMarkFrom.setFragment(map.value("name").toString()); + + QString locateUrl = to.path(); + int indexOfFirstDir = 0; + //挂载的设备目录特殊处理 + if (locateUrl.startsWith("/media")) { + indexOfFirstDir = locateUrl.lastIndexOf("/", locateUrl.length() - 1); + } else { + indexOfFirstDir = locateUrl.indexOf("/", 1); + } + locateUrl = locateUrl.mid(indexOfFirstDir); + + bookMarkTo.setFragment(map.value("name").toString()); + + //为防止locateUrl传入QUrl被转码,locateUrl统一保存为base64 + QByteArray ba = locateUrl.toLocal8Bit().toBase64(); + map["locateUrl"] = QString(ba); + map["url"] = bookMarkTo.path(); + list[i] = map; + DFMApplication::genericSetting()->setValue("BookMark", "Items", list); + + BookmarkData newData; + newData.m_url = bookMarkTo; + newData.m_created = item->m_created; + newData.m_lastModified = QDateTime::currentDateTime(); + newData.mountPoint = map.value("mountPoint").toString(); + newData.locateUrl = QString(ba); + + BookMarkPointer new_item(new BookMark(bookMarkTo)); + new_item->m_created = item->m_created; + new_item->m_lastModified = QDateTime::currentDateTime(); + new_item->mountPoint = map.value("mountPoint").toString(); + new_item->locateUrl = QString(ba); + + m_bookmarkDataMap.remove(bookMarkFrom.bookmarkTargetUrl()); + m_bookmarkDataMap[bookMarkTo.bookmarkTargetUrl()] = newData; + m_bookmarks.remove(bookMarkFrom.bookmarkTargetUrl()); + m_bookmarks[bookMarkTo.bookmarkTargetUrl()] = new_item; + + DAbstractFileWatcher::ghostSignal(DUrl(BOOKMARK_ROOT), &DAbstractFileWatcher::fileMoved, bookMarkFrom, bookMarkTo); + return true; + } + } + + return false; +} + +void BookMarkManager::refreshBookmark() +{ + update(DFMApplication::genericSetting()->value("BookMark", "Items")); +} + +const DUrlList BookMarkManager::getBookmarkUrls() +{ + DUrlList list; + for (const BookmarkData &data : m_bookmarkDataMap) { + list.append(data.m_url); + } + + return list; +} + +const QList BookMarkManager::getChildren(const QSharedPointer &event) const +{ + ///这个函数目前不会被调用了 + Q_UNUSED(event); + QList infolist; + + for (BookMarkPointer bk : m_bookmarks) { + infolist.append(DAbstractFileInfoPointer(bk)); + } + + return infolist; +} + +const DAbstractFileInfoPointer BookMarkManager::createFileInfo(const QSharedPointer &event) const +{ + if (event->fileUrl() == DUrl(BOOKMARK_ROOT)) { + return DAbstractFileInfoPointer(new BookMark(DUrl(BOOKMARK_ROOT))); + } + + DUrl bookmarkUrl = event->url().bookmarkTargetUrl(); + if (!m_bookmarkDataMap.contains(bookmarkUrl)) { + DUrl targetUrl = event->url().bookmarkTargetUrl(); + if (targetUrl.scheme().isEmpty()) { + targetUrl.setScheme(FILE_SCHEME); + } + return DFileService::instance()->createFileInfo(event->sender(), targetUrl); + } + + BookMarkPointer bp = findBookmark(event->url()); + if (!bp) { + BookmarkData data = m_bookmarkDataMap[bookmarkUrl]; + BookMarkPointer item(new BookMark(event->url())); + item->m_created = data.m_created; + item->m_lastModified = data.m_lastModified; + item->mountPoint = data.mountPoint; + item->locateUrl = data.locateUrl; + m_bookmarks[item->sourceUrl()] = item; + return item; + } + + return bp; +} + +DAbstractFileWatcher *BookMarkManager::createFileWatcher(const QSharedPointer &event) const +{ + if (event->url() != DUrl(BOOKMARK_ROOT)) { + return nullptr; + } + + return new BookMarkFileWatcher(event->url()); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/bookmarkmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/bookmarkmanager.h new file mode 100644 index 0000000..ff8b811 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/bookmarkmanager.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef BOOKMARKMANAGER_H +#define BOOKMARKMANAGER_H + +#include "dabstractfilecontroller.h" + +#include "models/bookmark.h" + +#include + +#include + +class DAbstractFileInfo; +class DBookmarkItem; + +struct BookmarkData { + DUrl m_url = DUrl(); + QDateTime m_created = QDateTime(); + QDateTime m_lastModified = QDateTime(); + QString mountPoint = QString(); + QString locateUrl = QString(); + QString udisksDBusPath = QString(); + QString udisksMountPoint = QString(); +}; + +class BookMarkManager : public DAbstractFileController +{ + Q_OBJECT +public: + explicit BookMarkManager(QObject *parent = nullptr); + ~BookMarkManager() override; + + bool checkExist(const DUrl &url); + + bool renameFile(const QSharedPointer &event) const override; + bool deleteFiles(const QSharedPointer &event) const override; + bool touch(const QSharedPointer &event) const override; + bool setPermissions(const QSharedPointer &event) const override; + + bool removeBookmark(const QSharedPointer &event) const override; + + const QList getChildren(const QSharedPointer &event) const override; + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + + bool onFileRenamed(const DUrl &from, const DUrl &to); + void refreshBookmark(); + const DUrlList getBookmarkUrls(); + +private: + BookMarkPointer findBookmark(const DUrl &url) const; + BookmarkData findBookmarkData(const DUrl &url) const; + mutable QMap m_bookmarks; + mutable QMap m_bookmarkDataMap; + + void update(const QVariant &value); + void onFileEdited(const QString &group, const QString &key, const QVariant &value); +// std::deque> m_tagBookmarks{}; +}; + +#endif // BOOKMARKMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/configuration/quicksearchdaemon.xml b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/configuration/quicksearchdaemon.xml new file mode 100644 index 0000000..f9a8b3f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/configuration/quicksearchdaemon.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/configuration/tagmanagerdaemon.xml b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/configuration/tagmanagerdaemon.xml new file mode 100644 index 0000000..e94ac28 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/configuration/tagmanagerdaemon.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/deletejobcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/deletejobcontroller.cpp new file mode 100644 index 0000000..64eb55a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/deletejobcontroller.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "deletejobcontroller.h" +#include "dialogs/confirmdeletedialog.h" +#include "app/global.h" +#include "deletejobworker.h" + +DeleteJobController::DeleteJobController(QObject *parent) : QObject(parent) +{ + initConnect(); +} + +void DeleteJobController::initConnect(){ + +} + +void DeleteJobController::createDeleteJob(const QStringList &files){ + DeletejobWorker* worker = new DeletejobWorker(files); + connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater())); + emit worker->startJob(); + qDebug() << worker; +} + +DeleteJobController::~DeleteJobController() +{ + +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/deletejobcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/deletejobcontroller.h new file mode 100644 index 0000000..ff74503 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/deletejobcontroller.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DELETEJOBCONTROLLER_H +#define DELETEJOBCONTROLLER_H + +#include + +#include +#include + +class DeleteJobInterface; + +class DeleteJobController : public QObject +{ + Q_OBJECT +public: + explicit DeleteJobController(QObject *parent = 0); + ~DeleteJobController(); + + void initConnect(); + +signals: + +public slots: + void createDeleteJob(const QStringList& files); +}; + +#endif // DELETEJOBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/deletejobworker.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/deletejobworker.cpp new file mode 100644 index 0000000..f33ef97 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/deletejobworker.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "deletejobworker.h" +#include "dialogs/confirmdeletedialog.h" +#include "app/global.h" + +DeletejobWorker::DeletejobWorker(const QStringList &files, QObject *parent): + QObject(parent), + m_deletefiles(files) +{ + m_progressTimer = new QTimer; + m_progressTimer->setInterval(1000); + m_time = new QTime; + initConnect(); +} + +void DeletejobWorker::initConnect(){ + connect(this, SIGNAL(startJob()), this, SLOT(start())); + connect(this, SIGNAL(finished()), this, SLOT(handleFinished())); + connect(m_progressTimer, SIGNAL(timeout()), this, SLOT(handleTimeout())); + +} + +void DeletejobWorker::start(){ + deleteFiles(m_deletefiles); +} + +void DeletejobWorker::deleteFiles(const QStringList &files){ + qDebug() << "delete" < reply = dbusController->getFileOperationsInterface()->NewDeleteJob(files, false, "", "", ""); +// reply.waitForFinished(); +// if (!reply.isError()){ +// QString service = reply.argumentAt(0).toString(); +// QString path = qdbus_cast(reply.argumentAt(1)).path(); +// qDebug() << "delete files" << files << path; + +// m_deletejobPath = path; +// m_jobDetail.insert("jobPath", path); +// m_jobDetail.insert("type", "delete"); + +// m_deleteJobInterface = new DeleteJobInterface(service, path, QDBusConnection::sessionBus(), this); +// connectDeleteJobSignal(); +// m_deleteJobInterface->Execute(); + +// m_progressTimer->start(); +// m_time->start(); +// emit signalManager->deleteJobAdded(m_jobDetail); +// }else{ +// qCritical() << reply.error().message(); +// } +} + +void DeletejobWorker::connectDeleteJobSignal(){ + +} + +void DeletejobWorker::disconnectDeleteJobSignal(){ + +} + + +void DeletejobWorker::deleteJobExcuteFinished(){ + + qDebug() << "delete job finished"; +} + +void DeletejobWorker::deleteJobAbort(){ + +} + +void DeletejobWorker::deleteJobAbortFinished(){ + deleteJobExcuteFinished(); + qDebug() << "delete job aborted"; +} + + +void DeletejobWorker::onDeletingFile(QString file){ + qDebug() << "onDeletingFile" << file; + + m_jobDataDetail.insert("file", QFileInfo(decodeUrl(file)).fileName()); + qDebug() << "onCopyingFile" << file; +} + +void DeletejobWorker::setTotalAmount(qlonglong amount, ushort type){ + qDebug() << "========="<< amount << type; + if (type == 0){ + m_totalAmout = amount; + } +} + +void DeletejobWorker::onDeletingProcessAmount(qlonglong progress, ushort info){ + if (info == 0){ + m_currentProgress = progress; + } + qDebug() << "onDeletingProcessAmount" << progress << info; +} + +void DeletejobWorker::onProcessedPercent(qlonglong percent){ + m_processedPercent = percent; + m_jobDataDetail.insert("progress", QString::number(percent)); + qDebug() << percent; +} + +void DeletejobWorker::handleTimeout(){ + float speed; + int remainTime; + QString speedString; + if (m_currentProgress - m_lastProgress > 1024 *1024){ + speed = (m_currentProgress - m_lastProgress) / (1024 * 1024); + speedString = QString("%1 M/s").arg(QString::number(speed)); + }else{ + speed = (m_currentProgress - m_lastProgress) / 1024; + speedString = QString("%1 Kb/s").arg(QString::number(speed)); + } + if (m_currentProgress - m_lastProgress > 0){ + remainTime = (m_totalAmout - m_currentProgress) / (m_currentProgress - m_lastProgress); + } + m_lastProgress = m_currentProgress; + + m_jobDataDetail.insert("speed", speedString); + m_jobDataDetail.insert("remainTime", QString("%1 s").arg(QString::number(remainTime))); +} + +void DeletejobWorker::handleFinished(){ + +} + +void DeletejobWorker::handleTaskAborted(const QMap &jobDetail){ + if (jobDetail == m_jobDetail){ + deleteJobAbort(); + } +} + +DeletejobWorker::~DeletejobWorker() +{ + +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/deletejobworker.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/deletejobworker.h new file mode 100644 index 0000000..3ad00c7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/deletejobworker.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DELETEJOBWORKER_H +#define DELETEJOBWORKER_H + +#include +#include +#include +#include +#include +class DeleteJobInterface; + + +class DeletejobWorker : public QObject +{ + Q_OBJECT +public: + explicit DeletejobWorker(const QStringList& files, QObject *parent = 0); + ~DeletejobWorker(); + void initConnect(); + +signals: + void startJob(); + void finished(); + +public slots: + void start(); + void deleteFiles(const QStringList& files); + void connectDeleteJobSignal(); + void disconnectDeleteJobSignal(); + void deleteJobExcuteFinished(); + void deleteJobAbort(); + void deleteJobAbortFinished(); + void onDeletingFile(QString file); + void setTotalAmount(qlonglong amount, ushort type); + void onDeletingProcessAmount(qlonglong progress, ushort info); + void onProcessedPercent(qlonglong percent); + void handleTimeout(); + void handleFinished(); + void handleTaskAborted(const QMap& jobDetail); + +private: + DeleteJobInterface* m_deleteJobInterface = NULL; + QStringList m_deletefiles; + + QString m_deletejobPath; + QTimer* m_progressTimer; + QMap m_jobDetail; + QMap m_jobDataDetail; + qlonglong m_totalAmout; + QTime* m_time; + qlonglong m_lastProgress = 0; + qlonglong m_currentProgress = 0; + qlonglong m_processedPercent = 0; + int m_elapsedTime; +}; + +#endif // DELETEJOBWORKER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmappentrycontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmappentrycontroller.cpp new file mode 100644 index 0000000..998e510 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmappentrycontroller.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2021 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: lanxuesong + * zhangsheng + * max-lv + * + * 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 + * 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 . + */ + +#include "interfaces/dabstractfileinfo.h" +#include "models/dfmappentryfileinfo.h" +#include "dfmappentrycontroller.h" +#include "dfmevent.h" +#include "dfmstandardpaths.h" +#include "private/dabstractfilewatcher_p.h" +#include "dfileproxywatcher.h" +#include "dfilewatcher.h" +#include "app/define.h" + +#include + +const QList DFMAppEntryController::getChildren(const QSharedPointer &event) const +{ + Q_UNUSED(event); + + static const QString appEntryPath = DFMStandardPaths::location(DFMStandardPaths::ExtensionsAppEntryPath); + QDir appEntryDir(appEntryPath); + if (!appEntryDir.exists()) + return {}; + + QList ret; + auto entries = appEntryDir.entryList(QDir::Files); + QList cmds; // for de-duplication + for (auto entry: entries) { + if (entry.endsWith(".desktop")) + entry.remove(QRegularExpression(".desktop$")); + // make the url to `appentry:///helloworld` to support a convinience way to open in search bar. + DUrl appEntryUrl(APPENTRY_ROOT + entry); + DAbstractFileInfoPointer fp(new DFMAppEntryFileInfo(appEntryUrl)); + if (!fp->exists()) { + qInfo() << "the appentry is in extension folder but not exist: " << fp->fileUrl(); + continue; + } + auto entryInfo = dynamic_cast(fp.data()); + if (!entryInfo) + continue; + if (cmds.contains(entryInfo->cmd())) + continue; + cmds.append(entryInfo->cmd()); + ret << fp; + } + return ret; +} + +const DAbstractFileInfoPointer DFMAppEntryController::createFileInfo(const QSharedPointer &event) const +{ + return DAbstractFileInfoPointer(new DFMAppEntryFileInfo(event->url())); +} + +DAbstractFileWatcher *DFMAppEntryController::createFileWatcher(const QSharedPointer &event) const +{ + Q_UNUSED(event); + auto entryPath = DFMStandardPaths::location(DFMStandardPaths::ExtensionsAppEntryPath); + DUrl entryUrl(entryPath); + auto watcher = new DFileProxyWatcher(entryUrl, new DFileWatcher(entryPath), DFMAppEntryController::localToAppEntry); + return watcher; +} + +bool DFMAppEntryController::openFile(const QSharedPointer &event) const +{ + auto e = dMakeEventPointer(event->sender(), event->url()); + auto info = createFileInfo(e); + auto appEntryInfo = dynamic_cast(info.data()); + if (appEntryInfo) { + auto cmd = appEntryInfo->cmd(); + auto ret = QProcess::startDetached(cmd); + if (!ret) { + qWarning() << "QProcess::startDetached(" << cmd << ") failed!"; + } + return ret; + } + qWarning() << "Cannot get the appEntryInfo!"; + return false; +} + +DUrl DFMAppEntryController::localToAppEntry(const DUrl &local) +{ + auto path = local.path(); + static const auto entryPath = DFMStandardPaths::location(DFMStandardPaths::ExtensionsAppEntryPath) + "/"; + if (!path.startsWith(entryPath)) { + qWarning() << "Not extension path: " << entryPath; + return DUrl(); + } + if (!path.endsWith(".desktop")) { + qWarning() << "Not entry file: " << entryPath; + return DUrl(); + } + QFileInfo entryFile(path); + if (entryFile.isDir()) { + qWarning() << "Not entry file: " << entryPath; + return DUrl(); + } + + path.remove(entryPath).remove(QRegularExpression(".desktop$")); + qDebug() << "converted path is: " << path; + return DUrl(APPENTRY_ROOT + path); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmappentrycontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmappentrycontroller.h new file mode 100644 index 0000000..3e2b3f6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmappentrycontroller.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2021 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: lanxuesong + * zhangsheng + * max-lv + * + * 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 + * 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 . + */ + +#ifndef DFMAPPENTRYCONTROLLER_H +#define DFMAPPENTRYCONTROLLER_H + +#include "dabstractfilecontroller.h" + +class DFMAppEntryController: public DAbstractFileController +{ + Q_OBJECT +public: + explicit DFMAppEntryController(QObject *parent = nullptr): DAbstractFileController (parent) {} + const QList getChildren(const QSharedPointer &event) const override; + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + bool openFile(const QSharedPointer &event) const override; + + static DUrl localToAppEntry(const DUrl &local); +}; + +#endif // DFMAPPENTRYCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmavfscrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmavfscrumbcontroller.cpp new file mode 100644 index 0000000..ebaa133 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmavfscrumbcontroller.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmavfscrumbcontroller.h" + +#include "dfileservices.h" +#include "dfileinfo.h" +DFM_BEGIN_NAMESPACE + +DFMAvfsCrumbController::DFMAvfsCrumbController(QObject *parent) + : DFMFileCrumbController(parent) +{ + +} + +DFMAvfsCrumbController::~DFMAvfsCrumbController() +{ + +} + +bool DFMAvfsCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == AVFS_SCHEME); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmavfscrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmavfscrumbcontroller.h new file mode 100644 index 0000000..0c0c564 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmavfscrumbcontroller.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMAVFSCRUMBCONTROLLER_H +#define DFMAVFSCRUMBCONTROLLER_H + +#include "controllers/dfmfilecrumbcontroller.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMAvfsCrumbController : public DFMFileCrumbController +{ +public: + explicit DFMAvfsCrumbController(QObject *parent = nullptr); + ~DFMAvfsCrumbController(); + + bool supportedUrl(DUrl url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMAVFSCRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmbookmarkcrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmbookmarkcrumbcontroller.cpp new file mode 100644 index 0000000..eaf47e9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmbookmarkcrumbcontroller.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmbookmarkcrumbcontroller.h" + +DFM_BEGIN_NAMESPACE + +DFMBookmarkCrumbController::DFMBookmarkCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMBookmarkCrumbController::~DFMBookmarkCrumbController() +{ + +} + +bool DFMBookmarkCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == BOOKMARK_SCHEME); +} + +QList DFMBookmarkCrumbController::seprateUrl(const DUrl &url) +{ + Q_UNUSED(url); + return { CrumbData(DUrl(BOOKMARK_ROOT), QObject::tr("Bookmarks"), "CrumbIconButton.Bookmarks") }; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmbookmarkcrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmbookmarkcrumbcontroller.h new file mode 100644 index 0000000..4449f97 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmbookmarkcrumbcontroller.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMBOOKMARKCRUMBCONTROLLER_H +#define DFMBOOKMARKCRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMBookmarkCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMBookmarkCrumbController(QObject *parent = nullptr); + ~DFMBookmarkCrumbController() override; + + bool supportedUrl(DUrl url) override; + QList seprateUrl(const DUrl &url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMBOOKMARKCRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmcomputercrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmcomputercrumbcontroller.cpp new file mode 100644 index 0000000..fa0edcb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmcomputercrumbcontroller.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dfmcomputercrumbcontroller.h" +#include "controllers/pathmanager.h" +#include "singleton.h" + +DFM_BEGIN_NAMESPACE + +DFMComputerCrumbController::DFMComputerCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMComputerCrumbController::~DFMComputerCrumbController() +{ + +} + +bool DFMComputerCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == COMPUTER_SCHEME); +} + +QList DFMComputerCrumbController::seprateUrl(const DUrl &url) +{ + Q_UNUSED(url); + QString text = Singleton::instance()->getSystemPathDisplayName("Computer"); + QString iconName = Singleton::instance()->getSystemPathIconName("Computer"); + return { CrumbData(DUrl::fromComputerFile("/"), text, iconName) }; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmcomputercrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmcomputercrumbcontroller.h new file mode 100644 index 0000000..cc13a7d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmcomputercrumbcontroller.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMCOMPUTERCRUMBCONTROLLER_H +#define DFMCOMPUTERCRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMComputerCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMComputerCrumbController(QObject *parent = nullptr); + ~DFMComputerCrumbController() override; + + bool supportedUrl(DUrl url) override; + QList seprateUrl(const DUrl &url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMCOMPUTERCRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmfilecrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmfilecrumbcontroller.cpp new file mode 100644 index 0000000..698b8f9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmfilecrumbcontroller.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmfilecrumbcontroller.h" +#include "controllers/pathmanager.h" +#include "deviceinfo/udiskdeviceinfo.h" +#include "deviceinfo/udisklistener.h" + +#include "dfileservices.h" +#include "dfileinfo.h" +#include "app/define.h" +#include "singleton.h" + +#include +#include + +#include + +DFM_BEGIN_NAMESPACE + +DFMFileCrumbController::DFMFileCrumbController(QObject *parent) + : DFMCrumbInterface(parent) + , homePath(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).last()) +{ + +} + +DFMFileCrumbController::~DFMFileCrumbController() +{ + +} + +bool DFMFileCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == FILE_SCHEME); +} + +QList DFMFileCrumbController::seprateUrl(const DUrl &url) +{ + QList list; + QString prefixPath = "/"; + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, url); + const QString &path = info->toLocalFile(); + + if (path.isEmpty()) { + return list; + } + + if (path.startsWith(homePath)) { + prefixPath = homePath; + QString iconName = Singleton::instance()->getSystemPathIconName("Home"); + CrumbData data(DUrl::fromLocalFile(homePath), getDisplayName("Home"), iconName); + list.append(data); + } else { + QStorageInfo storageInfo(path); + UDiskDeviceInfoPointer deviceInfo = deviceListener->getDeviceByPath(path); + if (!deviceInfo) { + deviceInfo = deviceListener->getDeviceByFilePath(path); + } + QString iconName = QStringLiteral("drive-harddisk-symbolic"); + prefixPath = storageInfo.rootPath(); + if (deviceInfo) { + switch (deviceInfo->getMediaType()) { + case UDiskDeviceInfo::MediaType::removable: + iconName = QStringLiteral("drive-removable-media-symbolic"); + break; + case UDiskDeviceInfo::MediaType::dvd: + iconName = QStringLiteral("media-optical-symbolic"); + break; + case UDiskDeviceInfo::MediaType::phone: + iconName = QStringLiteral("phone-symbolic"); + break; + case UDiskDeviceInfo::MediaType::iphone: + iconName = QStringLiteral("phone-apple-iphone-symbolic"); + break; + case UDiskDeviceInfo::MediaType::camera: + iconName = QStringLiteral("camera-photo-symbolic"); + break; + default: + break; + } + } + + if (prefixPath == "/") { + CrumbData data(DUrl(FILE_ROOT), getDisplayName("System Disk"), "drive-harddisk-root-symbolic"); + list.append(data); + } else { + CrumbData data(DUrl::fromLocalFile(prefixPath), QString(), iconName); + list.append(data); + } + } + + DUrlList urlList = info->parentUrlList(); + urlList.insert(0, url); + + DAbstractFileInfoPointer infoPointer; + // Push urls into crumb list (without prefix url) + DUrlList::const_reverse_iterator iter = urlList.crbegin(); + while (iter != urlList.crend()) { + const DUrl &oneUrl = *iter; + QString localFile = oneUrl.toLocalFile(); + if (!prefixPath.startsWith(oneUrl.toLocalFile())) { + QString displayText = oneUrl.fileName(); + // Check for possible display text. + infoPointer = DFileService::instance()->createFileInfo(nullptr, oneUrl); + if (infoPointer) { + displayText = infoPointer->fileDisplayName(); + } + CrumbData data(oneUrl, displayText); + list.append(data); + } + ++iter; + } + + return list; +} + +// blumia: avoid using this, recommand using the following way: +// DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, oneUrl); +// then you can get a proper display name via `info->fileDisplayName()`. +// We are using this since not all path can got a proper display name yet. +// TODO: When backend is ready, switch to DAbstractFileInfo::fileDisplayName(). +QString DFMFileCrumbController::getDisplayName(const QString &name) const +{ + QString text = Singleton::instance()->getSystemPathDisplayName(name); + return text.isEmpty() ? name : text; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmfilecrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmfilecrumbcontroller.h new file mode 100644 index 0000000..113d1eb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmfilecrumbcontroller.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMFILECRUMBCONTROLLER_H +#define DFMFILECRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +DFM_BEGIN_NAMESPACE + +class DFMFileCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMFileCrumbController(QObject *parent = nullptr); + ~DFMFileCrumbController() override; + + bool supportedUrl(DUrl url) override; + QList seprateUrl(const DUrl &url) override; + +private: + QString homePath = QString(); + + QString getDisplayName(const QString& name) const; +}; + +DFM_END_NAMESPACE + +#endif // DFMFILECRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmftpcrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmftpcrumbcontroller.cpp new file mode 100644 index 0000000..507d94d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmftpcrumbcontroller.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Li yigang + * + * Maintainer: Li yigang + * + * 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 + * 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 . + */ +#include "dfmftpcrumbcontroller.h" +#include "dfileservices.h" + +DFM_BEGIN_NAMESPACE + +DFMFtpCrumbController::DFMFtpCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMFtpCrumbController::~DFMFtpCrumbController() +{ + +} + +bool DFMFtpCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == FTP_SCHEME); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmftpcrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmftpcrumbcontroller.h new file mode 100644 index 0000000..76d3307 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmftpcrumbcontroller.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Li yigang + * + * Maintainer: Li yigang + * + * 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 + * 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 . + */ +#ifndef DFMFTPCRUMBCONTROLLER_H +#define DFMFTPCRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMFtpCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMFtpCrumbController(QObject *parent = nullptr); + ~DFMFtpCrumbController() override; + + bool supportedUrl(DUrl url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMSMBCRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmasteredmediacrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmasteredmediacrumbcontroller.cpp new file mode 100644 index 0000000..fd3ce20 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmasteredmediacrumbcontroller.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmmasteredmediacrumbcontroller.h" + +#include "dfileservices.h" + +DFM_BEGIN_NAMESPACE + +DFMMasteredMediaCrumbController::DFMMasteredMediaCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} +DFMMasteredMediaCrumbController::~DFMMasteredMediaCrumbController() +{ +} + +bool DFMMasteredMediaCrumbController::supportedUrl(DUrl url) +{ + return url.scheme() == BURN_SCHEME; +} + +QList DFMMasteredMediaCrumbController::seprateUrl(const DUrl &url) +{ + QList ret; + DUrl cururl(url); + while (true) { + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, cururl); + if (!info) { + break; + } + QString displayText = info->fileDisplayName(); + ret.push_front(CrumbData(cururl, displayText)); + if (info->parentUrl() == DUrl::fromLocalFile(QDir::homePath())) { + ret.front().iconName = "media-optical-symbolic"; + break; + } + cururl = info->parentUrl(); + } + return ret; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmasteredmediacrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmasteredmediacrumbcontroller.h new file mode 100644 index 0000000..ac4d685 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmasteredmediacrumbcontroller.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMMASTEREDMEDIACRUMBCONTROLLER_H +#define DFMMASTEREDMEDIACRUMBCONTROLLER_H + +#include "dfmcrumbinterface.h" + +DFM_BEGIN_NAMESPACE + +class DFMMasteredMediaCrumbController : public DFMCrumbInterface +{ + Q_OBJECT +public: + explicit DFMMasteredMediaCrumbController(QObject *parent = nullptr); + ~DFMMasteredMediaCrumbController(); + + bool supportedUrl(DUrl url) override; + QList seprateUrl(const DUrl &url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMMASTEREDMEDIACRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmdcrumbcontrooler.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmdcrumbcontrooler.cpp new file mode 100644 index 0000000..6bd1cbd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmdcrumbcontrooler.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmmdcrumbcontrooler.h" + +DFM_BEGIN_NAMESPACE + +DFMMDCrumbControoler::DFMMDCrumbControoler(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMMDCrumbControoler::~DFMMDCrumbControoler() +{ + +} + +bool DFMMDCrumbControoler::supportedUrl(DUrl url) +{ + return (url.scheme() == DFMMD_SCHEME); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmdcrumbcontrooler.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmdcrumbcontrooler.h new file mode 100644 index 0000000..ce96615 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmdcrumbcontrooler.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMMDCRUMBCONTROLLER_H +#define DFMMDCRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +// DFM Merged Desktop (dfmmd://) scheme, crumb support +class DFMMDCrumbControoler : public DFMCrumbInterface +{ +public: + explicit DFMMDCrumbControoler(QObject *parent = nullptr); + ~DFMMDCrumbControoler() override; + + bool supportedUrl(DUrl url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMMDCRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmtpcrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmtpcrumbcontroller.cpp new file mode 100644 index 0000000..3a4f596 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmtpcrumbcontroller.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmmtpcrumbcontroller.h" + +DFM_BEGIN_NAMESPACE + +DFMMtpCrumbController::DFMMtpCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMMtpCrumbController::~DFMMtpCrumbController() +{ + +} + +bool DFMMtpCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == MTP_SCHEME); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmtpcrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmtpcrumbcontroller.h new file mode 100644 index 0000000..bf474e7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmmtpcrumbcontroller.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMMTPCRUMBCONTROLLER_H +#define DFMMTPCRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMMtpCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMMtpCrumbController(QObject *parent = nullptr); + ~DFMMtpCrumbController() override; + + bool supportedUrl(DUrl url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMMTPCRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmnetworkcrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmnetworkcrumbcontroller.cpp new file mode 100644 index 0000000..9d686c9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmnetworkcrumbcontroller.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dfmnetworkcrumbcontroller.h" +#include "pathmanager.h" + +#include "singleton.h" + +DFM_BEGIN_NAMESPACE + +DFMNetworkCrumbController::DFMNetworkCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMNetworkCrumbController::~DFMNetworkCrumbController() +{ + +} + +bool DFMNetworkCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == NETWORK_SCHEME); +} + +QList DFMNetworkCrumbController::seprateUrl(const DUrl &url) +{ + Q_UNUSED(url); + QString displayText = Singleton::instance()->getSystemPathDisplayName("Network"); + QString iconName = Singleton::instance()->getSystemPathIconName("Network"); + return { CrumbData(DUrl(NETWORK_ROOT), displayText, iconName) }; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmnetworkcrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmnetworkcrumbcontroller.h new file mode 100644 index 0000000..f349c21 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmnetworkcrumbcontroller.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMNETWORKCRUMBCONTROLLER_H +#define DFMNETWORKCRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMNetworkCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMNetworkCrumbController(QObject *parent = nullptr); + ~DFMNetworkCrumbController() override; + + bool supportedUrl(DUrl url) override; + QList seprateUrl(const DUrl &url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMNETWORKCRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmrecentcrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmrecentcrumbcontroller.cpp new file mode 100644 index 0000000..f064699 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmrecentcrumbcontroller.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmrecentcrumbcontroller.h" +#include "dfileservices.h" +#include "pathmanager.h" +#include "singleton.h" + +#include + +DFM_BEGIN_NAMESPACE + +DFMRecentCrumbController::DFMRecentCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +bool DFMRecentCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == RECENT_SCHEME); +} + +QList DFMRecentCrumbController::seprateUrl(const DUrl &url) +{ + Q_UNUSED(url); + QString displayText = Singleton::instance()->getSystemPathDisplayName("Recent"); + QString iconName = Singleton::instance()->getSystemPathIconName("Recent"); + return { CrumbData(DUrl(RECENT_ROOT), displayText, iconName) }; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmrecentcrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmrecentcrumbcontroller.h new file mode 100644 index 0000000..1c269e4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmrecentcrumbcontroller.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMRECENTCONTROLLER_H +#define DFMRECENTCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMRecentCrumbController : public DFMCrumbInterface +{ + Q_OBJECT + +public: + explicit DFMRecentCrumbController(QObject *parent = nullptr); + + bool supportedUrl(DUrl url) override; + QList seprateUrl(const DUrl &url) override; + +private: + QString homePath = QString(); + + QString getDisplayName(const QString& name) const; +}; + +DFM_END_NAMESPACE + +#endif // DFMRECENTCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmrootcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmrootcontroller.cpp new file mode 100644 index 0000000..ae14b09 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmrootcontroller.cpp @@ -0,0 +1,674 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmrootcontroller.h" +#include "dfmevent.h" +#include "dfmapplication.h" +#include "dfmglobal.h" +#include "models/dfmrootfileinfo.h" +#include "private/dabstractfilewatcher_p.h" +#include "utils/singleton.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "shutil/fileutils.h" +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "dialogs/dialogmanager.h" +#include "deviceinfo/udisklistener.h" +#include +#include +#include +#include +#include + +DFM_USE_NAMESPACE + +class DFMRootFileWatcherPrivate : public DAbstractFileWatcherPrivate +{ +public: + explicit DFMRootFileWatcherPrivate(DFMRootFileWatcher *qq) + : DAbstractFileWatcherPrivate(qq) {} + + bool start() override; + bool stop() override; + bool handleGhostSignal(const DUrl &target, DAbstractFileWatcher::SignalType1 signal, const DUrl &url) override; + +protected: + void initBlockDevConnections(QSharedPointer blk, const QString &devs); + +private: + QSharedPointer vfsmgr; + QSharedPointer udisksmgr; + QList connections; + QList> blkdevs; + QStringList connectionsurl; + + Q_DECLARE_PUBLIC(DFMRootFileWatcher) +}; + +static bool ignoreBlkDevice(const QString& blkPath, QSharedPointer blk, QSharedPointer drv) +{ + if (blk->hintIgnore()) { + qWarning() << "block device is ignored by hintIgnore:" << blkPath; + return true; + } + + if (!blk->hasFileSystem() && !drv->mediaCompatibility().join(" ").contains("optical") && !blk->isEncrypted()) { + if (!drv->removable()){ // 满足外围条件的本地磁盘,直接遵循以前的处理直接 continue + qWarning() << "block device is ignored by wrong removeable set for system disk:" << blkPath; + return true; + } + } + + if (blk->cryptoBackingDevice().length() > 1) { + qWarning() << "block device is ignored by crypted back device:" << blkPath; + return true; + } + + // 是否是设备根节点,设备根节点无须记录 + if(blk->hasPartitionTable()){ // 替换 FileUtils::deviceShouldBeIgnore + qDebug() << "block device is ignored by parent node:" << blkPath; + return true; + } + + // 过滤snap产生的loop设备 + if(blk->isLoopDevice()){ + qDebug() << "block device is ignored by loop device:" << blkPath; + return true; + } + + if(blk->hasPartition()){ + QSharedPointer partition(DDiskManager::createBlockPartition(blkPath)); + if(!partition.isNull()){ + DBlockPartition::Type type = partition->eType(); + switch (type) { + //Extended partition with CHS addressing. It must reside within the first physical 8 GB of disk, else use 0Fh instead (see 0Fh, 85h, C5h, D5h) + case DBlockPartition::Win95_Extended_LBA: + case DBlockPartition::Linux_extended: + case DBlockPartition::DRDOS_sec_extend: + case DBlockPartition::Multiuser_DOS_extend: + case DBlockPartition::Extended:{ + qWarning() << "block device is ignored by partion type:" << partition->type() <<","<< blkPath; + return true; + } + default: + break; + } + } + } + return false; +} + +DFMRootController::DFMRootController(QObject *parent) : DAbstractFileController(parent) +{ + +} + +bool DFMRootController::renameFile(const QSharedPointer &event) const +{ + DAbstractFileInfoPointer fi(new DFMRootFileInfo(event->fromUrl())); + if (!fi->canRename()) { + return false; + } + + DFMRootFileInfo *rootFi = dynamic_cast(fi.data()); + if (rootFi && rootFi->canSetAlias()) + return setLocalDiskAlias(rootFi, event->toUrl().path()); + + QString udiskspath = fi->extraProperties()["udisksblk"].toString(); + QScopedPointer blk(DDiskManager::createBlockDevice(udiskspath)); + Q_ASSERT(blk && blk->path().length() > 0); + + const QString &curName = rootFi->udisksDisplayName(); + const QString &destName = event->toUrl().path(); + if (curName == destName) + return true; + + blk->setLabel(destName, {}); + if (blk->lastError().type() != QDBusError::NoError) { + qDebug() << blk->lastError() << blk->lastError().name(); + } + + return blk->lastError().type() == QDBusError::NoError; +} + +void DFMRootController::reloadBlkName(const QString& blkPath, QSharedPointer blk) const +{ + //检查挂载目录下是否存在diskinfo文件 + QByteArrayList mps = blk->mountPoints(); + if (mps.empty()) { + qWarning() << "failed to reload block device name for:" << blkPath; + return; + } + QString mpPath(mps.front()); + if (mpPath.lastIndexOf("/") != (mpPath.length() - 1)) + mpPath += "/"; + QDir kidDir(mpPath + "UOSICON"); + if (kidDir.exists()) { + QString jsonPath = kidDir.absolutePath(); + loadDiskInfo(jsonPath); + } +} + +const QList DFMRootController::getChildren(const QSharedPointer &event) const +{ + QList ret; + + if (event->url().scheme() != DFMROOT_SCHEME || event->url().path() != "/") { + return ret; + } + + static const QList udir = {"desktop", "videos", "music", "pictures", "documents", "downloads"}; + for (auto d : udir) { + DAbstractFileInfoPointer fp(new DFMRootFileInfo(DUrl(DFMROOT_ROOT + d + "." SUFFIX_USRDIR))); + if (fp->exists()) { + ret.push_back(fp); + } + } + + QStringList blkds = DDiskManager::blockDevices({}); + for (auto blks : blkds) { + QSharedPointer blk(DDiskManager::createBlockDevice(blks)); + QSharedPointer drv(DDiskManager::createDiskDevice(blk->drive())); + if(ignoreBlkDevice(blks, blk, drv)){ + continue; + } + + reloadBlkName(blks, blk); + + using namespace DFM_NAMESPACE; + if (DFMApplication::genericAttribute(DFMApplication::GA_HiddenSystemPartition).toBool() && blk->hintSystem()) { + qDebug() << "block device is ignored by hintSystem&HiddenSystemPartition:" << blks; + continue; + } + + DAbstractFileInfoPointer fp(new DFMRootFileInfo(DUrl(DFMROOT_ROOT + QString(blk->device()).mid(QString("/dev/").length()) + "." SUFFIX_UDISKS))); + ret.push_back(fp); + } + + for (auto gvfsvol : DGioVolumeManager::getVolumes()) { + if (gvfsvol->volumeMonitorName().contains(QRegularExpression("(MTP|GPhoto2|Afc)$")) && !gvfsvol->getMount()) { + gvfsvol->mount(); + } + } + if (event->canconst()) { + return ret; + } + //寻找所有的移动设备(移动硬盘,手机,U盘等) + QStringList urllist; + for (auto gvfsmp : DGioVolumeManager::getMounts()) { + auto volume = gvfsmp->getVolume(); + if (volume && volume->volumeMonitorName().endsWith("UDisks2")) + continue; + if (gvfsmp->mountClass() == "GUnixMount") + continue; + + auto rootFile = gvfsmp->getRootFile(); + if (!rootFile) + continue; + + if (DUrl(rootFile->uri()).scheme() == BURN_SCHEME) + continue; + // fix bug 60719. 分区编辑器打开后,原本该被过滤的由 udisks2 控制的磁盘,现无法过滤了,导致缓存中的 udisks2 磁盘显示一次 + // 在这里的 gvfs 里又显示一次,且数据内容不一致。 + // 因此,在这里通过过滤 /meida/ 目录挂载点的方式,来过滤 udisks2 设备(udisks2 在默认情况下都是挂载磁盘到 /media/$USER/ 目录下) + // 手动 sudo mount 挂载的设备不会被 Gio 捕获,因此不用考虑手动使用 mount 挂载到 /media 目录下的磁盘被过滤 + if (rootFile->uri().startsWith("file:///media/")) + continue; + + DUrl url; + url.setScheme(DFMROOT_SCHEME); + url.setPath("/" + QUrl::toPercentEncoding(rootFile->path()) + "." SUFFIX_GVFSMP); + + if (urllist.contains(QString("/" + QUrl::toPercentEncoding(rootFile->path()) + "." SUFFIX_GVFSMP))) + continue; + DAbstractFileInfoPointer fp(new DFMRootFileInfo(url)); + if (fp->exists()) { + urllist << QString("/" + QUrl::toPercentEncoding(rootFile->path()) + "." SUFFIX_GVFSMP); + ret.push_back(fp); + } + } + + // get the not connected, storaged remote connection + if (DFMApplication::genericAttribute(DFMApplication::GA_AlwaysShowOfflineRemoteConnections).toBool()) { + const QList &&stashedMounts = RemoteMountsStashManager::remoteMounts(); + qDebug() << stashedMounts; + for (const auto &mount: stashedMounts) { + if (!mount.contains(REMOTE_KEY)) + continue; + auto key = mount.value(REMOTE_KEY).toString() + "." + SUFFIX_GVFSMP; + auto encodedKey = QUrl::toPercentEncoding(key); + encodedKey.prepend("/"); + qDebug() << encodedKey; + if (urllist.contains(encodedKey)) { + qDebug() << "stashed mount is mounted" << mount; + continue; + } + + // ftp sometimes do not have share field + if (!(mount.contains(REMOTE_PROTOCOL) && mount.contains(REMOTE_HOST))) { + qWarning() << "invalid stashed remote connection: " << mount; + continue; + } + auto protocol = mount.value(REMOTE_PROTOCOL).toString(); + auto host = mount.value(REMOTE_HOST).toString(); + auto share = mount.value(REMOTE_SHARE).toString(); + if (protocol.isEmpty() || host.isEmpty()) { + qWarning() << "protocol or host is empty: " << mount; + continue; + } + + QString path = QString("%1://%2/%3").arg(protocol).arg(host).arg(share); + path.append(QString(".%1").arg(SUFFIX_STASHED_REMOTE)); + path.prepend(DFMROOT_ROOT); + qDebug() << "get stashed remote connection: " << path; + + auto stashedMountInfo = new DFMRootFileInfo(DUrl::fromPercentEncoding(path.toUtf8())); + DAbstractFileInfoPointer fp(stashedMountInfo); + ret.push_back(fp); + } + } + + qInfo() << "get rootfileinfo over !" << ret; + for(auto item: ret) { + qInfo() << item->fileUrl(); + } + + return ret; +} + +const DAbstractFileInfoPointer DFMRootController::createFileInfo(const QSharedPointer &event) const +{ + return DAbstractFileInfoPointer(new DFMRootFileInfo(event->url())); +} + +DAbstractFileWatcher *DFMRootController::createFileWatcher(const QSharedPointer &event) const +{ + return new DFMRootFileWatcher(event->url()); +} + +void DFMRootController::loadDiskInfo(const QString &jsonPath) const +{ + //不存在该目录 + if (jsonPath.isEmpty()) { + return; + } + + //读取本地json文件 + QFile file(jsonPath + "/diskinfo.json"); + if (!file.open(QIODevice::ReadWrite)) { + return; + } + + //解析json文件 + QJsonParseError jsonParserError; + QJsonDocument jsonDocument = QJsonDocument::fromJson(file.readAll(), &jsonParserError); + if (jsonDocument.isNull() || jsonParserError.error != QJsonParseError::NoError) { + return; + } + + if (jsonDocument.isObject()) { + QJsonObject jsonObject = jsonDocument.object(); + if (jsonObject.contains("DISKINFO") && jsonObject.value("DISKINFO").isArray()) { + QJsonArray jsonArray = jsonObject.value("DISKINFO").toArray(); + for (int i = 0; i < jsonArray.size(); i++) { + if (jsonArray[i].isObject()) { + QJsonObject jsonObjectInfo = jsonArray[i].toObject(); + DiskInfoStr str; + if (jsonObjectInfo.contains("uuid")) + str.uuid = jsonObjectInfo.value("uuid").toString(); + if (jsonObjectInfo.contains("drive")) + str.driver = jsonObjectInfo.value("drive").toString(); + if (jsonObjectInfo.contains("label")) + str.label = jsonObjectInfo.value("label").toString(); + + DFMRootFileInfo::DiskInfoMap[str.uuid] = str; + } + } + } + } +} + +bool DFMRootController::setLocalDiskAlias(DFMRootFileInfo *fi, const QString &alias) const +{ + if (!fi || !fi->canRename() || fi->getUUID().isEmpty()) { + qWarning() << "params 'fi' exception"; + return false; + } + + QString uuid(fi->getUUID()); + QString dispalyAlias(alias.trimmed()); + QString displayName(fi->udisksDisplayName()); + QVariantList list = DFMApplication::genericSetting()->value(DISKALIAS_GROUP, DISKALIAS_ITEMS).toList(); + + // [a] empty alias -> remove from list + // [b] exists alias -> cover it + // [c] not exists -> append + bool exists = false; + for (int i = 0; i < list.count(); i++) { + QVariantMap map = list.at(i).toMap(); + if (map.value(DISKALIAS_ITEM_UUID).toString() == uuid) { + if (dispalyAlias.isEmpty()) { // [a] + list.removeAt(i); + } else { // [b] + map[DISKALIAS_ITEM_NAME] = displayName; + map[DISKALIAS_ITEM_ALIAS] = dispalyAlias; + list[i] = map; + } + exists = true; + break; + } + } + + // [c] + if (!exists && !dispalyAlias.isEmpty() && !uuid.isEmpty()) { + QVariantMap map; + map[DISKALIAS_ITEM_UUID] = uuid; + map[DISKALIAS_ITEM_NAME] = displayName; + map[DISKALIAS_ITEM_ALIAS] = dispalyAlias; + list.append(map); + qInfo() << "append setting item: " << map; + } + + DFMApplication::genericSetting()->setValue(DISKALIAS_GROUP, DISKALIAS_ITEMS, list); + DAbstractFileWatcher::ghostSignal(DUrl(DFMROOT_ROOT), &DAbstractFileWatcher::fileAttributeChanged, fi->fileUrl()); + return true; +} + +DFMRootFileWatcher::DFMRootFileWatcher(const DUrl &url, QObject *parent): + DAbstractFileWatcher(*new DFMRootFileWatcherPrivate(this), url, parent) +{ + +} + +void DFMRootFileWatcherPrivate::initBlockDevConnections(QSharedPointer blk, const QString &devs) +{ + Q_Q(DFMRootFileWatcher); + DFMRootFileWatcher *wpar = qobject_cast(q); + blkdevs.push_back(blk); + blk->setWatchChanges(true); + QString urlstr = DFMROOT_ROOT + devs.mid(QString("/org/freedesktop/UDisks2/block_devices/").length()) + "." SUFFIX_UDISKS; + DUrl url(urlstr); + + if (blk->isEncrypted()) { + QSharedPointer ctblk(DDiskManager::createBlockDevice(blk->cleartextDevice())); + blkdevs.push_back(ctblk); + ctblk->setWatchChanges(true); + foreach (const QString &str, connectionsurl) { + if (str == urlstr + QString("_en")) { + return; + } + } + connections.push_back(QObject::connect(blk.data(), &DBlockDevice::cleartextDeviceChanged, [wpar, url](const QString &) { + Q_EMIT wpar->fileAttributeChanged(url); + })); + connections.push_back(QObject::connect(ctblk.data(), &DBlockDevice::idLabelChanged, [wpar, url](const QString &) { + Q_EMIT wpar->fileAttributeChanged(url); + })); + connections.push_back(QObject::connect(ctblk.data(), &DBlockDevice::mountPointsChanged, [wpar, url](const QByteArrayList &) { + Q_EMIT wpar->fileAttributeChanged(url); + })); + connectionsurl << urlstr + QString("_en"); + } else { + foreach (const QString &str, connectionsurl) { + if (str == urlstr) { + return; + } + } + connections.push_back(QObject::connect(blk.data(), &DBlockDevice::idLabelChanged, [wpar, url](const QString &) { + Q_EMIT wpar->fileAttributeChanged(url); + })); + connections.push_back(QObject::connect(blk.data(), &DBlockDevice::mountPointsChanged, [wpar, url](const QByteArrayList &) { + Q_EMIT wpar->fileAttributeChanged(url); + })); + + connections.push_back(QObject::connect(blk.data(), &DBlockDevice::sizeChanged, [wpar, url](qulonglong) { + Q_EMIT wpar->fileAttributeChanged(url); + })); + connections.push_back(QObject::connect(blk.data(), &DBlockDevice::idTypeChanged, [wpar, url](QString) { + Q_EMIT wpar->fileAttributeChanged(url); + })); + connections.push_back(QObject::connect(blk.data(), &DBlockDevice::cleartextDeviceChanged, [wpar, url](const QString &) { + Q_EMIT wpar->fileAttributeChanged(url); + })); + connectionsurl << urlstr; + } +} + +bool DFMRootFileWatcherPrivate::start() +{ + Q_Q(DFMRootFileWatcher); + + if (q->fileUrl().path() != "/" || started) { + return false; + } + + if (!vfsmgr) { + vfsmgr.reset(new DGioVolumeManager); + } + if (!udisksmgr) { + udisksmgr.reset(new DDiskManager); + } + + udisksmgr->setWatchChanges(true); + + DFMRootFileWatcher *wpar = qobject_cast(q); + + connections.push_back(QObject::connect(vfsmgr.data(), &DGioVolumeManager::mountAdded, [wpar](QExplicitlySharedDataPointer mnt) { + if (mnt->getVolume() && mnt->getVolume()->volumeMonitorName().endsWith("UDisks2")) { + return; + } + if (DUrl(mnt->getRootFile()->uri()).scheme() == BURN_SCHEME) { + return; + } + if (mnt->mountClass() == "GUnixMount") { + return; + } + if (mnt->getRootFile()->path().length() == 0) { + return; + } + + // fix bug 60719/65994. 分区编辑器打开后,原本该被过滤的由 udisks2 控制的磁盘,现无法过滤了,导致缓存中的 udisks2 磁盘显示一次 + // 在这里的 gvfs 里又显示一次,且数据内容不一致。 + // 因此,在这里通过过滤 /meida/ 目录挂载点的方式,来过滤 udisks2 设备(udisks2 在默认情况下都是挂载磁盘到 /media/$USER/ 目录下) + // 手动 sudo mount 挂载的设备不会被 Gio 捕获,因此不用考虑手动使用 mount 挂载到 /media 目录下的磁盘被过滤 + if (mnt->getRootFile()->uri().startsWith("file:///media/")) + return; + + DUrl url; + url.setScheme(DFMROOT_SCHEME); + QString mountPointPath = mnt->getRootFile()->path(); + if (mountPointPath.startsWith("/run/user/") && mountPointPath.contains("/gvfs/smb-share:server=")) { + //refresh all dde-file-manager window + emit fileSignalManager->requestFreshAllFileView(); + //refresh dde-desktop + emit fileSignalManager->requestFreshAllDesktop(); + } + url.setPath("/" + QUrl::toPercentEncoding(mnt->getRootFile()->path()) + "." SUFFIX_GVFSMP); + Q_EMIT wpar->subfileCreated(url); + if (mountPointPath.startsWith("/run/user/") && mountPointPath.contains("/gvfs/smb-share:server=")) + emit fileSignalManager->requestShowNewWindows(); + })); + connections.push_back(QObject::connect(vfsmgr.data(), &DGioVolumeManager::mountRemoved, [wpar](QExplicitlySharedDataPointer mnt) { + if (mnt->getVolume() && mnt->getVolume()->volumeMonitorName().endsWith("UDisks2")) { + return; + } + + DUrl url; + url.setScheme(DFMROOT_SCHEME); + QString path = mnt->getRootFile()->path(); + // 此处 Gio Wrapper 或许有 bug, 有时可以获取 uri,但无法获取 path, 因此有了以下略丑的代码 + // 目的是将已知的 uri 拼装成 path,相关 bug:46021 + if (path.isNull() || path.isEmpty()) { + QStringList qq = mnt->getRootFile()->uri().replace("/", "").split(":"); + if (qq.size() >= 3) { + path = QString("/run/user/") + QString::number(getuid()) + + QString("/gvfs/") + qq.at(0) + QString(":host=" + qq.at(1) + QString(",port=") + qq.at(2)); + } else if (qq.size() == 2) { + //修复bug55778,在mips合arm上这里切分出来就是2个 + if (qq.at(0).startsWith("smb")) { + QStringList smblist = mnt->getRootFile()->uri().replace(":/", "").split("/"); + path = smblist.count() >= 3 ? QString("/run/user/")+ QString::number(getuid()) + QString("/gvfs/") + + smblist.at(0) + QString("-share:server=" + smblist.at(1) + QString(",share=") + smblist.at(2)) : QString(); + } + else { + path = QString("/run/user/")+ QString::number(getuid()) + + QString("/gvfs/") + qq.at(0) + QString(":host=" + qq.at(1)); + } + } + } + qDebug() << path; + if (path.startsWith("/run/user/") && path.contains("/gvfs/smb-share:server=")) { + emit fileSignalManager->requestFreshAllFileView(); + emit fileSignalManager->requestFreshAllDesktop(); + } + url.setPath("/" + QUrl::toPercentEncoding(path) + "." SUFFIX_GVFSMP); + Q_EMIT wpar->fileDeleted(url); + QString uri = mnt->getRootFile()->uri(); + fileSignalManager->requestRemoveRecentFile(path); + qDebug() << uri << "mount removed"; + if (uri.contains("smb-share://") || uri.contains("smb://") || uri.contains("ftp://") || uri.contains("sftp://")) { + // remove NetworkNodes cache, so next time cd uri will fetchNetworks + std::string stdStr = uri.toStdString(); + QString smbUri = QUrl::fromPercentEncoding(QByteArray(stdStr.data())); + qDebug() << smbUri << "mount removed"; + if (smbUri.endsWith("/")) { + smbUri = smbUri.left(smbUri.length() - 1); + } + DUrl smbUrl(smbUri); + DUrlList networkNodesKeys = NetworkManager::NetworkNodes.keys(); + for (auto networkNodesKey : networkNodesKeys) { + if (networkNodesKey.toString().toLower().startsWith(smbUrl.toString().toLower())) + NetworkManager::NetworkNodes.remove(networkNodesKey); + } + NetworkManager::NetworkNodes.remove(smbUrl); + smbUrl.setPath(""); + NetworkManager::NetworkNodes.remove(smbUrl); + + mnt->unmount(); // yes, we need do it again...otherwise we will goto an removed path like /run/user/1000/gvfs/smb-sharexxxx + } + })); + connections.push_back(QObject::connect(vfsmgr.data(), &DGioVolumeManager::volumeAdded, [](QExplicitlySharedDataPointer vol) { + if (vol->volumeMonitorName().contains(QRegularExpression("(MTP|GPhoto2|Afc)$"))) { + vol->mount(); + } + })); + connections.push_back(QObject::connect(udisksmgr.data(), &DDiskManager::blockDeviceAdded, [wpar, this](const QString & blks) { + QSharedPointer blk(DDiskManager::createBlockDevice(blks)); + QSharedPointer drv(DDiskManager::createDiskDevice(blk->drive())); + + if(ignoreBlkDevice(blks, blk, drv)) { + return ; + } + + initBlockDevConnections(blk, blks); + + Q_EMIT wpar->subfileCreated(DUrl(DFMROOT_ROOT + blks.mid(QString("/org/freedesktop/UDisks2/block_devices/").length()) + "." SUFFIX_UDISKS)); + })); + connections.push_back(QObject::connect(udisksmgr.data(), &DDiskManager::blockDeviceRemoved, [wpar](const QString & blks) { + Q_EMIT wpar->fileDeleted(DUrl(DFMROOT_ROOT + blks.mid(QString("/org/freedesktop/UDisks2/block_devices/").length()) + "." SUFFIX_UDISKS)); + })); + + for (auto devs : udisksmgr->blockDevices({})) { + QSharedPointer blk(DDiskManager::createBlockDevice(devs)); + QSharedPointer drv(DDiskManager::createDiskDevice(blk->drive())); + + auto mountPoints = blk->mountPoints(); + if (!drv->removable() && !mountPoints.isEmpty()) { // feature: hide the specified dir of unremovable devices + QString mountPoint = mountPoints[0]; + if (!mountPoint.endsWith("/")) + mountPoint += "/"; + // no permission to create files under '/', cannot create .hidden file, so just hardcode here. + deviceListener->appendHiddenDirs(mountPoint + "root"); + deviceListener->appendHiddenDirs(mountPoint + "lost+found"); + } + + if(ignoreBlkDevice(devs, blk, drv)){ + continue; + } + + initBlockDevConnections(blk, devs); + } + + started = true; + return true; +} + +bool DFMRootFileWatcherPrivate::stop() +{ + if (!started) { + return false; + } + + udisksmgr->setWatchChanges(false); + + for (auto &conn : connections) { + QObject::disconnect(conn); + } + connections.clear(); + connectionsurl.clear(); + blkdevs.clear(); + + vfsmgr.clear(); + udisksmgr.clear(); + + started = false; + + return true; +} + +bool DFMRootFileWatcherPrivate::handleGhostSignal(const DUrl &target, DAbstractFileWatcher::SignalType1 signal, const DUrl &url) +{ + Q_UNUSED(target) + Q_Q(DFMRootFileWatcher); + + bool ok = true; + QString &&path = url.path(); + if (path.startsWith("/dev/loop")) { + if (signal == &DAbstractFileWatcher::fileDeleted) { + // 命令 umount loop 设备不会触发 udisks2 和 gio 的信号,因此此处使用 gostSignal 的方式在计算机面移除 loop 设备 (bug-63131) + qInfo() << "remove loop device: " << path; + DFMRootFileWatcher *wpar = qobject_cast(q); + Q_EMIT wpar->fileDeleted(DUrl(DFMROOT_ROOT + path.mid(QString("/dev/").length()) + "." SUFFIX_UDISKS)); + } else if (signal == &DAbstractFileWatcher::subfileCreated) { + // TODO(zhangs): loop 设备手动挂载当前计算机页面并不会及时响应, + // 但 loop 设备在未来的需求中, 将不会被显示在计算机页面,因此暂时不实现 + } else { + ok = false; + } + } else { + ok = false; + } + + return ok; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmrootcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmrootcontroller.h new file mode 100644 index 0000000..fdac6f4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmrootcontroller.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMROOTCONTROLLER_H +#define DFMROOTCONTROLLER_H + +#include "dabstractfilecontroller.h" +#include "dabstractfilewatcher.h" +#include "durl.h" +#include +#include + +class DFMRootFileInfo; +class DFMRootFileWatcherPrivate; +class DFMRootFileWatcher : public DAbstractFileWatcher +{ + Q_OBJECT + +public: + explicit DFMRootFileWatcher(const DUrl &url, QObject *parent = nullptr); + +private: + Q_DECLARE_PRIVATE(DFMRootFileWatcher) +}; + +class DFMRootController : public DAbstractFileController +{ + Q_OBJECT +public: + explicit DFMRootController(QObject *parent = nullptr); + bool renameFile(const QSharedPointer &event) const override; + + const QList getChildren(const QSharedPointer &event) const override; + + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + +private: + void reloadBlkName(const QString& blkPath, QSharedPointer blk) const; + + /** + * @brief loadDiskInfo 加载磁盘信息 + * @param jsonPath 磁盘信息文件路径 + */ + void loadDiskInfo(const QString &jsonPath) const; + + + /** + * @brief 为分区盘符设置一种别名,用于在计算机页面显示 + * @param fi + * @param alias + * @return + */ + bool setLocalDiskAlias(DFMRootFileInfo *fi, const QString &alias) const; + +}; + +#endif // DFMROOTCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsearchcrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsearchcrumbcontroller.cpp new file mode 100644 index 0000000..8c05dde --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsearchcrumbcontroller.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmsearchcrumbcontroller.h" + +#include "dfmcrumbbar.h" +#include "dfmeventdispatcher.h" + +#include "views/dfilemanagerwindow.h" +#include "views/dfileview.h" +#include "dfilesystemmodel.h" + +#include + +DFM_BEGIN_NAMESPACE + +DFMSearchCrumbController::DFMSearchCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMSearchCrumbController::~DFMSearchCrumbController() +{ + +} + +void DFMSearchCrumbController::processAction(DFMCrumbInterface::ActionType type) +{ + switch (type) { + case EscKeyPressed: + case ClearButtonPressed: { + crumbBar()->hideAddressBar(); + DFileManagerWindow *window = qobject_cast(crumbBar()->window()); + + if (!window) { + break; + } + + const DUrl ¤t_url = window->currentUrl(); + auto event = dMakeEventPointer(crumbBar(), current_url.searchTargetUrl(), window); + DFMEventDispatcher::instance()->processEvent(event); + break; + } + case PauseButtonClicked: { + DFileManagerWindow *window = qobject_cast(crumbBar()->window()); + if (!window) + break; + + DFileView *fileView = dynamic_cast(window->getFileView()); + if (!fileView) + break; + + fileView->model()->stopCurrentJob(); + break; + } + case AddressBarLostFocus: + // Do nothing here. + break; + //全量枚举case,因此为解决警告删除default + } +} + +void DFMSearchCrumbController::crumbUrlChangedBehavior(const DUrl url) +{ + crumbBar()->showAddressBar(url.searchKeyword()); +} + +bool DFMSearchCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == SEARCH_SCHEME); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsearchcrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsearchcrumbcontroller.h new file mode 100644 index 0000000..7742aba --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsearchcrumbcontroller.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMSEARCHCRUMBCONTROLLER_H +#define DFMSEARCHCRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMSearchCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMSearchCrumbController(QObject *parent = nullptr); + ~DFMSearchCrumbController(); + + void processAction(ActionType type) override; + void crumbUrlChangedBehavior(const DUrl url); + bool supportedUrl(DUrl url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMSEARCHCRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsftpcrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsftpcrumbcontroller.cpp new file mode 100644 index 0000000..0051226 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsftpcrumbcontroller.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Li yigang + * + * Maintainer: Li yigang + * + * 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 + * 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 . + */ +#include "dfmsftpcrumbcontroller.h" +#include "dfileservices.h" + +#include + +DFM_BEGIN_NAMESPACE + +DFMSftpCrumbController::DFMSftpCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMSftpCrumbController::~DFMSftpCrumbController() +{ + +} + +bool DFMSftpCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == SFTP_SCHEME); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsftpcrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsftpcrumbcontroller.h new file mode 100644 index 0000000..697ad92 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsftpcrumbcontroller.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd. + * + * Author: Li yigang + * + * Maintainer: Li yigang + * + * 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 + * 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 . + */ +#ifndef DFMSFTPCRUMBCONTROLLER_H +#define DFMSFTPCRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMSftpCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMSftpCrumbController(QObject *parent = nullptr); + ~DFMSftpCrumbController() override; + + bool supportedUrl(DUrl url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMSMBCRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebarbookmarkitemhandler.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebarbookmarkitemhandler.cpp new file mode 100644 index 0000000..ec842bc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebarbookmarkitemhandler.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmsidebarbookmarkitemhandler.h" + +#include "singleton.h" +#include "dfileservices.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "views/dfilemanagerwindow.h" +#include "views/dfmsidebar.h" +#include "views/windowmanager.h" +#include "controllers/bookmarkmanager.h" +#include "interfaces/dfmsidebaritem.h" +#include "dialogs/dialogmanager.h" +#include "dfmsidebarmanager.h" +#include "interfaces/dfilemenu.h" + +#include + +DFM_BEGIN_NAMESPACE + +DFMSideBarItem *DFMSideBarBookmarkItemHandler::createItem(const DUrl &url) +{ + // leave url a default display name. + QString displayName = url.bookmarkName(); + + QIcon icon = QIcon::fromTheme("folder-bookmark-symbolic"); + DFMSideBarItem * item = new DFMSideBarItem(icon, displayName, url); + + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsEditable | Qt::ItemNeverHasChildren); + item->setRegisteredHandler(SIDEBAR_ID_BOOKMARK); + + return item; +} + +DFMSideBarBookmarkItemHandler::DFMSideBarBookmarkItemHandler() +{ + +} + +void DFMSideBarBookmarkItemHandler::cdAction(const DFMSideBar *sidebar, const DFMSideBarItem *item) +{ + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, item->url()); + if (info->exists()) { + DFileManagerWindow *wnd = qobject_cast(sidebar->topLevelWidget()); + wnd->cd(info->fileUrl()); + } else { + int ret = dialogManager->showRemoveBookMarkDialog(DFMEvent(this)); + if (ret == QDialog::Accepted) { + DFileService::instance()->deleteFiles(this, {item->url()}, false); + } + } +} + +QMenu *DFMSideBarBookmarkItemHandler::contextMenu(const DFMSideBar *sidebar, const DFMSideBarItem *item) +{ + // this part could be duplicate since it seems every sidebar item should got + // a new window/tab option and a properties option. maybe we need a menu manager + // or other workaround? + + DFileMenu *menu = new DFileMenu(); + menu->setAccessibleInfo(AC_FILE_MENU_SIDEBAR_BOOK_MARK); + + DFileManagerWindow *wnd = qobject_cast(sidebar->topLevelWidget()); + bool shouldEnable = WindowManager::tabAddableByWinId(wnd->windowId()); + const DAbstractFileInfoPointer& info = DFileService::instance()->createFileInfo(nullptr, item->url()); + bool fileExist = info->exists(); + + menu->addAction(QObject::tr("Open in new window"), [item]() { + WindowManager::instance()->showNewWindow(item->url(), true); + })->setEnabled(fileExist); + + menu->addAction(QObject::tr("Open in new tab"), [wnd, item]() { + wnd->openNewTab(item->url()); + })->setEnabled(fileExist && shouldEnable); + + menu->addSeparator(); + + menu->addAction(QObject::tr("Rename"), [sidebar, item]() { + int index = sidebar->findItem(item); + if (index >= 0) { + sidebar->openItemEditor(index); + } + })->setEnabled(fileExist); + + menu->addAction(QObject::tr("Remove"), [item]() { + DFileService::instance()->deleteFiles(nullptr, DUrlList{item->url()}, false); + }); + + menu->addSeparator(); + + menu->addAction(QObject::tr("Properties"), [ = ]() { + DUrlList list; + //fix bug 33005 在是smb文件和ftp文件加标签后redirectedFileUrl取出的url对应不上,自己补齐 + DUrl openurl = info->redirectedFileUrl(); + QString strscheme = openurl.scheme(); + if (strscheme == SMB_SCHEME || strscheme == FTP_SCHEME || strscheme == SFTP_SCHEME) + { + QString sharename = info->absolutePath().mid(info->absolutePath().lastIndexOf("=")+1)+"/"; + QString localname = openurl.path().replace(sharename,""); + openurl = DUrl(info->absolutePath() + localname); + openurl.setScheme(FILE_SCHEME); + } + list.append(openurl); + fileSignalManager->requestShowPropertyDialog(DFMUrlListBaseEvent(nullptr, list)); + })->setEnabled(fileExist); + +#ifndef QT_NO_DEBUG + menu->addAction(QStringLiteral("Debug Info"), [ = ]() { + const DAbstractFileInfo * infoData = info.constData(); + const BookMark * bookmarkInfo = static_cast(infoData); + DDialog d; + QString messageLines; + messageLines.append("Bookmark Url: " + item->url().toString() + "\n"); + messageLines.append(QStringLiteral("(i) Bookmark Exist: ") + (info->exists() ? "Y" : "N") + "\n"); + messageLines.append("(i) Bookmark Mount Point: " + bookmarkInfo->mountPoint + "\n"); +// messageLines.append("(i) Bookmark Locate Url: " + bookmarkInfo->locateUrl + "\n"); + messageLines.append("(i) Bookmark Locate Url: " + QString(QByteArray::fromBase64(bookmarkInfo->locateUrl.toLocal8Bit())) + "\n"); + messageLines.append("(i) Bookmark Redirected Url: " + bookmarkInfo->redirectedFileUrl().toString() + "\n"); + d.setMessage(messageLines); + d.addButton("Gotcha", true, DDialog::ButtonNormal); + d.exec(); + }); +#endif + + return menu; +} + +void DFMSideBarBookmarkItemHandler::rename(const DFMSideBarItem *item, QString name) +{ + DUrl newUrl = item->url(); + newUrl.setFragment(name); + DFileService::instance()->renameFile(this, item->url(), newUrl, true); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebarbookmarkitemhandler.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebarbookmarkitemhandler.h new file mode 100644 index 0000000..8f3ad7d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebarbookmarkitemhandler.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#pragma once + +#include "dfmsidebariteminterface.h" + +#define SIDEBAR_ID_BOOKMARK "__bookmark" + +class DUrl; + +DFM_BEGIN_NAMESPACE + +class DFMSideBarBookmarkItemHandler : public DFMSideBarItemInterface +{ +public: + static DFMSideBarItem * createItem(const DUrl &url); + + DFMSideBarBookmarkItemHandler(); + + void cdAction(const DFMSideBar *sidebar, const DFMSideBarItem* item) override; + QMenu * contextMenu(const DFMSideBar *sidebar, const DFMSideBarItem* item) override; + void rename(const DFMSideBarItem *item, QString name) override; +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebardefaultitemhandler.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebardefaultitemhandler.cpp new file mode 100644 index 0000000..f95af06 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebardefaultitemhandler.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "dfmsidebardefaultitemhandler.h" + +#include "dfmsidebaritem.h" + +#include "singleton.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "controllers/pathmanager.h" +#include "views/dfilemanagerwindow.h" +#include "views/dfmsidebar.h" +#include "views/windowmanager.h" +#include "trashmanager.h" +#include "durl.h" +#include "interfaces/dfilemenu.h" + +DFM_BEGIN_NAMESPACE + +DFMSideBarItem *DFMSideBarDefaultItemHandler::createItem(const QString &pathKey) +{ + QString iconName = systemPathManager->getSystemPathIconName(pathKey); + if (!iconName.contains("-symbolic")) { + iconName.append("-symbolic"); + } + + QString pathStr = pathKey == "Trash" ? TRASH_ROOT : systemPathManager->getSystemPath(pathKey); + + DFMSideBarItem * item = new DFMSideBarItem( + QIcon::fromTheme(iconName), + systemPathManager->getSystemPathDisplayName(pathKey), + DUrl::fromUserInput(pathStr) + ); + + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren | Qt::ItemIsDropEnabled); + item->setData(SIDEBAR_ID_DEFAULT, DFMSideBarItem::ItemUseRegisteredHandlerRole); + + return item; +} + +DFMSideBarDefaultItemHandler::DFMSideBarDefaultItemHandler(QObject *parent) + : DFMSideBarItemInterface (parent) +{ + +} + +void DFMSideBarDefaultItemHandler::cdAction(const DFMSideBar *sidebar, const DFMSideBarItem *item) +{ + return DFMSideBarItemInterface::cdAction(sidebar, item); +} + +QMenu *DFMSideBarDefaultItemHandler::contextMenu(const DFMSideBar *sidebar, const DFMSideBarItem *item) +{ + static QStringList noPropertySchemes = {"usershare", "network"}; + +// if (item->url() != DUrl::fromTrashFile("/") && item->url() != DUrl::fromUserInput(QDir::rootPath()) +// && item->text() != systemPathManager->getSystemPathDisplayName("Home")) { +// return DFMSideBarItemInterface::contextMenu(sidebar, item); +// } + + DFileMenu *menu = new DFileMenu(); + menu->setAccessibleInfo(AC_FILE_MENU_DEFAULT_SIDEBAR); + + DFileManagerWindow *wnd = qobject_cast(sidebar->topLevelWidget()); + bool shouldDisable = !WindowManager::tabAddableByWinId(wnd->windowId()); + + menu->addAction(QObject::tr("Open in new window"), [item]() { + WindowManager::instance()->showNewWindow(item->url(), true); + }); + + menu->addAction(QObject::tr("Open in new tab"), [wnd, item]() { + wnd->openNewTab(item->url()); + })->setDisabled(shouldDisable); + + menu->addSeparator(); + + if (item->text() == systemPathManager->getSystemPathDisplayName("Recent")) { + QAction *emptyRecentVisits = new QAction(QObject::tr("Clear recent history"), menu); + + connect(emptyRecentVisits, &QAction::triggered, this, []() { + appController->actionClearRecent(); + }); + + menu->addAction(emptyRecentVisits); + } + + if (item->text() == systemPathManager->getSystemPathDisplayName("Trash")) { + QAction *emptyTrash = new QAction(QObject::tr("Empty Trash"), menu); + connect(emptyTrash, &QAction::triggered, this, [this]() { + appController->actionClearTrash(this); + }); + emptyTrash->setDisabled(TrashManager::isEmpty()); + menu->addAction(emptyTrash); + } + + menu->addSeparator(); + + if (!noPropertySchemes.contains(item->url().scheme()) && + item->text() != systemPathManager->getSystemPathDisplayName("Recent")) { + QString propertiesStr = QObject::tr("Properties"); + menu->addAction(propertiesStr, [item]() { + DUrlList list; + list.append(item->url()); + Singleton::instance()->requestShowPropertyDialog(DFMUrlListBaseEvent(nullptr, list)); + }); + } + + return menu; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebardefaultitemhandler.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebardefaultitemhandler.h new file mode 100644 index 0000000..2867f62 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebardefaultitemhandler.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#pragma once + +#include "dfmsidebariteminterface.h" + +#define SIDEBAR_ID_DEFAULT "__default" + +DFM_BEGIN_NAMESPACE + +class DFMSideBarDefaultItemHandler : public DFMSideBarItemInterface +{ +public: + static DFMSideBarItem * createItem(const QString &pathKey); + + explicit DFMSideBarDefaultItemHandler(QObject *parent = nullptr); + + void cdAction(const DFMSideBar *sidebar, const DFMSideBarItem* item) override; + QMenu * contextMenu(const DFMSideBar *sidebar, const DFMSideBarItem* item) override; +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebardeviceitemhandler.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebardeviceitemhandler.cpp new file mode 100644 index 0000000..ea9894f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebardeviceitemhandler.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "dfmsidebardeviceitemhandler.h" + +#include "singleton.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "dfileservices.h" +#include "views/dfilemanagerwindow.h" +#include "views/dfmsidebar.h" +#include "views/windowmanager.h" +#include "gvfs/gvfsmountmanager.h" +#include "interfaces/dfmsidebaritem.h" +#include "deviceinfo/udiskdeviceinfo.h" +#include "dfmsidebarmanager.h" +#include "dfilemenumanager.h" +#include "dfilemenu.h" +#include "models/dfmrootfileinfo.h" +#include "interfaces/drootfilemanager.h" + +#include + +DFM_BEGIN_NAMESPACE + +DViewItemAction *DFMSideBarDeviceItemHandler::createUnmountOrEjectAction(const DUrl &url, bool withText) +{ + DViewItemAction * action = new DViewItemAction(Qt::AlignCenter, QSize(16, 16), QSize(), true); + if (withText) { + action->setText(QObject::tr("Unmount")); + } + action->setIcon(QIcon::fromTheme("media-eject-symbolic")); + + QObject::connect(action, &QAction::triggered, [url](){ + const DAbstractFileInfoPointer infoPointer = DFileService::instance()->createFileInfo(nullptr, url); + const QVector menuactions = infoPointer->menuActionList(); + if (static_cast(infoPointer->fileType()) == DFMRootFileInfo::ItemType::UDisksOptical) { + AppController::instance()->actionEject(dMakeEventPointer(nullptr, url)); + } else if (menuactions.contains(MenuAction::SafelyRemoveDrive)) { + AppController::instance()->actionSafelyRemoveDrive(dMakeEventPointer(nullptr, url)); + } else if (menuactions.contains(MenuAction::Unmount)) { + AppController::instance()->actionUnmount(dMakeEventPointer(nullptr, url)); + } + }); + + return action; +} + +DFMSideBarItem *DFMSideBarDeviceItemHandler::createItem(const DUrl &url) +{ + DAbstractFileInfoPointer infoPointer = DFileService::instance()->createFileInfo(nullptr, url); + //fix 60959 如果是smb,sftp,ftp的共享文件,本来是显示的,但是断网了以后,新开窗口就创建了新的dfmrootfileinfo判断文件就不存在, + //到DRootFileManager中去获取缓存,如果缓存不存在就返回 + const QString urlString = url.toString(); + if(!infoPointer->exists() && infoPointer->suffix() == SUFFIX_GVFSMP && + ((urlString.contains("smb-share") && urlString.contains("server")) || + (urlString.contains("ftp") && urlString.contains("host")))) { + infoPointer = DRootFileManager::getFileInfo(url); + } + if(!infoPointer || (!infoPointer->exists() && infoPointer->suffix() != SUFFIX_GVFSMP && + !((urlString.contains("smb-share") && urlString.contains("server")) || + (urlString.contains("ftp") && urlString.contains("host"))))) { + return nullptr; + } + //QVariantHash info = infoPointer->extraProperties(); + QString displayName = infoPointer->fileDisplayName(); + QString iconName = infoPointer->iconName() + "-symbolic"; + + DFMSideBarItem * item = new DFMSideBarItem(QIcon::fromTheme(iconName), displayName, url); + + Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren; + + auto actionlist = infoPointer->menuActionList(); + if (actionlist.contains(MenuAction::Rename)) + flags |= Qt::ItemIsEditable; + item->setFlags(flags); + item->setData(SIDEBAR_ID_DEVICE, DFMSideBarItem::ItemUseRegisteredHandlerRole); + + DViewItemActionList lst; + DViewItemAction * act = createUnmountOrEjectAction(url, false); + act->setIcon(QIcon::fromTheme("media-eject-symbolic")); + act->setVisible(actionlist.contains(MenuAction::Eject) || + actionlist.contains(MenuAction::Unmount) || + actionlist.contains(MenuAction::SafelyRemoveDrive)); + + // 防止无图标的act也占用空间,item缩小时文字被压缩至空 + if (act->isVisible()) { + lst.push_back(act); + item->setActionList(Qt::RightEdge, lst); + } + + return item; +} + +DFMSideBarDeviceItemHandler::DFMSideBarDeviceItemHandler(QObject *parent) + : DFMSideBarItemInterface (parent) +{ + +} + +void DFMSideBarDeviceItemHandler::cdAction(const DFMSideBar *sidebar, const DFMSideBarItem *item) +{ + AppController::instance()->actionOpenDisk(dMakeEventPointer(sidebar, item->url())); +} + +QMenu *DFMSideBarDeviceItemHandler::contextMenu(const DFMSideBar *sidebar, const DFMSideBarItem *item) +{ + const DAbstractFileInfoPointer infoPointer = DFileService::instance()->createFileInfo(this, item->url()); + QVariantHash info = infoPointer->extraProperties(); + DFileManagerWindow *wnd = qobject_cast(sidebar->topLevelWidget()); + bool shouldDisable = !WindowManager::tabAddableByWinId(wnd->windowId()); + QSet disabled; + + if (shouldDisable) { + disabled.insert(MenuAction::OpenInNewTab); + disabled.insert(MenuAction::OpenDiskInNewTab); + } + //fix:光驱还没有加载成功前,右键点击光驱“挂载”,光驱自动弹出。 + if ((!info["mounted"].toBool()) && \ + (info["fsType"].toString().isEmpty()) && \ + (info["fsSize"].toLongLong() == 0)) { + disabled.insert(MenuAction::OpenDiskInNewWindow); + disabled.insert(MenuAction::OpenDiskInNewTab); + disabled.insert(MenuAction::Mount); + disabled.insert(MenuAction::OpticalBlank); + //fix:不插光盘,打开文件管理器,光盘的弹出按钮不能置灰 + //disabled.insert(MenuAction::Eject); + disabled.insert(MenuAction::SafelyRemoveDrive); + + disabled.insert(MenuAction::Property); + } + + if (item->url().path().endsWith(".remote")) { + disabled.remove(MenuAction::Mount); + disabled.remove(MenuAction::Property); + } + + DFileMenu *menu = DFileMenuManager::genereteMenuByKeys(infoPointer->menuActionList(), disabled); + menu->setEventData(DUrl(), {item->url()}, WindowManager::getWindowId(wnd), sidebar); + menu->setAccessibleInfo(AC_FILE_MENU_SIDEBAR_DEVICE_ITEM); + + return menu; +} + +void DFMSideBarDeviceItemHandler::rename(const DFMSideBarItem *item, QString name) +{ + const DAbstractFileInfoPointer infoPointer = DFileService::instance()->createFileInfo(this, item->url()); + if (infoPointer->fileDisplayName() != name) { + DUrl newUrl; + newUrl.setPath(name); // 直接构造 URL 会忽略掉一些特殊符号,因此使用 setPath + DFileService::instance()->renameFile(this, item->url(), newUrl); + } +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebardeviceitemhandler.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebardeviceitemhandler.h new file mode 100644 index 0000000..f753310 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebardeviceitemhandler.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#pragma once + +#include "dfmsidebariteminterface.h" +#include "dtkwidget_global.h" + +#define SIDEBAR_ID_DEVICE "__device" + +DWIDGET_BEGIN_NAMESPACE +class DViewItemAction; +DWIDGET_END_NAMESPACE + +class DUrl; + +DFM_BEGIN_NAMESPACE + +class DFMSideBarDeviceItemHandler : public DFMSideBarItemInterface +{ +public: + static DTK_WIDGET_NAMESPACE::DViewItemAction * createUnmountOrEjectAction(const DUrl &url, bool withText); + static DFMSideBarItem * createItem(const DUrl &url); + + explicit DFMSideBarDeviceItemHandler(QObject *parent = nullptr); + + void cdAction(const DFMSideBar *sidebar, const DFMSideBarItem* item) override; + QMenu * contextMenu(const DFMSideBar *sidebar, const DFMSideBarItem* item) override; + void rename(const DFMSideBarItem *item, QString name) override; +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebartagitemhandler.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebartagitemhandler.cpp new file mode 100644 index 0000000..aeb81ca --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebartagitemhandler.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "dfmsidebartagitemhandler.h" + +#include "tag/tagmanager.h" +#include "views/dfilemanagerwindow.h" +#include "views/dfmsidebar.h" +#include "views/windowmanager.h" +#include "views/dtagactionwidget.h" +#include "interfaces/dfmsidebaritem.h" +#include "dfmeventdispatcher.h" +#include "dfmsidebarmanager.h" + +#include +#include "durl.h" +#include "dfilemenu.h" + +DFM_BEGIN_NAMESPACE + +DFMSideBarItem *DFMSideBarTagItemHandler::createItem(const DUrl &url) +{ + QString iconName = TagManager::instance()->getTagIconName(url.fileName()); + QIcon icon = QIcon::fromTheme(iconName); + DFMSideBarItem * item = new DFMSideBarItem(icon, url.fileName(), url); + + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemNeverHasChildren | Qt::ItemIsEditable); + item->setData(SIDEBAR_ID_TAG, DFMSideBarItem::ItemUseRegisteredHandlerRole); + + return item; +} + +DFMSideBarTagItemHandler::DFMSideBarTagItemHandler(QObject *parent) + : DFMSideBarItemInterface (parent) +{ + +} + +QMenu *DFMSideBarTagItemHandler::contextMenu(const DFMSideBar *sidebar, const DFMSideBarItem *item) +{ + DFileMenu *menu = new DFileMenu(); + menu->setAccessibleInfo(AC_FILE_MENU_SIDEBAR_TAGITEM); + + DFileManagerWindow *wnd = qobject_cast(sidebar->topLevelWidget()); + bool shouldDisable = !WindowManager::tabAddableByWinId(wnd->windowId()); + DTagActionWidget* tagWidget{ new DTagActionWidget }; + QWidgetAction* tagAction{ new QWidgetAction{ nullptr } }; + + menu->addAction(QObject::tr("Open in new window"), [item]() { + WindowManager::instance()->showNewWindow(item->url(), true); + }); + + menu->addAction(QObject::tr("Open in new tab"), [wnd, item]() { + wnd->openNewTab(item->url()); + })->setDisabled(shouldDisable); + + menu->addSeparator(); + + menu->addAction(QObject::tr("Rename"), [sidebar, item]() { + int index = sidebar->findItem(item); + if (index >= 0) { + sidebar->openItemEditor(index); + } + }); + + menu->addAction(QObject::tr("Remove"), [item]() { + DFileService::instance()->deleteFiles(nullptr, DUrlList{item->url()}, false); + }); + + menu->addSeparator(); + + tagAction->setDefaultWidget(tagWidget); + tagAction->setText("Change color of present tag"); + tagWidget->setExclusive(true); + tagWidget->setToolTipVisible(false); + + menu->addAction(tagAction); + connect(tagAction, &QWidgetAction::triggered, this, [item, menu, tagWidget]() { + // should setIcon first, processEvent will reset checkedColorList + if (tagWidget->checkedColorList().size()>0) { + QString iconName = TagManager::instance()->getTagIconName(tagWidget->checkedColorList().first()); + QIcon icon = QIcon::fromTheme(iconName); + DFMSideBarItem *it = const_cast(item); + it->setIcon(icon); + } + + DFMEventDispatcher::instance()->processEvent(nullptr, menu, DUrl(TAG_ROOT), + DUrlList{item->url()}, DFMGlobal::ChangeTagColor); + }); + + return menu; +} + +void DFMSideBarTagItemHandler::rename(const DFMSideBarItem *item, QString name) +{ + DFileService::instance()->renameFile(this, item->url(), DUrl::fromUserTaggedFile(name, "")); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebartagitemhandler.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebartagitemhandler.h new file mode 100644 index 0000000..f00b5c2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebartagitemhandler.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#pragma once + +#include "dfmsidebariteminterface.h" + +#define SIDEBAR_ID_TAG "__tag" + +class DUrl; + +DFM_BEGIN_NAMESPACE + +class DFMSideBarTagItemHandler : public DFMSideBarItemInterface +{ +public: + static DFMSideBarItem * createItem(const DUrl &url); + + explicit DFMSideBarTagItemHandler(QObject *parent = nullptr); + + QMenu * contextMenu(const DFMSideBar *sidebar, const DFMSideBarItem* item) override; + + void rename(const DFMSideBarItem *item, QString name) override; +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebarvaultitemhandler.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebarvaultitemhandler.cpp new file mode 100644 index 0000000..2322da5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebarvaultitemhandler.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + + + + +#include "dfmsidebarvaultitemhandler.h" + +#include "dfmsidebaritem.h" + +#include "dfilemenumanager.h" + +#include "singleton.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "controllers/pathmanager.h" +#include "controllers/vaultcontroller.h" +#include "views/dfilemanagerwindow.h" +#include "views/dfmsidebar.h" +#include "views/windowmanager.h" +#include "durl.h" +#include "interfaces/dfilemenu.h" + +#include "vault/vaultlockmanager.h" +#include "vault/vaulthelper.h" + +DFM_BEGIN_NAMESPACE + +DFMSideBarItem *DFMSideBarVaultItemHandler::createItem(const QString &pathKey) +{ + QString iconName = systemPathManager->getSystemPathIconName(pathKey); + if (!iconName.contains("-symbolic")) { + iconName.append("-symbolic"); + } + + QString pathStr = systemPathManager->getSystemPath(pathKey); + + DFMSideBarItem *item = new DFMSideBarItem( + QIcon::fromTheme(iconName), + systemPathManager->getSystemPathDisplayName(pathKey), + VaultController::makeVaultUrl(VaultController::makeVaultLocalPath()) + ); + + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren | Qt::ItemIsDropEnabled); + item->setData(SIDEBAR_ID_VAULT, DFMSideBarItem::ItemUseRegisteredHandlerRole); + + //! Initalize vault manager. + VaultLockManager::getInstance(); + + return item; +} + +DFMSideBarVaultItemHandler::DFMSideBarVaultItemHandler(QObject *parent) + : DFMSideBarItemInterface(parent) +{ +} + +void DFMSideBarVaultItemHandler::cdAction(const DFMSideBar *sidebar, const DFMSideBarItem *item) +{ + DFMSideBarItemInterface::cdAction(sidebar, item); +} + +QMenu *DFMSideBarVaultItemHandler::contextMenu(const DFMSideBar *sidebar, const DFMSideBarItem *item) +{ + Q_UNUSED(item) + return generateMenu(sidebar->topLevelWidget(), sidebar); +} + +DFileMenu *DFMSideBarVaultItemHandler::generateMenu(QWidget *topWidget, const DFMSideBar *sender) +{ + DFileMenu * menu = DFileMenuManager::createVaultMenu(topWidget, sender); + if(menu){ menu -> setAccessibleInfo(AC_FILE_MENU_SIDEBAR_VAULT_ITEM);} + return menu; +} + +bool DFMSideBarVaultItemHandler::lockNow(DFileManagerWindow *wnd) +{ + //! Is there a vault task, top it if exist. + if(!VaultHelper::topVaultTasks()) { + emit fileSignalManager->requestCloseAllTabOfVault(wnd->windowId()); + VaultController::ins()->lockVault(); + } + + return true; +} + +bool DFMSideBarVaultItemHandler::autoLock(int lockState) +{ + return VaultLockManager::getInstance().autoLock(static_cast(lockState)); +} + +void DFMSideBarVaultItemHandler::showView(QWidget *wndPtr, QString host) +{ + DFileManagerWindow *wnd = qobject_cast(wndPtr); + wnd->cd(VaultController::makeVaultUrl("/", host)); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebarvaultitemhandler.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebarvaultitemhandler.h new file mode 100644 index 0000000..75a6400 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsidebarvaultitemhandler.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + + +#pragma once + +#include "dfmsidebariteminterface.h" + +#define SIDEBAR_ID_VAULT "__vault" + +class DFileManagerWindow; +class DFileMenu; +class DFMVaultUnlockPages; + +DFM_BEGIN_NAMESPACE +/** + * @brief 实现侧边栏保险箱 + */ +class DFMSideBarVaultItemHandler : public DFMSideBarItemInterface +{ +public: + /** + * @brief 创建该类实例 + * @param pathKey + * @return 创建的实例指针 + */ + static DFMSideBarItem *createItem(const QString &pathKey); + + /** + * @brief 构造函数 + * @param parent + */ + explicit DFMSideBarVaultItemHandler(QObject *parent = nullptr); + + /** + * @brief 打开操作 + * @param sidebar + * @param item + */ + void cdAction(const DFMSideBar *sidebar, const DFMSideBarItem *item) override; + + /** + * @brief 返回右键菜单 + * @param sidebar + * @param item + * @return 右键菜单 + */ + QMenu *contextMenu(const DFMSideBar *sidebar, const DFMSideBarItem *item) override; + + /** + * @brief 产生菜单 + * @param topWidget + * @param sender + * @return 菜单项目 + */ + DFileMenu *generateMenu(QWidget *topWidget, const DFMSideBar *sender = nullptr); + +private: + /** + * @brief 立即上锁 + * @return 上锁是否成功 + */ + bool lockNow(DFileManagerWindow *wnd); + + /** + * @brief 自动上锁 + * @param lockState 加锁状态 + * @return 自动上锁是否成功 + */ + bool autoLock(int lockState); + +private: + void showView(QWidget *wndPtr, QString host); + + DFMVaultUnlockPages *m_vaultUnlockPage { nullptr }; +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsmbcrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsmbcrumbcontroller.cpp new file mode 100644 index 0000000..ef7e731 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsmbcrumbcontroller.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "dfmsmbcrumbcontroller.h" +#include "dfileservices.h" + +#include + +DFM_BEGIN_NAMESPACE + +DFMSmbCrumbController::DFMSmbCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMSmbCrumbController::~DFMSmbCrumbController() +{ + +} + +bool DFMSmbCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == SMB_SCHEME); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsmbcrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsmbcrumbcontroller.h new file mode 100644 index 0000000..dbacd24 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmsmbcrumbcontroller.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef DFMSMBCRUMBCONTROLLER_H +#define DFMSMBCRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMSmbCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMSmbCrumbController(QObject *parent = nullptr); + ~DFMSmbCrumbController() override; + + bool supportedUrl(DUrl url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMSMBCRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmtagcrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmtagcrumbcontroller.cpp new file mode 100644 index 0000000..c2729f3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmtagcrumbcontroller.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmtagcrumbcontroller.h" +#include "tag/tagmanager.h" + +DFM_BEGIN_NAMESPACE + +DFMTagCrumbController::DFMTagCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMTagCrumbController::~DFMTagCrumbController() +{ + +} + +bool DFMTagCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == TAG_SCHEME); +} + +QList DFMTagCrumbController::seprateUrl(const DUrl &url) +{ + QString colorName; + QString displayText; + + if (url != DUrl(TAG_ROOT)) { + displayText = url.fileName(); + colorName = TagManager::instance()->getTagIconName(url.fileName()); + } else { + displayText = QCoreApplication::translate("DFMTagCrumbController", "Tag information"); + colorName = QStringLiteral("CrumbIconButton.Tags"); + } + + return { CrumbData(url, displayText, colorName) }; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmtagcrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmtagcrumbcontroller.h new file mode 100644 index 0000000..a701ed0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmtagcrumbcontroller.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMTAGCRUMBCONTROLLER_H +#define DFMTAGCRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMTagCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMTagCrumbController(QObject *parent = nullptr); + ~DFMTagCrumbController(); + + bool supportedUrl(DUrl url) override; + QList seprateUrl(const DUrl &url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMTAGCRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmtrashcrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmtrashcrumbcontroller.cpp new file mode 100644 index 0000000..8ffae94 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmtrashcrumbcontroller.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmtrashcrumbcontroller.h" +#include "dfileservices.h" +#include "dfileinfo.h" + +DFM_BEGIN_NAMESPACE + +DFMTrashCrumbController::DFMTrashCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMTrashCrumbController::~DFMTrashCrumbController() +{ + +} + +bool DFMTrashCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == TRASH_SCHEME); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmtrashcrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmtrashcrumbcontroller.h new file mode 100644 index 0000000..45a23d4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmtrashcrumbcontroller.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMTRASHCRUMBCONTROLLER_H +#define DFMTRASHCRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMTrashCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMTrashCrumbController(QObject *parent = nullptr); + ~DFMTrashCrumbController(); + + bool supportedUrl(DUrl url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMTRASHCRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmusersharecrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmusersharecrumbcontroller.cpp new file mode 100644 index 0000000..b9ccca3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmusersharecrumbcontroller.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmusersharecrumbcontroller.h" +#include "controllers/pathmanager.h" +#include "singleton.h" + +DFM_BEGIN_NAMESPACE + +DFMUserShareCrumbController::DFMUserShareCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMUserShareCrumbController::~DFMUserShareCrumbController() +{ + +} + +bool DFMUserShareCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == USERSHARE_SCHEME); +} + +QList DFMUserShareCrumbController::seprateUrl(const DUrl &url) +{ + Q_UNUSED(url); + return { CrumbData(DUrl(USERSHARE_ROOT), + Singleton::instance()->getSystemPathDisplayName("UserShare"), + Singleton::instance()->getSystemPathIconName("UserShare")) }; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmusersharecrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmusersharecrumbcontroller.h new file mode 100644 index 0000000..1136ff5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmusersharecrumbcontroller.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMUSERSHARECRUMBCONTROLLER_H +#define DFMUSERSHARECRUMBCONTROLLER_H + +#include "interfaces/dfmcrumbinterface.h" + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMUserShareCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMUserShareCrumbController(QObject *parent = nullptr); + ~DFMUserShareCrumbController() override; + + bool supportedUrl(DUrl url) override; + QList seprateUrl(const DUrl &url) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMUSERSHARECRUMBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmvaultcrumbcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmvaultcrumbcontroller.cpp new file mode 100644 index 0000000..4e5ba5f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmvaultcrumbcontroller.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + + +#include "dfmvaultcrumbcontroller.h" +#include "controllers/pathmanager.h" +#include "singleton.h" +#include "controllers/vaultcontroller.h" +#include "dfileservices.h" + +#include + +DFM_BEGIN_NAMESPACE + +DFMVaultCrumbController::DFMVaultCrumbController(QObject *parent) + : DFMCrumbInterface(parent) +{ + +} + +DFMVaultCrumbController::~DFMVaultCrumbController() +{ + +} + +bool DFMVaultCrumbController::supportedUrl(DUrl url) +{ + return (url.scheme() == DFMVAULT_SCHEME); +} + +QList DFMVaultCrumbController::seprateUrl(const DUrl &url) +{ + QList list; + QString prefixPath = "/"; + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, url); + const QString &path = info->toLocalFile(); + + if (path.isEmpty()) { + return list; + } + QStorageInfo storageInfo(path); + QFile file(path); + if (file.exists()) + prefixPath = storageInfo.rootPath() + "/"; + else + prefixPath = VaultController::makeVaultLocalPath(); + // 设置地址栏保险箱图标 + QString text = Singleton::instance()->getSystemPathDisplayName("Vault"); + QString iconName = Singleton::instance()->getSystemPathIconName("Vault"); + CrumbData data(VaultController::makeVaultUrl(VaultController::makeVaultLocalPath()), text, iconName); + list.append(data); + + DUrlList urlList = info->parentUrlList(); + urlList.insert(0, url); + + DAbstractFileInfoPointer infoPointer; + // Push urls into crumb list (without prefix url) + DUrlList::const_reverse_iterator iter = urlList.crbegin(); + while (iter != urlList.crend()) { + const DUrl &oneUrl = *iter; + + QString localFile = oneUrl.toLocalFile(); + if (!prefixPath.startsWith(localFile)) { + QString displayText = oneUrl.fileName(); + // Check for possible display text. + infoPointer = DFileService::instance()->createFileInfo(nullptr, oneUrl); + if (infoPointer) { + displayText = infoPointer->fileDisplayName(); + } + CrumbData crumbData(oneUrl, displayText); + list.append(crumbData); + } + ++iter; + } + + return list; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmvaultcrumbcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmvaultcrumbcontroller.h new file mode 100644 index 0000000..8c80bfd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/dfmvaultcrumbcontroller.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + + +#pragma once + +#include "interfaces/dfmcrumbinterface.h" + +DFM_BEGIN_NAMESPACE + +class DFMVaultCrumbController : public DFMCrumbInterface +{ +public: + explicit DFMVaultCrumbController(QObject *parent = nullptr); + ~DFMVaultCrumbController() override; + + bool supportedUrl(DUrl url) override; + QList seprateUrl(const DUrl &url) override; +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/filecontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/filecontroller.cpp new file mode 100644 index 0000000..1dbc3e6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/filecontroller.cpp @@ -0,0 +1,2027 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "filecontroller.h" +#include "dfileservices.h" +#include "fileoperations/filejob.h" +#include "dfilewatcher.h" +#include "dfileinfo.h" +#include "dgvfsfileinfo.h" +#include "trashmanager.h" +#include "dfmeventdispatcher.h" +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "dlocalfiledevice.h" +#include "dgiofiledevice.h" +#include "dlocalfilehandler.h" +#include "dfilecopymovejob.h" +#include "dstorageinfo.h" +#include +#include "models/desktopfileinfo.h" +#include "models/trashfileinfo.h" + +#include "app/define.h" +#include "dfmevent.h" +#include "app/filesignalmanager.h" +#include "tag/tagmanager.h" + +#include "shutil/fileutils.h" +#include "shutil/dfmregularexpression.h" +#include "shutil/dfmfilelistfile.h" + +#include "dialogs/dialogmanager.h" +#include "dialogs/dtaskdialog.h" + +#include "singleton.h" +#include "interfaces/dfmglobal.h" +#include "interfaces/dfmstandardpaths.h" + +#include "appcontroller.h" +#include "singleton.h" + +#include "models/sharefileinfo.h" +#include "usershare/usersharemanager.h" + +#include "fileoperations/sort.h" + +#include "deviceinfo/udisklistener.h" +#include "deviceinfo/udiskdeviceinfo.h" +#include "controllers/vaultcontroller.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "dfmsettings.h" +#include "dfmapplication.h" +#ifndef DISABLE_QUICK_SEARCH +#include "anything_interface.h" +#endif +#ifdef DISABLE_QUICK_SEARCH +#include "./search/dfsearch.h" +#include "vaultcontroller.h" +#endif + +class DFMQDirIterator : public DDirIterator +{ +public: + DFMQDirIterator(const QString &path, + const QStringList &nameFilters, + QDir::Filters filter, + QDirIterator::IteratorFlags flags, + const bool isgvfs = false) + : iterator(path, nameFilters, filter, flags) + , isgvfs(isgvfs) + { + + } + + DUrl next() override + { + return DUrl::fromLocalFile(iterator.next()); + } + + bool hasNext() const override + { + return iterator.hasNext(); + } + + QString fileName() const override + { + return iterator.fileName(); + } + + DUrl fileUrl() const override + { + return DUrl::fromLocalFile(iterator.filePath()); + } + + const DAbstractFileInfoPointer fileInfo() const override + { + const QFileInfo &info = iterator.fileInfo(); + bool isnotsyslink = !info.isSymLink(); + //父目录是gvfs目录,那么子目录和子文件必须是gvfs文件 + QString path = info.path(); + bool currentisgvfs = isgvfs ? true : FileUtils::isGvfsMountFile(path, true); + QMimeType mimetype; + bool isdesktop = currentisgvfs ? FileUtils::isDesktopFile(info, mimetype) : + FileUtils::isDesktopFile(info); + if (isnotsyslink && isdesktop) { + return DAbstractFileInfoPointer(new DesktopFileInfo(info)); + } + + if (currentisgvfs) { + return DAbstractFileInfoPointer(new DGvfsFileInfo(info, mimetype, false)); + } + return DAbstractFileInfoPointer(new DFileInfo(info)); + } + + DUrl url() const override + { + return DUrl::fromLocalFile(iterator.path()); + } + +private: + QDirIterator iterator; + bool isgvfs = false; +}; + +class DFMSortInodeDirIterator : public DDirIterator +{ +public: + explicit DFMSortInodeDirIterator(const QString &path) + : dir(path) + { + + } + + ~DFMSortInodeDirIterator() override + { + if (sortFiles) { + free(sortFiles); + } else if (sortFilesIndex) { + delete sortFilesIndex; + } + } + + DUrl next() override + { + const QByteArray name(sortFilesIndex); + + currentFileInfo.setFile(dir.absoluteFilePath(QFile::decodeName(name))); + sortFilesIndex += name.length() + 1; + + return DUrl::fromLocalFile(currentFileInfo.absoluteFilePath()); + } + + bool hasNext() const override + { + if (!sortFilesIndex) { + sortFiles = savedir(QFile::encodeName(dir.absolutePath()).constData()); + + if (sortFiles) { + sortFilesIndex = sortFiles; + } else { + sortFilesIndex = new char(0); + } + } + + return *sortFilesIndex; + } + + QString fileName() const override + { + return currentFileInfo.fileName(); + } + + DUrl fileUrl() const override + { + return DUrl::fromLocalFile(currentFileInfo.filePath()); + } + + const DAbstractFileInfoPointer fileInfo() const override + { + //判断是否是gvfs文件,是就创建DGvfsFileInfo + bool currentisgvfs = FileUtils::isGvfsMountFile(currentFileInfo.path(), true); + if (currentisgvfs) { + return DAbstractFileInfoPointer(new DGvfsFileInfo(currentFileInfo, false)); + } + return DAbstractFileInfoPointer(new DFileInfo(currentFileInfo)); + } + + DUrl url() const override + { + return DUrl::fromLocalFile(dir.absolutePath()); + } + +private: + QDir dir; + mutable char *sortFiles = nullptr; + mutable char *sortFilesIndex = nullptr; + QFileInfo currentFileInfo; +}; + +#ifndef DISABLE_QUICK_SEARCH +class DFMAnythingDirIterator : public DDirIterator +{ +public: + DFMAnythingDirIterator(ComDeepinAnythingInterface *u, + const QString &path, const QString &k) + : interface(u) + , keyword(k) + , dir(path) + { + keyword = DFMRegularExpression::checkWildcardAndToRegularExpression(keyword); + } + + ~DFMAnythingDirIterator() override + { + + } + + DUrl next() override + { + currentFileInfo.setFile(searchResults.takeFirst()); + + return fileUrl(); + } + + bool hasNext() const override + { + if (!initialized) { + const QString &dir_path = dir.absolutePath(); + // 如果挂载在此路径下的其它目录也支持索引数据, 则一并搜索 + searchDirList << interface->hasLFTSubdirectories(dir_path); + + if (searchDirList.isEmpty() || searchDirList.first() != dir_path) { + searchDirList.prepend(dir_path); + } + + initialized = true; + } + + while (searchResults.isEmpty() && !searchDirList.isEmpty()) { + const auto result = interface->search(100, 500, searchStartOffset, searchEndOffset, searchDirList.first(), keyword, true); + + searchResults = result.argumentAt<0>(); + searchStartOffset = result.argumentAt<1>(); + searchEndOffset = result.argumentAt<2>(); + + // 当前目录已经搜索到了结尾 + if (searchStartOffset >= searchEndOffset) { + searchStartOffset = searchEndOffset = 0; + searchDirList.removeAt(0); + } + + // 如果路径中存在链接,需要将其还原,用于展示 + if (m_hasSymLink) { + for (auto &path : searchResults) { + path.replace(m_newPrefix, m_oldPrefix); + if (m_isAddDataPrefix && path.startsWith("/data")) + path.remove(0, 5); + } + } else if (m_isAddDataPrefix) { + for (auto &path : searchResults) { + if (path.startsWith("/data")) + path.remove(0, 5); + } + } + } + + return !searchResults.isEmpty(); + } + + QString fileName() const override + { + return currentFileInfo.fileName(); + } + + DUrl fileUrl() const override + { + return DUrl::fromLocalFile(currentFileInfo.filePath()); + } + + const DAbstractFileInfoPointer fileInfo() const override + { + bool currentisgvfs = FileUtils::isGvfsMountFile(currentFileInfo.path(), true); + if (currentisgvfs) { + return DAbstractFileInfoPointer(new DGvfsFileInfo(currentFileInfo, false)); + } + return DAbstractFileInfoPointer(new DFileInfo(currentFileInfo)); + } + + DUrl url() const override + { + return DUrl::fromLocalFile(dir.absolutePath()); + } + + /// + /// \brief setPathPropertity 设置路径属性 + /// \param hasSymLink 是否存在链接目录 + /// \param oldPrefix 原始前缀 + /// \param newPrefix 修改后的前缀 + /// \param isAddDataPrefix 是否添加了data目录前缀 + /// + void setPathPropertity(bool hasSymLink, const QString &oldPrefix, const QString &newPrefix, const bool isAddDataPrefix) + { + m_hasSymLink = hasSymLink; + m_oldPrefix = oldPrefix; + m_newPrefix = newPrefix; + m_isAddDataPrefix = isAddDataPrefix; + } + +private: + ComDeepinAnythingInterface *interface; + QString keyword; + + mutable bool initialized = false; + mutable QStringList searchDirList; + mutable quint32 searchStartOffset = 0, searchEndOffset = 0; + mutable QStringList searchResults; + + bool m_hasSymLink = false; + bool m_isAddDataPrefix = false; + QString m_oldPrefix; + QString m_newPrefix; + + QDir dir; + QFileInfo currentFileInfo; +}; +#endif // DISABLE_QUICK_SEARCH + +#ifdef DISABLE_QUICK_SEARCH +//#if 0 +void Delay_MSec(unsigned int msec) +{ + QTime dieTime = QTime::currentTime().addMSecs(msec); + + while (QTime::currentTime() < dieTime) + + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); + +} +QString printList(BTreeNode *pNode) +{ + + QString fullPath(""); + if (pNode == nullptr) { + return ""; + } else { + int i = 0; + while (pNode != nullptr) { + if (pNode->name != nullptr) { + fullPath.insert(0, pNode->name); + if (strcmp(pNode->name, "") != 0) { + fullPath.insert(0, "/"); + } + } + pNode = pNode->parent; + i++; + } + } + + return fullPath; +} + +class DFMFSearchDirIterator : public DDirIterator +{ +public: + DFMFSearchDirIterator(const QString &path, const QString &k) + : keyword(k) + , dir(path) + { + dfsearch = new DFSearch(path, this); + } + + ~DFMFSearchDirIterator() override + { + if (dfsearch) { + delete dfsearch; + dfsearch = nullptr; + } + } + + static void callbackFunc(void *back, void *self) + { + if (!self || !back) { + return; + } + DFMFSearchDirIterator *it = static_cast(self); + DatabaseSearch *result = static_cast(back); + if (!result) + return; + GPtrArray *results = result->results; + if (results && results->len > 0) { + uint32_t num_results = results->len; + for (uint32_t j = 0; j < num_results; j++) { + if (results->len > 0 && results->pdata) { + DatabaseSearchEntry *entry = static_cast(g_ptr_array_index(results, j)); + QString strResult = ""; + if (entry && entry->node) { + strResult = printList(entry->node); + } + + if (!strResult.isEmpty()) { + /*fix task 30348 针对搜索不能搜索部分目录,可以将根目录加入索引库,搜索结果出来以后进行当前目录过滤就可以*/ + QFileInfo info(strResult); + QString fullPath = info.absoluteFilePath(); + QString filePath = info.absolutePath(); + if (filePath.startsWith(it->dir.absolutePath()) && !it->searchResults.contains(fullPath)) { + // 修复wayland-bug-51754 + // 刷选出保险箱内的文件,使其不被检索出来 + if (!VaultController::isVaultFile(it->dir.absolutePath()) && VaultController::isVaultFile(fullPath)) + continue; + it->searchResults.append(strResult); + } + } + } + } + qDebug() << "-------callback:" << num_results; + } + it->mDone = true; + } + + DUrl next() override + { + currentFileInfo.setFile(searchResults.takeFirst()); + + return fileUrl(); + } + + bool hasNext() const override + { + if (!initialized) { + const QString &dir_path = dir.absolutePath(); + //fix bug62654,搜索过程中有的时候无法搜索到东西,需要先清理搜索结果,再进行搜索 + searchResults.clear(); + if (searchDirList.isEmpty() || searchDirList.first() != dir_path) { + searchDirList.prepend(dir_path); + dfsearch->searchByKeyWord(keyword, callbackFunc); + qDebug() << "*******************************find"; + mDone = false; + } + + initialized = true; + } + if (!resultinit) { + int i = 0; + while (!closed) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + if (mDone || i++ > 10) { + break; + } + } + } + + resultinit = true; + searchDirList.removeAt(0); + return !searchResults.isEmpty(); + } + + QString fileName() const override + { + return currentFileInfo.fileName(); + } + + DUrl fileUrl() const override + { + return DUrl::fromLocalFile(currentFileInfo.filePath()); + } + + const DAbstractFileInfoPointer fileInfo() const override + { + return DAbstractFileInfoPointer(new DFileInfo(currentFileInfo)); + } + + DUrl url() const override + { + return DUrl::fromLocalFile(dir.absolutePath()); + } + + void close() override + { + closed = true; + if (dfsearch) + dfsearch->stop(); + } +private: + QString keyword; + mutable bool resultinit = false; + mutable bool initialized = false; + mutable QStringList searchDirList; + mutable quint32 searchStartOffset = 0, searchEndOffset = 0; + mutable QStringList searchResults; + + mutable bool mDone = false; + bool closed = false; + DFSearch *dfsearch = nullptr; + QDir dir; + QFileInfo currentFileInfo; +}; +#endif // DISABLE_FSEARCH + +class FileDirIterator : public DDirIterator +{ +public: + FileDirIterator(const QString &url, + const QStringList &nameFilters, + QDir::Filters filter, + QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags, + const bool gvfs = false); + ~FileDirIterator() override; + + DUrl next() override; + bool hasNext() const override; + + QString fileName() const override; + DUrl fileUrl() const override; + const DAbstractFileInfoPointer fileInfo() const override; + DUrl url() const override; + void close() override; + + bool enableIteratorByKeyword(const QString &keyword) override; + + /// + /// \brief hasSymLinkDir 用于判断当前路径中是否存在快捷方式 + /// \param path 需要判断的路径 + /// \return + /// + bool hasSymLinkDir(const QString &path); + + QString realSearchPath; // 真实的搜索路径 + QString oldPrefix; // 记录链接路径 + QString newPrefix; // 记录链接指向的路径 + + DFMFileListFile *hiddenFiles = nullptr; + +private: + DDirIterator *iterator = nullptr; + QDir::Filters filters; + bool nextIsCached = false; + QHash nextInofCached; +}; + +FileController::FileController(QObject *parent) + : DAbstractFileController(parent) +{ + qRegisterMetaType>(QT_STRINGIFY(QList)); +} + +bool FileController::findExecutable(const QString &executableName, const QStringList &paths) +{ + return !QStandardPaths::findExecutable(executableName, paths).isEmpty(); +} + +const DAbstractFileInfoPointer FileController::createFileInfo(const QSharedPointer &event) const +{ + DUrl url = event->url(); + QString localFile = url.toLocalFile(); + + //父目录是gvfs目录,那么子目录和子文件必须是gvfs文件 + bool currentisgvfs = FileUtils::isGvfsMountFile(url.toLocalFile(), true); + + QMimeType mimetype; + bool isdesktop = currentisgvfs ? FileUtils::isDesktopFile(localFile, mimetype) : + FileUtils::isDesktopFile(localFile); + + if (isdesktop) { + QFileInfo info(localFile); // time cost is about 100 ms + if (!info.isSymLink()) { + return DAbstractFileInfoPointer(new DesktopFileInfo(event->url())); + } + } + + if (currentisgvfs) { + //TODO: create FileInfo cost about 1000 ms on andriod mobile + return DAbstractFileInfoPointer(new DGvfsFileInfo(event->url(), false)); + } + + return DAbstractFileInfoPointer(new DFileInfo(event->url())); +} + +const DDirIteratorPointer FileController::createDirIterator(const QSharedPointer &event) const +{ + return DDirIteratorPointer(new FileDirIterator(event->url().toLocalFile(), event->nameFilters(), + event->filters(), event->flags(), event->isGvfsFile())); +} + +bool FileController::openFile(const QSharedPointer &event) const +{ + DUrl fileUrl = event->url(); + + const DAbstractFileInfoPointer pfile = createFileInfo(dMakeEventPointer(this, fileUrl)); + + if (pfile->isSymLink()) { + const DAbstractFileInfoPointer &linkInfo = DFileService::instance()->createFileInfo(this, pfile->symLinkTarget()); + + if (!linkInfo) { + dialogManager->showErrorDialog(tr("Unable to find the original file"), QString()); + return false; + } + const_cast(fileUrl) = linkInfo->redirectedFileUrl(); + if (!linkInfo->exists() && !FileUtils::isSmbUnmountedFile(fileUrl)) { + dialogManager->showBreakSymlinkDialog(linkInfo->fileName(), fileUrl); + return false; + } + } + + if (FileUtils::isExecutableScript(fileUrl.toLocalFile())) { + int code = dialogManager->showRunExcutableScriptDialog(fileUrl, event->windowId()); + return FileUtils::openExcutableScriptFile(fileUrl.toLocalFile(), code); + } + + if (FileUtils::isFileRunnable(fileUrl.toLocalFile()) && !pfile->isDesktopFile()) { + int code = dialogManager->showRunExcutableFileDialog(fileUrl, event->windowId()); + return FileUtils::openExcutableFile(fileUrl.toLocalFile(), code); + } + + if (FileUtils::shouldAskUserToAddExecutableFlag(fileUrl.toLocalFile()) && !pfile->isDesktopFile()) { + int code = dialogManager->showAskIfAddExcutableFlagAndRunDialog(fileUrl, event->windowId()); + return FileUtils::addExecutableFlagAndExecuse(fileUrl.toLocalFile(), code); + } + + QString url = fileUrl.toLocalFile(); + if (FileUtils::isFileWindowsUrlShortcut(url)) { + url = FileUtils::getInternetShortcutUrl(url); + } + + bool result = FileUtils::openFile(url); + if (!result) { + QFile file(url); + if (file.exists()) {//! 文件打开失败,排除已被删除的原因 + AppController::instance()->actionOpenWithCustom(event); // requestShowOpenWithDialog + } + file.close(); + } + + return result; +} + +bool FileController::openFiles(const QSharedPointer &event) const +{ + DUrlList fileUrls = event->urlList(); + DUrlList packUrl; + QStringList pathList; + bool result = false; + + for (DUrl fileUrl : fileUrls) { + const DAbstractFileInfoPointer pfile = createFileInfo(dMakeEventPointer(this, fileUrl)); + + if (pfile->isSymLink()) { + const DAbstractFileInfoPointer &linkInfo = DFileService::instance()->createFileInfo(this, pfile->symLinkTarget()); + + if (!linkInfo) { + dialogManager->showErrorDialog(tr("Unable to find the original file"), QString()); + continue; + } + fileUrl = linkInfo->redirectedFileUrl(); + if (!linkInfo->exists() && !FileUtils::isSmbUnmountedFile(fileUrl)) { + dialogManager->showBreakSymlinkDialog(linkInfo->fileName(), fileUrl); + continue; + } + } + + if (FileUtils::isExecutableScript(fileUrl.toLocalFile())) { + int code = dialogManager->showRunExcutableScriptDialog(fileUrl, event->windowId()); + result = FileUtils::openExcutableScriptFile(fileUrl.toLocalFile(), code) || result; + continue; + } + + if (FileUtils::isFileRunnable(fileUrl.toLocalFile()) && !pfile->isDesktopFile()) { + int code = dialogManager->showRunExcutableFileDialog(fileUrl, event->windowId()); + result = FileUtils::openExcutableFile(fileUrl.toLocalFile(), code) || result; + continue; + } + + if (FileUtils::shouldAskUserToAddExecutableFlag(fileUrl.toLocalFile()) && !pfile->isDesktopFile()) { + int code = dialogManager->showAskIfAddExcutableFlagAndRunDialog(fileUrl, event->windowId()); + result = FileUtils::addExecutableFlagAndExecuse(fileUrl.toLocalFile(), code) || result; + continue; + } + + packUrl << fileUrl; + QString url = fileUrl.toLocalFile(); + if (FileUtils::isFileWindowsUrlShortcut(url)) { + url = FileUtils::getInternetShortcutUrl(url); + } + pathList << url; + } + + if (!pathList.empty()) { + if (event->isEnter()) { + result = FileUtils::openEnterFiles(pathList); + } else { + result = FileUtils::openFiles(pathList); + } + if (!result) { + for (const DUrl &fileUrl : packUrl) { + AppController::instance()->actionOpenWithCustom(dMakeEventPointer(event->sender(), fileUrl)); // requestShowOpenWithDialog + } + } + } + + return result; +} + +bool FileController::openFileByApp(const QSharedPointer &event) const +{ + //处理快捷方式,还原成原路径 + DUrl fileUrl = event->url(); + + const DAbstractFileInfoPointer pfile = createFileInfo(dMakeEventPointer(this, fileUrl)); + + if (pfile->isSymLink()) { + const DAbstractFileInfoPointer &linkInfo = DFileService::instance()->createFileInfo(this, pfile->symLinkTarget()); + + if (!linkInfo) { + dialogManager->showErrorDialog(tr("Unable to find the original file"), QString()); + return false; + } + const_cast(fileUrl) = linkInfo->redirectedFileUrl(); + if (!linkInfo->exists() && !FileUtils::isSmbUnmountedFile(fileUrl)) { + dialogManager->showBreakSymlinkDialog(linkInfo->fileName(), fileUrl); + return false; + } + } + return FileUtils::openFilesByApp(event->appName(), {fileUrl.toString()}); +} + +bool FileController::openFilesByApp(const QSharedPointer &event) const +{ + //处理快捷方式,还原成原路径 + QList fileUrls = event->urlList(); + + QStringList pathList; + + for (DUrl fileUrl : fileUrls) { + const DAbstractFileInfoPointer pfile = createFileInfo(dMakeEventPointer(this, fileUrl)); + + if (pfile->isSymLink()) { + const DAbstractFileInfoPointer &linkInfo = DFileService::instance()->createFileInfo(this, pfile->symLinkTarget()); + + if (!linkInfo) { + dialogManager->showErrorDialog(tr("Unable to find the original file"), QString()); + continue; + } + fileUrl = linkInfo->redirectedFileUrl(); + if (!linkInfo->exists() && !FileUtils::isSmbUnmountedFile(fileUrl)) { + dialogManager->showBreakSymlinkDialog(linkInfo->fileName(), fileUrl); + continue; + } + } + QString url = fileUrl.toLocalFile(); + if (FileUtils::isFileWindowsUrlShortcut(url)) { + url = FileUtils::getInternetShortcutUrl(url); + } + pathList << url; + } + + return FileUtils::openFilesByApp(event->appName(), pathList); + +} + +bool FileController::compressFiles(const QSharedPointer &event) const +{ + if (findExecutable("file-roller")) { + QStringList args; + args << "-d"; + foreach (DUrl url, event->urlList()) { + args << url.toLocalFile(); + } + qDebug() << args; + bool result = QProcess::startDetached("file-roller", args); + return result; + } else { + dialogManager->showErrorDialog(tr("Kindly Reminder"), tr("Please install File Roller first and then continue")); + qDebug() << "file-roller is not installed"; + } + + return false; +} + +bool FileController::decompressFile(const QSharedPointer &event) const +{ + if (findExecutable("file-roller")) { + QStringList args; + args << "-f"; + for (auto it : event->urlList()) { + args << it.toLocalFile(); + } + qDebug() << args; + bool result = QProcess::startDetached("file-roller", args); + return result; + } else { + dialogManager->showErrorDialog(tr("Kindly Reminder"), tr("Please install File Roller first and then continue")); + qDebug() << "file-roller is not installed"; + } + + return false; +} + +bool FileController::decompressFileHere(const QSharedPointer &event) const +{ + if (findExecutable("file-roller")) { + QStringList args; + args << "-h"; + for (auto it : event->urlList()) { + args << it.toLocalFile(); + } + qDebug() << args; + bool result = QProcess::startDetached("file-roller", args); + return result; + } else { + dialogManager->showErrorDialog(tr("Kindly Reminder"), tr("Please install File Roller first and then continue")); + qDebug() << "file-roller is not installed"; + } + + return false; +} + +bool FileController::writeFilesToClipboard(const QSharedPointer &event) const +{ + //计算机和回收站桌面文件不能被复制或剪切,从这里过滤通过快捷键复制剪切的计算机和回收站桌面文件url + DUrlList urlList = event->urlList(); + urlList.removeAll(DesktopFileInfo::computerDesktopFileUrl()); + urlList.removeAll(DesktopFileInfo::trashDesktopFileUrl()); + urlList.removeAll(DesktopFileInfo::homeDesktopFileUrl()); + + if (urlList.isEmpty()) { + return false; + } + + DFMGlobal::setUrlsToClipboard(DUrl::toQUrlList(urlList), event->action()); + + return true; +} + +bool FileController::renameFileByGio(const DUrl &oldUrl, const DUrl &newUrl) const +{ + bool result = false; + QString fname = oldUrl.fileName(); + QString tname = newUrl.fileName(); + QString from = oldUrl.parentUrl().toLocalFile(); + QString to = newUrl.parentUrl().toLocalFile(); + + if (to.compare(from) != 0) { + qDebug() << "gio API can not rename file or directory those are not under same path!"; + return false; + } + + //获取当前目录 + const QString &curd = QDir::currentPath(); + + GError *error = nullptr; + if (!QDir::setCurrent(to)) { + qDebug() << "failed to chdir " << to; + return false; + } + + GFile *file = g_file_new_for_path(fname.toStdString().c_str()); + GFile *new_file = g_file_set_display_name(file, tname.toStdString().c_str(), nullptr, &error); + if (new_file == nullptr) { + qDebug() << error->message; + g_error_free(error); + } else { + char *path = g_file_get_path(new_file); + qDebug() << "Rename successful. New path: " << path; + g_object_unref(new_file); + g_free(path); + result = true; + } + + g_object_unref(file); + + if (result) { + emit fileSignalManager->fileMoved(from, fname, to, tname); + } + + if (!QDir::setCurrent(curd)) { + qDebug() << "failed to return to directory " << curd; + } + + return result; +} + +bool FileController::renameFile(const QSharedPointer &event) const +{ + const DUrl &oldUrl = event->fromUrl(); + const DUrl &newUrl = event->toUrl(); + + QFile file(oldUrl.toLocalFile()); + const QString &newFilePath = newUrl.toLocalFile(); + + const DAbstractFileInfoPointer &oldfilePointer = DFileService::instance()->createFileInfo(this, oldUrl); + const DAbstractFileInfoPointer &newfilePointer = DFileService::instance()->createFileInfo(this, newUrl); + + bool result(false); + + if (oldfilePointer->isDesktopFile() && !oldfilePointer->isSymLink()) { + QString filePath = oldUrl.toLocalFile(); + Properties desktop(filePath, "Desktop Entry"); + QString key; + QString localKey = QString("Name[%1]").arg(QLocale::system().name()); + if (desktop.contains(localKey)) { + key = localKey; + } else { + key = "Name"; + } + + const QString old_name = desktop.value(key).toString(); + + desktop.set(key, newfilePointer->fileName()); + desktop.set("X-Deepin-Vendor", QStringLiteral("user-custom")); + result = desktop.save(filePath, "Desktop Entry"); + + if (result) { + const QString path = QFileInfo(file).absoluteDir().absoluteFilePath(old_name); + + DFMEventDispatcher::instance()->processEvent(event, dMakeEventPointer(nullptr, oldUrl, DUrl::fromLocalFile(path))); + } + } else { + if (newFilePath.contains("gvfs/mtp")) { + result = renameFileByGio(oldUrl, newUrl); + } + + if (!result) { + result = file.rename(newFilePath); + } + + if (!result) { + result = QProcess::execute("mv \"" + file.fileName().toUtf8() + "\" \"" + newFilePath.toUtf8() + "\"") == 0; + } + + // mtp ftp(和ftp搭建的配置有关系) 目录无法删除,因此采用复制再删除的模式 + if (!result && (FileUtils::isFtpFile(oldUrl) || newFilePath.contains("gvfs/mtp")) && QFileInfo(file).isDir()) { + result = QProcess::execute("cp -r \"" + file.fileName().toUtf8() + "\" \"" + newFilePath.toUtf8() + "\"") == 0; + + if (result) { + QProcess::execute("rm -r \"" + file.fileName().toUtf8() + "\""); + } else { + QProcess::execute("rm -r \"" + newFilePath.toUtf8() + "\""); + } + } + + if (result) { + DFMEventDispatcher::instance()->processEvent(event, dMakeEventPointer(nullptr, newUrl, oldUrl)); + + //重命名成功时需要判断该文件原路径是否被添加到了剪贴版,如果是,就需要替换剪贴板路径。 + QList clipUrls = DFMGlobal::fetchUrlsFromClipboard(); + bool needReset = false; + for (QUrl &clipUrl : clipUrls) { + if (clipUrl.path() == oldUrl.path()) { + clipUrl.setUrl(newUrl.url()); + needReset = true; + } + } + + if (needReset) { + DFMGlobal::setUrlsToClipboard(clipUrls, DFMGlobal::fetchClipboardAction()); + } + } + } + + return result; +} + +bool FileController::isExtDeviceJobCase(void *curJob, const DUrl &url) const +{ + DFileCopyMoveJob *thisJob = static_cast(curJob); + if (!thisJob) + return false; + DUrlList srcUrlList = thisJob->sourceUrlList(); + DUrl targetUrl = thisJob->targetUrl(); + + QString devId; + QString filePath = url.path(); // 转换光盘路径为实际挂载路径 + if (url.scheme() == BURN_SCHEME) { + devId = url.path().remove("/" BURN_SEG_ONDISC "/").replace("/", "_"); // /dev/sr0/disc_files/ ——> _dev_sr0 + foreach (auto d, deviceListener->getDeviceList()) { + if (url.path().contains(d->getId())) { + filePath = d->getMountPoint(); + filePath.remove("file://"); + break; + } + } + } + + static const QString stagingPathPrefix = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/" + qApp->organizationName() + "/" DISCBURN_STAGING "/"; + QString stagingPath; + if (!devId.isEmpty()) + stagingPath = stagingPathPrefix + devId; + else + stagingPath = filePath; // 不为光驱时,目标路径就是设备的挂载点 + // 源路径为光盘文件或目标路径为暂存路径 + if (!stagingPath.isEmpty() && targetUrl.path().contains(stagingPath)) + return true; + foreach (auto u, srcUrlList) { + if (u.path().contains(filePath)) + return true; + } + return isDiscburnJobCase(thisJob, url); +} + +bool FileController::isDiscburnJobCase(void *curJob, const DUrl &url) const +{ + DFileCopyMoveJob *thisJob = static_cast(curJob); + + QString burnDestDevice = url.burnDestDevice(); + + DUrlList srcUrlList = thisJob->sourceUrlList(); + DUrl targetUrl = thisJob->targetUrl(); + + burnDestDevice.replace('/', '_'); + + // 查看当前路径是否是光驱缓存路径 + bool isDiscCase = false; + if (targetUrl.path().contains(DISCBURN_CACHE_MID_PATH) && + targetUrl.path().contains(burnDestDevice)) { + isDiscCase = true; + } + + foreach (DUrl oneUrl, srcUrlList) { + if (oneUrl.path().contains(DISCBURN_CACHE_MID_PATH) && + oneUrl.path().contains(burnDestDevice)) { + isDiscCase = true; + break; + } + } + + return isDiscCase; +} +// fix bug 35855修改复制拷贝流程,拷贝线程不去阻塞主线程,拷贝线程自己去处理,主线程直接返回,拷贝线程结束了在去处理以前的后续操作,delete还是走老流程 +DUrlList FileController::pasteFilesV2(const QSharedPointer &event, DFMGlobal::ClipboardAction action, const DUrlList &list, const DUrl &target, bool slient, bool force, bool bold) const +{ + // fix bug 27109 在某种情况下,存在 FileCopyMoveJob 还没被析构,但其中的成员 StatisticJob 已经被析构,又在 FileCopyMoveJob 的函数中调用了 StatisticJob 的对象,导致崩溃 + // 所以这里将原来的普通指针以 deleteLater 析构的内存管理方式交给智能指针去判定。测试百次左右没有再发生崩溃的现象。 + // 该现象发生于从搜索列表中往光驱中发送文件夹还不被支持的时候。现已可以从搜索列表、最近列表、标签列表中往光驱中发送文件 + QSharedPointer job = QSharedPointer(new DFileCopyMoveJob()); + //! 当前拷贝如果是退回到回收站,如要在job中保存回收站中文件原路径 + if (!event.isNull() && !qvariant_cast(event->cutData()).isEmpty()) { + job->setCurTrashData(event->cutData()); + } + + // 当前线程退出,局不变currentJob被释放,但是ErrorHandle线程还在使用它 + // fix bug 31324,判断当前操作是否是清空回收站,是就在结束时改变清空回收站状态 + bool bdoingcleartrash = DFileService::instance()->getDoClearTrashState(); + if (action == DFMGlobal::DeleteAction && bdoingcleartrash && list.count() == 1 && + list.first().toString().endsWith(".local/share/Trash/files")) { + connect(job.data(), &QThread::finished, this, [ = ]() { + DFileService::instance()->setDoClearTrashState(false); + }); + } + + if (force) { + job->setFileHints(DFileCopyMoveJob::ForceDeleteFile); + } + + // sp3 feature: 复制时不进行校验,后面调整为独立的功能 + job->setFileHints(job->fileHints() | DFileCopyMoveJob::DontIntegrityChecking); + if (action == DFMGlobal::DeleteAction) { + // for remove mode + job->setActionOfErrorType(DFileCopyMoveJob::NonexistenceError, DFileCopyMoveJob::SkipAction); + } + + if (QThread::currentThread()->loopLevel() <= 0) { + // 确保对象所在线程有事件循环 + job->moveToThread(qApp->thread()); + } + + class ErrorHandle : public QObject, public DFileCopyMoveJob::Handle + { + public: + ErrorHandle(QSharedPointer job, bool s) + : QObject(nullptr) + , slient(s) + , fileJob(job) + { + //线程启动传递源地址和目标地址 + connect(job.data(), &DFileCopyMoveJob::currentJobChanged, this, [this](const DUrl & from, const DUrl & to) { + QMutex mutex; + mutex.lock(); + currentJob.first = from; + currentJob.second = to; + mutex.unlock(); + }, Qt::DirectConnection); + if (!slient) { + timer_id = startTimer(1000); + moveToThread(qApp->thread()); + } else { + moveToThread(qApp->thread()); + } + } + + ~ErrorHandle() override + { + if (timer_id > 0) { + killTimer(timer_id); + } + dialogManager->taskDialog()->removeTaskJob(fileJob.data()); + fileJob->disconnect(); + fileJob.reset(nullptr); + qDebug() << "file copy error handle release!"; + } + + // 处理任务对话框显示之前的错误, 无法处理的错误将立即弹出对话框处理 + DFileCopyMoveJob::Action handleError(DFileCopyMoveJob *job, DFileCopyMoveJob::Error error, + const DAbstractFileInfoPointer sourceInfo, + const DAbstractFileInfoPointer targetInfo) override + { + if (slient) { + return DFileCopyMoveJob::SkipAction; + } + + if (error == DFileCopyMoveJob::DirectoryExistsError || error == DFileCopyMoveJob::FileExistsError) { + if (sourceInfo->fileUrl() == targetInfo->fileUrl() || + DStorageInfo::isSameFile(sourceInfo->fileUrl().path(), targetInfo->fileUrl().path())) { + return DFileCopyMoveJob::CoexistAction; + } + } + + if (timer_id > 0) { + killTimer(timer_id); + timer_id = 0; + } + + DFileCopyMoveJob::Handle *handle = dialogManager->taskDialog()->addTaskJob(job, true); + // fix bug 62822 设置当前进度条已显示,来显示进度到100% + fileJob->setProgressShow(true); + DUrl fromUrl = sourceInfo ? sourceInfo->fileUrl() : DUrl(); + DUrl toUrl = targetInfo ? targetInfo->fileUrl() : DUrl(); + emit job->currentJobChanged(fromUrl, toUrl, true); + + if (!handle) { + qWarning() << "addTaskJob create handle failed!!"; + return DFileCopyMoveJob::SkipAction; + } + return handle->handleError(job, error, sourceInfo, targetInfo); + } + + void timerEvent(QTimerEvent *e) override + { + if (e->timerId() != timer_id) { + return QObject::timerEvent(e); + } + + killTimer(timer_id); + timer_id = 0; + + //1. 此时说明pasteFilesV2函数已经结束 + if (!fileJob) + return; + //这里会出现pasteFilesV2函数线程和当前线程是同时在执行,会出现在1处pasteFilesV2所在线程 没结束,但是这时pasteFilesV2所在线程 结束 + //这里是延时处理,会出现正在执行吃此处代码时,filejob线程完成了 + if (!fileJob->isFinished() && fileJob->isCanShowProgress()) { + dialogManager->taskDialog()->addTaskJob(fileJob.data(), true); + // fix bug 62822 设置当前进度条已显示,来显示进度到100% + fileJob->setProgressShow(true); + emit fileJob->currentJobChanged(currentJob.first, currentJob.second, false); + } + //在移动到同一个目录时,先不现实进度条,当有其他目录到同一个目录时,才会去显示 + if (!fileJob->isFinished() && !fileJob->isCanShowProgress()) { + timer_id = startTimer(1000); + } + } + + int timer_id = 0; + bool slient; + QSharedPointer fileJob; + QPair currentJob; + }; + + ErrorHandle *error_handle = new ErrorHandle(job, slient); + + // bug 29419 期望在外设进行卸载,弹出时,终止复制操作 + DFileCopyMoveJob *thisJob = job.data(); + connect(fileSignalManager, &FileSignalManager::requestAsynAbortJob, thisJob, [thisJob, this](const DUrl & url) { + + bool isExtDeviceWorkingJob = isExtDeviceJobCase(thisJob, url); + if (isExtDeviceWorkingJob) { + + emit thisJob->stop(); + qDebug() << "break the FileCopyMoveJob for the device:" << url.path(); + + thisJob->wait(); // 等job线程结束 + sleep(1); // 加一个buffer 时间等外设相关设备结束 + } + + }); + + job->setErrorHandle(error_handle, slient ? nullptr : error_handle->thread()); + + DFileCopyMoveJob::Mode mode = DFileCopyMoveJob::CopyMode; + switch (action) { + case DFMGlobal::CopyAction: + mode = DFileCopyMoveJob::CopyMode; + break; + case DFMGlobal::CutAction: + mode = DFileCopyMoveJob::CutMode; + break; + case DFMGlobal::DeleteAction: + mode = DFileCopyMoveJob::MoveMode; + break; + case DFMGlobal::RemoteAction: + mode = DFileCopyMoveJob::RemoteMode; + break; + default: + mode = DFileCopyMoveJob::UnknowMode; + } + job->setMode(mode); + + job->start(list, target); + //走以前的老流程,阻塞主线去拷贝或者删除 + if (bold) { + job->wait(); + + QTimer::singleShot(200, dialogManager->taskDialog(), [job] { + dialogManager->taskDialog()->removeTaskJob(job.data()); + }); + //fix bug 31324,判断当前操作是否是清空回收站,是就在结束时改变清空回收站状态 + if (action == DFMGlobal::CutAction && bdoingcleartrash && list.count() == 1 && + list.first().toString().endsWith(".local/share/Trash/files")) { + DFileService::instance()->setDoClearTrashState(false); + } + + if (slient) { + error_handle->deleteLater(); + } else { + QMetaObject::invokeMethod(error_handle, "deleteLater"); + } + + return job->targetUrlList(); + } + //fix bug 35855走新流程不去阻塞主线程,拷贝线程自己去运行,主线程返回,当拷贝线程结束了再去处理以前的相应处理 + connect(job.data(), &QThread::finished, dialogManager->taskDialog(), [this, thisJob, error_handle, slient, event] { + dialogManager->taskDialog()->removeTaskJob(thisJob); + DUrlList targetUrlList = thisJob->targetUrlList(); + if (slient) + { + error_handle->deleteLater(); + } else + { + QMetaObject::invokeMethod(error_handle, "deleteLater"); + } + //处理复制、粘贴和剪切(拷贝)结束后操作 fix bug 35855 + this->dealpasteEnd(targetUrlList, event); + //! 判断目标目录是否是保险箱目录如果是,发送信号激活计算保险大小的线程 + if(!targetUrlList.isEmpty() && targetUrlList.at(0).toLocalFile().contains(VaultController::makeVaultLocalPath())) { + emit VaultController::ins()->sigFinishedCopyFile(); + } + }); + + return job->targetUrlList(); +} + +void FileController::dealpasteEnd(const DUrlList &list, const QSharedPointer &event) const +{ + DUrlList valid_files = list; + + valid_files.removeAll(DUrl()); + + if (valid_files.isEmpty()) { + //到dfileservice里面作处理 + DFileService::instance()->dealPasteEnd(event, list); + return; + } + + if (event->action() == DFMGlobal::CopyAction || event->action() == DFMGlobal::RemoteAction) { + DFMEventDispatcher::instance()->processEvent(event, dMakeEventPointer(nullptr, valid_files, true), true); + } else { + const QString targetDir(QFileInfo(event->urlList().first().toLocalFile()).absolutePath()); + + if (targetDir.isEmpty()) { + //到dfileservice里面作处理 + DFileService::instance()->dealPasteEnd(event, list); + return; + } + //! 新增剪切回收站路径event->urlList() + if (targetDir.startsWith(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))) { + DFMEventDispatcher::instance()->processEvent(event, dMakeEventPointer(nullptr, valid_files, false, event->urlList()), true); + } else { + DFMEventDispatcher::instance()->processEvent(event, dMakeEventPointer(nullptr, DFMGlobal::CutAction, DUrl::fromLocalFile(targetDir), valid_files), true); + } + } + + //到dfileservice里面作处理 + DFileService::instance()->dealPasteEnd(event, list); +} + +/** + * @brief FileController::deleteFiles + * @param urlList accepted + * + * Permanently delete file or directory with the given url. + */ +bool FileController::deleteFiles(const QSharedPointer &event) const +{ + // FileJob job(FileJob::Delete); + // job.setWindowId(event->windowId()); + // dialogManager->addJob(&job); + + // job.doDelete(event->urlList()); + // dialogManager->removeJob(job.getJobId()); + // 解决撤销操作后文件删除不提示问题 + // if (event->type() == DFMEvent::DeleteFiles) { + // return DFileService::instance()->deleteFiles(nullptr, event->urlList(), false); + // } + + + bool ok = !pasteFilesV2(nullptr, DFMGlobal::DeleteAction, event->fileUrlList(), DUrl(), event->silent(), event->force(), true).isEmpty(); + for (const auto &url : event->fileUrlList()) { + if (url.toLocalFile().contains("/mtp:")) { + DUrl mtpUrl(url); + mtpUrl.setScheme(MTP_SCHEME); + DAbstractFileWatcher::ghostSignal(mtpUrl.parentUrl(), &DAbstractFileWatcher::fileDeleted, mtpUrl); + } + } + return ok; +} + +/** + * @brief FileController::moveToTrash + * @param urlList accepted + * + * Trash file or directory with the given url address. + */ +DUrlList FileController::moveToTrash(const QSharedPointer &event) const +{ + QSharedPointer job(new FileJob(FileJob::Trash)); + job->setWindowId(static_cast(event->windowId())); + dialogManager->addJob(job); + DUrlList list = job->doMoveToTrash(event->urlList()); + dialogManager->removeJob(job->getJobId()); + + // save event + const QVariant &result = DFMEventDispatcher::instance()->processEvent(event->sender(), DUrl::fromTrashFile("/"), + QStringList(), QDir::AllEntries | QDir::Hidden | QDir::System); + const QList &infos = qvariant_cast>(result); + + if (infos.isEmpty()) { + return list; + } + + const QSet &source_files_set = event->urlList().toSet(); + const QSet &target_files_set = list.toSet(); + DUrlList has_restore_files; + + for (const DAbstractFileInfoPointer &info : infos) { + const DUrl &source_file = DUrl::fromLocalFile(static_cast(info.constData())->sourceFilePath()); + + if (source_files_set.contains(source_file) && target_files_set.contains(info->mimeDataUrl())) { + has_restore_files << info->fileUrl(); + } + } + + if (has_restore_files.isEmpty()) { + return list; + } + + DFMEventDispatcher::instance()->processEvent(event, dMakeEventPointer(nullptr, has_restore_files), true); + + return list; +} + +static DUrlList pasteFilesV1(const QSharedPointer &event) +{ + const DUrlList &urlList = event->urlList(); + + if (urlList.isEmpty()) { + return DUrlList(); + } + + DUrlList list; + QDir dir(event->targetUrl().toLocalFile()); + //Make sure the target directory exists. + if (!dir.exists()) { + return list; + } + + if (!QFileInfo(event->targetUrl().toLocalFile()).isWritable()) { + qDebug() << event->targetUrl() << "is not writable"; + DUrlList urls; + urls << event->targetUrl(); + + DFMUrlListBaseEvent noPermissionEvent{event->sender(), urls}; + noPermissionEvent.setWindowId(event->windowId()); + + emit fileSignalManager->requestShowNoPermissionDialog(noPermissionEvent); + return list; + } + + if (event->action() == DFMGlobal::CutAction) { + DUrl parentUrl = DUrl::parentUrl(urlList.first()); + + if (parentUrl != event->targetUrl()) { + QSharedPointer job(new FileJob(FileJob::Move)); + job->setWindowId(static_cast(event->windowId())); + dialogManager->addJob(job); + + list = job->doMove(urlList, event->targetUrl()); + dialogManager->removeJob(job->getJobId()); + } + + DFMGlobal::clearClipboard(); + } else { + QSharedPointer job(new FileJob(FileJob::Copy)); + job->setWindowId(static_cast(event->windowId())); + dialogManager->addJob(job); + + list = job->doCopy(urlList, event->targetUrl()); + dialogManager->removeJob(job->getJobId()); + } + + return list; +} + +DUrlList FileController::pasteFile(const QSharedPointer &event) const +{ + //新代码,修改复制拷贝流程,拷贝线程不去阻塞主线程,拷贝线程自己去处理,主线程直接返回,拷贝线程结束了在去处理以前的后续操作 + + bool use_old_filejob = false; + +#ifdef SW_LABEL + /*fix bug 38276 【服务器UOS】【sw64】【SP1 update1(B11)】【DDE-UOS】【文件管理器】 复制文件到有相同的文件名存在的目录时,弹窗提示异常 + *针对申威平台做针对性处理,如果io文件存在即内核做了优化则走pasteFilesV2函数,否则走pasteFilesV1 + */ + use_old_filejob = !QFile("/proc/thread-self/io").exists(); +#endif + // 将最近使用文件url转换为本地url + DUrlList urlList = event->urlList(); + if (!urlList.isEmpty() && urlList.first().isRecentFile()) { + for (auto &url : urlList) { + const auto &local = url.path(); + url = DUrl::fromLocalFile(local); + } + event->setData(urlList); + } + + DUrlList list; + //pasteFilesV1走以前的流程 + if (use_old_filejob) { + list = pasteFilesV1(event); + + DUrlList valid_files = list; + + valid_files.removeAll(DUrl()); + + if (valid_files.isEmpty()) { + //到dfileservice里面作处理 + DFileService::instance()->dealPasteEnd(event, list); + return list; + } + + if (event->action() == DFMGlobal::CopyAction) { + DFMEventDispatcher::instance()->processEvent(event, dMakeEventPointer(nullptr, valid_files, true), true); + } else { + const QString targetDir(QFileInfo(event->fileUrlList().first().toLocalFile()).absolutePath()); + + if (targetDir.isEmpty()) { + //到dfileservice里面作处理 + DFileService::instance()->dealPasteEnd(event, list); + return list; + + } + + DFMEventDispatcher::instance()->processEvent(event, dMakeEventPointer(nullptr, DFMGlobal::CutAction, DUrl::fromLocalFile(targetDir), valid_files), true); + } + //到dfileservice里面作处理 + DFileService::instance()->dealPasteEnd(event, list); + } else { + list = pasteFilesV2(event, event->action(), event->urlList(), event->targetUrl()); + } + + return list; + +} + +bool FileController::mkdir(const QSharedPointer &event) const +{ + //Todo:: check if mkdir is ok + AppController::selectionAndRenameFile = qMakePair(event->url(), event->windowId()); + + bool ok = QDir::current().mkpath(event->url().toLocalFile()); + + if (ok) { + fileAdded(event->url()); + DFMEventDispatcher::instance()->processEvent(event, dMakeEventPointer(nullptr, DUrlList() << event->url(), true)); + } else { + // 创建文件夹失败,提示错误信息 + QString strErr = tr("Unable to create files here: %1").arg(strerror(errno)); + DThreadUtil::runInMainThread(dialogManager, &DialogManager::showMessageDialog, + DialogManager::msgWarn, strErr, "", tr("Confirm","button")); + } + + return ok; +} + +bool FileController::touch(const QSharedPointer &event) const +{ + //Todo:: check if mkdir is ok + QFile file(event->url().toLocalFile()); + + AppController::selectionAndRenameFile = qMakePair(event->url(), event->windowId()); + + if (file.open(QIODevice::WriteOnly)) { + file.close(); + fileAdded(event->url()); + } else { + // 创建文件失败,提示错误信息 + QString strErr = tr("Unable to create files here: %1").arg(strerror(errno)); + dialogManager->showMessageDialog(DialogManager::msgWarn, strErr); + + return false; + } + + DFMEventDispatcher::instance()->processEvent(event, dMakeEventPointer(nullptr, DUrlList() << event->url(), true)); + + return true; +} + +bool FileController::setPermissions(const QSharedPointer &event) const +{ + QFile file(event->url().toLocalFile()); + + event->accept(); + + return file.setPermissions(event->permissions()); +} + +bool FileController::shareFolder(const QSharedPointer &event) const +{ + ShareInfo info; + info.setPath(event->url().toLocalFile()); + + info.setShareName(event->name()); + info.setIsGuestOk(event->allowGuest()); + info.setIsWritable(event->isWritable()); + + bool ret = userShareManager->addUserShare(info); + + return ret; +} + +bool FileController::unShareFolder(const QSharedPointer &event) const +{ + userShareManager->deleteUserShareByPath(event->url().toLocalFile()); + + return true; +} + +bool FileController::openInTerminal(const QSharedPointer &event) const +{ + const QString ¤t_dir = QDir::currentPath(); + + QDir::setCurrent(event->url().toLocalFile()); + + bool ok = QProcess::startDetached(FileUtils::defaultTerminalPath()); + + QDir::setCurrent(current_dir); + + return ok; +} + +bool FileController::addToBookmark(const QSharedPointer &event) const +{ + DUrl destUrl = event->url(); + + const DAbstractFileInfoPointer &p = fileService->createFileInfo(nullptr, destUrl); + DUrl bookmarkUrl = DUrl::fromBookMarkFile(destUrl, p->fileDisplayName()); + DStorageInfo info(destUrl.path()); + QString filePath = destUrl.path(); + QString rootPath = info.rootPath(); + if (rootPath != QStringLiteral("/") || rootPath != QStringLiteral("/home")) { + QString devStr = info.device(); + QString locateUrl; + int endPos = filePath.indexOf(rootPath); + if (endPos != -1) { + endPos += rootPath.length(); + locateUrl = filePath.mid(endPos); + } + if (devStr.startsWith(QStringLiteral("/dev/"))) { + devStr = DUrl::fromDeviceId(info.device()).toString(); + } + + QUrlQuery query; + query.addQueryItem("mount_point", devStr); +// query.addQueryItem("locate_url", locateUrl); + //为防止locateUrl传入QUrl被转码,locateUrl统一保存为base64 + QByteArray ba = locateUrl.toLocal8Bit().toBase64(); + query.addQueryItem("locate_url", ba); + + bookmarkUrl.setQuery(query); + } + + return DFileService::instance()->touchFile(event->sender(), bookmarkUrl); +} + +bool FileController::removeBookmark(const QSharedPointer &event) const +{ + return DFileService::instance()->deleteFiles(nullptr, {DUrl::fromBookMarkFile(event->url(), QString())}, false); +} + +bool FileController::createSymlink(const QSharedPointer &event) const +{ + QFile file(event->fileUrl().toLocalFile()); + + bool ok = file.link(event->toUrl().toLocalFile()); + + if (ok) { + return true; + } + + if (event->force()) { + // replace symlink, remove if target was existed + QFileInfo toLink(event->toUrl().toLocalFile()); + if (toLink.isSymLink() || toLink.exists()) { + QFile::remove(event->toUrl().toLocalFile()); + } + } + + int code = ::symlink(event->fileUrl().toLocalFile().toLocal8Bit().constData(), + event->toUrl().toLocalFile().toLocal8Bit().constData()); + if (code == -1) { + ok = false; + QString errorString = strerror(errno); + dialogManager->showFailToCreateSymlinkDialog(errorString); + } else { + ok = true; + } + + return ok; +} + +DAbstractFileWatcher *FileController::createFileWatcher(const QSharedPointer &event) const +{ + return new DFileWatcher(event->url().toLocalFile()); +} + +DFileDevice *FileController::createFileDevice(const QSharedPointer &event) const +{ + const DUrl url = event->fileUrl(); + if (FileUtils::isGvfsMountFile(url.toLocalFile())) { + return new DGIOFileDevice(url); + } + + DLocalFileDevice *device = new DLocalFileDevice(); + + device->setFileUrl(url); + + return device; +} + +DFileHandler *FileController::createFileHandler(const QSharedPointer &event) const +{ + Q_UNUSED(event) + + return new DLocalFileHandler(); +} + +DStorageInfo *FileController::createStorageInfo(const QSharedPointer &event) const +{ + return new DStorageInfo(event->url().toLocalFile()); +} + +class Match +{ +public: + explicit Match(const QString &group) + { + for (const QString &key : DFMApplication::genericObtuselySetting()->keys(group)) { + const QString &value = DFMApplication::genericObtuselySetting()->value(group, key).toString(); + + int last_dir_split = value.lastIndexOf(QDir::separator()); + + if (last_dir_split >= 0) { + QString path = value.left(last_dir_split); + + if (path.startsWith("~/")) { + path.replace(0, 1, QDir::homePath()); + } + + patternList << qMakePair(path, value.mid(last_dir_split + 1)); + } else { + patternList << qMakePair(QString(), value); + } + } + } + + bool match(const QString &path, const QString &name) + { + // 这里可能会析构 先复制一份再循环 + const QList> patternListNew = patternList; + for (auto pattern : patternListNew) { + QRegularExpression re(QString(), QRegularExpression::MultilineOption); + + if (!pattern.first.isEmpty()) { + re.setPattern(pattern.first); + + if (!re.isValid()) { + qWarning() << re.errorString(); + continue; + } + + if (!re.match(path).hasMatch()) { + continue; + } + } + + if (pattern.second.isEmpty()) { + return true; + } + + re.setPattern(pattern.second); + + if (!re.isValid()) { + qWarning() << re.errorString(); + continue; + } + + if (re.match(name).hasMatch()) { + return true; + } + } + + return false; + } + + QList> patternList; +}; + +bool FileController::customHiddenFileMatch(const QString &absolutePath, const QString &fileName) +{ + static Match match("HiddenFiles"); + + return match.match(absolutePath, fileName); +} + +bool FileController::privateFileMatch(const QString &absolutePath, const QString &fileName) +{ + static Match match("PrivateFiles"); + + return match.match(absolutePath, fileName); +} + +bool FileController::setFileTags(const QSharedPointer &event) const +{ + DUrl url = handleTagFileUrl(event->url()); + if (event->tags().isEmpty()) { + const QStringList &tags = TagManager::instance()->getTagsThroughFiles({url}); + + return tags.isEmpty() || TagManager::instance()->removeTagsOfFiles(tags, {url}); + } + + // 修复bug-59180 + // 保险箱文件不要创建标签 + if (VaultController::isVaultFile(event->url().toLocalFile())) + return true; + + return TagManager::instance()->makeFilesTags(event->tags(), {url}); +} + +bool FileController::removeTagsOfFile(const QSharedPointer &event) const +{ + DUrl url = handleTagFileUrl(event->url()); + return TagManager::instance()->removeTagsOfFiles(event->tags(), {url}); +} + +QList FileController::getTagsThroughFiles(const QSharedPointer &event) const +{ + DUrlList urlList; + for (auto url : event->urlList()) + urlList << handleTagFileUrl(url); + + return TagManager::instance()->getTagsThroughFiles(urlList); +} + +QString FileController::checkDuplicateName(const QString &name) const +{ + QString destUrl = name; + QFile file(destUrl); + QFileInfo startInfo(destUrl); + + int num = 1; + + while (file.exists()) { + num++; + destUrl = QString("%1/%2 %3").arg(startInfo.absolutePath()). + arg(startInfo.fileName()).arg(num); + file.setFileName(destUrl); + } + + return destUrl; +} + +bool FileController::fileAdded(const DUrl &url) const +{ + // 华为平台特有的问题,inotify无法向mtp发送信号,因此采用以下模式在文件创建完成后来刷新模型 + if (url.toLocalFile().contains("/mtp:")) { + return DAbstractFileWatcher::ghostSignal(url.parentUrl(), &DAbstractFileWatcher::subfileCreated, url); + } + return true; +} + +DUrl FileController::handleTagFileUrl(const DUrl &url) const +{ + DUrl newUrl(url); + if (newUrl.path().startsWith("/data/home/")) + newUrl.setPath(url.path().remove(0, sizeof("/data") - 1)); + + return newUrl; +} + +FileDirIterator::FileDirIterator(const QString &path, const QStringList &nameFilters, + QDir::Filters filter, QDirIterator::IteratorFlags flags, const bool gvfs) + : DDirIterator() + , filters(filter) +{ + bool sort_inode = flags.testFlag(static_cast(DDirIterator::SortINode)); + + if (sort_inode) { + iterator = new DFMSortInodeDirIterator(path); + } else { + iterator = new DFMQDirIterator(path, nameFilters, filter, flags, gvfs); + } + + // misc, not related to the file iterator at all. + hiddenFiles = new DFMFileListFile(path); +} + +FileDirIterator::~FileDirIterator() +{ + if (iterator) { + delete iterator; + } + + if (hiddenFiles) { + delete hiddenFiles; + } +} + +DUrl FileDirIterator::next() +{ + if (nextIsCached) { + nextIsCached = false; + + return iterator->fileUrl(); + } + + return iterator->next(); +} + +bool FileDirIterator::hasNext() const +{ + if (nextIsCached) { + return true; + } + + bool hasNext = iterator->hasNext(); + + if (!hasNext) { + return false; + } + bool showHidden = filters.testFlag(QDir::Hidden); + DAbstractFileInfoPointer info; + do { + const_cast(this)->iterator->next(); + if (!info) { + info = iterator->fileInfo(); + } + //特殊判断苹果.AAEAAE文件是iPhone编辑照片时留下的缓存文件。 它记录了编辑照片时用了什么滤镜,图片裁了多少等等编辑步骤和效果。可以说AAE文件就是一堆操作的记录文件。直接隐藏 + bool bhide = info->fileName().endsWith(QString(".AAE")); + if (!bhide && !info->isPrivate() && (showHidden || (!info->isHidden() && !hiddenFiles->contains(info->fileName())))) { + break; + } + info.reset(); + } while (iterator->hasNext()); + + // file is exists + if (info) { + const_cast(this)->nextInofCached.insert(info->fileUrl(), info); + const_cast(this)->nextIsCached = true; + return true; + } + + return false; +} + +QString FileDirIterator::fileName() const +{ + return iterator->fileName(); +} + +DUrl FileDirIterator::fileUrl() const +{ + return iterator->fileUrl(); +} + +const DAbstractFileInfoPointer FileDirIterator::fileInfo() const +{ + DAbstractFileInfoPointer newinfo = const_cast\ + (this)->nextInofCached.value(iterator->fileUrl()); + if (newinfo) { + const_cast\ + (this)->nextInofCached.remove(iterator->fileUrl()); + return newinfo; + } + return iterator->fileInfo(); +} + +DUrl FileDirIterator::url() const +{ + return iterator->url(); +} + +void FileDirIterator::close() +{ + if (iterator) + iterator->close(); +} + +bool FileDirIterator::enableIteratorByKeyword(const QString &keyword) +{ +#ifdef DISABLE_QUICK_SEARCH + Q_UNUSED(keyword); +// return false; +#else // !DISABLE_QUICK_SEARCH + QString pathForSearching = iterator->url().toLocalFile(); + + static ComDeepinAnythingInterface anything("com.deepin.anything", "/com/deepin/anything", + QDBusConnection::systemBus()); + + bool isAddDataPrefix = false; + if (!anything.hasLFT(pathForSearching)) { + if (pathForSearching.startsWith("/home") && QDir("/data/home").exists()) { + pathForSearching.prepend("/data"); + if (!anything.hasLFT(pathForSearching)) + return false; + isAddDataPrefix = true; + } else { + return false; + } + } else { + qDebug() << "support quick search for: " << pathForSearching; + } + + // fix bug#48091 当文件路径中存在快捷方式时,将其转换为真实地址 + bool hasLink = false; + if (hasSymLinkDir(pathForSearching)) { + hasLink = true; + pathForSearching = realSearchPath; + } + + if (iterator) + delete iterator; + + iterator = new DFMAnythingDirIterator(&anything, pathForSearching, keyword); + static_cast(iterator)->setPathPropertity(hasLink, oldPrefix, newPrefix, isAddDataPrefix); + + return true; +#endif // DISABLE_QUICK_SEARCH + +#ifdef DISABLE_QUICK_SEARCH + const QString pathForSearching = iterator->url().toLocalFile(); + if (!DFSearch::isSupportFSearch(pathForSearching)) + return false; + + if (iterator) + delete iterator; + + iterator = new DFMFSearchDirIterator(pathForSearching, keyword); + + return true; +#endif +} + +bool FileDirIterator::hasSymLinkDir(const QString &path) +{ + QFileInfo info(path); + if (info.isSymLink()) { + oldPrefix = path; + newPrefix = info.symLinkTarget(); + realSearchPath.prepend(newPrefix); + if (oldPrefix.startsWith("/data") && newPrefix.startsWith("/home")) { + realSearchPath.prepend("/data"); + newPrefix.prepend("/data"); + } + return true; + } else { + int last_dir_split_pos = path.lastIndexOf('/'); + if (last_dir_split_pos <= 0) + return false; + + realSearchPath.prepend(path.mid(last_dir_split_pos)); + QString tmp = path.left(last_dir_split_pos); + return hasSymLinkDir(tmp); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/filecontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/filecontroller.h new file mode 100644 index 0000000..c37d364 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/filecontroller.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef FILECONTROLLER_H +#define FILECONTROLLER_H + +#include "dabstractfilecontroller.h" + +class FileInfoGatherer; +class IconProvider; +class RecentHistoryManager; +class DAbstractFileInfo; +class FileMonitor; + +class FileController : public DAbstractFileController +{ + Q_OBJECT + +public: + explicit FileController(QObject *parent = nullptr); + + static bool findExecutable(const QString &executableName, const QStringList &paths = QStringList()); + + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + const DDirIteratorPointer createDirIterator(const QSharedPointer &event) const override; + + bool openFile(const QSharedPointer &event) const override; + bool openFiles(const QSharedPointer &event) const override; + bool openFileByApp(const QSharedPointer &event) const override; + bool openFilesByApp(const QSharedPointer &event) const override; + bool compressFiles(const QSharedPointer &event) const override; + bool decompressFile(const QSharedPointer &event) const override; + bool decompressFileHere(const QSharedPointer &event) const override; + bool writeFilesToClipboard(const QSharedPointer &event) const override; + bool renameFile(const QSharedPointer &event) const override; + bool deleteFiles(const QSharedPointer &event) const override; + DUrlList moveToTrash(const QSharedPointer &event) const override; + DUrlList pasteFile(const QSharedPointer &event) const override; + bool mkdir(const QSharedPointer &event) const override; + bool touch(const QSharedPointer &event) const override; + + bool setPermissions(const QSharedPointer &event) const override; + + bool shareFolder(const QSharedPointer &event) const override; + bool unShareFolder(const QSharedPointer &event) const override; + bool openInTerminal(const QSharedPointer &event) const override; + + bool addToBookmark(const QSharedPointer &event) const override; + bool removeBookmark(const QSharedPointer &event) const override; + bool createSymlink(const QSharedPointer &event) const override; + + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + DFM_NAMESPACE::DFileDevice *createFileDevice(const QSharedPointer &event) const override; + DFM_NAMESPACE::DFileHandler *createFileHandler(const QSharedPointer &event) const override; + DFM_NAMESPACE::DStorageInfo *createStorageInfo(const QSharedPointer &event) const override; + + static bool customHiddenFileMatch(const QString &absolutePath, const QString &fileName); + static bool privateFileMatch(const QString &absolutePath, const QString &fileName); + + bool setFileTags(const QSharedPointer &event) const override; + bool removeTagsOfFile(const QSharedPointer &event) const override; + QList getTagsThroughFiles(const QSharedPointer &event) const override; + + bool renameFileByGio(const DUrl &oldUrl, const DUrl &newUrl) const; +private: + QString checkDuplicateName(const QString &name) const; + //修改复制拷贝流程,拷贝线程不去阻塞主线程,拷贝线程自己去处理,主线程直接返回,拷贝线程结束了在去处理以前的后续操作,delete还是走老流程 + DUrlList pasteFilesV2(const QSharedPointer &event, DFMGlobal::ClipboardAction action, const DUrlList &list, const DUrl &target, bool slient = false, bool force = false, bool bold = false) const; + //处理复制、粘贴和剪切(拷贝)结束后操作 fix bug 35855 + void dealpasteEnd(const DUrlList &lsit, const QSharedPointer &event) const; + bool isExtDeviceJobCase(void *curJob, const DUrl &url) const; + bool isDiscburnJobCase(void *curJob, const DUrl &url) const; + bool fileAdded(const DUrl &url) const; + + DUrl handleTagFileUrl(const DUrl &url) const; +}; + +#endif // FILECONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/fileeventprocessor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/fileeventprocessor.cpp new file mode 100644 index 0000000..0661e77 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/fileeventprocessor.cpp @@ -0,0 +1,498 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "fileeventprocessor.h" +#include "dfmevent.h" +#include "dabstractfileinfo.h" +#include "dfileservices.h" +#include "dfmeventdispatcher.h" +#include "dfmapplication.h" + +#include "appcontroller.h" +#include "views/windowmanager.h" +#include "views/dfilemanagerwindow.h" +#include "shutil/fileutils.h" +#include "singleton.h" +#include "app/define.h" +#include "tag/tagmanager.h" +#include "interfaces/dfilemenu.h" +#include "views/dtagactionwidget.h" +#include "views/dfileview.h" +#ifndef DISABLE_QUICK_SEARCH +#include "shutil/danythingmonitor.h" +#endif // DISABLE_QUICK_SEARCH +#include "shutil/dsqlitehandle.h" +#include "controllers/tagmanagerdaemoncontroller.h" +#include "interfaces/dfileservices.h" +#include "controllers/vaultcontroller.h" + +#include "dcrumbedit.h" +#include "../app/filesignalmanager.h" + +#include + +#include +#include +#include +#include + + +DFM_BEGIN_NAMESPACE + +static FileEventProcessor eventProcessor; + +FileEventProcessor::FileEventProcessor() +{ + +} + +static bool isAvfsMounted() +{ + QProcess p; + QString cmd = "/bin/bash"; + QStringList args; + args << "-c" << "ps -ax -o 'cmd'|grep '.avfs$'"; + p.start(cmd, args); + p.waitForFinished(); + QString avfsBase = qgetenv("AVFSBASE"); + QString avfsdDir; + if (avfsBase.isEmpty()) { + QString home = qgetenv("HOME"); + avfsdDir = home + "/.avfs"; + } else { + avfsdDir = avfsBase + "/.avfs"; + } + + while (!p.atEnd()) { + QString result = p.readLine().trimmed(); + if (!result.isEmpty()) { + QStringList datas = result.split(" "); + + if (datas.count() == 2) { + //compare current user's avfs path + if (datas.last() != avfsdDir) { + continue; + } + + if (datas.first() == "avfsd" && QFile::exists(datas.last())) { + return true; + } + } + } + } + + return false; +} + +static bool processMenuEvent(const QSharedPointer &event) +{ + switch (static_cast(event->action())) { + case DFMGlobal::RenameTag: { + QList selectedUrl{ event->urlList() }; + + if (!selectedUrl.isEmpty()) { +// DUrl url{ selectedUrl.first() }; + DFileManagerWindow *window = qobject_cast(WindowManager::getWindowById(event->windowId())); + + if (window) { +// window->getLeftSideBar()->scene()->onRequestRenameTag(url); + } + } + break; + } + case DFMGlobal::ChangeTagColor: { + QAction *action{ event->menu()->actionAt("Change color of present tag") }; + + if (QWidgetAction *widgetAction = qobject_cast(action)) { + + if (DTagActionWidget *tagWidget = qobject_cast(widgetAction->defaultWidget())) { + const QList &checked_colors = tagWidget->checkedColorList(); + + // reset the color item checked state + tagWidget->setCheckedColorList(QList()); + + if (checked_colors.isEmpty()) { + break; + } + + QSharedPointer tagEvent{ + dMakeEventPointer(event->sender(), + checked_colors.last(), event->selectedUrls()[0]) + }; + + AppController::instance()->actionChangeTagColor(tagEvent); + } + } + + break; + } + case DFMGlobal::TagFilesUseColor: { + QStringList new_tagNames; + + //filemenumanager已从menu中取了标记数据,这里直接从event取出来使用 + for (const QColor &color : event->tagColors()) { + const QString &tag_name = TagManager::instance()->getTagNameThroughColor(color); + + if (tag_name.isEmpty()) { + continue; + } + + new_tagNames << tag_name; + } + + DFileService::instance()->makeTagsOfFiles(nullptr, event->selectedUrls(), new_tagNames, TagManager::instance()->allTagOfDefaultColors()); + break; + } + case DFMGlobal::DeleteTags: { + return DFileService::instance()->deleteFiles(nullptr, event->selectedUrls(), false); + } + case DFMGlobal::Open: + //判断网络文件是否可以到达 + if (!event->selectedUrls().isEmpty()) { + if (!DFileService::instance()->checkGvfsMountfileBusy(event->selectedUrls().first())) { + AppController::instance()->actionOpen(dMakeEventPointer(event->sender(), event->selectedUrls())); + } + } + break; + case DFMGlobal::OpenDisk: + //判断网络文件是否可以到达 + if (!event->selectedUrls().isEmpty()) { + if (!DFileService::instance()->checkGvfsMountfileBusy(event->selectedUrls().first())) { + AppController::instance()->actionOpenDisk(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + } + } + break; + case DFMGlobal::OpenInNewWindow: + //判断网络文件是否可以到达 + if (!event->selectedUrls().isEmpty()) { + if (!DFileService::instance()->checkGvfsMountfileBusy(event->selectedUrls().first())) { + AppController::instance()->actionOpenInNewWindow(dMakeEventPointer(event->sender(), event->selectedUrls())); + } + } + break; + case DFMGlobal::OpenInNewTab: + //判断网络文件是否可以到达 + if (!event->selectedUrls().isEmpty()) { + if (!DFileService::instance()->checkGvfsMountfileBusy(event->selectedUrls().first())) { + AppController::instance()->actionOpenInNewTab(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + } + } + break; + case DFMGlobal::OpenDiskInNewWindow: + //判断网络文件是否可以到达 + if (!event->selectedUrls().isEmpty()) { + if (!DFileService::instance()->checkGvfsMountfileBusy(event->selectedUrls().first())) { + AppController::instance()->actionOpenDiskInNewWindow(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + } + } + break; + case DFMGlobal::OpenDiskInNewTab: + //判断网络文件是否可以到达 + if (!event->selectedUrls().isEmpty()) { + if (!DFileService::instance()->checkGvfsMountfileBusy(event->selectedUrls().first())) { + AppController::instance()->actionOpenDiskInNewTab(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + } + } + break; + case DFMGlobal::OpenAsAdmin: + AppController::instance()->actionOpenAsAdmin(dMakeEventPointer(event->sender(), event->selectedUrls().isEmpty() ? event->currentUrl() : event->selectedUrls().first())); + break; + case DFMGlobal::OpenWithCustom: + if (event->selectedUrls().size() == 1) { + AppController::instance()->actionOpenWithCustom(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + } + else { + AppController::instance()->actionOpenFilesWithCustom(dMakeEventPointer(event->sender(), event->selectedUrls())); + } + + break; + case DFMGlobal::OpenFileLocation: + AppController::instance()->actionOpenFileLocation(dMakeEventPointer(event->sender(), event->selectedUrls())); + break; + case DFMGlobal::Compress: + AppController::instance()->actionCompress(dMakeEventPointer(event->sender(), event->selectedUrls())); + break; + case DFMGlobal::Decompress: + AppController::instance()->actionDecompress(dMakeEventPointer(event->sender(), event->selectedUrls())); + break; + case DFMGlobal::DecompressHere: + AppController::instance()->actionDecompressHere(dMakeEventPointer(event->sender(), event->selectedUrls())); + break; + case DFMGlobal::Cut: + AppController::instance()->actionCut(dMakeEventPointer(event->sender(), event->selectedUrls())); + break; + case DFMGlobal::Copy: + AppController::instance()->actionCopy(dMakeEventPointer(event->sender(), event->selectedUrls())); + break; + case DFMGlobal::Paste: + AppController::instance()->actionPaste(dMakeEventPointer(event->sender(), event->currentUrl())); + break; + case DFMGlobal::Rename: + AppController::instance()->actionRename(dMakeEventPointer(event->sender(), event->selectedUrls())); + break; + case DFMGlobal::BookmarkRename: + AppController::instance()->actionBookmarkRename(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::BookmarkRemove: + AppController::instance()->actionBookmarkRemove(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::CreateSymlink: + AppController::instance()->actionCreateSymlink(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::SendToDesktop: + AppController::instance()->actionSendToDesktop(dMakeEventPointer(event->sender(), event->selectedUrls())); + break; + case DFMGlobal::AddToBookMark: + AppController::instance()->actionAddToBookMark(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::Delete: + if (QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier)) { + AppController::instance()->actionCompleteDeletion(dMakeEventPointer(event->sender(), event->selectedUrls())); + } else { + AppController::instance()->actionDelete(dMakeEventPointer(event->sender(), event->selectedUrls())); + } + break; + case DFMGlobal::Property: + AppController::instance()->actionProperty(dMakeEventPointer(event->sender(), event->selectedUrls().isEmpty() ? DUrlList() << event->currentUrl() : event->selectedUrls())); + break; + case DFMGlobal::NewFolder: + AppController::instance()->actionNewFolder(dMakeEventPointer(event->sender(), event->currentUrl())); + break; + case DFMGlobal::NewWindow: { + DUrlList urlList = event->selectedUrls(); + AppController::instance()->actionNewWindow(dMakeEventPointer(event->sender(), urlList)); + break; + } + case DFMGlobal::SelectAll: + AppController::instance()->actionSelectAll(event->windowId()); + break; + case DFMGlobal::ClearRecent: + AppController::instance()->actionClearRecent(event); + break; + case DFMGlobal::ClearTrash: + AppController::instance()->actionClearTrash(event->sender()); + break; + case DFMGlobal::NewWord: /// sub menu + AppController::instance()->actionNewWord(dMakeEventPointer(event->sender(), event->currentUrl())); + break; + case DFMGlobal::NewExcel: /// sub menu + AppController::instance()->actionNewExcel(dMakeEventPointer(event->sender(), event->currentUrl())); + break; + case DFMGlobal::NewPowerpoint: /// sub menu + AppController::instance()->actionNewPowerpoint(dMakeEventPointer(event->sender(), event->currentUrl())); + break; + case DFMGlobal::NewText: /// sub menu + AppController::instance()->actionNewText(dMakeEventPointer(event->sender(), event->currentUrl())); + break; + case DFMGlobal::OpenInTerminal: + AppController::instance()->actionOpenInTerminal(dMakeEventPointer(event->sender(), event->selectedUrls().isEmpty() ? DUrlList() << event->currentUrl() : event->selectedUrls())); + break; + case DFMGlobal::Restore: + AppController::instance()->actionRestore(dMakeEventPointer(event->sender(), event->selectedUrls())); + break; + case DFMGlobal::RestoreAll: + AppController::instance()->actionRestoreAll(dMakeEventPointer(event->sender(), event->currentUrl())); + break; + case DFMGlobal::CompleteDeletion: + AppController::instance()->actionCompleteDeletion(dMakeEventPointer(event->sender(), event->selectedUrls())); + break; + case DFMGlobal::Mount: + AppController::instance()->actionMount(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::MountImage: + AppController::instance()->actionMountImage(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::Unmount: + AppController::instance()->actionUnmount(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::Eject: + AppController::instance()->actionEject(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::SafelyRemoveDrive: + AppController::instance()->actionSafelyRemoveDrive(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::Settings: + AppController::instance()->actionSettings(event->windowId()); + break; + case DFMGlobal::Exit: + AppController::instance()->actionExit(event->windowId()); + break; + case DFMGlobal::SetAsWallpaper: + AppController::instance()->actionSetAsWallpaper(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::ForgetPassword: + AppController::instance()->actionForgetPassword(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::Share: + AppController::instance()->actionShare(dMakeEventPointer(event->sender(), event->selectedUrls())); + break; + case DFMGlobal::UnShare: + AppController::instance()->actionUnShare(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::ConnectToServer: + AppController::instance()->actionConnectToServer(event->windowId()); + break; + case DFMGlobal::SetUserSharePassword: + AppController::instance()->actionSetUserSharePassword(event->windowId()); + break; + case DFMGlobal::FormatDevice: + AppController::instance()->actionFormatDevice(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::OpticalBlank: + AppController::instance()->actionOpticalBlank(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + case DFMGlobal::RemoveFromRecent: + /*解决在最近使用的文档里面搜索以后删除不了的问题*/ + if (event->urlList().first().isRecentFile()||event->urlList().first().isSearchFile()) { + DFileService::instance()->deleteFiles(event->sender(), event->urlList(), false, true); + } + break; + case DFMGlobal::RemoveStashedRemoteConn: + AppController::instance()->actionRemoveStashedMount(dMakeEventPointer(event->sender(), event->selectedUrls().first())); + break; + } + + return true; +} + +bool FileEventProcessor::fmEvent(const QSharedPointer &event, QVariant *resultData) +{ + switch (event->type()) { + case DFMEvent::OpenNewWindow: { + const QSharedPointer &e = event.staticCast(); + + for (const DUrl &url : e->urlList()) { + WindowManager::instance()->showNewWindow(url, e->force()); + } + + break; + } + case DFMEvent::ChangeCurrentUrl: { + const QSharedPointer &e = event.staticCast(); + const DAbstractFileInfoPointer &fileInfo = fileService->createFileInfo(nullptr, e->fileUrl()); + if (fileInfo && fileInfo->exists() && fileInfo->isFile()) { + DUrlList urls; + fmEvent(dMakeEventPointer(event->sender(), urls << event->fileUrl(), DFMOpenUrlEvent::OpenNewWindow), resultData); + } else { + if (DFileManagerWindow *window = const_cast(qobject_cast(e->window()))) { + window->cd(e->fileUrl()); + } + } + + break; + } + case DFMEvent::OpenUrl: { + const QSharedPointer &e = event.staticCast(); + + //sort urls by files and dirs + DUrlList dirList; + //fix 修改多文件选中右键打开只启动一次应用,传多个参数 + DUrlList fileList; + //end + + foreach (DUrl url, e->urlList()) { + + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, url); + + if (DFMApplication::instance()->genericAttribute(DFMApplication::GA_PreviewCompressFile).toBool() + && isAvfsMounted() + && FileUtils::isArchive(url.toLocalFile()) + && fileInfo->mimeType().name() != "application/vnd.debian.binary-package") { + // 修复bug-63703 设置菜单压缩文件预览,搜索界面打开压缩文件时,没有正常预览压缩文件 + if (url.isSearchFile()) + url = url.searchedFileUrl(); + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(Q_NULLPTR, DUrl::fromAVFSFile(url.path())); + + if (info->exists()) { + url.setScheme(AVFS_SCHEME); + dirList << url; + continue; + } + } +#if 1 //修改多文件选中右键打开只启动一次应用,传多个参数 + if (fileInfo) { + if (fileInfo->isDir()) { + dirList << url; + } else { + fileList << url; + } + } + + //computer url is virtual dir + if (url == DUrl::fromComputerFile("/") || url.scheme() == "mount") { + dirList << url; + } + } + + if (!fileList.empty()) + { + if (fileList.size() == 1) + DThreadUtil::runInMainThread(DFileService::instance(), &DFileService::openFile, event->sender(), fileList[0]); + else + DThreadUtil::runInMainThread(DFileService::instance(), &DFileService::openFiles, event->sender(), fileList, e->isEnter()); + } +#else + if (fileInfo) { + if (fileInfo->isDir()) { + dirList << url; + } else { + DThreadUtil::runInMainThread(DFileService::instance(), &DFileService::openFile, event->sender(), url); + } + } + + //computer url is virtual dir + if (url == DUrl::fromComputerFile("/") || url.scheme() == "mount") { + dirList << url; + } + } +#endif + if (dirList.isEmpty()) { + break; + } + + QVariant result; + + if (e->dirOpenMode() == DFMOpenUrlEvent::OpenInCurrentWindow) { + const QSharedPointer &newEvent = dMakeEventPointer(event->sender(), dirList.first(), WindowManager::getWindowById(event->windowId())); + result = DThreadUtil::runInMainThread(DFMEventDispatcher::instance(), static_cast &, DFMAbstractEventHandler *)>(&DFMEventDispatcher::processEvent), newEvent, Q_NULLPTR); + } else { + const QSharedPointer &newEvent = dMakeEventPointer(event->sender(), dirList, e->dirOpenMode() == DFMOpenUrlEvent::ForceOpenNewWindow); + result = DThreadUtil::runInMainThread(DFMEventDispatcher::instance(), static_cast &, DFMAbstractEventHandler *)>(&DFMEventDispatcher::processEvent), newEvent, Q_NULLPTR); + } + + if (resultData) { + *resultData = result; + } + + break; + } + case DFMEvent::MenuAction: + return processMenuEvent(event.staticCast()); + default: + return false; + } + + return true; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/fileeventprocessor.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/fileeventprocessor.h new file mode 100644 index 0000000..457a262 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/fileeventprocessor.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef FILEEVENTPROCESSOR_H +#define FILEEVENTPROCESSOR_H + +#include "dfmglobal.h" +#include "dfmabstracteventhandler.h" + +DFM_BEGIN_NAMESPACE + +class FileEventProcessor : public DFMAbstractEventHandler +{ +public: + FileEventProcessor(); + +private: + virtual bool fmEvent(const QSharedPointer &event, QVariant *resultData) override; +}; + +DFM_END_NAMESPACE + +#endif // FILEEVENTPROCESSOR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/interface/tagmanagerdaemon_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/interface/tagmanagerdaemon_interface.cpp new file mode 100644 index 0000000..a3865b7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/interface/tagmanagerdaemon_interface.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "../../dde-file-manager-lib/controllers/interface/tagmanagerdaemon_interface.h" + +/* + * Implementation of interface class TagManagerDaemonInterface + */ + +TagManagerDaemonInterface::TagManagerDaemonInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +TagManagerDaemonInterface::~TagManagerDaemonInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/interface/tagmanagerdaemon_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/interface/tagmanagerdaemon_interface.h new file mode 100644 index 0000000..ef7f66e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/interface/tagmanagerdaemon_interface.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef TAGMANAGERDAEMON_INTERFACE_H +#define TAGMANAGERDAEMON_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.TagManagerDaemon + */ +class TagManagerDaemonInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.TagManagerDaemon"; } + +public: + TagManagerDaemonInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~TagManagerDaemonInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply disposeClientData(const QVariantMap &filesAndTags, qulonglong type) + { + QList argumentList; + argumentList << QVariant::fromValue(filesAndTags) << QVariant::fromValue(type); + return asyncCallWithArgumentList(QStringLiteral("disposeClientData"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void addNewTags(const QDBusVariant &new_tags); + void changeTagColor(const QVariantMap &old_and_new_color); + void changeTagName(const QVariantMap &old_and_new_name); + void deleteTags(const QDBusVariant &be_deleted_tags); + void filesWereTagged(const QVariantMap &tagged_files); + void untagFiles(const QVariantMap &file_be_removed_tags); +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::TagManagerDaemonInterface TagManagerDaemon; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/jobcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/jobcontroller.cpp new file mode 100644 index 0000000..162ed4c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/jobcontroller.cpp @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "jobcontroller.h" +#include "dfileservices.h" +#ifdef FULLTEXTSEARCH_ENABLE +#include "fulltextsearch.h" +#endif + +#include + +#ifndef LOAD_FILE_INTERVAL +#define LOAD_FILE_INTERVAL 50 +#endif + +JobController::JobController(const DUrl &fileUrl, const DDirIteratorPointer &iterator, bool silent, QObject *parent) + : QThread(parent) + , m_silent(silent) + , m_iterator(iterator) + , m_fileUrl(fileUrl) +{ + +} + +JobController::JobController(const DUrl &fileUrl, const QStringList &nameFilters, + QDir::Filters filters, bool silent, QObject *parent) + : QThread(parent) + , m_silent(silent) + , m_fileUrl(fileUrl) + , m_nameFilters(nameFilters) + , m_filters(filters) +{ + +} + +JobController::~JobController() +{ + stop(); + wait(); + if (timer) { + delete timer; + timer = nullptr; + } +} + +JobController::State JobController::state() const +{ + return m_state; +} + +int JobController::timeCeiling() const +{ + return m_timeCeiling; +} + +int JobController::countCeiling() const +{ + return m_countCeiling; +} + +void JobController::start() +{ + if (m_state == Started) { + return; + } + + if (m_state == Paused) { + setState(Started); + waitCondition.wakeAll(); + + return; + } + setState(Started); + QThread::start(TimeCriticalPriority); +} + +void JobController::pause() +{ + if (m_state != Started) + return; + + setState(Paused); +} + +void JobController::stop() +{ + if (m_state == Stoped) + return; + + if (m_iterator) + m_iterator->close(); + + setState(Stoped); + + waitCondition.wakeAll(); +} + +void JobController::stopAndDeleteLater() +{ + stop(); + + if (!isRunning()) { + deleteLater(); + } else { + disconnect(this, &JobController::finished, this, &JobController::deleteLater); + connect(this, &JobController::finished, this, &JobController::deleteLater); + } +} + +void JobController::setTimeCeiling(int timeCeiling) +{ + if (isRunning()) + return; + + m_timeCeiling = timeCeiling; +} + +void JobController::setCountCeiling(int countCeiling) +{ + if (isRunning()) + return; + + m_countCeiling = countCeiling; +} + +void JobController::run() +{ + m_updateFinished = false; + if (!m_iterator) { + const auto &&list = DFileService::instance()->getChildren(this, m_fileUrl, m_nameFilters, m_filters, QDirIterator::NoIteratorFlags, m_silent); + + m_updateFinished = true; + emit childrenUpdated(list); + emit addChildrenList(list); + + setState(Stoped); + + return; + } + + QQueue fileInfoQueue; + + if (!timer) + timer = new QElapsedTimer(); + + timer->restart(); + + bool update_children = true; + + const DAbstractFileInfoPointer &rootInfo = DFileService::instance()->createFileInfo(this, m_fileUrl); + if (rootInfo && !rootInfo->hasOrderly() && fileInfoQueue.count() > 0) { + update_children = false; + emit childrenUpdated(fileInfoQueue); + emit addChildrenList(fileInfoQueue); + } + while (m_iterator->hasNext()) { + if (m_state == Paused) { + mutex.lock(); + waitCondition.wait(&mutex); + mutex.unlock(); + } + + if (m_state == Stoped) { + break; + } + if (!m_iterator->next().isValid()) + continue; + + DAbstractFileInfoPointer fileinfo; + fileinfo = m_iterator->fileInfo(); + /*fix bug 49039 解决多次调用m_iterator->hasNext导致有重复结果,这里去重*/ + if (!fileinfo || fileInfoQueue.contains(fileinfo)) + continue; + + if (update_children) { + fileInfoQueue.enqueue(fileinfo); + + if (timer->elapsed() > m_timeCeiling || fileInfoQueue.count() > m_countCeiling) { + update_children = false; + emit childrenUpdated(fileInfoQueue); + emit addChildrenList(fileInfoQueue); + + fileInfoQueue.clear(); + } + } else { + fileInfoQueue.enqueue(fileinfo); + + if (timer->elapsed() > m_timeCeiling || fileInfoQueue.count() > m_countCeiling) { + timer->restart(); + + emit addChildrenList(fileInfoQueue); + + fileInfoQueue.clear(); + } + + emit addChildren(fileinfo); + + } + } + //刷新已完成 + m_updateFinished = true; + + if (timer) { + delete timer; + timer = Q_NULLPTR; + } + if (update_children) { + emit childrenUpdated(fileInfoQueue); + emit addChildrenList(fileInfoQueue); + } + + setState(Stoped); +} + +void JobController::setState(JobController::State state) +{ + if (m_state == state) + return; + + m_state = state; +#ifdef FULLTEXTSEARCH_ENABLE + DFMFullTextSearchManager::getInstance()->setSearchState(state); +#endif + emit stateChanged(state); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/jobcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/jobcontroller.h new file mode 100644 index 0000000..b036244 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/jobcontroller.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef JOBCONTROLLER_H +#define JOBCONTROLLER_H + +#include "ddiriterator.h" + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QElapsedTimer; +QT_END_NAMESPACE + +class JobController : public QThread +{ + Q_OBJECT + + Q_PROPERTY(int timeCeiling READ timeCeiling WRITE setTimeCeiling) + Q_PROPERTY(int countCeiling READ countCeiling WRITE setCountCeiling) + +public: + enum State { + Started, + Paused, + Stoped + }; + + explicit JobController(const DUrl &fileUrl, const DDirIteratorPointer &iterator, bool silent = false, QObject *parent = nullptr); + explicit JobController(const DUrl &fileUrl, const QStringList &nameFilters, + QDir::Filters filters, bool silent = false, QObject *parent = nullptr); + + ~JobController() override; + + State state() const; + + int timeCeiling() const; + int countCeiling() const; + inline bool isUpdatedFinished() const {return m_updateFinished;} +public slots: + void start(); + void pause(); + void stop(); + void stopAndDeleteLater(); + + void setTimeCeiling(int timeCeiling); + void setCountCeiling(int countCeiling); + +signals: + void stateChanged(State state); + void addChildren(const DAbstractFileInfoPointer &info); + void addChildrenList(const QList &infoList); + void childrenUpdated(const QList &list); + +private: + bool m_silent; + DDirIteratorPointer m_iterator; + DUrl m_fileUrl; + QStringList m_nameFilters; + QDir::Filters m_filters; + + State m_state = Stoped; + QWaitCondition waitCondition; + QMutex mutex; + + QElapsedTimer *timer = Q_NULLPTR; + + int m_timeCeiling = 2000; + int m_countCeiling = 9999999; + volatile bool m_updateFinished = true; //刷新完成标志 + + void run() override; + void setState(State state); +}; + +#endif // JOBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/masteredmediacontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/masteredmediacontroller.cpp new file mode 100644 index 0000000..7228965 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/masteredmediacontroller.cpp @@ -0,0 +1,533 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "masteredmediacontroller.h" +#include "dfmevent.h" +#include "ddiskmanager.h" +#include "ddiskdevice.h" +#include "dblockdevice.h" +#include "deviceinfo/udisklistener.h" +#include "app/define.h" +#include "models/desktopfileinfo.h" +#include "models/masteredmediafileinfo.h" +#include "dfileservices.h" +#include "dfilewatcher.h" +#include "dialogs/dialogmanager.h" +#include "dialogs/burnoptdialog.h" +#include "interfaces/dfileproxywatcher.h" +#include "private/dabstractfilewatcher_p.h" +#include "disomaster.h" +#include "shutil/fileutils.h" +#include "controllers/masteredmediacontroller_p.h" + +#include +#include +#include + +DFMShadowedDirIterator::DFMShadowedDirIterator(const QUrl &path, const QStringList &nameFilters, QDir::Filters filter, QDirIterator::IteratorFlags flags) +{ + DUrl durl(path); + const QStringList &nodes = DDiskManager::resolveDeviceNode(durl.burnDestDevice(), {}); + QString udiskspath = nodes.isEmpty() ? QString() : nodes.first(); + QSharedPointer blkdev(DDiskManager::createBlockDevice(udiskspath)); + QSharedPointer diskdev(DDiskManager::createDiskDevice(blkdev->drive())); + auto points = blkdev->mountPoints(); + if (!points.isEmpty()) { + DUrl mnturl = DUrl::fromLocalFile(QString(points.front())); + mntpoint = mnturl.toLocalFile(); + } + while (*mntpoint.rbegin() == '/') { + mntpoint.chop(1); + } + devfile = durl.burnDestDevice(); + if (diskdev->opticalBlank()) { + //blank disc + iterator.clear(); + stagingiterator = QSharedPointer( + new QDirIterator(MasteredMediaController::getStagingFile(DUrl(path)).path(), + nameFilters, filter, flags) + ); + return; + } + QString realpath = mntpoint + durl.burnFilePath(); + iterator = QSharedPointer(new QDirIterator(realpath, nameFilters, filter, flags)); + stagingiterator = QSharedPointer( + new QDirIterator(MasteredMediaController::getStagingFile(DUrl(path)).path(), + nameFilters, filter, flags) + ); +} + +DUrl DFMShadowedDirIterator::next() +{ + return changeSchemeUpdate(DUrl::fromLocalFile(iterator && iterator->hasNext() ? iterator->next() : (iterator = QSharedPointer(Q_NULLPTR), stagingiterator->next()))); +} + +bool DFMShadowedDirIterator::hasNext() const +{ + return (iterator && iterator->hasNext()) || + (stagingiterator && stagingiterator->hasNext()); +} + +QString DFMShadowedDirIterator::fileName() const +{ + return iterator ? iterator->fileName() : stagingiterator->fileName(); +} + +DUrl DFMShadowedDirIterator::fileUrl() const +{ + return changeScheme(DUrl::fromLocalFile(iterator ? iterator->filePath() : stagingiterator->filePath())); +} + +const DAbstractFileInfoPointer DFMShadowedDirIterator::fileInfo() const +{ + DAbstractFileInfoPointer fileinfo = DAbstractFileInfoPointer(new MasteredMediaFileInfo(fileUrl())); + return fileinfo->exists() ? fileinfo : DAbstractFileInfoPointer(); //bug 64941, DVD+RW 只擦除文件系统部分信息,而未擦除全部,有垃圾数据,所以需要判断文件的有效性 +} + +DUrl DFMShadowedDirIterator::url() const +{ + return changeScheme(DUrl::fromLocalFile(iterator ? iterator->path() : stagingiterator->path())); +} + +DUrl DFMShadowedDirIterator::changeScheme(DUrl in) const +{ + DUrl burntmp = DUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/" + qApp->organizationName() + "/" DISCBURN_STAGING "/"); + QString stagingroot = burntmp.path() + QString(devfile).replace('/', '_'); + DUrl ret; + QString path = in.path(); + if (burntmp.isParentOf(in)) { + path.replace(stagingroot, devfile + "/" BURN_SEG_STAGING); + } else { + path.replace(mntpoint, devfile + "/" BURN_SEG_ONDISC); + } + ret = DUrl::fromBurnFile(path); + if (skip.contains(ret)) { + ret.setFragment("dup"); + } + return ret; +} + +DUrl DFMShadowedDirIterator::changeSchemeUpdate(DUrl in) +{ + DUrl ret = changeScheme(in); + if (seen.contains(ret.burnFilePath())) { + skip.insert(ret); + return DUrl(); + } + seen.insert(ret.burnFilePath()); + return ret; +} + +bool MasteredMediaFileWatcherPrivate::start() +{ + return (proxyOnDisk ? proxyOnDisk->startWatcher() : true) && proxyStaging && proxyStaging->startWatcher(); +} + +bool MasteredMediaFileWatcherPrivate::stop() +{ + return (proxyOnDisk ? proxyOnDisk->startWatcher() : true) && proxyStaging && proxyStaging->stopWatcher(); +} + +bool MasteredMediaFileWatcherPrivate::handleGhostSignal(const DUrl &target, DAbstractFileWatcher::SignalType1 signal, const DUrl &url) +{ + Q_Q(MasteredMediaFileWatcher); + Q_UNUSED(url); + + if (target.burnDestDevice() != q->fileUrl().burnDestDevice()) { + return false; + } + + (q->*signal)(q->fileUrl()); + return true; +} + +MasteredMediaFileWatcher::MasteredMediaFileWatcher(const DUrl &url, QObject *parent) + : DAbstractFileWatcher(*new MasteredMediaFileWatcherPrivate(this), url, parent) +{ + Q_D(MasteredMediaFileWatcher); + + DUrl url_staging = MasteredMediaController::getStagingFile(url); + d->proxyStaging = QPointer(new DFileProxyWatcher(url_staging, + new DFileWatcher(url_staging.path()), + [](const DUrl & in)->DUrl { + QRegularExpressionMatch m; + QString cachepath = QRegularExpression::escape(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/" + qApp->organizationName() + "/" DISCBURN_STAGING "/"); + m = QRegularExpression(cachepath + "(.*)").match(in.path()); + Q_ASSERT(m.hasMatch()); + QString cpth = m.captured(1); + m = QRegularExpression("(.*?)/(.*)").match(cpth); + QString devid(m.captured(1)); + QString path(m.captured(2)); + if (!m.hasMatch()) + { + devid = cpth; + } + return DUrl::fromBurnFile(devid.replace('_', '/') + "/" BURN_SEG_STAGING "/" + path); + } + )); + d->proxyStaging->moveToThread(thread()); + d->proxyStaging->setParent(this); + + connect(d->proxyStaging, &DAbstractFileWatcher::fileAttributeChanged, this, &MasteredMediaFileWatcher::onFileAttributeChanged); + connect(d->proxyStaging, &DAbstractFileWatcher::fileDeleted, this, &MasteredMediaFileWatcher::onFileDeleted); + connect(d->proxyStaging, &DAbstractFileWatcher::fileMoved, this, &MasteredMediaFileWatcher::onFileMoved); + connect(d->proxyStaging, &DAbstractFileWatcher::subfileCreated, this, &MasteredMediaFileWatcher::onSubfileCreated); + + d->proxyOnDisk.clear(); + + const QStringList &nodes = DDiskManager::resolveDeviceNode(url.burnDestDevice(), {}); + QString udiskspath = nodes.isEmpty() ? QString() : nodes.first(); + QSharedPointer blkdev(DDiskManager::createBlockDevice(udiskspath)); + + if (blkdev && blkdev->mountPoints().size()) { + DUrl url_mountpoint = DUrl::fromLocalFile(blkdev->mountPoints().front()); + d->proxyOnDisk = QPointer(new DFileWatcher(url_mountpoint.path())); + d->proxyOnDisk->moveToThread(thread()); + d->proxyOnDisk->setParent(this); + connect(d->proxyOnDisk, &DAbstractFileWatcher::fileDeleted, this, [this, url, url_mountpoint](DUrl deletedUrl) { + // 光盘挂载点中的文件可能被删除 (如:wps 打开文件时会创建一个临时文件, 关闭时删除) 导致此信号被触发 + // 此时若使用 url 会导致意外跳转主目录 + QString mountPath = url_mountpoint.toLocalFile(); + QString deletedPath = deletedUrl.toLocalFile(); + if (QUrl(mountPath) == QUrl(deletedPath)) { + emit fileDeleted(url); + } else { + emit fileDeleted(deletedUrl); + } + }); + } + /* + * blank disc doesn't mount + * ejecting disc by pressing the eject button doesn't properly remove the mount point + * therefore this is always needed as a "last resort". + */ + d->diskm.reset(new DDiskManager(this)); + connect(d->diskm.data(), &DDiskManager::opticalChanged, this, + [this, blkdev, url](const QString & path) { + if (path == blkdev->drive()) { + emit fileDeleted(url); + } + }); + d->diskm->setWatchChanges(true); + +} + +void MasteredMediaFileWatcher::onFileDeleted(const DUrl &url) +{ + emit fileDeleted(url); +} + +void MasteredMediaFileWatcher::onFileAttributeChanged(const DUrl &url) +{ + emit fileAttributeChanged(url); +} + +void MasteredMediaFileWatcher::onFileMoved(const DUrl &fromUrl, const DUrl &toUrl) +{ + emit fileMoved(fromUrl, toUrl); +} + +void MasteredMediaFileWatcher::onSubfileCreated(const DUrl &url) +{ + emit subfileCreated(url); +} + +MasteredMediaController::MasteredMediaController(QObject *parent) : DAbstractFileController(parent) +{ + +} + +bool MasteredMediaController::openFile(const QSharedPointer &event) const +{ + DUrl url = DUrl::fromLocalFile(MasteredMediaFileInfo(event->url()).extraProperties()["mm_backer"].toString()); + + return fileService->openFile(event->sender(), url); +} + +bool MasteredMediaController::openFileByApp(const QSharedPointer &event) const +{ + DUrl url = DUrl::fromLocalFile(MasteredMediaFileInfo(event->url()).extraProperties()["mm_backer"].toString()); + + return fileService->openFileByApp(event->sender(), event->appName(), url); +} + +bool MasteredMediaController::openFilesByApp(const QSharedPointer &event) const +{ + DUrlList lst; + for (auto &i : event->urlList()) { + if (i.burnIsOnDisc()) { + DUrl transUrl = DUrl::fromLocalFile(MasteredMediaFileInfo(i).extraProperties()["mm_backer"].toString()); + lst.append(transUrl); + } + } + return fileService->openFilesByApp(event->sender(), event->appName(), lst, event->isEnter()); +} + +bool MasteredMediaController::compressFiles(const QSharedPointer &event) const +{ + DUrlList lst; + for (auto &i : event->urlList()) { + if (i.burnIsOnDisc()) { + DUrl local_file = DUrl::fromLocalFile(MasteredMediaFileInfo(i).extraProperties()["mm_backer"].toString()); + lst.push_back(local_file); + } + } + + return fileService->compressFiles(event->sender(), lst); +} + +bool MasteredMediaController::decompressFile(const QSharedPointer &event) const +{ + DUrlList lst; + for (auto &i : event->urlList()) { + if (i.burnIsOnDisc()) { + DUrl local_file = DUrl::fromLocalFile(MasteredMediaFileInfo(i).extraProperties()["mm_backer"].toString()); + lst.push_back(local_file); + } + } + + return fileService->decompressFile(event->sender(), lst); +} + +bool MasteredMediaController::deleteFiles(const QSharedPointer &event) const +{ + DUrlList lst; + for (auto &i : event->urlList()) { + if (!i.burnIsOnDisc()) { + lst.push_back(getStagingFile(i)); + } + } + + return fileService->deleteFiles(event->sender(), lst, false, event->silent()); +} + +DUrlList MasteredMediaController::moveToTrash(const QSharedPointer &event) const +{ + DUrlList lst, retlst; + for (auto &i : event->urlList()) { + if (!i.burnIsOnDisc()) { + lst.push_back(getStagingFile(i)); + retlst.push_back(i); + } + } + fileService->deleteFiles(event->sender(), lst, false); + + return retlst; +} + +bool MasteredMediaController::writeFilesToClipboard(const QSharedPointer &event) const +{ + //TODO: hide/disable the menu item if no selected file is already on disc. + DUrlList lst; + for (auto &i : event->urlList()) { + DAbstractFileInfoPointer fp = fileService->createFileInfo(event->sender(), i); + if (!DUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/" + qApp->organizationName() + "/" DISCBURN_STAGING "/").isParentOf( + DUrl::fromLocalFile(fp->extraProperties()["mm_backer"].toString()))) { + lst.push_back(DUrl::fromLocalFile(fp->extraProperties()["mm_backer"].toString())); + } + } + DFMGlobal::setUrlsToClipboard(DUrl::toQUrlList(lst), event->action()); + + return !lst.empty(); +} + +DUrlList MasteredMediaController::pasteFile(const QSharedPointer &event) const +{ + DUrlList src = event->urlList(); + DUrl dst = event->targetUrl(); + + if (src.size() == 1) { + QString dev(dst.burnDestDevice()); + bool is_blank = ISOMaster->getDevicePropertyCached(dev).formatted; + if (!ISOMaster->getDevicePropertyCached(dev).devid.length()) { + auto nodes = DDiskManager::resolveDeviceNode(dev, {}); + if (nodes.isEmpty()) + return DUrlList(); + QString udiskspath = nodes.first(); + QScopedPointer blk(DDiskManager::createBlockDevice(udiskspath)); + if (!blk) + return DUrlList(); + QScopedPointer drv(DDiskManager::createDiskDevice(blk->drive())); + if (!drv) + return DUrlList(); + is_blank = drv->opticalBlank(); + } + QString dstdirpath = getStagingFile(DUrl::fromBurnFile(dev + "/" BURN_SEG_STAGING)).path(); + QDir dstdir = QDir(dstdirpath); + dstdir.setFilter(QDir::Filter::AllEntries | QDir::Filter::NoDotAndDotDot); + DAbstractFileInfoPointer fi = fileService->createFileInfo(event->sender(), src.front()); + QSet image_types = {"application/x-cd-image", "application/x-iso9660-image"}; + if (is_blank && fi && image_types.contains(fi->mimeTypeName()) && dstdir.count() == 0) { + int r = DThreadUtil::runInMainThread(dialogManager, &DialogManager::showOpticalImageOpSelectionDialog, DFMUrlBaseEvent(event->sender(), dst)); + if (r == 1) { + DAbstractFileInfoPointer srcInfo = DFileService::instance()->createFileInfo(nullptr, src.at(0)); + qint64 srcSize = srcInfo->size(); + DISOMasterNS::DeviceProperty dp = ISOMaster->getDevicePropertyCached(dst.burnDestDevice()); + if (dp.devid.isEmpty()) { + ISOMaster->acquireDevice(dev); + dp = ISOMaster->getDeviceProperty(); + qInfo() << "No cache for " << dev << ", acquire device again. after acquire the capacity is: " << dp.avail; + } + // 光盘容量小于刻录项目,对话框提示:目标磁盘剩余空间不足,无法进行刻录! + if (dp.avail == 0 || static_cast(srcSize) > dp.avail) { + DThreadUtil::runInMainThread([] { + dialogManager->showMessageDialog(DialogManager::msgWarn, tr("Unable to burn. Not enough free space on the target disk.")); + }); + } else { + DThreadUtil::runInMainThread([src, dev] { + QScopedPointer bd(new BurnOptDialog(dev)); + bd->setISOImage(src.front()); + bd->exec(); + }); + } + return DUrlList{}; + } + if (r == 0 || r == -1) { + return DUrlList{}; + } + } + } + + DUrl tmpdst = getStagingFile(dst); // getStagingFile 返回 file的path,叫getStagingfile比较恰当 + QFileInfo fileInfo(tmpdst.path()); + if(fileInfo.isFile()) { + tmpdst = tmpdst.parentUrl(); + } + + FileUtils::mkpath(tmpdst); + + return fileService->pasteFile(event->sender(), event->action(), tmpdst, src); +} + +const DAbstractFileInfoPointer MasteredMediaController::createFileInfo(const QSharedPointer &event) const +{ + return DAbstractFileInfoPointer(new MasteredMediaFileInfo(event->url())); +} + +const DDirIteratorPointer MasteredMediaController::createDirIterator(const QSharedPointer &event) const +{ + //Make sure the staging folder exists. Otherwise the staging watcher won't work. + if (event->url().burnFilePath().contains(QRegularExpression("^/*$"))) { + // 不走文管的事件机制创建 staging folter, 不需要撤销处理 + DUrl &&stagingUrl = getStagingFile(event->url()); + if (!QDir().mkpath(stagingUrl.toLocalFile())) { + FileUtils::mkpath(stagingUrl); + } + } + return DDirIteratorPointer(new DFMShadowedDirIterator(event->url(), event->nameFilters(), event->filters(), event->flags())); +} + +bool MasteredMediaController::shareFolder(const QSharedPointer &event) const +{ + DUrl url = DUrl::fromLocalFile(MasteredMediaFileInfo(event->url()).extraProperties()["mm_backer"].toString()); + + return fileService->shareFolder(event->sender(), url, event->name(), event->isWritable(), event->allowGuest()); +} + +bool MasteredMediaController::unShareFolder(const QSharedPointer &event) const +{ + DUrl url = DUrl::fromLocalFile(MasteredMediaFileInfo(event->url()).extraProperties()["mm_backer"].toString()); + + return fileService->unShareFolder(event->sender(), url); +} + +bool MasteredMediaController::openInTerminal(const QSharedPointer &event) const +{ + if (!event->url().burnIsOnDisc()) { + return false; + } + + const QString ¤t_dir = QDir::currentPath(); + + QString backer = MasteredMediaFileInfo(event->url()).extraProperties()["mm_backer"].toString(); + if (!backer.length()) { + return false; + } + QDir::setCurrent(backer); + + bool ok = QProcess::startDetached(FileUtils::defaultTerminalPath()); + + QDir::setCurrent(current_dir); + + return ok; +} + +bool MasteredMediaController::createSymlink(const QSharedPointer &event) const +{ + if (!event->fileUrl().burnIsOnDisc()) { + return false; + } + + if (event->toUrl().scheme() == BURN_SCHEME) { + return false; + } + + DUrl local_url = DUrl::fromLocalFile(MasteredMediaFileInfo(event->fileUrl()).extraProperties()["mm_backer"].toString()); + return fileService->createSymlink(event->sender(), local_url, event->toUrl(), true); +} + +bool MasteredMediaController::addToBookmark(const QSharedPointer &event) const +{ + DUrl destUrl = event->url(); + + const DAbstractFileInfoPointer &p = fileService->createFileInfo(nullptr, destUrl); + DUrl bookmarkUrl = DUrl::fromBookMarkFile(destUrl, p->fileDisplayName()); + + return fileService->touchFile(event->sender(), bookmarkUrl); +} + +bool MasteredMediaController::removeBookmark(const QSharedPointer &event) const +{ + return DFileService::instance()->deleteFiles(nullptr, {DUrl::fromBookMarkFile(event->url(), QString())}, false); +} + +DAbstractFileWatcher *MasteredMediaController::createFileWatcher(const QSharedPointer &event) const +{ + return new MasteredMediaFileWatcher(event->url()); +} + + +DUrl MasteredMediaController::getStagingFile(DUrl dst) +{ + Q_ASSERT(dst.burnDestDevice().length() > 0); + return DUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + + "/" + qApp->organizationName() + "/" DISCBURN_STAGING "/" + + dst.burnDestDevice().replace('/', '_') + + dst.burnFilePath()); +} + +DUrl MasteredMediaController::getStagingFile(QString dev) +{ + return DUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) // ~/.cache + + "/" + qApp->organizationName() + "/" DISCBURN_STAGING "/" // ~/.cache/deepin/discburn/ + + dev.replace('/','_')); // ~/.cache/deepin/discburn/_dev_srN +} + +QFileDevice::Permissions MasteredMediaController::getPermissionsCopyToLocal() +{ + // 基础的 rw-rw-r-- 权限 + static const QFileDevice::Permissions permissionsToLocal = (QFileDevice::WriteUser | QFileDevice::ReadUser + | QFileDevice::WriteGroup | QFileDevice::ReadGroup + | QFileDevice::ReadOther); + return permissionsToLocal; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/masteredmediacontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/masteredmediacontroller.h new file mode 100644 index 0000000..66e45b3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/masteredmediacontroller.h @@ -0,0 +1,61 @@ +#ifndef MASTEREDMEDIACONTROLLER_H +#define MASTEREDMEDIACONTROLLER_H + +#include "dabstractfilecontroller.h" +#include "dabstractfilewatcher.h" +#include "durl.h" + +class MasteredMediaFileWatcherPrivate; +class MasteredMediaFileWatcher : public DAbstractFileWatcher +{ + Q_OBJECT + +public: + explicit MasteredMediaFileWatcher(const DUrl &url, QObject *parent = nullptr); + +private slots: + void onFileDeleted(const DUrl &url); + void onFileAttributeChanged(const DUrl &url); + void onFileMoved(const DUrl &fromUrl, const DUrl &toUrl); + void onSubfileCreated(const DUrl &url); + +private: + Q_DECLARE_PRIVATE(MasteredMediaFileWatcher) +}; + +class MasteredMediaController : public DAbstractFileController +{ + Q_OBJECT +public: + explicit MasteredMediaController(QObject *parent = nullptr); + + bool openFile(const QSharedPointer &event) const override; + bool openFileByApp(const QSharedPointer &event) const override; + bool openFilesByApp(const QSharedPointer &event) const override; + bool compressFiles(const QSharedPointer &event) const override; + bool decompressFile(const QSharedPointer &event) const override; + bool deleteFiles(const QSharedPointer &event) const override; + DUrlList moveToTrash(const QSharedPointer &event) const override; + bool writeFilesToClipboard(const QSharedPointer &event) const override; + DUrlList pasteFile(const QSharedPointer &event) const override; + + bool shareFolder(const QSharedPointer &event) const override; + bool unShareFolder(const QSharedPointer &event) const override; + bool openInTerminal(const QSharedPointer &event) const override; + bool createSymlink(const QSharedPointer &event) const override; + + bool addToBookmark(const QSharedPointer &event) const override; + bool removeBookmark(const QSharedPointer &event) const override; + + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + const DDirIteratorPointer createDirIterator(const QSharedPointer &event) const override; + + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + +public: + static DUrl getStagingFile(DUrl dst); + static DUrl getStagingFile(QString dev/* = "/dev/sr0"*/); + static QFileDevice::Permissions getPermissionsCopyToLocal(); +}; + +#endif // MASTEREDMEDIACONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/masteredmediacontroller_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/masteredmediacontroller_p.h new file mode 100644 index 0000000..13c3af2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/masteredmediacontroller_p.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef MASTEREDMEDIACONTROLLER_P_H +#define MASTEREDMEDIACONTROLLER_P_H + +#include +#include "private/dabstractfilewatcher_p.h" +#include "masteredmediacontroller.h" +#include + + +class DFMShadowedDirIterator : public DDirIterator +{ +public: + DFMShadowedDirIterator(const QUrl &path, + const QStringList &nameFilters, + QDir::Filters filter, + QDirIterator::IteratorFlags flags); + + DUrl next() override; + + bool hasNext() const override; + + QString fileName() const override; + + DUrl fileUrl() const override; + + const DAbstractFileInfoPointer fileInfo() const override; + + DUrl url() const override; + +private: + QSharedPointer iterator; + QSharedPointer stagingiterator; + QString mntpoint; + QString devfile; + QSet seen; + QSet skip; + DUrl changeScheme(DUrl in) const; + DUrl changeSchemeUpdate(DUrl in); +}; + +class MasteredMediaFileWatcherPrivate : public DAbstractFileWatcherPrivate +{ +public: + explicit MasteredMediaFileWatcherPrivate(MasteredMediaFileWatcher *qq) + : DAbstractFileWatcherPrivate(qq) {} + + bool start() override; + bool stop() override; + bool handleGhostSignal(const DUrl &target, DAbstractFileWatcher::SignalType1 signal, const DUrl &url) override; + + QPointer proxyStaging; + QPointer proxyOnDisk; + QScopedPointer diskm; + + Q_DECLARE_PUBLIC(MasteredMediaFileWatcher) +}; + + +#endif // MASTEREDMEDIACONTROLLER_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mergeddesktopcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mergeddesktopcontroller.cpp new file mode 100644 index 0000000..f917d5f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mergeddesktopcontroller.cpp @@ -0,0 +1,629 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "mergeddesktopcontroller.h" +#include "mergeddesktopcontroller_p.h" + +#include "dfilewatcher.h" +#include "dfileservices.h" +#include "appcontroller.h" + +#include "interfaces/dfileservices.h" +#include "interfaces/dfmstandardpaths.h" +#include "models/mergeddesktopfileinfo.h" +#include "interfaces/private/mergeddesktop_common_p.h" +#include "private/dabstractfilewatcher_p.h" +#include "shutil/dfmfilelistfile.h" + +#include +#include + +MergedDesktopWatcher::MergedDesktopWatcher(const DUrl &url, DAbstractFileWatcher *baseWatcher, QObject *parent) + : DAbstractFileWatcher(*new MergedDesktopWatcherPrivate(this), url, parent) +{ + connect(baseWatcher, &DAbstractFileWatcher::fileAttributeChanged, this, &MergedDesktopWatcher::onFileAttributeChanged); + connect(baseWatcher, &DAbstractFileWatcher::fileModified, this, &MergedDesktopWatcher::onFileModified); +} + +void MergedDesktopWatcher::setEnabledSubfileWatcher(const DUrl &subfileUrl, bool enabled) +{ + if (subfileUrl.scheme() != DFMMD_SCHEME) { + return; + } + + if (enabled) { + addWatcher(subfileUrl); + } else { + removeWatcher(subfileUrl); + } +} + +void MergedDesktopWatcher::addWatcher(const DUrl &url) +{ + Q_D(MergedDesktopWatcher); + + if (!url.isValid() || d->urlToWatcherMap.contains(url)) { + return; + } + + DUrl real_url = MergedDesktopController::convertToRealPath(url); + + DAbstractFileWatcher *watcher = DFileService::instance()->createFileWatcher(this, real_url); + + if (!watcher) { + return; + } + + watcher->moveToThread(this->thread()); + watcher->setParent(this); + + connect(watcher, &DAbstractFileWatcher::fileAttributeChanged, this, &MergedDesktopWatcher::onFileAttributeChanged); + connect(watcher, &DAbstractFileWatcher::fileModified, this, &MergedDesktopWatcher::onFileModified); + + d->urlToWatcherMap[url] = watcher; + + if (d->started) { + watcher->startWatcher(); + } +} + +void MergedDesktopWatcher::removeWatcher(const DUrl &url) +{ + Q_D(MergedDesktopWatcher); + + DAbstractFileWatcher *watcher = d->urlToWatcherMap.take(url); + + if (!watcher) { + return; + } + + watcher->deleteLater(); +} + +void MergedDesktopWatcher::onFileAttributeChanged(const DUrl &url) +{ + emit fileAttributeChanged(MergedDesktopController::convertToDFMMDPath(url)); +} + +void MergedDesktopWatcher::onFileModified(const DUrl &url) +{ + emit fileModified(MergedDesktopController::convertToDFMMDPath(url)); +} + +MergedDesktopController::MergedDesktopController(QObject *parent) + : DAbstractFileController(parent), + m_desktopFileWatcher(new DFileWatcher(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first(), this)) +{ + connect(m_desktopFileWatcher, &DFileWatcher::fileDeleted, this, &MergedDesktopController::desktopFilesRemoved); + connect(m_desktopFileWatcher, &DFileWatcher::subfileCreated, this, &MergedDesktopController::desktopFilesCreated); + connect(m_desktopFileWatcher, &DFileWatcher::fileMoved, this, &MergedDesktopController::desktopFilesRenamed); + m_desktopFileWatcher->startWatcher(); +} + +const DAbstractFileInfoPointer MergedDesktopController::createFileInfo(const QSharedPointer &event) const +{ + return DAbstractFileInfoPointer(new MergedDesktopFileInfo(event->url(), currentUrl)); +} + +const QList MergedDesktopController::getChildren(const QSharedPointer &event) const +{ +// if (!dataInitialized) { +// initData(); +// dataInitialized = true; +// } + // blumia: 文件监听占用完了的时候有可能桌面会监听不到文件变动,此时即便 F5 也不会刷新该 Controller 存储的整理桌面数据,故改为每次都重新初始化整理数据 + + //加锁失败,说明有线程在跑后面的算法 + if (!m_runMtx.tryLock(0)){ + m_childrenLock.lock(); + m_cv.wait(&m_childrenLock); + QList infoList = m_childrenList; + m_childrenLock.unlock(); + return infoList; + } + + QMutexLocker aful(&m_arrangedFileUrlsMtx); //禁止其他线程修改arrangedFileUrls + + arrangedFileUrls = initData(event->filters()); + currentUrl = event->url(); + QString path { currentUrl.path() }; + QList infoList; + + auto appendEntryFiles = [this](QList &infoList, const DMD_TYPES &entryType){ + for (const DUrl & url : arrangedFileUrls[entryType]) { + DAbstractFileInfoPointer info { + new MergedDesktopFileInfo(convertToDFMMDPath(url), currentUrl) + }; + infoList.append(info); + } + }; + + auto appendVirtualEntries = [this, &infoList,appendEntryFiles](bool displayEmptyEntry = false, const QStringList & expandedEntries = {}) { + for (unsigned int i = DMD_FIRST_TYPE; i <= DMD_ALL_ENTRY; i++) { + DMD_TYPES oneType = static_cast(i); + if (!displayEmptyEntry && arrangedFileUrls[oneType].isEmpty()) { + continue; + } + //屏蔽掉2个以下文件的分类图标 + if(arrangedFileUrls[oneType].size() < 2){ + appendEntryFiles(infoList, oneType); + continue; + } + QString entryName = entryNameByEnum(oneType); + DUrl url(DFMMD_ROOT VIRTUALENTRY_FOLDER + entryNameByEnum(oneType)); + DAbstractFileInfoPointer infoPtr { + new MergedDesktopFileInfo(url, currentUrl) + }; + infoList.push_back(infoPtr); + if (expandedEntries.contains(entryName)) { + appendEntryFiles(infoList, oneType); + } + } + }; + + auto appendFolders = [this, &infoList]() { + for (const DUrl & url : arrangedFileUrls[DMD_FOLDER]) { + DAbstractFileInfoPointer info { + new MergedDesktopFileInfo(convertToDFMMDPath(url), currentUrl) + }; + infoList.append(info); + } + }; + + auto makeAndInsertInfo = [this, &infoList](QString urlStr) { + DUrl entryUrl(urlStr); + DAbstractFileInfoPointer adeEntryInfoPtr { + new MergedDesktopFileInfo(convertToDFMMDPath(entryUrl), currentUrl) + }; + infoList.push_back(adeEntryInfoPtr); + }; + + if(currentUrl.scheme() == DFMMD_SCHEME) { + if (path == QStringLiteral("/")) { + makeAndInsertInfo(DFMMD_ROOT VIRTUALENTRY_FOLDER); + makeAndInsertInfo(DFMMD_ROOT VIRTUALFOLDER_FOLDER); + makeAndInsertInfo(DFMMD_ROOT MERGEDDESKTOP_FOLDER); + } else if (path.startsWith(QStringLiteral(VIRTUALENTRY_PATH))) { + if (path == QStringLiteral(VIRTUALENTRY_PATH)) { + appendVirtualEntries(); + } else { + QString entryName = path.split('/', QString::SkipEmptyParts).last(); + DMD_TYPES entryType = entryTypeByName(entryName); + appendEntryFiles(infoList, entryType); + } + } else if (path == QStringLiteral(VIRTUALFOLDER_PATH)) { + appendFolders(); + } else if (path == QStringLiteral(MERGEDDESKTOP_PATH)) { + QString expandedFolder = currentUrl.fragment(); + QStringList expandedFolders; + if (!expandedFolder.isEmpty()) { + expandedFolders = expandedFolder.split(',', QString::SkipEmptyParts); + } + appendVirtualEntries(false, expandedFolders); + appendFolders(); + } + } + + m_runMtx.unlock(); + m_childrenLock.lock(); + m_childrenList = infoList; + m_childrenLock.unlock(); + m_cv.wakeAll(); + return infoList; +} + +DAbstractFileWatcher *MergedDesktopController::createFileWatcher(const QSharedPointer &) const +{ + return new MergedDesktopWatcher(DUrl(DFMMD_ROOT MERGEDDESKTOP_FOLDER), m_desktopFileWatcher, nullptr); +} + +bool MergedDesktopController::openFile(const QSharedPointer &event) const +{ + return DFileService::instance()->openFile(event->sender(), convertToRealPath(event->url())); +} + +bool MergedDesktopController::openFiles(const QSharedPointer &event) const +{ + return DFileService::instance()->openFiles(event->sender(), convertToRealPaths(event->urlList())); +} + +bool MergedDesktopController::openFileByApp(const QSharedPointer &event) const +{ + return DFileService::instance()->openFileByApp(event->sender(), event->appName(), convertToRealPath(event->url())); +} + +DUrlList MergedDesktopController::moveToTrash(const QSharedPointer &event) const +{ + DUrlList urlList = convertToRealPaths(event->urlList()); + return DFileService::instance()->moveToTrash(event->sender(), urlList); +} + +bool MergedDesktopController::writeFilesToClipboard(const QSharedPointer &event) const +{ + DUrlList urlList = convertToRealPaths(event->urlList()); + return DFileService::instance()->writeFilesToClipboard(event->sender(), event->action(), urlList); +} + +DUrlList MergedDesktopController::pasteFile(const QSharedPointer &event) const +{ +// return DUrlList(); // disabled for now. + + return DFileService::instance()->pasteFile(event->sender(), event->action(), + DUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)), + event->fileUrlList()); +} + +bool MergedDesktopController::deleteFiles(const QSharedPointer &event) const +{ + DUrlList urlList = convertToRealPaths(event->urlList()); + // 注意这里第三个参数 confirmationDialog, 在函数体内并未使用,但需要后面的两个参数所以给第三个参数赋值true + return DFileService::instance()->deleteFiles(event->sender(), urlList, true, event->silent(), event->force()); +} + +bool MergedDesktopController::renameFile(const QSharedPointer &event) const +{ + return DFileService::instance()->renameFile(event->sender(), + convertToRealPath(event->fromUrl()), + convertToRealPath(event->toUrl())); +} + +bool MergedDesktopController::openInTerminal(const QSharedPointer &event) const +{ + return DFileService::instance()->openInTerminal(event->sender(), + DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::DesktopPath))); +} + +// fixme: AppController::actionNewFolder 调了 FileUtils::newDocumentUrl 调了 getUrlByChildFileName ,可能需要重写 +// 否则在自动整理视图下新建文件后不会被选中 +bool MergedDesktopController::mkdir(const QSharedPointer &event) const +{ + bool result = DFileService::instance()->mkdir(event->sender(), + DUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation))); + + AppController::selectionAndRenameFile = qMakePair(event->url(), event->windowId()); + + return result; +} + +bool MergedDesktopController::touch(const QSharedPointer &event) const +{ + bool result = DFileService::instance()->touchFile(event->sender(), + DUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation))); + + AppController::selectionAndRenameFile = qMakePair(event->url(), event->windowId()); + + return result; +} + +bool MergedDesktopController::setPermissions(const QSharedPointer &event) const +{ + return DFileService::instance()->setPermissions(event->sender(), convertToRealPath(event->url()), event->permissions()); +} + +bool MergedDesktopController::compressFiles(const QSharedPointer &event) const +{ + DUrlList urlList = convertToRealPaths(event->urlList()); + return DFileService::instance()->compressFiles(event->sender(), urlList); +} + +bool MergedDesktopController::decompressFile(const QSharedPointer &event) const +{ + DUrlList urlList = convertToRealPaths(event->urlList()); + return DFileService::instance()->decompressFile(event->sender(), urlList); +} + +bool MergedDesktopController::createSymlink(const QSharedPointer &event) const +{ + return DFileService::instance()->createSymlink(event->sender(), + convertToRealPath(event->fileUrl()), + convertToRealPath(event->toUrl())); +} + +bool MergedDesktopController::setFileTags(const QSharedPointer &event) const +{ + return DFileService::instance()->setFileTags(event->sender(), convertToRealPath(event->url()), event->tags()); +} + +bool MergedDesktopController::removeTagsOfFile(const QSharedPointer &event) const +{ + return DFileService::instance()->removeTagsOfFile(event->sender(), convertToRealPath(event->url()), event->tags()); +} + +QList MergedDesktopController::getTagsThroughFiles(const QSharedPointer &event) const +{ + DUrlList urlList = convertToRealPaths(event->urlList()); + return DFileService::instance()->getTagsThroughFiles(event->sender(), urlList); +} + +DFileDevice *MergedDesktopController::createFileDevice(const QSharedPointer &event) const +{ + return DFileService::instance()->createFileDevice(event->sender(), convertToRealPath(event->url())); +} + +DFileHandler *MergedDesktopController::createFileHandler(const QSharedPointer &event) const +{ + return DFileService::instance()->createFileHandler(event->sender(), convertToRealPath(event->url())); +} + +DStorageInfo *MergedDesktopController::createStorageInfo(const QSharedPointer &event) const +{ + return DFileService::instance()->createStorageInfo(event->sender(), convertToRealPath(event->url())); +} + +bool MergedDesktopController::setExtraProperties(const QSharedPointer &event) const +{ + return DFileService::instance()->setExtraProperties(event->sender(), convertToRealPath(event->url()), + event->extraProperties()); +} + +const QString MergedDesktopController::entryNameByEnum(DMD_TYPES singleType) +{ + switch (singleType) { + case DMD_PICTURE: + return tr("Pictures"); + case DMD_MUSIC: + return tr("Music"); + case DMD_APPLICATION: + return tr("Applications"); + case DMD_VIDEO: + return tr("Videos"); + case DMD_DOCUMENT: + return tr("Documents"); + case DMD_OTHER: + return tr("Others"); + case DMD_FOLDER: + return "Folders"; + default: + return "Bug"; + } +} + +DMD_TYPES MergedDesktopController::entryTypeByName(QString entryName) +{ + if (entryName == tr("Pictures")) { + return DMD_PICTURE; + } else if (entryName == tr("Music")) { + return DMD_MUSIC; + } else if (entryName == tr("Applications")) { + return DMD_APPLICATION; + } else if (entryName == tr("Videos")) { + return DMD_VIDEO; + } else if (entryName == tr("Documents")) { + return DMD_DOCUMENT; + } else if (entryName == tr("Others")) { + return DMD_OTHER; + } + + qWarning() << "MergedDesktopController::entryTypeByName() cannot match a reasonable result, that can be a bug." << qPrintable(entryName); + + return DMD_OTHER; +} + +DUrl MergedDesktopController::getVirtualEntryPath(DMD_TYPES oneType) +{ + if (oneType == DMD_FOLDER) { + return DUrl(DFMMD_ROOT VIRTUALFOLDER_FOLDER "/"); + } + + return DUrl(DFMMD_ROOT VIRTUALENTRY_FOLDER + entryNameByEnum(oneType) + "/"); +} + + +DMD_TYPES MergedDesktopController::checkUrlArrangedType(const DUrl url) +{ + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, url); + if (info) { + QString mimetypeDisplayName = info->mimeTypeDisplayName(); + if (mimetypeDisplayName.startsWith(qApp->translate("MimeTypeDisplayManager", "Application"))) { + return DMD_APPLICATION; + } else if (mimetypeDisplayName.startsWith(qApp->translate("MimeTypeDisplayManager", "Image"))) { + return DMD_PICTURE; + } else if (mimetypeDisplayName.startsWith(qApp->translate("MimeTypeDisplayManager", "Audio"))) { + return DMD_MUSIC; + } else if (mimetypeDisplayName.startsWith(qApp->translate("MimeTypeDisplayManager", "Video"))) { + return DMD_VIDEO; + } else if (mimetypeDisplayName.startsWith(qApp->translate("MimeTypeDisplayManager", "Text"))) { + return DMD_DOCUMENT; + } else if (mimetypeDisplayName.startsWith(qApp->translate("MimeTypeDisplayManager", "Directory"))) { + return DMD_FOLDER; + } else { + return DMD_OTHER; + } + } + + return DMD_OTHER; +} + +void MergedDesktopController::desktopFilesCreated(const DUrl &url) +{ + QMutexLocker aful(&m_arrangedFileUrlsMtx); //禁止其他线程修改arrangedFileUrls + + DMD_TYPES typeInfo = checkUrlArrangedType(url); + if (arrangedFileUrls[typeInfo].contains(url)) { + qWarning() << url << "existed, it must be a bug!!!!!!!!"; + return; //不return会崩溃,不知道为什么 todo +// arrangedFileUrls[typeInfo].removeAll(url);//return后不执行,导致警告屏蔽之 + } + arrangedFileUrls[typeInfo].append(url); + aful.unlock(); + + DUrl vUrl = convertToDFMMDPath(url, typeInfo); + DUrl parentUrl = getVirtualEntryPath(typeInfo); + DAbstractFileWatcher::ghostSignal(parentUrl, &DAbstractFileWatcher::subfileCreated, vUrl); + DUrl parentUrl2(DFMMD_ROOT MERGEDDESKTOP_FOLDER); + DAbstractFileWatcher::ghostSignal(parentUrl2, &DAbstractFileWatcher::subfileCreated, vUrl); +} + +void MergedDesktopController::desktopFilesRemoved(const DUrl &url) +{ + QMutexLocker aful(&m_arrangedFileUrlsMtx); //禁止其他线程修改arrangedFileUrls + + for (unsigned int i = DMD_FIRST_TYPE; i <= DMD_ALL_TYPE; i++) { + DMD_TYPES typeInfo = static_cast(i); + if (arrangedFileUrls[typeInfo].removeOne(url)) { + aful.unlock(); + + DUrl vUrl = convertToDFMMDPath(url, typeInfo); + + DUrl parentUrl = getVirtualEntryPath(typeInfo); + DAbstractFileWatcher::ghostSignal(parentUrl, &DAbstractFileWatcher::fileDeleted, vUrl); + DUrl parentUrl2(DFMMD_ROOT MERGEDDESKTOP_FOLDER); + DAbstractFileWatcher::ghostSignal(parentUrl2, &DAbstractFileWatcher::fileDeleted, vUrl); + return; + } + } +} + +void +MergedDesktopController::desktopFilesRenamed(const DUrl &oriUrl, const DUrl &dstUrl) +{ + QMutexLocker aful(&m_arrangedFileUrlsMtx); //禁止其他线程修改arrangedFileUrls + + //获取原文件的类型 + DMD_TYPES orgTypeInfo = checkUrlArrangedType(oriUrl); + for (unsigned int i = DMD_FIRST_TYPE; i <= DMD_ALL_TYPE; i++) { + DMD_TYPES typeInfo = static_cast(i); + if (arrangedFileUrls[typeInfo].removeOne(oriUrl)) { + orgTypeInfo = typeInfo; + break; + } + } + + DMD_TYPES typeInfo = checkUrlArrangedType(dstUrl); + arrangedFileUrls[typeInfo].append(dstUrl); + aful.unlock(); + + DUrl vOriUrl = convertToDFMMDPath(oriUrl, orgTypeInfo); + DUrl vDstUrl = convertToDFMMDPath(dstUrl, typeInfo); + + DUrl parentUrl = getVirtualEntryPath(typeInfo); + DAbstractFileWatcher::ghostSignal(parentUrl, &DAbstractFileWatcher::fileMoved, vOriUrl, vDstUrl); + DUrl parentUrl2(DFMMD_ROOT MERGEDDESKTOP_FOLDER); + DAbstractFileWatcher::ghostSignal(parentUrl2, &DAbstractFileWatcher::fileMoved, vOriUrl, vDstUrl); +} + +QMap > MergedDesktopController::initData(QDir::Filters ftrs) +{ + QMap > tArrangedFileUrls; + + QDir desktopDir(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first()); +#if 0 + const QStringList &fileList = desktopDir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot); +#else + //自动整理下需要显示隐藏文件,故新加QDir::Filters ftrs + QStringList fileList = desktopDir.entryList(ftrs, QDir::Name); +#endif + //文件名排序 + auto compateFunc = [](const QString &str1, const QString &str2) -> bool{ + return FileSortFunction::compareByString(str1,str2); + }; + qSort(fileList.begin(),fileList.end(),compateFunc); + //end + + //解决自动整理时的文件隐藏显示问题 + bool showHidden = ftrs.testFlag(QDir::Hidden); + DFMFileListFile hiddenFiles(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first()); + + for (const QString &oneFile : fileList) { + if (!showHidden && hiddenFiles.contains(oneFile)){ + continue; + } + DUrl oneUrl = DUrl::fromLocalFile(desktopDir.filePath(oneFile)); + DMD_TYPES typeInfo = checkUrlArrangedType(oneUrl); + tArrangedFileUrls[typeInfo].append(oneUrl); + } + + return tArrangedFileUrls; +} + +//为了防止自动整理下剪切与分类名相同的文件夹,这里创建虚拟的分类路径做对比 +bool MergedDesktopController::isVirtualEntryPaths(const DUrl &oneUrl) +{ + auto tgPath = oneUrl.toString(); + for (unsigned int i = DMD_FIRST_TYPE; i <= DMD_ALL_ENTRY; i++) { + DMD_TYPES oneType = static_cast(i); + QString temp = DFMMD_ROOT VIRTUALENTRY_FOLDER + entryNameByEnum(oneType); + if(tgPath == temp) + return true; + } + + return false; +} + +DUrl MergedDesktopController::convertToDFMMDPath(const DUrl &oriUrl) +{ + DMD_TYPES typeInfo = checkUrlArrangedType(oriUrl); + QDir desktopDir(QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first()); + + return convertToDFMMDPath(oriUrl, typeInfo); +} + +DUrl MergedDesktopController::convertToDFMMDPath(const DUrl &oriUrl, DMD_TYPES oneType) +{ + DUrl vUrl; + + +#if 0 + // if (oneType == DMD_FOLDER) { + // vUrl = DUrl(DFMMD_ROOT VIRTUALFOLDER_FOLDER + oriUrl.fileName()); + // } else { + // vUrl = DUrl(DFMMD_ROOT VIRTUALENTRY_FOLDER + entryNameByEnum(oneType) + QDir::separator() + oriUrl.fileName()); + // } +#else + //oriUrl.fileName()自动整理时在获取带有特殊不规范字符的名字时不准确,改为‘/’获取 + auto str = oriUrl.toString(); + auto idxPos = str.indexOf("/"); + auto fileNameStartPos = str.length() - idxPos - 1; + auto fileName = str.right(fileNameStartPos); + if (oneType == DMD_FOLDER) { + vUrl = DUrl(DFMMD_ROOT VIRTUALFOLDER_FOLDER + fileName); + } else { + vUrl = DUrl(DFMMD_ROOT VIRTUALENTRY_FOLDER + entryNameByEnum(oneType) + QDir::separator() + fileName); + } +#endif + + return vUrl; +} + +DUrl MergedDesktopController::convertToRealPath(const DUrl &oneUrl) +{ + if (oneUrl.scheme() != DFMMD_SCHEME) return oneUrl; + + QString desktopPath = QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first() + QDir::separator(); + + return DUrl::fromLocalFile(desktopPath + oneUrl.fileName()); +} + +DUrlList MergedDesktopController::convertToRealPaths(DUrlList urlList) +{ + for (DUrl &url : urlList) { + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, url); + if (info && info->isVirtualEntry()) { + urlList.removeOne(url); + continue; + } + url = convertToRealPath(url); + } + + return urlList; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mergeddesktopcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mergeddesktopcontroller.h new file mode 100644 index 0000000..f209213 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mergeddesktopcontroller.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef MERGEDDESKTOPCONTROLLER_H +#define MERGEDDESKTOPCONTROLLER_H + +#include "dabstractfilecontroller.h" +#include +#include + +enum DMD_TYPES : unsigned int { + DMD_PICTURE, DMD_MUSIC, DMD_APPLICATION, DMD_VIDEO, DMD_DOCUMENT, DMD_OTHER, DMD_FOLDER, + DMD_FIRST_TYPE = DMD_PICTURE, DMD_ALL_TYPE = DMD_FOLDER, DMD_ALL_ENTRY = DMD_OTHER +}; + +class DFileWatcher; +class MergedDesktopController : public DAbstractFileController +{ + Q_OBJECT + +public: + explicit MergedDesktopController(QObject *parent = nullptr); + + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + const QList getChildren(const QSharedPointer &event) const override; + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &) const override; + + bool openFile(const QSharedPointer &event) const override; + bool openFiles(const QSharedPointer &event) const override; + bool openFileByApp(const QSharedPointer &event) const override; + DUrlList moveToTrash(const QSharedPointer &event) const override; + bool writeFilesToClipboard(const QSharedPointer &event) const override; + DUrlList pasteFile(const QSharedPointer &event) const override; + bool deleteFiles(const QSharedPointer &event) const override; + bool renameFile(const QSharedPointer &event) const override; + bool openInTerminal(const QSharedPointer &event) const override; + + bool mkdir(const QSharedPointer &event) const override; // AppController::actionNewFolder 有问题 + bool touch(const QSharedPointer &event) const override; + bool setPermissions(const QSharedPointer &event) const override; + bool compressFiles(const QSharedPointer &event) const override; + bool decompressFile(const QSharedPointer &event) const override; + bool createSymlink(const QSharedPointer &event) const override; + + bool setFileTags(const QSharedPointer &event) const override; + bool removeTagsOfFile(const QSharedPointer &event) const override; + QList getTagsThroughFiles(const QSharedPointer &event) const override; + + DFM_NAMESPACE::DFileDevice *createFileDevice(const QSharedPointer &event) const override; + DFM_NAMESPACE::DFileHandler *createFileHandler(const QSharedPointer &event) const override; + DFM_NAMESPACE::DStorageInfo *createStorageInfo(const QSharedPointer &event) const override; + + bool setExtraProperties(const QSharedPointer &event) const override; + + const static QString entryNameByEnum(DMD_TYPES singleType); + static DMD_TYPES entryTypeByName(QString entryName); + static DUrl getVirtualEntryPath(DMD_TYPES oneType); + static DUrl convertToDFMMDPath(const DUrl &oriUrl); + static DUrl convertToDFMMDPath(const DUrl &oriUrl, DMD_TYPES oneType); + static DUrl convertToRealPath(const DUrl &oneUrl); + static DUrlList convertToRealPaths(DUrlList urlList); + static DMD_TYPES checkUrlArrangedType(const DUrl url); + static QMap > initData(QDir::Filters ftrs); + //为了防止自动整理下剪切与分类名相同的文件夹,这里创建虚拟的分类路径做对比 + static bool isVirtualEntryPaths(const DUrl &oneUrl); + +public slots: + void desktopFilesCreated(const DUrl &url); + void desktopFilesRemoved(const DUrl &url); + void desktopFilesRenamed(const DUrl &oriUrl, const DUrl &dstUrl); + +private: + //void appendEntryFiles(QList &infoList, const DMD_TYPES &entryType) const; + + DFileWatcher* m_desktopFileWatcher; + mutable DUrl currentUrl; +// mutable bool dataInitialized = false; + mutable QMap > arrangedFileUrls; + mutable QMutex m_arrangedFileUrlsMtx; //多线程访问arrangedFileUrls 的锁 + + mutable QMutex m_childrenLock; + mutable QList m_childrenList; + mutable QMutex m_runMtx; //多线程调用时出问题,加锁,禁止多线程 + mutable QWaitCondition m_cv; +}; + +#endif // MERGEDDESKTOPCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mergeddesktopcontroller_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mergeddesktopcontroller_p.h new file mode 100644 index 0000000..9427593 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mergeddesktopcontroller_p.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef MERGEDDESKTOPCONTROLLER_P_H +#define MERGEDDESKTOPCONTROLLER_P_H + +#include "private/dabstractfilewatcher_p.h" + +class MergedDesktopWatcherPrivate; +class MergedDesktopWatcher : public DAbstractFileWatcher +{ +public: + explicit MergedDesktopWatcher(const DUrl &url, DAbstractFileWatcher *baseWatcher, QObject *parent = nullptr); + + void setEnabledSubfileWatcher(const DUrl &subfileUrl, bool enabled = true) override; + +private: + void addWatcher(const DUrl &url); + void removeWatcher(const DUrl &url); + + void onFileAttributeChanged(const DUrl &url); + void onFileModified(const DUrl &url); + + Q_DECLARE_PRIVATE(MergedDesktopWatcher) +}; + +class MergedDesktopWatcherPrivate : public DAbstractFileWatcherPrivate +{ +public: + explicit MergedDesktopWatcherPrivate(DAbstractFileWatcher *qq) + : DAbstractFileWatcherPrivate(qq) {} + + bool start() override + { + started = true; + + return true; + } + + bool stop() override + { + started = false; + + return true; + } + + QMap urlToWatcherMap; + + Q_DECLARE_PUBLIC(MergedDesktopWatcher) +}; + + +#endif // MERGEDDESKTOPCONTROLLER_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mountcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mountcontroller.cpp new file mode 100644 index 0000000..b8e8c2e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mountcontroller.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "mountcontroller.h" + +#include "app/define.h" +#include "views/windowmanager.h" +#include "models/mountfileinfo.h" + +#include "dfmeventdispatcher.h" +#include "ddiskmanager.h" +#include "dblockdevice.h" + +#include +#include + +DFM_USE_NAMESPACE + +MountController::MountController(QObject *parent) : DAbstractFileController(parent) +{ + +} + +MountController::~MountController() +{ + +} + +const DAbstractFileInfoPointer MountController::createFileInfo(const QSharedPointer &event) const +{ + MountFileInfo *info = new MountFileInfo(event->url()); + + return DAbstractFileInfoPointer(info); +} + +const QList MountController::getChildren(const QSharedPointer &event) const +{ + QString deviceUrlStr = event->url().fragment(); + if (deviceUrlStr.isEmpty()) { + return {}; + } + + DUrl deviceUrl(deviceUrlStr); + DUrl mountPointUrl; // just a init value + + if (deviceUrl.scheme() == DEVICE_SCHEME) { + // + } else if (deviceUrl.scheme() == "udisks") { + // for test: mount://test#udisks:///org/freedesktop/UDisks2/block_devices/sda1 + QScopedPointer blDev(DDiskManager::createBlockDevice(deviceUrl.path())); + if (!blDev || !blDev->hasFileSystem() || blDev->isEncrypted()) { + return {}; + } + QString mountPoint; + + if (blDev->mountPoints().isEmpty()) { + mountPoint = blDev->mount({}); + } else { + mountPoint = blDev->mountPoints().first(); + } + + if (!mountPoint.isEmpty()) { + mountPointUrl = DUrl(QUrl::fromLocalFile(mountPoint)); + } + } + + // Do change directory + if (mountPointUrl.isValid()) { + QWidget *p = WindowManager::getWindowById(event->windowId()); + QTimer::singleShot(0, p, [p, mountPointUrl] { + DFMEventDispatcher::instance()->processEvent(nullptr, mountPointUrl, p); + }); + } + + return {}; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mountcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mountcontroller.h new file mode 100644 index 0000000..f0f16d0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/mountcontroller.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef MOUNTCONTROLLER_H +#define MOUNTCONTROLLER_H + +#include "dabstractfilecontroller.h" + +class MountController : public DAbstractFileController +{ + Q_OBJECT +public: + explicit MountController(QObject *parent = nullptr); + ~MountController(); + + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + const QList getChildren(const QSharedPointer &event) const override; +}; + +#endif // MOUNTCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/movejobworker.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/movejobworker.cpp new file mode 100644 index 0000000..88d9b48 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/movejobworker.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "movejobworker.h" +#include "app/define.h" +#include "utils/utils.h" + +#include + +MovejobWorker::MovejobWorker(QStringList files, QString destination, QObject *parent) : + QObject(parent), + m_files(files), + m_destination(destination) +{ + m_progressTimer = new QTimer; + m_progressTimer->setInterval(2000); + m_time = new QTime; + initConnect(); +} + +void MovejobWorker::initConnect(){ + connect(this, SIGNAL(startJob()), this, SLOT(start())); + connect(this, SIGNAL(finished()), this, SLOT(handleFinished())); + connect(m_progressTimer, SIGNAL(timeout()), this, SLOT(handleTimeout())); +} + +QStringList MovejobWorker::getFiles(){ + return m_files; +} + +QString MovejobWorker::getDestination(){ + return m_destination; +} + +QString MovejobWorker::getJobPath(){ + return m_movejobPath; +} + +const QMap& MovejobWorker::getJobDetail(){ + return m_jobDetail; +} + +FileConflictController* MovejobWorker::getFileConflictController(){ + return m_conflictController; +} + + +void MovejobWorker::start(){ + moveFiles(m_files, m_destination); +} + +void MovejobWorker::moveFiles(QStringList files, QString destination){ + qDebug() << files << destination; +} + +void MovejobWorker::connectMoveJobSignal(){ + +} + + +void MovejobWorker::disconnectMoveJobSignal(){ + +} + + +void MovejobWorker::moveJobExcuteFinished(const QString& message){ + + qDebug() << "move job finished" << message; +} + +void MovejobWorker::moveJobAbort(){ + +} + +void MovejobWorker::moveJobAbortFinished(){ + moveJobExcuteFinished("move job aborted"); +} + +void MovejobWorker::onMovingFile(QString file){ + m_jobDataDetail.insert("file", QFileInfo(decodeUrl(file)).fileName()); + qDebug() << "onMovingFile" << file; + if (m_jobDetail.contains("jobPath")){ + + } +} + +void MovejobWorker::setTotalAmount(qlonglong amount, ushort type){ + qDebug() << "========="<< amount << type; + if (type == 0){ + m_totalAmout = amount; + } +} + +void MovejobWorker::onMovingProcessAmount(qlonglong progress, ushort info){ + if (info == 0){ + m_currentProgress = progress; + } + qDebug() << "onMovingProcessAmount" << progress << info; +} + +void MovejobWorker::handleTimeout(){ + float speed = (m_currentProgress - m_lastProgress) / (1024 * 1024); +// qDebug() << speed; + m_lastProgress = m_currentProgress; + int remainTime = (m_totalAmout - m_currentProgress) / speed; +// qDebug() << remainTime; + m_jobDataDetail.insert("speed", QString::number(speed)); + m_jobDataDetail.insert("remainTime", QString::number(remainTime)); +} + +void MovejobWorker::handleFinished(){ + if (m_jobDetail.contains("jobPath")){ + + } +} + +void MovejobWorker::handleTaskAborted(const QMap &jobDetail){ + if (jobDetail == m_jobDetail){ + moveJobAbort(); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/movejobworker.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/movejobworker.h new file mode 100644 index 0000000..473bf02 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/movejobworker.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef MOVEJOBWORKER_H +#define MOVEJOBWORKER_H + +#include +#include +#include +#include +#include +#include + +class MoveJobInterface; +class FileConflictController; + +class MovejobWorker : public QObject +{ + Q_OBJECT +public: + explicit MovejobWorker(QStringList files, QString destination, QObject *parent = 0); + void initConnect(); + QStringList getFiles(); + QString getDestination(); + QString getJobPath(); + const QMap& getJobDetail(); + FileConflictController* getFileConflictController(); + +signals: + void startJob(); + void finished(); + +public slots: + void start(); + void moveFiles(QStringList files, QString destination); + void connectMoveJobSignal(); + void disconnectMoveJobSignal(); + void moveJobExcuteFinished(const QString& message); + void moveJobAbort(); + void moveJobAbortFinished(); + void onMovingFile(QString file); + void setTotalAmount(qlonglong amount, ushort type); + void onMovingProcessAmount(qlonglong progress, ushort info); + void handleTimeout(); + void handleFinished(); + void handleTaskAborted(const QMap& jobDetail); +private: + QStringList m_files; + QString m_destination; + QString m_movejobPath; + MoveJobInterface* m_moveJobInterface = NULL; + FileConflictController* m_conflictController = NULL; + QTimer* m_progressTimer; + QMap m_jobDetail; + QMap m_jobDataDetail; + qlonglong m_totalAmout; + QTime* m_time; + qlonglong m_lastProgress = 0; + qlonglong m_currentProgress = 0; + int m_elapsedTime; +}; + +#endif // MOVEJOBWORKER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/networkcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/networkcontroller.cpp new file mode 100644 index 0000000..bfaad53 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/networkcontroller.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "networkcontroller.h" +#include "models/networkfileinfo.h" +#include "gvfs/networkmanager.h" +#include "durl.h" + +#include "singleton.h" + +#include + +Q_GLOBAL_STATIC(QMutex, fetchNetworksMutex) + +class NetworkFileDDirIterator : public DDirIterator +{ +public: + NetworkFileDDirIterator(const DUrl &url, const QObject *event_sender, bool silence) + : m_url(url) + , m_sender(event_sender) + , m_silence(silence) + { + + } + + DUrl next() override + { + m_currentInfo = m_infoList.takeFirst(); + + return m_currentInfo->fileUrl(); + } + + bool hasNext() const override + { + if (initialized) { + return !m_infoList.isEmpty(); + } + + initialized = true; + + fetchNetworksMutex->lock(); + if (!m_silence && NetworkManager::NetworkNodes.value(m_url).isEmpty()) { + Singleton::instance()->fetchNetworks(DFMUrlBaseEvent(m_sender.data(), m_url)); + } + fetchNetworksMutex->unlock(); + + foreach (const NetworkNode &node, NetworkManager::NetworkNodes.value(m_url)) { + NetworkFileInfo *info = new NetworkFileInfo(DUrl(node.url())); + info->setNetworkNode(node); + m_infoList.append(DAbstractFileInfoPointer(info)); + }; + + return !m_infoList.isEmpty(); + } + + void close() override + { + if (initialized) { + NetworkManager::cancelFeatchNetworks(); + } + } + + QString fileName() const override + { + if (m_currentInfo) { + return m_currentInfo->fileName(); + } + else return ""; + } + + DUrl fileUrl() const override + { + if (m_currentInfo) { + return m_currentInfo->fileUrl(); + } + else return DUrl(""); + } + + const DAbstractFileInfoPointer fileInfo() const override + { + return m_currentInfo; + } + + DUrl url() const override + { + return m_url; + } + +private: + mutable bool initialized = false; + DUrl m_url; + QPointer m_sender; + bool m_silence{ false }; + DAbstractFileInfoPointer m_currentInfo; + mutable QList m_infoList; +}; + +NetworkController::NetworkController(QObject *parent): + DAbstractFileController(parent) +{ + +} + +NetworkController::~NetworkController() +{ + +} + +const DAbstractFileInfoPointer NetworkController::createFileInfo(const QSharedPointer &event) const +{ + NetworkFileInfo *info = new NetworkFileInfo(event->url()); + auto nodes = NetworkManager::NetworkNodes.value(DUrl(NETWORK_ROOT)); + auto iter = std::find_if(nodes.begin(), nodes.end(), [event](const NetworkNode & node) { + return DUrl(node.url()) == event->url(); + }); + + if (iter != nodes.end()) { + info->setNetworkNode(*iter); + } + + return DAbstractFileInfoPointer(info); +} + +const QList NetworkController::getChildren(const QSharedPointer &event) const +{ + QList infolist; + + if (NetworkManager::NetworkNodes.value(event->url()).isEmpty()) { + if (event->silent()) { + // blumia: if silent is enabled, we'll not invoke fetchNetwork here. + Singleton::instance()->fetchNetworks(DFMUrlBaseEvent(this, event->url())); + } + } + + foreach (const NetworkNode &node, NetworkManager::NetworkNodes.value(event->url())) { + NetworkFileInfo *info = new NetworkFileInfo(DUrl(node.url())); + info->setNetworkNode(node); + infolist.append(DAbstractFileInfoPointer(info)); + }; + + return infolist; +} + +const DDirIteratorPointer NetworkController::createDirIterator(const QSharedPointer &event) const +{ + bool silence_flag{ event->property(QT_STRINGIFY(DFMGetChildrensEvent::slient)).toBool() }; + return DDirIteratorPointer(new NetworkFileDDirIterator(event->fileUrl(), event->sender().data(), silence_flag)); +} + +DUrlList NetworkController::pasteFile(const QSharedPointer &event) const +{ + Q_UNUSED(event) + + return DUrlList(); // disabled for now. +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/networkcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/networkcontroller.h new file mode 100644 index 0000000..e7b7dc1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/networkcontroller.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef NETWORKCONTROLLER_H +#define NETWORKCONTROLLER_H + + +#include "dabstractfilecontroller.h" + +class NetworkController: public DAbstractFileController +{ + Q_OBJECT + +public: + explicit NetworkController(QObject *parent = nullptr); + ~NetworkController() override; + + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + const QList getChildren(const QSharedPointer &event) const override; + const DDirIteratorPointer createDirIterator(const QSharedPointer &event) const override; + DUrlList pasteFile(const QSharedPointer &event) const override; +}; + +#endif // NETWORKCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/operatorrevocation.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/operatorrevocation.cpp new file mode 100644 index 0000000..a7a5f59 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/operatorrevocation.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "operatorrevocation.h" +#include "dfmeventdispatcher.h" +#include "models/trashfileinfo.h" +#include "dbusinterface/revocationmgr_interface.h" +#include "vaultcontroller.h" +#include +#include + +DFM_BEGIN_NAMESPACE + +class OperatorRevocationPrivate : public OperatorRevocation +{public: OperatorRevocationPrivate(){}}; +Q_GLOBAL_STATIC(OperatorRevocationPrivate, _dfm_or) + +OperatorRevocation *OperatorRevocation::instance() +{ + return _dfm_or; +} + +bool OperatorRevocation::fmEvent(const QSharedPointer &event, QVariant *resultData) +{ + Q_UNUSED(resultData) + + switch (static_cast(event->type())) { + case DFMEvent::SaveOperator: { + DFMSaveOperatorEvent *e = static_cast(event.data()); + + if (e->iniaiator() && e->iniaiator()->property("_dfm_is_revocaion_event").toBool()) + return true; + { + QMutexLocker lk(&m_mtx); + //fix bug44556、44632文件多次删除、剪切、撤销出现撤销失败(根据产品需求,限制最多连续撤销两次) + if (REVOCATION_TIMES == operatorStack.count()) { + operatorStack.pop_front(); + } + operatorStack.push(*event.data()); + } + pushEvent(); + return true; + } + case DFMEvent::Revocation: { + popEvent(); + return true; + } + case DFMEvent::CleanSaveOperator: + { + QMutexLocker lk(&m_mtx); + operatorStack.clear(); + } + break; + default: + break; + } + + return false; +} + +OperatorRevocation::OperatorRevocation() +{ + +} + +void OperatorRevocation::slotRevocationEvent(const QString & user) +{ + if (user == getProcessOwner()) + revocation(); +} + +bool OperatorRevocation::initialize() +{ + if (m_dbusInterface) { + delete m_dbusInterface; + m_dbusInterface = nullptr; + } + + m_dbusInterface = new RevocationMgrInterface("com.deepin.filemanager.daemon", + "/com/deepin/filemanager/daemon/RevocationManager", + QDBusConnection::systemBus(), + this); + + if (!m_dbusInterface->isValid()) { + qDebug() << "RevocationMgerInterface cannot linked!"; + + delete m_dbusInterface; + m_dbusInterface = nullptr; + + return false; + } + + //! Get revocation event type. + QString processName = getProcessName(); + if (processName == "dde-file-manager") { + m_eventType = DFM_FILE_MGR_EVENT; + } else { + m_eventType = DFM_DESKTOP_EVENT; + } + + //! Monitor revocation event from dde-file-manager-daemon + QString sigName = "fmgrRevocationAction"; + if (m_eventType == DFM_DESKTOP_EVENT) { + sigName = "deskRevocationAction"; + } + + bool bConnected = QDBusConnection::systemBus().connect( + "com.deepin.filemanager.daemon", + "/com/deepin/filemanager/daemon/RevocationManager", + "com.deepin.filemanager.daemon.RevocationManager", + sigName, + this, + SLOT(slotRevocationEvent(const QString&))); + if (!bConnected) { + qDebug() << "connect to daemon failed!"; + return false; + } + + qDebug() << "OperatorRevocation initialize successful."; + return true; +} + +bool OperatorRevocation::revocation() +{ + bool batch_mode = false; + + batch_revocation: + QMutexLocker lk(&m_mtx); + if (operatorStack.isEmpty()) + return true; + + DFMSaveOperatorEvent e = dfmevent_cast(operatorStack.pop()); + lk.unlock(); + + if (e.split()) { + if (batch_mode) { + return true; + } else { + batch_mode = true; + goto batch_revocation; + } + } + + const QSharedPointer new_event = e.event(); + + new_event->setProperty("_dfm_is_revocaion_event", true); + + //! 保险箱文件处理撤销事件,如果路径是保险箱路径但scheme是非保险箱的,需要重新设置scheme为DFMVAULT_SCHEME + DUrlList urlList = new_event.data()->fileUrlList(); + if(!urlList.isEmpty()) { + for(DUrl & url : urlList) { + if(url.toLocalFile().contains(VaultController::makeVaultLocalPath()) && url.scheme() != DFMVAULT_SCHEME) { + url.setScheme(DFMVAULT_SCHEME); + } + } + new_event.data()->setData(urlList); + } + + if (e.async()) + DFMEventDispatcher::instance()->processEventAsync(new_event); + else + DFMEventDispatcher::instance()->processEvent(new_event); + + if (batch_mode) + goto batch_revocation; + + return true; +} + +QString OperatorRevocation::getProcessName() +{ + char processPath[MAX_FILE_NAME_CHAR_COUNT] = {0}; + ssize_t ret = readlink("/proc/self/exe", processPath, sizeof(processPath)); + if (ret == -1) { + qDebug() << "readlink error"; + return ""; + } + DUrl url(processPath); + return url.fileName(); +} + +void OperatorRevocation::pushEvent() +{ + QString currentUser = getProcessOwner(); + if (m_dbusInterface && m_dbusInterface->isValid()) { + m_dbusInterface->pushEvent(m_eventType, currentUser); + } else { + bool bSuccess = initialize(); + if (bSuccess) { + m_dbusInterface->pushEvent(m_eventType, currentUser); + } + } +} + +void OperatorRevocation::popEvent() +{ + if (m_dbusInterface && m_dbusInterface->isValid()) { + m_dbusInterface->popEvent(); + } else { + bool bSuccess = initialize(); + if (bSuccess) { + m_dbusInterface->popEvent(); + } else { + revocation(); + } + } +} + +QString OperatorRevocation::getProcessOwner() +{ + QString command = "whoami"; + QProcess p; + p.start(command); + p.waitForFinished(); + QString strTemp = QString::fromLocal8Bit( p.readAllStandardOutput() ); + QString LoginUser = strTemp.trimmed(); + return LoginUser; +} + + + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/operatorrevocation.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/operatorrevocation.h new file mode 100644 index 0000000..2a513ed --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/operatorrevocation.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef OPERATORREVOCATION_H +#define OPERATORREVOCATION_H + +#include "dfmabstracteventhandler.h" +#include "dfmevent.h" + +#include +#include +class RevocationMgrInterface; + +DFM_BEGIN_NAMESPACE + +class OperatorRevocation : public QObject, public DFMAbstractEventHandler +{ + Q_OBJECT +public: + /** + * @brief The RevocationEventType enum + * 撤销事件类型 + */ + enum RevocationEventType + { + DFM_NO_EVENT = -1, + DFM_FILE_MGR_EVENT = 0, + DFM_DESKTOP_EVENT = 1 + }; + + static OperatorRevocation *instance(); + +protected: + bool fmEvent(const QSharedPointer &event, QVariant *resultData = nullptr) override; + + OperatorRevocation(); + +protected slots: + /** + * @brief slotRevocationEvent 根据用户名文管进行对应的撤销动作 + */ + void slotRevocationEvent(const QString& user); + +private: + /** + * @brief initialize 建立dbus连接,获取程序类型 + * @return + */ + bool initialize(); + + /** + * @brief revocation 执行恢复操作 + * @return + */ + bool revocation(); + + /** + * @brief getProcessName 获取当前进程名 + * @return + */ + QString getProcessName(); + + /** + * @brief pushEvent 存储对文件、文件夹的操作事件 + */ + void pushEvent(); + + /** + * @brief popEvent 恢复对文件、文件夹的操作事件 + */ + void popEvent(); + + /** + * @brief getProcessOwner 获取当前程序启动的的系统用户名 + * @return 当前程序启动的的系统用户名 + */ + QString getProcessOwner(); +private: + QStack operatorStack; + QMutex m_mtx; + + RevocationMgrInterface *m_dbusInterface = nullptr; + + RevocationEventType m_eventType = DFM_NO_EVENT; +}; + +DFM_END_NAMESPACE + +#endif // OPERATORREVOCATION_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/pathmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/pathmanager.cpp new file mode 100644 index 0000000..cad5724 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/pathmanager.cpp @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "pathmanager.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "controllers/vaultcontroller.h" +#include "usershare/usersharemanager.h" +#include "models/dfmrootfileinfo.h" +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "interfaces/dfmstandardpaths.h" +#include "interfaces/dfmglobal.h" +#include "plugins/schemepluginmanager.h" //NOTE [REN] 添加依赖头文件 + +DFM_USE_NAMESPACE + +PathManager::PathManager(QObject *parent) + : QObject(parent) +{ + initPaths(); +} + +PathManager::~PathManager() +{ + +} + +void PathManager::initPaths() +{ + loadSystemPaths(); + m_systemPathDisplayNamesMap["Home"] = tr("Home"); + m_systemPathDisplayNamesMap["Desktop"] = tr("Desktop"); + m_systemPathDisplayNamesMap["Videos"] = tr("Videos"); + m_systemPathDisplayNamesMap["Music"] = tr("Music"); + m_systemPathDisplayNamesMap["Pictures"] = tr("Pictures"); + m_systemPathDisplayNamesMap["Documents"] = tr("Documents"); + m_systemPathDisplayNamesMap["Downloads"] = tr("Downloads"); + m_systemPathDisplayNamesMap["Trash"] = tr("Trash"); + m_systemPathDisplayNamesMap["System Disk"] = tr("System Disk"); + m_systemPathDisplayNamesMap["Network"] = tr("Computers in LAN"); + m_systemPathDisplayNamesMap["UserShare"] = tr("My Shares"); + m_systemPathDisplayNamesMap["Computer"] = tr("Computer"); + m_systemPathDisplayNamesMap["Recent"] = tr("Recent"); + m_systemPathDisplayNamesMap["Vault"] = tr("File Vault"); + + //NOTE [REN] 将PLUGIN加载到m_systemPathDisplayNamesMap + for (auto plugin : SchemePluginManager::instance()->schemePlugins()) { + DFMSideBarItem *item = plugin.second->createSideBarItem(); + m_systemPathDisplayNamesMap[plugin.first] = item->text(); + } + + if (DFMApplication::instance()->genericObtuselySetting()->value("Disk/Options", "windowsStyle").toBool()) { + m_systemPathDisplayNamesMap["System Disk"] = m_systemPathDisplayNamesMap["System Disk"].append(" (C:)"); + } + + m_systemPathIconNamesMap["Recent"] = "document-open-recent"; + m_systemPathIconNamesMap["Home"] = "user-home"; + m_systemPathIconNamesMap["Desktop"] = "user-desktop"; + m_systemPathIconNamesMap["Videos"] = "folder-videos"; + m_systemPathIconNamesMap["Music"] = "folder-music"; + m_systemPathIconNamesMap["Pictures"] = "folder-pictures"; + m_systemPathIconNamesMap["Documents"] = "folder-documents"; + m_systemPathIconNamesMap["Downloads"] = "folder-downloads"; + m_systemPathIconNamesMap["Trash"] = "user-trash"; + m_systemPathIconNamesMap["Computer"] = "computer"; + m_systemPathIconNamesMap["System Disk"] = "drive-harddisk-root"; + m_systemPathIconNamesMap["Network"] = "network-server"; // folder-remote ? + m_systemPathIconNamesMap["UserShare"] = "folder-publicshare"; + m_systemPathIconNamesMap["Vault"] = "drive-harddisk-encrypted"; // 保险柜,图标还未确定 +} + +QString PathManager::getSystemPath(QString key) +{ + if (m_systemPathsMap.isEmpty()){ + initPaths(); + } + QString path = m_systemPathsMap.value(key); + if(key == "Desktop" || key == "Videos" || key == "Music" || + key == "Pictures" || key == "Documents" || key == "Downloads" || + key == "Trash"){ + + if (!QDir(path).exists()){ + bool flag = QDir::home().mkpath(path); + qDebug() << "mkpath" << path << flag; + } + } + return path; +} + +QString PathManager::getSystemPathDisplayName(QString key) const +{ + if (m_systemPathDisplayNamesMap.contains(key)) + return m_systemPathDisplayNamesMap.value(key); + + return QString(); +} + +void cleanPath(QString &path) +{ + //这里去掉/data的目的 是让通过数据盘路径进入的用户目录下的Docunment,Vedios等文件也可以被翻译 + if (path.startsWith("/data")) + { + path.remove(0, sizeof("/data") - 1); + } + + if (path.size() > 1 && path.at(0) == '/' && path.endsWith("/")) { + path.chop(1); + } +} + +QString PathManager::getSystemPathDisplayNameByPath(QString path) +{ + cleanPath(path); + + if (isSystemPath(path)){ + foreach (QString key, systemPathsMap().keys()) { + if (systemPathsMap().value(key) == path){ + QString displayName; + const QString &name = getSystemPathDisplayName(key); + // 系统盘如果有别名,就以别名显示 + displayName = (path == "/" ? getSystemPathDisplayAliasByName(name) : name); + if (displayName.isEmpty()) + displayName = name; + return displayName; + } + } + } + return QString(); +} + +QString PathManager::getSystemPathDisplayAliasByName(const QString &name) +{ + const QVariantList &list = DFMApplication::genericSetting()->value(DISKALIAS_GROUP, DISKALIAS_ITEMS).toList(); + QString alias; + + for (const QVariant &v : list) { + const QVariantMap &map = v.toMap(); + if (map.value(DISKALIAS_ITEM_NAME).toString() == name) { + alias = map.value(DISKALIAS_ITEM_ALIAS).toString(); + break; + } + } + + return alias; +} + + +QString PathManager::getSystemPathIconName(QString key) +{ + if (m_systemPathIconNamesMap.contains(key)) + return m_systemPathIconNamesMap.value(key); + return QString(); +} + +QString PathManager::getSystemPathIconNameByPath(QString path) +{ + cleanPath(path); + + if (isSystemPath(path)){ + foreach (QString key, systemPathsMap().keys()) { + if (systemPathsMap().value(key) == path){ + return getSystemPathIconName(key); + } + } + } + return QString(); +} + +/** + * @brief 系统盘&数据盘路径 + * @return + */ +QStringList PathManager::getSystemDiskAndDataDiskPathGroup() +{ + const QString &userName = UserShareManager::getCurrentUserName(); + QStringList group {"/", "/data", QString("/home/%1").arg(userName), QString("/data/home/%1").arg(userName)}; + return group; +} + +/** + * @brief 指定的挂载点 + * @return + */ +QStringList PathManager::getMountRangePathGroup() +{ + const QString &userName = UserShareManager::getCurrentUserName(); + QStringList ranges { + QString("/mnt"), + QString("/home/%1").arg(userName), + QString("/media/%1").arg(userName), + QString("/data/home/%1").arg(userName), + }; + return ranges; +} + +void PathManager::loadSystemPaths() +{ + m_systemPathsMap["Home"] = DFMStandardPaths::location(DFMStandardPaths::HomePath); + m_systemPathsMap["Desktop"] = DFMStandardPaths::location(DFMStandardPaths::DesktopPath); + m_systemPathsMap["Videos"] = DFMStandardPaths::location(DFMStandardPaths::VideosPath); + m_systemPathsMap["Music"] = DFMStandardPaths::location(DFMStandardPaths::MusicPath); + m_systemPathsMap["Pictures"] = DFMStandardPaths::location(DFMStandardPaths::PicturesPath); + m_systemPathsMap["Documents"] = DFMStandardPaths::location(DFMStandardPaths::DocumentsPath); + m_systemPathsMap["Downloads"] = DFMStandardPaths::location(DFMStandardPaths::DownloadsPath); + m_systemPathsMap["Trash"] = DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath); + m_systemPathsMap["System Disk"] = DFMStandardPaths::location(DFMStandardPaths::DiskPath); + m_systemPathsMap["Network"] = DFMStandardPaths::location(DFMStandardPaths::NetworkRootPath); + m_systemPathsMap["UserShare"] = DFMStandardPaths::location(DFMStandardPaths::UserShareRootPath); + m_systemPathsMap["Computer"] = DFMStandardPaths::location(DFMStandardPaths::ComputerRootPath); + m_systemPathsMap["Recent"] = DFMStandardPaths::location(DFMStandardPaths::RecentPath); + m_systemPathsMap["Vault"] = DFMStandardPaths::location(DFMStandardPaths::Vault); // 保险库路径 + + //NOTE [REN] 将PLUGIN加载到m_systemPathsMap + for (auto plugin : SchemePluginManager::instance()->schemePlugins()) { + DFMSideBarItem *item = plugin.second->createSideBarItem(); + m_systemPathsMap[plugin.first] = item->url().toString(); + } + + m_systemPathsSet.reserve(m_systemPathsMap.size()); + + foreach (const QString &key, m_systemPathsMap.keys()) { + const QString &path = m_systemPathsMap.value(key); + + if (key != "Trash") + m_systemPathsSet << path; + + if(key == "Desktop" || key == "Videos" || key == "Music" || + key == "Pictures" || key == "Documents" || key == "Downloads" || + key == "Trash"){ + mkPath(path); + } + } +} + +void PathManager::mkPath(const QString &path) +{ + if (!QDir(path).exists()){ + bool flag = QDir::home().mkpath(path); + qDebug() << "mkpath" << path << flag; + } +} + +QMap PathManager::systemPathDisplayNamesMap() const +{ + return m_systemPathDisplayNamesMap; +} + +bool PathManager::isSystemPath(QString path) const +{ + cleanPath(path); + + return m_systemPathsSet.contains(path); +} + +/** + * sp3 feature: 计算机页面展示分区范围说明 + * 分区识别范围: + * 1. 系统指定的分区 + * /,显示为系统盘 + * /data,显示为数据盘 + * /home/username/ + * /media/username/ + * /mnt/ + * 2. 除上述之外的挂载分区,不在系统文管中展示; + * + * @return 返回 true 则计算机页面显示该分区 + */ +bool PathManager::isVisiblePartitionPath(const DAbstractFileInfoPointer &fi) +{ +#ifdef SP3_UNSTABLE_FEATURE_ENABLE + QString suffix = fi->suffix(); + if (DFMGlobal::isRootUser()) { // root 用户不受限 + return true; + } else if (suffix == SUFFIX_USRDIR || suffix == SUFFIX_GVFSMP) { // 系统路径,MTP等不受限 + return true; + } else { // localdisk + DUrl url = fi->redirectedFileUrl(); + DUrl parentUrl = url.parentUrl(); + const QString &path = url.toLocalFile(); + const QString &parentPath = parentUrl.toLocalFile(); + + // [0] 光驱 + if (isOptical(fi)) + return true; + + // [1] 当打开文管时挂载U盘,进入到此函数时,很可能还没挂载完成,获取不到path + // 为了避免这种情况下无法显示,因此直接返回true + // todo:此处可能会被报bug,但目前没有想到更好的方案,待优化 + if (path.isEmpty()) + return true; + + // [2] 排除系统盘 & 数据盘 + const QStringList &sysRanges = getSystemDiskAndDataDiskPathGroup(); + if (sysRanges.contains(path)) + return true; + + // [3] 挂载只显示挂载到以下挂载点的内容 + const QStringList &parentRanges = getMountRangePathGroup(); + if (parentRanges.contains(parentPath)) + return true; + } + qDebug() << "partition ignore path:" << fi->redirectedFileUrl().toLocalFile(); + + return false; +#else + Q_UNUSED(fi) + return true; +#endif +} + +bool PathManager::isOptical(const DAbstractFileInfoPointer &fi) +{ + QString path = fi->fileUrl().toString(); + return path.contains("dfmroot:///sr") ? true : false; +} + +QMap PathManager::systemPathsMap() const +{ + return m_systemPathsMap; +} + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/pathmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/pathmanager.h new file mode 100644 index 0000000..0047ac6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/pathmanager.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef PATHMANAGER_H +#define PATHMANAGER_H + +#include +#include +#include + +#include "durl.h" +#include "dabstractfileinfo.h" + +class PathManager : public QObject +{ + Q_OBJECT + +public: + explicit PathManager(QObject *parent = nullptr); + ~PathManager(); + + void initPaths(); + + QString getSystemPath(QString key); + QString getSystemPathDisplayName(QString key) const; + QString getSystemPathDisplayNameByPath(QString path); + QString getSystemPathDisplayAliasByName(const QString &name); + QString getSystemPathIconName(QString key); + QString getSystemPathIconNameByPath(QString path); + QStringList getSystemDiskAndDataDiskPathGroup(); + QStringList getMountRangePathGroup(); + + QMap systemPathsMap() const; + QMap systemPathDisplayNamesMap() const; + + bool isSystemPath(QString path) const; + bool isVisiblePartitionPath(const DAbstractFileInfoPointer &fi); + bool isOptical(const DAbstractFileInfoPointer &fi); + +public slots: + void loadSystemPaths(); + void mkPath(const QString& path); + +private: + QMap m_systemPathsMap; + QMap m_systemPathDisplayNamesMap; + QMap m_systemPathIconNamesMap; + QSet m_systemPathsSet; +}; + +#endif // PATHMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/recentcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/recentcontroller.cpp new file mode 100644 index 0000000..c062a76 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/recentcontroller.cpp @@ -0,0 +1,682 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "recentcontroller.h" +#include "dfileservices.h" +#include "dfilewatcher.h" +#include "dfmevent.h" +#include "dfmglobal.h" +#include "private/dabstractfilewatcher_p.h" +#include "dialogs/dialogmanager.h" +#include "shutil/fileutils.h" +#include "app/define.h" +#include "vaultcontroller.h" +#include "singleton.h" +#include "app/filesignalmanager.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +DCORE_USE_NAMESPACE +DWIDGET_USE_NAMESPACE + +class RecentFileWatcherPrivate; +class RecentFileWatcher : public DAbstractFileWatcher +{ +public: + explicit RecentFileWatcher(const DUrl &url, DAbstractFileWatcher *proxy, QObject *parent = nullptr); + + void setEnabledSubfileWatcher(const DUrl &subfileUrl, bool enabled = true) override; + +private: + void addWatcher(const DUrl &url); + void removeWatcher(const DUrl &url); + + void onFileDeleted(const DUrl &url); + void onFileAttributeChanged(const DUrl &url); + void onFileModified(const DUrl &url); + void onFileMoved(const DUrl &from, const DUrl &to); + +public slots: + void removeRecentFile(const QString &path); + + Q_DECLARE_PRIVATE(RecentFileWatcher) +}; + +class RecentFileWatcherPrivate : public DAbstractFileWatcherPrivate +{ +public: + explicit RecentFileWatcherPrivate(DAbstractFileWatcher *qq) + : DAbstractFileWatcherPrivate(qq) {} + + bool start() override + { + started = true; + + return proxy && proxy->startWatcher();; + } + + bool stop() override + { + started = false; + + return proxy && proxy->stopWatcher(); + } + + QMap urlToWatcherMap; + QPointer proxy; + + Q_DECLARE_PUBLIC(RecentFileWatcher) +}; + +RecentFileWatcher::RecentFileWatcher(const DUrl &url, DAbstractFileWatcher *proxy, QObject *parent) + : DAbstractFileWatcher(*new RecentFileWatcherPrivate(this), url, parent) +{ + Q_ASSERT(proxy); + Q_ASSERT(!proxy->parent()); + + if (url == DUrl(RECENT_ROOT)) + connect(fileSignalManager, &FileSignalManager::requestRemoveRecentFile, this, &RecentFileWatcher::removeRecentFile); + + proxy->moveToThread(thread()); + proxy->setParent(this); + + d_func()->proxy = proxy; + connect(proxy, &DAbstractFileWatcher::fileAttributeChanged, this, &RecentFileWatcher::onFileAttributeChanged); + connect(proxy, &DAbstractFileWatcher::fileDeleted, this, &RecentFileWatcher::onFileDeleted); + connect(proxy, &DAbstractFileWatcher::fileMoved, this, &RecentFileWatcher::onFileMoved); + connect(proxy, &DAbstractFileWatcher::fileModified, this, &RecentFileWatcher::onFileModified); +} + +void RecentFileWatcher::setEnabledSubfileWatcher(const DUrl &subfileUrl, bool enabled) +{ + if (!subfileUrl.isRecentFile()) + return; + + if (enabled) { + addWatcher(subfileUrl); + } else { + removeWatcher(subfileUrl); + } +} + +void RecentFileWatcher::addWatcher(const DUrl &url) +{ + Q_D(RecentFileWatcher); + + if (!url.isValid() || d->urlToWatcherMap.contains(url)) { + return; + } + + if (DFileService::instance()->checkGvfsMountfileBusy(url,false)) + return; + + DUrl real_url = url; + real_url.setScheme(FILE_SCHEME); + + DAbstractFileWatcher *watcher = DFileService::instance()->createFileWatcher(this, real_url); + + if (!watcher) + return; + + watcher->moveToThread(this->thread()); + watcher->setParent(this); + + connect(watcher, &DAbstractFileWatcher::fileAttributeChanged, this, &RecentFileWatcher::onFileAttributeChanged); + connect(watcher, &DAbstractFileWatcher::fileDeleted, this, &RecentFileWatcher::onFileDeleted); + connect(watcher, &DAbstractFileWatcher::fileModified, this, &RecentFileWatcher::onFileModified); + connect(watcher, &DAbstractFileWatcher::fileMoved, this, &RecentFileWatcher::onFileMoved); + + d->urlToWatcherMap[url] = watcher; + + if (d->started) { + watcher->startWatcher(); + } +} + +void RecentFileWatcher::removeWatcher(const DUrl &url) +{ + Q_D(RecentFileWatcher); + + DAbstractFileWatcher *watcher = d->urlToWatcherMap.take(url); + + if (!watcher) { + return; + } + + watcher->deleteLater(); +} + +void RecentFileWatcher::onFileDeleted(const DUrl &url) +{ + DUrl newUrl = url; + newUrl.setScheme(RECENT_SCHEME); + removeWatcher(newUrl); + + emit fileDeleted(newUrl); +} + +void RecentFileWatcher::onFileAttributeChanged(const DUrl &url) +{ + DUrl newUrl = url; + newUrl.setScheme(RECENT_SCHEME); + + emit fileAttributeChanged(newUrl); +} + +void RecentFileWatcher::onFileModified(const DUrl &url) +{ + DUrl newUrl = url; + newUrl.setScheme(RECENT_SCHEME); + + emit fileModified(newUrl); +} + +void RecentFileWatcher::onFileMoved(const DUrl &from, const DUrl &to) +{ + DUrl newFromUrl = from; + newFromUrl.setScheme(RECENT_SCHEME); + removeWatcher(newFromUrl); + + emit fileMoved(newFromUrl, to); +} +//fix bug 63922 移除父目录是path的url +void RecentFileWatcher::removeRecentFile(const QString &path) +{ + Q_D(RecentFileWatcher); + + DUrlList removeUrls; + for (auto url : d->urlToWatcherMap.keys()) { + if (url.path().startsWith(path)) + removeUrls << url; + } + + for (auto url : removeUrls) { + onFileDeleted(url); + } +} + +class RecentDirIterator : public DDirIterator +{ +public: + RecentDirIterator(const DUrl &url, const QStringList &nameFilters, QDir::Filters filter, + QDirIterator::IteratorFlags flags, RecentController *parent); + + DUrl next() override; + bool hasNext() const override; + + QString fileName() const override; + DUrl fileUrl() const override; + const DAbstractFileInfoPointer fileInfo() const override; + DUrl url() const override; + +private: + DAbstractFileInfoPointer m_currentFileInfo; + RecentController *parent; + + mutable QQueue urlList; + DUrl m_url; +}; + +RecentDirIterator::RecentDirIterator(const DUrl &url, const QStringList &nameFilters, + QDir::Filters filter, QDirIterator::IteratorFlags flags, + RecentController *parent) + : DDirIterator(), + parent(parent) +{ + Q_UNUSED(url) + Q_UNUSED(nameFilters) + Q_UNUSED(filter) + Q_UNUSED(flags) + + for (DUrl url : parent->recentNodes.keys()) { + if (!DFileService::instance()->checkGvfsMountfileBusy(url,false)) + urlList << url; + } +} + +DUrl RecentDirIterator::next() +{ + if (!urlList.isEmpty()) { + m_url = urlList.dequeue(); + return m_url; + } + + return DUrl(); +} + +bool RecentDirIterator::hasNext() const +{ + if (!urlList.isEmpty()) { + return true; + } + + return false; +} + +QString RecentDirIterator::fileName() const +{ + DAbstractFileInfoPointer currentInfo = parent->recentNodes.value(m_url); + + return currentInfo ? currentInfo->fileName() : QString(); +} + +DUrl RecentDirIterator::fileUrl() const +{ + DAbstractFileInfoPointer currentInfo = parent->recentNodes.value(m_url); + + return currentInfo ? currentInfo->fileUrl() : DUrl(); +} + +const DAbstractFileInfoPointer RecentDirIterator::fileInfo() const +{ + return parent->recentNodes.value(m_url); +} + +DUrl RecentDirIterator::url() const +{ + return DUrl(RECENT_ROOT); +} + +RecentController::RecentController(QObject *parent) + : DAbstractFileController(parent), + m_xbelPath(QDir::homePath() + "/.local/share/recently-used.xbel"), + m_watcher(new DFileWatcher(m_xbelPath, this)) +{ + asyncHandleFileChanged(); + + connect(m_watcher, &DFileWatcher::subfileCreated, this, &RecentController::asyncHandleFileChanged); + connect(m_watcher, &DFileWatcher::fileModified, this, &RecentController::asyncHandleFileChanged); + + m_watcher->startWatcher(); +} + +bool RecentController::openFileLocation(const QSharedPointer &event) const +{ + return DFileService::instance()->openFileLocation(event->sender(), DUrl::fromLocalFile(event->url().path())); +} + +bool RecentController::openFile(const QSharedPointer &event) const +{ + //在smb/ftp更改文件名称后最近使用里面打开文件,使用createFileInfo不能判断源文件是否存在为真 + //这里直接获取真实路径进行判断源文件是否存在 + if (!QFile(event->url().path()).exists()) { + DDialog d(QObject::tr("Failed to open the file, cause: %1") + .arg(QObject::tr("Original file does not exist")), + QObject::tr("Do you want to delete %1?") + .arg(event->url().fileName())); + + Qt::WindowFlags flags = d.windowFlags(); + // dialog show top + d.setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint); + d.setIcon(QIcon::fromTheme("dialog-error")); + d.addButton(QObject::tr("Confirm","button"), true, DDialog::ButtonRecommend); + d.addButton(QObject::tr("Cancel","button"), false, DDialog::ButtonRecommend); + d.setMaximumWidth(640); + if(d.exec() == 0) + DRecentManager::removeItem(event->url().path()); //删除当前最近使用项 + return true; + } + + return DFileService::instance()->openFile(event->sender(), DUrl::fromLocalFile(event->url().path())); +} + +bool RecentController::openFiles(const QSharedPointer &event) const +{ + DUrlList fileUrls = event->urlList(); + DUrlList packUrl; + QStringList pathList; + bool result = false; + + for (DUrl fileUrl : fileUrls) { + const DAbstractFileInfoPointer pfile = createFileInfo(dMakeEventPointer(this, fileUrl)); + if (!pfile) { + continue; + } + if (pfile->isSymLink()) { + const DAbstractFileInfoPointer &linkInfo = DFileService::instance()->createFileInfo(this, pfile->symLinkTarget()); + + if (linkInfo && !linkInfo->exists()) { + dialogManager->showBreakSymlinkDialog(linkInfo->fileName(), DUrl(fileUrl.path().remove(RECENT_ROOT))); + continue; + } + fileUrl = linkInfo->redirectedFileUrl(); + } + + if (FileUtils::isExecutableScript(fileUrl.path().remove(RECENT_ROOT))) { + int code = dialogManager->showRunExcutableScriptDialog(DUrl(fileUrl.path().remove(RECENT_ROOT)), event->windowId()); + result = FileUtils::openExcutableScriptFile(fileUrl.path().remove(RECENT_ROOT), code) || result; + continue; + } + + if (FileUtils::isFileRunnable(fileUrl.path().remove(RECENT_ROOT)) && !pfile->isDesktopFile()) { + int code = dialogManager->showRunExcutableFileDialog(DUrl(fileUrl.path().remove(RECENT_ROOT)), event->windowId()); + result = FileUtils::openExcutableFile(fileUrl.path().remove(RECENT_ROOT), code) || result; + continue; + } + + if (FileUtils::shouldAskUserToAddExecutableFlag(fileUrl.path().remove(RECENT_ROOT)) && !pfile->isDesktopFile()) { + int code = dialogManager->showAskIfAddExcutableFlagAndRunDialog(DUrl(fileUrl.path().remove(RECENT_ROOT)), event->windowId()); + result = FileUtils::addExecutableFlagAndExecuse(fileUrl.path().remove(RECENT_ROOT), code) || result; + continue; + } + + packUrl << fileUrl; + QString url = fileUrl.path().remove(RECENT_ROOT); + if (FileUtils::isFileWindowsUrlShortcut(url)) { + url = FileUtils::getInternetShortcutUrl(url); + } + pathList << url; + } + if (!pathList.empty()) { + if (event->isEnter()) { + result = FileUtils::openEnterFiles(pathList); + } + else { + result = FileUtils::openFiles(pathList); + } + if (!result) { + for (const DUrl &fileUrl : packUrl) { + DFileService::instance()->openFile(event->sender(), fileUrl); + } + } + } + + return result; +} +bool RecentController::openFileByApp(const QSharedPointer &event) const +{ + return DFileService::instance()->openFileByApp(event->sender(), event->appName(), DUrl::fromLocalFile(event->url().path())); +} + +bool RecentController::openFilesByApp(const QSharedPointer &event) const +{ + //RecentController::openFilesByApp负责将所有recentUrl转成fileUrl然后走filecontroller::openFilesByApp的逻辑流程 + const DUrlList recentUrls = event.data()->urlList(); + DUrlList fileUrls; + for (const DUrl &url : recentUrls) { + fileUrls.append(DUrl::fromLocalFile(url.path())); + } + return DFileService::instance()->openFilesByApp(event->sender(), event->appName(), fileUrls); +} + +bool RecentController::writeFilesToClipboard(const QSharedPointer &event) const +{ + //最近使用文件不支持剪切,这里主要是屏蔽从ctrl+x快捷键操作过来的剪切事件。 + if (event->action() == DFMGlobal::CutAction) + return false; + return DFileService::instance()->writeFilesToClipboard(event->sender(), event->action(), + realUrlList(event->urlList())); +} + +bool RecentController::renameFile(const QSharedPointer &event) const +{ + DUrl oldUrl = DUrl::fromLocalFile(event->fromUrl().path()); + DUrl newUrl = DUrl::fromLocalFile(event->toUrl().path()); + + return DFileService::instance()->renameFile(event->sender(), oldUrl, newUrl); +} + +bool RecentController::compressFiles(const QSharedPointer &event) const +{ + return DFileService::instance()->compressFiles(event->sender(), realUrlList(event->urlList())); +} + +bool RecentController::decompressFile(const QSharedPointer &event) const +{ + return DFileService::instance()->decompressFile(event->sender(), realUrlList(event->urlList())); +} + +bool RecentController::createSymlink(const QSharedPointer &event) const +{ + return DFileService::instance()->createSymlink(event->sender(), DUrl::fromLocalFile(event->fileUrl().path()), event->toUrl(), event->force()); +} + +bool RecentController::deleteFiles(const QSharedPointer &event) const +{ + DThreadUtil::runInMainThread([event] { + DDialog dlg; + dlg.setIcon(QIcon::fromTheme("dialog-warning")); + dlg.addButton(tr("Cancel", "button")); + dlg.addButton(tr("Remove", "button"), true, DDialog::ButtonRecommend); + + if (event->urlList().size() == 1) + dlg.setTitle(tr("Do you want to remove this item?")); + else + dlg.setTitle(tr("Do yout want to remove %1 items?").arg(event->urlList().size())); + dlg.setMessage(tr("It does not delete the original files")); + + int code = dlg.exec(); + if (code == 1) { + QStringList list; + for (const DUrl &url : event->urlList()) { + //list << DUrl::fromLocalFile(url.path()).toString(); + //通过durl转换path会出现编码问题,这里直接用字符串拼出正确的path; + QString urlPath = url.path(); + list << "file://" + urlPath; + } + + DRecentManager::removeItems(list); + } + }); + + return true; +} + +DUrlList RecentController::moveToTrash(const QSharedPointer &event) const +{ + deleteFiles(dMakeEventPointer(event->sender(), + event->urlList(), + event->silent())); + + return DUrlList(); +} + +bool RecentController::setFileTags(const QSharedPointer &event) const +{ + if (!event->url().isValid()) { + return false; + } + + QList tags = event->tags(); + return DFileService::instance()->setFileTags(this, DUrl::fromLocalFile(event->fileUrl().path()), tags); +} + +bool RecentController::removeTagsOfFile(const QSharedPointer &event) const +{ + if (!event->url().isValid()) { + return false; + } + + return DFileService::instance()->removeTagsOfFile(this, DUrl::fromLocalFile(event->fileUrl().path()), event->tags()); +} + +QList RecentController::getTagsThroughFiles(const QSharedPointer &event) const +{ + QList list = event->urlList(); + + for (DUrl &item : list) { + item = DUrl::fromLocalFile(item.path()); + } + + return DFileService::instance()->getTagsThroughFiles(this, list); +} + +const DDirIteratorPointer RecentController::createDirIterator(const QSharedPointer &event) const +{ + RecentDirIterator *iterator = new RecentDirIterator(event->url(), event->nameFilters(), + event->filters(), event->flags(), + const_cast(this)); + return DDirIteratorPointer(iterator); +} + +const DAbstractFileInfoPointer RecentController::createFileInfo(const QSharedPointer &event) const +{ + if (event->url().path() == "/") { + return DAbstractFileInfoPointer(new RecentFileInfo(DUrl(RECENT_ROOT))); + } + + return DAbstractFileInfoPointer(recentNodes.value(event->url())); +} + +DAbstractFileWatcher *RecentController::createFileWatcher(const QSharedPointer &event) const +{ + DAbstractFileWatcher *base_watcher = DFileService::instance()->createFileWatcher(event->sender(), DUrl::fromLocalFile(event->url().path())); + return new RecentFileWatcher(event->url(), base_watcher); +} + +DUrlList RecentController::realUrlList(const DUrlList &recentUrls) +{ + DUrlList list; + + for (const DUrl &url : recentUrls) { + list << DUrl::fromLocalFile(url.path()); + } + + return list; +} + +void RecentController::handleFileChanged() +{ + // read xbel file. + QFile file(m_xbelPath); + QList urlList; + + // try interrupting any other running parsers, then acquire the lock + m_condition.wakeAll(); + if (!m_xbelFileLock.tryLock(100)) { + return; + } + + QPointer dp = this; + + if (m_condition.wait(&m_xbelFileLock, 1000)) { + // if the parser is interrupted. + // we need a timeout long enough so that + // virtually all execution time is spent here. + m_xbelFileLock.unlock(); + return; + } + + if (file.open(QIODevice::ReadOnly)) { + QXmlStreamReader reader(&file); + + while (!reader.atEnd()) { + + if (!reader.readNextStartElement() || + reader.name() != "bookmark") { + continue; + } + + const QStringRef &location = reader.attributes().value("href"); + const QStringRef &readTime = reader.attributes().value("modified"); + + if (!location.isEmpty()) { + DUrl url = DUrl(location.toString()); + QFileInfo info(url.toLocalFile()); + DUrl recentUrl = url; + recentUrl.setScheme(RECENT_SCHEME); + + if (info.exists() && info.isFile()) { + urlList << recentUrl; + + DThreadUtil::runInMainThread([ = ]() { + if (dp.isNull()) + return; + // 保险箱内文件不显示到最近使用页面 + if(!VaultController::isVaultFile(location.toString())) { + if (!recentNodes.contains(recentUrl)) { + recentNodes[recentUrl] = new RecentFileInfo(recentUrl); + DAbstractFileWatcher::ghostSignal(DUrl(RECENT_ROOT), + &DAbstractFileWatcher::subfileCreated, + recentUrl); + } + //如果readtime变更了,需要通知filesystemmodel重新排序 + else if (recentNodes[recentUrl]->readDateTime().toSecsSinceEpoch() != QDateTime::fromString(readTime.toString(), Qt::ISODate).toSecsSinceEpoch()) { + //先更新info数据 + recentNodes[recentUrl]->updateInfo(); + DAbstractFileWatcher::ghostSignal(DUrl(RECENT_ROOT), + &DAbstractFileWatcher::fileModified, + recentUrl); + } + } + }); + } + } + } + } + + if (dp.isNull()) + return; + // delete does not exist url. + for (auto iter = recentNodes.begin(); iter != recentNodes.end();) { + if (dp.isNull()) + return; + const DUrl &url = iter.key(); + if (!urlList.contains(url)) { + DThreadUtil::runInMainThread([this, &iter, url]() { + iter = recentNodes.erase(iter); + + DAbstractFileWatcher::ghostSignal(DUrl(RECENT_ROOT), + &DAbstractFileWatcher::fileDeleted, + url); + }); + } else { + auto info = iter.value(); + if (info) { + iter.value()->updateInfo(); + ++iter; + } else { + iter = recentNodes.erase(iter); + } + } + if (dp.isNull()) + return; + } + + m_xbelFileLock.unlock(); +} + +void RecentController::asyncHandleFileChanged() +{ + /* remark 190410: + * This slot always gets triggered multiple times consecutively by the + * file closed/modified events. The correct fix should be applying a + * lock to 'recently-used.xbel' whenever writing. + * The current solution is setting a timeout, during which no matter + * how many handleFileChanged()'s are triggered, only the last one + * gets executed. + * The issue mentioned above is specific to applications that use DTK. + * Applications using GTK does not trigger file closed/modified events + * at all for some obscure reasons. + */ + QtConcurrent::run(this, &RecentController::handleFileChanged); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/recentcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/recentcontroller.h new file mode 100644 index 0000000..11da3b6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/recentcontroller.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef RECENTCONTROLLER_H +#define RECENTCONTROLLER_H + +#include "dabstractfilecontroller.h" +#include "models/recentfileinfo.h" + +#include +#include + +class QFileSystemWatcher; +class DAbstractFileInfo; +class DFileWatcher; +class QTimer; + +class RecentController : public DAbstractFileController +{ + Q_OBJECT + +public: + explicit RecentController(QObject *parent = nullptr); + + bool openFileLocation(const QSharedPointer &event) const override; + bool openFile(const QSharedPointer &event) const override; + bool openFiles(const QSharedPointer &event) const override; + bool openFileByApp(const QSharedPointer &event) const override; + bool openFilesByApp(const QSharedPointer &event) const override; + bool writeFilesToClipboard(const QSharedPointer &event) const override; + bool renameFile(const QSharedPointer &event) const override; + bool compressFiles(const QSharedPointer &event) const override; + bool decompressFile(const QSharedPointer &event) const override; + bool createSymlink(const QSharedPointer &event) const override; + + bool deleteFiles(const QSharedPointer &event) const override; + DUrlList moveToTrash(const QSharedPointer &event) const override; + + bool setFileTags(const QSharedPointer &event) const override; + bool removeTagsOfFile(const QSharedPointer &event) const override; + QList getTagsThroughFiles(const QSharedPointer &event) const override; + + const DDirIteratorPointer createDirIterator(const QSharedPointer &event) const override; + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + +public: + mutable QMap recentNodes; + +private: + static DUrlList realUrlList(const DUrlList &recentUrls); + void handleFileChanged(); + void asyncHandleFileChanged(); + +private: + QString m_xbelPath; + DFileWatcher *m_watcher; + QWaitCondition m_condition; + QMutex m_xbelFileLock; +}; + +#endif // RECENTCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/searchcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/searchcontroller.cpp new file mode 100644 index 0000000..60f1220 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/searchcontroller.cpp @@ -0,0 +1,827 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "searchcontroller.h" +#include "dfileservices.h" +#include "dfmevent.h" +#include "dfileproxywatcher.h" +#include "private/dabstractfilewatcher_p.h" + +#include "models/searchfileinfo.h" +#include "ddiriterator.h" +#include "shutil/dfmregularexpression.h" +#include "shutil/dfmfilelistfile.h" +#include "dfmapplication.h" +#include "dfmstandardpaths.h" +#include "vaultcontroller.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "models/vaultfileinfo.h" + +#ifndef DISABLE_QUICK_SEARCH +#include "anything_interface.h" +#endif + +#include + +#include +#include +#include +#ifdef FULLTEXTSEARCH_ENABLE +#include "fulltextsearch/fulltextsearch.h" +#endif +class SearchFileWatcherPrivate; +class SearchFileWatcher : public DAbstractFileWatcher +{ +public: + explicit SearchFileWatcher(const DUrl &url, QObject *parent = nullptr); + ~SearchFileWatcher() override; + + void setEnabledSubfileWatcher(const DUrl &subfileUrl, bool enabled = true) override; + +private: + void addWatcher(const DUrl &url); + void removeWatcher(const DUrl &url); + + void onFileDeleted(const DUrl &url); + void onFileAttributeChanged(const DUrl &url); + void onFileMoved(const DUrl &fromUrl, const DUrl &toUrl); + void onSubfileCreated(const DUrl &url); + void onFileModified(const DUrl &url); + + Q_DECLARE_PRIVATE(SearchFileWatcher) +}; + +class SearchFileWatcherPrivate : public DAbstractFileWatcherPrivate +{ +public: + explicit SearchFileWatcherPrivate(SearchFileWatcher *qq) + : DAbstractFileWatcherPrivate(qq) {} + + bool start() override; + bool stop() override; + + QMap urlToWatcherMap; + + Q_DECLARE_PUBLIC(SearchFileWatcher) +}; + +SearchFileWatcher::SearchFileWatcher(const DUrl &url, QObject *parent) + : DAbstractFileWatcher(*new SearchFileWatcherPrivate(this), url, parent) +{ + +} + +SearchFileWatcher::~SearchFileWatcher() +{ + Q_D(SearchFileWatcher); + d->urlToWatcherMap.clear(); +} + +void SearchFileWatcher::setEnabledSubfileWatcher(const DUrl &subfileUrl, bool enabled) +{ + DUrl url = subfileUrl; + + url.setSearchedFileUrl(DUrl()); + + if (url != fileUrl()) { + return; + } + + if (enabled) { + addWatcher(subfileUrl.searchedFileUrl()); + } + //这里removeWatcher的逻辑是在文件超出可视区域时,就不监控其变化 + //但这样会导致在一些特殊目录下搜索后,做一些特殊操作(例如最近使用目录中移除文件 、标记目录中取消文件标记等)时, + //在可视区域外的文件不会从搜索结果中移除 + //宗上,将该行代码注释 + //else { + // removeWatcher(subfileUrl.searchedFileUrl()); + //} +} + +void SearchFileWatcher::addWatcher(const DUrl &url) +{ + Q_D(SearchFileWatcher); + + if (!url.isValid() || d->urlToWatcherMap.contains(url)) { + return; + } + + DAbstractFileWatcher *watcher = DFileService::instance()->createFileWatcher(this, url); + + if (!watcher) { + return; + } + + watcher->moveToThread(this->thread()); + watcher->setParent(this); + + d->urlToWatcherMap[url] = watcher; + + connect(watcher, &DAbstractFileWatcher::fileAttributeChanged, this, &SearchFileWatcher::onFileAttributeChanged); + connect(watcher, &DAbstractFileWatcher::fileDeleted, this, &SearchFileWatcher::onFileDeleted); + connect(watcher, &DAbstractFileWatcher::fileModified, this, &SearchFileWatcher::onFileModified); + connect(watcher, &DAbstractFileWatcher::fileMoved, this, &SearchFileWatcher::onFileMoved); + + if (d->started) { + watcher->startWatcher(); + } +} + +void SearchFileWatcher::removeWatcher(const DUrl &url) +{ + Q_D(SearchFileWatcher); + + DAbstractFileWatcher *watcher = d->urlToWatcherMap.take(url); + + if (!watcher) { + return; + } + + watcher->deleteLater(); +} + +void SearchFileWatcher::onFileDeleted(const DUrl &url) +{ + removeWatcher(url); + + DUrl newUrl = fileUrl(); + newUrl.setSearchedFileUrl(url); + + emit fileDeleted(newUrl); +} + +void SearchFileWatcher::onFileAttributeChanged(const DUrl &url) +{ + DUrl newUrl = fileUrl(); + newUrl.setSearchedFileUrl(url); + + emit fileAttributeChanged(newUrl); +} + +void SearchFileWatcher::onFileMoved(const DUrl &fromUrl, const DUrl &toUrl) +{ + DUrl newFromUrl = fileUrl(); + newFromUrl.setSearchedFileUrl(fromUrl); + + DUrl newToUrl = toUrl; + if (fileUrl().searchTargetUrl().scheme() == toUrl.scheme() && toUrl.path().startsWith(fileUrl().searchTargetUrl().path())) { + QString keywordPattern = DFMRegularExpression::checkWildcardAndToRegularExpression(fileUrl().searchKeyword()); + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, toUrl); + + QRegularExpression regexp(keywordPattern, QRegularExpression::CaseInsensitiveOption); + QRegularExpressionMatch match = regexp.match(info->fileDisplayName()); + if (match.hasMatch()) { + newToUrl = fileUrl(); + newToUrl.setSearchedFileUrl(toUrl); + + /*fix bug34957,搜索模式下,删除文件到回收站的文件不再加入到watcher中,不然会一直删除不掉*/ + if (toUrl.path().contains("/.local/share/Trash/files", Qt::CaseSensitive)) { + return; + } else { + /*fix bug 44187 修改搜索结果名称,文件夹会从搜索结果消失,因为watcher里面增加的是真实路径不是搜索路径*/ + addWatcher(newToUrl); + } + } + } + +// removeWatcher(fromUrl); // fix task 21431 临时解决方案。 + + emit fileMoved(newFromUrl, newToUrl); +} + +void SearchFileWatcher::onFileModified(const DUrl &url) +{ + DUrl newUrl = fileUrl(); + newUrl.setSearchedFileUrl(url); + + emit fileModified(newUrl); +} + +bool SearchFileWatcherPrivate::start() +{ + bool ok = true; + + for (DAbstractFileWatcher *watcher : urlToWatcherMap) { + ok = ok && watcher->startWatcher(); + } + + started = ok; + + return ok; +} + +bool SearchFileWatcherPrivate::stop() +{ + bool ok = true; + + for (DAbstractFileWatcher *watcher : urlToWatcherMap) { + ok = ok && watcher->stopWatcher(); + } + + started = !ok; + + return ok; +} + +class SearchDiriterator : public DDirIterator +{ +public: + SearchDiriterator(const DUrl &url, const QStringList &nameFilters, QDir::Filters filter, + QDirIterator::IteratorFlags flags, SearchController *parent); + ~SearchDiriterator() override; + + DUrl next() override; + bool hasNext() const override; + + QString fileName() const override; + DUrl fileUrl() const override; + const DAbstractFileInfoPointer fileInfo() const override; + DUrl url() const override; + void close() override; + void fullTextSearch(const QString &searchPath) const; + + // fix bug23761 新增搜索结果是否为隐藏文件判断 + // fix bug60961 递归判断搜索结果是否在隐藏目录下 + bool searchFileIsHidden(const QString &fileName) const; + + SearchController *parent; + DAbstractFileInfoPointer currentFileInfo; + mutable QQueue childrens; + + DUrl m_fileUrl; + DUrl targetUrl; + QString keyword; + QRegularExpression regex; + QStringList m_nameFilters; + QDir::Filters m_filter; + QDirIterator::IteratorFlags m_flags; + mutable QList searchPathList; + mutable DDirIteratorPointer it; + mutable bool m_hasIteratorByKeywordOfCurrentIt = false; + +#ifndef DISABLE_QUICK_SEARCH + // 所有支持快速搜索的子目录(可包含待搜索目录本身) + QStringList hasLFTSubdirectories; + QDBusPendingCallWatcher *dbusWatcher = nullptr; +#endif + +#ifdef DISABLE_QUICK_SEARCH + // 所有支持快速搜索的子目录(可包含待搜索目录本身) + QStringList hasLFTSubdirectories; +// QDBusPendingCallWatcher *dbusWatcher = nullptr; +#endif + + bool closed = false; + mutable bool hasExecuteFullTextSearch = false;/*全文搜索状态判断,false表示搜索未开始,true表示搜索已经完成。全文搜索只运行一次就出结果,其他搜索需要多次运行*/ + mutable bool hasUpdateIndex = false; + mutable QMap> hiddenFileMap; // 隐藏文件信息 +}; + +SearchDiriterator::SearchDiriterator(const DUrl &url, const QStringList &nameFilters, + QDir::Filters filter, QDirIterator::IteratorFlags flags, + SearchController *parent) + : DDirIterator() + , parent(parent) + , m_fileUrl(url) + , targetUrl(url.searchTargetUrl()) + , keyword(DFMRegularExpression::checkWildcardAndToRegularExpression(url.searchKeyword())) + , m_nameFilters(nameFilters) + , m_filter(filter) + , m_flags(flags) +{ + regex = QRegularExpression(keyword, QRegularExpression::CaseInsensitiveOption); + searchPathList << targetUrl; + +#ifndef DISABLE_QUICK_SEARCH + if (targetUrl.isLocalFile()) { + QStorageInfo info(targetUrl.toLocalFile()); + + if (info.isValid()) { + ComDeepinAnythingInterface *interface = new ComDeepinAnythingInterface("com.deepin.anything", + "/com/deepin/anything", + QDBusConnection::systemBus()); + + dbusWatcher = new QDBusPendingCallWatcher(interface->hasLFTSubdirectories(info.rootPath())); + interface->setTimeout(3); + interface->setParent(dbusWatcher); + + // 先将列表设置为适用于任意目录, 等取到异步结果后再更新此值 + hasLFTSubdirectories.append("/"); + QObject::connect(dbusWatcher, &QDBusPendingCallWatcher::finished, + dbusWatcher, [this](QDBusPendingCallWatcher * call) { + QDBusPendingReply result = *call; + + hasLFTSubdirectories = result.value(); + dbusWatcher->deleteLater(); + dbusWatcher = nullptr; + }); + } + } +#endif + +#ifdef DISABLE_QUICK_SEARCH +// if (targetUrl.isLocalFile()) { +// QStorageInfo info(targetUrl.toLocalFile()); + +// if (info.isValid()) { +// ComDeepinAnythingInterface *interface = new ComDeepinAnythingInterface("com.deepin.anything", +// "/com/deepin/anything", +// QDBusConnection::systemBus()); + +// dbusWatcher = new QDBusPendingCallWatcher(interface->hasLFTSubdirectories(info.rootPath())); +// interface->setTimeout(3); +// interface->setParent(dbusWatcher); + + // 先将列表设置为适用于任意目录, 等取到异步结果后再更新此值 + hasLFTSubdirectories.append("/"); +// QObject::connect(dbusWatcher, &QDBusPendingCallWatcher::finished, +// dbusWatcher, [this] (QDBusPendingCallWatcher *call) { +// QDBusPendingReply result = *call; + +// hasLFTSubdirectories = result.value(); +// dbusWatcher->deleteLater(); +// dbusWatcher = nullptr; +// }); +// } +// } +#endif +} + +SearchDiriterator::~SearchDiriterator() +{ +#ifndef DISABLE_QUICK_SEARCH + if (dbusWatcher) { + dbusWatcher->deleteLater(); + } +#endif + +#ifdef DISABLE_QUICK_SEARCH + //FSEARCH CLOSE +#endif +} + +DUrl SearchDiriterator::next() +{ + if (!childrens.isEmpty()) { + const DUrl &url = childrens.dequeue(); + + currentFileInfo = DFileService::instance()->createFileInfo(parent, url); + + return url; + } + + return DUrl(); +} +#ifdef FULLTEXTSEARCH_ENABLE +// 全文搜索 +void SearchDiriterator::fullTextSearch(const QString &searchPath) const +{ + QStringList searchResult = DFMFullTextSearchManager::getInstance()->fullTextSearch(m_fileUrl.searchKeyword(), searchPath); + for (QString res : searchResult) { + if (DFMFullTextSearchManager::getInstance()->getSearchState() == JobController::Stoped) { + return; + } + // 隐藏文件不显示 + if (searchFileIsHidden(res)) { + continue; + } + + DUrl url = m_fileUrl; + DUrl realUrl = DUrl::fromUserInput(res); + // 回收站的文件右键菜单比较特殊,需要将文件url转换为回收站类型的URL + if (targetUrl.isTrashFile()) { + realUrl = DUrl::fromTrashFile(realUrl.toLocalFile().remove(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))); + } + // 如果是保险箱文件,则设置成保险箱文件路径 + if (VaultController::isVaultFile(res)) { + realUrl = VaultController::localToVault(res); + } + url.setSearchedFileUrl(realUrl); + + if (!childrens.contains(url)) { + // 修复bug-51754 增加条件判断,保险箱内的文件不能被检索到 + if (!VaultController::isVaultFile(targetUrl.toLocalFile()) && VaultController::isVaultFile(url.fragment())) { + continue; + } + childrens << url; + } + } +} + +#endif + +bool SearchDiriterator::searchFileIsHidden(const QString &fileName) const +{ + if (!targetUrl.isLocalFile()) + return false; + + auto searchPath = targetUrl.toLocalFile(); + if (!fileName.startsWith(searchPath) || fileName == searchPath) + return false; + + QFileInfo fileInfo(fileName); + if (fileInfo.isHidden()) + return true; + + QString fileParentPath = fileInfo.absolutePath(); + DFMFileListFile flf(fileParentPath); + + // 判断.hidden文件是否存在,不存在说明该路径下没有隐藏文件 + QFileInfo localHiddenFileInfo(flf.filePath()); + if (!localHiddenFileInfo.exists()) + return searchFileIsHidden(fileParentPath); + + if (hiddenFileMap[fileParentPath].isEmpty()) { + // 判断.hidden文件中的内容是否为空,空则表示该路径下没有隐藏文件 + auto hiddenFiles = flf.getHiddenFiles(); + if (!hiddenFiles.isEmpty()) { + hiddenFileMap[fileParentPath] = hiddenFiles; + } else { + return searchFileIsHidden(fileParentPath); + } + } + + return hiddenFileMap[fileParentPath].contains(fileInfo.fileName()) + ? true + : searchFileIsHidden(fileParentPath); +} + +bool SearchDiriterator::hasNext() const +{ + if (!childrens.isEmpty()) { + return true; + } +#ifdef FULLTEXTSEARCH_ENABLE + if (!hasExecuteFullTextSearch && DFMApplication::instance()->genericAttribute(DFMApplication::GA_IndexFullTextSearch).toBool()) { + DAbstractFileInfoPointer fileInfo = fileService->createFileInfo(nullptr, targetUrl); + if (fileInfo->isVirtualEntry()) { + hasExecuteFullTextSearch = true; + return true; + } + + QString searchPath = fileInfo->filePath(); + fullTextSearch(searchPath); + hasExecuteFullTextSearch = true; + } +#endif + forever { + if (closed) { + return false; + } + + if (!it) { + if (searchPathList.isEmpty()) { + break; + } + + const DUrl &url = searchPathList.takeAt(0); + + it = DFileService::instance()->createDirIterator(parent, url, m_nameFilters, QDir::NoDotAndDotDot | m_filter, m_flags); + + if (!it) { + continue; + } + + m_hasIteratorByKeywordOfCurrentIt = false; + +#ifndef DISABLE_QUICK_SEARCH + if (url.isLocalFile()) { // 针对本地文件, 先判断此目录是否是索引数据的子目录, 可以依此过滤掉很多目录, 减少对anything dbus接口的调用 + const QString &file = url.toLocalFile().append("/"); + + for (const QString &path : hasLFTSubdirectories) { + if (path == "/") { + m_hasIteratorByKeywordOfCurrentIt = true; + break; + } + + if (file.startsWith(path + "/")) { + m_hasIteratorByKeywordOfCurrentIt = true; + break; + } + } + + if (m_hasIteratorByKeywordOfCurrentIt) + m_hasIteratorByKeywordOfCurrentIt = it->enableIteratorByKeyword(m_fileUrl.searchKeyword()); + } else +#endif + { + m_hasIteratorByKeywordOfCurrentIt = it->enableIteratorByKeyword(m_fileUrl.searchKeyword()); + } + } + + while (it->hasNext()) { + if (closed) { + return false; + } + + it->next(); + + DAbstractFileInfoPointer fileInfo = it->fileInfo(); + // fix bug58348 搜索结果中存在本地不存在的文件 + if (!fileInfo || !fileInfo->exists()) { + continue; + } + + fileInfo->makeAbsolute(); + + //隐藏文件不支持索引和搜索 + // fileInfo->isHidden()判断是否为系统隐藏文件,searchFileIsHidden判断是否为文管设置的隐藏文件 + if (fileInfo->isHidden() || searchFileIsHidden(fileInfo->absoluteFilePath())) { + continue; + } + + if (m_hasIteratorByKeywordOfCurrentIt) { + DUrl url = m_fileUrl; + const DUrl &realUrl = fileInfo->fileUrl(); + + url.setSearchedFileUrl(realUrl); + if (!childrens.contains(url)) { + // 修复bug-51754 增加条件判断,保险箱内的文件不能被检索到 + if (!VaultController::isVaultFile(targetUrl.toLocalFile()) && VaultController::isVaultFile(url.fragment())) { + continue; + } + childrens << url; + } + + return true; + } + + if (fileInfo->isDir() && !fileInfo->isSymLink()) { + const DUrl &url = fileInfo->fileUrl(); + + if (!searchPathList.contains(url)) { + //系统文件中包含类型异常的目录,搜索访问目录会卡死,暂时做跳过处理 + if (!url.path().startsWith("/sys/")) + searchPathList << url; + } + } + + QRegularExpressionMatch match = regex.match(fileInfo->fileDisplayName()); + if (match.hasMatch()) { + DUrl url = m_fileUrl; + const DUrl &realUrl = fileInfo->fileUrl(); + +// qDebug() << "search matched url = " << realUrl.path() + "/" + realUrl.fileName(); + url.setSearchedFileUrl(realUrl); + if (!childrens.contains(url)) {/*去重*/ + // 修复bug-51754 增加条件判断,保险箱内的文件不能被检索到 + if (!VaultController::isVaultFile(targetUrl.toLocalFile()) && VaultController::isVaultFile(url.fragment())) { + continue; + } + childrens << url; + } + + return true; + } + } + + it.clear(); + } +#ifdef FULLTEXTSEARCH_ENABLE + if (!hasUpdateIndex && DFMApplication::instance()->genericAttribute(DFMApplication::GA_IndexFullTextSearch).toBool()) { + DAbstractFileInfoPointer fileInfo = fileService->createFileInfo(nullptr, targetUrl); + if (fileInfo->isVirtualEntry()) { + hasUpdateIndex = true; + return true; + } + + QString searchPath = fileInfo->filePath(); + if (DFMFullTextSearchManager::getInstance()->updateIndex(searchPath)) { + fullTextSearch(searchPath); + } + hasUpdateIndex = true; + if (childrens.isEmpty()) { + return false; + } + return true; + } +#endif + return false; +} + +QString SearchDiriterator::fileName() const +{ + return currentFileInfo ? currentFileInfo->fileName() : QString(); +} + +DUrl SearchDiriterator::fileUrl() const +{ + return currentFileInfo ? currentFileInfo->fileUrl() : DUrl(); +} + +const DAbstractFileInfoPointer SearchDiriterator::fileInfo() const +{ + return currentFileInfo; +} + +DUrl SearchDiriterator::url() const +{ + return m_fileUrl; +} + +void SearchDiriterator::close() +{ + closed = true; + if (it) + it->close(); +} + +SearchController::SearchController(QObject *parent) + : DAbstractFileController(parent) +{ + +} + +const DAbstractFileInfoPointer SearchController::createFileInfo(const QSharedPointer &event) const +{ + DUrl url = event->url().searchTargetUrl(); + + if (url.isSearchFile()) { + url.setSearchKeyword(event->url().searchKeyword()); + } else { + url = event->url(); + } + + return DAbstractFileInfoPointer(new SearchFileInfo(url)); +} + +bool SearchController::openFileLocation(const QSharedPointer &event) const +{ + return DFileService::instance()->openFileLocation(event->sender(), realUrl(event->url())); +} + +bool SearchController::openFile(const QSharedPointer &event) const +{ + return DFileService::instance()->openFile(event->sender(), realUrl(event->url())); +} + +bool SearchController::openFileByApp(const QSharedPointer &event) const +{ + return DFileService::instance()->openFileByApp(event->sender(), event->appName(), realUrl(event->url())); +} + +bool SearchController::openFilesByApp(const QSharedPointer &event) const +{ + return DFileService::instance()->openFilesByApp(event->sender(), event->appName(), realUrlList(event->urlList()), event->isEnter()); +} + +bool SearchController::writeFilesToClipboard(const QSharedPointer &event) const +{ + return DFileService::instance()->writeFilesToClipboard(event->sender(), event->action(), realUrlList(event->urlList())); +} + +DUrlList SearchController::moveToTrash(const QSharedPointer &event) const +{ + return DFileService::instance()->moveToTrash(event->sender(), realUrlList(event->urlList())); +} + +bool SearchController::restoreFile(const QSharedPointer &event) const +{ + return DFileService::instance()->restoreFile(event->sender(), realUrlList(event->urlList())); +} + +bool SearchController::deleteFiles(const QSharedPointer &event) const +{ + return DFileService::instance()->deleteFiles(event->sender(), realUrlList(event->urlList()), false, event->silent(), event->force()); +} + +bool SearchController::renameFile(const QSharedPointer &event) const +{ + return DFileService::instance()->renameFile(event->sender(), realUrl(event->fromUrl()), realUrl(event->toUrl())); +} + +bool SearchController::setPermissions(const QSharedPointer &event) const +{ + DUrl url = event->url(); + /*解决搜索状态下修改文件属性会修改到当前用户的属性*/ + if (!url.searchTargetUrl().isEmpty()) { + return DFileService::instance()->setPermissions(event->sender(), DUrl(url.fragment()), event->permissions()); + } + + return false; +} + +bool SearchController::compressFiles(const QSharedPointer &event) const +{ + return DFileService::instance()->compressFiles(event->sender(), realUrlList(event->urlList())); +} + +bool SearchController::decompressFile(const QSharedPointer &event) const +{ + return DFileService::instance()->decompressFile(event->sender(), realUrlList(event->urlList())); +} + +bool SearchController::addToBookmark(const QSharedPointer &event) const +{ + return DFileService::instance()->addToBookmark(event->sender(), realUrl(event->url())); +} + +bool SearchController::removeBookmark(const QSharedPointer &event) const +{ + return DFileService::instance()->removeBookmark(nullptr, realUrl(event->url())); +} + +bool SearchController::createSymlink(const QSharedPointer &event) const +{ + return DFileService::instance()->createSymlink(event->sender(), realUrl(event->fileUrl()), event->toUrl(), event->force()); +} + +bool SearchController::shareFolder(const QSharedPointer &event) const +{ + return DFileService::instance()->shareFolder(event->sender(), realUrl(event->url()), + event->name(), event->isWritable(), event->allowGuest()); +} + +bool SearchController::unShareFolder(const QSharedPointer &event) const +{ + return DFileService::instance()->unShareFolder(event->sender(), realUrl(event->url())); +} + +bool SearchController::openInTerminal(const QSharedPointer &event) const +{ + return DFileService::instance()->openInTerminal(event->sender(), realUrl(event->url())); +} + +const DDirIteratorPointer SearchController::createDirIterator(const QSharedPointer &event) const +{ + SearchDiriterator *diriterator = new SearchDiriterator(event->url(), event->nameFilters(), + event->filters(), event->flags(), + const_cast(this)); + + return DDirIteratorPointer(diriterator); +} + +DAbstractFileWatcher *SearchController::createFileWatcher(const QSharedPointer &event) const +{ + if (event->url().searchedFileUrl().isValid()) { + return nullptr; + } + + return new SearchFileWatcher(event->url()); +} + +bool SearchController::setFileTags(const QSharedPointer &event) const +{ + if (!event->url().searchedFileUrl().isValid()) { + return false; + } + + QList tags = event->tags(); + return fileService->setFileTags(this, event->url().searchedFileUrl(), tags); +} + +bool SearchController::removeTagsOfFile(const QSharedPointer &event) const +{ + if (!event->url().searchedFileUrl().isValid()) { + return false; + } + + return fileService->removeTagsOfFile(this, event->url().searchedFileUrl(), event->tags()); +} + +QList SearchController::getTagsThroughFiles(const QSharedPointer &event) const +{ + QList list = event->urlList(); + for (DUrl &item : list) { + item = item.searchedFileUrl(); + } + return fileService->getTagsThroughFiles(this, list); +} + +DUrl SearchController::realUrl(const DUrl &searchUrl) +{ + return searchUrl.searchedFileUrl(); +} + +DUrlList SearchController::realUrlList(const DUrlList &searchUrls) +{ + DUrlList list; + + for (const DUrl &url : searchUrls) { + list << realUrl(url); + } + + return list; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/searchcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/searchcontroller.h new file mode 100644 index 0000000..19e9351 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/searchcontroller.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef SEARCHCONTROLLER_H +#define SEARCHCONTROLLER_H + +#include "dabstractfilecontroller.h" + +#include +#include + +class SearchFileWatcher; +class SearchController : public DAbstractFileController +{ + Q_OBJECT + +public: + explicit SearchController(QObject *parent = nullptr); + + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + bool openFileLocation(const QSharedPointer &event) const override; + + bool openFile(const QSharedPointer &event) const override; + bool openFileByApp(const QSharedPointer &event) const override; + bool openFilesByApp(const QSharedPointer &event) const override; + bool writeFilesToClipboard(const QSharedPointer &event) const override; + DUrlList moveToTrash(const QSharedPointer &event) const override; + bool restoreFile(const QSharedPointer &event) const override; + bool deleteFiles(const QSharedPointer &event) const override; + bool renameFile(const QSharedPointer &event) const override; + + bool setPermissions(const QSharedPointer &event) const override; + + bool compressFiles(const QSharedPointer &event) const override; + bool decompressFile(const QSharedPointer &event) const override; + + bool addToBookmark(const QSharedPointer &event) const override; + bool removeBookmark(const QSharedPointer &event) const override; + bool createSymlink(const QSharedPointer &event) const override; + + bool shareFolder(const QSharedPointer &event) const override; + bool unShareFolder(const QSharedPointer &event) const override; + bool openInTerminal(const QSharedPointer &event) const override; + + const DDirIteratorPointer createDirIterator(const QSharedPointer &event) const override; + + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + + bool setFileTags(const QSharedPointer &event) const override; + bool removeTagsOfFile(const QSharedPointer &event) const override; + QList getTagsThroughFiles(const QSharedPointer &event) const override; + +private: + static DUrl realUrl(const DUrl &searchUrl); + static DUrlList realUrlList(const DUrlList &searchUrls); + + friend class SearchDiriterator; + friend class SearchFileWatcher; +}; + +#endif // SEARCHCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/searchhistroymanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/searchhistroymanager.cpp new file mode 100644 index 0000000..4a3ba07 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/searchhistroymanager.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "searchhistroymanager.h" +#include "dfmapplication.h" +#include "dfmsettings.h" + +DFM_USE_NAMESPACE + +SearchHistroyManager::SearchHistroyManager() +{ + +} + +SearchHistroyManager::~SearchHistroyManager() +{ + +} + +QStringList SearchHistroyManager::toStringList() +{ + return DFMApplication::appObtuselySetting()->value("Cache", "SearchHistroy").toStringList(); +} + +void SearchHistroyManager::writeIntoSearchHistory(QString keyword) +{ + if (keyword.isEmpty()) + return; + + QStringList list = toStringList(); + + list << keyword; + + DFMApplication::appObtuselySetting()->setValue("Cache", "SearchHistroy", list); +} + +bool SearchHistroyManager::removeSearchHistory(QString keyword) +{ + if (keyword.isEmpty()) + return false; + + bool ret = false; + QStringList list = toStringList(); + if (list.removeOne(keyword)) { + DFMApplication::appObtuselySetting()->setValue("Cache", "SearchHistroy", list); + ret = true; + } else { + qWarning() << keyword << "not exist in history"; + } + return ret; +} + +void SearchHistroyManager::clearHistory() +{ + QStringList list; + + DFMApplication::appObtuselySetting()->setValue("Cache", "SearchHistroy", list); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/searchhistroymanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/searchhistroymanager.h new file mode 100644 index 0000000..9695aef --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/searchhistroymanager.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef SEARCHHISTROYMANAGER_H +#define SEARCHHISTROYMANAGER_H + +#include + +class SearchHistroyManager +{ +public: + explicit SearchHistroyManager(); + ~SearchHistroyManager(); + + QStringList toStringList(); + + void writeIntoSearchHistory(QString keyword); + bool removeSearchHistory(QString keyword); + + void clearHistory(); +}; + +#endif // SEARCHHISTROYMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/sharecontroler.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/sharecontroler.cpp new file mode 100644 index 0000000..81b75a0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/sharecontroler.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "sharecontroler.h" +#include "models/sharefileinfo.h" +#include "dfileinfo.h" +#include "dabstractfilewatcher.h" +#include "usershare/shareinfo.h" +#include "usershare/usersharemanager.h" +#include "singleton.h" +#include "app/define.h" +#include "dfileservices.h" +#include "dfmevent.h" +#include "private/dabstractfilewatcher_p.h" + +class ShareFileWatcherPrivate; +class ShareFileWatcher : public DAbstractFileWatcher +{ +public: + explicit ShareFileWatcher(QObject *parent = nullptr); + +private slots: + void onUserShareAdded(const QString &filePath); + void onUserShareDeleted(const QString &filePath); + +private: + Q_DECLARE_PRIVATE(ShareFileWatcher) +}; + +class ShareFileWatcherPrivate : public DAbstractFileWatcherPrivate +{ +public: + explicit ShareFileWatcherPrivate(ShareFileWatcher *qq) + : DAbstractFileWatcherPrivate(qq) {} + + bool start() override; + bool stop() override; + + Q_DECLARE_PUBLIC(ShareFileWatcher) +}; + +ShareFileWatcher::ShareFileWatcher(QObject *parent) + : DAbstractFileWatcher(*new ShareFileWatcherPrivate(this), DUrl::fromUserShareFile("/"), parent) +{ + +} + +bool ShareFileWatcherPrivate::start() +{ + Q_Q(ShareFileWatcher); + + return q->connect(userShareManager, &UserShareManager::userShareAdded, q, &ShareFileWatcher::onUserShareAdded) + && q->connect(userShareManager, &UserShareManager::userShareDeleted, q, &ShareFileWatcher::onUserShareDeleted); +} + +bool ShareFileWatcherPrivate::stop() +{ + Q_Q(ShareFileWatcher); + + return q->disconnect(userShareManager, nullptr, q, nullptr); +} + +void ShareFileWatcher::onUserShareAdded(const QString &filePath) +{ + emit subfileCreated(DUrl::fromUserShareFile(filePath)); +} + +void ShareFileWatcher::onUserShareDeleted(const QString &filePath) +{ + emit fileDeleted(DUrl::fromUserShareFile(filePath)); +} + +ShareControler::ShareControler(QObject *parent) : + DAbstractFileController(parent) +{ + +} + +const DAbstractFileInfoPointer ShareControler::createFileInfo(const QSharedPointer &event) const +{ + return DAbstractFileInfoPointer(new ShareFileInfo(event->url())); +} + +const QList ShareControler::getChildren(const QSharedPointer &event) const +{ + Q_UNUSED(event) + + QList infolist; + + userShareManager->updateUserShareInfo(false); + + ShareInfoList sharelist = userShareManager->shareInfoList(); + foreach (ShareInfo shareInfo, sharelist) { + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(this, DUrl::fromUserShareFile(shareInfo.path())); + + if (fileInfo->exists()) + infolist << fileInfo; + } + + return infolist; +} + +DAbstractFileWatcher *ShareControler::createFileWatcher(const QSharedPointer &event) const +{ + if (event->url().path() != "/") + return nullptr; + + return new ShareFileWatcher(); +} + +bool ShareControler::openFile(const QSharedPointer &event) const +{ + // 需要将共享URL转换为普通url + const DUrl &fileUrl = realUrl(event->url()); + + if (!fileUrl.isValid()) + return false; + + return DFileService::instance()->openFile(event->sender(), fileUrl); +} + +bool ShareControler::setPermissions(const QSharedPointer &event) const +{ + // 需要将共享URL转换为普通url + const DUrl &fileUrl = realUrl(event->url()); + + if (!fileUrl.isValid()) + return false; + + return DFileService::instance()->setPermissions(event->sender(), fileUrl, event->permissions()); +} + +bool ShareControler::shareFolder(const QSharedPointer &event) const +{ + return DFileService::instance()->shareFolder(event->sender(), realUrl(event->url()), + event->name(), event->isWritable(), + event->allowGuest()); +} + +bool ShareControler::unShareFolder(const QSharedPointer &event) const +{ + return DFileService::instance()->unShareFolder(event->sender(), realUrl(event->url())); +} + +bool ShareControler::addToBookmark(const QSharedPointer &event) const +{ + return DFileService::instance()->addToBookmark(event->sender(), realUrl(event->url())); +} + +bool ShareControler::removeBookmark(const QSharedPointer &event) const +{ + return DFileService::instance()->removeBookmark(nullptr, realUrl(event->url())); +} + +DUrl ShareControler::realUrl(const DUrl &shareUrl) +{ + DUrl ret = shareUrl; + ret.setScheme(FILE_SCHEME); + return ret; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/sharecontroler.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/sharecontroler.h new file mode 100644 index 0000000..c9f10d6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/sharecontroler.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef SHARECONTROLER_H +#define SHARECONTROLER_H + +#include "dabstractfilecontroller.h" + +class ShareControler : public DAbstractFileController +{ + Q_OBJECT +public: + explicit ShareControler(QObject *parent = nullptr); + + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + const QList getChildren(const QSharedPointer &event) const override; + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + + // 文件打开接口 + bool openFile(const QSharedPointer &event) const override; + // 权限设置接口 + bool setPermissions(const QSharedPointer &event) const override; + bool shareFolder(const QSharedPointer &event) const override; + bool unShareFolder(const QSharedPointer &event) const override; + + bool addToBookmark(const QSharedPointer &event) const override; + bool removeBookmark(const QSharedPointer &event) const override; + +private: + static DUrl realUrl(const DUrl &shareUrl); +}; + +#endif // SHARECONTROLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/subscriber.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/subscriber.cpp new file mode 100644 index 0000000..316d0ac --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/subscriber.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * hujianzhong + * + * 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 + * 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 . + */ + +#include "subscriber.h" + + +Subscriber::Subscriber() +{ +} + +Subscriber::~Subscriber() +{ +} + +int Subscriber::eventKey() const +{ + return m_eventKey; +} + +void Subscriber::setEventKey(int eventKey) +{ + m_eventKey = eventKey; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/subscriber.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/subscriber.h new file mode 100644 index 0000000..14486b6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/subscriber.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef SUBSCRIBER_H +#define SUBSCRIBER_H + +class QString; + +class Subscriber +{ +public: + Subscriber(); + virtual ~Subscriber(); + + virtual void doSubscriberAction(const QString &path) = 0; + + int eventKey() const; + void setEventKey(int eventKey); + +private: + int m_eventKey = 0; +}; + +#endif // SUBSCRIBER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/tagcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/tagcontroller.cpp new file mode 100644 index 0000000..9113545 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/tagcontroller.cpp @@ -0,0 +1,598 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include + +#include "app/define.h" +#include "dfileservices.h" +#include "tagcontroller.h" +#include "tag/tagmanager.h" +#include "shutil/fileutils.h" +#include "../tag/tagmanager.h" +#include "dialogs/dialogmanager.h" +#include "../models/tagfileinfo.h" +#include "../interfaces/dfileinfo.h" +#include "interfaces/dfileservices.h" +#include "controllers/appcontroller.h" +#include "private/dabstractfilewatcher_p.h" +#include "controllers/tagmanagerdaemoncontroller.h" +#include "dfileproxywatcher.h" +#include "dstorageinfo.h" +#include + +#include "controllers/vaultcontroller.h" +#include "models/vaultfileinfo.h" + +template +using citerator = typename QList::const_iterator; + +template +using itetrator = typename QList::iterator; + +TagController::TagController(QObject* const parent) + :DAbstractFileController{ parent } +{ + //constructor! +} + +const DAbstractFileInfoPointer TagController::createFileInfo(const QSharedPointer& event) const +{ + //! 如过在标记中有保险箱的文件需要创建保险箱的fileinfo + if (!dynamic_cast(event->sender().data())) { + if(VaultController::isVaultFile(event->url().fragment())) { + return DAbstractFileInfoPointer(new VaultFileInfo(event->url())); + } + } + + DAbstractFileInfoPointer TaggedFilesInfo{ new TagFileInfo{ event->url() } }; + return TaggedFilesInfo; +} + +const QList TagController::getChildren(const QSharedPointer& event) const +{ + DUrl currentUrl{ event->url() }; + QList infoList; + + + if(currentUrl.isTaggedFile()){ + QString path{ currentUrl.path() }; + + if(path == QString{"/"}){ + QMap tags{ TagManager::instance()->getAllTags() }; + QMap::const_iterator tagBeg{ tags.cbegin() }; + QMap::const_iterator tagEnd{ tags.cend() }; + + for(; tagBeg != tagEnd; ++tagBeg){ + DUrl url = DUrl::fromUserTaggedFile(tagBeg.key(), QString{}); + DAbstractFileInfoPointer tagInfoPtr { + DFileService::instance()->createFileInfo(this, url) + }; + infoList.push_back(tagInfoPtr); + } + + } else if (currentUrl.taggedLocalFilePath().isEmpty()) { + QString tagName{ currentUrl.tagName() }; + QList files{ TagManager::instance()->getFilesThroughTag(tagName) }; + + for(const QString& localFilePath : files){ + DUrl url{ currentUrl }; + url.setTaggedFileUrl(localFilePath); + DAbstractFileInfoPointer fileInfo{ new TagFileInfo(url) }; + + infoList.push_back(fileInfo); + } + } + } + + return infoList; +} + +class TaggedFileWatcherPrivate; +class TaggedFileWatcher final : public DAbstractFileWatcher +{ +public: + explicit TaggedFileWatcher(const DUrl& url, QObject* const parent = nullptr); + void setEnabledSubfileWatcher(const DUrl &subfileUrl, bool enabled = true); + +private: + Q_DECLARE_PRIVATE(TaggedFileWatcher) + + void addWatcher(const DUrl& url) noexcept; + void removeWatcher(const DUrl& url) noexcept; +}; + + +class TaggedFileWatcherPrivate final : public DAbstractFileWatcherPrivate +{ +public: + explicit TaggedFileWatcherPrivate(TaggedFileWatcher* qq) + :DAbstractFileWatcherPrivate{qq}{} + + virtual bool start() override; + virtual bool stop() override; + + Q_DECLARE_PUBLIC(TaggedFileWatcher) + + DUrl m_urlBak{}; + QString m_beWatchedPath{}; + QMap m_watchers{}; +}; + + +TaggedFileWatcher::TaggedFileWatcher(const DUrl& url, QObject* const parent) + :DAbstractFileWatcher{*(new TaggedFileWatcherPrivate{this}), url, parent} +{ + TaggedFileWatcherPrivate* d{ d_func() }; + d->m_beWatchedPath = url.path(); + +#ifdef QT_DEBUG + qDebug()<< "watched url: " << url; + qDebug()<< "watched path: " << url.path(); +#endif + +} + +void TaggedFileWatcher::setEnabledSubfileWatcher(const DUrl& subfileUrl, bool enabled) +{ + DUrl currentWatchedDir{ this->fileUrl() }; + + if (subfileUrl == currentWatchedDir) + return; + + if (enabled) { + this->addWatcher(subfileUrl); + } else { + this->removeWatcher(subfileUrl); + } +} + +void TaggedFileWatcher::addWatcher(const DUrl& url)noexcept +{ + TaggedFileWatcherPrivate* d{ d_func() }; + DUrl local_file_url{ DUrl::fromLocalFile(url.taggedLocalFilePath()) }; + + if (!local_file_url.isValid() || d->m_watchers.contains(url)) + return; + + DAbstractFileWatcher* watcher{ DFileService::instance()->createFileWatcher(this, local_file_url) }; + + if(!watcher) + return; + + watcher->moveToThread(this->thread()); + watcher->setParent(this); + d->m_watchers[url] = watcher; + + auto urlConvert = [this] (const DUrl &localUrl) { + DUrl new_url = this->fileUrl(); + new_url.setTaggedFileUrl(localUrl.toLocalFile()); + + return new_url; + }; + + connect(watcher, &DAbstractFileWatcher::fileAttributeChanged, this, [this, urlConvert] (const DUrl &url) { + emit fileAttributeChanged(urlConvert(url)); + }); + + connect(watcher, &DAbstractFileWatcher::fileModified, this, [this, urlConvert] (const DUrl &url) { + emit fileModified(urlConvert(url)); + }); + + connect(watcher, &DAbstractFileWatcher::fileDeleted, this, [this, urlConvert] (const DUrl &url) { + emit fileDeleted(urlConvert(url)); + }); + + if(d->started) + watcher->startWatcher(); +} + +void TaggedFileWatcher::removeWatcher(const DUrl& url)noexcept +{ + TaggedFileWatcherPrivate* d{ d_func() }; + DAbstractFileWatcher *watcher = d->m_watchers.take(url); + + if (!watcher){ + return; + } + + watcher->deleteLater(); +} + + +bool TaggedFileWatcherPrivate::start() +{ +// TaggedFileWatcher* q{q_func()}; + + bool ok = true; + + for (DAbstractFileWatcher *watcher : m_watchers) { + ok = ok && watcher->startWatcher(); + } + + return ok; +} + +bool TaggedFileWatcherPrivate::stop() +{ + TaggedFileWatcher* q{q_func()}; + bool value{ QObject::disconnect(TagManager::instance(), nullptr, q, nullptr) }; + + for (DAbstractFileWatcher *watcher : m_watchers) { + value = value && watcher->stopWatcher(); + } + + return value; +} + + +DAbstractFileWatcher* TagController::createFileWatcher(const QSharedPointer& event) const +{ +#ifdef QT_DEBUG + qDebug()<< "be watched url: " << event->url(); +#endif + + if (!event->url().taggedLocalFilePath().isEmpty()) { + DAbstractFileWatcher *base_watcher = DFileService::instance()->createFileWatcher(event->sender(), DUrl::fromLocalFile(event->url().taggedLocalFilePath())); + const QString &tag_name = event->url().tagName(); + + auto urlConvertFun = [tag_name] (const DUrl &baseUrl) { + return DUrl::fromUserTaggedFile(tag_name, baseUrl.toLocalFile()); + }; + + return new DFileProxyWatcher(event->url(), base_watcher, urlConvertFun); + } + + return (new TaggedFileWatcher{event->url()}); +} + +static DUrl toLocalFile(const DUrl &url) +{ + const QString &local_file = url.taggedLocalFilePath(); + + if (local_file.isEmpty()) + return DUrl(); + + return DUrl::fromLocalFile(local_file); +} + +static DUrlList toLocalFileList(const DUrlList &tagFiles) +{ + DUrlList list; + + for (const DUrl &url : tagFiles) { + const DUrl &new_url = toLocalFile(url); + + if (new_url.isValid()) + list << new_url; + } + + return list; +} + +bool TagController::openFile(const QSharedPointer &event) const +{ + const DUrl &local_file = toLocalFile(event->url()); + + if (!local_file.isValid()) + return false; + + return DFileService::instance()->openFile(event->sender(), local_file); +} + +bool TagController::openFiles(const QSharedPointer &event) const +{ + DUrlList fileUrls = event->urlList(); + DUrlList packUrl; + QStringList pathList; + bool result = false; + + for (DUrl fileUrl : fileUrls) { + const DAbstractFileInfoPointer pfile = createFileInfo(dMakeEventPointer(this, fileUrl)); + + if (pfile->isSymLink()) { + const DAbstractFileInfoPointer &linkInfo = DFileService::instance()->createFileInfo(this, pfile->symLinkTarget()); + + if (linkInfo && !linkInfo->exists()) { + dialogManager->showBreakSymlinkDialog(linkInfo->fileName(), fileUrl); + continue; + } + fileUrl = linkInfo->redirectedFileUrl(); + } + + if (FileUtils::isExecutableScript(fileUrl.toLocalFile())) { + int code = dialogManager->showRunExcutableScriptDialog(fileUrl, event->windowId()); + result = FileUtils::openExcutableScriptFile(fileUrl.toLocalFile(), code) || result; + continue; + } + + if (FileUtils::isFileRunnable(fileUrl.toLocalFile()) && !pfile->isDesktopFile()) { + int code = dialogManager->showRunExcutableFileDialog(fileUrl, event->windowId()); + result = FileUtils::openExcutableFile(fileUrl.toLocalFile(), code) || result; + continue; + } + + if (FileUtils::shouldAskUserToAddExecutableFlag(fileUrl.toLocalFile()) && !pfile->isDesktopFile()) { + int code = dialogManager->showAskIfAddExcutableFlagAndRunDialog(fileUrl, event->windowId()); + result = FileUtils::addExecutableFlagAndExecuse(fileUrl.toLocalFile(), code) || result; + continue; + } + + packUrl << fileUrl; + QString url = fileUrl.toLocalFile(); + if (FileUtils::isFileWindowsUrlShortcut(url)) { + url = FileUtils::getInternetShortcutUrl(url); + } + pathList << url; + } + + if (!pathList.empty()) { + if (event->isEnter()) { + result = FileUtils::openEnterFiles(pathList); + } + else { + result = FileUtils::openFiles(pathList); + } + if (!result) { + for (const DUrl &fileUrl : packUrl) { + AppController::instance()->actionOpenWithCustom(dMakeEventPointer(event->sender(), fileUrl)); // requestShowOpenWithDialog + } + } + } + + return result; +} + +bool TagController::openFileByApp(const QSharedPointer &event) const +{ + const DUrl &local_file = toLocalFile(event->url()); + + if (!local_file.isValid()) + return false; + + return DFileService::instance()->openFileByApp(event->sender(), event->appName(), local_file); +} + +bool TagController::openFilesByApp(const QSharedPointer &event) const +{ + QList fileUrls; + + for (DUrl url: event->urlList()) { + const DUrl &localFile = toLocalFile(url); + + if (!localFile.isValid()) + continue; + + fileUrls << localFile; + } + + return DFileService::instance()->openFilesByApp(event->sender(), event->appName(), fileUrls); +} + +bool TagController::compressFiles(const QSharedPointer &event) const +{ + const DUrlList &list = toLocalFileList(event->fileUrlList()); + + if (list.isEmpty()) + return false; + + return DFileService::instance()->compressFiles(event->sender(), list); +} + +bool TagController::decompressFile(const QSharedPointer &event) const +{ + const DUrlList &list = toLocalFileList(event->fileUrlList()); + + if (list.isEmpty()) + return false; + + return DFileService::instance()->decompressFile(event->sender(), list); +} + +bool TagController::decompressFileHere(const QSharedPointer &event) const +{ + const DUrlList &list = toLocalFileList(event->fileUrlList()); + + if (list.isEmpty()) + return false; + + return DFileService::instance()->decompressFileHere(event->sender(), list); +} + +bool TagController::writeFilesToClipboard(const QSharedPointer &event) const +{ + const DUrlList &list = toLocalFileList(event->fileUrlList()); + + if (list.isEmpty()) + return false; + + return DFileService::instance()->writeFilesToClipboard(event->sender(), event->action(), list); +} + +bool TagController::renameFile(const QSharedPointer &event) const +{ + const QString &local_file = event->fromUrl().taggedLocalFilePath(); + + if (local_file.isEmpty()) { + const QString &old_name = event->fromUrl().tagName(); + const QString &new_name = event->toUrl().tagName(); + + return TagManager::instance()->changeTagName(qMakePair(old_name, new_name)); + } + + return DFileService::instance()->renameFile(event->sender(), DUrl::fromLocalFile(local_file), DUrl::fromLocalFile(event->toUrl().taggedLocalFilePath())); +} + +bool TagController::deleteFiles(const QSharedPointer &event) const +{ + QStringList tagNames; + DUrlList localFiles; + + for (auto oneUrl : event->urlList()) { + if (!oneUrl.taggedLocalFilePath().isEmpty()) { + localFiles << DUrl::fromLocalFile(oneUrl.taggedLocalFilePath()); + } else { + tagNames.append(oneUrl.fileName()); + } + } + + if (!localFiles.isEmpty()) { + return DFileService::instance()->deleteFiles(event->sender(), localFiles, false, event->silent(), event->force()); + } + + return TagManager::instance()->deleteTags(tagNames); +} + +DUrlList TagController::moveToTrash(const QSharedPointer &event) const +{ + const DUrlList &list = toLocalFileList(event->fileUrlList()); + + if (list.isEmpty()) + return list; + + return DFileService::instance()->moveToTrash(event->sender(), list); +} + +DUrlList TagController::pasteFile(const QSharedPointer &event) const +{ + DUrlList list; + + const DUrl &to_url = event->targetUrl(); + + if (!to_url.taggedLocalFilePath().isEmpty()) { + return DFileService::instance()->pasteFile(event->sender(), event->action(), DUrl::fromLocalFile(to_url.taggedLocalFilePath()), event->urlList()); + } + + if (to_url.tagName().isEmpty()) + return list; + + if (event->action() != DFMGlobal::CopyAction) { + return list; + } + + for (const DUrl &url : event->urlList()) { + if (DFileService::instance()->makeTagsOfFiles(event->sender(), {url}, {to_url.tagName()}, {"just for not clear exist tags...."})) { + list << url; + } + } + + return list; +} + +bool TagController::setPermissions(const QSharedPointer &event) const +{ + DUrl url = event->url(); + + if (!url.taggedLocalFilePath().isEmpty()) { + return DFileService::instance()->setPermissions(event->sender(), DUrl::fromLocalFile(url.taggedLocalFilePath()), event->permissions()); + } + + return false; +} + +bool TagController::openFileLocation(const QSharedPointer &event) const +{ + const DUrl &local_file = toLocalFile(event->url()); + + if (!local_file.isValid()) + return false; + + return DFileService::instance()->openFileLocation(event->sender(), local_file); +} + +bool TagController::addToBookmark(const QSharedPointer &event) const +{ + return DFileService::instance()->addToBookmark(event->sender(), DUrl::fromLocalFile(event->url().taggedLocalFilePath())); +} + +bool TagController::removeBookmark(const QSharedPointer &event) const +{ + DUrl destUrl = DUrl::fromLocalFile(event->url().taggedLocalFilePath()); + return DFileService::instance()->removeBookmark(nullptr, destUrl); +} + +bool TagController::createSymlink(const QSharedPointer &event) const +{ + const DUrl &local_file = toLocalFile(event->fileUrl()); + + if (!local_file.isValid()) + return false; + + return DFileService::instance()->createSymlink(event->sender(), local_file, event->toUrl()); +} + +bool TagController::shareFolder(const QSharedPointer &event) const +{ + const DUrl &local_file = toLocalFile(event->url()); + + if (!local_file.isValid()) + return false; + + return DFileService::instance()->shareFolder(event->sender(), local_file, event->name(), event->isWritable(), event->allowGuest()); +} + +bool TagController::unShareFolder(const QSharedPointer &event) const +{ + const DUrl &local_file = toLocalFile(event->url()); + + if (!local_file.isValid()) + return false; + + return DFileService::instance()->unShareFolder(event->sender(), local_file); +} + +bool TagController::openInTerminal(const QSharedPointer &event) const +{ + const DUrl &local_file = toLocalFile(event->url()); + + if (!local_file.isValid()) + return false; + + return DFileService::instance()->openInTerminal(event->sender(), local_file); +} + +bool TagController::setFileTags(const QSharedPointer &event) const +{ + QList tags = event->tags(); + return DFileService::instance()->setFileTags(this, DUrl::fromLocalFile(event->url().taggedLocalFilePath()), tags); +} + +bool TagController::removeTagsOfFile(const QSharedPointer &event) const +{ + QList tags = event->tags(); + return DFileService::instance()->removeTagsOfFile(this, DUrl::fromLocalFile(event->url().taggedLocalFilePath()), tags); +} + +QList TagController::getTagsThroughFiles(const QSharedPointer &event) const +{ + DUrlList new_list; + + for (const DUrl &tag_url : event->urlList()) { + const QString &file = tag_url.taggedLocalFilePath(); + + if (!file.isEmpty()) + new_list << DUrl::fromLocalFile(file); + } + + return DFileService::instance()->getTagsThroughFiles(this, new_list); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/tagcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/tagcontroller.h new file mode 100644 index 0000000..946e772 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/tagcontroller.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef TAGCONTROLLER_H +#define TAGCONTROLLER_H + + +#include "dabstractfilecontroller.h" + +class TagController : public DAbstractFileController +{ + Q_OBJECT + +public: + explicit TagController(QObject* const parent = nullptr); + ~TagController()=default; + + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer& event) const override; + const QList getChildren(const QSharedPointer &event) const override; + + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + + bool openFile(const QSharedPointer &event) const override; + bool openFiles(const QSharedPointer &event) const override; + bool openFileByApp(const QSharedPointer &event) const override; + bool openFilesByApp(const QSharedPointer &event) const override; + bool compressFiles(const QSharedPointer &event) const override; + bool decompressFile(const QSharedPointer &event) const override; + bool decompressFileHere(const QSharedPointer &event) const override; + bool writeFilesToClipboard(const QSharedPointer &event) const override; + bool renameFile(const QSharedPointer &event) const override; + bool deleteFiles(const QSharedPointer &event) const override; + DUrlList moveToTrash(const QSharedPointer &event) const override; + DUrlList pasteFile(const QSharedPointer &event) const override; + + bool setPermissions(const QSharedPointer &event) const override; + + bool openFileLocation(const QSharedPointer &event) const override; + bool addToBookmark(const QSharedPointer &event) const override; + bool removeBookmark(const QSharedPointer &event) const override; + bool createSymlink(const QSharedPointer &event) const override; + bool shareFolder(const QSharedPointer &event) const override; + bool unShareFolder(const QSharedPointer &event) const override; + bool openInTerminal(const QSharedPointer &event) const override; + + bool setFileTags(const QSharedPointer &event) const override; + bool removeTagsOfFile(const QSharedPointer &event) const override; + QList getTagsThroughFiles(const QSharedPointer &event) const override; +}; + + +#endif // TAGCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/tagmanagerdaemoncontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/tagmanagerdaemoncontroller.cpp new file mode 100644 index 0000000..863b2e5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/tagmanagerdaemoncontroller.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include + +#include "tagmanagerdaemoncontroller.h" + +#include + +static constexpr const char *const service{ "com.deepin.filemanager.daemon" }; +static constexpr const char *const path{ "/com/deepin/filemanager/daemon/TagManagerDaemon" }; + +std::atomic flagForLockingBackend{ false }; + +TagManagerDaemonController::TagManagerDaemonController(QObject *const parent) + : QObject{ parent } + , m_daemonInterface{ nullptr} +{ + m_daemonInterface = std::unique_ptr { new TagManagerDaemonInterface { + service, + path, + QDBusConnection::systemBus() + } + }; + + // blumia: since it's associated with context menu so we need to set a shorter timeout time. + m_daemonInterface->setTimeout(3000); + + this->init_connect(); +} + +TagManagerDaemonController *TagManagerDaemonController::instance() +{ + static TagManagerDaemonController *the_instance{ new TagManagerDaemonController }; + return the_instance; +} + +void TagManagerDaemonController::onAddNewTags(const QDBusVariant &new_tags) +{ + emit addNewTags(new_tags.variant()); +} + +void TagManagerDaemonController::onChangeTagColor(const QVariantMap &old_and_new_color) +{ + emit changeTagColor(old_and_new_color); +} + +void TagManagerDaemonController::onChangeTagName(const QVariantMap &old_and_new_name) +{ + emit changeTagName(old_and_new_name); +} + +void TagManagerDaemonController::onDeleteTags(const QDBusVariant &be_deleted_tags) +{ + emit deleteTags(be_deleted_tags.variant()); +} + +void TagManagerDaemonController::onFilesWereTagged(const QVariantMap &files_were_tagged) +{ + emit filesWereTagged(files_were_tagged); +} + +void TagManagerDaemonController::onUntagFiles(const QVariantMap &tag_be_removed_files) +{ + emit untagFiles(tag_be_removed_files); +} + +void TagManagerDaemonController::init_connect()noexcept +{ + if (m_daemonInterface) { + QObject::connect(m_daemonInterface.get(), &TagManagerDaemonInterface::addNewTags, this, &TagManagerDaemonController::onAddNewTags); + QObject::connect(m_daemonInterface.get(), &TagManagerDaemonInterface::deleteTags, this, &TagManagerDaemonController::onDeleteTags); + QObject::connect(m_daemonInterface.get(), &TagManagerDaemonInterface::changeTagColor, this, &TagManagerDaemonController::onChangeTagColor); + QObject::connect(m_daemonInterface.get(), &TagManagerDaemonInterface::changeTagName, this, &TagManagerDaemonController::onChangeTagName); + QObject::connect(m_daemonInterface.get(), &TagManagerDaemonInterface::filesWereTagged, this, &TagManagerDaemonController::onFilesWereTagged); + QObject::connect(m_daemonInterface.get(), &TagManagerDaemonInterface::untagFiles, this, &TagManagerDaemonController::onUntagFiles); + } +} + +QVariant TagManagerDaemonController::disposeClientData(const QVariantMap &filesAndTags, Tag::ActionType type) +{ + QDBusVariant var{ m_daemonInterface->disposeClientData(filesAndTags, static_cast(type)) }; + QVariant variant{ var.variant() }; + QDBusArgument argument{ variant.value() }; + QDBusArgument::ElementType current_type{ argument.currentType() }; + QMap var_map{}; + + if (current_type == QDBusArgument::ElementType::MapType) { + argument >> var_map; + variant.setValue(var_map); + } + + return variant; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/tagmanagerdaemoncontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/tagmanagerdaemoncontroller.h new file mode 100644 index 0000000..84643ba --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/tagmanagerdaemoncontroller.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef TAGMANAGERDAEMONCONTROLLER_H +#define TAGMANAGERDAEMONCONTROLLER_H + +#include + + +#include "tag/tagutil.h" +#include "./interface/tagmanagerdaemon_interface.h" + +#include +#include + +class TagManagerDaemonController final : public QObject +{ + Q_OBJECT +public: + virtual ~TagManagerDaemonController()=default; + explicit TagManagerDaemonController(QObject* const parent = nullptr); + TagManagerDaemonController(const TagManagerDaemonController& other)=delete; + TagManagerDaemonController& operator=(const TagManagerDaemonController& other)=delete; + + QVariant disposeClientData(const QVariantMap& filesAndTags, Tag::ActionType type); + + static TagManagerDaemonController* instance(); + +signals: + void addNewTags(const QVariant& new_tags); + void changeTagColor(const QVariantMap& old_and_new_color); + void changeTagName(const QVariantMap& old_and_new_name); + void deleteTags(const QVariant& be_deleted_tags); + void filesWereTagged(const QVariantMap& files_were_tagged); + void untagFiles(const QVariantMap& tag_be_removed_files); + + +private slots: + void onAddNewTags(const QDBusVariant &new_tags); + void onChangeTagColor(const QVariantMap& old_and_new_color); + void onChangeTagName(const QVariantMap& old_and_new_name); + void onDeleteTags(const QDBusVariant& be_deleted_tags); + void onFilesWereTagged(const QVariantMap& files_were_tagged); + void onUntagFiles(const QVariantMap& tag_be_removed_files); + +private: + + void init_connect()noexcept; + + std::unique_ptr m_daemonInterface{ nullptr }; +}; + +#endif // TAGMANAGERDAEMONCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/trashjobcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/trashjobcontroller.cpp new file mode 100644 index 0000000..50d9661 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/trashjobcontroller.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "trashjobcontroller.h" +#include "app/global.h" +#include "dialogs/cleartrashdialog.h" + +TrashJobController::TrashJobController(QObject *parent) : QObject(parent) +{ + initConnect(); +} + +void TrashJobController::initConnect(){ + +} + +void TrashJobController::asyncRequestTrashCount(){ + +} + +void TrashJobController::setTrashEmptyFlag(bool flag){ + m_isTrashEmpty = flag; +} + +void TrashJobController::trashJobExcute(const QStringList &files){ + qDebug() << files; +// QDBusPendingReply reply = dbusController->getFileOperationsInterface()->NewTrashJob( +// files, +// false, +// ConflictAdaptor::staticServerPath(), +// m_conflictController->getObjectPath(), +// ConflictAdaptor::staticInterfaceName() +// ); +//// QDBusPendingReply reply = dbusController->getFileOperationsInterface()->NewTrashJob( +//// files, +//// false, +//// "", +//// "", +//// "" +//// ); +// reply.waitForFinished(); +// if (!reply.isError()){ +// QString service = reply.argumentAt(0).toString(); +// QString path = qdbus_cast(reply.argumentAt(1)).path(); +// m_trashJobInterface = new TrashJobInterface(service, path, QDBusConnection::sessionBus(), this); +// connectTrashSignal(); +// m_trashJobInterface->Execute(); +// }else{ +// qCritical() << reply.error().message() << files; +// } +} + +void TrashJobController::connectTrashSignal(){ + +} + +void TrashJobController::disconnectTrashSignal(){ + +} + +void TrashJobController::trashJobExcuteFinished(){ + + qDebug() << "trash files deleted"; +} + + +void TrashJobController::trashJobAbort(){ + +} + +void TrashJobController::trashJobAbortFinished(){ + +} + +void TrashJobController::onTrashingFile(QString /*file*/){ + +} + +void TrashJobController::onDeletingFile(QString /*file*/){ + +} + +void TrashJobController::onProcessAmount(qlonglong /*progress*/, ushort /*info*/){ + +} + +void TrashJobController::updateTrashIconByCount(uint /*count*/){ +// if (count == 0){ +// if (!m_isTrashEmpty){ +// dbusController->asyncRequestTrashIcon(); +// } +// m_isTrashEmpty = true; +// }else{ +// if (m_isTrashEmpty){ +// dbusController->asyncRequestTrashIcon(); +// } +// m_isTrashEmpty = false; +// } +} + + +void TrashJobController::confirmDelete(){ + +} + +void TrashJobController::handleTrashAction(int index){ + switch (index) { + case 0: + return; + break; + case 1: + createEmptyTrashJob(); + break; + default: + break; + } +} + +void TrashJobController::createEmptyTrashJob(){ +// QDBusPendingReply reply = dbusController->getFileOperationsInterface()->NewEmptyTrashJob(false, "", "", ""); +// reply.waitForFinished(); +// if (!reply.isError()){ +// QString service = reply.argumentAt(0).toString(); +// QString path = qdbus_cast(reply.argumentAt(1)).path(); +// m_emptyTrashJobInterface = new EmptyTrashJobInterface(service, path, QDBusConnection::sessionBus(), this); +// connect(m_emptyTrashJobInterface, SIGNAL(Done()), this, SLOT(emptyTrashJobExcuteFinished())); +// m_emptyTrashJobInterface->Execute(); +// }else{ +// qCritical() << reply.error().message(); +// } +} + +void TrashJobController::emptyTrashJobExcuteFinished(){ + +} + +TrashJobController::~TrashJobController() +{ + +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/trashjobcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/trashjobcontroller.h new file mode 100644 index 0000000..ccb03d4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/trashjobcontroller.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef TRASHJOBCONTROLLER_H +#define TRASHJOBCONTROLLER_H + +#include +#include + +class TrashMonitorInterface; +class TrashJobInterface; +class EmptyTrashJobInterface; +class FileConflictController; + +class TrashJobController : public QObject +{ + Q_OBJECT +public: + explicit TrashJobController(QObject *parent = 0); + ~TrashJobController(); + + void initConnect(); + +signals: + +public slots: + void setTrashEmptyFlag(bool flag); + void connectTrashSignal(); + void disconnectTrashSignal(); + void trashJobExcute(const QStringList& files); + void trashJobExcuteFinished(); + void trashJobAbort(); + void trashJobAbortFinished(); + void onTrashingFile(QString file); + void onDeletingFile(QString file); + void onProcessAmount(qlonglong progress, ushort info); + void updateTrashIconByCount(uint count); + + void confirmDelete(); + void handleTrashAction(int index); + void createEmptyTrashJob(); + void emptyTrashJobExcuteFinished(); + + void asyncRequestTrashCount(); + +private: + TrashMonitorInterface* m_trashMonitorInterface=NULL; + TrashJobInterface* m_trashJobInterface = NULL; + EmptyTrashJobInterface* m_emptyTrashJobInterface = NULL; + FileConflictController* m_conflictController = NULL; + bool m_isTrashEmpty = true; +}; + +#endif // TRASHJOBCONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/trashmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/trashmanager.cpp new file mode 100644 index 0000000..8c68cbf --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/trashmanager.cpp @@ -0,0 +1,487 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "trashmanager.h" +#include "dfileservices.h" +#include "dfilewatcher.h" +#include "dfileproxywatcher.h" +#include "dfileinfo.h" +#include "models/trashfileinfo.h" + +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "dfmevent.h" + +#include "interfaces/dfmstandardpaths.h" +#include "singleton.h" +#include "shutil/dfmfilelistfile.h" + +#include "dfmeventdispatcher.h" + +#include +#include +#include +#include +#include + +#include +#include "app/define.h" +#include "singleton.h" +#include "dialogs/dialogmanager.h" +#include "dialogs/dtaskdialog.h" + +#include "models/trashfileinfo.h" + +namespace FileSortFunction { +//! 定义根据路径排序函数 +COMPARE_FUN_DEFINE(sourceFilePath, TrashFilePath, TrashFileInfo) +} + +static bool kWorking = false; // tmp +class TrashDirIterator : public DDirIterator +{ +public: + TrashDirIterator(const DUrl &url, + const QStringList &nameFilters, + QDir::Filters filter, + QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags); + ~TrashDirIterator() override; + + DUrl next() override; + bool hasNext() const override; + + QString fileName() const override; + DUrl fileUrl() const override; + const DAbstractFileInfoPointer fileInfo() const override; + DUrl url() const override; + + DFMFileListFile *hiddenFiles = nullptr; +private: + QDirIterator *iterator; + bool nextIsCached = false; + QDir::Filters filters; +}; + +TrashDirIterator::TrashDirIterator(const DUrl &url, const QStringList &nameFilters, + QDir::Filters filter, QDirIterator::IteratorFlags flags) + : DDirIterator() + , filters(filter) +{ + QString path = DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath) + url.path(); + iterator = new QDirIterator(path, nameFilters, filter, flags); + + hiddenFiles = new DFMFileListFile(path); +} + +TrashDirIterator::~TrashDirIterator() +{ + if (iterator) { + delete iterator; + } + + if (hiddenFiles) { + delete hiddenFiles; + } +} + +DUrl TrashDirIterator::next() +{ + if (nextIsCached) { + nextIsCached = false; + + QString path = iterator->filePath(); + return DUrl::fromTrashFile(path.remove(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))); + } + return DUrl::fromTrashFile(DUrl::fromLocalFile(iterator->next()).path().remove(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))); +} + +bool TrashDirIterator::hasNext() const +{ + if (nextIsCached) { + return true; + } + + bool hasNext = iterator->hasNext(); + + if (!hasNext) { + return false; + } + + bool showHidden = filters.testFlag(QDir::Hidden); + DAbstractFileInfoPointer info; + + do { + const_cast(this)->iterator->next(); + QString absoluteFilePath = iterator->fileInfo().absoluteFilePath(); + info = DAbstractFileInfoPointer(new TrashFileInfo(DUrl::fromLocalFile(absoluteFilePath))); + + if (!info->isPrivate() && (showHidden || (!info->isHidden() && !hiddenFiles->contains(info->fileName())))) { + break; + } + + info.reset(); + } while (iterator->hasNext()); + + // file is exists + if (info) { + const_cast(this)->nextIsCached = true; + + return true; + } + + return false; +// return iterator->hasNext(); +} + +QString TrashDirIterator::fileName() const +{ + return iterator->fileName(); +} + +DUrl TrashDirIterator::fileUrl() const +{ + return DUrl::fromTrashFile(iterator->filePath().remove(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))); +} + +const DAbstractFileInfoPointer TrashDirIterator::fileInfo() const +{ + return DFileService::instance()->createFileInfo(Q_NULLPTR, fileUrl()); +} + +DUrl TrashDirIterator::url() const +{ + return DUrl::fromTrashFile(iterator->path().remove(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))); +} + +TrashManager::TrashManager(QObject *parent) + : DAbstractFileController(parent) + , m_trashFileWatcher(new DFileWatcher(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath), this)) +{ + m_isTrashEmpty = isEmpty(); + QString trashFilePath = DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath); + //make sure trash file exists + if (!QFile::exists(trashFilePath)) + QDir().mkdir(trashFilePath); + + connect(m_trashFileWatcher, &DFileWatcher::fileDeleted, this, &TrashManager::trashFilesChanged); + connect(m_trashFileWatcher, &DFileWatcher::subfileCreated, this, &TrashManager::trashFilesChanged); + m_trashFileWatcher->startWatcher(); +} + +const DAbstractFileInfoPointer TrashManager::createFileInfo(const QSharedPointer &event) const +{ + return DAbstractFileInfoPointer(new TrashFileInfo(event->url())); +} + +bool TrashManager::openFile(const QSharedPointer &event) const +{ + // fix bug#41297 回收站的文件夹预览,点击打开,应该不能弹出提示框 + // 判断url为文件夹则不弹出提示框,新开一个文管打开 + DUrl fileUrl = event->url(); + QFileInfo fileInfo(fileUrl.toLocalFile()); + if (fileInfo.isFile()) { + QString strMsg = tr("Unable to open items in the trash, please restore it first"); + dialogManager->showMessageDialog(DialogManager::msgWarn, strMsg); + return false; + } + + // 预览打开文件夹 + return DFileService::instance()->openFile(event->sender(), DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath) + event->url().path())); +} + +bool TrashManager::openFiles(const QSharedPointer &event) const +{ + Q_UNUSED(event) + + QString strMsg = tr("Unable to open items in the trash, please restore it first"); + dialogManager->showMessageDialog(DialogManager::msgWarn, strMsg); + return false; +} + +DUrlList TrashManager::moveToTrash(const QSharedPointer &event) const +{ + fileService->deleteFiles(event->sender(), event->urlList(), true, false, true); + + return DUrlList(); +} + +void TrashManager::sortByOriginPath(DUrlList &list) const +{ + DAbstractFileInfo::CompareFunction sortFun = FileSortFunction::compareFileListByTrashFilePath; + qSort(list.begin(), list.end(), [sortFun, this](const DUrl url1, const DUrl url2) { + const auto &&event1 = dMakeEventPointer(this, url1); + const auto &&event2 = dMakeEventPointer(this, url2); + return sortFun(TrashManager::createFileInfo(event1), TrashManager::createFileInfo(event2), Qt::AscendingOrder); + }); +} + +bool TrashManager::restoreFile(const QSharedPointer &event) const +{ + ::kWorking = true; + DUrlList originUrls; + DUrlList urlList = event->urlList(); + //如果是全部还原操作 需要先遍历trash根目录下的所有目录 + if (urlList.size() == 1 && DUrl::fromTrashFile("/") == urlList.first()) { + urlList.clear(); + // fix bug#33763 回收站内的隐藏文件应该被找出来进行还原 + for (const DAbstractFileInfoPointer &info : DFileService::instance()->getChildren(Q_NULLPTR, DUrl::fromTrashFile("/"), QStringList(), QDir::AllEntries | QDir::NoDotAndDotDot | QDir::System | QDir::Hidden)) + urlList << info->fileUrl(); + } + + //! fix bug#36608 按照原始路径排序,避免恢复时冲突 + sortByOriginPath(urlList); + + bool ok = restoreTrashFile(urlList, &originUrls); + + if (ok && !originUrls.isEmpty()) { + DFMEventDispatcher::instance()->processEvent(event, dMakeEventPointer(nullptr, originUrls)); + } + ::kWorking = false; + return ok; +} + +bool TrashManager::writeFilesToClipboard(const QSharedPointer &event) const +{ + if (event->action() != DFMGlobal::CopyAction && + // 取消对剪切操作的屏蔽 + event->action() != DFMGlobal::CutAction) { + event->ignore(); + return false; + } + + DUrlList localList; + + for (const DUrl &url : event->urlList()) { + const QString &path = url.path(); + + localList << DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath) + path); + + // blumia: shouldn't do this since we are just copy file out. It's okay if the file name is a hashed name. + // use the restore function provided by right click menu to perform restore behavior, not copy-paste. +// if(path.lastIndexOf('/') > 0) { +// localList << DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::TrashInfosPath) + path); +// } + } + + return fileService->writeFilesToClipboard(event->sender(), event->action(), localList); +} + +DUrlList TrashManager::pasteFile(const QSharedPointer &event) const +{ + if (event->action() != DFMGlobal::CutAction || event->targetUrl() != DUrl::fromTrashFile("/")) { + return DUrlList(); + } + + if (event->urlList().isEmpty()) + return DUrlList(); + + return fileService->moveToTrash(event->sender(), event->urlList()); +} + + +bool TrashManager::deleteFiles(const QSharedPointer &event) const +{ + DUrlList localList; + + for (const DUrl &url : event->urlList()) { + if (DUrl::fromTrashFile("/") == url) { + cleanTrash(event->sender(), event->silent()); + return true; + } + + const QString &path = url.path(); + + localList << DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath) + path); + + if (path.lastIndexOf('/') == 0) { + localList << DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::TrashInfosPath) + path + ".trashinfo"); + } + } + + fileService->deleteFiles(event->sender(), localList, false, event->silent(), true); + + return true; +} + +const DDirIteratorPointer TrashManager::createDirIterator(const QSharedPointer &event) const +{ + return DDirIteratorPointer(new TrashDirIterator(event->url(), event->nameFilters(), event->filters(), event->flags())); +} + +namespace TrashManagerPrivate { +DUrl localToTrash(const DUrl &url) +{ + const QString &localPath = url.toLocalFile(); + const QString &trashPath = DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath); + + if (!localPath.startsWith(trashPath)) + return DUrl(); + + DUrl u = DUrl::fromTrashFile(localPath.mid(trashPath.length())); + + if (u.path().isEmpty()) + u.setPath("/"); + + return u; +} +QString trashToLocal(const DUrl &url) +{ + return DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath) + url.path(); +} +} + +DAbstractFileWatcher *TrashManager::createFileWatcher(const QSharedPointer &event) const +{ + return new DFileProxyWatcher(event->url(), + new DFileWatcher(TrashManagerPrivate::trashToLocal(event->url())), + TrashManagerPrivate::localToTrash); +} + +bool TrashManager::restoreTrashFile(const DUrlList &list, DUrlList *restoreOriginUrls) +{ + bool ok = true; + if (list.size() == 0) + return true; + + DUrlList restoreFailedList; + DUrlList restoreFailedSourceNotExist; + DUrlList restoreFileOriginUrlList; + + DUrlList urlist; + QStringList pathlist; + for (const DUrl &url : list) { + QString jid = dialogManager->getJobIdByUrl(url); + if (jid.isEmpty() && !urlist.contains(url)) { + urlist << url; + pathlist << url.toLocalFile(); + } else { + qDebug() << "restore filejob url was existed " << url; + } + } + + if (urlist.size() == 0) { + DTaskDialog *dlg = dialogManager->taskDialog(); + if (dlg && dlg->getTaskListWidget() && dlg->getTaskListWidget()->count() > 0) { + dlg->raise(); + } + return true; // job already existed + } + + QSharedPointer job(new FileJob(FileJob::Restore)); + job->setProperty("pathlist", pathlist); + job->setManualRemoveJob(true); + dialogManager->addJob(job); + job->jobPrepared(); + + int i = 0; + int total = urlist.size(); + for (const DUrl &url : urlist) { + ++i; + job->setRestoreProgress(double(i) / total); + //###(zccrs): 必须通过 DAbstractFileInfoPointer 使用 + // 因为对象会被缓存,所以有可能在其它线程中被使用 + // 如果直接定义一个TrashFileInfo对象,就可能存在对象被重复释放 + QExplicitlySharedDataPointer info(new TrashFileInfo(url)); + + bool ret = info->restore(job); + if (!job->getIsApplyToAll()) { + job->resetCustomChoice(); // if not apply to all we should reset button state + } + + if (!ret && info->exists()) { + restoreFailedList << info->fileUrl(); + } else if (!ret && !info->exists()) { + restoreFailedSourceNotExist << info->fileUrl(); + } else { + //! 存储最终的文件路径 + restoreFileOriginUrlList << DUrl::fromLocalFile(job->getTargetDir()); + } + + ok = ok && ret; + } + job->setRestoreProgress(0); + emit job->finished(); + + if (!ok && restoreFailedList.count() > 0) { + emit fileSignalManager->requestShowRestoreFailedDialog(restoreFailedList); + } + + if (!ok && restoreFailedSourceNotExist.count() > 0) { + emit fileSignalManager->requestShowRestoreFailedSourceNotExist(restoreFailedSourceNotExist); + } + + if (restoreOriginUrls) + *restoreOriginUrls = restoreFileOriginUrlList; + + job->jobRemoved(); + dialogManager->removeJob(job->getJobId()); + //job->deleteLater(); + return ok; +} + +void TrashManager::cleanTrash(const QObject *sender, bool silent) const +{ + DUrlList list; + const DUrl &file_url = DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath)); + const DUrl &info_url = DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::TrashInfosPath)); + + if (QFile::exists(file_url.toLocalFile())) { + list << file_url; + } + bool ret = fileService->deleteFiles(sender, list, false, silent, true); + + // 清空回收站意味着回收站所有文件都被删除,因此直接删除info的目录即可 + if (ret) { + QString infoPaht = info_url.toLocalFile(); + QProcess::execute("rm -r \"" + infoPaht.toUtf8() + "\""); + } +} + +bool TrashManager::isEmpty() +{ + QDir dir(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath)); + + if (!dir.exists()) + return true; + + dir.setFilter(QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot); + + QDirIterator iterator(dir); + + return !iterator.hasNext(); +} + +bool TrashManager::isWorking() +{ + return ::kWorking; +} + +void TrashManager::trashFilesChanged(const DUrl &url) +{ + Q_UNUSED(url); + if (m_isTrashEmpty == isEmpty()) + return; + + m_isTrashEmpty = isEmpty(); + emit fileSignalManager->trashStateChanged(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/trashmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/trashmanager.h new file mode 100644 index 0000000..37e2def --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/trashmanager.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef TRASHMANAGER_H +#define TRASHMANAGER_H + +#include "dabstractfilecontroller.h" + +#include +#include +#include +#include + +class DAbstractFileInfo; +class FileMonitor; +class DFileWatcher; + +class TrashManager : public DAbstractFileController +{ + Q_OBJECT + +public: + explicit TrashManager(QObject *parent = nullptr); + + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + + bool openFile(const QSharedPointer &event) const override; + //! 多文件打开入口 + bool openFiles(const QSharedPointer &event) const override; + DUrlList moveToTrash(const QSharedPointer &event) const override; + /** + * @brief sortByOriginPath 根据原始路径对list进行排序 + * @param list + */ + void sortByOriginPath(DUrlList &list) const; + bool restoreFile(const QSharedPointer &event) const override; + bool writeFilesToClipboard(const QSharedPointer &event) const override; + DUrlList pasteFile(const QSharedPointer &event) const override; + bool deleteFiles(const QSharedPointer &event) const override; + const DDirIteratorPointer createDirIterator(const QSharedPointer &event) const override; + + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + + static bool restoreTrashFile(const DUrlList &list, DUrlList *restoreOriginUrls = nullptr); + void cleanTrash(const QObject *sender = nullptr, bool silent = false) const; + + static bool isEmpty(); + static bool isWorking(); +public slots: + void trashFilesChanged(const DUrl &url); +private: + bool m_isTrashEmpty; + DFileWatcher *m_trashFileWatcher; +}; + +#endif // TRASHMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaultcontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaultcontroller.cpp new file mode 100644 index 0000000..6dfd714 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaultcontroller.cpp @@ -0,0 +1,1433 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "vaultcontroller.h" +#include "models/vaultfileinfo.h" +#include "dfileservices.h" +#include "dfilewatcher.h" +#include "dfileproxywatcher.h" +#include "vaulthandle.h" +#include "vaulterrorcode.h" +#include "dfmeventdispatcher.h" +#include "dfilestatisticsjob.h" +#include "log/dfmLogManager.h" +#include "log/filterAppender.h" +#include "vaultconfig.h" +#include "../vault/operatorcenter.h" +#include "../vault/vaulthelper.h" +#include "dfmapplication.h" + +#include "appcontroller.h" +#include "singleton.h" +#include "dstorageinfo.h" +#include "models/desktopfileinfo.h" + +#include "tag/tagmanager.h" +#include "shutil/fileutils.h" +#include "shutil/dfmfilelistfile.h" +#include "usershare/shareinfo.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "usershare/usersharemanager.h" +#include "dialogs/dialogmanager.h" +#include "dialogs/dtaskdialog.h" + +#include "dfmevent.h" +#include "../vault/vaultglobaldefine.h" +#include "dbusinterface/vaultbruteforceprevention_interface.h" + +#include +#include +#include +#include +#include +#include + +#include + +VaultController *VaultController::cryfs = nullptr; +bool VaultController::m_isBigFileDeleting = false; + +class VaultControllerPrivate +{ +public: + explicit VaultControllerPrivate(VaultController *cryFs); + ~VaultControllerPrivate(); + + CryFsHandle *m_cryFsHandle = nullptr; + +private: + VaultController *q_ptr; + Q_DECLARE_PUBLIC(VaultController) +}; + +VaultControllerPrivate::VaultControllerPrivate(VaultController *cryFs) + : q_ptr(cryFs) +{ +} + +VaultControllerPrivate::~VaultControllerPrivate() +{ + if (m_cryFsHandle) { + delete m_cryFsHandle; + m_cryFsHandle = nullptr; + } +} + +class VaultDirIterator : public DDirIterator +{ +public: + VaultDirIterator(const DUrl &url, + const QStringList &nameFilters, + QDir::Filters filter, + QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags); + ~VaultDirIterator() override; + + DUrl next() override; + bool hasNext() const override; + + QString fileName() const override; + DUrl fileUrl() const override; + const DAbstractFileInfoPointer fileInfo() const override; + DUrl url() const override; + +private: + QDir::Filters filters; + DFMFileListFile *hiddenFiles = nullptr; + QDirIterator *iterator; + bool nextIsCached = false; +}; + +VaultDirIterator::VaultDirIterator(const DUrl &url, const QStringList &nameFilters, + QDir::Filters filter, QDirIterator::IteratorFlags flags) + : DDirIterator(), filters(filter) +{ + QString path = VaultController::vaultToLocal(url); + iterator = new QDirIterator(path, nameFilters, filter, flags); + + hiddenFiles = new DFMFileListFile(path); +} + +VaultDirIterator::~VaultDirIterator() +{ + if (iterator) { + delete iterator; + } + + if (hiddenFiles) { + delete hiddenFiles; + } +} + +DUrl VaultDirIterator::next() +{ + if (nextIsCached) { + nextIsCached = false; + + QString path = iterator->filePath(); + DUrl url = VaultController::localToVault(path); + VaultController::ins()->updateFileInfo(DUrlList() << url); + return url; + } + + DUrl url = VaultController::localToVault(iterator->next()); + VaultController::ins()->updateFileInfo(DUrlList() << url); + return url; +} + +// 添加过滤,将保险箱中.hidden中记录的文件隐藏 +bool VaultDirIterator::hasNext() const +{ + if (nextIsCached) { + return true; + } + + bool hasNext = iterator->hasNext(); + + if (!hasNext) { + return false; + } + + bool showHidden = filters.testFlag(QDir::Hidden); + DAbstractFileInfoPointer info; + + do { + const_cast(this)->iterator->next(); + QString absoluteFilePath = iterator->fileInfo().absoluteFilePath(); + info = DAbstractFileInfoPointer(new VaultFileInfo(DUrl::fromLocalFile(absoluteFilePath))); + + if (!info->isPrivate() && (showHidden || (!info->isHidden() && !hiddenFiles->contains(info->fileName())))) { + break; + } + + info.reset(); + } while (iterator->hasNext()); + + // file is exists + if (info) { + const_cast(this)->nextIsCached = true; + + return true; + } + + return false; +} + +QString VaultDirIterator::fileName() const +{ + return iterator->fileName(); +} + +DUrl VaultDirIterator::fileUrl() const +{ + return VaultController::localToVault(iterator->filePath()); +} + +const DAbstractFileInfoPointer VaultDirIterator::fileInfo() const +{ + return DFileService::instance()->createFileInfo(nullptr, fileUrl()); +} + +DUrl VaultDirIterator::url() const +{ + return fileUrl(); +} + +VaultController::VaultController(QObject *parent) + : DAbstractFileController(parent), + d_ptr(new VaultControllerPrivate(this)), + m_recordVaultPageMark(VaultPageMark::UNKNOWN), + m_vaultVisiable(true) +{ + Q_D(VaultController); + + //! 屏蔽保险箱内的文件信息写入到日志文件 + DFMLogManager::getFilterAppender()->addFilter(VAULT_DECRYPT_DIR_NAME); + + d->m_cryFsHandle = new CryFsHandle(); + + connect(this, &VaultController::sigCreateVault, d->m_cryFsHandle, &CryFsHandle::createVault); + connect(this, &VaultController::sigUnlockVault, d->m_cryFsHandle, &CryFsHandle::unlockVault); + connect(this, &VaultController::sigLockVault, d->m_cryFsHandle, &CryFsHandle::lockVault); + + // 创建保险箱,关联信号 + connect(d->m_cryFsHandle, &CryFsHandle::signalCreateVault, this, &VaultController::slotCreateVault); + connect(d->m_cryFsHandle, &CryFsHandle::signalUnlockVault, this, &VaultController::slotUnlockVault); + connect(d->m_cryFsHandle, &CryFsHandle::signalLockVault, this, &VaultController::slotLockVault); + connect(d->m_cryFsHandle, &CryFsHandle::signalReadError, this, &VaultController::signalReadError); + connect(d->m_cryFsHandle, &CryFsHandle::signalReadOutput, this, &VaultController::signalReadOutput); + connect(this, &VaultController::sigFinishedCopyFile, this, &VaultController::slotFinishedCopyFileTotalSize); + + // Get root dir size. + m_sizeWorker = new DFileStatisticsJob(this); + + slotFinishedCopyFileTotalSize(); + + connect(m_sizeWorker, &DFileStatisticsJob::dataNotify, this, &VaultController::updateFolderSizeLabel); + + // Refresh size when lock state changed. + connect(this, &VaultController::signalUnlockVault, this, &VaultController::refreshTotalSize); + connect(this, &VaultController::signalLockVault, this, &VaultController::refreshTotalSize); + + // 保险箱大小计算线程结束后,再次计算一次大小 + connect(m_sizeWorker, &QThread::finished, this, &VaultController::onFinishCalcSize); + + // 初始化时,记录保险箱状态 + m_enVaultState = state(); + + DTaskDialog *pTaskDlg = dialogManager->taskDialog(); + if (pTaskDlg) { + connect(pTaskDlg, &DTaskDialog::paused, this, &VaultController::taskPaused); + } + + m_vaultInterface = new VaultBruteForcePreventionInterface("com.deepin.filemanager.daemon", + "/com/deepin/filemanager/daemon/VaultManager2", + QDBusConnection::systemBus(), + this); + + slotVaultPolicy(); + + QDBusConnection::systemBus().connect("com.deepin.filemanager.daemon", + "/com/deepin/filemanager/daemon/AccessControlManager", + "com.deepin.filemanager.daemon.AccessControlManager", + "AccessVaultPolicyNotify", + this, + SLOT(slotVaultPolicy())); +} + +VaultController *VaultController::ins() +{ + if (!cryfs) { + DUrl url(DFMVAULT_ROOT); + url.setScheme(DFMVAULT_SCHEME); + QList vaultObjlist = DFileService::getHandlerTypeByUrl(url); + if (vaultObjlist.size() > 0) + cryfs = static_cast(vaultObjlist.first()); + } + return cryfs; +} + +const DAbstractFileInfoPointer VaultController::createFileInfo(const QSharedPointer &event) const +{ + DUrl url(makeVaultUrl()); + + if (url == event->url()) { + return DAbstractFileInfoPointer(new VaultFileInfo(makeVaultUrl(makeVaultLocalPath()))); + } + + //! 在保险箱中判断是否有桌面专属文件 + url = event->url(); + QString localFile = url.toLocalFile(); + QFileInfo info(localFile); + + if (!info.isSymLink() && FileUtils::isDesktopFile(localFile)) { + //! 创建桌面文件信息 + return DAbstractFileInfoPointer(new DesktopFileInfo(event->url())); + } + + const_cast(this)->updateFileInfo(DUrlList() << event->url()); + return DAbstractFileInfoPointer(new VaultFileInfo(event->url())); +} + +const DDirIteratorPointer VaultController::createDirIterator(const QSharedPointer &event) const +{ + DUrl url = event->url(); + if (event->url() == makeVaultUrl()) { + url = makeVaultUrl(makeVaultLocalPath()); + } + return DDirIteratorPointer(new VaultDirIterator(url, event->nameFilters(), event->filters(), event->flags())); +} + +DAbstractFileWatcher *VaultController::createFileWatcher(const QSharedPointer &event) const +{ + QString urlPath = event->url().toLocalFile(); + if (urlPath.isEmpty()) return nullptr; + + DUrl url = makeVaultUrl(urlPath); + auto watcher = new DFileProxyWatcher(url, + new DFileWatcher(urlPath), + VaultController::localUrlToVault); + + connect(watcher, &DFileProxyWatcher::fileDeleted, this, &VaultController::refreshTotalSize); + connect(watcher, &DFileProxyWatcher::subfileCreated, this, &VaultController::refreshTotalSize); + connect(watcher, &DFileProxyWatcher::fileMoved, this, &VaultController::refreshTotalSize); + connect(watcher, &DFileProxyWatcher::fileAttributeChanged, this, &VaultController::refreshTotalSize); + + return watcher; +} + +bool VaultController::openFile(const QSharedPointer &event) const +{ + return DFileService::instance()->openFile(event->sender(), vaultToLocalUrl(event->url())); +} + +bool VaultController::openFiles(const QSharedPointer &event) const +{ + // return DFileService::instance()->openFiles(event->sender(), vaultToLocalUrls(event->urlList())); + DUrlList fileUrls = event->urlList(); + DUrlList packUrl; + QStringList pathList; + bool result = false; + + for (DUrl fileUrl : fileUrls) { + const DAbstractFileInfoPointer pfile = createFileInfo(dMakeEventPointer(this, fileUrl)); + + if (pfile->isSymLink()) { + const DAbstractFileInfoPointer &linkInfo = DFileService::instance()->createFileInfo(this, pfile->symLinkTarget()); + + if (linkInfo && !linkInfo->exists()) { + dialogManager->showBreakSymlinkDialog(linkInfo->fileName(), fileUrl); + continue; + } + fileUrl = linkInfo->redirectedFileUrl(); + } + + if (FileUtils::isExecutableScript(fileUrl.toLocalFile())) { + int code = dialogManager->showRunExcutableScriptDialog(fileUrl, event->windowId()); + result = FileUtils::openExcutableScriptFile(fileUrl.toLocalFile(), code) || result; + continue; + } + + if (FileUtils::isFileRunnable(fileUrl.toLocalFile()) && !pfile->isDesktopFile()) { + int code = dialogManager->showRunExcutableFileDialog(fileUrl, event->windowId()); + result = FileUtils::openExcutableFile(fileUrl.toLocalFile(), code) || result; + continue; + } + + if (FileUtils::shouldAskUserToAddExecutableFlag(fileUrl.toLocalFile()) && !pfile->isDesktopFile()) { + int code = dialogManager->showAskIfAddExcutableFlagAndRunDialog(fileUrl, event->windowId()); + result = FileUtils::addExecutableFlagAndExecuse(fileUrl.toLocalFile(), code) || result; + continue; + } + + packUrl << fileUrl; + QString url = vaultToLocal(fileUrl); + if (FileUtils::isFileWindowsUrlShortcut(url)) { + url = FileUtils::getInternetShortcutUrl(url); + } + pathList << url; + } + + if (!pathList.empty()) { + if (event->isEnter()) { + result = FileUtils::openEnterFiles(pathList); + } else { + result = FileUtils::openFiles(pathList); + } + if (!result) { + for (const DUrl &fileUrl : packUrl) { + AppController::instance()->actionOpenWithCustom(dMakeEventPointer(event->sender(), fileUrl)); // requestShowOpenWithDialog + } + } + } + + return result; +} + +bool VaultController::openFileByApp(const QSharedPointer &event) const +{ + //处理快捷方式,还原成原路径 + DUrl fileUrl = event->url(); + + const DAbstractFileInfoPointer pfile = createFileInfo(dMakeEventPointer(this, fileUrl)); + + if (pfile->isSymLink()) { + const DAbstractFileInfoPointer &linkInfo = DFileService::instance()->createFileInfo(this, pfile->symLinkTarget()); + if (!linkInfo.data()) + return false; + + if (!linkInfo->exists()) { + dialogManager->showBreakSymlinkDialog(linkInfo->fileName(), fileUrl); + return false; + } + const_cast(fileUrl) = linkInfo->redirectedFileUrl(); + } + return DFileService::instance()->openFileByApp(event->sender(), event->appName(), vaultToLocalUrl(fileUrl)); +} + +bool VaultController::openFilesByApp(const QSharedPointer &event) const +{ + //处理快捷方式,还原成原路径 + QList fileUrls = event->urlList(); + + QStringList pathList; + + for (DUrl fileUrl : fileUrls) { + const DAbstractFileInfoPointer pfile = createFileInfo(dMakeEventPointer(this, fileUrl)); + + if (pfile->isSymLink()) { + const DAbstractFileInfoPointer &linkInfo = DFileService::instance()->createFileInfo(this, pfile->symLinkTarget()); + + if (linkInfo && !linkInfo->exists()) { + dialogManager->showBreakSymlinkDialog(linkInfo->fileName(), fileUrl); + continue; + } + fileUrl = linkInfo->redirectedFileUrl(); + } + QString url = fileUrl.toLocalFile(); + if (FileUtils::isFileWindowsUrlShortcut(url)) { + url = FileUtils::getInternetShortcutUrl(url); + } + pathList << url; + } + + return FileUtils::openFilesByApp(event->appName(), pathList); +} + +bool VaultController::deleteFiles(const QSharedPointer &event) const +{ + const_cast(this)->slotFinishedCopyFileTotalSize(); + + const_cast(this)->setVauleCurrentPageMark(VaultPageMark::DELETEFILEPAGE); + DUrlList urlList = vaultToLocalUrls(event->urlList()); + bool bDeletedSuccess = DFileService::instance()->deleteFiles(event->sender(), urlList, true, event->silent()); + if (bDeletedSuccess) { + const_cast(this)->updateFileInfo(urlList); + } + // 修复bug-89733 保险箱删除2个及以上的大文件时,删除完成后,界面不刷新 + // 删除两个及以上的大文件时,刷新操作非常卡顿,所以不在刷新,并且模态弹框(与产品沟通后的做法) + // 这就导致了上述bug的产生,此处修改,增加判断,如果是此种情况,删除完成后,刷新一次界面 + if (m_isBigFileDeleting) + emit fileSignalManager->requestFreshAllFileView(); + m_isBigFileDeleting = false; + return true; +} + +DUrlList VaultController::moveToTrash(const QSharedPointer &event) const +{ + const_cast(this)->slotFinishedCopyFileTotalSize(); + const_cast(this)->setVauleCurrentPageMark(VaultPageMark::DELETEFILEPAGE); + DUrlList urlList = vaultToLocalUrls(event->urlList()); + bool bDeletedSuccess = DFileService::instance()->deleteFiles(event->sender(), urlList); + if (bDeletedSuccess) { + const_cast(this)->updateFileInfo(urlList); + } + // 修复bug-89733 保险箱删除2个及以上的大文件时,删除完成后,界面不刷新 + // 删除两个及以上的大文件时,刷新操作非常卡顿,所以不在刷新,并且模态弹框(与产品沟通后的做法) + // 这就导致了上述bug的产生,此处修改,增加判断,如果是此种情况,删除完成后,刷新一次界面 + if (m_isBigFileDeleting) + emit fileSignalManager->requestFreshAllFileView(); + m_isBigFileDeleting = false; + return urlList; +} + +DUrlList VaultController::pasteFile(const QSharedPointer &event) const +{ + const_cast(this)->slotFinishedCopyFileTotalSize(); + const_cast(this)->setVauleCurrentPageMark(VaultPageMark::COPYFILEPAGE); + DUrlList urlList = vaultToLocalUrls(event->urlList()); + DUrl url = vaultToLocalUrl(event->targetUrl()); + DUrlList ulist = DFileService::instance()->pasteFile(event->sender(), event->action(), url, urlList); + return ulist; +} + +bool VaultController::writeFilesToClipboard(const QSharedPointer &event) const +{ + const_cast(this)->slotFinishedCopyFileTotalSize(); + const_cast(this)->setVauleCurrentPageMark(VaultPageMark::CLIPBOARDPAGE); + DUrlList urlList = vaultToLocalUrls(event->urlList()); + return DFileService::instance()->writeFilesToClipboard(event->sender(), event->action(), urlList); +} + +bool VaultController::renameFile(const QSharedPointer &event) const +{ + bool flg = DFileService::instance()->renameFile(event->sender(), + vaultToLocalUrl(event->fromUrl()), + vaultToLocalUrl(event->toUrl())); + if (flg) { + const_cast(this)->updateFileInfo(DUrlList() << event->fromUrl()); + } + return flg; +} + +bool VaultController::openInTerminal(const QSharedPointer &event) const +{ + const QString ¤t_dir = QDir::currentPath(); + + QDir::setCurrent(vaultToLocalUrl(event->url()).toLocalFile()); + + bool ok = QProcess::startDetached(FileUtils::defaultTerminalPath()); + + QDir::setCurrent(current_dir); + + return ok; +} + +bool VaultController::addToBookmark(const QSharedPointer &event) const +{ + DUrl destUrl = event->url(); + + const DAbstractFileInfoPointer &p = fileService->createFileInfo(nullptr, destUrl); + DUrl bookmarkUrl = DUrl::fromBookMarkFile(destUrl, p->fileDisplayName()); + DStorageInfo info(destUrl.path()); + QString filePath = destUrl.path(); + QString rootPath = info.rootPath(); + if (rootPath != QStringLiteral("/") || rootPath != QStringLiteral("/home")) { + QString devStr = info.device(); + QString locateUrl; + int endPos = filePath.indexOf(rootPath); + if (endPos != -1) { + endPos += rootPath.length(); + locateUrl = filePath.mid(endPos); + } + if (devStr.startsWith(QStringLiteral("/dev/"))) { + devStr = DUrl::fromDeviceId(info.device()).toString(); + } + + QUrlQuery query; + query.addQueryItem("mount_point", devStr); + query.addQueryItem("locate_url", locateUrl); + bookmarkUrl.setQuery(query); + } + + return DFileService::instance()->touchFile(event->sender(), bookmarkUrl); +} + +bool VaultController::removeBookmark(const QSharedPointer &event) const +{ + return DFileService::instance()->deleteFiles(nullptr, { DUrl::fromBookMarkFile(event->url(), QString()) }, false); +} + +bool VaultController::createSymlink(const QSharedPointer &event) const +{ + QString path = vaultToLocalUrl(event->fileUrl()).path(); + QFile file(path); + + QUrl url = event->toUrl().toLocalFile(); + + bool ok = file.link(event->toUrl().toLocalFile()); + + if (ok) { + return true; + } + + if (event->force()) { + // replace symlink, remove if target was existed + QFileInfo toLink(event->toUrl().toLocalFile()); + if (toLink.isSymLink() || toLink.exists()) { + QFile::remove(event->toUrl().toLocalFile()); + } + } + + int code = ::symlink(event->fileUrl().toLocalFile().toLocal8Bit().constData(), + event->toUrl().toLocalFile().toLocal8Bit().constData()); + if (code == -1) { + ok = false; + QString errorString = strerror(errno); + dialogManager->showFailToCreateSymlinkDialog(errorString); + } else { + ok = true; + } + + return ok; +} + +bool VaultController::setFileTags(const QSharedPointer &event) const +{ + DUrl url = event->url(); + DUrl durl = vaultToLocalUrl(url); + QList taglist = event->tags(); + if (taglist.isEmpty()) { + const QStringList &tags = TagManager::instance()->getTagsThroughFiles({ durl }); + + return tags.isEmpty() || TagManager::instance()->removeTagsOfFiles(tags, { durl }); + } + + return TagManager::instance()->makeFilesTags(taglist, { durl }); +} + +bool VaultController::removeTagsOfFile(const QSharedPointer &event) const +{ + DUrl url = event->url(); + DUrl durl = vaultToLocalUrl(url); + QList taglist = event->tags(); + return TagManager::instance()->removeTagsOfFiles(taglist, { durl }); +} + +QList VaultController::getTagsThroughFiles(const QSharedPointer &event) const +{ + DUrlList urllist = event->urlList(); + DUrlList tempList = vaultToLocalUrls(urllist); + return TagManager::instance()->getTagsThroughFiles(tempList); +} + +bool VaultController::setPermissions(const QSharedPointer &event) const +{ + DUrl url = event->url(); + DUrl durl = vaultToLocalUrl(url); + bool flg = DFileService::instance()->setPermissions(event->sender(), durl, event->permissions()); + if (flg) { + const_cast(this)->updateFileInfo(DUrlList() << url); + } + + return flg; +} + +void VaultController::updateFileInfo(const DUrlList &fileUrls) +{ + static QMutex mutex; + mutex.lock(); + for (const auto &url : fileUrls) { + QFileInfo fileInfo(url.path()); + if (!fileInfo.exists()) { + m_mapVaultFileInfo.remove(url); + + //当文件删除时,删除隐藏文件集中的隐藏 + QString absort = url.path().left(url.path().length() - url.fileName().length()); + DFMFileListFile flf(absort); + if (flf.contains(url.fileName())) { + flf.remove(url.fileName()); + flf.save(); + } + } else { + if (!m_mapVaultFileInfo.contains(url)) { + FileBaseInfo fbi; + fbi.isExist = true; + fbi.isDir = fileInfo.isDir(); + fbi.isFile = fileInfo.isFile(); + fbi.isSymLink = fileInfo.isSymLink(); + m_mapVaultFileInfo.insert(url, fbi); + } else { + m_mapVaultFileInfo[url].isDir = fileInfo.isDir(); + m_mapVaultFileInfo[url].isFile = fileInfo.isFile(); + m_mapVaultFileInfo[url].isSymLink = fileInfo.isSymLink(); + } + } + } + mutex.unlock(); +} + +VaultController::FileBaseInfo VaultController::getFileInfo(const DUrl &fileUrl) +{ + if (m_mapVaultFileInfo.contains(fileUrl)) { + return m_mapVaultFileInfo[fileUrl]; + } + + return FileBaseInfo(); +} + +DUrl VaultController::makeVaultUrl(QString path, QString host) +{ + Q_UNUSED(host) + // blumia: if path is not start with a `/`, QUrl::setPath will destory the whole QUrl + // and only leave the path to the QUrl. + if (!path.startsWith('/')) { + path = '/' + path; + } + + DUrl newUrl; + newUrl.setScheme(DFMVAULT_SCHEME); + newUrl.setHost(host); + newUrl.setPath(path); + return newUrl; +} + +DUrl VaultController::localUrlToVault(const DUrl &vaultUrl) +{ + return VaultController::localToVault(vaultUrl.path()); +} + +DUrl VaultController::localToVault(QString localPath) +{ + if (isVaultFile(localPath)) { + return VaultController::makeVaultUrl(localPath); + } else { + return DUrl(); + } +} + +QString VaultController::vaultToLocal(const DUrl &vaultUrl) +{ + if (vaultUrl.scheme() == DFMVAULT_SCHEME) { + if (vaultUrl == makeVaultUrl("/")) + return makeVaultLocalPath(vaultUrl.path()); + else { + return vaultUrl.toLocalFile(); + } + } + + return vaultUrl.toLocalFile(); +} + +DUrl VaultController::vaultToLocalUrl(const DUrl &vaultUrl) +{ + if (vaultUrl.scheme() != DFMVAULT_SCHEME) return vaultUrl; + return DUrl::fromLocalFile(vaultToLocal(vaultUrl)); +} + +DUrlList VaultController::vaultToLocalUrls(DUrlList vaultUrls) +{ + std::transform(vaultUrls.begin(), vaultUrls.end(), vaultUrls.begin(), [](const DUrl &url) { + return vaultToLocalUrl(url); + }); + + return vaultUrls; +} + +VaultController::VaultState VaultController::state(QString lockBaseDir) +{ + QString cryfsBinary = QStandardPaths::findExecutable("cryfs"); + if (cryfsBinary.isEmpty()) { + // 记录保险箱状态 + m_enVaultState = NotAvailable; + return NotAvailable; + } + + if (lockBaseDir.isEmpty()) { + lockBaseDir = makeVaultLocalPath("cryfs.config", VAULT_ENCRYPY_DIR_NAME); + } else { + if (lockBaseDir.endsWith("/")) + lockBaseDir += "cryfs.config"; + else + lockBaseDir += "/cryfs.config"; + } + if (QFile::exists(lockBaseDir)) { + QStorageInfo info(makeVaultLocalPath("")); + QString temp = info.fileSystemType(); + if (info.isValid() && temp == "fuse.cryfs") { + m_enVaultState = Unlocked; + return Unlocked; + } + m_enVaultState = Encrypted; + return Encrypted; + } else { + m_enVaultState = NotExisted; + return NotExisted; + } +} + +bool VaultController::isRootDirectory(QString path) +{ + bool bRootDir = false; + QString localFilePath = makeVaultLocalPath(); + QString pathNoSplash = localFilePath; + pathNoSplash.chop(1); + if (localFilePath == path || makeVaultUrl().toString() == path + || pathNoSplash == path) { + bRootDir = true; + } + return bRootDir; +} + +QString VaultController::getErrorInfo(int state) +{ + QString strErr(""); + switch (state) { + case 10: + strErr = "The command line arguments are invalid."; + break; + case 11: + strErr = "Couldn't load config file. Probably the password is wrong"; + break; + case 12: + strErr = "Password cannot be empty"; + break; + case 13: + strErr = "The file system format is too new for this CryFS version. Please update your CryFS version."; + break; + case 14: + strErr = "The file system format is too old for this CryFS version. Run with --allow-filesystem-upgrade to upgrade it."; + break; + case 15: + strErr = "The file system uses a different cipher than the one specified on the command line using the --cipher argument."; + break; + case 16: + strErr = "Base directory doesn't exist or is inaccessible (i.e. not read or writable or not a directory)"; + break; + case 17: + strErr = "Mount directory doesn't exist or is inaccessible (i.e. not read or writable or not a directory)"; + break; + case 18: + strErr = "Base directory can't be a subdirectory of the mount directory"; + break; + case 19: + strErr = "Something's wrong with the file system."; + break; + case 20: + strErr = "The filesystem id in the config file is different to the last time we loaded a filesystem from this basedir. This could mean an attacker replaced the file system with a different one. You can pass the --allow-replaced-filesystem option to allow this."; + break; + case 21: + strErr = "The filesystem encryption key differs from the last time we loaded this filesystem. This could mean an attacker replaced the file system with a different one. You can pass the --allow-replaced-filesystem option to allow this."; + break; + case 22: + strErr = "The command line options and the file system disagree on whether missing blocks should be treated as integrity violations."; + break; + case 23: + strErr = "File system is in single-client mode and can only be used from the client that created it."; + break; + case 24: + strErr = "A previous run of the file system detected an integrity violation. Preventing access to make sure the user notices. The file system will be accessible again after the user deletes the integrity state file."; + break; + case 25: + strErr = "An integrity violation was detected and the file system unmounted to make sure the user notices."; + break; + case 26: + strErr = "Mount directory is not empty."; + break; + case 27: + strErr = "Mount directory in use."; + break; + case 28: + strErr = "Cryfs not installed."; + break; + case 29: + strErr = "Mount directory doesn't exist."; + break; + case 30: + strErr = "Mounted directory encrypted."; + break; + case 31: + strErr = "No permissions."; + break; + case 32: + strErr = "Fusermount does not exist"; + break; + case 33: + strErr = "An encrypted folder created by Cryfs already exists."; + break; + default: + break; + } + + return strErr; +} + +QString VaultController::toInternalPath(const QString &externalPath) +{ + QString ret = externalPath; + DUrl url(externalPath); + if (url.isVaultFile()) { + QString path = url.toString(); + ret = path.replace(DFMVAULT_ROOT, VaultController::makeVaultUrl(VaultController::makeVaultLocalPath()).toString()); + } + return ret; +} + +QString VaultController::toExternalPath(const QString &internalPath) +{ + QString retPath = internalPath; + QString vaultRootPath = VaultController::makeVaultUrl(VaultController::makeVaultLocalPath()).toString(); + retPath = retPath.replace(vaultRootPath, DFMVAULT_ROOT); + + return retPath; +} + +QString VaultController::localPathToVirtualPath(const QString &localPath) +{ + if (localPath.isEmpty()) + return localPath; + QString result(localPath); + // 如果是目录,并且最后没有"/",加上"/" + DAbstractFileInfoPointer info = fileService->createFileInfo(nullptr, DUrl::fromLocalFile(result)); + if (info && info->isDir()) { + result = result.endsWith(QDir::separator()) ? result : result.append(QDir::separator()); + } + return result.replace(VaultController::makeVaultLocalPath(), DFMVAULT_ROOT); +} + +QString VaultController::virtualPathToLocalPath(const QString &virtualPath) +{ + if (virtualPath.isEmpty()) + return virtualPath; + QString result(virtualPath); + return result.replace(DFMVAULT_ROOT, VaultController::makeVaultLocalPath()); +} + +qint64 VaultController::totalsize() const +{ + return m_totalSize; +} + +void VaultController::setBigFileIsDeleting(const bool isDeleting) +{ + m_isBigFileDeleting = isDeleting; +} + +int VaultController::getLeftoverErrorInputTimes() +{ + createVaultBruteForcePreventionInterface(); + int leftChance = -1; + if (m_vaultInterface->isValid()) { + QDBusPendingReply reply = m_vaultInterface->getLeftoverErrorInputTimes(int(getuid())); + reply.waitForFinished(); + if (reply.isError()) { + qInfo() << "Warning: Obtaining the remaining number of password input errors!" << reply.error().message(); + } else { + leftChance = reply.value(); + } + } + return leftChance; +} + +void VaultController::leftoverErrorInputTimesMinusOne() +{ + createVaultBruteForcePreventionInterface(); + if (m_vaultInterface->isValid()) { + QDBusPendingReply<> reply = m_vaultInterface->leftoverErrorInputTimesMinusOne(int(getuid())); + reply.waitForFinished(); + if (reply.isError()) + qInfo() << "Warning: The remaining password input times minus 1 is wrong!" << reply.error().message(); + } +} + +void VaultController::restoreLeftoverErrorInputTimes() +{ + createVaultBruteForcePreventionInterface(); + if (m_vaultInterface->isValid()) { + QDBusPendingReply<> reply = m_vaultInterface->restoreLeftoverErrorInputTimes(int(getuid())); + reply.waitForFinished(); + if (reply.isError()) + qInfo() << "Warning: Error in restoring the remaining number of incorrect entries!" << reply.error().message(); + } +} + +void VaultController::startTimerOfRestorePasswordInput() +{ + createVaultBruteForcePreventionInterface(); + if (m_vaultInterface->isValid()) { + QDBusPendingReply<> reply = m_vaultInterface->startTimerOfRestorePasswordInput(int(getuid())); + reply.waitForFinished(); + if (reply.isError()) + qInfo() << "Warning: Error when opening the password input timer!" << reply.error().message(); + } +} + +int VaultController::getNeedWaitMinutes() +{ + createVaultBruteForcePreventionInterface(); + int result = 100; + if (m_vaultInterface->isValid()) { + QDBusPendingReply reply = m_vaultInterface->getNeedWaitMinutes(int(getuid())); + reply.waitForFinished(); + if (reply.isError()) + qInfo() << "Warning: Failed to get the number of minutes to wait!" << reply.error().message(); + else + result = reply.value(); + } + return result; +} + +void VaultController::restoreNeedWaitMinutes() +{ + createVaultBruteForcePreventionInterface(); + if (m_vaultInterface->isValid()) { + QDBusPendingReply<> reply = m_vaultInterface->restoreNeedWaitMinutes(int(getuid())); + reply.waitForFinished(); + if (reply.isError()) + qInfo() << "Warnning: The restore needs to wait for a few minutes to fail!" << reply.error().message(); + } +} + +void VaultController::updateFolderSizeLabel(const qint64 size) noexcept +{ + m_totalSize = size; +} + +bool VaultController::isVaultFile(QString path) +{ + bool bVaultFile = false; + QString rootPath = makeVaultLocalPath(); + + if (rootPath.isEmpty()) + return false; + + if (rootPath.back() == "/") { + rootPath.chop(1); + } + + if (path.contains(rootPath) && path.left(6) != "search") { + bVaultFile = true; + } + + return bVaultFile; +} + +QFileDevice::Permissions VaultController::getPermissions(QString filePath) +{ + QFileDevice::Permissions permissions; + QT_STATBUF statBuffer; + if (QT_STAT(QFile::encodeName(filePath), &statBuffer) == 0) { + auto st_mode = statBuffer.st_mode; + + auto setPermission = [&](bool isOwner, QFileDevice::Permissions permission) { + if (isOwner) { + permissions |= permission; + } else { + permissions &= ~permission; + } + }; + + setPermission(st_mode & S_IRUSR, QFileDevice::ReadOwner); + setPermission(st_mode & S_IWUSR, QFileDevice::WriteOwner); + setPermission(st_mode & S_IXUSR, QFileDevice::ExeOwner); + + setPermission(st_mode & S_IRUSR, QFileDevice::ReadUser); + setPermission(st_mode & S_IWUSR, QFileDevice::WriteUser); + setPermission(st_mode & S_IXUSR, QFileDevice::ExeUser); + + setPermission(st_mode & S_IRGRP, QFileDevice::ReadGroup); + setPermission(st_mode & S_IWGRP, QFileDevice::WriteGroup); + setPermission(st_mode & S_IXGRP, QFileDevice::ExeGroup); + + setPermission(st_mode & S_IROTH, QFileDevice::ReadOther); + setPermission(st_mode & S_IWOTH, QFileDevice::WriteOther); + setPermission(st_mode & S_IXOTH, QFileDevice::ExeOther); + } + + return permissions; +} + +QString VaultController::pathToVirtualPath(QString path) +{ + QString nextPath = path; + int index = nextPath.indexOf(VAULT_DECRYPT_DIR_NAME); + if (index == -1) { + // fallback to vault file root dir. + return VaultController::makeVaultUrl("/").toString(); + } + + index += QString(VAULT_DECRYPT_DIR_NAME).length(); + + return VaultController::makeVaultUrl(nextPath.mid(index)).toString(); +} + +DUrl VaultController::urlToVirtualUrl(QString path) +{ + QString nextPath = path; + int index = nextPath.indexOf(VAULT_DECRYPT_DIR_NAME); + if (index == -1) { + // fallback to vault file root dir. + return VaultController::makeVaultUrl("/"); + } + + index += QString(VAULT_DECRYPT_DIR_NAME).length(); + + return VaultController::makeVaultUrl(nextPath.mid(index)); +} + +bool VaultController::isBigFileDeleting() +{ + return m_isBigFileDeleting; +} + +void VaultController::createVault(const DSecureString &password, QString lockBaseDir, QString unlockFileDir) +{ + auto createIfNotExist = [](const QString &path) { + if (!QFile::exists(path)) { + QDir().mkpath(path); + } else { // 修复bug-52351 创建保险箱前,如果文件夹存在,则清空 + QDir dir(path); + if (!dir.isEmpty()) { + QDirIterator dirsIterator(path, QDir::AllEntries | QDir::NoDotAndDotDot); + while (dirsIterator.hasNext()) { + if (!dir.remove(dirsIterator.next())) { + QDir(dirsIterator.filePath()).removeRecursively(); + } + } + } + } + }; + + if (lockBaseDir.isEmpty() || unlockFileDir.isEmpty()) { + if (state() != NotExisted) { + emit signalCreateVault(static_cast(ErrorCode::EncryptedExist)); + return; + } + + createIfNotExist(makeVaultLocalPath("", VAULT_ENCRYPY_DIR_NAME)); + createIfNotExist(makeVaultLocalPath("", VAULT_DECRYPT_DIR_NAME)); + + emit sigCreateVault(makeVaultLocalPath("", VAULT_ENCRYPY_DIR_NAME), + makeVaultLocalPath("", VAULT_DECRYPT_DIR_NAME), + password); + } else { + if (state(lockBaseDir) != NotExisted) { + emit signalCreateVault(static_cast(ErrorCode::EncryptedExist)); + return; + } + + createIfNotExist(lockBaseDir); + createIfNotExist(unlockFileDir); + emit sigCreateVault(lockBaseDir, unlockFileDir, password); + } +} + +void VaultController::unlockVault(const DSecureString &password, QString lockBaseDir, QString unlockFileDir) +{ + // 修复bug-52351 + // 保险箱解锁前,创建挂载目录 + QString strPath; + if (unlockFileDir.isEmpty()) { + strPath = makeVaultLocalPath("", VAULT_DECRYPT_DIR_NAME); + } else { + strPath = unlockFileDir; + } + if (QFile::exists(strPath)) { // 如果存在,则清空目录 + QDir dir(strPath); + if (!dir.isEmpty()) { + QDirIterator dirsIterator(strPath, QDir::AllEntries | QDir::NoDotAndDotDot); + while (dirsIterator.hasNext()) { + if (!dir.remove(dirsIterator.next())) { + QDir(dirsIterator.filePath()).removeRecursively(); + } + } + } + } else { // 如果不存在,则创建目录 + QDir().mkpath(strPath); + } + + if (lockBaseDir.isEmpty() || unlockFileDir.isEmpty()) { + if (state() != Encrypted) { + emit signalUnlockVault(static_cast(ErrorCode::MountpointNotEmpty)); + return; + } + + emit sigUnlockVault(makeVaultLocalPath("", VAULT_ENCRYPY_DIR_NAME), + makeVaultLocalPath("", VAULT_DECRYPT_DIR_NAME), + password); + } else { + if (state(lockBaseDir) != Encrypted) { + emit signalUnlockVault(static_cast(ErrorCode::MountpointNotEmpty)); + return; + } + emit sigUnlockVault(lockBaseDir, unlockFileDir, password); + } +} + +void VaultController::lockVault(QString lockBaseDir, QString unlockFileDir) +{ + if (lockBaseDir.isEmpty() || unlockFileDir.isEmpty()) { + if (state() != Unlocked) { + emit signalLockVault(static_cast(ErrorCode::MountdirEncrypted)); + return; + } + emit sigLockVault(makeVaultLocalPath("", VAULT_DECRYPT_DIR_NAME)); + } else { + if (state(lockBaseDir) != Unlocked) { + emit signalLockVault(static_cast(ErrorCode::MountdirEncrypted)); + return; + } + emit sigLockVault(unlockFileDir); + } +} + +QString VaultController::makeVaultLocalPath(QString path, QString base) +{ + if (base.isEmpty()) { + base = VAULT_DECRYPT_DIR_NAME; + } + return VAULT_BASE_PATH + QDir::separator() + base + (path.startsWith('/') ? "" : "/") + path; +} + +QString VaultController::vaultLockPath() +{ + return makeVaultLocalPath("", VAULT_ENCRYPY_DIR_NAME); +} + +QString VaultController::vaultUnlockPath() +{ + return makeVaultLocalPath("", VAULT_DECRYPT_DIR_NAME); +} + +void VaultController::refreshTotalSize() +{ + // 修复BUG-42897 打开正在拷贝或剪贴的文件夹时,主界面卡死问题 + // 当保险箱大小计算线程没有结束时,直接返回 + if (m_sizeWorker->isRunning()) { + m_bNeedRefreshSize = true; + return; + } + + DUrl url = vaultToLocalUrl(makeVaultUrl()); + m_sizeWorker->start({ url }); +} + +void VaultController::onFinishCalcSize() +{ + // 但保险箱大小计算完成后,再次计算一次保险箱的大小 + if (m_bNeedRefreshSize && !m_sizeWorker->isRunning()) { + DUrl url = vaultToLocalUrl(makeVaultUrl()); + // 修复BUG-47507 增加判断,如果该线程正在启动,不要再次进入该线程 + m_sizeWorker->start({ url }); + m_bNeedRefreshSize = false; + } +} + +void VaultController::taskPaused(const DUrlList &src, const DUrl &dst) +{ + if (isVaultFile(dst.toLocalFile()) || (src.size() > 0 && isVaultFile(src.front().toLocalFile()))) { + refreshTotalSize(); + } +} + +// 创建保险箱,执行该槽函数,通知保险箱创建成功与否,并更新保险箱的状态 +void VaultController::slotCreateVault(int state) +{ + if (state == static_cast(ErrorCode::Success)) { + m_enVaultState = Unlocked; + } + emit signalCreateVault(state); +} + +void VaultController::slotUnlockVault(int state) +{ + if (state == static_cast(ErrorCode::Success)) { + m_enVaultState = Unlocked; + } + emit signalUnlockVault(state); +} + +void VaultController::slotLockVault(int state) +{ + if (state == static_cast(ErrorCode::Success)) { + m_enVaultState = Encrypted; + // 刷新下界面 + emit fileSignalManager->requestFreshAllFileView(); + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::UNKNOWN); + } + emit signalLockVault(state); +} + +void VaultController::slotFinishedCopyFileTotalSize() +{ + if (!m_sizeWorker->isRunning()) { + DUrl rootUrl = vaultToLocalUrl(makeVaultUrl()); + m_sizeWorker->start({ rootUrl }); + } +} + +void VaultController::slotVaultPolicy() +{ + switch (getVaultPolicy()) { + case INVISIBLE: { + switch (getVaultCurrentPageMark()) { + case VaultPageMark::UNKNOWN: + break; + case VaultPageMark::CREATEVAULTPAGE: + emit sigCloseWindow(); + break; + case VaultPageMark::RETRIEVEPASSWORDPAGE: + emit sigCloseWindow(); + break; + case VaultPageMark::VAULTPAGE: + emit sigCloseWindow(); + break; + case VaultPageMark::CLIPBOARDPAGE: + if (m_vaultVisiable) { + lockVault(); + m_vaultVisiable = false; + emit DFMApplication::instance()->reloadComputerModel(); + VaultHelper::killVaultTasks(); + return; + } + break; + case VaultPageMark::COPYFILEPAGE: + if (m_vaultVisiable) { + lockVault(); + m_vaultVisiable = false; + emit DFMApplication::instance()->reloadComputerModel(); + VaultHelper::killVaultTasks(); + return; + } + break; + case VaultPageMark::CREATEVAULTPAGE1: + case VaultPageMark::UNLOCKVAULTPAGE: + case VaultPageMark::DELETEFILEPAGE: + case VaultPageMark::DELETEVAULTPAGE: + setVaultPolicyState(2); + return; + } + + lockVault(); + m_vaultVisiable = false; + emit DFMApplication::instance()->reloadComputerModel(); + } break; + case VISIBLE: + if (!m_vaultVisiable) { + m_vaultVisiable = true; + emit DFMApplication::instance()->reloadComputerModel(); + } + break; + } +} + +bool VaultController::getVaultVersion() +{ + VaultConfig config; + QString strVersion = config.get(CONFIG_NODE_NAME, CONFIG_KEY_VERSION).toString(); + if (!strVersion.isEmpty() && strVersion != CONFIG_VAULT_VERSION) + return true; + + return false; +} + +void VaultController::createVaultBruteForcePreventionInterface() +{ + // 防暴力破解功能的dbus对象 + if (!m_vaultInterface->isValid()) + m_vaultInterface = new VaultBruteForcePreventionInterface("com.deepin.filemanager.daemon", + "/com/deepin/filemanager/daemon/VaultManager2", + QDBusConnection::systemBus(), + this); +} + +int VaultController::getVaultPolicy() +{ + QDBusInterface deepin_systemInfo("com.deepin.filemanager.daemon", + "/com/deepin/filemanager/daemon/AccessControlManager", + "com.deepin.filemanager.daemon.AccessControlManager", + QDBusConnection::systemBus(), this); + + int vaulthidestate = -1; + + //调用 + auto response = deepin_systemInfo.call("QueryVaultAccessPolicyVisible"); + //判断method是否被正确返回 + if (response.type() == QDBusMessage::ReplyMessage) { + //从返回参数获取返回值 + QVariantList value = response.arguments(); + if (!value.isEmpty()) { + QVariant varVaule = value.first(); + vaulthidestate = varVaule.toInt(); + } else { + vaulthidestate = -1; + } + + } else { + qDebug() << "value method called failed!"; + vaulthidestate = -1; + } + + return vaulthidestate; +} + +bool VaultController::setVaultPolicyState(int policyState) +{ + QDBusInterface deepin_systemInfo("com.deepin.filemanager.daemon", + "/com/deepin/filemanager/daemon/AccessControlManager", + "com.deepin.filemanager.daemon.AccessControlManager", + QDBusConnection::systemBus(), this); + + auto response = deepin_systemInfo.call("FileManagerReply", QVariant::fromValue(policyState)); + //判断method是否被正确返回 + if (response.type() == QDBusMessage::ReplyMessage) { + //从返回参数获取返回值 + QVariantList value = response.arguments(); + if (!value.isEmpty()) { + QVariant varVaule = value.first(); + if (!varVaule.toString().isEmpty()) { + return true; + } + } else { + return false; + } + + } else { + qDebug() << "value method called failed!"; + return false; + } + + return false; +} + +void VaultController::setVauleCurrentPageMark(VaultPageMark mark) +{ + m_recordVaultPageMark = mark; +} + +VaultPageMark VaultController::getVaultCurrentPageMark() +{ + return m_recordVaultPageMark; +} + +bool VaultController::isVaultVisiable() +{ + return m_vaultVisiable; +} + +VaultController::~VaultController() +{ + if (d_ptr) { + delete d_ptr; + d_ptr = nullptr; + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaultcontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaultcontroller.h new file mode 100644 index 0000000..e7496f5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaultcontroller.h @@ -0,0 +1,475 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef VAULTCONTROLLER_H +#define VAULTCONTROLLER_H + +#include "dabstractfilecontroller.h" +#include "../vault/vaultglobaldefine.h" + +#include + +class VaultBruteForcePreventionInterface; + +DFM_BEGIN_NAMESPACE +class DFileStatisticsJob; +DFM_END_NAMESPACE + +DCORE_USE_NAMESPACE + +class VaultControllerPrivate; +class VaultController : public DAbstractFileController +{ + Q_OBJECT +public: + enum VaultState { + NotExisted, + Encrypted, + Unlocked, + UnderProcess, + Broken, + NotAvailable + }; + + struct FileBaseInfo + { + bool isExist = false; + bool isFile; + bool isDir; + bool isWritable = true; + bool isSymLink = false; + }; + + //! 保险箱可见策略 + enum VaultVisiblePolicy { + INVISIBLE = 1, //! 不可见 + VISIBLE //! 可见 + }; + + explicit VaultController(QObject *parent = nullptr); + +public: + static VaultController *ins(); + + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + const DDirIteratorPointer createDirIterator(const QSharedPointer &event) const override; + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + + bool openFile(const QSharedPointer &event) const override; + bool openFiles(const QSharedPointer &event) const override; + bool deleteFiles(const QSharedPointer &event) const override; + DUrlList moveToTrash(const QSharedPointer &event) const override; + DUrlList pasteFile(const QSharedPointer &event) const override; + bool writeFilesToClipboard(const QSharedPointer &event) const override; + bool renameFile(const QSharedPointer &event) const override; + + /** + * @brief openInTerminal 右键菜单打开当前路径终端 + * @param event 打开终端信息事件 + * @return 是否打开终端成功 + */ + bool openInTerminal(const QSharedPointer &event) const override; + + /** + * @brief addToBookmark 添加当前文件夹书签 + * @param event 添加书签信息事件 + * @return 是否添加成功 + */ + bool addToBookmark(const QSharedPointer &event) const override; + + /** + * @brief removeBookmark 移除当前文件夹书签 + * @param event 移除书签信息事件 + * @return 是否移除成功 + */ + bool removeBookmark(const QSharedPointer &event) const override; + + /** + * @brief createSymlink 创建快捷方式 + * @param event 创建快捷方式信息事件 + * @return 是否创建成功 + */ + bool createSymlink(const QSharedPointer &event) const override; + + /** + * @brief setFileTags 设置文件标记信息 + * @param event 设置文件标记信息事件 + * @return 是否标记成功 + */ + bool setFileTags(const QSharedPointer &event) const override; + + /** + * @brief removeTagsOfFile 移除文件标记信息 + * @param event 移除文件标记信息事件 + * @return 是否移除文件标记 + */ + bool removeTagsOfFile(const QSharedPointer &event) const override; + + /** + * @brief getTagsThroughFiles 获取文件标记信息 + * @param event 获取文件标记信息事件 + * @return 标记信息列表 + */ + QList getTagsThroughFiles(const QSharedPointer &event) const override; + + bool setPermissions(const QSharedPointer &event) const override; + + bool openFileByApp(const QSharedPointer &event) const override; + bool openFilesByApp(const QSharedPointer &event) const override; + + void updateFileInfo(const DUrlList &fileUrls); + FileBaseInfo getFileInfo(const DUrl &fileUrl); + static DUrl makeVaultUrl(QString path = "", QString host = ""); + static DUrl localUrlToVault(const DUrl &vaultUrl); + static DUrl localToVault(QString localPath); + static QString vaultToLocal(const DUrl &vaultUrl); + static DUrl vaultToLocalUrl(const DUrl &vaultUrl); + static DUrlList vaultToLocalUrls(DUrlList vaultUrls); + + static QString pathToVirtualPath(QString path); + + static DUrl urlToVirtualUrl(QString path); + + /** + * @brief isDeleteFiles 判断保险箱当前是否正在删除文件 + * @return true/false + */ + static bool isBigFileDeleting(); + + /** + * @brief isVaultFile 是否为保险箱中的文件 + * @param path 文件路径 + * @return + */ + static bool isVaultFile(QString path); + + /** + * @brief getPermissions 获取文件的权限信息 + * @param filePath 文件路径 + * @return + */ + static QFileDevice::Permissions getPermissions(QString filePath); + + /** + * @brief state 获取当前保险箱状态,并记录到成员变量中(m_enVaultState) + * @param lockBaseDir 保险箱加密文件夹 + * @return 返回VaultState枚举值 + */ + VaultState state(QString lockBaseDir = ""); + + /** + * @brief VaultFileInfo::isRootDirectory 是否为保险箱根目录 + * @return + */ + static bool isRootDirectory(QString path); + + /** + * @brief getErrorInfo 根据错误码获取错误信息 + * @param state 错误码 + * @return + */ + static QString getErrorInfo(int state); + + /** + * @brief toInternalPath 外部路径转内部路径 + * @param external + * @return + */ + static QString toInternalPath(const QString &externalPath); + + /** + * @brief toExternalPath 转换成外部路径 + * @param internalPath + * @return + */ + static QString toExternalPath(const QString &internalPath); + + /** + * @brief localPathToVirtualPath 本地路径转虚拟路径 + * @param localPath + * @return + */ + static QString localPathToVirtualPath(const QString &localPath); + + /** + * @brief virtualPathToLocalPath 虚拟路径转本地路径 + * @param virtualPath + * @return + */ + static QString virtualPathToLocalPath(const QString &virtualPath); + + /** + * @brief totalsize 保险箱大小 + * @return + */ + qint64 totalsize() const; + + // 获得保险箱状态 + inline VaultState getVaultState() const + { + return m_enVaultState; + } + // 设置保险箱状态 + inline void setVaultState(const VaultState &state) + { + m_enVaultState = state; + } + + /** + * @brief setBigFileIsDeleting Record big file deleting state. + * Avoid block while mutl-file deleted. + * @param isDeleting + */ + void setBigFileIsDeleting(bool const isDeleting); + + // 获得保险箱剩余错误密码输入次数 + int getLeftoverErrorInputTimes(); + + // 保险箱剩余错误密码输入次数减1 + void leftoverErrorInputTimesMinusOne(); + + // 保险箱剩余错误密码输入次数还原 + void restoreLeftoverErrorInputTimes(); + + // 开启恢复密码输入定时器 + void startTimerOfRestorePasswordInput(); + + // 获得保险箱再次输入密码需要等待的分钟数 + int getNeedWaitMinutes(); + + // 保险箱再次输入密码的等待分钟数还原 + void restoreNeedWaitMinutes(); + +public slots: + + void updateFolderSizeLabel(const qint64 size) noexcept; + + /** + * @brief createVault 创建保险箱 + * @param lockBaseDir 保险箱加密文件夹 默认值内部自动创建 + * @param unlockFileDir 保险箱解密文件夹 默认值内部自动创建 + * @param passWord 保险箱密码 + + */ + void createVault(const DSecureString &password, QString lockBaseDir = "", QString unlockFileDir = ""); + + /** + * @brief unlockVault 解锁保险箱 + * @param lockBaseDir 保险箱加密文件夹 默认值内部自动创建 + * @param unlockFileDir 保险箱解密文件夹 默认值内部自动创建 + * @param passWord 保险箱密码 + */ + void unlockVault(const DSecureString &password, QString lockBaseDir = "", QString unlockFileDir = ""); + + /** + * @brief lockVault 加锁保险箱 + * @param lockBaseDir 保险箱加密文件夹 默认值内部自动创建 + * @param unlockFileDir 保险箱解密文件夹 默认值内部自动创建 + */ + void lockVault(QString lockBaseDir = "", QString unlockFileDir = ""); + + /** + * @brief makeVaultLocalPath 创建本地路径 + * @param path 子目录(文件或文件路径) + * @param base 父目录 + * @return 返回新路径 + */ + static QString makeVaultLocalPath(QString path = "", QString base = ""); + + /** + * @brief vaultLockPath 返回默认保险箱加密文件夹路径,如路径是外部传入暂时无法获取 + * @return 默认保险箱加密文件夹路径 + */ + static QString vaultLockPath(); + + /** + * @brief vaultLockPath 返回默认保险箱解密文件夹路径,如路径是外部传入暂时无法获取 + * @return 默认保险箱解密文件夹路径 + */ + static QString vaultUnlockPath(); + + /** + * @brief refreshTotalSize 刷新保险箱大小 + */ + void refreshTotalSize(); + + /** + * @brief refreshTotalSize 刷新保险箱大小完成 + */ + void onFinishCalcSize(); + + /** + * @brief taskPaused 处理任务暂停信号 + * @param src 任务源路径 + * @param dst 任务目的路径 + */ + void taskPaused(const DUrlList &src, const DUrl &dst); + +private slots: + // 创建保险箱,执行该槽函数,通知保险箱创建成功与否,并更新保险箱的状态 + void slotCreateVault(int state); + void slotUnlockVault(int state); + void slotLockVault(int state); + + void slotFinishedCopyFileTotalSize(); + + // 保险箱策略处理函数 + void slotVaultPolicy(); + +private: + // 创建保险箱防暴力破解的dbus接口对象 + void createVaultBruteForcePreventionInterface(); + +signals: + /** + * @brief readError 错误输出 + * @param error 错误信息 + */ + void signalReadError(QString error); + + /** + * @brief signalReadOutput 标准输出 + * @param msg 输出信息 + */ + void signalReadOutput(QString msg); + + /** + * @brief signalCreateVault 创建保险箱是否成功的信号 + * @param state 返回ErrorCode枚举值 + */ + void signalCreateVault(int state); + + /** + * @brief singalUnlockVault 解锁保险箱是否成功的信号 + * @param state 返回ErrorCode枚举值 + */ + void signalUnlockVault(int state); + + /** + * @brief signalLockVault 加锁保险箱是否成功的信号 + * @param state 返回ErrorCode枚举值 + */ + void signalLockVault(int state); + + //! 通知拷贝或剪切任务完成 + void sigFinishedCopyFile(); + +signals: + /** + * @brief 下列信号为本类内部使用,请勿外用 + */ + + /** + * @brief sigCreateVault 创建保险箱信号 + * @param lockBaseDir 保险箱加密文件夹 + * @param unlockFileDir 保险箱解密文件夹 + * @param passWord 保险箱密码 + */ + void sigCreateVault(QString lockBaseDir, QString unlockFileDir, QString passWord); + + /** + * @brief sigUnlockVault 解锁保险箱信号 + * @param lockBaseDir 保险箱加密文件夹 + * @param unlockFileDir 保险箱解密文件夹 + * @param passWord 保险箱密码 + */ + void sigUnlockVault(QString lockBaseDir, QString unlockFileDir, QString passWord); + + /** + * @brief sigLockVault 加锁保险箱信号 + * @param unlockFileDir 保险箱解密文件夹 + */ + void sigLockVault(QString unlockFileDir); + + //! 通知关闭对话框 + void sigCloseWindow(); + +public: + /** + * @brief getVaultVersion 获取当前保险箱版本是否是1050及以上版本 + * @return true大于等于1050,false小于1050 + */ + static bool getVaultVersion(); + + /** + * @brief getVaultPolicy 获取当前策略 + * @return 返回保险箱是否隐藏 1隐藏 2显示 + */ + int getVaultPolicy(); + + /** + * @brief setVaultPolicyState 设置策略是否可用 + * @param policyState 1策略可用 2策略不可用 + * @return 设置是否成功 + */ + bool setVaultPolicyState(int policyState); + + /** + * @brief setVauleCurrentPageMark 设置当前所处保险箱页面 + * @param mark 页面标识 + */ + void setVauleCurrentPageMark(VaultPageMark mark); + + /** + * @brief getVaultCurrentPageMark 获取当前所处保险箱页面 + * @return 返回当前页面标识 + */ + VaultPageMark getVaultCurrentPageMark(); + + /** + * @brief isVaultVisiable 获取保险箱显示状态 + * @return true显示、false隐藏 + */ + bool isVaultVisiable(); + +private: + ~VaultController() override; + QMap m_mapVaultFileInfo; + + VaultControllerPrivate *d_ptr; + + static VaultController *cryfs; + + qint64 m_totalSize = 0; + + static bool m_isBigFileDeleting; + + // 记录保险箱状态 + VaultState m_enVaultState { NotExisted }; + + DFM_NAMESPACE::DFileStatisticsJob *m_sizeWorker { nullptr }; + + // 计算当前保险箱大小是否需要刷新 + bool m_bNeedRefreshSize = false; + + // 防暴力破解功能的dbus对象 + VaultBruteForcePreventionInterface *m_vaultInterface = nullptr; + + //! 用于记录当前保险箱所处页面标识 + VaultPageMark m_recordVaultPageMark; + + bool m_vaultVisiable; + + Q_DECLARE_PRIVATE(VaultController) +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaulterrorcode.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaulterrorcode.h new file mode 100644 index 0000000..b661166 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaulterrorcode.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + + +#ifndef CRYFSERRORCODE_H +#define CRYFSERRORCODE_H + +enum class ErrorCode : int +{ + //! 成功 + Success = 0, + + //! 发生的错误没有与之相关的错误代码 + UnspecifiedError = 1, + + //! 命令行参数无效. + InvalidArguments = 10, + + //! 无法加载配置文件.密码可能不正确 + WrongPassword = 11, + + //! 密码不能为空 + EmptyPassword = 12, + + //! 对于此CryFS版本,文件系统格式太新了.请更新您的CryFS版本. + TooNewFilesystemFormat = 13, + + //! 对于此CryFS版本,文件系统格式过旧.与--allow-filesystem-upgrade一起运行以对其进行升级. + TooOldFilesystemFormat = 14, + + //! 文件系统使用的密码与使用--cipher参数在命令行上指定的密码不同. + WrongCipher = 15, + + //! 基本目录不存在或不可访问(即,不可读取或可写或非目录) + InaccessibleBaseDir = 16, + + //! 挂载目录不存在或不可访问(即无法读取或写入或不是目录) + InaccessibleMountDir = 17, + + //! 基本目录不能是安装目录的子目录 + BaseDirInsideMountDir = 18, + + //! 文件系统出了点问题. + InvalidFilesystem = 19, + + //! 配置文件中的文件系统ID与我们上次从此basedir加载文件系统的时间不同. + //! 这可能意味着攻击者用另一种文件系统替换了文件系统. + //! 您可以传递--allow-replaced-filesystem选项以允许此操作. + FilesystemIdChanged = 20, + + //! 文件系统加密密钥与我们上次加载此文件系统的时间不同. + //! 这可能意味着攻击者用另一种文件系统替换了文件系统. + //! 您可以传递--allow-replaced-filesystem选项以允许此操作. + EncryptionKeyChanged = 21, + + //! 命令行选项和文件系统在是否应该将丢失的块视为完整性违规方面存在分歧. + FilesystemHasDifferentIntegritySetup = 22, + + //! 文件系统处于单客户端模式,只能在创建它的客户端中使用. + SingleClientFileSystem = 23, + + //! 先前运行的文件系统检测到完整性违规. + //! 阻止访问以确保用户注意. + //! 用户删除完整性状态文件后,将可以再次访问文件系统. + IntegrityViolationOnPreviousRun = 24, + + //! 检测到完整性违规,并卸载文件系统以确保用户注意. + IntegrityViolation = 25, + + //! 挂载点不为空 + MountpointNotEmpty = 26, + + //! 挂载目录使用中 + ResourceBusy = 27, + + //! cryfs不存在 + CryfsNotExist = 28, + + //! 挂载目录不存在 + MountdirNotExist = 29, + + //! 挂载目录已加密 + MountdirEncrypted = 30, + + //! 没有权限 + PermissionDenied = 31, + + //! fusermount不存在 + FusermountNotExist = 32, + + //! Cryfs创建的加密文件夹已存在 + EncryptedExist = 33 +}; + +#endif //! CRYFSERRORCODE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaulthandle.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaulthandle.cpp new file mode 100644 index 0000000..8893d72 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaulthandle.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + + +#include "vaulthandle.h" +#include "vaulterrorcode.h" +#include "dfmsettings.h" +#include "vaultglobaldefine.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "singleton.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CryFsHandle::CryFsHandle(QObject *parent) : QObject(parent) +{ + m_process = new QProcess(this); + m_mutex = new QMutex; + m_thread = new QThread; + this->moveToThread(m_thread); + connect(m_process , &QProcess::readyReadStandardError, this, &CryFsHandle::slotReadError); + connect(m_process , &QProcess::readyReadStandardOutput, this, &CryFsHandle::slotReadOutput); + m_thread->start(); +} + +CryFsHandle::~CryFsHandle() +{ + disconnect(m_process, &QProcess::readyReadStandardError, this, &CryFsHandle::slotReadError); + disconnect(m_process, &QProcess::readyReadStandardOutput, this, &CryFsHandle::slotReadOutput); + + if (m_mutex) { + delete m_mutex; + m_mutex = nullptr; + } + + if (m_thread) { + m_thread->quit(); + m_thread->deleteLater(); + } +} + +void CryFsHandle::createVault(QString lockBaseDir, QString unlockFileDir, QString passWord) +{ + m_mutex->lock(); + m_activeState.insert(1, static_cast(ErrorCode::Success)); + int flg = runVaultProcess(lockBaseDir, unlockFileDir,passWord); + if(m_activeState.value(1) != static_cast(ErrorCode::Success)) + emit signalCreateVault(m_activeState.value(1)); + else{ + emit signalCreateVault(flg); + //! 记录保险箱创建时间. + DFM_NAMESPACE::DFMSettings setting(VAULT_TIME_CONFIG_FILE); + setting.setValue(QString("VaultTime"), QString("CreateTime"), QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); + } + m_activeState.clear(); + m_mutex->unlock(); +} + +void CryFsHandle::unlockVault(QString lockBaseDir, QString unlockFileDir, QString passWord) +{ + m_mutex->lock(); + m_activeState.insert(3, static_cast(ErrorCode::Success)); + qDebug() << "CryFsHandle::unlockVault:" << QThread::currentThread(); + int flg = runVaultProcess(lockBaseDir, unlockFileDir, passWord); + if(m_activeState.value(3) != static_cast(ErrorCode::Success)) + emit signalUnlockVault(m_activeState.value(3)); + else + emit signalUnlockVault(flg); + m_activeState.clear(); + m_mutex->unlock(); +} + +void CryFsHandle::lockVault(QString unlockFileDir) +{ + // 修复bug-88630 + // 由于保险箱上锁时,保险箱内文件物理地址已不存在,此时未完成的拖拽事件已经毫无意义, + // 并且此时拖拽移动还会导致崩溃问题 + // 所以,发送请求忽略当前保险箱的拖拽事件,避免崩溃问题 + emit fileSignalManager->requestIgnoreDragEvent(); + + m_mutex->lock(); + m_activeState.insert(7, static_cast(ErrorCode::Success)); + int flg = lockVaultProcess(unlockFileDir); + if(m_activeState.value(7) != static_cast(ErrorCode::Success)) + emit signalLockVault(m_activeState.value(7)); + else { + emit signalLockVault(flg); + //! 记录保险箱上锁时间 + DFM_NAMESPACE::DFMSettings setting(VAULT_TIME_CONFIG_FILE); + setting.setValue(QString("VaultTime"), QString("LockTime"), QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); + } + m_activeState.clear(); + m_mutex->unlock(); +} + +int CryFsHandle::runVaultProcess(QString lockBaseDir, QString unlockFileDir, QString passWord) +{ + QString cryfsBinary = QStandardPaths::findExecutable("cryfs"); + if (cryfsBinary.isEmpty()) return static_cast(ErrorCode::CryfsNotExist); + + QStringList arguments; + arguments << lockBaseDir << unlockFileDir; + + m_process->setEnvironment({"CRYFS_FRONTEND=noninteractive"}); + m_process->start(cryfsBinary, arguments); + m_process->waitForStarted(); + m_process->write(passWord.toUtf8()); + m_process->waitForBytesWritten(); + m_process->closeWriteChannel(); + m_process->waitForFinished(); + m_process->terminate(); + + if(m_process->exitStatus() == QProcess::NormalExit) + return static_cast(ErrorCode::Success); + else + return m_process->exitCode(); + +} + +int CryFsHandle::lockVaultProcess(QString unlockFileDir) +{ + QString fusermountBinary = QStandardPaths::findExecutable("fusermount"); + if (fusermountBinary.isEmpty()) return static_cast(ErrorCode::FusermountNotExist); + + m_process->start(fusermountBinary, {"-zu", unlockFileDir}); + m_process->waitForStarted(); + m_process->waitForFinished(); + m_process->terminate(); + + if(m_process->exitStatus() == QProcess::NormalExit) { + // 修复bug-52351 + // 保险箱上锁成功后,删除挂载目录 + if(rmdir(unlockFileDir.toStdString().c_str()) == -1) { + qDebug() << "Vault Info: remove vault unlock dir failure"; + } else { + qDebug() << "Vault Info: remove vault unlock dir success"; + } + return static_cast(ErrorCode::Success); + } else + return m_process->exitCode(); +} + +void CryFsHandle::slotReadError() +{ + QString error = m_process->readAllStandardError().data(); + if(m_activeState.contains(1)) + { + if(error.contains("mountpoint is not empty")) + m_activeState[1] = static_cast(ErrorCode::MountpointNotEmpty); + else if(error.contains("Permission denied")) + m_activeState[1] = static_cast(ErrorCode::PermissionDenied); + } else if(m_activeState.contains(3)) + { + if(error.contains("mountpoint is not empty")) + m_activeState[3] = static_cast(ErrorCode::MountpointNotEmpty); + else if(error.contains("Permission denied")) + m_activeState[3] = static_cast(ErrorCode::PermissionDenied); + } else if(m_activeState.contains(7)) + { + if(error.contains("Device or resource busy")) + m_activeState[7] = static_cast(ErrorCode::ResourceBusy); + } + emit signalReadError(error); +} + +void CryFsHandle::slotReadOutput() +{ + QString msg = m_process->readAllStandardOutput().data(); + emit signalReadOutput(msg); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaulthandle.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaulthandle.h new file mode 100644 index 0000000..aa0696f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/controllers/vaulthandle.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + + +#ifndef CRYFSHANDLE_H +#define CRYFSHANDLE_H + +#include +#include + +class QMutex; +class QProcess; +class QThread; +class CryFsHandle : public QObject +{ + Q_OBJECT +public: + explicit CryFsHandle(QObject *parent = nullptr); + ~CryFsHandle(); + + /** + * @brief createVault 创建保险箱 + * @param lockBaseDir 保险箱加密文件夹 + * @param unlockFileDir 保险箱解密文件夹 + * @param passWord 保险箱密码 + */ + void createVault(QString lockBaseDir, QString unlockFileDir, QString passWord); + + /** + * @brief unlockVault 解锁保险箱 + * @param lockBaseDir 保险箱加密文件夹 + * @param unlockFileDir 保险箱解密文件夹 + * @param passWord 保险箱密码 + */ + void unlockVault(QString lockBaseDir, QString unlockFileDir, QString passWord); + + /** + * @brief lockedStrongBox 加锁保险箱 + * @param unlockFileDir 保险箱解密文件夹 + */ + void lockVault(QString unlockFileDir); + +private: + /** + * @brief runVaultProcess 运行子进程执行创建保险箱或解锁保险箱 + * @param lockBaseDir 保险箱加密文件夹 + * @param unlockFileDir 保险箱解密文件夹 + * @param passWord 保险箱密码 + * @return 返回ErrorCode枚举值 + */ + int runVaultProcess(QString lockBaseDir, QString unlockFileDir, QString passWord); + + /** + * @brief vaultLockProcess 加锁保险箱 + * @param unlockFileDir 保险箱解密文件夹 + * @return 返回ErrorCode枚举值 + */ + int lockVaultProcess(QString unlockFileDir); + +signals: + /** + * @brief readError 错误输出 + * @param error 错误信息 + */ + void signalReadError(QString error); + + /** + * @brief signalReadOutput 标准输出 + * @param msg 输出信息 + */ + void signalReadOutput(QString msg); + + /** + * @brief signalCreateVault 创建保险箱是否成功的信号 + * @param state 返回ErrorCode枚举值 + */ + void signalCreateVault(int state); + + /** + * @brief singalUnlockVault 解锁保险箱是否成功的信号 + * @param state 返回ErrorCode枚举值 + */ + void signalUnlockVault(int state); + + /** + * @brief signalLockVault 加锁保险箱是否成功的信号 + * @param state 返回ErrorCode枚举值 + */ + void signalLockVault(int state); + +public slots: + /** + * @brief slotReadError 进程执行错误时执行并发送signalReadError信号 + */ + void slotReadError(); + + /** + * @brief slotReadOutput 进程执行过程中的输出信息,发送signalReadOutput信号 + */ + void slotReadOutput(); + +private: + QProcess * m_process; + QThread * m_thread; + + QMutex * m_mutex; + QMap m_activeState; +}; + + + +#endif // CRYFSHANDLE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbus/dbussysteminfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbus/dbussysteminfo.cpp new file mode 100644 index 0000000..a7bcfb0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbus/dbussysteminfo.cpp @@ -0,0 +1,12 @@ +#include "dbussysteminfo.h" + +DBusSystemInfo::DBusSystemInfo(QObject *parent) + : QDBusAbstractInterface(staticServiceName(), staticObjectPath(), staticInterfaceName(), QDBusConnection::sessionBus(), parent) +{ + QDBusConnection::sessionBus().connect(this->service(), this->path(), "org.freedesktop.DBus.Properties", "PropertiesChanged", "sa{sv}as", this, SLOT(__propertyChanged__(QDBusMessage))); +} + +DBusSystemInfo::~DBusSystemInfo() +{ + QDBusConnection::sessionBus().disconnect(service(), path(), "org.freedesktop.DBus.Properties", "PropertiesChanged", "sa{sv}as", this, SLOT(propertyChanged(QDBusMessage))); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbus/dbussysteminfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbus/dbussysteminfo.h new file mode 100644 index 0000000..db51216 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbus/dbussysteminfo.h @@ -0,0 +1,91 @@ +#ifndef DBUSSYSTEMINFO_H +#define DBUSSYSTEMINFO_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class DBusSystemInfo : public QDBusAbstractInterface +{ + Q_OBJECT + + Q_SLOT void __propertyChanged__(const QDBusMessage& msg) + { + QList arguments = msg.arguments(); + if (3 != arguments.count()) + return; + QString interfaceName = msg.arguments().at(0).toString(); + if (interfaceName !="com.deepin.daemon.SystemInfo") + return; + QVariantMap changedProps = qdbus_cast(arguments.at(1).value()); + QStringList keys = changedProps.keys(); + foreach(const QString &prop, keys) { + const QMetaObject* self = metaObject(); + for (int i=self->propertyOffset(); i < self->propertyCount(); ++i) { + QMetaProperty p = self->property(i); + if (p.name() == prop) { + Q_EMIT p.notifySignal().invoke(this); + } + } + } + } + +public: + static inline const char *staticInterfaceName() + { return "com.deepin.daemon.SystemInfo"; } + static inline const char *staticServiceName() + { return "com.deepin.daemon.SystemInfo"; } + static inline const char *staticObjectPath() + { return "/com/deepin/daemon/SystemInfo"; } + +public: + explicit DBusSystemInfo(QObject *parent = nullptr); + ~DBusSystemInfo(); + + Q_PROPERTY(qint64 SystemType READ systemType) + inline qint64 systemType() const + { return qvariant_cast< qint64 >(property("SystemType")); } + + Q_PROPERTY(QString DistroDesc READ distroDesc NOTIFY DistroDescChanged) + inline QString distroDesc() const + { return qvariant_cast< QString >(property("DistroDesc")); } + + Q_PROPERTY(QString DistroID READ distroID NOTIFY DistroIDChanged) + inline QString distroID() const + { return qvariant_cast< QString >(property("DistroID")); } + + Q_PROPERTY(QString DistroVer READ distroVer NOTIFY DistroVerChanged) + inline QString distroVer() const + { return qvariant_cast< QString >(property("DistroVer")); } + + Q_PROPERTY(QString Processor READ processor) + inline QString processor() const + { return qvariant_cast< QString >(property("Processor")); } + + Q_PROPERTY(QString Version READ version NOTIFY VersionChanged) + inline QString version() const + { return qvariant_cast< QString >(property("Version")); } + + Q_PROPERTY(quint64 DiskCap READ diskCap NOTIFY DiskCapChanged) + inline quint64 diskCap() const + { return qvariant_cast< quint64 >(property("DiskCap")); } + + Q_PROPERTY(quint64 MemoryCap READ memoryCap NOTIFY MemoryCapChanged) + inline quint64 memoryCap() const + { return qvariant_cast< quint64 >(property("MemoryCap")); } + +Q_SIGNALS: + void DistroDescChanged(); + void DistroIDChanged(); + void DistroVerChanged(); + void VersionChanged(); + void DiskCapChanged(); + void MemoryCapChanged(); +}; + +#endif // DBUSSYSTEMINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/dbusinterface.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/dbusinterface.pri new file mode 100644 index 0000000..c246481 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/dbusinterface.pri @@ -0,0 +1,24 @@ +HEADERS += \ + $$PWD/diskmount_interface.h \ + $$PWD/dbustype.h \ + $$PWD/usershare_interface.h \ + $$PWD/startmanager_interface.h \ + $$PWD/introspectable_interface.h \ + $$PWD/vault_interface.h \ + $$PWD/revocationmgr_interface.h \ + $$PWD/vaultbruteforceprevention_interface.h + +SOURCES += \ + $$PWD/diskmount_interface.cpp \ + $$PWD/dbustype.cpp \ + $$PWD/usershare_interface.cpp \ + $$PWD/startmanager_interface.cpp \ + $$PWD/introspectable_interface.cpp \ + $$PWD/vault_interface.cpp \ + $$PWD/revocationmgr_interface.cpp \ + $$PWD/vaultbruteforceprevention_interface.cpp + +!CONFIG(DISABLE_ANYTHING) { + dbus_anything.files = /usr/share/dbus-1/interfaces/com.deepin.anything.xml + DBUS_INTERFACES += dbus_anything +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/dbustype.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/dbustype.cpp new file mode 100644 index 0000000..d677645 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/dbustype.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "dbustype.h" + +DiskInfo::DiskInfo(){ + +} + +DiskInfo::~DiskInfo(){ + +} + +void DiskInfo::registerMetaType() +{ + qRegisterMetaType(QT_STRINGIFY(DiskInfo)); + qDBusRegisterMetaType(); + qRegisterMetaType(QT_STRINGIFY(DiskInfoList)); + qDBusRegisterMetaType(); +} + + +QDBusArgument &operator<<(QDBusArgument &argument, const DiskInfo &obj) +{ + argument.beginStructure(); + argument << obj.ID << obj.Name; + argument << obj.Type << obj.Path; + argument << obj.MountPoint << obj.Icon; + argument << obj.CanUnmount << obj.CanEject; + argument << obj.Used << obj.Total; + argument.endStructure(); + return argument; +} + + +const QDBusArgument &operator>>(const QDBusArgument &argument, DiskInfo &obj) +{ + argument.beginStructure(); + argument >> obj.ID >> obj.Name; + argument >> obj.Type >> obj.Path; + argument >> obj.MountPoint >> obj.Icon; + argument >> obj.CanUnmount >> obj.CanEject; + argument >> obj.Used >> obj.Total; + + obj.Total = obj.Total * 1024; + obj.Used = obj.Used * 1024; + obj.Free = obj.Total - obj.Used; + + argument.endStructure(); + + obj.MountPointUrl.setUrl(obj.MountPoint); + return argument; +} + + +QDebug operator<<(QDebug dbg, const DiskInfo &info) +{ + dbg.nospace() << "DiskInfo("; + dbg.nospace() << "ID: " << info.ID << ","; + dbg.nospace() << "Name: " << info.Name << ","; + dbg.nospace() << "Type: " << info.Type << ","; + dbg.nospace() << "Path: " << info.Path << ","; + dbg.nospace() << "MountPoint: " << info.MountPoint << ","; + dbg.nospace() << "Icon: " << info.Icon << ","; + dbg.nospace() << "CanUnmount: " << info.CanUnmount << ","; + dbg.nospace() << "CanEject: " << info.CanEject << ","; + dbg.nospace() << "Used: " << info.Used<< ","; + dbg.nospace() << "Total: " << info.Total<< ","; + dbg.nospace() << "MountPointUrl: " << info.MountPointUrl << ","; + dbg.nospace() << ")"; + return dbg; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/dbustype.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/dbustype.h new file mode 100644 index 0000000..105e5ab --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/dbustype.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DBUSTYPE_H +#define DBUSTYPE_H + +#include +#include + +#include "durl.h" + +class DiskInfo +{ + +public: + QString ID = ""; + QString Name = ""; + QString Type = ""; + QString Path = ""; + QString MountPoint = ""; + QString Icon = ""; + bool CanUnmount = false; + bool CanEject = false; + qulonglong Used = 0; + qulonglong Total = 0; + qulonglong Free = 0; + + DUrl MountPointUrl; + + /*if true show in computerview for especially used*/ + bool isNativeCustom = false; + + DiskInfo(); + ~DiskInfo(); + + friend QDBusArgument &operator<<(QDBusArgument &argument, const DiskInfo &obj); + + friend const QDBusArgument &operator>>(const QDBusArgument &argument, DiskInfo &obj); + + static void registerMetaType(); + + +}; + + +typedef QList DiskInfoList; + +Q_DECLARE_METATYPE(DiskInfo) +Q_DECLARE_METATYPE(DiskInfoList) + + +QDebug operator<<(QDebug dbg, const DiskInfo &info); + +#endif // DBUSTYPE_H + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/diskmount.xml b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/diskmount.xml new file mode 100644 index 0000000..a8b6a48 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/diskmount.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/diskmount_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/diskmount_interface.cpp new file mode 100644 index 0000000..c19e045 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/diskmount_interface.cpp @@ -0,0 +1,27 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -N -p diskmount_interface.h:diskmount_interface.cpp -c DiskMountInterface diskmount.xml + * + * qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "diskmount_interface.h" + +/* + * Implementation of interface class DiskMountInterface + */ + +DiskMountInterface::DiskMountInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ + DiskInfo::registerMetaType(); +} + +DiskMountInterface::~DiskMountInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/diskmount_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/diskmount_interface.h new file mode 100644 index 0000000..cba3985 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/diskmount_interface.h @@ -0,0 +1,85 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -N -p diskmount_interface.h:diskmount_interface.cpp -c DiskMountInterface diskmount.xml + * + * qdbusxml2cpp is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef DISKMOUNT_INTERFACE_H_1462956635 +#define DISKMOUNT_INTERFACE_H_1462956635 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dbustype.h" + +/* + * Proxy class for interface com.deepin.daemon.DiskMount + */ +class DiskMountInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + + static inline const char *staticServerPath() + { return "com.deepin.daemon.DiskMount"; } + static inline const char *staticInterfacePath() + { return "/com/deepin/daemon/DiskMount"; } + static inline const char *staticInterfaceName() + { return "com.deepin.daemon.DiskMount"; } + +public: + DiskMountInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~DiskMountInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> Eject(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("Eject"), argumentList); + } + + inline QDBusPendingReply ListDisk() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("ListDisk"), argumentList); + } + + inline QDBusPendingReply<> Mount(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("Mount"), argumentList); + } + + inline QDBusPendingReply QueryDisk(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("QueryDisk"), argumentList); + } + + inline QDBusPendingReply<> Unmount(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("Unmount"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void Changed(int in0, const QString &in1); + void Error(const QString &in0, const QString &in1); +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/introspectable.xml b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/introspectable.xml new file mode 100644 index 0000000..d0fa4c8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/introspectable.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/introspectable_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/introspectable_interface.cpp new file mode 100644 index 0000000..a5ea2b9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/introspectable_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c IntrospectableInterface -p introspectable_interface introspectable.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "introspectable_interface.h" + +/* + * Implementation of interface class IntrospectableInterface + */ + +IntrospectableInterface::IntrospectableInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +IntrospectableInterface::~IntrospectableInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/introspectable_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/introspectable_interface.h new file mode 100644 index 0000000..c344a33 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/introspectable_interface.h @@ -0,0 +1,61 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c IntrospectableInterface -p introspectable_interface introspectable.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef INTROSPECTABLE_INTERFACE_H +#define INTROSPECTABLE_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface org.freedesktop.DBus.Introspectable + */ +class IntrospectableInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.freedesktop.DBus.Introspectable"; } + +public: + IntrospectableInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~IntrospectableInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply InterfaceName() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("InterfaceName"), argumentList); + } + + inline QDBusPendingReply Introspect() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("Introspect"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace org { + namespace freedesktop { + namespace DBus { + typedef ::IntrospectableInterface Introspectable; + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/revocationmgr_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/revocationmgr_interface.cpp new file mode 100644 index 0000000..17678ba --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/revocationmgr_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c RevocationMgrInterface -p ../dbusservice/dbusinterface/revocationmgr_interface revocation.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "revocationmgr_interface.h" + +/* + * Implementation of interface class RevocationMgrInterface + */ + +RevocationMgrInterface::RevocationMgrInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +RevocationMgrInterface::~RevocationMgrInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/revocationmgr_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/revocationmgr_interface.h new file mode 100644 index 0000000..bacf9e1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/revocationmgr_interface.h @@ -0,0 +1,66 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c RevocationMgrInterface -p ../dbusservice/dbusinterface/revocationmgr_interface revocation.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef REVOCATIONMGR_INTERFACE_H +#define REVOCATIONMGR_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.RevocationManager + */ +class RevocationMgrInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.RevocationManager"; } + +public: + RevocationMgrInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~RevocationMgrInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply popEvent() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("popEvent"), argumentList); + } + + inline QDBusPendingReply<> pushEvent(int event, const QString &user) + { + QList argumentList; + argumentList << QVariant::fromValue(event) << QVariant::fromValue(user); + return asyncCallWithArgumentList(QStringLiteral("pushEvent"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void deskRevocationAction(const QString &user); + void fmgrRevocationAction(const QString &user); +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::RevocationMgrInterface RevocationManager; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/soundeffect.xml b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/soundeffect.xml new file mode 100644 index 0000000..17eab90 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/soundeffect.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/startmanager.xml b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/startmanager.xml new file mode 100644 index 0000000..151ed04 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/startmanager.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/startmanager_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/startmanager_interface.cpp new file mode 100644 index 0000000..b1547f6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/startmanager_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c StartManagerInterface -p startmanager_interface startmanager.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "startmanager_interface.h" + +/* + * Implementation of interface class StartManagerInterface + */ + +StartManagerInterface::StartManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +StartManagerInterface::~StartManagerInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/startmanager_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/startmanager_interface.h new file mode 100644 index 0000000..4f72aad --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/startmanager_interface.h @@ -0,0 +1,117 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c StartManagerInterface -p startmanager_interface startmanager.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef STARTMANAGER_INTERFACE_H +#define STARTMANAGER_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.StartManager + */ +class StartManagerInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.StartManager"; } + +public: + StartManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~StartManagerInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply AddAutostart(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("AddAutostart"), argumentList); + } + + inline QDBusPendingReply AutostartList() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("AutostartList"), argumentList); + } + + inline QDBusPendingReply IsAutostart(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("IsAutostart"), argumentList); + } + + inline QDBusPendingReply Launch(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("Launch"), argumentList); + } + + inline QDBusPendingReply<> LaunchApp(const QString &in0, uint in1, const QStringList &in2) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2); + return asyncCallWithArgumentList(QStringLiteral("LaunchApp"), argumentList); + } + + inline QDBusPendingReply<> LaunchAppAction(const QString &in0, const QString &in1, uint in2) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2); + return asyncCallWithArgumentList(QStringLiteral("LaunchAppAction"), argumentList); + } + + inline QDBusPendingReply LaunchWithTimestamp(const QString &in0, uint in1) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1); + return asyncCallWithArgumentList(QStringLiteral("LaunchWithTimestamp"), argumentList); + } + + inline QDBusPendingReply RemoveAutostart(const QString &in0) + { + QList argumentList; + argumentList << QVariant::fromValue(in0); + return asyncCallWithArgumentList(QStringLiteral("RemoveAutostart"), argumentList); + } + + inline QDBusPendingReply<> RunCommand(const QString &in0, const QStringList &in1) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1); + return asyncCallWithArgumentList(QStringLiteral("RunCommand"), argumentList); + } + + inline QDBusPendingReply<> RunCommandWithOptions(const QString &in0, const QStringList &in1, const QVariantMap &in2) + { + QList argumentList; + argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2); + return asyncCallWithArgumentList(QStringLiteral("RunCommandWithOptions"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void AutostartChanged(const QString &in0, const QString &in1); +}; + +namespace com { + namespace deepin { + typedef ::StartManagerInterface StartManager; + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/usershare_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/usershare_interface.cpp new file mode 100644 index 0000000..8867742 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/usershare_interface.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c UserShareInterface -p dbusinterface/usershare_interface usershare.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusinterface/usershare_interface.h" + +/* + * Implementation of interface class UserShareInterface + */ + +UserShareInterface::UserShareInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +UserShareInterface::~UserShareInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/usershare_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/usershare_interface.h new file mode 100644 index 0000000..fb22240 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/usershare_interface.h @@ -0,0 +1,64 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -c UserShareInterface -p dbusinterface/usershare_interface usershare.xml + * + * qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef USERSHARE_INTERFACE_H +#define USERSHARE_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.UserShareManager + */ +class UserShareInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.UserShareManager"; } + +public: + UserShareInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~UserShareInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply setUserSharePassword(const QString &username, const QString &passward) + { + QList argumentList; + argumentList << QVariant::fromValue(username) << QVariant::fromValue(passward); + return asyncCallWithArgumentList(QStringLiteral("setUserSharePassword"), argumentList); + } + inline QDBusPendingReply closeSmbShareByShareName(const QString &sharename,const bool bshow) + { + QList argumentList; + argumentList << QVariant::fromValue(sharename) << QVariant::fromValue(bshow); + return asyncCallWithArgumentList(QStringLiteral("closeSmbShareByShareName"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::UserShareInterface UserShareManager; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/vault_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/vault_interface.cpp new file mode 100644 index 0000000..d309b09 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/vault_interface.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "dbusinterface/vault_interface.h" + +/* + * Implementation of interface class VaultInterface + */ + +VaultInterface::VaultInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +VaultInterface::~VaultInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/vault_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/vault_interface.h new file mode 100644 index 0000000..c6393ed --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/vault_interface.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef VAULT_INTERFACE_H +#define VAULT_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.VaultManager + */ +class VaultInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.VaultManager"; } + +public: + VaultInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~VaultInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply checkAuthentication(const QString &type) + { + QList argumentList; + argumentList << QVariant::fromValue(type); + return asyncCallWithArgumentList(QStringLiteral("checkAuthentication"), argumentList); + } + + inline QDBusPendingReply<> clearLockEvent() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("clearLockEvent"), argumentList); + } + + inline QDBusPendingReply getLastestTime() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("getLastestTime"), argumentList); + } + + inline QDBusPendingReply getSelfTime() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("getSelfTime"), argumentList); + } + + inline QDBusPendingReply isLockEventTriggered() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("isLockEventTriggered"), argumentList); + } + + inline QDBusPendingReply<> setRefreshTime(qulonglong time) + { + QList argumentList; + argumentList << QVariant::fromValue(time); + return asyncCallWithArgumentList(QStringLiteral("setRefreshTime"), argumentList); + } + + inline QDBusPendingReply<> sysUserChanged(const QString &curUser) + { + QList argumentList; + argumentList << QVariant::fromValue(curUser); + return asyncCallWithArgumentList(QStringLiteral("sysUserChanged"), argumentList); + } + + inline QDBusPendingReply<> triggerLockEvent() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("triggerLockEvent"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::VaultInterface VaultManager; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/vaultbruteforceprevention_interface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/vaultbruteforceprevention_interface.cpp new file mode 100644 index 0000000..25c61a1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/vaultbruteforceprevention_interface.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "vaultbruteforceprevention_interface.h" + +/* + * Implementation of interface class VaultBruteForcePreventionInterface + */ + +VaultBruteForcePreventionInterface::VaultBruteForcePreventionInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +VaultBruteForcePreventionInterface::~VaultBruteForcePreventionInterface() +{ +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/vaultbruteforceprevention_interface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/vaultbruteforceprevention_interface.h new file mode 100644 index 0000000..e61a297 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dbusinterface/vaultbruteforceprevention_interface.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef VAULTBRUTEFORCEPREVENTION_INTERFACE_H +#define VAULTBRUTEFORCEPREVENTION_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.filemanager.daemon.VaultManager2 + */ +class VaultBruteForcePreventionInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "com.deepin.filemanager.daemon.VaultManager2"; } + +public: + VaultBruteForcePreventionInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~VaultBruteForcePreventionInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply getLeftoverErrorInputTimes(int userID) + { + QList argumentList; + argumentList << QVariant::fromValue(userID); + return asyncCallWithArgumentList(QStringLiteral("getLeftoverErrorInputTimes"), argumentList); + } + + inline QDBusPendingReply getNeedWaitMinutes(int userID) + { + QList argumentList; + argumentList << QVariant::fromValue(userID); + return asyncCallWithArgumentList(QStringLiteral("getNeedWaitMinutes"), argumentList); + } + + inline QDBusPendingReply<> leftoverErrorInputTimesMinusOne(int userID) + { + QList argumentList; + argumentList << QVariant::fromValue(userID); + return asyncCallWithArgumentList(QStringLiteral("leftoverErrorInputTimesMinusOne"), argumentList); + } + + inline QDBusPendingReply<> restoreLeftoverErrorInputTimes(int userID) + { + QList argumentList; + argumentList << QVariant::fromValue(userID); + return asyncCallWithArgumentList(QStringLiteral("restoreLeftoverErrorInputTimes"), argumentList); + } + + inline QDBusPendingReply<> restoreNeedWaitMinutes(int userID) + { + QList argumentList; + argumentList << QVariant::fromValue(userID); + return asyncCallWithArgumentList(QStringLiteral("restoreNeedWaitMinutes"), argumentList); + } + + inline QDBusPendingReply<> startTimerOfRestorePasswordInput(int userID) + { + QList argumentList; + argumentList << QVariant::fromValue(userID); + return asyncCallWithArgumentList(QStringLiteral("startTimerOfRestorePasswordInput"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace com { + namespace deepin { + namespace filemanager { + namespace daemon { + typedef ::VaultBruteForcePreventionInterface VaultManager2; + } + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dde-file-manager-lib.pro b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dde-file-manager-lib.pro new file mode 100644 index 0000000..88d32d8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dde-file-manager-lib.pro @@ -0,0 +1,229 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-06-24T09:14:17 +# +#------------------------------------------------- +#system($$PWD/../vendor/prebuild) +#include($$PWD/../vendor/vendor.pri) + +include(../common/common.pri) + +QT += core gui svg dbus x11extras concurrent multimedia dbus xml KCodecs network +#private +QT += gui-private +LIBS += -lKF5Codecs + +isEqual(ARCH, riscv64) { + LIBS += -latomic +} + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +QT += widgets-private + +TARGET = $$ProjectName + +TEMPLATE = lib +CONFIG += create_pc create_prl no_install_prl + +DEFINES += QMAKE_TARGET=\\\"$$TARGET\\\" QMAKE_VERSION=\\\"$$VERSION\\\" + +# sp3 不稳定的feature,使用宏 UNSTABLE_FEATURE_ENABLE 屏蔽,待稳定后放开 +#DEFINES += SP3_UNSTABLE_FEATURE_ENABLE + +isEmpty(QMAKE_ORGANIZATION_NAME) { + DEFINES += QMAKE_ORGANIZATION_NAME=\\\"deepin\\\" +} + +isEmpty(PREFIX){ + PREFIX = /usr +} + +CONFIG += c++11 link_pkgconfig +PKGCONFIG += libsecret-1 gio-unix-2.0 poppler-cpp dtkwidget dtkgui udisks2-qt5 disomaster gio-qt libcrypto Qt5Xdg dframeworkdbus polkit-agent-1 polkit-qt5-1 +#DEFINES += QT_NO_DEBUG_OUTPUT +DEFINES += QT_MESSAGELOGCONTEXT + +CONFIG(DISABLE_FFMPEG) | isEqual(BUILD_MINIMUM, YES) { + DEFINES += DISABLE_FFMEPG +} + +# BUILD_MINIMUM for live system +isEqual(BUILD_MINIMUM, YES){ + DEFINES += DFM_MINIMUM +} + +CONFIG(DISABLE_ANYTHING) { + message("Quick search and tag support disabled dut to Anything support disabled.") + DEFINES += DISABLE_QUICK_SEARCH + DEFINES += DISABLE_TAG_SUPPORT +} + +# 获取标签系统设置 +AC_FUNC_ENABLE = true +#AC_FUNC_ENABLE = $$(ENABLE_AC_FUNC) +# 检查集成测试标签 +equals( AC_FUNC_ENABLE, true ){ + DEFINES += ENABLE_ACCESSIBILITY + message("lib-dde-file-manager enabled accessibility function with set: " $$AC_FUNC_ENABLE) +} + +include(../dialogs/dialogs.pri) +include(../utils/utils.pri) +include(../chinese2pinyin/chinese2pinyin.pri) +include(../fileoperations/fileoperations.pri) +include(deviceinfo/deviceinfo.pri) +include(devicemanagement/devicemanagement.pri) +include(dbusinterface/dbusinterface.pri) +include(../usershare/usershare.pri) +include(../dde-file-manager-plugins/plugininterfaces/plugininterfaces.pri) +include(tag/tag.pri) +include(mediainfo/mediainfo.pri) +include(vault/vault.pri) +include(log/log.pri) + +isEqual(ARCH, sw_64){ + DEFINES += SW_LABEL + include(./sw_label/sw_label.pri) +} + +include(fulltextsearch/fulltextsearch.pri) +DEFINES += FULLTEXTSEARCH_ENABLE +TR_EXCLUDE += /usr/include/boost/ \ + $$PWD/fulltextsearch/* + +include(io/io.pri) +include(interfaces/vfs/vfs.pri) +include(interfaces/customization/customization.pri) +include(src.pri) + +isEqual(ARCH, sw_64) | isEqual(ARCH, mips64) | isEqual(ARCH, mips32) | isEqual(ARCH, aarch64) | isEqual(ARCH, loongarch64) | isEqual(ARCH, riscv) | isEqual(ARCH, riscv64) { + include(search/dfsearch.pri) +} + +#安全加固 +QMAKE_CXXFLAGS += -fstack-protector-all +QMAKE_LFLAGS += -z now -fPIC +isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + QMAKE_LFLAGS += -z noexecstack -z relro +} + +APPSHAREDIR = $$PREFIX/share/$$TARGET +ICONDIR = $$PREFIX/share/icons/hicolor/scalable/apps +DEFINES += APPSHAREDIR=\\\"$$APPSHAREDIR\\\" + +win32* { + DEFINES += STATIC_LIB + CONFIG += staticlib + LIB_DIR = +} + +isEmpty(LIB_INSTALL_DIR) { + target.path = $$[QT_INSTALL_LIBS] +} else { + target.path = $$LIB_INSTALL_DIR +} + +isEmpty(INCLUDE_INSTALL_DIR) { + includes.path = $$PREFIX/include/dde-file-manager +} else { + includes.path = $$INCLUDE_INSTALL_DIR/dde-file-manager +} + +includes.files += $$PWD/interfaces/*.h $$PWD/interfaces/plugins/*.h + +includes_private.path = $${includes.path}/private +includes_private.files += $$PWD/interfaces/private/*.h + +isEmpty(INCLUDE_INSTALL_DIR) { + gvfs_includes.path = $$PREFIX/include/dde-file-manager/gvfs +} else { + gvfs_includes.path = $$INCLUDE_INSTALL_DIR/dde-file-manager/gvfs +} + +gvfs_includes.files += $$PWD/gvfs/*.h + +isEmpty(INCLUDE_INSTALL_DIR) { + plugin_includes.path = $$PREFIX/include/dde-file-manager/dde-file-manager-plugins +} else { + plugin_includes.path = $$INCLUDE_INSTALL_DIR/dde-file-manager/dde-file-manager-plugins +} + +plugin_includes.files += $$PWD/../dde-file-manager-plugins/plugininterfaces/menu/*.h +plugin_includes.files += $$PWD/../dde-file-manager-plugins/plugininterfaces/preview/*.h +plugin_includes.files += $$PWD/../dde-file-manager-plugins/plugininterfaces/view/*.h + +QMAKE_PKGCONFIG_LIBDIR = $$target.path +QMAKE_PKGCONFIG_VERSION = $$VERSION +QMAKE_PKGCONFIG_DESTDIR = pkgconfig +QMAKE_PKGCONFIG_NAME = dde-file-manager +QMAKE_PKGCONFIG_DESCRIPTION = DDE File Manager Header Files +QMAKE_PKGCONFIG_INCDIR = $$includes.path + +templateFiles.path = $$APPSHAREDIR/templates + +isEqual(BUILD_MINIMUM, YES){ + templateFiles.files = skin/templates/newTxt.txt +}else{ + templateFiles.files = skin/templates/newDoc.doc \ + skin/templates/newExcel.xls \ + skin/templates/newPowerPoint.ppt \ + skin/templates/newDoc.wps \ + skin/templates/newExcel.et \ + skin/templates/newPowerPoint.dps \ + skin/templates/newTxt.txt +} + +mimetypeFiles.path = $$APPSHAREDIR/mimetypes +mimetypeFiles.files += \ + mimetypes/archive.mimetype \ + mimetypes/text.mimetype \ + mimetypes/video.mimetype \ + mimetypes/audio.mimetype \ + mimetypes/image.mimetype \ + mimetypes/executable.mimetype \ + mimetypes/backup.mimetype + +mimetypeAssociations.path = $$APPSHAREDIR/mimetypeassociations +mimetypeAssociations.files += \ + mimetypeassociations/mimetypeassociations.json + +TRANSLATIONS += $$PWD/translations/$${TARGET}.ts \ + $$PWD/translations/$${TARGET}_zh_CN.ts + +# Automating generation .qm files from .ts files +CONFIG(release, debug|release) { + !system($$PWD/generate_translations.sh): error("Failed to generate translation") + !system($$PWD/update_translations.sh): error("Failed to generate translation") +# DEFINES += QT_NO_DEBUG_OUTPUT +} + +translations.path = $$APPSHAREDIR/translations +translations.files = translations/*.qm + +icon.path = $$ICONDIR +icon.files = skin/images/$${TARGET}.svg + +defaultConfig.path = $$APPSHAREDIR/config +defaultConfig.files = configure/default-view-states.json + +# readme file for create oem-menuextension directory +readmefile.path = $$PREFIX/share/deepin/$$TARGET/oem-menuextensions +readmefile.files = plugins/.readme + +# readme file for create context-menus directory +contextmenusfile.path = /usr/share/applications/context-menus +contextmenusfile.files = plugins/.readme + +appentry.path = $$APPSHAREDIR/extensions/appEntry +appentry.files = plugins/.readme + +INSTALLS += target templateFiles translations mimetypeFiles mimetypeAssociations appentry \ + icon includes includes_private gvfs_includes plugin_includes defaultConfig readmefile contextmenusfile policy + +DISTFILES += \ + mimetypeassociations/mimetypeassociations.json \ + confirm/deepin-vault-authenticateProxy \ + policy/com.deepin.pkexec.deepin-vault-authenticateProxy.policy + +include($$PWD/settings_dialog_json.pri) diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/deviceinfo.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/deviceinfo.pri new file mode 100644 index 0000000..feb52a4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/deviceinfo.pri @@ -0,0 +1,7 @@ +HEADERS += \ + $$PWD/udisklistener.h \ + $$PWD/udiskdeviceinfo.h + +SOURCES += \ + $$PWD/udisklistener.cpp \ + $$PWD/udiskdeviceinfo.cpp diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/udiskdeviceinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/udiskdeviceinfo.cpp new file mode 100644 index 0000000..bb25421 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/udiskdeviceinfo.cpp @@ -0,0 +1,533 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "udiskdeviceinfo.h" +#include "dfmapplication.h" + +#include "app/define.h" +#include "shutil/fileutils.h" +#include "utils.h" +#include "durl.h" +#include "udisklistener.h" +#include "singleton.h" +#include "gvfs/gvfsmountmanager.h" +#include "gvfs/qdrive.h" +#include "app/define.h" + +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "ddiskmanager.h" +#include "dblockdevice.h" +#include "ddiskdevice.h" +#include "ddiskmanager.h" + +#include + +#include +#include + +DFM_USE_NAMESPACE + +#if 0 // storage i10n +QT_TRANSLATE_NOOP3("DeepinStorage", "Data Disk", "Data Partition") +#endif + +UDiskDeviceInfo::UDiskDeviceInfo() + : DFileInfo("", false) +{ + +} + +UDiskDeviceInfo::UDiskDeviceInfo(UDiskDeviceInfoPointer info) + : UDiskDeviceInfo() +{ + setDiskInfo(info->getDiskInfo()); +} + +UDiskDeviceInfo::UDiskDeviceInfo(const DUrl &url) + : DFileInfo(url, false) +{ + +} + +UDiskDeviceInfo::UDiskDeviceInfo(const QString &url) + : DFileInfo(url, false) +{ + +} + +UDiskDeviceInfo::~UDiskDeviceInfo() +{ + +} + +void UDiskDeviceInfo::setDiskInfo(QDiskInfo diskInfo) +{ + m_diskInfo = diskInfo; + DUrl url = getMountPointUrl(); + + url.setQuery(getMountPoint()); + setUrl(url); +} + +QDiskInfo UDiskDeviceInfo::getDiskInfo() const +{ + return m_diskInfo; +} + +QString UDiskDeviceInfo::getId() const +{ + return m_diskInfo.id(); +} + +QString UDiskDeviceInfo::getIdType() const +{ + // getIdType + QString dbusPath = this->getDBusPath(); + QScopedPointer blDev(DDiskManager::createBlockDevice(dbusPath)); + return blDev->idType(); +} + +QString UDiskDeviceInfo::getName() const +{ + return m_diskInfo.name(); +} + +QString UDiskDeviceInfo::getType() const +{ + return m_diskInfo.type(); +} + +QString UDiskDeviceInfo::getPath() const +{ + return m_diskInfo.unix_device(); +} + +QString UDiskDeviceInfo::getDBusPath() const +{ + QString devicePath = this->getPath(); + // blumia: since we now both use the old gvfs interface and the new udisks2 interface + // we should convert the path from local volumn path to the dbus path which is + // used by our udisks2 wrapper classes. + devicePath.replace("dev", "org/freedesktop/UDisks2/block_devices"); + return devicePath; +} + +QString UDiskDeviceInfo::getMountPoint() const +{ + return m_diskInfo.mounted_root_uri(); +} + +DUrl UDiskDeviceInfo::getMountPointUrl() const +{ + DUrl t_url = GvfsMountManager::getRealMountUrl(m_diskInfo); + if (!getId().isEmpty()) { + return GvfsMountManager::getRealMountUrl(m_diskInfo); + } else { + return DUrl(); + } +} + +QString UDiskDeviceInfo::getIcon() const +{ + return m_diskInfo.iconName(); +} + +bool UDiskDeviceInfo::canEject() const +{ + return m_diskInfo.can_eject(); +} + +bool UDiskDeviceInfo::canStop() const +{ + qDebug() << gvfsMountManager->Drives.contains(getDiskInfo().drive_unix_device()) << getDiskInfo().drive_unix_device(); + if (gvfsMountManager->Drives.contains(getDiskInfo().drive_unix_device())) { + const QDrive &drive = gvfsMountManager->Drives.value(getDiskInfo().drive_unix_device()); + if (drive.start_stop_type() == G_DRIVE_START_STOP_TYPE_SHUTDOWN && drive.is_removable() && drive.can_stop()) { + return true; + } + } + return false; +} + +bool UDiskDeviceInfo::canUnmount() const +{ + return m_diskInfo.can_unmount(); +} + +bool UDiskDeviceInfo::optical() const +{ + QScopedPointer blkdev(DDiskManager::createBlockDevice(getDBusPath())); + QScopedPointer diskdev(DDiskManager::createDiskDevice(blkdev->drive())); + return diskdev->optical(); +} + +bool UDiskDeviceInfo::opticalBlank() const +{ + QScopedPointer blkdev(DDiskManager::createBlockDevice(getDBusPath())); + QScopedPointer diskdev(DDiskManager::createDiskDevice(blkdev->drive())); + return diskdev->opticalBlank(); +} + +bool UDiskDeviceInfo::opticalReuseable() const +{ + QScopedPointer blkdev(DDiskManager::createBlockDevice(getDBusPath())); + QScopedPointer diskdev(DDiskManager::createDiskDevice(blkdev->drive())); + return diskdev->optical() && diskdev->media().indexOf("_rw") != -1 && !diskdev->opticalBlank(); +} + +qulonglong UDiskDeviceInfo::getFree() +{ + //when device is mounted, use QStorageInfo to get datas + if (canUnmount()) { + if (getMediaType() == dvd || getMediaType() == native || getMediaType() == removable) { + return QStorageInfo(getMountPointUrl().toLocalFile()).bytesFree(); + } + } + return m_diskInfo.free(); +} + +qulonglong UDiskDeviceInfo::getTotal() +{ + if (canUnmount()) { + if (getMediaType() == dvd || getMediaType() == native || getMediaType() == removable) { + return QStorageInfo(getMountPointUrl().toLocalFile()).bytesTotal(); + } + } + return m_diskInfo.total(); +} + +qint64 UDiskDeviceInfo::size() const +{ + return m_diskInfo.total(); +} + +QString UDiskDeviceInfo::fileName() const +{ + return getName(); +} + +QString UDiskDeviceInfo::fileDisplayName() const +{ + static QMap i18nMap { + {"data", "Data Disk"} + }; + + QString displayName = getName(); + + if (!displayName.isEmpty()) { + if (displayName.startsWith(ddeI18nSym)) { + QString i18nKey = displayName.mid(ddeI18nSym.size(), displayName.size() - ddeI18nSym.size()); + displayName = qApp->translate("DeepinStorage", i18nMap.value(i18nKey, i18nKey.toUtf8().constData())); + } + } else { + displayName = FileUtils::formatSize(size()); + } + + QString letter; + if (!m_diskInfo.uuid().isEmpty()) + letter = deviceListener->getVolumeLetters().value(m_diskInfo.uuid()); + else + qCritical() << "disk uuid is empty!"; + + if (!letter.isEmpty()) { + return QString("%1 (%2:)").arg(displayName, letter); + } else if (m_diskInfo.mounted_root_uri() != "/" + && m_diskInfo.id().startsWith("/dev/") + && DFMApplication::instance()->genericObtuselySetting()->value("Disk/Options", "windowsStyle").toBool()) { + // 记录最后一个被分配的盘符,默认为 C('C' + 0), C默认被系统盘所占用 + static quint8 lastPartNumber = 0; + quint8 partNumber = DFMApplication::instance()->genericObtuselySetting()->value("Disk/Options", m_diskInfo.id().append("/partNumber")).toUInt(); + + if (partNumber > 0) { + if (partNumber > lastPartNumber) { + lastPartNumber = partNumber; + } + + return QString("%1 (%2:)").arg(displayName).arg(QChar('C' + partNumber)); + } + + ++lastPartNumber; + DFMApplication::instance()->genericObtuselySetting()->setValue("Disk/Options", m_diskInfo.id().append("/partNumber"), lastPartNumber); + + return QString("%1 (%2:)").arg(displayName).arg(QChar('C' + lastPartNumber)); + } + + return displayName; +} + +UDiskDeviceInfo::MediaType UDiskDeviceInfo::getMediaType() const +{ + if (getType() == "native") { + return native; + } else if (getType() == "removable") { + return removable; + } else if (getType() == "network") { + return network; + } else if (getType() == "smb") { + return network; + } else if (getType() == "phone") { + return phone; + } else if (getType() == "iphone") { + return iphone; + } else if (getType() == "camera") { + return camera; + } else if (getType() == "dvd") { + return dvd; + } else { + return unknown; + } +} + +QString UDiskDeviceInfo::deviceTypeDisplayName() const +{ + if (getType() == "native") { + return QObject::tr("Local disk"); + } else if (getType() == "removable") { + return QObject::tr("Removable disk"); + } else if (getType() == "network") { + return QObject::tr("Network shared directory"); + } else if (getType() == "phone") { + return QObject::tr("Android mobile device"); + } else if (getType() == "iphone") { + return QObject::tr("Apple mobile device"); + } else if (getType() == "camera") { + return QObject::tr("Camera"); + } else if (getType() == "dvd") { + return QObject::tr("DVD"); + } else { + return QObject::tr("Unknown device"); + } +} + +QString UDiskDeviceInfo::sizeDisplayName() const +{ + if (filesCount() <= 1) { + return QObject::tr("%1 item").arg(filesCount()); + } else { + return QObject::tr("%1 items").arg(filesCount()); + } +} + +int UDiskDeviceInfo::filesCount() const +{ + return FileUtils::filesCount(const_cast(this)->getMountPointUrl().toLocalFile()); +} + +bool UDiskDeviceInfo::isReadable() const +{ + return true; +} + +bool UDiskDeviceInfo::isWritable() const +{ + return true; +} + +bool UDiskDeviceInfo::canRename() const +{ + QString devicePath = this->getDBusPath(); + + DBlockDevice *partition = DDiskManager::createBlockDevice(devicePath, nullptr); + bool result = partition->canSetLabel(); + partition->deleteLater(); + + return result; +} + +QIcon UDiskDeviceInfo::fileIcon() const +{ + return fileIcon(128, 128); +} + +QIcon UDiskDeviceInfo::fileIcon(int width, int height) const +{ +#define QResIcon( freedesktop_icon_name, res_icon_name ) \ + QIcon::fromTheme( freedesktop_icon_name , QIcon(svgToHDPIPixmap(":/devices/images/device/" res_icon_name "-256px.svg", width, height))) + + if (getType() == "native") { + return QResIcon("drive-harddisk", "drive-harddisk"); + } else if (getType() == "removable") { + return QResIcon("drive-removable-media-usb", "drive-removable-media-usb"); + } else if (getType() == "network") { + return QResIcon("drive-network", "drive-network"); + } else if (getType() == "phone") { + return QResIcon("phone-android", "android-device"); + } else if (getType() == "iphone") { + return QResIcon("phone-ios", "ios-device"); + } else if (getType() == "camera") { + return QResIcon("camera-photo", "camera"); + } else if (getType() == "dvd") { + return QResIcon("drive-optical", "media-dvd"); + } else { + return QResIcon("drive-harddisk", "drive-harddisk"); + } +#undef QResIcon +} + +bool UDiskDeviceInfo::isDir() const +{ + return true; +} + +DUrl UDiskDeviceInfo::parentUrl() const +{ + return DUrl::fromComputerFile("/"); +} + +QVector UDiskDeviceInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + QVector actionKeys; + + if (type == SpaceArea) { + return actionKeys; + } + + qDebug() << const_cast(this)->getMountPointUrl(); + + actionKeys.reserve(6); + + actionKeys << MenuAction::OpenDisk + << MenuAction::OpenDiskInNewWindow + << MenuAction::OpenDiskInNewTab + << MenuAction::Separator; + + if (canRename()) { + actionKeys << MenuAction::Rename; + } + + if (canEject()) { + actionKeys << MenuAction::Eject; + } + + if (canStop()) { + actionKeys << MenuAction::SafelyRemoveDrive; + } + + if (canUnmount()) { + actionKeys << MenuAction::Unmount; + } else { + actionKeys << MenuAction::Mount; + } + + if (getMediaType() == removable) { + actionKeys << MenuAction::FormatDevice; + } + + if (getId().startsWith("smb://") + || getId().startsWith("ftp://") + || getId().startsWith("sftp://")) { + actionKeys << MenuAction::ForgetPassword; + } + actionKeys << MenuAction::Separator << MenuAction::Property; + + return actionKeys; +} + +QSet UDiskDeviceInfo::disableMenuActionList() const +{ + QSet actionKeys = DAbstractFileInfo::disableMenuActionList(); + + if (DFMGlobal::isRootUser()) { + actionKeys << MenuAction::Unmount; + } + + /*Disable unmount of native disk in x86 pro*/ + if (getMediaType() == native && DFMApplication::instance()->genericAttribute(DFMApplication::GA_DisableNonRemovableDeviceUnmount).toBool()) { + actionKeys << MenuAction::Unmount; + } + + if (!canUnmount()) { + actionKeys << MenuAction::Property; + } + + + return actionKeys; +} + +DUrl UDiskDeviceInfo::getUrlByNewFileName(const QString &fileName) const +{ + DUrl url = DUrl::fromDeviceId(getId()); + QUrlQuery query; + query.addQueryItem("new_name", fileName); + url.setQuery(query); + + return url; +} + +DUrl UDiskDeviceInfo::getUrlByChildFileName(const QString &fileName) const +{ + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(nullptr, redirectedFileUrl()); + return fileInfo ? fileInfo->getUrlByChildFileName(fileName) : DUrl(); +} + +bool UDiskDeviceInfo::canRedirectionFileUrl() const +{ + return !getMountPointUrl().isEmpty(); +} + +DUrl UDiskDeviceInfo::redirectedFileUrl() const +{ + DUrl ret = getMountPointUrl(); + + const QStringList &nodes = DDiskManager::resolveDeviceNode(m_diskInfo.unix_device(), {}); + QString dbuspath = nodes.isEmpty() ? QString() : nodes.first(); + QScopedPointer blkdev(DDiskManager::createBlockDevice(dbuspath)); + QScopedPointer drive(DDiskManager::createDiskDevice(blkdev->drive())); + if (drive->optical()) { + ret = DUrl::fromBurnFile(m_diskInfo.unix_device() + "/" BURN_SEG_ONDISC); + } + + return ret; +} + +QVariantHash UDiskDeviceInfo::extraProperties() const +{ + QVariantHash attrMap; + + bool can_unmount = getMediaType() == native ? !DFMApplication::instance()->genericAttribute(DFMApplication::GA_DisableNonRemovableDeviceUnmount).toBool() : true; + + attrMap.insert("deviceId", getId()); + attrMap.insert("mediaType", static_cast(getMediaType())); + attrMap.insert("canMount", getDiskInfo().can_mount()); + attrMap.insert("canUnmount", canUnmount() && can_unmount); + attrMap.insert("canEject", canEject() && can_unmount); + attrMap.insert("canStop", canStop()); + attrMap.insert("isMounted", !getMountPointUrl().isEmpty()); + attrMap.insert("mountPointUrl", getMountPointUrl().toString()); + attrMap.insert("isRemovable", m_diskInfo.is_removable() && can_unmount); + attrMap.insert("optical", optical()); + attrMap.insert("opticalReuseable", opticalReuseable()); + + return attrMap; +} + +bool UDiskDeviceInfo::exists() const +{ + if (fileUrl().isComputerFile()) { + return true; + } + + return true; +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/udiskdeviceinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/udiskdeviceinfo.h new file mode 100644 index 0000000..dea3f29 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/udiskdeviceinfo.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef UDISKDEVICEINFO_H +#define UDISKDEVICEINFO_H + +#include "dfileinfo.h" + +#include +#include +#include +#include +#include "gvfs/qdiskinfo.h" + +class UDiskDeviceInfo; +typedef QExplicitlySharedDataPointer UDiskDeviceInfoPointer; + +class UDiskDeviceInfo : public DFileInfo +{ +public: + enum MediaType { + unknown, + native, + phone, + iphone, + removable, + camera, + network, + dvd + }; + + UDiskDeviceInfo(); + explicit UDiskDeviceInfo(UDiskDeviceInfoPointer info); + explicit UDiskDeviceInfo(const DUrl &url); + explicit UDiskDeviceInfo(const QString &url); + + ~UDiskDeviceInfo() override; + void setDiskInfo(QDiskInfo diskInfo); + QDiskInfo getDiskInfo() const; + QString getId() const; + QString getIdType() const; + QString getName() const; + QString getType() const; + QString getPath() const; + QString getDBusPath() const; + QString getMountPoint() const; + DUrl getMountPointUrl() const; + QString getIcon() const; + bool canEject() const; + bool canStop() const; + bool canUnmount() const; + bool optical() const; + bool opticalBlank() const; + bool opticalReuseable() const; + qulonglong getFree(); + qulonglong getTotal(); + qint64 size() const override; + QString fileName() const override; + QString fileDisplayName() const override; + MediaType getMediaType() const; + QString deviceTypeDisplayName() const; + QString sizeDisplayName() const override; + int filesCount() const override; + + bool isReadable() const override; + bool isWritable() const override; + + bool canRename() const override; + QIcon fileIcon() const override; + QIcon fileIcon(int width, int height) const; + bool isDir() const override; + DUrl parentUrl() const override; + + QVector menuActionList(MenuType type) const override; + QSet disableMenuActionList() const override; + + DUrl getUrlByNewFileName(const QString &fileName) const override; + DUrl getUrlByChildFileName(const QString &fileName) const override; + + bool canRedirectionFileUrl() const override; + DUrl redirectedFileUrl() const override; + + QVariantHash extraProperties() const override; + + bool exists() const override; + +private: + QDiskInfo m_diskInfo; + QString ddeI18nSym = QStringLiteral("_dde_"); +}; + +#endif // UDISKDEVICEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/udisklistener.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/udisklistener.cpp new file mode 100644 index 0000000..cfe0622 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/udisklistener.cpp @@ -0,0 +1,901 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "udisklistener.h" +#include "fstab.h" +#include "dfileservices.h" +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "disomaster.h" + +#include "app/define.h" +#include "app/filesignalmanager.h" + +#include "controllers/subscriber.h" +#include "singleton.h" + +#include "views/dfmopticalmediawidget.h" +#include "gvfs/gvfsmountmanager.h" +#include "udiskdeviceinfo.h" +#include "dblockdevice.h" +#include "ddiskdevice.h" +#include "ddiskmanager.h" +#include "shutil/fileutils.h" +#include "dialogs/dialogmanager.h" +#include "private/dabstractfilewatcher_p.h" +#include "app/define.h" +#include +#include +#include +#include + +#include +#include +#include +#include + + +class UDiskFileWatcher; +class UDiskFileWatcherPrivate : public DAbstractFileWatcherPrivate +{ +public: + explicit UDiskFileWatcherPrivate(DAbstractFileWatcher *qq) + : DAbstractFileWatcherPrivate(qq) {} + + bool start() override + { + started = true; + return true; + } + + bool stop() override + { + started = false; + return true; + } +}; + +class UDiskFileWatcher : public DAbstractFileWatcher +{ +public: + explicit UDiskFileWatcher(const DUrl &url, QObject *parent = nullptr) + : DAbstractFileWatcher(*new UDiskFileWatcherPrivate(this), url, parent) + { + + } +}; + +UDiskListener::UDiskListener(QObject *parent): + DAbstractFileController(parent) +{ + initDiskManager(); + initConnect(); + loadCustomVolumeLetters(); + + fileService->setFileUrlHandler(DEVICE_SCHEME, "", this); +} + +UDiskListener::~UDiskListener() +{ + DFileService::unsetFileUrlHandler(this); +} + +void UDiskListener::initDiskManager() +{ + m_diskMgr = new DDiskManager(this); + m_diskTimer = new QTimer(this); + m_diskMgr->setWatchChanges(true); + QStringList blDevList = m_diskMgr->blockDevices({}); + for (const QString &str : blDevList) { + insertFileSystemDevice(str); + } + +// 以下这段定时器代码可解决打开光驱访问文件后,物理弹出光驱,文管界面却没能卸载光驱设备的问题。 + connect(m_diskTimer, &QTimer::timeout, this, &UDiskListener::loopCheckCD); +} + +void UDiskListener::initConnect() +{ + connect(m_diskMgr, &DDiskManager::fileSystemAdded, this, &UDiskListener::insertFileSystemDevice); + connect(m_diskMgr, &DDiskManager::fileSystemRemoved, this, [this](const QString & path) { + delete m_fsDevMap.take(path); + }); + connect(gvfsMountManager, &GvfsMountManager::mount_added, this, &UDiskListener::addMountDiskInfo); + connect(gvfsMountManager, &GvfsMountManager::mount_removed, this, &UDiskListener::removeMountDiskInfo); + connect(gvfsMountManager, &GvfsMountManager::volume_added, this, &UDiskListener::addVolumeDiskInfo); + connect(gvfsMountManager, &GvfsMountManager::volume_removed, this, &UDiskListener::removeVolumeDiskInfo); + connect(gvfsMountManager, &GvfsMountManager::volume_changed, this, &UDiskListener::changeVolumeDiskInfo); + + connect(fileSignalManager, &FileSignalManager::stopCdScanTimer, this, [ = ](const QString & strDev) { + Q_UNUSED(strDev) + if (m_diskTimer->isActive()) { + m_diskTimer->stop(); + qDebug() << "timer stop, curr cdrom:" << m_nCDRomCount; + } + }); + connect(fileSignalManager, &FileSignalManager::restartCdScanTimer, this, [ = ](const QString & strDev) { + Q_UNUSED(strDev) + if (m_nCDRomCount > 0 && !m_diskTimer->isActive()) { + m_diskTimer->start(3000); + qDebug() << "timer restart, curr cdrom:" << m_nCDRomCount; + } + }); +} + +UDiskDeviceInfoPointer UDiskListener::getDevice(const QString &id) +{ + if (m_map.contains(id)) { + return m_map[id]; + } else { + return UDiskDeviceInfoPointer(); + } +} + +void UDiskListener::addDevice(UDiskDeviceInfoPointer device) +{ + m_map.insert(device->getDiskInfo().id(), device); + m_list.append(device); + + + DAbstractFileWatcher::ghostSignal(DUrl(DEVICE_ROOT), + &DAbstractFileWatcher::subfileCreated, + DUrl::fromDeviceId(device->getId())); + + if (device->getDiskInfo().drive_unix_device().contains("/dev/sr")) {// 探测到有光驱设备接入,启动光驱设备检测定时器 + m_nCDRomCount++; + if (!m_diskTimer) + m_diskTimer = new QTimer; + if (!m_diskTimer->isActive()) { + m_diskTimer->start(3000); + qDebug() << "timer start, curr cdrom:" << m_nCDRomCount; + } + } + emit volumeAdded(device); +} + +void UDiskListener::removeDevice(UDiskDeviceInfoPointer device) +{ + m_list.removeOne(device); + m_map.remove(device->getDiskInfo().id()); + if (device->getDiskInfo().drive_unix_device().contains("/dev/sr")) { + m_nCDRomCount--; + if (m_nCDRomCount == 0) { + m_diskTimer->stop(); + qDebug() << "timer stop, curr cdrom: " << m_nCDRomCount; + } + } + + DAbstractFileWatcher::ghostSignal(DUrl(DEVICE_ROOT), + &DAbstractFileWatcher::fileDeleted, + DUrl::fromDeviceId(device->getId())); +} + +bool UDiskListener::renameFile(const QSharedPointer &event) const +{ + const DUrl &oldUrl = event->fromUrl(); + const DUrl &newUrl = event->toUrl(); + + const QSharedPointer e(new DFMCreateFileInfoEvent(nullptr, oldUrl)); + const DAbstractFileInfoPointer &oldDevicePointer = UDiskListener::createFileInfo(e); + + DAbstractFileInfo *info = oldDevicePointer.data(); + UDiskDeviceInfo *udiskInfo = dynamic_cast(info); + QString devicePath; + if (udiskInfo) + devicePath = udiskInfo->getDBusPath(); + QUrlQuery query(newUrl); + QString newName = query.queryItemValue("new_name"); + DBlockDevice *partition = DDiskManager::createBlockDevice(devicePath, nullptr); + + if (!partition) { + return false; + } + + // set new label name + partition->setLabel(newName, {}); + + // check if we got error + QDBusError err = DDiskManager::lastError(); + qDebug() << err.type(); + switch (err.type()) { + case QDBusError::NoReply: + // blumia: user doesn't do action and caused a dbus message reply timeout error (org.freedesktop.DBus.Error.NoReply). + // just return it and don't show any error message dialog. + // notice that don't be confused with another timeout-releated error type (org.freedesktop.DBus.Error.Timeout + // and org.freedesktop.DBus.Error.TimedOut), the `Timeout` one *possibly* means a socket ETIMEDOUT error + // and the `Timedout` one means certain timeout errors. + // see also: https://dbus.freedesktop.org/doc/api/html/group__DBusProtocol.html + // https://www.freedesktop.org/wiki/Software/DBusBindingErrors/ (¯\_(ツ)_/¯) + return false; + case QDBusError::NoError: + // blumia: when renamed, a DBus signal will be sent by udisks2, and it will trigger `fileSystemDeviceIdLabelChanged()` + // we don't need do rename here so just return true. + return true; + default: + dialogManager->showErrorDialog(tr("Failed to rename the label"), err.message()); + return false; + } + + return false; +} + +void UDiskListener::update() +{ + QStringList keys; + + if (DFMGlobal::isRootUser()) { + keys.append(GvfsMountManager::Lsblk_Keys); + } else { + keys.append(GvfsMountManager::Volumes_Drive_Keys); + keys.append(GvfsMountManager::Volumes_No_Drive_Keys); + keys.append(GvfsMountManager::NoVolumes_Mounts_Keys); + } + foreach (QString key, keys) { + QDiskInfo diskInfo = GvfsMountManager::DiskInfos.value(key); + if (diskInfo.isValid()) { + addMountDiskInfo(diskInfo); + } + } +} + + +QString UDiskListener::lastPart(const QString &path) +{ + return path.split('/').last(); +} + + +UDiskDeviceInfoPointer UDiskListener::hasDeviceInfo(const QString &id) +{ + return m_map.value(id); +} + +void UDiskListener::addSubscriber(Subscriber *sub) +{ + if (!m_subscribers.contains(sub)) { + m_subscribers.append(sub); + } +} + +void UDiskListener::removeSubscriber(Subscriber *sub) +{ + if (m_subscribers.contains(sub)) { + m_subscribers.removeOne(sub); + } +} + +QMap UDiskListener::getAllDeviceInfos() +{ + return m_map; +} + +QList UDiskListener::getDeviceList() +{ + return m_list; +} + +QList UDiskListener::getMountList() +{ + return m_mountList; +} + +bool UDiskListener::isDeviceFolder(const QString &path) const +{ + for (int i = 0; i < m_list.size(); i++) { + UDiskDeviceInfoPointer info = m_list.at(i); + if (info->getMountPointUrl().toLocalFile() == path) { + return true; + } + } + return false; +} + +bool UDiskListener::isInDeviceFolder(const QString &path) const +{ + for (int i = 0; i < m_list.size(); i++) { + UDiskDeviceInfoPointer info = m_list.at(i); + if (info && !info->getMountPointUrl().toLocalFile().isEmpty()) { + if (path.startsWith(info->getMountPointUrl().toLocalFile())) { + return true; + } + } + } + return false; +} + +bool UDiskListener::isInRemovableDeviceFolder(const QString &path) const +{ + QList mediaTypes = {UDiskDeviceInfo::removable, + UDiskDeviceInfo::iphone, + UDiskDeviceInfo::phone, + UDiskDeviceInfo::camera + }; + for (int i = 0; i < m_list.size(); i++) { + UDiskDeviceInfoPointer info = m_list.at(i); + if (mediaTypes.contains(info->getMediaType())) { + if (!info->getMountPointUrl().isEmpty()) { + if (path.startsWith(info->getMountPointUrl().toLocalFile())) { + return true; + } + } + } + } + return false; +} + +UDiskDeviceInfoPointer UDiskListener::getDeviceByDevicePath(const QString &deveicePath) +{ + for (int i = 0; i < m_list.size(); i++) { + UDiskDeviceInfoPointer info = m_list.at(i); + if (info && info->getPath() == deveicePath) { + return info; + } + } + return UDiskDeviceInfoPointer(); +} + +UDiskDeviceInfoPointer UDiskListener::getDeviceByMountPoint(const QString &mountPoint) +{ + for (int i = 0; i < m_list.size(); i++) { + UDiskDeviceInfoPointer info = m_list.at(i); + if (info && !info->getMountPoint().isEmpty()) { + if (DUrl(info->getMountPoint()) == DUrl(mountPoint)) { + return info; + } + + // TODO: this is a polyfill since getting GFileInfo from network devices and mounted + // devices (both provided by gio) will return different uri (case insensitive + // when getting uri from network device, or say, samba/smb uri). + // this should be fixed or report to upstream. + if (mountPoint.startsWith("smb://")) { + QString source = mountPoint; + QString target = info->getMountPoint(); + + if (source.endsWith("/")) { + source.chop(1); + } + + source = QUrl::fromPercentEncoding(source.toUtf8()); + + if (target.endsWith("/")) { + target.chop(1); + } + + target = QUrl::fromPercentEncoding(target.toUtf8()); + + if (QString::compare(source, target, Qt::CaseInsensitive) == 0) { + return info; + } + } + } + } + return UDiskDeviceInfoPointer(); +} + +UDiskDeviceInfoPointer UDiskListener::getDeviceByMountPointFilePath(const QString &filePath) +{ + for (int i = 0; i < m_list.size(); i++) { + UDiskDeviceInfoPointer info = m_list.at(i); + if (info && !info->getMountPoint().isEmpty()) { + bool flag = DUrl(info->getMountPoint()) == DUrl(filePath); + if (!flag && filePath.startsWith(QString("%1").arg(info->getMountPointUrl().toLocalFile()))) { + return info; + } + } + } + return UDiskDeviceInfoPointer(); +} + +UDiskDeviceInfoPointer UDiskListener::getDeviceByPath(const QString &path) +{ + for (int i = 0; i < m_list.size(); i++) { + UDiskDeviceInfoPointer info = m_list.at(i); + if (info && !info->getMountPointUrl().isEmpty()) { + bool flag = (DUrl::fromLocalFile(path) == info->getMountPointUrl()); + + if (path.startsWith(info->getMountPointUrl().toLocalFile()) && flag) { + return info; + } + } + } + return UDiskDeviceInfoPointer(); +} +// fix task 29259 ,在判断空白光驱时就返回,是没有找到要用的UDiskDeviceInfoPointer,需要找的info在m_list中的位置在空白光驱之后,所以就不能直接返回 +// 使用bshareuse,是在判断可以共享时,根据路径取得UDiskDeviceInfoPointer,找到空白光驱就跳过,查询完m_list所有的元素 +UDiskDeviceInfoPointer UDiskListener::getDeviceByFilePath(const QString &path, const bool bshareuse) +{ + for (int i = 0; i < m_list.size(); i++) { + UDiskDeviceInfoPointer info = m_list.at(i); + if (info && !info->getMountPointUrl().isEmpty()) { + + bool t_ok = info->getId().contains("/dev/sr"); + Q_UNUSED(t_ok) + //获取空白光盘路径有问题,fix + if (!bshareuse && (info->getMountPointUrl().toString() == "burn:///" || info->getId().contains("/dev/sr"))) { + return UDiskDeviceInfoPointer(); + } + //获取空白光盘路径有问题,fix + // fix task 29259增加一个判断info->getMountPointUrl(),因为有可能空光盘的挂载点是空 + bool flag = (DUrl::fromLocalFile(path) == info->getMountPointUrl()); + if (!flag && !info->getMountPointUrl().toLocalFile().isEmpty() && path.startsWith(QString("%1").arg(info->getMountPointUrl().toLocalFile()))) { + return info; + } + } + } + return UDiskDeviceInfoPointer(); +} + +UDiskDeviceInfoPointer UDiskListener::getDeviceByDeviceID(const QString &deviceID) +{ + foreach (const UDiskDeviceInfoPointer &info, m_list) { + if (info->getId() == deviceID) { + return info; + } + } + return UDiskDeviceInfoPointer(); +} + +void UDiskListener::loadCustomVolumeLetters() +{ + const QSet &keys = DFMApplication::genericObtuselySetting()->keys("Disk/Volume"); + + for (const QString &key : keys) + m_volumeLetters.insert(key, DFMApplication::genericObtuselySetting()->value("Disk/Volume", key).toString()); +} + +QMap UDiskListener::getVolumeLetters() +{ + return m_volumeLetters; +} + +QMap UDiskListener::getMountedRemovableDiskDeviceInfos() +{ + QMap infos; + for (int i = 0; i < m_list.size(); i++) { + UDiskDeviceInfoPointer info = m_list.at(i); + if (info->getDiskInfo().is_removable() && info->getDiskInfo().can_unmount()) { + infos.insert(info->getDiskInfo().id(), info); + } + } + return infos; +} + +QMap UDiskListener::getCanSendDisksByUrl(QString filepath) +{ + QMap infos; + foreach (UDiskDeviceInfoPointer info, getMountedRemovableDiskDeviceInfos().values()) { + if (getDeviceByFilePath(filepath) == info) { + continue; + } + infos.insert(info->getDiskInfo().id(), info); + } + return infos; +} + +bool UDiskListener::isMountedRemovableDiskExits() +{ + for (int i = 0; i < m_list.size(); i++) { + UDiskDeviceInfoPointer info = m_list.at(i); + if (info->getDiskInfo().is_removable() && info->getDiskInfo().can_unmount()) { + return true; + } + } + return false; +} + +bool UDiskListener::isFileFromDisc(const QString &filePath) +{ + const QMap &&devices = getMountedRemovableDiskDeviceInfos(); + foreach (auto d, devices) { + // mountPath will be '/' if device is a blank disk + QString mountPath = d->getMountPointUrl().path(); + if (d->optical() && !d->opticalBlank() && mountPath != "/" + && !mountPath.isEmpty() && filePath.startsWith(mountPath)) { + qInfo() << filePath << "is belong to disc, mount point" << mountPath; + return true; + } + } + return false; +} + +void UDiskListener::appendHiddenDirs(const QString &path) +{ + if (!m_hiddenDirs.contains(path)) + m_hiddenDirs.append(path); +} + +QStringList UDiskListener::hiddenDirs() +{ + return m_hiddenDirs; +} + +bool UDiskListener::isBlockFile(const QString &filePath) +{ + const QMap &&devices = getMountedRemovableDiskDeviceInfos(); + foreach (auto d, devices) { + // mountPath will be '/' if device is a blank disk + // always return true if mountPath is '/' + if (d->optical() && d->opticalBlank()) + continue; + + QString mountPath = d->getMountPointUrl().path(); + if (!mountPath.isEmpty() && mountPath != "/" && filePath.startsWith(mountPath)) { + return true; + } + } + return false; +} + +bool UDiskListener::isFromNativeDisk(const QString &uuid) +{ + bool ret = false; + static std::once_flag flag; + + // 线程安全: getmntent 不是可重入函数, call_once 能保证线程安全 + // 性能: /etc/fstab 不是频繁变化的配置文件, 且配置后一般会重启才生效, 所以不必多次读取 + std::call_once(flag, [this]() { + FILE *f = nullptr; + f = setmntent(_PATH_FSTAB, "r"); + if (f) { + struct mntent *m = nullptr; + while ((m = getmntent(f))) { + QString name(m->mnt_fsname); + QStringList group(name.split("=")); + if (name.startsWith("UUID", Qt::CaseInsensitive) && group.size() == 2) { + m_uuids.append(group.at(1)); + } + } + endmntent(f); + } + }); + + if (m_uuids.contains(uuid)) + ret = true; + + return ret; +} + +void UDiskListener::addMountDiskInfo(const QDiskInfo &diskInfo) +{ + qDebug() << diskInfo; + UDiskDeviceInfoPointer device; + if (m_map.value(diskInfo.id())) { + device = m_map.value(diskInfo.id()); + device->setDiskInfo(diskInfo); + } else { + device = new UDiskDeviceInfo(); + device->setDiskInfo(diskInfo); + addDevice(device); + } + + if (!diskInfo.mounted_root_uri().isEmpty()) { + DAbstractFileWatcher::ghostSignal(DUrl(DEVICE_ROOT), + &DAbstractFileWatcher::fileAttributeChanged, + DUrl::fromDeviceId(device->getId())); + m_mountList.append(device); + emit mountAdded(device); + } + + qDebug() << m_subscribers; + for (Subscriber *sub : m_subscribers) { + QString url = device->getMountPointUrl().toString(); + QStringList devList = DDiskManager::resolveDeviceNode(device->getId(), {}); + if (!devList.isEmpty()) { + QScopedPointer blkdev(DDiskManager::createBlockDevice(devList.first())); + QScopedPointer drive(DDiskManager::createDiskDevice(blkdev->drive())); + if (drive->optical()) { + url = DUrl::fromBurnFile(device->getId() + "/" + BURN_SEG_ONDISC + "/").toString(); + } + qDebug() << url; + sub->doSubscriberAction(url); + } else { + if (DFMGlobal::isOpenAsAdmin()) + sub->doSubscriberAction(url); + } + } + + + +} + +void UDiskListener::removeMountDiskInfo(const QDiskInfo &diskInfo) +{ + UDiskDeviceInfoPointer device; + qDebug() << diskInfo; + qDebug() << m_map.contains(diskInfo.id()); + qDebug() << m_map; + if (m_map.value(diskInfo.id())) { + device = m_map.value(diskInfo.id()); + qDebug() << diskInfo.has_volume(); + if (diskInfo.has_volume()) { + device->setDiskInfo(diskInfo); + } else { + removeDevice(device); + } + + DAbstractFileWatcher::ghostSignal(DUrl(DEVICE_ROOT), + &DAbstractFileWatcher::fileAttributeChanged, + DUrl::fromDeviceId(device->getId())); + ISOMaster->nullifyDevicePropertyCache(QString(diskInfo.drive_unix_device())); + m_mountList.removeOne(device); + emit mountRemoved(device); + } +} + +void UDiskListener::addVolumeDiskInfo(const QDiskInfo &diskInfo) +{ + if (diskInfo.id().isEmpty()) { + return; + } + + UDiskDeviceInfoPointer device; + + if (m_map.contains(diskInfo.id())) { + device = m_map.value(diskInfo.id()); + device->setDiskInfo(diskInfo); + + emit volumeChanged(device); + } else { + device = new UDiskDeviceInfo(); + device->setDiskInfo(diskInfo); + addDevice(device); + } +} + +void UDiskListener::removeVolumeDiskInfo(const QDiskInfo &diskInfo) +{ + UDiskDeviceInfoPointer device; + qDebug() << diskInfo << m_list; + if (m_map.contains(diskInfo.id())) { + device = m_map.value(diskInfo.id()); +// removeDevice(device); +// emit volumeRemoved(device); + } else { + foreach (UDiskDeviceInfoPointer d, getDeviceList()) { + qDebug() << d->getDiskInfo(); + + if (!(diskInfo.uuid().isEmpty() && d->getDiskInfo().uuid() == diskInfo.uuid()) + || d->getDiskInfo().id() == diskInfo.id()) { + device = d; + break; + } + } + } + + ISOMaster->nullifyDevicePropertyCache(QString(diskInfo.drive_unix_device())); + + if (device) { + qDebug() << device->getDiskInfo(); + removeDevice(device); + emit volumeRemoved(device); + } +} + +void UDiskListener::changeVolumeDiskInfo(const QDiskInfo &diskInfo) +{ + UDiskDeviceInfoPointer device; + qDebug() << diskInfo; + qDebug() << m_map.value(diskInfo.id()); + + if (diskInfo.id().isEmpty()) { + return; + } + + if (m_map.value(diskInfo.id())) { + device = m_map.value(diskInfo.id()); + } else { + foreach (UDiskDeviceInfoPointer d, getDeviceList()) { + qDebug() << d->getDiskInfo().uuid() << diskInfo.uuid(); + if (d->getDiskInfo().uuid() == diskInfo.uuid()) { + device = d; + break; + } + } + } + if (device) { + device->setDiskInfo(diskInfo); + emit volumeChanged(device); + } + + // sp3 feature 35 光盘正在加载时,光标移动到光盘图标(左侧tab和计算机页面item),光标显示繁忙状态,加载完成后显示为正常指针 + if (diskInfo.id().contains("sr") && !diskInfo.mounted_root_uri().isEmpty()) { // 光盘已挂载上后挂载路径有值 + const QString &volTag = diskInfo.id().mid(5); + if (DFMOpticalMediaWidget::g_mapCdStatusInfo.contains(volTag)) { + DFMOpticalMediaWidget::g_mapCdStatusInfo[volTag].bLoading = false; + DFileService::instance()->setCursorBusyState(false); // 上面一行代码用于设置光标在移动时的判定条件,如果没有移动不会触发更新,因此这里要手动刷新一次状态 + } + } +} + +void UDiskListener::mount(const QString &path) +{ + qDebug() << path; + // main.cpp : handleEnvOfOpenAsAdmin 已经解决 gio root 用户下的挂载问题 + GvfsMountManager::mount(path); +#if 0 + // The gio's method cannot mount block device, use the UDisks's method replace it.(bug 42690) + if (DFMGlobal::isOpenAsAdmin() && mountByUDisks(path)) { + return; + } else { + GvfsMountManager::mount(path); + } +#endif +} + +bool UDiskListener::mountByUDisks(const QString &path) +{ + const QStringList &rootDeviceNode = DDiskManager::resolveDeviceNode(path, {}); + if (rootDeviceNode.isEmpty()) { + return false; + } + + const QString &udiskspath = rootDeviceNode.first(); + QSharedPointer blkdev(DDiskManager::createBlockDevice(udiskspath)); + if (blkdev) { + const QString &mountedPath = blkdev->mount({}); + qDebug() << "mounted path by udisks:" << mountedPath; + return mountedPath.isEmpty() ? false : true; + } + + return false; +} + +void UDiskListener::unmount(const QString &path) +{ + qDebug() << path; + GvfsMountManager::unmount(path); +} + +void UDiskListener::eject(const QString &path) +{ + GvfsMountManager::eject(path); +} + +void UDiskListener::stopDrive(const QString &path) +{ + GvfsMountManager::stop_device(path); +} + +void UDiskListener::forceUnmount(const QString &id) +{ + qDebug() << id; + if (m_map.contains(id)) { + UDiskDeviceInfoPointer device = m_map.value(id); + QStringList args; + args << "mount" << "-f" ; + if (device->canEject()) { + args << "-e" << device->getMountPointUrl().toLocalFile(); + } else { + args << "-u" << device->getMountPointUrl().toLocalFile(); + } + bool reslut = QProcess::startDetached("gio", args); + qDebug() << "gio mount" << args << reslut; + } +} + +void UDiskListener::fileSystemDeviceIdLabelChanged(const QString &labelName) +{ + DBlockDevice *blDev = qobject_cast(QObject::sender()); + DUrl oldUrl, newUrl; + oldUrl.setScheme(DEVICE_SCHEME); + if (blDev) + oldUrl.setPath(QString::fromLatin1(blDev->device())); + newUrl = oldUrl; + QUrlQuery query; + query.addQueryItem("new_name", labelName); + newUrl.setQuery(query); + DAbstractFileWatcher::ghostSignal(DUrl(DEVICE_ROOT), &DAbstractFileWatcher::fileMoved, oldUrl, newUrl); +} + +/*! + * \brief Insert a block device to filesysem device map. + * + * Won't insert if a block device ( \a dbusPath ) is not a filesystem patition + * + * \param dbusPath + */ +void UDiskListener::insertFileSystemDevice(const QString dbusPath) +{ + DBlockDevice *blDev = DDiskManager::createBlockDevice(dbusPath); + if (blDev->hasFileSystem()) { + blDev->setWatchChanges(true); + connect(blDev, &DBlockDevice::idLabelChanged, this, &UDiskListener::fileSystemDeviceIdLabelChanged); + m_fsDevMap.insert(dbusPath, blDev); + } else { + delete blDev; + } +} + +void UDiskListener::loopCheckCD() +{ + // 服务器版本会刷系统日志 + if (DFMGlobal::isServerSys()) + return; + for (int i = 0; i < m_list.size(); i++) { + UDiskDeviceInfoPointer info = m_list.at(i); + //qDebug() << "UDiskDeviceInfoPointer" << info->getDiskInfo().drive_unix_device(); + QString t_device = info->getDiskInfo().drive_unix_device(); + + //监测光驱托盘是否被弹出 + if (t_device.contains("/dev/sr")) { + + /* only try to open read/write if not root, since it doesn't seem + * to make a difference for root and can have negative side-effects + */ + if (geteuid()) { + QByteArray devBytes(t_device.toLatin1()); + int t_cdromfd = open(devBytes.data(), O_RDWR | O_NONBLOCK); + if (t_cdromfd != -1) { + close(t_cdromfd); + } + } + } + } +} + +const QList UDiskListener::getChildren(const QSharedPointer &event) const +{ + const QString &frav = event->url().fragment(); + + if (!frav.isEmpty()) { + const QList &list = fileService->getChildren(event->sender(), DUrl::fromLocalFile(frav), + event->nameFilters(), event->filters(), event->flags()); + + return list; + } + + QList infolist; + + for (int i = 0; i < m_list.size(); i++) { + DAbstractFileInfoPointer fileInfo(new UDiskDeviceInfo(DUrl::fromDeviceId(m_list.at(i)->getId()))); + infolist.append(fileInfo); + } + + return infolist; +} + +const DAbstractFileInfoPointer UDiskListener::createFileInfo(const QSharedPointer &event) const +{ + const QString &deviceId = event->url().path(); + + if (deviceId.isEmpty()) { + return DAbstractFileInfoPointer(); + } + + + for (int i = 0; i < m_list.size(); i++) { + UDiskDeviceInfoPointer info = m_list.at(i); + + if (info->getId() == deviceId) { + DAbstractFileInfoPointer fileInfo(new UDiskDeviceInfo(info)); + return fileInfo; + } + } + + return DAbstractFileInfoPointer(); +} + +DAbstractFileWatcher *UDiskListener::createFileWatcher(const QSharedPointer &event) const +{ + return new UDiskFileWatcher(event->url()); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/udisklistener.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/udisklistener.h new file mode 100644 index 0000000..a7be046 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/deviceinfo/udisklistener.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef UDISKLISTENER_H +#define UDISKLISTENER_H + +#include "dabstractfilecontroller.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "udiskdeviceinfo.h" + + +#define EventTypeVolumeAdded 1 +#define EventTypeVolumeRemoved 2 +#define EventTypeMountAdded 3 +#define EventTypeMountRemoved 4 + +class UDiskDeviceInfo; +class Subscriber; + +class DDiskManager; +class DBlockDevice; + +class UDiskListener : public DAbstractFileController +{ + Q_OBJECT + +public: + explicit UDiskListener(QObject *parent = nullptr); + ~UDiskListener(); + UDiskDeviceInfoPointer getDevice(const QString &id); + void addDevice(UDiskDeviceInfoPointer device); + void removeDevice(UDiskDeviceInfoPointer device); + bool renameFile(const QSharedPointer &event) const override; + + QString lastPart(const QString &path); + UDiskDeviceInfoPointer hasDeviceInfo(const QString &id); + + void addSubscriber(Subscriber *sub); + void removeSubscriber(Subscriber *sub); + + QMap getAllDeviceInfos(); + QList getDeviceList(); + QList getMountList(); + + bool isDeviceFolder(const QString &path) const; + bool isInDeviceFolder(const QString &path) const; + bool isInRemovableDeviceFolder(const QString &path) const; + + const QList getChildren(const QSharedPointer &event) const override; + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + + UDiskDeviceInfoPointer getDeviceByDevicePath(const QString &deveicePath); + UDiskDeviceInfoPointer getDeviceByMountPoint(const QString &mountPoint); + UDiskDeviceInfoPointer getDeviceByMountPointFilePath(const QString &filePath); + UDiskDeviceInfoPointer getDeviceByPath(const QString &path); + UDiskDeviceInfoPointer getDeviceByFilePath(const QString &path, const bool bshareuse = false); + UDiskDeviceInfoPointer getDeviceByDeviceID(const QString &deviceID); + + void loadCustomVolumeLetters(); + QMap getVolumeLetters(); + + QMap getMountedRemovableDiskDeviceInfos(); + + QMap getCanSendDisksByUrl(QString filepath); + + bool isMountedRemovableDiskExits(); + + bool isFileFromDisc(const QString &filePath); // 文件是否来自光盘 + void appendHiddenDirs(const QString &path); + QStringList hiddenDirs(); + bool isBlockFile(const QString &filePath); // 文件是否来自块设备 + bool isFromNativeDisk(const QString &uuid); // 是否为本地分区 + +private: + void initDiskManager(); + void initConnect(); + +signals: + void volumeAdded(UDiskDeviceInfoPointer device); + void volumeRemoved(UDiskDeviceInfoPointer device); + void volumeChanged(UDiskDeviceInfoPointer device); + void mountAdded(UDiskDeviceInfoPointer device); + void mountRemoved(UDiskDeviceInfoPointer device); + +public slots: + void update(); + void addMountDiskInfo(const QDiskInfo &diskInfo); + void removeMountDiskInfo(const QDiskInfo &diskInfo); + void addVolumeDiskInfo(const QDiskInfo &diskInfo); + void removeVolumeDiskInfo(const QDiskInfo &diskInfo); + void changeVolumeDiskInfo(const QDiskInfo &diskInfo); + void mount(const QString &path); + bool mountByUDisks(const QString &path); + void unmount(const QString &path); + void eject(const QString &path); + void stopDrive(const QString &path); + void forceUnmount(const QString &id); + +private slots: + void fileSystemDeviceIdLabelChanged(const QString &path); + void insertFileSystemDevice(const QString dbusPath); + void loopCheckCD(); + +private: + DDiskManager *m_diskMgr = nullptr; + QMap m_fsDevMap; + + QList m_list; + QList m_mountList; + QMap m_map; + QMap m_volumeLetters; + + QList m_subscribers; + + QTimer *m_diskTimer; + int m_nCDRomCount = 0; // 光驱接入个数 + + QStringList m_hiddenDirs; // feature: hide specified dirs of unremovable devices + QStringList m_uuids; // from /etc/fstab +}; + +#endif // UDISKLISTENER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/devicemanagement.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/devicemanagement.pri new file mode 100644 index 0000000..2a620b6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/devicemanagement.pri @@ -0,0 +1,18 @@ +# Actually for "Disk" or say "Partition" +# For replacing stuff in deviceinfo/ +# Replacement of current UDisksDevice* / GvfsMountManager* / etc. +HEADERS += \ + $$PWD/dfmabstractdeviceinterface.h \ + $$PWD/dfmudisks2deviceinfo.h \ + $$PWD/dfmvfsdeviceinfo.h \ + $$PWD/dfmdeviceinfo.h \ + $$PWD/dfminvaliddeviceinfo.h \ + $$PWD/dfmdevicecontroller.h + +SOURCES += \ + $$PWD/dfmudisks2deviceinfo.cpp \ + $$PWD/dfmvfsdeviceinfo.cpp \ + $$PWD/dfmdeviceinfo.cpp \ + $$PWD/dfminvaliddeviceinfo.cpp \ + $$PWD/dfmdevicecontroller.cpp \ + $$PWD/dfmabstractdeviceinterface.cpp diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmabstractdeviceinterface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmabstractdeviceinterface.cpp new file mode 100644 index 0000000..6231556 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmabstractdeviceinterface.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + + +#include "dfmabstractdeviceinterface.h" +DFM_BEGIN_NAMESPACE +DFMAbstractDeviceInterface::~DFMAbstractDeviceInterface() +{ +} +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmabstractdeviceinterface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmabstractdeviceinterface.h new file mode 100644 index 0000000..ba13e38 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmabstractdeviceinterface.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + + +#ifndef DFMABSTRACTDEVICEINTERFACE_H +#define DFMABSTRACTDEVICEINTERFACE_H + +#include + +DFM_BEGIN_NAMESPACE + +class DFMAbstractDeviceInterface +{ +public: + enum DeviceClassType { + invalid, + gvfs, + udisks2 + }; + virtual void mount() = 0; + + virtual bool unmountable() = 0; + virtual void unmount() = 0; + + virtual bool ejectable() = 0; + virtual void eject() = 0; + + virtual bool isReadOnly() const = 0; + + virtual QString name() const = 0; // device original name (can be empty). + virtual bool canRename() const = 0; // can be renamed or not. + virtual QString displayName() const = 0; // device display name. + virtual QString iconName() const = 0; // device icon (theme) name. + + virtual bool deviceUsageValid() const = 0; // storage valid / available or not. + virtual quint64 availableBytes() const = 0; + virtual quint64 freeBytes() const = 0; // may NOT equals to `total - available` + virtual quint64 totalBytes() const = 0; + + virtual QString mountpointPath() const = 0; // "/media/blumia/xxx" + + virtual enum DeviceClassType deviceClassType() { return invalid; } // gio / udisks2, for casting? + virtual ~DFMAbstractDeviceInterface() = 0; +}; + +DFM_END_NAMESPACE + +#endif // DFMABSTRACTDEVICEINTERFACE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmdevicecontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmdevicecontroller.cpp new file mode 100644 index 0000000..dbad622 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmdevicecontroller.cpp @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + + +#include "dfmdevicecontroller.h" + +#include "dfmevent.h" +#include "dfmdeviceinfo.h" +#include "dabstractfilewatcher.h" +#include "private/dabstractfilewatcher_p.h" + +#include +#include +#include + +DFM_USE_NAMESPACE + +class DFMDeviceWatcher; +class DFMDeviceWatcherPrivate : public DAbstractFileWatcherPrivate +{ +public: + explicit DFMDeviceWatcherPrivate(DAbstractFileWatcher *qq) + : DAbstractFileWatcherPrivate(qq) {} + + bool start() override + { + started = true; + return true; + } + + bool stop() override + { + started = false; + return true; + } +}; + +class DFMDeviceWatcher : public DAbstractFileWatcher +{ +public: + explicit DFMDeviceWatcher(const DUrl &url, QObject *parent = nullptr) + : DAbstractFileWatcher(*new DFMDeviceWatcherPrivate(this), url, parent) + { + + } +}; + +//------------------------------------------ + +DFMDeviceController::DFMDeviceController(QObject *parent) + : DAbstractFileController(parent) +{ + initDiskManager(); + initVfsManager(); +// initConnect(); +// loadCustomVolumeLetters(); + +// fileService->setFileUrlHandler(DEVICE_SCHEME, "", this); +} + +void DFMDeviceController::initDiskManager() +{ + m_diskMgr.reset(new DDiskManager(this)); + m_diskMgr->setWatchChanges(true); + + // "init" mounted filesystem device. + QStringList blDevList = m_diskMgr->blockDevices({}); + for (const QString &str : blDevList) { + fileSystemDeviceAdded(str); + } + + // watch change, signals. + connect(m_diskMgr.data(), &DDiskManager::fileSystemAdded, this, &DFMDeviceController::fileSystemDeviceAdded); + connect(m_diskMgr.data(), &DDiskManager::fileSystemRemoved, this, &DFMDeviceController::fileSystemDeviceRemoved); +} + +void DFMDeviceController::initVfsManager() +{ + m_vfsMgr.reset(new DFMVfsManager(this)); + + QList vfsdevList = m_vfsMgr->getVfsList(); + for (const QUrl &url : vfsdevList) { + virualFileSystemDeviceAttached(url); + } + + connect(m_vfsMgr.data(), &DFMVfsManager::vfsAttached, this, &DFMDeviceController::virualFileSystemDeviceAttached); + connect(m_vfsMgr.data(), &DFMVfsManager::vfsDetached, this, &DFMDeviceController::virualFileSystemDeviceDetached); +} + +const QList DFMDeviceController::getChildren(const QSharedPointer &event) const +{ + event->ignore(); + + QList list; + + // local + for (const QString &key : m_fsDevMap.keys()) { + list.append(DAbstractFileInfoPointer(new DFMDeviceInfo(DUrl::fromDeviceId(key)))); + } + + // vfs + for (const QUrl &url : m_vfsDevSet) { + list.append(DAbstractFileInfoPointer(new DFMDeviceInfo(DUrl(url)))); + } + + return list; +} + +const DAbstractFileInfoPointer DFMDeviceController::createFileInfo(const QSharedPointer &event) const +{ + const QString &devicePath = event->url().path(); + + if (devicePath.isEmpty()) { + return DAbstractFileInfoPointer(); + } + + DAbstractFileInfoPointer fileInfo(new DFMDeviceInfo(event->url())); + return fileInfo; +} + +DAbstractFileWatcher *DFMDeviceController::createFileWatcher(const QSharedPointer &event) const +{ + return new DFMDeviceWatcher(event->url()); +} + +void DFMDeviceController::mount(const QString &path) +{ + DUrl url = DUrl::fromUserInput(path); + if (url.hasScheme(DEVICE_SCHEME)) { + QString pathStr = url.path(); + if (!QUrl::fromUserInput(pathStr).scheme().isEmpty()) { + m_vfsMgr->attach(QUrl::fromUserInput(pathStr)); + } else { + QScopedPointer blDev(DDiskManager::createBlockDevice(pathStr)); + blDev->mount({}); + } + } else { + // consider accept path like "/dev/sda1" ? + // if not needed, we can only accept url with device:// scheme + } +} + +void DFMDeviceController::unmount(const QString &path) +{ + DUrl url = DUrl::fromUserInput(path); + if (url.hasScheme(DEVICE_SCHEME)) { + QString pathStr = url.path(); + if (!QUrl::fromUserInput(pathStr).scheme().isEmpty()) { + QScopedPointer vfsDev(DFMVfsDevice::create(QUrl::fromUserInput(pathStr))); + if (vfsDev) { + vfsDev->detachAsync(); + } + } else { + QScopedPointer blDev(DDiskManager::createBlockDevice(pathStr)); + blDev->unmount({}); + } + } else { + // consider accept path like "/dev/sda1" ? + // if not needed, we can only accept url with device:// scheme + } +} + +void DFMDeviceController::eject(const QString &path) +{ + Q_UNUSED(path) + throw "Not implemented"; +} + +void DFMDeviceController::stopDrive(const QString &path) +{ + Q_UNUSED(path) + throw "Not implemented"; +} + +void DFMDeviceController::forceUnmount(const QString &id) +{ + Q_UNUSED(id) + throw "Not implemented"; +} + +/*! + * \brief Insert a block device to filesysem device map. + * + * Won't insert if a block device ( \a dbusPath ) is not a filesystem patition + */ +void DFMDeviceController::fileSystemDeviceAdded(const QString dbusPath) +{ + DBlockDevice *blDev = DDiskManager::createBlockDevice(dbusPath); + if (blDev->hasFileSystem()) { + blDev->setWatchChanges(true); + connect(blDev, &DBlockDevice::idLabelChanged, this, &DFMDeviceController::fileSystemDeviceIdLabelChanged); + m_fsDevMap.insert(dbusPath, blDev); + // now we use dbusPath as device identifier + DAbstractFileWatcher::ghostSignal(DUrl(DEVICE_ROOT), + &DAbstractFileWatcher::subfileCreated, + DUrl::fromDeviceId(dbusPath)); + } else { + delete blDev; + } +} + +void DFMDeviceController::fileSystemDeviceRemoved(const QString dbusPath) +{ + delete m_fsDevMap.take(dbusPath); + // now we use dbusPath as device identifier + DAbstractFileWatcher::ghostSignal(DUrl(DEVICE_ROOT), + &DAbstractFileWatcher::subfileCreated, + DUrl::fromDeviceId(dbusPath)); +} + +void DFMDeviceController::fileSystemDeviceIdLabelChanged(const QString &labelName) +{ + DBlockDevice *blDev = qobject_cast(QObject::sender()); + DUrl oldUrl, newUrl; + oldUrl.setScheme(DEVICE_SCHEME); + oldUrl.setPath(blDev->drive()); + newUrl = oldUrl; + QUrlQuery query; + query.addQueryItem("new_name", labelName); + newUrl.setQuery(query); + DAbstractFileWatcher::ghostSignal(DUrl(DEVICE_ROOT), &DAbstractFileWatcher::fileMoved, oldUrl, newUrl); +} + +void DFMDeviceController::virualFileSystemDeviceAttached(const QUrl &url) +{ + if (m_vfsDevSet.contains(url)) return; + + m_vfsDevSet.insert(url); + // for vfs, device id is url. + DAbstractFileWatcher::ghostSignal(DUrl(DEVICE_ROOT), + &DAbstractFileWatcher::subfileCreated, + DUrl::fromDeviceId(url.toString())); +} + +void DFMDeviceController::virualFileSystemDeviceDetached(const QUrl &url) +{ + m_vfsDevSet.remove(url); + // for vfs, device id is url. + DAbstractFileWatcher::ghostSignal(DUrl(DEVICE_ROOT), + &DAbstractFileWatcher::fileDeleted, + DUrl::fromDeviceId(url.toString())); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmdevicecontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmdevicecontroller.h new file mode 100644 index 0000000..f8a5c8f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmdevicecontroller.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + + +#ifndef DFMDEVICECONTROLLER_H +#define DFMDEVICECONTROLLER_H + +#include +#include +#include + +DFM_BEGIN_NAMESPACE +class DFMVfsDevice; +DFM_END_NAMESPACE + +class DFMDeviceController : public DAbstractFileController +{ + Q_OBJECT + +public: + explicit DFMDeviceController(QObject *parent = nullptr); + + void initDiskManager(); + void initVfsManager(); + + const QList getChildren(const QSharedPointer &event) const override; + const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const override; + DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const override; + +signals: + void vfsMountAdded(const QUrl &url); + void vfsMountRemoved(const QUrl &url); + +public slots: + void mount(const QString &path); + void unmount(const QString &path); + void eject(const QString &path); + void stopDrive(const QString &path); + void forceUnmount(const QString &id); + +private slots: + // filesystem device managed by udisks2 + void fileSystemDeviceAdded(const QString dbusPath); + void fileSystemDeviceRemoved(const QString dbusPath); + void fileSystemDeviceIdLabelChanged(const QString &labelName); + // virtual filesystem (from network location) managed by gio + void virualFileSystemDeviceAttached(const QUrl &url); + void virualFileSystemDeviceDetached(const QUrl &url); + +private: + QScopedPointer m_diskMgr; + QScopedPointer m_vfsMgr; + + QMap m_fsDevMap; // key is udisks2 device dbus path + QSet m_vfsDevSet; // value is device scheme url with path as deviceId, eg. device:mtp://%5Busb%3A003,004%5D/ +}; + +#endif // DFMDEVICECONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmdeviceinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmdeviceinfo.cpp new file mode 100644 index 0000000..16130b4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmdeviceinfo.cpp @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + + +#include "dfmdeviceinfo.h" +#include "dfmabstractdeviceinterface.h" +#include "dfminvaliddeviceinfo.h" +#include "dfmudisks2deviceinfo.h" +#include "dfmvfsdeviceinfo.h" + +#include +#include + +#include + +DFM_USE_NAMESPACE + +DFMDeviceInfo::DFMDeviceInfo() + : DFileInfo("", false) +{ + c_attachedDevice.reset(new DFMInvalidDeviceInfo()); +} + +DFMDeviceInfo::DFMDeviceInfo(const DUrl &url) + : DFileInfo(url, false) +{ + using ClassType = DFMAbstractDeviceInterface::DeviceClassType; + ClassType devType = ClassType::invalid; + QString scheme = url.scheme(); + QString udisksDBusPath; + QUrl gvfsUrl; + + if (scheme.isEmpty() || scheme == FILE_SCHEME) { + // TODO: detect mounted list and check given url match a mountpoint? + devType = ClassType::invalid; + + if (url.path().contains(QStringLiteral("/org/freedesktop/UDisks2/"))) { + devType = ClassType::udisks2; + udisksDBusPath = url.path(); + } + } + + if (scheme == "udisks") { + devType = ClassType::udisks2; + udisksDBusPath = url.path(); + } + + if (scheme == DEVICE_SCHEME) { + QString pathStr = url.path(); + if (!QUrl::fromUserInput(pathStr).isEmpty()) { + devType = ClassType::gvfs; + gvfsUrl = QUrl::fromUserInput(pathStr); + } else { + devType = ClassType::udisks2; + udisksDBusPath = pathStr; + } + } + + if (url.isFTPFile() || url.isSFTPFile() || url.isSMBFile() || url.isMTPFile()) { + devType = ClassType::gvfs; + gvfsUrl = url; + } + + switch (devType) { + case ClassType::gvfs: + setVfsDeviceInfo(DUrl(gvfsUrl)); + break; + case ClassType::udisks2: + setUdisks2DeviceInfo(udisksDBusPath); + break; + default: + c_attachedDevice.reset(new DFMInvalidDeviceInfo()); + break; + } +} + +void DFMDeviceInfo::setUdisks2DeviceInfo(const QString &dbusPath) +{ + c_attachedDevice.reset(new DFMUdisks2DeviceInfo(dbusPath)); +} + +void DFMDeviceInfo::setVfsDeviceInfo(const DUrl &url) +{ + if (!url.scheme().isEmpty() && url.scheme() != FILE_SCHEME) { + c_attachedDevice.reset(new DFMVfsDeviceInfo(url)); + } +} + +bool DFMDeviceInfo::isValidDevice() const +{ + return c_attachedDevice->deviceClassType() != DFMAbstractDeviceInterface::invalid; +} + +quint64 DFMDeviceInfo::freeBytes() const +{ + return attachedDeviceConst()->freeBytes(); +} + +quint64 DFMDeviceInfo::totalBytes() const +{ + return attachedDeviceConst()->totalBytes(); +} + +DFMDeviceInfo::MediaType DFMDeviceInfo::mediaType() const +{ + // TODO + return unknown; +} + +bool DFMDeviceInfo::exists() const +{ + return true; +} + +QString DFMDeviceInfo::fileName() const +{ + return attachedDeviceConst()->name(); +} + +QString DFMDeviceInfo::fileDisplayName() const +{ + return attachedDeviceConst()->displayName(); +} + +bool DFMDeviceInfo::canRename() const +{ + return attachedDeviceConst()->canRename(); +} + +bool DFMDeviceInfo::isReadable() const +{ + return true; +} + +bool DFMDeviceInfo::isWritable() const +{ + return attachedDeviceConst()->isReadOnly(); +} + +qint64 DFMDeviceInfo::size() const +{ + return static_cast(attachedDeviceConst()->totalBytes()); +} + +int DFMDeviceInfo::filesCount() const +{ + QString mountPath = attachedDeviceConst()->mountpointPath(); + if (mountPath.isEmpty()) return 0; + return FileUtils::filesCount(mountPath); +} + +QIcon DFMDeviceInfo::fileIcon() const +{ + return QIcon::fromTheme(attachedDeviceConst()->iconName(), QIcon::fromTheme("drive-harddisk")); +} + +bool DFMDeviceInfo::isDir() const +{ + return true; +} + +DUrl DFMDeviceInfo::parentUrl() const +{ + return DUrl::fromComputerFile("/"); +} + +bool DFMDeviceInfo::canRedirectionFileUrl() const +{ + return attachedDeviceConst()->mountpointPath().isEmpty(); +} + +DUrl DFMDeviceInfo::redirectedFileUrl() const +{ + return DUrl::fromLocalFile(attachedDeviceConst()->mountpointPath()); +} + +DFMAbstractDeviceInterface *DFMDeviceInfo::attachedDevice() +{ + return c_attachedDevice.data(); +} + +const DFMAbstractDeviceInterface *DFMDeviceInfo::attachedDeviceConst() const +{ + return c_attachedDevice.data(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmdeviceinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmdeviceinfo.h new file mode 100644 index 0000000..bc36b6d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmdeviceinfo.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + + +#ifndef DFMDEVICEINFO_H +#define DFMDEVICEINFO_H + +#include "dfileinfo.h" + +DFM_BEGIN_NAMESPACE +class DFMAbstractDeviceInterface; +DFM_END_NAMESPACE + +class DFMDeviceInfo; +typedef QExplicitlySharedDataPointer DFMDeviceInfoPointer; + +class DFMDeviceInfo : public DFileInfo +{ +public: + enum MediaType { + unknown, + native, + phone, + iphone, + removable, + camera, + network, + dvd + }; + + DFMDeviceInfo(); + explicit DFMDeviceInfo(const DUrl &url); + + void setUdisks2DeviceInfo(const QString &dbusPath); + void setVfsDeviceInfo(const DUrl &url); + + bool isValidDevice() const; + quint64 freeBytes() const; + quint64 totalBytes() const; + MediaType mediaType() const; + + bool exists() const override; + + QString fileName() const override; + QString fileDisplayName() const override; + bool canRename() const override; + + bool isReadable() const override; + bool isWritable() const override; + + qint64 size() const override; + int filesCount() const override; + QIcon fileIcon() const override; + + bool isDir() const override; + DUrl parentUrl() const override; + + bool canRedirectionFileUrl() const override; + DUrl redirectedFileUrl() const override; + + DFM_NAMESPACE::DFMAbstractDeviceInterface* attachedDevice(); + const DFM_NAMESPACE::DFMAbstractDeviceInterface* attachedDeviceConst() const; + +private: + QScopedPointer c_attachedDevice; +}; + +#endif // DFMDEVICEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfminvaliddeviceinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfminvaliddeviceinfo.cpp new file mode 100644 index 0000000..67f0935 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfminvaliddeviceinfo.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + + +#include "dfminvaliddeviceinfo.h" + +#include + +DFM_BEGIN_NAMESPACE + +DFMInvalidDeviceInfo::DFMInvalidDeviceInfo() +{ + +} + +void DFMInvalidDeviceInfo::mount() +{ + +} + +bool DFMInvalidDeviceInfo::unmountable() +{ + return false; +} + +void DFMInvalidDeviceInfo::unmount() +{ + +} + +bool DFMInvalidDeviceInfo::ejectable() +{ + return false; +} + +void DFMInvalidDeviceInfo::eject() +{ + +} + +bool DFMInvalidDeviceInfo::isReadOnly() const +{ + return true; +} + +QString DFMInvalidDeviceInfo::name() const +{ + return QStringLiteral("Invalid Device"); +} + +bool DFMInvalidDeviceInfo::canRename() const +{ + return false; +} + +QString DFMInvalidDeviceInfo::displayName() const +{ + return QStringLiteral("Invalid Device"); +} + +QString DFMInvalidDeviceInfo::iconName() const +{ + return "dialog-error"; +} + +bool DFMInvalidDeviceInfo::deviceUsageValid() const +{ + return false; +} + +quint64 DFMInvalidDeviceInfo::availableBytes() const +{ + return -1; +} + +quint64 DFMInvalidDeviceInfo::freeBytes() const +{ + return -1; +} + +quint64 DFMInvalidDeviceInfo::totalBytes() const +{ + return 0; +} + +QString DFMInvalidDeviceInfo::mountpointPath() const +{ + return QString(); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfminvaliddeviceinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfminvaliddeviceinfo.h new file mode 100644 index 0000000..d6bd546 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfminvaliddeviceinfo.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + + +#ifndef DFMINVALIDDEVICEINFO_H +#define DFMINVALIDDEVICEINFO_H + +#include "dfmabstractdeviceinterface.h" + +#include + +DFM_BEGIN_NAMESPACE + +class DFMInvalidDeviceInfo : public DFMAbstractDeviceInterface +{ +public: + DFMInvalidDeviceInfo(); + + void mount() override; + + bool unmountable() override; + void unmount() override; + + bool ejectable() override; + void eject() override; + + bool isReadOnly() const override; + + QString name() const override; + bool canRename() const override; + QString displayName() const override; // device display name. + QString iconName() const override; // device icon (theme) name. + + bool deviceUsageValid() const override; // storage valid / available or not. + quint64 availableBytes() const override; + quint64 freeBytes() const override; // may NOT equals to `total - used` + quint64 totalBytes() const override; + + QString mountpointPath() const override; // "/media/blumia/xxx" +}; + +DFM_END_NAMESPACE + +#endif // DFMINVALIDDEVICEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmudisks2deviceinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmudisks2deviceinfo.cpp new file mode 100644 index 0000000..2b7e717 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmudisks2deviceinfo.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + + +#include "dfmudisks2deviceinfo.h" + +#include +#include +#include +#include + +#include + +DFM_BEGIN_NAMESPACE + +DFMUdisks2DeviceInfo::DFMUdisks2DeviceInfo(const DBlockDevice *blockDevicePointer) + : deviceDBusId(blockDevicePointer->path()) + , mountPoint(blockDevicePointer->mountPoints().first()) +{ + c_blockDevice.reset(DDiskManager::createBlockDevice(deviceDBusId)); // not take the ownership of the passed pointer. +} + +DFMUdisks2DeviceInfo::DFMUdisks2DeviceInfo(const QString &dbusPath) +{ + c_blockDevice.reset(DDiskManager::createBlockDevice(dbusPath)); // not take the ownership of the passed pointer. +} + +void DFMUdisks2DeviceInfo::mount() +{ + blockDevice()->mount({}); +} + +bool DFMUdisks2DeviceInfo::unmountable() +{ + QScopedPointer diskDev(DDiskManager::createDiskDevice(blockDevice()->drive())); + return diskDev->removable(); +} + +void DFMUdisks2DeviceInfo::unmount() +{ + blockDevice()->unmount({}); + QScopedPointer diskDev(DDiskManager::createDiskDevice(blockDevice()->drive())); + if (diskDev->optical()) { // is optical + if (diskDev->ejectable()) { + diskDev->eject({}); + } + } +} + +bool DFMUdisks2DeviceInfo::ejectable() +{ + QScopedPointer diskDev(DDiskManager::createDiskDevice(blockDevice()->drive())); + return diskDev->ejectable(); +} + +void DFMUdisks2DeviceInfo::eject() +{ + QScopedPointer diskDev(DDiskManager::createDiskDevice(blockDevice()->drive())); + if (diskDev->ejectable()) { + diskDev->eject({}); + } +} + +bool DFMUdisks2DeviceInfo::isReadOnly() const +{ + return blockDeviceConst()->readOnly(); +} + +QString DFMUdisks2DeviceInfo::name() const +{ + if (blockDeviceConst()->isValid()) { + return blockDeviceConst()->idLabel(); + } + + return QString(); +} + +bool DFMUdisks2DeviceInfo::canRename() const +{ + return blockDeviceConst()->canSetLabel(); +} + +QString DFMUdisks2DeviceInfo::displayName() const +{ + static QMap i18nMap { + {"data", "Data Disk"} + }; + + QStorageInfo storage_info(mountPoint); + bool hasLabelName = true; + QString result; + + if (blockDeviceConst()->isValid()) { + QString devName = blockDeviceConst()->idLabel(); + if (devName.isEmpty()) { + hasLabelName = false; + devName = qApp->translate("DeepinStorage", "%1 Volume").arg(FileUtils::formatSize(static_cast(blockDeviceConst()->size()))); + } + + // Deepin i10n Label text (_dde_text): + if (devName.startsWith(ddeI18nSym)) { + QString i18nKey = devName.mid(ddeI18nSym.size(), devName.size() - ddeI18nSym.size()); + devName = qApp->translate("DeepinStorage", i18nMap.value(i18nKey, i18nKey.toUtf8().constData())); + } + + result = devName; + } + + if (storage_info.isValid()) { + if (!hasLabelName) { + qint64 bytesTotal = storage_info.bytesTotal(); + result = qApp->translate("DeepinStorage", "%1 Volume").arg(FileUtils::formatSize(bytesTotal)); + } + } + + return result; +} + +QString DFMUdisks2DeviceInfo::iconName() const +{ + QScopedPointer diskDev(DDiskManager::createDiskDevice(blockDeviceConst()->drive())); + + bool isDvd = diskDev->optical(); + bool isRemovable = diskDev->removable(); + QString iconName = QStringLiteral("drive-harddisk"); + + if (isRemovable) { + iconName = QStringLiteral("drive-removable-media-usb"); + } + + if (isDvd) { + iconName = QStringLiteral("media-optical"); + } + + return iconName; +} + +bool DFMUdisks2DeviceInfo::deviceUsageValid() const +{ + QStorageInfo storage_info(mountPoint); + return storage_info.isValid(); +} + +quint64 DFMUdisks2DeviceInfo::availableBytes() const +{ + QStorageInfo storage_info(mountPoint); + + if (storage_info.isValid()) { + return static_cast(storage_info.bytesAvailable()); + } + + return static_cast(-1); +} + +quint64 DFMUdisks2DeviceInfo::freeBytes() const +{ + QStorageInfo storage_info(mountPoint); + + if (storage_info.isValid()) { + return static_cast(storage_info.bytesFree()); + } + + return static_cast(-1); +} + +quint64 DFMUdisks2DeviceInfo::totalBytes() const +{ + QStorageInfo storage_info(mountPoint); + + if (storage_info.isValid()) { + return static_cast(storage_info.bytesTotal()); + } + + return 0; +} + +QString DFMUdisks2DeviceInfo::mountpointPath() const +{ + return mountPoint; +} + +DFMAbstractDeviceInterface::DeviceClassType DFMUdisks2DeviceInfo::deviceClassType() +{ + return udisks2; +} + +DBlockDevice *DFMUdisks2DeviceInfo::blockDevice() +{ + return c_blockDevice.data(); +} + +const DBlockDevice *DFMUdisks2DeviceInfo::blockDeviceConst() const +{ + return c_blockDevice.data(); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmudisks2deviceinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmudisks2deviceinfo.h new file mode 100644 index 0000000..9470515 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmudisks2deviceinfo.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + + +#ifndef DFMUDISKS2DEVICEINFO_H +#define DFMUDISKS2DEVICEINFO_H + +#include "dfmabstractdeviceinterface.h" + +#include + +class DBlockDevice; + +DFM_BEGIN_NAMESPACE + +class DFMUdisks2DeviceInfo : public DFMAbstractDeviceInterface +{ +public: + explicit DFMUdisks2DeviceInfo(const DBlockDevice *blockDevicePointer); + explicit DFMUdisks2DeviceInfo(const QString &dbusPath); + + void mount() override; + + bool unmountable() override; + void unmount() override; + + bool ejectable() override; + void eject() override; + + bool isReadOnly() const override; + + QString name() const override; + bool canRename() const override; + QString displayName() const override; // device display name. + QString iconName() const override; // device icon (theme) name. + + bool deviceUsageValid() const override; // storage valid / available or not. + quint64 availableBytes() const override; + quint64 freeBytes() const override; // may NOT equals to `total - used` + quint64 totalBytes() const override; + + QString mountpointPath() const override; // "/media/blumia/xxx" + + enum DeviceClassType deviceClassType() override; + + DBlockDevice* blockDevice(); + const DBlockDevice* blockDeviceConst() const; + +private: + QScopedPointer c_blockDevice; + QString deviceDBusId; + QString mountPoint; + + const QString ddeI18nSym = QStringLiteral("_dde_"); +}; + +DFM_END_NAMESPACE + +#endif // DFMUDISKS2DEVICEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmvfsdeviceinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmvfsdeviceinfo.cpp new file mode 100644 index 0000000..459f65d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmvfsdeviceinfo.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + + +#include "dfmvfsdeviceinfo.h" + +#include "dfmvfsdevice.h" + +DFM_BEGIN_NAMESPACE + +DFMVfsDeviceInfo::DFMVfsDeviceInfo(const QUrl mountpointUrl) +{ + c_vfsDevice.reset(DFMVfsDevice::create(mountpointUrl)); +} + +void DFMVfsDeviceInfo::mount() +{ + vfsDevice()->attach(); +} + +bool DFMVfsDeviceInfo::unmountable() +{ + return vfsDevice()->canDetach(); +} + +void DFMVfsDeviceInfo::unmount() +{ + vfsDevice()->detachAsync(); +} + +bool DFMVfsDeviceInfo::ejectable() +{ + return unmountable(); +} + +void DFMVfsDeviceInfo::eject() +{ + unmount(); +} + +QString DFMVfsDeviceInfo::name() const +{ + return vfsDeviceConst()->name(); +} + +bool DFMVfsDeviceInfo::canRename() const +{ + return false; +} + +QString DFMVfsDeviceInfo::displayName() const +{ + return name(); +} + +QString DFMVfsDeviceInfo::iconName() const +{ + QList iconList = vfsDeviceConst()->iconList(); + + if (iconList.empty()) { + return QStringLiteral("drive-network"); + } + + return iconList.first(); +} + +bool DFMVfsDeviceInfo::deviceUsageValid() const +{ + return true; +} + +quint64 DFMVfsDeviceInfo::availableBytes() const +{ + return vfsDeviceConst()->freeBytes(); +} + +quint64 DFMVfsDeviceInfo::freeBytes() const +{ + return vfsDeviceConst()->freeBytes(); +} + +quint64 DFMVfsDeviceInfo::totalBytes() const +{ + return vfsDeviceConst()->totalBytes(); +} + +QString DFMVfsDeviceInfo::mountpointPath() const +{ + return vfsDeviceConst()->rootPath(); +} + +DFMAbstractDeviceInterface::DeviceClassType DFMVfsDeviceInfo::deviceClassType() +{ + return gvfs; +} + +bool DFMVfsDeviceInfo::isReadOnly() const +{ + return vfsDeviceConst()->isReadOnly(); +} + +DFMVfsDevice *DFMVfsDeviceInfo::vfsDevice() +{ + return c_vfsDevice.data(); +} + +const DFMVfsDevice *DFMVfsDeviceInfo::vfsDeviceConst() const +{ + return c_vfsDevice.data(); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmvfsdeviceinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmvfsdeviceinfo.h new file mode 100644 index 0000000..a7d369e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/devicemanagement/dfmvfsdeviceinfo.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + + +#ifndef DFMVFSDEVICEINFO_H +#define DFMVFSDEVICEINFO_H + +#include "dfmabstractdeviceinterface.h" + +#include + +DFM_BEGIN_NAMESPACE + +class DFMVfsDevice; +class DFMVfsDeviceInfo : public DFMAbstractDeviceInterface +{ +public: + explicit DFMVfsDeviceInfo(const QUrl mountpointUrl); + + void mount() override; + + bool unmountable() override; + void unmount() override; + + bool ejectable() override; + void eject() override; + + bool isReadOnly() const override; + + QString name() const override; + bool canRename() const override; + QString displayName() const override; // device display name. + QString iconName() const override; // device icon (theme) name. + + bool deviceUsageValid() const override; // storage valid / available or not. + quint64 availableBytes() const override; + quint64 freeBytes() const override; // may NOT equals to `total - used` + quint64 totalBytes() const override; + + QString mountpointPath() const override; // "/media/blumia/xxx" + + enum DeviceClassType deviceClassType() override; + + DFMVfsDevice* vfsDevice(); + const DFMVfsDevice* vfsDeviceConst() const; + +private: + QScopedPointer c_vfsDevice; +}; + +DFM_END_NAMESPACE + +#endif // DFMVFSDEVICEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/basedialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/basedialog.cpp new file mode 100644 index 0000000..c28f0d6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/basedialog.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "basedialog.h" +#include "dfmglobal.h" + +#include +#include + +#include +#include +#include +#include +#include + +BaseDialog::BaseDialog(QWidget *parent) : DAbstractDialog(parent) +{ + m_titlebar = new DTitlebar(this); + m_titlebar->setBackgroundTransparent(true); +// m_titlebar->setWindowFlags(Qt::WindowCloseButtonHint | Qt::WindowTitleHint); + if(DFMGlobal::isWayLand()) + { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + } +} + +BaseDialog::~BaseDialog() +{ + +} + +void BaseDialog::setTitle(const QString &title) +{ + m_titlebar->setTitle(title); +} + +void BaseDialog::resizeEvent(QResizeEvent *event) +{ + m_titlebar->setFixedWidth(event->size().width()); + + DAbstractDialog::resizeEvent(event); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/basedialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/basedialog.h new file mode 100644 index 0000000..d52a57d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/basedialog.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef BASEDIALOG_H +#define BASEDIALOG_H + +#include + +DWIDGET_USE_NAMESPACE + +DWIDGET_BEGIN_NAMESPACE +class DTitlebar; +DWIDGET_END_NAMESPACE + +class QShowEvent; +class QWidget; + +class BaseDialog : public DAbstractDialog +{ + Q_OBJECT +public: + explicit BaseDialog(QWidget *parent = nullptr); + ~BaseDialog(); + + void setTitle(const QString &title); + +protected: + void resizeEvent(QResizeEvent *event); + +private: + DTitlebar *m_titlebar = nullptr; +}; + +#endif // BASEDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/burnoptdialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/burnoptdialog.cpp new file mode 100644 index 0000000..346f714 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/burnoptdialog.cpp @@ -0,0 +1,406 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . +*/ + +#include "burnoptdialog.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "disomaster.h" +#include "app/define.h" +#include "fileoperations/filejob.h" +#include "dialogmanager.h" +#include "singleton.h" +#include "app/filesignalmanager.h" +#include "utils/desktopinfo.h" +#include "burnoptdialog_p.h" + +DWIDGET_USE_NAMESPACE + +#define MAX_LABEL_LEN 30 + +BurnOptDialog::BurnOptDialog(QString device, QWidget *parent) : + DDialog(parent), + d_ptr(new BurnOptDialogPrivate(this)) +{ + if (DFMGlobal::isWayLand()) { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + } + + Q_D(BurnOptDialog); + d->setDevice(device); + d->setupUi(); + connect(this, &BurnOptDialog::buttonClicked, this, + [ = ](int index, const QString & text) { + Q_UNUSED(text); + QFile opticalDevice(d->dev); + if (!opticalDevice.exists()) { + dialogManager->showErrorDialog(tr("Device error"), tr("Optical device %1 doesn't exist").arg(d->dev)); + return; + } + DISOMasterNS::BurnOptions opts; + if (d->cb_checkdisc->isChecked()) + opts |= DISOMasterNS::VerifyDatas; + if (d->cb_eject->isChecked()) + opts |= DISOMasterNS::EjectDisc; + if (index == 1 && d->cb_donotclose->isChecked()) // 关闭 session 仅在数据刻录有效(index == 1) + opts |= DISOMasterNS::KeepAppendable; + + // 文件系统 + if (d->cb_fs->currentIndex() == 0) + opts |= DISOMasterNS::ISO9660Only; + else if (d->cb_fs->currentIndex() == 1) + opts |= DISOMasterNS::JolietSupport; + else if (d->cb_fs->currentIndex() == 2) + opts |= DISOMasterNS::RockRidgeSupport; + else + opts |= DISOMasterNS::JolietAndRockRidge; // not used yet + + int nSpeeds = d->speedmap[d->cb_writespeed->currentText()]; + const QString &volName = d->le_volname->text().trimmed().isEmpty() + ? d->lastVolName + : d->le_volname->text().trimmed(); + + bool isUDBurn = d->cb_fs->currentIndex() == 3; + + if (index == 1) { + emit fileSignalManager->stopCdScanTimer(device); + if (d->image_file.path().length() == 0) { + QtConcurrent::run([ = ] { + QSharedPointer job(new FileJob(FileJob::OpticalBurn)); + job->moveToThread(qApp->thread()); + job->setWindowId(d->window_id); + dialogManager->addJob(job); + + DUrl dev(device); + + // fix: use fork() burn files + qDebug() << "start burn files"; + if (isUDBurn && DFMGlobal::isProfessional()) + job->doUDBurn(dev, volName, nSpeeds, opts); + else + job->doISOBurn(dev, volName, nSpeeds, opts); + dialogManager->removeJob(job->getJobId(), true); // 清除所有数据,防止脏数据出现 + //job->deleteLater(); + }); + } else { + QtConcurrent::run([ = ] { + QSharedPointer job(new FileJob(FileJob::OpticalImageBurn)); + job->moveToThread(qApp->thread()); + job->setWindowId(d->window_id); + dialogManager->addJob(job); + + DUrl dev(device); + //just to ensure we still have access to the image url even after 'this' is deleted + DUrl img(d->image_file); + + // fix: use fork() burn image + qDebug() << "start burn image"; + + job->doISOImageBurn(dev, img, nSpeeds, opts); + dialogManager->removeJob(job->getJobId(), true); // 清除所有数据,防止脏数据出现 + // job->deleteLater(); + }); + } + } + }); +} + +void BurnOptDialog::setISOImage(DUrl image) +{ + Q_D(BurnOptDialog); + + d->image_file = image; + d->cb_donotclose->hide(); + + d->lb_fs->hide(); + d->cb_fs->hide(); + + d->le_volname->setEnabled(false); + + //we are seemingly abusing DISOMaster here. However that's actually not the case. + ISOMaster->acquireDevice(QString("stdio:") + image.toLocalFile()); + DISOMasterNS::DeviceProperty dp = ISOMaster->getDeviceProperty(); + d->le_volname->setText(dp.volid); + ISOMaster->releaseDevice(); +} + +void BurnOptDialog::setJobWindowId(int wid) +{ + Q_D(BurnOptDialog); + d->window_id = wid; +} + +void BurnOptDialog::setDefaultVolName(const QString &volName) +{ + Q_D(BurnOptDialog); + d->le_volname->clear(); + d->le_volname->setText(volName); + d->le_volname->setSelection(0, volName.length()); + d->le_volname->setFocus(); + d->lastVolName = volName; +} + +void BurnOptDialog::setDiscAndFsInfo(int type, QString filesystem, QString version) +{ + Q_D(BurnOptDialog); + + if (!DFMGlobal::isProfessional()) + return; + + auto *model = d->cb_fs->model(); + if (!model || model->rowCount() < 4) + return; + + bool disableISOOpts = false; + auto supportUD = [ & ]{ + if (!isSupportedUDMedium(type)) // non dvd+-r is obviously not supported yet + return false; + if (filesystem.isEmpty()) // empty dvd+-r is supported + return true; + if (filesystem != QString("u/d/f").remove("/")) // non-udf fs do not supported udf option + return false; + if (isSupportedUDVersion(version)) { + disableISOOpts = true; + return true; + } + return false; + }; + + bool enableUD = supportUD(); + if (!enableUD) + model->setData(model->index(3, 0), 0, Qt::UserRole - 1); + if (disableISOOpts) { + model->setData(model->index(0, 0), 0, Qt::UserRole - 1); + model->setData(model->index(1, 0), 0, Qt::UserRole - 1); + model->setData(model->index(2, 0), 0, Qt::UserRole - 1); + d->cb_fs->setCurrentIndex(3); // since all iso opts is disable, select UD default + } +} + +bool BurnOptDialog::isSupportedUDVersion(const QString &version) +{ + static const QStringList && supported = { + "1.02" + }; + return supported.contains(version); +} + +bool BurnOptDialog::isSupportedUDMedium(int type) +{ + static const QList &&supportedMedium = { + DISOMasterNS::DVD_R, + DISOMasterNS::DVD_PLUS_R, + DISOMasterNS::CD_R, + DISOMasterNS::CD_RW + }; + return supportedMedium.contains(DISOMasterNS::MediaType(type)); +} + +BurnOptDialog::~BurnOptDialog() +{ +} + +BurnOptDialogPrivate::BurnOptDialogPrivate(BurnOptDialog *q) : + q_ptr(q) +{ +} + +BurnOptDialogPrivate::~BurnOptDialogPrivate() +{ +} + +void BurnOptDialogPrivate::setupUi() +{ + Q_Q(BurnOptDialog); + q->setModal(true); + q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); + q->setIcon(QIcon::fromTheme("media-optical").pixmap(96, 96)); + + q->addButton(QObject::tr("Cancel","button")); + q->addButton(QObject::tr("Burn","button"), true, DDialog::ButtonType::ButtonRecommend); + + q->layout()->setContentsMargins(0, 0, 0, 0); + w_content = new QWidget(q); + QVBoxLayout *contentLay = new QVBoxLayout; + QMargins mg(0, 15, 0, 0); + contentLay->setContentsMargins(mg); + w_content->setLayout(contentLay); + q->addContent(w_content, Qt::AlignTop); + + // 光盘名称 + lb_volname = new QLabel(QObject::tr("Disc name:")); + contentLay->addWidget(lb_volname, 0, Qt::AlignTop); + QFont f13 = lb_volname->font(); + f13.setPixelSize(13); + f13.setFamily("SourceHanSansSC"); + f13.setWeight(QFont::Medium); + lb_volname->setFont(f13); + + le_volname = new QLineEdit(); + QRegExp regx("[^\\\\/\':\\*\\?\"<>|%&.]+"); //屏蔽特殊字符 + QValidator *validator = new QRegExpValidator(regx, le_volname); + le_volname->setValidator(validator); + le_volname->setMaxLength(MAX_LABEL_LEN); + QObject::connect(le_volname, &QLineEdit::textChanged, [this] { + while (le_volname->text().toUtf8().length() > MAX_LABEL_LEN) + { + le_volname->setText(le_volname->text().chopped(1)); + } + }); + contentLay->addWidget(le_volname, 0, Qt::AlignTop); + QFont f14 = le_volname->font(); + f14.setPixelSize(14); + f14.setWeight(QFont::Medium); + f14.setFamily("SourceHanSansSC"); + le_volname->setFont(f14); + + // 高级设置内容 + DCommandLinkButton *advanceBtn = new DCommandLinkButton(BurnOptDialog::tr("Advanced settings"), q); + QFont f12 = advanceBtn->font(); + f12.setPixelSize(12); + f12.setWeight(QFont::Normal); + f12.setFamily("SourceHanSansSC"); + advanceBtn->setFont(f12); + + QHBoxLayout *advanceBtnLay = new QHBoxLayout(w_content); + advanceBtnLay->setMargin(0); + advanceBtnLay->setSpacing(0); + advanceBtnLay->addStretch(1); + advanceBtnLay->addWidget(advanceBtn); + contentLay->addLayout(advanceBtnLay); + + QWidget *advancedSettings = new QWidget(q); + contentLay->addWidget(advancedSettings, 0, Qt::AlignTop); + advancedSettings->hide(); + + QVBoxLayout *vLay = new QVBoxLayout(advancedSettings); + vLay->setMargin(0); + vLay->setSpacing(8); + advancedSettings->setLayout(vLay); + + // 文件系统 + lb_fs = new QLabel(BurnOptDialog::tr("File system: ")); + vLay->addWidget(lb_fs); + static const QStringList fsTypes { + BurnOptDialog::tr("ISO9660 Only"), + BurnOptDialog::tr("ISO9660/Joliet (For Windows)"), + BurnOptDialog::tr("ISO9660/Rock Ridge (For Unix)") + }; + + cb_fs = new QComboBox; + cb_fs->addItems(fsTypes); + cb_fs->setCurrentIndex(1); // 默认使用 i + j 的方式刻录 + vLay->addWidget(cb_fs); + lb_fs->setFont(f13); + cb_fs->setFont(f14); + + static const QString &udItem = BurnOptDialog::tr("%1 (Compatible with Windows CD/DVD mode)").arg(QString("U/D/F").remove("/")); + if (cb_fs->count() == fsTypes.count() && DFMGlobal::isProfessional()) + cb_fs->addItem(udItem); + + // 控制间距 + vLay->addItem(new QSpacerItem(1, 20)); + + // 刻录速度 + lb_writespeed = new QLabel(QObject::tr("Write speed:")); + vLay->addWidget(lb_writespeed, 0, Qt::AlignTop); + cb_writespeed = new QComboBox(); + cb_writespeed->addItem(QObject::tr("Maximum")); + vLay->addWidget(cb_writespeed, 0, Qt::AlignTop); + speedmap[QObject::tr("Maximum")] = 0; + DISOMasterNS::DeviceProperty dp = ISOMaster->getDevicePropertyCached(dev); + for (auto i : dp.writespeed) { + float speed; + int speedk; + QByteArray iBytes(i.toUtf8()); + sscanf(iBytes.data(), "%d%*c\t%f", &speedk, &speed); + speedmap[QString::number(speed, 'f', 1) + 'x'] = speedk; + cb_writespeed->addItem(QString::number(speed, 'f', 1) + 'x'); + } + lb_writespeed->setFont(f13); + cb_writespeed->setFont(f14); + + // 刻录选项-允许追加 + cb_donotclose = new QCheckBox(QObject::tr("Allow files to be added later")); + cb_donotclose->setChecked(true); + vLay->addWidget(cb_donotclose, 0, Qt::AlignTop); + QWidget *wpostburn = new QWidget(); + wpostburn->setLayout(new QHBoxLayout); + vLay->addWidget(wpostburn, 0, Qt::AlignTop); + wpostburn->layout()->setMargin(0); + cb_donotclose->setFont(f12); + + // 刻录选项-校验数据 + cb_checkdisc = new QCheckBox(QObject::tr("Verify data")); + cb_checkdisc->setFont(f12); + wpostburn->layout()->addWidget(cb_checkdisc); + // 刻录选项-弹出光盘(目前禁用) + cb_eject = new QCheckBox(QObject::tr("Eject")); + cb_eject->setFont(f12); + cb_eject->setChecked(true); + wpostburn->layout()->addWidget(cb_eject); + cb_eject->setVisible(false); // 20200430 xust 与产品沟通后决定隐藏弹出的配置项,默认刻录完成后弹出光盘仓 + + w_content->setFixedWidth(360); + q->layout()->setSizeConstraint(QLayout::SetFixedSize); + + QObject::connect(advanceBtn, &DCommandLinkButton::clicked, q, [ = ] { + advancedSettings->setHidden(!advancedSettings->isHidden()); + }); + + QObject::connect(cb_fs, static_cast(&QComboBox::currentIndexChanged), q, [this](int idx){ + if (idx == 3) { + cb_checkdisc->setChecked(false); + cb_checkdisc->setEnabled(false); + cb_donotclose->setChecked(true); + cb_donotclose->setEnabled(false); + cb_writespeed->setCurrentIndex(0); + cb_writespeed->setEnabled(false); + } else { + cb_checkdisc->setEnabled(true); + cb_donotclose->setEnabled(true); + cb_writespeed->setEnabled(true); + } + }); + +// q->setStyleSheet("border: 1px solid blue;"); +} + +void BurnOptDialogPrivate::setDevice(const QString &device) +{ + dev = device; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/burnoptdialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/burnoptdialog.h new file mode 100644 index 0000000..7709e7d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/burnoptdialog.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . +*/ + +#ifndef BURNOPTDIALOG_H +#define BURNOPTDIALOG_H +#include "ddialog.h" +#include "durl.h" + +#include +#include +#include + +class BurnOptDialogPrivate; +class BurnOptDialog : public Dtk::Widget::DDialog +{ + Q_OBJECT +public: + BurnOptDialog(QString device, QWidget *parent = nullptr); + ~BurnOptDialog(); + + void setISOImage(DUrl image); + void setJobWindowId(int wid); + void setDefaultVolName(const QString &volName); + void setDiscAndFsInfo(int type, QString filesystem, QString version); + static bool isSupportedUDVersion(const QString &version); + static bool isSupportedUDMedium(int type); + +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(BurnOptDialog) + +}; + +#endif // BURNOPTDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/burnoptdialog_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/burnoptdialog_p.h new file mode 100644 index 0000000..77278c3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/burnoptdialog_p.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2019 ~ 2020 Deepin Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: xushitong + * + * 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 + * 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 . + */ +#ifndef BURNOPTDIALOG_P_H +#define BURNOPTDIALOG_P_H +#include "burnoptdialog.h" + +class BurnOptDialogPrivate +{ +public: + explicit BurnOptDialogPrivate(BurnOptDialog *q); + ~BurnOptDialogPrivate(); + void setupUi(); + void setDevice(const QString &device); +private: + BurnOptDialog *q_ptr = nullptr; + QWidget *w_content = nullptr; + QLabel *lb_volname = nullptr; + QLineEdit *le_volname = nullptr; + QLabel *lb_writespeed = nullptr; + QComboBox *cb_writespeed = nullptr; + QLabel *lb_fs = nullptr; + QComboBox *cb_fs = nullptr; + QCheckBox *cb_donotclose = nullptr; + QLabel *lb_postburn = nullptr; + QCheckBox *cb_checkdisc = nullptr; + QCheckBox *cb_eject = nullptr; + QString dev{""}; + QHash speedmap; + DUrl image_file; + int window_id = 0; + + QString lastVolName; + + Q_DECLARE_PUBLIC(BurnOptDialog) +}; + + +#endif // BURNOPTDIALOG_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/closealldialogindicator.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/closealldialogindicator.cpp new file mode 100644 index 0000000..eac2790 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/closealldialogindicator.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "closealldialogindicator.h" +#include +#include +#include +#include +#include +#include +#include "shutil/fileutils.h" +#include "accessibility/ac-lib-file-manager.h" + +CloseAllDialogIndicator::CloseAllDialogIndicator(QWidget *parent) : DAbstractDialog(parent) +{ + setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + setFocusPolicy(Qt::NoFocus); + AC_SET_OBJECT_NAME(this, AC_CLOSE_ALL_DLG_INDICATOR); + AC_SET_ACCESSIBLE_NAME(this, AC_CLOSE_ALL_DLG_INDICATOR); + + initUI(); + initConnect(); +} + +CloseAllDialogIndicator::~CloseAllDialogIndicator() +{ + +} + +void CloseAllDialogIndicator::initUI() +{ + resize(QSize(400, 50)); + + m_messageLabel = new QLabel(this); + AC_SET_OBJECT_NAME(m_messageLabel, AC_CLOSE_ALL_DLG_INDICATOR_MSG_LABEL); + AC_SET_ACCESSIBLE_NAME(m_messageLabel, AC_CLOSE_ALL_DLG_INDICATOR_MSG_LABEL); + + m_closeButton = new QPushButton(tr("Close all"), this); + AC_SET_OBJECT_NAME(m_closeButton, AC_CLOSE_ALL_DLG_INDICATOR_CLOSE_BUTTON); + AC_SET_ACCESSIBLE_NAME(m_closeButton, AC_CLOSE_ALL_DLG_INDICATOR_CLOSE_BUTTON); + + QHBoxLayout* mainLayout = new QHBoxLayout; + mainLayout->addWidget(m_messageLabel, Qt::AlignCenter); + mainLayout->addSpacing(50); + mainLayout->addWidget(m_closeButton, Qt::AlignRight); + mainLayout->setContentsMargins(25, 5, 25, 5); + setLayout(mainLayout); + + setTotalMessage(0, 0); +} + +void CloseAllDialogIndicator::initConnect() +{ + connect(m_closeButton, &QPushButton::clicked, this, &CloseAllDialogIndicator::allClosed); +} + +void CloseAllDialogIndicator::setTotalMessage(qint64 size, int count) +{ + QString message = tr("Total size: %1, %2 files").arg(FileUtils::formatSize(size), QString::number(count)); + m_messageLabel->setText(message); +} + +void CloseAllDialogIndicator::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape){ + return; + } + QDialog::keyPressEvent(event); +} + +void CloseAllDialogIndicator::showEvent(QShowEvent *event) +{ + Q_UNUSED(event) + + //! task 36981 使用Dbus获取dock高度计算对话框显示位置 + QDBusInterface deepin_dockInfo("com.deepin.dde.daemon.Dock", + "/com/deepin/dde/daemon/Dock", + "com.deepin.dde.daemon.Dock", + QDBusConnection::sessionBus(), this); + + int dockHeight = 0; + if(deepin_dockInfo.isValid()) + { + QVariant temp = deepin_dockInfo.property("WindowSizeEfficient"); + dockHeight = temp.toInt(); + } + + QRect screenGeometry = qApp->desktop()->availableGeometry(); + + int geometryHeight = screenGeometry.height() - dockHeight; + int geometryWidth = screenGeometry.width(); + + move((geometryWidth - width()) / 2, geometryHeight - height()); + + return DAbstractDialog::showEvent(event); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/closealldialogindicator.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/closealldialogindicator.h new file mode 100644 index 0000000..63aa135 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/closealldialogindicator.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef CLOSEALLDIALOGINDICATOR_H +#define CLOSEALLDIALOGINDICATOR_H + +#include +#include + +#include + +DWIDGET_USE_NAMESPACE + +class CloseAllDialogIndicator : public DAbstractDialog +{ + Q_OBJECT +public: + explicit CloseAllDialogIndicator(QWidget *parent = nullptr); + ~CloseAllDialogIndicator() override; + + void initUI(); + void initConnect(); + +signals: + void allClosed(); + +public slots: + void setTotalMessage(qint64 size, int count); + +protected: +// void showEvent(QShowEvent* event); + void keyPressEvent(QKeyEvent *event) override; + void showEvent(QShowEvent *event) override; + +private: + QLabel *m_messageLabel; + QPushButton *m_closeButton; +}; + +#endif // CLOSEALLDIALOGINDICATOR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/computerpropertydialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/computerpropertydialog.cpp new file mode 100644 index 0000000..1aec811 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/computerpropertydialog.cpp @@ -0,0 +1,555 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "computerpropertydialog.h" +#include "ddiskmanager.h" +#include "dblockdevice.h" +#include "ddiskdevice.h" +#include "dbus/dbussysteminfo.h" +#include "shutil/fileutils.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE +DCORE_USE_NAMESPACE + +static QString formatCap(qulonglong cap, const int size = 1024, quint8 precision = 1) +{ + static QString type[] = {" B", " KB", " MB", " GB", " TB"}; + + qulonglong lc = cap; + double dc = cap; + double ds = size; + + for (size_t p = 0; p < sizeof(type); ++p) { + if (cap < pow(size, p + 1) || p == sizeof(type) - 1) { + if (!precision) { + //! 内存总大小只能是整数所以当内存大小有小数时,就需要向上取整 + int mem = ceil(lc / pow(size, p)); +#ifdef __sw_64__ + return QString::number(mem) + type[p]; +#else + //! 如果向上取整后内存大小不为偶数,就向下取整 + if(mem % 2 > 0) + mem = floor(lc / pow(size, p)); + return QString::number(mem) + type[p]; +#endif + } + + return QString::number(dc / pow(ds, p), 'f', precision) + type[p]; + } + } + + return ""; +} + +GetInfoWork::GetInfoWork(QObject *parent) + : QThread(parent) +{ +} + +void GetInfoWork::setInitData(QList datas) +{ + m_datas = datas; +} + +void GetInfoWork::startWork() +{ + m_bStop = false; + start(); +} + +void GetInfoWork::stopWork() +{ + m_bStop = true; +} + +void GetInfoWork::run() +{ + // 设置初始值 + DBusSystemInfo *systemInfo = nullptr; + QDBusInterface *deepin_systemInfo = nullptr; + QString computerName(""); + QString keyName = qApp->translate("ComputerPropertyDialog", "Computer Name"); + QString Edition(""); + QString keyEditon = qApp->translate("ComputerPropertyDialog", "Edition"); + QString version(""); + QString keyVersion = qApp->translate("ComputerPropertyDialog", "Version"); + QString systemType(""); + QString keyType = qApp->translate("ComputerPropertyDialog", "Type"); + QString processor(""); + QString keyProcessor = qApp->translate("ComputerPropertyDialog", "Processor"); + QString memoryInstallStr(""); + QString memoryStr(""); + QString keyMemory = qApp->translate("ComputerPropertyDialog", "Memory"); + qint64 tempMemory; + QMap mapDatas; + + while (!m_datas.isEmpty() && !m_bStop) { + // 创建dbus对象 + systemInfo = new DBusSystemInfo(); + // 从com.deepin.system.SystemInfo中获取实际安装的内存的大小 + deepin_systemInfo = new QDBusInterface("com.deepin.system.SystemInfo", + "/com/deepin/system/SystemInfo", + "com.deepin.system.SystemInfo", + QDBusConnection::systemBus(), this); + + // 部分数据优先从dbus读取 + if (deepin_systemInfo) { + // 获取安装内存 + if (m_datas.contains(keyMemory)) + memoryInstallStr = formatCap(deepin_systemInfo->property("MemorySize").toULongLong(), 1024, 0); + } + if (systemInfo->isValid()) { + // 获取cpu信息 + if (m_datas.contains(keyProcessor)) + processor = systemInfo->processor(); + // 获取系统是64位还是32位 + if (m_datas.contains(keyType)) + systemType = QString::number(systemInfo->systemType()) + qApp->translate("ComputerPropertyDialog", "Bit"); + // 获取系统版本信息 + if (m_datas.contains(keyEditon) || m_datas.contains(keyVersion)) { + if (Edition.isEmpty()) { + Edition = systemInfo->version(); + QStringList temp = Edition.split(' '); + if (temp.size() > 1) { + version = temp[0]; + Edition = temp[1]; + } else if (!temp.isEmpty()) { + Edition = temp[0]; + } + } + } + } + // 如果dbus没有,则从dtk读数据 + if (DSysInfo::isDeepin()) { + // 获取计算机名称 + if (m_datas.contains(keyName)) { + computerName = DSysInfo::computerName(); + // 因为用户可以修改计算机名称,所以检测到名称变化后,立刻发送出去 + if (!computerName.isEmpty()) { + mapDatas.insert(keyName, computerName); + emit sigSendInfo(mapDatas); + m_datas.removeAll(keyName); + mapDatas.clear(); + } + } + // 获取系统版本名 + if (m_datas.contains(keyEditon)) { + if (DSysInfo::UosType::UosServer == DSysInfo::uosType()) { // 服务器版本 + Edition = DSysInfo::minorVersion() + DSysInfo::uosEditionName(); + } else { + Edition = DSysInfo::uosEditionName(); + } + } + // 获取系统版本号 + if (m_datas.contains(keyVersion)) + version = DSysInfo::majorVersion(); + if (m_datas.contains(keyMemory)) { + // 获取实际可用内存总量 + tempMemory = DSysInfo::memoryTotalSize(); + if (tempMemory >= 0) + memoryStr = formatCap(static_cast(tempMemory)); + } + if (m_datas.contains(keyMemory) && memoryInstallStr.isEmpty()) { + // 如果没有通过dbus获取安装内存,则通过dtk获取 + tempMemory = DSysInfo::memoryInstalledSize(); + if (tempMemory >= 0) + memoryInstallStr = formatCap(static_cast(tempMemory), 1024, 0); + } + if (m_datas.contains(keyProcessor) && processor.isEmpty()) { + // 如果没有用过dbus获取CPU信息,则通过dtk获取 + processor = QString("%1 x %2").arg(DSysInfo::cpuModelName()) + .arg(QThread::idealThreadCount()); + } + + } + // 通过qt获得 + if (systemType.isEmpty()) { + systemType = QString::number(QSysInfo::WordSize) + qApp->translate("ComputerPropertyDialog", "Bit"); + } + + // 对外发送属性更新信号 + mapDatas.clear(); + if (m_datas.contains(keyEditon) && !Edition.isEmpty()) { + mapDatas.insert(keyEditon, Edition); + m_datas.removeAll(keyEditon); + } + if (m_datas.contains(keyVersion) && !version.isEmpty()) { + mapDatas.insert(keyVersion, version); + m_datas.removeAll(keyVersion); + } + if (m_datas.contains(keyType) && !systemType.isEmpty()) { + mapDatas.insert(keyType, systemType); + m_datas.removeAll(keyType); + } + if (m_datas.contains(keyProcessor) && !processor.isEmpty()) { + mapDatas.insert(keyProcessor, processor); + m_datas.removeAll(keyProcessor); + } + if (m_datas.contains(keyMemory) && !memoryInstallStr.isEmpty() && !memoryStr.isEmpty()) { + QString strMemory(memoryInstallStr + "(" + memoryStr + ' ' + qApp->translate("ComputerPropertyDialog", "Available") + ")"); + mapDatas.insert(keyMemory, strMemory); + m_datas.removeAll(keyMemory); + } + if (!mapDatas.isEmpty()) + emit sigSendInfo(mapDatas); + // 销毁dbus对象 + if (systemInfo) { + delete systemInfo; + systemInfo = nullptr; + } + if (deepin_systemInfo) { + delete deepin_systemInfo; + deepin_systemInfo = nullptr; + } + // 暂停1s + QThread::sleep(1); + } +} + +ComputerPropertyDialog::ComputerPropertyDialog(QWidget *parent) : DDialog(parent) +{ + m_systemInfo = new DBusSystemInfo(); + initUI(); +} + +ComputerPropertyDialog::~ComputerPropertyDialog() +{ + // 安全退出线程 + if (m_getInfoWork && m_getInfoWork->isRunning()) { + m_getInfoWork->stopWork(); + m_getInfoWork->wait(); + } +} + +void ComputerPropertyDialog::initUI() +{ + QLabel *iconLabel = new QLabel(this); + + if(DFMGlobal::isWayLand()) + { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + this->setFixedSize(320, 420); + } + + QString distributerLogoPath = DSysInfo::distributionOrgLogo(); + QIcon logoIcon; + if (!distributerLogoPath.isEmpty() && QFile::exists(distributerLogoPath)) { + logoIcon = QIcon(distributerLogoPath); + } else { + logoIcon = QIcon::fromTheme("dfm_deepin_logo"); + } + + iconLabel->setPixmap(logoIcon.pixmap(152, 39)); + QLabel *nameLabel = new QLabel(tr("Computer"), this); + auto pt = nameLabel->palette(); + pt.setColor(QPalette::Text, palette().color(QPalette::Normal, QPalette::Text)); + auto font = nameLabel->font(); + font.setBold(true); + font.setPixelSize(17); + nameLabel->setFont(font); + nameLabel->setPalette(pt); + + QLabel *messageLabel = new QLabel(tr("Basic Info"), this); + messageLabel->setPalette(pt); + messageLabel->setFont(font); + + + QGridLayout *gridLayout = new QGridLayout; + //gridLayout->setColumnMinimumWidth(0, 100); + gridLayout->setColumnMinimumWidth(1, 170); + gridLayout->setSpacing(10); + + QStringList msgsTitle; + msgsTitle << tr("Computer Name") + << tr("Edition") + << tr("Version") + << tr("Type") + << tr("Processor") + << tr("Memory"); + + int row = 0; + QHash datas = getMessage(msgsTitle); + + foreach (const QString &key, msgsTitle) { + + if (DSysInfo::isCommunityEdition() && key == tr("Version")) + continue; + + QLabel *keyLabel = new QLabel(key, this); + QLabel *valLabel = new QLabel(datas.value(key), this); + // 缓存值label,便于刷新属性值 + m_mapItems.insert(key, valLabel); + + valLabel->setTextFormat(Qt::PlainText); + valLabel->setWordWrap(true); + + font = keyLabel->font(); + font.setPixelSize(13); + keyLabel->setFont(font); + + font = valLabel->font(); + font.setPixelSize(12); + valLabel->setFont(font); + + pt = keyLabel->palette(); + pt.setColor(QPalette::Text, palette().color(QPalette::Normal, QPalette::HighlightedText)); + keyLabel->setPalette(pt); + + pt = valLabel->palette(); + pt.setColor(QPalette::Text, palette().color(QPalette::Inactive, QPalette::Text)); + valLabel->setPalette(pt); +// keyLabel->setStyleSheet("QLabel { color: #001A2E; font-size: 13px; }"); +// valLabel->setStyleSheet("QLabel { color: #526A7F; font-size: 12px; }"); + + gridLayout->addWidget(keyLabel, row, 0); + gridLayout->addWidget(valLabel, row, 1); + //! 使内存显示不换行 + if (key == tr("Memory")) + valLabel->setWordWrap(false); + //CPU字符匹配,因为CPU长度不定长在计算中gridLayout会产生错误 + if (key == tr("Processor")) { + auto boundingRect = valLabel->fontMetrics().boundingRect(valLabel->text()); + gridLayout->setRowMinimumHeight(row, boundingRect.height() - boundingRect.y()); + } + // 如果没有达到对应属性值 + if (datas.value(key).isEmpty()) { + // 隐藏属性视图 + valLabel->hide(); + // 创建并显示等待视图 + QFrame *frameWait = new QFrame(this); + QHBoxLayout *lay = new QHBoxLayout; + lay->setContentsMargins(0, 0, 0, 0); + lay->setSpacing(10); + // 创建等待圈控件 + DSpinner *spinWait = new DSpinner(frameWait); + spinWait->setFixedSize(16, 16); + spinWait->start(); + lay->addWidget(spinWait); + // 创建等待label控件 + QLabel *labelWait = new QLabel(tr("Obtaining..."), frameWait); + font = labelWait->font(); + font.setPixelSize(12); + labelWait->setFont(font); + pt = labelWait->palette(); + pt.setColor(QPalette::Text, palette().color(QPalette::Inactive, QPalette::Text)); + labelWait->setPalette(pt); + lay->addWidget(labelWait); + // 布局 + frameWait->setLayout(lay); + gridLayout->addWidget(frameWait, row, 1); + // 缓存第一次没有获取到的属性 + m_mapNotFinish.insert(key, frameWait); + } + row++; + } + + QFrame *contentFrame = new QFrame; + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->setSpacing(0); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->addWidget(nameLabel, 0, Qt::AlignHCenter); + mainLayout->addSpacing(25); + mainLayout->addWidget(iconLabel, 0, Qt::AlignHCenter); + mainLayout->addSpacing(21); + + QFrame *baseInfoFrame = new QFrame; + QString backColor = palette().color(QPalette::Base).name(); + baseInfoFrame->setStyleSheet(QString("background-color: %1; border-radius: 8px;").arg(backColor)); + QVBoxLayout *baseInfoLayout = new QVBoxLayout; + baseInfoFrame->setLayout(baseInfoLayout); + baseInfoLayout->addWidget(messageLabel); + baseInfoLayout->addSpacing(10); + baseInfoLayout->setContentsMargins(10, 5, 10, 5); + baseInfoLayout->addLayout(gridLayout); + + mainLayout->addWidget(baseInfoFrame); + + setFixedWidth(320); + contentFrame->setLayout(mainLayout); + + addContent(contentFrame); + + // 启动子线程,获取并更新当前未拿到的属性信息 + if (!m_mapNotFinish.isEmpty() && !m_getInfoWork) { + m_getInfoWork = new GetInfoWork(this); + connect(m_getInfoWork, &GetInfoWork::sigSendInfo, + this, &ComputerPropertyDialog::slotSetInfo); + m_getInfoWork->setInitData(m_mapNotFinish.keys()); + m_getInfoWork->startWork(); + } +} + +QHash ComputerPropertyDialog::getMessage(const QStringList &data) +{ + QHash datas; + QString Edition; + QString version; + QString memoryInstallStr; + QString memoryStr; + QString processor; + QString systemType; + qint64 tempMemory; + + //! 从com.deepin.system.SystemInfo中获取实际安装的内存的大小 + QDBusInterface *deepin_systemInfo = new QDBusInterface("com.deepin.system.SystemInfo", + "/com/deepin/system/SystemInfo", + "com.deepin.system.SystemInfo", + QDBusConnection::systemBus(), this); + + // 部分数据优先从dbus读取 + // 获取安装的内存总量 + if (deepin_systemInfo) + memoryInstallStr = formatCap(deepin_systemInfo->property("MemorySize").toULongLong(), 1024, 0); + if (m_systemInfo->isValid()) { + //! 获取cpu信息 + processor = m_systemInfo->processor(); + //! 获取系统是64位还是32位 + systemType = QString::number(m_systemInfo->systemType()) + tr("Bit"); + + if (Edition.isEmpty()) { + Edition = m_systemInfo->version(); + QStringList temp = Edition.split(' '); + if (temp.size() > 1) { + version = temp[0]; + Edition = temp[1]; + } else if (!temp.isEmpty()) { + Edition = temp[0]; + } + } + } + // 如果dbus没有,则从dtk读数据 + if (DSysInfo::isDeepin()) { + //! 获取系统版本名 + if (DSysInfo::UosType::UosServer == DSysInfo::uosType()) { // 服务器版本 + Edition = DSysInfo::minorVersion() + DSysInfo::uosEditionName(); + } else { + Edition = DSysInfo::uosEditionName(); + } + //! 获取系统版本号 + version = DSysInfo::majorVersion(); + //! 获取实际可用内存总量 + tempMemory = DSysInfo::memoryTotalSize(); + if (tempMemory >= 0) + memoryStr = formatCap(static_cast(tempMemory)); + // 如果dbus中没有获得,则从dtk获取安装的内存总量 + if (memoryInstallStr.isEmpty()) { + tempMemory = DSysInfo::memoryInstalledSize(); + if (tempMemory >= 0) + memoryInstallStr = formatCap(static_cast(tempMemory), 1024, 0); + } + // 如果dbus中没有获得,则从dtk获取cpu信息 + if (processor.isEmpty()) + processor = QString("%1 x %2").arg(DSysInfo::cpuModelName()) + .arg(QThread::idealThreadCount()); + + } + // 通过qt获得 + if (systemType.isEmpty()) + systemType = QString::number(QSysInfo::WordSize) + tr("Bit"); + + datas.insert(data.at(0), DSysInfo::computerName()); + datas.insert(data.at(1), Edition); + datas.insert(data.at(2), version); + datas.insert(data.at(3), systemType); + datas.insert(data.at(4), processor); + if (!memoryInstallStr.isEmpty() && !memoryStr.isEmpty()) + datas.insert(data.at(5), memoryInstallStr + + "(" + memoryStr + + ' ' + tr("Available") + ")"); + else + datas.insert(data.at(5), ""); + return datas; +} + +void ComputerPropertyDialog::updateComputerInfo() +{ + // 如果线程对象存在 + if (m_getInfoWork) { + if (m_getInfoWork->isRunning()) { + m_getInfoWork->stopWork(); + m_getInfoWork->wait(); + } + } else { + m_getInfoWork = new GetInfoWork(this); + connect(m_getInfoWork, &GetInfoWork::sigSendInfo, + this, &ComputerPropertyDialog::slotSetInfo); + } + // 设置所有属性项都需要更新 + m_getInfoWork->setInitData(m_mapItems.keys()); + m_getInfoWork->startWork(); +} + +void ComputerPropertyDialog::slotSetInfo(QMap mapNewDatas) +{ + QMap::iterator itr = mapNewDatas.begin(); + for (; itr != mapNewDatas.end(); ++itr) { + QString strItemKey = itr.key(); + // 销毁等待控件 + if (m_mapNotFinish.contains(strItemKey)) { + delete m_mapNotFinish[strItemKey]; + m_mapNotFinish.remove(strItemKey); + } + // 更新计算机信息 + if (m_mapItems.contains(strItemKey)) { + m_mapItems[strItemKey]->setText(itr.value()); + m_mapItems[strItemKey]->show(); + } + } + adjustSize(); +} + +void ComputerPropertyDialog::hideEvent(QHideEvent *event) +{ + // 结束子线程 + if (m_getInfoWork) { + if (m_getInfoWork->isRunning()) { + m_getInfoWork->stopWork(); + m_getInfoWork->wait(); + } + delete m_getInfoWork; + m_getInfoWork = nullptr; + } + DDialog::hideEvent(event); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/computerpropertydialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/computerpropertydialog.h new file mode 100644 index 0000000..f0046e2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/computerpropertydialog.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef COMPUTERPROPERTYDIALOG_H +#define COMPUTERPROPERTYDIALOG_H + +#include + +#include +#include + +QT_BEGIN_HEADER +class QFrame; +QT_END_NAMESPACE + +DWIDGET_USE_NAMESPACE + +class DBusSystemInfo; + +// 添加子线程,获取计算机配置信息,以及发送配置信息更新信号 +class GetInfoWork : public QThread +{ + Q_OBJECT +public: + explicit GetInfoWork(QObject *parent = nullptr); + // 设置初始数据(未获得信息的项目) + void setInitData(QList datas); + // 开始线程 + void startWork(); + // 结束线程 + void stopWork(); + +signals: + // 发送该信号,刷新最新属性值 + void sigSendInfo(QMap mapNewDatas); + +protected: + void run() override; + +private: + QList m_datas = {}; + bool m_bStop = false; +}; + +class ComputerPropertyDialog : public DDialog +{ + Q_OBJECT +public: + explicit ComputerPropertyDialog(QWidget *parent = nullptr); + ~ComputerPropertyDialog() override; + void initUI(); + QHash getMessage(const QStringList& data); + // 开启子线程,更新计算机信息 + void updateComputerInfo(); + +signals: + void closed(); + +protected: + // 重写隐藏事件,实现窗口隐藏时,关闭属性更新线程 + void hideEvent(QHideEvent *event) Q_DECL_OVERRIDE; + +private slots: + // 更新计算机信息 + void slotSetInfo(QMap mapNewDatas); + +private: + DBusSystemInfo *m_systemInfo = nullptr; + // 缓存计算机属性值项 + QHash m_mapItems = {}; + // 缓存未完成的计算机属性等待项 + QHash m_mapNotFinish = {}; + // 创建属性更新线程对象 + GetInfoWork *m_getInfoWork = nullptr; +}; + +#endif // COMPUTERPROPERTYDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/connecttoserverdialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/connecttoserverdialog.cpp new file mode 100644 index 0000000..89f2ad3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/connecttoserverdialog.cpp @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "durl.h" +#include "singleton.h" +#include "dfmeventdispatcher.h" +#include "connecttoserverdialog.h" +#include "../views/dfilemanagerwindow.h" +#include "../controllers/searchhistroymanager.h" +#include "../interfaces/dfmsettings.h" +#include "../interfaces/dfmapplication.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ConnectToServerDialog::ConnectToServerDialog(QWidget *parent) : DDialog(parent) +{ + setWindowTitle(tr("Connect to Server")); + initUI(); + initConnect(); +} + +void ConnectToServerDialog::onButtonClicked(const int &index) +{ + // connect to server + if(index == ConnectButton) { + QString text = m_serverComboBox->currentText(); + if (text.isEmpty()) { + close(); + return; + } + + QWidget *fileWindow = qobject_cast(parent()); + + const QString ¤tDir = QDir::currentPath(); + const DUrl ¤tUrl = qobject_cast(fileWindow->topLevelWidget())->currentUrl(); + + if (currentUrl.isLocalFile()) { + QDir::setCurrent(currentUrl.toLocalFile()); + } + + DUrl inputUrl = DUrl::fromUserInput(text, false); ///###: here, judge whether the text is a local file path. + + QDir::setCurrent(currentDir); + + DFMEventDispatcher::instance()->processEvent(this, inputUrl, fileWindow->window()); + + //add search history list + SearchHistroyManager *historyManager = Singleton::instance(); + if (!historyManager->toStringList().contains(text)) { + historyManager->writeIntoSearchHistory(text); + } + } + close(); +} + +void ConnectToServerDialog::onAddButtonClicked() +{ + QStringList serverList = static_cast(m_collectionServerView->model())->stringList(); + + const QString &text = m_serverComboBox->currentText(); + if (!text.isEmpty() && + !serverList.contains(text)) { + if(!m_collectionServerView->addItem(text)) { + qWarning() << "add server failed, server: " << text; + } else { + serverList = static_cast(m_collectionServerView->model())->stringList(); + const QModelIndex modelIndex = m_collectionServerView->model()->index(serverList.indexOf(text), + 0, + m_collectionServerView->currentIndex().parent()); + m_collectionServerView->setCurrentIndex(modelIndex); + + QStringList dataList; + const QList &serverData = DFMApplication::genericSetting()->value("ConnectServer", "URL").toList(); + for (const QVariant &data : serverData) { + dataList << data.toString(); + } + + if (!dataList.contains(text)) { + dataList << text; + DFMApplication::genericSetting()->setValue("ConnectServer", "URL", dataList); + } + } + } +} + +void ConnectToServerDialog::onDelButtonClicked() +{ + const QStringList &serverList = static_cast(m_collectionServerView->model())->stringList(); + const QString &text = m_serverComboBox->currentText(); + if (!text.isEmpty() && + serverList.contains(text)) { + if (!m_collectionServerView->removeItem(serverList.indexOf(text))) { + qWarning() << "remove server failed, server: " << text; + } else { + const QList &serverData = DFMApplication::genericSetting()->value("ConnectServer", "URL").toList(); + + QStringList dataList; + for (const QVariant &data : serverData) { + dataList << data.toString(); + } + + if (dataList.contains(text)) { + dataList.removeOne(text); + DFMApplication::genericSetting()->setValue("ConnectServer", "URL", dataList); + } + + const QModelIndex ¤tIndex = m_collectionServerView->currentIndex(); + if (currentIndex.isValid()) { + m_serverComboBox->setCurrentText(currentIndex.data().toString()); + } else { + m_serverComboBox->clearEditText(); + } + } + } +} + +void ConnectToServerDialog::initUI() +{ + if(DFMGlobal::isWayLand()) + { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + } + + setFixedSize(476, 380); + + QStringList buttonTexts; + buttonTexts.append(tr("Cancel","button")); + buttonTexts.append(tr("Connect","button")); + addButton(buttonTexts[CannelButton], false); + addButton(buttonTexts[ConnectButton], true, DDialog::ButtonRecommend); + + QFrame *contentFrame = new QFrame(this); + m_serverComboBox = new QComboBox(); + m_addButton = new DIconButton(nullptr); + m_delButton = new DIconButton(nullptr); + QLabel * collectionLabel = new QLabel(tr("My Favorites:")); + m_collectionServerView = new DListView(); + + m_addButton->setFixedSize(44, 44); + m_delButton->setFixedSize(44, 44); + //collectionLabel->setFixedSize(98, 20); + + m_addButton->setIcon(QIcon::fromTheme("dfm_add_server")); + m_addButton->setIconSize({44, 44}); + m_addButton->setFlat(true); + m_delButton->setIcon(QIcon::fromTheme("dfm_del_server")); + m_delButton->setIconSize({44, 44}); + m_delButton->setFlat(true); + + QHBoxLayout *comboButtonLayout = new QHBoxLayout(); + comboButtonLayout->addWidget(m_serverComboBox, 0, Qt::AlignVCenter); + comboButtonLayout->addSpacing(6); + comboButtonLayout->addWidget(m_addButton, 0, Qt::AlignVCenter); + comboButtonLayout->addSpacing(2); + comboButtonLayout->addWidget(m_delButton, 0, Qt::AlignVCenter); + comboButtonLayout->setContentsMargins(0, 0, 0, 0); + + QVBoxLayout *contentLayout = new QVBoxLayout(); + contentLayout->addLayout(comboButtonLayout); + contentLayout->addSpacing(5); + contentLayout->addWidget(collectionLabel, 0, Qt::AlignVCenter); + contentLayout->addSpacing(5); + contentLayout->addWidget(m_collectionServerView, 0, Qt::AlignVCenter); + contentLayout->setContentsMargins(5, 0, 0, 0); + + contentFrame->setLayout(contentLayout); + addContent(contentFrame); + + const QStringList &stringList = Singleton::instance()->toStringList(); + + QCompleter *completer = new QCompleter(stringList, this); + completer->setCaseSensitivity(Qt::CaseInsensitive); + completer->setCompletionMode(QCompleter::PopupCompletion); + completer->setMaxVisibleItems(10); + + m_serverComboBox->setEditable(true); + m_serverComboBox->addItems(stringList); + m_serverComboBox->insertItem(m_serverComboBox->count(), tr("Clear History")); + m_serverComboBox->setEditable(true); + m_serverComboBox->setMaxVisibleItems(10); + m_serverComboBox->setCompleter(completer); + m_serverComboBox->clearEditText(); + + m_collectionServerView->setViewportMargins(0, 0, m_collectionServerView->verticalScrollBar()->sizeHint().width(), 0); + m_collectionServerView->setVerticalScrollMode(DListView::ScrollPerPixel); + m_collectionServerView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + m_collectionServerView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_collectionServerView->setResizeMode(DListView::Fixed); + m_collectionServerView->setAlternatingRowColors(true); + m_collectionServerView->setUniformItemSizes(true); + m_collectionServerView->setItemSize({m_collectionServerView->width(), 36}); + m_collectionServerView->setItemMargins({0, 0, 0, 0}); + m_collectionServerView->setItemSpacing(1); + m_collectionServerView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_collectionServerView->setEditTriggers(QAbstractItemView::NoEditTriggers); + m_collectionServerView->setFrameShape(QFrame::Shape::NoFrame); + + QStringList dataList; + const QList &serverData = DFMApplication::genericSetting()->value("ConnectServer", "URL").toList(); + for (const QVariant &data : serverData) { + dataList << data.toString(); + } + + QStringListModel *listModel = new QStringListModel(this); + m_collectionServerView->setModel(listModel); + listModel->setStringList(dataList); + + setContentsMargins(0,0,0,0); +} + +void ConnectToServerDialog::initConnect() +{ + //QComboBox clear history + connect(m_serverComboBox, &QComboBox::currentTextChanged, this, [=](const QString &string){ + if (string == m_serverComboBox->itemText(m_serverComboBox->count() - 1)) { + QSignalBlocker blocker(m_serverComboBox); + Q_UNUSED(blocker) + + m_serverComboBox->clear(); + m_serverComboBox->addItem(tr("Clear History")); + m_serverComboBox->clearEditText(); + m_serverComboBox->completer()->setModel(new QStringListModel()); + + Singleton::instance()->clearHistory(); + } + }); + + connect(m_addButton, &DIconButton::clicked, this, &ConnectToServerDialog::onAddButtonClicked); + connect(m_delButton, &DIconButton::clicked, this, &ConnectToServerDialog::onDelButtonClicked); + connect(m_collectionServerView, &DListView::clicked, this, [=](const QModelIndex &index){ + if (index.data().toString() != m_serverComboBox->currentText()) { + m_serverComboBox->setCurrentText(index.data().toString()); + } + }); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/connecttoserverdialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/connecttoserverdialog.h new file mode 100644 index 0000000..00bfdf9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/connecttoserverdialog.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef CONNECTTOSERVERDIALOG_H +#define CONNECTTOSERVERDIALOG_H + +#include "dfmglobal.h" + +#include +#include + +DWIDGET_BEGIN_NAMESPACE +class DIconButton; +class DListView; +DWIDGET_END_NAMESPACE + +QT_BEGIN_NAMESPACE +class QComboBox; +QT_END_NAMESPACE + +DWIDGET_USE_NAMESPACE + +class ConnectToServerDialog : public DDialog +{ + Q_OBJECT +public: + explicit ConnectToServerDialog(QWidget *parent = nullptr); + +signals: + +public slots: + void onButtonClicked(const int& index); + +private: + void initUI(); + void initConnect(); + void onAddButtonClicked(); + void onDelButtonClicked(); + + enum DialogButton { + CannelButton, + ConnectButton + }; + + QComboBox *m_serverComboBox = nullptr; + DIconButton *m_addButton = nullptr; + DIconButton *m_delButton = nullptr; + DListView *m_collectionServerView = nullptr; +}; + +#endif // CONNECTTOSERVERDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/ddesktoprenamedialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/ddesktoprenamedialog.cpp new file mode 100644 index 0000000..5b9afdb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/ddesktoprenamedialog.cpp @@ -0,0 +1,559 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ddesktoprenamedialog.h" +#include "private/ddesktoprenamedialog_p.h" + +DDesktopRenameDialogPrivate::DDesktopRenameDialogPrivate(DDesktopRenameDialog *const qPtr) + : q_ptr{ qPtr} +{ + this->initUi(); + this->initUiParameters(); + this->initUiLayout(); + +} + +void DDesktopRenameDialogPrivate::initUi() +{ + + m_titleLabel = new QLabel{}; + + m_itemsForSelecting = std::make_tuple(new QLabel{}, new QComboBox{}, new QHBoxLayout{}); + + m_modeOneItemsForFinding = std::make_tuple(new QLabel{}, new QLineEdit{}, new QHBoxLayout{}); + m_modeOneItemsForReplacing = std::make_tuple(new QLabel{}, new QLineEdit{}, new QHBoxLayout{}); + m_modeOneLayout = QPair {new QVBoxLayout{}, new QFrame{}}; + + + m_modeTwoItemsForAdding = std::make_tuple(new QLabel{}, new QLineEdit{}, new QHBoxLayout); + m_modeTwoItemsForLocating = std::make_tuple(new QLabel{}, new QComboBox{}, new QHBoxLayout{}); + m_modeTwoLayout = QPair {new QVBoxLayout{}, new QFrame{}}; + + + m_modeThreeItemsForFileName = std::make_tuple(new QLabel{}, new QLineEdit{}, new QHBoxLayout{}); + m_modeThreeItemsForSNNumber = std::make_tuple(new QLabel{}, new QLineEdit{}, new QHBoxLayout{}); + m_modeThreeLayout = QPair {new QVBoxLayout{}, new QFrame{}}; + + QRegExp regStr{ QString{"[0-9]+"} }; + m_validator = new QRegExpValidator{ regStr, this->q_ptr }; + + m_mainFrame = new QFrame(this->q_ptr); + m_mainLayout = new QVBoxLayout(m_mainFrame); +} + + +void DDesktopRenameDialogPrivate::initUiParameters() +{ + m_titleLabel->setAlignment(Qt::AlignCenter); + + QLabel *tagLabel{ nullptr }; + QComboBox *modeChoseBox{ nullptr }; + QLineEdit *contentLineEdit{ nullptr }; + + tagLabel = std::get<0>(m_itemsForSelecting); + tagLabel->setText(QObject::tr("Mode:")); + modeChoseBox = std::get<1>(m_itemsForSelecting); + modeChoseBox->addItems(QList { QObject::tr("Replace Text"), QObject::tr("Add Text"), QObject::tr("Custom Text") }); + modeChoseBox->setFixedSize(QSize{275, 25}); + + ///###: mode 1 + tagLabel = std::get<0>(m_modeOneItemsForFinding); + tagLabel->setText(QObject::tr("Find:")); + contentLineEdit = std::get<1>(m_modeOneItemsForFinding); + contentLineEdit->setFocus(); + contentLineEdit->setPlaceholderText(QObject::tr("Required")); + contentLineEdit->setFixedSize(QSize{275, 25}); + + tagLabel = std::get<0>(m_modeOneItemsForReplacing); + tagLabel->setText(QObject::tr("Replace:")); + contentLineEdit = std::get<1>(m_modeOneItemsForReplacing); + contentLineEdit->setPlaceholderText(QObject::tr("Optional")); + contentLineEdit->setFixedSize(QSize{275, 25}); + + ///###: mode 2 + tagLabel = std::get<0>(m_modeTwoItemsForAdding); + tagLabel->setText(QObject::tr("Add:")); + contentLineEdit = std::get<1>(m_modeTwoItemsForAdding); + contentLineEdit->setPlaceholderText(QObject::tr("Required")); + contentLineEdit->setFixedSize(QSize{275, 25}); + contentLineEdit->setMaxLength(300); + + tagLabel = std::get<0>(m_modeTwoItemsForLocating); + tagLabel->setText(QObject::tr("Location:")); + modeChoseBox = std::get<1>(m_modeTwoItemsForLocating); + modeChoseBox->addItems(QList { QObject::tr("Before file name"), QObject::tr("After file name") }); + modeChoseBox->setFixedSize(QSize{275, 25}); + + ///###: mode3 + tagLabel = std::get<0>(m_modeThreeItemsForFileName); + tagLabel->setText(QObject::tr("File name:")); + contentLineEdit = std::get<1>(m_modeThreeItemsForFileName); + contentLineEdit->setPlaceholderText(QObject::tr("Required")); + contentLineEdit->setFixedSize(QSize{275, 25}); + + tagLabel = std::get<0>(m_modeThreeItemsForSNNumber); + tagLabel->setText(QObject::tr("Start at:")); + contentLineEdit = std::get<1>(m_modeThreeItemsForSNNumber); + contentLineEdit->setPlaceholderText(QObject::tr("Required")); + contentLineEdit->setFixedSize(QSize{275, 25}); + contentLineEdit->setValidator(m_validator); + contentLineEdit->setText(QString{"1"}); + + tagLabel = nullptr; + modeChoseBox = nullptr; + contentLineEdit = nullptr; +} + +void DDesktopRenameDialogPrivate::initUiLayout() +{ + QLabel *tagLabel{ nullptr }; + QComboBox *modeChoseBox{ nullptr }; + QLineEdit *contentLineEdit{ nullptr }; + QHBoxLayout *hLayout{ nullptr }; + + + tagLabel = std::get<0>(m_itemsForSelecting); + modeChoseBox = std::get<1>(m_itemsForSelecting); + tagLabel->setBuddy(modeChoseBox); + hLayout = std::get<2>(m_itemsForSelecting); + hLayout->addWidget(tagLabel); + hLayout->addSpacing(30); + hLayout->addWidget(modeChoseBox); + hLayout->setMargin(0); + + + ///###: mode 1 + tagLabel = std::get<0>(m_modeOneItemsForFinding); + contentLineEdit = std::get<1>(m_modeOneItemsForFinding); + tagLabel->setBuddy(contentLineEdit); + hLayout = std::get<2>(m_modeOneItemsForFinding); + hLayout->addWidget(tagLabel); + hLayout->addSpacing(30); + hLayout->addWidget(contentLineEdit); + hLayout->setMargin(0); + + + tagLabel = std::get<0>(m_modeOneItemsForReplacing); + contentLineEdit = std::get<1>(m_modeOneItemsForReplacing); + tagLabel->setBuddy(contentLineEdit); + hLayout = std::get<2>(m_modeOneItemsForReplacing); + hLayout->addWidget(tagLabel); + hLayout->addSpacing(30); + hLayout->addWidget(contentLineEdit); + + + m_modeOneLayout.first->addLayout(std::get<2>(m_modeOneItemsForFinding)); + m_modeOneLayout.first->addSpacing(10); + m_modeOneLayout.first->addLayout(std::get<2>(m_modeOneItemsForReplacing)); + m_modeOneLayout.first->setSpacing(0); + m_modeOneLayout.first->setMargin(0); + m_modeOneLayout.second->setLayout(m_modeOneLayout.first); + + + + + ///###: mode 2 + hLayout = std::get<2>(m_modeTwoItemsForAdding); + hLayout->setSpacing(0); + hLayout->setMargin(0); + tagLabel = std::get<0>(m_modeTwoItemsForAdding); + contentLineEdit = std::get<1>(m_modeTwoItemsForAdding); + tagLabel->setBuddy(contentLineEdit); + hLayout->addWidget(tagLabel); + hLayout->addSpacing(30); + hLayout->addWidget(contentLineEdit); + hLayout->setMargin(0); + + + tagLabel = std::get<0>(m_modeTwoItemsForLocating); + modeChoseBox = std::get<1>(m_modeTwoItemsForLocating); + tagLabel->setBuddy(modeChoseBox); + hLayout = std::get<2>(m_modeTwoItemsForLocating); + hLayout->addWidget(tagLabel); + hLayout->addWidget(modeChoseBox); + + + m_modeTwoLayout.first->addLayout(std::get<2>(m_modeTwoItemsForAdding)); + m_modeTwoLayout.first->addSpacing(10); + m_modeTwoLayout.first->addLayout(std::get<2>(m_modeTwoItemsForLocating)); + m_modeTwoLayout.first->setSpacing(0); + m_modeTwoLayout.first->setMargin(0); + m_modeTwoLayout.second->setLayout(m_modeTwoLayout.first); + + + ///###: mode 3 + tagLabel = std::get<0>(m_modeThreeItemsForFileName); + contentLineEdit = std::get<1>(m_modeThreeItemsForFileName); + tagLabel->setBuddy(contentLineEdit); + hLayout = std::get<2>(m_modeThreeItemsForFileName); + hLayout->addWidget(tagLabel); + hLayout->addWidget(contentLineEdit); + + tagLabel = std::get<0>(m_modeThreeItemsForSNNumber); + contentLineEdit = std::get<1>(m_modeThreeItemsForSNNumber); + tagLabel->setBuddy(contentLineEdit); + hLayout = std::get<2>(m_modeThreeItemsForSNNumber); + hLayout->addWidget(tagLabel); + hLayout->addWidget(contentLineEdit); + + + m_modeThreeLayout.first->addLayout(std::get<2>(m_modeThreeItemsForFileName)); + m_modeThreeLayout.first->addSpacing(10); + m_modeThreeLayout.first->addLayout(std::get<2>(m_modeThreeItemsForSNNumber)); + m_modeThreeLayout.first->setSpacing(0); + m_modeThreeLayout.first->setMargin(0); + m_modeThreeLayout.second->setLayout(m_modeThreeLayout.first); + + ///###: total layout. + m_mainLayout->setSpacing(0); + m_mainLayout->setMargin(0); + m_mainLayout->addWidget(m_titleLabel); + m_mainLayout->addSpacing(30); + m_mainLayout->addLayout(std::get<2>(m_itemsForSelecting)); + m_mainLayout->addSpacing(10); + + ///(Qt5.15.0)wayland下必须在此处创建m_stackedLayout并设置父子关系 + ///不设置父子关系会导致在m_stackedLayout中点击鼠标时无法获取焦点 + ///提前创建对象,再在此处设置父子关系无效,依然存在点击鼠标无焦点问题 + ///提前创建对象并设置父子关系,会导致m_stackedLayout位置在布局的最上面 + m_stackedLayout = new QStackedLayout(m_mainLayout); + m_stackedLayout->addWidget(m_modeOneLayout.second); + m_stackedLayout->addWidget(m_modeTwoLayout.second); + m_stackedLayout->addWidget(m_modeThreeLayout.second); + m_stackedLayout->setCurrentIndex(0); + m_mainLayout->addLayout(m_stackedLayout); + + m_mainLayout->addSpacing(15); + + m_mainFrame->setLayout(m_mainLayout); +} + +QString DDesktopRenameDialogPrivate::filteringText(const QString &text) +{ + if (text.isEmpty()) + return text; + + QString readyText = text; + return readyText.remove(QRegExp("[\\\\/:\\*\\?\"<>|%&]")); +} + +void DDesktopRenameDialogPrivate::updateLineEditText(QLineEdit *lineEdit, const QString &defaultValue) +{ + QString olderText = lineEdit->text(); + QString text = filteringText(olderText); + if (olderText != text) { + lineEdit->setText(text); + } + if (text.isEmpty()) { + lineEdit->setText(defaultValue); + } +} + +DDesktopRenameDialog::DDesktopRenameDialog(QWidget *const parent) + : DDialog{ parent }, + d_ptr{ new DDesktopRenameDialogPrivate{ this } } +{ + this->initUi(); + this->initConnect(); + + this->installEventFilter(this); +} + + +///###: I initialize buttons here. +/// and other widgets in DDesktopRenameDialog is initialized when new DDesktopRenameDialogPrivate. +void DDesktopRenameDialog::initUi() +{ + if(DFMGlobal::isWayLand()) + { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + } + + Q_D(const DDesktopRenameDialog); + this->addContent(d->m_mainFrame, Qt::AlignCenter); + this->addButton(QObject::tr("Cancel","button")); + this->addButton(QObject::tr("Rename","button"), true, ButtonRecommend); +} + +void DDesktopRenameDialog::initConnect() +{ + Q_D(const DDesktopRenameDialog); + using funcType = void (QComboBox::*)(int index); + + + QObject::connect(std::get<1>(d->m_itemsForSelecting), static_cast(&QComboBox::currentIndexChanged), this, &DDesktopRenameDialog::onCurrentModeChanged); + QObject::connect(std::get<1>(d->m_modeTwoItemsForLocating), static_cast(&QComboBox::currentIndexChanged), this, &DDesktopRenameDialog::onCurrentAddModeChanged); + QObject::connect(std::get<1>(d->m_modeThreeItemsForSNNumber), &QLineEdit::textChanged, this, &DDesktopRenameDialog::onContentChangedForCustomzedSN); + QObject::connect(this, &DDesktopRenameDialog::visibleChanged, this, &DDesktopRenameDialog::onVisibleChanged); + + connect(std::get<1>(d->m_modeOneItemsForFinding), &QLineEdit::textChanged, this, [ = ]() { + onVisibleChanged(true); + }); + connect(std::get<1>(d->m_modeOneItemsForReplacing), &QLineEdit::textChanged, this, [ = ]() { + onReplaceTextChanged(); + }); + connect(std::get<1>(d->m_modeTwoItemsForAdding), &QLineEdit::textChanged, this, [ = ]() { + onVisibleChanged(true); + }); + connect(std::get<1>(d->m_modeThreeItemsForFileName), &QLineEdit::textChanged, this, [ = ]() { + onVisibleChanged(true); + }); + + try { + + if (QPushButton *cancelButton = dynamic_cast(this->getButton(0))) { + QObject::connect(this, &DDesktopRenameDialog::clickCancelButton, cancelButton, &QPushButton::click); + } + + if (QPushButton *renameButton = dynamic_cast(this->getButton(1))) { + QObject::connect(this, &DDesktopRenameDialog::clickRenameButton, renameButton, &QPushButton::click); + } + + } catch (const std::bad_cast &error) { + (void)error; + + throw std::runtime_error{ "badly dynamic cast in DDesktopRenameDialog" }; + } + +} + + +void DDesktopRenameDialog::onCurrentModeChanged(const std::size_t &index)noexcept +{ + DDesktopRenameDialogPrivate *const d{ d_func() }; + + d->m_currentmode = index; + d->m_stackedLayout->setCurrentIndex(index); + + ///###: here, make lineEdit has focus immediately, after change mode. + this->onVisibleChanged(true); +} + +void DDesktopRenameDialog::onCurrentAddModeChanged(const std::size_t &index)noexcept +{ + DDesktopRenameDialogPrivate *d{ d_func() }; + + if (index == 0) { + d->m_flagForAdding = DFileService::AddTextFlags::Before; + + } else { + d->m_flagForAdding = DFileService::AddTextFlags::After; + } + + ///###: here, make lineEdit has focus immediately, after change mode. + this->onVisibleChanged(true); +} + +std::size_t DDesktopRenameDialog::getCurrentModeIndex()const noexcept +{ + const DDesktopRenameDialogPrivate *const d{ d_func() }; + + return d->m_currentmode; +} + +DFileService::AddTextFlags DDesktopRenameDialog::getAddMode()const noexcept +{ + const DDesktopRenameDialogPrivate *const d{ d_func() }; + + return d->m_flagForAdding; +} + +QPair DDesktopRenameDialog::getModeOneContent()const noexcept +{ + const DDesktopRenameDialogPrivate *const d{ d_func() }; + + QString findStr{ std::get<1>(d->m_modeOneItemsForFinding)->text() }; + QString replaceStr{ std::get<1>(d->m_modeOneItemsForReplacing)->text() }; + + return QPair { findStr, replaceStr }; +} + + +QPair DDesktopRenameDialog::getModeTwoContent()const noexcept +{ + const DDesktopRenameDialogPrivate *const d{ d_func() }; + + QString addStr{ std::get<1>(d->m_modeTwoItemsForAdding)->text() }; + DFileService::AddTextFlags flag{ d->m_flagForAdding }; + + return QPair { addStr, flag }; +} + + +QPair DDesktopRenameDialog::getModeThreeContent()const noexcept +{ + const DDesktopRenameDialogPrivate *const d{ d_func() }; + + QString fileName{ std::get<1>(d->m_modeThreeItemsForFileName)->text() }; + QString numberStr{ std::get<1>(d->m_modeThreeItemsForSNNumber)->text() }; + + if (numberStr.isEmpty()) { // if the number is empty should set one default value + numberStr = QString{"1"}; + } + + return QPair { fileName, numberStr}; +} + + +///###: This function will change enable of property of the button and +/// style sheet. +void DDesktopRenameDialog::setRenameButtonStatus(const bool &enabled) +{ + if (QPushButton *renameButton = dynamic_cast(this->getButton(1))) { + + renameButton->setEnabled(enabled); + } +} + + +void DDesktopRenameDialog::onContentChangedForFinding(const QString &content) +{ + DDesktopRenameDialogPrivate *const d{ d_func() }; + + if (content.isEmpty() == false) { + d->m_currentEnabled[0] = true; + this->setRenameButtonStatus(true); + + } else { + d->m_currentEnabled[0] = false; + this->setRenameButtonStatus(false); + } +} + + +void DDesktopRenameDialog::onContentChangedForAdding(const QString &content) +{ + DDesktopRenameDialogPrivate *const d{ d_func() }; + + if (content.isEmpty() == false) { + d->m_currentEnabled[1] = true; + this->setRenameButtonStatus(true); + + } else { + d->m_currentEnabled[1] = false; + this->setRenameButtonStatus(false); + } +} + +void DDesktopRenameDialog::onContentChangedForCustomzedSN(const QString &content) +{ + DDesktopRenameDialogPrivate *d{ d_func() }; + + QLineEdit *lineEditForSNNumber{ std::get<1>(d->m_modeThreeItemsForSNNumber) }; + + std::string numberStr{ content.toStdString() }; + try { + Q_UNUSED(std::stoull(numberStr)); + + } catch (const std::out_of_range &err) { + (void)err; + lineEditForSNNumber->setText(QString{"1"}); + + } catch (...) { + if (!numberStr.empty()) { // bug 26538: can edit the number + lineEditForSNNumber->setText(QString{"1"}); + } + } +} + +void DDesktopRenameDialog::setDialogTitle(const QString &tile)noexcept +{ + DDesktopRenameDialogPrivate *const d{ d_func() }; + d->m_titleLabel->setText(tile); +} + + +void DDesktopRenameDialog::setVisible(bool visible) +{ + this->DDialog::setVisible(visible); + emit visibleChanged(visible); +} + +void DDesktopRenameDialog::onReplaceTextChanged()noexcept +{ + DDesktopRenameDialogPrivate *const d{ d_func() }; + + QLineEdit *lineEdit{ std::get<1>(d->m_modeOneItemsForReplacing) }; + + d->updateLineEditText(lineEdit); +} + +void DDesktopRenameDialog::onVisibleChanged(bool visible)noexcept +{ + DDesktopRenameDialogPrivate *const d{ d_func() }; + + if (visible == true) { + + switch (d->m_currentmode) { + case 0: { + // for finding + QLineEdit *lineEdit = { std::get<1>(d->m_modeOneItemsForFinding) }; + + d->updateLineEditText(lineEdit); + setRenameButtonStatus(!lineEdit->text().isEmpty()); + lineEdit->setFocus(); + break; + } + case 1: { + QLineEdit *lineEdit{ std::get<1>(d->m_modeTwoItemsForAdding) }; + + d->updateLineEditText(lineEdit); + setRenameButtonStatus(!lineEdit->text().isEmpty()); + lineEdit->setFocus(); + break; + } + case 2: { + QLineEdit *lineEdit{ std::get<1>(d->m_modeThreeItemsForFileName) }; + + d->updateLineEditText(lineEdit); + setRenameButtonStatus(!lineEdit->text().isEmpty()); + lineEdit->setFocus(); + + QLineEdit *lineEditForSNNumber{ std::get<1>(d->m_modeThreeItemsForSNNumber) }; + d->updateLineEditText(lineEditForSNNumber, "1"); + + break; + } + default: + break; + + } + } +} + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/ddesktoprenamedialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/ddesktoprenamedialog.h new file mode 100644 index 0000000..6fcbfb0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/ddesktoprenamedialog.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DDESKTOPRENAMEDIALOG_H +#define DDESKTOPRENAMEDIALOG_H + + +#include + +#include "ddialog.h" +#include "interfaces/dfileservices.h" + +using namespace Dtk::Widget; + +class DDesktopRenameDialogPrivate; +class DDesktopRenameDialog : public DDialog +{ + Q_OBJECT + +public: + explicit DDesktopRenameDialog(QWidget* const parent = nullptr); + virtual ~DDesktopRenameDialog()=default; + + DDesktopRenameDialog(const DDesktopRenameDialog& other)=delete; + DDesktopRenameDialog& operator=(const DDesktopRenameDialog& other)=delete; + + + std::size_t getCurrentModeIndex()const noexcept; + DFileService::AddTextFlags getAddMode()const noexcept; + + QPair getModeOneContent()const noexcept; + QPair getModeTwoContent()const noexcept; + QPair getModeThreeContent()const noexcept; + + ///###: when is invoking DDesktopRenameDialog::show invoke this function actually. + virtual void setVisible(bool visible) override; + void setDialogTitle(const QString& tile)noexcept; + +signals: + void visibleChanged(bool visible); + void clickCancelButton(); + void clickRenameButton(); + +private slots: + void onCurrentModeChanged(const std::size_t& index)noexcept; + void onCurrentAddModeChanged(const std::size_t& index)noexcept; + + void onContentChangedForFinding(const QString& content); + void onContentChangedForAdding(const QString& content); + void onContentChangedForCustomzedSN(const QString& content); + void onVisibleChanged(bool visible)noexcept; + void onReplaceTextChanged()noexcept; + +private: + using DDialog::setWindowTitle; + + void initUi(); + void initConnect(); + void setRenameButtonStatus(const bool& enabled); + + QSharedPointer d_ptr{ nullptr }; + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), DDesktopRenameDialog) +}; + + + +#endif // DDESKTOPRENAMEDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dfmsettingdialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dfmsettingdialog.cpp new file mode 100644 index 0000000..84f7f4a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dfmsettingdialog.cpp @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmsettingdialog.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef DISABLE_QUICK_SEARCH +#include +#include +#include +#endif +#ifndef FULLTEXTSEARCH_ENABLE +#include +#include +#include +#else +#include "fulltextsearch/fulltextsearch.h" +#endif + +#include "dfmglobal.h" +#include "app/define.h" +#include "singleton.h" +#include "dfmapplication.h" +#include "app/filesignalmanager.h" +#include "dfmsettings.h" +#include "private/dfmsettingdialog_p.h" + +#define FULLTEXT_KEY "IndexFullTextSearch" +#define FULLTEXT_GROUP "GenericAttribute" + +SettingBackend::SettingBackend(QObject *parent) + : DSettingsBackend(parent) +{ + Q_ASSERT(DFMApplication::instance()); + + connect(DFMApplication::instance(), &DFMApplication::appAttributeEdited, this, &SettingBackend::onValueChanged); + connect(DFMApplication::instance(), &DFMApplication::genericAttributeEdited, this, &SettingBackend::onValueChanged); +} + +QStringList SettingBackend::keys() const +{ + return keyToAA.keys() + keyToGA.keys(); +} + +QVariant SettingBackend::getOption(const QString &key) const +{ + int attribute = keyToAA.value(key, static_cast(-1)); + + if (attribute >= 0) { + return DFMApplication::instance()->appAttribute(static_cast(attribute)); + } + + attribute = keyToGA.value(key, static_cast(-1)); + + Q_ASSERT(attribute >= 0); + + return DFMApplication::instance()->genericAttribute(static_cast(attribute)); +} + +void SettingBackend::doSync() +{ + +} + +void SettingBackend::doSetOption(const QString &key, const QVariant &value) +{ + QSignalBlocker blocker(this); + Q_UNUSED(blocker) + + int attribute = keyToAA.value(key, static_cast(-1)); + + if (attribute >= 0) { + return DFMApplication::instance()->setAppAttribute(static_cast(attribute), value); + } + + attribute = keyToGA.value(key, static_cast(-1)); + + Q_ASSERT(attribute >= 0); + + DFMApplication::instance()->setGenericAttribute(static_cast(attribute), value); + + //fix bug 39785 【专业版 sp3】【文件管理器】【5.2.0.8-1】文管菜单设置隐藏系统盘,关闭所有文管窗口,再打开新文管窗口,系统盘没有隐藏 + if (key == QString("advance.other.hide_system_partition")) { + fileSignalManager->requestHideSystemPartition(value.toBool()); + } + + // fix bug 81014 +#ifdef FULLTEXTSEARCH_ENABLE + if (key == QString("advance.index.index_search") && value.toBool()) + DFMFullTextSearchManager::getInstance()->fulltextIndex("/");/*全文搜索建立索引*/ +#endif +} + +void SettingBackend::onValueChanged(int attribute, const QVariant &value) +{ + QString key = keyToAA.key(static_cast(attribute)); + + if (key.isEmpty()) { + key = keyToGA.key(static_cast(attribute)); + } + + Q_ASSERT(!key.isEmpty()); + + emit optionChanged(key, value); +} + +static auto fromJsJson(const QString &fileName) -> decltype(DSettings::fromJson(QByteArray())) +{ + QFile file(fileName); + + if (!file.open(QFile::ReadOnly)) { + return nullptr; + } + + QByteArray data = file.readAll(); + + file.close(); + + auto indexOfChar = [](const QByteArray & data, char ch, int from) { + for (; from < data.size(); ++from) { + if (data.at(from) == '\\') { + continue; + } + + if (data.at(from) == ch) { + return from; + } + } + + return from; + }; + + auto clean_qsTr = [indexOfChar](QByteArray & data, int &from) { + const QByteArray &qsTr = QByteArrayLiteral("qsTr"); + const QByteArray &qsTranslate = QByteArrayLiteral("anslate("); + + if (qsTr != QByteArray(data.data() + from, qsTr.size())) { + return; + } + + int index = from + qsTr.size(); + + if (data.at(index) == '(') { + data.remove(from, index - from + 1); + } else if (qsTranslate == QByteArray(data.data() + index, qsTranslate.size())) { + index += qsTranslate.size(); + + // 寻找qsTranslate的第一个参数 + if (data.at(index) == '"' || data.at(index) == '\'') { + index = indexOfChar(data, data.at(index), index + 1); + + if (index >= data.size()) { + return; + } + } else { + return; + } + + int quote1_index = data.indexOf('"', index + 1); + int quote2_index = data.indexOf('\'', index + 1); + + if (quote1_index > 0) { + index = quote1_index; + } + + if (quote2_index > 0 && quote2_index < index) { + index = quote2_index; + } + + data.remove(from, index - from); + } else { + return; + } + + // 保留需要翻译的字符串 + if (data.at(from) == '"' || data.at(from) == '\'') { + from = indexOfChar(data, data.at(from), from + 1); + + if (from >= data.size()) { + return; + } + } else { + return; + } + + from = indexOfChar(data, ')', from + 1); + + if (from < data.size()) { + data.remove(from, 1); + from -= 1; + } + }; + + for (int i = 0; i < data.size(); ++i) { + char ch = data.at(i); + + switch (ch) { + case '\\': + break; + case '\'': + case '"': + i = indexOfChar(data, ch, i + 1); + break; + case 'q': + clean_qsTr(data, i); + break; + default: + break; + } + } + +#ifndef FULLTEXTSEARCH_ENABLE + auto const &jdoc = QJsonDocument::fromJson(data); + QJsonObject RootObject = jdoc.object(); + QJsonValueRef ArrayRef = RootObject.find("groups").value(); + QJsonArray Array = ArrayRef.toArray(); + QJsonArray::iterator ArrayIterator = Array.begin(); + QJsonValueRef ElementOneValueRef = ArrayIterator[1]; + QJsonObject ElementOneObject = ElementOneValueRef.toObject(); + QJsonValueRef ArrayRef2 = ElementOneObject.find("groups").value(); + QJsonArray Array2 = ArrayRef2.toArray(); + Array2.removeFirst(); + ArrayRef2 = Array2; + ElementOneValueRef = ElementOneObject; + ArrayRef = Array; + qDebug() << RootObject; + QByteArray arr = QJsonDocument(RootObject).toJson(); + + return DSettings::fromJson(arr); +#else +#ifdef DISABLE_QUICK_SEARCH + /*fix task 22667,针对ARM下不能使用anything,所以去掉整个索引配置项 + */ + //解析 + auto const &jdoc = QJsonDocument::fromJson(data); + QJsonObject RootObject = jdoc.object(); + QJsonValueRef ArrayRef = RootObject.find("groups").value(); + QJsonArray Array = ArrayRef.toArray(); + QJsonArray::iterator ArrayIterator = Array.begin(); + QJsonValueRef ElementOneValueRef = ArrayIterator[1]; + QJsonObject ElementOneObject = ElementOneValueRef.toObject(); + QJsonValueRef ArrayRef2 = ElementOneObject.find("groups").value(); + QJsonArray Array2 = ArrayRef2.toArray(); + QJsonArray::iterator ArrayIterator2 = Array2.begin(); + QJsonValueRef ElementOneValueRef2 = ArrayIterator2[0]; + QJsonObject ElementOneObject2 = ElementOneValueRef2.toObject(); + /*使能全文搜索在ARM下能正常工作*/ + QJsonValueRef indexArrayRef = ElementOneObject2.find("options").value(); + QJsonArray indexArray = indexArrayRef.toArray(); + indexArray.removeFirst(); + indexArray.removeFirst(); + indexArrayRef = indexArray; + + ElementOneValueRef2 = ElementOneObject2; + ArrayRef2 = Array2; + ElementOneValueRef = ElementOneObject; + ArrayRef = Array; + qDebug() << RootObject; + QByteArray arr = QJsonDocument(RootObject).toJson(); + + return DSettings::fromJson(arr); +#else + return DSettings::fromJson(data); +#endif +#endif +} + +QPointer DFMSettingDialog::AutoMountCheckBox = nullptr; +QPointer DFMSettingDialog::AutoMountOpenCheckBox = nullptr; + +DFMSettingDialog::DFMSettingDialog(QWidget *parent): + DSettingsDialog(parent) +{ + widgetFactory()->registerWidget("mountCheckBox", &DFMSettingDialog::createAutoMountCheckBox); + widgetFactory()->registerWidget("openCheckBox", &DFMSettingDialog::createAutoMountOpenCheckBox); + +#ifdef DISABLE_COMPRESS_PREIVEW + //load temlate + m_settings = fromJsJson(":/configure/global-setting-template-pro.js").data(); +#else +#ifdef DISABLE_FFMEPG + m_settings = fromJsJson(":/configure/global-setting-template-fedora.js").data(); +#else + m_settings = fromJsJson(":/configure/global-setting-template.js").data(); +#endif +#endif + + if(DFMGlobal::isWayLand()) + { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + this->setFixedSize(QSize(700, 700)); + } + + + //load conf value + auto backen = new SettingBackend(this); +#ifdef FULLTEXTSEARCH_ENABLE + //fulltext fix 42500 配置文件无FULLTEXT_KEY 导致第一次索引失败 + QVariant var = DFMApplication::genericSetting()->value(FULLTEXT_GROUP, FULLTEXT_KEY); + if (!var.isValid()) { + DFMApplication::genericSetting()->setValue(FULLTEXT_GROUP, FULLTEXT_KEY, QVariant(false)); + + } +#endif + m_settings->setParent(this); + m_settings->setBackend(backen); + updateSettings("GenerateSettingTranslate", m_settings); +} + +QPair DFMSettingDialog::createAutoMountCheckBox(QObject *opt) +{ + auto option = qobject_cast(opt); + QCheckBox *mountCheckBox = new QCheckBox(QObject::tr("Auto mount")); + DFMSettingDialog::AutoMountCheckBox = mountCheckBox; + + if (option->value().toBool()) { + mountCheckBox->setChecked(true); + } else if (AutoMountOpenCheckBox) { + AutoMountOpenCheckBox->setDisabled(true); + } + + QObject::connect(mountCheckBox, + &QCheckBox::stateChanged, + option, + [ = ](int state) { + if (state == 0) { + if (DFMSettingDialog::AutoMountOpenCheckBox) { + DFMSettingDialog::AutoMountOpenCheckBox->setDisabled(true); + DFMSettingDialog::AutoMountOpenCheckBox->setChecked(false); + } + option->setValue(false); + } else if (state == 2) { + if (DFMSettingDialog::AutoMountOpenCheckBox) { + DFMSettingDialog::AutoMountOpenCheckBox->setDisabled(false); + } + + option->setValue(true); + } + }); + + QObject::connect(option, &DSettingsOption::valueChanged, mountCheckBox, [ = ](QVariant value) { + mountCheckBox->setChecked(value.toBool()); + }); + + return qMakePair(mountCheckBox, nullptr); +} + +QPair DFMSettingDialog::createAutoMountOpenCheckBox(QObject *opt) +{ + auto option = qobject_cast(opt); + QCheckBox *openCheckBox = new QCheckBox(QObject::tr("Open after auto mount")); + DFMSettingDialog::AutoMountOpenCheckBox = openCheckBox; + + if (option->value().toBool()) { + openCheckBox->setChecked(true); + openCheckBox->setDisabled(false); + } else { + if (AutoMountCheckBox && !AutoMountCheckBox->isChecked()) { + openCheckBox->setDisabled(true); + } + } + + QObject::connect(openCheckBox, + &QCheckBox::stateChanged, + option, + [ = ](int state) { + if (state == 0) { + option->setValue(false); + } else if (state == 2) { + option->setValue(true); + } + }); + + QObject::connect(option, &DSettingsOption::valueChanged, openCheckBox, [ = ](QVariant value) { + openCheckBox->setChecked(value.toBool()); + }); + + return qMakePair(openCheckBox, nullptr); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dfmsettingdialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dfmsettingdialog.h new file mode 100644 index 0000000..d55e343 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dfmsettingdialog.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMSETTINGDIALOG_H +#define DFMSETTINGDIALOG_H + + +#include +#include + +DWIDGET_USE_NAMESPACE + +DCORE_BEGIN_NAMESPACE +class DSettings; +DCORE_END_NAMESPACE + +DCORE_USE_NAMESPACE + +class DFMSettingDialog : public DSettingsDialog +{ +public: + explicit DFMSettingDialog(QWidget *parent = nullptr); + + static QPair createAutoMountCheckBox(QObject* opt); + static QPair createAutoMountOpenCheckBox(QObject* opt); + + static QPointer AutoMountCheckBox; + static QPointer AutoMountOpenCheckBox; + +private: + QPointer m_settings; +}; + +#endif // DFMSETTINGDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dialogmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dialogmanager.cpp new file mode 100755 index 0000000..6ae76e4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dialogmanager.cpp @@ -0,0 +1,1618 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +//fix:一旦刻录失败,必须清楚磁盘临时缓存的数据文件,否则下次刻录操作等就会报一些错误,不能正常进行操作流程 +#include "qfile.h" +#include "dfilemenumanager.h" +#include "disomaster.h" + +#include "dialogmanager.h" +#include "closealldialogindicator.h" +#include "trashpropertydialog.h" +#include "computerpropertydialog.h" +#include "usersharepasswordsettingdialog.h" +#include "movetotrashconflictdialog.h" +#include "views/dfilemanagerwindow.h" +#include "interfaces/dfmstyleditemdelegate.h" +#include "shutil/mimetypedisplaymanager.h" +#include "filepreviewdialog.h" +#include "dfmsettingdialog.h" +#include "connecttoserverdialog.h" + +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "dfmevent.h" + +#include "fileoperations/filejob.h" +#include "dfileservices.h" +#include "interfaces/dfmstandardpaths.h" + +#include "dfileinfo.h" +#include "models/trashfileinfo.h" + +#include "controllers/vaultcontroller.h" + +#include "views/windowmanager.h" + +#include "xutil.h" +#include "utils.h" +#include "dialogs/ddesktoprenamedialog.h" +#include "dialogs/dtaskdialog.h" +#include "dialogs/propertydialog.h" +#include "dialogs/openwithdialog.h" +#include "dialogs/dmultifilepropertydialog.h" +#include "bluetooth/bluetoothtransdialog.h" +#include "plugins/pluginmanager.h" +#include "preview/previewinterface.h" +#include "views/dfmopticalmediawidget.h" + +#include "deviceinfo/udisklistener.h" +#include "deviceinfo/udiskdeviceinfo.h" + +#include "singleton.h" +#include "gvfs/gvfsmountmanager.h" +#include "ddiskmanager.h" +#include "dblockdevice.h" +#include "utils/desktopinfo.h" + +#ifdef SW_LABEL +#include "sw_label/llsdeepinlabellibrary.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DTK_USE_NAMESPACE +DWIDGET_USE_NAMESPACE + +DFM_USE_NAMESPACE + +DialogManager::DialogManager(QObject *parent) : QObject(parent) +{ + initData(); + initTaskDialog(); + initCloseIndicatorDialog(); + initConnect(); +} + +DialogManager::~DialogManager() +{ +} + +void DialogManager::initData() +{ + m_dialogInfoIcon = QIcon::fromTheme("dialog-information"); + m_dialogWarningIcon = QIcon::fromTheme("dialog-warning"); + m_dialogErrorIcon = QIcon::fromTheme("dialog-error"); +} + +void DialogManager::initTaskDialog() +{ + m_taskDialog = new DTaskDialog; + m_taskDialog->setWindowIcon(QIcon::fromTheme("dde-file-manager")); + m_updateJobTaskTimer = new QTimer(this); + m_updateJobTaskTimer->setInterval(1000); + connect(m_updateJobTaskTimer, &QTimer::timeout, this, &DialogManager::updateJob); +} + +void DialogManager::initCloseIndicatorDialog() +{ + m_closeIndicatorDialog = new CloseAllDialogIndicator; + m_closeIndicatorDialog->setWindowIcon(QIcon::fromTheme("dde-file-manager")); + m_closeIndicatorTimer = new QTimer(this); + m_closeIndicatorTimer->setInterval(1000); + connect(m_closeIndicatorTimer, &QTimer::timeout, this, &DialogManager::updateCloseIndicator); +} + +void DialogManager::initConnect() +{ + connect(fileSignalManager, &FileSignalManager::requestStartUpdateJobTimer, this, &DialogManager::startUpdateJobTimer); + connect(fileSignalManager, &FileSignalManager::requestStopUpdateJobTimer, this, &DialogManager::stopUpdateJobTimer); + + connect(fileSignalManager, &FileSignalManager::requestAbortJob, this, &DialogManager::abortJobByDestinationUrl); + + connect(m_taskDialog, &DTaskDialog::conflictRepsonseConfirmed, this, &DialogManager::handleConflictRepsonseConfirmed); + + connect(m_taskDialog, &DTaskDialog::abortTask, this, &DialogManager::abortJob); + connect(m_taskDialog, &DTaskDialog::closed, this, &DialogManager::removeAllJobs); + connect(m_closeIndicatorDialog, &CloseAllDialogIndicator::allClosed, this, &DialogManager::closeAllPropertyDialog); + + connect(fileSignalManager, &FileSignalManager::requestShowUrlWrongDialog, this, &DialogManager::showUrlWrongDialog); + connect(fileSignalManager, &FileSignalManager::requestShowOpenWithDialog, this, &DialogManager::showOpenWithDialog); + connect(fileSignalManager, &FileSignalManager::requestShowOpenFilesWithDialog, this, &DialogManager::showOpenFilesWithDialog); + connect(fileSignalManager, &FileSignalManager::requestShowPropertyDialog, this, &DialogManager::showPropertyDialog); + connect(fileSignalManager, &FileSignalManager::requestShowShareOptionsInPropertyDialog, this, &DialogManager::showShareOptionsInPropertyDialog); + connect(fileSignalManager, &FileSignalManager::requestShowComputerPropertyDialog, this, &DialogManager::showComputerPropertyDialog); + connect(fileSignalManager, &FileSignalManager::requestShowTrashPropertyDialog, this, &DialogManager::showTrashPropertyDialog); + connect(fileSignalManager, &FileSignalManager::requestShowDevicePropertyDialog, this, &DialogManager::showDevicePropertyDialog); + connect(fileSignalManager, &FileSignalManager::showDiskErrorDialog, + this, &DialogManager::showDiskErrorDialog); + connect(fileSignalManager, &FileSignalManager::requestShow4GFat32Dialog, + this, &DialogManager::show4gFat32Dialog); + connect(fileSignalManager, &FileSignalManager::requestShowRestoreFailedDialog, + this, &DialogManager::showRestoreFailedDialog); + connect(fileSignalManager, &FileSignalManager::requestShowRestoreFailedPerssionDialog, + this, &DialogManager::showRestoreFailedPerssionDialog); + connect(fileSignalManager, &FileSignalManager::requestShowRestoreFailedSourceNotExist, + this, &DialogManager::showRestoreFailedSourceNotExists); + connect(fileSignalManager, &FileSignalManager::requestShowNoPermissionDialog, + this, &DialogManager::showNoPermissionDialog); + + connect(fileSignalManager, &FileSignalManager::requestShowAddUserShareFailedDialog, + this, &DialogManager::showAddUserShareFailedDialog); + + connect(fileSignalManager, &FileSignalManager::requestShowFilePreviewDialog, this, &DialogManager::showFilePreviewDialog); + connect(fileSignalManager, &FileSignalManager::requestShowErrorDialog, this, &DialogManager::showErrorDialog); + connect(fileSignalManager, &FileSignalManager::activeTaskDlg, this, &DialogManager::showTaskProgressDlgOnActive); +#ifdef SW_LABEL + connect(fileSignalManager, &FileSignalManager::jobFailed, this, &DialogManager::onJobFailed_SW); +#endif + +// connect(qApp, &QApplication::focusChanged, this, &DialogManager::handleFocusChanged); + +} + +QPoint DialogManager::getPropertyPos(int dialogWidth, int dialogHeight) +{ + const QScreen *cursor_screen = Q_NULLPTR; + const QPoint &cursor_pos = QCursor::pos(); + + auto screens = qApp->screens(); + auto iter = std::find_if(screens.begin(), screens.end(), [cursor_pos](const QScreen * screen) { + return screen->geometry().contains(cursor_pos); + }); + + if (iter != screens.end()) { + cursor_screen = *iter; + } + + if (!cursor_screen) { + cursor_screen = qApp->primaryScreen(); + } + + int desktopWidth = cursor_screen->size().width(); + int desktopHeight = cursor_screen->size().height(); + int x = (desktopWidth - dialogWidth) / 2; + + int y = (desktopHeight - dialogHeight) / 2; + + return QPoint(x, y) + cursor_screen->geometry().topLeft(); +} + +QPoint DialogManager::getPerportyPos(int dialogWidth, int dialogHeight, int count, int index) +{ + Q_UNUSED(dialogHeight) + const QScreen *cursor_screen = Q_NULLPTR; + const QPoint &cursor_pos = QCursor::pos(); + + auto screens = qApp->screens(); + auto iter = std::find_if(screens.begin(), screens.end(), [cursor_pos](const QScreen * screen) { + return screen->geometry().contains(cursor_pos); + }); + + if (iter != screens.end()) { + cursor_screen = *iter; + } + + if (!cursor_screen) { + cursor_screen = qApp->primaryScreen(); + } + + int desktopWidth = cursor_screen->size().width(); +// int desktopHeight = cursor_screen->size().height();//后面未用,注释掉 + int SpaceWidth = 20; + int SpaceHeight = 70; + int row, x, y; + int numberPerRow = desktopWidth / (dialogWidth + SpaceWidth); + Q_ASSERT(numberPerRow != 0); + if (count % numberPerRow == 0) { + row = count / numberPerRow; + } else { + row = count / numberPerRow + 1; + } + Q_UNUSED(row) + int dialogsWidth; + if (count / numberPerRow > 0) { + dialogsWidth = dialogWidth * numberPerRow + SpaceWidth * (numberPerRow - 1); + } else { + dialogsWidth = dialogWidth * (count % numberPerRow) + SpaceWidth * (count % numberPerRow - 1); + } + +// int dialogsHeight = dialogHeight + SpaceHeight * (row - 1);//未用注释掉 + + x = (desktopWidth - dialogsWidth) / 2 + (dialogWidth + SpaceWidth) * (index % numberPerRow); + + y = 5 + (index / numberPerRow) * SpaceHeight; + return QPoint(x, y) + cursor_screen->geometry().topLeft(); +} + +bool DialogManager::isTaskDialogEmpty() +{ + if (m_taskDialog->getTaskListWidget()->count() == 0) { + return true; + } + return false; +} + +DTaskDialog *DialogManager::taskDialog() const +{ + return m_taskDialog; +} + +void DialogManager::addJob(QSharedPointer job) +{ + QMutexLocker locker(&m_mutexJob); + qInfo() << "add job: " << job->jobTypeToString() << "," << job->getJobId(); + + m_jobs.insert(job->getJobId(), job); + emit fileSignalManager->requestStartUpdateJobTimer(); + + job->disconnect(m_taskDialog); // 对于光盘刻录、擦除的 job,可能会因为进度框的关闭打开而多次被添加导致多次连接槽,所以这里在连接前先断开这部分的信号槽 + job->disconnect(this); + connect(job.data(), &FileJob::requestJobAdded, m_taskDialog, &DTaskDialog::addTask); + connect(job.data(), &FileJob::requestJobRemoved, m_taskDialog, &DTaskDialog::delayRemoveTask); + connect(job.data(), &FileJob::requestJobRemovedImmediately, m_taskDialog, &DTaskDialog::removeTaskImmediately); + connect(job.data(), &FileJob::requestJobDataUpdated, m_taskDialog, &DTaskDialog::handleUpdateTaskWidget); + connect(job.data(), &FileJob::requestAbortTask, m_taskDialog, &DTaskDialog::handleTaskClose); + connect(job.data(), &FileJob::requestCopyMoveToSelfDialogShowed, this, &DialogManager::showCopyMoveToSelfDialog); + connect(job.data(), &FileJob::requestNoEnoughSpaceDialogShowed, this, &DialogManager::showDiskSpaceOutOfUsedDialogLater); + connect(job.data(), &FileJob::requestCanNotMoveToTrashDialogShowed, this, &DialogManager::showMoveToTrashConflictDialog); + connect(job.data(), &FileJob::requestOpticalJobFailureDialog, this, &DialogManager::showOpticalJobFailureDialog); + connect(job.data(), &FileJob::requestOpticalJobCompletionDialog, this, &DialogManager::showOpticalJobCompletionDialog); +} + + +void DialogManager::removeJob(const QString &jobId, bool isRemoveOpticalJob) +{ + QMutexLocker locker(&m_mutexJob); + + if (m_jobs.contains(jobId)) { + QSharedPointer job = m_jobs.value(jobId); + if (job->getIsOpticalJob() && !job->getIsFinished()) { + if(!isRemoveOpticalJob) { + qDebug() << "ignore to remove job: " << job->jobTypeToString() << "," << job->getJobId(); + return; + } + } + qInfo() << "remove job: " << job->jobTypeToString() << "," << job->getJobId(); + + job->setIsAborted(true); + job->setApplyToAll(true); + job->cancelled(); + m_jobs.remove(jobId); + } + if (m_jobs.count() == 0) { + emit fileSignalManager->requestStopUpdateJobTimer(); + } +} + +QString DialogManager::getJobIdByUrl(const DUrl &url) +{ + foreach (const QString &jobId, m_jobs.keys()) { + QSharedPointer job = m_jobs.value(jobId); + bool ret = false; + QStringList pathlist = job->property("pathlist").toStringList(); + + auto iter = std::find_if(pathlist.begin(), pathlist.end(), [url](const QString & path) { + return path == url.toLocalFile(); + }); + + if (iter != pathlist.end()) { + ret = true; + } + + if (ret) { + return job->getJobId(); + } + } + + return QString(); +} + +void DialogManager::removeAllJobs() +{ + foreach (const QString &jobId, m_jobs.keys()) { + removeJob(jobId); + } +} + +void DialogManager::updateJob() +{ + foreach (QString jobId, m_jobs.keys()) { + QSharedPointer job = m_jobs.value(jobId); + if (job) { + if (!job->isCanShowProgress()) + return; + + if (job->currentMsec() - job->lastMsec() > FileJob::Msec_For_Display) { + if (!job->isJobAdded()) { + job->jobAdded(); + job->jobUpdated(); + } else { + job->jobUpdated(); + } + } + } + } +} + +void DialogManager::startUpdateJobTimer() +{ + m_updateJobTaskTimer->start(); +} + +void DialogManager::stopUpdateJobTimer() +{ + m_updateJobTaskTimer->stop(); +} + +void DialogManager::abortJob(const QMap &jobDetail) +{ + QString jobId = jobDetail.value("jobId"); + removeJob(jobId); +} + +void DialogManager::abortJobByDestinationUrl(const DUrl &url) +{ + qDebug() << url; + foreach (QString jobId, m_jobs.keys()) { + QSharedPointer job = m_jobs.value(jobId); + qDebug() << jobId << job->getTargetDir(); + if (!QFile(job->getTargetDir()).exists()) { + job->jobAborted(); + } + } +} + +void DialogManager::showCopyMoveToSelfDialog(const QMap &jobDetail) +{ + DDialog d; + d.setTitle(tr("Operation failed!")); + d.setMessage(tr("Target folder is inside the source folder!")); + QStringList buttonTexts; + buttonTexts.append(tr("OK","button")); + d.addButton(buttonTexts[0], true, DDialog::ButtonRecommend); + d.setDefaultButton(0); + d.setIcon(m_dialogWarningIcon); + QTimer::singleShot(200, &d, &DDialog::raise); + int code = d.exec(); + qDebug() << code; + if (code == 0) { + qDebug() << "close CopyMoveToSelf dialog" << jobDetail; + } +} + +void DialogManager::showUrlWrongDialog(const DUrl &url) +{ + Q_UNUSED(url) +} + +int DialogManager::showRunExcutableScriptDialog(const DUrl &url, quint64 winId) +{ + DDialog d(WindowManager::getWindowById(winId)); + int maxDisplayNameLength = 250; + QString _fileDisplayName = QFileInfo(url.path()).fileName(); + QString fileDisplayName = d.fontMetrics().elidedText(_fileDisplayName, Qt::ElideRight, maxDisplayNameLength); + QString message = tr("Do you want to run %1 or display its content?").arg(fileDisplayName); + QString tipMessage = tr("It is an executable text file."); + QStringList buttonKeys, buttonTexts; + buttonKeys.append("OptionCancel"); + buttonKeys.append("OptionRun"); + buttonKeys.append("OptionRunInTerminal"); + buttonKeys.append("OptionDisplay"); + buttonTexts.append(tr("Cancel","button")); + buttonTexts.append(tr("Run","button")); + buttonTexts.append(tr("Run in terminal","button")); + buttonTexts.append(tr("Display","button")); + d.setIcon(QIcon::fromTheme("application-x-shellscript")); + d.setTitle(message); + d.setMessage(tipMessage); + d.addButton(buttonTexts[0], true); + d.addButton(buttonTexts[1], false); + d.addButton(buttonTexts[2], false); + d.addButton(buttonTexts[3], false, DDialog::ButtonRecommend); + d.setDefaultButton(3); + d.setFixedWidth(480); + int code = d.exec(); + return code; +} + +int DialogManager::showRunExcutableFileDialog(const DUrl &url, quint64 winId) +{ + DDialog d(WindowManager::getWindowById(winId)); + const DAbstractFileInfoPointer &pfileInfo = fileService->createFileInfo(this, url); + int maxDisplayNameLength = 200; + QString _fileDisplayName = QFileInfo(url.path()).fileName(); + QString fileDisplayName = d.fontMetrics().elidedText(_fileDisplayName, Qt::ElideRight, maxDisplayNameLength); + QString message = tr("Do you want to run %1?").arg(fileDisplayName); + QString tipMessage = tr("It is an executable file."); + d.addButton(tr("Cancel","button")); + d.addButton(tr("Run in terminal","button")); + d.addButton(tr("Run","button"), true, DDialog::ButtonRecommend); + d.setTitle(message); + d.setMessage(tipMessage); + d.setIcon(pfileInfo->fileIcon()); + int code = d.exec(); + return code; +} + +int DialogManager::showAskIfAddExcutableFlagAndRunDialog(const DUrl &url, quint64 winId) +{ + DDialog d(WindowManager::getWindowById(winId)); + const DAbstractFileInfoPointer &pfileInfo = fileService->createFileInfo(this, url); + // i18n text from: https://github.com/linuxdeepin/internal-discussion/issues/456 , seems a little weird.. + QString message = tr("This file is not executable, do you want to add the execute permission and run?"); + d.addButton(tr("Cancel","button")); + d.addButton(tr("Run","button"), true, DDialog::ButtonRecommend); + d.setTitle(message); + d.setIcon(pfileInfo->fileIcon()); + int code = d.exec(); + return code; +} + + +int DialogManager::showRenameNameSameErrorDialog(const QString &name, const DFMEvent &event) +{ + DDialog d(WindowManager::getWindowById(event.windowId())); + QFontMetrics fm(d.font()); + d.setTitle(tr("\"%1\" already exists, please use another name.").arg(fm.elidedText(name, Qt::ElideMiddle, 150))); + QStringList buttonTexts; + buttonTexts.append(tr("Confirm","button")); + d.addButton(buttonTexts[0], true, DDialog::ButtonRecommend); + d.setDefaultButton(0); + d.setIcon(m_dialogWarningIcon); + int code = d.exec(); + return code; +} + +int DialogManager::showRenameNameDotDotErrorDialog(const DFMEvent &event) +{ + // 获取父对话框字体特性 + DDialog d(WindowManager::getWindowById(event.windowId())); + QFontMetrics fm(d.font()); + d.setTitle(tr("The file name must not contain two dots (..)")); + QStringList buttonTexts; + buttonTexts.append(tr("Confirm","button")); + d.addButton(buttonTexts[0], true, DDialog::ButtonRecommend); + d.setDefaultButton(0); + // 设置对话框icon + d.setIcon(m_dialogWarningIcon); + int code = d.exec(); + return code; +} + +void DialogManager::showRenameBusyErrDialog(const DFMEvent &event) +{ + // 获取父对话框字体特性 + DDialog d(WindowManager::getWindowById(event.windowId())); + QFontMetrics fm(d.font()); + d.setTitle(tr("Device or resource busy")); + QStringList buttonTexts; + buttonTexts.append(tr("Confirm","button")); + d.addButton(buttonTexts[0], true, DDialog::ButtonRecommend); + d.setDefaultButton(0); + // 设置对话框icon + d.setIcon(m_dialogWarningIcon); + d.exec(); +} + +int DialogManager::showOpticalBlankConfirmationDialog(const DFMUrlBaseEvent &event) +{ + QString EraseDisk = tr("Are you sure you want to erase all data on the disc?"); + + DUrl url = event.url(); + qDebug() << url; + QStringList buttonTexts; + buttonTexts.append(tr("Cancel","button")); + buttonTexts.append(tr("Erase","button")); + + DDialog d; + + if (!d.parentWidget()) { + d.setWindowFlags(d.windowFlags() | Qt::WindowStaysOnTopHint); + } + + d.setTitle(EraseDisk); + d.setMessage(tr("This action cannot be undone")); + d.setIcon(QIcon::fromTheme("media-optical").pixmap(64, 64)); + d.addButton(buttonTexts[0], true, DDialog::ButtonNormal); + d.addButton(buttonTexts[1], false, DDialog::ButtonWarning); + d.setDefaultButton(1); + d.getButton(1)->setFocus(); + d.moveToCenter(); + int code = d.exec(); + return code; +} + +int DialogManager::showOpticalImageOpSelectionDialog(const DFMUrlBaseEvent &event) +{ + QString EraseDisk = tr("How do you want to use this disc?"); + + DUrl url = event.url(); + QStringList buttonTexts; + buttonTexts.append(tr("Cancel","button")); + buttonTexts.append(tr("Burn image","button")); + buttonTexts.append(tr("Burn files","button")); + + DDialog d; + + if (!d.parentWidget()) { + d.setWindowFlags(d.windowFlags() | Qt::WindowStaysOnTopHint); + } + + d.setTitle(EraseDisk); + d.setIcon(QIcon::fromTheme("media-optical").pixmap(64, 64)); + d.addButton(buttonTexts[0], false, DDialog::ButtonNormal); + d.addButton(buttonTexts[1], false, DDialog::ButtonNormal); + d.addButton(buttonTexts[2], true, DDialog::ButtonRecommend); + d.setDefaultButton(2); + d.getButton(2)->setFocus(); + d.moveToCenter(); + int code = d.exec(); + return code; +} + +void DialogManager::showOpticalJobFailureDialog(int type, const QString &err, const QStringList &details) +{ + DDialog d; + d.setIcon(QIcon::fromTheme("dialog-error")); + QString failure_type; + switch (type) { + case FileJob::OpticalBlank: + failure_type = tr("Disc erase failed"); + break; + case FileJob::OpticalBurn: + case FileJob::OpticalImageBurn: + failure_type = tr("Burn process failed"); + break; + case FileJob::OpticalCheck: + failure_type = tr("Data verification failed"); + break; + } + QString failure_str = QString(tr("%1: %2")).arg(failure_type).arg(err); + d.setTitle(failure_str); + QWidget *detailsw = new QWidget(&d); + detailsw->setLayout(new QVBoxLayout()); + QTextEdit *te = new QTextEdit(); + te->setPlainText(details.join('\n')); + te->setReadOnly(true); + te->hide(); + detailsw->layout()->addWidget(te); + connect(&d, &DDialog::buttonClicked, this, [failure_str, te, &d](int idx, const QString &) { + if (idx == 1) { + d.done(idx); + return; + } + if (te->isVisible()) { + te->hide(); + d.getButton(0)->setText(tr("Show details")); + d.setTitle(failure_str); + } else { + te->show(); + d.getButton(0)->setText(tr("Hide details")); + d.setTitle(tr("Error")); + } + }); + + detailsw->setFixedWidth(360); + d.layout()->setSizeConstraint(QLayout::SetFixedSize); // make sure dialog can shrank after expanded for more info. + + d.addContent(detailsw); + d.setOnButtonClickedClose(false); + d.addButton(tr("Show details","button")); + d.addButton(tr("Confirm","button"), true, DDialog::ButtonRecommend); + d.setDefaultButton(1); + d.getButton(1)->setFocus(); + d.exec(); +} + +void DialogManager::showOpticalJobCompletionDialog(const QString &msg, const QString &icon) +{ + DDialog d; + d.setIcon(QIcon::fromTheme(icon)); + d.setTitle(msg); + d.addButton(tr("OK","button"), true, DDialog::ButtonRecommend); + d.setDefaultButton(0); + d.getButton(0)->setFocus(); + d.exec(); +} + +int DialogManager::showDeleteFilesClearTrashDialog(const DFMUrlListBaseEvent &event) +{ + QString ClearTrash = tr("Are you sure you want to empty %1 item?"); + QString ClearTrashMutliple = tr("Are you sure you want to empty %1 items?"); + QString DeleteFileName = tr("Permanently delete %1?"); + QString DeleteFileItems = tr("Permanently delete %1 items?"); + + const int maxFileNameWidth = MAX_FILE_NAME_CHAR_COUNT; + + DUrlList urlList = event.urlList(); + QStringList buttonTexts; + buttonTexts.append(tr("Cancel","button")); + buttonTexts.append(tr("Delete","button")); + + DDialog d; + + if (!d.parentWidget()) { + d.setWindowFlags(d.windowFlags() | Qt::WindowStaysOnTopHint); + } + + QFontMetrics fm(d.font()); + d.setIcon(QIcon::fromTheme("user-trash-full-opened")); + if (urlList.first() == DUrl::fromTrashFile("/")) { + buttonTexts[1] = tr("Empty"); + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(this, urlList.first()); + if (fileInfo->filesCount() == 1) { + d.setTitle(ClearTrash.arg(fileInfo->filesCount())); + } else { + d.setTitle(ClearTrashMutliple.arg(fileInfo->filesCount())); + } + } else if (urlList.first().isLocalFile()) { + if (urlList.size() == 1) { + DFileInfo f(urlList.first()); + d.setTitle(DeleteFileName.arg(fm.elidedText(f.fileDisplayName(), Qt::ElideMiddle, maxFileNameWidth))); + } else { + d.setTitle(DeleteFileItems.arg(urlList.size())); + } + } else if (urlList.first().isTrashFile()) { + if (urlList.size() == 1) { + TrashFileInfo f(urlList.first()); + d.setTitle(DeleteFileName.arg(fm.elidedText(f.fileDisplayName(), Qt::ElideMiddle, maxFileNameWidth))); + } else { + d.setTitle(DeleteFileItems.arg(urlList.size())); + } + } else { + d.setTitle(DeleteFileItems.arg(urlList.size())); + } + d.setMessage(tr("This action cannot be undone")); + d.addButton(buttonTexts[0], true, DDialog::ButtonNormal); + d.addButton(buttonTexts[1], false, DDialog::ButtonWarning); + d.setDefaultButton(1); + d.getButton(1)->setFocus(); + d.moveToCenter(); + int code = d.exec(); + return code; +} + +int DialogManager::showNormalDeleteConfirmDialog(const DFMUrlListBaseEvent &event) +{ + DDialog d; + + if (!d.parentWidget()) { + d.setWindowFlags(d.windowFlags() | Qt::WindowStaysOnTopHint); + } + + QFontMetrics fm(d.font()); + d.setIcon(QIcon::fromTheme("user-trash-full-opened")); + + QString deleteFileName = tr("Do you want to delete %1?"); + QString deleteFileItems = tr("Do you want to delete the selected %1 items?"); + + DUrlList urlList = event.urlList(); + + if (urlList.first().isLocalFile()) { // delete local file + if (urlList.size() == 1) { + DFileInfo f(urlList.first()); + d.setTitle(deleteFileName.arg(fm.elidedText(f.fileDisplayName(), Qt::ElideMiddle, MAX_FILE_NAME_CHAR_COUNT))); + } else { + d.setTitle(deleteFileItems.arg(urlList.size())); + } + } else { + d.setTitle(deleteFileItems.arg(urlList.size())); + } + + QStringList buttonTexts; + buttonTexts.append(tr("Cancel","button")); + buttonTexts.append(tr("Delete","button")); + d.addButton(buttonTexts[0], true, DDialog::ButtonNormal); + d.addButton(buttonTexts[1], false, DDialog::ButtonWarning); + d.setDefaultButton(1); + d.getButton(1)->setFocus(); + d.moveToCenter(); + + return d.exec(); +} + +int DialogManager::showRemoveBookMarkDialog(const DFMEvent &event) +{ + DDialog d(WindowManager::getWindowById(event.windowId())); + d.setTitle(tr("Sorry, unable to locate your bookmark directory, remove it?")); + d.setMessage(" "); + QStringList buttonTexts; + buttonTexts.append(tr("Cancel","button")); + buttonTexts.append(tr("Remove","button")); + d.addButton(buttonTexts[0], true); + d.addButton(buttonTexts[1], false, DDialog::ButtonRecommend); + d.setDefaultButton(1); + d.setIcon(QIcon::fromTheme("folder-bookmark", QIcon::fromTheme("folder")).pixmap(64, 64)); + int code = d.exec(); + return code; +} + +void DialogManager::showOpenWithDialog(const DFMEvent &event) +{ + QWidget *w = WindowManager::getWindowById(event.windowId()); + if (w) { + OpenWithDialog *d = new OpenWithDialog(event.fileUrl()); + d->setDisplayPosition(OpenWithDialog::Center); + d->exec(); + } +} + +void DialogManager::showOpenFilesWithDialog(const DFMEvent &event) +{ +// QWidget *w = WindowManager::getWindowById(event.windowId()); +// if (w) { +// OpenWithDialog *d = new OpenWithDialog(event.fileUrlList()); +// d->setDisplayPosition(OpenWithDialog::Center); +// d->exec(); +// } +// 以前的方法,为了能够从命令行打开对话框,弃用 + OpenWithDialog *dialog = new OpenWithDialog(event.fileUrlList()); + dialog->setDisplayPosition(OpenWithDialog::Center); + dialog->open(); //不建议使用show、exec +} + +void DialogManager::showPropertyDialog(const DFMUrlListBaseEvent &event) +{ + const DUrlList &urlList = event.urlList(); + int count = urlList.count(); + + if (count <= MAX_PROPERTY_DIALOG_NUMBER) { + + foreach (const DUrl &url, urlList) { + int index = urlList.indexOf(url); + if (DFMGlobal::isComputerDesktopFile(url) || url == DUrl::fromComputerFile("/")) { + showComputerPropertyDialog(); + } else if (DFMGlobal::isTrashDesktopFile(url) || url == DUrl::fromTrashFile("/")) { + DFMEvent event(this); + event.setData(url); + showTrashPropertyDialog(event); + } else { + if (urlList.count() >= 2) { + m_closeIndicatorDialog->show(); + m_closeIndicatorTimer->start(); + } + + PropertyDialog *dialog; + if (m_propertyDialogs.contains(url)) { + dialog = m_propertyDialogs.value(url); + dialog->raise(); + } else { + dialog = new PropertyDialog(event, url); + dialog->setWindowFlags(dialog->windowFlags() & ~ Qt::FramelessWindowHint); + m_propertyDialogs.insert(url, dialog); + if (1 == count) { + QPoint pos = getPropertyPos(dialog->size().width(), dialog->getDialogHeight()); + dialog->move(pos); + } else { + QPoint pos = getPerportyPos(dialog->size().width(), dialog->size().height(), count, index); + dialog->move(pos); + } + dialog->show(); + + connect(dialog, &PropertyDialog::closed, this, &DialogManager::removePropertyDialog); + // connect(dialog, &PropertyDialog::raised, this, &DialogManager::raiseAllPropertyDialog); + QTimer::singleShot(100, dialog, &PropertyDialog::raise); + } + } + } + + } else { + m_multiFilesPropertyDialog = std::unique_ptr { new DMultiFilePropertyDialog{ std::move(urlList) } }; + m_multiFilesPropertyDialog->show(); + m_multiFilesPropertyDialog->moveToCenter(); + m_multiFilesPropertyDialog->raise(); + } +} + +void DialogManager::showShareOptionsInPropertyDialog(const DFMUrlListBaseEvent &event) +{ + DUrl url = event.fileUrlList().first(); + showPropertyDialog(event); + if (m_propertyDialogs.contains(url)) { + PropertyDialog *dialog = m_propertyDialogs.value(url); + if (dialog->expandGroup().count() > 1) { + dialog->expandGroup().at(1)->setExpand(true); + } + } +} + +void DialogManager::showTrashPropertyDialog(const DFMEvent &event) +{ + Q_UNUSED(event); + if (m_trashDialog) { + m_trashDialog->close(); + } + m_trashDialog = new TrashPropertyDialog(DUrl::fromTrashFile("/")); + connect(m_trashDialog, &TrashPropertyDialog::finished, [ = ]() { + m_trashDialog = nullptr; + }); + QPoint pos = getPerportyPos(m_trashDialog->size().width(), m_trashDialog->size().height(), 1, 0); + m_trashDialog->move(pos); + m_trashDialog->show(); + + TIMER_SINGLESHOT(100, { + if (m_trashDialog) + m_trashDialog->raise(); + }, this) +} + +void DialogManager::showComputerPropertyDialog() +{ + if (m_computerDialog) { + m_computerDialog->updateComputerInfo(); + m_computerDialog->show(); + m_computerDialog->raise(); + return; + } + m_computerDialog = new ComputerPropertyDialog; + QPoint pos = getPerportyPos(m_computerDialog->size().width(), m_computerDialog->size().height(), 1, 0); + m_computerDialog->show(); + m_computerDialog->move(pos); + + TIMER_SINGLESHOT(100, { + m_computerDialog->raise(); + }, + this) +} + +void DialogManager::showDevicePropertyDialog(const DFMEvent &event) +{ + QWidget *w = WindowManager::getWindowById(event.windowId()); + if (w) { + PropertyDialog *dialog = new PropertyDialog(event, event.fileUrl()); + dialog->show(); + } +} + +void DialogManager::showDiskErrorDialog(const QString &id, const QString &errorText) +{ + Q_UNUSED(errorText) + + static QSet dialogHadShowForId; + + if (dialogHadShowForId.contains(id)) { + return; + } + + UDiskDeviceInfoPointer info = deviceListener->getDevice(id); + + if (info) { + DDialog d; + d.setTitle(tr("Disk is busy, cannot unmount now")); + d.setMessage(tr("Name: ") + info->fileDisplayName()/* + ", " + tr("Path: ") + info->getPath()*/); + QStringList buttonTexts; + buttonTexts.append(tr("Cancel","button")); + buttonTexts.append(tr("Force unmount","button")); + d.addButton(buttonTexts[0], true); + d.addButton(buttonTexts[1], false, DDialog::ButtonWarning); + d.setDefaultButton(0); + d.setIcon(info->fileIcon(64, 64)); + + dialogHadShowForId << id; + + int code = d.exec(); + + dialogHadShowForId.remove(id); + + if (code == 1) { + deviceListener->forceUnmount(id); + } + } +} + +void DialogManager::showBreakSymlinkDialog(const QString &targetName, const DUrl &linkfile) +{ + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(this, linkfile); + + DDialog d; + QString warnText = tr("%1 that this shortcut refers to has been changed or moved"); + QFontMetrics fm(d.font()); + QString _targetName = fm.elidedText(targetName, Qt::ElideMiddle, 120); + d.setTitle(warnText.arg(_targetName)); + d.setMessage(tr("Do you want to delete this shortcut?")); + QStringList buttonTexts; + buttonTexts.append(tr("Cancel","button")); + buttonTexts.append(tr("Confirm","button")); + d.addButton(buttonTexts[0], true); + d.addButton(buttonTexts[1], false, DDialog::ButtonRecommend); + d.setDefaultButton(1); + d.setIcon(fileInfo->fileIcon()); + int code = d.exec(); + if (code == 1) { + DUrlList urls; + urls << linkfile; + // fix bug#47512 回收站的无效链接需要单独处理,直接删除 + if (linkfile.toLocalFile().startsWith(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))) { + fileService->deleteFiles(this, urls, false, true, true); + } else { + fileService->moveToTrash(this, urls); + } + } +} + +void DialogManager::showConnectToServerDialog(quint64 winId) +{ + QWidget *w = WindowManager::getWindowById(winId); + if (!w || w->property("ConnectToServerDialogShown").toBool()) { + return; + } + + ConnectToServerDialog *dialog = new ConnectToServerDialog(w); + dialog->show(); + dialog->setAttribute(Qt::WA_DeleteOnClose); + connect(dialog, &ConnectToServerDialog::finished, dialog, &ConnectToServerDialog::onButtonClicked); + w->setProperty("ConnectToServerDialogShown", true); + connect(dialog, &ConnectToServerDialog::closed, [ = ] { + w->setProperty("ConnectToServerDialogShown", false); + }); +} + +void DialogManager::showUserSharePasswordSettingDialog(quint64 winId) +{ + QWidget *w = WindowManager::getWindowById(winId); + if (!w || w->property("UserSharePwdSettingDialogShown").toBool()) { + return; + } + + UserSharePasswordSettingDialog *dialog = new UserSharePasswordSettingDialog(w); + dialog->show(); + dialog->setAttribute(Qt::WA_DeleteOnClose); + connect(dialog, &UserSharePasswordSettingDialog::finished, dialog, &UserSharePasswordSettingDialog::onButtonClicked); + w->setProperty("UserSharePwdSettingDialogShown", true); + connect(dialog, &UserSharePasswordSettingDialog::closed, [ = ] { + w->setProperty("UserSharePwdSettingDialogShown", false); + }); +} + +void DialogManager::showGlobalSettingsDialog(quint64 winId) +{ + QWidget *w = WindowManager::getWindowById(winId); + if (!w) { + return; + } + if (w->property("isSettingDialogShown").toBool()) { + return; + } + + w->setProperty("isSettingDialogShown", true); + + DSettingsDialog *dsd = new DFMSettingDialog(w); + dsd->show(); + + connect(dsd, &DSettingsDialog::finished, [ = ] { + w->setProperty("isSettingDialogShown", false); + }); +} + +void DialogManager::showDiskSpaceOutOfUsedDialogLater() +{ + QTimer::singleShot(200, [ = ] { + showDiskSpaceOutOfUsedDialog(); + }); +} + +void DialogManager::showDiskSpaceOutOfUsedDialog() +{ + DDialog d; + d.setIcon(m_dialogWarningIcon); + d.setTitle(tr("Unable to copy. Not enough free space on the target disk.")); + d.addButton(tr("OK","button")); + + QRect rect = d.geometry(); + rect.moveCenter(qApp->desktop()->geometry().center()); + d.move(rect.x(), rect.y()); + d.exec(); +} + +void DialogManager::show4gFat32Dialog() +{ + DDialog d; + d.setTitle(tr("Failed, file size must be less than 4GB.")); + d.setIcon(m_dialogWarningIcon); + d.addButton(tr("OK","button"), true, DDialog::ButtonRecommend); + d.exec(); +} + +void DialogManager::showFailToCreateSymlinkDialog(const QString &errorString) +{ + DDialog d; + d.setTitle(tr("Fail to create symlink, cause:") + errorString); + d.setIcon(m_dialogWarningIcon); + d.addButton(tr("OK","button"), true, DDialog::ButtonRecommend); + d.exec(); +} + +void DialogManager::showMoveToTrashConflictDialog(const DUrlList &urls) +{ + MoveToTrashConflictDialog d(nullptr, urls); + int code = d.exec(); + if (code == 1) { + fileService->deleteFiles(this, urls, false); + } +} + +void DialogManager::showDeleteSystemPathWarnDialog(quint64 winId) +{ + DDialog d(WindowManager::getWindowById(winId)); + d.setTitle(tr("The selected files contain system file/directory, and it cannot be deleted")); + d.setIcon(m_dialogWarningIcon); + d.addButton(tr("OK","button"), true, DDialog::ButtonRecommend); + d.exec(); +} + +void DialogManager::showFilePreviewDialog(const DUrlList &selectUrls, const DUrlList &entryUrls) +{ + DUrlList canPreivewlist; + + //记录是否有无效的链接文件 + bool hasInvalidSymlink = false; + for (const DUrl &url : selectUrls) { + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, url); + + if (info && (info->fileUrl().isLocalFile() || info->toQFileInfo().exists())) { + //判断链接文件的源文件是否存在 + if (info->isSymLink()) { + DUrl targetUrl = info->symLinkTarget(); + if (!targetUrl.isValid()) { + hasInvalidSymlink = true; + continue; + } + + const DAbstractFileInfoPointer &linkInfo = DFileService::instance()->createFileInfo(this, targetUrl); + if (!linkInfo || !linkInfo->exists()) { + hasInvalidSymlink = true; + continue; + } + } + canPreivewlist << info->fileUrl(); + } + } + + //链接文件源文件不存在或找不到的情况,弹错误提示窗 + if (hasInvalidSymlink) { + dialogManager->showErrorDialog(tr("Unable to find the original file"), QString()); + } + + if (canPreivewlist.isEmpty()) { + return; + } + + if (DFMGlobal::isWayLand()) { + //! 判断当前预览是否于新的预览列表相同 + if (m_filePreviewDialog && DUrlListCompare(canPreivewlist)) { + m_filePreviewDialog->show(); + m_filePreviewDialog->raise(); + m_filePreviewDialog->activateWindow(); + return; + } + + if (m_filePreviewDialog) { + m_filePreviewDialog->close(); + m_filePreviewDialog = nullptr; + } + m_filePreviewDialog = new FilePreviewDialog(canPreivewlist, nullptr); + + //! 记录预览列表 + for (const DUrl &url : canPreivewlist) { + m_urlList << url; + } + //! 对话框关闭时回收FilePreviewDialog对象 + m_filePreviewDialog->setAttribute(Qt::WA_DeleteOnClose); + //! 对话框关闭时m_filePreviewDialog对象置空 + connect(m_filePreviewDialog, &FilePreviewDialog::signalCloseEvent, this, [ = ]() { + m_filePreviewDialog->DoneCurrent(); + m_filePreviewDialog = nullptr; + m_urlList.clear(); + }); + } else { + if (!m_filePreviewDialog) { + m_filePreviewDialog = new FilePreviewDialog(canPreivewlist, nullptr); + if (!DFMGlobal::isWayLand()) + DPlatformWindowHandle::enableDXcbForWindow(m_filePreviewDialog, true); + } else { + m_filePreviewDialog->updatePreviewList(canPreivewlist); + } + } + + if (canPreivewlist.count() == 1) { + m_filePreviewDialog->setEntryUrlList(entryUrls); + } + + m_filePreviewDialog->show(); + m_filePreviewDialog->raise(); + m_filePreviewDialog->activateWindow(); +} + +void DialogManager::showRestoreFailedDialog(const DUrlList &urlList) +{ + DDialog d; + d.setTitle(tr("Operation failed!")); + if (urlList.count() == 1) { + d.setMessage(tr("Failed to restore %1 file, the target folder is read-only").arg(QString::number(1))); + } else if (urlList.count() > 1) { + d.setMessage(tr("Failed to restore %1 files, the target folder is read-only").arg(QString::number(urlList.count()))); + } + d.setIcon(m_dialogWarningIcon); + d.addButton(tr("OK","button"), true, DDialog::ButtonRecommend); + d.exec(); +} + +void DialogManager::showRestoreFailedPerssionDialog(const QString &srcPath, const QString &targetPath) +{ + qDebug() << srcPath << "restore to" << targetPath; + DDialog d; + d.setTitle(tr("Operation failed!")); + d.setMessage(tr("You do not have permission to operate file/folder!")); + d.setIcon(m_dialogWarningIcon); + d.addButton(tr("OK","button"), true, DDialog::ButtonRecommend); + d.exec(); +} + +void DialogManager::showRestoreFailedSourceNotExists(const DUrlList &urlList) +{ + DDialog d; + d.setTitle(tr("Operation failed!")); + if (urlList.count() == 1) { + d.setMessage(tr("Failed to restore %1 file, the source file does not exist").arg(QString::number(1))); + } else if (urlList.count() > 1) { + d.setMessage(tr("Failed to restore %1 files, the source files do not exist").arg(QString::number(urlList.count()))); + } + d.setIcon(m_dialogWarningIcon); + d.addButton(tr("OK","button"), true, DDialog::ButtonRecommend); + d.exec(); +} + +void DialogManager::showNoPermissionDialog(const DFMUrlListBaseEvent &event) +{ + DUrlList urls = event.urlList(); + qDebug() << urls << "no perssion"; + if (urls.isEmpty()) { + return; + } + + QFont f; + f.setPixelSize(16); + QFontMetrics fm(f); + + DDialog d; + + if (urls.count() == 1) { + + d.setTitle(tr("You do not have permission to operate file/folder!")); + QString message = urls.at(0).toLocalFile(); + + if (fm.width(message) > MAX_FILE_NAME_CHAR_COUNT) { + message = fm.elidedText(message, Qt::ElideMiddle, MAX_FILE_NAME_CHAR_COUNT); + } + + d.setMessage(message); + d.setIcon(m_dialogWarningIcon); + } else { + + QFrame *contentFrame = new QFrame; + + QLabel *iconLabel = new QLabel; + iconLabel->setPixmap(m_dialogWarningIcon.pixmap(64, 64)); + + QLabel *titleLabel = new QLabel; + titleLabel->setText(tr("Sorry, you don't have permission to operate the following %1 file/folder(s)!").arg(QString::number(urls.count()))); + + QLabel *messageLabel = new QLabel; + messageLabel->setScaledContents(true); + + QString message; + for (int i = 0; i < urls.count(); i++) { + if (i >= 10) { + break; + } + QString s = QString("%1.%2").arg(QString::number(i + 1), urls.at(i).toLocalFile()); + if (fm.width(s) > MAX_FILE_NAME_CHAR_COUNT) { + s = fm.elidedText(s, Qt::ElideMiddle, MAX_FILE_NAME_CHAR_COUNT); + } + message += s + "\n"; + } + messageLabel->setText(message); + + QVBoxLayout *contentLayout = new QVBoxLayout; + contentLayout->addWidget(iconLabel, 0, Qt::AlignCenter); + contentLayout->addWidget(titleLabel, 0, Qt::AlignCenter); + contentLayout->addWidget(messageLabel, 0, Qt::AlignCenter); + contentLayout->setContentsMargins(0, 0, 0, 0); + contentLayout->setSpacing(10); + contentFrame->setLayout(contentLayout); + + d.addContent(contentFrame, Qt::AlignCenter); + } + + d.addButton(tr("OK","button"), true, DDialog::ButtonRecommend); + d.exec(); +} + +void DialogManager::showErrorDialog(const QString &title, const QString &message) +{ + DDialog d(title, message); + Qt::WindowFlags flags = d.windowFlags(); + // dialog show top + d.setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint); + d.setIcon(QIcon::fromTheme("dialog-error")); + d.addButton(tr("Confirm","button"), true, DDialog::ButtonRecommend); + d.setMaximumWidth(640); + d.exec(); +} + +void DialogManager::removePropertyDialog(const DUrl &url) +{ + if (m_propertyDialogs.contains(url)) { + m_propertyDialogs.remove(url); + } + if (m_propertyDialogs.count() == 0) { + m_closeIndicatorDialog->hide(); + } +} + +void DialogManager::closeAllPropertyDialog() +{ + foreach (const DUrl &url, m_propertyDialogs.keys()) { + m_propertyDialogs.value(url)->close(); + } + if (m_closeIndicatorDialog) { + m_closeIndicatorTimer->stop(); + m_closeIndicatorDialog->close(); + } + if (m_trashDialog) { + m_trashDialog->close(); + } + + if (m_computerDialog) { + m_computerDialog->close(); + } +} + +void DialogManager::updateCloseIndicator() +{ + qint64 size = 0; + int fileCount = 0; + foreach (PropertyDialog *d, m_propertyDialogs.values()) { + size += d->getFileSize(); + fileCount += d->getFileCount(); + } + m_closeIndicatorDialog->setTotalMessage(size, fileCount); +} + +void DialogManager::raiseAllPropertyDialog() +{ + foreach (PropertyDialog *d, m_propertyDialogs.values()) { + qDebug() << d->getUrl() << d->isVisible() << d->windowState(); +// d->showMinimized(); + d->showNormal(); + if (!DesktopInfo().waylandDectected()) { + QtX11::utils::ShowNormalWindow(d); + } + qobject_cast(d)->showNormal(); + d->show(); + d->raise(); + qDebug() << d->getUrl() << d->isVisible() << d->windowState(); + } + if (m_closeIndicatorDialog) + m_closeIndicatorDialog->raise(); +} + +void DialogManager::handleFocusChanged(QWidget *old, QWidget *now) +{ + Q_UNUSED(old) + Q_UNUSED(now) + + if (m_propertyDialogs.values().contains(qobject_cast(qApp->activeWindow()))) { + raiseAllPropertyDialog(); + } else if (m_closeIndicatorDialog == qobject_cast(qApp->activeWindow())) { + raiseAllPropertyDialog(); + } +} + +void DialogManager::showTaskProgressDlgOnActive() +{ + if (!m_taskDialog) + return; + + m_taskDialog->show(); + m_taskDialog->raise(); + m_taskDialog->activateWindow(); + + QMapIterator > iter(m_jobs); + while (iter.hasNext()) { + iter.next(); + if (iter.value()->getIsFinished()) + continue; + if (iter.value()->getIsOpticalJob()) // 目前业务只针对光盘业务 + emit iter.value()->requestJobAdded(iter.value()->jobDetail()); + } +} + +int DialogManager::showUnableToLocateDir(const QString &dir) +{ + // Ensure that only one dialog is displayed in the current screen + static bool showFlag = true; + int code = -1; + if (showFlag) { + showFlag = false; + DDialog d; + d.setTitle(tr("Unable to access %1").arg(dir)); + d.setMessage(" "); + QStringList buttonTexts; + buttonTexts.append(tr("Confirm","button")); + d.addButton(buttonTexts[0], true); + d.setDefaultButton(0); + d.setIcon(QIcon::fromTheme("folder").pixmap(64, 64)); + code = d.exec(); + showFlag = true; + } + + return code; +} + +void DialogManager::refreshPropertyDialogs(const DUrl &oldUrl, const DUrl &newUrl) +{ + PropertyDialog *d = m_propertyDialogs.value(oldUrl); + if (d) { + m_propertyDialogs.remove(oldUrl); + m_propertyDialogs.insert(newUrl, d); + } +} + + +void DialogManager::handleConflictRepsonseConfirmed(const QMap &jobDetail, const QMap &response) +{ + QString jobId = jobDetail.value("jobId"); + QSharedPointer job = m_jobs.value(jobId); + if (job != nullptr) { + bool applyToAll = response.value("applyToAll").toBool(); + int code = response.value("code").toInt(); + job->setApplyToAll(applyToAll); + //0 = coexist, 1 = replace, 2 = skip + switch (code) { + case 0: + job->setIsCoExisted(true); + job->setIsSkip(false); + job->setReplace(false); + job->started(); + break; + case 1: + job->setReplace(true); + job->setIsCoExisted(false); + job->setIsSkip(false); + job->started(); + break; + case 2: + job->setIsSkip(true); + job->setIsCoExisted(false); + job->setReplace(false); + job->cancelled(); + break; + default: + qDebug() << "unknown code" << code; + } + } +} + +int DialogManager::showMessageDialog(messageType messageLevel, const QString &title, const QString &message, QString btnTxt) +{ + DDialog d(title, message); + d.moveToCenter(); + QStringList buttonTexts; + buttonTexts.append(btnTxt); + d.addButtons(buttonTexts); + d.setDefaultButton(0); + if (messageLevel == msgInfo) { + d.setIcon(m_dialogInfoIcon); + } else if (messageLevel == msgWarn) { + d.setIcon(m_dialogWarningIcon); + } else if (messageLevel == msgErr) { + d.setIcon(m_dialogErrorIcon); + } else { + d.setIcon(m_dialogInfoIcon); + } + int code = d.exec(); + qDebug() << code; + return code; +} + +void DialogManager::showBluetoothTransferDlg(const DUrlList &files) +{ + if (!BluetoothTransDialog::canSendFiles()) { + showMessageDialog(messageType::msgInfo, tr("Sending files now, please try later")); + return; + } + + QStringList paths; + foreach (auto u, files) { + if (u.scheme() == RECENT_SCHEME) { + u = DUrl::fromLocalFile(u.path()); + } else if (u.scheme() == SEARCH_SCHEME) { //搜索结果也存在右键批量打开不成功的问题,这里做类似处理 + u = u.searchedFileUrl(); + } else if (u.scheme() == BURN_SCHEME) { + DAbstractFileInfoPointer info = fileService->createFileInfo(nullptr, u); + if (!info) + continue; + if (info->canRedirectionFileUrl()) + u = info->redirectedFileUrl(); + } else if (u.scheme() == TAG_SCHEME) { + u = DUrl::fromLocalFile(u.toLocalFile()); + } + paths << u.path(); + } + + BluetoothTransDialog *dlg = new BluetoothTransDialog(paths); + dlg->setAttribute(Qt::WA_DeleteOnClose); + dlg->show(); +} + +void DialogManager::showFormatDialog(const QString &devId) +{ + if (!devId.startsWith("/dev/")) + return; + + // fix 50005, 弹出格式化提示框仅针对可移动磁盘,且无法读取文件系统的设备,避免smb、mtp等设备也弹出提示框 + QString volTag = devId.mid(5); + static const QString udisksPrefix = "/org/freedesktop/UDisks2/block_devices/"; + QScopedPointer dev(DDiskManager::createBlockDevice(udisksPrefix + volTag)); + if (!dev || dev->hasFileSystem()) + return; + QScopedPointer drive(DDiskManager::createDiskDevice(dev->drive())); + if (!drive) + return; + if (drive->optical() || !drive->removable()) // 光驱不管,非移动存储设备不管 + return; + + qDebug() << "device formatter has shown: " << devId; + DDialog dlg; + dlg.setIcon(m_dialogWarningIcon); + dlg.addButton(tr("Cancel","button")); + dlg.addButton(tr("Format","button"), true, DDialog::ButtonRecommend); + dlg.setTitle(tr("To access the device, you must format the disk first. Are you sure you want to format it now?")); + int code = dlg.exec(); + if (code == 1) { + qDebug() << "start format " << devId; + // 显示格式化窗口 + QProcess::startDetached("dde-device-formatter", QStringList {devId}); + } +} + +int DialogManager::showStopScanningDialog() +{ + DDialog dlg; + dlg.setIcon(m_dialogWarningIcon); + dlg.addButton(tr("Cancel","button")); + dlg.addButton(tr("Stop","button"), true, DDialog::ButtonWarning); // 终止 + dlg.setTitle(tr("Scanning the device, stop it?")); // 正在扫描当前设备,是否终止扫描? + return dlg.exec(); +} + +bool DialogManager::DUrlListCompare(DUrlList urls) +{ + if (urls.size() != m_urlList.size()) { + return false; + } else { + for (int i = 0; i < urls.size(); ++i) { + if (urls[i] != m_urlList[i]) { + return false; + } + } + return true; + } +} + + +void DialogManager::showMultiFilesRenameDialog(const QList &selectedUrls) +{ + DDesktopRenameDialog renameDialog; + + renameDialog.moveToCenter(); + renameDialog.setDialogTitle(QObject::tr("Rename %1 Files").arg(QString::fromStdString(std::to_string(selectedUrls.size())))); + + std::size_t code { static_cast(renameDialog.exec()) }; + + AppController::flagForDDesktopRenameBar.store(true, std::memory_order_seq_cst); + + if (static_cast(code) == true) { //###: yes! + std::size_t modeIndex{ renameDialog.getCurrentModeIndex() }; + if (modeIndex == 0) { + QPair replaceModeValue{ renameDialog.getModeOneContent() }; + DFileService::instance()->multiFilesReplaceName(selectedUrls, replaceModeValue); + + } else if (modeIndex == 1) { + QPair addModeValue{ renameDialog.getModeTwoContent() }; + DFileService::instance()->multiFilesAddStrToName(selectedUrls, addModeValue); + + } else { + QPair customModeValue{ renameDialog.getModeThreeContent() }; + DFileService::instance()->multiFilesCustomName(selectedUrls, customModeValue); + } + + + AppController::multiSelectionFilesCache.second = 1; //###: give a number must be bigger than 0. + // We modified files will invoke dfilesystemmodel::selectAndRenameFile() at background. + } + +} + +void DialogManager::showAddUserShareFailedDialog(const QString &sharePath) +{ + (void)sharePath; + + DDialog d; + d.setTitle(tr("Share folder can't be named after the current username")); + d.setIcon(m_dialogWarningIcon); + d.addButton(tr("OK","button"), true, DDialog::ButtonRecommend); + d.exec(); +} + + +#ifdef SW_LABEL + +void DialogManager::onJobFailed_SW(int nRet, const QString &jobType, const QString &srcfilename) +{ + if (LlsDeepinLabelLibrary::instance()->isCompletion()) { + int ret = showPrivilegeDialog_SW(nRet, srcfilename); + if (ret == 0) { + qDebug() << jobType << nRet << srcfilename; + } + } +} + +int DialogManager::showPrivilegeDialog_SW(int nRet, const QString &srcfilename) +{ + if (LlsDeepinLabelLibrary::instance()->isCompletion()) { + qDebug() << "文件全路径名称" << srcfilename; + qDebug() << "错误码;" << nRet; + + std::string serrordst = ""; //错误描述 + int nerrorlevel = 0; //错误级别 +// nRet = lls_geterrordesc(nRet, serrordst, nerrorlevel); + nRet = LlsDeepinLabelLibrary::instance()->lls_geterrordesc()(nRet, serrordst, nerrorlevel); + if (nRet == 0) { + qDebug() << "错误描述:" << QString::fromStdString(serrordst); + qDebug() << "错误级别:" << nerrorlevel; + QString message = QString("%1 %2").arg(QFileInfo(srcfilename).fileName(), QString::fromStdString(serrordst)); + int code = showMessageDialog(messageType(nerrorlevel), message); + return code; + + } else { + qDebug() << "get error message fail" << nRet; + return -1; + } + } +} + +#endif + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dialogmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dialogmanager.h new file mode 100644 index 0000000..30a72ee --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dialogmanager.h @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DIALOGMANAGER_H +#define DIALOGMANAGER_H + +#include + +#include +#include +#include +#include +#include +#include + +#include "durl.h" +#include "dfmglobal.h" +#include "dtkwidget_global.h" + +class DTaskDialog; +class FileJob; +class DAbstractFileInfo; +class DUrl; +class DFMEvent; +class DFMUrlBaseEvent; +class DFMUrlListBaseEvent; +class PropertyDialog; +class CloseAllDialogIndicator; +class TrashPropertyDialog; +class ComputerPropertyDialog; +class QTimer; +class DMultiFilePropertyDialog; +class QDiskInfo; + +DFM_BEGIN_NAMESPACE +class FilePreviewDialog; +DFM_END_NAMESPACE + +DWIDGET_BEGIN_NAMESPACE +class DDialog; +DWIDGET_END_NAMESPACE + +class DialogManager : public QObject +{ + Q_OBJECT +public: + enum messageType { + msgInfo = 1, + msgWarn = 2, + msgErr = 3 + }; + +public: + explicit DialogManager(QObject *parent = nullptr); + ~DialogManager(); + QPoint getPropertyPos(int dialogWidth, int dialogHeight); + QPoint getPerportyPos(int dialogWidth, int dialogHeight, int count, int index); + bool isTaskDialogEmpty(); + DTaskDialog *taskDialog() const; + +private: + void initData(); + void initTaskDialog(); + void initCloseIndicatorDialog(); + void initConnect(); + +public slots: + void handleConflictRepsonseConfirmed(const QMap &jobDetail, const QMap &response); + void addJob(QSharedPointer job); + void removeJob(const QString &jobId, bool isRemoveOpticalJob = false); + QString getJobIdByUrl(const DUrl &url); + void removeAllJobs(); + void updateJob(); + void startUpdateJobTimer(); + void stopUpdateJobTimer(); + + void abortJob(const QMap &jobDetail); + void abortJobByDestinationUrl(const DUrl &url); + + void showCopyMoveToSelfDialog(const QMap &jobDetail); + + void showUrlWrongDialog(const DUrl &url); + int showRunExcutableScriptDialog(const DUrl &url, quint64 winId); + int showRunExcutableFileDialog(const DUrl &url, quint64 winId); + int showAskIfAddExcutableFlagAndRunDialog(const DUrl &url, quint64 winId); + int showRenameNameSameErrorDialog(const QString &name, const DFMEvent &event); + // 重命名文件时,如果文件名为..,则弹出警告对话框 + int showRenameNameDotDotErrorDialog(const DFMEvent &event); + void showRenameBusyErrDialog(const DFMEvent &event); + int showOpticalBlankConfirmationDialog(const DFMUrlBaseEvent &event); + int showOpticalImageOpSelectionDialog(const DFMUrlBaseEvent &event); + void showOpticalJobFailureDialog(int type, const QString &err, const QStringList &details); + void showOpticalJobCompletionDialog(const QString &msg, const QString &icon); + int showDeleteFilesClearTrashDialog(const DFMUrlListBaseEvent &event); + //! 显示普通删除确认对话框 + int showNormalDeleteConfirmDialog(const DFMUrlListBaseEvent &event); + int showRemoveBookMarkDialog(const DFMEvent &event); + void showOpenWithDialog(const DFMEvent &event); + void showOpenFilesWithDialog(const DFMEvent &event); + void showPropertyDialog(const DFMUrlListBaseEvent &event); + void showShareOptionsInPropertyDialog(const DFMUrlListBaseEvent &event); + void showTrashPropertyDialog(const DFMEvent &event); + void showComputerPropertyDialog(); + void showDevicePropertyDialog(const DFMEvent &event); + void showDiskErrorDialog(const QString &id, const QString &errorText); + void showBreakSymlinkDialog(const QString &targetName, const DUrl &linkfile); + void showConnectToServerDialog(quint64 winId); + void showUserSharePasswordSettingDialog(quint64 winId); + void showGlobalSettingsDialog(quint64 winId); + void showDiskSpaceOutOfUsedDialogLater(); + void showDiskSpaceOutOfUsedDialog(); + void show4gFat32Dialog(); + void showFailToCreateSymlinkDialog(const QString &errorString); + void showMoveToTrashConflictDialog(const DUrlList &urls); + void showDeleteSystemPathWarnDialog(quint64 winId); + void showFilePreviewDialog(const DUrlList &selectUrls, const DUrlList &entryUrls); + void showRestoreFailedDialog(const DUrlList &urlList); + void showRestoreFailedPerssionDialog(const QString &srcPath, const QString &targetPath); + void showRestoreFailedSourceNotExists(const DUrlList &urlList); + void showMultiFilesRenameDialog(const QList &selectedUrls); + void showAddUserShareFailedDialog(const QString &sharePath); + void showNoPermissionDialog(const DFMUrlListBaseEvent &event); + void showErrorDialog(const QString &title, const QString &message); + void removePropertyDialog(const DUrl &url); + void closeAllPropertyDialog(); + void updateCloseIndicator(); + void raiseAllPropertyDialog(); + void handleFocusChanged(QWidget *old, QWidget *now); + void showTaskProgressDlgOnActive(); + int showUnableToLocateDir(const QString &dir); + + void refreshPropertyDialogs(const DUrl &oldUrl, const DUrl &newUrl); + + int showMessageDialog(messageType messageLevel, const QString &title, const QString &message = "", QString btnTxt = tr("Confirm","button")); + void showBluetoothTransferDlg(const DUrlList &files); + + void showFormatDialog(const QString &devId); // sp3 feat 接入usb设备不能读取文件系统、存储信息、或是无法解锁的加密设备时,提示用户格式化 + int showStopScanningDialog(); // 显示设备正在被扫描的提示 + + /** + * DUrlListCompare 用于判断传入url列表是否与m_urlList一样 + */ + bool DUrlListCompare(DUrlList urls); + +#ifdef SW_LABEL + void onJobFailed_SW(int nRet, const QString &jobType, const QString &srcfilename); + int showPrivilegeDialog_SW(int nRet, const QString &srcfilename); +#endif + +private: + QIcon m_dialogInfoIcon; + QIcon m_dialogWarningIcon; + QIcon m_dialogErrorIcon; + QMutex m_mutexJob; + DTaskDialog *m_taskDialog {nullptr}; + CloseAllDialogIndicator *m_closeIndicatorDialog {nullptr}; + TrashPropertyDialog *m_trashDialog {nullptr}; + ComputerPropertyDialog *m_computerDialog {nullptr}; + QMap > m_jobs {}; + QMap m_propertyDialogs {}; + QTimer *m_closeIndicatorTimer {nullptr}; + QTimer *m_updateJobTaskTimer {nullptr}; + dde_file_manager::FilePreviewDialog *m_filePreviewDialog {nullptr}; + Dtk::Widget::DDialog *m_noPemesrsionDialog {nullptr}; + + std::unique_ptr m_multiFilesPropertyDialog; + + //! wayland视频预览当前预览列表 + DUrlList m_urlList; +}; + +#endif // DIALOGMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dmultifilepropertydialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dmultifilepropertydialog.cpp new file mode 100644 index 0000000..8a0ba19 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dmultifilepropertydialog.cpp @@ -0,0 +1,332 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dmultifilepropertydialog.h" +#include "dfilestatisticsjob.h" +#include "dabstractfileinfo.h" +#include "shutil/fileutils.h" +#include "dfileservices.h" +#include "dfileinfo.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace Dtk::Widget; + + + +class DMultiFilePropertyDialogPrivate +{ +public: + DMultiFilePropertyDialogPrivate(const QList& urlList, DMultiFilePropertyDialog* const qPtr); + + ~DMultiFilePropertyDialogPrivate()=default; + DMultiFilePropertyDialogPrivate(const DMultiFilePropertyDialogPrivate& other)=delete; + DMultiFilePropertyDialogPrivate& operator=(const DMultiFilePropertyDialogPrivate& other)=delete; + + + void getRandomUrls()noexcept; + + void initUi(); + void initUiParameter()noexcept; + void layoutItems()noexcept; + + + QList m_urlList{}; //###: this list contains all the urls which are selected! + std::array m_selectedUrls{}; //###: I chose 3 urls from list. + std::unique_ptr m_icon{ nullptr }; + + QLabel* m_iconLabel{ nullptr }; + + std::tuple m_nameLabelAndLineLabel{}; + QLabel* m_basicInfoLabel{ nullptr }; + + QHBoxLayout* m_basicInfoLayout{ nullptr }; + QLabel* m_folderSizeLabel{ nullptr }; + QGridLayout* m_gridLayout{ nullptr }; + QVBoxLayout* m_mainLayout{ nullptr }; + QFrame* m_mainFrame{ nullptr }; + + + std::shared_ptr m_filesSizeWorker{ nullptr }; + DMultiFilePropertyDialog* q_ptr{ nullptr }; + +}; + +DMultiFilePropertyDialogPrivate::DMultiFilePropertyDialogPrivate(const QList &urlList, DMultiFilePropertyDialog * const qPtr) + : m_urlList{urlList}, + q_ptr{ qPtr } +{ + this->getRandomUrls(); + + this->initUi(); + this->initUiParameter(); + this->layoutItems(); +} + + +void DMultiFilePropertyDialogPrivate::getRandomUrls()noexcept +{ + for(std::size_t index = 0; index != 3; ++index){ + std::size_t randomNumer{ DMultiFilePropertyDialog::getRandomNumber(std::make_pair(0, m_urlList.size() - 1)) }; + + m_selectedUrls[index] = m_urlList[randomNumer]; + } + +} + + +void DMultiFilePropertyDialogPrivate::initUi() +{ + + m_icon = std::unique_ptr{ new QIcon{} }; + + m_iconLabel = new QLabel{}; + + m_nameLabelAndLineLabel = std::make_tuple(new QLabel{}, new QLabel{}); + + m_basicInfoLabel = new QLabel; + + m_basicInfoLayout = new QHBoxLayout; + + m_folderSizeLabel = nullptr; + + m_gridLayout = new QGridLayout; + m_mainLayout = new QVBoxLayout; + m_mainFrame = new QFrame; +} + + + +void DMultiFilePropertyDialogPrivate::initUiParameter()noexcept +{ + q_ptr->setFixedSize(300, 360); + + m_icon->addFile(QString{":/images/images/multiple_files.png"}); + m_icon->addFile(QString{":/images/images/multiple_files@2x.png"}); + + m_iconLabel->setPixmap(m_icon->pixmap(128, 128)); + + + QLabel* nameLabel{ std::get<0>(m_nameLabelAndLineLabel) }; + nameLabel->setText(QObject::tr("Multiple Files")); + nameLabel->setObjectName(QString{"NameLabel"}); + nameLabel->setStyleSheet(QString{"QLabel#NameLabel{ font-size: 12px;}"}); + + QLabel* lineLabel{ std::get<1>(m_nameLabelAndLineLabel) }; + lineLabel->setFixedSize( QSize{260, 1} ); + lineLabel->setObjectName( QString{"LabelAsLine"} ); + lineLabel->setStyleSheet(QString{"QLabel#LabelAsLine{ border: none; background-color: #f0f0f0;}"}); + + m_basicInfoLabel->setText(QObject::tr("Basic info")); + m_basicInfoLabel->setObjectName(QString{"GridLayoutLabel"}); + m_basicInfoLabel->setObjectName(QString{"QLabel#GridLayoutLabel{ font-size: 12px;}"}); + + std::pair quantityOfFilesAndFolders{ + DMultiFilePropertyDialog::getTheQuantityOfFilesAndFolders(m_urlList) + }; + std::list> coupleLabelContent; + coupleLabelContent.emplace_back(QObject::tr("Total size"), QString{""}); + coupleLabelContent.emplace_back(QObject::tr("Number of files"), QObject::tr("%1 file(s), %2 folder(s)") + .arg( QString::fromStdString(std::to_string(quantityOfFilesAndFolders.first))) + .arg( QString::fromStdString(std::to_string(quantityOfFilesAndFolders.second)))); + + + coupleLabelContent.emplace_back(QObject::tr("Time accessed"), QString{"-"}); + coupleLabelContent.emplace_back(QObject::tr("Time modified"), QString{"-"}); + + + m_gridLayout->setColumnMinimumWidth(0, 100); + m_gridLayout->setColumnMinimumWidth(1, 180); + m_gridLayout->setSpacing(10); + + //add the couple of label to gridlayout. + std::size_t row{ 0 }; + bool flag{ false }; + for(const auto& coupleContent : coupleLabelContent){ + QLabel* husbandLabel{ new QLabel{ coupleContent.first } }; + QLabel* wifeLabel{ new QLabel{ coupleContent.second } }; + + husbandLabel->setObjectName(QString{"HusbandLabel"}); + husbandLabel->setStyleSheet(QString{ "QLabel#HusbandLabel{ font-size: 11px;}"}); + + if(flag == false){ + m_folderSizeLabel = wifeLabel; //###: this label for showing the quantity of current selected folders and files. + flag = true; + } + + wifeLabel->setObjectName(QString{"WifeLabel"}); + wifeLabel->setStyleSheet(QString{ "QLabel#WifeLabel{ font-size:11px;}"}); + wifeLabel->setTextFormat(Qt::PlainText); + wifeLabel->setWordWrap(true); + wifeLabel->setFixedWidth(180); + + + + m_gridLayout->addWidget(husbandLabel, row, 0, Qt::AlignRight | Qt::AlignTop); + m_gridLayout->addWidget(wifeLabel, row, 1, Qt::AlignLeft | Qt::AlignTop); + m_gridLayout->setRowMinimumHeight(row, 12); + ++row; + } + + m_filesSizeWorker = std::shared_ptr{ new DFileStatisticsJob(q_ptr) }; + + nameLabel = nullptr; + lineLabel = nullptr; +} + +void DMultiFilePropertyDialogPrivate::layoutItems()noexcept +{ + m_mainLayout->setSpacing(0); + m_mainLayout->setContentsMargins(0, 0, 0, 0); + m_mainLayout->setMargin(0); + m_mainLayout->addWidget(m_iconLabel, 0, Qt::AlignCenter); + m_mainLayout->addSpacing(10); + m_mainLayout->addWidget(std::get<0>(m_nameLabelAndLineLabel), 0, Qt::AlignCenter); + m_mainLayout->addSpacing(15); + m_mainLayout->addWidget(std::get<1>(m_nameLabelAndLineLabel), 0, Qt::AlignCenter); + + m_basicInfoLayout->setSpacing(0); + m_basicInfoLayout->addSpacing(10); + m_basicInfoLayout->addWidget(m_basicInfoLabel); + + m_mainLayout->addLayout(m_basicInfoLayout); + m_mainLayout->addSpacing(10); + m_mainLayout->addLayout(m_gridLayout); + m_mainLayout->addStretch(1); + m_mainLayout->addSpacing(15); + + + m_mainFrame->setLayout(m_mainLayout); + q_ptr->addContent(m_mainFrame, Qt::AlignCenter); +} + + + + +DMultiFilePropertyDialog::DMultiFilePropertyDialog(const QList &urlList, QWidget * const parent) + :DDialog{ parent }, + d_ptr{new DMultiFilePropertyDialogPrivate{ urlList, this} } +{ + if(DFMGlobal::isWayLand()) + { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + } + + this->initConnect(); + this->startComputingFolderSize(); +} + +DMultiFilePropertyDialog::~DMultiFilePropertyDialog() +{ + DMultiFilePropertyDialogPrivate* const d{ d_func() }; + d->m_filesSizeWorker->stop(); +} + +std::size_t DMultiFilePropertyDialog::getRandomNumber(const std::pair &scope) +{ + static std::random_device randomDevice; //###: here the device must be static. + std::default_random_engine engine{ randomDevice() }; + std::uniform_int_distribution distribution{scope.first, scope.second}; + + return distribution(engine); +} + + +void DMultiFilePropertyDialog::updateFolderSizeLabel(const qint64 foldersSize)noexcept +{ + DMultiFilePropertyDialogPrivate* const d{ d_func() }; + d->m_folderSizeLabel->setText(FileUtils::formatSize(foldersSize)); +} + +void DMultiFilePropertyDialog::initConnect() +{ + DMultiFilePropertyDialogPrivate* const d{ d_func() }; + + QObject::connect(d->m_filesSizeWorker.get(), &DFileStatisticsJob::dataNotify, this, &DMultiFilePropertyDialog::updateFolderSizeLabel); +} + +void DMultiFilePropertyDialog::startComputingFolderSize() +{ + DMultiFilePropertyDialogPrivate* const d{ d_func() }; + + d->m_filesSizeWorker->start(d->m_urlList); +} + + +///###: static function,compute the quantity of files and folders +std::pair DMultiFilePropertyDialog::getTheQuantityOfFilesAndFolders(const QList &urlList)noexcept +{ + std::pair quantityOfFilesAndFolders{0, 0}; + + if (urlList.empty()) + return quantityOfFilesAndFolders; + + for (const auto& url : urlList) { + + DAbstractFileInfoPointer fileInfoPointer = DFileService::instance()->createFileInfo(nullptr, url); + + DUrl fileUrl = url; + + if (fileInfoPointer && fileInfoPointer->canRedirectionFileUrl()) + fileUrl = fileInfoPointer->redirectedFileUrl(); + + QFileInfo info{ fileUrl.toLocalFile() }; + + if (info.isFile()) { + ++quantityOfFilesAndFolders.first; + } else { + ++quantityOfFilesAndFolders.second; + } + + } + + return quantityOfFilesAndFolders; +} + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dmultifilepropertydialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dmultifilepropertydialog.h new file mode 100644 index 0000000..d0d8e99 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/dmultifilepropertydialog.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DMULTIFILEPROPERTYDIALOG_H +#define DMULTIFILEPROPERTYDIALOG_H + +#include "durl.h" +#include "ddialog.h" +#include "dfmglobal.h" + +#include +#include + +#include +#include +#include +#include +#include + +class QWidget; +class QLabel; +class QVBoxLayout; +class QGridLayout; + +class DMultiFilePropertyDialogPrivate; + +DFM_BEGIN_NAMESPACE +class DFileStatisticsJob; +DFM_END_NAMESPACE + +using namespace Dtk::Widget; + +class DMultiFilePropertyDialog : public DDialog +{ + Q_OBJECT + +public: + + explicit DMultiFilePropertyDialog(const QList& urlList, QWidget* const parent = nullptr); + virtual ~DMultiFilePropertyDialog(); + + + DMultiFilePropertyDialog(const DMultiFilePropertyDialog&)=delete; + DMultiFilePropertyDialog& operator=(const DMultiFilePropertyDialog&)=delete; + + void startComputingFolderSize(); + + static std::size_t getRandomNumber(const std::pair& scope); + +private slots: + void updateFolderSizeLabel(const qint64 foldersSize)noexcept; + +private: + + void initConnect(); + + static std::pair getTheQuantityOfFilesAndFolders(const QList& urlList)noexcept; + + QSharedPointer d_ptr{ nullptr }; + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), DMultiFilePropertyDialog) + +}; + + +#endif // DMULTIFILEPROPERTYDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/filepreviewdialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/filepreviewdialog.cpp new file mode 100644 index 0000000..03528da --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/filepreviewdialog.cpp @@ -0,0 +1,673 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "filepreviewdialog.h" +#include "dfileservices.h" +#include "dabstractfileinfo.h" +#include "dfmfilepreviewfactory.h" +#include "dfilestatisticsjob.h" + +#include "shutil/fileutils.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DFM_BEGIN_NAMESPACE + +class FilePreviewDialogStatusBar : public QFrame +{ + Q_OBJECT +public: + explicit FilePreviewDialogStatusBar(QWidget *parent = nullptr); + + QLabel *title() const; + QPushButton *preButton() const; + QPushButton *nextButton() const; + QPushButton *openButton() const; + +private: + QLabel *m_title; + + QPushButton *m_preButton; + QPushButton *m_nextButton; + QPushButton *m_openButton; + +}; + +FilePreviewDialogStatusBar::FilePreviewDialogStatusBar(QWidget *parent) + : QFrame(parent) +{ + QSize iconSize(16, 16); + m_preButton = new QPushButton(this); + m_preButton->setObjectName("PreButton"); + m_preButton->setIcon(QIcon::fromTheme("go-previous").pixmap(iconSize)); + m_preButton->setIconSize(iconSize); + m_preButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_preButton->setShortcut(QKeySequence::Back); + m_preButton->setFocusPolicy(Qt::NoFocus); + + m_nextButton = new QPushButton(this); + m_nextButton->setObjectName("NextButton"); + m_nextButton->setIcon(QIcon::fromTheme("go-next").pixmap(iconSize)); + m_nextButton->setIconSize(iconSize); + m_nextButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_nextButton->setShortcut(QKeySequence::Forward); + m_nextButton->setFocusPolicy(Qt::NoFocus); + + m_title = new QLabel(this); + m_title->setObjectName("TitleLabel"); + m_title->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_title->hide(); + + m_openButton = new QPushButton(QObject::tr("Open","button"), this); + m_openButton->setObjectName("OpenButton"); + QFont font = m_openButton->font(); + font.setPixelSize(12); + m_openButton->setFont(font); + m_openButton->setMinimumWidth(60); + m_openButton->setShortcut(QKeySequence::Open); + + QHBoxLayout *layout = new QHBoxLayout(this); + + layout->setContentsMargins(10, 10, 10, 10); + layout->addWidget(m_preButton); + layout->addWidget(m_nextButton); + layout->addWidget(m_title); + layout->addWidget(m_openButton, 0, Qt::AlignRight); + + setLayout(layout); +} + +QPushButton *FilePreviewDialogStatusBar::openButton() const +{ + return m_openButton; +} + +QPushButton *FilePreviewDialogStatusBar::nextButton() const +{ + return m_nextButton; +} + +QPushButton *FilePreviewDialogStatusBar::preButton() const +{ + return m_preButton; +} + +QLabel *FilePreviewDialogStatusBar::title() const +{ + return m_title; +} + +UnknowFilePreview::UnknowFilePreview(QObject *parent) + : DFMFilePreview(parent) + , m_contentWidget(new QWidget()) +{ + m_contentWidget->setFixedSize(550, 200); + m_iconLabel = new QLabel(m_contentWidget); + m_iconLabel->setObjectName("IconLabel"); + m_iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_nameLabel = new QLabel(m_contentWidget); + m_nameLabel->setObjectName("NameLabel"); + m_nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_nameLabel->setWordWrap(true); + m_sizeLabel = new QLabel(m_contentWidget); + m_sizeLabel->setObjectName("SizeLabel"); + m_sizeLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_typeLabel = new QLabel(m_contentWidget); + m_typeLabel->setObjectName("TypeLabel"); + m_typeLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + QVBoxLayout *vlayout = new QVBoxLayout(); + + vlayout->addWidget(m_nameLabel); + vlayout->addWidget(m_sizeLabel); + vlayout->addWidget(m_typeLabel); + vlayout->addStretch(); + + QHBoxLayout *hlayout = new QHBoxLayout(m_contentWidget); + + hlayout->setContentsMargins(30, 20, 20, 20); + hlayout->addWidget(m_iconLabel); + hlayout->addSpacing(30); + hlayout->addLayout(vlayout); + hlayout->addStretch(); +} + +UnknowFilePreview::~UnknowFilePreview() +{ + if (m_contentWidget) { + m_contentWidget->deleteLater(); + } + + if (m_sizeWorker) { + m_sizeWorker->stop(); + m_sizeWorker->deleteLater(); + } +} + +bool UnknowFilePreview::setFileUrl(const DUrl &url) +{ + m_url = url; + + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, url); + + if (info) + setFileInfo(info); + + return true; +} + +DUrl UnknowFilePreview::fileUrl() const +{ + return m_url; +} + +void UnknowFilePreview::setFileInfo(const DAbstractFileInfoPointer &info) +{ + const QIcon &icon = info->fileIcon(); + + m_iconLabel->setPixmap(icon.pixmap(150)); + + QFont font = m_nameLabel->font(); + QFontMetrics fm(font); + QString elidedText = fm.elidedText(info->fileName(), Qt::ElideMiddle, 300); + + m_nameLabel->setText(elidedText); + + if (info->isFile() || info->isSymLink()) { + m_sizeLabel->setText(QObject::tr("Size: %1").arg(info->sizeDisplayName())); + m_typeLabel->setText(QObject::tr("Type: %1").arg(info->mimeTypeDisplayName())); + } else if (info->isDir()) { + if (!m_sizeWorker) { + m_sizeWorker = new DFileStatisticsJob(this); + + connect(m_sizeWorker, &DFileStatisticsJob::dataNotify, this, &UnknowFilePreview::updateFolderSize); + } else if (m_sizeWorker->isRunning()) { + m_sizeWorker->stop(); + m_sizeWorker->wait(); + } + + m_sizeWorker->start({info->fileUrl()}); + m_sizeLabel->setText(QObject::tr("Size: 0")); + } +} + +void UnknowFilePreview::updateFolderSize(qint64 size) +{ + m_typeLabel->setText(QObject::tr("Items: %1").arg(m_sizeWorker->filesCount() + m_sizeWorker->directorysCount())); + m_sizeLabel->setText(QObject::tr("Size: %1").arg(FileUtils::formatSize(size))); +} + + +QWidget *UnknowFilePreview::contentWidget() const +{ + return m_contentWidget; +} + +FilePreviewDialog::FilePreviewDialog(const DUrlList &previewUrllist, QWidget *parent) + : DAbstractDialog(parent) + , m_fileList(previewUrllist) +{ +#ifdef Q_OS_LINUX +#ifndef ARCH_SW // 申威和龙芯架构已禁用视频预览功能,不会触发此问题 +#ifndef ARCH_MIPSEL // + // 先触发Qt多媒体库加载gstreamter插件 + // 因为预览视频时会先加载mpv库,如果之后再加载gst库,会导致崩溃在init_plugin + // 崩溃的原因是libcdio这个demuxer的long_name字段为NULL,gst-libav代码segfault了。 + // 猜测原因是: + // 影院用的mpv初始化时,初始化了全部的demuxers,包括libavdevice里带的,特别是其中的libcdio。 + // Qt用了gst-libav,这个库加载时也会掉ffmpeg的初始化函数,但是只调用了部分,它编译时显示去掉了libavdevice依赖,所以初始化时不会加载libcdio的demuxer。 + //问题来了:如果先跑gst-libav去初始化ffmpeg,那么没有崩溃问题。因为libcdio demuxer没加载。如果先跑影院库预览视频后,libcdio demuxer被加载了。于是就崩了。 +// QMediaPlayer::hasSupport("audio/mpeg"); + // NOTE(zccrs): 不再需要此特殊处理,已给 gst-libav 添加 fix-crash-on-load-libcdio-plugin.patch +#endif +#endif +#endif + + initUI(); + + if (previewUrllist.count() < 2) { + m_statusBar->preButton()->hide(); + m_statusBar->nextButton()->hide(); + } + m_firstEnterSwitchToPage = true; + switchToPage(0); +} + +FilePreviewDialog::~FilePreviewDialog() +{ + if (m_preview) { + m_preview->deleteLater(); + m_preview = nullptr; + QGuiApplication::changeOverrideCursor(QCursor(Qt::ArrowCursor)); + } +} + +void FilePreviewDialog::updatePreviewList(const DUrlList &previewUrllist) +{ + // 视频预览的前一秒禁止再次播放 + if (m_playingVideo) { + return; + } + + m_fileList = previewUrllist; + m_currentPageIndex = -1; + + if (previewUrllist.count() < 2) { + m_statusBar->preButton()->hide(); + m_statusBar->nextButton()->hide(); + } else { + m_statusBar->preButton()->show(); + m_statusBar->nextButton()->show(); + } + m_firstEnterSwitchToPage = true; + switchToPage(0); +} + +void FilePreviewDialog::childEvent(QChildEvent *event) +{ + if (m_closeButton && event->added()) { + m_closeButton->raise(); + } + + return DAbstractDialog::childEvent(event); +} + +void FilePreviewDialog::showEvent(QShowEvent *event) +{ + windowHandle()->installEventFilter(this); + + return DAbstractDialog::showEvent(event); +} + +void FilePreviewDialog::closeEvent(QCloseEvent *event) +{ + emit signalCloseEvent(); + if (m_preview) { + m_preview->stop(); + if (DFMGlobal::isWayLand()) { + m_preview->DoneCurrent(); + } else { + m_preview->deleteLater(); + m_preview = nullptr; + } + } + + return DAbstractDialog::closeEvent(event); +} + +void FilePreviewDialog::resizeEvent(QResizeEvent *event) +{ + DAbstractDialog::resizeEvent(event); + QTimer::singleShot(50, this, [ = ]() { //fix 32985 【文件管理器】【5.1.1.86-1】【sp2】空格预览界面展示异常。50ms这个时间视机器性能而定 + repaint(); //通过重绘来解决调整大小前的窗口残留的问题 + }); +} + +bool FilePreviewDialog::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) { + const QKeyEvent *e = static_cast(event); + switch (e->key()) { + case Qt::Key_Left: + case Qt::Key_Up: + if (!e->isAutoRepeat()) + previousPage(); + break; + case Qt::Key_Right: + case Qt::Key_Down: + if (!e->isAutoRepeat()) + nextPage(); + break; + case Qt::Key_Space: { + // 视频预览的前一秒禁止再次播放 + if (m_playingVideo) { + break; + } + if (m_preview) { + m_preview->stop(); + } + close(); + return true; + } + default: + break; + } + } + + return DAbstractDialog::eventFilter(obj, event); +} + +void FilePreviewDialog::initUI() +{ + //wayland 暂时不用 task 36991 + if (DFMGlobal::isWayLand()) { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + } else { + m_closeButton = new DWindowCloseButton(this); + m_closeButton->setObjectName("CloseButton"); + m_closeButton->setFocusPolicy(Qt::NoFocus); + m_closeButton->setIconSize({50, 50}); + m_closeButton->setFixedSize({50, 50}); + QColor base_color = palette().base().color(); + DGuiApplicationHelper::ColorType ct = DGuiApplicationHelper::toColorType(base_color); + if (ct == DGuiApplicationHelper::LightType) { + m_closeButton->setStyleSheet("background-color:rgba(255, 255, 255, 25);"); + } else { + m_closeButton->setStyleSheet("background-color:rgba(0, 0, 0, 25);"); + } + + DAnchorsBase::setAnchor(m_closeButton, Qt::AnchorRight, this, Qt::AnchorRight); + connect(m_closeButton, &QPushButton::clicked, this, &FilePreviewDialog::close); + } + + + + m_separator = new DHorizontalLine(this); + m_separator->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + m_statusBar = new FilePreviewDialogStatusBar(this); + m_statusBar->setObjectName("StatusBar"); + m_statusBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_statusBar->openButton()->setFocus(); + + QVBoxLayout *layout = new QVBoxLayout(this); + + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + + QHBoxLayout *separator_layout = new QHBoxLayout(this); + + separator_layout->addSpacing(10); + separator_layout->addWidget(m_separator); + separator_layout->addSpacing(10); + + layout->addLayout(separator_layout, 1); + layout->addWidget(m_statusBar, 0, Qt::AlignBottom); + + QAction *shortcut_action = new QAction(this); + + shortcut_action->setShortcut(QKeySequence::Copy); + addAction(shortcut_action); + + connect(m_statusBar->preButton(), &QPushButton::clicked, this, &FilePreviewDialog::previousPage); + connect(m_statusBar->nextButton(), &QPushButton::clicked, this, &FilePreviewDialog::nextPage); + connect(m_statusBar->openButton(), &QPushButton::clicked, this, [this] { + /*fix bug 47136 在回收站预览打开不了,url传入错误,因为在回收站里面实现了openfile,所以这里倒回到以前代码*/ + if (DFileService::instance()->openFile(this, m_fileList.at(m_currentPageIndex))) + { + close(); + } + + }); + connect(shortcut_action, &QAction::triggered, this, [this] { + if (m_preview) + { + m_preview->copyFile(); + } + }); +} + +static QString generalKey(const QString &key) +{ + const QStringList &_tmp = key.split('/'); + + if (_tmp.size() > 1) + return _tmp.first() + "/*"; + + return key; +} + +void FilePreviewDialog::switchToPage(int index) +{ + if (m_preview) { + m_preview->stop(); + } + + m_currentPageIndex = index; + m_statusBar->preButton()->setEnabled(index > 0); + m_statusBar->nextButton()->setEnabled(index < m_fileList.count() - 1); + + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, m_fileList.at(index)); + + if (!info) { + m_fileList.removeAt(index); + + if (m_fileList.isEmpty()) + return; + + return switchToPage(index); + } + + DFMFilePreview *preview = nullptr; + const QMimeType &mime_type = info->mimeType(); + + QStringList key_list(mime_type.name()); + + key_list.append(mime_type.aliases()); + key_list.append(mime_type.allAncestors()); + + for (const QString &key : key_list) { + const QString &general_key = generalKey(key); + + if (m_preview && (DFMFilePreviewFactory::isSuitedWithKey(m_preview, key) + || DFMFilePreviewFactory::isSuitedWithKey(m_preview, general_key))) { + if (m_preview->setFileUrl(m_fileList.at(index))) { + m_preview->contentWidget()->updateGeometry(); + adjustSize(); + updateTitle(); + m_statusBar->openButton()->setFocus(); + playCurrentPreviewFile(); + moveToCenter(); + return; + } + } + preview = DFMFilePreviewFactory::create(key); + + if (!preview && general_key != key) { + preview = DFMFilePreviewFactory::create(general_key); + } + + if (preview) { + preview->initialize(this, m_statusBar); + + if (info->canRedirectionFileUrl() && preview->setFileUrl(info->redirectedFileUrl())) + break; + else if (preview->setFileUrl(m_fileList.at(index))) + break; + else + preview->deleteLater(); + } + } + if (!preview) { + if (qobject_cast(m_preview)) { + m_preview->setFileUrl(m_fileList.at(index)); + m_statusBar->openButton()->setFocus(); + return; + } else { + preview = new UnknowFilePreview(this); + preview->initialize(this, m_statusBar); + preview->setFileUrl(m_fileList.at(index)); + } + } + + if (m_preview) + disconnect(m_preview, &DFMFilePreview::titleChanged, this, &FilePreviewDialog::updateTitle); + + connect(preview, &DFMFilePreview::titleChanged, this, &FilePreviewDialog::updateTitle); + + + if (m_preview) { + m_preview->contentWidget()->setVisible(false); + m_preview->deleteLater(); + static_cast(layout())->removeWidget(m_preview->contentWidget()); + } + + + static_cast(layout())->insertWidget(0, preview->contentWidget()); + + if (m_preview) + static_cast(m_statusBar->layout())->removeWidget(m_preview->statusBarWidget()); + + if (QWidget *w = preview->statusBarWidget()) + static_cast(m_statusBar->layout())->insertWidget(3, w, 0, preview->statusBarWidgetAlignment()); + + m_separator->setVisible(preview->showStatusBarSeparator()); + m_preview = preview; + + QTimer::singleShot(0, this, [this] { + updateTitle(); + m_statusBar->openButton()->setFocus(); + this->resize(m_preview->contentWidget()->size().width(), m_preview->contentWidget()->size().height()); + QSize end_zoompin = size(); + adjustSize(); + if (end_zoompin.width() > size().width() && (m_preview->metaObject()->className() == QStringLiteral("dde_file_manager::DFMFilePreview"))) { + /*m_preview->contentWidget()->size().width() * 2 2和1.5是adjustSize的自适应值*/ + resize((double)m_preview->contentWidget()->size().width() * 2, (double)m_preview->contentWidget()->size().height() * 1.5); + } else if (end_zoompin.width() == size().width()) { + resize(m_preview->contentWidget()->size().width(), m_preview->contentWidget()->size().height()); + } + playCurrentPreviewFile(); + moveToCenter(); + }); +} + +void FilePreviewDialog::setEntryUrlList(const DUrlList &entryUrlList) +{ + if (entryUrlList.isEmpty()) + return; + DUrl currentUrl = m_fileList.at(m_currentPageIndex); + if (entryUrlList.contains(currentUrl)) { + m_entryUrlList = entryUrlList; + m_fileList = m_entryUrlList; + m_currentPageIndex = m_entryUrlList.indexOf(currentUrl); + } +} + +void FilePreviewDialog::done(int r) +{ + DAbstractDialog::done(r); + + if (m_preview) { + m_preview->stop(); + if (DFMGlobal::isWayLand()) { + m_preview->DoneCurrent(); + } else { + m_preview->deleteLater(); + m_preview = nullptr; + } + } +} + +void FilePreviewDialog::DoneCurrent() +{ + if (m_preview) { + m_preview->DoneCurrent(); + } +} + +void FilePreviewDialog::playCurrentPreviewFile() +{ + if (m_preview) { + // 修复bug-63504 bug-63352 + if (m_preview->metaObject()->className() == QStringLiteral("VideoPreview")) { + m_playingVideo = true; + // 1s 后才能重新预览视频,原因是快速切换预览视频会因为视频插件内部的崩溃引起文管崩溃 + QTimer::singleShot(1000, [this]() { + m_playingVideo = false; + }); + } + m_preview->play(); + } + +} + +void FilePreviewDialog::previousPage() +{ + if (m_currentPageIndex < 1) + return; + if (m_playingVideo) + return; + m_firstEnterSwitchToPage = false; + switchToPage(m_currentPageIndex - 1); +} + +void FilePreviewDialog::nextPage() +{ + if (m_currentPageIndex > m_fileList.count() - 2) + return; + if (m_playingVideo) + return; + m_firstEnterSwitchToPage = false; + switchToPage(m_currentPageIndex + 1); +} + +void FilePreviewDialog::updateTitle() +{ + // 在频繁启动关闭的场景下,m_preview可能会意外释放,引起空指针造成的崩溃 + if (!m_preview) + return; + + QFont font = m_statusBar->title()->font(); + QFontMetrics fm(font); + QString elidedText; + + if (!m_statusBar->preButton()->isVisible()) { + /*fix bug 46804 smb 中一直按着空格预览,m_preview 已经析构了,但是定时器的timeout事件已经执行,这里使用智能指针进行判断*/ + if (!m_preview) { + qDebug() << "m_preview is null,so exit"; + return; + } + elidedText = fm.elidedText(m_preview->title(), Qt::ElideMiddle, width() / 2 - m_statusBar->contentsMargins().left() - m_statusBar->layout()->spacing() - 30); + } else { + elidedText = fm.elidedText(m_preview->title(), Qt::ElideMiddle, width() / 2 - m_statusBar->preButton()->width() - + m_statusBar->nextButton()->width() - m_statusBar->contentsMargins().left() - m_statusBar->layout()->spacing() * 3 - 30); + } + m_statusBar->title()->setText(elidedText); + m_statusBar->title()->setHidden(m_statusBar->title()->text().isEmpty()); +} + +DFM_END_NAMESPACE + +#include "filepreviewdialog.moc" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/filepreviewdialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/filepreviewdialog.h new file mode 100644 index 0000000..f4fa9f6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/filepreviewdialog.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef FILEPREVIEWDIALOG_H +#define FILEPREVIEWDIALOG_H + +#include "dfmglobal.h" +#include "durl.h" +#include "dfmfilepreview.h" +#include "dabstractfileinfo.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QPushButton; +class QLabel; +QT_END_NAMESPACE + +DWIDGET_BEGIN_NAMESPACE +class DWindowCloseButton; +DWIDGET_END_NAMESPACE + +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE + +class FilePreviewDialogStatusBar; +class DFileStatisticsJob; + +class UnknowFilePreview : public DFMFilePreview +{ + Q_OBJECT +public: + explicit UnknowFilePreview(QObject *parent = nullptr); + ~UnknowFilePreview() override; + + bool setFileUrl(const DUrl &url) override; + DUrl fileUrl() const override; + void setFileInfo(const DAbstractFileInfoPointer &info); + + QWidget *contentWidget() const override; + +signals: + void requestStartFolderSize(); + +public slots: + void updateFolderSize(qint64 size); + +private: + DUrl m_url; + QPointer m_contentWidget; + QLabel *m_iconLabel; + QLabel *m_nameLabel; + QLabel *m_sizeLabel; + QLabel *m_typeLabel; + DFileStatisticsJob *m_sizeWorker = nullptr; +}; + + +class FilePreviewDialog : public DAbstractDialog +{ + Q_OBJECT +public: + explicit FilePreviewDialog(const DUrlList &previewUrllist, QWidget *parent = nullptr); + ~FilePreviewDialog() override; + + void updatePreviewList(const DUrlList &previewUrllist); + + void setEntryUrlList(const DUrlList &entryUrlList); + + void done(int r) override; + + void DoneCurrent(); + +signals: + void signalCloseEvent(); + +public slots: + void playCurrentPreviewFile(); + +private: + void childEvent(QChildEvent *event) override; + void showEvent(QShowEvent *event) override; + void closeEvent(QCloseEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; + + void initUI(); + void switchToPage(int index); + void previousPage(); + void nextPage(); + + void updateTitle(); + + DUrlList m_fileList; + DUrlList m_entryUrlList; + + DWindowCloseButton *m_closeButton = nullptr; + DHorizontalLine *m_separator; + FilePreviewDialogStatusBar *m_statusBar; + + bool m_playingVideo = false; + bool m_firstEnterSwitchToPage = false; + int m_currentPageIndex = -1; + DFMFilePreview *m_preview = nullptr; + +}; + +DFM_END_NAMESPACE + +#endif // FILEPREVIEWDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/movetotrashconflictdialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/movetotrashconflictdialog.cpp new file mode 100644 index 0000000..0dc9de9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/movetotrashconflictdialog.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "movetotrashconflictdialog.h" +#include "dfmglobal.h" + +#include +#include +#include + +MoveToTrashConflictDialog::MoveToTrashConflictDialog(QWidget *parent, const DUrlList &urls) : + DDialog(parent) +{ + + if(DFMGlobal::isWayLand()) + { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + } + + QString title; + QString tip; + + if(urls.size() == 1){ + title = tr("This file is too big for the trash"); + tip = tr("Are you sure you want to permanently delete %1?").arg(urls.first().fileName()); + } + else{ + title = tr("The files are too big for the trash"); + tip = tr("Are you sure you want to permanently delete %1 files?").arg(QString::number(urls.size())); + } + + setIcon(QIcon::fromTheme("dialog-warning")); + setTitle(title); + + QLabel* label = new QLabel(this); +// label->setWordWrap(true); + + QFont font; + font.setPixelSize(12); + label->setFont(font); + + QFontMetrics fm(font); + QString elidedTipStr = fm.elidedText(tip,Qt::ElideRight,240); + elidedTipStr += "?"; + label->setText(elidedTipStr); + + addContent(label); + + addButton(tr("Cancel","button"), false); + addButton(tr("Delete","button"), true, DDialog::ButtonWarning); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/movetotrashconflictdialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/movetotrashconflictdialog.h new file mode 100644 index 0000000..c9a12f3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/movetotrashconflictdialog.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef MOVETOTRASHCONFLICTDIALOG_H +#define MOVETOTRASHCONFLICTDIALOG_H + +#include +#include "ddialog.h" +#include "interfaces/durl.h" + +DWIDGET_USE_NAMESPACE + +class MoveToTrashConflictDialog : public DDialog +{ + Q_OBJECT +public: + explicit MoveToTrashConflictDialog(QWidget *parent = 0, + const DUrlList& urls = DUrlList()); + +signals: + +public slots: +}; + +#endif // MOVETOTRASHCONFLICTDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/openwithdialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/openwithdialog.cpp new file mode 100644 index 0000000..c08bc21 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/openwithdialog.cpp @@ -0,0 +1,512 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "openwithdialog.h" +#include "dfileservices.h" + +#include "shutil/mimesappsmanager.h" +#include "shutil/desktopfile.h" +#include "shutil/fileutils.h" + +#include "app/define.h" + +#include "singleton.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +OpenWithDialogListItem::OpenWithDialogListItem(const QIcon &icon, const QString &text, QWidget *parent) + : QWidget(parent) + , m_icon(icon) +{ + if (m_icon.isNull()) + m_icon = QIcon::fromTheme("application-x-desktop"); + + m_checkButton = new DIconButton(this); + m_checkButton->setFixedSize(10, 10); + m_checkButton->setFlat(true); + + m_label = new QLabel(this); + m_label->setText(text); + + m_iconLabel = new QLabel(this); + m_iconLabel->setAlignment(Qt::AlignCenter); + + QHBoxLayout *layout = new QHBoxLayout(this); + + layout->setContentsMargins(5, 0, 5, 0); + layout->addWidget(m_checkButton); + layout->addWidget(m_iconLabel); + layout->addWidget(m_label); + + setMouseTracking(true); +} + +void OpenWithDialogListItem::setChecked(bool checked) +{ + if (checked) { + m_checkButton->setIcon(DStyle::SP_MarkElement); + } else { + m_checkButton->setIcon(QIcon()); + } +} + +QString OpenWithDialogListItem::text() const +{ + return m_label->text(); +} + +void OpenWithDialogListItem::resizeEvent(QResizeEvent *e) +{ + QWidget::resizeEvent(e); + + m_iconLabel->setFixedSize(e->size().height() - 20, e->size().height() - 20); + m_iconLabel->setPixmap(m_icon.pixmap(m_iconLabel->size())); +} + +void OpenWithDialogListItem::enterEvent(QEvent *e) +{ + Q_UNUSED(e) + + update(); + + return QWidget::enterEvent(e); +} + +void OpenWithDialogListItem::leaveEvent(QEvent *e) +{ + Q_UNUSED(e) + + update(); + + return QWidget::leaveEvent(e); +} + +void OpenWithDialogListItem::paintEvent(QPaintEvent *e) +{ + Q_UNUSED(e) + + if (!underMouse()) + return; + + QPainter pa(this); + QPainterPath path; + + path.addRoundedRect(rect(), 6, 6); + pa.setRenderHint(QPainter::Antialiasing); + pa.fillPath(path, QColor(0, 0, 0, static_cast(0.05 * 255))); +} + +class OpenWithDialogListSparerItem : public QWidget +{ +public: + explicit OpenWithDialogListSparerItem(const QString &title, QWidget *parent = nullptr); + +private: + DHorizontalLine *m_separator; + QLabel *m_title; +}; + +OpenWithDialogListSparerItem::OpenWithDialogListSparerItem(const QString &title, QWidget *parent) + : QWidget(parent) + , m_separator(new DHorizontalLine(this)) + , m_title(new QLabel(title, this)) +{ + QFont font; + font.setPixelSize(18); + m_title->setFont(font); + + QVBoxLayout *layout = new QVBoxLayout(this); + + layout->addWidget(m_separator); + layout->addWidget(m_title); + layout->setContentsMargins(20, 0, 20, 0); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); +} + +OpenWithDialog::OpenWithDialog(const QList &urllist, QWidget *parent) + : BaseDialog(parent) + , m_urllist(urllist) +{ + setWindowFlags(windowFlags() + & ~ Qt::WindowMaximizeButtonHint + & ~ Qt::WindowMinimizeButtonHint + & ~ Qt::WindowSystemMenuHint); + mimeAppsManager->initMimeTypeApps(); + initUI(); + initConnect(); + initData(); +} + +OpenWithDialog::OpenWithDialog(const DUrl &url, QWidget *parent) + : BaseDialog(parent) + , m_url(url) +{ + setWindowFlags(windowFlags() + & ~ Qt::WindowMaximizeButtonHint + & ~ Qt::WindowMinimizeButtonHint + & ~ Qt::WindowSystemMenuHint); + mimeAppsManager->initMimeTypeApps(); + initUI(); + initConnect(); + initData(); +} + +OpenWithDialog::~OpenWithDialog() +{ + +} + +void OpenWithDialog::initUI() +{ + if (DFMGlobal::isWayLand()) { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + } + + setFixedSize(710, 450); + setTitle(tr("Open with")); + + m_scrollArea = new QScrollArea(this); + m_scrollArea->setObjectName("OpenWithDialog-QScrollArea"); + + m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_scrollArea->setFrameShape(QFrame::NoFrame); + m_scrollArea->setWidgetResizable(true); + QScroller::grabGesture(m_scrollArea); + m_scrollArea->installEventFilter(this); + m_scrollArea->viewport()->setStyleSheet("background-color:transparent;"); //设置滚动区域与主窗体颜色一致 + + QWidget *content_widget = new QWidget; + + content_widget->setObjectName("contentWidget"); + content_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + m_scrollArea->setWidget(content_widget); + + m_recommandLayout = new DFlowLayout; + m_otherLayout = new DFlowLayout; + + m_openFileChooseButton = new QCommandLinkButton(tr("Add other programs")); + m_setToDefaultCheckBox = new QCheckBox(tr("Set as default")); + m_setToDefaultCheckBox->setChecked(true); + m_cancelButton = new QPushButton(tr("Cancel","button")); + m_chooseButton = new QPushButton(tr("Confirm","button")); + + QVBoxLayout *content_layout = new QVBoxLayout; + content_layout->setContentsMargins(10, 0, 10, 0); + content_layout->addWidget(new OpenWithDialogListSparerItem(tr("Recommended Applications"), this)); + content_layout->addLayout(m_recommandLayout); + content_layout->addWidget(new OpenWithDialogListSparerItem(tr("Other Applications"), this)); + content_layout->addLayout(m_otherLayout); + content_layout->addStretch(); + + content_widget->setLayout(content_layout); + + QHBoxLayout *buttonLayout = new QHBoxLayout; + buttonLayout->addWidget(m_openFileChooseButton); + buttonLayout->addStretch(); + buttonLayout->addWidget(m_setToDefaultCheckBox); + buttonLayout->addSpacing(20); + buttonLayout->addWidget(m_cancelButton); + buttonLayout->addWidget(m_chooseButton); + buttonLayout->setContentsMargins(10, 0, 10, 0); + + QVBoxLayout *main_layout = new QVBoxLayout(this); + QVBoxLayout *bottom_layout = new QVBoxLayout; + + bottom_layout->addWidget(new DHorizontalLine(this)); + bottom_layout->addSpacing(5); + bottom_layout->addLayout(buttonLayout); + bottom_layout->setContentsMargins(10, 0, 10, 0); + + main_layout->addWidget(m_scrollArea); + main_layout->addLayout(bottom_layout); + main_layout->setContentsMargins(0, 35, 0, 10); +} + +void OpenWithDialog::initConnect() +{ + connect(m_cancelButton, &QPushButton::clicked, this, &OpenWithDialog::close); + connect(m_chooseButton, &QPushButton::clicked, this, &OpenWithDialog::openFileByApp); + connect(m_openFileChooseButton, &QCommandLinkButton::clicked, this, &OpenWithDialog::useOtherApplication); +} + +void OpenWithDialog::initData() +{ + //在选择默认程序时,有多个url,要传多个url + if (m_url.isValid() && m_urllist.size() == 0) { + const DAbstractFileInfoPointer &file_info = DFileService::instance()->createFileInfo(this, m_url); + + if (!file_info) + return; + + m_mimeType = file_info->mimeType(); + + if (file_info->isDesktopFile()) + m_setToDefaultCheckBox->hide(); + } else if (!m_url.isValid() && m_urllist.size() > 0) { + QList openlist; + bool bhide = true; + for (auto url : m_urllist) { + const DAbstractFileInfoPointer &file_info = DFileService::instance()->createFileInfo(this, url); + + if (!file_info) { + continue; + } + m_mimeType = file_info->mimeType(); + if (!file_info->isDesktopFile()) { + bhide = false; + } + openlist.push_back(url); + } + + if (0 == openlist.size()) + return; + + if (bhide) + m_setToDefaultCheckBox->hide(); + } + + + const QString &default_app = mimeAppsManager->getDefaultAppByMimeType(m_mimeType); + const QStringList &recommendApps = mimeAppsManager->getRecommendedAppsByQio(m_mimeType); + + for (int i = 0; i < recommendApps.count(); ++i) { + const DesktopFile &desktop_info = mimeAppsManager->DesktopObjs.value(recommendApps.at(i)); + + OpenWithDialogListItem *item = createItem(QIcon::fromTheme(desktop_info.getIcon()), desktop_info.getDisplayName(), recommendApps.at(i)); + m_recommandLayout->addWidget(item); + + if (!default_app.isEmpty() && recommendApps.at(i).endsWith(default_app)) + checkItem(item); + } + + QList other_app_list; + + foreach (const QString &f, mimeAppsManager->DesktopObjs.keys()) { + //filter recommend apps , no show apps and no mime support apps + const DesktopFile &app = mimeAppsManager->DesktopObjs.value(f); + if (recommendApps.contains(f)) + continue; + + if (mimeAppsManager->DesktopObjs.value(f).getNoShow()) + continue; + + if (mimeAppsManager->DesktopObjs.value(f).getMimeType().isEmpty()) + continue; + + bool isSameDesktop = false; + foreach (const DesktopFile &otherApp, other_app_list) { + if (otherApp.getExec() == app.getExec() && otherApp.getLocalName() == app.getLocalName()) + isSameDesktop = true; + } + + Properties desktop_info(f, "Desktop Entry"); + + const QString &custom_open_desktop = desktop_info.value("X-DDE-File-Manager-Custom-Open").toString(); + + // Filter self own desktop files for opening other types of files + if (!custom_open_desktop.isEmpty() && custom_open_desktop != m_mimeType.name()) + continue; + + if (isSameDesktop) + continue; + + other_app_list << mimeAppsManager->DesktopObjs.value(f); + QString iconName = other_app_list.last().getIcon(); + OpenWithDialogListItem *item = createItem(QIcon::fromTheme(iconName), other_app_list.last().getDisplayName(), f); + m_otherLayout->addWidget(item); + + if (!default_app.isEmpty() && f.endsWith(default_app)) + checkItem(item); + } +} + +void OpenWithDialog::checkItem(OpenWithDialogListItem *item) +{ + if (m_checkedItem) + m_checkedItem->setChecked(false); + + item->setChecked(true); + m_checkedItem = item; +} + +void OpenWithDialog::useOtherApplication() +{ + const QString &file_path = QFileDialog::getOpenFileName(this); + + if (file_path.isEmpty()) + return; + + QFileInfo info(file_path); + QString target_desktop_file_name("%1/%2-custom-open-%3.desktop"); + + target_desktop_file_name = target_desktop_file_name.arg(QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)).arg(qApp->applicationName()).arg(m_mimeType.name().replace("/", "-")); + + if (file_path.endsWith(".desktop")) { + auto list = m_recommandLayout->parentWidget()->findChildren(); + auto ret = std::any_of(list.begin(), list.end(), [file_path](const OpenWithDialog * w) { + return w->property("app").toString() == file_path; + }); + + if (ret) + return; + + Properties desktop(file_path, "Desktop Entry"); + + if (desktop.value("MimeType").toString().isEmpty()) + return; + + if (!QFile::link(file_path, target_desktop_file_name)) + return; + } else if (info.isExecutable()) { + Properties desktop; + + desktop.set("Type", "Application"); + desktop.set("Name", info.fileName()); + desktop.set("Icon", "application-x-desktop"); + desktop.set("Exec", file_path); + desktop.set("MimeType", "*/*"); + desktop.set("X-DDE-File-Manager-Custom-Open", m_mimeType.name()); + + if (QFile::exists(target_desktop_file_name)) + QFile(target_desktop_file_name).remove(); + + if (!desktop.save(target_desktop_file_name, "Desktop Entry")) + return; + } + + // remove old custom item + for (int i = 0; i < m_otherLayout->count(); ++i) { + QWidget *w = m_otherLayout->itemAt(i)->widget(); + + if (!w) + continue; + + if (w->property("app").toString() == target_desktop_file_name) { + m_otherLayout->removeWidget(w); + w->deleteLater(); + } + } + + OpenWithDialogListItem *item = createItem(QIcon::fromTheme("application-x-desktop"), info.fileName(), target_desktop_file_name); + + int other_layout_sizeHint_height = m_otherLayout->sizeHint().height(); + m_otherLayout->addWidget(item); + item->show(); + m_otherLayout->parentWidget()->setFixedHeight(m_otherLayout->parentWidget()->height() + m_otherLayout->sizeHint().height() - other_layout_sizeHint_height); + checkItem(item); +} + +OpenWithDialogListItem *OpenWithDialog::createItem(const QIcon &icon, const QString &name, const QString &filePath) +{ + OpenWithDialogListItem *item = new OpenWithDialogListItem(icon, name, this); + + item->setProperty("app", filePath); + item->setFixedSize(220, 50); + item->installEventFilter(this); + + return item; +} + +void OpenWithDialog::openFileByApp() +{ + if (!m_checkedItem) + return; + + const QString &app = m_checkedItem->property("app").toString(); + + if (m_setToDefaultCheckBox->isChecked()) + mimeAppsManager->setDefautlAppForTypeByGio(m_mimeType.name(), app); + + if (m_url.isValid() && DFileService::instance()->openFileByApp(this, app, m_url)) { + close(); + return; + } + if (m_urllist.size() == 0) { + close(); + return; + } + if (m_urllist.size() == 1 && DFileService::instance()->openFileByApp(this, app, m_urllist.first())) { + close(); + return; + } + if (m_urllist.size() > 1 && DFileService::instance()->openFilesByApp(this, app, m_urllist)) { + close(); + return; + } +} + +void OpenWithDialog::showEvent(QShowEvent *event) +{ + BaseDialog::showEvent(event); + + m_recommandLayout->parentWidget()->setFixedWidth(m_scrollArea->width()); + m_recommandLayout->parentWidget()->resize(m_recommandLayout->parentWidget()->layout()->sizeHint()); +} + +bool OpenWithDialog::eventFilter(QObject *obj, QEvent *event) +{ + // blumia: for m_scrollArea, to avoid touch screen scrolling cause window move + if (event->type() == QEvent::MouseMove) { + QMouseEvent *mouseEvent = static_cast(event); + if (mouseEvent->source() == Qt::MouseEventSynthesizedByQt) { + return true; + } + } + + if (event->type() == QEvent::MouseButtonPress) { + + if (static_cast(event)->button() == Qt::LeftButton) { + if (OpenWithDialogListItem *item = qobject_cast(obj)) + checkItem(item); + + return true; + } + } + + return false; +} + +//#include "openwithdialog.moc" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/openwithdialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/openwithdialog.h new file mode 100644 index 0000000..70e1b2b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/openwithdialog.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef OPENWITHDIALOG_H +#define OPENWITHDIALOG_H + +#include "basedialog.h" +#include "durl.h" + +#include +#include + +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +QT_BEGIN_NAMESPACE +class QPushButton; +class QScrollArea; +class QCheckBox; +QT_END_NAMESPACE + +class OpenWithDialogListItem : public QWidget +{ + Q_OBJECT + +public: + explicit OpenWithDialogListItem(const QIcon &icon, const QString &text, QWidget *parent = nullptr); + + void setChecked(bool checked); + QString text() const; + +protected: + void resizeEvent(QResizeEvent *e) override; + void enterEvent(QEvent *e) override; + void leaveEvent(QEvent *e) override; + void paintEvent(QPaintEvent *e) override; + +private: + QIcon m_icon; + DIconButton *m_checkButton; + QLabel *m_iconLabel; + QLabel *m_label; +}; + +class OpenWithDialog : public BaseDialog +{ + Q_OBJECT +public: + explicit OpenWithDialog(const QList& urllist, QWidget *parent = nullptr); + explicit OpenWithDialog(const DUrl &url, QWidget *parent = nullptr); + ~OpenWithDialog() override; + +public slots: + void openFileByApp(); + +protected: + void showEvent(QShowEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; + +private: + void initUI(); + void initConnect(); + void initData(); + void checkItem(OpenWithDialogListItem *item); + void useOtherApplication(); + OpenWithDialogListItem *createItem(const QIcon &icon, const QString &name, const QString &filePath); + + QScrollArea *m_scrollArea = nullptr; + DFlowLayout *m_recommandLayout = nullptr; + DFlowLayout *m_otherLayout = nullptr; + + QCommandLinkButton *m_openFileChooseButton = nullptr; + QCheckBox *m_setToDefaultCheckBox = nullptr; + QPushButton *m_cancelButton = nullptr; + QPushButton *m_chooseButton = nullptr; + QList m_urllist; + DUrl m_url; + QMimeType m_mimeType; + + OpenWithDialogListItem *m_checkedItem = nullptr; +}; + +#endif // OPENWITHDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/private/ddesktoprenamedialog_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/private/ddesktoprenamedialog_p.h new file mode 100644 index 0000000..80c5c20 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/private/ddesktoprenamedialog_p.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DDESKTOPRENAMEDIALOG_P_H +#define DDESKTOPRENAMEDIALOG_P_H + +#include +#include +#include +#include +#include +#include + +#include "interfaces/dfileservices.h" + +class DDesktopRenameDialog; + +class DDesktopRenameDialogPrivate +{ +public: + explicit DDesktopRenameDialogPrivate(DDesktopRenameDialog *const qPtr); + ~DDesktopRenameDialogPrivate() = default; + DDesktopRenameDialogPrivate(const DDesktopRenameDialogPrivate &other) = delete; + DDesktopRenameDialogPrivate &operator=(const DDesktopRenameDialogPrivate &other) = delete; + + + void initUi(); + void initUiParameters(); + void initUiLayout(); + + QString filteringText(const QString &text); //bug 26533 + void updateLineEditText(QLineEdit *lineEdit, const QString &defaultValue = ""); //bug 26533 + + DDesktopRenameDialog *q_ptr{ nullptr }; + + QLabel *m_titleLabel{ nullptr }; + + std::tuple m_itemsForSelecting{}; + QStackedLayout *m_stackedLayout{ nullptr }; + + std::tuple m_modeOneItemsForFinding{}; + std::tuple m_modeOneItemsForReplacing{}; + QPair m_modeOneLayout{}; + + + std::tuple m_modeTwoItemsForAdding{}; + std::tuple m_modeTwoItemsForLocating{}; + QPair m_modeTwoLayout{}; + + + std::tuple m_modeThreeItemsForFileName{}; + std::tuple m_modeThreeItemsForSNNumber{}; + QPair m_modeThreeLayout{}; + QRegExpValidator *m_validator{ nullptr }; + + QVBoxLayout *m_mainLayout{ nullptr }; + QFrame *m_mainFrame{ nullptr }; + std::size_t m_currentmode{ 0 }; //###: reocord current mode. + std::array m_currentEnabled{{ false }}; //###: this array record current status of renamebutton at current mode. + DFileService::AddTextFlags m_flagForAdding{ DFileService::AddTextFlags::Before }; //###: this flag is useful in mode 2. It record what to append str to name. +}; + +#endif // DDESKTOPRENAMEDIALOG_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/private/dfmsettingdialog_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/private/dfmsettingdialog_p.h new file mode 100644 index 0000000..c58c913 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/private/dfmsettingdialog_p.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMSETTINGDIALOG_P_H +#define DFMSETTINGDIALOG_P_H + +#include +#include +#include +#include "dfmapplication.h" + +DCORE_USE_NAMESPACE +DFM_USE_NAMESPACE + +template +class BidirectionHash +{ +public: +#ifdef Q_COMPILER_INITIALIZER_LISTS + inline BidirectionHash(std::initializer_list > list) + { + k2v.reserve(int(list.size())); + v2k.reserve(int(list.size())); + + for (auto it = list.begin(); it != list.end(); ++it) { + k2v.insert(it->first, it->second); + v2k.insert(it->second, it->first); + } + } +#endif + + bool containsKey(const Key &key) const + { + return k2v.contains(key); + } + bool containsValue(const T &value) const + { + return v2k.contains(value); + } + const Key key(const T &value) const + { + return v2k.value(value); + } + const Key key(const T &value, const Key &defaultKey) const + { + return v2k.value(value, defaultKey); + } + const T value(const Key &key) const + { + return k2v.value(key); + } + const T value(const Key &key, const T &defaultValue) const + { + return k2v.value(key, defaultValue); + } + QList keys() const + { + return k2v.keys(); + } + +private: + QHash k2v; + QHash v2k; +}; + +class SettingBackend : public DSettingsBackend +{ + Q_OBJECT +public: + explicit SettingBackend(QObject *parent = nullptr); + + QStringList keys() const; + QVariant getOption(const QString &key) const; + + void doSync(); + +protected: + void doSetOption(const QString &key, const QVariant &value); + void onValueChanged(int attribute, const QVariant &value); + +private: + BidirectionHash keyToAA { + {"base.open_action.allways_open_on_new_window", DFMApplication::AA_AllwayOpenOnNewWindow}, + {"base.open_action.open_file_action", DFMApplication::AA_OpenFileMode}, + {"base.new_tab_windows.default_window_path", DFMApplication::AA_UrlOfNewWindow}, + {"base.new_tab_windows.new_tab_path", DFMApplication::AA_UrlOfNewTab}, + {"base.default_view.icon_size", DFMApplication::AA_IconSizeLevel}, + {"base.default_view.view_mode", DFMApplication::AA_ViewMode}, + {"base.default_view.view_size_adjustable", DFMApplication::AA_ViewSizeAdjustable}, + }; + BidirectionHash keyToGA { + {"base.hidden_files.show_hidden", DFMApplication::GA_ShowedHiddenFiles}, + {"base.hidden_files.hide_suffix", DFMApplication::GA_ShowedFileSuffixOnRename}, + {"base.hidden_files.show_recent", DFMApplication::GA_ShowRecentFileEntry}, + {"advance.index.index_internal", DFMApplication::GA_IndexInternal}, + {"advance.index.index_external", DFMApplication::GA_IndexExternal}, +#ifdef FULLTEXTSEARCH_ENABLE + {"advance.index.index_search", DFMApplication::GA_IndexFullTextSearch}, +#endif + {"advance.search.show_hidden", DFMApplication::GA_ShowedHiddenOnSearch}, + {"advance.preview.compress_file_preview", DFMApplication::GA_PreviewCompressFile}, + {"advance.preview.text_file_preview", DFMApplication::GA_PreviewTextFile}, + {"advance.preview.document_file_preview", DFMApplication::GA_PreviewDocumentFile}, + {"advance.preview.image_file_preview", DFMApplication::GA_PreviewImage}, + {"advance.preview.video_file_preview", DFMApplication::GA_PreviewVideo}, + {"advance.mount.auto_mount", DFMApplication::GA_AutoMount}, + {"advance.mount.auto_mount_and_open", DFMApplication::GA_AutoMountAndOpen}, + {"advance.mount.mtp_show_bottom_info", DFMApplication::GA_MTPShowBottomInfo}, + {"advance.mount.always_show_offline_remote_connection", DFMApplication::GA_AlwaysShowOfflineRemoteConnections}, + {"advance.dialog.default_chooser_dialog", DFMApplication::GA_OverrideFileChooserDialog}, + {"advance.dialog.delete_confirmation_dialog", DFMApplication::GA_ShowDeleteConfirmDialog}, + {"advance.other.hide_system_partition", DFMApplication::GA_HiddenSystemPartition}, + {"advance.other.show_crumbbar_clickable_area", DFMApplication::GA_ShowCsdCrumbBarClickableArea}, + {"advance.other.show_filesystemtag_on_diskicon", DFMApplication::GA_ShowFileSystemTagOnDiskIcon}, + }; +}; + +#endif // DFMSETTINGDIALOG_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/propertydialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/propertydialog.cpp new file mode 100644 index 0000000..5c17fd3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/propertydialog.cpp @@ -0,0 +1,1780 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +//fixed:CD display size error +#include "views/dfmopticalmediawidget.h" + +#include "propertydialog.h" +#include "dabstractfilewatcher.h" +#include "dfileinfo.h" +#include + +#include "app/define.h" + +#include "dfileservices.h" +#include "dfilestatisticsjob.h" + +#include "shutil/fileutils.h" +#include "shutil/mimesappsmanager.h" +#include "shutil/dfmfilelistfile.h" + +#include "dialogs/dialogmanager.h" +#include "app/filesignalmanager.h" + +#include "models/dfmrootfileinfo.h" +#include "deviceinfo/udisklistener.h" + +#include "controllers/vaultcontroller.h" +#include "vaultglobaldefine.h" + +#include "utils.h" + +#include "singleton.h" + +#include "shareinfoframe.h" +#include "views/dfilemanagerwindow.h" +#include "views/windowmanager.h" +#include "views/dfileview.h" +#include "interfaces/dfilesystemmodel.h" + +#include "plugins/pluginmanager.h" +#include "../plugininterfaces/menu/menuinterface.h" +#include "dfmeventdispatcher.h" +#include "views/dfmsidebar.h" +#include "dfmapplication.h" +#include "dstorageinfo.h" +#include "dfmsettings.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#define ArrowLineExpand_HIGHT 30 +#define ArrowLineExpand_SPACING 10 + +bool DFMRoundBackground::eventFilter(QObject *watched, QEvent *event) +{ + if (watched == parent() && event->type() == QEvent::Paint) { + QWidget *w = dynamic_cast(watched); + if (!w) { + return false; + } + int radius = property("radius").toInt(); + + QPainter painter(w); + QRectF bgRect; + bgRect.setSize(w->size()); + const QPalette pal = QGuiApplication::palette(); + QColor bgColor = pal.color(QPalette::Base); + + QPainterPath path; + path.addRoundedRect(bgRect, radius, radius); + // drawbackground color + painter.setRenderHint(QPainter::Antialiasing, true); + painter.fillPath(path, bgColor); + painter.setRenderHint(QPainter::Antialiasing, false); + return true; + } + + return QObject::eventFilter(watched, event); +} + +NameTextEdit::NameTextEdit(const QString &text, QWidget *parent): + QTextEdit(text, parent) +{ + setObjectName("NameTextEdit"); + setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setFrameShape(QFrame::NoFrame); + setFixedSize(200, 60); + setContextMenuPolicy(Qt::NoContextMenu); + + connect(this, &QTextEdit::textChanged, this, [this] { + QSignalBlocker blocker(this); + Q_UNUSED(blocker) + + QString text = this->toPlainText(); + const QString old_text = text; + + int text_length = text.length(); + + text.remove('/'); + text.remove(QChar(0)); + + QVector list = text.toUcs4(); + int cursor_pos = this->textCursor().position() - text_length + text.length(); + + while (text.toLocal8Bit().count() > MAX_FILE_NAME_CHAR_COUNT) + { + text.chop(1); + } + + if (text.count() != old_text.count()) + { + this->setText(text); + } + + QTextCursor cursor = this->textCursor(); + + cursor.movePosition(QTextCursor::Start); + + do + { + QTextBlockFormat format = cursor.blockFormat(); + + format.setLineHeight(TEXT_LINE_HEIGHT, QTextBlockFormat::FixedHeight); + cursor.setBlockFormat(format); + } while (cursor.movePosition(QTextCursor::NextBlock)); + + cursor.setPosition(cursor_pos); + + this->setTextCursor(cursor); + this->setAlignment(Qt::AlignHCenter); + + if (this->isReadOnly()) + this->setFixedHeight(this->document()->size().height()); + }); +} + +void NameTextEdit::setPlainText(const QString &text) +{ + QTextEdit::setPlainText(text); + setAlignment(Qt::AlignCenter); +} + +void NameTextEdit::focusOutEvent(QFocusEvent *event) +{ + QTextEdit::focusOutEvent(event); +} + +void NameTextEdit::keyPressEvent(QKeyEvent *event) +{ + QEvent::Type ty = event->type(); + Q_UNUSED(ty) + Qt::KeyboardModifiers modifiers = event->modifiers(); + Q_UNUSED(modifiers) + if (event->key() == Qt::Key_Escape) { + setIsCanceled(true); + emit editFinished(); + return; + } + if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { + setIsCanceled(false); + emit editFinished(); + } + QTextEdit::keyPressEvent(event); +} + +bool NameTextEdit::isCanceled() const +{ + return m_isCanceled; +} + +void NameTextEdit::setIsCanceled(bool isCanceled) +{ + m_isCanceled = isCanceled; +} + + +GroupTitleLabel::GroupTitleLabel(const QString &text, QWidget *parent, Qt::WindowFlags f): + QLabel(text, parent, f) +{ + setObjectName("GroupTitleLabel"); +} + +SectionKeyLabel::SectionKeyLabel(const QString &text, QWidget *parent, Qt::WindowFlags f): + QLabel(text, parent, f) +{ + setObjectName("SectionKeyLabel"); + setFixedWidth(120); + QFont font = this->font(); + font.setWeight(QFont::Bold - 8); + font.setPixelSize(13); + setFont(font); + setAlignment(Qt::AlignVCenter | Qt::AlignLeft); +} + + +SectionValueLabel::SectionValueLabel(const QString &text, QWidget *parent, Qt::WindowFlags f): + QLabel(text, parent, f) +{ + setObjectName("SectionValueLabel"); + setFixedWidth(150); + QFont font = this->font(); + font.setPixelSize(12); + setFont(font); + setAlignment(Qt::AlignVCenter | Qt::AlignLeft); + setWordWrap(true); +} + +LinkSectionValueLabel::LinkSectionValueLabel(const QString &text, QWidget *parent, Qt::WindowFlags f): + SectionValueLabel(text, parent, f) +{ + +} + +void LinkSectionValueLabel::mouseReleaseEvent(QMouseEvent *event) +{ + DFMEventDispatcher::instance()->processEvent(Q_NULLPTR, linkTargetUrl()); + SectionValueLabel::mouseReleaseEvent(event); +} + +DUrl LinkSectionValueLabel::linkTargetUrl() const +{ + return m_linkTargetUrl; +} + +void LinkSectionValueLabel::setLinkTargetUrl(const DUrl &linkTargetUrl) +{ + m_linkTargetUrl = linkTargetUrl; +} + + +PropertyDialog::PropertyDialog(const DFMEvent &event, const DUrl url, QWidget *parent) + : DDialog(parent) + , m_fmevent(event) + , m_url(url) + , m_icon(new QLabel) + , m_edit(new NameTextEdit) + , m_platformWindowHandle(new DPlatformWindowHandle(this, this)) +{ + //允许窗口拖拽缩放 + m_platformWindowHandle->setEnableSystemResize(true); + + if (DFMGlobal::isWayLand()) { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + } else { + setAttribute(Qt::WA_DeleteOnClose); + setWindowFlags(windowFlags() + & ~ Qt::WindowMaximizeButtonHint + & ~ Qt::WindowMinimizeButtonHint + & ~ Qt::WindowSystemMenuHint); + } + + QString basicInfo = tr("Basic info"); + QString openWith = tr("Open with"); + QString shareManager = tr("Sharing"); + QString authManager = tr("Permissions"); + initUI(); + QString query = m_url.query(); + + if (m_url.scheme() == DFMROOT_SCHEME) { + //dgvfsinfo有缓存的才去刷新缓存的信息 + DAbstractFileInfoPointer fi = DAbstractFileInfo::getFileInfo(m_url); + if (fi) { + fi->refresh(fi->isGvfsMountFile()); + } else { + fi = fileService->createFileInfo(this, m_url); + } + Q_ASSERT(fi); + + QString name = fi->fileDisplayName(); + QIcon icon = QIcon::fromTheme(fi->iconName()); + + m_icon->setPixmap(icon.pixmap(128, 128)); + m_edit->setPlainText(name); + m_editDisbaled = true; + const QList > &properties = createLocalDeviceInfoWidget(fi); + m_deviceInfoFrame = createInfoFrame(properties); + + QStringList titleList; + titleList << basicInfo; + m_expandGroup = addExpandWidget(titleList); + m_expandGroup.at(0)->setContent(m_deviceInfoFrame); + m_expandGroup.at(0)->setExpand(true); + + uint64_t dskspace = fi->extraProperties()["fsSize"].toULongLong(); + uint64_t dskinuse = fi->extraProperties()["fsUsed"].toULongLong(); + QString devid(fi->suffix() == SUFFIX_GVFSMP ? fi->fileDisplayName() : fi->baseName()); + if (devid == name) { + devid.clear(); + } + + DColoredProgressBar *progbdf = new DTK_WIDGET_NAMESPACE::DColoredProgressBar(); + // fix bug#47111 由于addThreshold接口不支持渐变色类(QLinearGradient),暂时采用固定颜色 + progbdf->addThreshold(0, QColor(0xFF0080FF)); + progbdf->addThreshold(7000, QColor(0xFFFFAE00)); + progbdf->addThreshold(9000, QColor(0xFFFF0000)); + + //fixed:CD display size error + if (static_cast(fi->fileType()) == DFMRootFileInfo::ItemType::UDisksOptical) { + DFMRootFileInfo *pFileInfo = dynamic_cast(fi.data()); + QString strVolTag; + if (pFileInfo) + strVolTag = pFileInfo->getVolTag(); + dskspace = DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].nTotal; + dskinuse = DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].nUsage; + } + + progbdf->setMaximum(10000); + progbdf->setValue(dskspace && ~dskinuse ? int(10000. * dskinuse / dskspace) : 0); + progbdf->setMaximumHeight(8); + progbdf->setTextVisible(false); + + // fix bug#47111 在浅色模式下,手动设置进度条背景色 + if (DGuiApplicationHelper::LightType == DGuiApplicationHelper::instance()->themeType()) { + DPalette palette = progbdf->palette(); + palette.setBrush(DPalette::ObviousBackground, QColor("#ededed")); + DApplicationHelper::instance()->setPalette(progbdf, palette); + } + + // 进度条背景色跟随主题变化而变化 + connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, [ = ](DGuiApplicationHelper::ColorType type) { + DPalette palette = progbdf->palette(); + if (type == DGuiApplicationHelper::LightType) { + palette.setBrush(DPalette::ObviousBackground, QColor("#ededed")); + DApplicationHelper::instance()->setPalette(progbdf, palette); + } else { + palette.setBrush(DPalette::ObviousBackground, QColor("#4e4e4e")); + DApplicationHelper::instance()->setPalette(progbdf, palette); + } + }); + + //fix 没有devid则只显示名称 + QString text = devid.isEmpty() ? tr("%1").arg(name) : tr("%1 (%2)").arg(name).arg(devid); + //end + + QLabel *lbdf_l = new SectionKeyLabel(); + QString fullText(text); + text = lbdf_l->fontMetrics().elidedText(text, Qt::ElideMiddle, 150); + lbdf_l->setText(text); + if (text != fullText) { + lbdf_l->setToolTip(fullText); + } + QLabel *lbdf_r = new SectionKeyLabel(tr("%1 / %2").arg(FileUtils::formatSize(dskinuse)).arg(FileUtils::formatSize(dskspace))); + if (!~dskinuse) { + lbdf_r->setText(FileUtils::formatSize(dskspace)); + } + lbdf_l->setAlignment(Qt::AlignLeft); + lbdf_r->setAlignment(Qt::AlignRight); + lbdf_l->setMaximumWidth(QWIDGETSIZE_MAX); + lbdf_r->setMaximumWidth(QWIDGETSIZE_MAX); + QWidget *wdfl = new QWidget(); + wdfl->setLayout(new QHBoxLayout); + wdfl->layout()->setMargin(0); + wdfl->layout()->addWidget(lbdf_l); + wdfl->layout()->addWidget(lbdf_r); + + m_wdf = new QFrame(this); + m_wdf->setLayout(new QVBoxLayout); + m_wdf->layout()->setMargin(0); + m_wdf->layout()->setContentsMargins(12, 8, 12, 8); + m_wdf->layout()->addWidget(wdfl); + m_wdf->layout()->addWidget(progbdf); + new DFMRoundBackground(m_wdf, 8); + qobject_cast(m_scrollArea->widget()->layout())->insertWidget(0, m_wdf); + + } else { + // tagged file basicinfo not complete?? + DUrl realUrl = m_url.isTaggedFile() ? DUrl::fromLocalFile(m_url.fragment(QUrl::FullyDecoded)) : m_url; + + //! bug#40608 解决通过标记访问保险箱,属性菜单显示不正确的问题. + bool isVaultFile = VaultController::isRootDirectory(realUrl.toLocalFile()); + if (isVaultFile) { + //! set scheme to get vault file info. + realUrl.setScheme(DFMVAULT_SCHEME); + } + //dgvfsinfo有缓存的才去刷新缓存的信息 + DAbstractFileInfoPointer fileInfo = DAbstractFileInfo::getFileInfo(m_url); + if (fileInfo) { + fileInfo->refresh(fileInfo->isGvfsMountFile()); + } else { + fileInfo = DFileService::instance()->createFileInfo(this, realUrl); + } + if (!fileInfo) { + close(); + return; + } + + m_icon->setPixmap(fileInfo->fileIcon().pixmap(128, 128)); + m_edit->setPlainText(fileInfo->fileDisplayName()); + m_edit->setAlignment(Qt::AlignHCenter); + + if (!fileInfo->canRename()) { + m_editDisbaled = true; + } + + m_basicInfoFrame = createBasicInfoWidget(fileInfo); + + QStringList titleList; + if (fileInfo->isFile()) { + titleList << basicInfo; + //在回收站搜索文件,需要使搜索结果的文件属性面板与回收站文件属性面板保持一致 + if (!m_url.isTrashFile() && !(m_url.isSearchFile() && fileInfo->redirectedFileUrl().isTrashFile())) { + titleList << openWith; + if (fileInfo->canManageAuth()) + titleList << authManager; + } + } else { + titleList << basicInfo; + //! 选中的文件是保险箱的,则屏蔽掉共享选项 + if (fileInfo->canShare() && !VaultController::isVaultFile(fileInfo->toQFileInfo().canonicalFilePath())) { + titleList << shareManager; + } + if (!fileInfo->isVirtualEntry() && !m_url.isTrashFile() && fileInfo->canManageAuth() && + !VaultController::ins()->isRootDirectory(m_url.toLocalFile())) { + //在回收站搜索文件,需要使搜索结果的文件属性面板与回收站文件属性面板保持一致 + if (m_url.isSearchFile()) { + if (!fileInfo->redirectedFileUrl().isTrashFile()) { + titleList << authManager; + } + } else { + titleList << authManager; + } + } + } + m_expandGroup = addExpandWidget(titleList); + m_expandGroup.at(0)->setContent(m_basicInfoFrame); + + if (fileInfo->isDir()) { + if (fileInfo->canShare()) { + m_shareinfoFrame = createShareInfoFrame(fileInfo); + m_expandGroup.at(1)->setContent(m_shareinfoFrame); + m_expandGroup.at(1)->setExpand(false); + } + + if (fileInfo->toLocalFile().isEmpty()) { + startComputerFolderSize(m_url); + } else if (fileInfo->isSymLink()) { + startComputerFolderSize(fileInfo->redirectedFileUrl()); + } else { + startComputerFolderSize(DUrl::fromLocalFile(fileInfo->toLocalFile())); + } + + m_fileCount = fileInfo->filesCount(); + } else { + m_fileCount = 1; + m_size = fileInfo->size(); + + int openWithIndex = titleList.indexOf(openWith); + if (openWithIndex != -1) { + m_OpenWithListWidget = createOpenWithListWidget(fileInfo); + m_expandGroup.at(openWithIndex)->setContent(m_OpenWithListWidget); + m_expandGroup.at(openWithIndex)->setExpand(false); + } + } + + int authMgrIndex = titleList.indexOf(authManager); + if (authMgrIndex != -1) { + m_authorityManagementFrame = createAuthorityManagementWidget(fileInfo); + m_expandGroup.at(authMgrIndex)->setContent(m_authorityManagementFrame); + m_expandGroup.at(authMgrIndex)->setExpand(false); + } + } + initTextShowFrame(m_edit->toPlainText()); + if (m_editDisbaled) { + m_editButton->hide(); + } + + loadPluginExpandWidgets(); + + m_expandGroup.first()->setExpand(true); + + initConnect(); +} + +void PropertyDialog::initUI() +{ + m_icon->setFixedHeight(128); + m_icon->setParent(this); + QFrame *m_editFrame = new QFrame; + + QHBoxLayout *editLayout = new QHBoxLayout; + editLayout->addStretch(); + editLayout->addWidget(m_edit); + editLayout->addStretch(); + editLayout->setSpacing(0); + editLayout->setContentsMargins(0, 0, 0, 0); + m_editFrame->setLayout(editLayout); + m_edit->setParent(m_editFrame); + + m_editStackWidget = new QStackedWidget(this); + m_editStackWidget->addWidget(m_editFrame); + + m_mainLayout = new QVBoxLayout; + + m_mainLayout->setContentsMargins(0, 0, 0, 0); + m_mainLayout->setMargin(0); + m_mainLayout->setSpacing(0); + m_mainLayout->addWidget(m_icon, 0, Qt::AlignHCenter | Qt::AlignTop); + m_mainLayout->addWidget(m_editStackWidget, 0, Qt::AlignHCenter | Qt::AlignTop); + + QFrame *frame = new QFrame(this); + frame->setLayout(m_mainLayout); + addContent(frame); + + m_scrollArea = new QScrollArea(); + m_scrollArea->setObjectName("PropertyDialog-QScrollArea"); + QPalette palette = m_scrollArea->viewport()->palette(); + palette.setBrush(QPalette::Background, Qt::NoBrush); + m_scrollArea->viewport()->setPalette(palette); + m_scrollArea->setFrameShape(QFrame::Shape::NoFrame); + QFrame *infoframe = new QFrame; + QVBoxLayout *scrollWidgetLayout = new QVBoxLayout; + // 修复BUG-47113 UI显示不对 + scrollWidgetLayout->setContentsMargins(10, 0, 10, 20); + scrollWidgetLayout->setSpacing(ArrowLineExpand_SPACING); + infoframe->setLayout(scrollWidgetLayout); + m_scrollArea->setWidget(infoframe); + m_scrollArea->setWidgetResizable(true); + m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff); + + QVBoxLayout *scrolllayout = new QVBoxLayout; + scrolllayout->addWidget(m_scrollArea); + QVBoxLayout *layout = qobject_cast(this->layout()); + layout->addLayout(scrolllayout, 1); + + QFrame *tagFrame = initTagFrame(m_url); + if (tagFrame != nullptr) { + scrollWidgetLayout->addWidget(tagFrame); + } + + setFixedWidth(350); +} + +QFrame *PropertyDialog::initTagFrame(const DUrl &url) +{ + if (m_tagInfoFrame != nullptr) { + ((DFMTagWidget *)m_tagInfoFrame)->loadTags(url); + return m_tagInfoFrame; + } + + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(this, url); + DUrl t_url = url; + //! 保险箱中属性窗口中要获取标记需要真实路径,需要将虚拟路径转换为真实路径 + if (url.isVaultFile()) { + t_url = VaultController::vaultToLocalUrl(url); + } + if (fileInfo && fileInfo->canTag()) { + DFMTagWidget *tagInfoFrame = new DFMTagWidget(t_url, this); + new DFMRoundBackground(tagInfoFrame, 8); + m_tagInfoFrame = tagInfoFrame; + + QFont font = tagInfoFrame->tagTitle()->font(); + font.setBold(true); + font.setPixelSize(17); + tagInfoFrame->tagTitle()->setFont(font); + m_tagInfoFrame->setMaximumHeight(150); + + qDebug() << "tag frame is created for: " << t_url; + + return m_tagInfoFrame; + } + + return nullptr; +} + +void PropertyDialog::updateInfo() +{ + initTagFrame(m_url); +} + +const DUrl PropertyDialog::getRealUrl() +{ + if (m_url.isRecentFile()) { + return DUrl::fromLocalFile(m_url.path()); + } + + return m_url; +} + +bool PropertyDialog::canChmod(const DAbstractFileInfoPointer &info) +{ + bool ret = true; + + if (info->scheme() == BURN_SCHEME || info->isGvfsMountFile()) + ret = false; + + if (!info->canRename() || !info->canManageAuth()) + ret = false; + + QString path = info->filePath(); + static QRegularExpression regExp("^/run/user/\\d+/gvfs/.+$", + QRegularExpression::DotMatchesEverythingOption + | QRegularExpression::DontCaptureOption + | QRegularExpression::OptimizeOnFirstUsageOption); + if (regExp.match(path, 0, QRegularExpression::NormalMatch, QRegularExpression::DontCheckSubjectStringMatchOption).hasMatch()) + ret = false; + + return ret; +} + +void PropertyDialog::initConnect() +{ + connect(m_edit, &NameTextEdit::editFinished, this, &PropertyDialog::showTextShowFrame); + connect(m_edit, &NameTextEdit::textChanged, this, [this]() { + QString text = m_edit->toPlainText(); + const QString old_text = text; + + text = DFMGlobal::preprocessingFileName(text); + if (text.count() != old_text.count()) { + m_edit->setPlainText(text); + } + }); + + DAbstractFileWatcher *fileWatcher = DFileService::instance()->createFileWatcher(this, m_url, this); + + connect(fileWatcher, &DAbstractFileWatcher::fileDeleted, this, &PropertyDialog::onChildrenRemoved); + connect(fileWatcher, &DAbstractFileWatcher::fileMoved, this, [this](const DUrl & from, const DUrl & to) { + Q_UNUSED(to) + + onChildrenRemoved(from); + }); +} + + +void PropertyDialog::updateFolderSize(qint64 size) +{ + m_size = size; + if(m_sizeWorker) + m_fileCount = m_sizeWorker->filesCount() + m_sizeWorker->directorysCount(false); + m_folderSizeLabel->setText(FileUtils::formatSize(size)); + m_containSizeLabel->setText(QString::number(m_fileCount)); +} + +void PropertyDialog::renameFile() +{ + bool donotShowSuffix{ DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowedFileSuffixOnRename).toBool() }; + + const DAbstractFileInfoPointer &fileInfo = fileService->createFileInfo(this, m_url); + + QString fileName; + if (donotShowSuffix && + fileInfo->isFile() && + !fileInfo->suffix().isEmpty() && !fileInfo->isDesktopFile()) { + fileName = fileInfo->baseNameOfRename(); + } else { + fileName = fileInfo->fileNameOfRename(); + } + + m_edit->setPlainText(fileName); + m_editStackWidget->setCurrentIndex(0); + m_edit->setFixedHeight(m_textShowFrame->height()); + m_edit->setFocus(); + + int endPos = -1; + if (fileInfo->isFile()) { + + QString suffixStr{ fileInfo->suffix() }; + if (suffixStr.isEmpty() || donotShowSuffix || fileInfo->isDesktopFile()) { + endPos = m_edit->toPlainText().length(); + } else if (m_edit->toPlainText().endsWith(suffixStr)) { + endPos = m_edit->toPlainText().length() - fileInfo->suffix().length() - 1; + } + } + if (endPos == -1) { + m_edit->selectAll(); + endPos = m_edit->toPlainText().length(); + } + QTextCursor cursor = m_edit->textCursor(); + cursor.setPosition(0); + cursor.setPosition(endPos, QTextCursor::KeepAnchor); + m_edit->setTextCursor(cursor); +} + +void PropertyDialog::showTextShowFrame() +{ + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(this, m_url); + + bool donotShowSuffix{ DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowedFileSuffixOnRename).toBool() }; + + QString newName = m_edit->toPlainText(); + + if (newName.trimmed().isEmpty()) { + m_edit->setIsCanceled(true); + } + + if (donotShowSuffix && fileInfo->isFile() && + !fileInfo->suffix().isEmpty() && !fileInfo->isDesktopFile()) { + newName += "." + fileInfo->suffix(); + } + + if (m_edit->isCanceled()) { + initTextShowFrame(fileInfo->fileDisplayName()); + } else { + DUrl oldUrl = m_url; + DUrl newUrl = fileInfo->getUrlByNewFileName(newName); + + if (oldUrl == newUrl) { + m_editStackWidget->setCurrentIndex(1); + return; + } + + if (fileService->renameFile(this, oldUrl, newUrl)) { + if (!fileInfo->isDesktopFile()) { // this is a dirty fix. + m_url = newUrl; + updateInfo();//bug 25419 + onHideFileCheckboxChecked(false); //bug 29958 + if (m_basicInfoFrame) { //bug 29961 + QCheckBox *hideThisFile = m_basicInfoFrame->findChild(QString("hideThisFileCheckBox")); + if (hideThisFile) { + hideThisFile->setChecked(false); + } + } + + dialogManager->refreshPropertyDialogs(oldUrl, newUrl); + } + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, m_url); + + initTextShowFrame(info->fileDisplayName()); + + if (m_shareinfoFrame) { + m_shareinfoFrame->setFileinfo(info); + } + } else { + m_editStackWidget->setCurrentIndex(1); + } + } +} + +void PropertyDialog::onChildrenRemoved(const DUrl &fileUrl) +{ + if (m_url.isUserShareFile()) { + return; + } + if (fileUrl == m_url) { + QTimer::singleShot(100, this, [ = ] { + this->close(); + }); + // close(); + } +} + +void PropertyDialog::flickFolderToSidebar(const DUrl &fileUrl) +{ + //! 只处理当前触发的对话框 + if (fileUrl.toLocalFile() != this->getUrl().toLocalFile()) { + return; + } + + DFileManagerWindow *window = qobject_cast(WindowManager::getWindowById(m_fmevent.windowId())); + if (!window) { + return; + } + + //when current window is minimized,cancle animation + if (window->windowState() == Qt::WindowMinimized) { + return; + } + + // we are actually using network group's center position as target position + // since it's used as a animation target position, a fuzzy result is okay. + DFMSideBar *sideBar = window->getLeftSideBar(); + QString groupName = DFMSideBar::groupName(DFMSideBar::GroupName::Network); + sideBar->scrollToGroup(groupName); + QPoint targetPos = sideBar->groupGeometry(groupName).center(); + + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(this, m_url); + + //QLabel *aniLabel = new QLabel(window); + m_aniLabel = new QLabel(window); + m_aniLabel->raise(); + m_aniLabel->setFixedSize(m_icon->size()); + m_aniLabel->setAttribute(Qt::WA_TranslucentBackground); + m_aniLabel->setPixmap(fileInfo->fileIcon().pixmap(160, 160)); + m_aniLabel->move(window->mapFromGlobal(m_icon->mapToGlobal(m_icon->pos()))); + + int angle; + if (targetPos.x() > m_aniLabel->x()) { + angle = 45; + } else { + angle = -45; + } + + // QVariantAnimation *xani = new QVariantAnimation(this); + m_xani = new QVariantAnimation(this); + m_xani->setStartValue(m_aniLabel->pos()); + m_xani->setEndValue(QPoint(targetPos.x(), angle)); + if (DFMGlobal::isWayLand()) { + m_xani->setDuration(700); + } else { + m_xani->setDuration(440); + } + + //QVariantAnimation *gani = new QVariantAnimation(this); + m_gani = new QVariantAnimation(this); + m_gani->setStartValue(m_aniLabel->geometry()); + m_gani->setEndValue(QRect(targetPos.x(), targetPos.y(), 20, 20)); + m_gani->setEasingCurve(QEasingCurve::InBack); + if (DFMGlobal::isWayLand()) { + m_gani->setDuration(700); + } else { + m_gani->setDuration(440); + } + + connect(m_xani, &QVariantAnimation::valueChanged, [ = ](const QVariant & val) { + if (m_aniLabel) { + m_aniLabel->move(QPoint(val.toPoint().x() - m_aniLabel->width() / 2, m_aniLabel->y())); + QImage img = fileInfo->fileIcon().pixmap(m_aniLabel->size()).toImage(); + QMatrix ma; + ma.rotate(val.toPoint().y()); + img = img.transformed(ma, Qt::SmoothTransformation); + img = img.scaled(m_aniLabel->width() / 2, m_aniLabel->height() / 2, Qt::KeepAspectRatio, Qt::SmoothTransformation); + m_aniLabel->setPixmap(QPixmap::fromImage(img)); + if (m_aniLabel->isHidden()) { + m_aniLabel->show(); + } + } + }); + connect(m_xani, &QVariantAnimation::finished, [ = ] { + m_xani->deleteLater(); + }); + + connect(m_gani, &QVariantAnimation::valueChanged, [ = ](const QVariant & val) { + m_aniLabel->move(QPoint(m_aniLabel->x(), + val.toRect().y() - val.toRect().width() / 2)); + m_aniLabel->setFixedSize(val.toRect().size() * 2); + }); + connect(m_gani, &QVariantAnimation::finished, [ = ] { + m_gani->deleteLater(); + m_aniLabel->deleteLater(); + }); + m_xani->start(); + m_gani->start(); +} +void PropertyDialog::onOpenWithBntsChecked(QAbstractButton *w) +{ + if (w) { + MimesAppsManager::setDefautlAppForTypeByGio(w->property("mimeTypeName").toString(), + w->property("appPath").toString()); + } +} + +void PropertyDialog::onHideFileCheckboxChecked(bool checked) +{ + DUrl url = getRealUrl(); + QFileInfo info(url.toLocalFile()); + if (!info.exists()) return; + + DFMFileListFile flf(info.absolutePath()); + const QString fileName = info.fileName(); + + //隐藏属性无变动,则不保存文件。task#40201 + bool save = false; + qDebug() << info.absolutePath(); + if (checked) { + if (!flf.contains(fileName)) { + flf.insert(fileName); + save = true; + } + } else { + if (flf.contains(fileName)) { + flf.remove(info.fileName()); + save = true; + } + } + + if (save) + flf.save(); +} + +void PropertyDialog::onCancelShare() +{ + if (m_xani.data()) { + m_xani->setDuration(0); + } + + if (m_gani.data()) { + m_gani->setDuration(0); + } +} + +void PropertyDialog::mousePressEvent(QMouseEvent *event) +{ + if (m_edit->isVisible()) { + if (event->button() != Qt::RightButton) { + m_edit->setIsCanceled(m_edit->toPlainText().isEmpty()); + emit m_edit->editFinished(); + } + } + DDialog::mousePressEvent(event); +} + +void PropertyDialog::startComputerFolderSize(const DUrl &url) +{ + DUrl validUrl = url; + if (url.isUserShareFile()) { + validUrl.setScheme(FILE_SCHEME); + } + DUrlList urls; + urls << validUrl; + + if (!m_sizeWorker) + m_sizeWorker = new DFileStatisticsJob(this); + + connect(m_sizeWorker, &DFileStatisticsJob::dataNotify, this, &PropertyDialog::updateFolderSize); + m_sizeWorker->start(urls); +} + +void PropertyDialog::toggleFileExecutable(bool isChecked) +{ + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(this, m_url); + if (isChecked) { + DFileService::instance()->setPermissions(this, getRealUrl(), info->permissions() | QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther); + } else { + DFileService::instance()->setPermissions(this, getRealUrl(), info->permissions() & ~(QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther)); + } +} + +DUrl PropertyDialog::getUrl() +{ + return m_url; +} + +int PropertyDialog::getFileCount() +{ + return m_fileCount; +} + +qint64 PropertyDialog::getFileSize() +{ + return m_size; +} + +void PropertyDialog::raise() +{ + DDialog::raise(); + emit raised(); +} + +void PropertyDialog::hideEvent(QHideEvent *event) +{ + if (m_xani) { + m_xani->stop(); + delete m_xani; + } + if (m_gani) { + m_gani->stop(); + delete m_gani; + } + if (m_aniLabel) + delete m_aniLabel; + emit aboutToClosed(m_url); + DDialog::hideEvent(event); + emit closed(m_url); + if (m_sizeWorker) { + m_sizeWorker->stop(); + } +} + +void PropertyDialog::resizeEvent(QResizeEvent *event) +{ + DDialog::resizeEvent(event); +} + +const QList &PropertyDialog::expandGroup() const +{ + return m_expandGroup; +} + +int PropertyDialog::contentHeight() const +{ + int expandsHeight = ArrowLineExpand_SPACING; + for (const DDrawer *expand : m_expandGroup) { + if (m_shareinfoFrame && m_shareinfoFrame->isHidden()) { + m_shareinfoFrame->show(); + } + expandsHeight += expand->height(); + } +#define DIALOG_TITLEBAR_HEIGHT 50 + return (DIALOG_TITLEBAR_HEIGHT + + m_icon->height() + + m_editStackWidget->height() + + expandsHeight + + contentsMargins().top() + + contentsMargins().bottom() + + (m_wdf ? m_wdf->height() : 0) + + (m_tagInfoFrame ? m_tagInfoFrame->height() : 0) + + 40); +} + +int PropertyDialog::getDialogHeight() const +{ + int totalHeight = this->size().height() + contentHeight() ; + totalHeight += std::accumulate(m_expandGroup.begin(), m_expandGroup.end(), 0, [](int total, const DDrawer * expand) { + if (expand->expand()) + return total += expand->window()->height(); + return total; + }); + + return totalHeight; +} + +void PropertyDialog::loadPluginExpandWidgets() +{ + //QVBoxLayout *layout = qobject_cast(this->layout()); + QVBoxLayout *layout = qobject_cast(m_scrollArea->widget()->layout()); + QList plugins = PluginManager::instance()->getExpandInfoInterfaces(); + foreach (PropertyDialogExpandInfoInterface *plugin, plugins) { + DArrowLineDrawer *expand = new DArrowLineDrawer;//DArrowLineExpand; + QWidget *frame = plugin->expandWidget(m_url.toString()); + if (!frame) { + expand->deleteLater(); + continue; + } + frame->setMaximumHeight(EXTEND_FRAME_MAXHEIGHT); + frame->setParent(this); + expand->setTitle(plugin->expandWidgetTitle(m_url.toString())); + expand->setExpand(false); + expand->setContent(frame); + + initExpand(layout, expand); + m_expandGroup.push_back(expand); + } + layout->addStretch(); +} + +void PropertyDialog::initExpand(QVBoxLayout *layout, DDrawer *expand) +{ + expand->setFixedHeight(ArrowLineExpand_HIGHT); + QMargins cm = layout->contentsMargins(); + QRect rc = contentsRect(); + expand->setFixedWidth(rc.width() - cm.left() - cm.right()); + expand->setExpandedSeparatorVisible(false); + expand->setSeparatorVisible(false); + layout->addWidget(expand, 0, Qt::AlignTop); + + DEnhancedWidget *hanceedWidget = new DEnhancedWidget(expand, expand); + connect(hanceedWidget, &DEnhancedWidget::heightChanged, hanceedWidget, [ = ]() { + QRect rect = geometry(); + rect.setHeight(contentHeight() + ArrowLineExpand_SPACING * 2); + setGeometry(rect); + }); +} + +QList PropertyDialog::addExpandWidget(const QStringList &titleList) +{ + QVBoxLayout *layout = qobject_cast(m_scrollArea->widget()->layout()); + QList group; + + for (const QString &title : titleList) { + DArrowLineDrawer *expand = new DArrowLineDrawer;//DArrowLineExpand; + expand->setTitle(title); + initExpand(layout, expand); + group.push_back(expand); + } + + return group; +} + +void PropertyDialog::initTextShowFrame(const QString &text) +{ + m_textShowFrame = new QFrame(this); + + m_editButton = new DIconButton(m_textShowFrame); + m_editButton->setObjectName("EditButton"); + m_editButton->setIcon(QIcon::fromTheme("edit-rename")); + m_editButton->setIconSize({24, 24}); + m_editButton->setFixedSize(24, 24); + m_editButton->setFlat(true); + connect(m_editButton, &QPushButton::clicked, this, &PropertyDialog::renameFile); + + QString t = DFMGlobal::elideText(text, m_edit->size(), QTextOption::WrapAtWordBoundaryOrAnywhere, m_edit->font(), Qt::ElideMiddle, 0); + QStringList labelTexts = t.split("\n"); + const int maxLineCount = 3; + + int textHeight = 0; + QVBoxLayout *textShowLayout = new QVBoxLayout; + + for (int i = 0; i < labelTexts.length(); i++) { + if (i > (maxLineCount - 1)) { + break; + } + QString labelText = labelTexts.at(i); + QLabel *label = new QLabel(labelText, m_textShowFrame); + label->setAlignment(Qt::AlignHCenter); + QHBoxLayout *hLayout = new QHBoxLayout; + + textHeight += label->fontInfo().pixelSize() + 10; + + hLayout->addStretch(1); + hLayout->addWidget(label); + if (i < (labelTexts.length() - 1) && i != (maxLineCount - 1)) { + if (label->fontMetrics().width(labelText) > (m_edit->width() - 10)) { + label->setFixedWidth(m_edit->width()); + } + } else { + // the final line of file name label, with a edit btn. + if (labelTexts.length() >= maxLineCount) { + for (int idx = i + 1; idx < labelTexts.length(); idx++) { + labelText += labelTexts.at(idx); + } + } + + if (label->fontMetrics().width(labelText) > (m_edit->width() - 2 * m_editButton->width()) && labelTexts.length() >= maxLineCount) { + labelText = label->fontMetrics().elidedText(labelText, Qt::ElideMiddle, m_edit->width() - m_editButton->width()); + } + label->setText(labelText); + hLayout->addSpacing(2); + hLayout->addWidget(m_editButton); + } + textShowLayout->addLayout(hLayout); + hLayout->addStretch(1); + } + + textShowLayout->setContentsMargins(0, 0, 0, 0); + textShowLayout->setSpacing(0); + m_textShowFrame->setLayout(textShowLayout); + textShowLayout->addStretch(1); + + m_textShowFrame->setFixedHeight(textHeight + 15); + + if (m_editStackWidget->count() == 1) { + m_editStackWidget->addWidget(m_textShowFrame); + } else { + m_editStackWidget->insertWidget(1, m_textShowFrame); + } + m_editStackWidget->setCurrentIndex(1); + m_editStackWidget->setFixedHeight(m_textShowFrame->height()); +} + +QFrame *PropertyDialog::createBasicInfoWidget(const DAbstractFileInfoPointer &info) +{ + QFrame *widget = new QFrame(this); + SectionKeyLabel *sizeSectionLabel = new SectionKeyLabel(QObject::tr("Size"), widget); + SectionKeyLabel *typeSectionLabel = new SectionKeyLabel(QObject::tr("Type"), widget); + SectionKeyLabel *TimeCreatedSectionLabel = new SectionKeyLabel(QObject::tr("Time created"), widget); + SectionKeyLabel *TimeReadSectionLabel = new SectionKeyLabel(QObject::tr("Time accessed"), widget); + SectionKeyLabel *TimeModifiedSectionLabel = new SectionKeyLabel(QObject::tr("Time modified"), widget); + SectionKeyLabel *sourcePathSectionLabel = new SectionKeyLabel(QObject::tr("Source path"), nullptr); + + m_containSizeLabel = new SectionValueLabel(info->sizeDisplayName()); + m_folderSizeLabel = new SectionValueLabel("", widget); + SectionValueLabel *typeLabel = new SectionValueLabel(info->mimeTypeDisplayName()); + SectionValueLabel *timeCreatedLabel = nullptr; + SectionValueLabel *timeReadLabel = nullptr; + SectionValueLabel *timeModifiedLabel = nullptr; + if(VaultController::isRootDirectory(info->fileUrl().toLocalFile())){ + TimeModifiedSectionLabel->setText(QObject::tr("Time locked")); + //! 保险箱根目录创建、访问、修改时间的读取 + DFM_NAMESPACE::DFMSettings setting(VAULT_TIME_CONFIG_FILE); + timeCreatedLabel = new SectionValueLabel(setting.value(QString("VaultTime"), QString("CreateTime")).toString()); + timeReadLabel = new SectionValueLabel(setting.value(QString("VaultTime"), QString("InterviewTime")).toString()); + if(setting.value(QString("VaultTime"), QString("LockTime")).toString().isEmpty()) + timeModifiedLabel = new SectionValueLabel(setting.value(QString("VaultTime"), QString("InterviewTime")).toString()); + else + timeModifiedLabel = new SectionValueLabel(setting.value(QString("VaultTime"), QString("LockTime")).toString()); + } + else{ + TimeModifiedSectionLabel->setText(QObject::tr("Time modified")); + timeCreatedLabel = new SectionValueLabel(info->createdDisplayName()); + timeReadLabel = new SectionValueLabel(info->lastReadDisplayName()); + timeModifiedLabel = new SectionValueLabel(info->lastModifiedDisplayName()); + } + + DFMGlobal::setToolTip(TimeCreatedSectionLabel); + DFMGlobal::setToolTip(TimeReadSectionLabel); + DFMGlobal::setToolTip(TimeModifiedSectionLabel); + DFMGlobal::setToolTip(sourcePathSectionLabel); + + QFormLayout *layout = new QFormLayout; + layout->setHorizontalSpacing(12); + layout->setVerticalSpacing(16); + layout->setLabelAlignment(Qt::AlignRight); + + if (info->isDir()) { + SectionKeyLabel *fileAmountSectionLabel = new SectionKeyLabel(QObject::tr("Contains")); + layout->addRow(sizeSectionLabel, m_folderSizeLabel); + layout->addRow(fileAmountSectionLabel, m_containSizeLabel); + } else { + layout->addRow(sizeSectionLabel, m_containSizeLabel); + } + + if (!info->isVirtualEntry()) { + layout->addRow(typeSectionLabel, typeLabel); + } + + SectionKeyLabel *linkPathSectionLabel = new SectionKeyLabel(QObject::tr("Location")); + QLabel *locationPathLabel = nullptr; + if (info->isSymLink()) { + LinkSectionValueLabel *linkPathLabel = new LinkSectionValueLabel(info->symlinkTargetPath()); + linkPathLabel->setToolTip(info->symlinkTargetPath()); + linkPathLabel->setLinkTargetUrl(info->redirectedFileUrl()); + linkPathLabel->setOpenExternalLinks(true); + linkPathLabel->setWordWrap(false); + QString t = linkPathLabel->fontMetrics().elidedText(info->symlinkTargetPath(), Qt::ElideMiddle, 150); + linkPathLabel->setText(t); + locationPathLabel = linkPathLabel; + } else { + locationPathLabel = new SectionValueLabel(); + QString absoluteFilePath = info->absoluteFilePath(); + //! 在属性窗口中不显示保险箱中的文件真实路径 + if (info->fileUrl().isVaultFile()) { + absoluteFilePath = VaultController::pathToVirtualPath(absoluteFilePath); + } + locationPathLabel->setText(absoluteFilePath); + locationPathLabel->setToolTip(absoluteFilePath); + QString t = locationPathLabel->fontMetrics().elidedText(absoluteFilePath, Qt::ElideMiddle, 150); + locationPathLabel->setWordWrap(false); + locationPathLabel->setText(t); + } + + layout->addRow(linkPathSectionLabel, locationPathLabel); + if (!info->isVirtualEntry()) { + layout->addRow(TimeCreatedSectionLabel, timeCreatedLabel); + layout->addRow(TimeReadSectionLabel, timeReadLabel); + layout->addRow(TimeModifiedSectionLabel, timeModifiedLabel); + } + + //在回收站搜索文件,需要使搜索结果的文件属性面板与回收站文件属性面板保持一致 + QString trashSourcePath = ""; + if (info->fileUrl().isSearchFile() && info->redirectedFileUrl().isTrashFile()) { + const DAbstractFileInfoPointer &trashfileInfo = DFileService::instance()->createFileInfo(this, info->redirectedFileUrl()); + trashSourcePath = static_cast(trashfileInfo.constData())->sourceFilePath(); + } + + if (info->fileUrl().isTrashFile()) { + trashSourcePath = static_cast(info.constData())->sourceFilePath(); + } + + //添加回收站文件原始路径 + if (!trashSourcePath.isEmpty()) { + SectionValueLabel *sourcePathLabel = new SectionValueLabel(trashSourcePath); + QString elidedStr = sourcePathLabel->fontMetrics().elidedText(trashSourcePath, Qt::ElideMiddle, 150); + sourcePathLabel->setToolTip(trashSourcePath); + sourcePathLabel->setWordWrap(false); + sourcePathLabel->setText(elidedStr); + sourcePathSectionLabel->setParent(widget); + layout->addRow(sourcePathSectionLabel, sourcePathLabel); + } + + if (info->fileUrl().isRecentFile()) { + QString pathStr = info->filePath(); + SectionValueLabel *sourcePathLabel = new SectionValueLabel(pathStr); + QString elidedStr = sourcePathLabel->fontMetrics().elidedText(pathStr, Qt::ElideMiddle, 150); + sourcePathLabel->setToolTip(pathStr); + sourcePathLabel->setWordWrap(false); + sourcePathLabel->setText(elidedStr); + sourcePathSectionLabel->setParent(widget); + layout->addRow(sourcePathSectionLabel, sourcePathLabel); + } + + if (!sourcePathSectionLabel->parent()) { + delete sourcePathSectionLabel; + } + + DGioSettings gsettings("com.deepin.dde.filemanager.general", "/com/deepin/dde/filemanager/general/"); + + if (gsettings.value("property-dlg-hidefile-checkbox").toBool() && DFMFileListFile::supportHideByFile(info->filePath()) + && !VaultController::ins()->isRootDirectory(info->filePath())) { + DFMFileListFile flf(QFileInfo(info->filePath()).absolutePath()); + QString fileName = info->fileName(); + QCheckBox *hideThisFile = new QCheckBox(info->isDir() ? tr("Hide this folder") : tr("Hide this file")); + hideThisFile->setObjectName(QString("hideThisFileCheckBox")); + // hideThisFile->setToolTip("TODO: hint message?"); + + //在回收站搜索文件,需要使搜索结果的文件属性面板与回收站文件属性面板保持一致 + bool canHide = false; + if (DFMFileListFile::canHideByFile(info->filePath()) && !info->fileUrl().isTrashFile()) { // fix bug#33763 回收站中不允许对文件属性进行编辑 + canHide = true; + if (info->fileUrl().isSearchFile()) { + DUrl url = info->redirectedFileUrl(); + if (url.isTrashFile()) + canHide = false; + } + } + + hideThisFile->setEnabled(canHide); + hideThisFile->setChecked(flf.contains(fileName)); + layout->addWidget(hideThisFile); // FIXME: do the UI thing later. + connect(hideThisFile, &QCheckBox::clicked, this, &PropertyDialog::onHideFileCheckboxChecked); + } + + layout->setContentsMargins(15, 15, 30, 15); + widget->setLayout(layout); + + return widget; +} + +ShareInfoFrame *PropertyDialog::createShareInfoFrame(const DAbstractFileInfoPointer &info) +{ + DAbstractFileInfoPointer infoPtr = info->canRedirectionFileUrl() ? DFileService::instance()->createFileInfo(nullptr, info->redirectedFileUrl()) + : info; + ShareInfoFrame *frame = new ShareInfoFrame(infoPtr, this); + //play animation after a folder is shared + // 侧边栏创建完成共享标签后再执行动画 + DFileManagerWindow *window = qobject_cast(WindowManager::getWindowById(m_fmevent.windowId())); + if (window) { + DFMSideBar *sideBar = window->getLeftSideBar(); + connect(sideBar, &DFMSideBar::addUserShareItemFinished, this, &PropertyDialog::flickFolderToSidebar); + } + + if (DFMGlobal::isWayLand()) { + // 取消共享时停止动画效果 + connect(frame, &ShareInfoFrame::unfolderShared, this, &PropertyDialog::onCancelShare); + } + + return frame; +} + +QList > PropertyDialog::createLocalDeviceInfoWidget(const DAbstractFileInfoPointer &info) +{ + QList > results; + + if (!info) { + qWarning("BUG: cannot create local device info because given device info pointer is not valid"); + return results; + } + + QString fsType = info->extraProperties()["fsType"].toString(); + quint64 fsUsed = info->extraProperties()["fsUsed"].toULongLong(); + quint64 fsFreeSize = info->extraProperties()["fsFreeSize"].toULongLong(); + quint64 fsSize = info->extraProperties()["fsSize"].toULongLong(); + //fixed:CD display size error + if (static_cast(info->fileType()) == DFMRootFileInfo::ItemType::UDisksOptical) { + DFMRootFileInfo *pFileInfo = dynamic_cast(info.data()); + QString strVolTag; + if (pFileInfo) + strVolTag = pFileInfo->getVolTag(); + fsSize = DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].nTotal; + fsFreeSize = fsSize - DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].nUsage; + } + quint64 fileCount = 0; + DUrl redirectedFileUrl = info->redirectedFileUrl(); + if (!redirectedFileUrl.isEmpty()) { + if (redirectedFileUrl.burnIsOnDisc()) { + if (!redirectedFileUrl.burnDestDevice().isEmpty()) { + DUrl stagingUrl = DUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + + "/" + qApp->organizationName() + "/" DISCBURN_STAGING "/" + + redirectedFileUrl.burnDestDevice().replace('/', '_')); + QString stagingFilePath = stagingUrl.toLocalFile(); + if (!stagingFilePath.isEmpty()) { + fileCount = FileUtils::filesCount(stagingFilePath); + } + } + + DAbstractFileInfoPointer fi = fileService->createFileInfo(this, redirectedFileUrl); + DUrl url = DUrl::fromLocalFile(fi->extraProperties()["mm_backer"].toString()); + redirectedFileUrl = url; + } + + QString localFilePath = redirectedFileUrl.toLocalFile(); + if (!localFilePath.isEmpty()) { + fileCount += FileUtils::filesCount(localFilePath); + } + } + + static QHash devtypemap = { + {DFMRootFileInfo::ItemType::UDisksRoot, QObject::tr("Local disk")}, + {DFMRootFileInfo::ItemType::UDisksData, QObject::tr("Local disk")}, + {DFMRootFileInfo::ItemType::UDisksFixed, QObject::tr("Local disk")}, + {DFMRootFileInfo::ItemType::UDisksRemovable, QObject::tr("Removable disk")}, + {DFMRootFileInfo::ItemType::UDisksOptical, QObject::tr("DVD")}, + {DFMRootFileInfo::ItemType::GvfsFTP, QObject::tr("Network shared directory")}, + {DFMRootFileInfo::ItemType::GvfsSMB, QObject::tr("Network shared directory")}, + {DFMRootFileInfo::ItemType::GvfsMTP, QObject::tr("Android mobile device")}, + {DFMRootFileInfo::ItemType::GvfsGPhoto2, QObject::tr("Apple mobile device")}, + {DFMRootFileInfo::ItemType::GvfsCamera, QObject::tr("Camera")}, + {DFMRootFileInfo::ItemType::NotConnRemote, QObject::tr("Unconnected network shared directory")} + }; + + //fix GvfsGPhoto2协议对Apple mobile device判断有问题,再增加一层判断 + { + auto itemtype = static_cast(info->fileType()); + if (itemtype == DFMRootFileInfo::ItemType::GvfsGPhoto2) { + QString devicePath = info->redirectedFileUrl().path(); + + qInfo() << "Deivce Type: DFMRootFileInfo::ItemType::GvfsGPhoto2 Device Path:" << devicePath; + + //判断host中是否有"Apple_Inc",没有且不为空则改为安卓 + if (!devicePath.isEmpty() && !devicePath.contains("Apple_Inc")) { + qWarning() << "Deivce Type is DFMRootFileInfo::ItemType::GvfsGPhoto2. Not find Apple_Inc in device path" + << devicePath << "Set Deivce Type [GvfsGPhoto2] to [GvfsMTP]"; + itemtype = DFMRootFileInfo::ItemType::GvfsMTP; + } + } + results.append({QObject::tr("Device type"), devtypemap.value(itemtype, QObject::tr("Unknown device"))}); + } + //old + //results.append({QObject::tr("Device type"), devtypemap.value(static_cast(info->fileType()), QObject::tr("Unknown device"))}); + //end fix + + //fixed:CD display size error + if (static_cast(info->fileType()) == DFMRootFileInfo::ItemType::UDisksOptical) { + DFMRootFileInfo *pFileInfo = dynamic_cast(info.data()); + QString strVolTag; + if (pFileInfo) + strVolTag = pFileInfo->getVolTag(); + fsSize = DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].nTotal; + fsUsed = DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].nUsage; + } + + results.append({QObject::tr("Total space"), FileUtils::formatSize(fsSize)}); + if (!fsType.isEmpty()) { + results.append({QObject::tr("File system"), fsType}); + } + results.append({QObject::tr("Contains"), (fileCount != 1 ? QObject::tr("%1 items") : QObject::tr("%1 item")).arg(fileCount)}); + + quint64 fsFreeSizeSet = fsFreeSize > 0 ? fsFreeSize : (fsSize - fsUsed); + results.append({QObject::tr("Free space"), FileUtils::formatSize(fsFreeSizeSet)}); + + return results; +} + +QFrame *PropertyDialog::createInfoFrame(const QList > &properties) +{ + QFrame *widget = new QFrame(this); + + QFormLayout *layout = new QFormLayout; + layout->setHorizontalSpacing(12); + layout->setVerticalSpacing(16); + layout->setLabelAlignment(Qt::AlignRight); + + for (const QPair &kv : properties) { + SectionKeyLabel *keyLabel = new SectionKeyLabel(kv.first, widget); + SectionValueLabel *valLabel = new SectionValueLabel(kv.second, widget); + layout->addRow(keyLabel, valLabel); + } + + widget->setLayout(layout); + //widget是最小高度时,藏语会发生截断,layout自适应,设置最小展示高度 + widget->setMinimumHeight(EXTEND_FRAME_MAXHEIGHT); + return widget; +} + +QListWidget *PropertyDialog::createOpenWithListWidget(const DAbstractFileInfoPointer &info) +{ + DUrl fileUrl = info->fileUrl(); + DAbstractFileInfoPointer infoPtr = info; + while (infoPtr->canRedirectionFileUrl()) { + if (fileUrl == infoPtr->redirectedFileUrl()) { + break; + } + fileUrl = infoPtr->redirectedFileUrl(); + infoPtr = fileService->createFileInfo(nullptr, fileUrl); + } + QListWidget *listWidget = new QListWidget(this); + listWidget->setSpacing(8); + listWidget->setObjectName("OpenWithListWidget"); + // 修复BUG-47113 UI显示问题 + listWidget->setFrameShape(QFrame::HLine); + m_OpenWithButtonGroup = new QButtonGroup(listWidget); + listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + QStringList recommendApps = mimeAppsManager->getRecommendedApps(fileUrl); + + QString mimeType = infoPtr->mimeType().name(); + QString defaultApp = mimeAppsManager->getDefaultAppDisplayNameByGio(mimeType); + + foreach (const QString &appFile, recommendApps) { + if (!QFile::exists(appFile)) { + continue; + } + DesktopFile df(appFile); + + QListWidgetItem *item = new QListWidgetItem; + + QCheckBox *itemBox = new QCheckBox(df.getDisplayName()); + itemBox->setObjectName("OpenWithItem"); + itemBox->setIcon(QIcon::fromTheme(df.getIcon())); + itemBox->setIconSize(QSize(16, 16)); + itemBox->setProperty("appPath", appFile); + itemBox->setProperty("mimeTypeName", mimeType); + m_OpenWithButtonGroup->addButton(itemBox); + item->setData(Qt::UserRole, df.getName()); + listWidget->addItem(item); + listWidget->setItemWidget(item, itemBox); + + if (df.getLocalName() == defaultApp) { + itemBox->setChecked(true); + } + + } + + int listHeight = 0; + int count = listWidget->count(); + for (int i = 0; i < count; i++) { + QListWidgetItem *item = listWidget->item(i); + item->setFlags(Qt::NoItemFlags); + int h = listWidget->itemWidget(item)->height(); + item->setSizeHint(QSize(item->sizeHint().width(), h)); + // 乘以2是因为item与item之间有两个spacing + listHeight += h + listWidget->spacing() * 2; + } + // 加上最后一个spacing + listHeight += listWidget->spacing(); + + // 修复UI-BUG-48789 自动设置listwidget的高度,使得根据内容延展其面板的长度 + if (count < 1) { + // 当没有打开方式时,设置一个固定大小 + listWidget->setFixedHeight(ArrowLineExpand_HIGHT); + } else { + listWidget->setFixedHeight(listHeight); + } + listWidget->setFixedWidth(300); + // 隐藏垂直滚动条 + listWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + connect(m_OpenWithButtonGroup, SIGNAL(buttonClicked(QAbstractButton *)), + this, SLOT(onOpenWithBntsChecked(QAbstractButton *))); + + return listWidget; +} + +QFrame *PropertyDialog::createAuthorityManagementWidget(const DAbstractFileInfoPointer &info) +{ + QFrame *widget = new QFrame; + QFormLayout *layout = new QFormLayout; + + QComboBox *ownerBox = new QComboBox; + QComboBox *groupBox = new QComboBox; + QComboBox *otherBox = new QComboBox; + + ownerBox->view()->parentWidget()->setAttribute(Qt::WA_TranslucentBackground); + groupBox->view()->parentWidget()->setAttribute(Qt::WA_TranslucentBackground); + otherBox->view()->parentWidget()->setAttribute(Qt::WA_TranslucentBackground); + + DUrl parentUrl = info->parentUrl(); + DStorageInfo storageInfo(parentUrl.toLocalFile()); + const QString &fsType = storageInfo.fileSystemType(); + // these are for file or folder, folder will with executable index. + int readWriteIndex = 0, readOnlyIndex = 0; + + int readOnlyFlag = 4; + int readOnlyWithXFlag = 5; + + int readWriteFlag = 6; + int readWriteWithXFlag = 7; + + QStringList authorityList; + + authorityList << QObject::tr("Access denied") // 0 + << QObject::tr("Executable") // 1 + << QObject::tr("Write only") // 2 + << QObject::tr("Write only") // 3 with x + << QObject::tr("Read only") // 4 + << QObject::tr("Read only") // 5 with x + << QObject::tr("Read-write") // 6 + << QObject::tr("Read-write"); // 7 with x + + static QStringList canChmodFileType = {"vfat", "fuseblk"}; + + if (info->isFile()) { + // append `Executable` string + QString append = QStringLiteral(" , ") + QObject::tr("Executable"); + authorityList[3] += append; + authorityList[5] += append; + authorityList[7] += append; + + // file: read is read, read-write is read-write + readOnlyIndex = readOnlyFlag; + readWriteIndex = readWriteFlag; + } + + if (info->isDir()) { + // folder: read is read and executable, read-write is read-write and executable + readOnlyIndex = readOnlyWithXFlag; + readWriteIndex = readWriteWithXFlag; + } + + // enumFlag should be 0~7, this is just a check to avoid runtime error + auto getPermissionString = [ &authorityList ](int enumFlag) { + enumFlag &= 0x0007; + if (enumFlag < 0 || enumFlag > 7) { + return QStringLiteral("..what?"); + } else { + return authorityList[enumFlag]; + } + }; + + // set QComboBox, notice this permission number is not just 0~7 + auto setComboBoxByPermission = [ = ](QComboBox * cb, int permission, int offset) { + int index = permission >> offset; + if (index == readWriteFlag || index == readWriteWithXFlag) { + cb->setCurrentIndex(0); + } else if (index == readOnlyFlag || index == readOnlyWithXFlag) { + cb->setCurrentIndex(1); + } else { + cb->addItem(getPermissionString(index), QVariant(permission)); + cb->setCurrentIndex(2); + } + }; + + // when change the index... + auto onComboBoxChanged = [ = ]() { + + // 保险箱文件权限特殊处理,不要修改文件权限,保证文件出保险箱和进保险箱权限一直 + if(VaultController::isVaultFile(info->fileUrl().toLocalFile())) + return; + + struct stat fileStat; + QByteArray infoBytes(info->toLocalFile().toUtf8()); + stat(infoBytes.data(), &fileStat); + auto preMode = fileStat.st_mode; + + int ownerFlags = ownerBox->currentData().toInt(); + int groupFlags = groupBox->currentData().toInt(); + int otherFlags = otherBox->currentData().toInt(); + + QFile::Permissions permissions = info->permissions(); + //点击combobox都需要保持执行权限,否则将失去相关权限位 + ownerFlags |= (permissions & QFile::ExeOwner); + groupFlags |= (permissions & QFile::ExeGroup); + otherFlags |= (permissions & QFile::ExeOther); + + DFileService::instance()->setPermissions(this, getRealUrl(), + QFileDevice::Permissions(ownerFlags) | + /*(info->permissions() & 0x0700) |*/ + QFileDevice::Permissions(groupFlags) | + QFileDevice::Permissions(otherFlags)); + infoBytes = info->toLocalFile().toUtf8(); + stat(infoBytes.data(), &fileStat); + auto afterMode = fileStat.st_mode; + // 修改权限失败 + // todo 回滚权限 + if (preMode == afterMode) { + qDebug() << "chmod failed"; + } + }; + + ownerBox->addItem(authorityList[readWriteIndex], QVariant(QFile::WriteOwner | QFile::ReadOwner)); + ownerBox->addItem(authorityList[readOnlyIndex], QVariant(QFile::ReadOwner)); + groupBox->addItem(authorityList[readWriteIndex], QVariant(QFile::WriteGroup | QFile::ReadGroup)); + groupBox->addItem(authorityList[readOnlyIndex], QVariant(QFile::ReadGroup)); + otherBox->addItem(authorityList[readWriteIndex], QVariant(QFile::WriteOther | QFile::ReadOther)); + otherBox->addItem(authorityList[readOnlyIndex], QVariant(QFile::ReadOther)); + + setComboBoxByPermission(ownerBox, info->permissions() & 0x7000, 12); + setComboBoxByPermission(groupBox, info->permissions() & 0x0070, 4); + setComboBoxByPermission(otherBox, info->permissions() & 0x0007, 0); + + layout->setLabelAlignment(Qt::AlignLeft); + layout->addRow(QObject::tr("Owner"), ownerBox); + layout->addRow(QObject::tr("Group"), groupBox); + layout->addRow(QObject::tr("Others"), otherBox); + + if (info->isFile()) { + m_executableCheckBox = new QCheckBox; + m_executableCheckBox->setText(tr("Allow to execute as program")); + connect(m_executableCheckBox, &QCheckBox::toggled, this, &PropertyDialog::toggleFileExecutable); + if (info->ownerId() != getuid()) { + m_executableCheckBox->setDisabled(true); + } + + QString filePath = info->path(); + if (VaultController::ins()->isVaultFile(info->path())) { // Vault file need to use stat function to read file permission. + QString localFile = info->toLocalFile(); + struct stat buf; + std::string stdStr = localFile.toStdString(); + stat(stdStr.c_str(), &buf); + if ((buf.st_mode & S_IXUSR) || (buf.st_mode & S_IXGRP) || (buf.st_mode & S_IXOTH)) { + m_executableCheckBox->setChecked(true); + } + } else { + if (info->permission(QFile::ExeUser) || info->permission(QFile::ExeGroup) || info->permission(QFile::ExeOther)) { + m_executableCheckBox->setChecked(true); + } + } + // 一些文件系统不支持修改可执行权限 + if (!canChmod(info) || canChmodFileType.contains(fsType)) { + m_executableCheckBox->setDisabled(true); + } + layout->addRow(m_executableCheckBox); + } + + + layout->setContentsMargins(15, 10, 30, 10); + widget->setLayout(layout); + + connect(ownerBox, static_cast(&QComboBox::currentIndexChanged), widget, onComboBoxChanged); + connect(groupBox, static_cast(&QComboBox::currentIndexChanged), widget, onComboBoxChanged); + connect(otherBox, static_cast(&QComboBox::currentIndexChanged), widget, onComboBoxChanged); + + // 置灰: + // 1. 本身用户无权限 + // 2. 所属文件系统无权限机制 + if (info->ownerId() != getuid() || + !canChmod(info) || + fsType == "fuseblk") { + ownerBox->setDisabled(true); + groupBox->setDisabled(true); + otherBox->setDisabled(true); + } + + // tmp: 暂时的处理 + if (fsType == "vfat") { + groupBox->setDisabled(true); + otherBox->setDisabled(true); + if (info->isDir()) { + ownerBox->setDisabled(true); + } + } + + // 保险箱文件权限特殊处理 + if(VaultController::isVaultFile(info->fileUrl().toLocalFile())) { + ownerBox->setCurrentIndex(0); + ownerBox->setDisabled(true); + groupBox->setDisabled(true); + otherBox->setDisabled(true); + } + + // smb、ftp、sftp不支持文件权限的修改 + if (info->isGvfsMountFile()) { + ownerBox->setDisabled(true); + groupBox->setDisabled(true); + otherBox->setDisabled(true); + } + + return widget; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/propertydialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/propertydialog.h new file mode 100644 index 0000000..fd45821 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/propertydialog.h @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef PROPERTYDIALOG_H +#define PROPERTYDIALOG_H + +#include "basedialog.h" +#include "dabstractfileinfo.h" +#include "deviceinfo/udiskdeviceinfo.h" +#include "dfmevent.h" +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define EXTEND_FRAME_MAXHEIGHT 160 + +QT_BEGIN_NAMESPACE +class QFrame; +class QCheckBox; +class QTimer; +class QListWidget; +class QButtonGroup; +QT_END_NAMESPACE + +DWIDGET_BEGIN_NAMESPACE +class DDrawer; +class DIconButton; +DWIDGET_END_NAMESPACE + +class DAbstractFileInfo; +class UDiskDeviceInfo; +class DUrl; +class ShareInfoFrame; + + +DFM_BEGIN_NAMESPACE +class DFileStatisticsJob; +DFM_END_NAMESPACE + +class DFMRoundBackground : public QObject +{ + Q_OBJECT +public: + DFMRoundBackground(QWidget *parent, int radius): QObject(parent) + { + parent->installEventFilter(this); + setProperty("radius", radius); + } + ~DFMRoundBackground() + { + parent()->removeEventFilter(this); + } + + virtual bool eventFilter(QObject *watched, QEvent *event); +}; + +DWIDGET_USE_NAMESPACE + + +class NameTextEdit: public QTextEdit +{ + Q_OBJECT + +public: + explicit NameTextEdit(const QString &text = "", QWidget *parent = nullptr); + + bool isCanceled() const; + void setIsCanceled(bool isCanceled); + +signals: + void editFinished(); + +public slots: + void setPlainText(const QString &text); + +protected: + void focusOutEvent(QFocusEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + +private: + bool m_isCanceled = false; +}; + + +class GroupTitleLabel: public QLabel +{ + Q_OBJECT + +public: + explicit GroupTitleLabel(const QString &text = "", QWidget *parent = nullptr, Qt::WindowFlags f = {}); +}; + +class SectionKeyLabel: public QLabel +{ + Q_OBJECT + +public: + explicit SectionKeyLabel(const QString &text = "", QWidget *parent = nullptr, Qt::WindowFlags f = {}); +}; + +class SectionValueLabel: public QLabel +{ + Q_OBJECT + +public: + explicit SectionValueLabel(const QString &text = "", QWidget *parent = nullptr, Qt::WindowFlags f = {}); +}; + +class LinkSectionValueLabel: public SectionValueLabel +{ + Q_OBJECT + +public: + explicit LinkSectionValueLabel(const QString &text = "", QWidget *parent = nullptr, Qt::WindowFlags f = {}); + + DUrl linkTargetUrl() const; + void setLinkTargetUrl(const DUrl &linkTargetUrl); + +protected: + void mouseReleaseEvent(QMouseEvent *event) override; + +private: + DUrl m_linkTargetUrl; +}; + +class PropertyDialog : public DDialog +{ + Q_OBJECT + +public: + explicit PropertyDialog(const DFMEvent &event, const DUrl url, QWidget *parent = nullptr); + +public: + void initUI(); + void initConnect(); + void startComputerFolderSize(const DUrl &url); + void toggleFileExecutable(bool isChecked); + DUrl getUrl(); + int getFileCount(); + qint64 getFileSize(); + + const QList &expandGroup() const; + int contentHeight() const; + int getDialogHeight() const; + + void loadPluginExpandWidgets(); + +public slots: + void raise(); + void updateFolderSize(qint64 size); + void renameFile(); + void showTextShowFrame(); + void onChildrenRemoved(const DUrl &fileUrl); + // fileUrl:共享文件夹路径 + void flickFolderToSidebar(const DUrl &fileUrl); + void onOpenWithBntsChecked(QAbstractButton *w); + void onHideFileCheckboxChecked(bool checked); + // 取消共享时停止动画效果 + void onCancelShare(); + +signals: + void closed(const DUrl &url); + void aboutToClosed(const DUrl &url); + void raised(); + +protected: + void mousePressEvent(QMouseEvent *event) override; + void hideEvent(QHideEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + + void initExpand(QVBoxLayout *layout, DDrawer *expand); + +private: + QFrame *initTagFrame(const DUrl &url); + void updateInfo(); // when any property has been changed should update the linked properties ASAP, bug 25419 + //属性框的URL需要重定向 + const DUrl getRealUrl(); + bool canChmod(const DAbstractFileInfoPointer &info); + +private: + DFMEvent m_fmevent{}; + DUrl m_url{}; + QString m_absolutePath{}; + qint64 m_size{ 0 }; + bool m_editDisbaled{ false }; + int m_fileCount{ 0 }; + QLabel *m_icon{ nullptr }; + NameTextEdit *m_edit{ nullptr }; + QStackedWidget *m_editStackWidget{ nullptr }; + QFrame *m_textShowFrame{ nullptr }; + DIconButton *m_editButton{ nullptr }; + QCheckBox *m_executableCheckBox{ nullptr }; + SectionValueLabel *m_folderSizeLabel{ nullptr }; + SectionValueLabel *m_containSizeLabel{ nullptr }; + QFrame *m_basicInfoFrame{ nullptr }; + ShareInfoFrame *m_shareinfoFrame{ nullptr }; + QFrame *m_authorityManagementFrame{ nullptr }; + QFrame *m_deviceInfoFrame{ nullptr }; + QListWidget *m_OpenWithListWidget{ nullptr }; + QButtonGroup *m_OpenWithButtonGroup{ nullptr }; + QList m_expandGroup; + DFM_NAMESPACE::DFileStatisticsJob *m_sizeWorker{ nullptr }; + QVBoxLayout *m_mainLayout{ nullptr }; + QFrame *m_wdf{ nullptr }; + QScrollArea *m_scrollArea{ nullptr }; + QFrame *m_tagInfoFrame{ nullptr }; + QPointer m_xani {nullptr}; + QPointer m_gani {nullptr}; + QPointer m_aniLabel {nullptr}; + + + QList addExpandWidget(const QStringList &titleList); + + void initTextShowFrame(const QString &text); + QFrame *createBasicInfoWidget(const DAbstractFileInfoPointer &info); + ShareInfoFrame *createShareInfoFrame(const DAbstractFileInfoPointer &info); + QList > createLocalDeviceInfoWidget(const DAbstractFileInfoPointer &info); + QFrame *createInfoFrame(const QList > &properties); + QListWidget *createOpenWithListWidget(const DAbstractFileInfoPointer &info); + QFrame *createAuthorityManagementWidget(const DAbstractFileInfoPointer &info); + + QPointer m_platformWindowHandle {nullptr}; +}; + +#endif // PROPERTYDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/shareinfoframe.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/shareinfoframe.cpp new file mode 100644 index 0000000..f290efb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/shareinfoframe.cpp @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "shareinfoframe.h" +#include "propertydialog.h" +#include "usershare/shareinfo.h" +#include "usershare/usersharemanager.h" +#include "singleton.h" +#include "app/define.h" +#include "dfileservices.h" +#include "dialogmanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +ShareInfoFrame::ShareInfoFrame(const DAbstractFileInfoPointer &info, QWidget *parent) : + QFrame(parent), + m_fileinfo(info) +{ +// m_jobTimer = new QTimer(); +// m_jobTimer->setInterval(1000); +// ->setSingleShot(true); + initUI(); + updateShareInfo(m_fileinfo->absoluteFilePath()); + initConnect(); +} + +void ShareInfoFrame::initUI() +{ + int labelWidth = 100; + int fieldWidth = 160; + + m_shareCheckBox = new QCheckBox(this); + m_shareCheckBox->setFixedWidth(fieldWidth); + m_shareCheckBox->setText(tr("Share this folder")); + + QWidget *centerAlignContainer = new QWidget(); + QHBoxLayout *centerAlignLayout = new QHBoxLayout(centerAlignContainer); + centerAlignLayout->addWidget(m_shareCheckBox); + centerAlignLayout->setAlignment(Qt::AlignCenter); + centerAlignLayout->setContentsMargins(0, 0, 0, 0); + centerAlignContainer->setLayout(centerAlignLayout); + + SectionKeyLabel *shareNameLabel = new SectionKeyLabel(tr("Share name:")); + shareNameLabel->setFixedWidth(labelWidth); + m_shareNamelineEdit = new QLineEdit(this); + m_shareNamelineEdit->setObjectName("ShareNameEdit"); + m_shareNamelineEdit->setText(m_fileinfo->fileDisplayName()); + m_shareNamelineEdit->setFixedWidth(fieldWidth); + // sp3需求 共享文件名设置限制 + // 设置只能输入大小写字母、数字和部分符号的正则表达式 + QRegExp regx("^[^\\s+\\[\\]\"'/\\\\:|<>+=;,?*\r\n\t]*$"); + // 创建验证器 + QValidator *validator = new QRegExpValidator(regx, this); + m_shareNamelineEdit->setValidator(validator); + + SectionKeyLabel *permissionLabel = new SectionKeyLabel(tr("Permission:")); + permissionLabel->setFixedWidth(labelWidth); + m_permissoComBox = new QComboBox(this); + m_permissoComBox->view()->parentWidget()->setAttribute(Qt::WA_TranslucentBackground); + m_permissoComBox->setFixedWidth(fieldWidth); + QStringList permissions; + permissions << tr("Read and write") << tr("Read only"); + m_permissoComBox->addItems(permissions); + + SectionKeyLabel *anonymityLabel = new SectionKeyLabel(tr("Anonymous:")); + anonymityLabel->setFixedWidth(labelWidth); + m_anonymityCombox = new QComboBox(this); + m_anonymityCombox->view()->parentWidget()->setAttribute(Qt::WA_TranslucentBackground); + m_anonymityCombox->setFixedWidth(fieldWidth); + QStringList anonymityChoices; + anonymityChoices << tr("Not allow") << tr("Allow"); + m_anonymityCombox->addItems(anonymityChoices); + + QFormLayout *mainLayoyt = new QFormLayout(this); + + DFMGlobal::setToolTip(shareNameLabel); + DFMGlobal::setToolTip(permissionLabel); + DFMGlobal::setToolTip(anonymityLabel); + + mainLayoyt->addRow(centerAlignContainer); + mainLayoyt->addRow(shareNameLabel, m_shareNamelineEdit); + mainLayoyt->addRow(permissionLabel, m_permissoComBox); + mainLayoyt->addRow(anonymityLabel, m_anonymityCombox); + mainLayoyt->setLabelAlignment(Qt::AlignVCenter | Qt::AlignRight); + mainLayoyt->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); + mainLayoyt->setFormAlignment(Qt::AlignVCenter | Qt::AlignCenter); + mainLayoyt->setContentsMargins(10, 10, 10, 10); + setLayout(mainLayoyt); + + //当前文件夹已被共享 + if (userShareManager->isShareFile(m_fileinfo->filePath())) { + auto creatorShareUid = userShareManager->getCreatorUidByShareName(m_fileinfo->fileSharedName().toLower()); + //文件共享创建者不是当前process的打开者或者不是文件所有者 排除root用户 + if ((creatorShareUid != getuid() || creatorShareUid != m_fileinfo->ownerId()) + && getuid() != 0) { + this->setEnabled(false); + } + } + + //判断文件属主与进程属主是否相同,排除进程属主为根用户情况 + if (m_fileinfo->ownerId() != getuid() && getuid() != 0) { + this->setEnabled(false); +// m_shareCheckBox->setEnabled(false); +// m_shareNamelineEdit->setEnabled(false); +// m_permissoComBox->setEnabled(false); +// m_anonymityCombox->setEnabled(false); + } +} + +void ShareInfoFrame::initConnect() +{ + connect(m_shareCheckBox, &QCheckBox::clicked, this, &ShareInfoFrame::handleCheckBoxChanged); +// connect(m_shareNamelineEdit, &QLineEdit::textChanged, this, &ShareInfoFrame::handleShareNameChanged); + connect(m_shareNamelineEdit, &QLineEdit::editingFinished, this, &ShareInfoFrame::handleShareNameFinished); + //connect(m_shareNamelineEdit, &QLineEdit::returnPressed, this, [ = ]() {qDebug() << "回车按下";}); //不知为何没有发送returnPressed信号 + connect(m_permissoComBox, SIGNAL(currentIndexChanged(int)), this, SLOT(handlePermissionComboxChanged(int))); + connect(m_anonymityCombox, SIGNAL(currentIndexChanged(int)), this, SLOT(handleAnonymityComboxChanged(int))); + //connect(m_jobTimer, &QTimer::timeout, this, &ShareInfoFrame::doShareInfoSetting); + connect(userShareManager, &UserShareManager::userShareAdded, this, &ShareInfoFrame::updateShareInfo); + connect(userShareManager, &UserShareManager::userShareDeleted, this, &ShareInfoFrame::updateShareInfo); + connect(userShareManager, &UserShareManager::userShareDeletedFailed, this, &ShareInfoFrame::updateShareInfo); +} + +void ShareInfoFrame::handleCheckBoxChanged(const bool &checked) +{ + //为了避免在高速点击时引发ui错乱,只有在share流程完全结束后才允许用户再次修改共享状态 + m_shareCheckBox->setEnabled(false); + bool ret = doShareInfoSetting(); + + if (ret) { + if (checked) { +// emit folderShared(m_fileinfo->absoluteFilePath()); + activateWidgets(); + } + } else { + m_shareCheckBox->setChecked(false); + m_shareCheckBox->setEnabled(true); + disactivateWidgets(); + } +} + +void ShareInfoFrame::handleShareNameFinished() +{ + // 修复bug-54080 + // 当失去焦点时,判断文件名是否符合规则 + if (!m_shareNamelineEdit->hasFocus()) + doShareInfoSetting(); + else // 如果焦点存在,将焦点设置到下一个控件 + m_permissoComBox->setFocus(); + //handShareInfoChanged(); +} + +void ShareInfoFrame::handleShareNameChanged(const QString &str) +{ + // fix bug 69970 与文件名规则保持一致 + // 采用validator过滤,屏蔽信号 + QString dstText = DFMGlobal::preprocessingFileName(str); + if (str != dstText) { + QSignalBlocker blocker(m_shareNamelineEdit); + + int currPos = m_shareNamelineEdit->cursorPosition(); + m_shareNamelineEdit->setText(dstText); + currPos += dstText.length() - str.length(); + m_shareNamelineEdit->setText(dstText); + m_shareNamelineEdit->setCursorPosition(currPos); + } +} + +void ShareInfoFrame::handlePermissionComboxChanged(const int &index) +{ + Q_UNUSED(index); + doShareInfoSetting(); +} + +void ShareInfoFrame::handleAnonymityComboxChanged(const int &index) +{ + Q_UNUSED(index); + doShareInfoSetting(); +} + +void ShareInfoFrame::handShareInfoChanged() +{ + //m_jobTimer->start(); +} + +bool ShareInfoFrame::doShareInfoSetting() +{ + if (m_shareCheckBox->isChecked()) { //判断是否为添加共享 + if (!checkShareName()) { //检查共享名 + return false; + } + } else { + emit unfolderShared(); +// hide(); + return DFileService::instance()->unShareFolder(this, m_fileinfo->fileUrl()); + } + // fix bug#51124 只读共享文件夹,修改“匿名访问”,此文件夹权限改变 + // 用户权限保持不变,修改组、其他权限为可读写 + if (m_permissoComBox->currentIndex() == 0 && m_anonymityCombox->currentIndex() != 0) { + DUrl localUrl = DUrl::fromLocalFile(m_fileinfo->fileUrl().toLocalFile()); + fileService->setPermissions(nullptr, localUrl, m_fileinfo->permissions() + | QFileDevice::ReadOther | QFileDevice::WriteOther | QFileDevice::ExeOther + | QFileDevice::ReadGroup | QFileDevice::WriteGroup | QFileDevice::ExeGroup); + } + + bool ret = DFileService::instance()->shareFolder(this, m_fileinfo->fileUrl(), m_shareNamelineEdit->text(), + m_permissoComBox->currentIndex() == 0, + m_anonymityCombox->currentIndex() != 0); + + //修改用户目录其他权限为可执行 + //该权限修改逻辑只针对普通用户共享自己的文件时有效 + //root用户共享的行为不主动修改目录权限,既共享时不修改/root的其他执行权限和普通用户主目录的其他执行权限 + if (ret && m_anonymityCombox->currentIndex() != 0 && getuid() != 0) { + DUrl userUrl = DUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + if (m_fileinfo->path().startsWith(userUrl.path())) { + DAbstractFileInfoPointer userFileInfo = fileService->createFileInfo(this, userUrl); + if (userFileInfo && userFileInfo->exists() + && (userFileInfo->permissions() & QFileDevice::ExeOther) != QFileDevice::ExeOther) + fileService->setPermissions(this, userUrl, userFileInfo->permissions() | QFileDevice::ExeOther); + } + } + + return ret; +} + +void ShareInfoFrame::updateShareInfo(const QString &filePath) +{ + //为了避免在高速点击时引发ui错乱,只有在share流程完全结束后才允许用户再次修改共享状态 + m_shareCheckBox->setEnabled(true); + if (filePath != m_fileinfo->absoluteFilePath()) + return; + + if (!m_fileinfo->fileSharedName().isEmpty()) { + m_shareCheckBox->setChecked(true); + activateWidgets(); + //disconnect(m_shareNamelineEdit, &QLineEdit::editingFinished, this, &ShareInfoFrame::handleShareNameChanged); + //int cursorPos = m_shareNamelineEdit->cursorPosition(); + m_shareNamelineEdit->setText(m_fileinfo->fileSharedName()); + //m_shareNamelineEdit->setCursorPosition(cursorPos); + //connect(m_shareNamelineEdit, &QLineEdit::editingFinished, this, &ShareInfoFrame::handleShareNameChanged); + if (m_fileinfo->isWritableShared()) { + m_permissoComBox->setCurrentIndex(0); + } else { + m_permissoComBox->setCurrentIndex(1); + } + + if (m_fileinfo->isAllowGuestShared()) { + m_anonymityCombox->setCurrentIndex(1); + } else { + m_anonymityCombox->setCurrentIndex(0); + } + } else { + m_shareCheckBox->setChecked(false); + m_permissoComBox->setCurrentIndex(0); + m_anonymityCombox->setCurrentIndex(0); + + const QString share_name = m_fileinfo->fileDisplayName().remove(QRegExp("[%<>*?|\\\\+=;:\",]")); + + m_shareNamelineEdit->setText(share_name); + + disactivateWidgets(); + } +} + +void ShareInfoFrame::activateWidgets() +{ + //m_shareNamelineEdit->setEnabled(true); + m_permissoComBox->setEnabled(true); + m_anonymityCombox->setEnabled(true); +} + +void ShareInfoFrame::disactivateWidgets() +{ +// m_shareNamelineEdit->setEnabled(false); + m_permissoComBox->setEnabled(false); + m_anonymityCombox->setEnabled(false); +} + +void ShareInfoFrame::setFileinfo(const DAbstractFileInfoPointer &fileinfo) +{ + m_fileinfo = fileinfo; + updateShareInfo(m_fileinfo->absoluteFilePath()); +} + +bool ShareInfoFrame::checkShareName() //返回值表示是否继续 +{ + // 共享名不能为空 + const QString &name = m_shareNamelineEdit->text(); + if (name.isEmpty() || name == "") { + return false; + } + // 修复BUG-44972 + // 当共享文件名为“..”或“.”时,弹出提示框 + if (name == ".." || name == ".") { + QString strMsg = tr("The share name must not be two dots (..) or one dot (.)"); + dialogManager->showMessageDialog(DialogManager::msgWarn, strMsg); + return false; + } + + if (m_fileinfo->fileSharedName().toLower() == m_shareNamelineEdit->text().toLower()) { //共享名未更改(不区分大小写)时,直接返回true + return true; + } + QDir d("/var/lib/samba/usershares"); //该目录存放了通过程序net共享的共享信息,文件名是共享名,文件名统一小写 + QFileInfoList infolist = d.entryInfoList(QDir::Files); //读取/var/lib/samba/usershares目录下文件信息 + for (QFileInfo info : infolist) { + if (m_shareNamelineEdit->text().toLower() == info.fileName()) { //查询共享名是否重复,因为程序net保存的文件名统一小写,所以先将共享名转为小写判断 + DDialog dialog(this); + dialog.setIcon(QIcon::fromTheme("dialog-warning")); + + if (!info.isWritable()) { //不可则无法替换 + dialog.setTitle(tr("The share name is used by another user.")); + dialog.addButton(tr("OK","button"), true); + } else { //可写则添加替换按钮 + dialog.setTitle(tr("The share name already exists. Do you want to replace the shared folder?")); + dialog.addButton(tr("Cancel","button"), true); + dialog.addButton(tr("Replace","button"), false, DDialog::ButtonWarning); + } + + if (dialog.exec() != DDialog::Accepted) { + //m_shareCheckBox->setChecked(false); + m_shareNamelineEdit->setFocus(); //进入编辑 + return false; + } + break; //终止循环 + } + } + return true; +} + +ShareInfoFrame::~ShareInfoFrame() +{ + +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/shareinfoframe.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/shareinfoframe.h new file mode 100644 index 0000000..2db1494 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/shareinfoframe.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef SHAREINFOFRAME_H +#define SHAREINFOFRAME_H + +#include +#include + +#include "dabstractfileinfo.h" + +QT_BEGIN_NAMESPACE +class QComboBox; +class QCheckBox; +class QLineEdit; +QT_END_NAMESPACE + +class ShareInfoFrame : public QFrame +{ + Q_OBJECT +public: + explicit ShareInfoFrame(const DAbstractFileInfoPointer &info, QWidget *parent = 0); + ~ShareInfoFrame(); + + void initUI(); + void initConnect(); + void setFileinfo(const DAbstractFileInfoPointer &fileinfo); + bool checkShareName(); + +signals: + void folderShared(const QString &filePath); + void unfolderShared(); + +public slots: + void handleCheckBoxChanged(const bool &checked); + void handleShareNameFinished(); + // 屏蔽NameChanged信号 + void handleShareNameChanged(const QString &str); + void handlePermissionComboxChanged(const int &index); + void handleAnonymityComboxChanged(const int &index); + void handShareInfoChanged(); + bool doShareInfoSetting(); + void updateShareInfo(const QString &filePath); + void activateWidgets(); + void disactivateWidgets(); + +private: + DAbstractFileInfoPointer m_fileinfo; + QCheckBox *m_shareCheckBox = nullptr; + QLineEdit *m_shareNamelineEdit = nullptr; + QComboBox *m_permissoComBox = nullptr; + QComboBox *m_anonymityCombox = nullptr; + //QTimer *m_jobTimer; +}; + +#endif // SHAREINFOFRAME_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/trashpropertydialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/trashpropertydialog.cpp new file mode 100644 index 0000000..2ca26f9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/trashpropertydialog.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "trashpropertydialog.h" +#include "shutil/fileutils.h" +#include "dfileservices.h" +#include "dfilestatisticsjob.h" + +#include + +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE +DFM_USE_NAMESPACE + +TrashPropertyDialog::TrashPropertyDialog(const DUrl &url, QWidget *parent) + : DDialog(parent) + , m_url(url) +{ + initUI(); +} + +TrashPropertyDialog::~TrashPropertyDialog() +{ + +} + +void TrashPropertyDialog::initUI() +{ + if (DFMGlobal::isWayLand()) { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + } + + setFixedWidth(320); + setTitle(tr("Trash")); + + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(this, m_url); + QIcon trashIcon; + if (fileInfo->filesCount() > 0) { + trashIcon = QIcon::fromTheme("user-trash-full"); + } else { + trashIcon = QIcon::fromTheme("user-trash"); + } + + m_iconLabel = new QLabel(this); + m_iconLabel->setFixedSize(160, 160); + m_iconLabel->setPixmap(trashIcon.pixmap(m_iconLabel->size())); + m_iconLabel->setAlignment(Qt::AlignCenter); + + const int fCount = fileInfo->filesCount(); + QString itemStr = tr("item"); + if (fCount != 1) + itemStr = tr("items"); + + DHorizontalLine *hLine = new DHorizontalLine(this); + m_countLabel = new QLabel(tr("Contains %1 %2").arg(QString::number(fCount), itemStr), this); + m_sizeLabel = new QLabel(this); + + QFrame *infoFrame = new QFrame; + infoFrame->setFixedHeight(48); + QHBoxLayout *infoLayout = new QHBoxLayout; + infoLayout->addWidget(m_countLabel); + infoLayout->addStretch(); + infoLayout->addWidget(m_sizeLabel); + infoLayout->setContentsMargins(10, 0, 10, 0); + infoFrame->setLayout(infoLayout); + + QString backColor = palette().color(QPalette::Base).name(); + infoFrame->setStyleSheet(QString("background-color: %1; border-radius: 8px;").arg(backColor)); + + QFrame *contenFrame = new QFrame; + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(m_iconLabel, 0, Qt::AlignHCenter); + mainLayout->addWidget(hLine); + //mainLayout->addLayout(infoLayout); + mainLayout->addWidget(infoFrame); + mainLayout->setContentsMargins(10, 10, 10, 10); + contenFrame->setLayout(mainLayout); + + addContent(contenFrame); + + startComputerFolderSize(m_url); + + +} + +void TrashPropertyDialog::startComputerFolderSize(const DUrl &url) +{ + DFileStatisticsJob *worker = new DFileStatisticsJob(this); + + connect(worker, &DFileStatisticsJob::finished, worker, &DFileStatisticsJob::deleteLater); + connect(worker, &DFileStatisticsJob::dataNotify, this, &TrashPropertyDialog::updateFolderSize); + worker->start({url}); +} + +void TrashPropertyDialog::updateFolderSize(qint64 size) +{ + m_sizeLabel->setText(FileUtils::formatSize(size)); +} + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/trashpropertydialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/trashpropertydialog.h new file mode 100644 index 0000000..1a58f8b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/trashpropertydialog.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef TRASHPROPERTYDIALOG_H +#define TRASHPROPERTYDIALOG_H + +#include "durl.h" +#include "propertydialog.h" +#include +#include + +DWIDGET_USE_NAMESPACE + +class TrashPropertyDialog : public DDialog +{ + Q_OBJECT +public: + explicit TrashPropertyDialog(const DUrl& url, QWidget *parent = nullptr); + ~TrashPropertyDialog(); + + void initUI(); + void startComputerFolderSize(const DUrl& url); + +public slots: + void updateFolderSize(qint64 size); + +private: + DUrl m_url; + QLabel* m_iconLabel; + QLabel* m_nameLable; + QLabel* m_countLabel; + QLabel* m_sizeLabel; +}; + +#endif // TRASHPROPERTYDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/usersharepasswordsettingdialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/usersharepasswordsettingdialog.cpp new file mode 100644 index 0000000..a48c153 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/usersharepasswordsettingdialog.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "usersharepasswordsettingdialog.h" +#include "../dbusinterface/usershare_interface.h" +#include "../app/define.h" +#include "singleton.h" +#include "usershare/usersharemanager.h" +#include +#include +#include +#include +#include +#include + +UserSharePasswordSettingDialog::UserSharePasswordSettingDialog(QWidget *parent) : DDialog(parent) +{ + setTitle(tr("Enter a password to protect shared folders")); + setIcon(QIcon::fromTheme("dialog-password-publicshare")); + initUI(); +} + +void UserSharePasswordSettingDialog::initUI() +{ + QStringList buttonTexts; + buttonTexts.append(tr("Cancel","button")); + buttonTexts.append(tr("Confirm","button")); + addButton(buttonTexts[0], false); + addButton(buttonTexts[1], false, DDialog::ButtonRecommend); + setDefaultButton(1); + m_passwordEdit = new DPasswordEdit(this); + m_passwordEdit->setFocus(); + addContent(m_passwordEdit); + setContentsMargins(0,0,0,0); + getButton(1)->setEnabled(false); + + connect(m_passwordEdit,&DPasswordEdit::textChanged,this,[this]{ + getButton(1)->setEnabled(!m_passwordEdit->text().isEmpty()); + }); + + if(DFMGlobal::isWayLand()) + { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + this->setFixedSize(QSize(390, 210)); + } +} + +void UserSharePasswordSettingDialog::onButtonClicked(const int &index) +{ + if (index == 1) { + // set usershare password + QString password = m_passwordEdit->text(); + if (password.isEmpty()) { + close(); + return; + } + userShareManager->setSambaPassword(UserShareManager::getCurrentUserName(), password); + } + close(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/usersharepasswordsettingdialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/usersharepasswordsettingdialog.h new file mode 100644 index 0000000..2a7dfc4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/dialogs/usersharepasswordsettingdialog.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef USERSHAREPASSWORDSETTINGDIALOG_H +#define USERSHAREPASSWORDSETTINGDIALOG_H + +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class UserSharePasswordSettingDialog : public DDialog +{ + Q_OBJECT +public: + explicit UserSharePasswordSettingDialog(QWidget *parent = nullptr); + void initUI(); + +signals: + +public slots: + void onButtonClicked(const int& index); + +private: + DPasswordEdit *m_passwordEdit; + QWidget *m_content; +}; + +#endif // USERSHAREPASSWORDSETTINGDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/chineseanalyzer.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/chineseanalyzer.cpp new file mode 100644 index 0000000..2f6dfe1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/chineseanalyzer.cpp @@ -0,0 +1,44 @@ +#include "chineseanalyzer.h" +#include "chinesetokenizer.h" + +#include +#include + +#define UNUSED(x) (void)x; + +namespace Lucene { + +ChineseAnalyzer::~ChineseAnalyzer() +{ +} + +TokenStreamPtr ChineseAnalyzer::tokenStream(const String &fieldName, const ReaderPtr &reader) +{ + UNUSED(fieldName) + + TokenStreamPtr result = newLucene(reader); + result = newLucene(result); + return result; +} + +TokenStreamPtr ChineseAnalyzer::reusableTokenStream(const String &fieldName, const ReaderPtr &reader) +{ + UNUSED(fieldName) + + ChineseAnalyzerSavedStreamsPtr streams(boost::dynamic_pointer_cast(getPreviousTokenStream())); + if (!streams) { + streams = newLucene(); + streams->source = newLucene(reader); +// streams->result = newLucene(streams->source); + setPreviousTokenStream(streams); + } else { + streams->source->reset(reader); + } + return streams->source; +} + +ChineseAnalyzerSavedStreams::~ChineseAnalyzerSavedStreams() +{ +} + +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/chineseanalyzer.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/chineseanalyzer.h new file mode 100644 index 0000000..90ac3a1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/chineseanalyzer.h @@ -0,0 +1,44 @@ +#ifndef CHINESEANALYZER_H +#define CHINESEANALYZER_H + +#include +#include + +namespace Lucene { + +/// An {@link Analyzer} that tokenizes text with {@link ChineseTokenizer} and filters with {@link ChineseFilter} +class LPPCONTRIBAPI ChineseAnalyzer : public Analyzer +{ +public: + virtual ~ChineseAnalyzer(); + + LUCENE_CLASS(ChineseAnalyzer); + +public: + /// Creates a {@link TokenStream} which tokenizes all the text in the provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from {@link ChineseTokenizer}, filtered with {@link ChineseFilter} + virtual TokenStreamPtr tokenStream(const String &fieldName, const ReaderPtr &reader); + + /// Returns a (possibly reused) {@link TokenStream} which tokenizes all the text in the + /// provided {@link Reader}. + /// + /// @return A {@link TokenStream} built from {@link ChineseTokenizer}, filtered with {@link ChineseFilter} + virtual TokenStreamPtr reusableTokenStream(const String &fieldName, const ReaderPtr &reader); +}; + +class LPPCONTRIBAPI ChineseAnalyzerSavedStreams : public LuceneObject +{ +public: + virtual ~ChineseAnalyzerSavedStreams(); + + LUCENE_CLASS(ChineseAnalyzerSavedStreams); + +public: + TokenizerPtr source; + TokenStreamPtr result; +}; + +} + +#endif // CHINESEANALYZER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/chinesetokenizer.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/chinesetokenizer.cpp new file mode 100644 index 0000000..4c7b56f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/chinesetokenizer.cpp @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Lucene { + +const int32_t ChineseTokenizer::MAX_WORD_LEN = 255; +const int32_t ChineseTokenizer::IO_BUFFER_SIZE = 1024; + +ChineseTokenizer::ChineseTokenizer(const ReaderPtr &input) : Tokenizer(input) +{ +} + +ChineseTokenizer::ChineseTokenizer(const AttributeSourcePtr &source, const ReaderPtr &input) : Tokenizer(source, input) +{ +} + +ChineseTokenizer::ChineseTokenizer(const AttributeFactoryPtr &factory, const ReaderPtr &input) : Tokenizer(factory, input) +{ +} + +ChineseTokenizer::~ChineseTokenizer() +{ +} + +void ChineseTokenizer::initialize() +{ + offset = 0; + bufferIndex = 0; + dataLen = 0; + buffer = CharArray::newInstance(MAX_WORD_LEN); + memset(buffer.get(), 0, MAX_WORD_LEN); + ioBuffer = CharArray::newInstance(IO_BUFFER_SIZE); + memset(ioBuffer.get(), 0, IO_BUFFER_SIZE); + length = 0; + start = 0; + + termAtt = addAttribute(); + offsetAtt = addAttribute(); +} + +void ChineseTokenizer::push(wchar_t c) +{ + if (length == 0) { + start = offset - 1; // start of token + } + buffer[length++] = CharFolder::toLower(c); // buffer it +} + +bool ChineseTokenizer::flush() +{ + if (length > 0) { + termAtt->setTermBuffer(buffer.get(), 0, length); + offsetAtt->setOffset(correctOffset(start), correctOffset(start + length)); + return true; + } else { + return false; + } +} + +bool ChineseTokenizer::incrementToken() +{ + clearAttributes(); + + length = 0; + start = offset; + + bool last_is_en = false, last_is_num = false; + while (true) { + wchar_t c; + ++offset; + + if (bufferIndex >= dataLen) { + dataLen = input->read(ioBuffer.get(), 0, ioBuffer.size()); + bufferIndex = 0; + } + + if (dataLen == -1) { + --offset; + return flush(); + } else { + c = ioBuffer[bufferIndex++]; + } + + if (UnicodeUtil::isLower(c) || UnicodeUtil::isUpper(c)) { + if (last_is_num) { + --bufferIndex; + --offset; + return flush(); + } + + push(c); + if (length == MAX_WORD_LEN) { + return flush(); + } + last_is_en = true; + } else if (UnicodeUtil::isDigit(c)) { + if (last_is_en) { + --bufferIndex; + --offset; + return flush(); + } + + push(c); + if (length == MAX_WORD_LEN) { + return flush(); + } + last_is_num = true; + } else if (UnicodeUtil::isOther(c)) { + if (length > 0) { + --bufferIndex; + --offset; + return flush(); + } + push(c); + return flush(); + } else if (length > 0) { + return flush(); + } + } +} + +void ChineseTokenizer::end() +{ + // set final offset + int32_t finalOffset = correctOffset(offset); + offsetAtt->setOffset(finalOffset, finalOffset); +} + +void ChineseTokenizer::reset() +{ + Tokenizer::reset(); + offset = 0; + bufferIndex = 0; + dataLen = 0; +} + +void ChineseTokenizer::reset(const ReaderPtr &input) +{ + Tokenizer::reset(input); + reset(); +} + +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/chinesetokenizer.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/chinesetokenizer.h new file mode 100644 index 0000000..403f375 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/chinesetokenizer.h @@ -0,0 +1,59 @@ +#ifndef CHINESETOKENIZER_H +#define CHINESETOKENIZER_H + +#include + +namespace Lucene { +class ChineseTokenizer: public Tokenizer +{ +public: + explicit ChineseTokenizer(const ReaderPtr &input); + ChineseTokenizer(const AttributeSourcePtr &source, const ReaderPtr &input); + ChineseTokenizer(const AttributeFactoryPtr &factory, const ReaderPtr &input); + + virtual ~ChineseTokenizer(); + + LUCENE_CLASS(ChineseTokenizer); + +protected: + /// Max word length + static const int32_t MAX_WORD_LEN; + + static const int32_t IO_BUFFER_SIZE; + +protected: + /// word offset, used to imply which character(in) is parsed + int32_t offset; + + /// the index used only for ioBuffer + int32_t bufferIndex; + + /// data length + int32_t dataLen; + + /// character buffer, store the characters which are used to compose the returned Token + CharArray buffer; + + /// I/O buffer, used to store the content of the input (one of the members of Tokenizer) + CharArray ioBuffer; + + TermAttributePtr termAtt; + OffsetAttributePtr offsetAtt; + + int32_t length; + int32_t start; + +public: + virtual void initialize(); + virtual bool incrementToken(); + virtual void end(); + virtual void reset(); + virtual void reset(const ReaderPtr &input); + +protected: + void push(wchar_t c); + bool flush(); +}; +} + +#endif // CHINESETOKENIZER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/fulltextsearch.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/fulltextsearch.cpp new file mode 100644 index 0000000..0bffcdc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/fulltextsearch.cpp @@ -0,0 +1,392 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 lawrence + * + * Author: lawrence + * + * 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 + * 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 . + */ + +#include "fulltextsearch.h" +#include "dfmapplication.h" +#include "chineseanalyzer.h" + +#include +#include +#include +#include +#include +#include + +//lucene++ header +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +DFM_BEGIN_NAMESPACE +#define SEARCH_RESULT_NUM 100000 + +DFMFullTextSearchManager::DFMFullTextSearchManager(QObject *parent) + : QObject(parent) +{ + status = false; + indexStorePath = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first() + + "/" + QApplication::organizationName() + + "/" + QApplication::applicationName() + + "/" + "index"; +} + +DFMFullTextSearchManager *DFMFullTextSearchManager::getInstance() +{ + static DFMFullTextSearchManager instance; + return &instance; +} + +QString DFMFullTextSearchManager::getFileContents(const QString &filePath) +{ + auto text = DocParser::convertFile(filePath.toStdString()); + return QString(text.c_str()); +} + +//先将字段加入到文档,在将文档加入到IndexWriter中 +DocumentPtr DFMFullTextSearchManager::getFileDocument(const QString &filename) +{ + DocumentPtr doc = newLucene(); + doc->add(newLucene(L"path", filename.toStdWString(), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); + QFileInfo info(filename); + QString modifyTime = info.lastModified().toString("yyyyMMddHHmmss"); + doc->add(newLucene(L"modified", modifyTime.toStdWString(), Field::STORE_YES, Field::INDEX_NOT_ANALYZED)); + QString contents = getFileContents(filename); + doc->add(newLucene(L"contents", contents.toStdWString(), Field::STORE_YES, Field::INDEX_ANALYZED)); + return doc; +} +void DFMFullTextSearchManager::indexDocs(const IndexWriterPtr &writer, const QString &sourceDir) +{ + isCreateIndex = true; + QStringList files; + traverseFloder(sourceDir.toStdString().c_str(), files); + isCreateIndex = false; + for (auto file : files) { + qDebug() << "Adding [" << file << "]"; + try { + writer->addDocument(getFileDocument(file)); + } catch (FileNotFoundException &ex) { + qDebug() << "addDocument error: " << QString::fromStdWString(ex.getError()); + } + } +} + +void DFMFullTextSearchManager::doSearch(const SearcherPtr &searcher, const QueryPtr &query, const QString &searchPath) +{ + // 创建过滤器,过滤掉非搜索目录的结果 + String filterPath = searchPath.endsWith("/") ? (searchPath + "*").toStdWString() : (searchPath + "/*").toStdWString(); + FilterPtr filter = newLucene(newLucene(newLucene(L"path", filterPath))); + TopDocsPtr topDocs = searcher->search(query, filter, SEARCH_RESULT_NUM); + Collection scoreDocs = topDocs->scoreDocs; + int resNum = 0; + for (auto scoreDoc : scoreDocs) { + DocumentPtr doc = searcher->doc(scoreDoc->doc); + String path = doc->get(L"path"); + + if (!path.empty()) { + /*fix bug 45096 对搜索结果里面的修改时间进行判断,如果时间不一样则表示文件已经更改,搜索结果不出现该文件*/ + QFileInfo info(QString::fromStdWString(path)); + QString modifyTime = info.lastModified().toString("yyyyMMddHHmmss"); + String storeTime = doc->get(L"modified"); + if (modifyTime.toStdWString() != storeTime) { + continue; + } else { + searchResults.append(StringUtils::toUTF8(path).c_str()); + qDebug() << ++resNum << " " << QString::fromStdWString(path.c_str()); + } + } + } +} + +bool DFMFullTextSearchManager::searchByKeyworld(const QString &keyword, const QString &searchPath) +{ + try { + // only searching, so read-only=true + IndexReaderPtr reader = IndexReader::open(FSDirectory::open(indexStorePath.toStdWString()), true); + + SearcherPtr searcher = newLucene(reader); + AnalyzerPtr analyzer = newLucene(); + QueryParserPtr parser = newLucene(LuceneVersion::LUCENE_CURRENT, L"contents", analyzer); + parser->setAllowLeadingWildcard(true);//设定第一个* 可以匹配 + + QString newKeyWorld = dealKeyWorld(keyword); + QueryPtr query = parser->parse(newKeyWorld.toStdWString()); + qDebug() << "Searching for: " << keyword; + + doSearch(searcher, query, searchPath); + reader->close(); + } catch (LuceneException &e) { + qDebug() << "Exception: " << QString::fromStdWString(e.getError()); + return false; + } + + return true; +} + +int DFMFullTextSearchManager::fulltextIndex(const QString &sourceDir) +{ + if (status == true) { + return 0; + } else { + status = true; + QtConcurrent::run([ = ] { + createFileIndex(sourceDir); + status = false; + }); + return 1; + } +} + +void DFMFullTextSearchManager::traverseFloder(const char *filePath, QStringList &result) +{ + if (!isCreateIndex && m_state == JobController::Stoped) { + return; + } + + QRegExp reg("^/(boot|dev|proc|sys|run|lib|usr).*$"); + if (reg.exactMatch(QString(filePath)) && !QString(filePath).startsWith("/run/user")) { + return; + } + + std::string path(filePath); + int pathLevel = 0; + std::for_each(std::begin(path), std::end(path), [&](char ch) { + if (ch == '/') { + pathLevel++; + } + }); + /*目录级数限定*/ + if (pathLevel > 20) { + return; + } + + DIR *dir = nullptr; + if (!(dir = opendir(filePath))) { + //trace ("can't open: %s\n", dname); + return; + } + struct dirent *dent = nullptr; + size_t len = strlen(filePath); + if (len >= FILENAME_MAX - 1) { + //trace ("filename too long: %s\n", dname); + return; + } + + char fn[FILENAME_MAX] = ""; + strcpy(fn, filePath); + if (strcmp(filePath, "/")) { + // TODO: use a more performant fix to handle root directory + fn[len++] = '/'; + } + while ((dent = readdir(dir))) { + if ((QString(dent->d_name).at(0) == '.') && !QString(dent->d_name).startsWith(".local")) { + continue; + } + if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..") || !strcmp(dent->d_name, ".avfs")) { + continue; + } + + struct stat st; + strncpy(fn + len, dent->d_name, FILENAME_MAX - len); + if (lstat(fn, &st) == -1) { + //warn("Can't stat %s", fn); + continue; + } + const bool is_dir = S_ISDIR(st.st_mode); + if (is_dir) { + traverseFloder(fn, result); + } else { + QFileInfo info(fn); + QString suffix = info.suffix(); + QRegExp regExp("(rtf)|(odt)|(ods)|(odp)|(odg)|(docx)|(xlsx)|(pptx)|(ppsx)|(md)|" + "(xls)|(xlsb)|(doc)|(dot)|(wps)|(ppt)|(pps)|(txt)|(htm)|(html)|(pdf)|(dps)"); + if (regExp.exactMatch(suffix)) { + result.append(fn); + } + } + } + if (dir) { + closedir(dir); + } +} + +QString DFMFullTextSearchManager::dealKeyWorld(const QString &keyWorld) +{ + static QRegExp cnReg("^[\u4e00-\u9fa5]"); + static QRegExp enReg("^[A-Za-z]+$"); + static QRegExp numReg("^[0-9]$"); + CharType oldType = CN, currType = CN; + QString newStr; + for (auto c : keyWorld) { + if (cnReg.exactMatch(c)) { + currType = CN; + } else if (enReg.exactMatch(c)) { + currType = EN; + } else if (numReg.exactMatch(c)) { + currType = DIGIT; + } else { + // 特殊符号均当作空格处理 + newStr += ' '; + currType = SPACE; + continue; + } + + newStr += c; + // 如果上一个字符是空格,则不需要再加空格 + if (oldType == SPACE) { + oldType = currType; + continue; + } + + if (oldType != currType) { + oldType = currType; + newStr.insert(newStr.length() - 1, " "); + } + } + + return newStr.trimmed(); +} + +bool DFMFullTextSearchManager::updateIndex(const QString &filePath) +{ + bool res = false; + qDebug() << "Update index"; + QStringList files; + traverseFloder(filePath.toStdString().c_str(), files); + for (QString file : files) { + if (m_state == JobController::Stoped) { + qDebug() << "full text search stop!"; + return false; + } + + try { + IndexReaderPtr reader = IndexReader::open(FSDirectory::open(indexStorePath.toStdWString()), true); + SearcherPtr searcher = newLucene(reader); + TermQueryPtr query = newLucene(newLucene(L"path", file.toStdWString())); + + // 文件路径为唯一值,所以搜索一个结果就行了 + TopDocsPtr topDocs = searcher->search(query, 1); + int32_t numTotalHits = topDocs->totalHits; + if (numTotalHits == 0) { + try { + IndexWriterPtr writer = newLucene(FSDirectory::open(indexStorePath.toStdWString()), + newLucene(), + IndexWriter::MaxFieldLengthLIMITED); + writer->addDocument(getFileDocument(file)); + qDebug() << "Add file: [" << file << "]"; + writer->close(); + res = true; + } catch (LuceneException &ex) { + qDebug() << "Add file error:" << QString::fromStdWString(ex.getError()); + } + + } else { + DocumentPtr doc = searcher->doc(topDocs->scoreDocs[0]->doc); + QFileInfo info(file); + QString modifyTime = info.lastModified().toString("yyyyMMddHHmmss"); + String storeTime = doc->get(L"modified"); + if (modifyTime.toStdWString() == storeTime) { + continue; + } else { + try { + IndexWriterPtr writer = newLucene(FSDirectory::open(indexStorePath.toStdWString()), + newLucene(), + IndexWriter::MaxFieldLengthLIMITED); + //定义一个更新条件 + TermPtr term = newLucene(L"path", file.toStdWString()); + //更新 + writer->updateDocument(term, getFileDocument(file)); + qDebug() << "Update file: [" << file << "]"; + //关闭 + writer->close(); + res = true; + } catch (LuceneException &ex) { + qDebug() << "Update file error:" << QString::fromStdWString(ex.getError()); + } + } + } + reader->close(); + } catch (LuceneException &ex) { + qDebug() << QString::fromStdWString(ex.getError()); + } + } + + return res; +} + +bool DFMFullTextSearchManager::createFileIndex(const QString &sourcePath) +{ + QDir sourceDir(sourcePath); + if (!sourceDir.exists()) { + qDebug() << "Source directory doesn't exist: " << sourcePath; + return false; + } + + QDir indexDir(indexStorePath); + if (!indexDir.exists()) { + if (!indexDir.mkpath(indexStorePath)) { + qDebug() << "Unable to create directory: " << indexStorePath; + return false; + } + } + + uint64_t beginIndex = MiscUtils::currentTimeMillis(); + + try { + IndexWriterPtr writer = newLucene(FSDirectory::open(indexStorePath.toStdWString()), + newLucene(), + true, + IndexWriter::MaxFieldLengthLIMITED); + qDebug() << "Indexing to directory: " << indexStorePath; + writer->deleteAll(); + indexDocs(writer, sourcePath); + + uint64_t endIndex = MiscUtils::currentTimeMillis(); + uint64_t indexDuration = endIndex - beginIndex; + writer->optimize(); + + uint64_t optimizeDuration = MiscUtils::currentTimeMillis() - endIndex; + writer->close(); + + qDebug() << "\n\nIndex time: " << indexDuration + optimizeDuration << " milliseconds\n\n"; + } catch (LuceneException &e) { + qDebug() << "Exception: " << QString::fromStdWString(e.getError()); + return false; + } + return true; +} + +QStringList DFMFullTextSearchManager::fullTextSearch(const QString &keyword, const QString &searchPath) +{ + searchResults.clear(); + if (searchByKeyworld(keyword, searchPath)) + return searchResults; + + return QStringList(); +} +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/fulltextsearch.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/fulltextsearch.h new file mode 100644 index 0000000..c013f84 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/fulltextsearch.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 lawrence + * + * Author: lawrence + * + * 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 + * 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 . + */ + +#ifndef FULLTEXTSEARCH_H +#define FULLTEXTSEARCH_H + +#include +#include +#include +#include +#include +#include +#include "controllers/jobcontroller.h" + +using namespace Lucene; +DFM_BEGIN_NAMESPACE +class DFMFullTextSearchManager : public QObject +{ + Q_OBJECT + +public: + enum CharType { + CN, + EN, + DIGIT, + SPACE + }; + + static DFMFullTextSearchManager *getInstance(); + + /** + * @brief fullTextSearch 全文搜索接口 + * @param keyword 搜索关键字 + * @return 搜索结果 + */ + QStringList fullTextSearch(const QString &keyword, const QString &searchPath); + + /** + * @brief fulltextIndex 创建索引接口 + * @param sourceDir 索引目录 + * @return + */ + int fulltextIndex(const QString &sourceDir); + + bool updateIndex(const QString &filePath); + + inline void setSearchState(JobController::State state) + { + m_state = state; + } + + inline JobController::State getSearchState() const + { + return m_state; + } + +private: + explicit DFMFullTextSearchManager(QObject *parent = nullptr); + + void indexDocs(const IndexWriterPtr &writer, const QString &sourceDir); + + DocumentPtr getFileDocument(const QString &filename); + + /** + * @brief createFileIndex 创建文件索引 + * @param sourcePath 文件路径 + * @return + */ + bool createFileIndex(const QString &sourcePath); + + /** + * @brief getFileContents 获取文件内容 + * @param filePath 文件路径 + * @return + */ + QString getFileContents(const QString &filePath); + + /** + * @brief searchByKeyworld 搜索 + * @param keyword 搜索关键字 + * @return + */ + bool searchByKeyworld(const QString &keyword, const QString &searchPath); + + void doSearch(const SearcherPtr &searcher, const QueryPtr &query, const QString &searchPath); + + /** + * @brief traverseFloder 遍历文件夹,获取文件名 + * @param filePath 需要遍历的文件夹 + * @param result 遍历结果 + */ + void traverseFloder(const char *filePath, QStringList &result); + + /** + * @brief dealKeyWorld 对搜索关键字进行处理,不同类型之间以空格隔开 + * @param keyWorld 搜索关键字 + * @return + */ + QString dealKeyWorld(const QString &keyWorld); + +private: + bool status; + + /*! + * \brief searchResults 搜索结果 + */ + QStringList searchResults; + + /** + * @brief indexStorePath 索引存储目录 + */ + QString indexStorePath; + + JobController::State m_state = JobController::Stoped; + + QMutex mutex; + + bool isCreateIndex = false; +}; + +DFM_END_NAMESPACE +#endif // FULLTEXTSEARCH_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/fulltextsearch.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/fulltextsearch.pri new file mode 100644 index 0000000..226511a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/fulltextsearch/fulltextsearch.pri @@ -0,0 +1,41 @@ +# Copyright (C) 2019 ~ 2020 Uniontech Technology Co., Ltd. + +#Author: hujianzhong + +#Maintainer: hujianzhong + +#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 +#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 . + +#This program is the full text search at dde-file-manager. +#------------------------------------------------- +# +# Project created by QtCreator 2020-05-12T16:00:00 +#这个搜索引擎是利用C++语言,文件搜索速度相当快,是移植的开源代码doctotext的核心部分 +#------------------------------------------------- + +QT += widgets +CONFIG += c++11 link_pkgconfig +PKGCONFIG += liblucene++ liblucene++-contrib docparser + +HEADERS += \ + $$PWD/fulltextsearch.h \ + $$PWD/chinesetokenizer.h \ + $$PWD/chineseanalyzer.h + +SOURCES += \ + $$PWD/fulltextsearch.cpp \ + $$PWD/chinesetokenizer.cpp \ + $$PWD/chineseanalyzer.cpp + +INCLUDEPATH += $$PWD +LIBS += -lboost_system diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/generate_translations.sh b/dde-file-manager-5.5.3/src/dde-file-manager-lib/generate_translations.sh new file mode 100755 index 0000000..c908092 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/generate_translations.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# this file is used to auto-generate .qm file from .ts file. +# author: shibowen at linuxdeepin.com + +ts_list=(`ls translations/*.ts`) + +for ts in "${ts_list[@]}" +do + printf "\nprocess ${ts}\n" + lrelease "${ts}" +done diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/gvfsmountmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/gvfsmountmanager.cpp new file mode 100644 index 0000000..9b29c6a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/gvfsmountmanager.cpp @@ -0,0 +1,2048 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +//fix: 设置光盘容量属性 +#include "../views/dfmopticalmediawidget.h" + +#include "gvfsmountmanager.h" +#include "qdrive.h" +#include "qvolume.h" +#include "qmount.h" +#include "qdiskinfo.h" +#include "singleton.h" +#include "../app/define.h" +#include "../interfaces/dfileservices.h" +#include "../interfaces/dfmevent.h" +#include "deviceinfo/udisklistener.h" +#include "dialogs/dialogmanager.h" +#include "mountsecretdiskaskpassworddialog.h" +#include "app/filesignalmanager.h" +#include "shutil/fileutils.h" +#include "utils.h" + +#include "networkmanager.h" +#include "dfmapplication.h" +#include "dabstractfilewatcher.h" +#include "ddiskmanager.h" +#include "dblockdevice.h" +#include "ddiskdevice.h" +#include "mountaskpassworddialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +/*afc has no unix_device, so use uuid as unix_device*/ + +QMap GvfsMountManager::Drives = {}; // key is unix-device +QMap GvfsMountManager::Volumes = {}; // key is unix-device or uuid +QMap GvfsMountManager::Mounts = {}; // key is mount point root uri +QMap GvfsMountManager::DiskInfos = {}; + +QStringList GvfsMountManager::Drives_Keys = {};//key is unix-device +QStringList GvfsMountManager::Volumes_Drive_Keys = {}; // key is unix-device +QStringList GvfsMountManager::Volumes_No_Drive_Keys = {}; // key is unix-device or uuid + +QStringList GvfsMountManager::NoVolumes_Mounts_Keys = {}; // key is mount point root uri +QStringList GvfsMountManager::Lsblk_Keys = {}; // key is got by lsblk + +MountSecretDiskAskPasswordDialog *GvfsMountManager::mountSecretDiskAskPasswordDialog = nullptr; + +bool GvfsMountManager::AskedPasswordWhileMountDisk = false; + +QHash> GvfsMountManager::MountEventHash; +QHash> GvfsMountManager::MountTimerHash; +QHash GvfsMountManager::CancellHash; +QHash> GvfsMountManager::eventLoopHash; +QHash GvfsMountManager::AskingPasswordHash; +QHash GvfsMountManager::askPasswordDialogHash; +QHash GvfsMountManager::SMBLoginObjHash; + +//fix: 每次弹出光驱时需要删除临时缓存数据文件 +QString GvfsMountManager::g_qVolumeId = "sr0"; + +#ifdef QT_DEBUG +Q_LOGGING_CATEGORY(mountManager, "gvfs.mountMgr") +#else +Q_LOGGING_CATEGORY(mountManager, "gvfs.mountMgr", QtInfoMsg) +#endif + +GvfsMountManager::GvfsMountManager(QObject *parent) : QObject(parent) +{ + m_gVolumeMonitor = g_volume_monitor_get(); + qRegisterMetaType("QDrive"); +} + +void GvfsMountManager::initConnect() +{ + if (DFMGlobal::isRootUser()) { + g_signal_connect(m_gVolumeMonitor, "mount-added", (GCallback)&GvfsMountManager::monitor_mount_added_root, nullptr); + g_signal_connect(m_gVolumeMonitor, "mount-removed", (GCallback)&GvfsMountManager::monitor_mount_removed_root, nullptr); + } + //fix 28660 【文件管理器】【5.1.1.60-1】【服务器】root用户,卸载U盘后,无法重新挂载 + g_signal_connect(m_gVolumeMonitor, "mount-added", (GCallback)&GvfsMountManager::monitor_mount_added, nullptr); + g_signal_connect(m_gVolumeMonitor, "mount-removed", (GCallback)&GvfsMountManager::monitor_mount_removed, nullptr); + g_signal_connect(m_gVolumeMonitor, "mount-changed", (GCallback)&GvfsMountManager::monitor_mount_changed, nullptr); + g_signal_connect(m_gVolumeMonitor, "volume-added", (GCallback)&GvfsMountManager::monitor_volume_added, nullptr); + g_signal_connect(m_gVolumeMonitor, "volume-removed", (GCallback)&GvfsMountManager::monitor_volume_removed, nullptr); + g_signal_connect(m_gVolumeMonitor, "volume-changed", (GCallback)&GvfsMountManager::monitor_volume_changed, nullptr); +// }else{ +// g_signal_connect (m_gVolumeMonitor, "mount-added", (GCallback)&GvfsMountManager::monitor_mount_added, nullptr); +// g_signal_connect (m_gVolumeMonitor, "mount-removed", (GCallback)&GvfsMountManager::monitor_mount_removed, nullptr); +// g_signal_connect (m_gVolumeMonitor, "mount-changed", (GCallback)&GvfsMountManager::monitor_mount_changed, nullptr); +// g_signal_connect (m_gVolumeMonitor, "volume-added", (GCallback)&GvfsMountManager::monitor_volume_added, nullptr); +// g_signal_connect (m_gVolumeMonitor, "volume-removed", (GCallback)&GvfsMountManager::monitor_volume_removed, nullptr); +// g_signal_connect (m_gVolumeMonitor, "volume-changed", (GCallback)&GvfsMountManager::monitor_volume_changed, nullptr); +// } + connect(this, &GvfsMountManager::loadDiskInfoFinished, deviceListener, &UDiskListener::update); +} + +GvfsMountManager *GvfsMountManager::instance() +{ + return gvfsMountManager; +} + +QStringList GvfsMountManager::getIconNames(GThemedIcon *icon) +{ + QStringList iconNames; + char **names; + char **iter; + names = nullptr; + g_object_get(icon, "names", &names, nullptr); + for (iter = names; *iter; iter++) { + iconNames.append(QString(*iter)); + } + g_strfreev(names); + return iconNames; +} + +QDrive GvfsMountManager::gDriveToqDrive(GDrive *drive) +{ + QDrive qDrive; + char *name; + char **ids; + GIcon *icon; + + name = g_drive_get_name(drive); + qDrive.setName(QString(name)); + g_free(name); + + ids = g_drive_enumerate_identifiers(drive); + if (ids && ids[0] != nullptr) { + for (int i = 0; ids[i] != nullptr; i++) { + char *id = g_drive_get_identifier(drive, + ids[i]); + if (QString(ids[i]) == "unix-device") { + qDrive.setUnix_device(QString(id)); + } + g_free(id); + } + } + g_strfreev(ids); + + qDrive.setHas_volumes(g_drive_has_volumes(drive)); + qDrive.setCan_eject(g_drive_can_eject(drive)); + qDrive.setCan_start(g_drive_can_start(drive)); + qDrive.setCan_start_degraded(g_drive_can_start_degraded(drive)); + qDrive.setCan_poll_for_media(g_drive_can_poll_for_media(drive)); + qDrive.setCan_stop(g_drive_can_stop(drive)); + qDrive.setIs_removable(g_drive_is_removable(drive)); + qDrive.setStart_stop_type(g_drive_get_start_stop_type(drive)); + qDrive.setHas_media(g_drive_has_media(drive)); + qDrive.setIs_media_check_automatic(g_drive_is_media_check_automatic(drive)); + qDrive.setIs_media_removable(g_drive_is_media_removable(drive)); + + icon = g_drive_get_icon(drive); + if (icon) { + if (G_IS_THEMED_ICON(icon)) { + qDrive.setIcons(getIconNames(G_THEMED_ICON(icon))); + } + g_object_unref(icon); + } + + icon = g_drive_get_symbolic_icon(drive); + if (icon) { + if (G_IS_THEMED_ICON(icon)) { + qDrive.setSymbolic_icons(getIconNames(G_THEMED_ICON(icon))); + } + g_object_unref(icon); + } + + return qDrive; +} + +QVolume GvfsMountManager::gVolumeToqVolume(GVolume *gvolume) +{ + if (!gvolume) + return QVolume(); + + QVolume qVolume; + char *name; + char **ids; + GIcon *icon; + GFile *activation_root; + + name = g_volume_get_name(gvolume); + qVolume.setName(QString(name)); + g_free(name); + + ids = g_volume_enumerate_identifiers(gvolume); + if (ids && ids[0] != nullptr) { + for (int i = 0; ids[i] != nullptr; i++) { + char *id = g_volume_get_identifier(gvolume, ids[i]); + if (QString(ids[i]) == G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) { + qVolume.setUnix_device(QString(id)); + } else if (QString(ids[i]) == G_VOLUME_IDENTIFIER_KIND_LABEL) { + qVolume.setLable(QString(id)); + } else if (QString(ids[i]) == G_VOLUME_IDENTIFIER_KIND_UUID) { + qVolume.setUuid(QString(id)); + } else if (QString(ids[i]) == G_VOLUME_IDENTIFIER_KIND_NFS_MOUNT) { + qVolume.setNfs_mount(QString(id)); + } + + if (qVolume.unix_device().isEmpty()) { + qVolume.setUnix_device(qVolume.uuid()); + } + + g_free(id); + } + } + g_strfreev(ids); + + qVolume.setCan_mount(g_volume_can_mount(gvolume)); + qVolume.setCan_eject(g_volume_can_eject(gvolume)); + qVolume.setShould_automount(g_volume_should_automount(gvolume)); + + + icon = g_volume_get_icon(gvolume); + if (icon) { + if (G_IS_THEMED_ICON(icon)) { + qVolume.setIcons(getIconNames(G_THEMED_ICON(icon))); + } + g_object_unref(icon); + } + + icon = g_volume_get_symbolic_icon(gvolume); + if (icon) { + if (G_IS_THEMED_ICON(icon)) { + qVolume.setSymbolic_icons(getIconNames(G_THEMED_ICON(icon))); + } + g_object_unref(icon); + } + + GMount *mount = g_volume_get_mount(gvolume); + if (mount) { + qVolume.setIsMounted(true); + GFile *root = g_mount_get_root(mount); + char *uri = g_file_get_uri(root); + qVolume.setMounted_root_uri(QString(uri)); + + g_object_unref(root); + g_free(uri); + } + + activation_root = g_volume_get_activation_root(gvolume); + if (activation_root != nullptr) { + char *action_root_uri = g_file_get_uri(activation_root); + qVolume.setActivation_root_uri(QString(action_root_uri)); + g_object_unref(activation_root); + g_free(action_root_uri); + } + + GDrive *gDrive = g_volume_get_drive(gvolume); + if (gDrive) { + QDrive qDrive = gDriveToqDrive(gDrive); + qVolume.setDrive_unix_device(QString(g_drive_get_identifier(gDrive, "unix-device"))); + qVolume.setDrive(qDrive); + } + + return qVolume; +} + +QMount GvfsMountManager::gMountToqMount(GMount *gmount) +{ + if(!gmount) + return QMount(); + + QMount qMount; + char *name, *uri; + GFile *root, *default_location; + GIcon *icon; + + name = g_mount_get_name(gmount); + qMount.setName(QString(name)); + g_free(name); + + root = g_mount_get_root(gmount); + uri = g_file_get_uri(root); + qMount.setMounted_root_uri(QString(uri)); + g_object_unref(root); + g_free(uri); + + default_location = g_mount_get_default_location(gmount); + if (default_location) { + char *loc_uri = g_file_get_uri(default_location); + qMount.setDefault_location(QString(loc_uri)); + g_free(loc_uri); + g_object_unref(default_location); + } + + icon = g_mount_get_icon(gmount); + if (icon) { + if (G_IS_THEMED_ICON(icon)) { + qMount.setIcons(getIconNames(G_THEMED_ICON(icon))); + } + g_object_unref(icon); + } + + icon = g_mount_get_symbolic_icon(gmount); + if (icon) { + if (G_IS_THEMED_ICON(icon)) { + qMount.setSymbolic_icons(getIconNames(G_THEMED_ICON(icon))); + } + g_object_unref(icon); + } + + qMount.setCan_unmount(g_mount_can_unmount(gmount)); + qMount.setCan_eject(g_mount_can_eject(gmount)); + qMount.setIs_shadowed(g_mount_is_shadowed(gmount)); + + return qMount; +} + +QDiskInfo GvfsMountManager::qVolumeToqDiskInfo(const QVolume &volume) +{ + QDiskInfo diskInfo; + diskInfo.setId(volume.unix_device()); + + diskInfo.setName(volume.name()); + + diskInfo.setDrive_unix_device(volume.drive_unix_device()); + diskInfo.setUnix_device(volume.unix_device()); + diskInfo.setUuid(volume.uuid()); + diskInfo.setActivation_root_uri(volume.activation_root_uri()); + diskInfo.setMounted_root_uri(volume.mounted_root_uri()); + + if (volume.icons().count() > 0) { + diskInfo.setIconName(volume.icons().at(0)); + } + + diskInfo.setCan_mount(volume.can_mount()); + diskInfo.setCan_eject(volume.can_eject()); + + if (!volume.mounted_root_uri().isEmpty()) { + diskInfo.setCan_unmount(true); + } + + if (diskInfo.iconName() == "phone-apple-iphone") { + diskInfo.setType("iphone"); + } else if (diskInfo.iconName() == "phone" || diskInfo.iconName() == "multimedia-player") { + diskInfo.setType("phone"); + } else if (diskInfo.iconName() == "camera-photo" || diskInfo.iconName() == "camera") { + diskInfo.setType("camera"); + } else if (diskInfo.can_eject() && (diskInfo.iconName() == "drive-harddisk-usb" || diskInfo.iconName() == "drive-removable-media-usb")) { + diskInfo.setType("removable"); + diskInfo.setIs_removable(true); + } else if (isDVD(volume)) { + diskInfo.setType("dvd"); + } else { + diskInfo.setType("native"); + } + + diskInfo.setHas_volume(true); + + diskInfo.updateGvfsFileSystemInfo(); + + + if (Drives.contains(volume.drive_unix_device())) { + const QDrive &drive = Drives.value(volume.drive_unix_device()); + if (drive.is_removable()) { + diskInfo.setType("removable"); + diskInfo.setIs_removable(true); + } + } + + return diskInfo; +} + +QDiskInfo GvfsMountManager::qMountToqDiskinfo(const QMount &mount, bool updateUsage) +{ + QDiskInfo diskInfo; + diskInfo.setId(mount.mounted_root_uri()); + + diskInfo.setName(mount.name()); +// diskInfo.setType(); + diskInfo.setUuid(mount.uuid()); + diskInfo.setMounted_root_uri(mount.mounted_root_uri()); + + if (mount.icons().count() > 0) { + diskInfo.setIconName(mount.icons().at(0)); + } + + diskInfo.setCan_unmount(mount.can_unmount()); + diskInfo.setCan_eject(mount.can_eject()); + diskInfo.setDefault_location(mount.default_location()); + + if (diskInfo.mounted_root_uri().startsWith("smb://")) { + diskInfo.setType("smb"); + } else if (diskInfo.iconName() == "drive-optical" || diskInfo.iconName().startsWith("CD")) { + diskInfo.setType("dvd"); + } else { + diskInfo.setType("network"); + } + if (updateUsage) // 该函数的具体作用是通过 Gio 获取文件系统的用量信息,获取该用量信息在一些场景下非常迟滞例如当移除 iPhone 设备时;但在移除设备时,用量信息是无需有的,因此这里添加参数控制是否需要更新用量。默认更新 + diskInfo.updateGvfsFileSystemInfo(); + return diskInfo; +} + +QVolume GvfsMountManager::getVolumeByMountedRootUri(const QString &mounted_root_uri) +{ + foreach (const QVolume &volume, Volumes) { + if (volume.isMounted() && volume.mounted_root_uri() == mounted_root_uri) { + return volume; + } + } + return QVolume(); +} + +QVolume GvfsMountManager::getVolumeByUnixDevice(const QString &unix_device) +{ + foreach (const QVolume &volume, Volumes) { + if (volume.unix_device() == unix_device) { + return volume; + } + } + return QVolume(); +} + +void GvfsMountManager::monitor_mount_added_root(GVolumeMonitor *volume_monitor, GMount *mount) +{ + Q_UNUSED(volume_monitor) + qCDebug(mountManager()) << "==============================monitor_mount_added_root=============================="; + QMount qMount = gMountToqMount(mount); + qCDebug(mountManager()) << qMount; + + QDiskInfo diskInfo = qMountToqDiskinfo(qMount); + if (qMount.can_unmount()) + diskInfo.setCan_unmount(true); + if (qMount.can_eject()) + diskInfo.setCan_eject(true); + DiskInfos.insert(diskInfo.id(), diskInfo); + emit gvfsMountManager->volume_added(diskInfo); +} + +void GvfsMountManager::monitor_mount_removed_root(GVolumeMonitor *volume_monitor, GMount *mount) +{ + Q_UNUSED(volume_monitor) + qCDebug(mountManager()) << "==============================monitor_mount_removed_root=============================="; + QMount qMount = gMountToqMount(mount); + qCDebug(mountManager()) << qMount; + + QDiskInfo diskInfo = qMountToqDiskinfo(qMount, false); + DiskInfos.remove(diskInfo.id()); + emit gvfsMountManager->volume_removed(diskInfo); +} + +void GvfsMountManager::monitor_mount_added(GVolumeMonitor *volume_monitor, GMount *gmount) +{ + Q_UNUSED(volume_monitor) + qCDebug(mountManager()) << "==============================monitor_mount_added=============================="; + QMount qMount = gMountToqMount(gmount); + GVolume *gvolume = g_mount_get_volume(gmount); + QVolume qVolume = gVolumeToqVolume(gvolume); + + //fix: 探测光盘推进,弹出和挂载状态机标识 + if (qMount.icons().contains("media-optical")) { //CD/DVD + QString volTag = getVolTag(gvolume); + DFMOpticalMediaWidget::g_mapCdStatusInfo[volTag].bMntFlag = true; + DFMOpticalMediaWidget::g_mapCdStatusInfo[volTag].bVolFlag = true; + + // 对于光盘来说,执行挂载之后,一定是能够获取到 dp 对象的,在 actionMount 函数以及 setRootUrl 函数中,均请求了光盘的 dp 属性 + DISOMasterNS::DeviceProperty dp = ISOMaster->getDevicePropertyCached(qVolume.unix_device()); + if (dp.avail == 0) { + QString mpt = qMount.mounted_root_uri(); + mpt.remove(FILE_ROOT); + mpt = mpt.startsWith("/") ? mpt : ("/" + mpt); + QStorageInfo info(mpt); + if (info.isValid()) { + quint64 total = static_cast(info.bytesTotal()); + DFMOpticalMediaWidget::g_mapCdStatusInfo[volTag].nTotal = total; + DFMOpticalMediaWidget::g_mapCdStatusInfo[volTag].nUsage = total; + } + } else { + DFMOpticalMediaWidget::g_mapCdStatusInfo[volTag].nTotal = dp.avail + dp.data; + DFMOpticalMediaWidget::g_mapCdStatusInfo[volTag].nUsage = dp.data; + } + } + + qCDebug(mountManager()) << "===================" << qMount.mounted_root_uri() << gvolume << "======================="; + qCDebug(mountManager()) << "===================" << qMount << "======================="; + if (gvolume != nullptr) { + QVolume qVolume = gVolumeToqVolume(gvolume); + Volumes.insert(qVolume.unix_device(), qVolume); + + QDiskInfo diskInfo = qVolumeToqDiskInfo(qVolume); + if (qMount.can_unmount()) { + diskInfo.setCan_unmount(true); + } + if (qMount.can_eject()) { + diskInfo.setCan_eject(true); + } + + DiskInfos.insert(diskInfo.id(), diskInfo); + emit gvfsMountManager->mount_added(diskInfo); + qCDebug(mountManager()) << "========mount_added===========" << diskInfo; + } else { + // ignore afc first mounted event + if (isIgnoreUnusedMounts(qMount)) { + return; + } + + if (!NoVolumes_Mounts_Keys.contains(qMount.mounted_root_uri())) { + NoVolumes_Mounts_Keys.append(qMount.mounted_root_uri()); + + QDiskInfo diskInfo = qMountToqDiskinfo(qMount); + DiskInfos.insert(diskInfo.id(), diskInfo); + emit gvfsMountManager->mount_added(diskInfo); + } + } + + // when remote connection is mounted, reload computer model. + if (qMount.mounted_root_uri().startsWith("smb://")) { + QScopedPointer file(DGioFile::createFromUri(qMount.mounted_root_uri())); + RemoteMountsStashManager::stashRemoteMount(file->path(), qMount.name()); + } + + Mounts.insert(qMount.mounted_root_uri(), qMount); +} + +void GvfsMountManager::monitor_mount_removed(GVolumeMonitor *volume_monitor, GMount *mount) +{ + Q_UNUSED(volume_monitor) + qCDebug(mountManager()) << "==============================monitor_mount_removed==============================" ; + QMount qMount = gMountToqMount(mount); + + //fix: 探测光盘推进,弹出和挂载状态机标识 + if (qMount.name().contains("CD/DVD") || qMount.name().contains("CD") || qMount.icons().contains("media-optical")) { //CD/DVD + DFMOpticalMediaWidget::g_mapCdStatusInfo[getVolTag(mount)].bMntFlag = false; + } + + qCDebug(mountManager()) << "===================" << qMount.mounted_root_uri() << "======================="; + + QVolume volume = getVolumeByMountedRootUri(qMount.mounted_root_uri()); + qCDebug(mountManager()) << volume.isValid() << volume; + if (volume.isValid()) { + volume.setIsMounted(false); + volume.setMounted_root_uri(""); + Volumes.insert(volume.unix_device(), volume); + } else { + NoVolumes_Mounts_Keys.removeOne(qMount.mounted_root_uri()); + } + + bool removed = Mounts.remove(qMount.mounted_root_uri()); + if (removed) { + + if (volume.isValid()) { + QDiskInfo diskInfo = qVolumeToqDiskInfo(volume); + DiskInfos.insert(diskInfo.id(), diskInfo); + diskInfo.setHas_volume(true); + emit gvfsMountManager->mount_removed(diskInfo); + } else { + QDiskInfo diskInfo = qMountToqDiskinfo(qMount, false); // 在卸载设备的时候无需关心设备的用量信息 + bool diskInfoRemoved = DiskInfos.remove(diskInfo.id()); + if (diskInfoRemoved) { + diskInfo.setHas_volume(false); + emit gvfsMountManager->mount_removed(diskInfo); + } + } + + // 触发关闭标签的信号 + GFile *root = g_mount_get_root(mount); + char *path = g_file_get_path(root); + DUrl durl = DUrl::fromLocalFile(path); + g_free(path); + g_object_unref(root); + emit fileSignalManager->requestCloseTab(durl); + + if (qMount.mounted_root_uri().startsWith("smb://")) { + if (DFMApplication::genericAttribute(DFMApplication::GA_AlwaysShowOfflineRemoteConnections).toBool()) + emit DFMApplication::instance()->reloadComputerModel(); + } + } +} + +void GvfsMountManager::monitor_mount_changed(GVolumeMonitor *volume_monitor, GMount *mount) +{ + Q_UNUSED(volume_monitor) + Q_UNUSED(mount) +// qDebug() << "==============================monitor_mount_changed==============================" ; + GVolume *volume = g_mount_get_volume(mount); + if (volume != nullptr) { +// qDebug() << "==============================changed removed==============================" ; + + QVolume qVolume = gVolumeToqVolume(volume); + QDiskInfo diskInfo = qVolumeToqDiskInfo(qVolume); + + bool isDVDChanged = isDVD(qVolume); + if (isDVDChanged) { + diskInfo.setType("dvd"); + qCDebug(mountManager()) << diskInfo; + if (diskInfo.can_unmount()) { + diskInfo.updateGvfsFileSystemInfo(); + emit gvfsMountManager->volume_changed(diskInfo); + } + } + } else { +// qDebug() << "==============================changed volume empty==============================" ; + } +} + +void GvfsMountManager::monitor_volume_added(GVolumeMonitor *volume_monitor, GVolume *volume) +{ + Q_UNUSED(volume_monitor) + qCDebug(mountManager()) << "==============================monitor_volume_added==============================" ; + QVolume qVolume = gVolumeToqVolume(volume); + + qCDebug(mountManager()) << "===================" << qVolume.unix_device() << "======================="; + + //fix: 每次弹出光驱时需要删除临时缓存数据文件 + //id="/dev/sr1" -> tempId="sr1" + GvfsMountManager::g_qVolumeId = qVolume.unix_device().mid(5); + + //fix: 探测光盘推进,弹出和挂载状态机标识 + if (qVolume.icons().contains("media-optical")) { //CD/DVD + DFMOpticalMediaWidget::g_mapCdStatusInfo[getVolTag(volume)].bMntFlag = false; + DFMOpticalMediaWidget::g_mapCdStatusInfo[getVolTag(volume)].bVolFlag = true; + DFMOpticalMediaWidget::g_mapCdStatusInfo[getVolTag(volume)].bBurningOrErasing = false; + //fix: 设置光盘容量属性 + DFMOpticalMediaWidget::setBurnCapacity(DFMOpticalMediaWidget::BCSA_BurnCapacityStatusAdd, getVolTag(volume)); + } + + GDrive *drive = g_volume_get_drive(volume); + if (drive) { + QDrive qDrive = gDriveToqDrive(drive); + + if (!qDrive.unix_device().isEmpty()) { + Drives.insert(qDrive.unix_device(), qDrive); + if (!Volumes_Drive_Keys.contains(qDrive.unix_device())) { + Volumes_Drive_Keys.append(qDrive.unix_device()); + } + } + + if (drive != nullptr) { + qVolume.setDrive_unix_device(QString(g_drive_get_identifier(drive, "unix-device"))); + } + } + Volumes.insert(qVolume.unix_device(), qVolume); + + QDiskInfo diskInfo = qVolumeToqDiskInfo(qVolume); + + if (diskInfo.type() == "iphone") { + QRegularExpression express(QString("afc://%1(:[\\d]+)?/").arg(diskInfo.uuid())); + auto match = express.match(diskInfo.activation_root_uri()); + + if (!match.isValid()) { + return; + } + } + + DiskInfos.insert(diskInfo.id(), diskInfo); + emit gvfsMountManager->volume_added(diskInfo); +} + +void GvfsMountManager::monitor_volume_removed(GVolumeMonitor *volume_monitor, GVolume *volume) +{ + Q_UNUSED(volume_monitor) + qCDebug(mountManager()) << "==============================monitor_volume_removed==============================" ; + QVolume qVolume = gVolumeToqVolume(volume); + + qCDebug(mountManager()) << "===================" << qVolume.unix_device() << "======================="; + + //fix: 探测光盘推进,弹出和挂载状态机标识 + if (qVolume.name().contains("CD/DVD") || qVolume.name().contains("CD") || qVolume.icons().contains("media-optical")) { //CD/DVD + DFMOpticalMediaWidget::g_mapCdStatusInfo[getVolTag(volume)].bVolFlag = false; + // DFMOpticalMediaWidget::g_mapCdStatusInfo[getVolTag(volume)].bBurningOrErasing = false; + } + + //fix: 每次弹出光驱时需要删除临时缓存数据文件 + if ((qVolume.activation_root_uri().contains("burn:///") && qVolume.unix_device().contains("")) || \ + (qVolume.activation_root_uri().contains("") || qVolume.unix_device().contains("/dev/sr"))) { + //fix: 设置光盘容量属性 + DFMOpticalMediaWidget::g_mapCdStatusInfo[getVolTag(volume)].nTotal = 0; + DFMOpticalMediaWidget::g_mapCdStatusInfo[getVolTag(volume)].nUsage = 0;; + DFMOpticalMediaWidget::setBurnCapacity(DFMOpticalMediaWidget::BCSA_BurnCapacityStatusEjct, getVolTag(volume)); + emit fileSignalManager->requestUpdateComputerView(); + + const static QString stagePrefix = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/" + + qApp->organizationName() + "/" DISCBURN_STAGING "/"; + clearStageDir(stagePrefix + qVolume.unix_device().replace("/", "_")); + } + + GDrive *drive = g_volume_get_drive(volume); + if (drive) { + QDrive qDrive = gDriveToqDrive(drive); + + if (!qDrive.unix_device().isEmpty()) { + Drives.insert(qDrive.unix_device(), qDrive); + Volumes_Drive_Keys.removeOne(qDrive.unix_device()); + } + } + + bool removed = Volumes.remove(qVolume.unix_device()); + + qCDebug(mountManager()) << removed << qVolume << qVolumeToqDiskInfo(qVolume); + if (removed) { + QDiskInfo diskInfo = qVolumeToqDiskInfo(qVolume); + qCDebug(mountManager()) << diskInfo; + bool diskInfoRemoved = DiskInfos.remove(diskInfo.id()); + if (diskInfoRemoved) { + emit gvfsMountManager->volume_removed(diskInfo); + } + } else { + QDiskInfo diskInfo = qVolumeToqDiskInfo(qVolume); + emit gvfsMountManager->volume_removed(diskInfo); + } +} + +void GvfsMountManager::monitor_volume_changed(GVolumeMonitor *volume_monitor, GVolume *volume) +{ + Q_UNUSED(volume_monitor) + qCDebug(mountManager()) << "==============================monitor_volume_changed==============================" ; + + if (volume != nullptr) { + qCDebug(mountManager()) << "==============================volume changed==============================" ; + + QVolume qVolume = gVolumeToqVolume(volume); + QDiskInfo diskInfo = qVolumeToqDiskInfo(qVolume); + DiskInfos.insert(diskInfo.id(), diskInfo); + qCDebug(mountManager()) << diskInfo; + emit gvfsMountManager->volume_changed(diskInfo); + } else { + qCDebug(mountManager()) << "==============================changed volume empty==============================" ; + } +} + +GMountOperation *GvfsMountManager::new_mount_op(bool isDisk = true) +{ + GMountOperation *op; + + op = g_mount_operation_new(); + + g_signal_connect(op, "ask_question", G_CALLBACK(ask_question_cb), NULL); + g_signal_connect(op, "ask_password", + isDisk ? G_CALLBACK(ask_disk_password_cb) : G_CALLBACK(ask_password_cb), + nullptr); + + /* TODO: we *should* also connect to the "aborted" signal but since the + * main thread is blocked handling input we won't get that signal + * anyway... + */ + + return op; +} + +static int requestAnswerDialog(WId parentWindowId, const QString &message, QStringList choices) +{ + DDialog askQuestionDialog(WindowManager::getWindowById(parentWindowId)); + + askQuestionDialog.setMessage(message); + askQuestionDialog.addButtons(choices); + askQuestionDialog.setMaximumWidth(480); + + return askQuestionDialog.exec(); +} + +// blumia: This callback is mainly for sftp fingerprint identity dialog, but should works on any ask-question signal. +// ref: https://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/gio/GMountOperation.html#GMountOperation-ask-question +void GvfsMountManager::ask_question_cb(GMountOperation *op, const char *message, const GStrv choices) +{ + char **ptr = choices; + int choice; + QStringList choiceList; + + QString oneMessage(message); + qCDebug(mountManager()) << "ask_question_cb() message: " << message; + + while (*ptr) { + QString oneOption = QString::asprintf("%s", *ptr++); + qCDebug(mountManager()) << "ask_question_cb() - option(s): " << oneOption; + choiceList << oneOption; + } + + QString newmsg = oneMessage; + if (oneMessage.startsWith("Can’t verify the identity of") && + oneMessage.endsWith("If you want to be absolutely sure it is safe to continue, contact the system administrator.")) { + QString arg1, arg2; + QRegularExpression ovrex("“.*?”"); + auto ovrxm = ovrex.match(oneMessage); + if (ovrxm.hasMatch()) { + arg1 = ovrxm.captured(0); + newmsg = newmsg.replace(arg1, ""); + auto ovr_xm = ovrex.match(newmsg); + arg2 = ovr_xm.captured(0); + // 修复文管文案问题 + newmsg = tr("Can’t verify the identity of %1.").arg(arg1) + '\n' + + tr("This happens when you log in to a computer the first time.") + '\n' + + tr("The identity sent by the remote computer is") + '\n' + + arg2 + '\n' + + tr("If you want to be absolutely sure it is safe to continue, contact the system administrator."); + } + newmsg = newmsg.replace("\\r\\n", "\n"); + qDebug() << newmsg; + } + + if (MountEventHash.contains(op) && MountEventHash.value(op)) { + choice = DThreadUtil::runInMainThread(requestAnswerDialog, MountEventHash.value(op)->windowId(), newmsg, choiceList); + } else { + choice = -1; + qWarning() << "MountEventHash: bad choice."; + } qCDebug(mountManager()) << "ask_question_cb() user choice(start at 0): " << choice; + + // check if choose is invalid + if (choice < 0 || choice >= choiceList.count()) { + g_mount_operation_reply(op, G_MOUNT_OPERATION_ABORTED); + return; + } + + g_mount_operation_set_choice(op, choice); + g_mount_operation_reply(op, G_MOUNT_OPERATION_HANDLED); + + return; +} + +static QJsonObject requestPasswordDialog(WId parentWindowId, bool showDomainLine, const QJsonObject &data,GMountOperation *op) +{ + //fix 22749 修复输入秘密错误了后,2到3次才弹提示框 + if (!GvfsMountManager::instance()->askPasswordDialogHash.contains(op)) { + GvfsMountManager::instance()->askPasswordDialogHash.insert(op, new MountAskPasswordDialog(WindowManager::getWindowById(parentWindowId))); + } + GvfsMountManager::instance()->askPasswordDialogHash.value(op)->setLoginData(data); + GvfsMountManager::instance()->askPasswordDialogHash.value(op)->setDomainLineVisible(showDomainLine); + + int ret = GvfsMountManager::instance()->askPasswordDialogHash.value(op)->exec(); + + if (ret == DDialog::Accepted) { + return GvfsMountManager::instance()->askPasswordDialogHash.value(op)->getLoginData(); + } + + return QJsonObject(); +} + +void GvfsMountManager::ask_password_cb(GMountOperation *op, const char *message, const char *default_user, const char *default_domain, GAskPasswordFlags flags) +{ + if (MountTimerHash.contains(op)) + MountTimerHash.value(op)->stop(); + //fix 22749 修复输入秘密错误了后,2到3次才弹提示框 + if (askPasswordDialogHash.value(op)) { + askPasswordDialogHash.value(op)->deleteLater(); + askPasswordDialogHash.remove(op); + if (AskingPasswordHash.value(op)) + DThreadUtil::runInMainThread(dialogManager, &DialogManager::showErrorDialog, + tr("Mounting device error"), tr("Wrong username or password")); + //fix bug 63796,是sftp和ftp时,后面不会弹窗,所以这里要弹提示 + if (!AskingPasswordHash.value(op) && MountEventHash.value(op) && MountEventHash.contains(op) && MountEventHash.value(op)->fileUrl().scheme() != SMB_SCHEME) + DThreadUtil::runInMainThread(dialogManager, &DialogManager::showErrorDialog, + tr("Mounting device error"), QString()); + return; + } + + bool anonymous = g_mount_operation_get_anonymous(op); + GPasswordSave passwordSave = g_mount_operation_get_password_save(op); + + const char *default_password = g_mount_operation_get_password(op); + + qCDebug(mountManager()) << "anonymous" << anonymous; + qCDebug(mountManager()) << "message" << message; + qCDebug(mountManager()) << "username" << default_user; + qCDebug(mountManager()) << "domain" << default_domain; + qCDebug(mountManager()) << "password" << default_password; + qCDebug(mountManager()) << "GAskPasswordFlags" << flags; + qCDebug(mountManager()) << "passwordSave" << passwordSave; + + QJsonObject obj; + obj.insert("message", message); + obj.insert("anonymous", anonymous); + obj.insert("username", default_user); + obj.insert("domain", default_domain); + obj.insert("password", default_password); + obj.insert("GAskPasswordFlags", flags); + obj.insert("passwordSave", passwordSave); + QJsonObject loginObj; + if (MountTimerHash.contains(op) && MountEventHash.value(op)) { + loginObj = DThreadUtil::runInMainThread(requestPasswordDialog, + MountEventHash.value(op)->windowId(), + MountEventHash.value(op)->fileUrl().isSMBFile(), obj, op); + } + + if (!loginObj.isEmpty()) { + anonymous = loginObj.value("anonymous").toBool(); + QString username = loginObj.value("username").toString(); + QString domain = loginObj.value("domain").toString(); + QString password = loginObj.value("password").toString(); + GPasswordSave passwordsaveFlag = static_cast(loginObj.value("passwordSave").toInt()); + + SMBLoginObjHash.insert(op,new QJsonObject(loginObj)); + + if ((flags & G_ASK_PASSWORD_ANONYMOUS_SUPPORTED) && anonymous) { + g_mount_operation_set_anonymous(op, TRUE); + } else { + if (flags & G_ASK_PASSWORD_NEED_USERNAME) { + g_mount_operation_set_username(op, username.toStdString().c_str()); + } + + if (flags & G_ASK_PASSWORD_NEED_DOMAIN) { + g_mount_operation_set_domain(op, domain.toStdString().c_str()); + } + + if (flags & G_ASK_PASSWORD_NEED_PASSWORD) { + g_mount_operation_set_password(op, password.toStdString().c_str()); + } + + if (flags & G_ASK_PASSWORD_SAVING_SUPPORTED) { + g_mount_operation_set_password_save(op, passwordsaveFlag); + } + } + + /* Only try anonymous access once. */ + if (anonymous && + GPOINTER_TO_INT(g_object_get_data(G_OBJECT(op), "state")) == MOUNT_OP_ASKED) { + g_object_set_data(G_OBJECT(op), "state", GINT_TO_POINTER(MOUNT_OP_ABORTED)); + g_mount_operation_reply(op, G_MOUNT_OPERATION_ABORTED); + } else { + qCDebug(mountManager()) << "g_mount_operation_reply before"; +// g_object_set_data (G_OBJECT (op), "state", GINT_TO_POINTER (MOUNT_OP_ASKED)); + g_mount_operation_reply(op, G_MOUNT_OPERATION_HANDLED); + qCDebug(mountManager()) << "g_mount_operation_reply end"; + } + AskingPasswordHash.insert(op,!anonymous); + qCDebug(mountManager()) << "AskingPassword" << AskingPasswordHash.value(op); + + } else { + qCDebug(mountManager()) << "cancel connect"; + AskingPasswordHash.insert(op,false); + g_object_set_data(G_OBJECT(op), "state", GINT_TO_POINTER(MOUNT_OP_ABORTED)); + g_mount_operation_reply(op, G_MOUNT_OPERATION_ABORTED); + } + if (MountTimerHash.contains(op)) + MountTimerHash.value(op)->start(); +} + +void GvfsMountManager::ask_disk_password_cb(GMountOperation *op, const char *message, const char *default_user, const char *default_domain, GAskPasswordFlags flags) +{ + if (mountSecretDiskAskPasswordDialog) { + return; + } + + AskedPasswordWhileMountDisk = true; + + g_print("%s\n", message); + + bool anonymous = g_mount_operation_get_anonymous(op); + GPasswordSave passwordSave = g_mount_operation_get_password_save(op); + + const char *default_password = g_mount_operation_get_password(op); + + qCDebug(mountManager()) << "anonymous" << anonymous; + qCDebug(mountManager()) << "message" << message; + qCDebug(mountManager()) << "username" << default_user; + qCDebug(mountManager()) << "domain" << default_domain; + qCDebug(mountManager()) << "password" << default_password; + qCDebug(mountManager()) << "GAskPasswordFlags" << flags; + qCDebug(mountManager()) << "passwordSave" << passwordSave; + + if (flags & G_ASK_PASSWORD_NEED_USERNAME) { + g_mount_operation_set_username(op, default_user); + } + + if (flags & G_ASK_PASSWORD_NEED_DOMAIN) { + g_mount_operation_set_domain(op, default_domain); + } + + if (flags & G_ASK_PASSWORD_NEED_PASSWORD) { + QString tipMessage; + QString m(message); + QStringList messageList = m.split("\n"); + if (messageList.count() >= 2) { + tipMessage = messageList.at(1); + } + mountSecretDiskAskPasswordDialog = new MountSecretDiskAskPasswordDialog(tipMessage); + int code = mountSecretDiskAskPasswordDialog->exec(); + QString p = mountSecretDiskAskPasswordDialog->password(); + if (code == 0) { + p.clear(); + } + qCDebug(mountManager()) << "password is:" << p; + std::string pstd = p.toStdString(); + g_mount_operation_set_password(op, pstd.c_str()); + mountSecretDiskAskPasswordDialog->deleteLater(); + mountSecretDiskAskPasswordDialog = nullptr; + } + + g_mount_operation_reply(op, G_MOUNT_OPERATION_HANDLED); +} + +void GvfsMountManager::printVolumeMounts() +{ + qDebug() << QThread::currentThread() << qApp->thread(); + qDebug() << "=============================="; + qDebug() << "Volumes: " << Volumes; + qDebug() << "Mounts: " << Mounts; + qDebug() << "=============================="; + qDebug() << "Volumes_Drive_Keys" << Volumes_Drive_Keys; + qDebug() << "Volumes_No_Drive_Keys" << Volumes_No_Drive_Keys; + qDebug() << "NoVolumes_Mounts_Keys: " << NoVolumes_Mounts_Keys; + qDebug() << "=============================="; +} + +QDiskInfo GvfsMountManager::getDiskInfo(const QString &path, bool bupdate) +{ + QDiskInfo info; + foreach (const QDiskInfo &diskInfo, DiskInfos.values()) { + if (!path.isEmpty() && path == diskInfo.id()) { + info = diskInfo; + break; + } else if (!path.isEmpty() && diskInfo.mounted_root_uri() == path) { + info = diskInfo; + break; + } else if (!path.isEmpty() && path == diskInfo.unix_device()) { + info = diskInfo; + break; + } else if (!path.isEmpty() && path == diskInfo.uuid()) { + info = diskInfo; + break; + } + } + if (!info.isValid()) { + qDebug() << "获取磁盘信息失败"; + dialogManager->showFormatDialog(path); + } + if (bupdate) { + info.updateGvfsFileSystemInfo(); + } + return info; +} + +bool GvfsMountManager::isDVD(const QVolume &volume) +{ + if (volume.drive().isValid() && volume.unix_device().startsWith("/dev/sr")) { + return true; + } + return false; +} + +bool GvfsMountManager::isIgnoreUnusedMounts(const QMount &mount) +{ + /*the following protocol has two mounts event, ignore unused one*/ + if (mount.mounted_root_uri().startsWith("mtp://") || mount.mounted_root_uri().startsWith("gphoto2://")) { + return true; + } + return false; +} + +QString GvfsMountManager::getDriveUnixDevice(const QString &unix_device) +{ + QString drive_unix_device; + if (gvfsMountManager->DiskInfos.contains(unix_device)) { + drive_unix_device = gvfsMountManager->DiskInfos.value(unix_device).drive_unix_device(); + } + return drive_unix_device; +} + +bool GvfsMountManager::isDeviceCrypto_LUKS(const QDiskInfo &diskInfo) +{ + if (diskInfo.can_mount()) { + QStringList &&udiskspaths = DDiskManager::resolveDeviceNode(diskInfo.unix_device(), {}); + if (udiskspaths.isEmpty()) return false; + QScopedPointer blk(DDiskManager::createBlockDevice(udiskspaths.first())); + QString fstype = blk->idType(); + if (fstype == "crypto_LUKS") { + return true; + } + } + return false; +} + +void GvfsMountManager::startMonitor() +{ + if (DFMGlobal::isRootUser()) { + listMountsBylsblk(); + } + listVolumes(); + listMounts(); + listDrives(); + updateDiskInfos(); //磁盘信息root用户也需要刷新,否则会出现root用户只能挂载不能卸载的情况 +#ifdef DFM_MINIMUM + qDebug() << "Don't auto mount disk"; +#else +// if (qApp->applicationName() == QMAKE_TARGET && !DFMGlobal::IsFileManagerDiloagProcess){ +// TIMER_SINGLESHOT_OBJECT(this, 1000, { +// this->autoMountAllDisks(); +// }, this) +// } +#endif + initConnect(); + emit loadDiskInfoFinished(); +} + +void GvfsMountManager::listDrives() +{ + GList *drives = g_volume_monitor_get_connected_drives(m_gVolumeMonitor); + + GList *volumes, *d, *v; + char **ids; + int c, j, k; + for (c = 0, d = drives; d != nullptr; d = d->next, c++) { + GDrive *drive = static_cast(d->data); + QDrive qDrive = gDriveToqDrive(drive); + + if (!qDrive.unix_device().isEmpty()) { + Drives.insert(qDrive.unix_device(), qDrive); + Drives_Keys.append(qDrive.unix_device()); + } + + volumes = g_drive_get_volumes(drive); + for (j = 0, v = volumes; v != nullptr; v = v->next, j++) { + GVolume *volume = static_cast(v->data); + + ids = g_volume_enumerate_identifiers(volume); + if (ids && ids[0] != nullptr) { + for (k = 0; ids[k] != nullptr; k++) { + char *id = g_volume_get_identifier(volume, + ids[k]); + if (QString(ids[k]) == "unix-device") { + Volumes_Drive_Keys.append(QString(id)); + } + g_free(id); + } + } + g_strfreev(ids); + } + g_list_free_full(volumes, g_object_unref); + } + + g_list_free_full(drives, g_object_unref); +} + +void GvfsMountManager::listVolumes() +{ + GList *volumes = g_volume_monitor_get_volumes(m_gVolumeMonitor); + + GList *v; + int c; + for (c = 0, v = volumes; v != nullptr; v = v->next, c++) { + GVolume *volume = static_cast(v->data); + QVolume qVolume = gVolumeToqVolume(volume); + GDrive *drive = g_volume_get_drive(volume); + if (drive != nullptr) { + qVolume.setDrive_unix_device(QString(g_drive_get_identifier(drive, "unix-device"))); + } else { + if (!Volumes_No_Drive_Keys.contains(qVolume.unix_device())) { + Volumes_No_Drive_Keys.append(qVolume.unix_device()); + } + } + Volumes.insert(qVolume.unix_device(), qVolume); + } + + g_list_free_full(volumes, g_object_unref); +} + +void GvfsMountManager::listMounts() +{ + GList *mounts = g_volume_monitor_get_mounts(m_gVolumeMonitor); + + GList *m; + int c; + for (c = 0, m = mounts; m != nullptr; m = m->next, c++) { + GMount *mount = static_cast(m->data); + QMount qMount = gMountToqMount(mount); + Mounts.insert(qMount.mounted_root_uri(), qMount); + GVolume *volume = g_mount_get_volume(mount); + if (volume != nullptr) { + continue; + } else { + if (isIgnoreUnusedMounts(qMount)) { + continue; + } + } + NoVolumes_Mounts_Keys.append(qMount.mounted_root_uri()); + } + + g_list_free_full(mounts, g_object_unref); +} + +void GvfsMountManager::updateDiskInfos() +{ + Volumes_Drive_Keys.sort(); + foreach (QString key, Volumes_Drive_Keys) { + if (Volumes.contains(key)) { + QVolume volume = Volumes.value(key); + QDiskInfo diskInfo = qVolumeToqDiskInfo(volume); + DiskInfos.insert(diskInfo.id(), diskInfo); + qCDebug(mountManager()) << diskInfo; + } + } + Volumes_No_Drive_Keys.sort(); + foreach (QString key, Volumes_No_Drive_Keys) { + if (Volumes.contains(key)) { + QVolume volume = Volumes.value(key); + QDiskInfo diskInfo = qVolumeToqDiskInfo(volume); + if (diskInfo.type() == "iphone") { + if (diskInfo.activation_root_uri() != QString("afc://%1/").arg(diskInfo.uuid())) { + continue; + } + } + DiskInfos.insert(diskInfo.id(), diskInfo); + qCDebug(mountManager()) << diskInfo; + } + } + NoVolumes_Mounts_Keys.sort(); + foreach (QString key, NoVolumes_Mounts_Keys) { + if (Mounts.contains(key)) { + QMount mount = Mounts.value(key); + QDiskInfo diskInfo = qMountToqDiskinfo(mount); + DiskInfos.insert(diskInfo.id(), diskInfo); + qCDebug(mountManager()) << diskInfo; + } + } + qCDebug(mountManager()) << Mounts; +} + +void GvfsMountManager::listMountsBylsblk() +{ + QString output; + QString err; + QProcess p; + p.setProgram("lsblk"); + p.setArguments({"-OJlb"}); + p.start(); + p.waitForFinished(-1); + output = p.readAllStandardOutput(); + err = p.readAllStandardError(); + bool status = p.exitStatus() == QProcess::NormalExit && p.exitCode() == 0; + if (status) { + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(output.toLocal8Bit(), &error); + if (error.error == QJsonParseError::NoError) { + QJsonObject devObj = doc.object(); + foreach (QString key, devObj.keys()) { + if (key == "blockdevices") { + QJsonArray objArray = devObj.value(key).toArray(); + for (int i = 0; i < objArray.count(); i++) { + QJsonObject obj = objArray.at(i).toObject(); + QDiskInfo diskInfo; + + if (obj.contains("mountpoint")) { + QString mountPoint = obj.value("mountpoint").toString(); + if (mountPoint.isEmpty() || mountPoint == "/") { + continue; + } else { + diskInfo.setMounted_root_uri(QString("file://%1").arg(obj.value("mountpoint").toString())); + } + } + + if (obj.contains("name")) { + diskInfo.setName(obj.value("name").toString()); + } + if (obj.contains("path")) { + diskInfo.setUnix_device(obj.value("path").toString()); + diskInfo.setId(diskInfo.unix_device()); + } + if (obj.contains("fstype")) { + diskInfo.setId_filesystem(obj.value("fstype").toString()); + } + if (obj.contains("label")) { + //diskInfo.setName(obj.value("label").toString()); + } + if (obj.contains("uuid")) { + diskInfo.setUuid(obj.value("uuid").toString()); + } + if (obj.contains("rm")) { + QVariant data(obj.value("rm").toVariant()); + diskInfo.setIs_removable(data.toBool()); + } + if (obj.contains("fsavail") && obj.value("fsavail").type() != QJsonValue::Type::Null) { + diskInfo.setFree(obj.value("fsavail").toVariant().toULongLong()); + } + if (obj.contains("fssize") && obj.value("fssize").type() != QJsonValue::Type::Null) { + diskInfo.setTotal(obj.value("fssize").toVariant().toULongLong()); + } else if (obj.contains("size") && obj.value("size").type() != QJsonValue::Type::Null) { + diskInfo.setTotal(obj.value("size").toVariant().toULongLong()); + } + + diskInfo.setCan_unmount(true); + diskInfo.setCan_mount(false); + diskInfo.setCan_eject(false); + if (diskInfo.is_removable()) { + diskInfo.setType("removable"); + } else { + diskInfo.setType("native"); + } + Lsblk_Keys.append(diskInfo.unix_device()); + DiskInfos.insert(diskInfo.id(), diskInfo); + } + } + } + } else { + qCDebug(mountManager()) << error.errorString(); + } + } else { + qCDebug(mountManager()) << status << output << err; + } +} + +bool GvfsMountManager::errorCodeNeedSilent(int errorCode) +{ + switch (errorCode) { + case G_IO_ERROR_NOT_SUPPORTED: + case G_IO_ERROR_DBUS_ERROR: // to avoid: An operation is already pending. + return true; + default: + break; + } + + return false; +} + +/* + * get real mount url from mounted_root_uri of info + * smb://10.0.12.150/share -> file:///run/user/1000/gvfs/smb-share:server=10.0.12.150,share=share +*/ +DUrl GvfsMountManager::getRealMountUrl(const QDiskInfo &info) +{ + QString path = QString("/run/user/%1/gvfs").arg(getuid()); + + QString mounted_root_uri = info.mounted_root_uri(); + DUrl MountPointUrl = DUrl(mounted_root_uri); + + // blumia: It's possible that the device is not managed by gvfs so the real mount url won't be under + // gvfs mount path, try `sshfs` mount something... + // blumia: We assume `mounted_root_uri()` can get the correct mount path, and only return it directly + // if it is a local file path. + if (MountPointUrl.isLocalFile()) { + return MountPointUrl; + } + + if (mounted_root_uri == "/") { + MountPointUrl = DUrl::fromLocalFile("/"); + } else { + if ((info.type() != "native" && + info.type() != "removable" && + info.type() != "dvd") && !info.id_filesystem().isEmpty()) { + if (info.type() == "network") { + MountPointUrl = DUrl::fromLocalFile(QString("%1/%2%3").arg(path, info.id_filesystem(), DUrl(info.default_location()).path())); + } else { + MountPointUrl = DUrl::fromLocalFile(QString("%1/%2").arg(path, info.id_filesystem())); + } + } + } + + return MountPointUrl; +} + +QString GvfsMountManager::getVolTag(GMount *m) +{ + if (!m) return QString(); + QMount qMount = gMountToqMount(m); + QVolume volume = getVolumeByMountedRootUri(qMount.mounted_root_uri()); + return volume.unix_device().mid(5); +} + +QString GvfsMountManager::getVolTag(GVolume *v) +{ + if (!v) return QString(); + QVolume qVolume = gVolumeToqVolume(v); + return qVolume.unix_device().mid(5); +} + +void GvfsMountManager::cancellMountSync(GMountOperation *op) +{ + if (CancellHash.contains(op)) { + GCancellable * cancell = CancellHash.value(op); + CancellHash.remove(op); + if (cancell) { + g_cancellable_cancel(cancell); + //84859 g_cancellable_get_fd或g_cancellable_make_pollfd 后才能调用g_cancellable_release_fd + //g_cancellable_release_fd(cancell); + g_object_unref(cancell); + } + } +} + +void GvfsMountManager::autoMountAllDisks() +{ + // check if we are in live system, don't do auto mount if we are in live system. + static QMap cmdline = FileUtils::getKernelParameters(); + if (cmdline.value("boot", "") == QStringLiteral("live")) { + return; + } + + if (DFMApplication::instance()->genericAttribute(DFMApplication::GA_AutoMount).toBool()) { + foreach (const QDiskInfo &diskInfo, DiskInfos.values()) { + if (diskInfo.can_mount()) { + if (isDeviceCrypto_LUKS(diskInfo)) + continue; + mount(diskInfo, true); + } + } + } +} + +void GvfsMountManager::mount(const QString &path, bool silent) +{ + QDiskInfo diskInfo = getDiskInfo(path); + mount(diskInfo, silent); +} + +void GvfsMountManager::mount(const QDiskInfo &diskInfo, bool silent) +{ + if (!diskInfo.mounted_root_uri().isEmpty()) { + mount_mounted(diskInfo.mounted_root_uri(), silent); + } else if (!diskInfo.activation_root_uri().isEmpty()) { + mount_mounted(diskInfo.activation_root_uri(), silent); + } else { + mount_device(diskInfo.unix_device(), silent); + } +} + +MountStatus GvfsMountManager::mount_sync(const DFMUrlBaseEvent &event) +{ + DUrl fileUrl = event.fileUrl(); + // fix bug 100864 获取真实的网络挂载点 + static const QRegExp rxPath(R"((^/[^/]+))"); + if (rxPath.indexIn(fileUrl.path()) != -1) { + qInfo() << rxPath.cap(1); + fileUrl.setPath(rxPath.cap(1)); + } + GFile *file = g_file_new_for_uri(fileUrl.toString().toUtf8().constData()); + + if (file == nullptr) + return MOUNT_FAILED; + + GMountOperation *op = new_mount_op(false); + + + QSharedPointer evettemp(new DFMUrlBaseEvent(event)); + + MountEventHash.insert(op, evettemp); + QSharedPointer event_loop(new QEventLoop); + eventLoopHash.insert(op, event_loop); + + QSharedPointer timer(new QTimer); + MountTimerHash.insert(op,timer); + timer->connect(timer.data(), &QTimer::timeout, timer.data(),[=](){ + cancellMountSync(op); + qInfo() << "mount_sync time out !!!!!!"; + }); + timer->setInterval(10000); + + GCancellable *cancell = g_cancellable_new(); + if (cancell) + CancellHash.insert(op,cancell); + + g_file_mount_enclosing_volume(file, static_cast(0), + op, cancell, mount_done_cb, op); + timer->start(); + int ret = event_loop->exec(); + if (MountTimerHash.value(op)) + MountTimerHash.value(op)->stop(); + if (askPasswordDialogHash.value(op)) + askPasswordDialogHash.value(op)->deleteLater(); + MountEventHash.remove(op); + MountTimerHash.remove(op); + if (CancellHash.value(op)) { + g_object_unref(CancellHash.value(op)); + } + CancellHash.remove(op); + eventLoopHash.remove(op); + AskingPasswordHash.remove(op); + askPasswordDialogHash.remove(op); + if (SMBLoginObjHash.value(op)) + delete SMBLoginObjHash.value(op); + SMBLoginObjHash.remove(op); + + g_object_unref(file); + g_object_unref(op); + + return static_cast(ret); +} + +void GvfsMountManager::mount_done_cb(GObject *object, GAsyncResult *res, gpointer user_data) +{ + //fix 22749 修复输入秘密错误了后,2到3次才弹提示框 + bool bshow = true; + GMountOperation *op = static_cast(user_data); + if (MountTimerHash.contains(op)) + MountTimerHash.value(op)->stop(); + + if (askPasswordDialogHash.value(op)) { + askPasswordDialogHash.value(op)->deleteLater(); + askPasswordDialogHash.remove(op); + } else { + bshow = false; + } + gboolean succeeded; + GError *error = nullptr; + + MountStatus status = MOUNT_FAILED; + + succeeded = g_file_mount_enclosing_volume_finish(G_FILE(object), res, &error); + + DUrl rootUri = DUrl(g_file_get_uri(G_FILE (object))); + + if (!succeeded) { + Q_ASSERT(error->domain == G_IO_ERROR); + emit fileSignalManager->requestRemoveSmbUrl(rootUri); + bool showWarnDlg = false; + + switch (error->code) { + case G_IO_ERROR_FAILED: + if (AskingPasswordHash.value(op)) { + status = MOUNT_PASSWORD_WRONG; + } else { + showWarnDlg = true; + } + break; + + case G_IO_ERROR_FAILED_HANDLED: // Operation failed and a helper program has already interacted with the user. Do not display any error dialog. + status = MOUNT_CANCEL; + break; + + default: + showWarnDlg = true; + break; + } + +// if (showWarnDlg) { +// DThreadUtil::runInMainThread(dialogManager, &DialogManager::showErrorDialog, +// tr("Mounting device error"), QString(error->message)); +// } + if (showWarnDlg) { + DThreadUtil::runInMainThread(dialogManager, &DialogManager::showErrorDialog, + tr("Mounting device error"), QString()); + qInfo() << "Mounting device error: " << QString(error->message); + } else { + //fix 22749 修复输入秘密错误了后,2到3次才弹提示框 + if (status == MOUNT_PASSWORD_WRONG && bshow) { + DThreadUtil::runInMainThread(dialogManager, &DialogManager::showErrorDialog, + tr("Mounting device error"), tr("Wrong username or password")); + } else if (status == MOUNT_CANCEL && bshow) { + DThreadUtil::runInMainThread(dialogManager, &DialogManager::showErrorDialog, + tr("Mounting device error"), tr(error->message)); + } + + } + qCDebug(mountManager()) << "g_file_mount_enclosing_volume_finish" << succeeded << error; + qCDebug(mountManager()) << "username" << g_mount_operation_get_username(op) << error->message; + } else { + qCDebug(mountManager()) << "g_file_mount_enclosing_volume_finish" << succeeded << AskingPasswordHash.value(op); + if (AskingPasswordHash.value(op) && SMBLoginObjHash.value(op)) { + SMBLoginObjHash.value(op)->insert("id", rootUri.toString()); + if (SMBLoginObjHash.value(op)->value("passwordSave").toInt() == 2) { + SMBLoginObjHash.value(op)->remove("password"); + emit fileSignalManager->requsetCacheLoginData(*SMBLoginObjHash.value(op)); + } + delete SMBLoginObjHash.value(op); + SMBLoginObjHash.remove(op); + } else { + qCDebug(mountManager()) << "username" << g_mount_operation_get_username(op); + } + + status = MOUNT_SUCCESS; + } + + AskingPasswordHash.remove(op); + + if (eventLoopHash.value(op)) { + eventLoopHash.value(op)->exit(status); + } + + emit fileSignalManager->requestChooseSmbMountedFile(*MountEventHash.value(op)); + MountEventHash.remove(op); +} + +void GvfsMountManager::mount_mounted(const QString &mounted_root_uri, bool silent) +{ + std::string file_uri = mounted_root_uri.toStdString(); + const char *f = file_uri.data(); + GFile *file; + file = g_file_new_for_uri(f); + if (file == nullptr) + return; + GMountOperation *op; + op = new_mount_op(); + g_file_mount_enclosing_volume(file, G_MOUNT_MOUNT_NONE, op, nullptr, &GvfsMountManager::mount_with_mounted_uri_done, silent ? &silent : nullptr); + g_object_unref(file); +} + +void GvfsMountManager::mount_with_mounted_uri_done(GObject *object, GAsyncResult *res, gpointer user_data) +{ + gboolean succeeded; + GError *error = nullptr; + + succeeded = g_file_mount_enclosing_volume_finish(G_FILE(object), res, &error); + + if (!succeeded) { + qCDebug(mountManager()) << "Error mounting location: " << error->message << error->code; + if (!user_data && !errorCodeNeedSilent(error->code)) { + fileSignalManager->requestShowErrorDialog(QString::fromLocal8Bit(error->message), QString(" ")); + } + } +} + +void GvfsMountManager::mount_device(const QString &unix_device, bool silent) +{ + if (unix_device.isEmpty()) + return; + std::string file_uri = unix_device.toStdString(); + const char *device_file = file_uri.data(); + + GVolumeMonitor *volume_monitor; + GList *volumes; + GList *l; + int outstanding_mounts = 0; + volume_monitor = g_volume_monitor_get(); + + volumes = g_volume_monitor_get_volumes(volume_monitor); + for (l = volumes; l != nullptr; l = l->next) { + GVolume *volume = G_VOLUME(l->data); + + if (g_strcmp0(g_volume_get_identifier(volume, + G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE), device_file) == 0) { + GMountOperation *op; + + op = new_mount_op(); + + g_volume_mount(volume, + G_MOUNT_MOUNT_NONE, + op, + nullptr, + &GvfsMountManager::mount_with_device_file_cb, + silent ? &silent : nullptr); + + outstanding_mounts++; + } + } + g_list_free_full(volumes, g_object_unref); + + if (outstanding_mounts == 0) { + qDebug() << "No volume for device file" << device_file; + return; + } + g_object_unref(volume_monitor); +} + +bool GvfsMountManager::try_to_get_mounted_point(GVolume *volume) +{ + if(volume == nullptr) + return false; + + GMount *mount = nullptr; + GFile *root = nullptr; + char *mount_path = nullptr; + mount = g_volume_get_mount(volume); + root = g_mount_get_root(mount); + mount_path = g_file_get_path(root); + bool ret = (mount_path != nullptr); + qCDebug(mountManager()) << "Mounted" << g_volume_get_identifier(volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) << "at" << mount_path; + + g_object_unref(mount); + g_object_unref(root); + g_free(mount_path); + return ret; +} + +void GvfsMountManager::mount_with_device_file_cb(GObject *object, GAsyncResult *res, gpointer user_data) +{ + GVolume *volume; + gboolean succeeded; + GError *error = nullptr; + + volume = G_VOLUME(object); + + succeeded = g_volume_mount_finish(volume, res, &error); + QVolume qVolume = gVolumeToqVolume(volume); + + // 返回false 的情况,如果有挂载点也算成功,此时要看看 gio 相关流程是否存在bug + if (!succeeded && !try_to_get_mounted_point(volume)) { + qCDebug(mountManager()) << "Error mounting: " << g_volume_get_identifier(volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) + << error->message << user_data << error->code; + + //! 下面这样做只是为了字符串翻译,因为错误信息是底层返回的 + QString err = QString::fromLocal8Bit(error->message); + bool format = true; // 根据错误的种类, 选择是否需要格式化, 这里仅对于错误 G_IO_ERROR_DBUS_ERROR 不处理, 后续可能会扩充 + switch (error->code) { + case G_IO_ERROR_FAILED: + err = QString(tr("No key available to unlock device")); + break; + case G_IO_ERROR_DBUS_ERROR: + format = false; + break; + default: + break; + } + if (AskedPasswordWhileMountDisk) { // 显示过密码框的设备,说明该设备可解锁,但密码不一定正确或取消了,不需要提示用户格式化 + if (!user_data && !errorCodeNeedSilent(error->code)) { + fileSignalManager->requestShowErrorDialog(err, QString(" ")); + } + } else { + if (format) { + dialogManager->showFormatDialog(qVolume.drive_unix_device()); + } + } + } + AskedPasswordWhileMountDisk = false; +} + +void GvfsMountManager::unmount(const QDiskInfo &diskInfo) +{ + if (diskInfo.can_unmount() && !diskInfo.mounted_root_uri().isEmpty()) { + unmount_mounted(diskInfo.mounted_root_uri()); + } +} + +void GvfsMountManager::unmount(const QString &id) +{ + QDiskInfo diskInfo = getDiskInfo(id, false); + unmount(diskInfo); +} + +void GvfsMountManager::unmount_mounted(const QString &mounted_root_uri) +{ + if (mounted_root_uri.isEmpty()) + return; + + GFile *file; + file = g_file_new_for_uri(QFile::encodeName(mounted_root_uri)); + if (file == nullptr) + return; + + GMount *mount; + GError *error = nullptr; + GMountOperation *mount_op; + + mount = g_file_find_enclosing_mount(file, nullptr, &error); + if (mount == nullptr) { + bool no_permission = false; + + QFileInfo info(QUrl(mounted_root_uri).toLocalFile()); + + while (!info.exists() && info.fileName() != QDir::rootPath() && !info.absolutePath().isEmpty()) { + info.setFile(info.absolutePath()); + } + + if (info.exists()) { + if (getuid() == info.ownerId()) { + if (!info.permission(QFile::ReadOwner | QFile::ExeOwner)) + no_permission = true; + } else if (getgid() == info.groupId()) { + if (!info.permission(QFile::ReadGroup | QFile::ExeGroup)) + no_permission = true; + } else if (!info.permission(QFile::ReadOther | QFile::ExeOther)) { + no_permission = true; + } + } + + if (no_permission) { + QString user_name = info.owner(); + + if (info.absoluteFilePath().startsWith("/media/")) { + user_name = info.baseName(); + } + + DDialog error_dilaog(tr("The disk is mounted by user \"%1\", you cannot unmount it.").arg(user_name), QString(" ")); + + error_dilaog.setIcon(QIcon::fromTheme("dialog-error")); + error_dilaog.addButton(tr("Confirm","button"), true, DDialog::ButtonRecommend); + error_dilaog.setModal(true); + error_dilaog.exec(); + return; + } + + DDialog error_dilaog(tr("Cannot find the mounted device"), QString(error->message)); + + g_error_free(error); + + error_dilaog.setIcon(QIcon::fromTheme("dialog-error")); + error_dilaog.addButton(tr("Confirm","button"), true, DDialog::ButtonRecommend); + error_dilaog.setModal(true); + error_dilaog.exec(); + return; + } + + g_error_free(error); + char *local_mount_point = g_file_get_path(file); + + mount_op = new_mount_op(); + g_mount_unmount_with_operation(mount, G_MOUNT_UNMOUNT_NONE, mount_op, nullptr, &GvfsMountManager::unmount_done_cb, local_mount_point); + g_object_unref(mount_op); + g_object_unref(file); +} + + +void GvfsMountManager::unmount_done_cb(GObject *object, GAsyncResult *res, gpointer user_data) +{ + gboolean succeeded; + GError *error = nullptr; + + succeeded = g_mount_unmount_with_operation_finish(G_MOUNT(object), res, &error); + + if (!succeeded) { + DDialog error_dilaog(tr("Cannot unmount the device"), QString(error->message)); + + error_dilaog.setIcon(QIcon::fromTheme("dialog-error")); + error_dilaog.addButton(tr("Confirm","button"), true, DDialog::ButtonRecommend); + error_dilaog.setModal(true); + error_dilaog.exec(); + } else { + char *local_mount_point = reinterpret_cast(user_data); + + if (local_mount_point) { + // 由于卸载gvfs设备时不会触发文件系统的inotify, 所以此处手动模拟文件夹被移除的信号 + const DUrl durl = DUrl::fromLocalFile(local_mount_point); + DAbstractFileWatcher::ghostSignal(durl.parentUrl(), &DAbstractFileWatcher::fileDeleted, durl); + + g_free(local_mount_point); + } + + // 从缓存的Network节点中清理数据 + GFile *root_file = g_mount_get_root(G_MOUNT(object)); + char *root_uri = g_file_get_uri(root_file); + const QString &root_url = QFile::decodeName(root_uri); + + if (root_uri && !root_url.startsWith("file://")) { + DUrlList dirty_list; + + for (auto begin = NetworkManager::NetworkNodes.keyBegin(); begin != NetworkManager::NetworkNodes.keyEnd(); ++begin) { + if (begin->toString().startsWith(root_url.endsWith("/") ? root_url.left(root_url.size() - 1) : root_url)) { + dirty_list << *begin; + } + } + + for (const DUrl &durl : dirty_list) + NetworkManager::NetworkNodes.remove(durl); + } + + if (root_uri) g_free(root_uri); + if (root_file) g_object_unref(root_file); + } + + if (G_IS_MOUNT(object)) g_object_unref(G_MOUNT(object)); +} + +void GvfsMountManager::eject(const QString &path) +{ + foreach (const QDiskInfo &diskInfo, DiskInfos.values()) { + if (!path.isEmpty() && diskInfo.can_eject() && diskInfo.mounted_root_uri() == path) { + eject_mounted(diskInfo.mounted_root_uri()); + return; + } else if (!path.isEmpty() && diskInfo.can_eject() && path == diskInfo.unix_device()) { + eject_device(diskInfo.unix_device()); + return; + } + } +} + +void GvfsMountManager::eject(const QDiskInfo &diskInfo) +{ + if (!diskInfo.mounted_root_uri().isEmpty()) { + eject_mounted(diskInfo.mounted_root_uri()); + } else { + eject_device(diskInfo.unix_device()); + } +} + +void GvfsMountManager::eject_device(const QString &unix_device) +{ + if (unix_device.isEmpty()) + return; + std::string file_uri = unix_device.toStdString(); + const char *device_file = file_uri.data(); + + GVolumeMonitor *volume_monitor; + GList *volumes; + GList *l; + int outstanding_mounts = 0; + volume_monitor = g_volume_monitor_get(); + + volumes = g_volume_monitor_get_volumes(volume_monitor); + for (l = volumes; l != nullptr; l = l->next) { + GVolume *volume = G_VOLUME(l->data); + + if (g_strcmp0(g_volume_get_identifier(volume, + G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE), device_file) == 0) { + GMountOperation *op; + + op = new_mount_op(); + + g_volume_eject_with_operation(volume, + G_MOUNT_UNMOUNT_NONE, + op, + nullptr, + &GvfsMountManager::eject_with_device_file_cb, + op); + + outstanding_mounts++; + } + } + g_list_free_full(volumes, g_object_unref); + + if (outstanding_mounts == 0) { + qCDebug(mountManager()) << "No volume for device file: " << device_file; + return; + } + g_object_unref(volume_monitor); +} + +void GvfsMountManager::eject_with_device_file_cb(GObject *object, GAsyncResult *res, gpointer user_data) +{ + Q_UNUSED(user_data) + GVolume *volume; + gboolean succeeded; + GError *error = nullptr; + + volume = G_VOLUME(object); + + succeeded = g_volume_eject_with_operation_finish(volume, res, &error); + + if (!succeeded) { + DDialog error_dilaog(tr("Cannot eject the device \"%1\"").arg(g_volume_get_identifier(volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE)), + QString(error->message)); + + error_dilaog.setIcon(QIcon::fromTheme("dialog-error")); + error_dilaog.addButton(tr("Confirm","button"), true, DDialog::ButtonRecommend); + error_dilaog.setModal(true); + error_dilaog.exec(); + } else { + qCDebug(mountManager()) << "eject" << g_volume_get_identifier(volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) << "succeeded"; + } +} + +void GvfsMountManager::eject_mounted(const QString &mounted_root_uri) +{ + if (mounted_root_uri.isEmpty()) + return; + + std::string file_uri = mounted_root_uri.toStdString(); + GFile *file = g_file_new_for_uri(file_uri.data()); + if (file == nullptr) + return; + + GError *error = nullptr; + GMount *mount = g_file_find_enclosing_mount(file, nullptr, &error); + if (mount == nullptr) { + DDialog error_dilaog(tr("Cannot find the mounted device"), QString(error->message)); + g_error_free(error); + error_dilaog.setIcon(QIcon::fromTheme("dialog-error")); + error_dilaog.addButton(tr("Confirm","button"), true, DDialog::ButtonRecommend); + error_dilaog.setModal(true); + error_dilaog.exec(); + return; + } + g_error_free(error); + GMountOperation *mount_op = new_mount_op(); + g_mount_eject_with_operation(mount, G_MOUNT_UNMOUNT_NONE, mount_op, nullptr, &GvfsMountManager::eject_with_mounted_file_cb, nullptr); + g_object_unref(mount_op); + +} + +void GvfsMountManager::eject_with_mounted_file_cb(GObject *object, GAsyncResult *res, gpointer user_data) +{ + Q_UNUSED(user_data) + GMount *mount; + gboolean succeeded; + GError *error = nullptr; + + mount = G_MOUNT(object); + succeeded = g_mount_eject_with_operation_finish(G_MOUNT(object), res, &error); + + g_object_unref(G_MOUNT(object)); + + if (!succeeded) { + qDebug() << "Error ejecting mount:" << error->message; + } else { + qCDebug(mountManager()) << "eject" << g_mount_get_name(mount) << "succeeded"; + } +} + +void GvfsMountManager::stop_device(const QString &drive_unix_device) +{ + if (drive_unix_device.isEmpty()) + return; + std::string file_uri = drive_unix_device.toStdString(); + const char *device_file = file_uri.data(); + + GVolumeMonitor *volume_monitor; + GList *drives, *d; + int i; + volume_monitor = g_volume_monitor_get(); + + drives = g_volume_monitor_get_connected_drives(volume_monitor); + for (i = 0, d = drives; d != nullptr; d = d->next, i++) { + GDrive *drive = static_cast(d->data); + + if (g_strcmp0(g_drive_get_identifier(drive, "unix-device"), device_file) == 0) { + GMountOperation *op; + + op = new_mount_op(); + + g_drive_stop(drive, + G_MOUNT_UNMOUNT_NONE, + op, + nullptr, + &GvfsMountManager::stop_with_device_file_cb, + op); + } + + } + g_list_free_full(drives, g_object_unref); + g_object_unref(volume_monitor); +} + +void GvfsMountManager::stop_with_device_file_cb(GObject *object, GAsyncResult *res, gpointer user_data) +{ + Q_UNUSED(user_data) + GDrive *drive; + gboolean succeeded; + GError *error = nullptr; + + drive = G_DRIVE(object); + + succeeded = g_drive_stop_finish(drive, res, &error); + + if (!succeeded) { + qDebug() << "Error remove disk:" << g_drive_get_identifier(drive, "unix-device") << error->message; + } else { + qCDebug(mountManager()) << "Safely remove disk" << g_drive_get_identifier(drive, "unix-device") << "succeeded"; + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/gvfsmountmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/gvfsmountmanager.h new file mode 100644 index 0000000..34d7d11 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/gvfsmountmanager.h @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef GVFSMOUNTMANAGER_H +#define GVFSMOUNTMANAGER_H + +#include +#include +#include "dfmevent.h" +#include "durl.h" + +class QDrive; +class QVolume; +class QMount; +class QDiskInfo; +class MountSecretDiskAskPasswordDialog; +class MountAskPasswordDialog; + +#undef signals +extern "C" { + #include +} +#define signals public + +typedef enum { + MOUNT_SUCCESS, + MOUNT_FAILED, + MOUNT_CANCEL, + MOUNT_PASSWORD_WRONG, +}MountStatus; + +class GvfsMountManager : public QObject +{ + Q_OBJECT +public: + explicit GvfsMountManager(QObject *parent = nullptr); + void initConnect(); + + enum MountOpState{ + MOUNT_OP_NONE, + MOUNT_OP_ASKED, + MOUNT_OP_ABORTED + }; + + //fix: 每次弹出光驱时需要删除临时缓存数据文件 + static QString g_qVolumeId; + + static GvfsMountManager* instance(); + static MountSecretDiskAskPasswordDialog* mountSecretDiskAskPasswordDialog; + + static QMap Drives; + static QMap Volumes; + static QMap Mounts; + static QMap DiskInfos; + + static QStringList Drives_Keys; + static QStringList Volumes_Drive_Keys; + static QStringList Volumes_No_Drive_Keys; + + static QStringList NoVolumes_Mounts_Keys; + static QStringList Lsblk_Keys; + + static bool AskedPasswordWhileMountDisk; + + static QHash> MountEventHash; + static QHash> MountTimerHash; + static QHash CancellHash; + static QHash> eventLoopHash; + static QHash AskingPasswordHash; + static QHash askPasswordDialogHash; + static QHash SMBLoginObjHash; + + static QStringList getIconNames(GThemedIcon *icon); + static QDrive gDriveToqDrive(GDrive *drive); + static QVolume gVolumeToqVolume(GVolume *volume); + static QMount gMountToqMount(GMount *mount); + + static QDiskInfo qVolumeToqDiskInfo(const QVolume& volume); + static QDiskInfo qMountToqDiskinfo(const QMount& mount, bool updateUsage = true); + + static QVolume getVolumeByMountedRootUri(const QString& mounted_root_uri); + static QVolume getVolumeByUnixDevice(const QString& unix_device); + + static void monitor_mount_added_root(GVolumeMonitor *volume_monitor, GMount *mount); + static void monitor_mount_removed_root(GVolumeMonitor *volume_monitor, GMount *mount); + + static void monitor_mount_added(GVolumeMonitor *volume_monitor, GMount *mount); + static void monitor_mount_removed (GVolumeMonitor *volume_monitor, GMount *mount); + static void monitor_mount_changed (GVolumeMonitor *volume_monitor, GMount *mount); + + static void monitor_volume_added (GVolumeMonitor *volume_monitor, GVolume *volume); + static void monitor_volume_removed (GVolumeMonitor *volume_monitor, GVolume *volume); + static void monitor_volume_changed (GVolumeMonitor *volume_monitor, GVolume *volume); + + + static GMountOperation* new_mount_op(bool isDisk); + static void ask_question_cb(GMountOperation *op, const char *message, const GStrv choices); + static void ask_password_cb(GMountOperation *op, + const char *message, + const char *default_user, + const char *default_domain, + GAskPasswordFlags flags); + static void ask_disk_password_cb(GMountOperation *op, + const char *message, + const char *default_user, + const char *default_domain, + GAskPasswordFlags flags); + + static void mount(const QString& path, bool silent = false); + static void mount(const QDiskInfo& diskInfo, bool silent = false); + static MountStatus mount_sync(const DFMUrlBaseEvent &event); + static void mount_done_cb(GObject *object, GAsyncResult *res, gpointer user_data); + static void mount_device(const QString& unix_device, bool silent = false); + static void mount_mounted(const QString& mounted_root_uri, bool silent = false); + static void unmount(const QDiskInfo& diskInfo); + static void unmount(const QString& id); + static void unmount_mounted(const QString& mounted_root_uri); + static void eject(const QString& path); + static void eject(const QDiskInfo& diskInfo); + static void eject_device(const QString& unix_device); + static void eject_mounted(const QString& mounted_root_uri); + static void stop_device(const QString& drive_unix_device); + + static void mount_with_mounted_uri_done(GObject *object, GAsyncResult *res, gpointer user_data); + static void mount_with_device_file_cb (GObject *object, GAsyncResult *res, gpointer user_data); + static void unmount_done_cb(GObject *object, GAsyncResult *res, gpointer user_data); + static void eject_with_device_file_cb(GObject *object, GAsyncResult *res, gpointer user_data); + static void eject_with_mounted_file_cb(GObject *object, GAsyncResult *res, gpointer user_data); + static void stop_with_device_file_cb(GObject *object, GAsyncResult *res, gpointer user_data); + + static void printVolumeMounts(); + + static QDiskInfo getDiskInfo(const QString& path, bool bupdate = true); + static bool isDVD(const QVolume& volume); + static bool isIgnoreUnusedMounts(const QMount& mount); + + static QString getDriveUnixDevice(const QString& unix_device); + static bool isDeviceCrypto_LUKS(const QDiskInfo& diskInfo); + + static DUrl getRealMountUrl(const QDiskInfo& info); + + static QString getVolTag(GMount *m); + static QString getVolTag(GVolume *v); + //cancell mount_sync + static void cancellMountSync(GMountOperation *op); + + void autoMountAllDisks(); + +private: + static bool try_to_get_mounted_point(GVolume *volume); + +signals: + void loadDiskInfoFinished(); + void mount_added(const QDiskInfo& diskInfo); + void mount_removed(const QDiskInfo& diskInfo); + void volume_added(const QDiskInfo& diskInfo); + void volume_removed(const QDiskInfo& diskInfo); + void volume_changed(const QDiskInfo& diskInfo); // only for cd/dvd + +public slots: + void startMonitor(); + void listDrives(); + void listVolumes(); + void listMounts(); + void updateDiskInfos(); + + void listMountsBylsblk(); + +private: + GVolumeMonitor* m_gVolumeMonitor = nullptr; + static bool errorCodeNeedSilent(int errorCode); +}; + +#endif // GVFSMOUNTMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/mountaskpassworddialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/mountaskpassworddialog.cpp new file mode 100644 index 0000000..158c5a5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/mountaskpassworddialog.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "mountaskpassworddialog.h" +#include +#include +#include +#include "utils.h" + +MountAskPasswordDialog::MountAskPasswordDialog(QWidget *parent) : DDialog(parent) +{ + setModal(true); + initUI(); + initConnect(); +} + +MountAskPasswordDialog::~MountAskPasswordDialog() +{ + +} + +void MountAskPasswordDialog::initUI() +{ + layout()->setSizeConstraint(QLayout::SetFixedSize); + + QStringList buttonTexts; + buttonTexts << tr("Cancel","button") << tr("Connect","button"); + + QFrame* content = new QFrame; + + QLabel* connectTypeLabel = new QLabel(tr("Log in as")); + connectTypeLabel->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); + connectTypeLabel->setFixedWidth(80); + + DButtonBox *anonmymousButtonBox = new DButtonBox(this); + anonmymousButtonBox->setEnabled(true); + m_anonymousButton = new DButtonBoxButton(tr("Anonymous")); + m_anonymousButton->setObjectName("AnonymousButton"); + m_anonymousButton->setCheckable(true); + m_anonymousButton->setMinimumWidth(100); + m_anonymousButton->setFocusPolicy(Qt::NoFocus); + m_registerButton = new DButtonBoxButton(tr("Registered user")); + m_registerButton->setObjectName("RegisterButton"); + m_registerButton->setCheckable(true); + m_registerButton->setMinimumWidth(100); + m_registerButton->setFocusPolicy(Qt::NoFocus); + + QList buttonList; + buttonList << m_anonymousButton << m_registerButton; + + anonmymousButtonBox->setButtonList(buttonList, true); + anonmymousButtonBox->setFocusPolicy(Qt::NoFocus); + + m_passwordFrame = new QFrame; + + QLabel* usernameLable = new QLabel(tr("Username")); + usernameLable->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); + usernameLable->setFixedWidth(80); + + m_usernameLineEdit = new QLineEdit; + m_usernameLineEdit->setMinimumWidth(240); + + m_domainLabel = new QLabel(tr("Domain")); + m_domainLabel->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); + m_domainLabel->setFixedWidth(80); + + m_domainLineEdit = new QLineEdit; + m_domainLineEdit->setMinimumWidth(240); + + QLabel* passwordLable = new QLabel(tr("Password")); + passwordLable->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); + passwordLable->setFixedWidth(80); + + m_passwordLineEdit = new DPasswordEdit; + m_passwordLineEdit->setMinimumWidth(240); + m_passwordLineEdit->setAttribute(Qt::WA_InputMethodEnabled, false); + + m_passwordButtonGroup = new QButtonGroup(this); + m_passwordButtonGroup->setExclusive(true); + + m_passwordCheckBox = new QCheckBox(); + QWidget *empty = new QWidget(); + m_passwordCheckBox->setText(tr("Remember password")); + + QHBoxLayout* anonymousLayout = new QHBoxLayout; + anonymousLayout->addWidget(anonmymousButtonBox); + anonymousLayout->setSpacing(0); + anonymousLayout->setContentsMargins(0, 0, 0, 0); + + QFormLayout* connectTypeLayout = new QFormLayout; + connectTypeLayout->setLabelAlignment(Qt::AlignVCenter | Qt::AlignLeft); + connectTypeLayout->addRow(connectTypeLabel, anonymousLayout); + + QFormLayout* inputLayout = new QFormLayout; + inputLayout->setLabelAlignment(Qt::AlignVCenter | Qt::AlignLeft); + inputLayout->setFormAlignment(Qt::AlignVCenter | Qt::AlignLeft); + inputLayout->addRow(usernameLable, m_usernameLineEdit); + inputLayout->addRow(m_domainLabel, m_domainLineEdit); + inputLayout->addRow(passwordLable, m_passwordLineEdit); + inputLayout->addRow(empty, m_passwordCheckBox); + inputLayout->setSpacing(10); + + QVBoxLayout* passwordFrameLayout = new QVBoxLayout; + passwordFrameLayout->addLayout(inputLayout, Qt::AlignCenter); +// passwordFrameLayout->addWidget(m_passwordCheckBox); + passwordFrameLayout->setSpacing(0); + passwordFrameLayout->setContentsMargins(0, 0, 0, 0); + m_passwordFrame->setLayout(passwordFrameLayout); + + QVBoxLayout* mainLayout = new QVBoxLayout; + mainLayout->addSpacing(16); + mainLayout->addLayout(connectTypeLayout); + mainLayout->addWidget(m_passwordFrame); + mainLayout->setSpacing(10); + mainLayout->setContentsMargins(0, 0, 20, 0); + content->setLayout(mainLayout); + + addContent(content); + addButtons(buttonTexts); + setSpacing(10); + setDefaultButton(1); +} + +void MountAskPasswordDialog::initConnect() +{ + connect(m_anonymousButton, &DButtonBoxButton::clicked, this, [=](){ + m_passwordFrame->setVisible(false); + }); + connect(m_registerButton, &DButtonBoxButton::clicked, this, [=](){ + m_passwordFrame->setVisible(true); + }); + connect(this, SIGNAL(buttonClicked(int,QString)), this, SLOT(handleButtonClicked(int,QString))); +} + +QJsonObject MountAskPasswordDialog::getLoginData() +{ + return m_loginObj; +} + +void MountAskPasswordDialog::setLoginData(const QJsonObject &obj) +{ + m_loginObj = obj; + + QFontMetrics fm(this->font()); + const QString &str = fm.elidedText(m_loginObj.value("message").toString() + ,Qt::ElideMiddle, + this->size().width()-80); + + setTitle(str); + + if (m_loginObj.value("anonymous").toBool()) { + m_anonymousButton->click(); + } else { + m_registerButton->click(); + } + + m_usernameLineEdit->setText(m_loginObj.value("username").toString()); + m_domainLineEdit->setText(m_loginObj.value("domain").toString()); + m_passwordLineEdit->setText(m_loginObj.value("password").toString()); + + if (m_loginObj.value("passwordSave").toInt() == 2){ + m_passwordCheckBox->setChecked(true); + }else{ + m_passwordCheckBox->setChecked(false); + } + +} + +void MountAskPasswordDialog::handleConnect() +{ + m_loginObj.insert("message", title()); + + if (m_anonymousButton->isChecked()){ + m_loginObj.insert("anonymous", true); + }else{ + m_loginObj.insert("anonymous", false); + } + + m_loginObj.insert("username", m_usernameLineEdit->text()); + m_loginObj.insert("domain", m_domainLineEdit->text()); + m_loginObj.insert("password", m_passwordLineEdit->text()); + + if(m_passwordCheckBox->isChecked()){ + m_loginObj.insert("passwordSave", 2); + }else{ + m_loginObj.insert("passwordSave", 0); + } + accept(); +} + +void MountAskPasswordDialog::handleButtonClicked(int index, QString text) +{ + Q_UNUSED(text) + if (index == 1){ + handleConnect(); + } +} + +bool MountAskPasswordDialog::getDomainLineVisible() const +{ + return m_domainLineVisible; +} + +void MountAskPasswordDialog::setDomainLineVisible(bool domainLineVisible) +{ + if (domainLineVisible){ + m_domainLabel->show(); + m_domainLineEdit->show(); + }else{ + m_domainLabel->hide(); + m_domainLineEdit->hide(); + } + m_domainLineVisible = domainLineVisible; +} + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/mountaskpassworddialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/mountaskpassworddialog.h new file mode 100644 index 0000000..5adff69 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/mountaskpassworddialog.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef MOUNTASKPASSWORDDIALOG_H +#define MOUNTASKPASSWORDDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class MountAskPasswordDialog : public DDialog +{ + Q_OBJECT +public: + explicit MountAskPasswordDialog(QWidget *parent = nullptr); + ~MountAskPasswordDialog(); + + void initUI(); + void initConnect(); + QJsonObject getLoginData(); + + bool getDomainLineVisible() const; + void setDomainLineVisible(bool domainLineVisible); + +signals: + +public slots: + void setLoginData(const QJsonObject& obj); + void handleConnect(); + void handleButtonClicked(int index, QString text); + +private: + QLabel* m_messageLabel; + QLabel* m_domainLabel; + + QFrame* m_passwordFrame; + + DButtonBoxButton *m_anonymousButton; + DButtonBoxButton *m_registerButton; + + QLineEdit* m_usernameLineEdit; + QLineEdit* m_domainLineEdit; + DPasswordEdit* m_passwordLineEdit; + + QCheckBox* m_passwordCheckBox; + + QButtonGroup* m_passwordButtonGroup; + + + QJsonObject m_loginObj; + + bool m_domainLineVisible = true; +}; + +#endif // MOUNTASKPASSWORDDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/mountsecretdiskaskpassworddialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/mountsecretdiskaskpassworddialog.cpp new file mode 100644 index 0000000..b9998cd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/mountsecretdiskaskpassworddialog.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "mountsecretdiskaskpassworddialog.h" +#include +#include + + +MountSecretDiskAskPasswordDialog::MountSecretDiskAskPasswordDialog(const QString &tipMessage, QWidget *parent): + DDialog(parent), + m_descriptionMessage(tipMessage) +{ + setModal(true); + initUI(); + initConnect(); +} + +MountSecretDiskAskPasswordDialog::~MountSecretDiskAskPasswordDialog() +{ + +} + +void MountSecretDiskAskPasswordDialog::initUI() +{ + + QStringList buttonTexts; + buttonTexts << tr("Cancel","button") << tr("Unlock","button"); + + QFrame* content = new QFrame; + + m_titleLabel = new QLabel(tr("Input password to decrypt the disk")); + QFont titlefont; + titlefont.setPointSize(10); + m_titleLabel->setFont(titlefont); + m_descriptionLabel = new QLabel(m_descriptionMessage); + QFont tipfont; + tipfont.setPointSize(8); + m_descriptionLabel->setFont(tipfont); + +// m_passwordLabel = new QLabel(tr("Password")); + m_passwordLineEdit = new DPasswordEdit; + + +// m_neverRadioCheckBox = new QRadioButton(tr("never")); +// m_sessionRadioCheckBox = new QRadioButton(tr("session")); +// m_forerverRadioCheckBox = new QRadioButton(tr("forver")); + +// m_passwordButtonGroup = new QButtonGroup; +// m_passwordButtonGroup->addButton(m_neverRadioCheckBox); +// m_passwordButtonGroup->addButton(m_sessionRadioCheckBox); +// m_passwordButtonGroup->addButton(m_forerverRadioCheckBox); + + QVBoxLayout* mainLayout = new QVBoxLayout; + mainLayout->addWidget(m_titleLabel); + mainLayout->addWidget(m_descriptionLabel); + mainLayout->addSpacing(10); + mainLayout->addWidget(m_passwordLineEdit); + mainLayout->addSpacing(10); +// mainLayout->addWidget(m_neverRadioCheckBox, 0); +// mainLayout->addWidget(m_sessionRadioCheckBox, 1); +// mainLayout->addWidget(m_forerverRadioCheckBox, 2); + + + content->setLayout(mainLayout); + + addContent(content); + addButtons(buttonTexts); + setSpacing(10); + setDefaultButton(1); + setIcon(QIcon::fromTheme("dialog-warning")); +} + +void MountSecretDiskAskPasswordDialog::initConnect() +{ +// connect(m_passwordButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(handleRadioButtonClicked(int))); + connect(this, SIGNAL(buttonClicked(int,QString)), this, SLOT(handleButtonClicked(int,QString))); +} + +void MountSecretDiskAskPasswordDialog::handleRadioButtonClicked(int index) +{ + m_passwordSaveMode = index; +} + +void MountSecretDiskAskPasswordDialog::handleButtonClicked(int index, QString text) +{ + Q_UNUSED(text) + if (index == 1){ + m_password = m_passwordLineEdit->text(); + } + accept(); +} + +void MountSecretDiskAskPasswordDialog::showEvent(QShowEvent *event) +{ + m_passwordLineEdit->setFocus(); + DDialog::showEvent(event); +} + +int MountSecretDiskAskPasswordDialog::passwordSaveMode() const +{ + return m_passwordSaveMode; +} + +QString MountSecretDiskAskPasswordDialog::password() const +{ + return m_password; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/mountsecretdiskaskpassworddialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/mountsecretdiskaskpassworddialog.h new file mode 100644 index 0000000..e5db000 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/mountsecretdiskaskpassworddialog.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef MOUNTSECRETDISKASKPASSWORDDIALOG_H +#define MOUNTSECRETDISKASKPASSWORDDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class MountSecretDiskAskPasswordDialog : public DDialog +{ + Q_OBJECT +public: + explicit MountSecretDiskAskPasswordDialog(const QString& tipMessage, QWidget *parent = nullptr); + ~MountSecretDiskAskPasswordDialog(); + + void initUI(); + void initConnect(); + + QString password() const; + + int passwordSaveMode() const; + +public slots: + void handleRadioButtonClicked(int index); + void handleButtonClicked(int index, QString text); + +protected: + void showEvent(QShowEvent* event); + +private: + QString m_descriptionMessage = ""; + QLabel* m_titleLabel = nullptr; + QLabel* m_descriptionLabel = nullptr; + DPasswordEdit* m_passwordLineEdit = nullptr; + + QRadioButton* m_neverRadioCheckBox = nullptr; + QRadioButton* m_sessionRadioCheckBox = nullptr; + QRadioButton* m_forerverRadioCheckBox = nullptr; + + QButtonGroup* m_passwordButtonGroup = nullptr; + + + QString m_password = ""; + int m_passwordSaveMode = 0; +}; + +#endif // MOUNTSECRETDISKASKPASSWORDDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/networkmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/networkmanager.cpp new file mode 100644 index 0000000..4ac36e4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/networkmanager.cpp @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "networkmanager.h" +#include "dfmeventdispatcher.h" +#include "dfileservices.h" + +#include "app/filesignalmanager.h" +#include "app/define.h" + +#include "singleton.h" +#include "deviceinfo/udisklistener.h" + +#include "views/windowmanager.h" + +#include "gvfsmountmanager.h" + +#include +#include +#include + +DFM_USE_NAMESPACE + +enum EventLoopCode { + FetchFinished = 0, + MountFinished = 1, + FetchFailed = -1 +}; + +NetworkNode::NetworkNode() +{ + +} + +NetworkNode::~NetworkNode() +{ + +} + +QString NetworkNode::url() const +{ + return m_url; +} + +void NetworkNode::setUrl(const QString &url) +{ + m_url = url; +} + +QString NetworkNode::displayName() const +{ + return m_displayName; +} + +void NetworkNode::setDisplayName(const QString &displayName) +{ + m_displayName = displayName; +} +QString NetworkNode::iconType() const +{ + return m_iconType; +} + +void NetworkNode::setIconType(const QString &iconType) +{ + m_iconType = iconType; +} + +QDebug operator<<(QDebug dbg, const NetworkNode &node) +{ + dbg.nospace() << "NetworkNode{" + << "url: " << node.url() << ", " + << "displayName: " << node.displayName() << ", " + << "iconType: " << node.iconType() << ", " + << "}"; + return dbg; +} + + +QStringList NetworkManager::SupportScheme = { + "network", + "smb", + "ftp", + "sftp" +}; +QMap NetworkManager::NetworkNodes = {}; +GCancellable *NetworkManager::m_networks_fetching_cancellable = NULL; +QPointer NetworkManager::eventLoop; + +NetworkManager::NetworkManager(QObject *parent) : QObject(parent) +{ + qDebug() << "Create NetworkManager"; + qRegisterMetaType(QT_STRINGIFY(NetworkNodeList)); + initData(); + initConnect(); +} + +NetworkManager::~NetworkManager() +{ + initData(); + initConnect(); +} + +void NetworkManager::initData() +{ + +} + +void NetworkManager::initConnect() +{ + connect(fileSignalManager, &FileSignalManager::requestFetchNetworks, this, &NetworkManager::fetchNetworks); +} + +bool NetworkManager::fetch_networks(gchar *url, DFMEvent *e) +{ + QPointer oldEventLoop = eventLoop; + QEventLoop event_loop; + + eventLoop = &event_loop; + + GFile *network_file; + network_file = g_file_new_for_uri(url); + + if (m_networks_fetching_cancellable) { + g_cancellable_cancel(m_networks_fetching_cancellable); + g_clear_object(&m_networks_fetching_cancellable); + } + m_networks_fetching_cancellable = g_cancellable_new(); + + int ret = 0; + + do { + g_file_enumerate_children_async(network_file, + "standard::type,standard::target-uri,standard::name,standard::display-name,standard::icon,mountable::can-mount", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + m_networks_fetching_cancellable, + network_enumeration_finished, + e); + ret = eventLoop->exec(); + } while (ret == EventLoopCode::MountFinished); // 需要重新执行 g_file_enumerate_children_async + + g_clear_object(&network_file); + + if (oldEventLoop) { + oldEventLoop->exit(ret); + } + + return ret == EventLoopCode::FetchFinished; +} + +void NetworkManager::network_enumeration_finished(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GFileEnumerator *enumerator = nullptr; + GError *error = nullptr; + + enumerator = g_file_enumerate_children_finish(G_FILE(source_object), res, &error); + + qDebug() << "network_enumeration_finished"; + + if (error) { + DFMUrlBaseEvent *event = static_cast(user_data); + if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED) && + !g_error_matches(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) { + qWarning("Failed to fetch network locations: %s", error->message); + if (event->fileUrl() == DUrl::fromNetworkFile("/")) { + NetworkManager::restartGVFSD(); + } + } + qDebug() << error->message; + MountStatus status = gvfsMountManager->mount_sync(*event); + g_clear_error(&error); + + if (eventLoop) { + // 挂载完成时, 返回 1, 在fetch_networks中再次调用g_file_enumerate_children_async获取列表 + if (status == MOUNT_SUCCESS || status == MOUNT_PASSWORD_WRONG) { + eventLoop->exit(EventLoopCode::MountFinished); + } else { + eventLoop->exit(EventLoopCode::FetchFailed); + } + } + } else { + if (!enumerator) { + if (eventLoop) { + eventLoop->exit(EventLoopCode::FetchFailed); + } + + return; + } + + g_file_enumerator_next_files_async(enumerator, + G_MAXINT32, + G_PRIORITY_DEFAULT, + m_networks_fetching_cancellable, + network_enumeration_next_files_finished, + user_data); + } +} + +void NetworkManager::network_enumeration_next_files_finished(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GList *detected_networks; + GError *error; + + error = NULL; + + detected_networks = g_file_enumerator_next_files_finish(G_FILE_ENUMERATOR(source_object), + res, &error); + + if (error) { + if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + qWarning("Failed to fetch network locations: %s", error->message); + DFMEvent *event = static_cast(user_data); + if (event->fileUrl() == DUrl::fromNetworkFile("/")) { + NetworkManager::restartGVFSD(); + } + } + g_clear_error(&error); + } else { + populate_networks(G_FILE_ENUMERATOR(source_object), detected_networks, user_data); + + g_list_free_full(detected_networks, g_object_unref); + } + + if (eventLoop) { + eventLoop->exit(error ? EventLoopCode::FetchFailed : EventLoopCode::FetchFinished); + } +} + +void NetworkManager::populate_networks(GFileEnumerator *enumerator, GList *detected_networks, gpointer user_data) +{ + GList *l; + GFile *file; + GFile *activatable_file; + gchar *uri; + GFileType type; +// gchar *name; + + NetworkNodeList nodeList; + + for (l = detected_networks; l != NULL; l = l->next) { + GFileInfo *fileInfo = static_cast(l->data); + file = g_file_enumerator_get_child(enumerator, fileInfo); + type = g_file_info_get_file_type(fileInfo); + if (type == G_FILE_TYPE_SHORTCUT || type == G_FILE_TYPE_MOUNTABLE) + uri = g_file_info_get_attribute_as_string(fileInfo, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI); + else + uri = g_file_get_uri(file); + + activatable_file = g_file_new_for_uri(uri); +// name = g_file_info_get_attribute_as_string (fileInfo, G_FILE_ATTRIBUTE_STANDARD_NAME); + gchar *display_name = g_file_info_get_attribute_as_string(fileInfo, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME); + GIcon *icon = g_file_info_get_icon(fileInfo); + gchar *iconPath = g_icon_to_string(icon); + + // URL Cleanup: + // blumia: sometimes it will happend in weird Mac mini device with a url format like: `smb://[10.0.61.210]:445/` + // Wikipedia said (haven't take a look at releated RFCs) brackets should only be used with IPv6 addresses. + // Not sure it's a bug of gvfs or Apple, so do a workaround cleanup here. + QString uriStr = QString(uri); + QRegularExpression re(R"reg((\[)(?:\d+\.){3}\d+(\]))reg"); + if (re.match(uriStr).hasMatch()) { + uriStr.remove('['); + uriStr.remove(']'); + } + + NetworkNode node; + node.setUrl(uriStr); + node.setDisplayName(QString(display_name)); + node.setIconType(QString(iconPath)); + + qDebug() << node; + + nodeList.append(node); + + g_free(uri); + g_free(display_name); + g_free(iconPath); + g_clear_object(&file); + g_clear_object(&activatable_file); + } + + DFMUrlBaseEvent *event = static_cast(user_data); + DUrl neturl = event->fileUrl(); + static QRegularExpression regExp("^(smb|smb-share)://((?!/).*)/(?((?!/).*))", + QRegularExpression::DotMatchesEverythingOption + | QRegularExpression::DontCaptureOption + | QRegularExpression::OptimizeOnFirstUsageOption); + std::string stdStr = neturl.toString().toStdString(); + QString urlString = QUrl::fromPercentEncoding(stdStr.data()); + const QRegularExpressionMatch &match = regExp.match(urlString, 0, QRegularExpression::NormalMatch, + QRegularExpression::DontCheckSubjectStringMatchOption); + if (match.hasMatch()) { + QString filename = match.captured("name"); + if (!filename.isEmpty()) + neturl = DUrl(urlString.replace(filename,filename.toLower())); + qInfo() << "current net url = " << neturl.toString(); + } + NetworkNodes.remove(neturl); + NetworkNodes.insert(neturl, nodeList); + qDebug() << "request NetworkNodeList successfully"; +} + +void NetworkManager::restartGVFSD() +{ + QProcess p; + p.start("killall", {"gvfsd"}); + bool ret = p.waitForFinished(); + if (ret) { + bool result = QProcess::startDetached("/usr/lib/gvfs/gvfsd"); + qDebug() << "restart gvfsd" << result; + } else { + qDebug() << "killall gvfsd failed"; + } +} + +void NetworkManager::fetchNetworks(const DFMUrlBaseEvent &event) +{ + qDebug() << event; + DFMEvent *e = new DFMEvent(event); + // fix bug 100864 使用smb://ip或者域名/共享名/path,gio使用这个路径作为挂载,就会直接通过网络访问smb://ip或者域名/共享名/path, + // 但是共享下的path被删除了,所以gio返回错误,不让挂载。其真实要挂载的是smb://ip或者域名/共享名,这里修改流程挂载smb://ip或者域名/共享名 + // 再跳转到这个目录下smb://ip或者域名/共享名/path + DUrl fileUrl = event.fileUrl(); + static const QRegExp rxPath(R"((^/[^/]+))"); + if (rxPath.indexIn(fileUrl.path()) != -1) { + fileUrl.setPath(rxPath.cap(1)); + } + QString path = fileUrl.toString(); + QString fullPath = event.fileUrl().toString(); + + UDiskDeviceInfoPointer p1 = deviceListener->getDeviceByMountPoint(fullPath); + UDiskDeviceInfoPointer p2 = deviceListener->getDeviceByMountPointFilePath(fullPath); + + qDebug() << path << fullPath << p1 << p2; + + if (p1) { + e->setData(p1->getMountPointUrl()); + if (DUrl(path) != p1->getMountPointUrl()) { + DFMEventDispatcher::instance()->processEvent(this, e->fileUrl(), WindowManager::getWindowById(e->windowId())); + } else { + qWarning() << p1->getMountPointUrl() << "can't get data"; + } + } else { + std::string stdPath = path.toStdString(); + gchar *url = const_cast(stdPath.c_str()); + + if (fetch_networks(url, e)) { + QWidget *main_window = WindowManager::getWindowById(e->windowId()); + + // call later + QTimer::singleShot(0, this, [fullPath, main_window] { + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(nullptr, DUrl(fullPath)); + + if (info && info->canRedirectionFileUrl()) { + DUrl redirectUrl = info->redirectedFileUrl(); + redirectUrl.setScheme(redirectUrl.scheme()+ NETWORK_REDIRECT_SCHEME_EX); + redirectUrl.setQuery(fullPath); + DFMEventDispatcher::instance()->processEvent(nullptr, redirectUrl, main_window); + } + }); + } + } + delete e; +} + +void NetworkManager::cancelFeatchNetworks() +{ + if (eventLoop) + eventLoop->exit(EventLoopCode::FetchFailed); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/networkmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/networkmanager.h new file mode 100644 index 0000000..7d60ca0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/networkmanager.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef NETWORKMANAGER_H +#define NETWORKMANAGER_H + +#include +#include +#include +#include "debugobejct.h" +#include "dfmevent.h" + +#undef signals +extern "C" { + #include +} +#define signals public + +#include +#include + +class NetworkNode +{ + +public: + explicit NetworkNode(); + ~NetworkNode(); + + QString url() const; + void setUrl(const QString &url); + + QString displayName() const; + void setDisplayName(const QString &displayName); + + QString iconType() const; + void setIconType(const QString &iconType); + +signals: + +public slots: + +private: + QString m_url; + QString m_displayName; + QString m_iconType; + + + friend QDebug operator<<(QDebug dbg, const NetworkNode &node); +}; + + +QDebug operator<<(QDebug dbg, const NetworkNode &node); + + +typedef QList NetworkNodeList; + +class NetworkManager : public QObject +{ + Q_OBJECT + +public: + + + explicit NetworkManager(QObject *parent = 0); + ~NetworkManager(); + + void initData(); + void initConnect(); + + static QStringList SupportScheme; + static QMap NetworkNodes; + static GCancellable * m_networks_fetching_cancellable; + static bool fetch_networks(gchar* url, DFMEvent* e); + static void network_enumeration_finished (GObject *source_object, + GAsyncResult *res, + gpointer user_data); + + static void network_enumeration_next_files_finished (GObject *source_object, + GAsyncResult *res, + gpointer user_data); + + static void populate_networks (GFileEnumerator *enumerator, GList *detected_networks, gpointer user_data); + static void restartGVFSD(); + +signals: + +public slots: + void fetchNetworks(const DFMUrlBaseEvent &event); + static void cancelFeatchNetworks(); + +private: + static QPointer eventLoop; +}; + +#endif // NETWORKMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qdiskinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qdiskinfo.cpp new file mode 100644 index 0000000..a67efc3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qdiskinfo.cpp @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "qdiskinfo.h" +#include "deviceinfo/udisklistener.h" + +#include "app/define.h" +#include "singleton.h" + +#undef signals +extern "C" { +#include +} +#define signals public + +QDiskInfo::QDiskInfo() +{ + +} + +QString QDiskInfo::id() const +{ + return m_id; +} + +void QDiskInfo::setId(const QString &id) +{ + m_id = id; +} + +QString QDiskInfo::name() const +{ + return m_name; +} + +void QDiskInfo::setName(const QString &name) +{ + m_name = name; +} + +QString QDiskInfo::type() const +{ + return m_type; +} + +void QDiskInfo::setType(const QString &type) +{ + m_type = type; +} + +QString QDiskInfo::unix_device() const +{ + return m_unix_device; +} + +void QDiskInfo::setUnix_device(const QString &unix_device) +{ + m_unix_device = unix_device; +} + +QString QDiskInfo::uuid() const +{ + return m_uuid; +} + +void QDiskInfo::setUuid(const QString &uuid) +{ + m_uuid = uuid; +} + +QString QDiskInfo::mounted_root_uri() const +{ + return m_mounted_root_uri; +} + +void QDiskInfo::setMounted_root_uri(const QString &mounted_root_uri) +{ + m_mounted_root_uri = mounted_root_uri; +} + +QString QDiskInfo::iconName() const +{ + return m_iconName; +} + +void QDiskInfo::setIconName(const QString &iconName) +{ + m_iconName = iconName; +} + +bool QDiskInfo::can_unmount() const +{ + return m_can_unmount; +} + +void QDiskInfo::setCan_unmount(bool can_unmount) +{ + m_can_unmount = can_unmount; +} + +bool QDiskInfo::can_eject() const +{ + return m_can_eject; +} + +void QDiskInfo::setCan_eject(bool can_eject) +{ + m_can_eject = can_eject; +} + +qulonglong QDiskInfo::used() const +{ + return m_used; +} + +void QDiskInfo::setUsed(const qulonglong &used) +{ + m_used = used; +} + +qulonglong QDiskInfo::total() const +{ + return m_total; +} + +void QDiskInfo::setTotal(const qulonglong &total) +{ + m_total = total; +} + +qulonglong QDiskInfo::free() const +{ + return m_free; +} + +void QDiskInfo::setFree(const qulonglong &free) +{ + m_free = free; +} + +//DUrl QDiskInfo::mounted_url() const +//{ +// return m_mounted_url; +//} + +//void QDiskInfo::setMounted_url(const DUrl &mounted_url) +//{ +// m_mounted_url = mounted_url; +//} + +bool QDiskInfo::isNativeCustom() const +{ + return m_isNativeCustom; +} + +void QDiskInfo::setIsNativeCustom(bool isNativeCustom) +{ + m_isNativeCustom = isNativeCustom; +} + +bool QDiskInfo::can_mount() const +{ + return m_can_mount; +} + +void QDiskInfo::setCan_mount(bool can_mount) +{ + m_can_mount = can_mount; +} + +void QDiskInfo::updateGvfsFileSystemInfo(int retryTimes/*=3*/) +{ + if (m_mounted_root_uri.isEmpty()) { + return; + } + std::string file_uri = m_mounted_root_uri.toStdString(); + GFile *file; + GFileInfo *systemInfo; + GFileInfo *info; + GError *error; + file = g_file_new_for_uri(file_uri.data()); + if (file == nullptr) { + return; + } + error = nullptr; + // 根据 API 文档,需要什么属性就去获取什么属性,全部拿可能影响性能。 + systemInfo = g_file_query_filesystem_info(file, + G_FILE_ATTRIBUTE_FILESYSTEM_SIZE "," + G_FILE_ATTRIBUTE_FILESYSTEM_FREE "," + G_FILE_ATTRIBUTE_FILESYSTEM_USED "," + G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, + nullptr, &error); + if (error) { + g_error_free(error); + error = nullptr; + } + info = g_file_query_info(file, G_FILE_ATTRIBUTE_ID_FILESYSTEM, G_FILE_QUERY_INFO_NONE, nullptr, &error); + if (info == nullptr && error) { + if (systemInfo) + g_object_unref(systemInfo); + g_object_unref(file); + qWarning() << "g_file_query_filesystem_info" << error->message << error->code; + if (error->code == 0 && retryTimes > 0) { + g_error_free(error); + return updateGvfsFileSystemInfo(--retryTimes); + } + + g_error_free(error); + return; + } + + m_total = g_file_info_get_attribute_uint64(systemInfo, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE); + m_free = g_file_info_get_attribute_uint64(systemInfo, G_FILE_ATTRIBUTE_FILESYSTEM_FREE); + m_used = g_file_info_get_attribute_uint64(systemInfo, G_FILE_ATTRIBUTE_FILESYSTEM_USED); + m_read_only = g_file_info_get_attribute_boolean(systemInfo, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY); + m_id_filesystem = QString(g_file_info_get_attribute_as_string(info, G_FILE_ATTRIBUTE_ID_FILESYSTEM)); + + if (m_used == 0) { + m_used = m_total - m_free; + } + + g_object_unref(systemInfo); + g_object_unref(info); + g_object_unref(file); + +} + +bool QDiskInfo::read_only() const +{ + return m_read_only; +} + +void QDiskInfo::setRead_only(bool read_only) +{ + m_read_only = read_only; +} + +QString QDiskInfo::activation_root_uri() const +{ + return m_activation_root_uri; +} + +void QDiskInfo::setActivation_root_uri(const QString &activation_root_uri) +{ + m_activation_root_uri = activation_root_uri; +} + +bool QDiskInfo::isValid() +{ + if (id().isEmpty()) { + return false; + } + return true; +} + +bool QDiskInfo::is_removable() const +{ + return m_is_removable; +} + +void QDiskInfo::setIs_removable(bool is_removable) +{ + m_is_removable = is_removable; +} + +bool QDiskInfo::has_volume() const +{ + return m_has_volume; +} + +void QDiskInfo::setHas_volume(bool has_volume) +{ + m_has_volume = has_volume; +} + +QString QDiskInfo::id_filesystem() const +{ + return m_id_filesystem; +} + +void QDiskInfo::setId_filesystem(const QString &id_filesystem) +{ + m_id_filesystem = id_filesystem; +} + +QString QDiskInfo::default_location() const +{ + return m_default_location; +} + +void QDiskInfo::setDefault_location(const QString &default_location) +{ + m_default_location = default_location; +} + +QString QDiskInfo::drive_unix_device() const +{ + return m_drive_unix_device; +} + +void QDiskInfo::setDrive_unix_device(const QString &drive_unix_device) +{ + m_drive_unix_device = drive_unix_device; +} + +QDiskInfo QDiskInfo::getDiskInfo(const DAbstractFileInfo &fileInfo) +{ + QDiskInfo info; + qDebug() << fileInfo.filePath(); + UDiskDeviceInfoPointer uDiskDeviceInfoPointer = deviceListener->getDeviceByPath(fileInfo.filePath()); + if (!uDiskDeviceInfoPointer) { + uDiskDeviceInfoPointer = deviceListener->getDeviceByFilePath(fileInfo.filePath()); + } + if (uDiskDeviceInfoPointer) { + info = uDiskDeviceInfoPointer->getDiskInfo(); + } + return info; +} + + +QDebug operator<<(QDebug dbg, const QDiskInfo &info) +{ + dbg.nospace() << "QDiskInfo("; + dbg.nospace() << "id: " << info.id() << ","; + dbg.nospace() << "name: " << info.name() << ","; + dbg.nospace() << "type: " << info.type() << ","; + dbg.nospace() << "drive_unix_device: " << info.drive_unix_device() << ","; + dbg.nospace() << "unix_device: " << info.unix_device() << ","; + dbg.nospace() << "uuid: " << info.uuid() << ","; + dbg.nospace() << "activation_root_uri: " << info.activation_root_uri() << ","; + dbg.nospace() << "mounted_root_uri: " << info.mounted_root_uri() << ","; + dbg.nospace() << "id_filesystem: " << info.id_filesystem() << ","; + dbg.nospace() << "default_location: " << info.default_location() << ","; + dbg.nospace() << "iconName: " << info.iconName() << ","; + dbg.nospace() << "is_removable: " << info.is_removable() << ","; + dbg.nospace() << "can_mount: " << info.can_mount() << ","; + dbg.nospace() << "can_unmount: " << info.can_unmount() << ","; + dbg.nospace() << "can_eject: " << info.can_eject() << ","; + dbg.nospace() << "used: " << info.used() << ","; + dbg.nospace() << "total: " << info.total() << ","; +// dbg.nospace() << "mounted_url: " << info.mounted_url() << ","; + dbg.nospace() << ")"; + return dbg; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qdiskinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qdiskinfo.h new file mode 100644 index 0000000..5b47541 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qdiskinfo.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef QDISKINFO_H +#define QDISKINFO_H + +#include +#include +#include "durl.h" + +class DAbstractFileInfo; +class QDiskInfo +{ +public: + QDiskInfo(); + + QString id() const; + void setId(const QString &id); + + QString name() const; + void setName(const QString &name); + + QString type() const; + void setType(const QString &type); + + QString unix_device() const; + void setUnix_device(const QString &unix_device); + + QString uuid() const; + void setUuid(const QString &uuid); + + QString mounted_root_uri() const; + void setMounted_root_uri(const QString &mounted_root_uri); + + QString iconName() const; + void setIconName(const QString &iconName); + + bool can_unmount() const; + void setCan_unmount(bool can_unmount); + + bool can_eject() const; + void setCan_eject(bool can_eject); + + qulonglong used() const; + void setUsed(const qulonglong &used); + + qulonglong total() const; + void setTotal(const qulonglong &total); + + qulonglong free() const; + void setFree(const qulonglong &free); + +// DUrl mounted_url() const; +// void setMounted_url(const DUrl &mounted_url); + + bool isNativeCustom() const; + void setIsNativeCustom(bool isNativeCustom); + + bool can_mount() const; + void setCan_mount(bool can_mount); + + + void updateGvfsFileSystemInfo(int retryTimes=3); + + bool read_only() const; + void setRead_only(bool read_only); + + QString activation_root_uri() const; + void setActivation_root_uri(const QString &activation_root_uri); + + bool isValid(); + + bool is_removable() const; + void setIs_removable(bool is_removable); + + bool has_volume() const; + void setHas_volume(bool has_volume); + + QString id_filesystem() const; + void setId_filesystem(const QString &id_filesystem); + + QString default_location() const; + void setDefault_location(const QString &default_location); + + QString drive_unix_device() const; + void setDrive_unix_device(const QString &drive_unix_device); + + static QDiskInfo getDiskInfo(const DAbstractFileInfo &fileInfo); + +private: + QString m_id; + QString m_name; + QString m_type; + QString m_drive_unix_device; + QString m_unix_device; + QString m_uuid; + QString m_activation_root_uri; + QString m_mounted_root_uri; + QString m_iconName; + QString m_id_filesystem; + QString m_default_location; + bool m_is_removable = false; + bool m_can_mount = false; + bool m_can_unmount = false; + bool m_can_eject = false; + bool m_read_only = false; + bool m_has_volume = false; + qulonglong m_used = 0; + qulonglong m_total = 0; + qulonglong m_free = 0; + +// DUrl m_mounted_url; + /*if true show in computerview for especially used*/ + bool m_isNativeCustom = false; + +}; + +typedef QList QDiskInfoList; + +Q_DECLARE_METATYPE(QDiskInfo) +Q_DECLARE_METATYPE(QDiskInfoList) + +QDebug operator<<(QDebug dbg, const QDiskInfo &info); + +#endif // QDISKINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qdrive.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qdrive.cpp new file mode 100644 index 0000000..6575be6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qdrive.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "qdrive.h" + +QDrive::QDrive() +{ + +} + +QString QDrive::name() const +{ + return m_name; +} + +void QDrive::setName(const QString &name) +{ + m_name = name; +} + +QStringList QDrive::icons() const +{ + return m_icons; +} + +void QDrive::setIcons(const QStringList &icons) +{ + m_icons = icons; +} + +QStringList QDrive::symbolic_icons() const +{ + return m_symbolic_icons; +} + +void QDrive::setSymbolic_icons(const QStringList &symbolic_icons) +{ + m_symbolic_icons = symbolic_icons; +} + +bool QDrive::has_volumes() const +{ + return m_has_volumes; +} + +void QDrive::setHas_volumes(bool has_volumes) +{ + m_has_volumes = has_volumes; +} + +bool QDrive::can_eject() const +{ + return m_can_eject; +} + +void QDrive::setCan_eject(bool can_eject) +{ + m_can_eject = can_eject; +} + +bool QDrive::can_start() const +{ + return m_can_start; +} + +void QDrive::setCan_start(bool can_start) +{ + m_can_start = can_start; +} + +bool QDrive::can_start_degraded() const +{ + return m_can_start_degraded; +} + +void QDrive::setCan_start_degraded(bool can_start_degraded) +{ + m_can_start_degraded = can_start_degraded; +} + +bool QDrive::can_poll_for_media() const +{ + return m_can_poll_for_media; +} + +void QDrive::setCan_poll_for_media(bool can_poll_for_media) +{ + m_can_poll_for_media = can_poll_for_media; +} + +bool QDrive::can_stop() const +{ + return m_can_stop; +} + +void QDrive::setCan_stop(bool can_stop) +{ + m_can_stop = can_stop; +} + +bool QDrive::has_media() const +{ + return m_has_media; +} + +void QDrive::setHas_media(bool has_media) +{ + m_has_media = has_media; +} + +bool QDrive::is_media_check_automatic() const +{ + return m_is_media_check_automatic; +} + +void QDrive::setIs_media_check_automatic(bool is_media_check_automatic) +{ + m_is_media_check_automatic = is_media_check_automatic; +} + +bool QDrive::is_removable() const +{ + return m_is_removable; +} + +void QDrive::setIs_removable(bool is_removable) +{ + m_is_removable = is_removable; +} + +bool QDrive::is_media_removable() const +{ + return m_is_media_removable; +} + +void QDrive::setIs_media_removable(bool is_media_removable) +{ + m_is_media_removable = is_media_removable; +} + +GDriveStartStopType QDrive::start_stop_type() const +{ + return m_start_stop_type; +} + +void QDrive::setStart_stop_type(const GDriveStartStopType &start_stop_type) +{ + m_start_stop_type = start_stop_type; +} + +QString QDrive::unix_device() const +{ + return m_unix_device; +} + +void QDrive::setUnix_device(const QString &unix_device) +{ + m_unix_device = unix_device; +} + +bool QDrive::isValid() +{ + return !name().isEmpty(); +} + +QDebug operator<<(QDebug dbg, const QDrive &drive) +{ + dbg << "QDrive: {" + << "name:" << drive.name() << "," + << "unix_device:" << drive.unix_device() << "," + << "icons:" << drive.icons() << "," + << "is_removable" << drive.is_removable() << "," + << "start_stop_type" << drive.start_stop_type() << "," + << "can_stop:" << drive.can_stop() + << "}"; + return dbg; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qdrive.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qdrive.h new file mode 100644 index 0000000..e04a336 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qdrive.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef QDRIVE_H +#define QDRIVE_H + +#include +#include + +#undef signals +extern "C" { + #include +} +#define signals public + +class QDrive +{ +public: + QDrive(); + + QString name() const; + void setName(const QString &name); + + QStringList icons() const; + void setIcons(const QStringList &icons); + + QStringList symbolic_icons() const; + void setSymbolic_icons(const QStringList &symbolic_icons); + + bool has_volumes() const; + void setHas_volumes(bool has_volumes); + + bool can_eject() const; + void setCan_eject(bool can_eject); + + bool can_start() const; + void setCan_start(bool can_start); + + bool can_start_degraded() const; + void setCan_start_degraded(bool can_start_degraded); + + bool can_poll_for_media() const; + void setCan_poll_for_media(bool can_poll_for_media); + + bool can_stop() const; + void setCan_stop(bool can_stop); + + bool has_media() const; + void setHas_media(bool has_media); + + bool is_media_check_automatic() const; + void setIs_media_check_automatic(bool is_media_check_automatic); + + bool is_removable() const; + void setIs_removable(bool is_removable); + + bool is_media_removable() const; + void setIs_media_removable(bool is_media_removable); + + GDriveStartStopType start_stop_type() const; + void setStart_stop_type(const GDriveStartStopType &start_stop_type); + + QString unix_device() const; + void setUnix_device(const QString &unix_device); + + bool isValid(); + +private: + QString m_name; + QString m_unix_device; + QStringList m_icons; + QStringList m_symbolic_icons; + bool m_has_volumes = false; + bool m_can_eject = false; + bool m_can_start = false; + bool m_can_start_degraded = false; + bool m_can_poll_for_media = false; + bool m_can_stop = false; + bool m_has_media = false; + bool m_is_media_check_automatic = false; + bool m_is_removable = false; + bool m_is_media_removable = false; + GDriveStartStopType m_start_stop_type; +}; + +Q_DECLARE_METATYPE(QDrive) + +QDebug operator<<(QDebug dbg, const QDrive& drive); + +#endif // QDRIVE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qmount.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qmount.cpp new file mode 100644 index 0000000..4d3d126 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qmount.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "qmount.h" + +QMount::QMount() +{ + +} + +QString QMount::name() const +{ + return m_name; +} + +QString QMount::uuid() const +{ + return m_uuid; +} + +QString QMount::default_location() const +{ + return m_default_location; +} + +void QMount::setDefault_location(const QString &default_location) +{ + m_default_location = default_location; +} + +QStringList QMount::icons() const +{ + return m_icons; +} + +QStringList QMount::symbolic_icons() const +{ + return m_symbolic_icons; +} + +void QMount::setSymbolic_icons(const QStringList &symbolic_icons) +{ + m_symbolic_icons = symbolic_icons; +} + +bool QMount::can_unmount() const +{ + return m_can_unmount; +} + +void QMount::setCan_unmount(bool can_unmount) +{ + m_can_unmount = can_unmount; +} + +bool QMount::can_eject() const +{ + return m_can_eject; +} + +void QMount::setCan_eject(bool can_eject) +{ + m_can_eject = can_eject; +} + +bool QMount::is_shadowed() const +{ + return m_is_shadowed; +} + +void QMount::setIs_shadowed(bool is_shadowed) +{ + m_is_shadowed = is_shadowed; +} + +void QMount::setName(const QString &name) +{ + m_name = name; +} + +void QMount::setIcons(const QStringList &icons) +{ + m_icons = icons; +} + +QString QMount::mounted_root_uri() const +{ + return m_mounted_root_uri; +} + +void QMount::setMounted_root_uri(const QString &mounted_root_uri) +{ + m_mounted_root_uri = mounted_root_uri; +} + +QDebug operator<<(QDebug dbg, const QMount &mount) +{ + dbg << "QMount: {" + << "name:" << mount.name() << "," + << "mounted root uri:" << mount.mounted_root_uri() << "," + << "can_unmount:" << mount.can_unmount() << "," + << "icon:" << mount.icons() << "," + << "is_shadowed:" << mount.is_shadowed() + << "}"; + return dbg; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qmount.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qmount.h new file mode 100644 index 0000000..8516384 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qmount.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef QMOUNT_H +#define QMOUNT_H + +#include +#include +#include + +class QMount +{ +public: + QMount(); + + QString name() const; + QString uuid() const; + + QString default_location() const; + void setDefault_location(const QString &default_location); + + QStringList icons() const; + + QStringList symbolic_icons() const; + void setSymbolic_icons(const QStringList &symbolic_icons); + + bool can_unmount() const; + void setCan_unmount(bool can_unmount); + + bool can_eject() const; + void setCan_eject(bool can_eject); + + bool is_shadowed() const; + void setIs_shadowed(bool is_shadowed); + + void setName(const QString &name); + + void setIcons(const QStringList &icons); + + QString mounted_root_uri() const; + void setMounted_root_uri(const QString &mounted_root_uri); + +private: + QString m_name; + QString m_mounted_root_uri; + QString m_uuid; + QString m_default_location; + QStringList m_icons; + QStringList m_symbolic_icons; + bool m_can_unmount = false; + bool m_can_eject = false; + bool m_is_shadowed = false; +}; + +QDebug operator<<(QDebug dbg, const QMount& mount); + +#endif // QMOUNT_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qvolume.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qvolume.cpp new file mode 100644 index 0000000..cae133f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qvolume.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "qvolume.h" + +QVolume::QVolume() +{ + +} + +QString QVolume::name() const +{ + return m_name; +} + +void QVolume::setName(const QString &name) +{ + m_name = name; +} + +QString QVolume::uuid() const +{ + return m_uuid; +} + +void QVolume::setUuid(const QString &uuid) +{ + m_uuid = uuid; +} + +QStringList QVolume::icons() const +{ + return m_icons; +} + +void QVolume::setIcons(const QStringList &icons) +{ + m_icons = icons; +} + +QStringList QVolume::symbolic_icons() const +{ + return m_symbolic_icons; +} + +void QVolume::setSymbolic_icons(const QStringList &symbolic_icons) +{ + m_symbolic_icons = symbolic_icons; +} + +bool QVolume::can_mount() const +{ + return m_can_mount; +} + +void QVolume::setCan_mount(bool can_mount) +{ + m_can_mount = can_mount; +} + +bool QVolume::can_eject() const +{ + return m_can_eject; +} + +void QVolume::setCan_eject(bool can_eject) +{ + m_can_eject = can_eject; +} + +bool QVolume::should_automount() const +{ + return m_should_automount; +} + +void QVolume::setShould_automount(bool should_automount) +{ + m_should_automount = should_automount; +} + +QString QVolume::unix_device() const +{ + return m_unix_device; +} + +void QVolume::setUnix_device(const QString &unix_device) +{ + m_unix_device = unix_device; +} + +QString QVolume::lable() const +{ + return m_lable; +} + +void QVolume::setLable(const QString &lable) +{ + m_lable = lable; +} + +QString QVolume::nfs_mount() const +{ + return m_nfs_mount; +} + +void QVolume::setNfs_mount(const QString &nfs_mount) +{ + m_nfs_mount = nfs_mount; +} + +bool QVolume::isMounted() const +{ + return m_isMounted; +} + +void QVolume::setIsMounted(bool isMounted) +{ + m_isMounted = isMounted; +} + +QString QVolume::mounted_root_uri() const +{ + return m_mounted_root_uri; +} + +void QVolume::setMounted_root_uri(const QString &mounted_root_uri) +{ + m_mounted_root_uri = mounted_root_uri; +} + +bool QVolume::isValid() +{ + return !m_unix_device.isEmpty(); +} + +QString QVolume::activation_root_uri() const +{ + return m_activation_root_uri; +} + +void QVolume::setActivation_root_uri(const QString &activation_root_uri) +{ + m_activation_root_uri = activation_root_uri; +} + +bool QVolume::is_removable() const +{ + return m_is_removable; +} + +void QVolume::setIs_removable(bool is_removable) +{ + m_is_removable = is_removable; +} + +QDrive QVolume::drive() const +{ + return m_drive; +} + +void QVolume::setDrive(const QDrive &drive) +{ + m_drive = drive; +} + +QString QVolume::drive_unix_device() const +{ + return m_drive_unix_device; +} + +void QVolume::setDrive_unix_device(const QString &drive_unix_device) +{ + m_drive_unix_device = drive_unix_device; +} + +QDebug operator<<(QDebug dbg, const QVolume &volume) +{ + dbg << "QVolume: {" + << "name:" << volume.name() << "," + << "unix_device:" << volume.unix_device() << "," + << "icons:" << volume.icons() << "," + << "is_Mounted:" << volume.isMounted() << "," + << "is_removable:" << volume.is_removable() << "," + << "mounted_root_uri:" << volume.mounted_root_uri() + << "}"; + return dbg; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qvolume.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qvolume.h new file mode 100644 index 0000000..1519f71 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/qvolume.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef QVOLUME_H +#define QVOLUME_H + +#include +#include +#include + +#include "qdrive.h" + + +class QVolume +{ +public: + QVolume(); + + QString name() const; + void setName(const QString &name); + + QString uuid() const; + void setUuid(const QString &uuid); + + QStringList icons() const; + void setIcons(const QStringList &icons); + + QStringList symbolic_icons() const; + void setSymbolic_icons(const QStringList &symbolic_icons); + + bool can_mount() const; + void setCan_mount(bool can_mount); + + bool can_eject() const; + void setCan_eject(bool can_eject); + + bool should_automount() const; + void setShould_automount(bool should_automount); + + QString unix_device() const; + void setUnix_device(const QString &unix_device); + + QString lable() const; + void setLable(const QString &lable); + + QString nfs_mount() const; + void setNfs_mount(const QString &nfs_mount); + + bool isMounted() const; + void setIsMounted(bool isMounted); + + QString mounted_root_uri() const; + void setMounted_root_uri(const QString &mounted_root_uri); + + bool isValid(); + + QString activation_root_uri() const; + void setActivation_root_uri(const QString &activation_root_uri); + + bool is_removable() const; + void setIs_removable(bool is_removable); + + QDrive drive() const; + void setDrive(const QDrive &drive); + + QString drive_unix_device() const; + void setDrive_unix_device(const QString &drive_unix_device); + +private: + QString m_name; + QString m_drive_unix_device; + QString m_unix_device; + QString m_lable; + QString m_uuid; + QString m_nfs_mount; + QStringList m_icons; + QStringList m_symbolic_icons; + QString m_activation_root_uri; + QString m_mounted_root_uri; + bool m_can_mount = false; + bool m_can_eject = false; + bool m_should_automount = false; + bool m_isMounted = false; + bool m_is_removable = false; + QDrive m_drive; +}; + +QDebug operator<<(QDebug dbg, const QVolume& volume); + +#endif // QVOLUME_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/secretmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/secretmanager.cpp new file mode 100644 index 0000000..1549ddb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/secretmanager.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "secretmanager.h" + +#include "app/define.h" +#include "app/filesignalmanager.h" + +#include "interfaces/dfmstandardpaths.h" + +#include "singleton.h" +#include "shutil/fileutils.h" + +#include +#include +#include + +SecretManager::SecretManager(QObject *parent) : QObject(parent) +{ + qDebug() << "Create SecretManager"; + initData(); + initConnect(); +} + +SecretManager::~SecretManager() +{ + +} + +void SecretManager::initData() +{ + loadCache(); +} + +void SecretManager::initConnect() +{ + connect(fileSignalManager, &FileSignalManager::requsetCacheLoginData, this, &SecretManager::cacheSambaLoginData); +} + +const SecretSchema *SecretManager::SMBSecretSchema() +{ + static const SecretSchema the_schema = { + "org.gnome.keyring.NetworkPassword", SECRET_SCHEMA_DONT_MATCH_NAME, + { + {"user", SECRET_SCHEMA_ATTRIBUTE_STRING }, + {"domain", SECRET_SCHEMA_ATTRIBUTE_STRING }, + {"server", SECRET_SCHEMA_ATTRIBUTE_STRING }, + {"protocol", SECRET_SCHEMA_ATTRIBUTE_STRING } + }, + 0, 0, 0, 0, 0, 0, 0, 0 + }; + + return &the_schema; +} + +const SecretSchema *SecretManager::FTPSecretSchema() +{ + static const SecretSchema the_schema = { + "org.gnome.keyring.NetworkPassword", SECRET_SCHEMA_DONT_MATCH_NAME, + { + {"user", SECRET_SCHEMA_ATTRIBUTE_STRING }, + {"server", SECRET_SCHEMA_ATTRIBUTE_STRING }, + {"protocol", SECRET_SCHEMA_ATTRIBUTE_STRING } + }, + 0, 0, 0, 0, 0, 0, 0, 0 + }; + + return &the_schema; +} + +const SecretSchema *SecretManager::VaultSecretSchema() +{ + static const SecretSchema the_schema = { + "com.deepin.filemanager.VaultPassword", SECRET_SCHEMA_DONT_MATCH_NAME, { + {"user", SECRET_SCHEMA_ATTRIBUTE_STRING } + }, + 0, 0, 0, 0, 0, 0, 0, 0 + }; + + return &the_schema; +} + +void SecretManager::on_password_cleared(GObject *source, GAsyncResult *result, gpointer unused) +{ + Q_UNUSED(source) + Q_UNUSED(unused) + + qDebug() << "on_password_cleared"; + GError *error = nullptr; + + gboolean removed = secret_password_clear_finish(result, &error); + + qDebug() << removed; + + if (error != nullptr) { + /* ... handle the failure here */ + g_error_free(error); + + } else { + /* removed will be TRUE if a password was removed */ + qDebug() << "password was removed"; + } +} + +bool SecretManager::storeVaultPassword(const DSecureString &string) +{ + GError *error = nullptr; + secret_password_store_sync(VaultSecretSchema(), SECRET_COLLECTION_SESSION, "Vault session password", string.toStdString().c_str(), + nullptr, &error, + "user", "dde-file-manager", + nullptr); + if (error != nullptr) { + /* ... handle the failure here */ + g_error_free(error); + return false; + } + + return true; +} + +DSecureString SecretManager::lookupVaultPassword() +{ + GError *error = nullptr; + gchar *password = secret_password_lookup_sync(VaultSecretSchema(), {}, &error, + "user", "dde-file-manager", + NULL); + DSecureString result(password); + + if (error != nullptr) { + /* ... handle the failure here */ + g_error_free(error); + } else if (password == nullptr) { + /* password will be null, if no matching password found */ + } else { + /* ... do something with the password */ + secret_password_free(password); + } + + return result; +} + +bool SecretManager::clearVaultPassword() +{ + GError *error = nullptr; + + /* + * The variable argument list is the attributes used to later + * lookup the password. These attributes must conform to the schema. + */ + gboolean removed = secret_password_clear_sync(VaultSecretSchema(), nullptr, &error, + "user", "dde-file-manager", + nullptr); + + if (error != nullptr) { + /* ... handle the failure here */ + g_error_free(error); + } else { + /* removed will be TRUE if a password was removed */ + } + return removed; +} + +void SecretManager::clearPasswordByLoginObj(const QJsonObject &obj) +{ + if (obj.value("protocol") == "smb") { + secret_password_clear(SMBSecretSchema(), nullptr, on_password_cleared, nullptr, + "user", obj.value("user").toString().toStdString().c_str(), + "domain", obj.value("domain").toString().toStdString().c_str(), + "server", obj.value("server").toString().toStdString().c_str(), + "protocol", obj.value("protocol").toString().toStdString().c_str(), + nullptr); + } else if (obj.value("protocol") == "ftp" || obj.value("protocol") == "sftp") { + secret_password_clear(FTPSecretSchema(), nullptr, on_password_cleared, nullptr, + "user", obj.value("user").toString().toStdString().c_str(), + "server", obj.value("server").toString().toStdString().c_str(), + "protocol", obj.value("protocol").toString().toStdString().c_str(), + nullptr); + } + QMutexLocker lk(&smbMutex); + m_smbLoginObjs.remove(obj.value("key").toString()); + saveCache(); +} + +QJsonObject SecretManager::getLoginData(const QString &id) +{ + QMutexLocker lk(&smbMutex); + for (auto key : m_smbLoginObjs.keys()) + { + if (key.startsWith(id) || id.startsWith(key)) { + QJsonObject smbObj = m_smbLoginObjs.value(key).toObject(); + smbObj.insert("key", key); + return smbObj; + } + } + return m_smbLoginObjs.value(id).toObject(); +} + +QJsonObject SecretManager::getLoginDatas() +{ + return m_smbLoginObjs; +} + +QString SecretManager::cachePath() +{ + return QString("%1/samba.json").arg(DFMStandardPaths::location(DFMStandardPaths::ApplicationConfigPath)); +} + +void SecretManager::cacheSambaLoginData(const QJsonObject &obj) +{ + QJsonValue v(obj); + QString path = obj.value("id").toString(); + + QMutexLocker lk(&smbMutex); + m_smbLoginObjs.insert(path, v); + saveCache(); +} + +void SecretManager::loadCache() +{ + //Migration for old config files, and rmove that codes for further + FileUtils::migrateConfigFileFromCache("samba"); + + QFile file(cachePath()); + if (!file.open(QIODevice::ReadOnly)) { + qDebug() << "Couldn't write samba file!"; + return; + } + QByteArray data = file.readAll(); + QJsonDocument jsonDoc(QJsonDocument::fromJson(data)); + m_smbLoginObjs = jsonDoc.object(); + file.close(); + qDebug() << m_smbLoginObjs; +} + +void SecretManager::saveCache() +{ + QFile file(cachePath()); + if (!file.open(QIODevice::WriteOnly)) { + qDebug() << "Couldn't write samba file!"; + return; + } + QJsonDocument jsonDoc(m_smbLoginObjs); + file.write(jsonDoc.toJson()); + file.close(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/secretmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/secretmanager.h new file mode 100644 index 0000000..ade89f5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/gvfs/secretmanager.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef SECRETMANAGER_H +#define SECRETMANAGER_H + +#include +#include +#include + +#include + +DCORE_USE_NAMESPACE + +#undef signals +extern "C" { + #include +} +#define signals public + +class SecretManager : public QObject +{ + Q_OBJECT +public: + explicit SecretManager(QObject *parent = nullptr); + ~SecretManager(); + + void initData(); + void initConnect(); + + static const SecretSchema * SMBSecretSchema(); + static const SecretSchema * FTPSecretSchema(); + static const SecretSchema * VaultSecretSchema(); + + static void on_password_cleared (GObject *source, + GAsyncResult *result, + gpointer unused); + + bool storeVaultPassword(const DSecureString &string); + DSecureString lookupVaultPassword(); + bool clearVaultPassword(); + void clearPasswordByLoginObj(const QJsonObject& obj); + QJsonObject getLoginData(const QString& id); + QJsonObject getLoginDatas(); + static QString cachePath(); +signals: + +public slots: + void cacheSambaLoginData(const QJsonObject& obj); + void loadCache(); + void saveCache(); + + +private: + QJsonObject m_smbLoginObjs; + QMutex smbMutex; +}; + +#endif // SECRETMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/customization.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/customization.pri new file mode 100644 index 0000000..ee42a88 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/customization.pri @@ -0,0 +1,12 @@ +SOURCES += \ + $$PWD/dcustomactiondata.cpp \ + $$PWD/dcustomactionparser.cpp \ + $$PWD/dcustomactionbuilder.cpp + +HEADERS += \ + $$PWD/dcustomactiondata.h \ + $$PWD/dcustomactionparser.h \ + $$PWD/dcustomactionbuilder.h \ + $$PWD/dcustomactiondefine.h + +INCLUDEPATH += $$PWD diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactionbuilder.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactionbuilder.cpp new file mode 100644 index 0000000..f0b49c7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactionbuilder.cpp @@ -0,0 +1,633 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * liqiang + * + * 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 + * 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 . + */ + +#include "dcustomactionbuilder.h" +#include "dfilemenu.h" + +#include +#include +#include +#include + +DCustomActionBuilder::DCustomActionBuilder(QObject *parent) + : QObject(parent) + , m_fm(QFontMetrics(QAction().font())) +{ + +} + +/*! + 根据 \a actionData中配置信息自动识别创建菜单和动作对象并递归完成子项的创建。 + \a parentForSubmenu 指定子菜单的父对象,必须为有效值,子菜单随 \a parentForSubmenu 释放而释放, + 若为无效值则子菜单将无法释放,造成内存泄漏。 + 返回值 QAction* 对象的生命周期由调用方控制。 +*/ +QAction *DCustomActionBuilder::buildAciton(const DCustomActionData &actionData, QWidget *parentForSubmenu) const +{ + QAction *ret = nullptr; + if (actionData.isAction()) { + ret = createAciton(actionData); + } else { + ret = createMenu(actionData, parentForSubmenu); + } + + return ret; +} + +/*! + 设置菜单的文件夹 \a dir 。提取文件夹名称,用于菜单传参 + */ +void DCustomActionBuilder::setActiveDir(const DUrl &dir) +{ + m_dirPath = dir; + auto info = DFileService::instance()->createFileInfo(nullptr, dir); + if (info) { + m_dirName = info->fileName(); + + //解决根目录没有名称问题 + if (m_dirName.isEmpty() && dir.toLocalFile() == "/") { + m_dirName = "/"; + } + } +} + +/*! + 设置焦点文件 \a file ,即右键点击的文件。当为空白区域时,无需设置。 + 提取文件\a file 的不带扩展名的文件名称和文件完整名称,用于菜单传参 + */ +void DCustomActionBuilder::setFocusFile(const DUrl &file) +{ + m_filePath = file; + auto info = DFileService::instance()->createFileInfo(nullptr, file); + if (info) { + m_fileFullName = info->fileName(); + //baseName + if (info->isDir()) { + m_fileBaseName = m_fileFullName; + return; + } + //fix bug 65159,这里只针对一些常见的后缀处理,暂不针对一些非标准的特殊情况做处理,待后续产品有特殊要求再处理特殊情况 + //suffixForFileName对复式后缀会返回xx.*,比如test.7z.001返回的是7z.* + //不过在一些非标准的复式后缀判定中,仍可能判定不准确:比如:test.part1.rar被识别成rar + //隐藏文件:".tar"、".tar.gz"后缀识别成""和".gz" + //可能无法识别到后缀:如test.run或者.tar + QString suffix = mimeDatabase.suffixForFileName(m_fileFullName); + if (suffix.isEmpty()) { + m_fileBaseName = m_fileFullName; + return; + } + //二次过滤后缀,方式识别到分卷带*的情况 + suffix = this->getCompleteSuffix(m_fileFullName, suffix); + m_fileBaseName = m_fileFullName.left(m_fileFullName.length() - suffix.length() - 1); + + //解决 .xx 一类的隐藏文件 + if (m_fileBaseName.isEmpty()) + m_fileBaseName = m_fileFullName; + } +} + +/*! + 过滤识别结果带*的情况,返回当前文件名的实际全后缀(已经经过DMimeDatabase识别后且为复式后缀后使用)。 + 检查 \a fileName 待划分后缀的全文件名, \a suf 经过DMimeDatabase识别后的复式后缀。 + */ +QString DCustomActionBuilder::getCompleteSuffix(const QString &fileName, const QString &suf) +{ + QString tempStr; + if (!suf.contains(".") || suf.isEmpty()) + return suf; + auto sufLst = suf.split("."); + if (0 < sufLst.size()) { + tempStr = sufLst.first(); + int index = fileName.lastIndexOf(tempStr); + if (index > 0) { + return fileName.mid(index);; + } + } + return suf; +} + +/*! + 检查 \a files 文件列表中的文件组合 + */ +DCustomActionDefines::ComboType DCustomActionBuilder::checkFileCombo(const DUrlList &files) +{ + int fileCount = 0; + int dirCount = 0; + for (const DUrl &file : files) { + if (file.isEmpty()) + continue; + + auto info = DFileService::instance()->createFileInfo(Q_NULLPTR, file); + if (!info) + continue; + + //目前只判断是否为文件夹 + info->isDir() ? ++dirCount : ++fileCount; + + //文件夹和文件同时存在 + if (dirCount > 0 && fileCount > 0) + return DCustomActionDefines::FileAndDir; + } + + //文件 + if (fileCount > 0) + return fileCount > 1 ? DCustomActionDefines::MultiFiles : DCustomActionDefines::SingleFile; + + //文件夹 + if (dirCount > 0) + return dirCount > 1 ? DCustomActionDefines::MultiDirs : DCustomActionDefines::SingleDir; + + return DCustomActionDefines::BlankSpace; +} + +/*! + 筛选 \a rootActions 中支持 \a type 文件组合的菜单项 + */ +QList DCustomActionBuilder::matchFileCombo(const QList &rootActions, + DCustomActionDefines::ComboTypes type) +{ + QList ret; + //无自定义菜单项 + if(0 == rootActions.size()) + return ret; + + for (auto it = rootActions.begin(); it != rootActions.end(); ++it) { + if (it->fileCombo() & type) + ret << *it; + } + return ret; +} + +QList DCustomActionBuilder::matchActions(const DUrlList &selects, + QList oriActions) +{ + //todo:细化功能颗粒度,一个函数尽量专职一件事 + /* + *根据选中内容、配置项、选中项类型匹配合适的菜单项 + *是否action支持的协议 + *是否action支持的后缀 + *action不支持类型过滤(不加上父类型过滤,todo: 为何不支持项不考虑?) + *action支持类型过滤(类型过滤要加上父类型一起过滤) + */ + + //具体配置过滤 + for (auto &singleUrl : selects) { + //协议、后缀 + DAbstractFileInfoPointer fileInfo; + fileInfo = DFileService::instance()->createFileInfo(nullptr, singleUrl); + if (!fileInfo) { + qWarning() << "create selected FileInfo failed: " << singleUrl.toString(); + continue; + } + + /* + * 选中文件类型过滤: + * fileMimeTypes:包括所有父类型的全量类型集合 + * fileMimeTypesNoParent:不包含父类mimetype的集合 + * 目的是在一些应用对文件的识别支持上有差异:比如xlsx的 parentMimeTypes 是application/zip + * 归档管理器打开则会被作为解压 + */ + + QStringList fileMimeTypes; + QStringList fileMimeTypesNoParent; +// fileMimeTypes.append(fileInfo->mimeType().name()); +// fileMimeTypes.append(fileInfo->mimeType().aliases()); +// const QMimeType &mt = fileInfo->mimeType(); +// fileMimeTypesNoParent = fileMimeTypes; +// appendParentMimeType(mt.parentMimeTypes(), fileMimeTypes); +// fileMimeTypes.removeAll({}); +// fileMimeTypesNoParent.removeAll({}); + + appendAllMimeTypes(fileInfo, fileMimeTypesNoParent, fileMimeTypes); + for (auto it = oriActions.begin(); it != oriActions.end();) { + DCustomActionEntry &tempAction = *it; + //协议,后缀 + if (!isSchemeSupport(tempAction, singleUrl) || !isSuffixSupport(tempAction, singleUrl)) { + it = oriActions.erase(it); //不支持的action移除 + continue; + } + + //不支持的mimetypes,使用不包含父类型的mimetype集合过滤 + if (isMimeTypeMatch(fileMimeTypesNoParent, tempAction.excludeMimeTypes())) { + it = oriActions.erase(it); + continue; + } + + // MimeType在原有oem中,未指明或Mimetype=*都作为支持所有类型 + if (tempAction.mimeTypes().isEmpty()) { + ++it; + continue; + } + + //支持的mimetype,使用包含父类型的mimetype集合过滤 + QStringList supportMimeTypes = tempAction.mimeTypes(); + supportMimeTypes.removeAll({}); + auto match = isMimeTypeMatch(fileMimeTypes, supportMimeTypes); + +//在自定义右键菜中有作用域限制,此类情况不显示自定义菜单,故可屏蔽,若后续有作用域的调整再考虑是否开放 +#if 0 + //部分mtp挂载设备目录下文件属性不符合规范(普通目录mimetype被认为是octet-stream),暂时做特殊处理- + if (singleUrl.path().contains("/mtp:host") && supportMimeTypes.contains("application/octet-stream") && fileMimeTypes.contains("application/octet-stream")) + match = false; +#endif + if (!match) { + it = oriActions.erase(it); + continue; + } + ++it; + } + + } + + return oriActions; +} + +/*! + 展开 \a cmd 中需要的参数。只处理找到的一个有效的 \a arg 参数,后面的不再替换。 + 参数类型只支持:DirPath FilePath FilePaths UrlPath UrlPaths + 若参数 \a arg 为FilePaths和UrlPaths则只支持作为独立参数(“ %u ”),不支持组合(“\"--file %u\"” 或者“\"--file-%u\"” ) + */ +QPair DCustomActionBuilder::makeCommand(const QString &cmd, DCustomActionDefines::ActionArg arg, const DUrl &dir, const DUrl &foucs, const DUrlList &files) +{ + QPair ret; + auto args = splitCommand(cmd); + if (args.isEmpty()) { + return ret; + } + + //执行程序 + ret.first = args.takeFirst(); + //无参数 + if (args.isEmpty()) { + return ret; + } + + auto replace = [ = ](QStringList & args, const QString & before, const QString & after) { + QStringList rets; + while (!args.isEmpty()) { + QString arg = args.takeFirst(); + //找到在参数中第一个有效的before匹配值,并替换为after。之后的不在处理 + int index = arg.indexOf(before); + if (index >= 0) { + rets << arg.replace(index, before.size(), after); + rets << args; + args.clear(); + } else { + rets << arg; + } + } + return rets; + }; + + auto replaceList = [ = ](QStringList & args, const QString & before, const QStringList & after) { + QStringList rets; + while (!args.isEmpty()) { + QString arg = args.takeFirst(); + //仅支持独立参数,有其它组合的不处理 + if (arg == before) { + //放入文件路径 + rets << after; + //放入原参数 + rets << args; + args.clear(); + } else { + rets << arg; + } + } + return rets; + }; + + //url转为文件路径 + auto urlListToLocalFile = [](const DUrlList & files) { + QStringList rets; + for (auto it = files.begin(); it != files.end(); ++it) { + rets << it->toLocalFile(); + } + return rets; + }; + + //url字符串 + auto urlListToString = [](const DUrlList & files) { + QStringList rets; + for (auto it = files.begin(); it != files.end(); ++it) { + rets << it->toString(); + } + return rets; + }; + + //传参 + switch (arg) { + case DCustomActionDefines::DirPath: + ret.second = replace(args, DCustomActionDefines::kStrActionArg[arg], dir.toLocalFile()); + break; + case DCustomActionDefines::FilePath: + ret.second = replace(args, DCustomActionDefines::kStrActionArg[arg], foucs.toLocalFile()); + break; + case DCustomActionDefines::FilePaths: + ret.second = replaceList(args, DCustomActionDefines::kStrActionArg[arg], urlListToLocalFile(files)); + break; + case DCustomActionDefines::UrlPath: + ret.second = replace(args, DCustomActionDefines::kStrActionArg[arg], foucs.toString()); + break; + case DCustomActionDefines::UrlPaths: + ret.second = replaceList(args, DCustomActionDefines::kStrActionArg[arg], urlListToString(files)); + break; + default: + ret.second = args; + break; + } + return ret; +} + +/*! + 将命令行 \a cmd 中的数据使用空格(" ")分割。 + 引号内的空格不做分割。 + */ +QStringList DCustomActionBuilder::splitCommand(const QString &cmd) +{ + QStringList args; + bool inQuote = false; + + QString arg; + for (int i = 0 ; i < cmd.count(); i++) { + const bool isEnd = (cmd.size() == (i + 1)); + + const QChar &ch = cmd.at(i); + //引号 + const bool isQuote = (ch == QLatin1Char('\'') || ch == QLatin1Char('\"')); + + //遇到引号或者最后一个字符 + if (!isEnd && isQuote) { + //进入引号内或退出引号 + inQuote = !inQuote; + } else { + //处于引号中或者非空格作为一个参数 + if ((!ch.isSpace() || inQuote) && !isQuote) { + arg.append(ch); + } + + //遇到空格且不再引号中解出一个单独参数 + if ((ch.isSpace() && !inQuote) || isEnd) { + if (!arg.isEmpty()) { + args << arg; + } + arg.clear(); + } + } + } + return args; +} + +bool DCustomActionBuilder::isMimeTypeSupport(const QString &mt, const QStringList &fileMimeTypes) +{ + foreach (const QString &fmt, fileMimeTypes) { + if (fmt.contains(mt, Qt::CaseInsensitive)) { + return true; + } + } + return false; +} + +bool DCustomActionBuilder::isMimeTypeMatch(const QStringList &fileMimeTypes, const QStringList &supportMimeTypes) +{ + bool match = false; + for (const QString &mt : supportMimeTypes) { + if (fileMimeTypes.contains(mt, Qt::CaseInsensitive)) { + match = true; + break; + } + + int starPos = mt.indexOf("*"); + if (starPos >= 0 && isMimeTypeSupport(mt.left(starPos), fileMimeTypes)) { + match = true; + break; + } + } + return match; +} + +bool DCustomActionBuilder::isSchemeSupport(const DCustomActionEntry &action, const DUrl &url) +{ + // X-DFM-SupportSchemes not exist + auto supportList = action.surpportSchemes(); + if (supportList.contains("*") || supportList.isEmpty()) + return true; //支持所有协议: 未特殊指明X-DFM-SupportSchemes或者"X-DFM-SupportSchemes=*" + return supportList.contains(url.scheme(), Qt::CaseInsensitive); +} + +bool DCustomActionBuilder::isSuffixSupport(const DCustomActionEntry &action, const DUrl &url) +{ + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(nullptr, url); + auto supportList = action.supportStuffix(); + if (!fileInfo || fileInfo->isDir() || supportList.isEmpty() || supportList.contains("*")) { + return true;//未特殊指明支持项或者包含*为支持所有 + } + QFileInfo info(url.toLocalFile()); + + //例如: 7z.001,7z.002, 7z.003 ... 7z.xxx + QString cs = info.completeSuffix(); + if (supportList.contains(cs, Qt::CaseInsensitive)) { + return true; + } + + bool match = false; + for (const QString &suffix : supportList) { + auto tempSuffix = suffix; + int endPos = tempSuffix.lastIndexOf("*"); // 例如:7z.* + if (endPos >= 0 && cs.length() > endPos && tempSuffix.left(endPos) == cs.left(endPos)) { + match = true; + break; + } + } + return match; +} + +void DCustomActionBuilder::appendAllMimeTypes(const DAbstractFileInfoPointer &fileInfo, QStringList &noParentmimeTypes, QStringList &allMimeTypes) +{ + noParentmimeTypes.append(fileInfo->mimeType().name()); + noParentmimeTypes.append(fileInfo->mimeType().aliases()); + const QMimeType &mt = fileInfo->mimeType(); + allMimeTypes = noParentmimeTypes; + appendParentMimeType(mt.parentMimeTypes(), allMimeTypes); + noParentmimeTypes.removeAll({}); + allMimeTypes.removeAll({}); +} + +void DCustomActionBuilder::appendParentMimeType(const QStringList &parentmimeTypes, QStringList &mimeTypes) +{ + if (parentmimeTypes.size() == 0) + return; + + for (const QString &mtName : parentmimeTypes) { + QMimeDatabase db; + QMimeType mt = db.mimeTypeForName(mtName); + mimeTypes.append(mt.name()); + mimeTypes.append(mt.aliases()); + QStringList pmts = mt.parentMimeTypes(); + appendParentMimeType(pmts, mimeTypes); + } +} + +/*! + 创建菜单项,\a parentForSubmenu 用于指定菜单的父对象,用于自动释放 + 通过获取 \a actionData 中的标题,图标等信息创建菜单项,并遍历创建子项和分割符号。 + 返回值 QAction* 对象的生命周期由调用方控制。 +*/ +QAction *DCustomActionBuilder::createMenu(const DCustomActionData &actionData, QWidget *parentForSubmenu) const +{ + //fix-bug 59298 + //createAction 构造action 图标等, 把关于构造action参数放在createAction中 + QAction *action = createAciton(actionData); + QMenu *menu = new DFileMenu(parentForSubmenu); + menu->setToolTipsVisible(true); + + action->setMenu(menu); + action->setProperty(DCustomActionDefines::kCustomActionFlag, true); + + //子项,子项的顺序由解析器保证 + QList subActions = actionData.acitons(); + for (auto it = subActions.begin(); it != subActions.end(); ++it) { + QAction *ba = buildAciton(*it, parentForSubmenu); + if (!ba) + continue; + + auto separator = it->separator(); + //上分割线 + if (separator & DCustomActionDefines::Top) { + const QList &actionList = menu->actions(); + if (!actionList.isEmpty()) { + auto lastAction = menu->actions().last(); + + //不是分割线则插入 + if (!lastAction->isSeparator()) { + menu->addSeparator(); + } + } + } + + ba->setParent(menu); + menu->addAction(ba); + + //下分割线 + if ((separator & DCustomActionDefines::Bottom) && ((it + 1) != subActions.end())) { + menu->addSeparator(); + } + } + + return action; +} + +/*! + 使用 \a actionData 创建动作对象。 + 将动作需要执行的命令写入属性 \key DCustomActionDefines::kCustomActionCommand 中。 + 返回值 QAction* 对象的生命周期由调用方控制。 +*/ +QAction *DCustomActionBuilder::createAciton(const DCustomActionData &actionData) const +{ + QAction *action = new QAction; + action->setProperty(DCustomActionDefines::kCustomActionFlag, true); + + //执行动作 + action->setProperty(DCustomActionDefines::kCustomActionCommand, actionData.command()); + action->setProperty(DCustomActionDefines::kCustomActionCommandArgFlag, actionData.commandArg()); + + //标题 + { + const QString &&name = makeName(actionData.name(), actionData.nameArg()); + //TODO width是临时值,最终效果需设计定义 + const QString &&elidedName = m_fm.elidedText(name, Qt::ElideMiddle, 150); + action->setText(elidedName); + if (elidedName != name) + action->setToolTip(name); + } +//story#4481,产品变更暂不考虑图标 +#if 0 + //图标 + const QString &iconName = actionData.icon(); + if (!iconName.isEmpty()) { + const QIcon &&icon = getIcon(iconName); + if (!icon.isNull()) + action->setIcon(icon); + } +#endif + return action; +} + +/*! + 使用 \a iconName 获取图标,可以是主题类型的图标名,也可以是图标的绝对路径。 + 若找不到图标,则返回空对象 +*/ +QIcon DCustomActionBuilder::getIcon(const QString &iconName) const +{ + QIcon ret; + + //通过路径获取图标 + QFileInfo info(iconName.startsWith("~") ? (QDir::homePath() + iconName.mid(1)) : iconName); + + if (!info.exists()) + info.setFile(QUrl::fromUserInput(iconName).toLocalFile()); + + if (info.exists()) { + ret = QIcon(info.absoluteFilePath()); + } + + //从主题获取 + if (ret.isNull()) { + ret = QIcon::fromTheme(iconName); + } + + return ret; +} + +/*! + 使用当前文件或文件夹信息替换 \a name 中的 \a arg 参数。 + 只处理找到的一个有效的 \a arg 参数,后面的不再替换。 + 参数类型仅支持:DirName BaseName FileName + */ +QString DCustomActionBuilder::makeName(const QString &name, DCustomActionDefines::ActionArg arg) const +{ + auto replace = [](QString input, const QString & before, const QString & after) { + QString ret = input; + int index = input.indexOf(before); + if (index >= 0) { + ret = input.replace(index, before.size(), after); + } + return ret; + }; + + QString ret; + switch (arg) { + case DCustomActionDefines::DirName: + ret = replace(name, DCustomActionDefines::kStrActionArg[arg], m_dirName); + break; + case DCustomActionDefines::BaseName: + ret = replace(name, DCustomActionDefines::kStrActionArg[arg], m_fileBaseName); + break; + case DCustomActionDefines::FileName: + ret = replace(name, DCustomActionDefines::kStrActionArg[arg], m_fileFullName); + break; + default: + ret = name; + break; + } + return ret; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactionbuilder.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactionbuilder.h new file mode 100644 index 0000000..7a45743 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactionbuilder.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * liqiang + * + * 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 + * 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 . + */ + +#ifndef DCUSTOMACTIONBUILDER_H +#define DCUSTOMACTIONBUILDER_H + +#include "dcustomactiondata.h" +#include "durl.h" +#include "interfaces/dfileservices.h" +#include "dmimedatabase.h" + +#include +#include +#include + +class QMenu; +class QAction; +class DCustomActionBuilder : public QObject +{ + Q_OBJECT +public: + explicit DCustomActionBuilder(QObject *parent = nullptr); + QAction *buildAciton(const DCustomActionData &actionData, QWidget *parentForSubmenu) const; + void setActiveDir(const DUrl &dir); + void setFocusFile(const DUrl &file); + QString getCompleteSuffix(const QString & fileName, const QString &suf); + static DCustomActionDefines::ComboType checkFileCombo(const DUrlList &files); + static QList matchFileCombo(const QList &rootActions, + DCustomActionDefines::ComboTypes type); + static QList matchActions(const DUrlList &selects, + QList oriActions); + static QPair makeCommand(const QString &cmd, DCustomActionDefines::ActionArg arg, + const DUrl &dir, const DUrl& foucs, const DUrlList &files); + static QStringList splitCommand(const QString &cmd); +private: + static bool isMimeTypeSupport(const QString &mt, const QStringList &fileMimeTypes); + static bool isMimeTypeMatch(const QStringList &fileMimeTypes, const QStringList &supportMimeTypes); + static bool isSchemeSupport(const DCustomActionEntry &action, const DUrl &url); + static bool isSuffixSupport(const DCustomActionEntry &action, const DUrl &url); + static void appendAllMimeTypes(const DAbstractFileInfoPointer &fileInfo, QStringList &noParentmimeTypes, QStringList &allMimeTypes); + static void appendParentMimeType(const QStringList &parentmimeTypes, QStringList& mimeTypes); +protected: + QAction *createMenu(const DCustomActionData &actionData, QWidget *parentForSubmenu) const; + QAction *createAciton(const DCustomActionData &actionData) const; +signals: + +public slots: +protected: + QIcon getIcon(const QString &iconName) const; + QString makeName(const QString &name, DCustomActionDefines::ActionArg arg) const; + +private: + QFontMetrics m_fm; + QString m_dirName; + DUrl m_dirPath; + QString m_fileBaseName; + QString m_fileFullName; + DUrl m_filePath; + DMimeDatabase mimeDatabase; +}; + +#endif // DCUSTOMACTIONBUILDER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactiondata.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactiondata.cpp new file mode 100644 index 0000000..0cbd56e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactiondata.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * liqiang + * + * 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 + * 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 . + */ + +#include "dcustomactiondata.h" + +DCustomActionData::DCustomActionData() : + m_position(0) + , m_nameArg(DCustomActionDefines::NoneArg) + , m_cmdArg(DCustomActionDefines::NoneArg) + , m_separator(DCustomActionDefines::None) +{ + +} + +DCustomActionData::DCustomActionData(const DCustomActionData &other) + : m_comboPos(other.m_comboPos) + , m_position(other.m_position) + , m_nameArg(other.m_nameArg) + , m_cmdArg(other.m_cmdArg) + , m_name(other.m_name) + , m_icon(other.m_icon) + , m_command(other.m_command) + , m_separator(other.m_separator) + , m_childrenActions(other.m_childrenActions) +{ + +} + +DCustomActionData &DCustomActionData::operator=(const DCustomActionData &other) +{ + if (this == &other) + return *this; + m_nameArg = other.m_nameArg; + m_cmdArg = other.m_cmdArg; + m_name = other.m_name; + m_comboPos = other.m_comboPos; + m_position = other.m_position; + m_separator = other.m_separator; + m_icon = other.m_icon; + m_command = other.m_command; + m_childrenActions = other.m_childrenActions; + return *this; +} + +bool DCustomActionData::isMenu() const +{ + return !m_childrenActions.isEmpty(); +} + +bool DCustomActionData::isAction() const +{ + return m_childrenActions.isEmpty(); +} + +QString DCustomActionData::name() const +{ + return m_name; +} + +int DCustomActionData::position(DCustomActionDefines::ComboType combo) const +{ + auto it = m_comboPos.find(combo); + if (it != m_comboPos.end()) + return it.value(); + else + return m_position; +} + +int DCustomActionData::position() const +{ + return m_position; +} + +QString DCustomActionData::icon() const +{ + return m_icon; +} + +QString DCustomActionData::command() const +{ + return m_command; +} + +DCustomActionDefines::Separator DCustomActionData::separator() const +{ + return m_separator; +} + +QList DCustomActionData::acitons() const +{ + return m_childrenActions; +} + +DCustomActionDefines::ActionArg DCustomActionData::nameArg() const +{ + return m_nameArg; +} + +DCustomActionDefines::ActionArg DCustomActionData::commandArg() const +{ + return m_cmdArg; +} + + +DCustomActionEntry::DCustomActionEntry() +{ + +} + +DCustomActionEntry::DCustomActionEntry(const DCustomActionEntry &other) + : m_package(other.m_package) + , m_version(other.m_version) + , m_comment(other.m_comment) + , m_sign(other.m_sign) + , m_fileCombo(other.m_fileCombo) + , m_mimeTypes(other.m_mimeTypes) + , m_excludeMimeTypes(other.m_excludeMimeTypes) + , m_supportSchemes(other.m_supportSchemes) + , m_notShowIn(other.m_notShowIn) + , m_supportSuffix(other.m_supportSuffix) + , m_data(other.m_data) +{ + +} + +DCustomActionEntry &DCustomActionEntry::operator=(const DCustomActionEntry &other) +{ + if (this == &other) + return *this; + m_package = other.m_package; + m_version = other.m_version; + m_comment = other.m_comment; + m_fileCombo = other.m_fileCombo; + m_mimeTypes = other.m_mimeTypes; + m_excludeMimeTypes = other.m_excludeMimeTypes; + m_supportSchemes = other.m_supportSchemes; + m_notShowIn = other.m_notShowIn; + m_supportSuffix = other.m_supportSuffix; + m_sign = other.m_sign; + m_data = other.m_data; + return *this; +} + +QString DCustomActionEntry::package() const +{ + return m_package; +} + +QString DCustomActionEntry::version() const +{ + return m_version; +} + +QString DCustomActionEntry::comment() const +{ + return m_comment; +} + +DCustomActionDefines::ComboTypes DCustomActionEntry::fileCombo() const +{ + return m_fileCombo; +} + +QStringList DCustomActionEntry::mimeTypes() const +{ + return m_mimeTypes; +} + +QStringList DCustomActionEntry::excludeMimeTypes() const +{ + return m_excludeMimeTypes; +} + +QStringList DCustomActionEntry::surpportSchemes() const +{ + return m_supportSchemes; +} + +QStringList DCustomActionEntry::notShowIn() const +{ + return m_notShowIn; +} + +QStringList DCustomActionEntry::supportStuffix() const +{ + return m_supportSuffix; +} + +DCustomActionData DCustomActionEntry::data() const +{ + return m_data; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactiondata.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactiondata.h new file mode 100644 index 0000000..3cd26a8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactiondata.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: liqiang + * + * Maintainer: liqiang + * zhangyu + * + * 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 + * 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 . + */ + +#ifndef DCUSTOMACTIONDATA_H +#define DCUSTOMACTIONDATA_H + + +#include "dcustomactiondefine.h" + +#include + +class DCustomActionData +{ + friend class DCustomActionParser; + friend class DCustomActionBuilder; +public: + explicit DCustomActionData(); + DCustomActionData(const DCustomActionData &other); + DCustomActionData &operator=(const DCustomActionData &other); + bool isMenu() const; + bool isAction() const; + QString name() const; + int position(DCustomActionDefines::ComboType) const; + int position() const; + QString icon() const; + QString command() const; + DCustomActionDefines::Separator separator() const; + QList acitons() const; + DCustomActionDefines::ActionArg nameArg() const; + DCustomActionDefines::ActionArg commandArg() const; +signals: + +public slots: +protected: + QMap m_comboPos; //一级菜单,不同的文件组合时的位置 + int m_position; //显示位置,二,三级菜单的位置,一级菜单文件组合的默认位置 + DCustomActionDefines::ActionArg m_nameArg; //菜单名参数 + DCustomActionDefines::ActionArg m_cmdArg; //命令参数 + QString m_name; + QString m_icon; + QString m_command; //菜单执行动作 + DCustomActionDefines::Separator m_separator; + QList m_childrenActions; //当前action的子actions +}; + +//根项 +class DCustomActionEntry +{ + friend class DCustomActionParser; + friend class DCustomActionBuilder; +public: + explicit DCustomActionEntry(); + explicit DCustomActionEntry(const DCustomActionEntry &other); + DCustomActionEntry &operator=(const DCustomActionEntry &other); + QString package() const; + QString version() const; + QString comment() const; + DCustomActionDefines::ComboTypes fileCombo() const; + QStringList mimeTypes() const; + QStringList excludeMimeTypes() const; + QStringList surpportSchemes() const; + QStringList notShowIn() const; + QStringList supportStuffix() const; + DCustomActionData data() const; +protected: + QString m_package; //配置文件名 + QString m_version; //版本 + QString m_comment; //描述 + QString m_sign; //签名 + DCustomActionDefines::ComboTypes m_fileCombo; //支持的选中项类型 + QStringList m_mimeTypes; //支持的文件类型 + QStringList m_excludeMimeTypes; //不支持文件类型 + QStringList m_supportSchemes; //支持协议:file、trash, tag... + QStringList m_notShowIn; //仅桌面或文管展示:"Desktop", "Filemanager" + QStringList m_supportSuffix; //支持后缀: 归档管理器 *.7z.001,*.7z.002,*.7z.003... + DCustomActionData m_data; //一级菜单项的数据 +}; +#endif // DCUSTOMACTIONDATA_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactiondefine.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactiondefine.h new file mode 100644 index 0000000..f88545e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactiondefine.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * liqiang + * + * 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 + * 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 . + */ + +#ifndef DCUSTOMACTIONDEFINE_H +#define DCUSTOMACTIONDEFINE_H + +#include +#include + +namespace DCustomActionDefines +{ + //分割线 + enum Separator { + None = 0, + Top = 1, + Bottom = 1 << 1, + Both = Top | Bottom + }; + + //支持的文件组合方式 + enum ComboType { + BlankSpace = 1, //空白区域 + SingleFile = 1 << 1, //单个文件 + SingleDir = 1 << 2, //单个文件夹 + MultiFiles = 1 << 3, //多个文件 + MultiDirs = 1 << 4, //多个文件夹 + FileAndDir = 1 << 5, //文件和文件夹,必须都包含 + AllFile = SingleFile | MultiFiles, + AllDir = SingleDir | MultiDirs, + AllCombo = BlankSpace | AllFile | AllDir | FileAndDir + }; + Q_DECLARE_FLAGS(ComboTypes, DCustomActionDefines::ComboType); + Q_DECLARE_OPERATORS_FOR_FLAGS(ComboTypes); + + //支持菜单层级 + enum MenuHierarchy { + One = 1, + Two, + Three + }; + + //动态参数 + enum ActionArg { + NoneArg = -1, + DirName = 0, //%d 当前文件夹名称 + DirPath, //%p 当前文件夹路径 + BaseName, //%b 文件名,不含路径和扩展名 + FileName, //%a 文件全名,包含扩展名,不含路径 + FilePath,//%f 文件路径 + FilePaths, //%F 多个文件路径 + UrlPath, //%u 使用url表示的文件路径 + UrlPaths, //%U 多个url + }; + + static const QStringList kStrActionArg = {"%d","%p","%b","%a","%f","%F","%u","%U"}; + + template + void sortFunc(const QMap> &locate, QList &orgin, AddFunc addfunc,IsCount countFunc) { + int maxPos = locate.isEmpty() ? 0 : locate.lastKey(); + int currentCount = 0; + auto nextIter = locate.begin(); + for (int i = 1; i <= maxPos; ++i) { + auto current = locate.find(i); + if (current == locate.end()) { + if (orgin.isEmpty()) { + //已经取完,剩下的全部按顺序放入 + for (; nextIter != locate.end(); ++nextIter) { + currentCount += nextIter->size(); + addfunc(*nextIter); + } + break; + } else { + //用原有数据占位 + int added = i - currentCount; + for (int j = 0; j < added;) { + if (orgin.isEmpty()) + break; + auto el = orgin.takeFirst(); + addfunc({el}); + + //是否记数 + if (countFunc(el)) { + ++j; + ++currentCount; + } + } + } + } else { + currentCount += current->size(); + addfunc(*current); + nextIter = current + 1; + } + } + + //最后剩下的 + addfunc(orgin); + orgin.clear(); + } + + static const char* const kCustomActionFlag = "Custom_Action_Flag"; + static const char* const kCustomActionCommand = "Custom_Action_Command"; + static const char* const kCustomActionCommandArgFlag = "Custom_Action_Command_Arg_Flag"; + static const char* const kCustomActionDataDir = "Custom_Action_Data_Dir"; + static const char* const kCustomActionDataFoucsFile = "Custom_Action_Foucs_File"; + static const char* const kCustomActionDataSelectedFiles = "Custom_Action_Seletcted_Files"; + static const int kCustomMaxNumOne = 50; + static const int kCustomMaxNumTwo = 100; + static const int kCustomMaxNumThree = 100; + + //基本信息,置于一级菜单之中 + static const QLatin1String kMenuPrefix("Menu Entry"); + static const QLatin1String kConfFileVersion("Version"); + static const QLatin1String kConfComment("Comment"); + static const QLatin1String kConfCombo("X-DFM-MenuTypes"); + static const QLatin1String kConfMimeType("MimeType"); + static const QLatin1String kConfExcludeMimeTypes("X-DFM-ExcludeMimeTypes"); + static const QLatin1String kConfSupportSchemes("X-DFM-SupportSchemes"); + static const QLatin1String kConfNotShowIn("X-DFM-NotShowIn"); // "Desktop", "Filemanager" + static const QLatin1String kConfSupportSuffix("X-DFM-SupportSuffix"); // for deepin-compress *.7z.001,*.7z.002,*.7z.003... + static const QLatin1String kConfSign("Sign"); + + //菜单基本信息 + static const QLatin1String kActionGenericName("GenericName"); + static const QLatin1String kActionName("Name"); + static const QLatin1String kActionIcon("Icon"); + static const QLatin1String kActionPos("PosNum"); + static const QLatin1String kActionSeparator("Separator"); + static const QLatin1String kActionCmd("Exec"); + static const QLatin1String kActionGroups("Actions"); + static const QLatin1String kActionPrefix("Menu Action"); + + //指定路径 + static const QLatin1String kCustomMenuPath("/usr/share/applications/context-menus"); + + struct FileBasicInfos { + QString m_package; //配置文件名 + QString m_version; //版本 + QString m_comment; //描述 + ComboTypes m_fileCombo; //支持的选中项类型 + QString m_sign; //签名 + }; +} + +#endif // DCUSTOMACTIONDEFINE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactionparser.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactionparser.cpp new file mode 100644 index 0000000..7274f3c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactionparser.cpp @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangyu + * + * Maintainer: zhangyu + * liqiang + * + * 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 + * 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 . + */ + +#include "dcustomactionparser.h" + +#include +#include +#include +#include + +using namespace DCustomActionDefines; + +/*! + * \brief 自定义配置文件读规则 + * \param device 读取io + * \param settingsMap 保存读取结果 + * \return + */ +bool RegisterCustomFormat::readConf(QIODevice &device, QSettings::SettingsMap &settingsMap) +{ + QString section; + QTextStream stream(&device); + bool prefixExists = false; + while (!stream.atEnd()) { + QString line = stream.readLine().trimmed(); + + // 跳过备注 + if (line.startsWith(QLatin1Char('#'))) + continue; + // 分组 + if (line.startsWith(QLatin1Char('[')) && line.endsWith(QLatin1Char(']'))) { + section = line.mid(1, line.length()-2); + if (section == kMenuPrefix) + prefixExists = true; + continue; + } + + QString key = line.section(QLatin1Char('='), 0, 0).trimmed(); + QString value = line.section(QLatin1Char('='), 1).trimmed(); + + if (key.isEmpty()) + continue; + settingsMap[section + QLatin1Char('/') + key] = QVariant(value); + } + return prefixExists; +} + +/*! + * \brief 自定义配置文件写规则 + * \param device + * \param settingsMap + * \return + */ +bool RegisterCustomFormat::writeConf(QIODevice &device, const QSettings::SettingsMap &settingsMap) +{ + Q_UNUSED(device) + Q_UNUSED(settingsMap) + return true; +} + +/*! + * \brief 注册自定义qsettings读取规则 + */ +RegisterCustomFormat &RegisterCustomFormat::instance() +{ + static RegisterCustomFormat instance; + return instance; +} + +QSettings::Format RegisterCustomFormat::customFormat() +{ + return m_customFormat; +} + +RegisterCustomFormat::RegisterCustomFormat() +{ + //注册读写规则 + m_customFormat = QSettings::registerFormat("conf", &RegisterCustomFormat::readConf, &RegisterCustomFormat::writeConf); +} + +DCustomActionParser::DCustomActionParser(QObject *parent) + : QObject(parent) +{ + //获取注册的自定义方式 + m_customFormat = RegisterCustomFormat::instance().customFormat(); + m_fileWatcher = new QFileSystemWatcher; + //监听目录 + m_fileWatcher->addPath(kCustomMenuPath); + connect(m_fileWatcher, &QFileSystemWatcher::directoryChanged, this, &DCustomActionParser::delayRefresh); + connect(m_fileWatcher, &QFileSystemWatcher::fileChanged, this, &DCustomActionParser::delayRefresh); + + initHash(); + loadDir(kCustomMenuPath); + //暂时不考虑效率,todo后续优化考虑开线程处理此loadDir +} + +DCustomActionParser::~DCustomActionParser() +{ + if (m_fileWatcher) { + m_fileWatcher->deleteLater(); + m_fileWatcher = nullptr; + } +} + +/*! + 根据给定的文件夹路径\a dirPath 遍历解析该文件夹下的.conf文件, + 返回值 bool* 为是否成功遍历文件夹。 +*/ +bool DCustomActionParser::loadDir(const QString &dirPath) +{ + if (dirPath.isEmpty()) + return false; + m_topActionCount = 0; + QDir dir(dirPath); + if (!dir.exists()) + return false; + m_actionEntry.clear(); + + m_fileWatcher->removePaths(m_fileWatcher->files()); + + //以时间先后遍历 + for (const QFileInfo &actionFileInfo : dir.entryInfoList({"*.conf"}, QDir::Files, QDir::Time)) { + //监听每个conf文件的修改 + m_fileWatcher->addPath(actionFileInfo.absoluteFilePath()); + + //解析文件字段 + QSettings actionSetting(actionFileInfo.filePath(), m_customFormat); + actionSetting.setIniCodec("UTF-8"); + parseFile(actionSetting); + } + return true; +} + +/*! + 返回值QList,返回加载解析的菜单项. + \a onDesktop 匹配是否不再桌面/文管显示 +*/ +QList DCustomActionParser::getActionFiles(bool onDesktop) +{ + QList ret; + foreach (const DCustomActionEntry &entry, m_actionEntry) { + //NotShowIn + if (isActionShouldShow(entry.m_notShowIn, onDesktop)) + ret << entry;//一级菜单不在桌面/文管显示则跳过该项 + } + + return ret; +} + +/*! + 根据传入的\a actionSetting 解析菜单项,返回返回值为解析成功与否,关键字段缺失会被断定未无效文件,归于失败 +*/ +bool DCustomActionParser::parseFile(QSettings &actionSetting) +{ + //基本信息,版本,选中类型,且选中类型无明确说明则认为是无效的配置文件 + FileBasicInfos basicInfos; + bool prefixExists = actionSetting.childGroups().contains(kMenuPrefix); + if (!prefixExists) { //关键入口信息没有,认为是无效的配置文件 + return false; + } + if (!actionFileInfos(basicInfos, actionSetting)) + return false;//关键信息无效则 + + auto actions = getValue(actionSetting, kMenuPrefix, kActionGroups).toString().simplified(); + if (actions.isEmpty()) + return false; //无一级菜单,无效文件 + + auto actStr = getValue(actionSetting, kMenuPrefix, kActionGroups); + auto actList = actStr.toString().simplified().split(":", QString::SkipEmptyParts); + + for(auto &once : actList) { + if (m_topActionCount == kCustomMaxNumOne) //一级数量限制 + break; + QList childrenActions;//这个实际上一级时没用 + bool needSort;//一级用不到 + QString targetGroup = QString("%1 %2").arg(kActionPrefix).arg(once); + m_hierarchyNum = 1; + bool isVisible = parseFile(childrenActions, actionSetting, targetGroup, basicInfos, needSort, true); + //bug-59348 解决解析失败 count++ 导致不能显示50个有效文件(一级菜单) + if (isVisible) { + m_topActionCount++; + } + } + return true; +} + +/*! + 该方法用于递归解析对应组下的菜单信息,\a childrenActions 获取菜单项,\a actionSetting 为解析对象,\a group 为待解析分组, +\a basicInfos 是为一级菜单项准备的基本信息,\a isTop 表示当前解析的是否是一级菜单 +*/ +bool DCustomActionParser::parseFile(QList &childrenActions, QSettings &actionSetting, const QString &group, const FileBasicInfos &basicInfos, bool &isSort, bool isTop) +{ + m_hierarchyNum++; + if (4 < m_hierarchyNum) //超过三级不解 + return false; + + DCustomActionData actData; + //暂时用localname 和name,方式有些不确定,oem和之前的自定义右键是localName,打开方式又好像是genaricName + //后续确认优化 + //目前菜单项名的国际化暂支持"语言_地区/国家"或“语言”简写,即支持“zh_CN”或“zh”的方式。若未找到对应国际化信息,则采用兜底信息 + QString name; + auto getNameByType = [this, &name, &actionSetting, group](const QString& type) { + + QString systemName = QLocale::system().name().simplified(); + QString localName = QString("%1[%2]").arg(type).arg(systemName); + name = getValue(actionSetting, group, localName).toString().simplified(); + QStringList localeList = systemName.simplified().split("_"); + + if (name.isEmpty() && localeList.size() > 0) { + localName = QString("%1[%2]").arg(type).arg(localeList.first()); + name = getValue(actionSetting, group, localName).toString().simplified(); + } + + if (name.isEmpty()) { + name = getValue(actionSetting, group, type).toString().simplified(); + } + }; + + getNameByType(kActionName); + if (name.isEmpty()) { + qInfo() << "systemName: " << QLocale::system().name(); + return false; + } + + actData.m_name = name; + actionNameDynamicArg(actData); + + //story#4481,产品变更暂不考虑icon +#if 0 + //icon + actData.m_icon = getValue(actionSetting, group, kActionIcon).toString(); +#endif + //pos + actData.m_position = getValue(actionSetting, group, kActionPos).toInt(); + if (0 == actData.m_position && isSort) //未定义pos行为当前层级以上级指定顺序 + isSort = false; + + //separator + QString separator = getValue(actionSetting, group, kActionSeparator).toString().simplified(); + actData.m_separator = m_separtor.value(separator, None); + + //actions 父子action级联与动作 + + //actions 父级级联与动作 + QString actions = getValue(actionSetting, group, kActionGroups).toString().simplified(); + if (actions.isEmpty()) { + //无级联检查是否有动作 + QString command = getValue(actionSetting, group, kActionCmd).toString().simplified(); + if (command.isEmpty()) + return false; //无动作无子级 + actData.m_command = command; + execDynamicArg(actData); + } + else { + //add 子菜单项,父级有子菜单,则忽略动作,即便子菜单无一有效,后续也不再添加动作 + QList tpChildrenActions; + auto actStr = getValue(actionSetting, group, kActionGroups); + auto actList = actStr.toString().simplified().split(":", QString::SkipEmptyParts); + + int actCount = 0; + bool needSort = true; + for(auto &once : actList) { + QString targetGroup = QString("%1 %2").arg(kActionPrefix).arg(once); + //解决二三级存在的count问题 + bool isVisible = parseFile(tpChildrenActions, actionSetting, targetGroup, basicInfos, needSort, false); + m_hierarchyNum--; + if(isVisible) { + actCount++; + } + if (2 == m_hierarchyNum && actCount == kCustomMaxNumTwo) //二级数量限制 + break; + if (3 == m_hierarchyNum && actCount == kCustomMaxNumThree) //三级数量限制 + break; + } + if (0 == tpChildrenActions.size()) + return false; //作为无动作无子级,不再为其添加已有动作 +// actData.m_childrenActions = tpChildrenActions; + if (needSort)//全量二三级才排序,否则按照写入actions顺序 + std::stable_sort(tpChildrenActions.begin() + , tpChildrenActions.end() + , [](const DCustomActionData& a + , const DCustomActionData& b){ + return a.m_position < b.m_position; + }); + actData.m_childrenActions = tpChildrenActions; + } + + if (isTop) { + DCustomActionEntry tpEntry; + + //支持类型combo + auto comboStr = getValue(actionSetting, group, kConfCombo).toString().simplified(); + if (comboStr.isEmpty()) { + return false;//无支持选中类型默认该一级无效 + } + else { + QStringList comboList = comboStr.split(":", QString::SkipEmptyParts); + ComboTypes target; + for (auto temp : comboList) { + auto tp = temp.simplified(); + if (m_combos.contains(tp)) + target = target | m_combos.value(temp); + } + tpEntry.m_fileCombo = target; + } + + //MimeType + QString mimeTypeStr = getValue(actionSetting, group, kConfMimeType).toString().simplified(); + if (!mimeTypeStr.isEmpty()) + tpEntry.m_mimeTypes = mimeTypeStr.split(":"); + + //X-DFM-ExcludeMimeTypes + QString excludeMimeTypesStr = getValue(actionSetting, group, kConfExcludeMimeTypes).toString().simplified(); + if (!excludeMimeTypesStr.isEmpty()) + tpEntry.m_excludeMimeTypes= excludeMimeTypesStr.split(":"); + + //X-DFM-SupportSchemes + QString supportSchemesStr = getValue(actionSetting, group, kConfSupportSchemes).toString().simplified(); + if (!supportSchemesStr.isEmpty()) + tpEntry.m_supportSchemes = supportSchemesStr.split(":"); + + //X-DFM-NotShowIn + QString supportNotShowInStr = getValue(actionSetting, group, kConfNotShowIn).toString().simplified(); + if (!supportNotShowInStr.isEmpty()) + tpEntry.m_notShowIn = supportNotShowInStr.split(":"); + + //X-DFM-SupportSuffix + QString supportSuffixStr = getValue(actionSetting, group, kConfSupportSuffix).toString().simplified(); + if (!supportSuffixStr.isEmpty()) + tpEntry.m_supportSuffix = supportSuffixStr.split(":"); + + //comboPos + if (!comboPosForTopAction(actionSetting, group, actData)) + return false;//有一级菜单项支持的类型,但全无效,自动作为无效废弃项 + + tpEntry.m_package = basicInfos.m_package; + tpEntry.m_version = basicInfos.m_version; + tpEntry.m_comment = basicInfos.m_comment; + tpEntry.m_data = actData; + m_actionEntry.append(tpEntry); + } + else { + childrenActions.append(actData); + } + return true; +} + +/*! + 初始化一些判断内容 +*/ +void DCustomActionParser::initHash() +{ + m_combos.insert("SingleFile", ComboType::SingleFile); + m_combos.insert("SingleDir", ComboType::SingleDir); + m_combos.insert("MultiFiles", ComboType::MultiFiles); + m_combos.insert("MultiDirs", ComboType::MultiDirs); + m_combos.insert("FileAndDir", ComboType::FileAndDir); + m_combos.insert("BlankSpace", ComboType::BlankSpace); + + m_separtor.insert("None", Separator::None); + m_separtor.insert("Top", Separator::Top); + m_separtor.insert("Both", Separator::Both); + m_separtor.insert("Bottom", Separator::Bottom); + + //name参数类型仅支持:DirName BaseName FileName + m_actionNameArg.insert(kStrActionArg[DirName], ActionArg::DirName); //%d + m_actionNameArg.insert(kStrActionArg[BaseName], ActionArg::BaseName); //%b + m_actionNameArg.insert(kStrActionArg[FileName], ActionArg::FileName); //"%a", + + //cmd参数类型只支持:DirPath FilePath FilePaths UrlPath UrlPaths + m_actionExecArg.insert(kStrActionArg[DirPath], ActionArg::DirPath); //"%p" + m_actionExecArg.insert(kStrActionArg[FilePath], ActionArg::FilePath); //"%f" + m_actionExecArg.insert(kStrActionArg[FilePaths], ActionArg::FilePaths); //"%F" + m_actionExecArg.insert(kStrActionArg[UrlPath], ActionArg::UrlPath); //"%u" + m_actionExecArg.insert(kStrActionArg[UrlPaths], ActionArg::UrlPaths); //"%U" +} + +/*! + 获取配置文件对应组下的对应字段信息,\a actionSetting 是解析对象,\a group是待解析的组, \a key是待解析字段 +*/ +QVariant DCustomActionParser::getValue(QSettings &actionSetting, const QString &group, const QString &key) +{ + actionSetting.beginGroup(group); + auto temp = actionSetting.value(key, QVariant()); + actionSetting.endGroup(); + return temp; +} + +/*! + 获取配置文件的一些基本信息,\a actionSetting获取解析的基本信息,\a actionSetting 是解析对象, + 返回值表示该文件有效与否,基本的关键信息没有会被判定成无效的配置文件 +*/ +bool DCustomActionParser::actionFileInfos(FileBasicInfos &basicInfo, QSettings &actionSetting) +{ + //基本信息 + //文件名 + basicInfo.m_package = actionSetting.fileName(); + + //签名 + basicInfo.m_sign = getValue(actionSetting, kMenuPrefix, kConfSign).toString().simplified(); + + //版本 + basicInfo.m_version = getValue(actionSetting, kMenuPrefix, kConfFileVersion).toString().simplified(); + if (basicInfo.m_version.isEmpty()) + return false; + + //描述 + basicInfo.m_comment = getValue(actionSetting, kMenuPrefix, kConfComment).toString().simplified(); + return true; +} + +/*! + 菜单项名字参数动态获取 +*/ +void DCustomActionParser::actionNameDynamicArg(DCustomActionData &act) +{ + //name参数类型仅支持:DirName BaseName FileName + int firstValidIndex = act.m_name.indexOf("%"); + auto cnt = act.m_name.length() - 1; + if (0 == cnt || 0 > firstValidIndex) { + act.m_nameArg = NoneArg; + return; + } + + while (cnt > firstValidIndex) { + auto tgStr = act.m_name.mid(firstValidIndex, 2); + auto tempValue = m_actionNameArg.value(tgStr, NoneArg); + if (NoneArg != tempValue) { + act.m_nameArg = tempValue; + break; + } + firstValidIndex = act.m_name.indexOf("%", firstValidIndex + 1); + if (-1 == firstValidIndex) + break; + } +} + +/*! + 菜单项执行参数动态获取 +*/ +void DCustomActionParser::execDynamicArg(DCustomActionData &act) +{ + //cmd参数类型只支持:DirPath FilePath FilePaths UrlPath UrlPaths + int firstValidIndex = act.m_command.indexOf("%"); + auto cnt = act.m_command.length() - 1; + if (0 == cnt || 0 > firstValidIndex) { + act.m_cmdArg = NoneArg; + return; + } + + while (cnt > firstValidIndex) { + auto tgStr = act.m_command.mid(firstValidIndex, 2); + auto tempValue = m_actionExecArg.value(tgStr, NoneArg); + if (NoneArg != tempValue) { + act.m_cmdArg = tempValue; + break; + } + firstValidIndex = act.m_name.indexOf("%", firstValidIndex + 1); + if (-1 == firstValidIndex) + break; + } +} + +/*! + 菜单项对应位置 +*/ +bool DCustomActionParser::comboPosForTopAction(QSettings &actionSetting, const QString &group, DCustomActionData &act) +{ + //能到这一步说明这个文件的有效性已经验证了 + auto comboStr = getValue(actionSetting, group, kConfCombo).toString().simplified(); + QStringList comboList = comboStr.split(":", QString::SkipEmptyParts); + + QString cPos; + bool hasCombo = false; + for (auto temp : comboList) { + cPos = QString("%1-%2").arg(kActionPos, temp.simplified()); + auto ret = getValue(actionSetting, group, cPos); //取出对应选中类型的pos + if (m_combos.contains(temp)) { + int pos = act.m_position; + if (ret.isValid()) + pos = ret.toInt(); + act.m_comboPos.insert(m_combos.value(temp), pos); + hasCombo = true; + } + } + return hasCombo; +} + +void DCustomActionParser::delayRefresh() +{ + if (m_refreshTimer) { + m_refreshTimer->start(300); + qDebug() << "restart refresh timer" << this; + return; + } + + qDebug() << "create refresh timer" << this; + m_refreshTimer = new QTimer; + connect(m_refreshTimer,&QTimer::timeout,this,[this](){ + m_actionEntry.clear(); + + qInfo() << "loading custom menus" << this; + loadDir(kCustomMenuPath); + + m_refreshTimer->stop(); + m_refreshTimer->deleteLater(); + m_refreshTimer = nullptr; + }); + m_refreshTimer->start(300); +} + +bool DCustomActionParser::isActionShouldShow(const QStringList ¬ShowInList, bool onDesktop) +{ + // X-DFM-NotShowIn not exist + if (notShowInList.isEmpty()) + return true; //未明确指明仅显示在桌面或者文管窗口默认都显示 + if (notShowInList.contains("*")) + return false; //都不显示: 配置了"X-DFM-NotShowIn=*"或者"X-DFM-NotShowIn=desktop:filemanager" + + // is menu triggered on desktop + return (onDesktop && !notShowInList.contains("Desktop", Qt::CaseInsensitive)) || + (!onDesktop && !notShowInList.contains("Filemanager", Qt::CaseInsensitive)); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactionparser.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactionparser.h new file mode 100644 index 0000000..0408e07 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/customization/dcustomactionparser.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: liqiang + * + * Maintainer: liqiang + * zhangyu + * + * 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 + * 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 . + */ + +#ifndef DCUSTOMACTIONPARSER_H +#define DCUSTOMACTIONPARSER_H + +#include "dcustomactiondata.h" + +#include +#include +#include +#include +#include + +class QFileSystemWatcher; +class RegisterCustomFormat +{ +public: + static RegisterCustomFormat& instance(); + QSettings::Format customFormat(); +private: + RegisterCustomFormat(); + static bool readConf(QIODevice &device, QSettings::SettingsMap &settingsMap); + static bool writeConf(QIODevice &device, const QSettings::SettingsMap &settingsMap); +private: + QSettings::Format m_customFormat; +}; +class DCustomActionParser : public QObject +{ + Q_OBJECT +public: + explicit DCustomActionParser(QObject *parent = nullptr); + ~DCustomActionParser(); + + bool loadDir(const QString &dirPath); + QList getActionFiles(bool onDesktop); + + bool parseFile(QSettings &actionSetting); + bool parseFile(QList &childrenActions + , QSettings &actionSetting + , const QString &group + , const DCustomActionDefines::FileBasicInfos& basicInfos + , bool &isSort + , bool isTop = false); + + + void initHash(); + QVariant getValue(QSettings &actionSetting, const QString &group, const QString &key); + bool actionFileInfos(DCustomActionDefines::FileBasicInfos &basicInfo, QSettings &actionSetting); + + void actionNameDynamicArg(DCustomActionData &act); + void execDynamicArg(DCustomActionData &act); + bool comboPosForTopAction(QSettings &actionSetting, const QString&group, DCustomActionData &act); + static bool isActionShouldShow(const QStringList ¬ShowInList, bool onDesktop); + +signals: + void customMenuChanged(); +public slots: + void delayRefresh(); +private: + QTimer *m_refreshTimer = nullptr; + QFileSystemWatcher *m_fileWatcher = nullptr; + QList m_actionEntry; + QSettings::Format m_customFormat; + QHash m_combos; + QHash m_separtor; + QHash m_actionNameArg; + QHash m_actionExecArg; + int m_hierarchyNum = 0; + int m_topActionCount = 0; +}; + +#endif // DCUSTOMACTIONPARSER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfilecontroller.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfilecontroller.cpp new file mode 100644 index 0000000..1b2eb5e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfilecontroller.cpp @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dabstractfilecontroller.h" +#include "dfmevent.h" +#include "dfmstandardpaths.h" + +#include +#include + +DWIDGET_USE_NAMESPACE + +class DefaultDiriterator : public DDirIterator +{ +public: + DefaultDiriterator(const DAbstractFileController *controller, const QSharedPointer &event) ; + + DUrl next() override; + bool hasNext() const override; + + QString fileName() const override; + DUrl fileUrl() const override; + const DAbstractFileInfoPointer fileInfo() const override; + DUrl url() const override; + +private: + mutable QList m_children; + DAbstractFileController *m_controller; + mutable QSharedPointer m_event; + int m_current = -1; +}; + +DefaultDiriterator::DefaultDiriterator(const DAbstractFileController *controller, const QSharedPointer &event) + : m_event(event) +{ + m_controller = const_cast(controller); +} + +DUrl DefaultDiriterator::next() +{ + return m_children.at(++m_current)->fileUrl(); +} + +bool DefaultDiriterator::hasNext() const +{ + if (m_event) { + m_children = m_controller->getChildren(m_event); + m_event.clear(); + } + return m_current + 1 < m_children.count(); +} + +QString DefaultDiriterator::fileName() const +{ + return m_children.at(m_current)->fileName(); +} + +DUrl DefaultDiriterator::fileUrl() const +{ + return m_children.at(m_current)->fileUrl(); +} + +const DAbstractFileInfoPointer DefaultDiriterator::fileInfo() const +{ + return m_children.at(m_current); +} + +DUrl DefaultDiriterator::url() const +{ + return m_event->fileUrl(); +} + +DAbstractFileController::DAbstractFileController(QObject *parent) + : QObject(parent) +{ + +} + +bool DAbstractFileController::openFile(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::openFiles(const QSharedPointer &event) const +{ + event->ignore(); + return false; +} + +bool DAbstractFileController::openFileByApp(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::openFilesByApp(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::compressFiles(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::decompressFile(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::decompressFileHere(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::writeFilesToClipboard(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::renameFile(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::deleteFiles(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +DUrlList DAbstractFileController::moveToTrash(const QSharedPointer &event) const +{ + event->ignore(); + + return DUrlList(); +} + +DUrlList DAbstractFileController::pasteFile(const QSharedPointer &event) const +{ + event->ignore(); + + return DUrlList(); +} + +bool DAbstractFileController::restoreFile(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::mkdir(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::touch(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::setPermissions(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::openFileLocation(const QSharedPointer &event) const +{ + const DUrl &durl = event->url(); + // why? because 'DDesktopServices::showFileItem(realUrl(event->url()))' will call session bus 'org.freedesktop.FileManager1' + // but cannot find session bus when user is root! + if (DFMGlobal::isRootUser()) { + QStringList urls{QStringList() << durl.toLocalFile()}; + // call by platform 'mips' + if (QProcess::startDetached("file-manager.sh", QStringList() << "--show-item" << urls << "--raw")) + return true; + + return QProcess::startDetached("dde-file-manager", QStringList() << "--show-item" << urls << "--raw"); + } + + DUrl realUrl = durl; + if (durl.path().startsWith(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))) { + QString trashFilePath = durl.path(); + if (trashFilePath == DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath)) + trashFilePath = trashFilePath + "/"; + realUrl = trashFilePath.replace(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath) + "/", TRASH_ROOT); + } + return DDesktopServices::showFileItem(realUrl); +} + +const QList DAbstractFileController::getChildren(const QSharedPointer &event) const +{ + const_cast(this)->setProperty("_d_call_createDirIterator_in_DAbstractFileController::getChildren", true); + + const DDirIteratorPointer &iterator = createDirIterator(dMakeEventPointer(event->sender(), event->url(), event->nameFilters(), + event->filters(), event->flags())); + + const_cast(this)->setProperty("_d_call_createDirIterator_in_DAbstractFileController::getChildren", false); + + QList list; + + if (iterator) { + while (iterator->hasNext()) { + iterator->next(); + list.append(iterator->fileInfo()); + } + } + + return list; +} + +const DAbstractFileInfoPointer DAbstractFileController::createFileInfo(const QSharedPointer &event) const +{ + event->ignore(); + + return DAbstractFileInfoPointer(); +} + +const DDirIteratorPointer DAbstractFileController::createDirIterator(const QSharedPointer &event) const +{ + if (property("_d_call_createDirIterator_in_DAbstractFileController::getChildren").toBool()) { + event->ignore(); + + return DDirIteratorPointer(); + } + +// const QList &children = getChildren(event); + + return DDirIteratorPointer(new DefaultDiriterator(this, event)); +} + +bool DAbstractFileController::addToBookmark(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::removeBookmark(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::createSymlink(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::shareFolder(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::unShareFolder(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::openInTerminal(const QSharedPointer &event) const +{ + event->ignore(); + + return false; +} + +bool DAbstractFileController::setFileTags(const QSharedPointer &event) const +{ + event->ignore(); + return false; +} + +bool DAbstractFileController::removeTagsOfFile(const QSharedPointer &event) const +{ + event->ignore(); + return false; +} + +QList DAbstractFileController::getTagsThroughFiles(const QSharedPointer &event) const +{ + event->ignore(); + return {QString()}; +} + +DAbstractFileWatcher *DAbstractFileController::createFileWatcher(const QSharedPointer &event) const +{ + event->ignore(); + + return nullptr; +} + +DFM_NAMESPACE::DFileDevice *DAbstractFileController::createFileDevice(const QSharedPointer &event) const +{ + event->ignore(); + + return nullptr; +} + +DFM_NAMESPACE::DFileHandler *DAbstractFileController::createFileHandler(const QSharedPointer &event) const +{ + event->ignore(); + + return nullptr; +} + +DFM_NAMESPACE::DStorageInfo *DAbstractFileController::createStorageInfo(const QSharedPointer &event) const +{ + event->ignore(); + + return nullptr; +} + +bool DAbstractFileController::setExtraProperties(const QSharedPointer &event) const +{ + const auto &&ep = event->extraProperties(); + const QStringList &tag_name_list = ep.value("tag_name_list").toStringList(); + + return setFileTags(dMakeEventPointer(event->sender(), event->url(), tag_name_list)); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfilecontroller.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfilecontroller.h new file mode 100644 index 0000000..f3942ce --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfilecontroller.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef ABSTRACTFILECONTROLLER_H +#define ABSTRACTFILECONTROLLER_H + +#include "dabstractfileinfo.h" +#include "ddiriterator.h" + +#include +#include +#include + +class DFMEvent; +class DFMOpenFileEvent; +class DFMOpenFilesEvent; +class DFMOpenFileByAppEvent; +class DFMOpenFilesByAppEvent; +class DFMCompressEvent; +class DFMDecompressEvent; +class DFMWriteUrlsToClipboardEvent; +class DFMRenameEvent; +class DFMDeleteEvent; +class DFMMoveToTrashEvent; +class DFMRestoreFromTrashEvent; +class DFMPasteEvent; +class DFMMkdirEvent; +class DFMTouchFileEvent; +class DFMSetPermissionEvent; +class DFMOpenFileLocation; +class DFMAddToBookmarkEvent; +class DFMRemoveBookmarkEvent; +class DFMCreateSymlinkEvent; +class DFMGetChildrensEvent; +class DFMCreateDiriterator; +class DFMCreateFileInfoEvent; +class DFMCreateFileWatcherEvent; +class DFMOpenInTerminalEvent; +class DFMFileShareEvent; +class DFMCancelFileShareEvent; +class DUrl; +class DAbstractFileWatcher; +class DFMSetFileTagsEvent; +class DFMRemoveTagsOfFileEvent; +class DFMGetTagsThroughFilesEvent; +class DFMSetFileExtraProperties; +class DFMUrlBaseEvent; + +DFM_BEGIN_NAMESPACE +class DFileHandler; +class DFileDevice; +class DStorageInfo; +DFM_END_NAMESPACE + +typedef QList DUrlList; +class DAbstractFileController : public QObject +{ + Q_OBJECT + +public: + explicit DAbstractFileController(QObject *parent = 0); + + virtual bool openFile(const QSharedPointer &event) const; + virtual bool openFiles(const QSharedPointer &event) const; + virtual bool openFileByApp(const QSharedPointer &event) const; + virtual bool openFilesByApp(const QSharedPointer &event) const; + virtual bool compressFiles(const QSharedPointer &event) const; + virtual bool decompressFile(const QSharedPointer &event) const; + virtual bool decompressFileHere(const QSharedPointer &event) const; + virtual bool writeFilesToClipboard(const QSharedPointer &event) const; + virtual bool renameFile(const QSharedPointer &event) const; + virtual bool deleteFiles(const QSharedPointer &event) const; + virtual DUrlList moveToTrash(const QSharedPointer &event) const; + virtual DUrlList pasteFile(const QSharedPointer &event) const; + virtual bool restoreFile(const QSharedPointer &event) const; + virtual bool mkdir(const QSharedPointer &event) const; + virtual bool touch(const QSharedPointer &event) const; + virtual bool setPermissions(const QSharedPointer &event) const; + + virtual bool openFileLocation(const QSharedPointer &event) const; + + virtual const QList getChildren(const QSharedPointer &event) const; + virtual const DAbstractFileInfoPointer createFileInfo(const QSharedPointer &event) const; + virtual const DDirIteratorPointer createDirIterator(const QSharedPointer &event) const; + + virtual bool addToBookmark(const QSharedPointer &event) const; + virtual bool removeBookmark(const QSharedPointer &event) const; + + virtual bool createSymlink(const QSharedPointer &event) const; + virtual bool shareFolder(const QSharedPointer &event) const; + virtual bool unShareFolder(const QSharedPointer &event) const; + virtual bool openInTerminal(const QSharedPointer &event) const; + + virtual bool setFileTags(const QSharedPointer &event) const; + virtual bool removeTagsOfFile(const QSharedPointer &event) const; + virtual QList getTagsThroughFiles(const QSharedPointer &event) const; + + virtual DAbstractFileWatcher *createFileWatcher(const QSharedPointer &event) const; + virtual DFM_NAMESPACE::DFileDevice *createFileDevice(const QSharedPointer &event) const; + virtual DFM_NAMESPACE::DFileHandler *createFileHandler(const QSharedPointer &event) const; + virtual DFM_NAMESPACE::DStorageInfo *createStorageInfo(const QSharedPointer &event) const; + + virtual bool setExtraProperties(const QSharedPointer &event) const; +}; + +#endif // ABSTRACTFILECONTROLLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfileinfo.cpp new file mode 100644 index 0000000..20feea1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfileinfo.cpp @@ -0,0 +1,2025 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "gio/gio.h" + +#include "dabstractfileinfo.h" +#include "private/dabstractfileinfo_p.h" +#include "views/dfileview.h" +#include "dfilemenu.h" + +#include "dfilesystemmodel.h" +#include "dfilemenumanager.h" + +#include "shutil/fileutils.h" +#include "shutil/mimetypedisplaymanager.h" + +#include "controllers/bookmarkmanager.h" +#include "controllers/pathmanager.h" +#include "controllers/vaultcontroller.h" +#include "dfileservices.h" +#include "dmimedatabase.h" + +#include "app/define.h" +#include "shutil/mimesappsmanager.h" +#include "controllers/appcontroller.h" + +#include "singleton.h" +#include "plugins/pluginmanager.h" +#include "dde-file-manager-plugins/plugininterfaces/menu/menuinterface.h" + +#include "deviceinfo/udisklistener.h" +#include "ddiskmanager.h" +#include "ddiskdevice.h" + +#include "bluetooth/bluetoothmanager.h" +#include "bluetooth/bluetoothmodel.h" + +#include "io/dstorageinfo.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // std::unique_ptr + +DCORE_USE_NAMESPACE + +#ifdef SW_LABEL +#include "sw_label/filemanagerlibrary.h" +#include "dfilemenumanager.h" +#endif + + +namespace FileSortFunction { +//fix 多线程排序时,该处的全局变量在compareByString函数中可能导致软件崩溃 +//QCollator sortCollator; +class DCollator : public QCollator +{ +public: + DCollator() : QCollator() + { + setNumericMode(true); + setCaseSensitivity(Qt::CaseInsensitive); + } +}; + +bool compareByString(const QString &str1, const QString &str2, Qt::SortOrder order) +{ + thread_local static DCollator sortCollator; + //其他符号要排在最后,需要在中文前先做判断 + if (DFMGlobal::startWithSymbol(str1)) { + if (!DFMGlobal::startWithSymbol(str2)) + return order == Qt::DescendingOrder; + } else if (DFMGlobal::startWithSymbol(str2)) + return order != Qt::DescendingOrder; + + if (DFMGlobal::startWithHanzi(str1)) { + if (!DFMGlobal::startWithHanzi(str2)) { + return order == Qt::DescendingOrder; + } + } else if (DFMGlobal::startWithHanzi(str2)) { + return order != Qt::DescendingOrder; + } + + return ((order == Qt::DescendingOrder) ^ (sortCollator.compare(str1, str2) < 0)) == 0x01; +} + +COMPARE_FUN_DEFINE(fileDisplayName, DisplayName, DAbstractFileInfo) +COMPARE_FUN_DEFINE(fileSize, Size, DAbstractFileInfo) +COMPARE_FUN_DEFINE(lastModified, Modified, DAbstractFileInfo) +COMPARE_FUN_DEFINE(fileTypeDisplayName, Mime, DAbstractFileInfo) +COMPARE_FUN_DEFINE(created, Created, DAbstractFileInfo) +COMPARE_FUN_DEFINE(lastRead, LastRead, DAbstractFileInfo) +} /// end namespace FileSortFunction + +#define CALL_PROXY(Fun)\ + Q_D(const DAbstractFileInfo);\ + if (d->proxy) return d->proxy->Fun; + +QMap DAbstractFileInfoPrivate::urlToFileInfoMap; +QReadWriteLock *DAbstractFileInfoPrivate::urlToFileInfoMapLock = new QReadWriteLock(); +DMimeDatabase DAbstractFileInfoPrivate::mimeDatabase; + +DAbstractFileInfoPrivate::DAbstractFileInfoPrivate(const DUrl &url, DAbstractFileInfo *qq, bool hasCache) + : q_ptr(qq) + , fileUrl(url) +{ + //###(zccrs): 只在主线程中开启缓存,防止不同线程中持有同一对象时的竞争问题 + if (hasCache && (url.isValid() && (QThread::currentThread()) && qApp && qApp->thread() && QThread::currentThread() == qApp->thread())) { + QWriteLocker locker(urlToFileInfoMapLock); + Q_UNUSED(locker) + + urlToFileInfoMap[url] = qq; + } +} + +DAbstractFileInfoPrivate::~DAbstractFileInfoPrivate() +{ + QReadLocker read_locker(urlToFileInfoMapLock); + if (urlToFileInfoMap.value(fileUrl) == q_ptr) { + read_locker.unlock(); + QWriteLocker write_locker(urlToFileInfoMapLock); + Q_UNUSED(write_locker) + urlToFileInfoMap.remove(fileUrl); + } else { + read_locker.unlock(); + } +} + +void DAbstractFileInfoPrivate::setUrl(const DUrl &url, bool hasCache) +{ + if (url == fileUrl) { + return; + } + + if (urlToFileInfoMap.value(fileUrl) == q_ptr) { + QWriteLocker locker(urlToFileInfoMapLock); + Q_UNUSED(locker) + urlToFileInfoMap.remove(fileUrl); + } + + if (hasCache) { + QWriteLocker locker(urlToFileInfoMapLock); + Q_UNUSED(locker) + urlToFileInfoMap[url] = q_ptr; + } + fileUrl = url; +} + +DAbstractFileInfo *DAbstractFileInfoPrivate::getFileInfo(const DUrl &fileUrl) +{ + //###(zccrs): 只在主线程中开启缓存,防止不同线程中持有同一对象时的竞争问题,优化都可以 + if (!QThread::currentThread() || !qApp || !qApp->thread() || QThread::currentThread() != qApp->thread()) { + return nullptr; + } + + if (!fileUrl.isValid()) { + return nullptr; + } + return urlToFileInfoMap.value(fileUrl); +} + +DAbstractFileInfo::DAbstractFileInfo(const DUrl &url, bool hasCache) + : d_ptr(new DAbstractFileInfoPrivate(url, this, hasCache)) +{ + +} + +DAbstractFileInfo::DAbstractFileInfo(const DUrl &url, const QMimeType &mimetype, bool hasCache) + : d_ptr(new DAbstractFileInfoPrivate(url, this, hasCache)) +{ + Q_UNUSED(mimetype); +} + +DAbstractFileInfo::~DAbstractFileInfo() +{ + +} + +const DAbstractFileInfoPointer DAbstractFileInfo::getFileInfo(const DUrl &fileUrl) +{ + return DAbstractFileInfoPointer(DAbstractFileInfoPrivate::getFileInfo(fileUrl)); +} + +bool DAbstractFileInfo::exists() const +{ + CALL_PROXY(exists()); + + return false; +} + +bool DAbstractFileInfo::isPrivate() const +{ + return false; +} + +QString DAbstractFileInfo::path() const +{ + CALL_PROXY(path()); + + const QString &filePath = this->filePath(); + + int index = filePath.lastIndexOf(QDir::separator()); + + if (index >= 0) { + return filePath.left(index); + } + + return filePath; +} + +QString DAbstractFileInfo::filePath() const +{ + CALL_PROXY(filePath()); + + return fileUrl().path(); +} + +QString DAbstractFileInfo::absolutePath() const +{ + CALL_PROXY(absolutePath()); + + if (isAbsolute()) { + return path(); + } + + QFileInfo info(filePath()); + + return info.absolutePath(); +} + +QString DAbstractFileInfo::absoluteFilePath() const +{ + CALL_PROXY(absoluteFilePath()); + + if (isAbsolute()) { + return filePath(); + } + + QFileInfo info(filePath()); + + return info.absoluteFilePath(); +} + +QString DAbstractFileInfo::baseName() const +{ + CALL_PROXY(baseName()); + + const QString &fileName = this->fileName(); + const QString &suffix = this->suffix(); + + if (suffix.isEmpty()) { + return fileName; + } + + return fileName.left(fileName.length() - suffix.length() - 1); +} + +QString DAbstractFileInfo::baseNameOfRename() const +{ + return baseName(); +} + +QString DAbstractFileInfo::fileName() const +{ + CALL_PROXY(fileName()); + + QString filePath = this->filePath(); + + if (filePath.endsWith(QDir::separator())) { + filePath.chop(1); + } + + int index = filePath.lastIndexOf(QDir::separator()); + + if (index >= 0) { + return filePath.mid(index + 1); + } + + return filePath; +} + +QString DAbstractFileInfo::fileNameOfRename() const +{ + return fileName(); +} + +QString DAbstractFileInfo::fileDisplayName() const +{ + CALL_PROXY(fileDisplayName()); + + return fileName(); +} + +QString DAbstractFileInfo::fileSharedName() const +{ + CALL_PROXY(fileSharedName()); + + return QString(); +} + +QString DAbstractFileInfo::fileDisplayPinyinName() const +{ + Q_D(const DAbstractFileInfo); + + const QString &diaplayName = this->fileDisplayName(); + + if (d->pinyinName.isEmpty()) { + d->pinyinName = DFMGlobal::toPinyin(diaplayName); + } + + return d->pinyinName; +} + +bool DAbstractFileInfo::canRename() const +{ + CALL_PROXY(canRename()); + + return false; +} + +bool DAbstractFileInfo::canShare() const +{ + CALL_PROXY(canShare()); + + return false; +} + +bool DAbstractFileInfo::canFetch() const +{ + CALL_PROXY(canFetch()); + + return isDir() && !isPrivate(); +} + +bool DAbstractFileInfo::isReadable() const +{ + CALL_PROXY(isReadable()); + + return permission(QFile::ReadUser); +} + +bool DAbstractFileInfo::isWritable() const +{ + CALL_PROXY(isWritable()); + + return permission(QFile::WriteUser); +} + +bool DAbstractFileInfo::isExecutable() const +{ + CALL_PROXY(isExecutable()); + + return permission(QFile::ExeUser); +} + +bool DAbstractFileInfo::isHidden() const +{ + CALL_PROXY(isHidden()); + + return false; +} + +bool DAbstractFileInfo::isRelative() const +{ + CALL_PROXY(isRelative()); + + return false; +} + +bool DAbstractFileInfo::isAbsolute() const +{ + CALL_PROXY(isAbsolute()); + + return false; +} + +bool DAbstractFileInfo::isShared() const +{ + CALL_PROXY(isShared()); + + return false; +} + +bool DAbstractFileInfo::isTaged() const +{ + CALL_PROXY(isTaged()); + + return false; +} + +bool DAbstractFileInfo::canTag() const +{ + CALL_PROXY(canTag()); + + return false; +} + +bool DAbstractFileInfo::isWritableShared() const +{ + CALL_PROXY(isWritableShared()); + + return false; +} + +bool DAbstractFileInfo::isAllowGuestShared() const +{ + CALL_PROXY(isAllowGuestShared()); + + return false; +} + +bool DAbstractFileInfo::makeAbsolute() +{ + CALL_PROXY(makeAbsolute()); + + return false; +} + +bool DAbstractFileInfo::canDragCompress() const +{ + CALL_PROXY(canDragCompress()); + + return false; +} + +bool DAbstractFileInfo::canManageAuth() const +{ + CALL_PROXY(canManageAuth()); + + return true; +} + +bool DAbstractFileInfo::canMoveOrCopy() const +{ + CALL_PROXY(canMoveOrCopy()); + + return true; +} + +DAbstractFileInfo::FileType DAbstractFileInfo::fileType() const +{ + CALL_PROXY(fileType()); + + return Unknown; +} + +bool DAbstractFileInfo::isFile() const +{ + CALL_PROXY(isFile()); + + return false; +} + +bool DAbstractFileInfo::isDir() const +{ + CALL_PROXY(isDir()); + + return false; +} + +bool DAbstractFileInfo::isSymLink() const +{ + CALL_PROXY(isSymLink()); + + return false; +} + +bool DAbstractFileInfo::isDesktopFile() const +{ + CALL_PROXY(isDesktopFile()); + + return mimeTypeName() == "application/x-desktop"; +} + +// blumia: 任何对应不到实际文件的项都应当被视为虚拟的项,虚拟的项没有 MimeType , 最后修改时间等实际文件本身所应具有的相关属性。 +bool DAbstractFileInfo::isVirtualEntry() const +{ + CALL_PROXY(isVirtualEntry()); + + return false; +} + +bool DAbstractFileInfo::needCompleteDelete() const +{ + return (isGvfsMountFile() + || VaultController::isVaultFile(toLocalFile()) + || deviceListener->isInRemovableDeviceFolder(absoluteFilePath())) + && !isVirtualEntry(); +} + +bool DAbstractFileInfo::isDragCompressFileFormat() const +{ + CALL_PROXY(isDragCompressFileFormat()); + + return false; +} + +QString DAbstractFileInfo::symlinkTargetPath() const +{ + CALL_PROXY(symlinkTargetPath()); + + return QString(); +} + +DUrl DAbstractFileInfo::symLinkTarget() const +{ + CALL_PROXY(symLinkTarget()); + + return DUrl(); +} + +DUrl DAbstractFileInfo::rootSymLinkTarget() const +{ + DAbstractFileInfoPointer info = fileService->createFileInfo(Q_NULLPTR, fileUrl()); + + while (info->isSymLink()) { + DUrl targetUrl = info->symLinkTarget(); + + if (targetUrl == info->fileUrl()) { + break; + } + + info = fileService->createFileInfo(Q_NULLPTR, targetUrl); + if (!info) { + return DUrl(); + } + } + + return info->fileUrl(); +} + +QString DAbstractFileInfo::owner() const +{ + CALL_PROXY(owner()); + + return QString(); +} + +uint DAbstractFileInfo::ownerId() const +{ + CALL_PROXY(ownerId()); + + return 0; +} + +QString DAbstractFileInfo::group() const +{ + CALL_PROXY(group()); + + return QString(); +} + +uint DAbstractFileInfo::groupId() const +{ + CALL_PROXY(groupId()); + + return 0; +} + +bool DAbstractFileInfo::permission(QFileDevice::Permissions permissions) const +{ + CALL_PROXY(permission(permissions)); + + return (permissions & this->permissions()) == permissions; +} + +QFileDevice::Permissions DAbstractFileInfo::permissions() const +{ + CALL_PROXY(permissions()); + + return QFileDevice::Permissions(); +} + +qint64 DAbstractFileInfo::size() const +{ + CALL_PROXY(size()); + + return -1; +} + +int DAbstractFileInfo::filesCount() const +{ + CALL_PROXY(filesCount()); + + const DDirIteratorPointer &iterator = fileService->createDirIterator(Q_NULLPTR, fileUrl(), QStringList(), + QDir::AllEntries | QDir::System + | QDir::NoDotAndDotDot | QDir::Hidden, + QDirIterator::NoIteratorFlags); + + int count = 0; + + if (!iterator) { + return -1; + } + + while (iterator->hasNext()) { + iterator->next(); + + ++count; + } + + return count; +} + +qint64 DAbstractFileInfo::fileSize() const +{ + if (isDir()) { + return filesCount(); + } + + return size(); +} + +QDateTime DAbstractFileInfo::created() const +{ + CALL_PROXY(created()); + + return QDateTime(); +} + +QDateTime DAbstractFileInfo::lastModified() const +{ + CALL_PROXY(lastModified()); + + return QDateTime(); +} + +QDateTime DAbstractFileInfo::lastRead() const +{ + CALL_PROXY(lastRead()); + + return QDateTime(); +} + +QMimeType DAbstractFileInfo::mimeType(QMimeDatabase::MatchMode mode) const +{ + CALL_PROXY(mimeType(mode)); + + return QMimeType(); +} + +QString DAbstractFileInfo::iconName() const +{ + return mimeType().iconName(); +} + +QString DAbstractFileInfo::genericIconName() const +{ + return mimeType().genericIconName(); +} + +QString DAbstractFileInfo::lastReadDisplayName() const +{ + CALL_PROXY(lastReadDisplayName()); + + return lastRead().toString(dateTimeFormat()); +} + +QString DAbstractFileInfo::lastModifiedDisplayName() const +{ + CALL_PROXY(lastModifiedDisplayName()); + + if (!lastModified().isValid()) + return qApp->translate("MimeTypeDisplayManager", "Unknown"); + + return lastModified().toString(dateTimeFormat()); +} + +QString DAbstractFileInfo::createdDisplayName() const +{ + CALL_PROXY(createdDisplayName()); + + return created().toString(dateTimeFormat()); +} + +QString DAbstractFileInfo::sizeDisplayName() const +{ + CALL_PROXY(sizeDisplayName()); + + if (isDir()) { + int size = filesCount(); + + if (size <= 1) { + return QObject::tr("%1 item").arg(size); + } else { + return QObject::tr("%1 items").arg(size); + } + } else { + return FileUtils::formatSize(size()); + } +} + +QString DAbstractFileInfo::mimeTypeDisplayName() const +{ + CALL_PROXY(mimeTypeDisplayName()); + + return mimeTypeDisplayManager->displayName(mimeTypeName()); +} + +QString DAbstractFileInfo::fileTypeDisplayName() const +{ + CALL_PROXY(fileTypeDisplayName()); + + return QString::number(mimeTypeDisplayManager->displayNameToEnum(mimeTypeName())).append(suffix()); +} + +DUrl DAbstractFileInfo::fileUrl() const +{ + Q_D(const DAbstractFileInfo); + + return d->fileUrl; +} + +QIcon DAbstractFileInfo::fileIcon() const +{ + CALL_PROXY(fileIcon()); + + QIcon icon = QIcon::fromTheme(iconName()); + + if (icon.isNull()) { + icon = QIcon::fromTheme("application-default-icon"); + } + return icon; +} + +QList DAbstractFileInfo::additionalIcon() const +{ + CALL_PROXY(additionalIcon()); + + QList icons; + + if (isSymLink()) { + icons << QIcon::fromTheme("emblem-symbolic-link", DFMGlobal::instance()->standardIcon(DFMGlobal::LinkIcon)); + } + + if (!isWritable()) { + icons << QIcon::fromTheme("emblem-readonly", DFMGlobal::instance()->standardIcon(DFMGlobal::LockIcon)); + } + + if (!isReadable()) { + icons << QIcon::fromTheme("emblem-unreadable", DFMGlobal::instance()->standardIcon(DFMGlobal::UnreadableIcon)); + } + + if (isShared()) { + icons << QIcon::fromTheme("emblem-shared", DFMGlobal::instance()->standardIcon(DFMGlobal::ShareIcon)); + } + +#ifdef SW_LABEL + QString labelIconPath = getLabelIcon(); + if (!labelIconPath.isEmpty()) { + icons << QIcon(labelIconPath); + } +#endif + + return icons; +} + +DUrl DAbstractFileInfo::parentUrl() const +{ + return DUrl::parentUrl(fileUrl()); +} + +DUrlList DAbstractFileInfo::parentUrlList() const +{ + QList urlList; + + Q_UNUSED(isAncestorsUrl(DUrl(), &urlList)); + + return urlList; +} + +bool DAbstractFileInfo::isAncestorsUrl(const DUrl &url, QList *ancestors) const +{ + DUrl parentUrl = this->parentUrl(); + + forever { + if (ancestors && parentUrl.isValid()) { + ancestors->append(parentUrl); + } + + if (parentUrl == url || DStorageInfo::isSameFile(parentUrl.path(), url.path())) { + return true; + } + + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, parentUrl); + + if (!fileInfo) { + break; + } + + const DUrl &pu = fileInfo->parentUrl(); + + if (pu == parentUrl) { + break; + } + + parentUrl = pu; + } + + return false; +} + +QVector DAbstractFileInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + QVector actionKeys; +// Q_D(const DAbstractFileInfo); 未使用 + if (type == SpaceArea) { + actionKeys.reserve(9); + + actionKeys << MenuAction::NewFolder + << MenuAction::NewDocument + << MenuAction::Separator + << MenuAction::DisplayAs + << MenuAction::SortBy + << MenuAction::OpenAsAdmin + << MenuAction::OpenInTerminal + << MenuAction::RefreshView + << MenuAction::Separator + << MenuAction::Paste + << MenuAction::SelectAll + << MenuAction::Separator + << MenuAction::Property; + } else if (type == SingleFile) { + + if (isDir() && systemPathManager->isSystemPath(filePath())) { + actionKeys << MenuAction::Open + << MenuAction::OpenInNewWindow + << MenuAction::OpenInNewTab + << MenuAction::OpenAsAdmin + << MenuAction::Separator + << MenuAction::Copy + << MenuAction::Separator + << MenuAction::Compress + << MenuAction::Separator; + + if (canShare() && !isShared()) { + actionKeys << MenuAction::Share + << MenuAction::Separator; + } else if (isShared()) { + actionKeys << MenuAction::UnShare + << MenuAction::Separator; + } + actionKeys << MenuAction::CreateSymlink + << MenuAction::SendToDesktop + << MenuAction::Separator + << MenuAction::OpenInTerminal + << MenuAction::Separator; + + actionKeys << MenuAction::Property; + + } else { + actionKeys << MenuAction::Open; + + if (!isVirtualEntry()) { + actionKeys << MenuAction::OpenWith; + } + + if (isDir()) { + actionKeys << MenuAction::OpenInNewWindow + << MenuAction::OpenInNewTab + << MenuAction::OpenAsAdmin; + } else { + QSet mountable = {"application/x-cd-image", "application/x-iso9660-image"}; + if (mountable.contains(mimeTypeName())) { + actionKeys << MenuAction::MountImage; + } + } + actionKeys << MenuAction::Separator + << MenuAction::Cut + << MenuAction::Copy + << MenuAction::Rename; + const_cast(this)->checkMountFile(); + if (isGvfsMountFile() || deviceListener->isInRemovableDeviceFolder(absoluteFilePath())) { + if (!isVirtualEntry()) { + actionKeys << MenuAction::CompleteDeletion; + } + } else { + actionKeys << MenuAction::Delete; + } + actionKeys << MenuAction::Separator; + + if (isDir()) { + actionKeys << MenuAction::Compress; + + actionKeys << MenuAction::Separator; + + if (canShare() && !isShared()) { + actionKeys << MenuAction::Share + << MenuAction::Separator; + } else if (isShared()) { + actionKeys << MenuAction::UnShare + << MenuAction::Separator; + } + + } else if (isFile()) { + if (!FileUtils::isArchive(absoluteFilePath())) { + actionKeys << MenuAction::Compress + << MenuAction::Separator; + } + } + + if (isFile()) { + if (FileUtils::isArchive(absoluteFilePath())) { + actionKeys << MenuAction::Decompress + << MenuAction::DecompressHere + << MenuAction::Separator; + } + } + + actionKeys << MenuAction::CreateSymlink + << MenuAction::SendToDesktop; + + if (deviceListener->getCanSendDisksByUrl(absoluteFilePath()).count() > 0 + || bluetoothManager->hasAdapter()) { + actionKeys << MenuAction::SendToRemovableDisk; + } + + DDiskManager diskm; + for (auto &devs : diskm.diskDevices()) { + QScopedPointer dev(DDiskManager::createDiskDevice(devs)); + if (dev->mediaCompatibility().join(' ').contains("_r") && dev->optical()) { + actionKeys << MenuAction::StageFileForBurning; + break; + } + } + + if (isDir()) { + // FIXME: reimplement BookMark::exist() 's behavior and use it for check bookmark existance. + // after doing this, don't forget to remove the "bookmarkmanager.h" header file include. + // if (DFileService::instance()->createFileInfo(nullptr, DUrl::fromBookMarkFile(fileUrl(), QString()))) { + if (!isSymLink()) { + if (Singleton::instance()->checkExist(DUrl::fromBookMarkFile(fileUrl(), QString()))) { + actionKeys << MenuAction::BookmarkRemove; + } else { + actionKeys << MenuAction::AddToBookMark; + } + } + + actionKeys << MenuAction::Separator + << MenuAction::OpenInTerminal + << MenuAction::Separator; + } else if (isFile()) { + if (mimeTypeName().startsWith("image") && isReadable() +// && !mimeTypeName().endsWith("gif") + && !mimeTypeName().endsWith("svg+xml") + && !mimeTypeName().endsWith("raf") + && !mimeTypeName().endsWith("crw")) { + actionKeys << MenuAction::SetAsWallpaper + << MenuAction::Separator; + } + } + +#ifdef SW_LABEL + qDebug() << LabelMenuItemIds; + foreach (QString id, LabelMenuItemIds) { + int index = LabelMenuItemIds.indexOf(id); + MenuAction actionType = MenuAction(MenuAction::Unknow + index + 1); + actionKeys << actionType; + fileMenuManger->setActionString(actionType, LabelMenuItemDatas[id].label); + fileMenuManger->setActionID(actionType, id); + } + actionKeys << MenuAction::Separator; +#endif + int size { actionKeys.size() }; + + if (actionKeys[size - 1] != MenuAction::Separator) { + actionKeys << MenuAction::Separator; + } + + ///###: tag protocol + actionKeys << MenuAction::TagInfo; + actionKeys << MenuAction::TagFilesUseColor; + + actionKeys << MenuAction::Property; + } + + } else if (type == MultiFiles) { + actionKeys << MenuAction::Open + << MenuAction::OpenWith + << MenuAction::Separator + << MenuAction::Cut + << MenuAction::Copy + << MenuAction::Rename + << MenuAction::Compress + << MenuAction::SendToDesktop; + + if (deviceListener->getCanSendDisksByUrl(absoluteFilePath()).count() > 0 + || bluetoothManager->hasAdapter()) { + actionKeys << MenuAction::SendToRemovableDisk; + } + + DDiskManager diskm; + for (auto &devs : diskm.diskDevices()) { + QScopedPointer dev(DDiskManager::createDiskDevice(devs)); + if (dev->mediaCompatibility().join(' ').contains("_r") && dev->optical()) { + actionKeys << MenuAction::StageFileForBurning; + break; + } + } + const_cast(this)->checkMountFile(); + if (isGvfsMountFile() || deviceListener->isInRemovableDeviceFolder(absoluteFilePath())) { + if (!isVirtualEntry()) { + actionKeys << MenuAction::CompleteDeletion; + } + } else { + actionKeys << MenuAction::Delete; + } + actionKeys << MenuAction::Separator + << MenuAction::Property; + + ///###: tag protocol. + actionKeys << MenuAction::TagInfo; + actionKeys << MenuAction::TagFilesUseColor; + + actionKeys << MenuAction::Property; + + } else if (type == MultiFilesSystemPathIncluded) { + actionKeys << MenuAction::Open + << MenuAction::Separator + << MenuAction::Copy + << MenuAction::Compress + << MenuAction::SendToDesktop + << MenuAction::Separator; + + ///###: tag protocol. + actionKeys << MenuAction::TagInfo; + actionKeys << MenuAction::TagFilesUseColor; + + actionKeys << MenuAction::Property; + } + + if (isGvfsMountFile()) + actionKeys.removeAll(MenuAction::OpenAsAdmin); + + return actionKeys; +} + + +quint8 DAbstractFileInfo::supportViewMode() const +{ + return DFileView::AllViewMode; +} + +QList DAbstractFileInfo::supportSelectionModes() const +{ + return QList() << ExtendedSelection << SingleSelection << MultiSelection + << ContiguousSelection << NoSelection; +} + +void DAbstractFileInfo::setColumnCompact(bool compact) +{ + Q_D(DAbstractFileInfo); + + d->columnCompact = compact; +} + +bool DAbstractFileInfo::columnIsCompact() const +{ + Q_D(const DAbstractFileInfo); + + return d->columnCompact; +} + +QList DAbstractFileInfo::userColumnRoles() const +{ + Q_D(const DAbstractFileInfo); + + if (d->columnCompact) { + static QList userColumnRoles { + DFileSystemModel::FileDisplayNameRole, + DFileSystemModel::FileUserRole + 1 + }; + + return userColumnRoles; + } + + static QList userColumnRoles = QList() << DFileSystemModel::FileDisplayNameRole + << DFileSystemModel::FileLastModifiedRole + << DFileSystemModel::FileSizeRole + << DFileSystemModel::FileMimeTypeRole; + + return userColumnRoles; +} + +QVariant DAbstractFileInfo::userColumnDisplayName(int userColumnRole) const +{ + Q_D(const DAbstractFileInfo); + + if (d->columnCompact && userColumnRole == DFileSystemModel::FileUserRole + 1) { + return qApp->translate("DFileSystemModel", "Time modified"); + } + + return DFileSystemModel::roleName(userColumnRole); +} + +QVariant DAbstractFileInfo::userColumnData(int userColumnRole) const +{ + Q_D(const DAbstractFileInfo); + + if (d->columnCompact && userColumnRole == DFileSystemModel::FileUserRole + 1) { + return QVariant::fromValue(qMakePair(lastModifiedDisplayName(), qMakePair(sizeDisplayName(), mimeTypeDisplayName()))); + } + + switch (userColumnRole) { + case DFileSystemModel::FileLastModifiedRole: + return lastModifiedDisplayName(); + case DFileSystemModel::FileSizeRole: + return sizeDisplayName(); + case DFileSystemModel::FileMimeTypeRole: + return mimeTypeDisplayName(); + case DFileSystemModel::FileCreatedRole: + return createdDisplayName(); + default: + break; + } + + return QVariant(); +} + +QList DAbstractFileInfo::userColumnChildRoles(int column) const +{ + Q_D(const DAbstractFileInfo); + + if (d->columnCompact && column == 1) { + static QList userColumnRoles { + DFileSystemModel::FileLastModifiedRole, + DFileSystemModel::FileSizeRole, + DFileSystemModel::FileMimeTypeRole + }; + + return userColumnRoles; + } + + return QList(); +} + +int DAbstractFileInfo::userColumnWidth(int userColumnRole) const +{ + return userColumnWidth(userColumnRole, qApp->fontMetrics()); +} + +int DAbstractFileInfo::userColumnWidth(int userColumnRole, const QFontMetrics &fontMetrics) const +{ + switch (userColumnRole) { + case DFileSystemModel::FileNameRole: + case DFileSystemModel::FileDisplayNameRole: + return -1; + case DFileSystemModel::FileSizeRole: + return 80; + case DFileSystemModel::FileMimeTypeRole: + return 80; + default: + return fontMetrics.width("0000/00/00 00:00:00"); + } +} + +int DAbstractFileInfo::userRowHeight() const +{ + return userRowHeight(qApp->fontMetrics()); +} + +int DAbstractFileInfo::userRowHeight(const QFontMetrics &fontMetrics) const +{ + Q_D(const DAbstractFileInfo); + + if (d->columnCompact) { + return fontMetrics.height() * 2 + 10; + } + + return fontMetrics.height(); +} + +bool DAbstractFileInfo::columnDefaultVisibleForRole(int role) const +{ + Q_D(const DAbstractFileInfo); + + if (d->columnCompact && role == DFileSystemModel::FileUserRole + 1) { + return true; + } + + return !(role == DFileSystemModel::FileCreatedRole); +} + +DAbstractFileInfo::CompareFunction DAbstractFileInfo::compareFunByColumn(int columnRole) const +{ + switch (columnRole) { + case DFileSystemModel::FileDisplayNameRole: + return FileSortFunction::compareFileListByDisplayName; + case DFileSystemModel::FileLastModifiedRole: + return FileSortFunction::compareFileListByModified; + case DFileSystemModel::FileSizeRole: + return FileSortFunction::compareFileListBySize; + case DFileSystemModel::FileMimeTypeRole: + return FileSortFunction::compareFileListByMime; + case DFileSystemModel::FileCreatedRole: + return FileSortFunction::compareFileListByCreated; + case DFileSystemModel::FileLastReadRole: + return FileSortFunction::compareFileListByLastRead; + default: + return CompareFunction(); + } +} + +bool DAbstractFileInfo::hasOrderly() const +{ + return true; +} + +bool DAbstractFileInfo::canRedirectionFileUrl() const +{ + return isSymLink(); +} + +DUrl DAbstractFileInfo::redirectedFileUrl() const +{ + if (isSymLink()) { + return symLinkTarget(); + } + + return fileUrl(); +} + +bool DAbstractFileInfo::isEmptyFloder(const QDir::Filters &filters) const +{ + CALL_PROXY(isEmptyFloder(filters)); + + if (!isDir()) { + return false; + } + + DDirIteratorPointer it = DFileService::instance()->createDirIterator(Q_NULLPTR, fileUrl(), QStringList(), + filters, + QDirIterator::NoIteratorFlags); + + return it && !it->hasNext(); +} + +Qt::ItemFlags DAbstractFileInfo::fileItemDisableFlags() const +{ + CALL_PROXY(fileItemDisableFlags()); + + return Qt::ItemFlags(); +} + +bool DAbstractFileInfo::canIteratorDir() const +{ + return false; +} + +DUrl DAbstractFileInfo::getUrlByNewFileName(const QString &fileName) const +{ + DUrl url = fileUrl(); + + url.setPath(absolutePath() + QDir::separator() + fileName); + + return url; +} + +DUrl DAbstractFileInfo::getUrlByChildFileName(const QString &fileName) const +{ + CALL_PROXY(getUrlByChildFileName(fileName)); + + if (!isDir()) { + return DUrl(); + } + + DUrl url = fileUrl(); + + url.setPath(absoluteFilePath() + QDir::separator() + fileName); + + return url; +} + +DUrl DAbstractFileInfo::mimeDataUrl() const +{ + return fileUrl(); +} + +Qt::DropActions DAbstractFileInfo::supportedDragActions() const +{ + return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; +} + +Qt::DropActions DAbstractFileInfo::supportedDropActions() const +{ + if (isWritable()) { + return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; + } + + if (canDrop()) { + return Qt::CopyAction | Qt::MoveAction; + } + + return Qt::IgnoreAction; +} + +QString DAbstractFileInfo::loadingTip() const +{ + return QObject::tr("Loading..."); +} + +QString DAbstractFileInfo::subtitleForEmptyFloder() const +{ + return QString(); +} + +QString DAbstractFileInfo::suffix() const +{ + CALL_PROXY(suffix()); + + if (isDir()) { + return QString(); + } + // xushitong 20200424 修改后缀名获取策略为小数点后非空字符串 + const QString &strFileName = this->fileName(); + QString tmpName = strFileName; + int nIdx = 0; + QString strSuffix; + while (strSuffix.isEmpty()) { + nIdx = tmpName.lastIndexOf("."); + if (nIdx == -1) + return QString(); + strSuffix = tmpName.mid(nIdx + 1); + tmpName = tmpName.mid(0, nIdx); + } + return strFileName.mid(nIdx + 1); +} + +QString DAbstractFileInfo::suffixOfRename() const +{ + return suffix(); +} + +QString DAbstractFileInfo::completeSuffix() const +{ + CALL_PROXY(completeSuffix()); + + if (isDir()) { + return QString(); + } + + const QString &fileName = this->fileName(); + + int index = fileName.indexOf('.'); + + if (index >= 0) { + return fileName.mid(index + 1); + } + + return QString(); +} + +void DAbstractFileInfo::makeToInactive() +{ + Q_D(DAbstractFileInfo); + + if (d->proxy) { + d->proxy->makeToInactive(); + } + + if (!d->active) { + return; + } + + { + Q_D(DAbstractFileInfo); + + d->active = false; + } +} + +DUrl DAbstractFileInfo::goToUrlWhenDeleted() const +{ + DUrl parentUrl; + + foreach (const DUrl &url, parentUrlList()) { + parentUrl = url; + + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, url); + + if (fileInfo && fileInfo->exists()) { + break; + } + } + + return parentUrl.isValid() ? parentUrl : DUrl::fromLocalFile(QDir::homePath()); +} + +QString DAbstractFileInfo::toLocalFile() const +{ + CALL_PROXY(toLocalFile()); + + if (fileUrl().isLocalFile()) { + return fileUrl().toLocalFile(); + } + + const QFileInfo &info = toQFileInfo(); + + if (!info.fileName().isEmpty()) { + return info.absoluteFilePath(); + } + + return QString(); +} + +bool DAbstractFileInfo::canDrop() const +{ + if (isPrivate()) { + return false; + } + + if (!isSymLink()) { + return isDir() || isDesktopFile() || (canDragCompress() && isDragCompressFileFormat()); + } + + DAbstractFileInfoPointer info(const_cast(this)); + + do { + const DUrl &targetUrl = info->symLinkTarget(); + + if (targetUrl == info->fileUrl()) { + return false; + } + + info = fileService->createFileInfo(Q_NULLPTR, targetUrl); + + if (!info) { + return false; + } + } while (info->isSymLink()); + + return info->canDrop(); +} + +QFileInfo DAbstractFileInfo::toQFileInfo() const +{ + CALL_PROXY(toQFileInfo()); + + return QFileInfo(); +} + +QIODevice *DAbstractFileInfo::createIODevice() const +{ + CALL_PROXY(createIODevice()); + + return 0; +} + +QVariantHash DAbstractFileInfo::extraProperties() const +{ + CALL_PROXY(extraProperties()); + + return QVariantHash(); +} + +bool DAbstractFileInfo::checkMpsStr(const QString &) const +{ + return false; +} + +const QDateTime DAbstractFileInfo::getReadTime() const +{ + return QDateTime(); +} + +void DAbstractFileInfo::updateReadTime(const QDateTime &) +{ + +} + +bool DAbstractFileInfo::isGvfsMountFile() const +{ + Q_D(const DAbstractFileInfo); + if (-1 == d->gvfsMountFile) { + return false; + } + return d->gvfsMountFile > 0; +} + +qint8 DAbstractFileInfo::gvfsMountFile() const +{ + Q_D(const DAbstractFileInfo); + return d->gvfsMountFile; +} + +void DAbstractFileInfo::checkMountFile() +{ + Q_D(DAbstractFileInfo); + if (-1 == gvfsMountFile()) { + d->gvfsMountFile = FileUtils::isGvfsMountFile(absoluteFilePath()); + } +} + +quint64 DAbstractFileInfo::inode() const +{ + return 0; +} + +void DAbstractFileInfo::makeToActive() +{ + Q_D(DAbstractFileInfo); + if (d->proxy) { + d->proxy->makeToActive(); + } + if (d->active) { + return; + } + + { + Q_D(DAbstractFileInfo); + + d->active = true; + } +} + +bool DAbstractFileInfo::isActive() const +{ + CALL_PROXY(isActive()); + + return d->active; +} + +void DAbstractFileInfo::refresh(const bool isForce) +{ + CALL_PROXY(refresh(isForce)); +#ifdef SW_LABEL + updateLabelMenuItems(); +#endif +} + +DAbstractFileInfo::DAbstractFileInfo(DAbstractFileInfoPrivate &dd) + : d_ptr(&dd) +{ + +} + +static void onActionTriggered(QAction *action) +{ + const QString &target_dir = action->property("_fileinfo_path").toString(); + + if (target_dir.isEmpty()) { + return; + } + + const DFileMenu *menu = qvariant_cast(action->property("_dfm_menu")); + const QPair &data = qvariant_cast>(action->data()); + + const QWidget *w = menu; + + while (w->parentWidget()) { + w = w->parentWidget(); + } + + menu = qobject_cast(w); + + AppController::createFile(data.first, target_dir, data.second, menu ? menu->eventId() : -1); +} + +static QList getTemplateFileList() +{ + QList result; + + // blumia: Following is support for `xdg-user-dir TEMPLATES` Templates folder. + // It's suppored by many GNOME Nautilus based file manager. I don't think it's a good idea + // since we can't localization the file name text at all. + // blumia: templateFolderPathCStr owned by glib, should NOT be freeed. + QString templateFolderPath = DGlibUtils::userSpecialDir(DGlibUserDirectory::USER_DIRECTORY_TEMPLATES); + if (!templateFolderPath.isEmpty()) { + QDir templateFolder(templateFolderPath); + if (templateFolder.exists() && templateFolder != QDir::home()) { // accroding to xdg-user-dir, dir point to home means disable. + const QFileInfoList &templateFileInfoList = templateFolder.entryInfoList(QDir::Files | QDir::Readable | QDir::NoSymLinks); + for (const QFileInfo &fileInfo : templateFileInfoList) { + auto dfileinfo = DFileService::instance()->createFileInfo(nullptr, DUrl::fromLocalFile(fileInfo.filePath())); + const QString entrySourcePath = fileInfo.absoluteFilePath(); + const QString entryText = fileInfo.baseName(); + const QString entryFileBaseName = entryText; // suffix is based on source file, only base name is okay here. + QIcon icon = dfileinfo->fileIcon(); + QAction *action = new QAction(icon, entryText, Q_NULLPTR); + action->setData(QVariant::fromValue(qMakePair(entrySourcePath, entryFileBaseName))); + QObject::connect(action, &QAction::triggered, action, [action] { + onActionTriggered(action); + }); + result << action; + } + } + } + + // blumia: Following is support for `kf5-config --path templates` Templates folder. + QStringList systemDataFolderList = DGlibUtils::systemDataDirs(); + QStringList templateFolderList; + for (const QString &oneFolder : systemDataFolderList) { + templateFolderList << (oneFolder + QStringLiteral("templates")); + } + // user-specific template dir + templateFolderList << QString(DGlibUtils::userDataDir() + "templates"); + // start scan.. + for (const QString &oneTemplateFolder : templateFolderList) { + QDir templateFolder(oneTemplateFolder); + if (templateFolder.exists()) { + const QStringList &templateFileList = templateFolder.entryList(QStringList(QStringLiteral("*.desktop")), QDir::Files | QDir::Readable | QDir::NoSymLinks); + for (const QString &filePath : templateFileList) { + DDesktopEntry desktopFile(templateFolder.absoluteFilePath(filePath)); + const QString entrySourcePath = templateFolder.absoluteFilePath(desktopFile.stringValue("URL")); + const QString entryText = desktopFile.localizedValue("Name"); + const QString entryFileBaseName = entryText; // suffix is based on source file, only base name is okay here. + if (!QFileInfo(entrySourcePath).exists() || entryText.isEmpty()) { + continue; // holy shit! + } + qDebug() << templateFolder.absoluteFilePath(filePath) << entrySourcePath; + QIcon icon = QIcon::fromTheme(desktopFile.stringValue("Icon")); + QAction *action = new QAction(icon, entryText, Q_NULLPTR); + action->setData(QVariant::fromValue(qMakePair(entrySourcePath, entryFileBaseName))); + QObject::connect(action, &QAction::triggered, action, [action] { + onActionTriggered(action); + }); + result << action; + } + } + } + + return result; +} + +static QVector getMenuActionTypeListByAction(const QList &list) +{ + QVector type_list; + + type_list.reserve(type_list.size()); + + for (QAction *action : list) { + type_list.append(DFileMenuManager::registerMenuActionType(action)); + } + + return type_list; +} + +QMap > DAbstractFileInfo::subMenuActionList(MenuType type) const +{ + Q_UNUSED(type) + QMap > actions; + + QVector openwithMenuActionKeys; + actions.insert(MenuAction::OpenWith, openwithMenuActionKeys); + + + QVector docmentMenuActionKeys; +#ifdef DFM_MINIMUM + docmentMenuActionKeys << MenuAction::NewText; +#else + docmentMenuActionKeys << MenuAction::NewWord + << MenuAction::NewExcel + << MenuAction::NewPowerpoint + << MenuAction::NewText; +#endif + + static const QList template_file_list = getTemplateFileList(); + static const QVector action_type_list = getMenuActionTypeListByAction(template_file_list); + + QString urlStr = toLocalFile(); + if (urlStr.isEmpty()) { +#ifdef QT_DEBUG + qCritical() << fileUrl() << "scheme fileinfo seems doesn't implement toLocalFile() or implemented incorrectly."; + qCritical() << "This can be a bug and should be fixed!!!!!!!!"; +#endif + urlStr = fileUrl().toLocalFile(); + } + + for (QAction *action : template_file_list) { + action->setProperty("_fileinfo_path", urlStr); + } + + docmentMenuActionKeys << action_type_list; + actions.insert(MenuAction::NewDocument, docmentMenuActionKeys); + + QVector displayAsMenuActionKeys; + + int support_view_mode = supportViewMode(); + + if ((support_view_mode & DListView::IconMode) == DListView::IconMode) { + displayAsMenuActionKeys << MenuAction::IconView; + } + + if ((support_view_mode & DListView::ListMode) == DListView::ListMode) { + displayAsMenuActionKeys << MenuAction::ListView; + } + + actions.insert(MenuAction::DisplayAs, displayAsMenuActionKeys); + + QVector sortByMenuActionKeys; +// sortByMenuActionKeys << MenuAction::Name; + + for (int role : sortSubMenuActionUserColumnRoles()) { + sortByMenuActionKeys << menuActionByColumnRole(role); + } + + actions.insert(MenuAction::SortBy, sortByMenuActionKeys); + + if (deviceListener->isMountedRemovableDiskExits() + || bluetoothManager->hasAdapter()) { + QVector diskMenuActionKeys; + actions.insert(MenuAction::SendToRemovableDisk, diskMenuActionKeys); + } + + DDiskManager diskm; + for (auto &drvs : diskm.diskDevices()) { + QScopedPointer drv(DDiskManager::createDiskDevice(drvs)); + if (drv->mediaCompatibility().join(' ').contains("_r") && drv->optical()) { + actions.insert(MenuAction::StageFileForBurning, {}); + break; + } + } + + return actions; +} + +QSet DAbstractFileInfo::disableMenuActionList() const +{ + QSet list; + + if (!isWritable()) { + list << MenuAction::NewFolder + << MenuAction::NewDocument + << MenuAction::Paste; + } + + if (!canRename()) { + list << MenuAction::Cut << MenuAction::Rename << MenuAction::Delete << MenuAction::CompleteDeletion; + } + + if (isVirtualEntry() || (!isReadable() && !isSymLink())) { + list << MenuAction::Copy; + } + + return list; +} + +MenuAction DAbstractFileInfo::menuActionByColumnRole(int role) const +{ + switch (role) { + case DFileSystemModel::FileDisplayNameRole: + case DFileSystemModel::FileNameRole: + return MenuAction::Name; + case DFileSystemModel::FileSizeRole: + return MenuAction::Size; + case DFileSystemModel::FileMimeTypeRole: + return MenuAction::Type; + case DFileSystemModel::FileCreatedRole: + return MenuAction::CreatedDate; + case DFileSystemModel::FileLastModifiedRole: + return MenuAction::LastModifiedDate; + case DFileSystemModel::FileLastReadRole: + return MenuAction::LastRead; + default: + return MenuAction::Unknow; + } +} + +QList DAbstractFileInfo::sortSubMenuActionUserColumnRoles() const +{ + Q_D(const DAbstractFileInfo); + + if (!d->columnCompact) { + return userColumnRoles(); + } + + QList roles; + + int column = 0; + + for (int role : userColumnRoles()) { + const QList child_roles = userColumnChildRoles(column++); + + if (child_roles.isEmpty()) { + roles << role; + } else { + roles << child_roles; + } + } + + return roles; +} + +QT_BEGIN_NAMESPACE +QDebug operator<<(QDebug deg, const DAbstractFileInfo &info) +{ + deg << "file url:" << info.fileUrl() + << "mime type:" << info.mimeTypeName(); + + return deg; +} +QT_END_NAMESPACE + +void DAbstractFileInfo::setProxy(const DAbstractFileInfoPointer &proxy) +{ + Q_D(DAbstractFileInfo); + + d->proxy = proxy; +} + +void DAbstractFileInfo::setUrl(const DUrl &url) +{ + Q_D(DAbstractFileInfo); + + d->setUrl(url, false); +} + +bool DAbstractFileInfo::loadFileEmblems(QList &iconList) const +{ + //如果没有位置可以显示徽标,则不显示 + if (iconList.length() >= 4) { + return false; + } + + std::string str = filePath().toStdString(); + + //获取gfileinfo + GFile *g_file = g_file_new_for_path(str.c_str()); + GError *g_error = nullptr; + GFileInfo *g_fileInfo = g_file_query_info(g_file, "metadata::emblems", GFileQueryInfoFlags::G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, nullptr, &g_error); + + if (g_error != nullptr) { + //report error + g_object_unref(g_file); + g_error_free(g_error); + return false; + } + + //通过gfileinfo获取文件徽标的值 + char **emblemStr = g_file_info_get_attribute_stringv(g_fileInfo, "metadata::emblems"); + if (!emblemStr) { + g_object_unref(g_fileInfo); + g_object_unref(g_file); + return false; + } + + QString emStr(*emblemStr); + g_object_unref(g_fileInfo); + g_object_unref(g_file); + if (!emStr.isEmpty()) { + QList newIcons = {QIcon(), QIcon(), QIcon(), QIcon()}; + //设置了多条徽标的情况 + if (emStr.contains("|")) { + QStringList emblems = emStr.split("|"); + for (int i = 0; i < emblems.length(); i++) { + QString pos; + QIcon emblem; + if (parseEmblemString(emblem, pos, emblems.at(i))) { + setEmblemIntoIcons(pos, emblem, newIcons); + } + } + } + //只设置了一条徽标的情况 + else { + QString pos; + QIcon emblem; + if (parseEmblemString(emblem, pos, emStr)) { + setEmblemIntoIcons(pos, emblem, newIcons); + } + } + + for (int i = 0; i < iconList.length(); i++) { + newIcons[i] = iconList.at(i); + } + + iconList = newIcons; + + return true; + } + + return false; +} + +bool DAbstractFileInfo::parseEmblemString(QIcon &emblem, QString &pos, const QString &emblemStr) const +{ + //默认位置在右下 + pos = "rd"; + + if (!emblemStr.isEmpty()) { + QIcon emblemIcon; + QString imgPath; + //位置参数和徽标图标由 ; 隔开 + if (emblemStr.contains(";")) { + QStringList emStrList = emblemStr.split(";"); + imgPath = emStrList.at(0); + pos = emStrList.at(1); + } else { + imgPath = emblemStr; + } + + //修正主目录为标准路径 + if (imgPath.startsWith("~/")) { + imgPath.replace(0, 1, QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + } + +// QFile imgFile(imgPath); + QFileInfo fileInfo(imgPath); + if (fileInfo.exists()) { + if (fileInfo.size() > 102400) { //图片大小大于100不显示 + return false; + } + + //只支持部分格式的图片作为徽标图源 + if (fileInfo.completeSuffix() != "svg" && + fileInfo.completeSuffix() != "png" && + fileInfo.completeSuffix() != "gif" && + fileInfo.completeSuffix() != "bmp" && + fileInfo.completeSuffix() != "jpg") { + return false; + } + + emblemIcon = QIcon(imgPath); + if (!emblemIcon.isNull()) { + emblem = emblemIcon; + return true; + } + } + } + + return false; +} + +void DAbstractFileInfo::setEmblemIntoIcons(const QString &pos, const QIcon &emblem, QList &iconList) const +{ + int emblemIndex = 0; //徽标目标位置,默认位置右下rd=0 + + //左下 + if (pos == "ld") { + emblemIndex = 1; + } + //左上 + else if (pos == "lu") { + emblemIndex = 2; + } + //右上 + else if (pos == "ru") { + emblemIndex = 3; + } + + iconList[emblemIndex] = emblem; +} + +#ifdef SW_LABEL +QString DAbstractFileInfo::getLabelIcon() const +{ + if (FileManagerLibrary::instance()->isCompletion()) { + std::string path = fileUrl().toLocalFile().toStdString(); +// char* icon = auto_add_emblem(const_cast(path.c_str())); + char *icon = FileManagerLibrary::instance()->auto_add_emblem()(const_cast(path.c_str())); + if (QString::fromLocal8Bit(icon) == "No") { + return ""; + } else { + return QString::fromLocal8Bit(icon); + } + } + return ""; +} + +void DAbstractFileInfo::updateLabelMenuItems() +{ + if (FileManagerLibrary::instance()->isCompletion()) { + LabelMenuItemIds.clear(); + LabelMenuItemDatas.clear(); + // QString menu = "{\"id\":[\"010101\",\"010201\",\"010501\"],\"label\":[\"查看标签\",\"编辑标签\",\"转换为公有\"],\"tip\":[\"\",\"\",\"\"],\"icon\":[\"viewlabel.svg\",\"editlabel.svg\",\"editlabel.svg\"],\"sub0\":\"\",\"sub1\":\"\",\"sub2\":\"\"}"; + // QString menu = "{\"id\":[\"020100\"],\"label\":[\"设置标签\"],\"tip\":[\"\"],\"icon\":[\"setlabel.svg\"],\"sub0\":\"\"}"; + std::string path = fileUrl().toLocalFile().toStdString(); +// QString menu = auto_add_rightmenu(const_cast(path.c_str())); + QString menu = FileManagerLibrary::instance()->auto_add_rightmenu()(const_cast(path.c_str())); + qDebug() << menu; + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(menu.toLocal8Bit(), &error); + if (error.error == QJsonParseError::NoError) { + QJsonObject obj = doc.object(); + QJsonArray ids = obj.value("id").toArray(); + QJsonArray labels = obj.value("label").toArray(); + QJsonArray tips = obj.value("tip").toArray(); + QJsonArray icons = obj.value("icon").toArray(); + + for (int i = 0; i < ids.count(); i++) { + LabelMenuItemData item; + item.id = ids.at(i).toString(); + item.label = labels.at(i).toString(); + item.tip = tips.at(i).toString(); + item.icon = icons.at(i).toString(); + LabelMenuItemIds.append(item.id); + LabelMenuItemDatas.insert(item.id, item); + qDebug() << item.id << item.icon << item.label; + } + } else { + qDebug() << "load menu fail: " << error.errorString(); + } + } +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfileinfo.h new file mode 100644 index 0000000..b44f9ac --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfileinfo.h @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef ABSTRACTFILEINFO_H +#define ABSTRACTFILEINFO_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "durl.h" +#include "dfmglobal.h" + +#define SUFFIX_USRDIR "userdir" +#define SUFFIX_GVFSMP "gvfsmp" +#define SUFFIX_UDISKS "localdisk" +#define SUFFIX_STASHED_REMOTE "remote" +#define SUFFIX_APP_ENTRY "appentry" + +#define COMPARE_FUN_DEFINE(Value, Name, Type) \ + bool compareFileListBy##Name(const DAbstractFileInfoPointer &info1, const DAbstractFileInfoPointer &info2, Qt::SortOrder order)\ + {\ + bool isDir1 = info1->isDir();\ + bool isDir2 = info2->isDir();\ + \ + bool isFile1 = info1->isFile();\ + bool isFile2 = info2->isFile();\ + \ + if (!static_cast(info1.data())) \ + return false; \ + if (!static_cast(info2.data())) \ + return false; \ + auto value1 = static_cast(info1.data())->Value();\ + auto value2 = static_cast(info2.data())->Value();\ + \ + if (isDir1) {\ + if (!isDir2) return true;\ + } else {\ + if (isDir2) return false;\ + }\ + \ + if ((isDir1 && isDir2 && (value1 == value2)) || (isFile1 && isFile2 && (value1 == value2))) {\ + return compareByString(info1->fileDisplayName(), info2->fileDisplayName());\ + }\ + \ + bool isStrType = typeid(value1) == typeid(QString);\ + if (isStrType)\ + return compareByString(value1, value2, order);\ + \ + return ((order == Qt::DescendingOrder) ^ (value1 < value2)) == 0x01;\ + } + +namespace FileSortFunction { +bool compareByString(const QString &str1, const QString &str2, Qt::SortOrder order = Qt::AscendingOrder); +template +bool compareByString(T, T, Qt::SortOrder order = Qt::AscendingOrder) +{ + Q_UNUSED(order) + + return false; +} +} + +class DAbstractFileInfo; +class DAbstractFileWatcher; +typedef QExplicitlySharedDataPointer DAbstractFileInfoPointer; +typedef std::function getFileInfoFun; +typedef DFMGlobal::MenuAction MenuAction; +class DAbstractFileInfoPrivate; + + +#ifdef SW_LABEL + +struct LabelMenuItemData { + QString id; + QString label; + QString tip; + QString icon; +}; +static QStringList LabelMenuItemIds; +static QMap LabelMenuItemDatas; +#endif + +class DAbstractFileInfo : public QSharedData +{ +public: + enum MenuType { + SingleFile, + MultiFiles, + MultiFilesSystemPathIncluded, + SpaceArea + }; + + enum SelectionMode { + NoSelection, + SingleSelection, + MultiSelection, + ExtendedSelection, + ContiguousSelection + }; + + enum FileType { + // base type + Directory, + CharDevice, + BlockDevice, + FIFOFile, + SocketFile, + RegularFile, + // + Documents, + Images, + Videos, + Audios, + Archives, + DesktopApplication, + Executable, + Backups, + Unknown, + CustomType = 0x100 + }; + + inline static QString dateTimeFormat() + { + return "yyyy/MM/dd HH:mm:ss"; + } + + explicit DAbstractFileInfo(const DUrl &url, bool hasCache = true); + explicit DAbstractFileInfo(const DUrl &url, const QMimeType &mimetype, bool hasCache = true); + virtual ~DAbstractFileInfo(); + + static const DAbstractFileInfoPointer getFileInfo(const DUrl &fileUrl); + + virtual bool exists() const; + virtual bool isPrivate() const; + + virtual QString path() const; + virtual QString filePath() const; + virtual QString absolutePath() const; + virtual QString absoluteFilePath() const; + virtual QString baseName() const; + virtual QString baseNameOfRename() const; + virtual QString fileName() const; + virtual QString fileNameOfRename() const; + virtual QString fileDisplayName() const; + virtual QString fileSharedName() const; + QString fileDisplayPinyinName() const; + + virtual bool canRename() const; + virtual bool canShare() const; + virtual bool canFetch() const; + virtual bool isReadable() const; + virtual bool isWritable() const; + virtual bool isExecutable() const; + virtual bool isHidden() const; + virtual bool isRelative() const; + virtual bool isAbsolute() const; + virtual bool isShared() const; + virtual bool isTaged() const; + virtual bool canTag() const; + virtual bool isWritableShared() const; + virtual bool isAllowGuestShared() const; + virtual bool makeAbsolute(); + + + + /** + * @brief canManageAuth 是否可以管理权限 + * @return + */ + virtual bool canManageAuth() const; + /** + * @brief canMoveOrCopy 是否可以复制或剪切 + * @return + */ + virtual bool canMoveOrCopy() const; + + // only for base file type + virtual FileType fileType() const; + virtual bool isFile() const; + virtual bool isDir() const; + virtual bool isSymLink() const; + virtual bool isDesktopFile() const; + virtual bool isVirtualEntry() const; + + virtual QString symlinkTargetPath() const; + virtual DUrl symLinkTarget() const; + virtual DUrl rootSymLinkTarget() const; + + virtual QString owner() const; + virtual uint ownerId() const; + virtual QString group() const; + virtual uint groupId() const; + + virtual bool permission(QFile::Permissions permissions) const; + virtual QFile::Permissions permissions() const; + + virtual qint64 size() const; + virtual int filesCount() const; + // Return fileCounts() if file is folder; otherwise return size() + qint64 fileSize() const; + + virtual QDateTime created() const; + virtual QDateTime lastModified() const; + virtual QDateTime lastRead() const; + + virtual QMimeType mimeType(QMimeDatabase::MatchMode mode = QMimeDatabase::MatchDefault) const; + virtual QString mimeTypeName(QMimeDatabase::MatchMode mode = QMimeDatabase::MatchDefault) const + { return mimeType(mode).name();} + virtual QString iconName() const; + virtual QString genericIconName() const; + + virtual QString lastReadDisplayName() const; + virtual QString lastModifiedDisplayName() const; + virtual QString createdDisplayName() const; + virtual QString sizeDisplayName() const; + virtual QString mimeTypeDisplayName() const; + /// Used for sorting + virtual QString fileTypeDisplayName() const; + + virtual DUrl fileUrl() const; + inline QString scheme() const + {return fileUrl().scheme();} + + virtual QIcon fileIcon() const; + virtual QList additionalIcon() const; + + virtual DUrl parentUrl() const; + /// from parentUrl() to top level parent url + virtual DUrlList parentUrlList() const; + virtual bool isAncestorsUrl(const DUrl &url, QList *ancestors = nullptr) const; + virtual QVector menuActionList(MenuType type = SingleFile) const; + virtual QMap > subMenuActionList(MenuType type = SingleFile) const; + virtual QSet disableMenuActionList() const; + virtual MenuAction menuActionByColumnRole(int role) const; + virtual QList sortSubMenuActionUserColumnRoles() const; /*sortby submenu contains column roles*/ + + /// return DFileView::ViewMode flags + virtual quint8 supportViewMode() const; + /// support selection mode + virtual QList supportSelectionModes() const; + + virtual void setColumnCompact(bool compact); + bool columnIsCompact() const; + virtual QList userColumnRoles() const; + + virtual QVariant userColumnDisplayName(int userColumnRole) const; + /// get custom column data + virtual QVariant userColumnData(int userColumnRole) const; + virtual QList userColumnChildRoles(int column) const; + /// get custom column width + int userColumnWidth(int userColumnRole) const; + virtual int userColumnWidth(int userColumnRole, const QFontMetrics &fontMetrics) const; + /// get custom row height + int userRowHeight() const; + virtual int userRowHeight(const QFontMetrics &fontMetrics) const; + + /// user column default visible for role + virtual bool columnDefaultVisibleForRole(int role) const; + + typedef std::function CompareFunction; + virtual CompareFunction compareFunByColumn(int columnRole) const; + /// Whether the file should be inserted into a position according to the current sort type and order + virtual bool hasOrderly() const; + + virtual bool canRedirectionFileUrl() const; + virtual DUrl redirectedFileUrl() const; + + virtual bool isEmptyFloder(const QDir::Filters &filters = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::System) const; + + virtual Qt::ItemFlags fileItemDisableFlags() const; + + virtual bool canIteratorDir() const; + + virtual DUrl getUrlByNewFileName(const QString &fileName) const; + /// Return absoluteFilePath + "/" + fileName if is dir; otherwise return DUrl() + virtual DUrl getUrlByChildFileName(const QString &fileName) const; + + virtual DUrl mimeDataUrl() const; + virtual Qt::DropActions supportedDragActions() const; + virtual Qt::DropActions supportedDropActions() const; + + virtual QString loadingTip() const; + virtual QString subtitleForEmptyFloder() const; + + virtual QString suffix() const; + virtual QString suffixOfRename() const; + virtual QString completeSuffix() const; + + /// Make to inactive. stop get icon; stop watcher file + virtual void makeToInactive(); + virtual void makeToActive(); + bool isActive() const; + //优化gvfs文件卡,其他文件不改变,只有gvfs文件,传入true为强制刷新 + virtual void refresh(const bool isForce = false); + + virtual DUrl goToUrlWhenDeleted() const; + virtual QString toLocalFile() const; + + virtual bool canDrop() const; + + virtual QFileInfo toQFileInfo() const; + virtual QIODevice *createIODevice() const; + + virtual QVariantHash extraProperties() const; + + virtual bool checkMpsStr(const QString &) const; + + //为recentInfo提供接口 + virtual const QDateTime getReadTime() const; + virtual void updateReadTime(const QDateTime &); + virtual bool isGvfsMountFile() const; + virtual qint8 gvfsMountFile() const; + virtual void checkMountFile(); + + virtual quint64 inode() const; + + + /** + * @brief canDragCompress 是否支持拖拽压缩 + * @return + */ + virtual bool canDragCompress() const; + + virtual bool needCompleteDelete() const; + + /** + * @brief isDragCompressFile 判断是否是支持拖拽压缩的文件格式 + * @return + */ + virtual bool isDragCompressFileFormat() const; + +protected: + explicit DAbstractFileInfo(DAbstractFileInfoPrivate &dd); + void setProxy(const DAbstractFileInfoPointer &proxy); + Q_DECL_DEPRECATED_X("!!!!!!!!!!!!!!!!!!!!!!!") virtual void setUrl(const DUrl &url); + + /** + * @brief loadFileEmblems 加载文件的自定义徽标 + * @param iconList 角标列表 + * @return 是否成功加载 + */ + bool loadFileEmblems(QList &iconList) const; + /** + * @brief parseEmblemString 解析徽标设置的字符串 + * @param emblem 图标对象 + * @param pos 位置 + * @param emblemStr 徽标字符串 + * @return 是否解析成功 + */ + bool parseEmblemString(QIcon &emblem, QString &pos, const QString &emblemStr) const; + /** + * @brief setEmblemIntoIcons 设置徽标icon到要显示的iconlist + * @param pos 徽标位置 + * @param emblem 图标对象 + * @param iconList 显示的角标列表 + */ + void setEmblemIntoIcons(const QString &pos, const QIcon &emblem, QList &iconList) const; + + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(DAbstractFileInfo) + +private: + Q_DISABLE_COPY(DAbstractFileInfo) + +#ifdef SW_LABEL +public: + QString getLabelIcon() const; + void updateLabelMenuItems(); +#endif +}; + +QT_BEGIN_NAMESPACE +QDebug operator<<(QDebug deg, const DAbstractFileInfo &info); +QT_END_NAMESPACE +Q_DECLARE_METATYPE(DAbstractFileInfoPointer) + +#endif // ABSTRACTFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfilewatcher.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfilewatcher.cpp new file mode 100644 index 0000000..02402d9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfilewatcher.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dabstractfilewatcher.h" +#include "private/dabstractfilewatcher_p.h" + +#include +#include + +QList DAbstractFileWatcherPrivate::watcherList; +DAbstractFileWatcherPrivate::DAbstractFileWatcherPrivate(DAbstractFileWatcher *qq) + : q_ptr(qq) +{ + +} + +bool DAbstractFileWatcherPrivate::handleGhostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType1 signal, const DUrl &arg1) +{ + + if (url == targetUrl || url == arg1) { + (q_ptr->*signal)(arg1); + + return true; + } + + return false; +} + +bool DAbstractFileWatcherPrivate::handleGhostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType3 signal, const DUrl &arg1, int isExternalSource) +{ + + if (url == targetUrl || url == arg1) { + (q_ptr->*signal)(arg1, isExternalSource); + + return true; + } + + return false; +} + +bool DAbstractFileWatcherPrivate::handleGhostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType2 signal, const DUrl &arg1, const DUrl &arg2) +{ + + if (url == targetUrl || url == arg1 || url == arg2) { + (q_ptr->*signal)(arg1, arg2); + + return true; + } + + return false; +} + +DAbstractFileWatcher::~DAbstractFileWatcher() +{ + stopWatcher(); + DAbstractFileWatcherPrivate::watcherList.removeOne(this); +} + +DUrl DAbstractFileWatcher::fileUrl() const +{ + Q_D(const DAbstractFileWatcher); + + return d->url; +} + +bool DAbstractFileWatcher::startWatcher() +{ + Q_D(DAbstractFileWatcher); + + if (d->started) + return true; + + if (d->start()) { + d->started = true; + + return true; + } + + return false; +} + +bool DAbstractFileWatcher::stopWatcher() +{ + Q_D(DAbstractFileWatcher); + + if (!d->started) + return false; + + if (d->stop()) { + d->started = false; + + return true; + } + + return false; +} + +bool DAbstractFileWatcher::restartWatcher() +{ + bool ok = stopWatcher(); + return ok && startWatcher(); +} + +void DAbstractFileWatcher::setEnabledSubfileWatcher(const DUrl &subfileUrl, bool enabled) +{ + Q_UNUSED(subfileUrl) + Q_UNUSED(enabled) +} + +bool DAbstractFileWatcher::ghostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType1 signal, const DUrl &arg1) +{ + if (!signal) + return false; + + bool ok = false; + + for (DAbstractFileWatcher *watcher : DAbstractFileWatcherPrivate::watcherList) { + if (watcher->d_func()->handleGhostSignal(targetUrl, signal, arg1)) + ok = true; + } + + return ok; +} + +bool DAbstractFileWatcher::ghostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType3 signal, const DUrl &arg1, const int isExternalSource) +{ + if (!signal) + return false; + + bool ok = false; + + for (DAbstractFileWatcher *watcher : DAbstractFileWatcherPrivate::watcherList) { + if (watcher->d_func()->handleGhostSignal(targetUrl, signal, arg1, isExternalSource)) + ok = true; + } + + return ok; +} + +bool DAbstractFileWatcher::ghostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType2 signal, const DUrl &arg1, const DUrl &arg2) +{ + if (!signal) + return false; + + bool ok = false; + + for (DAbstractFileWatcher *watcher : DAbstractFileWatcherPrivate::watcherList) { + if (watcher->d_func()->handleGhostSignal(targetUrl, signal, arg1, arg2)) + ok = true; + } + + return ok; +} + +DAbstractFileWatcher::DAbstractFileWatcher(DAbstractFileWatcherPrivate &dd, + const DUrl &url, QObject *parent) + : QObject(parent) + , d_ptr(&dd) +{ + Q_ASSERT(url.isValid()); + +// qDebug() << "add file watcher for: " << url; + + d_ptr->url = url; + DAbstractFileWatcherPrivate::watcherList << this; +} + +#include "moc_dabstractfilewatcher.cpp" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfilewatcher.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfilewatcher.h new file mode 100644 index 0000000..deae294 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dabstractfilewatcher.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DABSTRACTFILEWATCHER_H +#define DABSTRACTFILEWATCHER_H + +#include + +class DUrl; +class DAbstractFileWatcherPrivate; +class DAbstractFileWatcher : public QObject +{ + Q_OBJECT + +public: + virtual ~DAbstractFileWatcher(); + + DUrl fileUrl() const; + + bool startWatcher(); + bool stopWatcher(); + bool restartWatcher(); + + virtual void setEnabledSubfileWatcher(const DUrl &subfileUrl, bool enabled = true); + + using SignalType1 = void(DAbstractFileWatcher::*)(const DUrl &); + using SignalType2 = void(DAbstractFileWatcher::*)(const DUrl &, const DUrl &); + using SignalType3 = void(DAbstractFileWatcher::*)(const DUrl &, const int &); + static bool ghostSignal(const DUrl &targetUrl, SignalType1 signal, const DUrl &arg1); + static bool ghostSignal(const DUrl &targetUrl, SignalType2 signal, const DUrl &arg1, const DUrl &arg2); + static bool ghostSignal(const DUrl &targetUrl, SignalType3 signal, const DUrl &arg1, const int isExternalSource = 1); + +signals: + void fileDeleted(const DUrl &url); + void fileAttributeChanged(const DUrl &url, const int &isExternalSource = 1); + void fileMoved(const DUrl &fromUrl, const DUrl &toUrl); + void subfileCreated(const DUrl &url); + void fileModified(const DUrl &url); + void fileClosed(const DUrl &url); + +protected: + explicit DAbstractFileWatcher(DAbstractFileWatcherPrivate &dd, const DUrl &url, QObject *parent = nullptr); + + QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(DAbstractFileWatcher) + Q_DECLARE_PRIVATE(DAbstractFileWatcher) +}; + +#endif // DABSTRACTFILEWATCHER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/ddiriterator.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/ddiriterator.h new file mode 100644 index 0000000..6ffaf8a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/ddiriterator.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DDIRITERATOR_H +#define DDIRITERATOR_H + +#include "dabstractfileinfo.h" + +class DDirIterator +{ +public: + enum { + // 把目录中的文件按文件系统的inode排序, 用于目录复制/移动 + // 在机械硬盘上, 读取排序后的文件内容会减少很多磁盘寻道和磁头定位的时间 + SortINode = 0x800 + }; + + virtual ~DDirIterator() {} + + virtual DUrl next() = 0; + virtual bool hasNext() const = 0; + virtual void close() {} + + virtual QString fileName() const = 0; + // Returns the full file url for the current directory entry. + virtual DUrl fileUrl() const = 0; + virtual const DAbstractFileInfoPointer fileInfo() const = 0; + // Returns the base url of the iterator. + virtual DUrl url() const = 0; + + virtual bool enableIteratorByKeyword(const QString &keyword) {Q_UNUSED(keyword); return false;} +public: +}; + +typedef QSharedPointer DDirIteratorPointer; + +Q_DECLARE_METATYPE(DDirIteratorPointer) +#endif // DDIRITERATOR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/defenderinterface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/defenderinterface.cpp new file mode 100644 index 0000000..08adbe7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/defenderinterface.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2019 ~ 2019 Deepin Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: dengkeyun + * + * 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 + * 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 . + */ + +#include "defenderinterface.h" + +#include +#include +#include +#include +#include + +#define DBUS_SERVICE_NAME "com.deepin.defender.daemonservice" +#define DBUS_SERVICE_PATH "/com/deepin/defender/daemonservice" +#define DBUS_INTERFACE_NAME "com.deepin.defender.daemonservice" + +DefenderInterface::DefenderInterface(QObject *parent) + : QObject(parent) + , m_started(false) +{ + +} + +void DefenderInterface::start() +{ + if (m_started) + return; + + m_started = true; + + qInfo() << "create dbus interface:" << DBUS_SERVICE_NAME; + interface.reset(new QDBusInterface(DBUS_SERVICE_NAME, + DBUS_SERVICE_PATH, + DBUS_INTERFACE_NAME, + QDBusConnection::sessionBus())); + + qInfo() << "create dbus interface done"; + + QDBusConnection::sessionBus().connect( + DBUS_SERVICE_NAME, + DBUS_SERVICE_PATH, + DBUS_INTERFACE_NAME, + "ScanningUsbPathsChanged", + this, + SLOT(scanningUsbPathsChanged(QStringList))); + + qInfo() << "start get usb scanning path"; + QStringList list = interface->property("ScanningUsbPaths").toStringList(); + foreach (const QString &p, list) + scanningPaths << QUrl::fromLocalFile(p); + + qInfo() << "get usb scanning path done:" << scanningPaths; +} + +void DefenderInterface::scanningUsbPathsChanged(QStringList list) +{ + qInfo() << "reveive signal: scanningUsbPathsChanged, " << list; + scanningPaths.clear(); + foreach (const QString &p, list) + scanningPaths << QUrl::fromLocalFile(p); +} + +/* + * 从当前扫描路径选取url的子目录,若url本身也被扫描,也会在返回列表中 + */ +QList DefenderInterface::getScanningPaths(const QUrl &url) +{ + QList list; + foreach (const QUrl &p, scanningPaths) { + if (url.isParentOf(p) || url == p) + list << p; + } + return list; +} + + +/* + * 停止扫描url及url的子目录,返回false为停止失败 + */ +bool DefenderInterface::stopScanning(const QUrl &url) +{ + QList urls; + urls << url; + return stopScanning(urls); +} + +#define MAX_DBUS_TIMEOUT 1000 // 需要考虑同时停止多个目录扫描, 适当延长超时时间 +bool DefenderInterface::stopScanning(const QList &urls) +{ + qInfo() << "stopScanning:" << urls; + qInfo() << "current scanning:" << scanningPaths; + + // 确保DBus监听 + start(); + + QList paths; + foreach(const QUrl &url, urls) + paths << getScanningPaths(url); + + if (paths.empty()) + return true; + + foreach (const QUrl &path, paths) { + qInfo() << "send RequestStopUsbScannig:" << path; + interface->asyncCall("RequestStopUsbScannig", path.toLocalFile()); + } + + // 等待扫描目录改变信号,直到超时 + QTime t; + t.start(); + while (t.elapsed() < MAX_DBUS_TIMEOUT) { + qApp->processEvents(); + if (!isScanning(urls)) + return true; + QThread::msleep(10); + } + return false; +} + +/* + * 检查当前扫描路径中是否包含url或url的子目录 + */ +bool DefenderInterface::isScanning(const QUrl &url) +{ + // 确保DBus监听 + start(); + + QList paths = getScanningPaths(url); + return !paths.empty(); +} + +bool DefenderInterface::isScanning(const QList &urls) +{ + foreach(const QUrl &url, urls) { + if (isScanning(url)) + return true; + } + return false; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/defenderinterface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/defenderinterface.h new file mode 100644 index 0000000..75a10c1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/defenderinterface.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2019 ~ 2019 Deepin Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: dengkeyun + * + * 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 + * 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 . + */ + +#ifndef DEFENDER_INTERFACE_H +#define DEFENDER_INTERFACE_H + +#include +#include +#include +#include + +class DefenderInterface : public QObject +{ + Q_OBJECT + +public: + DefenderInterface(QObject *parent = nullptr); + ~DefenderInterface() {} + + /* + * 检查当前扫描路径中是否存在url或url的子目录 + */ + bool isScanning(const QUrl &url); + bool isScanning(const QList &urls); + /* + * 停止扫描url及url的子目录,返回false为停止失败 + */ + bool stopScanning(const QUrl &url); + bool stopScanning(const QList &urls); + +public Q_SLOTS: + void scanningUsbPathsChanged(QStringList list); + +private: + // 从当前扫描路径选取url的子目录,若url本身也被扫描,也会在返回列表中 + QList getScanningPaths(const QUrl &url = QUrl("/")); + void start(); + +private: + QScopedPointer interface; + QList scanningPaths; + bool m_started; +}; + +#endif // DEFENDER_INTERFACE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfiledialoghandle.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfiledialoghandle.cpp new file mode 100644 index 0000000..2762d90 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfiledialoghandle.cpp @@ -0,0 +1,425 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfiledialoghandle.h" +#include "views/dfiledialog.h" + +#include +#include + +DWIDGET_USE_NAMESPACE + +class DFileDialogHandlePrivate +{ +public: + explicit DFileDialogHandlePrivate(DFileDialogHandle *qq) + : q_ptr(qq) {} + + ~DFileDialogHandlePrivate() + { + if (dialog) + dialog->deleteLater(); + } + + QPointer dialog; + + DFileDialogHandle *q_ptr; + + Q_DECLARE_PUBLIC(DFileDialogHandle) +}; + +DFileDialogHandle::DFileDialogHandle(QWidget *parent) + : QObject(parent) + , d_ptr(new DFileDialogHandlePrivate(this)) +{ + d_func()->dialog = new DFileDialog(parent); + + connect(d_func()->dialog, &DFileDialog::accepted, this, &DFileDialogHandle::accepted); + connect(d_func()->dialog, &DFileDialog::rejected, this, &DFileDialogHandle::rejected); + connect(d_func()->dialog, &DFileDialog::finished, this, &DFileDialogHandle::finished); + connect(d_func()->dialog, &DFileDialog::selectionFilesChanged, + this, &DFileDialogHandle::selectionFilesChanged); + connect(d_func()->dialog, &DFileDialog::currentUrlChanged, + this, &DFileDialogHandle::currentUrlChanged); + connect(d_func()->dialog, &DFileDialog::selectedNameFilterChanged, + this, &DFileDialogHandle::selectedNameFilterChanged); +} + +DFileDialogHandle::~DFileDialogHandle() +{ + +} + +void DFileDialogHandle::setParent(QWidget *parent) +{ + D_D(DFileDialogHandle); + + d->dialog->setParent(parent); + + QObject::setParent(parent); +} + +QWidget *DFileDialogHandle::widget() const +{ + D_DC(DFileDialogHandle); + + return d->dialog; +} + +void DFileDialogHandle::setDirectory(const QString &directory) +{ + D_D(DFileDialogHandle); + + d->dialog->setDirectory(directory); +} + +void DFileDialogHandle::setDirectory(const QDir &directory) +{ + D_D(DFileDialogHandle); + + d->dialog->setDirectory(directory); +} + +QDir DFileDialogHandle::directory() const +{ + D_DC(DFileDialogHandle); + + return d->dialog->directory(); +} + +void DFileDialogHandle::setDirectoryUrl(const QUrl &directory) +{ + D_D(DFileDialogHandle); + + d->dialog->setDirectoryUrl(DUrl(directory)); +} + +QUrl DFileDialogHandle::directoryUrl() const +{ + D_DC(DFileDialogHandle); + + return d->dialog->directoryUrl(); +} + +void DFileDialogHandle::selectFile(const QString &filename) +{ + D_D(DFileDialogHandle); + + d->dialog->selectFile(filename); +} + +QStringList DFileDialogHandle::selectedFiles() const +{ + D_DC(DFileDialogHandle); + + return d->dialog->selectedFiles(); +} + +void DFileDialogHandle::selectUrl(const QUrl &url) +{ + D_D(DFileDialogHandle); + + d->dialog->selectUrl(url); +} + +QList DFileDialogHandle::selectedUrls() const +{ + D_DC(DFileDialogHandle); + + return d->dialog->selectedUrls(); +} + +void DFileDialogHandle::addDisableUrlScheme(const QString &scheme) +{ + D_D(DFileDialogHandle); + + d->dialog->addDisableUrlScheme(scheme); +} + +void DFileDialogHandle::setNameFilters(const QStringList &filters) +{ + D_D(DFileDialogHandle); + + d->dialog->setNameFilters(filters); +} + +QStringList DFileDialogHandle::nameFilters() const +{ + D_DC(DFileDialogHandle); + + return d->dialog->nameFilters(); +} + +void DFileDialogHandle::selectNameFilter(const QString &filter) +{ + D_D(DFileDialogHandle); + + d->dialog->selectNameFilter(filter); +} + +QString DFileDialogHandle::selectedNameFilter() const +{ + D_DC(DFileDialogHandle); + + return d->dialog->selectedNameFilter(); +} + +void DFileDialogHandle::selectNameFilterByIndex(int index) +{ + D_DC(DFileDialogHandle); + + d->dialog->selectNameFilterByIndex(index); +} + +int DFileDialogHandle::selectedNameFilterIndex() const +{ + D_DC(DFileDialogHandle); + + return d->dialog->selectedNameFilterIndex(); +} + +QDir::Filters DFileDialogHandle::filter() const +{ + D_DC(DFileDialogHandle); + + return d->dialog->filter(); +} + +void DFileDialogHandle::setFilter(QDir::Filters filters) +{ + D_D(DFileDialogHandle); + + d->dialog->setFilter(filters); +} + +void DFileDialogHandle::setViewMode(QFileDialog::ViewMode mode) +{ + D_D(DFileDialogHandle); + + if (mode == QFileDialog::Detail) + d->dialog->setViewMode(DFileView::ListMode); + else + d->dialog->setViewMode(DFileView::IconMode); +} + +QFileDialog::ViewMode DFileDialogHandle::viewMode() const +{ + D_DC(DFileDialogHandle); + + if (d->dialog->viewMode() == DFileView::ListMode) + return QFileDialog::Detail; + + return QFileDialog::List; +} + +void DFileDialogHandle::setFileMode(QFileDialog::FileMode mode) +{ + D_D(DFileDialogHandle); + + d->dialog->setFileMode(mode); +} + +void DFileDialogHandle::setAcceptMode(QFileDialog::AcceptMode mode) +{ + D_D(DFileDialogHandle); + + d->dialog->setAcceptMode(mode); +} + +QFileDialog::AcceptMode DFileDialogHandle::acceptMode() const +{ + D_DC(DFileDialogHandle); + + return d->dialog->acceptMode(); +} + +void DFileDialogHandle::setLabelText(QFileDialog::DialogLabel label, const QString &text) +{ + D_D(DFileDialogHandle); + + d->dialog->setLabelText(label, text); +} + +QString DFileDialogHandle::labelText(QFileDialog::DialogLabel label) const +{ + D_DC(DFileDialogHandle); + + return d->dialog->labelText(label); +} + +void DFileDialogHandle::setOptions(QFileDialog::Options options) +{ + D_DC(DFileDialogHandle); + + return d->dialog->setOptions(options); +} + +void DFileDialogHandle::setOption(QFileDialog::Option option, bool on) +{ + D_DC(DFileDialogHandle); + + d->dialog->setOption(option, on); +} + +QFileDialog::Options DFileDialogHandle::options() const +{ + D_DC(DFileDialogHandle); + + return d->dialog->options(); +} + +bool DFileDialogHandle::testOption(QFileDialog::Option option) const +{ + D_DC(DFileDialogHandle); + + return d->dialog->testOption(option); +} + +void DFileDialogHandle::setCurrentInputName(const QString &name) +{ + D_DC(DFileDialogHandle); + + d->dialog->setCurrentInputName(name); +} + +void DFileDialogHandle::addCustomWidget(int type, const QString &data) +{ + D_D(DFileDialogHandle); + + d->dialog->addCustomWidget(static_cast(type), data); +} + +QDBusVariant DFileDialogHandle::getCustomWidgetValue(int type, const QString &text) const +{ + D_DC(DFileDialogHandle); + + return QDBusVariant(d->dialog->getCustomWidgetValue(static_cast(type), text)); +} + +QVariantMap DFileDialogHandle::allCustomWidgetsValue(int type) const +{ + D_DC(DFileDialogHandle); + + return d->dialog->allCustomWidgetsValue(static_cast(type)); +} + +void DFileDialogHandle::beginAddCustomWidget() +{ + D_D(DFileDialogHandle); + + d->dialog->beginAddCustomWidget(); +} + +void DFileDialogHandle::endAddCustomWidget() +{ + D_D(DFileDialogHandle); + + d->dialog->endAddCustomWidget(); +} + +void DFileDialogHandle::setAllowMixedSelection(bool on) +{ + D_D(DFileDialogHandle); + + d->dialog->setAllowMixedSelection(on); +} + +void DFileDialogHandle::setHideOnAccept(bool enable) +{ + D_D(DFileDialogHandle); + + d->dialog->setHideOnAccept(enable); +} + +bool DFileDialogHandle::hideOnAccept() const +{ + D_DC(DFileDialogHandle); + + return d->dialog->hideOnAccept(); +} + +void DFileDialogHandle::show() +{ + D_D(DFileDialogHandle); + + d->dialog->show(); + //解决打开文件对话框无焦点问题 + QWindow *window = d->dialog->windowHandle(); + bool isFirst = true; //仅首次激活 + connect(window, &QWindow::activeChanged, this, [ = ]() + mutable{ //matable使isFisrt可修改 + if (!isFirst) + return; + isFirst = false; //仅首次激活 + //激活窗口 + d->dialog->activateWindow(); + //50毫秒后再次检测 + QTimer::singleShot(50, this, [ = ]() + { + if (!d->dialog->isActiveWindow()) + d->dialog->activateWindow(); + }); + }); +} + +void DFileDialogHandle::hide() +{ + D_D(DFileDialogHandle); + + d->dialog->hide(); +} + +void DFileDialogHandle::accept() +{ + D_D(DFileDialogHandle); + + d->dialog->accept(); +} + +void DFileDialogHandle::done(int r) +{ + D_D(DFileDialogHandle); + + d->dialog->done(r); +} + +int DFileDialogHandle::exec() +{ + D_D(DFileDialogHandle); + + return d->dialog->exec(); +} + +void DFileDialogHandle::open() +{ + D_D(DFileDialogHandle); + + d->dialog->open(); +} + +void DFileDialogHandle::reject() +{ + D_D(DFileDialogHandle); + + d->dialog->reject(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfiledialoghandle.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfiledialoghandle.h new file mode 100644 index 0000000..63505ec --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfiledialoghandle.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILEDIALOGHANDLE_H +#define DFILEDIALOGHANDLE_H + +#include +#include +#include + +class DFileDialogHandlePrivate; +class DFileDialogHandle : public QObject +{ + Q_OBJECT + +public: + explicit DFileDialogHandle(QWidget *parent = 0); + ~DFileDialogHandle(); + + void setParent(QWidget *parent); + QWidget *widget() const; + + void setDirectory(const QString & directory); + void setDirectory(const QDir & directory); + QDir directory() const; + + void setDirectoryUrl(const QUrl & directory); + QUrl directoryUrl() const; + + void selectFile(const QString &filename); + QStringList selectedFiles() const; + + void selectUrl(const QUrl &url); + QList selectedUrls() const; + + void addDisableUrlScheme(const QString &scheme); + + void setNameFilters(const QStringList &filters); + QStringList nameFilters() const; + void selectNameFilter(const QString &filter); + QString selectedNameFilter() const; + void selectNameFilterByIndex(int index); + int selectedNameFilterIndex() const; + + QDir::Filters filter() const; + void setFilter(QDir::Filters filters); + + void setViewMode(QFileDialog::ViewMode mode); + QFileDialog::ViewMode viewMode() const; + + void setFileMode(QFileDialog::FileMode mode); + + void setAcceptMode(QFileDialog::AcceptMode mode); + QFileDialog::AcceptMode acceptMode() const; + + void setLabelText(QFileDialog::DialogLabel label, const QString &text); + QString labelText(QFileDialog::DialogLabel label) const; + + void setOptions(QFileDialog::Options options); + void setOption(QFileDialog::Option option, bool on = true); + QFileDialog::Options options() const; + bool testOption(QFileDialog::Option option) const; + + void setCurrentInputName(const QString &name); + void addCustomWidget(int type, const QString &data); + QDBusVariant getCustomWidgetValue(int type, const QString &text) const; + QVariantMap allCustomWidgetsValue(int type) const; + void beginAddCustomWidget(); + void endAddCustomWidget(); + + void setAllowMixedSelection(bool on); + + void setHideOnAccept(bool enable); + bool hideOnAccept() const; + +Q_SIGNALS: + void finished(int result); + void accepted(); + void rejected(); + void selectionFilesChanged(); + void currentUrlChanged(); + void selectedNameFilterChanged(); + +public Q_SLOTS: + void show(); + void hide(); + void accept(); + void done(int r); + int exec(); + void open(); + void reject(); + +private: + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), DFileDialogHandle) + Q_DISABLE_COPY(DFileDialogHandle) +}; + +#endif // DFILEDIALOGHANDLE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileiconprovider.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileiconprovider.cpp new file mode 100644 index 0000000..53f9faf --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileiconprovider.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include +#include + +#include "dfileiconprovider.h" +#include "dfileinfo.h" +#include "dgvfsfileinfo.h" + +#include +#include + +DFM_BEGIN_NAMESPACE + +class DFileIconProviderPrivate +{ +public: + DFileIconProviderPrivate(); + + void init(); + QIcon getFilesystemIcon(const QFileInfo &info) const; + QIcon fromTheme(QString iconName) const; +}; + +DFileIconProviderPrivate::DFileIconProviderPrivate() +{ + init(); +} + +void DFileIconProviderPrivate::init() +{ + +} + +// fallback to gio +QIcon DFileIconProviderPrivate::getFilesystemIcon(const QFileInfo &info) const +{ + QIcon icon; + //fix 修复当链接文件指向的文件被删时,界面卡顿。如果文件不存在,直接返回空图标 + if (!info.exists()) + return icon; + //end + + QScopedPointer file(DGioFile::createFromPath(info.absoluteFilePath())); + //todo 当链接文件指向的文件被删除时,file->createFileInfo函数耗时很长 + QExplicitlySharedDataPointer fileinfo = file->createFileInfo("*", FILE_QUERY_INFO_NONE, 616); + //end + if (!fileinfo) { + return icon; + } + + QStringList icons = fileinfo->themedIconNames(); + if (!icons.isEmpty()) return QIcon::fromTheme(icons.first()); + + QString iconStr(fileinfo->iconString()); + if (iconStr.startsWith('/')) { + icon = QIcon(iconStr); + } else { + // blumia: I guess it will failed since the g_icon_to_string() returned str can be something like + // ". GThemedIcon text-plain text-x-generic text-plain-symbolic" which is definitely not + // a valid icon name from theme. + // Anyway here I keep the code as-is. + // TODO: a more Qt way than using gio? + icon = QIcon::fromTheme(iconStr); + } + + return icon; +} + +QIcon DFileIconProviderPrivate::fromTheme(QString iconName) const +{ + QIcon icon = QIcon::fromTheme(iconName); + + if (Q_LIKELY(!icon.isNull())) + return icon; + + if (iconName == "application-vnd.debian.binary-package") { + iconName = "application-x-deb"; + } else if (iconName == "application-vnd.rar") { + iconName = "application-zip"; + } else if (iconName == "application-vnd.ms-htmlhelp") { + iconName = "chmsee"; + } else if (iconName == "Zoom.png"){ + iconName = "application-x-zoom"; + } else { + return icon; + } + + icon = QIcon::fromTheme(iconName); + + return icon; +} + +Q_GLOBAL_STATIC(DFileIconProvider, globalFIP) + +DFileIconProvider::DFileIconProvider() + : d_ptr(new DFileIconProviderPrivate()) +{ + +} + +DFileIconProvider::~DFileIconProvider() +{ + +} + +DFileIconProvider *DFileIconProvider::globalProvider() +{ + return globalFIP; +} + +QIcon DFileIconProvider::icon(const QFileInfo &info) const +{ + Q_D(const DFileIconProvider); + + return d->getFilesystemIcon(info); +} + +QIcon DFileIconProvider::icon(const QFileInfo &info, const QIcon &feedback) const +{ + const QIcon &icon = this->icon(info); + + if (icon.isNull()) + return feedback; + + return icon; +} + +QIcon DFileIconProvider::icon(const DFileInfo &info, const QIcon &feedback) const +{ + Q_D(const DFileIconProvider); + + QIcon icon = d->fromTheme(info.iconName()); + + if (Q_LIKELY(!icon.isNull())) + return icon; + + icon = this->icon(info.toQFileInfo()); + + if (Q_LIKELY(!icon.isNull())) + return icon; + + icon = d->fromTheme(info.genericIconName()); + + if (icon.isNull()) + icon = d->fromTheme("unknown"); + + if (icon.isNull()) + return feedback; + + return icon; +} + +QIcon DFileIconProvider::icon(const DGvfsFileInfo &info, const QIcon &feedback) const +{ + Q_D(const DFileIconProvider); + + QIcon icon = d->fromTheme(info.iconName()); + + if (Q_LIKELY(!icon.isNull())) + return icon; + + icon = this->icon(info.toQFileInfo()); + + if (Q_LIKELY(!icon.isNull())) + return icon; + + icon = d->fromTheme(info.genericIconName()); + + if (icon.isNull()) + icon = d->fromTheme("unknown"); + + if (icon.isNull()) + return feedback; + + return icon; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileiconprovider.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileiconprovider.h new file mode 100644 index 0000000..4f5d1ef --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileiconprovider.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILEICONPROVIDER_H +#define DFILEICONPROVIDER_H + +#include + +#include "dfmglobal.h" + +class DFileInfo; +class DGvfsFileInfo; + +DFM_BEGIN_NAMESPACE + +class DFileIconProviderPrivate; +class DFileIconProvider : public QFileIconProvider +{ +public: + DFileIconProvider(); + ~DFileIconProvider() override; + + static DFileIconProvider *globalProvider(); + + QIcon icon(const QFileInfo &info) const override; + QIcon icon(const QFileInfo &info, const QIcon &feedback) const ; + QIcon icon(const DFileInfo &info, const QIcon &feedback = QIcon()) const; + QIcon icon(const DGvfsFileInfo &info, const QIcon &feedback = QIcon()) const; + +private: + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(DFileIconProvider) + Q_DISABLE_COPY(DFileIconProvider) +}; + +DFM_END_NAMESPACE + +#endif // DFILEICONPROVIDER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileinfo.cpp new file mode 100644 index 0000000..cc229d2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileinfo.cpp @@ -0,0 +1,1152 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfileinfo.h" +#include "private/dfileinfo_p.h" +#include "app/define.h" + +#include "shutil/fileutils.h" + +#include "controllers/pathmanager.h" +#include "controllers/filecontroller.h" +#include "controllers/vaultcontroller.h" + +#include "app/define.h" +#include "singleton.h" +#include "usershare/usersharemanager.h" +#include "deviceinfo/udisklistener.h" +#include "tag/tagmanager.h" + +#include "dfileservices.h" +#include "dthumbnailprovider.h" +#include "dfileiconprovider.h" +#include "dmimedatabase.h" +#include "dabstractfilewatcher.h" +#include "dstorageinfo.h" +#include "shutil/danythingmonitorfilter.h" +#include "dfmapplication.h" +#include "dfmstandardpaths.h" + +#ifdef SW_LABEL +#include "sw_label/filemanagerlibrary.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +DFM_USE_NAMESPACE + +#define REQUEST_THUMBNAIL_DEALY 500 + +class RequestEP : public QThread +{ + Q_OBJECT + +public: + static RequestEP *instance(); + + ~RequestEP() override; + + // Request get the file extra properties + QQueue> requestEPFiles; + QReadWriteLock requestEPFilesLock; + QSet dirtyFileInfos; + QMutex dirtyFileInfosMutex; + QMutex requestEPCancelLock; + bool isCanceled = false; + + void run() override; + void requestEP(const DUrl &url, DFileInfoPrivate *info); + void cancelRequestEP(DFileInfoPrivate *info); + +Q_SIGNALS: + void requestEPFinished(const DUrl &url, const QVariantHash &ep); + +private Q_SLOTS: + void processEPChanged(const DUrl &url, DFileInfoPrivate *info, const QVariantHash &ep); + +private: + explicit RequestEP(QObject *parent = nullptr); +}; + +RequestEP::RequestEP(QObject *parent) + : QThread(parent) +{ + QMetaType::registerEqualsComparator>(); + qRegisterMetaType(); + + connect(this, &RequestEP::finished, this, [this] { + QMutexLocker lk(&dirtyFileInfosMutex); + dirtyFileInfos.clear(); + }); +} + +RequestEP *RequestEP::instance() +{ + // RequestEP对象必须和线程相关,不然线程销毁后,QObject::thread()为nullptr + // 导致使用QCoreApplication::postEvent给此对象发送事件无效 + // 间接导致 run 中调用 QMetaObject::invokeMethod(this, "processEPChanged", Qt::QueuedConnection, Q_ARG(DUrl, url), Q_ARG(DFileInfoPrivate*, file_info.second), Q_ARG(QVariantHash, ep)); + // 时无效,因为Qt::QueueConnection参数会将此调用交给事件循环处理 + thread_local static RequestEP eq; + + return &eq; +} + +RequestEP::~RequestEP() +{ + requestEPFilesLock.lockForWrite(); + requestEPFiles.clear(); + requestEPFilesLock.unlock(); + + if (!wait(1000)) { + terminate(); + } +} + +void RequestEP::run() +{ + forever { + requestEPFilesLock.lockForRead(); + if (requestEPFiles.isEmpty()) { + requestEPFilesLock.unlock(); + return; + } + requestEPFilesLock.unlock(); + requestEPFilesLock.lockForWrite(); + auto file_info = requestEPFiles.dequeue(); + requestEPFilesLock.unlock(); + + const DUrl &url = file_info.first; + const QStringList &tag_list = DFileService::instance()->getTagsThroughFiles(nullptr, {url}); + + QVariantHash ep; + + if (!tag_list.isEmpty()) { + ep["tag_name_list"] = tag_list; + } + + QList colors; + + for (const QColor &color : TagManager::instance()->getTagColor(tag_list)) { + colors << color; + } + + if (!colors.isEmpty()) { + ep["colored"] = QVariant::fromValue(colors); + } + + QMetaObject::invokeMethod(this, "processEPChanged", Qt::QueuedConnection, + Q_ARG(DUrl, url), Q_ARG(DFileInfoPrivate *, file_info.second), Q_ARG(QVariantHash, ep)); + } +} + +void RequestEP::requestEP(const DUrl &url, DFileInfoPrivate *info) +{ + requestEPFilesLock.lockForRead(); + + for (int i = 0; i < requestEPFiles.count(); ++i) { + auto file_info = requestEPFiles.at(i); + + if (file_info.second == info) { + requestEPFilesLock.unlock(); + return; + } + } + + requestEPFilesLock.unlock(); + requestEPFilesLock.lockForWrite(); + requestEPFiles << qMakePair(url, info); + requestEPFilesLock.unlock(); + + if (!isRunning()) { + start(); + } +} + +void RequestEP::cancelRequestEP(DFileInfoPrivate *info) +{ + requestEPCancelLock.lock(); + isCanceled = true; + requestEPCancelLock.unlock(); + + dirtyFileInfosMutex.lock(); + dirtyFileInfos << info; + dirtyFileInfosMutex.unlock(); + + requestEPFilesLock.lockForRead(); + + for (int i = 0; i < requestEPFiles.count(); ++i) { + auto file_info = requestEPFiles.at(i); + + if (file_info.second == info) { + requestEPFilesLock.unlock(); + requestEPFilesLock.lockForWrite(); + requestEPFiles.removeAt(i); + requestEPFilesLock.unlock(); + info->requestEP = nullptr; + + dirtyFileInfosMutex.lock(); + dirtyFileInfos.remove(info); + dirtyFileInfosMutex.unlock(); + return; + } + } + + requestEPFilesLock.unlock(); +} + +void RequestEP::processEPChanged(const DUrl &url, DFileInfoPrivate *info, const QVariantHash &ep) +{ + Q_EMIT requestEPFinished(url, ep); + + if (info == nullptr) { + return; + } + + //fix bug 44093 和 task 36486 文件的多次创建和删除崩溃 + if (isCanceled) { + return; + } + + requestEPCancelLock.lock(); + if (isCanceled) { + requestEPCancelLock.unlock(); + return; + } + QVariantHash oldEP; + + dirtyFileInfosMutex.lock(); + if (!dirtyFileInfos.contains(info)) { + oldEP = info->extraProperties; + info->extraProperties = ep; + info->epInitialized = true; + info->requestEP = nullptr; + } else { + dirtyFileInfos.remove(info); + info = nullptr; + } + dirtyFileInfosMutex.unlock(); + + if (!ep.isEmpty() || oldEP != ep) { + DAbstractFileWatcher::ghostSignal(url.parentUrl(), &DAbstractFileWatcher::fileAttributeChanged, url, 0); // source is internal signal + + if (info) { + // ###(zccrs): DFileSystemModel中收到通知后会调用DAbstractFileInfo::refresh,导致会重新获取扩展属性 + info->epInitialized = true; + } + } + requestEPCancelLock.unlock(); +} + +DFileInfoPrivate::DFileInfoPrivate(const DUrl &fileUrl, DFileInfo *qq, bool hasCache) + : DAbstractFileInfoPrivate(fileUrl, qq, hasCache) +{ + fileInfo.setFile(fileUrl.toLocalFile()); + gvfsMountFile = 0; +} + +DFileInfoPrivate::~DFileInfoPrivate() +{ + if (getIconTimer) { + getIconTimer->disconnect(SIGNAL(timeout())); // 导致指针析构问题,UT注意 + getIconTimer->stop(); + getIconTimer->deleteLater(); + } + + if (getEPTimer) { + getEPTimer->disconnect(SIGNAL(timeout())); // 导致指针析构问题,UT注意 + getEPTimer->stop(); + getEPTimer->deleteLater(); + } + + if (requestEP) + requestEP->cancelRequestEP(this); +} + +bool DFileInfoPrivate::isLowSpeedFile() const +{ + if (lowSpeedFile < 0) { + lowSpeedFile = DStorageInfo::isLowSpeedDevice(fileInfo.absoluteFilePath()); + } + + return lowSpeedFile; +} + +DFileInfo::DFileInfo(const QString &filePath, bool hasCache) + : DFileInfo(DUrl::fromLocalFile(filePath), hasCache) +{ +} + +DFileInfo::DFileInfo(const DUrl &fileUrl, bool hasCache) + : DAbstractFileInfo(*new DFileInfoPrivate(fileUrl, this, hasCache)) +{ +} + +DFileInfo::DFileInfo(const QFileInfo &fileInfo, bool hasCache) + : DFileInfo(DUrl::fromLocalFile(fileInfo.absoluteFilePath()), hasCache) +{ + +} + +DFileInfo::~DFileInfo() +{ + +} + +bool DFileInfo::exists(const DUrl &fileUrl) +{ + return QFileInfo::exists(fileUrl.toLocalFile()); +} + +QMimeType DFileInfo::mimeType(const QString &filePath, QMimeDatabase::MatchMode mode, const QString inod, const bool isgvfs) +{ + static DMimeDatabase db; + if (isgvfs) { + return db.mimeTypeForFile(filePath, mode, inod, isgvfs); + } + return db.mimeTypeForFile(filePath, mode); +} + +bool DFileInfo::exists() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.exists() || d->fileInfo.isSymLink(); +} + +bool DFileInfo::isPrivate() const +{ + Q_D(const DFileInfo); + + return FileController::privateFileMatch(d->fileInfo.absolutePath(), d->fileInfo.fileName()); +} + +QString DFileInfo::path() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.path(); +} + +QString DFileInfo::filePath() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.filePath(); +} + +QString DFileInfo::absolutePath() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.absolutePath(); +} + +QString DFileInfo::absoluteFilePath() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.absoluteFilePath(); +} + +QString DFileInfo::fileName() const +{ + Q_D(const DFileInfo); + + if (d->fileInfo.absoluteFilePath().endsWith(QDir::separator())) + return QFileInfo(d->fileInfo.absolutePath()).fileName(); + + return d->fileInfo.fileName(); +} + +QString DFileInfo::fileSharedName() const +{ + const ShareInfo &info = userShareManager->getShareInfoByPath(absoluteFilePath()); + + return info.shareName(); +} + +QList DFileInfo::additionalIcon() const +{ + Q_D(const DFileInfo); + + if (d->proxy) + return d->proxy->additionalIcon(); + + QList icons; + + bool needEmblem = true; + // wayland TASK-38720 修复重命名文件时,文件图标有小锁显示的问题, + // 当为快捷方式时,有源文件文件不存在的情况,所以增加特殊判断 + if (!isSymLink() && !exists()) { + return icons; + } + + if (isSymLink()) { + icons << QIcon::fromTheme("emblem-symbolic-link", DFMGlobal::instance()->standardIcon(DFMGlobal::LinkIcon)); + //链接文件不显示自定义标记 + needEmblem = false; + } + + if (!d->gvfsMountFile) { + if (!isWritable()) { + icons << QIcon::fromTheme("emblem-readonly", DFMGlobal::instance()->standardIcon(DFMGlobal::LockIcon)); + } + + if (!isReadable()) { + icons << QIcon::fromTheme("emblem-unreadable", DFMGlobal::instance()->standardIcon(DFMGlobal::UnreadableIcon)); + } + } + //网络文件不显示自定义标记 + else { + needEmblem = false; + } + + if (isShared()) { + icons << QIcon::fromTheme("emblem-shared", DFMGlobal::instance()->standardIcon(DFMGlobal::ShareIcon)); + } + + //部分文件和目录不显示徽标 + if (needEmblem && + fileUrl().parentUrl().path() != "/" && + fileUrl().parentUrl().path() != "/data" && + !fileUrl().path().startsWith("/media")) + loadFileEmblems(icons); + +#ifdef SW_LABEL + QString labelIconPath = getLabelIcon(); + if (!labelIconPath.isEmpty()) { + icons << QIcon(labelIconPath); + } +#endif + + return icons; +} + +// 此函数高频调用,使用 DFileInfo 会降低性能 +bool DFileInfo::fileIsWritable(const QString &path, uint ownerId) +{ + Q_UNUSED(ownerId) + + // 如果是root,则拥有权限 + if (DFMGlobal::isRootUser()) { + return true; + } + + // check user's permissions for a file + QByteArray pathBytes(path.toLocal8Bit()); + int result = access(pathBytes.data(), W_OK); + if (result == 0) { + return true; + } + + return false; +} + +bool DFileInfo::isDragCompressFileFormat() const +{ + Q_D(const DFileInfo); + + // 支持".zip"结尾的,支持".7z"结尾的但不支持".tar.7z"结尾的 + return d->fileInfo.fileName().endsWith(".zip") + || (d->fileInfo.fileName().endsWith(".7z") + && !d->fileInfo.fileName().endsWith(".tar.7z")); +} + +bool DFileInfo::canRename() const +{ + if (systemPathManager->isSystemPath(absoluteFilePath())) + return false; + Q_D(const DFileInfo); + + return fileIsWritable(d->fileInfo.absolutePath(), d->fileInfo.ownerId()); +} + +bool DFileInfo::canShare() const +{ + if (isDir() && isReadable()) { + QStorageInfo stInfo(fileUrl().toLocalFile()); + QStorageInfo hstInfo(QDir::homePath()); + QString userPath = QDir::homePath(); + if (stInfo.device() == hstInfo.device()) { // /data/user ==> /home/user ==> /dev/sda + userPath = stInfo.rootPath() + QString("/").append(UserShareManager::getCurrentUserName()); + } + + if (absoluteFilePath().startsWith(userPath)) { + return true; + } + //fix fix task 29259,说明是共享使用true + UDiskDeviceInfoPointer info = deviceListener->getDeviceByFilePath(filePath(), true); + + if (info) { + if (info->getMediaType() != UDiskDeviceInfo::unknown && info->getMediaType() != UDiskDeviceInfo::network) + return true; + } else { + QStringList udiskspathes = DDiskManager::resolveDeviceNode(stInfo.device(), {}); + return udiskspathes.size() > 0; + } + } + + return false; +} + +bool DFileInfo::canFetch() const +{ + if (isPrivate()) + return false; + + return (isDir() || + (FileUtils::isArchive(absoluteFilePath()) && DFMApplication::instance()->genericAttribute(DFMApplication::GA_PreviewCompressFile).toBool())); +} + +bool DFileInfo::canTag() const +{ +#ifdef DISABLE_TAG_SUPPORT + return false; +#endif // DISABLE_TAG_SUPPORT + + bool isFiltered = DAnythingMonitorFilter::instance()->whetherFilterCurrentPath(parentUrl().toLocalFile().toLocal8Bit()); + if (!isFiltered) + return false; + + //压缩包内的文件和目录不支持添加tag的功能 + QString compressPath = QDir::homePath() + "/.avfs/"; + if (filePath().startsWith(compressPath)) + return false; + + //主目录不允许添加标记 + QString parentPath = parentUrl().path(); + if (parentPath == "/home" || parentPath == "/data/home") + return false; + + //判断所有用户的固定文件夹 + QString rootPath = parentUrl().parentUrl().path(); + QString path = filePath(); + if (rootPath == "/home" || rootPath == "/data/home") { + if (path.endsWith("/Desktop") || path.endsWith("/Videos") || path.endsWith("/Music") || + path.endsWith("/Pictures") || path.endsWith("/Documents") || path.endsWith("/Downloads")) + return false; + } + + return !systemPathManager->isSystemPath(filePath()); +} + +bool DFileInfo::isReadable() const +{ + if (isPrivate()) + return false; + + Q_D(const DFileInfo); + + return d->fileInfo.isReadable(); +} + +bool DFileInfo::isWritable() const +{ + if (isPrivate()) + return false; + + Q_D(const DFileInfo); + + return d->fileInfo.isWritable(); +} + +bool DFileInfo::isExecutable() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.isExecutable(); +} + +bool DFileInfo::isHidden() const +{ + Q_D(const DFileInfo); + // blumia: 目前不在这里读 .hidden 文件并以此返回显示状态的原因是,切换到某个目录时遍历所有文件,每个文件都会调一次 isHidden() ,而每次 + // 都重新读那个文件显然不合适,FileController 又位于没有跑事件循环的线程,也无法简单的缓存并监视文件变动。 + // 鉴于需求要的特别急,所以先使用比较脏的做法,在 Controller 里创建目录迭代器时读取一次文件,这样以达到减少不必要的读取,不需要监视 + // 文件变动,并且退出并重新进入目录时即会重新加载配置。 + return d->fileInfo.isHidden() || FileController::customHiddenFileMatch(d->fileInfo.absolutePath(), d->fileInfo.fileName()); +} + +bool DFileInfo::isRelative() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.isRelative(); +} + +bool DFileInfo::isAbsolute() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.isAbsolute(); +} + +bool DFileInfo::isShared() const +{ + return userShareManager->isShareFile(absoluteFilePath()); +} + +bool DFileInfo::isWritableShared() const +{ + const ShareInfo &info = userShareManager->getShareInfoByPath(absoluteFilePath()); + + return info.isWritable(); +} + +bool DFileInfo::isAllowGuestShared() const +{ + const ShareInfo &info = userShareManager->getShareInfoByPath(absoluteFilePath()); + + return info.isGuestOk(); +} + +bool DFileInfo::makeAbsolute() +{ + Q_D(DFileInfo); + + return d->fileInfo.makeAbsolute(); +} + +DAbstractFileInfo::FileType DFileInfo::fileType() const +{ + Q_D(const DFileInfo); + + // fix bug#52950 【专业版1030】【文管5.2.0.72】回收站删除指向块设备的链接文件时,删除失败 + // QT_STATBUF判断链接文件属性时,判断的是指向文件的属性,使用QFileInfo判断 + QString absoluteFilePath = d->fileInfo.absoluteFilePath(); + if (absoluteFilePath.startsWith(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath)) + && d->fileInfo.isSymLink()) { + return RegularFile; + } + + // Cannot access statBuf.st_mode from the filesystem engine, so we have to stat again. + // In addition we want to follow symlinks. + const QByteArray &nativeFilePath = QFile::encodeName(absoluteFilePath); + QT_STATBUF statBuffer; + if (QT_STAT(nativeFilePath.constData(), &statBuffer) == 0) { + if (S_ISDIR(statBuffer.st_mode)) + return Directory; + + if (S_ISCHR(statBuffer.st_mode)) + return CharDevice; + + if (S_ISBLK(statBuffer.st_mode)) + return BlockDevice; + + if (S_ISFIFO(statBuffer.st_mode)) + return FIFOFile; + + if (S_ISSOCK(statBuffer.st_mode)) + return SocketFile; + + if (S_ISREG(statBuffer.st_mode)) + return RegularFile; + } + + return Unknown; +} + +bool DFileInfo::isFile() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.isFile(); +} + +bool DFileInfo::isDir() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.isDir(); +} + +bool DFileInfo::isSymLink() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.isSymLink(); +} + +bool DFileInfo::canDragCompress() const +{ + Q_D(const DFileInfo); + + return isDragCompressFileFormat() + && d->fileInfo.isWritable() + && d->fileInfo.isReadable(); +} + +QString DFileInfo::symlinkTargetPath() const +{ + Q_D(const DFileInfo); + + if (d->fileInfo.isSymLink()) { + char s[PATH_MAX + 1]; + int len = static_cast(readlink(d->fileInfo.absoluteFilePath().toLocal8Bit().constData(), s, PATH_MAX)); + + return QString::fromLocal8Bit(s, len); + } + + return QString(); +} + +DUrl DFileInfo::symLinkTarget() const +{ + Q_D(const DFileInfo); + + if (d->fileInfo.isSymLink()) + return DUrl::fromLocalFile(d->fileInfo.symLinkTarget()); + + return DAbstractFileInfo::symLinkTarget(); +} + +QString DFileInfo::owner() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.owner(); +} + +uint DFileInfo::ownerId() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.ownerId(); +} + +QString DFileInfo::group() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.group(); +} + +uint DFileInfo::groupId() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.groupId(); +} + +bool DFileInfo::permission(QFileDevice::Permissions permissions) const +{ + Q_D(const DFileInfo); + + if (isPrivate()) + return false; + + return d->fileInfo.permission(permissions); +} + +QFileDevice::Permissions DFileInfo::permissions() const +{ + Q_D(const DFileInfo); + + if (isPrivate()) + return QFileDevice::Permissions(); + + return d->fileInfo.permissions(); +} + +qint64 DFileInfo::size() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.size(); +} + +int DFileInfo::filesCount() const +{ + + if (isDir()) + return FileUtils::filesCount(absoluteFilePath()); + + return -1; +} + +QString DFileInfo::sizeDisplayName() const +{ + if (isDir()) { + return QStringLiteral("-"); + } + + return FileUtils::formatSize(size()); +} + +QDateTime DFileInfo::created() const +{ + Q_D(const DFileInfo); + + return d->fileInfo.created(); +} + +QDateTime DFileInfo::lastModified() const +{ + Q_D(const DFileInfo); + + if (isSymLink() && !d->fileInfo.exists()) { + struct stat attrib; + + if (lstat(d->fileInfo.filePath().toLocal8Bit().constData(), &attrib) >= 0) + return QDateTime::fromTime_t(static_cast(attrib.st_mtime)); + } + + return d->fileInfo.lastModified(); +} + +QDateTime DFileInfo::lastRead() const +{ + Q_D(const DFileInfo); + + if (isSymLink() && !d->fileInfo.exists()) { + struct stat attrib; + + if (lstat(d->fileInfo.filePath().toLocal8Bit().constData(), &attrib) >= 0) + return QDateTime::fromTime_t(static_cast(attrib.st_mtime)); + } + + return d->fileInfo.lastRead(); +} + +QMimeType DFileInfo::mimeType(QMimeDatabase::MatchMode mode) const +{ + Q_D(const DFileInfo); + + if (!d->mimeType.isValid() || d->mimeTypeMode != mode) { + //优化是苹果的就用新的minetype + DUrl url = fileUrl(); + + d->mimeType = mimeType(fileUrl().path(), mode); + d->mimeTypeMode = mode; + } + + return d->mimeType; +} + +bool DFileInfo::canIteratorDir() const +{ + return true; +} + +QString DFileInfo::subtitleForEmptyFloder() const +{ + Q_D(const DFileInfo); + + if (!exists()) { + return QObject::tr("File has been moved or deleted"); + } else if (!isReadable()) { + return QObject::tr("You do not have permission to access this folder"); + } else if (isDir()) { + //当一个目录没有执行权限时,其子文件不能被遍历也就无法显示出来 + if (!isExecutable()) + return QObject::tr("You do not have permission to traverse files in it"); + + if (d->gvfsMountFile) { + // blumia: when user visiting dir as anonymous, file permission won't work + // if you want to check user can list a dir or not. i.e. you'll see + // a 700 permission with your username on it, but you can't do readdir + // at all. + struct dirent *next; + DIR *dirp = opendir(absoluteFilePath().toUtf8().constData()); + if (!dirp) return QObject::tr("You do not have permission to access this folder"); + errno = 0; + next = readdir(dirp); + closedir(dirp); + if (!next && errno != 0) { + // qDebug() << errno; + return QObject::tr("You do not have permission to access this folder"); + } + } + } + + return QObject::tr("Folder is empty"); +} + +QString DFileInfo::fileDisplayName() const +{ + if (systemPathManager->isSystemPath(toLocalFile())) { + const QString &displayName = systemPathManager->getSystemPathDisplayNameByPath(filePath()); + + if (!displayName.isEmpty()) + return displayName; + } /*else if (getUDiskListener(false) && deviceListener->isDeviceFolder(toLocalFile())) { + const UDiskDeviceInfoPointer &deviceInfo = deviceListener->getDeviceByPath(filePath()); + + if (deviceInfo && !deviceInfo->fileDisplayName().isEmpty()) + return deviceInfo->fileDisplayName(); + }*/ + + return fileName(); +} + +void DFileInfo::refresh(const bool isForce) +{ + Q_D(DFileInfo); + + Q_UNUSED(isForce) + + d->fileInfo.refresh(); + d->icon = QIcon(); + d->epInitialized = false; + d->hasThumbnail = -1; + d->mimeType = QMimeType(); + d->inode = 0; +} + +DUrl DFileInfo::goToUrlWhenDeleted() const +{ + const QString &absFilePath = absoluteFilePath(); + if (deviceListener->isInDeviceFolder(absFilePath) || + absFilePath.startsWith("/run/user") // for gvfs mount point + || absFilePath.startsWith("/media/")) { + return DUrl(COMPUTER_ROOT); + } + + return DAbstractFileInfo::goToUrlWhenDeleted(); +} + +void DFileInfo::makeToActive() +{ + Q_D(DFileInfo); + + if (!d->isLowSpeedFile()) + d->fileInfo.refresh(); + + DAbstractFileInfo::makeToActive(); +} + +void DFileInfo::makeToInactive() +{ + Q_D(DFileInfo); + + DAbstractFileInfo::makeToInactive(); + + if (d->getIconTimer) { + d->getIconTimer->stop(); + d->getIconTimer->deleteLater(); + } else if (d->requestingThumbnail) { + d->requestingThumbnail = false; + DThumbnailProvider::instance()->removeInProduceQueue(d->fileInfo, DThumbnailProvider::Large); + } + + if (d->getEPTimer) { + d->getEPTimer->stop(); + d->getEPTimer->deleteLater(); + d->requestEP = nullptr; + d->epInitialized = false; + } +} + +QIcon DFileInfo::fileIcon() const +{ + Q_D(const DFileInfo); + + if (!d->icon.isNull() && !d->needThumbnail && (!d->iconFromTheme || !d->icon.name().isEmpty())) { + return d->icon; + } + + d->iconFromTheme = false; + + const DUrl &fileUrl = this->fileUrl(); + +#ifdef DFM_MINIMUM + d->hasThumbnail = 0; +#else + if (d->hasThumbnail < 0) { + // 如果是保险箱,直接获取图片(解决保险箱没有图标问题) + if (fileUrl.toString().contains(VaultController::makeVaultLocalPath())) { + d->hasThumbnail = DThumbnailProvider::instance()->hasThumbnail(d->fileInfo) && !DStorageInfo::isCdRomDevice(absoluteFilePath()); + } else { + d->hasThumbnail = DStorageInfo::isLocalDevice(absoluteFilePath()) && DThumbnailProvider::instance()->hasThumbnail(d->fileInfo) && !DStorageInfo::isCdRomDevice(absoluteFilePath()); + } + } +#endif + if (d->needThumbnail || d->hasThumbnail > 0) { + d->needThumbnail = true; + + const QIcon icon(DThumbnailProvider::instance()->thumbnailFilePath(d->fileInfo, DThumbnailProvider::Large)); + + if (!icon.isNull()) { + QPixmap pixmap = icon.pixmap(DThumbnailProvider::Large, DThumbnailProvider::Large); + QPainter pa(&pixmap); + + pa.setPen(Qt::gray); + pa.drawPixmap(0, 0, pixmap); + d->icon.addPixmap(pixmap); + d->iconFromTheme = false; + d->needThumbnail = false; + + return d->icon; + } + + if (d->getIconTimer) { + QMetaObject::invokeMethod(d->getIconTimer, "start", Qt::QueuedConnection); + } else if (isActive()) { + QTimer *timer = new QTimer(); + const QExplicitlySharedDataPointer me(const_cast(this)); + + d->getIconTimer = timer; + timer->setSingleShot(true); + timer->moveToThread(qApp->thread()); + timer->setInterval(REQUEST_THUMBNAIL_DEALY); + + QObject::connect(timer, &QTimer::timeout, timer, [fileUrl, timer, me] { + DThumbnailProvider::instance()->appendToProduceQueue(me->d_func()->fileInfo, DThumbnailProvider::Large, + [me](const QString & path) + { + DThreadUtil::runInMainThread([me, path]() { + if (path.isEmpty()) { + me->d_func()->iconFromTheme = true; + } else { + // clean old icon + me->d_func()->icon = QIcon(); + } + + me->d_func()->needThumbnail = false; + }); + + }); + me->d_func()->requestingThumbnail = true; + timer->deleteLater(); + }); + + QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection); + } + + if (d->icon.isNull()) + d->icon = DFileIconProvider::globalProvider()->icon(*this); + + return d->icon; + } else { + d->needThumbnail = false; + } + + if (isSymLink()) { + const DUrl &symLinkTarget = this->symLinkTarget(); + + if (symLinkTarget != fileUrl) { + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, symLinkTarget); + + if (fileInfo) { + d->icon = fileInfo->fileIcon(); + d->iconFromTheme = false; + + return d->icon; + } + } + } + + d->icon = DFileIconProvider::globalProvider()->icon(*this); + d->iconFromTheme = true; + + return d->icon; +} + +QString DFileInfo::iconName() const +{ + if (systemPathManager->isSystemPath(absoluteFilePath())) + return systemPathManager->getSystemPathIconNameByPath(absoluteFilePath()); + + return DAbstractFileInfo::iconName(); +} + +QFileInfo DFileInfo::toQFileInfo() const +{ + Q_D(const DFileInfo); + + return d->fileInfo; +} + +QIODevice *DFileInfo::createIODevice() const +{ + return new QFile(absoluteFilePath()); +} + +QVariantHash DFileInfo::extraProperties() const +{ + Q_D(const DFileInfo); + + // ensure extra properties + if (!d->epInitialized) { + d->epInitialized = true; + + const DUrl &url = fileUrl(); + + if (!d->getEPTimer) { + d->getEPTimer = new QTimer(qApp); + d->getEPTimer->setSingleShot(true); + d->getEPTimer->moveToThread(qApp->thread()); + d->getEPTimer->setInterval(REQUEST_THUMBNAIL_DEALY); + } + + QObject::connect(d->getEPTimer, &QTimer::timeout, d->getEPTimer, [d, url] { + d->requestEP = RequestEP::instance(); + + //线程run之前先确保fileinfo未被析构时request不会被取消 + d->requestEP->requestEPCancelLock.lock(); + d->requestEP->isCanceled = false; + d->requestEP->requestEPCancelLock.unlock(); + + d->requestEP->requestEP(url, const_cast(d)); + d->getEPTimer->deleteLater(); + }); + + QMetaObject::invokeMethod(d->getEPTimer, "start", Qt::QueuedConnection); + } + + return d->extraProperties; +} + +quint64 DFileInfo::inode() const +{ + Q_D(const DFileInfo); + if (d->inode != 0) { + return d->inode; + } + + struct stat statinfo; + QByteArray pathArry = d->fileInfo.absoluteFilePath().toUtf8(); + std::string pathStd = pathArry.toStdString(); + if (stat(pathStd.c_str(), &statinfo) != 0) + return 0; + d->inode = statinfo.st_ino; + + return d->inode; +} + +DFileInfo::DFileInfo(DFileInfoPrivate &dd) + : DAbstractFileInfo(dd) +{ + +} + +#include "dfileinfo.moc" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileinfo.h new file mode 100644 index 0000000..5154635 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileinfo.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef FILEINFO_H +#define FILEINFO_H + +#include "dabstractfileinfo.h" + +class DFileInfoPrivate; +class DFileInfo : public DAbstractFileInfo +{ +public: + explicit DFileInfo(const QString &filePath, bool hasCache = true); + explicit DFileInfo(const DUrl &fileUrl, bool hasCache = true); + explicit DFileInfo(const QFileInfo &fileInfo, bool hasCache = true); + ~DFileInfo() override; + + static bool exists(const DUrl &fileUrl); + static QMimeType mimeType(const QString &filePath, QMimeDatabase::MatchMode mode = QMimeDatabase::MatchDefault, + const QString inod = QString(), const bool isgvfs = false); + + bool exists() const override; + bool isPrivate() const override; + + QString path() const override; + QString filePath() const override; + QString absolutePath() const override; + QString absoluteFilePath() const override; + QString fileName() const override; + QString fileSharedName() const override; + + QList additionalIcon() const override; + + bool canRename() const override; + bool canShare() const override; + bool canFetch() const override; + bool canTag() const override; + + bool isReadable() const override; + bool isWritable() const override; + bool isExecutable() const override; + bool isHidden() const override; + bool isRelative() const override; + bool isAbsolute() const override; + bool isShared() const override; + bool isWritableShared() const override; + bool isAllowGuestShared() const override; + bool makeAbsolute() override; + + FileType fileType() const override; + bool isFile() const override; + bool isDir() const override; + bool isSymLink() const override; + + /** + * @brief canDragCompress 是否支持拖拽压缩 + * @return + */ + bool canDragCompress() const override; + + QString symlinkTargetPath() const override; + DUrl symLinkTarget() const override; + + QString owner() const override; + uint ownerId() const override; + QString group() const override; + uint groupId() const override; + + bool permission(QFile::Permissions permissions) const override; + QFile::Permissions permissions() const override; + + qint64 size() const override; + int filesCount() const override; + QString sizeDisplayName() const override; + + QDateTime created() const override; + QDateTime lastModified() const override; + QDateTime lastRead() const override; + + QMimeType mimeType(QMimeDatabase::MatchMode mode = QMimeDatabase::MatchDefault) const override; + + bool canIteratorDir() const override; + + QString subtitleForEmptyFloder() const override; + + QString fileDisplayName() const override; + + void refresh(const bool isForce = false) override; + DUrl goToUrlWhenDeleted() const override; + + void makeToActive() override; + void makeToInactive() override; + QIcon fileIcon() const override; + + QString iconName() const override; + + QFileInfo toQFileInfo() const override; + QIODevice *createIODevice() const override; + + QVariantHash extraProperties() const override; + + quint64 inode() const override; + + // 此函数高频调用,使用 DFileInfo 会降低性能 + static bool fileIsWritable(const QString &path, uint ownerId); + + /** + * @brief isDragCompressFile 判断是否是支持拖拽压缩的文件 + * @return + */ + bool isDragCompressFileFormat() const override; + +protected: + explicit DFileInfo(DFileInfoPrivate &dd); + +private: + Q_DECLARE_PRIVATE(DFileInfo) + + friend class RequestEP; +}; + +#endif // FILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilemenu.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilemenu.cpp new file mode 100644 index 0000000..645749e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilemenu.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfilemenu.h" +#include "dfmevent.h" +#include "accessibility/acintelfunctions.h" +#include +#include + +DFileMenu::DFileMenu(QWidget *parent) + : QMenu(parent) +{ + this->setAccessibleInfo(AC_FILE_MENU_DEFAULT); +} + +const QSharedPointer DFileMenu::makeEvent(DFMGlobal::MenuAction action) const +{ + DFMMenuActionEvent *event = new DFMMenuActionEvent(m_sender, this, m_currentUrl, m_selectedUrls, action, m_clickedIndex); + + event->setWindowId(m_eventId); + + return QSharedPointer(event); +} + +void DFileMenu::setEventData(const DUrl ¤tUrl, const DUrlList &selectedUrls, quint64 eventId, const QObject *sender, const QModelIndex &index) +{ + m_currentUrl = currentUrl; + m_selectedUrls = selectedUrls; + m_eventId = eventId; + m_sender = sender; + //设置当前点击的index + m_clickedIndex = index; +} + +QAction *DFileMenu::actionAt(int index) const +{ + return actions().value(index); +} + +QAction *DFileMenu::actionAt(const QString &text) const +{ + for (QAction *action : actions()) { + if (action->text() == text) { + return action; + } + } + + return Q_NULLPTR; +} + +QAction *DFileMenu::exec() +{ + return QMenu::exec(QCursor::pos()); +} + +QAction *DFileMenu::exec(const QPoint &pos, QAction *at) +{ + return QMenu::exec(pos,at); +} + +quint64 DFileMenu::eventId() const +{ + return m_eventId; +} + +QSet DFileMenu::ignoreMenuActions() const +{ + return m_ignoreMenuActions; +} + +void DFileMenu::setIgnoreMenuActions(const QSet &ignoreMenuActions) +{ + m_ignoreMenuActions = ignoreMenuActions; +} + +DUrlList DFileMenu::selectedUrls() const +{ + return m_selectedUrls; +} + +// 重定义,防止多次右键点击造成崩溃 +void DFileMenu::deleteLater(QWidget *w) +{ + if (w) + qApp->setActiveWindow(w); + QMenu::deleteLater(); +} + +void DFileMenu::mouseMoveEvent(QMouseEvent * event) +{ + QMenu::mouseMoveEvent(event); + update(); +} + +void DFileMenu::setAccessibleInfo(const QString& name) +{ + AC_SET_OBJECT_NAME(this,name); + AC_SET_ACCESSIBLE_NAME(this,name); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilemenu.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilemenu.h new file mode 100644 index 0000000..29068e3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilemenu.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILEMENU_H +#define DFILEMENU_H + +#include + +#include "dfmglobal.h" +#include "durl.h" +#include "accessibility/ac-lib-file-manager.h" +#include + +class DFMMenuActionEvent; +class DFileMenu : public QMenu +{ + Q_OBJECT + +public: + explicit DFileMenu(QWidget * parent = nullptr); + ~DFileMenu() override { } + + const QSharedPointer makeEvent(DFMGlobal::MenuAction action) const; + void setEventData(const DUrl ¤tUrl, const DUrlList &selectedUrls, quint64 eventId = 0, const QObject *sender = nullptr, const QModelIndex &index = QModelIndex()); + + QAction *actionAt(int index) const; + QAction *actionAt(const QString &text) const; + + QAction *exec(); + QAction *exec(const QPoint &pos, QAction *at = nullptr); + using QMenu::exec; + + quint64 eventId() const; + + QSet ignoreMenuActions() const; + void setIgnoreMenuActions(const QSet &ignoreMenuActions); + + DUrlList selectedUrls() const; + void setCanUse(const bool canuse); + void mouseMoveEvent(QMouseEvent * event) override; + + void setAccessibleInfo(const QString& name); + +public Q_SLOTS: + void deleteLater(QWidget *w = nullptr); + +private: + DUrl m_currentUrl; + DUrlList m_selectedUrls; + quint64 m_eventId = 0; + const QObject *m_sender = Q_NULLPTR; + QSet m_ignoreMenuActions; //Don't handle MenuAction list in libdde-file-manager in m_ignoreMenuActions; + QModelIndex m_clickedIndex; //右键点击的index +}; + +#endif // DFILEMENU_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilemenumanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilemenumanager.cpp new file mode 100644 index 0000000..8330b4b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilemenumanager.cpp @@ -0,0 +1,1480 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "dfilemenumanager.h" +#include "dfmglobal.h" +#include "app/define.h" +#include "dfmevent.h" +#include "dfilemenu.h" +#include "dfileservices.h" +#include "dfmeventdispatcher.h" +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "controllers/vaultcontroller.h" +#include "controllers/appcontroller.h" +#include "controllers/trashmanager.h" +#include "models/desktopfileinfo.h" +#include "shutil/mimetypedisplaymanager.h" +#include "singleton.h" +#include "views/windowmanager.h" +#include "shutil/fileutils.h" +#include "shutil/mimesappsmanager.h" +#include "shutil/danythingmonitorfilter.h" +#include "controllers/pathmanager.h" +#include "plugins/pluginmanager.h" +#include "dde-file-manager-plugins/plugininterfaces/menu/menuinterface.h" +#include "dfmstandardpaths.h" +#include "deviceinfo/udisklistener.h" +#include "ddiskmanager.h" +#include "dblockdevice.h" +#include "ddiskdevice.h" +#include "views/dtagactionwidget.h" +#include "plugins/dfmadditionalmenu.h" +#include "models/dfmrootfileinfo.h" +#include "bluetooth/bluetoothmanager.h" +#include "bluetooth/bluetoothmodel.h" +#include "io/dstorageinfo.h" +#include "vault/vaultlockmanager.h" +#include "vault/vaulthelper.h" +#include "app/filesignalmanager.h" +#include "views/dfilemanagerwindow.h" +#include "customization/dcustomactionbuilder.h" +#include "customization/dcustomactionparser.h" +#include "gvfs/gvfsmountmanager.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +//fix:临时获取光盘刻录前临时的缓存地址路径,便于以后直接获取使用 + +namespace DFileMenuData { +static QMap actionKeys; +static QMap actionIcons; +static QMap actions; +static QMap actionToMenuAction; +static QMap actionIDs; +static QVector sortActionTypes; +static QSet whitelist; +static QSet blacklist; +static QQueue availableUserActionQueue; +static DFMAdditionalMenu *additionalMenu; +static DCustomActionParser *customMenuParser = nullptr; + +void initData(); +void initActions(); +void clearActions(); + +MenuAction takeAvailableUserActionType() +{ + if (availableUserActionQueue.isEmpty()) { + availableUserActionQueue.append(MenuAction(MenuAction::UserMenuAction + 1)); + + return MenuAction::UserMenuAction; + } + + MenuAction type = availableUserActionQueue.dequeue(); + + if (availableUserActionQueue.isEmpty()) { + availableUserActionQueue.append(MenuAction(type + 1)); + } + + return type; +} +void recycleUserActionType(MenuAction type) +{ + availableUserActionQueue.prepend(type); + QAction *action = actions.take(type); + + if (action) { + actionToMenuAction.remove(action); + } + if (DFileMenuManager::needDeleteAction()) + delete action; +} +} + +DFileMenu *DFileMenuManager::createDefaultBookMarkMenu(const QSet &disableList) +{ + QVector actionKeys; + + actionKeys.reserve(2); + + actionKeys << MenuAction::OpenInNewWindow + << MenuAction::OpenInNewTab + << MenuAction::Property; + + return genereteMenuByKeys(actionKeys, disableList); +} + +DFileMenu *DFileMenuManager::createUserShareMarkMenu(const QSet &disableList) +{ + QVector actionKeys; + + actionKeys.reserve(1); + + actionKeys << MenuAction::OpenInNewWindow + << MenuAction::OpenInNewTab; + + DFileMenu *menu = genereteMenuByKeys(actionKeys, disableList); + menu->setAccessibleInfo(AC_FILE_MENU_USER_SHARE); + return menu; +} + +DFileMenu *DFileMenuManager::createToolBarSettingsMenu(const QSet &disableList) +{ + QVector actionKeys; + QMap > subMenuKeys; + + actionKeys.reserve(5); + + actionKeys << MenuAction::NewWindow + << MenuAction::Separator + << MenuAction::ConnectToServer + << MenuAction::SetUserSharePassword + << MenuAction::Settings; + + DFileMenu *menu = genereteMenuByKeys(actionKeys, disableList, false, subMenuKeys, false); + menu->setAccessibleInfo(AC_FILE_MENU_TOOLBAR_SEETINGS); + return menu; +} + +DFileMenu *DFileMenuManager::createNormalMenu(const DUrl ¤tUrl, const DUrlList &urlList, QSet disableList, QSet unusedList, int windowId, bool onDesktop) +{ + // remove compress/decompress action + unusedList << MenuAction::Compress << MenuAction::Decompress << MenuAction::DecompressHere; + + DAbstractFileInfoPointer info = fileService->createFileInfo(Q_NULLPTR, currentUrl); + DFileMenu *menu = Q_NULLPTR; + if (!info) { + return menu; + } + + //! urlList中有保险箱的DUrl需要进行转换否则会出现报错或功能不可用 + DUrlList urls = urlList; + for (int i = 0; i < urlList.size(); ++i) { + if (urlList[i].isVaultFile()) + urls[i] = VaultController::vaultToLocalUrl(urlList[i]); + } + + auto dirInUrls = [](const DUrlList &urls) { + for (const auto &url: urls) { + auto fileInfo = fileService->createFileInfo(nullptr, url); + if (fileInfo && fileInfo->isDir()) + return true; + } + return false; + }; + + DUrlList redirectedUrlList; + if (urls.length() == 1) { + QVector actions = info->menuActionList(DAbstractFileInfo::SingleFile); + //修改在挂载的文件下面,不能删除,但是显示了删除 + //判定逻辑,如果是挂载盘,并且这个文件是对应的不是一个虚拟的项(表示有实体),那么这个文件就有彻底删除权限MenuAction::CompleteDeletion + //但是这个文件canrename权限为false,以前的判断输出就是,不能MenuAction::Cut,MenuAction::Rename + // MenuAction::delete + //当彻底删除时,判断canrename权限,true可以删除,false不可以删除 + //所以这里要把MenuAction::CompleteDeletion权限不能用 + if (FileUtils::isGvfsMountFile(info->absoluteFilePath()) && !info->canRename()) { + disableList << MenuAction::CompleteDeletion; + } + if (info->isDir()) { //判断是否目录 + if (info->ownerId() != getuid() && !DFMGlobal::isRootUser()) { //判断文件属主与进程属主是否相同,排除进程属主为根用户情况 + disableList << MenuAction::UnShare << MenuAction::Share; //设置取消共享、取消共享不可选 + } + } + foreach (MenuAction action, unusedList) { + if (actions.contains(action)) { + actions.remove(actions.indexOf(action)); + } + } + + if (actions.isEmpty()) { + return menu; + } + + const QMap > &subActions = info->subMenuActionList(); + disableList += DFileMenuManager::getDisableActionList(urls); + const bool &tabAddable = WindowManager::tabAddableByWinId(windowId); + if (!tabAddable) { + disableList << MenuAction::OpenInNewTab; + } + + ///###: tag protocol. + if (!DFileMenuManager::whetherShowTagActions(urls)) { + actions.removeAll(MenuAction::TagInfo); + actions.removeAll(MenuAction::TagFilesUseColor); + } + + // sp3 feature: root用户, 服务器版本用户, 非开发者模式均不需要以管理员身份打开的功能 + if (DFMGlobal::isRootUser() || DFMGlobal::isServerSys() || !DFMGlobal::isDeveloperMode()) { + actions.removeAll(MenuAction::OpenAsAdmin); + } + + menu = DFileMenuManager::genereteMenuByKeys(actions, disableList, true, subActions); + } else { + bool isSystemPathIncluded = false; + bool isAllCompressedFiles = true; +// QMimeType fileMimeType; + QStringList supportedMimeTypes; + bool mime_displayOpenWith = true; + //fix bug 35546 【文件管理器】【5.1.2.2-1】【sp2】【sp1】选择多个只读文件夹,删除按钮没有置灰 + //只判断当前选中的文件夹是否是只读文件夹 + if (!info->isWritable() && !info->isFile() && !info->isSymLink()) { + disableList << MenuAction::Delete; + } + +#if 1 //!fix bug#29264.部分格式的文件在上面的MimesAppsManager::getDefaultAppDesktopFileByMimeType + //!调用中可以找到app打开,但是在后面的判断是由于该app的supportedMimeTypes中并没有本文件的mimeTypeList支持 + //!导致了无法匹配,matched为false。因此这里加做一次判断,如果本次文件的后缀名与与上面查询app的文件后缀名一样,则直接匹配 + + //获取当前文件的app + if (supportedMimeTypes.isEmpty()) { + QMimeType fileMimeType = info->mimeType(); + QString defaultAppDesktopFile = MimesAppsManager::getDefaultAppDesktopFileByMimeType(fileMimeType.name()); + QSettings desktopFile(defaultAppDesktopFile, QSettings::IniFormat); + desktopFile.setIniCodec("UTF-8"); + Properties mimeTypeList(defaultAppDesktopFile, "Desktop Entry"); + supportedMimeTypes = mimeTypeList.value("MimeType").toString().split(';'); + supportedMimeTypes.removeAll(""); + } + + redirectedUrlList.clear(); + foreach (DUrl url, urls) { + const DAbstractFileInfoPointer &file_info = fileService->createFileInfo(Q_NULLPTR, url); + // fix bug202007010011 优化文件判断效率,提升右键菜单响应速度 + auto redirectedUrl = file_info->redirectedFileUrl(); + if (redirectedUrl.isValid()) { + redirectedUrlList << redirectedUrl; + } + + if (!FileUtils::isArchive(url.path())) { + isAllCompressedFiles = false; + } + + if (systemPathManager->isSystemPath(file_info->fileUrl().toLocalFile())) { + isSystemPathIncluded = true; + } + + if (!mime_displayOpenWith) { + continue; + } + + QStringList mimeTypeList = { file_info->mimeType().name() }; + mimeTypeList.append(file_info->mimeType().parentMimeTypes()); + bool matched = false; + + //后缀名相同直接匹配 + if (file_info->suffix() == info->suffix()) { + matched = true; + } else { + for (const QString &oneMimeType : mimeTypeList) { + if (supportedMimeTypes.contains(oneMimeType)) { + matched = true; + break; + } + } + } + + if (!matched) { + mime_displayOpenWith = false; + disableList << MenuAction::Open << MenuAction::OpenWith; + break; + } + } +#else //原来的实现 + foreach (DUrl url, urls) { + const DAbstractFileInfoPointer &fileInfo = fileService->createFileInfo(Q_NULLPTR, url); + + if (!FileUtils::isArchive(url.path())) { + isAllCompressedFiles = false; + } + + if (systemPathManager->isSystemPath(fileInfo->fileUrl().toLocalFile())) { + isSystemPathIncluded = true; + } + + if (!mime_displayOpenWith) { + continue; + } + + if (supportedMimeTypes.isEmpty()) { + QMimeType fileMimeType = fileInfo->mimeType(); + QString defaultAppDesktopFile = MimesAppsManager::getDefaultAppDesktopFileByMimeType(fileMimeType.name()); + QSettings desktopFile(defaultAppDesktopFile, QSettings::IniFormat); + desktopFile.setIniCodec("UTF-8"); + Properties mimeTypeList(defaultAppDesktopFile, "Desktop Entry"); + supportedMimeTypes = mimeTypeList.value("MimeType").toString().split(';'); + supportedMimeTypes.removeAll({}); + } else { + QStringList mimeTypeList = { fileInfo->mimeType().name() }; + mimeTypeList.append(fileInfo->mimeType().parentMimeTypes()); + bool matched = false; + for (const QString &oneMimeType : mimeTypeList) { + if (supportedMimeTypes.contains(oneMimeType)) { + matched = true; + break; + } + } + if (!matched) { + mime_displayOpenWith = false; + disableList << MenuAction::Open << MenuAction::OpenWith; + } + } + } +#endif + QVector actions; + + if (isSystemPathIncluded) { + actions = info->menuActionList(DAbstractFileInfo::MultiFilesSystemPathIncluded); + } else { + actions = info->menuActionList(DAbstractFileInfo::MultiFiles); + } + + if (actions.isEmpty()) { + return menu; + } + + if (isAllCompressedFiles) { + int index = actions.indexOf(MenuAction::Compress); + actions.insert(index + 1, MenuAction::Decompress); + actions.insert(index + 2, MenuAction::DecompressHere); + } + + const QMap > &subActions = info->subMenuActionList(); + disableList += DFileMenuManager::getDisableActionList(urls); + const bool &tabAddable = WindowManager::tabAddableByWinId(windowId); + if (!tabAddable) { + disableList << MenuAction::OpenInNewTab; + } + + foreach (MenuAction action, unusedList) { + if (actions.contains(action)) { + actions.remove(actions.indexOf(action)); + } + } + + ///###: tag protocol. + if (!DFileMenuManager::whetherShowTagActions(urls)) { + actions.removeAll(MenuAction::TagInfo); + actions.removeAll(MenuAction::TagFilesUseColor); + } + + menu = DFileMenuManager::genereteMenuByKeys(actions, disableList, true, subActions); + } + + QAction *openWithAction = menu->actionAt(DFileMenuManager::getActionString(DFMGlobal::OpenWith)); + DFileMenu *openWithMenu = openWithAction ? qobject_cast(openWithAction->menu()) : Q_NULLPTR; + + if (openWithMenu && openWithMenu->isEnabled()) { + QStringList recommendApps = mimeAppsManager->getRecommendedApps(info->redirectedFileUrl()); + recommendApps.removeOne("/usr/share/applications/dde-open.desktop"); //在右键菜单打开方式中屏蔽/usr/share/applications/dde-open.desktop,在此处更改不影响打开效果 +// bug 20275 【桌面社区版版V20】【beta】【DDE】【 桌面】选中图片右键打开方式多了“ImageMagick”需隐藏 + recommendApps.removeOne("/usr/share/applications/display-im6.q16.desktop"); //按产品经理要求屏蔽咯 + recommendApps.removeOne("/usr/share/applications/display-im6.q16hdri.desktop"); //按产品经理要求屏蔽咯 + foreach (QString app, recommendApps) { +// const DesktopFile& df = mimeAppsManager->DesktopObjs.value(app); + //ignore no show apps +// if(df.getNoShow()) +// continue; + DesktopFile desktopFile(app); + QAction *action = new QAction(desktopFile.getDisplayName(), openWithMenu); + action->setIcon(FileUtils::searchAppIcon(desktopFile)); + action->setProperty("app", app); + if (urls.length() == 1) { + action->setProperty("url", QVariant::fromValue(info->redirectedFileUrl())); + } else { +#if 0 // fix bug202007010011 优化文件判断效率,提升右键菜单响应速度 + DUrlList redirectedUrlList; + for (auto url : urls) { + DAbstractFileInfoPointer info = fileService->createFileInfo(Q_NULLPTR, url); + auto redirectedUrl = info->redirectedFileUrl(); + if (redirectedUrl.isValid()) { + redirectedUrlList << redirectedUrl; + } + } +#endif + action->setProperty("urls", QVariant::fromValue(redirectedUrlList)); + } + openWithMenu->addAction(action); + connect(action, &QAction::triggered, appController, &AppController::actionOpenFileByApp); + } + + QAction *action = new QAction(fileMenuManger->getActionString(MenuAction::OpenWithCustom), openWithMenu); + action->setData((int)MenuAction::OpenWithCustom); + openWithMenu->addAction(action); + DFileMenuData::actions[MenuAction::OpenWithCustom] = action; + DFileMenuData::actionToMenuAction[action] = MenuAction::OpenWithCustom; + } + + if (deviceListener->isMountedRemovableDiskExits() + || bluetoothManager->hasAdapter()) { + QAction *sendToMountedRemovableDiskAction = menu->actionAt(DFileMenuManager::getActionString(DFMGlobal::SendToRemovableDisk)); + if (currentUrl.path().contains("/dev/sr") + || (currentUrl.scheme() == SEARCH_SCHEME && currentUrl.query().contains("/dev/sr"))) // 禁用光盘搜索列表中的发送到选项 + menu->removeAction(sendToMountedRemovableDiskAction); + else { + DFileMenu *sendToMountedRemovableDiskMenu = sendToMountedRemovableDiskAction ? qobject_cast(sendToMountedRemovableDiskAction->menu()) : Q_NULLPTR; + if (sendToMountedRemovableDiskMenu) { + // 如果有蓝牙设备并且当前文件不在保险箱内 + if (BluetoothManager::bluetoothSendEnable() // is system disabled "sending via bluetooth" + && bluetoothManager->hasAdapter() + && !VaultController::isVaultFile(currentUrl.toLocalFile())) { + QAction *sendToBluetooth = new QAction(DFileMenuManager::getActionString(DFMGlobal::SendToBluetooth), sendToMountedRemovableDiskMenu); + sendToBluetooth->setProperty("urlList", DUrl::toStringList(urls)); + sendToMountedRemovableDiskMenu->addAction(sendToBluetooth); + connect(sendToBluetooth, &QAction::triggered, appController, &AppController::actionSendToBluetooth); + if (dirInUrls(urls)) + sendToBluetooth->setEnabled(false); + } + + foreach (UDiskDeviceInfoPointer pDeviceinfo, deviceListener->getCanSendDisksByUrl(currentUrl.toLocalFile()).values()) { + //fix:临时获取光盘刻录前临时的缓存地址路径,便于以后直接获取使用 id="/dev/sr1" -> tempId="sr1" + QString tempId = pDeviceinfo->getDiskInfo().id().mid(5); + DUrl gvfsmpurl; + gvfsmpurl.setScheme(DFMROOT_SCHEME); + gvfsmpurl.setPath("/" + QUrl::toPercentEncoding(tempId) + "." SUFFIX_UDISKS); + + DAbstractFileInfoPointer fp(new DFMRootFileInfo(gvfsmpurl)); // 通过DFMRootFileInfo 拿到与桌面显示一致的 名字 + + qDebug() << "add send action: [ diskinfoname:" << pDeviceinfo->getDiskInfo().name() << " to RootFileInfo: " << fp->fileDisplayName(); + + QAction *action = new QAction(fp->fileDisplayName(), sendToMountedRemovableDiskMenu); + action->setProperty("mounted_root_uri", pDeviceinfo->getDiskInfo().mounted_root_uri()); + action->setProperty("urlList", DUrl::toStringList(urls)); + action->setProperty("blkDevice", tempId); + + // 禁用发送到列表中的本设备项 + if (urls.count() > 0) { + DUrl durl = urls[0]; + if (durl.path().contains(pDeviceinfo->getDiskInfo().id())) + action->setEnabled(false); + } + + sendToMountedRemovableDiskMenu->addAction(action); + connect(action, &QAction::triggered, appController, &AppController::actionSendToRemovableDisk, Qt::QueuedConnection); //改为队列,防止exec无法退出,关联bug#25613 + } + // 如果子菜单中没有内容,移除父菜单 + if(sendToMountedRemovableDiskMenu->actions().count() < 1) { + menu->removeAction(sendToMountedRemovableDiskAction); + } + } + + } + } + if (QAction *stageAction = menu->actionAt(DFileMenuManager::getActionString(DFMGlobal::StageFileForBurning))) { + + QMap diskUrlsMap; + QStringList odrv; + DDiskManager diskm; + for (auto &blks : diskm.blockDevices({})) { + QScopedPointer blk(DDiskManager::createBlockDevice(blks)); + QScopedPointer drv(DDiskManager::createDiskDevice(blk->drive())); + if (drv->mediaCompatibility().join(' ').contains("_r")) { + if ((currentUrl.scheme() == BURN_SCHEME && QString(blk->device()) == currentUrl.burnDestDevice()) || odrv.contains(drv->path()) + || (currentUrl.scheme() == SEARCH_SCHEME && currentUrl.query().contains("/dev/sr"))) { // 禁用光盘搜索列表中的“添加到光盘刻录”选项 + continue; + } + DUrl rootUrl(DFMROOT_ROOT + QString(blk->device()).mid(QString("/dev/").length()) + ".localdisk"); + odrv.push_back(drv->path()); + diskUrlsMap[drv->path()] = rootUrl; + } + } + + if (odrv.empty()) { + stageAction->setEnabled(false); + } else if (odrv.size() == 1) { + QScopedPointer dev(DDiskManager::createDiskDevice(odrv.front())); + QString devID = dev->id(); + stageAction->setProperty("dest_drive", odrv.front()); + stageAction->setProperty("urlList", DUrl::toStringList(urls)); + connect(stageAction, &QAction::triggered, appController, &AppController::actionStageFileForBurning, Qt::UniqueConnection); + if (DFileMenu *stageMenu = qobject_cast(stageAction->menu())) { + stageAction->setMenu(nullptr); + delete stageMenu; + } + } else { + if (DFileMenu *stageMenu = qobject_cast(stageAction->menu())) { + for (auto &devs : odrv) { + QScopedPointer dev(DDiskManager::createDiskDevice(devs)); + //右键菜单 发送文件到光驱 选项需要展示光驱目录的displayName + DAbstractFileInfoPointer fi; + QString devName(dev->id()); + if (diskUrlsMap.contains(devs)) { + fi = fileService->createFileInfo(nullptr, diskUrlsMap[devs]); + if (fi) { + if (!fi->fileDisplayName().isEmpty()) { + devName = fi->fileDisplayName(); + } + } + } + QAction *action = new QAction(devName, stageMenu); + action->setProperty("dest_drive", devs); + action->setProperty("urlList", DUrl::toStringList(urls)); + stageMenu->addAction(action); + connect(action, &QAction::triggered, appController, &AppController::actionStageFileForBurning, Qt::UniqueConnection); + } + } + } + } + + if (currentUrl == DesktopFileInfo::computerDesktopFileUrl() + || currentUrl == DesktopFileInfo::trashDesktopFileUrl() + || currentUrl == DesktopFileInfo::homeDesktopFileUrl()) { + return menu; + } + // 保险箱不需要其它非文管的插件菜单 + if(!VaultController::isVaultFile(currentUrl.toLocalFile())) { + loadNormalPluginMenu(menu, urls, currentUrl, onDesktop); + } + // stop loading Extension menus from json files + //loadNormalExtensionMenu(menu, urlList, currentUrl); + + return menu; +} + +DFileMenu *DFileMenuManager::createVaultMenu(QWidget *topWidget, const QObject *sender) +{ + DFileMenu *menu = nullptr; + + DFileManagerWindow *wnd = qobject_cast(topWidget); + VaultController *controller = VaultController::ins(); + + VaultController::VaultState vaultState = controller->state(); + + DUrl durl = controller->vaultToLocalUrl(controller->makeVaultUrl()); + durl.setScheme(DFMVAULT_SCHEME); + const DAbstractFileInfoPointer infoPointer = DFileService::instance()->createFileInfo(nullptr, durl); + + QSet disableList; + if (!VaultLockManager::getInstance().isValid()) { + disableList << MenuAction::FiveMinutes + << MenuAction::TenMinutes + << MenuAction::TwentyMinutes; + } + + menu = DFileMenuManager::genereteMenuByKeys(infoPointer->menuActionList(), disableList, true, infoPointer->subMenuActionList(), false); + menu->setEventData(DUrl(), {durl}, WindowManager::getWindowId(wnd), sender); + menu->setAccessibleInfo(AC_FILE_MENU_VAULT); + + auto lockNow = [](DFileManagerWindow * wnd)->bool { + //! Is there a vault task, top it if exist. + if (!VaultHelper::topVaultTasks()) + { + emit fileSignalManager->requestCloseAllTabOfVault(wnd->windowId()); + VaultController::ins()->lockVault(); + } + + return true; + }; + + auto autoLock = [](int lockState)->bool { + return VaultLockManager::getInstance().autoLock(static_cast(lockState)); + }; + + auto showView = [&](QWidget * wndPtr, QString host) { + DFileManagerWindow *file_mng_wnd = qobject_cast(wndPtr); + file_mng_wnd->cd(VaultController::makeVaultUrl("/", host)); + }; + + if (vaultState == VaultController::Unlocked) { + + //! 立即上锁 + QAction *action = DFileMenuManager::getAction(MenuAction::LockNow); + QObject::connect(action, &QAction::triggered, action, [ &, wnd]() { + lockNow(wnd); + }); + + //! 自动上锁 + VaultLockManager::AutoLockState lockState = VaultLockManager::getInstance().autoLockState(); + + QAction *actionNever = DFileMenuManager::getAction(MenuAction::Never); + QObject::connect(actionNever, &QAction::triggered, actionNever, [&]() { + autoLock(VaultLockManager::Never); + }); + actionNever->setCheckable(true); + actionNever->setChecked(lockState == VaultLockManager::Never ? true : false); + + QAction *actionFiveMins = DFileMenuManager::getAction(MenuAction::FiveMinutes); + QObject::connect(actionFiveMins, &QAction::triggered, actionFiveMins, [&]() { + autoLock(VaultLockManager::FiveMinutes); + }); + actionFiveMins->setCheckable(true); + actionFiveMins->setChecked(lockState == VaultLockManager::FiveMinutes ? true : false); + + QAction *actionTenMins = DFileMenuManager::getAction(MenuAction::TenMinutes); + QObject::connect(actionTenMins, &QAction::triggered, actionTenMins, [&]() { + autoLock(VaultLockManager::TenMinutes); + }); + actionTenMins->setCheckable(true); + actionTenMins->setChecked(lockState == VaultLockManager::TenMinutes ? true : false); + + QAction *actionTwentyMins = DFileMenuManager::getAction(MenuAction::TwentyMinutes); + QObject::connect(actionTwentyMins, &QAction::triggered, actionTwentyMins, [&]() { + autoLock(VaultLockManager::TwentyMinutes); + }); + actionTwentyMins->setCheckable(true); + actionTwentyMins->setChecked(lockState == VaultLockManager::TwentyMinutes ? true : false); + + //! 删除保险柜 + action = DFileMenuManager::getAction(MenuAction::DeleteVault); + QObject::connect(action, &QAction::triggered, action, [ &, topWidget]() { + showView(topWidget, "delete"); + }); + } else if (vaultState == VaultController::Encrypted) { + + //! 解锁 + QAction *action = DFileMenuManager::getAction(MenuAction::UnLock); + QObject::connect(action, &QAction::triggered, action, [ &, topWidget]() { + showView(topWidget, "unlock"); + }); + + //! 使用恢复凭证 + action = DFileMenuManager::getAction(MenuAction::UnLockByKey); + QObject::connect(action, &QAction::triggered, action, [ &, topWidget]() { + showView(topWidget, "certificate"); + }); + } + + return menu; +} + +QList DFileMenuManager::loadNormalPluginMenu(DFileMenu *menu, const DUrlList &urlList, const DUrl ¤tUrl, bool onDesktop) +{ + qDebug() << "load normal plugin menu"; + QStringList files; + foreach (DUrl url, urlList) { + files << url.toString(); + } + + // 对menu->actions()增加判空,避免ut崩溃(临时方案,后续需要结合该函数的使用情况完成为空情况的处理) + QList actions; + if (menu->actions().isEmpty()) + return actions; + + QAction *lastAction = menu->actions().last(); + if (lastAction->isSeparator()) { + lastAction = menu->actionAt(menu->actions().count() - 2); + } + + if (DFileMenuData::additionalMenu) { + actions = DFileMenuData::additionalMenu->actions(files, currentUrl.toString(), onDesktop); + } + foreach (QAction *action, actions) { + menu->insertAction(lastAction, action); + } + + menu->insertSeparator(lastAction); + return actions; +} + +QList DFileMenuManager::loadEmptyAreaPluginMenu(DFileMenu *menu, const DUrl ¤tUrl, bool onDesktop) +{ + qDebug() << "load empty area plugin menu"; + QList actions; + // 对menu->actions()增加为空判断(临时方案,后续需要结合该函数的使用情况完成为空情况的处理) + if (menu->actions().isEmpty()) + return actions; + QAction *lastAction = menu->actions().last(); + if (lastAction->isSeparator()) { + lastAction = menu->actionAt(menu->actions().count() - 2); + } + + if (DFileMenuData::additionalMenu) { + actions = DFileMenuData::additionalMenu->actions({}, currentUrl.toString(), onDesktop); + } + + for (QAction *action : actions) { + menu->insertAction(lastAction, action); + } + + menu->insertSeparator(lastAction); + return actions; +} + +QAction *DFileMenuManager::getAction(MenuAction action) +{ + return DFileMenuData::actions.value(action); +} + +QString DFileMenuManager::getActionText(MenuAction action) +{ + return DFileMenuData::actionKeys.value(action); +} + +QSet DFileMenuManager::getDisableActionList(const DUrl &fileUrl) +{ + DUrlList list; + + list << fileUrl; + + return getDisableActionList(list); +} + +QSet DFileMenuManager::getDisableActionList(const DUrlList &urlList) +{ + QSet disableList; + + for (const DUrl &file_url : urlList) { + DUrl durl = file_url; + if (VaultController::isVaultFile(durl.path())) { + durl = VaultController::localUrlToVault(file_url); + } + const DAbstractFileInfoPointer &file_info = fileService->createFileInfo(Q_NULLPTR, durl); + + if (file_info) { + disableList += file_info->disableMenuActionList(); + } + } + + if (DFMGlobal::instance()->clipboardAction() == DFMGlobal::UnknowAction) { + disableList << MenuAction::Paste; + } + + return disableList; +} + +DFileMenuManager::DFileMenuManager() +{ + qRegisterMetaType>(QT_STRINGIFY(QMap)); + qRegisterMetaType>(QT_STRINGIFY(QList)); +} + +DFileMenuManager::~DFileMenuManager() +{ + if (DFileMenuData::additionalMenu) { + DFileMenuData::additionalMenu->deleteLater(); + DFileMenuData::additionalMenu = nullptr; + } + + if (DFileMenuData::customMenuParser) { + DFileMenuData::customMenuParser->deleteLater(); + DFileMenuData::customMenuParser = nullptr; + } +} + +void DFileMenuData::initData() +{ + actionKeys[MenuAction::Open] = QObject::tr("Open"); + actionKeys[MenuAction::OpenInNewWindow] = QObject::tr("Open in new window"); + actionKeys[MenuAction::OpenInNewTab] = QObject::tr("Open in new tab"); + actionKeys[MenuAction::OpenDisk] = QObject::tr("Open"); + actionKeys[MenuAction::OpenDiskInNewWindow] = QObject::tr("Open in new window"); + actionKeys[MenuAction::OpenDiskInNewTab] = QObject::tr("Open in new tab"); + actionKeys[MenuAction::OpenAsAdmin] = QObject::tr("Open as administrator"); + actionKeys[MenuAction::OpenWith] = QObject::tr("Open with"); + actionKeys[MenuAction::OpenWithCustom] = QObject::tr("Select default program"); + actionKeys[MenuAction::OpenFileLocation] = QObject::tr("Open file location"); + actionKeys[MenuAction::Compress] = QObject::tr("Compress"); + actionKeys[MenuAction::Decompress] = QObject::tr("Extract"); + actionKeys[MenuAction::DecompressHere] = QObject::tr("Extract here"); + actionKeys[MenuAction::Cut] = QObject::tr("Cut"); + actionKeys[MenuAction::Copy] = QObject::tr("Copy"); + actionKeys[MenuAction::Paste] = QObject::tr("Paste"); + actionKeys[MenuAction::Rename] = QObject::tr("Rename"); + actionKeys[MenuAction::BookmarkRename] = QObject::tr("Rename"); + actionKeys[MenuAction::BookmarkRemove] = QObject::tr("Remove bookmark"); + actionKeys[MenuAction::CreateSymlink] = QObject::tr("Create link"); + actionKeys[MenuAction::SendToDesktop] = QObject::tr("Send to desktop"); + actionKeys[MenuAction::SendToRemovableDisk] = QObject::tr("Send to"); + actionKeys[MenuAction::SendToBluetooth] = QObject::tr("Bluetooth"); + actionKeys[MenuAction::AddToBookMark] = QObject::tr("Add to bookmark"); + actionKeys[MenuAction::Delete] = QObject::tr("Delete"); + actionKeys[MenuAction::CompleteDeletion] = QObject::tr("Delete"); + actionKeys[MenuAction::Property] = QObject::tr("Properties"); + + actionKeys[MenuAction::NewFolder] = QObject::tr("New folder"); + actionKeys[MenuAction::NewWindow] = QObject::tr("New window"); + actionKeys[MenuAction::SelectAll] = QObject::tr("Select all"); + actionKeys[MenuAction::ClearRecent] = QObject::tr("Clear recent history"); + actionKeys[MenuAction::ClearTrash] = QObject::tr("Empty Trash"); + actionKeys[MenuAction::DisplayAs] = QObject::tr("Display as"); + actionKeys[MenuAction::SortBy] = QObject::tr("Sort by"); + actionKeys[MenuAction::NewDocument] = QObject::tr("New document"); + actionKeys[MenuAction::NewWord] = QObject::tr("Office Text"); + actionKeys[MenuAction::NewExcel] = QObject::tr("Spreadsheets"); + actionKeys[MenuAction::NewPowerpoint] = QObject::tr("Presentation"); + actionKeys[MenuAction::NewText] = QObject::tr("Plain Text"); + actionKeys[MenuAction::OpenInTerminal] = QObject::tr("Open in terminal"); + actionKeys[MenuAction::Restore] = QObject::tr("Restore"); + actionKeys[MenuAction::RestoreAll] = QObject::tr("Restore all"); + actionKeys[MenuAction::Mount] = QObject::tr("Mount"); + actionKeys[MenuAction::Unmount] = QObject::tr("Unmount"); + actionKeys[MenuAction::Eject] = QObject::tr("Eject"); + actionKeys[MenuAction::SafelyRemoveDrive] = QObject::tr("Safely Remove"); + actionKeys[MenuAction::RemoveFromRecent] = QObject::tr("Remove"); + actionKeys[MenuAction::Name] = QObject::tr("Name"); + actionKeys[MenuAction::Size] = QObject::tr("Size"); + actionKeys[MenuAction::Type] = QObject::tr("Type"); + actionKeys[MenuAction::CreatedDate] = QObject::tr("Time created"); + actionKeys[MenuAction::LastModifiedDate] = QObject::tr("Time modified"); + actionKeys[MenuAction::LastRead] = qApp->translate("DFileSystemModel", "Last access"); + actionKeys[MenuAction::Settings] = QObject::tr("Settings"); + actionKeys[MenuAction::Exit] = QObject::tr("Exit"); + actionKeys[MenuAction::IconView] = QObject::tr("Icon"); + actionKeys[MenuAction::ListView] = QObject::tr("List"); + actionKeys[MenuAction::ExtendView] = QObject::tr("Extend"); + actionKeys[MenuAction::SetAsWallpaper] = QObject::tr("Set as wallpaper"); + actionKeys[MenuAction::ForgetPassword] = QObject::tr("Clear saved password and unmount"); + actionKeys[MenuAction::DeletionDate] = QObject::tr("Time deleted"); + actionKeys[MenuAction::SourcePath] = QObject::tr("Source path"); + actionKeys[MenuAction::AbsolutePath] = QObject::tr("Path"); + actionKeys[MenuAction::Share] = QObject::tr("Share folder"); + actionKeys[MenuAction::UnShare] = QObject::tr("Cancel sharing"); + actionKeys[MenuAction::Vault] = QObject::tr("File Vault"); + actionKeys[MenuAction::ConnectToServer] = QObject::tr("Connect to Server"); + actionKeys[MenuAction::SetUserSharePassword] = QObject::tr("Set share password"); + actionKeys[MenuAction::FormatDevice] = QObject::tr("Format"); + actionKeys[MenuAction::OpticalBlank] = QObject::tr("Erase"); + + ///###: tag protocol. + actionKeys[MenuAction::TagInfo] = QObject::tr("Tag information"); + actionKeys[MenuAction::TagFilesUseColor] = QString{"Add color tags"}; + actionKeys[MenuAction::DeleteTags] = QObject::tr("Delete"); + actionKeys[MenuAction::ChangeTagColor] = QString{"Change color of present tag"}; + actionKeys[MenuAction::RenameTag] = QObject::tr("Rename"); + + actionKeys[MenuAction::MountImage] = QObject::tr("Mount"); + //fix: 调整右键菜单中的"刻录"为"添加至光盘刻录" + //actionKeys[MenuAction::StageFileForBurning] = QObject::tr("Burn"); + actionKeys[MenuAction::StageFileForBurning] = QObject::tr("Add to disc"); + + // Vault + actionKeys[MenuAction::LockNow] = QObject::tr("Lock"); + actionKeys[MenuAction::AutoLock] = QObject::tr("Auto lock"); + actionKeys[MenuAction::Never] = QObject::tr("Never"); + actionKeys[MenuAction::FiveMinutes] = QObject::tr("5 minutes"); + actionKeys[MenuAction::TenMinutes] = QObject::tr("10 minutes"); + actionKeys[MenuAction::TwentyMinutes] = QObject::tr("20 minutes"); + actionKeys[MenuAction::DeleteVault] = QObject::tr("Delete File Vault"); + actionKeys[MenuAction::UnLock] = QObject::tr("Unlock"); + actionKeys[MenuAction::UnLockByKey] = QObject::tr("Unlock by key"); + + // Action Icons: + DGioSettings settings("com.deepin.dde.filemanager.general", "/com/deepin/dde/filemanager/general/"); + if (settings.value("context-menu-icons").toBool()) { + actionIcons[MenuAction::NewFolder] = QIcon::fromTheme("folder-new"); + actionIcons[MenuAction::NewDocument] = QIcon::fromTheme("document-new"); + actionIcons[MenuAction::OpenInNewWindow] = QIcon::fromTheme("window-new"); + actionIcons[MenuAction::OpenInNewTab] = QIcon::fromTheme("tab-new"); + actionIcons[MenuAction::OpenInTerminal] = QIcon::fromTheme("utilities-terminal"); + actionIcons[MenuAction::AddToBookMark] = QIcon::fromTheme("bookmark-new"); + actionIcons[MenuAction::BookmarkRemove] = QIcon::fromTheme("bookmark-remove"); + actionIcons[MenuAction::Copy] = QIcon::fromTheme("edit-copy"); + actionIcons[MenuAction::Paste] = QIcon::fromTheme("edit-paste"); + actionIcons[MenuAction::Cut] = QIcon::fromTheme("edit-cut"); + actionIcons[MenuAction::Rename] = QIcon::fromTheme("edit-rename"); + actionIcons[MenuAction::Delete] = QIcon::fromTheme("edit-delete"); + actionIcons[MenuAction::CompleteDeletion] = QIcon::fromTheme("edit-delete-shred"); + actionIcons[MenuAction::Share] = QIcon::fromTheme("document-share"); + actionIcons[MenuAction::SelectAll] = QIcon::fromTheme("edit-select-all"); + actionIcons[MenuAction::CreateSymlink] = QIcon::fromTheme("insert-link"); + actionIcons[MenuAction::Property] = QIcon::fromTheme("document-properties"); + } + + actionKeys[MenuAction::RemoveStashedRemoteConn] = QObject::tr("Remove"); + actionKeys[MenuAction::RefreshView] = QObject::tr("Refresh"); +} + +void DFileMenuData::initActions() +{ + QList unCachedActions; + unCachedActions << MenuAction::NewWindow << MenuAction::RefreshView; + foreach (MenuAction key, actionKeys.keys()) { + if (unCachedActions.contains(key)) { + continue; + } + + ///###: MenuAction::TagFilesUseColor represents the button for tagging files. + ///###: MenuAction::ChangeTagColor represents that you change the color of a present tag. + ///###: They are different event. + if (key == MenuAction::TagFilesUseColor || key == MenuAction::ChangeTagColor) { +//为了解决在自动整理模式下,选择多个文件发送到一个没有空间的光驱上,在桌面上打开任意文件, +//弹出很多文件的窗口并且右键菜单颜色标记出现英文问题。临时方案 +//将里面color相关的代码到外面初始化时重新加载 +// DTagActionWidget *tagWidget{ new DTagActionWidget }; +// QWidgetAction *tagAction{ new QWidgetAction{ nullptr } }; + +// tagAction->setDefaultWidget(tagWidget); + +// switch (key) { +// case MenuAction::TagFilesUseColor: { +// tagAction->setText("Add color tags"); +// break; +// } +// case MenuAction::ChangeTagColor: { +// tagAction->setText("Change color of present tag"); +// tagWidget->setExclusive(true); +// tagWidget->setToolTipVisible(false); +// break; +// } +// default: +// break; +// } + +// tagAction->setData(key); +// actions.insert(key, tagAction); +// actionToMenuAction.insert(tagAction, key); + continue; + } + + QAction *action = new QAction(actionIcons.value(key), actionKeys.value(key), nullptr); + action->setData(key); + actions.insert(key, action); + actionToMenuAction.insert(action, key); + } + + additionalMenu = new DFMAdditionalMenu(); +} + +/** + * @brief 谨慎调用!!! 该函数用于ut清理action用, 其它地方调用后果自负 + * @param + * @return + */ +void DFileMenuData::clearActions() +{ + for (const auto &menu : actions.keys()) { + QAction *action = actions.take(menu); + actionToMenuAction.remove(action); + delete action; + } + actions.clear(); + actionToMenuAction.clear(); +} + +bool DFileMenuManager::needDeleteAction() +{ + return false; +} + +DFileMenu *DFileMenuManager::genereteMenuByKeys(const QVector &keys, + const QSet &disableList, + bool checkable, + const QMap > &subMenuList, bool isUseCachedAction, bool isRecursiveCall) +{ + static bool actions_initialized = false; + + if (!actions_initialized) { + actions_initialized = true; + DFileMenuData::initData(); + DFileMenuData::initActions(); + } + + if (!isUseCachedAction) { + foreach (MenuAction actionKey, keys) { + QAction *action = DFileMenuData::actions.take(actionKey); + + if (action) { + DFileMenuData::actionToMenuAction.remove(action); + } + if (needDeleteAction()) + delete action; + } + } + + DFileMenu *menu = new DFileMenu(); + + if (!isRecursiveCall) { + connect(menu, &DFileMenu::triggered, fileMenuManger, &DFileMenuManager::actionTriggered); + } + + foreach (MenuAction key, keys) { + if (!isAvailableAction(key)) { + continue; + } + /****************************************************************************/ + //为了解决在自动整理模式下,选择多个文件发送到一个没有空间的光驱上,在桌面上打开任意文件, + //弹出很多文件的窗口并且右键菜单颜色标记出现英文问题。临时方案 + //将里面color相关的代码到外面初始化时重新加载 + if (key == MenuAction::TagFilesUseColor || key == MenuAction::ChangeTagColor) { + DTagActionWidget *tagWidget{ new DTagActionWidget }; + QWidgetAction *tagAction{ new QWidgetAction{ nullptr } }; + + tagAction->setDefaultWidget(tagWidget); + + switch (key) { + case MenuAction::TagFilesUseColor: { + tagAction->setText("Add color tags"); + break; + } + case MenuAction::ChangeTagColor: { + tagAction->setText("Change color of present tag"); + tagWidget->setExclusive(true); + tagWidget->setToolTipVisible(false); + break; + } + default: + break; + } + + tagAction->setData(key); + auto keyAction = DFileMenuData::actions.take(key); + if (keyAction) { + QWidgetAction *widAction = dynamic_cast(keyAction); + if (widAction && widAction->defaultWidget()) { + widAction->defaultWidget()->deleteLater(); + } + + DFileMenuData::actionToMenuAction.remove(keyAction); + keyAction->deleteLater(); + } + DFileMenuData::actions.insert(key, tagAction); + DFileMenuData::actionToMenuAction.insert(tagAction, key); + } + /****************************************************************************/ + if (key == MenuAction::Separator) { + menu->addSeparator(); + } else { + QAction *action = DFileMenuData::actions.value(key); + + if (!action) { + action = new QAction(DFileMenuData::actionKeys.value(key), nullptr); + action->setData(key); + DFileMenuData::actions[key] = action; + DFileMenuData::actionToMenuAction[action] = key; + } + + action->setDisabled(disableList.contains(key)); + action->setProperty("_dfm_menu", QVariant::fromValue(menu)); + + menu->addAction(action); + + if (!subMenuList.contains(key)) { + continue; + } + + DFileMenu *subMenu = genereteMenuByKeys(subMenuList.value(key), disableList, checkable, QMap >(), true, true); + + subMenu->QObject::setParent(menu); + action->setMenu(subMenu); + } + } + + return menu; +} + +QString DFileMenuManager::getActionString(MenuAction type) +{ + return DFileMenuData::actionKeys.value(type); +} + +//创建自定义菜单 +void DFileMenuManager::extendCustomMenu(DFileMenu *menu, bool isNormal, const DUrl &dir, const DUrl &focusFile, const DUrlList &selected, bool onDesktop) +{ + if (!DFileMenuData::customMenuParser) { + DFileMenuData::customMenuParser = new DCustomActionParser; + } + + const QList &rootEntry = DFileMenuData::customMenuParser->getActionFiles(onDesktop); + qDebug() << "extendCustomMenu " << isNormal << dir << focusFile << "files" << selected.size() << "entrys" << rootEntry.size(); + + if (menu == nullptr || rootEntry.isEmpty()) + return; + + DCustomActionBuilder builder; + //呼出菜单的文件夹 + builder.setActiveDir(dir); + + //获取文件列表的组合 + DCustomActionDefines::ComboType fileCombo = DCustomActionDefines::BlankSpace; + if (isNormal) { + fileCombo = builder.checkFileCombo(selected); + if (fileCombo == DCustomActionDefines::BlankSpace) + return; + + //右键单击作用的文件 + builder.setFocusFile(focusFile); + } + + //获取支持的菜单项 + auto usedEntrys = builder.matchFileCombo(rootEntry, fileCombo); + + //匹配类型支持 + usedEntrys = builder.matchActions(selected, usedEntrys); + qDebug() << "selected combo" << fileCombo << "entry count" << usedEntrys.size(); + + if (usedEntrys.isEmpty()) + return; + + //添加菜单响应所需的数据 + { + QVariant var; + var.setValue(dir); + menu->setProperty(DCustomActionDefines::kCustomActionDataDir, var); + + var.setValue(focusFile); + menu->setProperty(DCustomActionDefines::kCustomActionDataFoucsFile, var); + + var.setValue(selected); + menu->setProperty(DCustomActionDefines::kCustomActionDataSelectedFiles, var); + } + + //开启tooltips + menu->setToolTipsVisible(true); + + //移除所有菜单项 + auto systemActions = menu->actions(); + for (auto it = systemActions.begin(); it != systemActions.end(); ++it) + menu->removeAction(*it); + Q_ASSERT(menu->actions().isEmpty()); + + QMap> locate; + QMap actionsSeparator; + //根据配置信息创建菜单项 + for (auto it = usedEntrys.begin(); it != usedEntrys.end(); ++it) { + const DCustomActionData &actionData = it->data(); + auto *action = builder.buildAciton(actionData, menu); + if (action == nullptr) + continue; + + //自动释放 + action->setParent(menu); + + //记录分隔线 + if (actionData.separator() != DCustomActionDefines::None) + actionsSeparator.insert(action, actionData.separator()); + + //根据组合类型获取插入位置 + auto pos = actionData.position(fileCombo); + + //位置是否有效 + if (pos > 0) { + auto temp = locate.find(pos); + if (temp == locate.end()) { + locate.insert(pos, {action}); + } + else { //位置冲突,往后放 + temp->append(action); + } + } + else { //没有配置位置,则直接添加 + systemActions.append(action); + } + } + + //开始按顺序插入菜单 + DCustomActionDefines::sortFunc(locate, systemActions, [menu](const QList &acs){ + menu->addActions(acs); + },[](QAction *ac) ->bool { + return ac && !ac->isSeparator(); + }); + + Q_ASSERT(systemActions.isEmpty()); + + //插入分隔线 + for (auto it = actionsSeparator.begin(); it != actionsSeparator.end(); ++it) { + //上分割线 + if (it.value() & DCustomActionDefines::Top) { + menu->insertSeparator(it.key()); + } + + //下分割线 + if ((it.value() & DCustomActionDefines::Bottom)) { + const QList &actionList = menu->actions(); + int nextIndex = actionList.indexOf(it.key()) + 1; + + //后一个action + if (nextIndex < actionList.size()) { + auto nextAction = menu->actionAt(nextIndex); + + //不是分割线则插入 + if (!nextAction->isSeparator()) { + menu->insertSeparator(nextAction); + } + } + } + + } +} + +/* + * 自定义菜单在以下作用域时支持: + * U盘盘内文件、移动硬盘盘内文件、桌面 + * + * 自定义菜单在以下作用域时不支持: + * 光盘盘内文件、回收站入口、回收站目录内、搜索框内、 + * 搜索结果列表页、文件管理器计算机主页面左侧导航全部菜单项、 + * 文件管理器计算机主页面我的目录及分区、保险箱入口、保险箱路径 + */ +bool DFileMenuManager::isCustomMenuSupported(const DUrl &viewRootUrl) +{ + const QString &path = viewRootUrl.toLocalFile(); + //U盘、硬盘支持显示 + if (deviceListener->isBlockFile(path)) + return true; + + DStorageInfo st(path); + return st.isLocalDevice() //过滤 手机 网络 smb ftp + && !viewRootUrl.isUserShareFile() //过滤共享文件 + && !deviceListener->isFileFromDisc(path) //过滤光盘 + && !viewRootUrl.isVaultFile() //过滤保险箱 + && !viewRootUrl.isTrashFile();//过滤回收站 + +} + +void DFileMenuManager::addActionWhitelist(MenuAction action) +{ + DFileMenuData::whitelist << action; +} + +void DFileMenuManager::setActionWhitelist(const QSet &actionList) +{ + DFileMenuData::whitelist = actionList; +} + +QSet DFileMenuManager::actionWhitelist() +{ + return DFileMenuData::whitelist; +} + +void DFileMenuManager::addActionBlacklist(MenuAction action) +{ + DFileMenuData::blacklist << action; +} + +void DFileMenuManager::setActionBlacklist(const QSet &actionList) +{ + DFileMenuData::blacklist = actionList; +} + +QSet DFileMenuManager::actionBlacklist() +{ + return DFileMenuData::blacklist; +} + +bool DFileMenuManager::isAvailableAction(MenuAction action) +{ + const QString &group_name = QStringLiteral("MenuActions"); + + // init menu action black list + const QMetaEnum &action_enum = QMetaEnum::fromType(); + + for (const QString &action_name : DFMApplication::genericObtuselySetting()->value(group_name, "disable").toStringList()) { + bool ok = false; + int key = action_enum.keyToValue(action_name.toUtf8(), &ok); + + if (ok && key == action) { + return false; + } + } + + if (DFileMenuData::whitelist.isEmpty()) { + return !DFileMenuData::blacklist.contains(action); + } + + return DFileMenuData::whitelist.contains(action) && !DFileMenuData::blacklist.contains(action); +} + +void DFileMenuManager::setActionString(MenuAction type, QString actionString) +{ + DFileMenuData::actionKeys.insert(type, actionString); + + QAction *action = new QAction(actionString, nullptr); + action->setData(type); + DFileMenuData::actions.insert(type, action); + DFileMenuData::actionToMenuAction[action] = type; +} + +void DFileMenuManager::setActionID(MenuAction type, QString id) +{ + DFileMenuData::actionIDs.insert(type, id); +} + +MenuAction DFileMenuManager::registerMenuActionType(QAction *action) +{ + Q_ASSERT(action); + + MenuAction type = DFileMenuData::actionToMenuAction.value(action, MenuAction::Unknow); + + if (type >= MenuAction::UserMenuAction) { + return type; + } + + type = DFileMenuData::takeAvailableUserActionType(); + DFileMenuData::actions[type] = action; + DFileMenuData::actionToMenuAction[action] = type; + + QObject::connect(action, &QAction::destroyed, action, [type] { + DFileMenuData::recycleUserActionType(type); + }); + + return type; +} + +bool DFileMenuManager::whetherShowTagActions(const QList &urls) +{ +#ifdef DISABLE_TAG_SUPPORT + return false; +#endif // DISABLE_TAG_SUPPORT + + for (const DUrl &durl : urls) { + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(nullptr, durl); + + if (!info) + return false; + +// bool temp{ DAnythingMonitorFilter::instance()->whetherFilterCurrentPath(info->toLocalFile().toLocal8Bit()) }; + + if (!info->canTag()) { + return false; + } + + //多选文件中包含一下文件时 则不展示标记信息菜单项 + if (info->fileUrl() == DesktopFileInfo::computerDesktopFileUrl() + || info->fileUrl() == DesktopFileInfo::trashDesktopFileUrl() + || info->fileUrl() == DesktopFileInfo::homeDesktopFileUrl()) { + return false; + } + } + + return true; +} + +void DFileMenuManager::clearActions() +{ + DFileMenuData::clearActions(); +} + +void DFileMenuManager::actionTriggered(QAction *action) +{ + qDebug() << action << action->data().isValid(); + DFileMenu *menu = qobject_cast(sender()); + if (!(menu->property("ToolBarSettingsMenu").isValid() && menu->property("ToolBarSettingsMenu").toBool())) { + disconnect(menu, &DFileMenu::triggered, fileMenuManger, &DFileMenuManager::actionTriggered); + } + + //扩展菜单 + if (action->property(DCustomActionDefines::kCustomActionFlag).isValid()) { + QString cmd = action->property(DCustomActionDefines::kCustomActionCommand).toString(); + DCustomActionDefines::ActionArg argFlag = static_cast + (action->property(DCustomActionDefines::kCustomActionCommandArgFlag).toInt()); + DUrl dir = menu->property(DCustomActionDefines::kCustomActionDataDir).value(); + DUrl foucs = menu->property(DCustomActionDefines::kCustomActionDataFoucsFile).value(); + DUrlList selected = menu->property(DCustomActionDefines::kCustomActionDataSelectedFiles).value(); + + qDebug() << "argflag" << argFlag << "dir" << dir << "foucs" << foucs << "selected" << selected; + qInfo() << "extend" << action->text() << cmd; + + QPair runable = DCustomActionBuilder::makeCommand(cmd,argFlag,dir,foucs,selected); + qInfo () << "exec:" << runable.first << runable.second; + + if (!runable.first.isEmpty()) + FileUtils::runCommand(runable.first, runable.second); + return; + } + + if (action->data().isValid()) { + bool flag = false; + int _type = action->data().toInt(&flag); + MenuAction type; + if (flag) { + type = (MenuAction)_type; + } else { + qDebug() << action->data().toString();; + return; + } + + if (type >= MenuAction::UserMenuAction) { + return; + } + + if (menu->ignoreMenuActions().contains(type)) { + return; + } + + QAction *typeAction = DFileMenuData::actions.value(type); + qDebug() << typeAction << action; + if (typeAction) { + qDebug() << typeAction->text() << action->text(); + if (typeAction->text() == action->text()) { + const QSharedPointer &event = menu->makeEvent(type); + + // fix bug 39754 【sp3专业版】【文件管理器】【5.2.0.8-1】挂载磁盘右键菜单,拔出挂载磁盘,选择任意右键菜单列表-属性,界面展示大小异常 + // 按照测试期望处理,当 url 构造出来的文件信息不存在的时候,不执行后续的事件处理 + const DUrlList &selUrls = event->selectedUrls(); + if (selUrls.count() > 0) { + const DUrl &u = selUrls.first(); + // fix bug 60949 如果url是网络文件的挂载文件的rootpath,就要解密路径,不解密路径isLowSpeedDevice返回true + // 网络设备不走这个流程 + QString path = u.path(); + if (u.scheme() == DFMROOT_SCHEME && path.endsWith(SUFFIX_GVFSMP)) { + path = QUrl::fromPercentEncoding(u.path().toUtf8()); + path = path.startsWith("//") ? path.mid(1) : path; + } + if (u.isValid() && !DStorageInfo::isLowSpeedDevice(path)) { // 这里只针对非低速设备做判定,否则可能导致正常情况下的右键菜单响应过慢 + DAbstractFileInfoPointer info = fileService->createFileInfo(nullptr, u); + if (info && !info->exists()) + return; + } + } + + //批量标记操作耗时较长,同步事件处理会使menu.exec结束等待时间过长,频繁操作下会引起崩溃 + //右键菜单本身对标记操作没有同步等待结果的需求,所以直接采用异步事件处理标记操作 + if (type == MenuAction::TagFilesUseColor) { + //异步事件处理存在menu对象先被析构的情况,这里将标记所需的数据先取出来放在event中 + //fileeventprocessor中直接从event中取数据 + QAction *action{ menu->actionAt("Add color tags") }; + if (QWidgetAction *widgetAction = qobject_cast(action)) { + if (DTagActionWidget *tagWidget = qobject_cast(widgetAction->defaultWidget())) { + QList colors{ tagWidget->checkedColorList() }; + event->setTagColors(colors); + DFMEventDispatcher::instance()->processEventAsync(event); + } + } + } else { + DFMEventDispatcher::instance()->processEvent(event); + } + } + } + +#ifdef SW_LABEL + if (DFileMenuData::actionIDs.contains(type)) { + const QSharedPointer &menuActionEvent = menu->makeEvent(type); + DFMEvent event; + event.setWindowId(menuActionEvent->windowId()); + event.setData(menuActionEvent->fileUrl()); + QMetaObject::invokeMethod(appController, + "actionByIds", + Qt::DirectConnection, + Q_ARG(DFMEvent, event), Q_ARG(QString, DFileMenuData::actionIDs.value(type))); + } +#endif + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilemenumanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilemenumanager.h new file mode 100644 index 0000000..11352ca --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilemenumanager.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef FILEMENUMANAGER_H +#define FILEMENUMANAGER_H + +#include "dfmglobal.h" + +#include + +#include +#include +#include + +class DFileMenu; +class DUrl; +typedef DFMGlobal::MenuAction MenuAction; +typedef QList DUrlList; + +class DFileMenuManager : public QObject +{ + Q_OBJECT + +public: + //fix:临时获取光盘刻录前临时的缓存地址路径,便于以后直接获取使用 + static QString fmblkDevice; + + DFileMenuManager(); + ~DFileMenuManager(); + + static DFileMenu *createDefaultBookMarkMenu(const QSet &disableList = QSet()); + static DFileMenu *createUserShareMarkMenu(const QSet &disableList = QSet()); + static DFileMenu *createToolBarSettingsMenu(const QSet &disableList = QSet()); + + static DFileMenu *createNormalMenu(const DUrl ¤tUrl, const DUrlList &urlList, QSet disableList, QSet unusedList, int windowId, bool onDesktop); + static DFileMenu *createVaultMenu(QWidget *topWidget, const QObject *sender = nullptr); + + static QList loadNormalPluginMenu(DFileMenu *menu, const DUrlList &urlList, const DUrl ¤tUrl, bool onDesktop); + static QList loadEmptyAreaPluginMenu(DFileMenu *menu, const DUrl ¤tUrl, bool onDesktop); + + static QAction *getAction(MenuAction action); + static QString getActionText(MenuAction action); + + static QSet getDisableActionList(const DUrl &fileUrl); + static QSet getDisableActionList(const DUrlList &urlList); + + static DFileMenu *genereteMenuByKeys(const QVector &keys, + const QSet &disableList, + bool checkable = false, + const QMap > &subMenuList = QMap >(), + bool isUseCachedAction = true, + bool isRecursiveCall = false); + static QString getActionString(MenuAction type); + static bool needDeleteAction(); + + static void extendCustomMenu(DFileMenu *menu, bool isNormal, + const DUrl &dir, + const DUrl &focusFile, + const DUrlList &selected = {}, + bool onDesktop = false); + static bool isCustomMenuSupported(const DUrl &viewRootUrl); + + /// actions filter(global) + static void addActionWhitelist(MenuAction action); + static void setActionWhitelist(const QSet &actionList); + static QSet actionWhitelist(); + static void addActionBlacklist(MenuAction action); + static void setActionBlacklist(const QSet &actionList); + static QSet actionBlacklist(); + static bool isAvailableAction(MenuAction action); + + static QList> ExtensionMenuItems; + + + static void setActionString(MenuAction type, QString actionString); + static void setActionID(MenuAction type, QString id); + + static MenuAction registerMenuActionType(QAction *action); + + static bool whetherShowTagActions(const QList &urls); + + static void clearActions(); + +public slots: + void actionTriggered(QAction *action); +}; + +#endif // FILEMENUMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileproxywatcher.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileproxywatcher.cpp new file mode 100644 index 0000000..cc953e6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileproxywatcher.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfileproxywatcher.h" +#include "private/dabstractfilewatcher_p.h" +#include "controllers/vaultcontroller.h" + +#include + +class DFileProxyWatcherPrivate : public DAbstractFileWatcherPrivate +{ +public: + explicit DFileProxyWatcherPrivate(DFileProxyWatcher *qq) + : DAbstractFileWatcherPrivate(qq) {} + + bool start() override; + bool stop() override; + + QPointer proxy; + std::function urlConvertFun; + + Q_DECLARE_PUBLIC(DFileProxyWatcher) +}; + +bool DFileProxyWatcherPrivate::start() +{ + return proxy && proxy->startWatcher(); +} + +bool DFileProxyWatcherPrivate::stop() +{ + return proxy && proxy->stopWatcher(); +} + +DFileProxyWatcher::DFileProxyWatcher(const DUrl &url, DAbstractFileWatcher *proxy, + std::function urlConvertFun, + QObject *parent) + : DAbstractFileWatcher(*new DFileProxyWatcherPrivate(this), url, parent) +{ + Q_ASSERT(proxy); + Q_ASSERT(urlConvertFun); + Q_ASSERT(!proxy->parent()); + + proxy->moveToThread(thread()); + proxy->setParent(this); + + d_func()->proxy = proxy; + d_func()->urlConvertFun = urlConvertFun; + + connect(proxy, &DAbstractFileWatcher::fileAttributeChanged, this, &DFileProxyWatcher::onFileAttributeChanged); + connect(proxy, &DAbstractFileWatcher::fileDeleted, this, &DFileProxyWatcher::onFileDeleted); + connect(proxy, &DAbstractFileWatcher::fileMoved, this, &DFileProxyWatcher::onFileMoved); + connect(proxy, &DAbstractFileWatcher::subfileCreated, this, &DFileProxyWatcher::onSubfileCreated); + connect(proxy, &DAbstractFileWatcher::fileModified, this, &DFileProxyWatcher::onFileModified); +} + +void DFileProxyWatcher::onFileDeleted(const DUrl &url) +{ + Q_D(const DFileProxyWatcher); + + emit fileDeleted(d->urlConvertFun(url)); +} + +void DFileProxyWatcher::onFileAttributeChanged(const DUrl &url) +{ + Q_D(const DFileProxyWatcher); + + emit fileAttributeChanged(d->urlConvertFun(url)); +} + +void DFileProxyWatcher::onFileMoved(const DUrl &fromUrl, const DUrl &toUrl) +{ + Q_D(const DFileProxyWatcher); + + emit fileMoved(d->urlConvertFun(fromUrl), d->urlConvertFun(toUrl)); +} + +void DFileProxyWatcher::onSubfileCreated(const DUrl &url) +{ + Q_D(const DFileProxyWatcher); + + emit subfileCreated(d->urlConvertFun(url)); +} + +void DFileProxyWatcher::onFileModified(const DUrl &url) +{ + Q_D(const DFileProxyWatcher); + + emit fileModified(d->urlConvertFun(url)); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileproxywatcher.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileproxywatcher.h new file mode 100644 index 0000000..f8f4ca6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileproxywatcher.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILEPROXYWATCHER_H +#define DFILEPROXYWATCHER_H + +#include "dabstractfilewatcher.h" + +#include + +class DFileProxyWatcherPrivate; +class DFileProxyWatcher : public DAbstractFileWatcher +{ +public: + explicit DFileProxyWatcher(const DUrl &url, DAbstractFileWatcher *proxy, + std::function urlConvertFun, + QObject *parent = nullptr); + +private slots: + void onFileDeleted(const DUrl &url); + void onFileAttributeChanged(const DUrl &url); + void onFileMoved(const DUrl &fromUrl, const DUrl &toUrl); + void onSubfileCreated(const DUrl &url); + + /** + * @brief onFileModified 文件修改 + * @param url 文件url + */ + void onFileModified(const DUrl &url); + +private: + Q_DECLARE_PRIVATE(DFileProxyWatcher) +}; + +#endif // DFILEPROXYWATCHER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileservices.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileservices.cpp new file mode 100755 index 0000000..faa9aef --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileservices.cpp @@ -0,0 +1,1334 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfileservices.h" +#include "dabstractfilecontroller.h" +#include "dabstractfileinfo.h" +#include "dabstractfilewatcher.h" +#include "dfmeventdispatcher.h" +#include "dfmfilecontrollerfactory.h" +#include "dfiledevice.h" +#include "dfilehandler.h" +#include "dstorageinfo.h" +#include "dfmapplication.h" + +#include "app/filesignalmanager.h" +#include "dfmevent.h" +#include "app/define.h" +#include "controllers/jobcontroller.h" +#include "controllers/appcontroller.h" +#include "controllers/mergeddesktopcontroller.h" +#include "views/windowmanager.h" +#include "dfileinfo.h" +#include "models/trashfileinfo.h" +#include "models/desktopfileinfo.h" +#include "controllers/pathmanager.h" +#include "controllers/vaultcontroller.h" +#include "dfmstandardpaths.h" +#include "views/windowmanager.h" +#include "models/avfsfileinfo.h" +#include "shutil/fileutils.h" +#include "shutil/filebatchprocess.h" +#include "dialogs/dialogmanager.h" +#include "deviceinfo/udisklistener.h" +#include "interfaces/dfmglobal.h" +#include "singleton.h" +#include "models/dfmrootfileinfo.h" +#include "shutil/checknetwork.h" +#include +#include "execinfo.h" +#include "math.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +DWIDGET_USE_NAMESPACE + +class DFileServicePrivate +{ +public: + + static QMultiHash controllerHash; + static QHash handlerHash; + static QMultiHash controllerCreatorHash; + + bool m_bcursorbusy = false; + bool m_bdoingcleartrash = false; + QHash m_rootsmbftpurllist; + QMutex checkgvfsmtx, smbftpmutex, timerMutex; + QNetworkConfigurationManager *m_networkmgr = nullptr; + + QTimer m_tagEditorChangeTimer; + CheckNetwork m_checknetwork; + DUrlList m_tagEditorFiles; + QStringList m_tagEditorTags; + bool m_isMoveToTrashOver = true; //! 移除事件是否已处理完成,避免嵌套调用 +}; + +QMultiHash DFileServicePrivate::controllerHash; +QHash DFileServicePrivate::handlerHash; +QMultiHash DFileServicePrivate::controllerCreatorHash; + +DFileService::DFileService(QObject *parent) + : QObject(parent) + , d_ptr(new DFileServicePrivate()) +{ + /// init url handler register + AppController::registerUrlHandle(); + // register plugins + for (const QString &key : DFMFileControllerFactory::keys()) { + const QUrl qurl(key); + + insertToCreatorHash(HandlerType(qurl.scheme(), qurl.host()), HandlerCreatorType(typeid(DFMFileControllerFactory).name(), [key] { + return DFMFileControllerFactory::create(key); + })); + } + + d_ptr->m_tagEditorChangeTimer.setSingleShot(true); + connect(&d_ptr->m_tagEditorChangeTimer, &QTimer::timeout, this, [ = ] { + makeTagsOfFiles(nullptr, d_ptr->m_tagEditorFiles, d_ptr->m_tagEditorTags); + }); +} + +DFileService::~DFileService() +{ + d_ptr->m_rootsmbftpurllist.clear(); + //sanitinizer工具检测到dde-file-manager-lib/controllers/appcontroller.cpp中143泄露,故添加 + clearFileUrlHandler(TRASH_SCHEME, ""); +} + +template +QVariant eventProcess(DFileService *service, const QSharedPointer &event, T function) +{ + QSet controller_set; + QSet scheme_set; + + for (const DUrl &durl : event->handleUrlList()) { + QList list = service->getHandlerTypeByUrl(durl); + if (!scheme_set.contains(durl.scheme())) { + list << service->getHandlerTypeByUrl(durl, true); + } else { + scheme_set << durl.scheme(); + } + + for (DAbstractFileController *controller : list) { + if (!controller || controller_set.contains(controller)) { + continue; + } + + controller_set << controller; + + typedef typename std::remove_reference::Arguments::Car>::type::Type DFMEventType; + + const QVariant result = QVariant::fromValue((controller->*function)(event.staticCast())); + + if (event->isAccepted()) { + return result; + } + } + } + + return QVariant(); +} + +bool DFileService::fmEvent(const QSharedPointer &event, QVariant *resultData) +{ +#ifdef DDE_COMPUTER_TRASH + switch (event->type()) { + case DFMEvent::WriteUrlsToClipboard: + case DFMEvent::DeleteFiles: + case DFMEvent::MoveToTrash: { + DUrlList urlList = event->fileUrlList(); + + if (urlList.contains(DesktopFileInfo::computerDesktopFileUrl())) { + DesktopFile df(DesktopFileInfo::computerDesktopFileUrl().toLocalFile()); + if (df.getDeepinId() == "dde-computer") { + urlList.removeOne(DesktopFileInfo::computerDesktopFileUrl()); + } + } + + if (urlList.contains(DesktopFileInfo::trashDesktopFileUrl())) { + DesktopFile df(DesktopFileInfo::trashDesktopFileUrl().toLocalFile()); + if (df.getDeepinId() == "dde-trash") { + urlList.removeOne(DesktopFileInfo::trashDesktopFileUrl()); + } + } + + event->setData(urlList); + break; + } + default: + break; + } +#endif + +#define CALL_CONTROLLER(Fun)\ + eventProcess(this, event, &DAbstractFileController::Fun); + + QVariant result; + + switch (event->type()) { + case DFMEvent::OpenFile: + result = CALL_CONTROLLER(openFile); + + if (result.toBool()) { + emit fileOpened(event->fileUrl()); + } + break; + case DFMEvent::OpenFileByApp: + result = CALL_CONTROLLER(openFileByApp); + + if (result.toBool()) { + emit fileOpened(event->fileUrl()); + } + + break; + case DFMEvent::CompressFiles: + result = CALL_CONTROLLER(compressFiles); + break; + case DFMEvent::DecompressFile: + result = CALL_CONTROLLER(decompressFile); + break; + case DFMEvent::DecompressFileHere: + result = CALL_CONTROLLER(decompressFileHere); + break; + case DFMEvent::WriteUrlsToClipboard: + result = CALL_CONTROLLER(writeFilesToClipboard); + break; + case DFMEvent::RenameFile: { + const QSharedPointer &e = event.staticCast(); + const DAbstractFileInfoPointer &f = createFileInfo(this, e->toUrl()); + if (f && f->exists() && !e->silent()) { + // sp3_fix: 添加文件命名规则 当文件名为..时,弹出提示,文件名不能为.. + QString strFrom = e->fromUrl().toString(); + QString strTo = e->toUrl().toString(); + QString strGrandParent = strFrom.section(QDir::separator(), 0, -3); + if (strTo == strGrandParent) { // 如果目的目录是源目录的父目录的父目录(及目录名为..) + DThreadUtil::runInMainThread(dialogManager, &DialogManager::showRenameNameDotDotErrorDialog, *event.data()); + } else { + DThreadUtil::runInMainThread(dialogManager, &DialogManager::showRenameNameSameErrorDialog, f->fileDisplayName(), *event.data()); + } + result = false; + } else { + result = CALL_CONTROLLER(renameFile); + + if (result.toBool()) { + emit fileRenamed(e->fromUrl(), e->toUrl()); + } else { + DThreadUtil::runInMainThread(dialogManager, &DialogManager::showRenameBusyErrDialog, *event.data()); + } + } + + break; + } + case DFMEvent::DeleteFiles: { + // 解决撤销操作后文件删除不提示问题 + for (const DUrl &durl : event->fileUrlList()) { + //书签保存已删除目录,在这里剔除对书签文件是否存在的判断 + if (durl.scheme() == "bookmark") { + result = CALL_CONTROLLER(deleteFiles); + + if (result.toBool()) { + for (const DUrl &r : event->fileUrlList()) { + emit fileDeleted(r); + } + } + break; + } + + const DAbstractFileInfoPointer &f = createFileInfo(this, durl); + if (f && f->exists()) { + // 如果传入的 event 中 silent 为 true,就不再弹框询问是否删除 + auto delEvent = dynamic_cast(event.data()); + bool deleteFileSilently = delEvent && delEvent->silent(); + if (deleteFileSilently || DThreadUtil::runInMainThread(dialogManager, &DialogManager::showDeleteFilesClearTrashDialog, DFMUrlListBaseEvent(nullptr, event->fileUrlList())) == DDialog::Accepted) { + // 这里已经确认删除了,同次调用走静默删除,避免二次弹窗 + if (delEvent) + delEvent->setProperty(QT_STRINGIFY(DFMDeleteEvent::silent), true); + result = CALL_CONTROLLER(deleteFiles); + if (result.toBool()) { + for (const DUrl &r : event->fileUrlList()) { + emit fileDeleted(r); + } + } + } + + //fix bug 31324,判断当前操作是否是清空回收站,是就在结束时改变清空回收站状态 + if (event->fileUrlList().count() == 1 && event->fileUrlList().first().toString() == TRASH_ROOT) { + setDoClearTrashState(false); + } + + break; + } else { + continue; + } + } + break; + + } + case DFMEvent::MoveToTrash: { + if (event->fileUrlList().isEmpty()) + break; + + //handle system files should not be able to move to trash + foreach (const DUrl &url, event->fileUrlList()) { + if (systemPathManager->isSystemPath(url.toLocalFile())) { + DThreadUtil::runInMainThread(dialogManager, &DialogManager::showDeleteSystemPathWarnDialog, event->windowId()); + result = QVariant::fromValue(event->fileUrlList()); + goto end; + } + } + + d_ptr->m_isMoveToTrashOver = false; + result = CALL_CONTROLLER(moveToTrash); + d_ptr->m_isMoveToTrashOver = true; + + const DUrlList &list = event->fileUrlList(); + const DUrlList new_list = qvariant_cast(result); + + for (int i = 0; i < new_list.count(); ++i) { + if (!new_list.at(i).isValid() || VaultController::isVaultFile(new_list.at(i).path())) + continue; + + emit fileMovedToTrash(list.at(i), new_list.at(i)); + } + + break; + } + case DFMEvent::RestoreFromTrash: { + result = CALL_CONTROLLER(restoreFile); + break; + } + case DFMEvent::PasteFile: { + result = CALL_CONTROLLER(pasteFile); + break; + } + case DFMEvent::Mkdir: + result = CALL_CONTROLLER(mkdir); + break; + case DFMEvent::TouchFile: + result = CALL_CONTROLLER(touch); + break; + case DFMEvent::OpenFileLocation: + result = CALL_CONTROLLER(openFileLocation); + break; + case DFMEvent::AddToBookmark: + result = CALL_CONTROLLER(addToBookmark); + break; + case DFMEvent::RemoveBookmark: + result = CALL_CONTROLLER(removeBookmark); + break; + case DFMEvent::CreateSymlink: + result = CALL_CONTROLLER(createSymlink); + break; + case DFMEvent::FileShare: + result = CALL_CONTROLLER(shareFolder); + break; + case DFMEvent::CancelFileShare: + result = CALL_CONTROLLER(unShareFolder); + break; + case DFMEvent::OpenInTerminal: + result = CALL_CONTROLLER(openInTerminal); + break; + case DFMEvent::GetChildrens: + result = CALL_CONTROLLER(getChildren); + break; + case DFMEvent::CreateFileInfo: + result = CALL_CONTROLLER(createFileInfo); + break; + case DFMEvent::CreateDiriterator: + result = CALL_CONTROLLER(createDirIterator); + break; + case DFMEvent::CreateGetChildrensJob: { + result = CALL_CONTROLLER(createDirIterator); + + const QSharedPointer &e = event.staticCast(); + + if (event->isAccepted()) { + result = QVariant::fromValue(new JobController(e->url(), qvariant_cast(result))); + } else { + result = QVariant::fromValue(new JobController(e->url(), e->nameFilters(), e->filters())); + } + + break; + } + case DFMEvent::CreateFileWatcher: + result = CALL_CONTROLLER(createFileWatcher); + break; + case DFMEvent::CreateFileDevice: + result = CALL_CONTROLLER(createFileDevice); + break; + case DFMEvent::CreateFileHandler: + result = CALL_CONTROLLER(createFileHandler); + break; + case DFMEvent::CreateStorageInfo: + result = CALL_CONTROLLER(createStorageInfo); + break; + case DFMEvent::Tag: { + result = CALL_CONTROLLER(setFileTags); + break; + } + case DFMEvent::Untag: + result = CALL_CONTROLLER(removeTagsOfFile); + break; + case DFMEvent::GetTagsThroughFiles: + result = CALL_CONTROLLER(getTagsThroughFiles); + break; + case DFMEvent::SetFileExtraProperties: + result = CALL_CONTROLLER(setExtraProperties); + break; + case DFMEvent::SetPermission: + result = CALL_CONTROLLER(setPermissions); + break; + case DFMEvent::OpenFiles: + result = CALL_CONTROLLER(openFiles); + if (result.toBool()) { + for (auto durl : event->fileUrlList()) { + emit fileOpened(durl); + } + } + break; + case DFMEvent::OpenFilesByApp: + result = CALL_CONTROLLER(openFilesByApp); + if (result.toBool()) { + for (auto durl : event->fileUrlList()) { + emit fileOpened(durl); + } + } + + break; + default: + return false; + } + +end: + if (resultData) { + *resultData = result; + } + + return true; +} + +bool DFileService::isRegisted(const QString &scheme, const QString &host, const std::type_info &info) +{ + const HandlerType &type = HandlerType(scheme, host); + + foreach (const HandlerCreatorType &value, DFileServicePrivate::controllerCreatorHash.values(type)) { + if (value.first == info.name()) { + return true; + } + } + + foreach (const DAbstractFileController *controller, DFileServicePrivate::controllerHash.values(type)) { + if (typeid(*controller) == info) { + return true; + } + } + + return false; +} + +bool DFileService::isRegisted(const QString &scheme, const QString &host) +{ + const HandlerType &type = HandlerType(scheme, host); + + return !DFileServicePrivate::controllerCreatorHash.values(type).isEmpty() || !DFileServicePrivate::controllerHash.values(type).isEmpty(); +} + +void DFileService::initHandlersByCreators() +{ + QMultiHash::const_iterator begin = DFileServicePrivate::controllerCreatorHash.constBegin(); + + while (begin != DFileServicePrivate::controllerCreatorHash.constEnd()) { + setFileUrlHandler(begin.key().first, begin.key().second, (begin.value().second)()); + ++begin; + } + + DFileServicePrivate::controllerCreatorHash.clear(); +} + +void DFileService::clearController(const QString &scheme, const QString &host) +{ + const HandlerType &type = HandlerType(scheme, host); + auto controllers = DFileServicePrivate::controllerHash.values(type); + for (auto controller : controllers) { + DFileServicePrivate::handlerHash.remove(controller); + DFileServicePrivate::controllerHash.remove(type, controller); + delete controller; + controller = nullptr; + } +} + +DFileService *DFileService::instance() +{ + static DFileService services; + + return &services; +} + +bool DFileService::setFileUrlHandler(const QString &scheme, const QString &host, + DAbstractFileController *controller) +{ + if (DFileServicePrivate::handlerHash.contains(controller)) { + return true; + } + + const HandlerType &type = HandlerType(scheme, host); + + foreach (const DAbstractFileController *value, DFileServicePrivate::controllerHash.values(type)) { + if (typeid(*value) == typeid(*controller)) { + controller->deleteLater(); + return false; + } + } + + DFileServicePrivate::handlerHash[controller] = type; + DFileServicePrivate::controllerHash.insertMulti(type, controller); + + return true; +} + +void DFileService::unsetFileUrlHandler(DAbstractFileController *controller) +{ + if (!DFileServicePrivate::handlerHash.contains(controller)) { + return; + } + + DFileServicePrivate::controllerHash.remove(DFileServicePrivate::handlerHash.value(controller), controller); +} + +void DFileService::clearFileUrlHandler(const QString &scheme, const QString &host) +{ + const HandlerType handler(scheme, host); + //sanitinizer工具检测到dde-file-manager-lib/controllers/appcontroller.cpp中143泄露,故添加 + if (TRASH_SCHEME == scheme && DFileServicePrivate::controllerHash.contains(handler)) { + auto temp = DFileServicePrivate::controllerHash.values(handler); + for (auto tempTrash : temp) { + if ("trashMgr" == tempTrash->objectName()) { + tempTrash->deleteLater(); + DFileServicePrivate::controllerHash.remove(handler); + DFileServicePrivate::controllerCreatorHash.remove(handler); + return; + } + } + } + DFileServicePrivate::controllerHash.remove(handler); + DFileServicePrivate::controllerCreatorHash.remove(handler); +} + +bool DFileService::openFile(const QObject *sender, const DUrl &url) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, url)).toBool(); +} + +bool DFileService::openFiles(const QObject *sender, const DUrlList &list, const bool isEnter) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, list, isEnter)).toBool(); +} + +bool DFileService::openFileByApp(const QObject *sender, const QString &appName, const DUrl &url) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, appName, url)).toBool(); +} + +bool DFileService::openFilesByApp(const QObject *sender, const QString &appName, const QList &urllist, const bool isenter) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, appName, urllist, isenter)).toBool(); +} + +bool DFileService::compressFiles(const QObject *sender, const DUrlList &list) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, list)).toBool(); +} + +bool DFileService::decompressFile(const QObject *sender, const DUrlList &list) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, list)).toBool(); +} + +bool DFileService::decompressFileHere(const QObject *sender, const DUrlList &list) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, list)).toBool(); +} + +bool DFileService::writeFilesToClipboard(const QObject *sender, DFMGlobal::ClipboardAction action, const DUrlList &list) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, action, list)).toBool(); +} + +bool DFileService::renameFile(const QObject *sender, const DUrl &from, const DUrl &to, const bool silent) const +{ + bool ok = DFMEventDispatcher::instance()->processEvent(sender, from, to, silent).toBool(); + + return ok; +} + +bool DFileService::deleteFiles(const QObject *sender, const DUrlList &list, bool confirmationDialog, bool slient, bool force) const +{ + Q_UNUSED(confirmationDialog) + if (list.isEmpty()) + return false; + + foreach (const DUrl &url, list) { + if (systemPathManager->isSystemPath(url.toLocalFile())) { + if (!slient) { + DThreadUtil::runInMainThread(dialogManager, &DialogManager::showDeleteSystemPathWarnDialog, DFMEvent::windowIdByQObject(sender)); + } + + return false; + } + } + +// if (!confirmationDialog || DThreadUtil::runInMainThread(dialogManager, &DialogManager::showDeleteFilesClearTrashDialog, DFMUrlListBaseEvent(sender, list)) == DDialog::Accepted) { +// if (!confirmationDialog ) { + return DFMEventDispatcher::instance()->processEventWithEventLoop(dMakeEventPointer(sender, list, slient, force)).toBool(); +// } + +// return false; +} + +DUrlList DFileService::moveToTrash(const QObject *sender, const DUrlList &list) const +{ + if (list.isEmpty()) { + return list; + } + + //fix bug#30027 删除文件时将剪切板中的该文件移除 + { + QList org = DFMGlobal::instance()->clipboardFileUrlList(); + DFMGlobal::ClipboardAction action = DFMGlobal::instance()->clipboardAction(); + if (!org.isEmpty() && action != DFMGlobal::UnknowAction) { + for (const DUrl &nd : list) { + if (org.isEmpty()) + break; + org.removeAll(nd); + } + if (org.isEmpty()) //没有文件则清空剪切板 + DFMGlobal::clearClipboard(); + else + DFMGlobal::setUrlsToClipboard(org, action); + } + } + //end + + const QString& rootPath = list.first().toLocalFile(); + + if (!rootPath.isEmpty() && (FileUtils::isGvfsMountFile(rootPath) || deviceListener->isInRemovableDeviceFolder(rootPath) || VaultController::isVaultFile(rootPath))) { + deleteFiles(sender, list); + return list; + } + + //! 显示删除确认对话框 + bool bShowConfimDlg = DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowDeleteConfirmDialog).toBool(); + DUrl url = list.first(); + if (bShowConfimDlg + && d_ptr->m_isMoveToTrashOver + && !url.isTrashFile() + && !url.isRecentFile() + && url.scheme() != BURN_SCHEME + && !VaultController::isVaultFile(url.toLocalFile()) + && !url.isUserShareFile() + && !url.isSMBFile()) { + + if (DThreadUtil::runInMainThread( + dialogManager, + &DialogManager::showNormalDeleteConfirmDialog, + DFMUrlListBaseEvent(nullptr, list)) != DDialog::Accepted) + return DUrlList(); + } + + const DUrlList &result = qvariant_cast(DFMEventDispatcher::instance()->processEventWithEventLoop(dMakeEventPointer(sender, list))); + + return result; +} + +void DFileService::pasteFileByClipboard(const QObject *sender, const DUrl &targetUrl) const +{ + DFMGlobal::ClipboardAction action = DFMGlobal::instance()->clipboardAction(); + + if (action == DFMGlobal::UnknowAction) { + return; + } + if (targetUrl.scheme() == SEARCH_SCHEME) { + return; + } + if (action == DFMGlobal::RemoteAction) { + qInfo() << "RemoteAction download remote files"; + pasteFile(sender, action, targetUrl, DUrlList()); + return; + } + const DUrlList &list = DUrl::fromQUrlList(DFMGlobal::instance()->clipboardFileUrlList()); + + if (action == DFMGlobal::CutAction) { + // fix bug 63441 + // 如果是剪切操作,则禁止跨用户的粘贴操作 + QByteArray userId = qApp->clipboard()->mimeData()->data("userId"); + if (!userId.isEmpty() && (userId.toInt() != DFMGlobal::getUserId())) + return; + + DFMGlobal::instance()->clearClipboard(); + } + + // 某些文件剪切到回收站需处理成"永久删除" + if (action == DFMGlobal::CutAction && targetUrl.scheme() == TRASH_SCHEME && !list.empty()) { + auto fi = DFileService::createFileInfo(this, list[0]); + if (fi && fi->needCompleteDelete()) { + deleteFiles(sender, list, true, false, true); + return; + } + } + pasteFile(sender, action, targetUrl, list); +} + +DUrlList DFileService::pasteFile(const QObject *sender, DFMGlobal::ClipboardAction action, const DUrl &targetUrl, const DUrlList &list) const +{ + const QSharedPointer &event = dMakeEventPointer(sender, action, targetUrl, list); + const DUrlList &new_list = qvariant_cast(DFMEventDispatcher::instance()->processEvent(event)); + + return new_list; +} + +bool DFileService::restoreFile(const QObject *sender, const DUrlList &list) const +{ + return DFMEventDispatcher::instance()->processEventWithEventLoop(sender, list).toBool(); +} + +bool DFileService::mkdir(const QObject *sender, const DUrl &targetUrl) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, targetUrl)).toBool(); +} + +bool DFileService::touchFile(const QObject *sender, const DUrl &targetUrl) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, targetUrl)).toBool(); +} + +bool DFileService::openFileLocation(const QObject *sender, const DUrl &url) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, url)).toBool(); +} + +bool DFileService::setPermissions(const QObject *sender, const DUrl &url, const QFileDevice::Permissions permissions) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, url, permissions)).toBool(); +} + +bool DFileService::addToBookmark(const QObject *sender, const DUrl &fileUrl) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, fileUrl)).toBool(); +} + +bool DFileService::removeBookmark(const QObject *sender, const DUrl &fileUrl) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, fileUrl)).toBool(); +} + +bool DFileService::createSymlink(const QObject *sender, const DUrl &fileUrl) const +{ + QString linkName = getSymlinkFileName(fileUrl); + QString linkPath = QFileDialog::getSaveFileName(qobject_cast(sender) ? qobject_cast(sender)->window() : Q_NULLPTR, + QObject::tr("Create symlink"), linkName); + + //! QFileDialog::getSaveFileName not support vault file, so we need get path self. + if (VaultController::ins()->isVaultFile(linkPath)) { + QStringList strList = linkPath.split("/"); + if (strList.back() != linkName) { + strList.removeLast(); + linkPath = strList.join("/") + "/" + linkName; + } + } + + //handle for cancel select file + if (linkPath.isEmpty()) { + return false; + } + + return createSymlink(sender, fileUrl, DUrl::fromLocalFile(linkPath), true); +} + +bool DFileService::createSymlink(const QObject *sender, const DUrl &fileUrl, const DUrl &linkToUrl, bool force/* = false*/) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, fileUrl, linkToUrl, force)).toBool(); +} + +bool DFileService::sendToDesktop(const QObject *sender, const DUrlList &urlList) const +{ + const QString &desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + + if (desktopPath.isEmpty()) { + return false; + } + + const QDir &desktopDir(desktopPath); + bool ok = true; + + for (const DUrl &durl : urlList) { + const QString &linkName = getSymlinkFileName(durl, desktopDir); + + ok = ok && createSymlink(sender, durl, DUrl::fromLocalFile(desktopDir.filePath(linkName))); + } + + return ok; +} + +void DFileService::sendToBluetooth(const DUrlList &urlList) const +{ + dialogManager->showBluetoothTransferDlg(urlList); +} + +bool DFileService::shareFolder(const QObject *sender, const DUrl &fileUrl, const QString &name, bool isWritable, bool allowGuest) +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, fileUrl, name, isWritable, allowGuest)).toBool(); +} + +bool DFileService::unShareFolder(const QObject *sender, const DUrl &fileUrl) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, fileUrl)).toBool(); +} + +bool DFileService::openInTerminal(const QObject *sender, const DUrl &fileUrl) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, fileUrl)).toBool(); +} + + +///###: make file tag(s). +bool DFileService::setFileTags(const QObject *sender, const DUrl &url, const QList &tags) const +{ + QSharedPointer event(new DFMSetFileTagsEvent(sender, url, tags)); + return DFMEventDispatcher::instance()->processEvent(event).toBool(); +} + +bool DFileService::makeTagsOfFiles(const QObject *sender, const DUrlList &urlList, const QStringList &tags, const QSet dirtyTagFilter) const +{ + QRegExp rx("[\\\\/\':\\*\\?\"<>|%&]"); + auto ret = std::any_of(tags.begin(), tags.end(), [rx](const QString & tag) { + return tag.indexOf(rx) >= 0; + }); + + if (ret) + return false; + + QStringList old_tagNames = getTagsThroughFiles(sender, urlList);//###: the mutual tags of multi files. + QStringList dirty_tagNames; //###: for deleting. + const QSet tags_set = QSet::fromList(tags); + + for (const QString &tag : old_tagNames) { + if (!tags_set.contains(tag) && (dirtyTagFilter.isEmpty() || dirtyTagFilter.contains(tag))) { + dirty_tagNames << tag; + } + } + + bool loopEvent = urlList.length() > 5; + QList eventList; + for (const DUrl &durl : urlList) { + QStringList tags_of_file = getTagsThroughFiles(sender, {durl}, loopEvent); + QSet tags_of_file_set = tags_set; + + tags_of_file_set += QSet::fromList(tags_of_file); + + for (const QString &dirty_tag : dirty_tagNames) { + tags_of_file_set.remove(dirty_tag); + } + + DFMSetFileTagsEvent *event = new DFMSetFileTagsEvent(sender, durl, tags_of_file_set.toList()); + eventList.append(event); + } + + for (DFMSetFileTagsEvent *event : eventList) { + QSharedPointer spEvent(event); + bool result = DFMEventDispatcher::instance()->processEventWithEventLoop(spEvent).toBool(); + + if (!result) + return false; + } + + return true; +} + +///###: remove tag(s) of file. +bool DFileService::removeTagsOfFile(const QObject *sender, const DUrl &url, const QList &tags) const +{ + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, url, tags)).toBool(); +} + +QList DFileService::getTagsThroughFiles(const QObject *sender, const QList &urls, const bool loopEvent) const +{ + if (urls.count() > 10 || loopEvent) + return DFMEventDispatcher::instance()->processEventWithEventLoop(dMakeEventPointer(sender, urls)).value>(); + + return DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, urls)).value>(); +} + +const DAbstractFileInfoPointer DFileService::createFileInfo(const QObject *sender, const DUrl &fileUrl, const bool isFromCache) const +{ + if (isFromCache) { + const DAbstractFileInfoPointer &info = DAbstractFileInfo::getFileInfo(fileUrl); + + if (info) { + info->refresh(); + return info; + } + } + const auto &&event = dMakeEventPointer(sender, fileUrl); + + return qvariant_cast(DFMEventDispatcher::instance()->processEvent(event)); +} + +const DDirIteratorPointer DFileService::createDirIterator(const QObject *sender, const DUrl &fileUrl, const QStringList &nameFilters, + QDir::Filters filters, QDirIterator::IteratorFlags flags, bool silent, bool isgvfs) const +{ + const auto &&event = dMakeEventPointer(sender, fileUrl, nameFilters, filters, flags, silent, isgvfs); + return qvariant_cast(DFMEventDispatcher::instance()->processEvent(event)); +} + +const QList DFileService::getChildren(const QObject *sender, const DUrl &fileUrl, const QStringList &nameFilters, + QDir::Filters filters, QDirIterator::IteratorFlags flags, bool silent, bool canconst) const +{ + const auto &&event = dMakeEventPointer(sender, fileUrl, nameFilters, filters, flags, silent, canconst); + + return qvariant_cast>(DFMEventDispatcher::instance()->processEvent(event)); +} + +JobController *DFileService::getChildrenJob(const QObject *sender, const DUrl &fileUrl, const QStringList &nameFilters, + QDir::Filters filters, QDirIterator::IteratorFlags flags, bool silent, const bool isgfvs) const +{ + const auto &&event = dMakeEventPointer(sender, fileUrl, nameFilters, filters, flags, silent, isgfvs); + + return qvariant_cast(DFMEventDispatcher::instance()->processEvent(event)); +} + +DAbstractFileWatcher *DFileService::createFileWatcher(const QObject *sender, const DUrl &fileUrl, QObject *parent) const +{ + DAbstractFileWatcher *w = qvariant_cast(DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(sender, fileUrl))); + + if (w) { + w->setParent(parent); + } + + return w; +} + +bool DFileService::setExtraProperties(const QObject *sender, const DUrl &fileUrl, const QVariantHash &ep) const +{ + const auto &&event = dMakeEventPointer(sender, fileUrl, ep); + + return DFMEventDispatcher::instance()->processEvent(event).toBool(); +} + +DFileDevice *DFileService::createFileDevice(const QObject *sender, const DUrl &url) +{ + const auto &&event = dMakeEventPointer(DFMEvent::CreateFileDevice, sender, url); + + return qvariant_cast(DFMEventDispatcher::instance()->processEvent(event)); +} + +DFileHandler *DFileService::createFileHandler(const QObject *sender, const DUrl &url) +{ + const auto &&event = dMakeEventPointer(DFMEvent::CreateFileHandler, sender, url); + + return qvariant_cast(DFMEventDispatcher::instance()->processEvent(event)); +} + +DStorageInfo *DFileService::createStorageInfo(const QObject *sender, const DUrl &url) +{ + const auto &&event = dMakeEventPointer(DFMEvent::CreateStorageInfo, sender, url); + + return qvariant_cast(DFMEventDispatcher::instance()->processEvent(event)); +} + +void DFileService::setCursorBusyState(const bool bbusy) +{ + //fix bug 34594,当快速点击左边侧边栏会出现鼠标一直在转圈圈, 去掉全局判断,直接调用鼠标状态 + if (bbusy) { + if (QApplication::overrideCursor() && QApplication::overrideCursor()->shape() == Qt::WaitCursor) + return; + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + } else { +// QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); + //! fix bug#39929 列表模式调整列表宽度无选中标记。 + QApplication::restoreOverrideCursor(); + } +} + +bool DFileService::checkGvfsMountfileBusy(const DUrl &url, const bool showdailog) +{ + //找出url的rootfile路径,判断rootfile是否存在 + Q_D(DFileService); +// printStacktrace(6); + + DUrl rooturl; + QString urlpath = url.path(); + QString rootfilename; + if (url.scheme() == DFMROOT_SCHEME && urlpath.endsWith(SUFFIX_GVFSMP)) { + rootfilename = QUrl::fromPercentEncoding(url.path().toUtf8()); + QStringList rootstrlist = rootfilename.split(QRegularExpression(GVFS_ROOT_MATCH)); + if (rootstrlist.size() >= 2) { + rootfilename = rootstrlist.at(1); + rootfilename = rootfilename.replace(QString(".") + QString(SUFFIX_GVFSMP), ""); + } + if (!(rootfilename.startsWith(SMB_SCHEME) || rootfilename.startsWith(FTP_SCHEME) + || rootfilename.startsWith(SFTP_SCHEME))) { + return false; + } + rooturl = url; + } else { + static QRegularExpression regExp(GVFS_MATCH_EX, + QRegularExpression::DotMatchesEverythingOption + | QRegularExpression::DontCaptureOption + | QRegularExpression::OptimizeOnFirstUsageOption); + + if (!regExp.match(urlpath, 0, QRegularExpression::NormalMatch, QRegularExpression::DontCheckSubjectStringMatchOption).hasMatch()) { + return false; + } + int qi = 0; + QStringList urlpathlist = urlpath.split(QRegularExpression(GVFS_MATCH)); + QString urlstr; + QString urllast; + if (urlpathlist.size() >= 2) { + urllast = urlpathlist[1]; + urlstr = urlpath.left(urlpath.indexOf(urllast)); + } + + qi = urllast.indexOf("/"); + QString path; + if (0 >= qi) { + path = urlpath; + QStringList rootstrlist = path.split(QRegularExpression(GVFS_MATCH)); + if (rootstrlist.size() >= 2) { + rootfilename = rootstrlist.at(1); + rootfilename = rootfilename.replace(QString(".") + QString(SUFFIX_GVFSMP), ""); + } + } else { + rootfilename = urllast.left(qi); + path = urlstr + urllast.left(qi); + } + if (path.isNull() || path.isEmpty() || + !(rootfilename.startsWith(SMB_SCHEME) || rootfilename.startsWith(FTP_SCHEME) + || rootfilename.startsWith(SFTP_SCHEME))) { + return false; + } + rooturl.setScheme(DFMROOT_SCHEME); + rooturl.setPath("/" + QUrl::toPercentEncoding(path) + "." SUFFIX_GVFSMP); + } + if (isSmbFtpContain(rooturl)) { + d->smbftpmutex.lock(); + bool bbusy = d->m_rootsmbftpurllist.value(rooturl); + d->smbftpmutex.unlock(); + return bbusy; + } + bool isbusy = checkGvfsMountfileBusy(rooturl, rootfilename, showdailog); + d->smbftpmutex.lock(); + d->m_rootsmbftpurllist.insert(rooturl, isbusy); + d->smbftpmutex.unlock(); + QTimer::singleShot(500, this, [rooturl, d]() { + QMutexLocker lk(&d->smbftpmutex); + d->m_rootsmbftpurllist.remove(rooturl); + }); + return isbusy; +} + +bool DFileService::checkGvfsMountfileBusy(const DUrl &rootUrl, const QString &rootFileName, const bool bShowDailog) +{ + Q_D(DFileService); + + if (!rootUrl.isValid()) { + return false; + } + //设置鼠标状态,查看文件状态是否存在 + setCursorBusyState(true); + + if (rootFileName.startsWith(SMB_SCHEME) || rootFileName.startsWith(SFTP_SCHEME)) { + DAbstractFileInfoPointer rootptr = createFileInfo(nullptr, rootUrl); + bool fileExists = rootptr->exists(); + setCursorBusyState(false); + //文件不存在弹提示框 + if (!fileExists && bShowDailog && FileUtils::isNetworkUrlMounted(rootUrl)) { + dialogManager->showUnableToLocateDir(rootFileName); + } + return !fileExists; + } + + //是网络文件,就去确定host和port端口号 + bool bvist = true; + QString host, port; + QStringList ipInfoList = rootFileName.split(","); + if (!ipInfoList.isEmpty()) { + int spliteIndex = ipInfoList[0].indexOf("="); + host = ipInfoList[0].mid((spliteIndex >= 0 && spliteIndex < ipInfoList[0].length() - 1) + ? spliteIndex + 1 : 0); + } else { + setCursorBusyState(false); + return true; + } + + if (ipInfoList.count() >= 2 && -1 != ipInfoList[1].indexOf("port=")) { + port = ipInfoList[1].replace("port=", ""); + } + + bvist = d->m_checknetwork.isHostAndPortConnect(host, port.toUShort() <= 0 ? QString("21") : port); + + setCursorBusyState(false); + + //文件不存在弹提示框 + if (!bvist && bShowDailog && FileUtils::isNetworkUrlMounted(rootUrl)) { + dialogManager->showUnableToLocateDir(rootFileName); + } + qDebug() << bvist; + return !bvist; +} + +bool DFileService::getDoClearTrashState() const +{ + Q_D(const DFileService); + + return d->m_bdoingcleartrash; +} + +void DFileService::setDoClearTrashState(const bool bdoing) +{ + Q_D(DFileService); + + d->m_bdoingcleartrash = bdoing; +} + +void DFileService::dealPasteEnd(const QSharedPointer &event, const DUrlList &result) +{ + if (event->isAccepted()) { + DFMUrlListBaseEvent e(event->sender(), result); + + e.setWindowId(event->windowId()); + laterRequestSelectFiles(e); + } + + const DUrlList &list = event->fileUrlList(); + const DUrlList new_list = result; + + for (int i = 0; i < new_list.count(); ++i) { + const DUrl &durl = new_list.at(i); + + if (durl.isEmpty()) + continue; + + DFMGlobal::ClipboardAction action = event.staticCast()->action(); + + if (action == DFMGlobal::ClipboardAction::CopyAction) { + emit fileCopied(list.at(i), durl); + } else if (action == DFMGlobal::ClipboardAction::CutAction) { + emit fileRenamed(list.at(i), durl); + } + } + + // fix bug#202007010020 发送到光驱暂存区的文件保留了文件的原始权限信息,在刻录或删除的时候可能会报错,因此在文件复制完成时添加用户写权限,让去重/删除可以顺利往下走 + if (result.count() > 0 && result[0].path().contains(DISCBURN_CACHE_MID_PATH)) { + QString strFilePath = result[0].path(); + static QRegularExpression reg("/_dev_sr[0-9]*/"); // 正则匹配 _dev_srN N为任意数字,考虑可能接入多光驱的情况 + QRegularExpressionMatch match = reg.match(strFilePath); + if (match.hasMatch()) { + QString strTag = match.captured(); + QString strStagingPath = strFilePath.mid(0, strFilePath.indexOf(strTag) + strTag.length()); + QProcess::execute("chmod -R u+w " + strStagingPath); // 之前尝试使用 DLocalFileHandler 去处理权限问题但是会失败,因此这里采用命令去更改权限 + } + } +} + +bool DFileService::isSmbFtpContain(const DUrl &url) +{ + QMutexLocker lk(&d_ptr->smbftpmutex); + return d_ptr->m_rootsmbftpurllist.contains(url); +} + +void DFileService::onTagEditorChanged(const QStringList &tags, const DUrlList &files) +{ + Q_D(DFileService); + + //暂停timer + d->m_tagEditorChangeTimer.stop(); + + //重设tag数据和files + d->m_tagEditorTags.clear(); + d->m_tagEditorTags.append(tags); + d->m_tagEditorFiles.clear(); + d->m_tagEditorFiles.append(files); + + //开始timer计时,500毫秒内连续的editor被编辑改变合并为一次改变 + d->m_tagEditorChangeTimer.start(500); +} + +QList DFileService::getHandlerTypeByUrl(const DUrl &fileUrl, bool ignoreHost, bool ignoreScheme) +{ + HandlerType handlerType(ignoreScheme ? "" : fileUrl.scheme(), ignoreHost ? "" : fileUrl.host()); + + if (DFileServicePrivate::controllerCreatorHash.contains(handlerType)) { + QList list = DFileServicePrivate::controllerHash.values(handlerType); + + for (const HandlerCreatorType &creator : DFileServicePrivate::controllerCreatorHash.values(handlerType)) { + DAbstractFileController *controller = (creator.second)(); + + setFileUrlHandler(handlerType.first, handlerType.second, controller); + + list << controller; + } + + DFileServicePrivate::controllerCreatorHash.remove(handlerType); + } + + return DFileServicePrivate::controllerHash.values(handlerType); +} + +QString DFileService::getSymlinkFileName(const DUrl &fileUrl, const QDir &targetDir) +{ + const DAbstractFileInfoPointer &pInfo = instance()->createFileInfo(Q_NULLPTR, fileUrl); + + if (pInfo && pInfo->exists()) { + QString baseName = pInfo->fileDisplayName() == pInfo->fileName() ? pInfo->baseName() : pInfo->fileDisplayName(); + QString shortcut = QObject::tr("Shortcut"); + QString linkBaseName; + + int number = 1; + + forever { + if (pInfo->isFile()) { + if (pInfo->suffix().isEmpty()) { + if (number == 1) { + + linkBaseName = QString("%1 %2").arg(baseName, shortcut); + } else { + linkBaseName = QString("%1 %2%3").arg(baseName, shortcut, QString::number(number)); + } + } else { + if (number == 1) { + linkBaseName = QString("%1 %2.%3").arg(baseName, shortcut, pInfo->suffix()); + } else { + linkBaseName = QString("%1 %2%3.%4").arg(baseName, shortcut, QString::number(number), pInfo->suffix()); + } + } + } else if (pInfo->isDir()) { + if (number == 1) { + linkBaseName = QString("%1 %2").arg(baseName, shortcut); + } else { + linkBaseName = QString("%1 %2%3").arg(baseName, shortcut, QString::number(number)); + } + } else if (pInfo->isSymLink()) { + return QString(); + } + + if (targetDir.path().isEmpty()) { + return linkBaseName; + } + + if (targetDir.exists(linkBaseName)) { + ++number; + } else { + //链接文件失效后exists会返回false,通过lstat再次判断链接文件本身是否存在 + auto strLinkPath = targetDir.filePath(linkBaseName).toStdString(); + struct stat st; + if ((lstat(strLinkPath.c_str(), &st) == 0) && S_ISLNK(st.st_mode)) + ++number; + else + return linkBaseName; + } + } + } + + return QString(); +} + +void DFileService::insertToCreatorHash(const HandlerType &type, const HandlerCreatorType &creator) +{ + DFileServicePrivate::controllerCreatorHash.insertMulti(type, creator); +} + +void DFileService::laterRequestSelectFiles(const DFMUrlListBaseEvent &event) const +{ + FileSignalManager *manager = fileSignalManager; + + TIMER_SINGLESHOT_OBJECT(manager, qMax(event.fileUrlList().count() * (10 + event.fileUrlList().count() / 150), 200), { + manager->requestSelectFile(event); + }, event, manager) +} + +///###: replace +bool DFileService::multiFilesReplaceName(const QList &urls, const QPair &pair)const +{ + auto alteredAndUnAlteredUrls = FileBatchProcess::instance()->replaceText(urls, pair); + AppController::multiSelectionFilesCache.first = FileBatchProcess::batchProcessFile(alteredAndUnAlteredUrls).values(); + + return DFileService::checkMultiSelectionFilesCache(); +} + + +///###: add +bool DFileService::multiFilesAddStrToName(const QList &urls, const QPair &pair)const +{ + auto alteredAndUnAlteredUrls = FileBatchProcess::instance()->addText(urls, pair); + AppController::multiSelectionFilesCache.first = FileBatchProcess::batchProcessFile(alteredAndUnAlteredUrls).values(); + + return DFileService::checkMultiSelectionFilesCache(); +} + +///###: customize +bool DFileService::multiFilesCustomName(const QList &urls, const QPair &pair)const +{ + auto alteredAndUnAlteredUrls = FileBatchProcess::instance()->customText(urls, pair); + AppController::multiSelectionFilesCache.first = FileBatchProcess::batchProcessFile(alteredAndUnAlteredUrls).values(); + + return DFileService::checkMultiSelectionFilesCache(); +} + +///###: helper function. +bool DFileService::checkMultiSelectionFilesCache() +{ + if (AppController::multiSelectionFilesCache.first.isEmpty()) { + return false; + } + + return true; +} + +//打印函数的调用堆栈 +void DFileService::printStacktrace(int level) +{ + int size = 16; + void *array[16]; + int stack_num = backtrace(array, size); + char **stacktrace = backtrace_symbols(array, stack_num); + int total = std::min(level, stack_num); + for (int i = 0; i < total; ++i) { + printf("%s\n", stacktrace[i]); + } + free(stacktrace); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileservices.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileservices.h new file mode 100644 index 0000000..760e383 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileservices.h @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef FILESERVICES_H +#define FILESERVICES_H + +#include "dabstractfilecontroller.h" +#include "durl.h" +#include "dfmabstracteventhandler.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +DFM_USE_NAMESPACE + +typedef QPair HandlerType; +typedef QPair> HandlerCreatorType; + +class DFMUrlListBaseEvent; +class DAbstractFileInfo; +class JobController; +class DFMCreateGetChildrensJob; +class DFileServicePrivate; + +DFM_BEGIN_NAMESPACE +class DFileHandler; +class DFileDevice; +class DStorageInfo; +DFM_END_NAMESPACE + +class DFileService : public QObject, public DFMAbstractEventHandler +{ + Q_OBJECT + +public: + enum class AddTextFlags : std::size_t { + Before = 0, + After = 1 + }; + + template + static void dRegisterUrlHandler(const QString &scheme, const QString &host) + { + if (isRegisted(scheme, host)) { + return; + } + + insertToCreatorHash(HandlerType(scheme, host), HandlerCreatorType(typeid(T).name(), [ = ] { + DAbstractFileController *handler = new T(); + DFileService *that = instance(); + + if (handler->thread() != that->thread()) + { + handler->moveToThread(that->thread()); + } + + handler->setParent(that); + + return handler; + })); + } + static bool isRegisted(const QString &scheme, const QString &host, const std::type_info &info); + template + static bool isRegisted(const QString &scheme, const QString &host) + { + return isRegisted(scheme, host, typeid(T)); + } + static bool isRegisted(const QString &scheme, const QString &host); + + static void initHandlersByCreators(); + + /** + * @brief ut 主动清理controller 其它地方慎用 + * @param + * @return + */ + static void clearController(const QString &scheme, const QString &host); + + static void printStacktrace(int level = 4); + + static DFileService *instance(); + + static bool setFileUrlHandler(const QString &scheme, const QString &host, + DAbstractFileController *controller); + static void unsetFileUrlHandler(DAbstractFileController *controller); + static void clearFileUrlHandler(const QString &scheme, const QString &host); + + static QList getHandlerTypeByUrl(const DUrl &fileUrl, + bool ignoreHost = false, + bool ignoreScheme = false); + + bool openFile(const QObject *sender, const DUrl &url) const; + bool openFiles(const QObject *sender, const DUrlList &list, const bool isEnter = false) const; + bool openFileByApp(const QObject *sender, const QString &appName, const DUrl &url) const; + bool openFilesByApp(const QObject *sender, const QString &appName, const QList &urllist, const bool isenter = false) const; + bool compressFiles(const QObject *sender, const DUrlList &list) const; + bool decompressFile(const QObject *sender, const DUrlList &list) const; + bool decompressFileHere(const QObject *sender, const DUrlList &list) const; + bool writeFilesToClipboard(const QObject *sender, DFMGlobal::ClipboardAction action, const DUrlList &list) const; + bool renameFile(const QObject *sender, const DUrl &from, const DUrl &to, const bool silent = false) const; + bool multiFilesReplaceName(const QList &urls, const QPair &pair)const; + bool multiFilesAddStrToName(const QList &urls, const QPair &pair)const; + bool multiFilesCustomName(const QList &urls, const QPair &pair)const; + bool deleteFiles(const QObject *sender, const DUrlList &list, bool confirmationDialog = true, bool slient = false, bool force = false) const; + DUrlList moveToTrash(const QObject *sender, const DUrlList &list) const; + void pasteFileByClipboard(const QObject *sender, const DUrl &targetUrl) const; + DUrlList pasteFile(const QObject *sender, DFMGlobal::ClipboardAction action, + const DUrl &targetUrl, const DUrlList &list) const; + bool restoreFile(const QObject *sender, const DUrlList &list) const; + bool mkdir(const QObject *sender, const DUrl &targetUrl) const; + bool touchFile(const QObject *sender, const DUrl &targetUrl) const; + bool openFileLocation(const QObject *sender, const DUrl &url) const; + bool setPermissions(const QObject *sender, const DUrl &url, const QFileDevice::Permissions permissions) const; + + bool addToBookmark(const QObject *sender, const DUrl &fileUrl) const; + bool removeBookmark(const QObject *sender, const DUrl &fileUrl) const; + bool createSymlink(const QObject *sender, const DUrl &fileUrl) const; + bool createSymlink(const QObject *sender, const DUrl &fileUrl, const DUrl &linkToUrl, bool force = false) const; + bool sendToDesktop(const QObject *sender, const DUrlList &urlList) const; + void sendToBluetooth(const DUrlList &urlList) const; + + bool shareFolder(const QObject *sender, const DUrl &fileUrl, const QString &name, bool isWritable = false, bool allowGuest = false); + bool unShareFolder(const QObject *sender, const DUrl &fileUrl) const; + bool openInTerminal(const QObject *sender, const DUrl &fileUrl) const; + + ///###: for tag protocol. + bool setFileTags(const QObject *sender, const DUrl &url, const QList &tags) const; + bool makeTagsOfFiles(const QObject *sender, const DUrlList &urlList, const QStringList &tags, const QSet dirtyTagFilter = QSet()) const; + bool removeTagsOfFile(const QObject *sender, const DUrl &url, const QList &tags) const; + QList getTagsThroughFiles(const QObject *sender, const QList &urls, const bool loopEvent = false) const; + + const DAbstractFileInfoPointer createFileInfo(const QObject *sender, const DUrl &fileUrl, const bool isFromCache = true) const; + const DDirIteratorPointer createDirIterator(const QObject *sender, const DUrl &fileUrl, const QStringList &nameFilters, QDir::Filters filters, + QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags, bool silent = false, bool isgvfs = false) const; + + const QList getChildren(const QObject *sender, const DUrl &fileUrl, const QStringList &nameFilters, QDir::Filters filters, + QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags, bool silent = false, bool canconst = false) const; + + JobController *getChildrenJob(const QObject *sender, const DUrl &fileUrl, const QStringList &nameFilters, + QDir::Filters filters, + QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags, bool silent = false, const bool isgfvs = false) const; + + DAbstractFileWatcher *createFileWatcher(const QObject *sender, const DUrl &fileUrl, QObject *parent = nullptr) const; + bool setExtraProperties(const QObject *sender, const DUrl &fileUrl, const QVariantHash &ep) const; + + DFileDevice *createFileDevice(const QObject *sender, const DUrl &url); + DFileHandler *createFileHandler(const QObject *sender, const DUrl &url); + DStorageInfo *createStorageInfo(const QObject *sender, const DUrl &url); + + + //set cursor busy status + void setCursorBusyState(const bool bbusy); + //check networkfile is busy(or network is unline) + bool checkGvfsMountfileBusy(const DUrl &url, const bool showdailog = true); + bool checkGvfsMountfileBusy(const DUrl &rootUrl, const QString &rootFileName, const bool bShowDailog = true); + //获取是否是正在清空回收站 fix bug 31324, + bool getDoClearTrashState() const; + //设置当前是否是在清空回收站 fix bug 31324, + void setDoClearTrashState(const bool bdoing); + //处理复制、粘贴和剪切(拷贝)结束后操作 fix bug 35855 + void dealPasteEnd(const QSharedPointer &event, const DUrlList &result); + //判断当前的可访问的smb和ftp中是否包含某个url + bool isSmbFtpContain(const DUrl &url); + + void onTagEditorChanged(const QStringList &tags, const DUrlList &files); +signals: + void fileOpened(const DUrl &fileUrl) const; + void fileCopied(const DUrl &source, const DUrl &target) const; + void fileDeleted(const DUrl &fileUrl) const; + void fileMovedToTrash(const DUrl &from, const DUrl &to) const; + void fileRenamed(const DUrl &from, const DUrl &to) const; + +private slots: + void laterRequestSelectFiles(const DFMUrlListBaseEvent &event) const; + +private: + explicit DFileService(QObject *parent = nullptr); + ~DFileService() override; + + bool fmEvent(const QSharedPointer &event, QVariant *resultData = nullptr) override; + + static QString getSymlinkFileName(const DUrl &fileUrl, const QDir &targetDir = QDir()); + static void insertToCreatorHash(const HandlerType &type, const HandlerCreatorType &creator); + static bool checkMultiSelectionFilesCache(); + + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(DFileService) +}; + +#endif // FILESERVICES_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemmodel.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemmodel.cpp new file mode 100644 index 0000000..18a7b5c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemmodel.cpp @@ -0,0 +1,3102 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfilesystemmodel.h" +#include "dabstractfileinfo.h" +#include "dfileservices.h" +#include "dabstractfilewatcher.h" +#include "dfmstyleditemdelegate.h" +#include "dfmapplication.h" +#include "views/dfileview.h" +#include "dfmstandardpaths.h" + +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "singleton.h" + +#include "controllers/vaultcontroller.h" +#include "controllers/jobcontroller.h" +#include "controllers/appcontroller.h" +#include "shutil/desktopfile.h" +//处理自动整理的路径问题 +#include "controllers/mergeddesktopcontroller.h" +#include "shutil/dfmfilelistfile.h" +#include "dfilesystemmodel_p.h" +#include "dfmsettings.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define fileService DFileService::instance() +#define DEFAULT_COLUMN_COUNT 0 + +FileSystemNode::FileSystemNode(FileSystemNode *parent, + const DAbstractFileInfoPointer &info, + DFileSystemModel *dFileSystemModel, + QReadWriteLock *lock) + : fileInfo(info) + , parent(parent) + , m_dFileSystemModel(dFileSystemModel) + , rwLock(lock) +{ + +} + +FileSystemNode::~FileSystemNode() +{ + visibleChildren.clear(); + children.clear(); +} + +QVariant FileSystemNode::dataByRole(int role) +{ + using Role = DFileSystemModel::Roles; + + switch (role) + { + case Role::FilePathRole: + return fileInfo->absoluteFilePath(); + case Role::FileDisplayNameRole: + return fileInfo->fileDisplayName(); + case Role::FileNameRole: + return fileInfo->fileName(); + case Role::FileNameOfRenameRole: + return fileInfo->fileNameOfRename(); + case Role::FileBaseNameRole: + return fileInfo->baseName(); + case Role::FileBaseNameOfRenameRole: + return fileInfo->baseNameOfRename(); + case Role::FileSuffixRole: + return fileInfo->suffix(); + case Role::FileSuffixOfRenameRole: + return fileInfo->suffixOfRename(); + case Qt::TextAlignmentRole: + return Qt::AlignVCenter; + case Role::FileLastModifiedRole: + return fileInfo->lastModifiedDisplayName(); + case Role::FileLastModifiedDateTimeRole: + return fileInfo->lastModified(); + case Role::FileSizeRole: + return fileInfo->sizeDisplayName(); + case Role::FileSizeInKiloByteRole: + return fileInfo->size(); + case Role::FileMimeTypeRole: + return fileInfo->mimeTypeDisplayName(); + case Role::FileCreatedRole: + return fileInfo->createdDisplayName(); + case Role::FilePinyinName: + return fileInfo->fileDisplayPinyinName(); + case Role::ExtraProperties: + return fileInfo->extraProperties(); + case Role::FileLastReadDateTimeRole: + return fileInfo->lastRead(); + case Role::FileCreatedDateTimeRole: + return fileInfo->created(); + default: { + return QVariant(); + } + } +} + +void FileSystemNode::setNodeVisible(const FileSystemNodePointer &node, bool visible) +{ + if (visible) { + if (!visibleChildren.contains(node)) { + visibleChildren.append(node); + } + } else { + if (visibleChildren.contains(node)) { + visibleChildren.removeOne(node); + } + } +} + +void FileSystemNode::applyFileFilter(std::shared_ptr filter) +{ + if (!filter) return; + + // fix bug 54887 【专业版1030】【文管5.2.0.82】搜索结果页多次筛选后,再重置筛选结果,重置搜索界面页面,出现重复搜索界面 + // 点击重置按钮,会触发所有combox的change信号,都会访问visibleChildren资源,因此加锁限制 + rwLock->lockForWrite(); + visibleChildren.clear(); + + for (auto node : children) { + if (!node->shouldHideByFilterRule(filter)) { + visibleChildren.append(node); + } + } + rwLock->unlock(); +} + +bool FileSystemNode::shouldHideByFilterRule(std::shared_ptr filter) +{ + if (!filter) return false; + + if (filter->f_comboValid[SEARCH_RANGE] && !filter->f_includeSubDir) { + DUrl parentUrl = fileInfo->parentUrl().isSearchFile() ? fileInfo->parentUrl().searchTargetUrl() : fileInfo->parentUrl(); + QString filePath = dataByRole(DFileSystemModel::FilePathRole).toString(); + // fix bug 44185 【专业版 sp3】【文件管理器】【5.2.0.28-1】多标签操作筛选搜索结果,回退路径时出现空白页面 + filePath.remove(parentUrl.toLocalFile().endsWith("/") ? parentUrl.toLocalFile() : parentUrl.toLocalFile() + '/'); + if (filePath.contains('/')) return true; + } + + if (filter->f_comboValid[FILE_TYPE]) { + QString fileTypeStr = dataByRole(DFileSystemModel::FileMimeTypeRole).toString(); + if (!fileTypeStr.startsWith(filter->f_typeString)) return true; + } + + if (filter->f_comboValid[SIZE_RANGE]) { + // note: FileSizeInKiloByteRole is the size of Byte, not KB! + quint64 fileSize = dataByRole(DFileSystemModel::FileSizeInKiloByteRole).toULongLong(); + quint32 blockSize = 1 << 10; + quint64 lower = filter->f_sizeRange.first * blockSize; + quint64 upper = filter->f_sizeRange.second * blockSize; + // filter file size in Bytes, not Kilobytes + if (fileSize < lower || fileSize > upper) return true; + } + + if (filter->f_comboValid[DATE_RANGE]) { + QDateTime filemtime = dataByRole(DFileSystemModel::FileLastModifiedDateTimeRole).toDateTime(); + if (filemtime < filter->f_dateRangeStart || filemtime > filter->f_dateRangeEnd) return true; + } + + if (filter->f_comboValid[ACCESS_DATE_RANGE]) { + QDateTime filemtime = dataByRole(DFileSystemModel::FileLastReadDateTimeRole).toDateTime(); + if (filemtime < filter->f_accessDateRangeStart || filemtime > filter->f_accessDateRangeEnd) return true; + } + + if (filter->f_comboValid[CREATE_DATE_RANGE]) { + QDateTime filemtime = dataByRole(DFileSystemModel::FileCreatedDateTimeRole).toDateTime(); + if (filemtime < filter->f_createDateRangeStart || filemtime > filter->f_createDateRangeEnd) return true; + } + + return false; +} + +void FileSystemNode::noLockInsertChildren(int index, const DUrl &url, const FileSystemNodePointer &node) +{ + // fix bug 105595 + if (!children.contains(url)) { + children[url] = node; + visibleChildren.insert(index, node); + } +} + +void FileSystemNode::insertChildren(int index, const DUrl &url, const FileSystemNodePointer &node) +{ + rwLock->lockForWrite(); + noLockInsertChildren(index, url, node); + rwLock->unlock(); +} + +void FileSystemNode::noLockAppendChildren(const DUrl &url, const FileSystemNodePointer &node) +{ + // fix bug 105595 + if (!children.contains(url)) { + children[url] = node; + visibleChildren.append(node); + } +} + +void FileSystemNode::appendChildren(const DUrl &url, const FileSystemNodePointer &node) +{ + rwLock->lockForWrite(); + noLockAppendChildren(url, node); + rwLock->unlock(); +} + +FileSystemNodePointer FileSystemNode::getNodeByUrl(const DUrl &url) +{ + rwLock->lockForRead(); + FileSystemNodePointer node = children.value(url); + rwLock->unlock(); + + return node; +} + +FileSystemNodePointer FileSystemNode::getNodeByIndex(int index) +{ + rwLock->lockForRead(); + FileSystemNodePointer node = visibleChildren.value(index); + rwLock->unlock(); + return node; +} + +FileSystemNodePointer FileSystemNode::takeNodeByUrl(const DUrl &url) +{ + rwLock->lockForWrite(); + FileSystemNodePointer node = children.take(url); + visibleChildren.removeOne(node); + rwLock->unlock(); + + return node; +} + +FileSystemNodePointer FileSystemNode::takeNodeByIndex(const int index) +{ + rwLock->lockForWrite(); + FileSystemNodePointer node; + if (index >= 0 && visibleChildren.size() > index) { + node = visibleChildren.takeAt(index); + children.remove(node->fileInfo->fileUrl()); + } else { + qWarning() << "index [" << index << "] out of range [" << visibleChildren.size() << "]"; + } + rwLock->unlock(); + + return node; +} + +int FileSystemNode::indexOfChild(const FileSystemNodePointer &node) +{ + rwLock->lockForRead(); + int index = visibleChildren.indexOf(node); + rwLock->unlock(); + + return index; +} + +int FileSystemNode::indexOfChild(const DUrl &url) +{ + rwLock->lockForRead(); + const FileSystemNodePointer &node = children.value(url); + int index = visibleChildren.indexOf(node); + rwLock->unlock(); + + return index; +} + +int FileSystemNode::childrenCount() +{ + QReadLocker rl(rwLock); + + return visibleChildren.count(); +} + +QList FileSystemNode::getChildrenList() const +{ + return visibleChildren; +} + +DUrlList FileSystemNode::getChildrenUrlList() +{ + DUrlList list; + + rwLock->lockForRead(); + + list.reserve(visibleChildren.size()); + + for (const FileSystemNodePointer &node : visibleChildren) + list << node->fileInfo->fileUrl(); + + rwLock->unlock(); + + return list; +} + +void FileSystemNode::setChildrenList(const QList &list) +{ + rwLock->lockForWrite(); + visibleChildren = list; + + rwLock->unlock(); +} + +void FileSystemNode::setChildrenMap(const QHash &map) +{ + rwLock->lockForWrite(); + children = map; + rwLock->unlock(); +} + +void FileSystemNode::clearChildren() +{ + rwLock->lockForWrite(); + visibleChildren.clear(); + children.clear(); + rwLock->unlock(); +} + +bool FileSystemNode::childContains(const DUrl &url) +{ + QReadLocker rl(rwLock); + + return children.contains(url); +} + + +void FileSystemNode::addFileSystemNode(const FileSystemNodePointer &node) +{ + if (nullptr != node->parent) { + QString url = node->fileInfo->filePath(); + rwLock->lockForWrite(); + if (!m_dFileSystemModel->m_allFileSystemNodes.contains(url)) { + m_dFileSystemModel->m_allFileSystemNodes[url] = node; + } + rwLock->unlock(); + } +} + +void FileSystemNode::removeFileSystemNode(const FileSystemNodePointer &node) +{ + if (nullptr != node->parent) { + QString url = node->fileInfo->filePath(); + rwLock->lockForWrite(); + qDebug() << m_dFileSystemModel->m_allFileSystemNodes[url]; + m_dFileSystemModel->m_allFileSystemNodes.remove(url); + rwLock->unlock(); + } +} + +const FileSystemNodePointer FileSystemNode::getFileSystemNode(FileSystemNode *parent) +{ + if (nullptr == parent) { + return FileSystemNodePointer(); + } + +// return FileSystemNodePointer(parent); + +// qDebug() << "start check map!"; +// qDebug() << "Count = " << QString::number(m_dFileSystemModel->m_allFileSystemNodes.count()); +// for (FileSystemNodePointer pointer : m_dFileSystemModel->m_allFileSystemNodes) +// { +// auto key = m_dFileSystemModel->m_allFileSystemNodes.key(pointer); +// qDebug() << "value = " << pointer.data(); +// qDebug() << "key = " << key; +// } + + +// qDebug() << "start check list!"; +// QList keyList = m_dFileSystemModel->m_allFileSystemNodes.uniqueKeys(); +// qDebug() << "Count = " << QString::number(keyList.count()); +// for (FileSystemNode *t_node : keyList) +// { +// qDebug() << "key = " << t_node; +// } + + QString url = parent->fileInfo->filePath(); + + rwLock->lockForWrite(); + if (!m_dFileSystemModel->m_allFileSystemNodes.contains(url)) { + FileSystemNodePointer tmpNode(parent); + m_dFileSystemModel->m_allFileSystemNodes[url] = tmpNode; + rwLock->unlock(); + return tmpNode; + } + + FileSystemNodePointer tmpNode1(m_dFileSystemModel->m_allFileSystemNodes[url]); + rwLock->unlock(); + return tmpNode1; +} + + + +FileNodeManagerThread::FileNodeManagerThread(DFileSystemModel *parent) + : QThread(parent) + , waitTimer(new QTimer(this)) + , enable(true) +{ + waitTimer->setSingleShot(true); + waitTimer->setInterval(50); + + connect(waitTimer, &QTimer::timeout, this, &FileNodeManagerThread::start); +} + +FileNodeManagerThread::~FileNodeManagerThread() +{ + stop(); +} + +void FileNodeManagerThread::start() +{ + if (fileQueue.isEmpty()) + return; + + QThread::start(); +} + +void FileNodeManagerThread::addFile(const DAbstractFileInfoPointer &info, bool append) +{ + if (!enable) + return; + + fileQueue.enqueue(qMakePair(append ? AppendFile : AddFile, info)); + + if (!isRunning()) { + if (!waitTimer->isActive()) { + // 确保从第一个文件操作开始,处理此文件操作做多不应超过1s + QTimer::singleShot(1000, this, &FileNodeManagerThread::start); + } + + waitTimer->start(); + } +} + +void FileNodeManagerThread::removeFile(const DAbstractFileInfoPointer &info) +{ + if (!enable) + return; + + fileQueue.enqueue(qMakePair(RmFile, info)); + + if (!isRunning()) { + if (!waitTimer->isActive()) { + // 确保从第一个文件操作开始,处理此文件操作做多不应超过1s + QTimer::singleShot(1000, this, &FileNodeManagerThread::start); + } + + waitTimer->start(); + } +} + +void FileNodeManagerThread::setRootNode(const FileSystemNodePointer &node) +{ + rootNode = node; +} + +void FileNodeManagerThread::setEnable(bool enable) +{ + this->enable = enable; +} + +void FileNodeManagerThread::stop() +{ + enable = false; + // 确保在timer的所在线程停止它 + waitTimer->metaObject()->invokeMethod(waitTimer, "stop"); + // 取消工作线程的等待,防止产生死锁 + semaphore.release(); + wait(); + + // 消除释放出的多余信号量 + if (semaphore.available() == 1) + semaphore.acquire(); + + fileQueue.clear(); +} + +void FileNodeManagerThread::run() +{ + // 缓存需要批量插入的文件信息列表 + QList backlogFileInfoList; + QList backlogDirInfoList; + // 使用计时器避免文件在批量插入列表中等待太久 + QTime timerOfFileList, timerOfDirList; + + auto insertInfoList = [&](int index, const QList &list) { + DThreadUtil::runInThread(&semaphore, model()->thread(), model(), &DFileSystemModel::beginInsertRows, + model()->createIndex(rootNode, 0), index, index + list.count() - 1); + + if (!enable) + return false; + + for (const DAbstractFileInfoPointer &fileInfo : list) { + if (!enable) { + return false; + } + + FileSystemNodePointer node = model()->createNode(rootNode.data(), fileInfo); + rootNode->insertChildren(index++, fileInfo->fileUrl(), node); + if (node->shouldHideByFilterRule(model()->advanceSearchFilter())) { + rootNode->setNodeVisible(node, false); + } + } + + DThreadUtil::runInThread(&semaphore, model()->thread(), model(), &DFileSystemModel::endInsertRows); + + return enable.load(); + }; + + auto disposeBacklogFileList = [&] { + if (backlogFileInfoList.isEmpty()) + { + return true; + } + + int row = rootNode->childrenCount(); + + if (!insertInfoList(row, backlogFileInfoList)) + return false; + + backlogFileInfoList.clear(); + + return true; + }; + + auto disposeBacklogDirList = [&] { + if (backlogDirInfoList.isEmpty()) + { + return true; + } + + int row = 0; + + forever + { + if (!enable) { + return false; + } + + if (row >= rootNode->childrenCount()) { + break; + } + + const FileSystemNodePointer &node = rootNode->getNodeByIndex(row); + + //因在自动整理时,超时会在次判定,导致文件夹以及分类文件夹会出现在扩展分类之前, + //所以加一个node->fileInfo->fileUrl().scheme() != DFMMD_SCHEME规避掉 + if (node->fileInfo->isFile() && node->fileInfo->fileUrl().scheme() != DFMMD_SCHEME) { + break; + } + + ++row; + } + + if (!insertInfoList(row, backlogDirInfoList)) + return false; + + backlogDirInfoList.clear(); + + return true; + }; + + auto removeInList = [&](QList &list, const DUrl & url) { + for (int i = 0; i < list.count(); ++i) { + if (list.at(i)->fileUrl() == url) { + list.removeAt(i); + + return true; + } + } + + return false; + }; + +begin: + + while (!fileQueue.isEmpty()) { + if (!enable) { + return; + } + + const QPair &v = fileQueue.dequeue(); + const DAbstractFileInfoPointer &fileInfo = v.second; + if (!fileInfo) { + continue; + } + const DUrl &fileUrl = fileInfo->fileUrl(); + + if (v.first == AddFile || v.first == AppendFile) { + if (rootNode->childContains(fileUrl)) + continue; + + int row = -1; + + if (model()->enabledSort()) { + row = 0; + + if (fileInfo->hasOrderly() && v.first == AddFile) { + DAbstractFileInfo::CompareFunction compareFun = fileInfo->compareFunByColumn(model()->sortRole()); + + if (compareFun) { + forever { + if (!enable) { + return; + } + + if (row >= rootNode->childrenCount()) { + break; + } + + const FileSystemNodePointer &node = rootNode->getNodeByIndex(row); + if (node) { + if (compareFun(fileInfo, node->fileInfo, model()->sortOrder())) { + break; + } + } + + ++row; + } + } else { + row = -1; + } + } else { + row = -1; + } + } + + if (row < 0) { + bool isFile = fileInfo->isFile(); + + // 先加到待插入列表 + if (isFile) { + if (backlogFileInfoList.isEmpty()) { + timerOfFileList.start(); + } else if (timerOfFileList.elapsed() > 1000) { + disposeBacklogFileList(); + timerOfFileList.start(); + } + + backlogFileInfoList << fileInfo; + } else { + if (backlogDirInfoList.isEmpty()) { + timerOfDirList.start(); + } else if (timerOfDirList.elapsed() > 1000) { + disposeBacklogDirList(); + timerOfDirList.start(); + } + + backlogDirInfoList << fileInfo; + } + } else { + if (!enable) { + return; + } + + DThreadUtil::runInThread(&semaphore, model()->thread(), model(), &DFileSystemModel::beginInsertRows, + model()->createIndex(rootNode, 0), row, row); + + if (!enable) { + return; + } + + FileSystemNodePointer node = model()->createNode(rootNode.data(), fileInfo); + rootNode->insertChildren(row, fileUrl, node); + + DThreadUtil::runInThread(&semaphore, model()->thread(), model(), &DFileSystemModel::endInsertRows); + } + } else { + // 先尝试从待插入列表中删除 + if (fileInfo->isFile()) { + if (removeInList(backlogFileInfoList, fileUrl)) { + continue; + } + } else if (removeInList(backlogDirInfoList, fileUrl)) { + continue; + } + + int row = rootNode->indexOfChild(fileUrl); + + if (!enable) { + return; + } + + if (row < 0) { + continue; + } + + if (DThreadUtil::runInThread(&semaphore, model()->thread(), model(), &DFileSystemModel::beginRemoveRows, + model()->createIndex(rootNode, 0), row, row)) { + if (!enable) { + return; + } + + Q_UNUSED(rootNode->takeNodeByIndex(row)); + DThreadUtil::runInThread(&semaphore, model()->thread(), model(), &DFileSystemModel::endRemoveRows); + } + } + } + + // 退出前确保所有文件都被处理 + disposeBacklogFileList(); + disposeBacklogDirList(); + + if (!enable) { + return; + } + + // 先等待一秒看是否还有数据 + QThread::msleep(300); + + if (!enable) { + return; + } + + if (!fileQueue.isEmpty()) { + goto begin; + } +} + +DFileSystemModelPrivate::DFileSystemModelPrivate(DFileSystemModel *qq) + : q_ptr(qq) + , rootNodeManager(new FileNodeManagerThread(qq)) + , needQuitUpdateChildren(false) +{ + _q_processFileEvent_runing.store(false); + if (DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowedHiddenFiles).toBool()) { + filters = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::System | QDir::Hidden; + } else { + filters = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::System; + } + + columnCompact = DFMApplication::instance()->appAttribute(DFMApplication::AA_ViewComppactMode).toBool(); + + qq->connect(rootNodeManager, &FileNodeManagerThread::finished, qq, [this, qq] { + // 在此线程结束时判断是否需要将model的状态设置为空闲 + if (!jobController || !jobController->isRunning()) + { + qq->setState(DFileSystemModel::Idle); + } + + //当遍历文件的耗时超过JobController::m_timeCeiling时, + //onJobFinished函数中拿到的文件不足,因为rootNodeManager还要处理剩余文件 + //因此在这里rootNodeManager处理完后,再次发送信号 关联bug#24863 + emit qq->sigJobFinished(); + }); +} + +DFileSystemModelPrivate::~DFileSystemModelPrivate() +{ + if (_q_processFileEvent_runing.load()) { + fileEventQueue.clear(); + } +} + +bool DFileSystemModelPrivate::passNameFilters(const FileSystemNodePointer &node) const +{ + if (nameFilters.isEmpty()) + return true; + + if (!node || !node->fileInfo) + return true; + + // 大量的过滤规则场景时,框选会出现卡顿,在性能较差的平台上较明显 + const DUrl fileUrl = node->fileInfo->fileUrl(); + if (nameFiltersMatchResultMap.contains(fileUrl)) + return nameFiltersMatchResultMap.value(fileUrl, false); + + // Check the name regularexpression filters + if (!(node->fileInfo->isDir() && (filters & QDir::Dirs))) { + const Qt::CaseSensitivity caseSensitive = (filters & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive; + const QString &fileDisplayName = node->fileInfo->fileDisplayName(); + QRegExp re("", caseSensitive, QRegExp::Wildcard); + + for (int i = 0; i < nameFilters.size(); ++i) { + re.setPattern(nameFilters.at(i)); + if (re.exactMatch(fileDisplayName)) { + nameFiltersMatchResultMap[fileUrl] = true; + return true; + } + } + + nameFiltersMatchResultMap[fileUrl] = false; + return false; + } + + nameFiltersMatchResultMap[fileUrl] = true; + return true; +} + +bool DFileSystemModelPrivate::passFileFilters(const DAbstractFileInfoPointer &info) const +{ + if (!(filters & (QDir::Dirs | QDir::AllDirs)) && info->isDir()) { + return false; + } + + if (!(filters & QDir::Files) && info->isFile()) { + return false; + } + + if ((filters & QDir::NoSymLinks) && info->isSymLink()) { + return false; + } + + if (!(filters & QDir::Hidden) && info->isHidden()) { + return false; + } + + if ((filters & QDir::Readable) && !info->isReadable()) { + return false; + } + + if ((filters & QDir::Writable) && !info->isWritable()) { + return false; + } + + if ((filters & QDir::Executable) && !info->isExecutable()) { + return false; + } + + return !info->isPrivate(); +} + +void DFileSystemModelPrivate::_q_onFileCreated(const DUrl &fileUrl, bool isPickUpQueue) +{ + Q_Q(DFileSystemModel); + + DAbstractFileInfoPointer info = DAbstractFileInfo::getFileInfo(fileUrl); + if (info) { + info->refresh(info->isGvfsMountFile()); + } else { + info = DFileService::instance()->createFileInfo(q, fileUrl); + } + + if ((!info || !passFileFilters(info)) && !isPickUpQueue) { + return; + } +// rootNodeManager->addFile(info); + mutex.lock(); + fileEventQueue.enqueue(qMakePair(AddFile, fileUrl)); + mutex.unlock(); + q->metaObject()->invokeMethod(q, QT_STRINGIFY(_q_processFileEvent), Qt::QueuedConnection); + +// if (!_q_processFileEvent_runing.load()) { +// queueWLock.lockForWrite(); +// while (!laterFileEventQueue.isEmpty()) { +// fileEventQueue.enqueue(laterFileEventQueue.dequeue()); +// } +// fileEventQueue.enqueue(qMakePair(AddFile, fileUrl)); +// queueWLock.unlock(); +// q->metaObject()->invokeMethod(q, QT_STRINGIFY(_q_processFileEvent), Qt::QueuedConnection); +// } else { +// queueWLock.lockForWrite(); +// laterFileEventQueue.enqueue(qMakePair(AddFile, fileUrl)); +// queueWLock.unlock(); +// } +} + +void DFileSystemModelPrivate::_q_onFileDeleted(const DUrl &fileUrl) +{ + Q_Q(DFileSystemModel); + +// rootNodeManager->removeFile(DFileService::instance()->createFileInfo(q, fileUrl)); + //当文件删除时,删除隐藏文件集中的隐藏 + QString absort = fileUrl.path().left(fileUrl.path().length() - fileUrl.fileName().length()); + DFMFileListFile flf(absort); + if (flf.contains(fileUrl.fileName())) { + flf.remove(fileUrl.fileName()); + flf.save(); + } + + mutex.lock(); + fileEventQueue.enqueue(qMakePair(RmFile, fileUrl)); + mutex.unlock(); + q->metaObject()->invokeMethod(q, QT_STRINGIFY(_q_processFileEvent), Qt::QueuedConnection); +// if (!_q_processFileEvent_runing.load()) { +// while (!laterFileEventQueue.isEmpty()) { +// fileEventQueue.enqueue(laterFileEventQueue.dequeue()); +// } +// fileEventQueue.enqueue(qMakePair(RmFile, fileUrl)); +// q->metaObject()->invokeMethod(q, QT_STRINGIFY(_q_processFileEvent), Qt::QueuedConnection); +// } else { +// laterFileEventQueue.enqueue(qMakePair(RmFile, fileUrl)); +// } +} + +void DFileSystemModelPrivate::_q_onFileUpdated(const DUrl &fileUrl) +{ + Q_Q(DFileSystemModel); + + //fix 31327, 监控./.hidden文件更改 + //bug#30019 task#40201 补充 + if ((fileUrl.fileName() == ".hidden") && !(q->filters() & QDir::Hidden)) { + q->refresh(); + } + + const FileSystemNodePointer &node = rootNode; + + if (!node) { + return; + } + + const QModelIndex &index = q->index(fileUrl); + + if (!index.isValid()) { + return; + } + + if (const DAbstractFileInfoPointer &fileInfo = q->fileInfo(index)) { + fileInfo->refresh(true); + } + + q->parent()->parent()->update(index); +// emit q->dataChanged(index, index); + //recentfile变更需要调整排序 + if (fileUrl.isRecentFile()) { + //fileinfo已在recentcontroller中更新,只需要重排序 + q->sort(); + } +} + +void DFileSystemModelPrivate::_q_onFileUpdated(const DUrl &fileUrl, const int &isExternalSource) +{ + Q_Q(DFileSystemModel); + + const FileSystemNodePointer &node = rootNode; + //fix 27828 文件属性改变刷新一次缓存数据,这里只是刷缓存数据 + if (!node) { + return; + } + + const QModelIndex &index = q->index(fileUrl); + + if (!index.isValid()) { + return; + } + + if (const DAbstractFileInfoPointer &fileInfo = q->fileInfo(index)) { + if (isExternalSource) { + fileInfo->refresh(fileInfo->isGvfsMountFile()); + } + } + + q->parent()->parent()->update(index); +// emit q->dataChanged(index, index); +} + +void DFileSystemModelPrivate::_q_onFileRename(const DUrl &from, const DUrl &to) +{ + Q_Q(DFileSystemModel); + + //如果被重命名的目录是root目录,则不刷新该目录,而是直接退回到上层目录 + bool isLocalFile = from.isLocalFile() || (from.isVaultFile() || to.isVaultFile()); + if (isLocalFile && from.path() == rootNode->dataByRole(DFileSystemModel::Roles::FilePathRole).toString()) { + QString trashPath = DFMStandardPaths::location(DFMStandardPaths::TrashPath); + bool isMoveToTrash = to.toLocalFile().contains(trashPath); + if (!isMoveToTrash && !to.toLocalFile().isEmpty()) { + // re-enter directory if tab root directory renamed. + DFileView *fileview = static_cast(q->parent()->parent()); + fileSignalManager->requestRedirectTabUrl(fileview->rootUrl(), to); + } + + return; + } + _q_onFileDeleted(from); + _q_onFileCreated(to); +} + +void DFileSystemModelPrivate::_q_processFileEvent() +{ + Q_Q(DFileSystemModel); + //处理异步正在执行此函数,但是当前类释放了 + QPointer me = q; + if (_q_processFileEvent_runing.load()) { + return; + } + + // CAS + bool expect = false; + _q_processFileEvent_runing.compare_exchange_strong(expect, true); + + while (checkFileEventQueue()) { + if (!q->isDesktop) //紧急修复,由于修复bug#33209添加了一次事件循环的处理,导致桌面的自动排列在删除,恢复文件时显示异常 + qApp->processEvents(); + + if (me.isNull()) { // 当前窗口被关闭以后,me 指针指向的窗口会马上被析构,后面的流程不需要再走了 + return; + } + mutex.lock(); + const QPair &event = fileEventQueue.dequeue(); + mutex.unlock(); + const DUrl &fileUrl = event.second; + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(q, fileUrl); + + if (!info) { + continue; + } + if (event.first != AddFile) { + info->refresh(info->isGvfsMountFile()); + } + const DUrl &rootUrl = q->rootUrl(); + const DAbstractFileInfoPointer rootinfo = fileService->createFileInfo(q, rootUrl); + DUrl nparentUrl(info->parentUrl()); + DUrl nfileUrl(fileUrl); + + if (rootUrl.scheme() == BURN_SCHEME) { + QRegularExpression burn_rxp("^(.*?)/(" BURN_SEG_ONDISC "|" BURN_SEG_STAGING ")(.*)$"); + QString rxp_after(QString("\\1/%1\\3").arg(rootUrl.burnIsOnDisc() ? BURN_SEG_ONDISC : BURN_SEG_STAGING)); + nfileUrl.setPath(nfileUrl.path().replace(burn_rxp, rxp_after)); + nparentUrl.setPath(nparentUrl.path().replace(burn_rxp, rxp_after)); + if (!nparentUrl.path().endsWith('/') && rootUrl.path().endsWith("/")) { + nparentUrl.setPath(nparentUrl.path() + "/"); + } + } + + if (nfileUrl == rootUrl) { + if (event.first == RmFile) { + //! close tab if root url deleted. + emit fileSignalManager->requestCloseTab(nfileUrl); + //! return to parent. + emit q->rootUrlDeleted(rootUrl); + } + + // It must be refreshed when the root url itself is deleted or newly created + q->refresh(); + continue; + } + if (nparentUrl != rootUrl) { + continue; + } + // Will refreshing the file info meta data + info->refresh(); + if (event.first == AddFile) { + q->addFile(info); + q->selectAndRenameFile(fileUrl); + } else {// rm file event + // q->update();/*解决文管多窗口删除文件的时候,文官会崩溃的问题*/ + // todo: 此处引起效率变低,暂时注释 + q->remove(fileUrl); + } + if (me.isNull()) { + return; + } + } + _q_processFileEvent_runing.store(false); +} + +bool DFileSystemModelPrivate::checkFileEventQueue() +{ + mutex.lock(); + bool isemptyqueue = fileEventQueue.isEmpty(); + mutex.unlock(); + return !isemptyqueue; +} + +DFileSystemModel::DFileSystemModel(DFileViewHelper *parent) + : QAbstractItemModel(parent) + , d_ptr(new DFileSystemModelPrivate(this)) +{ + qRegisterMetaType(QT_STRINGIFY(State)); + qRegisterMetaType(QT_STRINGIFY(DAbstractFileInfoPointer)); + + m_smForDragEvent = new QSharedMemory(); +} + +DFileSystemModel::~DFileSystemModel() +{ + Q_D(DFileSystemModel); + + d->needQuitUpdateChildren = true; + + isNeedToBreakBusyCase = true; // 清场的时候,必须让其他资源线程跳出相关流程 + + if (m_smForDragEvent) { + delete m_smForDragEvent; + m_smForDragEvent = nullptr; + } + + //fix bug 33014 +// releaseJobController(); + + if (d->jobController) { + disconnect(d->jobController, &JobController::addChildren, this, &DFileSystemModel::onJobAddChildren); + disconnect(d->jobController, &JobController::finished, this, &DFileSystemModel::onJobFinished); + disconnect(d->jobController, &JobController::childrenUpdated, this, &DFileSystemModel::updateChildrenOnNewThread); + d->jobController->stopAndDeleteLater(); + } + + QMutexLocker locker(&m_mutex); // 必须等待其他 资源性线程结束,否则 要崩溃 + + if (d->updateChildrenFuture.isRunning()) { + d->updateChildrenFuture.cancel(); + d->updateChildrenFuture.waitForFinished(); + } + + if (d->watcher) { + d->watcher->deleteLater(); + } + + if (d->rootNodeManager->isRunning()) { + d->rootNodeManager->stop(); + } + + d->needQuitUpdateChildren = false; + QMutexLocker lk(&d_ptr->mutexFlags); + + qDebug() << "DFileSystemModel is released soon!"; +} + +DFileViewHelper *DFileSystemModel::parent() const +{ + return static_cast(QAbstractItemModel::parent()); +} + +QModelIndex DFileSystemModel::index(const DUrl &fileUrl, int column) +{ + Q_D(DFileSystemModel); + + if (!fileUrl.isValid()) + return QModelIndex(); + + if (fileUrl == rootUrl()) { + return createIndex(d->rootNode, column); + } + + if (!d->rootNode) { + return QModelIndex(); + } + +// const FileSystemNodePointer &node = d->urlToNode.value(fileUrl); + const FileSystemNodePointer &node = d->rootNode->getNodeByUrl(fileUrl); + + if (!node) { + return QModelIndex(); + } + + QModelIndex idx = createIndex(node, column); + + return idx; +} + +QModelIndex DFileSystemModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_D(const DFileSystemModel); + + if (row < 0 || column < 0/* || row >= rowCount(parent) || column >= columnCount(parent)*/) { + return QModelIndex(); + } + + const FileSystemNodePointer &parentNode = parent.isValid() + ? FileSystemNodePointer(getNodeByIndex(parent)) + : d->rootNode; + + if (!parentNode) { + return QModelIndex(); + } + + FileSystemNode *childNode = parentNode->getNodeByIndex(row).data(); + + if (!childNode) { + return QModelIndex(); + } + + return createIndex(row, column, childNode); +} + +QModelIndex DFileSystemModel::parent(const QModelIndex &child) const +{ + const FileSystemNodePointer &indexNode = getNodeByIndex(child); + + if (!indexNode || !indexNode->parent) { + return QModelIndex(); + } + + FileSystemNodePointer parentNode(indexNode->parent); + + return createIndex(parentNode, 0); +} + +int DFileSystemModel::rowCount(const QModelIndex &parent) const +{ + Q_D(const DFileSystemModel); + + const FileSystemNodePointer &parentNode = parent.isValid() + ? FileSystemNodePointer(getNodeByIndex(parent)) + : d->rootNode; + + if (!parentNode) { + return 0; + } + + return parentNode->childrenCount(); +} + +int DFileSystemModel::columnCount(const QModelIndex &parent) const +{ + Q_D(const DFileSystemModel); + + int columnCount = parent.column() > 0 ? 0 : DEFAULT_COLUMN_COUNT; + if (!d->rootNode) { + return columnCount; + } + + const DAbstractFileInfoPointer ¤tFileInfo = d->rootNode->fileInfo; + + if (currentFileInfo) { + columnCount += currentFileInfo->userColumnRoles().count(); + } + + return columnCount; +} + +QVariant DFileSystemModel::columnNameByRole(int role, const QModelIndex &index) const +{ + Q_D(const DFileSystemModel); + +// const AbstractFileInfoPointer &fileInfo = this->fileInfo(index.isValid() ? index : d->activeIndex); + const DAbstractFileInfoPointer &fileInfo = index.isValid() ? this->fileInfo(index) : d->rootNode->fileInfo; + + if (fileInfo) { + return fileInfo->userColumnDisplayName(role); + } + + return QVariant(); +} + +int DFileSystemModel::columnWidthByRole(int role) const +{ + Q_D(const DFileSystemModel); + + const DAbstractFileInfoPointer ¤tFileInfo = d->rootNode->fileInfo; + + if (currentFileInfo) { + return currentFileInfo->userColumnWidth(role, parent()->parent()->fontMetrics()); + } + + return 140; +} + +bool DFileSystemModel::columnDefaultVisibleForRole(int role, const QModelIndex &index) const +{ + Q_D(const DFileSystemModel); + +// const AbstractFileInfoPointer &fileInfo = this->fileInfo(index.isValid() ? index : d->activeIndex); + const DAbstractFileInfoPointer &fileInfo = index.isValid() ? this->fileInfo(index) : d->rootNode->fileInfo; + + if (fileInfo) { + return fileInfo->columnDefaultVisibleForRole(role); + } + + return true; +} + +bool DFileSystemModel::hasChildren(const QModelIndex &parent) const +{ + if (!parent.isValid()) { // drives + return false; + } + + const FileSystemNodePointer &indexNode = getNodeByIndex(parent); + + return indexNode && isDir(indexNode); +} + +QVariant DFileSystemModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.model() != this) { + return QVariant(); + } + + const FileSystemNodePointer &indexNode = getNodeByIndex(index); + + if (!indexNode) { + return QVariant(); + } + + switch (role) { + case Qt::EditRole: + case Qt::DisplayRole: { + int column_role = columnToRole(index.column()); + + const QVariant &d = data(index.sibling(index.row(), 0), column_role); + + if (d.canConvert()) { + return d; + } else if (d.canConvert>()) { + return qvariant_cast>(d).first; + } else if (d.canConvert>>()) { + return qvariant_cast>>(d).first; + } + + return d; + } + case FilePathRole: + case FileDisplayNameRole: + case FileNameRole: + case FileNameOfRenameRole: + case FileBaseNameRole: + case FileBaseNameOfRenameRole: + case FileSuffixRole: + case FileSuffixOfRenameRole: + return indexNode->dataByRole(role); + case FileIconRole: + if (index.column() == 0) { + return indexNode->fileInfo->fileIcon(); + } + break; + case Qt::TextAlignmentRole: + case FileLastModifiedRole: + case FileLastModifiedDateTimeRole: + case FileSizeRole: + case FileSizeInKiloByteRole: + case FileMimeTypeRole: + case FileCreatedRole: + case FilePinyinName: + return indexNode->dataByRole(role); + case Qt::ToolTipRole: { + const QList column_role_list = parent()->columnRoleList(); + + if (column_role_list.length() < 2) { + break; + } + + const QPoint &cursor_pos = parent()->parent()->mapFromGlobal(QCursor::pos()); + QStyleOptionViewItem option; + + option.init(parent()->parent()); + parent()->initStyleOption(&option, index); + option.rect = parent()->parent()->visualRect(index); + const QList &geometries = parent()->itemDelegate()->paintGeomertys(option, index); + + // 从1开始是为了排除掉icon区域 + for (int i = 1; i < geometries.length() && i <= column_role_list.length(); ++i) { + const QRect &rect = geometries.at(i); + + if (rect.left() <= cursor_pos.x() && rect.right() >= cursor_pos.x()) { + const QString &tooltip = data(index, columnActiveRole(i - 1)).toString(); + + if (option.fontMetrics.width(tooltip, -1, Qt::Alignment(index.data(Qt::TextAlignmentRole).toInt())) > rect.width()) { + return tooltip; + } else { + break; + } + } + } + + return QString(); + } + case ExtraProperties: + return indexNode->dataByRole(role); + case FileIconModelToolTipRole: { // fix bug 202007010029 由于 list 视图处理 tooltip 的代码通用性太弱,所以这里新增一个 role 用来返回 tooltip + /*fix bug 63708 tooltip应该显示的是显示的名字,不是实际的名字*/ + QString strToolTip = data(index, Qt::DisplayRole).toString(); + QStyleOptionViewItem option; + + option.init(parent()->parent()); + parent()->initStyleOption(&option, index); + option.rect = parent()->parent()->visualRect(index); + const QList &geometries = parent()->itemDelegate()->paintGeomertys(option, index); + if (geometries.count() < 3) + return QString(); + if (option.fontMetrics.width(strToolTip) > geometries[1].width() * 2) { + //主目录下的用户文件是做过特殊处理的(文档、音乐等),在这里也需要对长度达标的目录做特殊过滤 + //否则文档和下载目录会显示hoverTip + const QString filePath = data(index, FilePathRole).toString(); + const QString stdDocPath = QStandardPaths::writableLocation(QStandardPaths::StandardLocation::DocumentsLocation); + const QString stdDownPath = QStandardPaths::writableLocation(QStandardPaths::StandardLocation::DownloadLocation); + if (filePath == stdDocPath || filePath == stdDownPath || filePath == "/data" + stdDocPath || filePath == "/data" + stdDownPath) + return QString(); + + return strToolTip; + } + return QString(); + } + + default: { + const DAbstractFileInfoPointer &fileInfo = indexNode->fileInfo; + + return fileInfo->userColumnData(role); + } + } + + return QVariant(); +} + +QVariant DFileSystemModel::headerData(int column, Qt::Orientation, int role) const +{ + Q_D(const DFileSystemModel); + + if (role == Qt::DisplayRole) { + int column_role = columnToRole(column); + + if (column_role < FileUserRole) { + return roleName(column_role); + } else { +// const AbstractFileInfoPointer &fileInfo = this->fileInfo(d->activeIndex); + const DAbstractFileInfoPointer &fileInfo = d->rootNode->fileInfo; + + if (fileInfo) { + if (fileInfo->columnIsCompact()) { + const QList roles = fileInfo->userColumnChildRoles(column); + + if (!roles.isEmpty()) { + column_role = d->columnActiveRole.value(column, roles.first()); + } + } + + return fileInfo->userColumnDisplayName(column_role); + } + + return QVariant(); + } + } + + return QVariant(); +} + +QString DFileSystemModel::roleName(int role) +{ + switch (role) { + case FileDisplayNameRole: + case FileNameRole: + return tr("Name"); + case FileLastModifiedRole: + return tr("Time modified"); + case FileSizeRole: + return tr("Size"); + case FileMimeTypeRole: + return tr("Type"); + case FileCreatedRole: + return tr("Time created"); + case FileLastReadRole: + return tr("Last access"); + case FilePathRole: + return tr("Path"); + default: + return QString(); + } +} + +int DFileSystemModel::columnToRole(int column) const +{ + Q_D(const DFileSystemModel); + + if (!d->rootNode) + return UnknowRole; + + const DAbstractFileInfoPointer &fileInfo = d->rootNode->fileInfo; + + if (fileInfo) { + //获取修改过顺序后的列属性 + DUrl url = rootUrl(); + //搜索目录统一从"search:"项中取配置数据 + if (url.isSearchFile()) { + url = DUrl(); + url.setScheme(SEARCH_SCHEME); + } + const QVariantMap &map = DFMApplication::appObtuselySetting()->value("FileViewState", url).toMap(); + if (map.contains("headerList")) { + const QVariantList &indexList = map.value("headerList").toList(); + if (indexList.length() > column) + return indexList.at(column).toInt(); + } + + return fileInfo->userColumnRoles().value(column, UnknowRole); + } + + return UnknowRole; +} + +int DFileSystemModel::roleToColumn(int role) const +{ + Q_D(const DFileSystemModel); + + if (!d->rootNode) { + return -1; + } + +// const AbstractFileInfoPointer &fileInfo = this->fileInfo(d->activeIndex); + const DAbstractFileInfoPointer &fileInfo = d->rootNode->fileInfo; + + if (fileInfo) { + int column = fileInfo->userColumnRoles().indexOf(role); + DUrl url = rootUrl(); + //搜索目录统一从"search:"项中取配置数据 + if (url.isSearchFile()) { + url = DUrl(); + url.setScheme(SEARCH_SCHEME); + } + //获取修改过顺序后的列属性的索引 + const QVariantMap &map = DFMApplication::appObtuselySetting()->value("FileViewState", url).toMap(); + if (map.contains("headerList")) { + const QVariantList &indexList = map.value("headerList").toList(); + if (indexList.length() > column) + column = indexList.indexOf(role); + } + + if (column < 0) { + return -1; + } + + return column; + } + + return -1; +} + +void DFileSystemModel::fetchMore(const QModelIndex &parent) +{ + Q_D(DFileSystemModel); + + if (d->eventLoop || !d->rootNode) { + return; + } + + isNeedToBreakBusyCase = false; // 这是fileview 切换的入口,切换的时候 置 flag,不要停止正常流程 + + const FileSystemNodePointer &parentNode = getNodeByIndex(parent); + + if (!parentNode || parentNode->populatedChildren) { + return; + } + + // + if (!releaseJobController()) { + return; + } + qInfo() << "fetchMore start traverse all files in current dir = " << parentNode->fileInfo->fileUrl(); + d->jobController = fileService->getChildrenJob(this, parentNode->fileInfo->fileUrl(), QStringList(), d->filters, + QDirIterator::NoIteratorFlags, false, parentNode->fileInfo->isGvfsMountFile()); + + if (!d->jobController) { + return; + } + if (!d->rootNode->fileInfo->hasOrderly()) { + // 对于无需列表, 较少返回结果的等待时间 + d->jobController->setTimeCeiling(100); + } + + connect(d->jobController, &JobController::addChildren, this, &DFileSystemModel::onJobAddChildren, Qt::QueuedConnection); + connect(d->jobController, &JobController::finished, this, &DFileSystemModel::onJobFinished, Qt::QueuedConnection); + connect(d->jobController, &JobController::childrenUpdated, this, &DFileSystemModel::updateChildrenOnNewThread, Qt::DirectConnection); + /// make root file to active + d->rootNode->fileInfo->makeToActive(); + /// start file watcher + if (d->watcher) { + d->watcher->startWatcher(); + } + parentNode->populatedChildren = true; + + setState(Busy); + + d->childrenUpdated = false; + // + d->jobController->start(); + d->rootNodeManager->setEnable(true); +} + +Qt::ItemFlags DFileSystemModel::flags(const QModelIndex &index) const +{ + Q_D(const DFileSystemModel); + QPointer me = const_cast(this); +// QMutexLocker lk(&d_ptr->mutexFlags); + if (!me) { + return Qt::NoItemFlags; + } + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + if (!index.isValid()) { + return flags; + } + const FileSystemNodePointer &indexNode = getNodeByIndex(index); + + if (!indexNode) { + return flags; + } + if (!d->passNameFilters(indexNode)) { + flags &= ~(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + // ### TODO you shouldn't be able to set this as the current item, task 119433 + return flags & ~ indexNode->fileInfo->fileItemDisableFlags(); + } + + flags |= Qt::ItemIsDragEnabled; + if ((index.column() == 0)) { + if (d->readOnly) { + return flags; + } + //fix bug 29914 fileInof为nullptr + if (indexNode && indexNode->fileInfo && indexNode->fileInfo->canRename()) { + flags |= Qt::ItemIsEditable; + } + if (indexNode && indexNode->fileInfo && indexNode->fileInfo->isWritable()) { + //candrop十分耗时,在不关心Qt::ItemDropEnable的调用时ignoreDropFlag为true,不调用candrop,节省时间,bug#10926 + if (!ignoreDropFlag && indexNode && indexNode->fileInfo && indexNode->fileInfo->canDrop()) { + flags |= Qt::ItemIsDropEnabled; + } else { + flags |= Qt::ItemNeverHasChildren; + } + } + } else { + flags = flags & ~Qt::ItemIsSelectable; + } + return flags & ~ indexNode->fileInfo->fileItemDisableFlags(); +} + +Qt::DropActions DFileSystemModel::supportedDragActions() const +{ + Q_D(const DFileSystemModel); + + if (d->rootNode) { + return d->rootNode->fileInfo->supportedDragActions(); + } + + return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; +} + +Qt::DropActions DFileSystemModel::supportedDropActions() const +{ + Q_D(const DFileSystemModel); + + if (d->rootNode) { + return d->rootNode->fileInfo->supportedDropActions(); + } + + return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; +} + +QStringList DFileSystemModel::mimeTypes() const +{ + return QStringList(QLatin1String("text/uri-list")); +} + +bool DFileSystemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ +// qDebug() << "drop mime data"; + Q_UNUSED(row); + Q_UNUSED(column); + if (!parent.isValid()) { + return false; + } + + bool success = true; + DUrl toUrl = getUrlByIndex(parent); + + DUrlList urlList = DUrl::fromQUrlList(data->urls()); + + const DAbstractFileInfoPointer &info = fileService->createFileInfo(this, toUrl); + + // 当为拖拽压缩时 + if (info->canDragCompress() + && !info->isDir()) { // fix 101867: 如果是文件夹 就不走压缩逻辑 + qDebug() << "执行拖拽压缩"; + return FileUtils::appendCompress(toUrl, urlList); + } + + for (DUrl &u : urlList) { + // we only do redirection for burn:// urls for the fear of screwing everything up again + if (u.scheme() == BURN_SCHEME) { + for (DAbstractFileInfoPointer fi = fileService->createFileInfo(nullptr, u); fi->canRedirectionFileUrl(); fi = fileService->createFileInfo(nullptr, u)) { + u = fi->redirectedFileUrl(); + } + } + } + + if (info->isSymLink()) { + toUrl = info->rootSymLinkTarget(); + } + + if (DFMGlobal::isTrashDesktopFile(toUrl)) { + toUrl = DUrl::fromTrashFile("/"); + fileService->moveToTrash(this, urlList); + return true; + } else if (DFMGlobal::isComputerDesktopFile(toUrl)) { + return true; + } else if (DFMGlobal::isDesktopFile(toUrl)) { + return FileUtils::launchApp(toUrl.toLocalFile(), DUrl::toStringList(urlList)); + } + + switch (action) { + case Qt::CopyAction: + if (urlList.count() > 0) { + // blumia: 如果不在新线程跑的话,用户就只能在复制完毕之后才能进行新的拖拽操作。 + QtConcurrent::run([ = ]() { + fileService->pasteFile(this, DFMGlobal::CopyAction, toUrl, urlList); + }); + } + break; + case Qt::LinkAction: + break; + case Qt::MoveAction: + // NOTE(zccrs): 为MoveAction时,如果执行成功,QAbstractItemView会调用clearOrRemove移除此item + // 所以此处必须判断是否粘贴完成,不然会导致此item消失 + // fix bug 63341 ,开启普通文件删除提示功能后,打开最近使用和回收站两个窗口,拖拽最近使用到回收站,在还没有 + // 弹出对话框的时候,快速框选最近访问窗口。这时弹窗出现(使用的runinMainThread)使用的exec就会开启一个本地事件循环,将框选事件加入本地循环 + // 执行,框选事件又在等待drag事件结束(mousemove事件结束),本地事件又阻塞drag事件,相互等待。使用线程去执行 + // 业务逻辑,让drop事件快速返回。 + if (toUrl.isTrashFile()) { + QtConcurrent::run([=]() { + fileService->moveToTrash(this, urlList); + }); + break; + } + success = !fileService->pasteFile(this, DFMGlobal::CutAction, toUrl, urlList).isEmpty(); + break; + default: + return false; + } + + return success; +} + +QMimeData *DFileSystemModel::mimeData(const QModelIndexList &indexes) const +{ + QList urls; + QSet urls_set; + QList::const_iterator it = indexes.begin(); + + for (; it != indexes.end(); ++it) { + if ((*it).column() == 0) { + const DAbstractFileInfoPointer &fileInfo = this->fileInfo(*it); + const QUrl &url = fileInfo->mimeDataUrl(); + + if (urls_set.contains(url)) { + continue; + } + + urls << url; + urls_set << url; + } + } + + QMimeData *data = new QMimeData(); + + DFMGlobal::setMimeDataUserID(data); + data->setUrls(urls); + qInfo() << data->data(MIME_USER_ID); +// data->setText(urls.first().path()); +// data->setData("forDragEvent", urls.first().toEncoded()); +// FOR_DRAGEVENT = urls; +// qDebug() << "Set FOR_DRAGEVENT urls FOR_DRAGEVENT count = " << FOR_DRAGEVENT.length(); + m_smForDragEvent->setKey(DRAG_EVENT_URLS); + //qDebug() << DRAG_EVENT_URLS; + if (m_smForDragEvent->isAttached()) { + if (!m_smForDragEvent->detach()) { + return data; + } + } + QBuffer buffer; + buffer.open(QBuffer::ReadWrite); + QDataStream out(&buffer); + out << urls; + //int size = static_cast(buffer.size()); + //fix task 21485 分配一个固定的5M内存 + bool bcanwrite = m_smForDragEvent->create(5 * 1024 * 1024); + if (bcanwrite || m_smForDragEvent->error() == QSharedMemory::AlreadyExists) { + //因为创建失败,就没有连接内存,所以写失败 + if (!bcanwrite) { + m_smForDragEvent->attach(); + } + m_smForDragEvent->lock(); + char *to = static_cast(m_smForDragEvent->data()); + const char *from = buffer.data().data(); + memcpy(to, from, qMin(static_cast(buffer.size()), static_cast(m_smForDragEvent->size()))); + m_smForDragEvent->unlock(); + qDebug() << " write mem finish. " << m_smForDragEvent->errorString() << m_smForDragEvent->size(); + } + return data; +} + +bool DFileSystemModel::canFetchMore(const QModelIndex &parent) const +{ + const FileSystemNodePointer &parentNode = getNodeByIndex(parent); + + if (!parentNode) { + return false; + } + + return (parentNode->fileInfo->canFetch() || !parentNode->fileInfo->exists()) && !parentNode->populatedChildren; +} + +QModelIndex DFileSystemModel::setRootUrl(const DUrl &fileUrl) +{ + Q_D(DFileSystemModel); + //首次进入目录记录过滤规则 + if (isFirstRun) { + m_filters = d->filters; + isFirstRun = false; + } + qDebug() << fileUrl; + //非回收站还原规则 + if (!fileUrl.isTrashFile()) { + d->filters = m_filters; + } + //回收站设置规则 + else { + d->filters = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::System | QDir::Hidden; + } + // Restore state + setState(Idle); + + disconnect(fileSignalManager, &FileSignalManager::requestRefreshFileModel, this, &DFileSystemModel::refresh); + if (fileUrl == DUrl::fromUserShareFile("/")) { + connect(fileSignalManager, &FileSignalManager::requestRefreshFileModel, this, &DFileSystemModel::refresh); + } + + if (d->eventLoop) { + d->eventLoop->exit(1); + } + + // 断开获取上个目录的job的信号 + if (d->jobController) { + disconnect(d->jobController, &JobController::addChildren, this, &DFileSystemModel::onJobAddChildren); + disconnect(d->jobController, &JobController::finished, this, &DFileSystemModel::onJobFinished); + disconnect(d->jobController, &JobController::childrenUpdated, this, &DFileSystemModel::updateChildrenOnNewThread); + } + + if (d->updateChildrenFuture.isRunning()) { + // 使用QFuture::cancel() 函数无效,定义个变量控制线程的退出 + d->needQuitUpdateChildren = true; + d->updateChildrenFuture.cancel(); + d->updateChildrenFuture.waitForFinished(); + d->needQuitUpdateChildren = false; + } + + if (d->rootNode) { +// const DUrl rootFileUrl = d->rootNode->fileInfo->fileUrl(); + +// if (fileUrl == rootFileUrl) { +// return createIndex(d->rootNode, 0); +// } +// 对于相同路径也要走同样的流程 + + clear(); + } + + if (d->watcher) { + disconnect(d->watcher, nullptr, this, nullptr); + d->watcher->deleteLater(); + } + +// d->rootNode = d->urlToNode.value(fileUrl); + + d->rootNode = createNode(Q_NULLPTR, fileService->createFileInfo(this, fileUrl), &d->rootNodeRWLock); + + d->rootNodeManager->stop(); + d->rootNodeManager->setRootNode(d->rootNode); + d->watcher = DFileService::instance()->createFileWatcher(this, fileUrl); + d->columnActiveRole.clear(); + + if (d->watcher) + d->watcher->setParent(this); + + if (d->watcher && !d->rootNode->fileInfo->isPrivate()) { + connect(d->watcher, SIGNAL(fileAttributeChanged(DUrl, int)), + this, SLOT(_q_onFileUpdated(DUrl, int))); + connect(d->watcher, SIGNAL(fileDeleted(DUrl)), + this, SLOT(_q_onFileDeleted(DUrl))); + connect(d->watcher, SIGNAL(subfileCreated(DUrl)), + this, SLOT(_q_onFileCreated(DUrl))); + connect(d->watcher, SIGNAL(fileMoved(DUrl, DUrl)), + this, SLOT(_q_onFileRename(DUrl, DUrl))); + connect(d->watcher, SIGNAL(fileModified(DUrl)), + this, SLOT(_q_onFileUpdated(DUrl))); + } + + return index(fileUrl); +} + +DUrl DFileSystemModel::rootUrl() const +{ + Q_D(const DFileSystemModel); + + return d->rootNode ? d->rootNode->fileInfo->fileUrl() : DUrl(); +} + +DUrlList DFileSystemModel::sortedUrls() +{ + Q_D(const DFileSystemModel); + if (!d->rootNode) { + return DUrlList(); + } + return d->rootNode->getChildrenUrlList(); +} + +DUrlList DFileSystemModel::getNoTransparentUrls() +{ + DUrlList lst = sortedUrls(); + DUrlList lstValid; + for (DUrl url : lst) { + QModelIndex idx = index(url); + if (!idx.isValid()) + continue; + if (parent()->isTransparent(idx)) + continue; + lstValid << url; + } + return lstValid; +} + +DUrl DFileSystemModel::getUrlByIndex(const QModelIndex &index) const +{ + const FileSystemNodePointer &node = getNodeByIndex(index); + if (!node) { + return DUrl(); + } + + return node->fileInfo->fileUrl(); +} + +void DFileSystemModel::setSortColumn(int column, Qt::SortOrder order) +{ + int role = columnActiveRole(column); + setSortRole(role, order); +} + +void DFileSystemModel::setSortRole(int role, Qt::SortOrder order) +{ + Q_D(DFileSystemModel); + + d->sortRole = role; + d->srotOrder = order; +} + +void DFileSystemModel::setNameFilters(const QStringList &nameFilters) +{ + Q_D(DFileSystemModel); + + if (d->nameFilters == nameFilters) { + return; + } + + d->nameFiltersMatchResultMap.clear(); + d->nameFilters = nameFilters; + + emitAllDataChanged(); +} + +void DFileSystemModel::setFilters(QDir::Filters filters) +{ + Q_D(DFileSystemModel); + + m_filters = filters; //记录文件过滤规则 + if (d->filters == filters) { + return; + } + + d->nameFiltersMatchResultMap.clear(); + d->filters = filters; + + refresh(); +} + +void DFileSystemModel::setAdvanceSearchFilter(const QMap &formData, bool turnOn, bool updateView) +{ + Q_D(DFileSystemModel); + + if (!advanceSearchFilter()) { + d->advanceSearchFilter.reset(new FileFilter); + } + + advanceSearchFilter()->filterEnabled = turnOn; + + if (advanceSearchFilter()->filterRule == formData) { + return; + } + + advanceSearchFilter()->filterRule = formData; + + advanceSearchFilter()->f_comboValid[SEARCH_RANGE] = true; + advanceSearchFilter()->f_includeSubDir = advanceSearchFilter()->filterRule[SEARCH_RANGE].toBool(); + + advanceSearchFilter()->f_typeString = advanceSearchFilter()->filterRule[FILE_TYPE].toString(); + advanceSearchFilter()->f_comboValid[FILE_TYPE] = !advanceSearchFilter()->f_typeString.isEmpty(); + + advanceSearchFilter()->f_comboValid[SIZE_RANGE] = advanceSearchFilter()->filterRule[SIZE_RANGE].canConvert >(); + if (advanceSearchFilter()->f_comboValid[SIZE_RANGE]) { + advanceSearchFilter()->f_sizeRange = advanceSearchFilter()->filterRule[SIZE_RANGE].value >(); + } + + // 计算时间过滤条件 + auto calDateFilter = [ = ](_asb_LabelIndex labelIndex, QDateTime & startTime, QDateTime & endTime) { + int dateRange = advanceSearchFilter()->filterRule[labelIndex].toInt(); + advanceSearchFilter()->f_comboValid[labelIndex] = (dateRange != 0); + + if (advanceSearchFilter()->f_comboValid[labelIndex]) { + int firstDayOfWeek = QLocale::system().firstDayOfWeek(); + QDate today = QDate::currentDate(); + QDate tomorrow = QDate::currentDate().addDays(+1); + int dayDist = today.dayOfWeek() - firstDayOfWeek; + if (dayDist < 0) dayDist += 7; + + switch (dateRange) { // see DFMAdvanceSearchBar::initUI() for all cases + case 1: + startTime = QDateTime(today); + endTime = QDateTime(tomorrow); + break; + case 2: + startTime = QDateTime(today).addDays(-1); + endTime = QDateTime(today); + break; + case 7: + startTime = QDateTime(today).addDays(0 - dayDist); + endTime = QDateTime(tomorrow); + break; + case 14: + startTime = QDateTime(today).addDays(-7 - dayDist); + endTime = QDateTime(today).addDays(0 - dayDist); + break; + case 30: + startTime = QDateTime(QDate(today.year(), today.month(), 1)); + endTime = QDateTime(tomorrow); + break; + case 60: + startTime = QDateTime(QDate(today.year(), today.month(), 1)).addMonths(-1); + endTime = QDateTime(QDate(today.year(), today.month(), 1)); + break; + case 365: + startTime = QDateTime(QDate(today.year(), 1, 1)); + endTime = QDateTime(tomorrow); + break; + case 730: + startTime = QDateTime(QDate(today.year(), 1, 1)).addYears(-1); + endTime = QDateTime(QDate(today.year(), 1, 1)); + break; + default: + break; + } + } + }; + + calDateFilter(DATE_RANGE, advanceSearchFilter()->f_dateRangeStart, advanceSearchFilter()->f_dateRangeEnd); + calDateFilter(ACCESS_DATE_RANGE, advanceSearchFilter()->f_accessDateRangeStart, advanceSearchFilter()->f_accessDateRangeEnd); + calDateFilter(CREATE_DATE_RANGE, advanceSearchFilter()->f_createDateRangeStart, advanceSearchFilter()->f_createDateRangeEnd); + + if (updateView) { + applyAdvanceSearchFilter(); + } +} + +void DFileSystemModel::applyAdvanceSearchFilter() +{ + Q_D(DFileSystemModel); + if (!d->rootNode) + return; + setState(Busy); + d->rootNode->applyFileFilter(advanceSearchFilter()); + setState(Idle); + sort(); +} + +std::shared_ptr DFileSystemModel::advanceSearchFilter() +{ + Q_D(DFileSystemModel); + + return d->advanceSearchFilter; +} + +Qt::SortOrder DFileSystemModel::sortOrder() const +{ + Q_D(const DFileSystemModel); + + return d->srotOrder; +} + +void DFileSystemModel::setSortOrder(const Qt::SortOrder &order) +{ + Q_D(DFileSystemModel); + d->srotOrder = order; +} + +int DFileSystemModel::sortColumn() const +{ + Q_D(const DFileSystemModel); + + if (!d->rootNode || !d->rootNode->fileInfo) { + return -1; + } + + if (d->rootNode->fileInfo->columnIsCompact()) { + int i = 0; + + for (const int role : d->rootNode->fileInfo->userColumnRoles()) { + if (role == d->sortRole) { + return i; + } + + const QList childe_roles = d->rootNode->fileInfo->userColumnChildRoles(i); + + if (childe_roles.indexOf(d->sortRole) >= 0) { + return i; + } + + ++i; + } + } + + return roleToColumn(d->sortRole); +} + +int DFileSystemModel::sortRole() const +{ + Q_D(const DFileSystemModel); + + return d->sortRole; +} + +QStringList DFileSystemModel::nameFilters() const +{ + Q_D(const DFileSystemModel); + + return d->nameFilters; +} + +QDir::Filters DFileSystemModel::filters() const +{ + Q_D(const DFileSystemModel); + + return d->filters; +} + +void DFileSystemModel::sort(int column, Qt::SortOrder order) +{ + Q_D(DFileSystemModel); + + int old_sortRole = d->sortRole; + int old_sortOrder = d->srotOrder; + + setSortColumn(column, order); + + if (old_sortRole == d->sortRole && old_sortOrder == d->srotOrder) { + return; + } + + sort(); +} + +bool DFileSystemModel::sort() +{ + return sort(true); +} + +bool DFileSystemModel::sort(bool emitDataChange) +{ + if (!enabledSort()) { + return false; + } + + if (state() == Busy) { + qWarning() << "I'm busying"; + + return false; + } + + if (QThreadPool::globalInstance()->activeThreadCount() >= MAX_THREAD_COUNT) { + qDebug() << "Beyond the maximum number of threads!"; + return false; + } + + if (QThread::currentThread() == qApp->thread()) { + QtConcurrent::run(QThreadPool::globalInstance(), this, &DFileSystemModel::sort); + + return false; + } + + return doSortBusiness(emitDataChange); +} + +bool DFileSystemModel::doSortBusiness(bool emitDataChange) +{ + if (isNeedToBreakBusyCase) // 有清场流程来了,其他线程无需进行处理了 + return false; + + Q_D(const DFileSystemModel); + + QMutexLocker locker(&m_mutex); + + if (isNeedToBreakBusyCase) // bug 27384: 有清场流程来了,其他线程无需进行处理了, 这里做处理是 其他线程可能获取 锁,那么这里做及时处理 + return false; + + const FileSystemNodePointer &node = d->rootNode; + + if (!node) { + return false; + } + +// qDebug() << "start the sort business"; + + QList list = node->getChildrenList(); + + bool ok = sort(node->fileInfo, list); + + if (ok) { + node->setChildrenList(list); + if (emitDataChange) { + emitAllDataChanged(); + } + } + +// qDebug() << "end the sort business"; + emit sortFinished(); + return ok; +} + +const DAbstractFileInfoPointer DFileSystemModel::fileInfo(const QModelIndex &index) const +{ + const FileSystemNodePointer &node = getNodeByIndex(index); +// if (node && node->fileInfo){ +// node->fileInfo->updateFileInfo(); +// } + + return node ? node->fileInfo : DAbstractFileInfoPointer(); +} + +const DAbstractFileInfoPointer DFileSystemModel::fileInfo(const DUrl &fileUrl) const +{ + Q_D(const DFileSystemModel); + + if (!d->rootNode) { + return DAbstractFileInfoPointer(); + } + + if (fileUrl == d->rootNode->fileInfo->fileUrl()) { + return d->rootNode->fileInfo; + } + + const FileSystemNodePointer &node = d->rootNode->getNodeByUrl(fileUrl); + + return node ? node->fileInfo : DAbstractFileInfoPointer(); +} + +const DAbstractFileInfoPointer DFileSystemModel::parentFileInfo(const QModelIndex &index) const +{ + const FileSystemNodePointer &node = getNodeByIndex(index); + + return node ? node->parent->fileInfo : DAbstractFileInfoPointer(); +} + +const DAbstractFileInfoPointer DFileSystemModel::parentFileInfo(const DUrl &fileUrl) const +{ + Q_D(const DFileSystemModel); +// const FileSystemNodePointer &node = d->urlToNode.value(fileUrl); +// const FileSystemNodePointer &node = d->rootNode->children.value(fileUrl); + +// return node ? node->parent->fileInfo : AbstractFileInfoPointer(); + if (fileUrl == rootUrl()) { + return d->rootNode->fileInfo; + } + + return fileService->createFileInfo(this, fileUrl.parentUrl(fileUrl)); +} + +DFileSystemModel::State DFileSystemModel::state() const +{ + Q_D(const DFileSystemModel); + + return d->state; +} + +void DFileSystemModel::setReadOnly(bool readOnly) +{ + Q_D(DFileSystemModel); + + d->readOnly = readOnly; +} + +bool DFileSystemModel::isReadOnly() const +{ + Q_D(const DFileSystemModel); + + return d->readOnly; +} + +DAbstractFileWatcher *DFileSystemModel::fileWatcher() const +{ + Q_D(const DFileSystemModel); + + return d->watcher; +} + +bool DFileSystemModel::enabledSort() const +{ + Q_D(const DFileSystemModel); + + return d->enabledSort; +} + +bool DFileSystemModel::setColumnCompact(bool compact) +{ + Q_D(DFileSystemModel); + + if (d->columnCompact == compact) { + return false; + } + + d->columnCompact = compact; + + if (d->rootNode) { + if (d->rootNode->fileInfo) { + d->rootNode->fileInfo->setColumnCompact(compact); + } + + for (const FileSystemNodePointer &child : d->rootNode->getChildrenList()) { + child->fileInfo->setColumnCompact(compact); + } + } + + return true; +} + +bool DFileSystemModel::columnIsCompact() const +{ + Q_D(const DFileSystemModel); + + if (d->rootNode && d->rootNode->fileInfo) { + return d->rootNode->fileInfo->columnIsCompact(); + } + + return d->columnCompact; +} + +void DFileSystemModel::setColumnActiveRole(int column, int role) +{ + Q_D(DFileSystemModel); + + d->columnActiveRole[column] = role; +} + +int DFileSystemModel::columnActiveRole(int column) const +{ + Q_D(const DFileSystemModel); + + if (!d->rootNode || !d->rootNode->fileInfo) { + return UnknowRole; + } + + if (!d->rootNode->fileInfo->columnIsCompact()) { + return columnToRole(column); + } + + const QList &roles = d->rootNode->fileInfo->userColumnChildRoles(column); + + if (roles.isEmpty()) { + return columnToRole(column); + } + + return d->columnActiveRole.value(column, roles.first()); +} + +void DFileSystemModel::stopCurrentJob() +{ + releaseJobController(); + setState(Idle); +} + +void DFileSystemModel::updateChildren(QList list) +{ + Q_D(DFileSystemModel); + +// qDebug() << "Begin update chidren. file list count " << list.count(); + const FileSystemNodePointer &node = d->rootNode; + + if (!node) { + return; + } + + QPointer job = d->jobController; + QPointer dp = this; + + if (!job.isNull()) { + job->pause(); + } + node->clearChildren(); + + QHash fileHash; + QList fileList; + + fileHash.reserve(list.size()); + fileList.reserve(list.size()); + + if (dp.isNull()) + return; + + for (const DAbstractFileInfoPointer &fileInfo : list) { + if (d->needQuitUpdateChildren) { + break; + } + + if (!fileInfo) { + continue; + } + //挂载设备下目录添加tag后 移除该挂载设备 目录已不存在但其URL依然还保存在tag集合中 + //该问题导致这些不存在的目录依然会添加到tag的fileview下 引起其他被标记文件可能标记数据获取失败 + //为了避免引起其他问题 暂时只对tag的目录做处理 + if (fileInfo->fileUrl().scheme() == TAG_SCHEME && !fileInfo->exists()) { + continue; + } + + // feature: hide specified dirs of unremovable devices directly under devices' mountpoint + if (!isDesktop // 桌面不执行隐藏,否则将导致桌面无法实时刷新“发送到”列表:这行语句将导致 gvfsManager 提前在线程中被初始化 + && !filters().testFlag(QDir::Hidden) + && fileInfo->isDir() + && deviceListener->hiddenDirs().contains(fileInfo->filePath())) { + continue; + } + + // qDebug() << "update node url = " << fileInfo->filePath(); + const FileSystemNodePointer &chileNode = createNode(node.data(), fileInfo); + //当文件路径和名称都相同的情况下,fileHash在赋值,会释放,fileList保存的普通指针就是悬空指针 + if (!chileNode->shouldHideByFilterRule(advanceSearchFilter()) && !fileHash[fileInfo->fileUrl()]) { + fileHash[fileInfo->fileUrl()] = chileNode; + fileList << chileNode; + if (fileInfo->fileUrl().scheme() == SEARCH_SCHEME) + emit showFilterButton(); + } + } + if (dp.isNull()) + return; + if (enabledSort()) + sort(node->fileInfo, fileList); + + if (dp.isNull()) + return; +// qDebug() << "begin insert rows count = " << QString::number(list.count()); + beginInsertRows(createIndex(node, 0), 0, list.count() - 1); + + node->setChildrenMap(fileHash); + node->setChildrenList(fileList); + endInsertRows(); + + if (dp.isNull()) + return; + + if (d->needQuitUpdateChildren) + return; + if (job.isNull() || job->isFinished()) { + setState(Idle); + } else { + d->childrenUpdated = true; + } + + if (!job.isNull() && job->state() == JobController::Paused) { + job->start(); + } + + if (dp.isNull()) + return; + +// qDebug() << "finish update children. file count = " << node->childrenCount() << (job ? job->state() : -1); + if (!job.isNull()) { + //刷新完成标志 + bool finished = job->isUpdatedFinished(); + qInfo() << " finish update children. isUpdatedFinished = " << finished; + //若刷新完成通知桌面重新获取文件 + if (finished && !dp.isNull()) + emit sigJobFinished(); + } else if (!dp.isNull()) { + emit sigJobFinished(); + } +} + +void DFileSystemModel::updateChildrenOnNewThread(QList list) +{ + Q_D(DFileSystemModel); + QMutexLocker locker(&m_mutex); + QPointer me = this; + if (!me) { + return; + } + + if (d->jobController) { + d->jobController->pause(); + } + + if (QThreadPool::globalInstance()->activeThreadCount() >= QThreadPool::globalInstance()->maxThreadCount()) { + QThreadPool::globalInstance()->setMaxThreadCount(QThreadPool::globalInstance()->maxThreadCount() + 10); + } + + emit updateFilterRule(d->advanceSearchFilter.get()); + d->updateChildrenFuture = QtConcurrent::run(QThreadPool::globalInstance(), this, &DFileSystemModel::updateChildren, list); +} + +void DFileSystemModel::refresh(const DUrl &fileUrl) +{ + Q_D(const DFileSystemModel); + + if (d->state != Idle) { + return; + } + +// const FileSystemNodePointer &node = d->urlToNode.value(fileUrl); + const FileSystemNodePointer &node = d->rootNode; + + if (!node) { + return; + } + + if (!fileUrl.isEmpty() && fileUrl != node->fileInfo->fileUrl()) { + return; + } + +// if(!isDir(node)) +// return; + + node->populatedChildren = false; + + const QModelIndex &index = createIndex(node, 0); + if (beginRemoveRows(index, 0, rowCount(index) - 1)) { + node->clearChildren(); + endRemoveRows(); + } + + fetchMore(index); +} + +void DFileSystemModel::update() +{ + Q_D(const DFileSystemModel); + + const QModelIndex &rootIndex = createIndex(d->rootNode, 0); + + for (const FileSystemNodePointer &node : d->rootNode->getChildrenList()) { + if (node->fileInfo) + node->fileInfo->refresh(); + } + + emit dataChanged(rootIndex.child(0, 0), rootIndex.child(rootIndex.row() - 1, 0)); +} + +void DFileSystemModel::toggleHiddenFiles(const DUrl &fileUrl) +{ + Q_D(DFileSystemModel); + + d->filters = ~(d->filters ^ QDir::Filter(~QDir::Hidden)); + + refresh(fileUrl); +} + +void DFileSystemModel::setEnabledSort(bool enabledSort) +{ + Q_D(DFileSystemModel); + + if (d->enabledSort == enabledSort) { + return; + } + + d->enabledSort = enabledSort; + emit enabledSortChanged(enabledSort); +} + +bool DFileSystemModel::removeRows(int row, int count, const QModelIndex &parent) +{ + Q_D(DFileSystemModel); + + const FileSystemNodePointer &parentNode = parent.isValid() ? getNodeByIndex(parent) : d->rootNode; + if (parentNode && parentNode->populatedChildren) { + const DAbstractFileInfoPointer &fileInfo = this->fileInfo(index(row, 0)); + fileInfo->refresh(); + if (fileInfo->exists()) + return true; + if (d->currentRemove) { + return true; + } + if (beginRemoveRows(createIndex(parentNode, 0), row, row + count - 1)) { + for (int i = 0; i < count; ++i) { + Q_UNUSED(parentNode->takeNodeByIndex(row)); + } + endRemoveRows(); + } + } + + return true; +} + +bool DFileSystemModel::remove(const DUrl &url) +{ + Q_D(DFileSystemModel); + + const FileSystemNodePointer &parentNode = d->rootNode; + + if (parentNode && parentNode->populatedChildren) { + int index = parentNode->indexOfChild(url); + if (index < 0) { + return false; + } + d->currentRemove = true; + if (beginRemoveRows(createIndex(parentNode, 0), index, index)) { + Q_UNUSED(parentNode->takeNodeByIndex(index)); + endRemoveRows(); + } + d->currentRemove = false; + + return true; + } + + return false; +} + +const FileSystemNodePointer DFileSystemModel::getNodeByIndex(const QModelIndex &index) const +{ + Q_D(const DFileSystemModel); + + if (!d->rootNode) { + return FileSystemNodePointer(); + } + + FileSystemNode *indexNode = static_cast(index.internalPointer()); + + if (!indexNode) { + return FileSystemNodePointer(); + } + + if (indexNode == d->rootNode.constData()) { + return d->rootNode; + } + + if (d->rootNode->getNodeByIndex(index.row()).data() != indexNode + || indexNode->ref <= 0) { + return FileSystemNodePointer(); + } + + return FileSystemNodePointer(indexNode); +} + +QModelIndex DFileSystemModel::createIndex(const FileSystemNodePointer &node, int column) const +{ + int row = (node->parent && node->parent->childrenCount() > 0) + ? node->parent->indexOfChild(node) + : 0; + + return createIndex(row, column, const_cast(node.data())); +} + +bool DFileSystemModel::isDir(const FileSystemNodePointer &node) const +{ + return node->fileInfo->isDir(); +} + +bool DFileSystemModel::sort(const DAbstractFileInfoPointer &parentInfo, QList &list) const +{ + Q_D(const DFileSystemModel); + + if (!parentInfo) { + return false; + } + + DAbstractFileInfo::CompareFunction sortFun = parentInfo->compareFunByColumn(d->sortRole); + + if (!sortFun) { + return false; + } + + qSort(list.begin(), list.end(), [sortFun, d, this](const FileSystemNodePointer node1, const FileSystemNodePointer node2) { + if (this->isNeedToBreakBusyCase) //bug 27384: 当是网络文件的时候,这里奇慢,需要快速跳出 qSort操作,目前我只想到这种方案:不做比较,或者 直接跳出sort 更好 + return false; + + return sortFun(node1->fileInfo, node2->fileInfo, d->srotOrder); + }); + + if (columnIsCompact() && d->rootNode && d->rootNode->fileInfo) { + int column = 0; + + for (int role : d->rootNode->fileInfo->userColumnRoles()) { + if (role == d->sortRole) { + return true; + } + + if (d->rootNode->fileInfo->userColumnChildRoles(column).indexOf(d->sortRole) >= 0) { + const_cast(this)->setColumnActiveRole(column, d->sortRole); + } + + ++column; + } + } + + return true; +} + +const FileSystemNodePointer DFileSystemModel::createNode(FileSystemNode *parent, const DAbstractFileInfoPointer &info, QReadWriteLock *lock) +{ + Q_ASSERT(info); + +// const FileSystemNodePointer &node = d->urlToNode.value(info->fileUrl()); + +// if(node) { +// if(node->fileInfo != info) { +// node->fileInfo = info; +// } + +// node->parent = parent; + +// return node; +// } else { + Q_D(const DFileSystemModel); + QString url(info->filePath()); + if (m_allFileSystemNodes.contains(url) && d->rootNode) { + qDebug() << "recreate node url = " << url; + d->rootNode->removeFileSystemNode(m_allFileSystemNodes[url]); + } + + FileSystemNodePointer node(new FileSystemNode(parent, info, this, lock)); + + node->fileInfo->setColumnCompact(d->columnCompact); +// d->urlToNode[info->fileUrl()] = node; + + return node; +// } +} + +void DFileSystemModel::deleteNode(const FileSystemNodePointer &node) +{ +// d->urlToNode.remove(d->urlToNode.key(node)); + +// for(const FileSystemNodePointer &children : node->children) { +// if(children->parent == node) { +// deleteNode(children); +// } +// } + node->fileInfo->makeToInactive(); +// deleteNodeByUrl(node->fileInfo->fileUrl()); +} + +void DFileSystemModel::clear() +{ + Q_D(const DFileSystemModel); + + if (!d->rootNode) { + return; + } + + isNeedToBreakBusyCase = true; // 清场的时候,必须进口跳出相关流程 + + QMutexLocker locker(&m_mutex); // bug 26972, while the sort case is ruuning, there should be crashed ASAP, so add locker here! + + const QModelIndex &index = createIndex(d->rootNode, 0); + if (beginRemoveRows(index, 0, d->rootNode->childrenCount() - 1)) { + deleteNode(d->rootNode); + endRemoveRows(); + } +} + +void DFileSystemModel::setState(DFileSystemModel::State state) +{ + Q_D(DFileSystemModel); + + if (d->state == state) { + return; + } + + d->state = state; + + emit stateChanged(state); +} + +void DFileSystemModel::onJobAddChildren(const DAbstractFileInfoPointer &fileInfo) +{ +// static QMutex mutex; +// static QWaitCondition condition; + +// QTimer *volatile timer = new QTimer; +// timer->setSingleShot(true); +// timer->moveToThread(qApp->thread()); +// timer->setParent(this); +// connect(timer, &QTimer::timeout, this, [this, fileInfo, &timer] { +// timer->deleteLater(); +// addFile(fileInfo); +// timer = Q_NULLPTR; +// condition.wakeAll(); +// }, Qt::DirectConnection); +// mutex.lock(); +// timer->metaObject()->invokeMethod(timer, "start", Q_ARG(int, 0)); + +// if (timer) { +// condition.wait(&mutex); +// } + +// mutex.unlock(); + Q_D(DFileSystemModel); + d->rootNodeManager->addFile(fileInfo, FileNodeManagerThread::AppendFile); + if (fileInfo->fileUrl().scheme() == SEARCH_SCHEME) + emit showFilterButton(); +} + +void DFileSystemModel::onJobFinished() +{ + Q_D(const DFileSystemModel); + + if (d->childrenUpdated && !d->rootNodeManager->isRunning()) { + setState(Idle); + } +} + +void DFileSystemModel::addFile(const DAbstractFileInfoPointer &fileInfo) +{ + Q_D(const DFileSystemModel); + + const FileSystemNodePointer parentNode = d->rootNode; + const DUrl &fileUrl = fileInfo->fileUrl(); + + if (parentNode && parentNode->populatedChildren && !parentNode->childContains(fileUrl)) { + QPointer me = this; + + int row = -1; + + if (enabledSort()) { + row = 0; + + QFuture result; + + // tmp: 暂时不排序 排序的宏在大量添加文件操作时会崩(最近访问目录不存在大量文件添加的情况 可放开) + if (fileInfo->hasOrderly() && fileUrl.isRecentFile()) { + DAbstractFileInfo::CompareFunction compareFun = fileInfo->compareFunByColumn(d->sortRole); + + if (compareFun) { + result = QtConcurrent::run(QThreadPool::globalInstance(), [&] { + forever + { + if (!me || row >= parentNode->childrenCount()) { + break; + } + + const FileSystemNodePointer &node = parentNode->getNodeByIndex(row); + if (node) { + if (compareFun(fileInfo, node->fileInfo, d->srotOrder)) { + break; + } + } + + ++row; + } + }); + } else { + row = -1; + } + } else if (fileInfo->isFile()) { + row = -1; + } else { + result = QtConcurrent::run(QThreadPool::globalInstance(), [&] { + forever + { + if (!me || row >= parentNode->childrenCount()) { + break; + } + + const FileSystemNodePointer &node = parentNode->getNodeByIndex(row); + if (node) { + if (node->fileInfo && node->fileInfo->isFile()) { + break; + } + + } + + ++row; + } + }); + } + while (!result.isFinished()) { + qApp->processEvents(); + } + } + if (!me) { + return; + } + + if (row == -1) { + row = parentNode->childrenCount(); + } + + if (m_allFileSystemNodes.contains(fileInfo->filePath())) { + qDebug() << "File already exist url = " << fileInfo->filePath(); + return; + } + + //qDebug() << "insert node row = " << QString::number(row); + beginInsertRows(createIndex(parentNode, 0), row, row); + +// FileSystemNodePointer node = d->urlToNode.value(fileUrl); + +// if(!node) { + FileSystemNodePointer node = createNode(parentNode.data(), fileInfo); + +// d->urlToNode[fileUrl] = node; +// } + + parentNode->insertChildren(row, fileUrl, node); + + endInsertRows(); + } +} + +void DFileSystemModel::emitAllDataChanged() +{ + Q_D(const DFileSystemModel); + + if (!d->rootNode) { + return; + } + + QModelIndex parentIndex = createIndex(d->rootNode, 0); + QModelIndex topLeftIndex = index(0, 0, parentIndex); + QModelIndex rightBottomIndex = index(d->rootNode->childrenCount(), columnCount(parentIndex), parentIndex); + + QMetaObject::invokeMethod(this, "dataChanged", Qt::QueuedConnection, + Q_ARG(QModelIndex, topLeftIndex), Q_ARG(QModelIndex, rightBottomIndex)); +} + +void DFileSystemModel::selectAndRenameFile(const DUrl &fileUrl) +{ + /// TODO: 暂时放在此处实现,后面将移动到DFileService中实现。 + if (fileUrl.scheme() == DFMMD_SCHEME) { //自动整理路径特殊实现,fix bug#24715 + auto realFileUrl = MergedDesktopController::convertToRealPath(fileUrl); + if (AppController::selectionAndRenameFile.first == realFileUrl) { + quint64 windowId = AppController::selectionAndRenameFile.second; + if (windowId != parent()->windowId()) { + return; + } + + AppController::selectionAndRenameFile = qMakePair(DUrl(), 0); + DFMUrlBaseEvent event(this, fileUrl); + event.setWindowId(windowId); + emit newFileByInternal(fileUrl); + } + } else if (fileUrl.isVaultFile()) { //! 设置保险箱新建文件选中并重命名状态 + DUrl url = DUrl::fromLocalFile(VaultController::vaultToLocal(fileUrl)); + if (AppController::selectionAndRenameFile.first == url) { + quint64 windowId = AppController::selectionAndRenameFile.second; + + if (windowId != parent()->windowId()) { + return; + } + + AppController::selectionAndRenameFile = qMakePair(DUrl(), 0); + DFMUrlBaseEvent event(this, fileUrl); + event.setWindowId(windowId); + + TIMER_SINGLESHOT_OBJECT(const_cast(this), 100, { + emit fileSignalManager->requestSelectRenameFile(event); + }, event) + + emit newFileByInternal(fileUrl); + } + } else if (AppController::selectionAndRenameFile.first == fileUrl) { + quint64 windowId = AppController::selectionAndRenameFile.second; + + if (windowId != parent()->windowId()) { + return; + } + + AppController::selectionAndRenameFile = qMakePair(DUrl(), 0); + DFMUrlBaseEvent event(this, fileUrl); + event.setWindowId(windowId); + + TIMER_SINGLESHOT_OBJECT(const_cast(this), 100, { + emit fileSignalManager->requestSelectRenameFile(event); + }, event) + + emit newFileByInternal(fileUrl); + } else if (AppController::selectionFile.first == fileUrl) { + quint64 windowId = AppController::selectionFile.second; + + if (windowId != parent()->windowId()) { + return; + } + + AppController::selectionFile = qMakePair(DUrl(), 0); + DFMUrlListBaseEvent event(parent()->parent(), DUrlList() << fileUrl); + event.setWindowId(windowId); + + TIMER_SINGLESHOT_OBJECT(const_cast(this), 100, { + emit fileSignalManager->requestSelectFile(event); + emit this->requestSelectFiles(event.urlList()); + }, event, this) + + } else if (AppController::multiSelectionFilesCache.second != 0) { + quint64 winId{ AppController::multiSelectionFilesCache.second }; + if (winId == parent()->windowId() || AppController::flagForDDesktopRenameBar) { //###: flagForDDesktopRenameBar is false usually. + + if (!AppController::multiSelectionFilesCache.first.isEmpty()) { + + if (AppController::multiSelectionFilesCache.first.contains(fileUrl) == true) { + + ++AppController::multiSelectionFilesCacheCounter; + if (static_cast(AppController::multiSelectionFilesCacheCounter.load(std::memory_order_seq_cst)) == + AppController::multiSelectionFilesCache.first.size()) { + + DFMUrlListBaseEvent event{ parent()->parent(), AppController::multiSelectionFilesCache.first}; + event.setWindowId(winId); + + ////###: clean cache! + AppController::multiSelectionFilesCache.first.clear(); + AppController::multiSelectionFilesCache.second = 0; + + ///###: make ref-counter be 0(zero). + AppController::multiSelectionFilesCacheCounter.store(0, std::memory_order_seq_cst); + + ///###:request to select files which was renamed successfully. + QTimer::singleShot(100, [event, this] { + emit fileSignalManager->requestSelectFile(event); + emit this->requestSelectFiles(event.urlList()); + }); + } + } + } + } + } +} + +bool DFileSystemModel::beginRemoveRows(const QModelIndex &parent, int first, int last) +{ + Q_D(DFileSystemModel); + + if (d->beginRemoveRowsFlag) { + return false; + } else { + QAbstractItemModel::beginRemoveRows(parent, first, last); + d->beginRemoveRowsFlag = true; + return true; + } +} + +void DFileSystemModel::endRemoveRows() +{ + Q_D(DFileSystemModel); + + d->beginRemoveRowsFlag = false; + QAbstractItemModel::endRemoveRows(); +} +//fix bug 33014,在文件或者文件很多时,切换到computer时DFileSystemModel已释放但是d->jobController未释放,发送更新消息就崩溃,在DFileSystemModel析构时释放d->jobController +bool DFileSystemModel::releaseJobController() +{ + Q_D(DFileSystemModel); + + if (d->jobController) { + disconnect(d->jobController, &JobController::addChildren, this, &DFileSystemModel::onJobAddChildren); + disconnect(d->jobController, &JobController::finished, this, &DFileSystemModel::onJobFinished); + disconnect(d->jobController, &JobController::childrenUpdated, this, &DFileSystemModel::updateChildrenOnNewThread); + + if (d->jobController->isFinished()) { + d->jobController->deleteLater(); + d->jobController = nullptr; + } else { + QEventLoop eventLoop; + QPointer me = this; + d->eventLoop = &eventLoop; + + connect(d->jobController, &JobController::destroyed, &eventLoop, &QEventLoop::quit); + + d->jobController->stopAndDeleteLater(); + + d->jobController = nullptr; + + int code = eventLoop.exec(); + + d->eventLoop = Q_NULLPTR; + + if (code != 0) { + // if (d->jobController) { //有时候d->jobController已销毁,会导致崩溃 + //fix bug 33007 在释放d->jobController时,eventLoop退出异常, + //此时d->jobController有可能已经在析构了,不能调用terminate + // d->jobController->terminate(); + // d->jobController->quit(); + // d->jobController.clear(); + // d->jobController->stopAndDeleteLater(); + // } + return false; + } + + if (!me) { + return false; + } + } + } + return true; +} + +#include "moc_dfilesystemmodel.cpp" + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemmodel.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemmodel.h new file mode 100644 index 0000000..e6092a1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemmodel.h @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILESYSTEMMODEL_H +#define DFILESYSTEMMODEL_H + +#include +#include +#include +#include + +// for std::shared_ptr +#include +#include + +#include "durl.h" +#include "dabstractfileinfo.h" + +#include + +QT_BEGIN_NAMESPACE +class QEventLoop; +class QReadWriteLock; +QT_END_NAMESPACE + +//#define DRAG_EVENT_URLS "UrlsInDragEvent" +#define DRAG_EVENT_URLS ((getuid()==0) ? (QString(getlogin())+"_RootUrlsInDragEvent") :(QString(getlogin())+"_UrlsInDragEvent")) +//临时解决一普通用户使用共享内存的时候,其他用户不能访问问题,增加用户名可解决多个用户同时访问共享内存的问题 +//临时解决root用户使用共享内存后其它用户无法使用的问题,但可能会造成内存占用过大的问题 unistd.h在此处被使用,后面若有更换的解决办法,此处应被修改 + +class FileSystemNode; +class DAbstractFileInfo; +class DFMEvent; +class JobController; +class DFileViewHelper; +class DFMUrlListBaseEvent; +class QSharedMemory; + +enum _asb_LabelIndex { + SEARCH_RANGE, FILE_TYPE, SIZE_RANGE, DATE_RANGE, ACCESS_DATE_RANGE, CREATE_DATE_RANGE, LABEL_COUNT, + TRIGGER_SEARCH = 114514 +}; + +typedef struct fileFilter { + QMap filterRule; // for advanced search. + bool filterEnabled = false; + QPair f_sizeRange; + QDateTime f_dateRangeStart; + QDateTime f_dateRangeEnd; + QDateTime f_accessDateRangeStart; + QDateTime f_accessDateRangeEnd; + QDateTime f_createDateRangeStart; + QDateTime f_createDateRangeEnd; + QString f_typeString; + bool f_includeSubDir; + bool f_comboValid[LABEL_COUNT]; +} FileFilter; + +Q_DECLARE_METATYPE(FileFilter) + +static QList FOR_DRAGEVENT; + +typedef QExplicitlySharedDataPointer FileSystemNodePointer; +class DFileSystemModelPrivate; +class DFileSystemModel : public QAbstractItemModel +{ + Q_OBJECT + + Q_PROPERTY(bool enabledSort READ enabledSort WRITE setEnabledSort NOTIFY enabledSortChanged) +public: + enum Roles { + FileIconRole = Qt::DecorationRole, + FilePathRole = Qt::UserRole + 1, + FileNameRole = Qt::UserRole + 2, + FileSizeRole = Qt::UserRole + 3, // a QString + FileMimeTypeRole = Qt::UserRole + 4, // a QString + FileOwnerRole = Qt::UserRole + 5, + FileLastModifiedRole = Qt::UserRole + 6, // a QString + FileLastReadRole = Qt::UserRole + 7, + FileCreatedRole = Qt::UserRole + 8, + FileDisplayNameRole = Qt::UserRole + 9, + FilePinyinName = Qt::UserRole + 10, + ExtraProperties = Qt::UserRole + 11, + FileBaseNameRole = Qt::UserRole + 12, + FileSuffixRole = Qt::UserRole + 13, + FileNameOfRenameRole = Qt::UserRole + 14, + FileBaseNameOfRenameRole = Qt::UserRole + 15, + FileSuffixOfRenameRole = Qt::UserRole + 16, + FileSizeInKiloByteRole = Qt::UserRole + 17, + FileLastModifiedDateTimeRole = Qt::UserRole + 18, + FileIconModelToolTipRole = Qt::UserRole + 19, // 用于返回图标视图下的tooltip + FileLastReadDateTimeRole = Qt::UserRole + 20, //文件最近访问时间 + FileCreatedDateTimeRole = Qt::UserRole + 21, //文件创建时间 + FileUserRole = Qt::UserRole + 99, + UnknowRole = Qt::UserRole + 999 + }; + + Q_ENUM(Roles) + + enum State { + Idle, + Busy, + Unknow + }; + + explicit DFileSystemModel(DFileViewHelper *parent); + ~DFileSystemModel() override; + + DFileViewHelper *parent() const; + + QModelIndex index(const DUrl &fileUrl, int column = 0); + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &child) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + inline int columnWidth(int column) const + { + return columnWidthByRole(columnToRole(column)); + } + QVariant columnNameByRole(int role, const QModelIndex &index = QModelIndex()) const; + + int columnWidthByRole(int role) const; + + bool columnDefaultVisibleForRole(int role, const QModelIndex &index = QModelIndex()) const; + + bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int column, Qt::Orientation orientation, int role) const override; + + static QString roleName(int role); + + int columnToRole(int column) const; + int roleToColumn(int role) const; + + bool canFetchMore(const QModelIndex &parent) const override; + void fetchMore(const QModelIndex &parent) override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + Qt::DropActions supportedDragActions() const override; + Qt::DropActions supportedDropActions() const override; + + QStringList mimeTypes() const override; + bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; + QMimeData *mimeData(const QModelIndexList &indexes) const override; + + QModelIndex setRootUrl(const DUrl &fileUrl); + DUrl rootUrl() const; + DUrlList sortedUrls(); + DUrlList getNoTransparentUrls(); + + DUrl getUrlByIndex(const QModelIndex &index) const; + + void setSortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); + void setSortRole(int role, Qt::SortOrder order = Qt::AscendingOrder); + void setNameFilters(const QStringList &nameFilters); + void setFilters(QDir::Filters filters); + void setAdvanceSearchFilter(const QMap &formData, bool turnOn, bool updateView); + void applyAdvanceSearchFilter(); + std::shared_ptr advanceSearchFilter(); + + Qt::SortOrder sortOrder() const; + void setSortOrder(const Qt::SortOrder &order); + int sortColumn() const; + int sortRole() const; + QStringList nameFilters() const; + QDir::Filters filters() const; + + void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; + bool sort(); + bool sort(bool emitDataChange); + + const DAbstractFileInfoPointer fileInfo(const QModelIndex &index) const; + const DAbstractFileInfoPointer fileInfo(const DUrl &fileUrl) const; + const DAbstractFileInfoPointer parentFileInfo(const QModelIndex &index) const; + const DAbstractFileInfoPointer parentFileInfo(const DUrl &fileUrl) const; + + State state() const; + + void setReadOnly(bool readOnly); + bool isReadOnly() const; + + DAbstractFileWatcher *fileWatcher() const; + + bool enabledSort() const; + + bool setColumnCompact(bool compact); + bool columnIsCompact() const; + + void setColumnActiveRole(int column, int role); + int columnActiveRole(int column) const; + void stopCurrentJob(); + +// static QList m_urlForDragEvent; + +public slots: + void updateChildren(QList list); + void updateChildrenOnNewThread(QList list); + /// warning: only refresh current url + void refresh(const DUrl &fileUrl = DUrl()); + void update(); + void toggleHiddenFiles(const DUrl &fileUrl); + + void setEnabledSort(bool enabledSort); + +signals: + void rootUrlDeleted(const DUrl &rootUrl); + void stateChanged(State state); + void enabledSortChanged(bool enabledSort); + void newFileByInternal(const DUrl &url); + void requestSelectFiles(const QList &urls); + void sigJobFinished(); + void requestRedirect(const DUrl &rootUrl, const DUrl &newUrl); + void showFilterButton(); + // fix bug 63938 + // 切换标签时,更新高级选项中的过滤项 + void updateFilterRule(const FileFilter *filter); + void sortFinished(); + +protected: + bool remove(const DUrl &url); + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + +private: + inline const FileSystemNodePointer getNodeByIndex(const QModelIndex &index) const; + QModelIndex createIndex(const FileSystemNodePointer &node, int column) const; + using QAbstractItemModel::createIndex; + + bool isDir(const FileSystemNodePointer &node) const; + + bool sort(const DAbstractFileInfoPointer &parentInfo, QList &list) const; + bool doSortBusiness(bool emitDataChange); + + const FileSystemNodePointer createNode(FileSystemNode *parent, const DAbstractFileInfoPointer &info, QReadWriteLock *lock = nullptr); + + void deleteNode(const FileSystemNodePointer &node); + void clear(); + + void setState(State state); + void onJobAddChildren(const DAbstractFileInfoPointer &fileInfo); + void onJobFinished(); + void addFile(const DAbstractFileInfoPointer &fileInfo); + + void emitAllDataChanged(); + void selectAndRenameFile(const DUrl &fileUrl); + + bool beginRemoveRows(const QModelIndex &parent, int first, int last); + void endRemoveRows(); + //fix bug释放jobcontroller + bool releaseJobController(); + QDir::Filters m_filters; //仅记录非回收站文件过滤规则 + bool isFirstRun = true; //判断是否首次运行 + bool isNeedToBreakBusyCase = false; // 停止那些忙的流程 // bug 26972, 27384 + QMutex m_mutex; // 对当前文件资源进行单操作 // bug 26972 + +private: + + QMap m_allFileSystemNodes; + + friend class FileSystemNode; + friend class DFileView; + friend class FileNodeManagerThread; + friend class DListItemDelegate; + + QScopedPointer d_ptr; + QSharedMemory *m_smForDragEvent; + + Q_PRIVATE_SLOT(d_func(), void _q_onFileCreated(const DUrl &fileUrl)) + Q_PRIVATE_SLOT(d_func(), void _q_onFileDeleted(const DUrl &fileUrl)) + Q_PRIVATE_SLOT(d_func(), void _q_onFileUpdated(const DUrl &fileUrl)) + Q_PRIVATE_SLOT(d_func(), void _q_onFileUpdated(const DUrl &fileUrl, const int isExternalSource)) + Q_PRIVATE_SLOT(d_func(), void _q_onFileRename(const DUrl &from, const DUrl &to)) + Q_PRIVATE_SLOT(d_func(), void _q_processFileEvent()) + + Q_DECLARE_PRIVATE(DFileSystemModel) + Q_DISABLE_COPY(DFileSystemModel) +public: + bool ignoreDropFlag = false; //candrop十分耗时,在不关心Qt::ItemDropEnable的调用时设置其为true, + //不调用candrop,节省时间,bug#10926 + bool isDesktop = false; //紧急修复,由于修复bug#33209添加了一次事件循环的处理,导致桌面的自动排列在删除,恢复文件时显示异常 +}; + +#endif // DFILESYSTEMMODEL_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemmodel_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemmodel_p.h new file mode 100644 index 0000000..4d7a0e4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemmodel_p.h @@ -0,0 +1,270 @@ +#ifndef DFILESYSTEMMODEL_P_H +#define DFILESYSTEMMODEL_P_H + +#include "dfilesystemmodel.h" +#include "interfaces/durl.h" +#include "interfaces/dfileviewhelper.h" +#include "shutil/fileutils.h" +#include "deviceinfo/udisklistener.h" +#include "shutil/dfmfilelistfile.h" + +#include +#include + +class FileSystemNode : public QSharedData +{ +public: + FileSystemNode(FileSystemNode *parent, + const DAbstractFileInfoPointer &info, + DFileSystemModel *dFileSystemModel, + QReadWriteLock *lock = nullptr); + + ~FileSystemNode(); + QVariant dataByRole(int role); + void setNodeVisible(const FileSystemNodePointer &node, bool visible); + void applyFileFilter(std::shared_ptr filter); + bool shouldHideByFilterRule(std::shared_ptr filter); + void noLockInsertChildren(int index, const DUrl &url, const FileSystemNodePointer &node); + void insertChildren(int index, const DUrl &url, const FileSystemNodePointer &node); + void noLockAppendChildren(const DUrl &url, const FileSystemNodePointer &node); + void appendChildren(const DUrl &url, const FileSystemNodePointer &node); + FileSystemNodePointer getNodeByUrl(const DUrl &url); + FileSystemNodePointer getNodeByIndex(int index); + FileSystemNodePointer takeNodeByUrl(const DUrl &url); + FileSystemNodePointer takeNodeByIndex(const int index); + int indexOfChild(const FileSystemNodePointer &node); + int indexOfChild(const DUrl &url); + int childrenCount(); + QList getChildrenList() const; + DUrlList getChildrenUrlList(); + void setChildrenList(const QList &list); + void setChildrenMap(const QHash &map); + void clearChildren(); + bool childContains(const DUrl &url); + void addFileSystemNode(const FileSystemNodePointer &node); + void removeFileSystemNode(const FileSystemNodePointer &node); + const FileSystemNodePointer getFileSystemNode(FileSystemNode *parent); +public: + DAbstractFileInfoPointer fileInfo; + FileSystemNode *parent = Q_NULLPTR; + bool populatedChildren = false; +private: + QHash children; + //fix bug 31225,if children clear,another thread useing visibleChildren will crush,so use FileSystemNodePointer + QList visibleChildren; + DFileSystemModel *m_dFileSystemModel = nullptr; + QReadWriteLock *rwLock = nullptr; +}; + +template +class LockFreeQueue +{ +public: + struct Node { + T data; + QAtomicPointer next; + }; + + LockFreeQueue() + { + m_head.store(new Node()); + m_head.load()->next.store(nullptr); + m_tail.store(m_head.load()); + } + + ~LockFreeQueue() + { + clear(); + + delete m_head.load(); + } + + void clear() + { + while (!isEmpty()) { + dequeue(); + } + } + + bool isEmpty() const + { + Node *_head = m_head.load(); + + return _head->next == nullptr; + } + + T dequeue() + { + Node *_head; + + do { + _head = m_head.load(); + + if (_head->next == nullptr) { + std::abort(); + } + } while (!m_head.testAndSetAcquire(_head, _head->next.load())); + + const T &data = _head->next.load()->data; + delete _head; + + return data; + } + + void enqueue(const T &t) + { + Node *node = new Node(); + + node->data = t; + node->next = nullptr; + + Node *_tail = nullptr; + + do { + _tail = m_tail.load(); + } while (!_tail->next.testAndSetAcquire(nullptr, node)); + + m_tail = node; + } + + T &head() + { + return m_head.load(); + } + + const T &head() const + { + return m_head.load(); + } + + Node *headNode() + { + return m_head.load()->next.load(); + } + + void removeNode(Node *node) + { + auto _head = &m_head; + + do { + if (!_head->load()->next.load()) { + std::abort(); + } + + _head = &_head->load()->next; + } while (!_head->testAndSetAcquire(node, node->next.load())); + + delete node; + } + +private: + QAtomicPointer m_head; + QAtomicPointer m_tail; +}; + +class FileNodeManagerThread : public QThread +{ +public: + enum EventType { + AddFile, // 在需要排序时会插入到对应位置 + AppendFile, // 直接放到列表末尾,不管当前列表的顺序,不过文件和文件夹还是分开的 + RmFile + }; + explicit FileNodeManagerThread(DFileSystemModel *parent); + ~FileNodeManagerThread() override; + void start(); + inline DFileSystemModel *model() const + { + return static_cast(parent()); + } + void addFile(const DAbstractFileInfoPointer &info, bool append = false); + void removeFile(const DAbstractFileInfoPointer &info); + void setRootNode(const FileSystemNodePointer &node); + void setEnable(bool enable); + void stop(); +private: + void run() override; + +private: + QTimer *waitTimer; + LockFreeQueue> fileQueue; + FileSystemNodePointer rootNode; + QAtomicInteger enable; + QSemaphore semaphore; +}; + +class DFileSystemModelPrivate +{ +public: + enum EventType { + AddFile, + RmFile + }; + explicit DFileSystemModelPrivate(DFileSystemModel *qq); + ~DFileSystemModelPrivate(); + + DFileSystemModelPrivate(DFileSystemModelPrivate &) = delete; + DFileSystemModelPrivate &operator=(DFileSystemModelPrivate &) = delete; + + bool passNameFilters(const FileSystemNodePointer &node) const; + bool passFileFilters(const DAbstractFileInfoPointer &info) const; + + void _q_onFileCreated(const DUrl &fileUrl, bool isPickUpQueue = false); + void _q_onFileDeleted(const DUrl &fileUrl); + void _q_onFileUpdated(const DUrl &fileUrl); + void _q_onFileUpdated(const DUrl &fileUrl, const int &isExternalSource); + void _q_onFileRename(const DUrl &from, const DUrl &to); + + /// add/rm file event + void _q_processFileEvent(); + bool checkFileEventQueue(); + + DFileSystemModel *q_ptr; + + FileSystemNodePointer rootNode; + QReadWriteLock rootNodeRWLock; + QReadWriteLock queueWLock; + FileNodeManagerThread *rootNodeManager; + // 是否支持一列中包含多个元素 + bool columnCompact = false; + +// QHash d->urlToNode; + + int sortRole = DFileSystemModel::FileDisplayNameRole; + QStringList nameFilters; + QDir::Filters filters; + Qt::SortOrder srotOrder = Qt::AscendingOrder; +// QModelIndex d->activeIndex; + + QPointer jobController; + QEventLoop *eventLoop = Q_NULLPTR; + QFuture updateChildrenFuture; + QAtomicInteger needQuitUpdateChildren; + DAbstractFileWatcher *watcher = Q_NULLPTR; + std::shared_ptr advanceSearchFilter; + + DFileSystemModel::State state = DFileSystemModel::Idle; + + bool childrenUpdated = false; + bool readOnly = false; + + /// add/rm file event + std::atomic _q_processFileEvent_runing; + QQueue> fileEventQueue; + QQueue> laterFileEventQueue; + + bool enabledSort = true; + + bool beginRemoveRowsFlag = false; + QMutex mutex; + //防止析构后,添加flags崩溃锁 + QMutex mutexFlags; + QAtomicInteger currentRemove = false; + + // 每列包含多个role时,存储此列活跃的role + QMap columnActiveRole; + mutable QMap nameFiltersMatchResultMap; + Q_DECLARE_PUBLIC(DFileSystemModel) +}; + +#endif // DFILESYSTEMMODEL_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemwatcher.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemwatcher.cpp new file mode 100644 index 0000000..fe7da0c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemwatcher.cpp @@ -0,0 +1,685 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfilesystemwatcher.h" +#include "private/dfilesystemwatcher_p.h" +#include "dfmglobal.h" + +#include +#include +#include + +#if defined(Q_OS_LINUX) +#include +#include +#include +#include +#endif + +DFileSystemWatcherPrivate::DFileSystemWatcherPrivate(int fd, DFileSystemWatcher *qq) + : q_ptr(qq) + , inotifyFd(fd) + , notifier(fd, QSocketNotifier::Read, qq) +{ + fcntl(inotifyFd, F_SETFD, FD_CLOEXEC); + qq->connect(¬ifier, SIGNAL(activated(int)), q_ptr, SLOT(_q_readFromInotify())); +} + +DFileSystemWatcherPrivate::~DFileSystemWatcherPrivate() +{ + notifier.setEnabled(false); + foreach (int id, pathToID) + inotify_rm_watch(inotifyFd, id < 0 ? -id : id); + + ::close(inotifyFd); +} + +QStringList DFileSystemWatcherPrivate::addPaths(const QStringList &paths, QStringList *files, QStringList *directories) +{ + QStringList p = paths; + QMutableListIterator it(p); + while (it.hasNext()) { + QString path = it.next(); + QFileInfo fi(path); + bool isDir = fi.isDir(); + if (isDir) { + if (directories->contains(path)) + continue; + } else { + if (files->contains(path)) + continue; + } + + int wd = inotify_add_watch(inotifyFd, + QFile::encodeName(path), + (isDir + ? (0 + | IN_ATTRIB + | IN_MOVE + | IN_MOVE_SELF + | IN_CREATE + | IN_DELETE + | IN_DELETE_SELF + | IN_MODIFY + | IN_UNMOUNT + ) + : (0 + | IN_ATTRIB + | IN_CLOSE_WRITE + | IN_MODIFY + | IN_MOVE + | IN_MOVE_SELF + | IN_DELETE_SELF + ))); + if (wd < 0) { + perror("DFileSystemWatcherPrivate::addPaths: inotify_add_watch failed"); + continue; + } + + it.remove(); + + int id = isDir ? -wd : wd; + if (id < 0) { + directories->append(path); + } else { + files->append(path); + } + + pathToID.insert(path, id); + idToPath.insert(id, path); + } + + return p; +} + +QStringList DFileSystemWatcherPrivate::removePaths(const QStringList &paths, QStringList *files, QStringList *directories) +{ + QStringList p = paths; + QMutableListIterator it(p); + while (it.hasNext()) { + QString path = it.next(); + int id = pathToID.take(path); + for (auto hit = idToPath.find(id); hit != idToPath.end() && hit.key() == id; ++hit) { + if (hit.value() == path) { + idToPath.erase(hit); + break; + } + } + + it.remove(); + + if (!idToPath.contains(id)) { + int wd = id < 0 ? -id : id; + //qDebug() << "removing watch for path" << path << "wd" << wd; + inotify_rm_watch(inotifyFd, wd); + } + + if (id < 0) { + directories->removeAll(path); + } else { + files->removeAll(path); + } + } + + return p; +} + +void DFileSystemWatcherPrivate::_q_readFromInotify() +{ + Q_Q(DFileSystemWatcher); +// qDebug() << "QInotifyFileSystemWatcherEngine::readFromInotify"; + + int buffSize = 0; + // fix task#36123 【自测】【桌面专业版】【SP2】【wayland】【文件管理器】 文件管理器概率出现卡死 + if (ioctl(inotifyFd, FIONREAD, (char *) &buffSize) <0 || buffSize == 0) + return; + + QVarLengthArray buffer(buffSize); + buffSize = static_cast(read(inotifyFd, buffer.data(), static_cast(buffSize))); + char *at = buffer.data(); + char * const end = at + buffSize; + + QList eventList; + QMultiHash batch_pathmap; + /// only save event: IN_MOVE_TO + QMultiMap cookieToFilePath; + QMultiMap cookieToFileName; + QSet hasMoveFromByCookie; +#ifdef QT_DEBUG + int exist_count = 0; +#endif + while (at < end) { + inotify_event *event = reinterpret_cast(at); + QStringList paths; + + at += sizeof(inotify_event) + event->len; + + int id = event->wd; + paths = idToPath.values(id); + if (paths.empty()) { + // perhaps a directory? + id = -id; + paths = idToPath.values(id); + if (paths.empty()) + continue; + } + + if (!(event->mask & IN_MOVED_TO) || !hasMoveFromByCookie.contains(event->cookie)) { + //fix bug57628归档管理器压缩成功后,桌面不显示 + //归档管理器使用命令调用7z完成压缩,压缩多个文件不在相同路径时会采用追加的方式,每次追加都会创建zip.tmp文件,追加后删除zip,再移动zip.tmp为zip文件。 + //多次追加时会创建多次zip.tmp文件,如果丢弃后面的创建事件,会导致移动时找不到原文件。 + /*! + * 经查以下代码提交记录,以及与作者沟通确认,添加去除重复事件的逻辑,是为了处理当时的wps表格保存含有大量数据行时,会收到多次重复的保存事件,导致wps表格卡死。 + * 在现有的版本(wps表格:11.1.0.9719)测试问题已不存在,谨慎放开。 + */ +#ifdef QT_DEBUG + auto it = std::find_if(eventList.begin(), eventList.end(), [event](inotify_event *e){ + return event->wd == e->wd && event->mask == e->mask && + event->cookie == e->cookie && + event->len == e->len && + !strcmp(event->name, e->name); + }); + + if (it != eventList.end()) { + qDebug() << "exist event and event->wd:" << event->wd << "event->mask:" << event->mask + << "event->cookie:" << event->cookie << "event->len:" << event->len + << "event->name:" << event->name << "exist counts " << ++exist_count; + } +#endif + eventList.append(event); + + const QList bps = batch_pathmap.values(id); + for (auto &path : paths) { + if (!bps.contains(path)) { + batch_pathmap.insert(id, path); + } + } + } + + if (event->mask & IN_MOVED_TO) { + for (auto &path : paths) { + cookieToFilePath.insert(event->cookie, path); + } + cookieToFileName.insert(event->cookie, QString::fromUtf8(event->name)); + } + + if (event->mask & IN_MOVED_FROM) + hasMoveFromByCookie << event->cookie; + } + +// qDebug() << "event count:" << eventList.count(); + + QList::const_iterator it = eventList.constBegin(); + while (it != eventList.constEnd()) { + const inotify_event &event = **it; + ++it; + +// qDebug() << "inotify event, wd" << event.wd << "cookie" << event.cookie << "mask" << hex << event.mask; + + int id = event.wd; + QStringList paths = batch_pathmap.values(id); + + if (paths.empty()) { + id = -id; + paths = batch_pathmap.values(id); + + if (paths.isEmpty()) + continue; + } + const QString &name = QString::fromUtf8(event.name, static_cast(strlen(event.name))); + + for (auto &path : paths) { +// qDebug() << "event for path" << path; + + /// TODO: Existence of invalid utf8 characters QFile can not read the file information + if (event.name != QString::fromLocal8Bit(event.name, static_cast(strlen(event.name))).toLocal8Bit()) { + if (event.mask & (IN_CREATE | IN_MOVED_TO)) { + DFMGlobal::fileNameCorrection(path); + } + } + + if ((event.mask & (IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT)) != 0) { + do { + if (event.mask & IN_MOVE_SELF) { + QMap::const_iterator iterator = cookieToFilePath.constBegin(); + + bool isMove = false; + + while (iterator != cookieToFilePath.constEnd()) { + const QString &_path = iterator.value(); + const QString &_name = cookieToFileName.value(iterator.key()); + + if (QFileInfo(_path + QDir::separator() + _name) == QFileInfo(path)) { + isMove = true; + break; + } + + ++iterator; + } + + if (isMove) + break; + } else if(event.mask & IN_UNMOUNT){//! 文件系统没卸载进行信号发送处理 + emit q->fileSystemUMount(path, QString(), DFileSystemWatcher::QPrivateSignal()); + } + + /// Keep watcher +// pathToID.remove(path); +// idToPath.remove(id, getPathFromID(id)); +// if (!idToPath.contains(id)) +// inotify_rm_watch(inotifyFd, event.wd); +// +// if (id < 0) +// onDirectoryChanged(path, true); +// else +// onFileChanged(path, true); + + emit q->fileDeleted(path, QString(), DFileSystemWatcher::QPrivateSignal()); + } while (false); + } else { + if (id < 0) + onDirectoryChanged(path, false); + else + onFileChanged(path, false); + } + + QString filePath = path; + + if (id < 0) { + if (path.endsWith(QDir::separator())) + filePath = path + name; + else + filePath = path + QDir::separator() + name; + } + + if (event.mask & IN_CREATE) { +// qDebug() << "IN_CREATE" << filePath << name; + + if (name.isEmpty()) { + if (pathToID.contains(path)) { + q->removePath(path); + q->addPath(path); + } + } else if (pathToID.contains(filePath)) { + q->removePath(filePath); + q->addPath(filePath); + } + + emit q->fileCreated(path, name, DFileSystemWatcher::QPrivateSignal()); + } + + if (event.mask & IN_DELETE) { +// qDebug() << "IN_DELETE" << filePath; + + emit q->fileDeleted(path, name, DFileSystemWatcher::QPrivateSignal()); + } + + if (event.mask & IN_MOVED_FROM) { + const QString toName = cookieToFileName.value(event.cookie); + + if (cookieToFilePath.values(event.cookie).empty()) { + emit q->fileMoved(path, name, "", "", DFileSystemWatcher::QPrivateSignal()); + } + else { + for (QString &toPath : cookieToFilePath.values(event.cookie)) { +// qDebug() << "IN_MOVED_FROM" << filePath << "to path:" << toPath << "to name:" << toName; + + emit q->fileMoved(path, name, toPath, toName, DFileSystemWatcher::QPrivateSignal()); + } + } + } + + if (event.mask & IN_MOVED_TO) { +// qDebug() << "IN_MOVED_TO" << filePath << name; + + if (!hasMoveFromByCookie.contains(event.cookie)) + emit q->fileMoved(QString(), QString(), path, name, DFileSystemWatcher::QPrivateSignal()); + } + + if (event.mask & IN_ATTRIB) { +// qDebug() << "IN_ATTRIB" << event.mask << filePath; + + emit q->fileAttributeChanged(path, name, DFileSystemWatcher::QPrivateSignal()); + } + + /*only monitor file close event which is opend by write mode*/ + if (event.mask & IN_CLOSE_WRITE) { +// qDebug() << "IN_CLOSE_WRITE" << event.mask << filePath; + + emit q->fileClosed(path, id < 0 ? name : QString(), DFileSystemWatcher::QPrivateSignal()); + } + + if (event.mask & IN_MODIFY) { +// qDebug() << "IN_MODIFY" << event.mask << filePath << name; + + emit q->fileModified(path, name, DFileSystemWatcher::QPrivateSignal()); + } + } + } +} + +void DFileSystemWatcherPrivate::onFileChanged(const QString &path, bool removed) +{ + if (!files.contains(path)) { + // the path was removed after a change was detected, but before we delivered the signal + return; + } + if (removed) { + files.removeAll(path); + } +// emit q->fileChanged(path, DFileSystemWatcher::QPrivateSignal()); +} + +void DFileSystemWatcherPrivate::onDirectoryChanged(const QString &path, bool removed) +{ + if (!directories.contains(path)) { + // perhaps the path was removed after a change was detected, but before we delivered the signal + return; + } + if (removed) { + directories.removeAll(path); + } +// emit q->directoryChanged(path, DFileSystemWatcher::QPrivateSignal()); +} + +/*! + \class DFileSystemWatcher + \inmodule QtCore + \brief The DFileSystemWatcher class provides an interface for monitoring files and directories for modifications. + \ingroup io + \since 4.2 + \reentrant + + DFileSystemWatcher monitors the file system for changes to files + and directories by watching a list of specified paths. + + Call addPath() to watch a particular file or directory. Multiple + paths can be added using the addPaths() function. Existing paths can + be removed by using the removePath() and removePaths() functions. + + DFileSystemWatcher examines each path added to it. Files that have + been added to the DFileSystemWatcher can be accessed using the + files() function, and directories using the directories() function. + + The fileChanged() signal is emitted when a file has been modified, + renamed or removed from disk. Similarly, the directoryChanged() + signal is emitted when a directory or its contents is modified or + removed. Note that DFileSystemWatcher stops monitoring files once + they have been renamed or removed from disk, and directories once + they have been removed from disk. + + \note On systems running a Linux kernel without inotify support, + file systems that contain watched paths cannot be unmounted. + + \note Windows CE does not support directory monitoring by + default as this depends on the file system driver installed. + + \note The act of monitoring files and directories for + modifications consumes system resources. This implies there is a + limit to the number of files and directories your process can + monitor simultaneously. On all BSD variants, for + example, an open file descriptor is required for each monitored + file. Some system limits the number of open file descriptors to 256 + by default. This means that addPath() and addPaths() will fail if + your process tries to add more than 256 files or directories to + the file system monitor. Also note that your process may have + other file descriptors open in addition to the ones for files + being monitored, and these other open descriptors also count in + the total. OS X uses a different backend and does not + suffer from this issue. + + + \sa QFile, QDir +*/ + + +/*! + Constructs a new file system watcher object with the given \a parent. +*/ +DFileSystemWatcher::DFileSystemWatcher(QObject *parent) + : QObject(parent) +{ + int fd = -1; +#ifdef IN_CLOEXEC + fd = inotify_init1(IN_CLOEXEC); +#endif + if (fd == -1) { + fd = inotify_init(); + } + + if (fd != -1) + d_ptr.reset(new DFileSystemWatcherPrivate(fd, this)); +} + +/*! + Constructs a new file system watcher object with the given \a parent + which monitors the specified \a paths list. +*/ +DFileSystemWatcher::DFileSystemWatcher(const QStringList &paths, QObject *parent) + : DFileSystemWatcher(parent) +{ + addPaths(paths); +} + +/*! + Destroys the file system watcher. +*/ +DFileSystemWatcher::~DFileSystemWatcher() +{ } + +/*! + Adds \a path to the file system watcher if \a path exists. The + path is not added if it does not exist, or if it is already being + monitored by the file system watcher. + + If \a path specifies a directory, the directoryChanged() signal + will be emitted when \a path is modified or removed from disk; + otherwise the fileChanged() signal is emitted when \a path is + modified, renamed or removed. + + If the watch was successful, true is returned. + + Reasons for a watch failure are generally system-dependent, but + may include the resource not existing, access failures, or the + total watch count limit, if the platform has one. + + \note There may be a system dependent limit to the number of + files and directories that can be monitored simultaneously. + If this limit is been reached, \a path will not be monitored, + and false is returned. + + \sa addPaths(), removePath() +*/ +bool DFileSystemWatcher::addPath(const QString &file) +{ + if (file.isEmpty()) { + //qWarning("DFileSystemWatcher::addPath: path is empty"); + return true; + } + + QStringList paths = addPaths(QStringList(file)); + return paths.isEmpty(); +} + +/*! + Adds each path in \a paths to the file system watcher. Paths are + not added if they not exist, or if they are already being + monitored by the file system watcher. + + If a path specifies a directory, the directoryChanged() signal + will be emitted when the path is modified or removed from disk; + otherwise the fileChanged() signal is emitted when the path is + modified, renamed, or removed. + + The return value is a list of paths that could not be watched. + + Reasons for a watch failure are generally system-dependent, but + may include the resource not existing, access failures, or the + total watch count limit, if the platform has one. + + \note There may be a system dependent limit to the number of + files and directories that can be monitored simultaneously. + If this limit has been reached, the excess \a paths will not + be monitored, and they will be added to the returned QStringList. + + \sa addPath(), removePaths() +*/ +QStringList DFileSystemWatcher::addPaths(const QStringList &paths) +{ + Q_D(DFileSystemWatcher); + + QStringList p = paths; + QMutableListIterator it(p); + + while (it.hasNext()) { + const QString &path = it.next(); + if (path.isEmpty()) + it.remove(); + } + + if (p.isEmpty()) { + //qWarning("DFileSystemWatcher::addPaths: list is empty"); + return QStringList(); + } + + if (d) + p = d->addPaths(p, &d->files, &d->directories); + + return p; +} + +/*! + Removes the specified \a path from the file system watcher. + + If the watch is successfully removed, true is returned. + + Reasons for watch removal failing are generally system-dependent, + but may be due to the path having already been deleted, for example. + + \sa removePaths(), addPath() +*/ +bool DFileSystemWatcher::removePath(const QString &path) +{ + if (path.isEmpty()) { + // qWarning("DFileSystemWatcher::removePath: path is empty"); + return true; + } + + QStringList paths = removePaths(QStringList(path)); + return paths.isEmpty(); +} + +/*! + Removes the specified \a paths from the file system watcher. + + The return value is a list of paths which were not able to be + unwatched successfully. + + Reasons for watch removal failing are generally system-dependent, + but may be due to the path having already been deleted, for example. + + \sa removePath(), addPaths() +*/ +QStringList DFileSystemWatcher::removePaths(const QStringList &paths) +{ + Q_D(DFileSystemWatcher); + + QStringList p = paths; + QMutableListIterator it(p); + + while (it.hasNext()) { + const QString &path = it.next(); + if (path.isEmpty()) + it.remove(); + } + + if (p.isEmpty()) { + //qWarning("DFileSystemWatcher::removePaths: list is empty"); + return QStringList(); + } + + if (d) + p = d->removePaths(p, &d->files, &d->directories); + + return p; +} + +/*! + \fn void DFileSystemWatcher::fileChanged(const QString &path) + + This signal is emitted when the file at the specified \a path is + modified, renamed or removed from disk. + + \sa directoryChanged() +*/ + +/*! + \fn void DFileSystemWatcher::directoryChanged(const QString &path) + + This signal is emitted when the directory at a specified \a path + is modified (e.g., when a file is added or deleted) or removed + from disk. Note that if there are several changes during a short + period of time, some of the changes might not emit this signal. + However, the last change in the sequence of changes will always + generate this signal. + + \sa fileChanged() +*/ + +/*! + \fn QStringList DFileSystemWatcher::directories() const + + Returns a list of paths to directories that are being watched. + + \sa files() +*/ + +/*! + \fn QStringList DFileSystemWatcher::files() const + + Returns a list of paths to files that are being watched. + + \sa directories() +*/ + +QStringList DFileSystemWatcher::directories() const +{ + Q_D(const DFileSystemWatcher); + + if (!d) + return QStringList(); + + return d->directories; +} + +QStringList DFileSystemWatcher::files() const +{ + Q_D(const DFileSystemWatcher); + + if (!d) + return QStringList(); + + return d->files; +} + +#include "moc_dfilesystemwatcher.cpp" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemwatcher.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemwatcher.h new file mode 100644 index 0000000..a4b28ed --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilesystemwatcher.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILESYSTEMWATCHER_H +#define DFILESYSTEMWATCHER_H + +#include + +class DFileSystemWatcherPrivate; +class DFileSystemWatcher : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DFileSystemWatcher) + +public: + explicit DFileSystemWatcher(QObject *parent = Q_NULLPTR); + DFileSystemWatcher(const QStringList &paths, QObject *parent = Q_NULLPTR); + ~DFileSystemWatcher(); + + bool addPath(const QString &file); + QStringList addPaths(const QStringList &paths); + bool removePath(const QString &path); + QStringList removePaths(const QStringList &paths); + + QStringList files() const; + QStringList directories() const; + +Q_SIGNALS: + void fileDeleted(const QString &path, const QString &name, QPrivateSignal); + void fileAttributeChanged(const QString &path, const QString &name, QPrivateSignal); + void fileClosed(const QString &path, const QString &name, QPrivateSignal); + void fileMoved(const QString &fromPath, const QString &fromName, + const QString &toPath, const QString &toName, QPrivateSignal); + void fileCreated(const QString &path, const QString &name, QPrivateSignal); + void fileModified(const QString &path, const QString &name, QPrivateSignal); + + //! 当挂载的文件系统被卸载时发送卸载卸载信号 + void fileSystemUMount(const QString &path, const QString &name, QPrivateSignal); +private: + QScopedPointer d_ptr; + + Q_PRIVATE_SLOT(d_func(), void _q_readFromInotify()) +}; + +#endif // DFILESYSTEMWATCHER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileviewhelper.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileviewhelper.cpp new file mode 100644 index 0000000..215915e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileviewhelper.cpp @@ -0,0 +1,1010 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfileviewhelper.h" +#include "dfmglobal.h" +#include "dfmstyleditemdelegate.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "dfmevent.h" +#include "views/windowmanager.h" +#include "dabstractfileinfo.h" +#include "dfilesystemmodel.h" +#include "views/fileitem.h" +#include "views/dtagactionwidget.h" +#include "singleton.h" +#include "dfileservices.h" +#include "dfmgenericfactory.h" +#include "dialogs/filepreviewdialog.h" +#include "controllers/appcontroller.h" +#include "controllers/mergeddesktopcontroller.h" +#include "dfmeventdispatcher.h" +#include "dfilemenu.h" +#include "tag/tagmanager.h" +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "dstorageinfo.h" +#include "controllers/vaultcontroller.h" +#include "dfmstandardpaths.h" +#include "deviceinfo/udisklistener.h" + +#include + +#include +#include +#define protected public +#include +#undef protected +#include +#include +#include +#include + +#include + +DWIDGET_USE_NAMESPACE + +class MenuActionEventHandler : public DFMAbstractEventHandler +{ +public: + explicit MenuActionEventHandler(DFileViewHelper *helper) + : DFMAbstractEventHandler(false) + , viewHelper(helper) + { + } + + bool fmEventFilter(const QSharedPointer &event, DFMAbstractEventHandler *target, QVariant *resultData) override + { + Q_UNUSED(target) + Q_UNUSED(resultData) + + if (event->type() != DFMEvent::MenuAction) { + return false; + } + + if (event->windowId() != viewHelper->windowId()) { + return false; + } + + const DFMMenuActionEvent &menu_event = dfmevent_cast(*event.data()); + if (menu_event.action() == DFMGlobal::MenuAction::RefreshView) { + viewHelper->viewFlicker(); + return true; + } + if (menu_event.action() != DFMGlobal::TagInfo) + return false; + + if (menu_event.selectedUrls().isEmpty()) + return false; + + //在多标签的情况下只判断currentUrl无法区分同一个目录打开的多个标签 + //修改为判断事件发送者和viewhelper的持有者是否为同一个view对象 + if (menu_event.sender() && viewHelper->parent()) { + if (menu_event.sender().data() != viewHelper->parent()) + return false; + } + + //优先取当前点击的index作为tagedit的基点 + const QModelIndex &index = menu_event.clickedIndex() != QModelIndex() ? menu_event.clickedIndex() : viewHelper->model()->index(menu_event.selectedUrls().first()); + const QRect &rect = viewHelper->parent()->visualRect(index); + QStyleOptionViewItem option = viewHelper->parent()->viewOptions(); + + option.rect = rect; + + const QList &geometry_list = viewHelper->itemDelegate()->paintGeomertys(option, index); + const QRect &icon_rect = geometry_list.first(); + bool isCanvas = viewHelper->property("isCanvasViewHelper").toBool(); + int iconTopOffset = isCanvas ? 0 : (option.rect.height() - icon_rect.height()) / 3.0; + + const QPoint &edit_pos = QPoint(icon_rect.x() + icon_rect.width() / 2, icon_rect.bottom() + iconTopOffset); + /****************************************************************************************************************************/ + //在靠近边框底部不够显示编辑框时,编辑框的箭头出现在底部 + //appController->showTagEdit(viewHelper->parent()->viewport()->mapToGlobal(edit_pos), menu_event.selectedUrls()); + const QRect &parentRect = viewHelper->parent()->geometry(); + appController->showTagEdit(parentRect, viewHelper->parent()->viewport()->mapToGlobal(edit_pos), menu_event.selectedUrls()); + /****************************************************************************************************************************/ + return true; + } + +private: + DFileViewHelper *viewHelper = nullptr; +}; + +class DFileViewHelperPrivate +{ +public: + explicit DFileViewHelperPrivate(DFileViewHelper *qq) + : menuEventHandler(new MenuActionEventHandler(qq)) + , q_ptr(qq) + { + DFMEventDispatcher::instance()->installEventFilter(menuEventHandler); + } + + ~DFileViewHelperPrivate() + { + delete menuEventHandler; + menuEventHandler = nullptr; + } + + DFileViewHelperPrivate(DFileViewHelperPrivate &) = delete; + DFileViewHelperPrivate &operator=(DFileViewHelperPrivate &) = delete; + + void init(); + QModelIndex findIndex(const QByteArray &keys, bool matchStart, + int current, bool reverse_order, bool excludeCurrent) const; + + void _q_edit(const DFMUrlBaseEvent &event); + void _q_selectAndRename(const DFMUrlBaseEvent &event); + + QByteArray keyboardSearchKeys; + QTimer keyboardSearchTimer; + MenuActionEventHandler *menuEventHandler; + + static QObjectList pluginObjectList; + static QList getAdditionalIconByPlugins(const DAbstractFileInfoPointer &fileInfo); + + DFileViewHelper *q_ptr; + + Q_DECLARE_PUBLIC(DFileViewHelper) +}; + +QObjectList DFileViewHelperPrivate::pluginObjectList; + +void DFileViewHelperPrivate::init() +{ + Q_Q(DFileViewHelper); + + keyboardSearchTimer.setSingleShot(true); + keyboardSearchTimer.setInterval(200); + + // init connects + QObject::connect(&keyboardSearchTimer, &QTimer::timeout, + q, [this] { + keyboardSearchKeys.clear(); + }); + QObject::connect(qApp, &DApplication::iconThemeChanged, q->parent(), static_cast(&QWidget::update)); + QObject::connect(DFMGlobal::instance(), &DFMGlobal::clipboardDataChanged, q, [q] { + if (q->itemDelegate()) + { + for (const QModelIndex &index : q->itemDelegate()->hasWidgetIndexs()) { + QWidget *item = q->indexWidget(index); + + if (item) { + item->setProperty("opacity", q->isTransparent(index) ? 0.3 : 1); + } + } + } + + q->parent()->update(); + }); + + // init actions + QAction *copy_action = new QAction(q->parent()); + + copy_action->setAutoRepeat(false); + copy_action->setShortcut(QKeySequence::Copy); + + QObject::connect(copy_action, &QAction::triggered, + q, [q] { + // fix bug 62872 + // 与右键菜单保持一致,如果选中项只有一个且选中项不可读,则复制操作无效 + if (q->selectedUrls().size() == 1) { + const DAbstractFileInfoPointer &fileInfo = fileService->createFileInfo(nullptr, q->selectedUrls().first()); + if (!fileInfo || !fileInfo->isReadable()) + return; + } + DUrlList selectedUrls = q->selectedUrls(); + qInfo() << " ctrl C writeFilesToClipboard and selectedUrls = " << selectedUrls + << " currentUrl = " << q->currentUrl(); + fileService->writeFilesToClipboard(q, DFMGlobal::CopyAction, selectedUrls); + }); + + QAction *cut_action = new QAction(q->parent()); + + cut_action->setAutoRepeat(false); + cut_action->setShortcut(QKeySequence::Cut); + + QObject::connect(cut_action, &QAction::triggered, + q, [q] { + // 只支持回收站根目录下的文件执行剪切 + const DAbstractFileInfoPointer &rootInfo = fileService->createFileInfo(q, q->currentUrl()); + if (!rootInfo || !rootInfo->isWritable()) { + qInfo() << "Read only folders do not support Ctrl + X operations!folders = " << q->currentUrl(); + return; + } + + if (!q->selectedUrls().isEmpty()) { + DUrl url = q->selectedUrls().first(); + if (url.isTrashFile() && url.parentUrl() != DUrl::fromTrashFile("/")) + return; + } + DUrlList selectedUrls = q->selectedUrls(); + qInfo() << " ctrl X writeFilesToClipboard and selectedUrls = " << selectedUrls + << " currentUrl = " << q->currentUrl(); + fileService->writeFilesToClipboard(q, DFMGlobal::CutAction, selectedUrls); + }); + + QAction *paste_action = new QAction(q->parent()); + + paste_action->setShortcut(QKeySequence::Paste); + + QObject::connect(paste_action, &QAction::triggered, + q, [q] { + qInfo() << " ctrl V pasteFileByClipboard and currentUrl = " << q->currentUrl(); + fileService->pasteFileByClipboard(q->parent(), q->currentUrl()); + }); + + QAction *revocation_action = new QAction(q->parent()); + + revocation_action->setShortcut(QKeySequence::Undo); + + QObject::connect(revocation_action, &QAction::triggered, + q, [q] { + qInfo() << " ctrl Z recovert operation !"; + DFMEventDispatcher::instance()->processEvent(q); + }); + + q->parent()->addAction(copy_action); + q->parent()->addAction(cut_action); + q->parent()->addAction(paste_action); + q->parent()->addAction(revocation_action); + + q->connect(fileSignalManager, SIGNAL(requestRename(DFMUrlBaseEvent)), q, SLOT(_q_edit(DFMUrlBaseEvent))); + q->connect(fileSignalManager, SIGNAL(requestSelectRenameFile(DFMUrlBaseEvent)), q, SLOT(_q_selectAndRename(DFMUrlBaseEvent))); + // call later + QTimer::singleShot(0, q, [q] { + q->connect(fileSignalManager, SIGNAL(trashStateChanged()), q->model(), SLOT(update())); + }); + + // init plugin objects + static bool initialized = false; + + if (!initialized) { + initialized = true; + + pluginObjectList = DFMGenericFactory::createAll(QStringLiteral("fileinfo/additionalIcon")); + } +} + +QModelIndex DFileViewHelperPrivate::findIndex(const QByteArray &keys, bool matchStart, + int current, bool reverse_order, bool excludeCurrent) const +{ + Q_Q(const DFileViewHelper); + + int row_count = q->parent()->model()->rowCount(q->parent()->rootIndex()); + + for (int i = excludeCurrent ? 1 : 0; i < row_count; ++i) { + int row = reverse_order ? row_count + current - i : current + i; + + row = row % row_count; + + if (excludeCurrent && row == current) { + continue; + } + + const QModelIndex &index = q->parent()->model()->index(row, 0, q->parent()->rootIndex()); + const QString &pinyin_name = q->parent()->model()->data(index, DFileSystemModel::FilePinyinName).toString(); + + if (matchStart ? pinyin_name.startsWith(keys, Qt::CaseInsensitive) + : pinyin_name.contains(keys, Qt::CaseInsensitive)) { + return index; + } + } + + return QModelIndex(); +} + +void DFileViewHelperPrivate::_q_edit(const DFMUrlBaseEvent &event) +{ + Q_Q(DFileViewHelper); + + if (event.windowId() != q->windowId()) { + return; + } + + DUrl fileUrl = event.url(); + + if (!fileUrl.isValid()) { + return; + } + + const QModelIndex &index = q->model()->index(fileUrl); + + if (q->parent()->isVisible()) { + q->parent()->edit(index, QAbstractItemView::EditKeyPressed, 0); + } +} + +void DFileViewHelperPrivate::_q_selectAndRename(const DFMUrlBaseEvent &event) +{ + Q_Q(DFileViewHelper); + + if (event.windowId() != q->windowId() || !q->parent()->isVisible()) { + return; + } + + q->select(DUrlList() << event.url()); + _q_edit(event); +} + +QList DFileViewHelperPrivate::getAdditionalIconByPlugins(const DAbstractFileInfoPointer &fileInfo) +{ + QList list; + + for (QObject *object : pluginObjectList) { + QList plugin_list; + + bool ok = object->metaObject()->invokeMethod(object, "fileAdditionalIcon", + Q_RETURN_ARG(QList, plugin_list), + Q_ARG(const DAbstractFileInfoPointer &, fileInfo)); + + if (ok) { + list << plugin_list; + } else { + qWarning() << "call the fileAdditionalIcon slot failed"; + } + } + + return list; +} + +DFileViewHelper::DFileViewHelper(QAbstractItemView *parent) + : QObject(parent) + , d_ptr(new DFileViewHelperPrivate(this)) +{ + Q_ASSERT(parent); + + d_func()->init(); +} + +DFileViewHelper::~DFileViewHelper() +{ + +} + +QAbstractItemView *DFileViewHelper::parent() const +{ + return qobject_cast(QObject::parent()); +} + +/*! + * \brief Returns the window id of the top-level window in the parent widget. + * \return + */ +quint64 DFileViewHelper::windowId() const +{ + return WindowManager::getWindowId(parent()); +} + +/*! + * \brief Return true if index is transparent; otherwise return false. + * \param index + * \return + */ +bool DFileViewHelper::isTransparent(const QModelIndex &index) const +{ + const DAbstractFileInfoPointer &fileInfo = this->fileInfo(index); + + if (!fileInfo) { + return false; + } + DUrl fileUrl = fileInfo->fileUrl(); + + if (fileInfo->fileUrl().isSearchFile()) { + fileUrl = fileInfo->fileUrl().searchedFileUrl(); + } + + //如果在tag的view下,获取的url是tag的,需要转为localfile的url + if (fileInfo->fileUrl().isTaggedFile()) { + fileUrl = DUrl::fromLocalFile(fileInfo->fileUrl().taggedLocalFilePath()); + } + + //staging files are transparent + if (currentUrl().scheme() == BURN_SCHEME && fileUrl.scheme() == BURN_SCHEME && !fileUrl.burnIsOnDisc()) { + return true; + } + + // 解决在保险箱中执行剪切时,图标不灰显的问题 + if (fileUrl.scheme() == DFMVAULT_SCHEME) { + fileUrl = VaultController::vaultToLocalUrl(fileUrl); + } + + // 将回收站路径转化成真实路径,解决在回收站中执行剪切时,图标不灰显的问题 + bool isTrashFile = false; + if (fileUrl.scheme() == TRASH_SCHEME) { + isTrashFile = true; + const QString &path = fileUrl.path(); + fileUrl = DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath) + path); + } + + //为了防止自动整理下剪切与分类名相同的文件夹,如果是分类就不转真实路径了 + auto isVPath = MergedDesktopController::isVirtualEntryPaths(fileUrl); + if (fileUrl.scheme() == DFMMD_SCHEME && !isVPath) + fileUrl = MergedDesktopController::convertToRealPath(fileUrl); + + //判断该文件是否被剪切 + if (DFMGlobal::instance()->clipboardAction() == DFMGlobal::CutAction && (isTrashFile || fileInfo->canRename())) { + if (DFMGlobal::instance()->clipboardFileUrlList().contains(fileUrl)) + return true; + + //链接文件只判断url,不判断inode,因为链接文件的inode与源文件的inode是一致的 + if (!fileInfo->isSymLink()) { + if (DFMGlobal::instance()->clipboardFileInodeList().contains(fileInfo->inode())) + return true; + } + } + + return false; +} + +/*! + * \brief Return true if index is selected; otherwise return false. + * \param index + * \return + */ +bool DFileViewHelper::isSelected(const QModelIndex &index) const +{ + return parent()->selectionModel()->isSelected(index); +} + +/*! + * \brief Return true if file view drag moveing and mouse hover on index; otherwise return false. + * \param index + * \return + */ +bool DFileViewHelper::isDropTarget(const QModelIndex &index) const +{ + Q_UNUSED(index) + + return false; +} + +/*! + * \brief Return the view of selected index count. + * \return + */ +int DFileViewHelper::selectedIndexsCount() const +{ + return parent()->selectionModel()->selectedIndexes().count(); +} + +/*! + * \brief Return the view row count. + * \return + */ +int DFileViewHelper::rowCount() const +{ + return parent()->model()->rowCount(parent()->rootIndex()); +} + +/*! + * \brief Return the index row index. + * \param index + * \return + */ +int DFileViewHelper::indexOfRow(const QModelIndex &index) const +{ + Q_UNUSED(index) + + return -1; +} + +/*! + * \brief Returns corner icon by file info(file permission...). + * \param index + * \return + */ +QList DFileViewHelper::additionalIcon(const QModelIndex &index) const +{ + QList list; + const DAbstractFileInfoPointer &fileInfo = this->fileInfo(index); + + if (!fileInfo || !fileInfo->exists()) { + return list; + } + + list << fileInfo->additionalIcon(); + list << DFileViewHelperPrivate::getAdditionalIconByPlugins(fileInfo); + + return list; +} + +/*! + * \brief Returns the complete base name of the file without the path. + The complete base name consists of all characters in the file up to (but not including) the file suffix. + * \param index + * \return + */ +QString DFileViewHelper::baseName(const QModelIndex &index) const +{ + const DAbstractFileInfoPointer &fileInfo = this->fileInfo(index); + + if (!fileInfo) { + return QString(); + } + + return fileInfo->baseName(); +} + +/*! + * \brief Return the view role list by column + * \return + */ +QList DFileViewHelper::columnRoleList() const +{ + return QList(); +} + +/*! + * \brief Return column width by column index + * \param columnIndex + * \return + */ +int DFileViewHelper::columnWidth(int columnIndex) const +{ + Q_UNUSED(columnIndex) + + return -1; +} + +DUrl DFileViewHelper::currentUrl() const +{ + const DAbstractFileInfoPointer &fileInfo = this->fileInfo(parent()->rootIndex()); + + if (!fileInfo) { + return DUrl(); + } + + return fileInfo->fileUrl(); +} + +void DFileViewHelper::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const +{ + if (isSelected(index) && index.flags().testFlag(Qt::ItemFlag::ItemIsSelectable)) { + option->state |= QStyle::State_Selected; + } else { + option->state &= QStyle::StateFlag(~QStyle::State_Selected); + } + + QPalette appPalette = QGuiApplication::palette(); + + auto setcolor1 = [](QPalette & p1, QPalette & p2, QPalette::ColorRole role) { + p1.setColor(role, p2.color(role)); + }; + + auto setcolor2 = [](QPalette & p1, QPalette & p2, QPalette::ColorGroup group, QPalette::ColorRole role) { + p1.setColor(group, role, p2.color(group, role)); + }; + + setcolor1(option->palette, appPalette, QPalette::Text); + setcolor2(option->palette, appPalette, QPalette::Disabled, QPalette::Text); + + if ((option->state & QStyle::State_Selected) && option->showDecorationSelected) { + setcolor2(option->palette, appPalette, QPalette::Inactive, QPalette::Text); + } else { + setcolor2(option->palette, appPalette, QPalette::Inactive, QPalette::Text); + } + + option->palette.setColor(QPalette::BrightText, Qt::white); + + setcolor1(option->palette, appPalette, QPalette::Shadow); + + if ((option->state & QStyle::State_HasFocus) && option->showDecorationSelected && selectedIndexsCount() > 1) { + setcolor2(option->palette, appPalette, QPalette::Current, QPalette::Background); + } else { + setcolor2(option->palette, appPalette, QPalette::Normal, QPalette::Background); + } + + bool transp = isTransparent(index); + option->backgroundBrush = appPalette.brush(transp ? QPalette::Inactive : QPalette::Current, QPalette::Background); + + option->textElideMode = Qt::ElideLeft; +} + +void DFileViewHelper::handleMenu(QMenu *menu) +{ + DFileMenu *file_menu = qobject_cast(menu); + + if (Q_UNLIKELY(!file_menu)) + return; + + + QAction *tag_action = file_menu->actionAt("Add color tags"); + + if (!tag_action) + return; + + QWidgetAction *widget_action = qobject_cast(tag_action); + + if (Q_UNLIKELY(!widget_action)) + return; + + DTagActionWidget *tag_widget = qobject_cast(widget_action->defaultWidget()); + + if (Q_UNLIKELY(!tag_widget)) + return; + + const QStringList &tag_names = DFileService::instance()->getTagsThroughFiles(parent(), file_menu->selectedUrls()); + QList colors; + + for (const QString &tag : tag_names) { + const QString &color_display_name = TagManager::instance()->getColorByDisplayName(tag); + + if (color_display_name.isEmpty()) + continue; + + const QColor &color = TagManager::instance()->getColorByColorName(color_display_name); + + if (Q_LIKELY(color.isValid())) + colors << color; + } + + tag_widget->setCheckedColorList(colors); + + connect(tag_widget, &DTagActionWidget::hoverColorChanged, menu, [tag_widget](const QColor & color) { + if (color.isValid()) { + const QString &tag_name = TagManager::instance()->getTagNameThroughColor(color); + + tag_widget->setToolTipText(tr("Add tag \"%1\"").arg(tag_name)); + } else { + tag_widget->clearToolTipText(); + } + }); +} + +/*! + * \brief Sets the given widget on the item at the given index, passing the ownership of the widget to the view viewport. + * If index is invalid (e.g., if you pass the root index), this function will do nothing. + * \param index + * \param widget + * \sa indexWidget() + */ +void DFileViewHelper::setIndexWidget(const QModelIndex &index, QWidget *widget) +{ + parent()->setIndexWidget(index, widget); +} + +/*! + * \brief Returns the widget for the item at the given index. + * \param index + * \return + * \sa setIndexWidget() + */ +QWidget *DFileViewHelper::indexWidget(const QModelIndex &index) const +{ + return parent()->indexWidget(index); +} + +/*! + * \brief Updates the geometry of the child widgets of the view. + */ +void DFileViewHelper::updateGeometries() +{ + parent()->updateGeometries(); +} + +/*! + * \brief Returns the margins around the file view. By default all the margins are zero. + * \return + */ +QMargins DFileViewHelper::fileViewViewportMargins() const +{ + return parent()->viewportMargins(); +} + +/*! + * \brief DFileViewHelper::keyboardSearch + * \param key + */ +void DFileViewHelper::keyboardSearch(char key) +{ + Q_D(DFileViewHelper); + QByteArray indexChar; + d->keyboardSearchKeys.append(key); + bool reverse_order = qApp->keyboardModifiers() == Qt::ShiftModifier; + const QModelIndex ¤t_index = parent()->currentIndex(); + + QModelIndex index = d->findIndex(d->keyboardSearchKeys, true, current_index.row(), reverse_order, !d->keyboardSearchTimer.isActive()); +// if (!index.isValid()) { +// // 使用 QString::contains 模式再次匹配 +// index = d->findIndex(d->keyboardSearchKeys, false, current_index.row(), reverse_order, !d->keyboardSearchTimer.isActive()); +// } + + if (index.isValid()) { + parent()->setCurrentIndex(index); + parent()->scrollTo(index, reverse_order ? QAbstractItemView::PositionAtBottom : QAbstractItemView::PositionAtTop); + } + // 开始计时,超过此时间后的搜索将清空之前输入的关键字 + d->keyboardSearchTimer.start(); +} + +/*! + * \brief Return true if the position is empty area; otherwise return false. + * \param pos + * \return + */ +bool DFileViewHelper::isEmptyArea(const QPoint &pos) const +{ + const QModelIndex &index = parent()->indexAt(pos); + + if (index.isValid() && isSelected(index)) { + return false; + } else { + const QRect &rect = parent()->visualRect(index); + + if (!rect.contains(pos)) { + return true; + } + + QStyleOptionViewItem option = parent()->viewOptions(); + + option.rect = rect; + + const QList &geometry_list = itemDelegate()->paintGeomertys(option, index); + auto ret = std::any_of(geometry_list.begin(), geometry_list.end(), [pos](const QRect & rect) { + return rect.contains(pos); + }); + if (ret) + return false; + } + + return index.isValid();//true; +} + +void DFileViewHelper::preproccessDropEvent(QDropEvent *event) const +{ + bool sameUser = DFMGlobal::isMimeDatafromCurrentUser(event->mimeData()); + if (event->source() == parent() && !DFMGlobal::keyCtrlIsPressed()) { + event->setDropAction(sameUser ? Qt::MoveAction : Qt::IgnoreAction); + } else { + DAbstractFileInfoPointer info = model()->fileInfo(parent()->indexAt(event->pos())); + + if (!info) + info = model()->fileInfo(parent()->rootIndex()); + + if (!info) { + return; + } + + QList urls = event->mimeData()->urls(); + + if (urls.empty()) + return; + + Qt::DropAction default_action = Qt::CopyAction; + const DUrl from = DUrl(urls.first()); + DUrl to = info->fileUrl(); + + //fix bug#23703勾选自动整理,拖拽其他目录文件到桌面做得是复制操作 + //因为自动整理的路径被DStorageInfo::inSameDevice判断为false,这里做转化 + if (to.scheme() == DFMMD_SCHEME) { + to = DUrl(info->absoluteFilePath()); + to.setScheme(FILE_SCHEME); + } + //end + + if (qApp->keyboardModifiers() == Qt::AltModifier) { + default_action = Qt::MoveAction; + } else if (!DFMGlobal::keyCtrlIsPressed()) { + // 如果文件和目标路径在同一个分区下,默认为移动文件,否则默认为复制文件 + if (DStorageInfo::inSameDevice(from, to)) { + default_action = Qt::MoveAction; + } + } + + //任意来源为回收站的drop操作均为move(统一回收站拖拽标准) + bool isFromTrash = from.url().contains(".local/share/Trash/"); + bool isToTrash = to.isTrashFile(); + if (isFromTrash || isToTrash) { + if (!isFromTrash || !isToTrash) { + default_action = Qt::MoveAction; + } else { + return event->setDropAction(Qt::IgnoreAction); + } + } + + if (event->possibleActions().testFlag(default_action)) { + event->setDropAction((default_action == Qt::MoveAction && !sameUser) ? Qt::IgnoreAction : default_action); + } + + if (!info->supportedDropActions().testFlag(event->dropAction())) { + QList actions; + + actions.reserve(3); + actions << Qt::CopyAction << Qt::MoveAction << Qt::LinkAction; + + for (Qt::DropAction action : actions) { + + if (event->possibleActions().testFlag(action) && info->supportedDropActions().testFlag(action)) { + event->setDropAction((action == Qt::MoveAction && !sameUser) ? Qt::IgnoreAction : action); + break; + } + } + } + + // 保险箱时,修改DropAction为Qt::CopyAction + if ((VaultController::isVaultFile(info->fileUrl().toString()) + || VaultController::isVaultFile(urls[0].toString())) + && !isToTrash) { + event->setDropAction(Qt::CopyAction); + } + + // 最近使用目录下的文件,只有拖拽到回收站为剪切,其他都为拷贝 + if (from.isRecentFile()) { + default_action = isToTrash ? Qt::MoveAction : Qt::CopyAction; + event->setDropAction(default_action); + } + } +} + +void DFileViewHelper::preproccessDropEvent(QDropEvent *event, const QList &urls) const +{ + bool sameUser = DFMGlobal::isMimeDatafromCurrentUser(event->mimeData()); + if (event->source() == parent() && !DFMGlobal::keyCtrlIsPressed()) { + event->setDropAction(sameUser ? Qt::MoveAction : Qt::IgnoreAction); + } else { + DAbstractFileInfoPointer info = model()->fileInfo(parent()->indexAt(event->pos())); + if (!info) + info = model()->fileInfo(parent()->rootIndex()); + + if (!info) { + return; + } + + if (urls.empty()) + return; + + const DUrl from = DUrl(urls.first()); + DUrl to = info->fileUrl(); + Qt::DropAction default_action = Qt::CopyAction; + + //fix bug#23703勾选自动整理,拖拽其他目录文件到桌面做得是复制操作 + //因为自动整理的路径被DStorageInfo::inSameDevice判断为false,这里做转化 + if (to.scheme() == DFMMD_SCHEME) { + to = DUrl(info->absoluteFilePath()); + to.setScheme(FILE_SCHEME); + } + //end + + if (qApp->keyboardModifiers() == Qt::AltModifier) { + default_action = Qt::MoveAction; + } else if (!DFMGlobal::keyCtrlIsPressed()) { + // 如果文件和目标路径在同一个分区下,默认为移动文件,否则默认为复制文件 + if (DStorageInfo::inSameDevice(from, to)) { + default_action = Qt::MoveAction; + } + } + + //任意来源为回收站的drop操作均为move(统一回收站拖拽标准) + bool isFromTrash = from.url().contains(".local/share/Trash/"); + bool isToTrash = to.isTrashFile(); + + if (isFromTrash || isToTrash) { + if (!isFromTrash || !isToTrash) { + default_action = Qt::MoveAction; + } else { + return event->setDropAction(Qt::IgnoreAction); + } + } + + if (event->possibleActions().testFlag(default_action)) { + event->setDropAction((default_action == Qt::MoveAction && !sameUser) ? Qt::IgnoreAction : default_action); + } + + // 保险箱时,修改DropAction为Qt::CopyAction + if (VaultController::isVaultFile(info->fileUrl().toString()) + || VaultController::isVaultFile(urls[0].toString())) { + event->setDropAction(Qt::CopyAction); + } + + if (!info->supportedDropActions().testFlag(event->dropAction())) { + QList actions; + + actions.reserve(3); + actions << Qt::CopyAction << Qt::MoveAction << Qt::LinkAction; + + for (Qt::DropAction action : actions) { + + if (event->possibleActions().testFlag(action) && info->supportedDropActions().testFlag(action)) { + event->setDropAction((action == Qt::MoveAction && !sameUser) ? Qt::IgnoreAction : action); + break; + } + } + } + + // 最近使用目录下的文件,只有拖拽到回收站为剪切,其他都为拷贝 + if (from.isRecentFile()) { + default_action = isToTrash ? Qt::MoveAction : Qt::CopyAction; + event->setDropAction(default_action); + } + } +} + +void DFileViewHelper::handleCommitData(QWidget *editor) const +{ + if (!editor) { + return; + } + + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(itemDelegate()->editingIndex()); + + if (!fileInfo) { + return; + } + + QLineEdit *lineEdit = qobject_cast(editor); + FileIconItem *item = qobject_cast(editor); + + DFMEvent event(this); + event.setData(fileInfo->fileUrl()); + event.setWindowId(windowId()); + + QString new_file_name = lineEdit ? lineEdit->text() : item ? item->edit->toPlainText() : ""; + + if (new_file_name.isEmpty()) { + return; + } + + QString suffix_str_as_var{ editor->property("_d_whether_show_suffix").toString() }; + + if (!suffix_str_as_var.isEmpty()) { + new_file_name += QString{"."}; + new_file_name += suffix_str_as_var; + } else if (DFMApplication::genericObtuselySetting()->value("FileName", "non-allowableEmptyCharactersOfEnd").toBool()) { + //保留文件名称中的空格符号 + //new_file_name = new_file_name.trimmed(); + + if (new_file_name.isEmpty()) { + return; + } + } + + if (fileInfo->fileName() == new_file_name) { + return; + } + + DUrl old_url = fileInfo->fileUrl(); + //处理tag目录重命名了逻辑 + if (old_url.isTaggedFile() && old_url.taggedLocalFilePath().isEmpty()) { + TagManager::instance()->changeTagName(qMakePair(old_url.tagName(), new_file_name)); + return; + } + + DUrl new_url = fileInfo->getUrlByNewFileName(new_file_name); + + const DAbstractFileInfoPointer &newFileInfo = DFileService::instance()->createFileInfo(this, new_url); + + if (newFileInfo && newFileInfo->fileName().isEmpty() && newFileInfo->suffixOfRename() == fileInfo->suffixOfRename()) { + return; + } + AppController::selectionFile = qMakePair(new_url, windowId()); + + // 重命名文件完成后会删除view中的文件所在行,此时会触发销毁文件名编辑控件的动作。 + // 但是QAbstractItemView再调用commitEditorData之后紧接着还会调用closeEditor + // 此时又会尝试销毁编辑控件,导致应用程序崩溃 + TIMER_SINGLESHOT(0, { + fileService->renameFile(this, old_url, new_url); + }, old_url, new_url, this) +} + +#include "moc_dfileviewhelper.cpp" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileviewhelper.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileviewhelper.h new file mode 100644 index 0000000..aa31149 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfileviewhelper.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILEVIEWHELPER_H +#define DFILEVIEWHELPER_H + +#include +#include +#include + +#include "dabstractfileinfo.h" + +QT_BEGIN_NAMESPACE +class QAbstractItemView; +class QStyleOptionViewItem; +class QMenu; +QT_END_NAMESPACE +class DAbstractFileInfo; +class DFMStyledItemDelegate; +class DFileSystemModel; +class DFileViewHelperPrivate; +class DFileViewHelper : public QObject +{ + Q_OBJECT + +public: + explicit DFileViewHelper(QAbstractItemView *parent); + ~DFileViewHelper(); + + QAbstractItemView *parent() const; + + virtual quint64 windowId() const; + virtual bool isTransparent(const QModelIndex &index) const; + virtual bool isSelected(const QModelIndex &index) const; + virtual bool isDropTarget(const QModelIndex &index) const; + virtual int selectedIndexsCount() const; + virtual int rowCount() const; + virtual int indexOfRow(const QModelIndex &index) const; + QList additionalIcon(const QModelIndex &index) const; + QString baseName(const QModelIndex &index) const; + virtual QList columnRoleList() const; + virtual int columnWidth(int columnIndex) const; + virtual DUrl currentUrl() const; + + virtual const DAbstractFileInfoPointer fileInfo(const QModelIndex &index) const = 0; + virtual DFMStyledItemDelegate *itemDelegate() const = 0; + virtual DFileSystemModel *model() const = 0; + virtual const DUrlList selectedUrls() const = 0; + virtual void select(const QList &list) = 0; + + virtual void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const; + virtual void handleMenu(QMenu *menu); + + virtual void viewFlicker() = 0; + void setIndexWidget(const QModelIndex &index, QWidget *widget); + QWidget *indexWidget(const QModelIndex &index) const; + void updateGeometries(); + QMargins fileViewViewportMargins() const; + + void keyboardSearch(char key); + bool isEmptyArea(const QPoint &pos) const; + + void preproccessDropEvent(QDropEvent *event) const; + void preproccessDropEvent(QDropEvent *event, const QList &urls) const; + +public slots: + void handleCommitData(QWidget *editor) const; + +signals: + void triggerEdit(const QModelIndex &index); + +private: + QScopedPointer d_ptr; + + Q_PRIVATE_SLOT(d_func(), void _q_edit(const DFMUrlBaseEvent &event)) + Q_PRIVATE_SLOT(d_func(), void _q_selectAndRename(const DFMUrlBaseEvent &event)) + + Q_DECLARE_PRIVATE(DFileViewHelper) + Q_DISABLE_COPY(DFileViewHelper) +}; + +#endif // DFILEVIEWHELPER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilewatcher.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilewatcher.cpp new file mode 100644 index 0000000..13f7a73 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilewatcher.cpp @@ -0,0 +1,439 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfilewatcher.h" +#include "private/dabstractfilewatcher_p.h" + +#include "dfileservices.h" +#include "dfilesystemwatcher.h" + +#include "private/dfilesystemwatcher_p.h" +#include "../vault/vaultglobaldefine.h" +#include "controllers/vaultcontroller.h" +#include "app/filesignalmanager.h" +#include "utils/singleton.h" +#include "app/define.h" +#include +#include + +static QString joinFilePath(const QString &path, const QString &name) +{ + if (path.endsWith(QDir::separator())) + return path + name; + + return path + QDir::separator() + name; +} + +class DFileWatcherPrivate : DAbstractFileWatcherPrivate +{ +public: + explicit DFileWatcherPrivate(DFileWatcher *qq) + : DAbstractFileWatcherPrivate(qq) {} + + bool start() override; + bool stop() override; + bool handleGhostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType1 signal, const DUrl &arg1) override; + bool handleGhostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType2 signal, const DUrl &arg1, const DUrl &arg2) override; + + void _q_handleFileDeleted(const QString &path, const QString &parentPath); + void _q_handleFileAttributeChanged(const QString &path, const QString &parentPath); + bool _q_handleFileMoved(const QString &from, const QString &fromParent, const QString &to, const QString &toParent); + void _q_handleFileCreated(const QString &path, const QString &parentPath); + void _q_handleFileModified(const QString &path, const QString &parentPath); + void _q_handleFileClose(const QString &path, const QString &parentPath); + + static QString formatPath(const QString &path); + + QString path; + QStringList watchFileList; + + static QMap filePathToWatcherCount; + + Q_DECLARE_PUBLIC(DFileWatcher) +}; + +QMap DFileWatcherPrivate::filePathToWatcherCount; +Q_GLOBAL_STATIC(DFileSystemWatcher, watcher_file_private) + +bool isPathWatched(const QString &path); + +QStringList parentPathList(const QString &path) +{ + QStringList list; + QDir dir(path); + + list << path; + + QString strTmpPath = path; + // fix bug#27870 往已刻录的文件夹中的文件夹...中添加文件夹,界面不刷新 + // 往已刻录的文件夹中放置文件时,由于父路径可能不存在,导致不能创建对应的 watcher ,因此不能监听到文件夹变化,导致界面不刷新 + if (!dir.exists() && path.contains("/.cache/deepin/discburn/")) // 目前仅针对光驱刻录的暂存区进行处理 + dir.mkdir(path); + + while (dir.cdUp()) { + //! fixed the bug that directory not refresh when same pathes in the list. + if (isPathWatched(dir.absolutePath())) { + continue; + } + list << dir.absolutePath(); + } + + return list; +} + +bool isPathWatched(const QString &path) +{ + QFileInfo fi(path); + return (fi.isDir() && watcher_file_private->directories().contains(path)) || + (fi.isFile() && watcher_file_private->files().contains(path)); +} + +bool DFileWatcherPrivate::start() +{ + Q_Q(DFileWatcher); + + started = true; + + foreach (const QString &path, parentPathList(this->path)) { + if (watchFileList.contains(path)) + continue; + + if (filePathToWatcherCount.value(path, -1) <= 0 || !isPathWatched(path)) { + if (QFile::exists(path)) { + bool shouldAddToPath = true; + // vault directory should not be watched before filesystem mounted. + if (VaultController::isVaultFile(path) && + (VaultController::ins()->state() != VaultController::Unlocked)) { + shouldAddToPath = false; + } + if (shouldAddToPath && !watcher_file_private->addPath(path)) { + qWarning() << Q_FUNC_INFO << "start watch failed, file path =" << path; + q->stopWatcher(); + started = false; + return false; + } + } + } + + watchFileList << path; + filePathToWatcherCount[path] = filePathToWatcherCount.value(path, 0) + 1; + } + + q->connect(watcher_file_private, &DFileSystemWatcher::fileDeleted, + q, &DFileWatcher::onFileDeleted); + q->connect(watcher_file_private, &DFileSystemWatcher::fileAttributeChanged, + q, &DFileWatcher::onFileAttributeChanged); + q->connect(watcher_file_private, &DFileSystemWatcher::fileMoved, + q, &DFileWatcher::onFileMoved); + q->connect(watcher_file_private, &DFileSystemWatcher::fileCreated, + q, &DFileWatcher::onFileCreated); + q->connect(watcher_file_private, &DFileSystemWatcher::fileModified, + q, &DFileWatcher::onFileModified); + q->connect(watcher_file_private, &DFileSystemWatcher::fileClosed, + q, &DFileWatcher::onFileClosed); + q->connect(watcher_file_private, &DFileSystemWatcher::fileSystemUMount, + q, &DFileWatcher::onFileSystemUMount); + + q->connect(fileSignalManager, &FileSignalManager::fileMoved, + q, &DFileWatcher::onFileMoved); + return true; +} + +bool DFileWatcherPrivate::stop() +{ + Q_Q(DFileWatcher); + + if (watcher_file_private.isDestroyed()) + return true; + +// q->disconnect(watcher_file_private, 0, q, 0);//避免0值警告 + q->disconnect(watcher_file_private, nullptr, q, nullptr); + + bool ok = true; + + for (auto it = watchFileList.begin(); it != watchFileList.end();) { + int count = filePathToWatcherCount.value(*it, 0); + + --count; + if (count > 0 && !isPathWatched(*it)) { // already removed from DFileSystemWatcher + filePathToWatcherCount.remove(*it); + it = watchFileList.erase(it); + continue; + } + + if (count <= 0) { + filePathToWatcherCount.remove(*it); + ok = ok && watcher_file_private->removePath(*it); + it = watchFileList.erase(it); + continue; + } else { + filePathToWatcherCount[*it] = count; + } + + ++it; + } + + return ok; +} + +bool DFileWatcherPrivate::handleGhostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType1 signal, const DUrl &arg1) +{ + if (!targetUrl.isLocalFile() && !arg1.isMTPFile()) // 华为版本,MTP删除文件自行刷新 + return false; + +// Q_Q(DFileWatcher); //没有被使用 + + if (signal == &DAbstractFileWatcher::fileDeleted) { + if (arg1.isMTPFile()) { + q_ptr->fileDeleted(arg1); + return true; + } else { + for (const QString &path : watchFileList) { + const DUrl &_url = DUrl::fromLocalFile(path); + + if (_url == arg1) { + q_ptr->fileDeleted(this->url); + + return true; + } + } + } + } else { + return DAbstractFileWatcherPrivate::handleGhostSignal(targetUrl, signal, arg1); + } + + return false; +} + +bool DFileWatcherPrivate::handleGhostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType2 signal, const DUrl &arg1, const DUrl &arg2) +{ + if (!targetUrl.isLocalFile()) + return false; + + if (signal != &DAbstractFileWatcher::fileMoved) { + return DAbstractFileWatcherPrivate::handleGhostSignal(targetUrl, signal, arg1, arg2); + } + + return _q_handleFileMoved(arg1.toLocalFile(), arg1.parentUrl().toLocalFile(), arg2.toLocalFile(), arg2.parentUrl().toLocalFile()); +} + +void DFileWatcherPrivate::_q_handleFileDeleted(const QString &path, const QString &parentPath) +{ + Q_Q(DFileWatcher); + + //如果被删除目录是当前目录的父级及以上目录 + //则需要发出当前目录也被删除的事件 + // fix 99280 + // 原判断会造成误删 例如删除 /media/uos/vfat时,会将 /media/uos/vfat1一起删除了 + const QUrl ¤tUrl = QUrl(path); + const QUrl &thisPathUrl = QUrl(this->path); + if (currentUrl.isParentOf(thisPathUrl)) { + emit q->fileDeleted(DUrl::fromLocalFile(this->path)); + return; + } + + //如果被删除的目录是当前目录或当前目录的子目录 + //则需要发出被删除目录已被删除的事件 + if (path != this->path && parentPath != this->path) + return; + + emit q->fileDeleted(DUrl::fromLocalFile(path)); +} + +void DFileWatcherPrivate::_q_handleFileAttributeChanged(const QString &path, const QString &parentPath) +{ + if (path != this->path && parentPath != this->path) + return; + + Q_Q(DFileWatcher); + + emit q->fileAttributeChanged(DUrl::fromLocalFile(path)); +} + +bool DFileWatcherPrivate::_q_handleFileMoved(const QString &from, const QString &fromParent, const QString &to, const QString &toParent) +{ + Q_Q(DFileWatcher); + + if ((fromParent == this->path && toParent == this->path) || from == this->path) { + emit q->fileMoved(DUrl::fromLocalFile(from), DUrl::fromLocalFile(to)); + } else if (fromParent == this->path) { + emit q->fileDeleted(DUrl::fromLocalFile(from)); + } else if (watchFileList.contains(from)) { + emit q->fileDeleted(url); + } else if (toParent == this->path) { + emit q->subfileCreated(DUrl::fromLocalFile(to)); + } else { + return false; + } + + return true; +} + +void DFileWatcherPrivate::_q_handleFileCreated(const QString &path, const QString &parentPath) +{ + if (watchFileList.contains(path)) { + bool result = watcher_file_private->addPath(path); + if (!result) { + qWarning() << Q_FUNC_INFO << "add to watcher failed, file path =" << path; + } + } + + if (path != this->path && parentPath != this->path) + return; + + Q_Q(DFileWatcher); + + emit q->subfileCreated(DUrl::fromLocalFile(path)); +} + +void DFileWatcherPrivate::_q_handleFileModified(const QString &path, const QString &parentPath) +{ + //if (path != this->path && parentPath != this->path) + // bug 25533: some path add some external path when modified, so use the contain function + if (!path.contains(this->path) && parentPath != this->path) + return; + + Q_Q(DFileWatcher); + + emit q->fileModified(DUrl::fromLocalFile(path)); +} + +void DFileWatcherPrivate::_q_handleFileClose(const QString &path, const QString &parentPath) +{ + if (path != this->path && parentPath != this->path) + return; + + Q_Q(DFileWatcher); + + emit q->fileClosed(DUrl::fromLocalFile(path)); +} + +QString DFileWatcherPrivate::formatPath(const QString &path) +{ + QString p = QFileInfo(path).absoluteFilePath(); + + if (p.endsWith(QDir::separator())) + p.chop(1); + + return p.isEmpty() ? path : p; +} + +DFileWatcher::DFileWatcher(const QString &filePath, QObject *parent) + : DAbstractFileWatcher(*new DFileWatcherPrivate(this), DUrl::fromLocalFile(filePath), parent) +{ + d_func()->path = DFileWatcherPrivate::formatPath(filePath); +} + +void DFileWatcher::onFileDeleted(const QString &path, const QString &name) +{ + // 为防止文管卡死,保险箱里文件删除不执行后续流程 + // 只有删除保险箱文件时,才不执行后续流程 + if (VaultController::isBigFileDeleting()) { + return; + } + + if (name.isEmpty()) + d_func()->_q_handleFileDeleted(path, QString()); + else + d_func()->_q_handleFileDeleted(joinFilePath(path, name), path); +} + +void DFileWatcher::onFileAttributeChanged(const QString &path, const QString &name) +{ + if (name.isEmpty()) + d_func()->_q_handleFileAttributeChanged(path, QString()); + else + d_func()->_q_handleFileAttributeChanged(joinFilePath(path, name), path); +} + +void DFileWatcher::onFileMoved(const QString &from, const QString &fname, const QString &to, const QString &tname) +{ + QString fromPath, fpPath; + QString toPath, tpPath; + + if (fname.isEmpty()) { + fromPath = from; + } else { + fromPath = joinFilePath(from, fname); + fpPath = from; + } + + if (tname.isEmpty()) { + toPath = to; + } else { + toPath = joinFilePath(to, tname); + tpPath = to; + } + + d_func()->_q_handleFileMoved(fromPath, fpPath, toPath, tpPath); +} + +void DFileWatcher::onFileCreated(const QString &path, const QString &name) +{ + d_func()->_q_handleFileCreated(joinFilePath(path, name), path); +} + +void DFileWatcher::onFileModified(const QString &path, const QString &name) +{ + if (name.isEmpty()) + d_func()->_q_handleFileModified(path, QString()); + else + d_func()->_q_handleFileModified(joinFilePath(path, name), path); +} + +void DFileWatcher::onFileClosed(const QString &path, const QString &name) +{ + if (name.isEmpty()) + d_func()->_q_handleFileClose(path, QString()); + else + d_func()->_q_handleFileClose(joinFilePath(path, name), path); +} + +void DFileWatcher::onFileSystemUMount(const QString &path, const QString &name) +{ + Q_UNUSED(name) + + d_func()->filePathToWatcherCount.remove(path); + watcher_file_private->removePath(path); + d_func()->watchFileList.removeOne(path); +} + +QStringList DFileWatcher::getMonitorFiles() +{ + QStringList list; + + list << watcher_file_private->directories(); + list << watcher_file_private->files(); + + list << "---------------------------"; + + QMap::const_iterator i = DFileWatcherPrivate::filePathToWatcherCount.constBegin(); + + while (i != DFileWatcherPrivate::filePathToWatcherCount.constEnd()) { + list << QString("%1, %2").arg(i.key()).arg(i.value()); + ++i; + } + + return list; +} + +#include "moc_dfilewatcher.cpp" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilewatcher.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilewatcher.h new file mode 100644 index 0000000..5460749 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilewatcher.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILEWATCHER_H +#define DFILEWATCHER_H + +#include "dabstractfilewatcher.h" + +class DFileWatcherPrivate; +class DFileWatcher : public DAbstractFileWatcher +{ + Q_OBJECT + +public: + explicit DFileWatcher(const QString &filePath, QObject *parent = nullptr); + + //debug function + static QStringList getMonitorFiles(); + +private slots: + void onFileDeleted(const QString &path, const QString &name); + void onFileAttributeChanged(const QString &path, const QString &name); + void onFileMoved(const QString &from, const QString &fname, const QString &to, const QString &tname); + void onFileCreated(const QString &path, const QString &name); + void onFileModified(const QString &path, const QString &name); + void onFileClosed(const QString &path, const QString &name); + + //! 处理文件系统卸载事件如U盘、Cryfs加密保险箱 + void onFileSystemUMount(const QString &path, const QString &name); + +private: + Q_DECLARE_PRIVATE(DFileWatcher) +}; + +#endif // DFILEWATCHER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilewatchermanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilewatchermanager.cpp new file mode 100644 index 0000000..c18f31d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilewatchermanager.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dfilewatchermanager.h" +#include "dfilewatcher.h" +#include "durl.h" + +DFM_BEGIN_NAMESPACE + +class DFileWatcherManagerPrivate +{ +public: + DFileWatcherManagerPrivate(); + + QMap watchersMap; +}; + +DFileWatcherManagerPrivate::DFileWatcherManagerPrivate() +{ + +} + +DFileWatcherManager::DFileWatcherManager(QObject *parent) + : QObject(parent) + , d_ptr(new DFileWatcherManagerPrivate()) +{ + +} + +DFileWatcherManager::~DFileWatcherManager() +{ + +} + +DFileWatcher *DFileWatcherManager::add(const QString &filePath) +{ + Q_D(DFileWatcherManager); + + DFileWatcher *watcher = d->watchersMap.value(filePath); + + if (watcher) + return watcher; + + watcher = new DFileWatcher(filePath, this); + + connect(watcher, &DFileWatcher::fileAttributeChanged, this, [this](const DUrl &url) { + emit fileAttributeChanged(url.toLocalFile()); + }); + connect(watcher, &DFileWatcher::fileClosed, this, [this](const DUrl &url) { + emit fileClosed(url.toLocalFile()); + }); + connect(watcher, &DFileWatcher::fileDeleted, this, [this](const DUrl &url) { + emit fileDeleted(url.toLocalFile()); + }); + connect(watcher, &DFileWatcher::fileModified, this, [this](const DUrl &url) { + emit fileModified(url.toLocalFile()); + }); + connect(watcher, &DFileWatcher::fileMoved, this, [this](const DUrl &fromUrl, const DUrl &toUrl) { + emit fileMoved(fromUrl.toLocalFile(), toUrl.toLocalFile()); + }); + connect(watcher, &DFileWatcher::subfileCreated, this, [this](const DUrl &url) { + emit subfileCreated(url.toLocalFile()); + }); + + d->watchersMap[filePath] = watcher; + watcher->startWatcher(); + + return watcher; +} + +void DFileWatcherManager::remove(const QString &filePath) +{ + Q_D(DFileWatcherManager); + + DFileWatcher *watcher = d->watchersMap.take(filePath); + + if (watcher) + watcher->deleteLater(); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilewatchermanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilewatchermanager.h new file mode 100644 index 0000000..dd5afd0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfilewatchermanager.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILEWATCHERMANAGER_H +#define DFILEWATCHERMANAGER_H + +#include + +#include "dfmglobal.h" + +class DFileWatcher; +DFM_BEGIN_NAMESPACE + +class DFileWatcherManagerPrivate; +class DFileWatcherManager : public QObject +{ + Q_OBJECT + +public: + explicit DFileWatcherManager(QObject *parent = 0); + ~DFileWatcherManager(); + + DFileWatcher *add(const QString &filePath); + void remove(const QString &filePath); + +signals: + void fileDeleted(const QString &filePath); + void fileAttributeChanged(const QString &filePath); + void fileMoved(const QString &fromFilePath, const QString &toFilePath); + void subfileCreated(const QString &filePath); + void fileModified(const QString &filePath); + void fileClosed(const QString &filePath); + +private: + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(DFileWatcherManager) + Q_DISABLE_COPY(DFileWatcherManager) +}; + +DFM_END_NAMESPACE + +#endif // DFILEWATCHERMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmabstracteventhandler.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmabstracteventhandler.cpp new file mode 100644 index 0000000..7527720 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmabstracteventhandler.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmabstracteventhandler.h" +#include "dfmeventdispatcher.h" + +DFM_BEGIN_NAMESPACE + +QObject *DFMAbstractEventHandler::object() const +{ + return Q_NULLPTR; +} + +DFMAbstractEventHandler::DFMAbstractEventHandler(bool autoInstallHandler) +{ + if (autoInstallHandler) + DFMEventDispatcher::instance()->installEventHandler(this); +} + +DFMAbstractEventHandler::~DFMAbstractEventHandler() +{ + DFMEventDispatcher::instance()->removeEventHandler(this); + DFMEventDispatcher::instance()->removeEventFilter(this); +} + +bool DFMAbstractEventHandler::fmEvent(const QSharedPointer &event, QVariant *resultData) +{ + Q_UNUSED(event) + Q_UNUSED(resultData) + + return false; +} + +bool DFMAbstractEventHandler::fmEventFilter(const QSharedPointer &event, DFMAbstractEventHandler *target, QVariant *resultData) +{ + Q_UNUSED(event) + Q_UNUSED(target) + Q_UNUSED(resultData) + + return false; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmabstracteventhandler.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmabstracteventhandler.h new file mode 100644 index 0000000..5044257 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmabstracteventhandler.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMABSTRACTEVENTHANDLER_H +#define DFMABSTRACTEVENTHANDLER_H + +#include "dfmglobal.h" + +class DFMEvent; +DFM_BEGIN_NAMESPACE + +class DFMAbstractEventHandler +{ +public: + virtual QObject *object() const; + +protected: + explicit DFMAbstractEventHandler(bool autoInstallHandler = true); + virtual ~DFMAbstractEventHandler(); + + virtual bool fmEvent(const QSharedPointer &event, QVariant *resultData = 0); + virtual bool fmEventFilter(const QSharedPointer &event, DFMAbstractEventHandler *target = 0, QVariant *resultData = 0); + + friend class DFMEventDispatcher; +}; + +DFM_END_NAMESPACE + +#endif // DFMABSTRACTEVENTHANDLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmapplication.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmapplication.cpp new file mode 100644 index 0000000..aa12675 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmapplication.cpp @@ -0,0 +1,341 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dfmapplication.h" +#include "private/dfmapplication_p.h" +#if QT_HAS_INCLUDE("anything_interface.h") +#include "anything_interface.h" +#else +#ifndef DISABLE_QUICK_SEARCH +#define DISABLE_QUICK_SEARCH +#endif +#endif + +#include "dfmsettings.h" +#include "utils.h" + +#include +#include +#include + +DFM_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC_WITH_ARGS(DFMSettings, gsGlobal, ("deepin/dde-file-manager", DFMSettings::GenericConfig)) +Q_GLOBAL_STATIC_WITH_ARGS(DFMSettings, asGlobal, ("deepin/dde-file-manager/dde-file-manager", DFMSettings::GenericConfig)) +//Q_GLOBAL_STATIC_WITH_ARGS(DFMSettings, asGlobal, ("dde-file-manager", DFMSettings::AppConfig)) + +Q_GLOBAL_STATIC_WITH_ARGS(DFMSettings, gosGlobal, ("deepin/dde-file-manager.obtusely", DFMSettings::GenericConfig)) +Q_GLOBAL_STATIC_WITH_ARGS(DFMSettings, aosGlobal, ("deepin/dde-file-manager/dde-file-manager.obtusely", DFMSettings::GenericConfig)) +//Q_GLOBAL_STATIC_WITH_ARGS(DFMSettings, aosGlobal, ("dde-file-manager.obtusely", DFMSettings::AppConfig)) + +// blumia: since dde-desktop now also do show file selection dialog job, thus dde-desktop should share the same config file +// with dde-file-manager, so we use GenericConfig with specify path to simulate AppConfig. + +DFMApplication *DFMApplicationPrivate::self = nullptr; + +DFMApplicationPrivate::DFMApplicationPrivate(DFMApplication *qq) +{ + Q_ASSERT_X(!self, "DFMApplication", "there should be only one application object"); + self = qq; +} + +void DFMApplicationPrivate::_q_onSettingsValueChanged(const QString &group, const QString &key, const QVariant &value, bool edited) +{ + if (group == QT_STRINGIFY(ApplicationAttribute)) { + const QMetaEnum &me = QMetaEnum::fromType(); + + DFMApplication::ApplicationAttribute aa = static_cast(me.keyToValue(QByteArray("AA_" + key.toLatin1()).constData())); + + if (edited) + Q_EMIT self->appAttributeEdited(aa, value); + + Q_EMIT self->appAttributeChanged(aa, value); + + if (aa == DFMApplication::AA_IconSizeLevel) { + Q_EMIT self->iconSizeLevelChanged(value.toInt()); + } else if (aa == DFMApplication::AA_ViewMode) { + Q_EMIT self->viewModeChanged(value.toInt()); + } + } else if (group == QT_STRINGIFY(GenericAttribute)) { + const QMetaEnum &me = QMetaEnum::fromType(); + + DFMApplication::GenericAttribute ga = static_cast(me.keyToValue(QByteArray("GA_" + key.toLatin1()).constData())); + + if (edited) + Q_EMIT self->genericAttributeEdited(ga, value); + + Q_EMIT self->genericAttributeChanged(ga, value); + + switch (ga) { + case DFMApplication::GA_PreviewDocumentFile: + case DFMApplication::GA_PreviewImage: + case DFMApplication::GA_PreviewTextFile: + case DFMApplication::GA_PreviewVideo: + Q_EMIT self->previewAttributeChanged(ga, value.toBool()); + break; + case DFMApplication::GA_ShowedHiddenFiles: + Q_EMIT self->showedHiddenFilesChanged(value.toBool()); + break; + case DFMApplication::GA_ShowRecentFileEntry: + Q_EMIT self->recentDisplayChanged(value.toBool()); + break; + case DFMApplication::GA_PreviewCompressFile: + Q_EMIT self->previewCompressFileChanged(value.toBool()); + break; + case DFMApplication::GA_ShowCsdCrumbBarClickableArea: + Q_EMIT self->csdClickableAreaAttributeChanged(value.toBool()); + break; + case DFMApplication::GA_AlwaysShowOfflineRemoteConnections: + gsGlobal->sync(); // cause later invocations may update the config file, so sync the config before. + if (value.toBool()) { // stash all mounted remote connections + RemoteMountsStashManager::stashCurrentMounts(); + } else { // remove all stashed remote connections + RemoteMountsStashManager::clearRemoteMounts(); + } + Q_EMIT self->reloadComputerModel(); + break; + default: + break; + } + } else if (group == "RemoteMounts") { + Q_EMIT self->reloadComputerModel(); + } +} + +void DFMApplicationPrivate::_q_onSettingsValueEdited(const QString &group, const QString &key, const QVariant &value) +{ + _q_onSettingsValueChanged(group, key, value, true); +} + +DFMApplication::DFMApplication(QObject *parent) + : DFMApplication(new DFMApplicationPrivate(this), parent) +{ + qRegisterMetaType(); + qRegisterMetaType(); +} + +DFMApplication::~DFMApplication() +{ + +} + +QVariant DFMApplication::appAttribute(DFMApplication::ApplicationAttribute aa) +{ + const QString group(QT_STRINGIFY(ApplicationAttribute)); + const QMetaEnum &me = QMetaEnum::fromType(); + const QString key = QString::fromLatin1(me.valueToKey(aa)).split("_").last(); + + return appSetting()->value(group, key); +} + +DUrl DFMApplication::appUrlAttribute(DFMApplication::ApplicationAttribute aa) +{ + const QString group(QT_STRINGIFY(ApplicationAttribute)); + const QMetaEnum &me = QMetaEnum::fromType(); + const QString key = QString::fromLatin1(me.valueToKey(aa)).split("_").last(); + + return appSetting()->urlValue(group, key); +} + +void DFMApplication::setAppAttribute(DFMApplication::ApplicationAttribute aa, const QVariant &value) +{ + const QString group(QT_STRINGIFY(ApplicationAttribute)); + const QMetaEnum &me = QMetaEnum::fromType(); + const QString key = QString::fromLatin1(me.valueToKey(aa)).split("_").last(); + + // clear all self iconSize, use globbal iconSize + if (key == "IconSizeLevel") { + auto settings = appObtuselySetting(); + const QStringList &keys = settings->keyList("FileViewState"); + for (const QString &url : keys) { + auto map = settings->value("FileViewState", url).toMap(); + if (map.contains("iconSizeLevel")) { + qDebug() << "reset" << url << "iconSizeLevel to " << value.toInt(); + map["iconSizeLevel"] = value; + settings->setValue("FileViewState", url, map); + } + } + } + + appSetting()->setValue(group, key, value); +} + +bool DFMApplication::syncAppAttribute() +{ + return appSetting()->sync(); +} + +#ifndef DISABLE_QUICK_SEARCH +static ComDeepinAnythingInterface *getAnythingInterface() +{ + static ComDeepinAnythingInterface *interface = new ComDeepinAnythingInterface("com.deepin.anything", "/com/deepin/anything", QDBusConnection::systemBus()); + + return interface; +} +#endif + +QVariant DFMApplication::genericAttribute(DFMApplication::GenericAttribute ga) +{ + if (ga == GA_IndexInternal) { +#ifndef DISABLE_QUICK_SEARCH + return getAnythingInterface()->autoIndexInternal(); +#endif + } else if (ga == GA_IndexExternal) { +#ifndef DISABLE_QUICK_SEARCH + return getAnythingInterface()->autoIndexExternal(); +#endif + } + + const QString group(QT_STRINGIFY(GenericAttribute)); + const QMetaEnum &me = QMetaEnum::fromType(); + const QString key = QString::fromLatin1(me.valueToKey(ga)).split("_").last(); + + return genericSetting()->value(group, key); +} + +void DFMApplication::setGenericAttribute(DFMApplication::GenericAttribute ga, const QVariant &value) +{ + if (ga == GA_IndexInternal) { +#ifndef DISABLE_QUICK_SEARCH + return getAnythingInterface()->setAutoIndexInternal(value.toBool()); +#endif + } else if (ga == GA_IndexExternal) { +#ifndef DISABLE_QUICK_SEARCH + return getAnythingInterface()->setAutoIndexExternal(value.toBool()); +#endif + } + + const QString group(QT_STRINGIFY(GenericAttribute)); + const QMetaEnum &me = QMetaEnum::fromType(); + const QString key = QString::fromLatin1(me.valueToKey(ga)).split("_").last(); + + genericSetting()->setValue(group, key, value); +} + +bool DFMApplication::syncGenericAttribute() +{ + return genericSetting()->sync(); +} + +DFMApplication *DFMApplication::instance() +{ + return DFMApplicationPrivate::self; +} + +DFMSettings *DFMApplication::genericSetting() +{ + if (!gsGlobal.exists()) { + if (instance()) { + gsGlobal->moveToThread(instance()->thread()); + connect(gsGlobal, &DFMSettings::valueChanged, + instance(), &DFMApplication::onSettingsValueChanged); + connect(gsGlobal, &DFMSettings::valueEdited, + instance(), &DFMApplication::onSettingsValueEdited); + } + + gsGlobal->setAutoSync(true); +#ifndef DFM_NO_FILE_WATCHER + gsGlobal->setWatchChanges(true); +#endif + + if (instance()) + Q_EMIT instance()->genericSettingCreated(gsGlobal); + } + + return gsGlobal; +} + +DFMSettings *DFMApplication::appSetting() +{ + if (!asGlobal.exists()) { + if (instance()) { + asGlobal->moveToThread(instance()->thread()); + connect(asGlobal, &DFMSettings::valueChanged, + instance(), &DFMApplication::onSettingsValueChanged); + connect(asGlobal, &DFMSettings::valueEdited, + instance(), &DFMApplication::onSettingsValueEdited); + } + + asGlobal->setAutoSync(true); +#ifndef DFM_NO_FILE_WATCHER + asGlobal->setWatchChanges(true); +#endif + + if (instance()) + Q_EMIT instance()->appSettingCreated(asGlobal); + } + + return asGlobal; +} + +DFMSettings *DFMApplication::genericObtuselySetting() +{ + if (!gosGlobal.exists()) { + gosGlobal->setAutoSync(false); +#ifndef DFM_NO_FILE_WATCHER + gosGlobal->setWatchChanges(false); +#endif + } + + return gosGlobal; +} + +DFMSettings *DFMApplication::appObtuselySetting() +{ + if (!aosGlobal.exists()) { + aosGlobal->setAutoSync(false); +#ifndef DFM_NO_FILE_WATCHER + aosGlobal->setWatchChanges(true); +#endif + } + + return aosGlobal; +} + +DFMApplication::DFMApplication(DFMApplicationPrivate *dd, QObject *parent) + : QObject(parent) + , d_ptr(dd) +{ + if (gsGlobal.exists()) { + gsGlobal->moveToThread(thread()); + connect(gsGlobal, &DFMSettings::valueChanged, + this, &DFMApplication::onSettingsValueChanged); + } + + if (asGlobal.exists()) { + asGlobal->moveToThread(thread()); + connect(asGlobal, &DFMSettings::valueChanged, + this, &DFMApplication::onSettingsValueChanged); + } +} + +void DFMApplication::onSettingsValueChanged(const QString &group, const QString &key, const QVariant &value) +{ + d_func()->_q_onSettingsValueChanged(group, key, value); +} + +void DFMApplication::onSettingsValueEdited(const QString &group, const QString &key, const QVariant &value) +{ + d_func()->_q_onSettingsValueEdited(group, key, value); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmapplication.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmapplication.h new file mode 100644 index 0000000..b5b6ef3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmapplication.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMAPPLICATION_H +#define DFMAPPLICATION_H + +#include + +#include + +DFM_BEGIN_NAMESPACE + +class DFMSettings; +class DFMApplicationPrivate; +class DFMApplication : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DFMApplication) + +public: + // 应用级别的配置,默认存储于 ~/.config/deepin/{AppName}/dde-file-manager.json + enum ApplicationAttribute { + AA_AllwayOpenOnNewWindow, + AA_IconSizeLevel, + AA_ViewMode, + AA_ViewSizeAdjustable, // 可调整列表模式的表头宽度 + AA_ViewComppactMode, + AA_ViewAutoCompace, + AA_OpenFileMode, // 点击/双击[0/1] + AA_UrlOfNewWindow, // 新窗口默认路径 + AA_UrlOfNewTab, // 新标签页默认路径 + AA_ThemeName + }; + + Q_ENUM(ApplicationAttribute) + + // 通用型配置,默认存储于 ~/.config/deepin/dde-file-manager.json + enum GenericAttribute { + GA_IndexInternal, + GA_IndexExternal, + GA_IndexFullTextSearch, //全文搜索 + GA_PreviewCompressFile, // 把压缩包当做目录打开 + GA_PreviewTextFile, // 纯文本生成缩略图 + GA_PreviewDocumentFile, // 文档生成缩略图(pdf) + GA_PreviewImage, // 图片生成缩略图 + GA_PreviewVideo, // 文件生成缩略图 + GA_AutoMount, // 自动挂载硬盘设备 + GA_AutoMountAndOpen, // 自动挂载并打开硬盘设备 + GA_MTPShowBottomInfo, // mtp 挂载时显示底部数据统计 + GA_AlwaysShowOfflineRemoteConnections, // 始终显示离线的远程挂载(目前只包括 smb 挂载常驻) + GA_OverrideFileChooserDialog, // 将DDE文件管理器作为应用选择文件时的对话框 + GA_ShowedHiddenOnSearch, // 搜索时显示隐藏文件 + GA_ShowedHiddenFiles, // 显示隐藏文件 + GA_ShowedFileSuffixOnRename, // 重命名文件时显示后缀 + GA_DisableNonRemovableDeviceUnmount, // 禁用本地磁盘卸载功能 + GA_HiddenSystemPartition, // 隐藏系统分区 + GA_ShowRecentFileEntry, // 在侧边栏显示“最近文件”入口 + GA_ShowCsdCrumbBarClickableArea, // 在面包屑栏预留可供点击以进入地址栏编辑状态的区域 + GA_ShowFileSystemTagOnDiskIcon, // 在磁盘图标上显示文件系统信息 + GA_ShowDeleteConfirmDialog // 显示删除确认对话框 + }; + + Q_ENUM(GenericAttribute) + + explicit DFMApplication(QObject *parent = nullptr); + ~DFMApplication(); + + static QVariant appAttribute(ApplicationAttribute aa); + static DUrl appUrlAttribute(ApplicationAttribute aa); + static void setAppAttribute(ApplicationAttribute aa, const QVariant &value); + static bool syncAppAttribute(); + + static QVariant genericAttribute(GenericAttribute ga); + static void setGenericAttribute(GenericAttribute ga, const QVariant &value); + static bool syncGenericAttribute(); + + static DFMApplication *instance(); + + static DFMSettings *genericSetting(); + static DFMSettings *appSetting(); + + static DFMSettings *genericObtuselySetting(); + static DFMSettings *appObtuselySetting(); + +Q_SIGNALS: + void appAttributeChanged(ApplicationAttribute aa, const QVariant &value); + void genericAttributeChanged(GenericAttribute ga, const QVariant &value); + void appAttributeEdited(ApplicationAttribute aa, const QVariant &value); + void genericAttributeEdited(GenericAttribute ga, const QVariant &value); + void iconSizeLevelChanged(int level); + void viewModeChanged(int mode); + void previewCompressFileChanged(bool enable); + void previewAttributeChanged(GenericAttribute ga, bool enable); + void showedHiddenFilesChanged(bool enable); + void recentDisplayChanged(bool enable); + void csdClickableAreaAttributeChanged(bool enabled); + void reloadComputerModel(); +// void fullTextSearchChanged(bool enable); + + void genericSettingCreated(DFMSettings *settings); + void appSettingCreated(DFMSettings *settings); + +protected: + DFMApplication(DFMApplicationPrivate *dd, QObject *parent = nullptr); + +private: + void onSettingsValueChanged(const QString &, const QString &, const QVariant &); + void onSettingsValueEdited(const QString &, const QString &, const QVariant &); + + QScopedPointer d_ptr; +}; + +DFM_END_NAMESPACE + +#endif // DFMAPPLICATION_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmbaseview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmbaseview.cpp new file mode 100644 index 0000000..1677e47 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmbaseview.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmbaseview.h" +#include "views/dfilemanagerwindow.h" + +#include + +DFM_BEGIN_NAMESPACE + +DFMBaseView::DFMBaseView() +{ + +} + +DFMBaseView::~DFMBaseView() +{ + +} + +void DFMBaseView::deleteLater() +{ + if (QObject *obj = dynamic_cast(this)) + return obj->deleteLater(); + + delete this; +} + +DFMBaseView::ViewState DFMBaseView::viewState() const +{ + return ViewIdle; +} + +QList DFMBaseView::toolBarActionList() const +{ + return QList(); +} + +void DFMBaseView::refresh() +{ + +} + +void DFMBaseView::notifyUrlChanged() +{ + if (DFileManagerWindow *w = qobject_cast(widget()->window())) { + w->currentUrlChanged(); + } +} + +void DFMBaseView::notifyStateChanged() +{ + if (DFileManagerWindow *w = qobject_cast(widget()->window())) { + w->currentViewStateChanged(); + } +} + +void DFMBaseView::requestCdTo(const DUrl &url) +{ + if (DFileManagerWindow *w = qobject_cast(widget()->window())) { + w->cdForTabByView(this, url); + } +} + +void DFMBaseView::notifySelectUrlChanged(const QList &urlList) +{ + if (DFileManagerWindow *w = qobject_cast(widget()->window())) { + emit w->selectUrlChanged(urlList); + } +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmbaseview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmbaseview.h new file mode 100644 index 0000000..eb21c72 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmbaseview.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMBASEVIEW_H +#define DFMBASEVIEW_H + +#include "dfmglobal.h" +#include "durl.h" + +QT_BEGIN_NAMESPACE +class QWidget; +QT_END_NAMESPACE + +DFM_BEGIN_NAMESPACE + +class DFMBaseView +{ +public: + enum ViewState { + ViewBusy, + ViewIdle + }; + + DFMBaseView(); + virtual ~DFMBaseView(); + + void deleteLater(); + + virtual QWidget *widget() const = 0; + virtual DUrl rootUrl() const = 0; + virtual ViewState viewState() const; + virtual bool setRootUrl(const DUrl &url) = 0; + virtual QList toolBarActionList() const; + virtual void refresh(); + +protected: + void notifyUrlChanged(); + void notifyStateChanged(); + void requestCdTo(const DUrl &url); + void notifySelectUrlChanged(const QList &urlList); +}; + +DFM_END_NAMESPACE + +#endif // DFMBASEVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbbar.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbbar.cpp new file mode 100644 index 0000000..0fc0a0b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbbar.cpp @@ -0,0 +1,660 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dfmapplication.h" +#include "dfmcrumbbar.h" +#include "private/dfmcrumbbar_p.h" +#include "dfmcrumbmanager.h" +#include "dfmsettings.h" +#include "views/windowmanager.h" +#include "views/dfilemanagerwindow.h" +#include "views/dfmaddressbar.h" +#include "dfmcrumbfactory.h" +#include "dfmcrumbinterface.h" +#include "dfmapplication.h" +#include "dfmevent.h" +#include "dlistview.h" +#include "dfmcrumblistviewmodel.h" +#include "app/define.h" +#include "singleton.h" +#include "interfaces/dfmstandardpaths.h" +#include "controllers/pathmanager.h" +#include "controllers/vaultcontroller.h" +#include "interfaces/dfilemenu.h" +#include "accessibility/ac-lib-file-manager.h" + +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE + +DFMCrumbBarPrivate::DFMCrumbBarPrivate(DFMCrumbBar *qq) + : q_ptr(qq) +{ + initData(); + initUI(); + initConnections(); +} + +DFMCrumbBarPrivate::~DFMCrumbBarPrivate() +{ + if (crumbController) { + crumbController->deleteLater(); + crumbController = nullptr; + } +} + +/*! + * \brief Remove all crumbs List items inside crumb listView. + */ +void DFMCrumbBarPrivate::clearCrumbs() +{ + leftArrow.hide(); + rightArrow.hide(); + + if (crumbListviewModel) + crumbListviewModel->removeAll(); +} + +void DFMCrumbBarPrivate::checkArrowVisiable() +{ + QScrollBar *sb = crumbListView.horizontalScrollBar(); + if (!sb) + return; + AC_SET_OBJECT_NAME(sb, AC_COMPUTER_CRUMB_BAR_SCROLL_BAR); + AC_SET_ACCESSIBLE_NAME(sb, AC_COMPUTER_CRUMB_BAR_SCROLL_BAR); + + leftArrow.setVisible(!addressBar->isVisible() && sb->maximum() > 0); + rightArrow.setVisible(!addressBar->isVisible() && sb->maximum() > 0); + + leftArrow.setEnabled(sb->value() != sb->minimum()); + rightArrow.setEnabled(sb->value() != sb->maximum()); +} + +/*! + * \brief Update the crumb controller hold by the crumb bar. + * + * \param url The url which controller should supported. + */ +void DFMCrumbBarPrivate::updateController(const DUrl &url) +{ + Q_Q(DFMCrumbBar); + + if (!crumbController || !crumbController->supportedUrl(url)) { + if (crumbController) { + crumbController->deleteLater(); + } + // 修复bug41522-保险箱内,右键文件管理器打开文件夹,面包屑显示不对问题 + DUrl newurl; + if (VaultController::isVaultFile(url.toString())) { + newurl = VaultController::localUrlToVault(url); + } else { + newurl = url; + } + crumbController = DFMCrumbManager::instance()->createControllerByUrl(newurl, q); + // Not found? Then nothing here... + if (!crumbController) { + qDebug() << "Unsupported url / scheme: " << newurl; + } else + crumbController->setParent(q_ptr); + } +} + +void DFMCrumbBarPrivate::setClickableAreaEnabled(bool enabled) +{ + Q_Q(DFMCrumbBar); + + if (clickableAreaEnabled == enabled) return; + + clickableAreaEnabled = enabled; + //crumbListHolder->setContentsMargins(0, 0, (enabled ? 30 : 0), 0); + + q->update(); +} + +void DFMCrumbBarPrivate::initUI() +{ + Q_Q(DFMCrumbBar); + + // Address Bar + addressBar->hide(); + + // Crumbbar Widget + //q->setFixedHeight(24); + + // Arrows + QSize size(24, 24), iconSize(16, 16); + AC_SET_OBJECT_NAME((&leftArrow), AC_COMPUTER_CRUMB_BAR_LEFT_ARROW); + AC_SET_ACCESSIBLE_NAME((&leftArrow), AC_COMPUTER_CRUMB_BAR_LEFT_ARROW); + AC_SET_OBJECT_NAME((&rightArrow), AC_COMPUTER_CRUMB_BAR_RIGHT_ARROW); + AC_SET_ACCESSIBLE_NAME((&rightArrow), AC_COMPUTER_CRUMB_BAR_RIGHT_ARROW); + + leftArrow.setFocusPolicy(Qt::NoFocus); + leftArrow.setIcon(QIcon::fromTheme("go-previous")); + rightArrow.setIcon(QIcon::fromTheme("go-next")); + rightArrow.setFocusPolicy(Qt::NoFocus); + + leftArrow.setFixedSize(size); + leftArrow.setIconSize(iconSize); + rightArrow.setFixedSize(size); + rightArrow.setIconSize(iconSize); + leftArrow.setFlat(true); + rightArrow.setFlat(true); + leftArrow.hide(); + rightArrow.hide(); + + // Crumb List Layout + crumbListView.setObjectName("DCrumbListScrollArea"); + AC_SET_OBJECT_NAME((&crumbListView), AC_COMPUTER_CRUMB_BAR_LIST_VIEW); + AC_SET_ACCESSIBLE_NAME((&crumbListView), AC_COMPUTER_CRUMB_BAR_LIST_VIEW); + + crumbListView.setItemSpacing(10); + crumbListView.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + crumbListView.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + crumbListView.setFocusPolicy(Qt::NoFocus); + crumbListView.setContentsMargins(0, 0, 0, 0); + crumbListView.setSizeAdjustPolicy(QAbstractScrollArea::AdjustIgnored); + crumbListView.setIconSize({16, 16}); + crumbListView.setHorizontalScrollMode(QAbstractItemView::ScrollPerItem); + crumbListView.setOrientation(QListView::LeftToRight, false); + crumbListView.setEditTriggers(QAbstractItemView::NoEditTriggers); + crumbListView.setDragDropMode(QAbstractItemView::DragDropMode::NoDragDrop); + + crumbListviewModel = new DFMCrumbListviewModel(q); + crumbListView.setModel(crumbListviewModel); + crumbListView.setContextMenuPolicy(Qt::CustomContextMenu); + + // 点击listview空白可拖动窗口 + crumbListView.viewport()->installEventFilter(q); + + // for first icon item icon AlignCenter... + class IconItemDelegate : public DStyledItemDelegate + { + public: + explicit IconItemDelegate(QAbstractItemView *parent = nullptr): DStyledItemDelegate(parent) + { + setItemSpacing(10); + } + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override + { + QStyleOptionViewItem opt = option; + opt.decorationAlignment = Qt::AlignCenter; + DStyledItemDelegate::paint(painter, opt, index); + } + }; + crumbListView.setItemDelegateForRow(0, new IconItemDelegate(&crumbListView)); + + // Crumb Bar Layout + crumbBarLayout = new QHBoxLayout(q); + crumbBarLayout->addWidget(&leftArrow); + crumbBarLayout->addWidget(&crumbListView); + crumbBarLayout->addWidget(&rightArrow); + crumbBarLayout->setContentsMargins(0, 0, 0, 0); + crumbBarLayout->setSpacing(0); + q->setLayout(crumbBarLayout); + + return; +} + +void DFMCrumbBarPrivate::initData() +{ + Q_Q(DFMCrumbBar); + addressBar = new DFMAddressBar(q); + clickableAreaEnabled = DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowCsdCrumbBarClickableArea).toBool(); +} + +void DFMCrumbBarPrivate::initConnections() +{ + Q_Q(DFMCrumbBar); + QObject::connect(&crumbListView, &QListView::customContextMenuRequested, q, &DFMCrumbBar::onListViewContextMenu); + + QObject::connect(&crumbListView, &QListView::clicked, q, [q](const QModelIndex & index) { + if (index.isValid()) { + emit q->crumbListItemSelected(DUrl(index.data(DFMCrumbListviewModel::FileUrlRole).toUrl())); + } + }); + + q->connect(&leftArrow, &QPushButton::clicked, q, [this]() { + crumbListView.horizontalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepSub); + }); + + q->connect(&rightArrow, &QPushButton::clicked, q, [this]() { + crumbListView.horizontalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepAdd); + }); + + q->connect(crumbListView.horizontalScrollBar(), &QScrollBar::valueChanged, q, [this]() { + checkArrowVisiable(); + }); + + q->connect(addressBar, &DFMAddressBar::returnPressed, q, [q, this]() { + + //! 如果为保险箱路径则进行路径转换 + QString str = VaultController::toInternalPath(addressBar->text()); + + emit q->addressBarContentEntered(str); + }); + + q->connect(addressBar, &DFMAddressBar::escKeyPressed, q, [this]() { + if (crumbController) { + crumbController->processAction(DFMCrumbInterface::EscKeyPressed); + } + }); + + q->connect(addressBar, &DFMAddressBar::lostFocus, q, [q, this]() { + if (crumbController && !qobject_cast(q->window())->isAdvanceSearchBarVisible()) { + crumbController->processAction(DFMCrumbInterface::AddressBarLostFocus); + } + }); + + q->connect(addressBar, &DFMAddressBar::clearButtonPressed, q, [this] { + if (crumbController && !addressBar->text().isEmpty()) + { + crumbController->processAction(DFMCrumbInterface::ClearButtonPressed); + } + }); + + q->connect(addressBar, &DFMAddressBar::pauseButtonClicked, q, [this]() { + if (crumbController) + crumbController->processAction(DFMCrumbInterface::PauseButtonClicked); + }); + + q->connect(DFMApplication::instance(), &DFMApplication::csdClickableAreaAttributeChanged, q, [this](bool enabled) { + setClickableAreaEnabled(enabled); + }); +} + +/*! + * \class DFMCrumbBar + * \inmodule dde-file-manager-lib + * + * \brief DFMCrumbBar is the crumb bar widget of Deepin File Manager + * + * DFMCrumbBar is the crumb bar widget of Deepin File Manager, provide the interface to manage + * crumb bar state. + * + * \sa DFMCrumbInterface, DFMCrumbManager + */ + +DFMCrumbBar::DFMCrumbBar(QWidget *parent) + : QFrame(parent) + , d_ptr(new DFMCrumbBarPrivate(this)) +{ + AC_SET_OBJECT_NAME(this, AC_COMPUTER_CRUMB_BAR); + AC_SET_ACCESSIBLE_NAME(this, AC_COMPUTER_CRUMB_BAR); + setFrameShape(QFrame::NoFrame); +} + +DFMCrumbBar::~DFMCrumbBar() +{ + +} + +/*! + * \brief Toggle and show the address bar. + * + * \param text The text in the address bar. + */ +void DFMCrumbBar::showAddressBar(const QString &text) +{ + Q_D(DFMCrumbBar); + + d->leftArrow.hide(); + d->rightArrow.hide(); + d->crumbListView.hide(); + + d->addressBar->show(); + d->addressBar->setText(text); + //d->addressBar->setSelection(0, text.length()); + d->addressBar->setFocus(); + + emit addressBarShown(); + + return; +} + +/*! + * \brief Toggle and show the address bar. + * + * \param url The url in the address bar. + */ +void DFMCrumbBar::showAddressBar(const DUrl &url) +{ + Q_D(DFMCrumbBar); + + d->leftArrow.hide(); + d->rightArrow.hide(); + d->crumbListView.hide(); + + d->addressBar->show(); + d->addressBar->setCurrentUrl(url); + d->addressBar->setFocus(); + + emit addressBarShown(); + + return; +} + +/*! + * \brief Hide the address bar. + */ +void DFMCrumbBar::hideAddressBar() +{ + Q_D(DFMCrumbBar); + + d->addressBar->hide(); + + d->crumbListView.show(); + d->checkArrowVisiable(); + + emit addressBarHidden(); + + return; +} + +static QString getIconName(const CrumbData &c) +{ + QString iconName = c.iconName; + if (c.url == DUrl(TRASH_ROOT)) { + iconName = systemPathManager->getSystemPathIconName("Trash"); + } else if (c.url.isNetWorkFile() || c.url.isSMBFile() || c.url.isFTPFile() || c.url.isSFTPFile()) { + iconName = systemPathManager->getSystemPathIconName("Network"); + } + + if (!iconName.isEmpty() && !iconName.startsWith("dfm_") && !iconName.contains("-symbolic")) + iconName.append("-symbolic"); + + return iconName; +} + +/*! + * \brief Update crumbs in crumb bar by the given \a url + * + * \param url The newly switched url. + * + * DFMCrumbBar holds an instance of crumb controller (derived from DFMCrumbInterface), and when + * calling updateCrumb, it will check the current used crumb controller is supporting the given + * \a url. if isn't, we will create a new crumb controller form the registed controllers or the + * plugin list. Then we will call DFMCrumbInterface::seprateUrl to seprate the url + */ +void DFMCrumbBar::updateCrumbs(const DUrl &url) +{ + Q_D(DFMCrumbBar); + + d->clearCrumbs(); + + if (!d->crumbController) { + qWarning("No controller found when trying to call DFMCrumbBar::updateCrumbs() !!!"); + qDebug() << "updateCrumbs (no controller) : " << url; + return; + } + + // 回收站预览打开文件夹时传过来的是真实路径,所以将其转换为虚拟路径 + DUrl fileUrl = url; + if (url.path().startsWith(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))) { + QString trashFilePath = url.path(); + if (trashFilePath == DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath)) + trashFilePath = trashFilePath + "/"; + fileUrl = DUrl::fromTrashFile(trashFilePath.remove(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))); + d->updateController(fileUrl); + } else if (VaultController::isVaultFile(url.toLocalFile())) { + // 修复bug-60781 + // 如果是保险箱文件,转化为保险箱路径,以便创建保险箱的面包屑 + fileUrl = VaultController::localToVault(url.toLocalFile()); + } + + //NOTE [HMOE REN] 已注册的CrumbController(面包屑)创建的面包屑值 + QList crumbDataList = d->crumbController->seprateUrl(fileUrl); + for (const CrumbData &c : crumbDataList) { + if (d->crumbListviewModel) { + QString iconName = getIconName(c); + QStandardItem *listitem = nullptr; + if (!iconName.isEmpty()) { + listitem = new QStandardItem(QIcon::fromTheme(iconName), QString()); + } else { + listitem = new QStandardItem(c.displayText); + } + listitem->setTextAlignment(Qt::AlignCenter);//垂直与水平居中 + listitem->setCheckable(false); + listitem->setData(c.url, DFMCrumbListviewModel::FileUrlRole); + d->crumbListviewModel->appendRow(listitem); + } + } + + if (d->crumbListView.selectionModel() && d->crumbListviewModel) + d->crumbListView.selectionModel()->select(d->crumbListviewModel->lastIndex(), QItemSelectionModel::Select); + + d->checkArrowVisiable(); + d->crumbListView.horizontalScrollBar()->triggerAction(QScrollBar::SliderToMaximum); +} + +void DFMCrumbBar::playAddressBarAnimation() +{ + Q_D(DFMCrumbBar); + + d->addressBar->playAnimation(); +} + +void DFMCrumbBar::stopAddressBarAnimation() +{ + Q_D(DFMCrumbBar); + + d->addressBar->stopAnimation(); +} + +/*! + * \brief Call when toolbar url got changed. + * + * \param url Current url which we changed to. + */ +void DFMCrumbBar::updateCurrentUrl(const DUrl &url) +{ + Q_D(DFMCrumbBar); + + d->updateController(url); + + if (d->crumbController) { + d->crumbController->crumbUrlChangedBehavior(url); + } +} + +void DFMCrumbBar::mousePressEvent(QMouseEvent *event) +{ + Q_D(DFMCrumbBar); + d->clickedPos = event->globalPos(); + + if (event->button() == Qt::RightButton && d->clickableAreaEnabled) { + event->accept(); + return; + } + + QModelIndex index = d->crumbListView.indexAt(event->pos()); + if (event->button() != Qt::RightButton || !index.isValid()) { + QFrame::mousePressEvent(event); + } +} + +void DFMCrumbBar::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(DFMCrumbBar); + + if (!d->clickableAreaEnabled) { + return QFrame::mouseReleaseEvent(event);; + } + + // blumia: no need to check if it's clicked on other widgets + // since this will only happend when clicking empty. + const QPoint pos_difference = d->clickedPos - event->globalPos(); + + if (qAbs(pos_difference.x()) < 2 && qAbs(pos_difference.y()) < 2) { + showAddressBar(qobject_cast(topLevelWidget())->currentUrl()); + } + + QFrame::mouseReleaseEvent(event); +} + +void DFMCrumbBar::resizeEvent(QResizeEvent *event) +{ + Q_D(DFMCrumbBar); + + d->checkArrowVisiable(); + d->addressBar->resize(event->size()); + + return QFrame::resizeEvent(event); +} + +void DFMCrumbBar::showEvent(QShowEvent *event) +{ + Q_D(DFMCrumbBar); + + //d->crumbListScrollArea.horizontalScrollBar()->setPageStep(d->crumbListHolder->width()); + d->crumbListView.horizontalScrollBar()->triggerAction(QScrollBar::SliderToMaximum); + + d->checkArrowVisiable(); + + return QFrame::showEvent(event); +} + +bool DFMCrumbBar::eventFilter(QObject *watched, QEvent *event) +{ + Q_D(DFMCrumbBar); + QMouseEvent *me = nullptr; + if (watched && watched->parent() == &d->crumbListView && (me = dynamic_cast(event))) { + QEvent::Type type = event->type(); + bool isMousePressed = type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick; + static QPoint pos; + if (isMousePressed) { + pos = QCursor::pos(); + } + + bool isIgnore = isMousePressed || type == QEvent::MouseMove; + if (isIgnore) { + event->ignore(); + return true; + } + + bool isDragging = (pos - QCursor::pos()).manhattanLength() > QApplication::startDragDistance(); + if (type == QEvent::MouseButtonRelease && me->button() == Qt::LeftButton && !isDragging) { + QModelIndex index = d->crumbListView.indexAt(me->pos()); + if (index.isValid() && index != d->crumbListView.currentIndex()) { + d->crumbListView.clicked(index); + return true; + } + } + } + + return QFrame::eventFilter(watched, event); +} + +void DFMCrumbBar::onListViewContextMenu(const QPoint &point) +{ + Q_D(DFMCrumbBar); + QModelIndex index = d->crumbListView.indexAt(point); + if (!index.isValid()) + return ; + + DFileMenu *menu = new DFileMenu(); + DUrl url = DUrl(index.data(DFMCrumbListviewModel::FileUrlRole).toUrl()); + menu->setAccessibleInfo(AC_FILE_MENU_CRUMB_BAR); + DGioSettings settings("com.deepin.dde.filemanager.general", "/com/deepin/dde/filemanager/general/"); + bool displayIcon = settings.value("context-menu-icons").toBool(); + QIcon copyIcon, newWndIcon, newTabIcon, editIcon; + if (displayIcon) { + copyIcon = QIcon::fromTheme("edit-copy"); + newWndIcon = QIcon::fromTheme("window-new"); + newTabIcon = QIcon::fromTheme("tab-new"); + editIcon = QIcon::fromTheme("entry-edit"); + } + + DFileManagerWindow *wnd = qobject_cast(window()); + if (!wnd) { + menu->deleteLater(); + menu = nullptr; + return; + } + + bool shouldDisable = !WindowManager::tabAddableByWinId(wnd->windowId()); + menu->addAction(copyIcon, QObject::tr("Copy path"), [ = ]() { + // 如果为保险箱路径则进行路径转换 + QString virtualUrl(url.toString()); + if (VaultController::isVaultFile(virtualUrl)) + virtualUrl = VaultController::localPathToVirtualPath(url.toLocalFile()); + QGuiApplication::clipboard()->setText(virtualUrl); + }); + + menu->addAction(newWndIcon, QObject::tr("Open in new window"), [url]() { + WindowManager::instance()->showNewWindow(url, true); + }); + + menu->addAction(newTabIcon, QObject::tr("Open in new tab"), [wnd, url]() { + wnd->openNewTab(url); + })->setDisabled(shouldDisable); + + menu->addSeparator(); + + menu->addAction(editIcon, QObject::tr("Edit address"), this, [ = ]() { + + DUrl url = wnd->currentUrl(); + // 如果为保险箱路径则进行路径转换 + QString realUrl(url.toString()); + if (VaultController::isVaultFile(realUrl)) { + realUrl = VaultController::localPathToVirtualPath(url.toLocalFile()); + } else if (url.path().startsWith(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))) { + QString trashFilePath = url.path(); + if (trashFilePath == DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath)) + trashFilePath = trashFilePath + "/"; + realUrl = trashFilePath.replace(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath) + "/", TRASH_ROOT); + } + showAddressBar(realUrl); + }); + //fix bug 33305 在用右键菜单复制大量文件时,在复制过程中,关闭窗口这时this释放了,在关闭拷贝menu的exec退出,menu的deleteLater崩溃 + QPointer me = this; + menu->exec(QCursor::pos()); + menu->deleteLater(me); +} + +/*! + * \fn DFMCrumbBar::addressBarShown() + * + * \brief Emit when the address bar got shown. + * + * \sa DFMAddressBar + */ + +/*! + * \fn DFMCrumbBar::addressBarHidden() + * + * \brief Emit when the address bar got hidden. + * + * \sa DFMAddressBar + */ + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbbar.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbbar.h new file mode 100644 index 0000000..e9ccb01 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbbar.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ +#ifndef DFMCRUMBBAR_H +#define DFMCRUMBBAR_H + +#include + +#include + +DFM_BEGIN_NAMESPACE + +class DFMCrumbBarPrivate; +class DFMCrumbBar : public QFrame +{ + Q_OBJECT +public: + explicit DFMCrumbBar(QWidget *parent = nullptr); + ~DFMCrumbBar(); + + void showAddressBar(const QString &text); + void showAddressBar(const DUrl &url); + void hideAddressBar(); + void updateCrumbs(const DUrl &url); + + void playAddressBarAnimation(); + void stopAddressBarAnimation(); + +public Q_SLOTS: + void updateCurrentUrl(const DUrl &url); + +private: + QScopedPointer d_ptr; + +Q_SIGNALS: + void addressBarShown(); + void addressBarHidden(); + void addressBarContentEntered(QString content); + void crumbListItemSelected(const DUrl &url); + +protected: + void mousePressEvent(QMouseEvent * event) override; + void mouseReleaseEvent(QMouseEvent * event) override; + void resizeEvent(QResizeEvent *event) override; + void showEvent(QShowEvent *event) override; + bool eventFilter(QObject *watched, QEvent *event) override; + + void onListViewContextMenu(const QPoint &point); + + Q_DECLARE_PRIVATE(DFMCrumbBar) +}; + +DFM_END_NAMESPACE + +#endif // DFMCRUMBBAR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbinterface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbinterface.cpp new file mode 100644 index 0000000..c961c46 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbinterface.cpp @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dfmcrumbinterface.h" +#include "dfmcrumbbar.h" + +#include "controllers/jobcontroller.h" + +#include "dfileservices.h" +#include "dfileinfo.h" + +#include + +DFM_BEGIN_NAMESPACE + +/*! + * \class CrumbData + * \inmodule dde-file-manager-lib + * + * \brief CrumbData is a class which providing data for DFMCrumbInterface + * + * \sa DFMCrumbInterface + */ + +/*! + * \fn CrumbData::CrumbData(DUrl url, QString displayText, QString iconName, QString iconKey) + * + * \brief Construct function of CrumbData + * + * \param url url of a crumb item + * \param displayText display text of a crumb item + * \param iconName the icon name of a crumb item (if it have) + * \param iconKey the icon key of a crumb item + */ +CrumbData::CrumbData(DUrl url, QString displayText, QString iconName, QString iconKey) + : url(url) + , iconName(iconName) + , displayText(displayText) + , iconKey(iconKey) +{ + +} + + +class DFMCrumbInterfacePrivate +{ + +public: + explicit DFMCrumbInterfacePrivate(DFMCrumbInterface *qq); + + QPointer folderCompleterJobPointer; + DFMCrumbBar *crumbBar = nullptr; + + DFMCrumbInterface *q_ptr; + + Q_DECLARE_PUBLIC(DFMCrumbInterface) +}; + +DFMCrumbInterfacePrivate::DFMCrumbInterfacePrivate(DFMCrumbInterface *qq) + : q_ptr(qq) +{ + +} + + +/*! + * \class DFMCrumbInterface + * \inmodule dde-file-manager-lib + * + * \brief DFMCrumbInterface is the interface for crumb item management of DFMCrumbBar + * + * DFMCrumbInterface is the interface for crumb item management for DFMCrumbBar, and should + * be implemented as a controller. Each different URL scheme got a corresponding controller + * for creating crumb items. DFMCrumbManager holds all avaliable crumb controllers. + * + * DFMCrumbInterface provides all neccessary interfaces for crumb management and some URL + * processing utils functions. + * + * \sa DFMCrumbBar, DFMCrumbManager + */ + +DFMCrumbInterface::DFMCrumbInterface(QObject *parent) + : QObject(parent) + , d_ptr(new DFMCrumbInterfacePrivate(this)) +{ + +} + +DFMCrumbInterface::~DFMCrumbInterface() +{ + +} + +void DFMCrumbInterface::processAction(DFMCrumbInterface::ActionType type) +{ + switch (type) { + case EscKeyPressed: + case ClearButtonPressed: + case AddressBarLostFocus: + crumbBar()->hideAddressBar(); + break; + default: + break; + } +} + +/*! + * \brief The crumb bar behavior when crumb bar url changed. + * + * \param url The url which crumb bar changed to. + */ +void DFMCrumbInterface::crumbUrlChangedBehavior(const DUrl url) +{ + crumbBar()->hideAddressBar(); + crumbBar()->updateCrumbs(url); +} + +/*! + * \brief Get the crumb bar instance. + * + * \return The crumb bar instance + */ +DFMCrumbBar *DFMCrumbInterface::crumbBar() +{ + Q_D(DFMCrumbInterface); + + return d->crumbBar; +} + +/*! + * \brief Set the crumb bar instance + * + * \param crumbBar The crumb bar instance pointer + */ +void DFMCrumbInterface::setCrumbBar(DFMCrumbBar *crumbBar) +{ + Q_D(DFMCrumbInterface); + + d->crumbBar = crumbBar; +} + +/*! + * \brief Seprate Url into a list of CrumbData for creating crumb items. + * + * \param url The url to be seprated. + * + * \return a list of CrumbData for creating crumb items. + */ +QList DFMCrumbInterface::seprateUrl(const DUrl &url) +{ + QList list; + + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, url); + if (!info) { + // blumia: it's possible if the url is not a file url at all, so we are not able + // to create a fileinfo for a non-file url. In this case we just return + // the empty list. + return list; + } + + DUrlList urlList; + urlList.append(url); + urlList.append(info->parentUrlList()); + + DAbstractFileInfoPointer infoPointer; + // Push urls into crumb list + DUrlList::const_reverse_iterator iter = urlList.crbegin(); + while (iter != urlList.crend()) { + const DUrl &oneUrl = *iter; + + QString displayText = oneUrl.fileName(); + // Check for possible display text. + infoPointer = DFileService::instance()->createFileInfo(nullptr, oneUrl); + if (infoPointer) { + displayText = infoPointer->fileDisplayName(); + } + CrumbData data(oneUrl, displayText); + list.append(data); + + ++iter; + } + + return list; +} + +/*! + * \brief Start request a completion list for address bar auto-completion. + * + * \param url The base url need to be completed. + * + * Since completion list can be long, so we need do async completion. Calling this + * function will start a completion request and the completion list item will be sent + * via signal completionFound. When user no longer need current completion list and + * the transmission isn't completed, you should call cancelCompletionListTransmission. + * When transmission completed, it will send completionListTransmissionCompleted signal. + * + * \sa completionFound, completionListTransmissionCompleted, cancelCompletionListTransmission + */ +void DFMCrumbInterface::requestCompletionList(const DUrl &url) +{ + Q_D(DFMCrumbInterface); + + if (d->folderCompleterJobPointer) { + d->folderCompleterJobPointer->disconnect(); + d->folderCompleterJobPointer->stopAndDeleteLater(); + d->folderCompleterJobPointer->setParent(nullptr); + } + + d->folderCompleterJobPointer = DFileService::instance()->getChildrenJob(this, url, QStringList(), QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot, QDirIterator::NoIteratorFlags, true, false); + d->folderCompleterJobPointer->setParent(this); + if (!d->folderCompleterJobPointer) { + return; + } + + connect(d->folderCompleterJobPointer, &JobController::addChildrenList, this, [this](const QList &infoList) { + QStringList list; + for (const DAbstractFileInfoPointer &infoPointer : infoList) { + if (infoPointer.data()) + list.append(infoPointer->fileName()); + } + emit completionFound(list); + }, Qt::DirectConnection); + + connect(d->folderCompleterJobPointer, &JobController::finished, this, [this]() { + emit completionListTransmissionCompleted(); + }, Qt::QueuedConnection); + + d->folderCompleterJobPointer->setTimeCeiling(1000); + d->folderCompleterJobPointer->setCountCeiling(500); + d->folderCompleterJobPointer->start(); +} + +/*! + * \brief Cancel the started completion list transmission. + * + * \sa completionFound, completionListTransmissionCompleted, requestCompletionList + */ +void DFMCrumbInterface::cancelCompletionListTransmission() +{ + Q_D(DFMCrumbInterface); + + if (d->folderCompleterJobPointer) { + d->folderCompleterJobPointer->stop(); + } +} + +/*! + * \fn virtual bool DFMCrumbInterface::supportedUrl(DUrl url) + * + * \brief Check if the given \a url is supported in this controller. + */ + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbinterface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbinterface.h new file mode 100644 index 0000000..8ffe9ac --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbinterface.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMCRUMBINTERFACE_H +#define DFMCRUMBINTERFACE_H + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class CrumbData +{ +public: + CrumbData(DUrl url = DUrl(), QString displayText = QString(), QString iconName = QString(), QString iconKey = "icon"); + + operator QString() const; + + DUrl url = DUrl(); + QString iconName = QString(); // icon group name + QString displayText = QString(); + QString iconKey = "icon"; // icon key +}; + +class DFMCrumbBar; +class DFMCrumbInterfacePrivate; +class DFMCrumbInterface : public QObject +{ + Q_OBJECT +public: + explicit DFMCrumbInterface(QObject *parent = 0); + ~DFMCrumbInterface(); + + // Actions may cause DFMAddressBar focusOut + enum ActionType { + EscKeyPressed, + ClearButtonPressed, + AddressBarLostFocus, + PauseButtonClicked + }; + + virtual void processAction(ActionType type); + virtual void crumbUrlChangedBehavior(const DUrl url); + virtual DFMCrumbBar* crumbBar() final; + virtual void setCrumbBar(DFMCrumbBar *crumbBar) final; + virtual bool supportedUrl(DUrl) = 0; + virtual QList seprateUrl(const DUrl &url); + virtual void requestCompletionList(const DUrl &url); + virtual void cancelCompletionListTransmission(); + +signals: + void completionFound(const QStringList &completions); //< emit multiple times with less or equials to 10 items in a group. + void completionListTransmissionCompleted(); //< emit when all avaliable completions has been sent. + +private: + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(DFMCrumbInterface) +}; + +DFM_END_NAMESPACE + +#endif // DFMCRUMBINTERFACE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumblistviewmodel.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumblistviewmodel.cpp new file mode 100644 index 0000000..409a38e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumblistviewmodel.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmcrumblistviewmodel.h" +#include "dtkwidget_global.h" + +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE + +DFMCrumbListviewModel::DFMCrumbListviewModel(QObject *parent) + :QStandardItemModel (parent) +{ + +} + +DFMCrumbListviewModel::~DFMCrumbListviewModel() +{ + +} + +void DFMCrumbListviewModel::removeAll() +{ + removeRows(0, rowCount()); +} + +QModelIndex DFMCrumbListviewModel::lastIndex() +{ + return index(rowCount()-1,0); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumblistviewmodel.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumblistviewmodel.h new file mode 100644 index 0000000..6a6c644 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumblistviewmodel.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMCRUMBLISTVIEWDELEGATE_H +#define DFMCRUMBLISTVIEWDELEGATE_H + +#include "dfmcrumbinterface.h" +#include "dfmglobal.h" +#include +#include + +DFM_BEGIN_NAMESPACE + +class DFMCrumbListviewModel : public QStandardItemModel +{ +public: + enum Roles { + FileUrlRole = Dtk::UserRole + 1 + }; + Q_ENUM(Roles) + + explicit DFMCrumbListviewModel(QObject *parent = nullptr); + virtual ~DFMCrumbListviewModel(); + + void removeAll(); + QModelIndex lastIndex(); +}; + + +DFM_END_NAMESPACE + +#endif // DFMCRUMBLISTVIEWDELEGATE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbmanager.cpp new file mode 100644 index 0000000..98a8e46 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbmanager.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmcrumbmanager.h" +#include "dfmcrumbinterface.h" +#include "dfmcrumbbar.h" +#include "plugins/dfmcrumbfactory.h" + +#include "controllers/dfmcomputercrumbcontroller.h" +#include "controllers/dfmtrashcrumbcontroller.h" +#include "controllers/dfmfilecrumbcontroller.h" +#include "controllers/dfmbookmarkcrumbcontroller.h" +#include "controllers/dfmtagcrumbcontroller.h" +#include "controllers/dfmnetworkcrumbcontroller.h" +#include "controllers/dfmusersharecrumbcontroller.h" +#include "controllers/dfmavfscrumbcontroller.h" +#include "controllers/dfmsmbcrumbcontroller.h" +#include "controllers/dfmmtpcrumbcontroller.h" +#include "controllers/dfmsearchcrumbcontroller.h" +#include "controllers/dfmrecentcrumbcontroller.h" +#include "controllers/dfmmdcrumbcontrooler.h" +#include "controllers/dfmmasteredmediacrumbcontroller.h" +#include "controllers/dfmvaultcrumbcontroller.h" +#include "controllers/dfmftpcrumbcontroller.h" +#include "controllers/dfmsftpcrumbcontroller.h" +#include "plugins/schemepluginmanager.h" + +DFM_BEGIN_NAMESPACE + +class DFMCrumbManagerPrivate +{ +public: + explicit DFMCrumbManagerPrivate(DFMCrumbManager *qq); + + QMultiHash controllerCreatorHash; + + DFMCrumbManager *q_ptr; +}; + +DFMCrumbManagerPrivate::DFMCrumbManagerPrivate(DFMCrumbManager *qq) + : q_ptr(qq) +{ + +} + +/*! + * \class DFMCrumbManager + * \inmodule dde-file-manager-lib + * + * \brief DFMCrumbManager is the manager of crumb controllers + * + * DFMCrumbManager is the manager of crumb controllers, it holds all avaliable crumb + * controllers to do crumb bar reletive stuff. + * + * User can also write plugins to extend crumb bar functionality (by derive the DFMCrumbInterface + * class) and DFMCrumbManager do the job about load and manage the plugins. + * + * \sa DFMCrumbBar, DFMCrumbInterface + */ + +DFMCrumbManager *DFMCrumbManager::instance() +{ + static DFMCrumbManager manager; + + return &manager; +} + +bool DFMCrumbManager::isRegisted(const QString &scheme, const std::type_info &info) const +{ + Q_D(const DFMCrumbManager); + + const KeyType &type = KeyType(scheme); + + foreach (const CrumbCreaterType &value, d->controllerCreatorHash.values(type)) { + if (value.first == info.name()) + return true; + } + + return false; +} + +/*! + * \brief Create a crumb controller by the given \a fileUrl + * + * \param fileUrl The url for creating controller + * \param crumbBar The DFMCrumbBar pointer. + * + * \return Pointer of the created crumb controller. + * + * The DFMCrumbBar reference(pointer) is required in order to make sure the crumb controller will always + * hold a instance of DFMCrumbBar. Thus the controller can invoke method provided by the crumb bar when + * neccessary. + */ +DFMCrumbInterface *DFMCrumbManager::createControllerByUrl(const DUrl &fileUrl, DFMCrumbBar *crumbBar) const +{ + Q_D(const DFMCrumbManager); + + KeyType theType = fileUrl.scheme(); + //NOTE [HMOE REN] 插件(plugin)中注册的CrumbController(面包屑)对应的hash索引为url的host + if (theType == PLUGIN_SCHEME) { + theType = fileUrl.host(); + } + + const QList creatorList = d->controllerCreatorHash.values(theType); + + Q_CHECK_PTR(crumbBar); + + if (!creatorList.isEmpty()) { + DFMCrumbInterface *i = (creatorList.first().second)(); + i->setCrumbBar(crumbBar); + return i; + } + + return nullptr; +} + +DFMCrumbManager::DFMCrumbManager(QObject *parent) + : QObject(parent) + , d_ptr(new DFMCrumbManagerPrivate(this)) +{ + // register built-in + dRegisterCrumbCreator(QStringLiteral(FILE_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(TRASH_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(COMPUTER_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(BOOKMARK_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(TAG_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(NETWORK_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(USERSHARE_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(AVFS_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(SMB_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(FTP_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(SFTP_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(MTP_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(SEARCH_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(RECENT_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(DFMMD_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(BURN_SCHEME)); + dRegisterCrumbCreator(QStringLiteral(DFMVAULT_SCHEME)); + + // register plugins + for (const QString &key : DFMCrumbFactory::keys()) { + const DUrl url(key); + + insertToCreatorHash(KeyType(url.scheme()), CrumbCreaterType(typeid(DFMCrumbFactory).name(), [key] { + return DFMCrumbFactory::create(key); + })); + } + + //NOTE [XIAO] 从PLUGIN中加载面包屑插件 + initCrumbControllerFromPlugin(); +} + +DFMCrumbManager::~DFMCrumbManager() +{ + +} + +void DFMCrumbManager::insertToCreatorHash(const DFMCrumbManager::KeyType &type, const DFMCrumbManager::CrumbCreaterType &creator) +{ + Q_D(DFMCrumbManager); + + d->controllerCreatorHash.insertMulti(type, creator); +} + +//NOTE [XIAO] 从PLUGIN中加载面包屑插件 +void DFMCrumbManager::initCrumbControllerFromPlugin() +{ + qWarning() << "[PLUGIN]" << "try to load plugin of crumb controller"; + auto plugins = SchemePluginManager::instance()->schemePlugins(); + for (auto plugin : plugins) { + qWarning() << "[PLUGIN]" << "load crumb controller from plugin:" << plugin.first; + insertToCreatorHash(plugin.first, plugin.second->createCrumbCreaterTypeFunc()); + } +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbmanager.h new file mode 100644 index 0000000..c099c72 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmcrumbmanager.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMCRUMBMANAGER_H +#define DFMCRUMBMANAGER_H + +#include "dfmglobal.h" + +#include + +DFM_BEGIN_NAMESPACE + +class DFMCrumbBar; +class DFMCrumbInterface; +class DFMCrumbManagerPrivate; +class DFMCrumbManager : public QObject +{ + Q_OBJECT + + typedef QString KeyType; + typedef QPair> CrumbCreaterType; + +public: + static DFMCrumbManager *instance(); + + template + void dRegisterCrumbCreator(const QString &scheme) + { + if (isRegisted(scheme)) + return; + + insertToCreatorHash(KeyType(scheme), CrumbCreaterType(typeid(T).name(), [ = ]() { + return static_cast(new T()); + })); + } + + bool isRegisted(const QString &scheme, const std::type_info &info) const; + + template + bool isRegisted(const QString &scheme) const + { + return isRegisted(scheme, typeid(T)); + } + + DFMCrumbInterface *createControllerByUrl(const DUrl &fileUrl, DFMCrumbBar *crumbBar) const; + +private: + explicit DFMCrumbManager(QObject *parent = nullptr); + ~DFMCrumbManager(); + + void insertToCreatorHash(const KeyType &type, const CrumbCreaterType &creator); + + QScopedPointer d_ptr; + + //NOTE [XIAO] 从PLUGIN中加载面包屑插件 + void initCrumbControllerFromPlugin(); + + Q_DECLARE_PRIVATE(DFMCrumbManager) + +}; + +DFM_END_NAMESPACE + +#endif // DFMCRUMBMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmevent.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmevent.cpp new file mode 100644 index 0000000..ea28050 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmevent.cpp @@ -0,0 +1,1155 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmevent.h" +#include "views/windowmanager.h" + +#include +#include +#include +#include +#include +#include +#include + +static QString fmeventType2String(DFMEvent::Type type) +{ + switch (type) { + case DFMEvent::UnknowType: + return QStringLiteral(QT_STRINGIFY(Unknow)); + case DFMEvent::OpenFile: + return QStringLiteral(QT_STRINGIFY(OpenFile)); + case DFMEvent::OpenFileByApp: + return QStringLiteral(QT_STRINGIFY(OpenFileByApp)); + case DFMEvent::CompressFiles: + return QStringLiteral(QT_STRINGIFY(CompressFiles)); + case DFMEvent::DecompressFile: + return QStringLiteral(QT_STRINGIFY(DecompressFile)); + case DFMEvent::DecompressFileHere: + return QStringLiteral(QT_STRINGIFY(DecompressFileHere)); + case DFMEvent::WriteUrlsToClipboard: + return QStringLiteral(QT_STRINGIFY(WriteUrlsToClipboard)); + case DFMEvent::RenameFile: + return QStringLiteral(QT_STRINGIFY(RenameFile)); + case DFMEvent::DeleteFiles: + return QStringLiteral(QT_STRINGIFY(DeleteFiles)); + case DFMEvent::MoveToTrash: + return QStringLiteral(QT_STRINGIFY(MoveToTrash)); + case DFMEvent::RestoreFromTrash: + return QStringLiteral(QT_STRINGIFY(RestoreFromTrash)); + case DFMEvent::PasteFile: + return QStringLiteral(QT_STRINGIFY(PasteFile)); + case DFMEvent::Mkdir: + return QStringLiteral(QT_STRINGIFY(Mkdir)); + case DFMEvent::TouchFile: + return QStringLiteral(QT_STRINGIFY(TouchFile)); + case DFMEvent::OpenFileLocation: + return QStringLiteral(QT_STRINGIFY(OpenFileLocation)); + case DFMEvent::CreateSymlink: + return QStringLiteral(QT_STRINGIFY(CreateSymlink)); + case DFMEvent::FileShare: + return QStringLiteral(QT_STRINGIFY(FileShare)); + case DFMEvent::CancelFileShare: + return QStringLiteral(QT_STRINGIFY(CancelFileShare)); + case DFMEvent::OpenInTerminal: + return QStringLiteral(QT_STRINGIFY(OpenInTerminal)); + case DFMEvent::GetChildrens: + return QStringLiteral(QT_STRINGIFY(GetChildrens)); + case DFMEvent::CreateFileInfo: + return QStringLiteral(QT_STRINGIFY(CreateFileInfo)); + case DFMEvent::CreateDiriterator: + return QStringLiteral(QT_STRINGIFY(CreateDiriterator)); + case DFMEvent::CreateGetChildrensJob: + return QStringLiteral(QT_STRINGIFY(CreateGetChildrensJob)); + case DFMEvent::CreateFileWatcher: + return QStringLiteral(QT_STRINGIFY(CreateFileWatcher)); + case DFMEvent::ChangeCurrentUrl: + return QStringLiteral(QT_STRINGIFY(ChangeCurrentUrl)); + case DFMEvent::OpenNewWindow: + return QStringLiteral(QT_STRINGIFY(OpenNewWindow)); + case DFMEvent::OpenUrl: + return QStringLiteral(QT_STRINGIFY(OpenUrl)); + case DFMEvent::MenuAction: + return QStringLiteral(QT_STRINGIFY(MenuAction)); + case DFMEvent::SaveOperator: + return QStringLiteral(QT_STRINGIFY(SaveOperator)); + case DFMEvent::Revocation: + return QStringLiteral(QT_STRINGIFY(Revocation)); + case DFMEvent::CleanSaveOperator: + return QStringLiteral(QT_STRINGIFY(CleanSaveOperator)); + case DFMEvent::GetTagsThroughFiles: + return QStringLiteral(QT_STRINGIFY(GetTagsThroughFiles)); + default: + return QStringLiteral("Custom: %1").arg(type); + } +} + +DFMEvent::DFMEvent(const QObject *sender) + : DFMEvent(UnknowType, sender) +{ + +} + +DFMEvent::DFMEvent(DFMEvent::Type type, const QObject *sender) + : m_type(type) + , m_sender(sender) + , m_accept(true) + , m_id(0) +{ + +} + +DFMEvent::DFMEvent(const DFMEvent &other) + : m_type(other.m_type) + , m_data(other.m_data) + , m_cutData(other.m_cutData) + , m_properties(other.m_properties) + , m_sender(other.m_sender) + , m_accept(other.m_accept) + , m_id(other.m_id) +{ + +} + +DFMEvent::~DFMEvent() +{ + +} + +DFMEvent &DFMEvent::operator =(const DFMEvent &other) +{ + m_type = other.m_type; + m_sender = other.m_sender; + m_accept = other.m_accept; + m_data = other.m_data; + m_cutData = other.m_cutData; + m_properties = other.m_properties; + m_id = other.m_id; + + return *this; +} + +DFMEvent::Type DFMEvent::nameToType(const QString &name) +{ + for (int i = UnknowType; i <= CustomBase; ++i) { + if (fmeventType2String(static_cast(i)) == name) { + return static_cast(i); + } + } + + return UnknowType; +} + +QString DFMEvent::typeToName(DFMEvent::Type type) +{ + return fmeventType2String(type); +} + +quint64 DFMEvent::windowIdByQObject(const QObject *object) +{ + const QObject *obj = object; + + while (obj) { + const QWidget *w = qobject_cast(obj); + + if (w) { + return WindowManager::getWindowId(w); + } + + obj = obj->parent(); + } + + const QGraphicsWidget *gw = qobject_cast(object); + + return (gw && !gw->scene()->views().isEmpty()) ? WindowManager::getWindowId(gw->scene()->views().first()) : 0; +} + +quint64 DFMEvent::windowId() const +{ + if (m_id > 0) { + return m_id; + } + + if (!m_sender) { + return 0; + } + + const QObject *obj = m_sender.data(); + + return windowIdByQObject(obj); +} + +void DFMEvent::setWindowId(quint64 id) +{ + m_id = id; +} + +DUrlList DFMEvent::handleUrlList() const +{ + DUrlList list = qvariant_cast(m_data); + + if (list.isEmpty()) { + const DUrl &url = qvariant_cast(m_data); + + if (url.isValid()) { + list << url; + } + } + + return list; +} + +const QSharedPointer DFMEvent::fromJson(DFMEvent::Type type, const QJsonObject &json) +{ + switch (static_cast(type)) { + case OpenFile: + return DFMOpenFileEvent::fromJson(json); + case OpenFileByApp: + return DFMOpenFileByAppEvent::fromJson(json); + case OpenFilesByApp: + return DFMOpenFilesByAppEvent::fromJson(json); + case CompressFiles: + return DFMCompressEvent::fromJson(json); + case DecompressFile: + return DFMDecompressEvent::fromJson(json); + case DecompressFileHere: + return DFMDecompressHereEvent::fromJson(json); + case WriteUrlsToClipboard: + return DFMWriteUrlsToClipboardEvent::fromJson(json); + case RenameFile: + return DFMRenameEvent::fromJson(json); + case DeleteFiles: + return DFMDeleteEvent::fromJson(json); + case MoveToTrash: + return DFMMoveToTrashEvent::fromJson(json); + case RestoreFromTrash: + return DFMRestoreFromTrashEvent::fromJson(json); + case PasteFile: + return DFMPasteEvent::fromJson(json); + case Mkdir: + return DFMMkdirEvent::fromJson(json); + case TouchFile: + return DFMTouchFileEvent::fromJson(json); + case OpenFileLocation: + return DFMOpenFileLocation::fromJson(json); + case CreateSymlink: + return DFMCreateSymlinkEvent::fromJson(json); + case FileShare: + return DFMFileShareEvent::fromJson(json); + case CancelFileShare: + return DFMCancelFileShareEvent::fromJson(json); + case OpenInTerminal: + return DFMOpenInTerminalEvent::fromJson(json); + case GetChildrens: + return DFMGetChildrensEvent::fromJson(json); + case CreateFileInfo: + return DFMCreateFileInfoEvent::fromJson(json); + case CreateDiriterator: + return DFMCreateDiriterator::fromJson(json); + case CreateGetChildrensJob: + return DFMCreateGetChildrensJob::fromJson(json); + case CreateFileWatcher: + return DFMCreateFileWatcherEvent::fromJson(json); + case ChangeCurrentUrl: + return DFMChangeCurrentUrlEvent::fromJson(json); + case OpenNewWindow: + return DFMOpenNewWindowEvent::fromJson(json); + case OpenUrl: + return DFMOpenUrlEvent::fromJson(json); + case MenuAction: + return DFMMenuActionEvent::fromJson(json); + case Back: + return DFMBackEvent::fromJson(json); + case Forward: + return DFMForwardEvent::fromJson(json); + default: break; + } + + return QSharedPointer(); +} + +const QSharedPointer DFMEvent::fromJson(const QJsonObject &json) +{ + return fromJson(nameToType(json["eventType"].toString()), json); +} + +QT_BEGIN_NAMESPACE +QDebug operator<<(QDebug deg, const DFMEvent &info) +{ + deg << "type:" << fmeventType2String(info.type()) << "sender:" << info.sender(); + deg << "data:" << info.data(); + deg << "properties:" << info.properties(); + + return deg; +} +QT_END_NAMESPACE + +DFMUrlBaseEvent::DFMUrlBaseEvent(const QObject *sender, const DUrl &url) + : DFMUrlBaseEvent(DFMEvent::UnknowType, sender, url) +{ + +} + +DFMUrlBaseEvent::DFMUrlBaseEvent(DFMEvent::Type type, const QObject *sender, const DUrl &url) + : DFMEvent(type, sender) +{ + setData(url); +} + +QSharedPointer DFMUrlBaseEvent::fromJson(Type type, const QJsonObject &json) +{ + return dMakeEventPointer(type, Q_NULLPTR, DUrl::fromUserInput(json["url"].toString())); +} + +DFMUrlListBaseEvent::DFMUrlListBaseEvent() + : DFMUrlListBaseEvent(nullptr, DUrlList()) +{ + +} + +DFMUrlListBaseEvent::DFMUrlListBaseEvent(const QObject *sender, const DUrlList &list) + : DFMUrlListBaseEvent(DFMEvent::UnknowType, sender, list) +{ + +} + +DFMUrlListBaseEvent::DFMUrlListBaseEvent(DFMEvent::Type type, const QObject *sender, const DUrlList &list) + : DFMEvent(type, sender) +{ + //从数据盘删除文件到回收站实际是同一目录下的操作 + //处理数据盘下的url 使其与回收站路径开头相同 保证后续删除还原逻辑判断正确 + if (type == MoveToTrash) { + DUrlList urls; + //遍历传入的urllist + for (DUrl url : list) { + //判断是否是来自数据盘路径 + //fix bug63348 在最近使用文件夹下无法删除/data目录下的文件,因为在删除的时候把/data/home处理成/home + if (url.path().startsWith("/data/home/") && !url.isRecentFile()) { + //去掉数据盘路径开头 + url.setPath(url.path().mid(sizeof("/data") - 1)); + } + //将处理后的url添加到临时list + urls.append(url); + } + //设置事件的url列表 + setData(urls); + } + //暂时只处理movetotrash事件 + else { + setData(list); + } +} + +QSharedPointer DFMUrlListBaseEvent::fromJson(Type type, const QJsonObject &json) +{ + DUrlList list; + + for (const QJsonValue &value : json["urlList"].toArray()) { + list << DUrl::fromUserInput(value.toString()); + } + + return dMakeEventPointer(type, Q_NULLPTR, list); +} + +DFMOpenFileEvent::DFMOpenFileEvent(const QObject *sender, const DUrl &url) + : DFMUrlBaseEvent(OpenFile, sender, url) +{ + +} + +QSharedPointer DFMOpenFileEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlBaseEvent::fromJson(OpenFile, json).staticCast(); +} + +DFMOpenFileByAppEvent::DFMOpenFileByAppEvent(const QObject *sender, const QString &appName, const DUrl &url) + : DFMOpenFileEvent(sender, url) +{ + m_type = OpenFileByApp; + setProperty(QT_STRINGIFY(DFMOpenFileByAppEvent::appName), appName); +} + +QString DFMOpenFileByAppEvent::appName() const +{ + return property(QT_STRINGIFY(DFMOpenFileByAppEvent::appName), QString()); +} + +QSharedPointer DFMOpenFileByAppEvent::fromJson(const QJsonObject &json) +{ + return dMakeEventPointer(Q_NULLPTR, json["appName"].toString(), DUrl::fromUserInput(json["url"].toString())); +} + +DFMOpenFilesByAppEvent::DFMOpenFilesByAppEvent(const QObject *sender, const QString &appName, const QList &url, const bool isEnter) + : DFMOpenFilesEvent(sender, url, isEnter) +{ + m_type = OpenFilesByApp; + setProperty(QT_STRINGIFY(DFMOpenFilesByAppEvent::appName), appName); +} + +QString DFMOpenFilesByAppEvent::appName() const +{ + return property(QT_STRINGIFY(DFMOpenFilesByAppEvent::appName), QString()); +} + +QSharedPointer DFMOpenFilesByAppEvent::fromJson(const QJsonObject &json) +{ + DUrlList list; + + for (const QJsonValue &value : json["urlList"].toArray()) { + list << DUrl::fromUserInput(value.toString()); + } + + return dMakeEventPointer(Q_NULLPTR, json["appName"].toString(), list); +} + +DFMCompressEvent::DFMCompressEvent(const QObject *sender, const DUrlList &list) + : DFMUrlListBaseEvent(CompressFiles, sender, list) +{ + +} + +QSharedPointer DFMCompressEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlListBaseEvent::fromJson(CompressFiles, json).staticCast(); +} + +DFMDecompressEvent::DFMDecompressEvent(const QObject *sender, const DUrlList &list) + : DFMUrlListBaseEvent(DecompressFile, sender, list) +{ + +} + +QSharedPointer DFMDecompressEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlListBaseEvent::fromJson(DecompressFile, json).staticCast(); +} + +DFMDecompressHereEvent::DFMDecompressHereEvent(const QObject *sender, const DUrlList &list) + : DFMDecompressEvent(sender, list) +{ + m_type = DecompressFileHere; +} + +QSharedPointer DFMDecompressHereEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlListBaseEvent::fromJson(DecompressFileHere, json).staticCast(); +} + +DFMWriteUrlsToClipboardEvent::DFMWriteUrlsToClipboardEvent(const QObject *sender, + DFMGlobal::ClipboardAction action, + const DUrlList &list) + : DFMUrlListBaseEvent(WriteUrlsToClipboard, sender, list) +{ + setProperty(QT_STRINGIFY(DFMWriteUrlsToClipboardEvent::action), action); +} + +DFMGlobal::ClipboardAction DFMWriteUrlsToClipboardEvent::action() const +{ + return property(QT_STRINGIFY(DFMWriteUrlsToClipboardEvent::action), DFMGlobal::CutAction); +} + +QSharedPointer DFMWriteUrlsToClipboardEvent::fromJson(const QJsonObject &json) +{ + const QSharedPointer &event = DFMUrlListBaseEvent::fromJson(WriteUrlsToClipboard, json).staticCast(); + + event->setProperty(QT_STRINGIFY(DFMWriteUrlsToClipboardEvent::action), (DFMGlobal::ClipboardAction)json["action"].toInt()); + + return event; +} + +DFMRenameEvent::DFMRenameEvent(const QObject *sender, const DUrl &from, const DUrl &to, const bool silent) + : DFMEvent(RenameFile, sender) +{ + setData(QPair(from, to)); + setProperty(QT_STRINGIFY(DFMRenameEvent::silent), silent); +} + +DUrlList DFMRenameEvent::handleUrlList() const +{ + const auto &&d = qvariant_cast>(m_data); + + return DUrlList() << d.first << d.second; +} + +bool DFMRenameEvent::silent() const +{ + return property(QT_STRINGIFY(DFMRenameEvent::silent), false); +} + +QSharedPointer DFMRenameEvent::fromJson(const QJsonObject &json) +{ + return dMakeEventPointer(Q_NULLPTR, DUrl::fromUserInput(json["from"].toString()), DUrl::fromUserInput(json["to"].toString())); +} + +DFMDeleteEvent::DFMDeleteEvent(const QObject *sender, const DUrlList &list, bool silent, bool force) + : DFMUrlListBaseEvent(DeleteFiles, sender, list) +{ + setProperty(QT_STRINGIFY(DFMDeleteEvent::silent), silent); + setProperty(QT_STRINGIFY(DFMDeleteEvent::force), force); +} + +bool DFMDeleteEvent::silent() const +{ + return property(QT_STRINGIFY(DFMDeleteEvent::silent), false); +} + +bool DFMDeleteEvent::force() const +{ + return property(QT_STRINGIFY(DFMDeleteEvent::force), false); +} + +QSharedPointer DFMDeleteEvent::fromJson(const QJsonObject &json) +{ + const QSharedPointer &event = DFMUrlListBaseEvent::fromJson(DeleteFiles, json).staticCast(); + + event->setProperty(QT_STRINGIFY(DFMDeleteEvent::silent), json["silent"].toBool()); + event->setProperty(QT_STRINGIFY(DFMDeleteEvent::force), json["force"].toBool()); + + return event; +} + +DFMMoveToTrashEvent::DFMMoveToTrashEvent(const QObject *sender, const DUrlList &list, bool silent, const DUrlList &cutList) + : DFMUrlListBaseEvent(MoveToTrash, sender, list) +{ + setProperty(QT_STRINGIFY(DFMMoveToTrashEvent::silent), silent); + setCutData(cutList); +} + +bool DFMMoveToTrashEvent::silent() const +{ + return property(QT_STRINGIFY(DFMMoveToTrashEvent::silent), false); +} + +QSharedPointer DFMMoveToTrashEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlListBaseEvent::fromJson(MoveToTrash, json).staticCast(); +} + +DFMRestoreFromTrashEvent::DFMRestoreFromTrashEvent(const QObject *sender, const DUrlList &list) + : DFMUrlListBaseEvent(RestoreFromTrash, sender, list) +{ + +} + +QSharedPointer DFMRestoreFromTrashEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlListBaseEvent::fromJson(RestoreFromTrash, json).staticCast(); +} + +DFMPasteEvent::DFMPasteEvent(const QObject *sender, DFMGlobal::ClipboardAction action, + const DUrl &targetUrl, const DUrlList &list) + : DFMUrlListBaseEvent(PasteFile, sender, list) +{ + setData(list); + setProperty(QT_STRINGIFY(DFMPasteEvent::action), action); + setProperty(QT_STRINGIFY(DFMPasteEvent::targetUrl), targetUrl); +} + +DFMGlobal::ClipboardAction DFMPasteEvent::action() const +{ + return property(QT_STRINGIFY(DFMPasteEvent::action), DFMGlobal::CutAction); +} + +DUrl DFMPasteEvent::targetUrl() const +{ + return property(QT_STRINGIFY(DFMPasteEvent::targetUrl), DUrl()); +} + +DUrlList DFMPasteEvent::handleUrlList() const +{ + return DUrlList() << targetUrl() << urlList(); +} + +QSharedPointer DFMPasteEvent::fromJson(const QJsonObject &json) +{ + const QSharedPointer &event = DFMUrlListBaseEvent::fromJson(PasteFile, json); + + return dMakeEventPointer(Q_NULLPTR, (DFMGlobal::ClipboardAction)json["action"].toInt(), + DUrl::fromUserInput(json["targetUrl"].toString()), event->urlList()); +} + +DFMMkdirEvent::DFMMkdirEvent(const QObject *sender, const DUrl &url) + : DFMUrlBaseEvent(Mkdir, sender, url) +{ + +} + +QSharedPointer DFMMkdirEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlBaseEvent::fromJson(Mkdir, json).staticCast(); +} + +DFMTouchFileEvent::DFMTouchFileEvent(const QObject *sender, const DUrl &url) + : DFMUrlBaseEvent(TouchFile, sender, url) +{ + +} + +QSharedPointer DFMTouchFileEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlBaseEvent::fromJson(TouchFile, json).staticCast(); +} + +DFMOpenFileLocation::DFMOpenFileLocation(const QObject *sender, const DUrl &url) + : DFMUrlBaseEvent(OpenFileLocation, sender, url) +{ + +} + +QSharedPointer DFMOpenFileLocation::fromJson(const QJsonObject &json) +{ + return DFMUrlBaseEvent::fromJson(OpenFileLocation, json).staticCast(); +} + +DFMAddToBookmarkEvent::DFMAddToBookmarkEvent(const QObject *sender, const DUrl &url) + : DFMUrlBaseEvent(AddToBookmark, sender, url) +{ + +} + +DFMRemoveBookmarkEvent::DFMRemoveBookmarkEvent(const QObject *sender, const DUrl &url) + : DFMUrlBaseEvent(RemoveBookmark, sender, url) +{ + +} + +DFMCreateSymlinkEvent::DFMCreateSymlinkEvent(const QObject *sender, const DUrl &fileUrl, const DUrl &toUrl, bool force/* = false*/) + : DFMEvent(CreateSymlink, sender) +{ + setData(makeData(fileUrl, toUrl)); + setProperty(QT_STRINGIFY(DFMDeleteEvent::force), force); +} + +bool DFMCreateSymlinkEvent::force() const +{ + return property(QT_STRINGIFY(DFMDeleteEvent::force), false); +} + +DUrlList DFMCreateSymlinkEvent::handleUrlList() const +{ + return DUrlList() << fileUrl() << toUrl(); +} + +QSharedPointer DFMCreateSymlinkEvent::fromJson(const QJsonObject &json) +{ + const QSharedPointer &event = dMakeEventPointer(Q_NULLPTR, DUrl::fromUserInput(json["fileUrl"].toString()), + DUrl::fromUserInput(json["toUrl"].toString())); + event->setProperty(QT_STRINGIFY(DFMDeleteEvent::force), json["force"].toBool()); + return event; +} + +DFMFileShareEvent::DFMFileShareEvent(const QObject *sender, const DUrl &url, + const QString &name, bool isWritable, bool allowGuest) + : DFMUrlBaseEvent(FileShare, sender, url) +{ + setProperty(QT_STRINGIFY(DFMFileShareEvent::name), name); + setProperty(QT_STRINGIFY(DFMFileShareEvent::isWritable), isWritable); + setProperty(QT_STRINGIFY(DFMFileShareEvent::allowGuest), allowGuest); +} + +QString DFMFileShareEvent::name() const +{ + return property(QT_STRINGIFY(DFMFileShareEvent::name), QString()); +} + +bool DFMFileShareEvent::isWritable() const +{ + return property(QT_STRINGIFY(DFMFileShareEvent::isWritable), false); +} + +bool DFMFileShareEvent::allowGuest() const +{ + return property(QT_STRINGIFY(DFMFileShareEvent::allowGuest), false); +} + +QSharedPointer DFMFileShareEvent::fromJson(const QJsonObject &json) +{ + return dMakeEventPointer(Q_NULLPTR, DUrl::fromUserInput(json["url"].toString()), json["name"].toString(), + json["isWritable"].toBool(), json["allowGuest"].toBool()); +} + +DFMCancelFileShareEvent::DFMCancelFileShareEvent(const QObject *sender, const DUrl &url) + : DFMUrlBaseEvent(CancelFileShare, sender, url) +{ + +} + +QSharedPointer DFMCancelFileShareEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlBaseEvent::fromJson(CancelFileShare, json).staticCast(); +} + +DFMOpenInTerminalEvent::DFMOpenInTerminalEvent(const QObject *sender, const DUrl &url) + : DFMUrlBaseEvent(OpenInTerminal, sender, url) +{ + +} + +QSharedPointer DFMOpenInTerminalEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlBaseEvent::fromJson(OpenInTerminal, json).staticCast(); +} + +DFMGetChildrensEvent::DFMGetChildrensEvent(const QObject *sender, const DUrl &url, const QStringList &nameFilters, + QDir::Filters filters, QDirIterator::IteratorFlags flags, bool slient, bool canconst) + : DFMUrlBaseEvent(GetChildrens, sender, url) +{ + setProperty(QT_STRINGIFY(DFMGetChildrensEvent::nameFilters), nameFilters); + setProperty(QT_STRINGIFY(DFMGetChildrensEvent::filters), filters); + setProperty(QT_STRINGIFY(DFMGetChildrensEvent::flags), flags); + setProperty(QT_STRINGIFY(DFMGetChildrensEvent::slient), slient); + setProperty(QT_STRINGIFY(DFMGetChildrensEvent::canconst), canconst); +} + +DFMGetChildrensEvent::DFMGetChildrensEvent(const QObject *sender, const DUrl &url, const QStringList &nameFilters, + QDir::Filters filters, bool slient, bool canconst) + : DFMGetChildrensEvent(sender, url, nameFilters, filters, QDirIterator::NoIteratorFlags, slient, canconst) +{ + +} + +QStringList DFMGetChildrensEvent::nameFilters() const +{ + return property(QT_STRINGIFY(DFMGetChildrensEvent::nameFilters), QStringList()); +} + +QDir::Filters DFMGetChildrensEvent::filters() const +{ + return property(QT_STRINGIFY(DFMGetChildrensEvent::filters), QDir::Filters()); +} + +QDirIterator::IteratorFlags DFMGetChildrensEvent::flags() const +{ + return property(QT_STRINGIFY(DFMGetChildrensEvent::flags), QDirIterator::IteratorFlags()); +} + +bool DFMGetChildrensEvent::silent() const +{ + return property(QT_STRINGIFY(DFMGetChildrensEvent::silent), false); +} + +bool DFMGetChildrensEvent::canconst() const +{ + return property(QT_STRINGIFY(DFMGetChildrensEvent::canconst), false); +} + +QSharedPointer DFMGetChildrensEvent::fromJson(const QJsonObject &json) +{ + QStringList nameFilters; + + for (const QJsonValue &value : json["nameFilters"].toArray()) { + nameFilters << value.toString(); + } + + return dMakeEventPointer(Q_NULLPTR, DUrl::fromUserInput(json["url"].toString()), + nameFilters, (QDir::Filters)json["filters"].toInt(), QDirIterator::NoIteratorFlags, + json["silent"].toBool()); +} + +DFMCreateDiriterator::DFMCreateDiriterator(const QObject *sender, const DUrl &fileUrl, const QStringList &nameFilters, + QDir::Filters filters, QDirIterator::IteratorFlags flags, bool silent, bool isgvfs) + : DFMGetChildrensEvent(sender, fileUrl, nameFilters, filters, flags, silent) +{ + m_type = CreateDiriterator; + setProperty(QT_STRINGIFY(DFMCreateDiriterator::isgvfsfile), isgvfs); +} + +DFMCreateDiriterator::DFMCreateDiriterator(const QObject *sender, const DUrl &fileUrl, const QStringList &nameFilters, + QDir::Filters filters, bool silent, bool isgvfs) + : DFMGetChildrensEvent(sender, fileUrl, nameFilters, filters, silent) +{ + m_type = CreateDiriterator; + setProperty(QT_STRINGIFY(DFMCreateDiriterator::isgvfsfile), isgvfs); +} + +bool DFMCreateDiriterator::isGvfsFile() const +{ + return property(QT_STRINGIFY(DFMCreateDiriterator::isgvfsfile)); +} + +QSharedPointer DFMCreateDiriterator::fromJson(const QJsonObject &json) +{ + const QSharedPointer &event = DFMGetChildrensEvent::fromJson(json).staticCast(); + + event->m_type = CreateDiriterator; + + return event; +} + +DFMCreateGetChildrensJob::DFMCreateGetChildrensJob(const QObject *sender, const DUrl &url, const QStringList &nameFilters, + QDir::Filters filters, QDirIterator::IteratorFlags flags, bool silent, const bool isgvfsfile) + : DFMCreateDiriterator(sender, url, nameFilters, filters, flags, silent, isgvfsfile) +{ + m_type = CreateGetChildrensJob; +} + +DFMCreateGetChildrensJob::DFMCreateGetChildrensJob(const QObject *sender, const DUrl &url, const QStringList &nameFilters, + QDir::Filters filters, bool silent, const bool isgvfsfile) + : DFMCreateDiriterator(sender, url, nameFilters, filters, silent, isgvfsfile) +{ + m_type = CreateGetChildrensJob; +} + +QSharedPointer DFMCreateGetChildrensJob::fromJson(const QJsonObject &json) +{ + const QSharedPointer &event = DFMCreateDiriterator::fromJson(json).staticCast(); + + event->m_type = CreateGetChildrensJob; + + return event; +} + +DFMCreateFileInfoEvent::DFMCreateFileInfoEvent(const QObject *sender, const DUrl &url) + : DFMUrlBaseEvent(CreateFileInfo, sender, url) +{ + +} + +QSharedPointer DFMCreateFileInfoEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlBaseEvent::fromJson(CreateFileInfo, json).staticCast(); +} + +DFMCreateFileWatcherEvent::DFMCreateFileWatcherEvent(const QObject *sender, const DUrl &url) + : DFMUrlBaseEvent(CreateFileWatcher, sender, url) +{ + +} + +QSharedPointer DFMCreateFileWatcherEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlBaseEvent::fromJson(CreateFileWatcher, json).staticCast(); +} + +DFMChangeCurrentUrlEvent::DFMChangeCurrentUrlEvent(const QObject *sender, const DUrl &url, const QWidget *window) + : DFMUrlBaseEvent(ChangeCurrentUrl, sender, url) +{ + setProperty(QT_STRINGIFY(DFMChangeCurrentUrlEvent::window), (quintptr)window); +} + +const QWidget *DFMChangeCurrentUrlEvent::window() const +{ + return (const QWidget *)(property(QT_STRINGIFY(DFMChangeCurrentUrlEvent::window))); +} + +QSharedPointer DFMChangeCurrentUrlEvent::fromJson(const QJsonObject &json) +{ + return dMakeEventPointer(Q_NULLPTR, DUrl::fromUserInput(json["url"].toString()), Q_NULLPTR); +} + +DFMOpenNewWindowEvent::DFMOpenNewWindowEvent(const QObject *sender, const DUrlList &list, bool force) + : DFMUrlListBaseEvent(OpenNewWindow, sender, list) +{ + setProperty(QT_STRINGIFY(DFMOpenNewWindowEvent::force), force); +} + +bool DFMOpenNewWindowEvent::force() const +{ + return property(QT_STRINGIFY(DFMOpenNewWindowEvent::force), false); +} + +QSharedPointer DFMOpenNewWindowEvent::fromJson(const QJsonObject &json) +{ + const QSharedPointer &event = DFMUrlListBaseEvent::fromJson(OpenNewWindow, json).staticCast(); + + event->setProperty(QT_STRINGIFY(DFMOpenNewWindowEvent::force), json["force"].toBool()); + + return event; +} + +DFMOpenNewTabEvent::DFMOpenNewTabEvent(const QObject *sender, const DUrl &url) + : DFMUrlBaseEvent(OpenNewTab, sender, url) +{ + +} + +QSharedPointer DFMOpenNewTabEvent::fromJson(const QJsonObject &json) +{ + return DFMUrlBaseEvent::fromJson(OpenNewTab, json).staticCast(); +} + +DFMOpenUrlEvent::DFMOpenUrlEvent(const QObject *sender, const DUrlList &list, DFMOpenUrlEvent::DirOpenMode mode, const bool isEnter) + : DFMUrlListBaseEvent(OpenUrl, sender, list) +{ + setProperty(QT_STRINGIFY(DFMOpenUrlEvent::dirOpenMode), mode); + setProperty(QT_STRINGIFY(DFMOpenUrlEvent::isEnter), isEnter); +} + +DFMOpenUrlEvent::DirOpenMode DFMOpenUrlEvent::dirOpenMode() const +{ + return property(QT_STRINGIFY(DFMOpenUrlEvent::dirOpenMode), DirOpenMode::OpenNewWindow); +} + +bool DFMOpenUrlEvent::isEnter() const +{ + return property(QT_STRINGIFY(DFMOpenUrlEvent::isEnter)).toBool(); +} + +QSharedPointer DFMOpenUrlEvent::fromJson(const QJsonObject &json) +{ + const QSharedPointer &event = DFMUrlListBaseEvent::fromJson(OpenUrl, json).staticCast(); + + event->setProperty(QT_STRINGIFY(DFMOpenUrlEvent::dirOpenMode), static_cast(json["mode"].toInt())); + event->setProperty(QT_STRINGIFY(DFMOpenUrlEvent::isEnter), json["isEnter"].toBool()); + + return event; +} + +DFMMenuActionEvent::DFMMenuActionEvent(const QObject *sender, const DFileMenu *menu, const DUrl ¤tUrl, + const DUrlList &selectedUrls, DFMGlobal::MenuAction action, const QModelIndex &index) + : DFMUrlListBaseEvent(MenuAction, sender, selectedUrls) +{ + setProperty(QT_STRINGIFY(DFMMenuActionEvent::menu), (quintptr)menu); + setProperty(QT_STRINGIFY(DFMMenuActionEvent::currentUrl), currentUrl); + setProperty(QT_STRINGIFY(DFMMenuActionEvent::action), action); + setProperty(QT_STRINGIFY(DFMMenuActionEvent::clickedIndex), index); +} + +const DFileMenu *DFMMenuActionEvent::menu() const +{ + return (const DFileMenu *)(property(QT_STRINGIFY(DFMMenuActionEvent::menu), 0)); +} + +const DUrl DFMMenuActionEvent::currentUrl() const +{ + return property(QT_STRINGIFY(DFMMenuActionEvent::currentUrl), DUrl()); +} + +const DUrlList DFMMenuActionEvent::selectedUrls() const +{ + return data(); +} + +DFMGlobal::MenuAction DFMMenuActionEvent::action() const +{ + return property(QT_STRINGIFY(DFMMenuActionEvent::action), DFMGlobal::Unknow); +} + +const QModelIndex DFMMenuActionEvent::clickedIndex() const +{ + return property(QT_STRINGIFY(DFMMenuActionEvent::clickedIndex), QModelIndex()); +} + +const QList DFMMenuActionEvent::tagColors() const +{ + return m_tagColorsList; +} + +void DFMMenuActionEvent::setTagColors(const QList &list) +{ + m_tagColorsList = list; +} + +QSharedPointer DFMMenuActionEvent::fromJson(const QJsonObject &json) +{ + const QSharedPointer &event = DFMUrlListBaseEvent::fromJson(MenuAction, json).staticCast(); + int action = DFMGlobal::instance()->metaObject()->enumerator(DFMGlobal::instance()->metaObject()->indexOfEnumerator("MenuAction")).keyToValue(json["action"].toString().toLocal8Bit().constData()); + + event->setProperty(QT_STRINGIFY(DFMMenuActionEvent::currentUrl), DUrl::fromUserInput(json["currentUrl"].toString())); + event->setProperty(QT_STRINGIFY(DFMMenuActionEvent::action), static_cast(action)); + + return event; +} + +DFMBackEvent::DFMBackEvent(const QObject *sender) + : DFMEvent(Back, sender) +{ + +} + +QSharedPointer DFMBackEvent::fromJson(const QJsonObject &json) +{ + Q_UNUSED(json) + + return dMakeEventPointer(Q_NULLPTR); +} + +DFMForwardEvent::DFMForwardEvent(const QObject *sender) + : DFMEvent(Forward, sender) +{ + +} + +QSharedPointer DFMForwardEvent::fromJson(const QJsonObject &json) +{ + Q_UNUSED(json) + + return dMakeEventPointer(Q_NULLPTR); +} + +DFMSaveOperatorEvent::DFMSaveOperatorEvent(const QSharedPointer &iniaiator, const QSharedPointer &event, bool async) + : DFMEvent(SaveOperator, nullptr) +{ + setProperty(QT_STRINGIFY(DFMSaveOperatorEvent::iniaiator), QVariant::fromValue(iniaiator)); + setProperty(QT_STRINGIFY(DFMSaveOperatorEvent::event), QVariant::fromValue(event)); + setProperty(QT_STRINGIFY(DFMSaveOperatorEvent::async), async); +} + +DFMSaveOperatorEvent::DFMSaveOperatorEvent() + : DFMEvent(SaveOperator, nullptr) +{ + setProperty(QT_STRINGIFY(DFMSaveOperatorEvent::split), true); +} + +QSharedPointer DFMSaveOperatorEvent::iniaiator() const +{ + return qvariant_cast>(property(QT_STRINGIFY(DFMSaveOperatorEvent::iniaiator))); +} + +QSharedPointer DFMSaveOperatorEvent::event() const +{ + return qvariant_cast>(property(QT_STRINGIFY(DFMSaveOperatorEvent::event))); +} + +bool DFMSaveOperatorEvent::async() const +{ + return property(QT_STRINGIFY(DFMSaveOperatorEvent::async)).toBool(); +} + +bool DFMSaveOperatorEvent::split() const +{ + return property(QT_STRINGIFY(DFMSaveOperatorEvent::split)).toBool(); +} + +DFMRevocationEvent::DFMRevocationEvent(const QObject *sender) + : DFMEvent(Revocation, sender) +{ + +} + +DFMCleanSaveOperatorEvent::DFMCleanSaveOperatorEvent(const QObject *sender) + : DFMEvent(CleanSaveOperator, sender) +{ + +} + +DFMSetFileTagsEvent::DFMSetFileTagsEvent(const QObject *sender, const DUrl &url, const QList &tags) + : DFMUrlBaseEvent{Tag, sender, url } +{ + setProperty(QT_STRINGIFY(DFMSetFileTagsEvent::tags), tags); +} + +QSharedPointer DFMSetFileTagsEvent::fromJson(const QJsonObject &json) +{ + (void)json; + return QSharedPointer { nullptr }; +} + +QList DFMSetFileTagsEvent::tags() const +{ + QVariant var{ property(QT_STRINGIFY(DFMSetFileTagsEvent::tags), {QString()}) }; + QList tag_name{ var.value>() }; + + return tag_name; +} + +DFMRemoveTagsOfFileEvent::DFMRemoveTagsOfFileEvent(const QObject *sender, const DUrl &url, const QList &tags) + : DFMUrlBaseEvent{DFMEvent::Untag, sender, url} +{ + setProperty(QT_STRINGIFY(DFMRemoveTagsOfFileEvent::tags), QVariant{tags}); +} + +QSharedPointer DFMRemoveTagsOfFileEvent::fromJson(const QJsonObject &json) +{ + (void)json; + return QSharedPointer { nullptr }; +} + +QList DFMRemoveTagsOfFileEvent::tags() const +{ + QVariant var{ property(QT_STRINGIFY(DFMRemoveTagsOfFileEvent::tags), {QString()}) }; + QList tag_name{ var.toStringList() }; + + return tag_name; +} + + + + +DFMChangeTagColorEvent::DFMChangeTagColorEvent(const QObject *sender, const QColor &color, const DUrl &tagUrl) + : DFMEvent{ Type::ChangeTagColor, sender }, + m_newColorForTag{ color }, + m_tagUrl{ tagUrl } +{ +} + +QSharedPointer DFMChangeTagColorEvent::fromJson(const QJsonObject &json) +{ + (void)json; + return QSharedPointer { nullptr }; +} + +DFMGetTagsThroughFilesEvent::DFMGetTagsThroughFilesEvent(const QObject *sender, const QList &files) + : DFMUrlListBaseEvent{ Type::GetTagsThroughFiles, sender, files } +{ +} + +QSharedPointer DFMGetTagsThroughFilesEvent::fromJson(const QJsonObject &json) +{ + (void)json; + return QSharedPointer { nullptr }; +} + +DFMSetFileExtraProperties::DFMSetFileExtraProperties(const QObject *sender, const DUrl &url, const QVariantHash &ep) + : DFMUrlBaseEvent(SetFileExtraProperties, sender, url) +{ + setProperty(QT_STRINGIFY(DFMSetFileExtraProperties::extraProperties), ep); +} + +QVariantHash DFMSetFileExtraProperties::extraProperties() const +{ + return property(QT_STRINGIFY(DFMSetFileExtraProperties::extraProperties)).toHash(); +} + +DFMSetPermissionEvent::DFMSetPermissionEvent(const QObject *sender, const DUrl &url, const QFileDevice::Permissions &permissions) + : DFMUrlBaseEvent{ Type::SetPermission, sender, url } +{ + setProperty(QT_STRINGIFY(DFMSetPermissionEvent::permissions), static_cast(permissions)); +} + +QFileDevice::Permissions DFMSetPermissionEvent::permissions() const +{ + return static_cast(property(QT_STRINGIFY(DFMSetPermissionEvent::permissions)).toInt()); +} + +DFMOpenFilesEvent::DFMOpenFilesEvent(const QObject *sender, const DUrlList &list, const bool isEnter) + : DFMUrlListBaseEvent(OpenFiles, sender, list) +{ + setProperty(QT_STRINGIFY(DFMOpenFilesEvent::isEnter), isEnter); +} + +bool DFMOpenFilesEvent::isEnter() const +{ + return property(QT_STRINGIFY(DFMOpenFilesEvent::isEnter)).toBool(); +} + +QSharedPointer DFMOpenFilesEvent::fromJson(const QJsonObject &json) +{ + DUrlList list; + + for (const QJsonValue value : json["urlList"].toArray()) { + list << DUrl::fromUserInput(value.toString()); + } + + return dMakeEventPointer(Q_NULLPTR, list, json["isEnter"].toBool()); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmevent.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmevent.h new file mode 100644 index 0000000..0dd54f2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmevent.h @@ -0,0 +1,777 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef FMEVENT_H +#define FMEVENT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "durl.h" +#include "dfmglobal.h" + +class DFMEvent +{ +public: + enum Type { + UnknowType, + // for file serices + OpenFile, + OpenFileByApp, + CompressFiles, + DecompressFile, + DecompressFileHere, + WriteUrlsToClipboard, + RenameFile, + DeleteFiles, + MoveToTrash, + RestoreFromTrash, + PasteFile, + Mkdir, + TouchFile, + OpenFileLocation, + AddToBookmark, + RemoveBookmark, + CreateSymlink, + FileShare, + CancelFileShare, + OpenInTerminal, + GetChildrens, + CreateFileInfo, + CreateDiriterator, + CreateGetChildrensJob, + CreateFileWatcher, + CreateFileDevice, + CreateFileHandler, + CreateStorageInfo, + SetFileExtraProperties, + SetPermission, + + // other + ChangeCurrentUrl, + OpenNewWindow, + OpenNewTab, + OpenUrl, + MenuAction, + Back, + Forward, + // save operator + SaveOperator, + // Ctrl+Z + CleanSaveOperator, + Revocation, + + ///###: tag protocol. + Tag, + Untag, + ChangeTagColor, + GetTagsThroughFiles, + OpenFiles, //fix 修改多文件选中右键打开只启动一次应用,传多个参数 + OpenFilesByApp,//fix 修改选择多个文件时,选择默认程序,只传了一个 + // user custom + CustomBase = 1000 // first user event id + }; + + explicit DFMEvent(const QObject *sender = nullptr); + explicit DFMEvent(Type type, const QObject *sender); + + DFMEvent(const DFMEvent &other); + + virtual ~DFMEvent(); + + DFMEvent &operator =(const DFMEvent &other); + + static Type nameToType(const QString &name); + static QString typeToName(Type type); + inline Type type() const + { + return static_cast(m_type); + } + inline void setType(Type type) + { + m_type = type; + } + inline QPointer sender() const + { + return m_sender; + } + inline void setSender(const QObject *sender) + { + m_sender = sender; + } + + inline void setAccepted(bool accepted) + { + m_accept = accepted; + } + inline bool isAccepted() const + { + return m_accept; + } + + inline void accept() + { + m_accept = true; + } + inline void ignore() + { + m_accept = false; + } + + static quint64 windowIdByQObject(const QObject *object); + quint64 windowId() const; + void setWindowId(quint64 id); + + //! 在DFileServices中通过此url列表来获取处理此事件的Controller + virtual DUrlList handleUrlList() const; + inline void setData(const QVariant &data) + { + m_data = data; + } + template + void setData(T &&data) + { + m_data = QVariant::fromValue(std::forward(data)); + } + inline QVariant data() const + { + return m_data; + } + template + inline T data() const + { + return qvariant_cast(m_data); + } + //! 设置剪切文件在回收站的路径 + inline void setCutData(const QVariant &data) + { + m_cutData = data; + } + template + void setCutData(T &&data) + { + m_cutData = QVariant::fromValue(std::forward(data)); + } + inline QVariant cutData() const + { + return m_cutData; + } + template + inline T cutData() const + { + return qvariant_cast(m_cutData); + } + +// template +// inline T data()const +// { +// return m_data.value(); +// } + + inline DUrl fileUrl() const + { + return data(); + } + inline DUrlList fileUrlList() const + { + return data(); + } + + inline QVariantMap properties() const + { + return m_properties; + } + inline QVariant property(const QString &name, const QVariant &defaultValue = QVariant()) const + { + return m_properties.value(name, defaultValue); + } + template + T property(const QString &name, T &&defaultValue) const + { + return qvariant_cast(m_properties.value(name, QVariant::fromValue(std::forward(defaultValue)))); + } + template + T property(const QString &name) const + { + return qvariant_cast(property(name)); + } + inline void setProperty(const QString &name, const QVariant &value) + { + m_properties[name] = value; + } + template + void setProperty(const QString &name, T &&value) + { + m_properties[name] = QVariant::fromValue(std::forward(value)); + } + + static const QSharedPointer fromJson(Type type, const QJsonObject &json); + static const QSharedPointer fromJson(const QJsonObject &json); + +protected: + ushort m_type; + QVariant m_data; + QVariant m_cutData; //! 剪切原路径 + QVariantMap m_properties; + QPointer m_sender; + +private: + ushort m_accept : 1; + quint64 m_id; +}; + +Q_DECLARE_METATYPE(DFMEvent) +Q_DECLARE_METATYPE(QSharedPointer) + +template +const T dfmevent_cast(const DFMEvent &event) +{ + if (!QString(typeid(T).name()).contains(DFMEvent::typeToName(event.type()))) { + DFMEvent e; + + return *reinterpret_cast(&e); + } + + return *reinterpret_cast(&event); +} + +template +T dfmevent_cast(DFMEvent &event) +{ + if (!QString(typeid(T).name()).contains(DFMEvent::typeToName(event.type()))) { + DFMEvent e; + + return *reinterpret_cast(&e); + } + + return *reinterpret_cast(&event); +} + +QT_BEGIN_NAMESPACE +QDebug operator<<(QDebug deg, const DFMEvent &info); +QT_END_NAMESPACE + +class DFMUrlBaseEvent : public DFMEvent +{ +public: + explicit DFMUrlBaseEvent(const QObject *sender, const DUrl &url); + explicit DFMUrlBaseEvent(Type type, const QObject *sender, const DUrl &url); + + inline DUrl url() const + { + return qvariant_cast(m_data); + } + + static QSharedPointer fromJson(Type type, const QJsonObject &json); +}; + +class DFMUrlListBaseEvent : public DFMEvent +{ +public: + explicit DFMUrlListBaseEvent(); + explicit DFMUrlListBaseEvent(const QObject *sender, const DUrlList &list); + explicit DFMUrlListBaseEvent(Type type, const QObject *sender, const DUrlList &list); + + inline DUrlList urlList() const + { + return qvariant_cast(m_data); + } + + static QSharedPointer fromJson(Type type, const QJsonObject &json); +}; +Q_DECLARE_METATYPE(DFMUrlListBaseEvent) + +template +QSharedPointer dMakeEventPointer(Args &&... args) +{ + return QSharedPointer(new T(std::forward(args)...)); +} + +class DFMOpenFileEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMOpenFileEvent(const QObject *sender, const DUrl &url); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMOpenFilesEvent : public DFMUrlListBaseEvent +{ +public: + explicit DFMOpenFilesEvent(const QObject *sender, const DUrlList &list, const bool isEnter = false); + + bool isEnter() const; + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMOpenFileByAppEvent : public DFMOpenFileEvent +{ +public: + explicit DFMOpenFileByAppEvent(const QObject *sender, const QString &appName, const DUrl &url); + + QString appName() const; + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMOpenFilesByAppEvent : public DFMOpenFilesEvent +{ +public: + explicit DFMOpenFilesByAppEvent(const QObject *sender, const QString &appName, const QList &url, const bool isEnter = false); + + QString appName() const; + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMCompressEvent : public DFMUrlListBaseEvent +{ +public: + explicit DFMCompressEvent(const QObject *sender, const DUrlList &list); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMDecompressEvent : public DFMUrlListBaseEvent +{ +public: + explicit DFMDecompressEvent(const QObject *sender, const DUrlList &list); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMDecompressHereEvent : public DFMDecompressEvent +{ +public: + explicit DFMDecompressHereEvent(const QObject *sender, const DUrlList &list); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMWriteUrlsToClipboardEvent : public DFMUrlListBaseEvent +{ +public: + explicit DFMWriteUrlsToClipboardEvent(const QObject *sender, DFMGlobal::ClipboardAction action, const DUrlList &list); + + DFMGlobal::ClipboardAction action() const; + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMRenameEvent : public DFMEvent +{ +public: + explicit DFMRenameEvent(const QObject *sender, const DUrl &from, const DUrl &to, const bool silent = false); + + inline DUrl fromUrl() const + { + return qvariant_cast>(m_data).first; + } + inline DUrl toUrl() const + { + return qvariant_cast>(m_data).second; + } + + DUrlList handleUrlList() const override; + + bool silent() const; + + inline static QVariant makeData(const DUrl &from, const DUrl &to) + { + return QVariant::fromValue(QPair(from, to)); + } + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMDeleteEvent : public DFMUrlListBaseEvent +{ +public: + explicit DFMDeleteEvent(const QObject *sender, const DUrlList &list, bool silent = false, bool force = false); + + bool silent() const; + bool force() const; + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMMoveToTrashEvent : public DFMUrlListBaseEvent +{ +public: + //! 新增剪切回收站路径cutList + explicit DFMMoveToTrashEvent(const QObject *sender, const DUrlList &list, bool silent = false, const DUrlList &cutList = DUrlList()); + + bool silent() const; + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMRestoreFromTrashEvent : public DFMUrlListBaseEvent +{ +public: + explicit DFMRestoreFromTrashEvent(const QObject *sender, const DUrlList &list); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMPasteEvent : public DFMUrlListBaseEvent +{ +public: + explicit DFMPasteEvent(const QObject *sender, DFMGlobal::ClipboardAction action, + const DUrl &targetUrl, const DUrlList &list); + + DFMGlobal::ClipboardAction action() const; + DUrl targetUrl() const; + + DUrlList handleUrlList() const override; + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMMkdirEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMMkdirEvent(const QObject *sender, const DUrl &url); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMTouchFileEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMTouchFileEvent(const QObject *sender, const DUrl &url); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMOpenFileLocation : public DFMUrlBaseEvent +{ +public: + explicit DFMOpenFileLocation(const QObject *sender, const DUrl &url); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMAddToBookmarkEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMAddToBookmarkEvent(const QObject *sender, const DUrl &url); +}; + +class DFMRemoveBookmarkEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMRemoveBookmarkEvent(const QObject *sender, const DUrl &url); +}; + +class DFMCreateSymlinkEvent : public DFMEvent +{ +public: + explicit DFMCreateSymlinkEvent(const QObject *sender, const DUrl &fileUrl, const DUrl &toUrl, bool force = false); + + bool force() const; + + inline DUrl fileUrl() const + { + return qvariant_cast>(m_data).first; + } + inline DUrl toUrl() const + { + return qvariant_cast>(m_data).second; + } + + DUrlList handleUrlList() const override; + + inline static QVariant makeData(const DUrl &url, const DUrl &to) + { + return QVariant::fromValue(QPair(url, to)); + } + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMFileShareEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMFileShareEvent(const QObject *sender, const DUrl &url, const QString &name, bool isWritable = false, bool allowGuest = false); + + QString name() const; + bool isWritable() const; + bool allowGuest() const; + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMCancelFileShareEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMCancelFileShareEvent(const QObject *sender, const DUrl &url); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMOpenInTerminalEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMOpenInTerminalEvent(const QObject *sender, const DUrl &url); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMGetChildrensEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMGetChildrensEvent(const QObject *sender, const DUrl &url, const QStringList &nameFilters, + QDir::Filters filters, QDirIterator::IteratorFlags flags, bool slient = false, bool canconst = false); + explicit DFMGetChildrensEvent(const QObject *sender, const DUrl &url, + const QStringList &nameFilters, QDir::Filters filters, bool slient = false, bool canconst = false); + + QStringList nameFilters() const; + QDir::Filters filters() const; + QDirIterator::IteratorFlags flags() const; + bool silent() const; + bool canconst() const; + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +Q_DECLARE_METATYPE(QDir::Filters) +Q_DECLARE_METATYPE(QDirIterator::IteratorFlags) + +class DFMCreateDiriterator : public DFMGetChildrensEvent +{ +public: + explicit DFMCreateDiriterator(const QObject *sender, const DUrl &url, const QStringList &nameFilters, + QDir::Filters filters, QDirIterator::IteratorFlags flags, bool slient = false, bool isgvfs = false); + explicit DFMCreateDiriterator(const QObject *sender, const DUrl &url, + const QStringList &nameFilters, QDir::Filters filters, bool slient = false, bool isgvfs = false); + bool isGvfsFile() const; + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMCreateGetChildrensJob : public DFMCreateDiriterator +{ +public: + explicit DFMCreateGetChildrensJob(const QObject *sender, const DUrl &url, const QStringList &nameFilters, + QDir::Filters filters, QDirIterator::IteratorFlags flags, bool silent = false, const bool isgvfsfile = false); + explicit DFMCreateGetChildrensJob(const QObject *sender, const DUrl &url, + const QStringList &nameFilters, QDir::Filters filters, bool silent = false, const bool isgvfsfile = false); + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMCreateFileInfoEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMCreateFileInfoEvent(const QObject *sender, const DUrl &url); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMCreateFileWatcherEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMCreateFileWatcherEvent(const QObject *sender, const DUrl &url); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMChangeCurrentUrlEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMChangeCurrentUrlEvent(const QObject *sender, const DUrl &url, const QWidget *window); + + const QWidget *window() const; + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMOpenNewWindowEvent : public DFMUrlListBaseEvent +{ +public: + //! force为false时,如果当前已打开窗口中有currentUrl==url的窗口时时不会打开新的窗口,只会激活此窗口。 + explicit DFMOpenNewWindowEvent(const QObject *sender, const DUrlList &list, bool force = true); + + bool force() const; + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMOpenNewTabEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMOpenNewTabEvent(const QObject *sender, const DUrl &url); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMOpenUrlEvent : public DFMUrlListBaseEvent +{ +public: + enum DirOpenMode { + OpenInCurrentWindow, + OpenNewWindow, + ForceOpenNewWindow + }; + + explicit DFMOpenUrlEvent(const QObject *sender, const DUrlList &list, DirOpenMode mode, const bool isEnter = false); + + DirOpenMode dirOpenMode() const; + bool isEnter() const; + + static QSharedPointer fromJson(const QJsonObject &json); +}; +Q_DECLARE_METATYPE(DFMOpenUrlEvent::DirOpenMode) + +class DFileMenu; +class DFMMenuActionEvent : public DFMUrlListBaseEvent +{ +public: + explicit DFMMenuActionEvent(const QObject *sender, const DFileMenu *menu, const DUrl ¤tUrl, + const DUrlList &selectedUrls, DFMGlobal::MenuAction action, const QModelIndex &index = QModelIndex()); + + const DFileMenu *menu() const; + const DUrl currentUrl() const; + const DUrlList selectedUrls() const; + DFMGlobal::MenuAction action() const; + const QModelIndex clickedIndex() const; //当前右键点击的index + const QList tagColors() const; + void setTagColors(const QList &list); + + static QSharedPointer fromJson(const QJsonObject &json); + +protected: + QList m_tagColorsList; +}; + +class DFMBackEvent : public DFMEvent +{ +public: + explicit DFMBackEvent(const QObject *sender); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMForwardEvent : public DFMEvent +{ +public: + explicit DFMForwardEvent(const QObject *sender); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + + +class DFMSaveOperatorEvent : public DFMEvent +{ +public: + explicit DFMSaveOperatorEvent(const QSharedPointer &iniaiator, const QSharedPointer &event, bool async = false); + // is split type + explicit DFMSaveOperatorEvent(); + + QSharedPointer iniaiator() const; + QSharedPointer event() const; + bool async() const; + // 用于实现可回退一系列操作的分隔符, 遇到此类事件时,会一直重复执行撤销动作,直到再次遇到此分隔符或事件栈为空 + bool split() const; +}; + +class DFMCleanSaveOperatorEvent : public DFMEvent +{ +public: + explicit DFMCleanSaveOperatorEvent(const QObject *sender); +}; + +class DFMRevocationEvent : public DFMEvent +{ +public: + explicit DFMRevocationEvent(const QObject *sender); +}; + +class DFMSetPermissionEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMSetPermissionEvent(const QObject *sender, const DUrl &url, const QFileDevice::Permissions &permissions); + QFileDevice::Permissions permissions() const; +}; + +class DFMSetFileTagsEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMSetFileTagsEvent(const QObject *sender, const DUrl &url, const QList &tags); + + static QSharedPointer fromJson(const QJsonObject &json); + + QList tags() const; +}; + +class DFMRemoveTagsOfFileEvent : public DFMUrlBaseEvent +{ +public: + explicit DFMRemoveTagsOfFileEvent(const QObject *sender, const DUrl &url, const QList &tags); + + static QSharedPointer fromJson(const QJsonObject &json); + + QList tags() const; +}; + + +class DFMChangeTagColorEvent : public DFMEvent +{ +public: + explicit DFMChangeTagColorEvent(const QObject *sender, const QColor &color, const DUrl &tagUrl); + DFMChangeTagColorEvent(const DFMChangeTagColorEvent &other) = delete; + DFMChangeTagColorEvent &operator=(const DFMChangeTagColorEvent &other) = delete; + + static QSharedPointer fromJson(const QJsonObject &json); + + QColor m_newColorForTag{}; + DUrl m_tagUrl{}; +}; + + +class DFMGetTagsThroughFilesEvent final : public DFMUrlListBaseEvent +{ +public: + explicit DFMGetTagsThroughFilesEvent(const QObject *sender, const QList &files); + + static QSharedPointer fromJson(const QJsonObject &json); +}; + +class DFMSetFileExtraProperties : public DFMUrlBaseEvent +{ +public: + explicit DFMSetFileExtraProperties(const QObject *sender, const DUrl &url, const QVariantHash &ep); + + QVariantHash extraProperties() const; +}; + +#endif // FMEVENT_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmeventdispatcher.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmeventdispatcher.cpp new file mode 100644 index 0000000..b6f62e9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmeventdispatcher.cpp @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmeventdispatcher.h" +#include "dfmabstracteventhandler.h" + +#include +#include +#include +#include +#include + +DFM_BEGIN_NAMESPACE + +class DFMEventDispatcherPrivate +{ +public: + explicit DFMEventDispatcherPrivate(DFMEventDispatcher *qq) + : q_ptr(qq) + , state(DFMEventDispatcher::Normal) {} + + DFMEventDispatcher *q_ptr; + DFMEventDispatcher::State state; + + void setState(DFMEventDispatcher::State state); + + Q_DECLARE_PUBLIC(DFMEventDispatcher) +}; + +void DFMEventDispatcherPrivate::setState(DFMEventDispatcher::State state) +{ + Q_Q(DFMEventDispatcher); + + if (this->state == state) + return; + + this->state = state; + emit q->stateChanged(state); +} + +DFMEventFuture::DFMEventFuture(const QFuture &future) + : m_future(future) +{ + +} + +DFMEventFuture::DFMEventFuture(const DFMEventFuture &other) + : m_future(other.m_future) +{ + +} + +void DFMEventFuture::cancel() +{ + m_future.cancel(); +} + +bool DFMEventFuture::isCanceled() const +{ + return m_future.isCanceled(); +} + +bool DFMEventFuture::isStarted() const +{ + return m_future.isStarted(); +} + +bool DFMEventFuture::isFinished() const +{ + return m_future.isFinished(); +} + +bool DFMEventFuture::isRunning() const +{ + return m_future.isRunning(); +} + +void DFMEventFuture::waitForFinished() +{ + m_future.waitForFinished(); +} + +int DFMEventFuture::waitForFinishedWithEventLoop(QEventLoop::ProcessEventsFlags flags) const +{ + auto fun = [flags, this]() { + QEventLoop loop; + QFutureWatcher watcher; + + watcher.setFuture(m_future); + QObject::connect(&watcher, &QFutureWatcherBase::finished, &loop, &QEventLoop::quit); + + return loop.exec(flags); + }; + //Run in main thread + return DThreadUtil::runInMainThread(fun); +} + +QVariant DFMEventFuture::result() const +{ + return m_future.result(); +} + +void DFMEventFuture::operator =(const DFMEventFuture &other) +{ + m_future = other.m_future; +} + +namespace DFMEventDispatcherData { +static QList eventHandler; +static QList eventFilter; + +Q_GLOBAL_STATIC(QThreadPool, threadPool) +} + +class DFMEventDispatcher_ : public DFMEventDispatcher {}; +Q_GLOBAL_STATIC(DFMEventDispatcher_, fmedGlobal) + +DFMEventDispatcher *DFMEventDispatcher::instance() +{ + return fmedGlobal; +} + +DFMEventDispatcher::~DFMEventDispatcher() +{ + +} + +QVariant DFMEventDispatcher::processEvent(const QSharedPointer &event, DFMAbstractEventHandler *target) +{ + Q_D(DFMEventDispatcher); + + auto sender = event->sender(); + d->setState(Busy); + + QVariant result; + + for (DFMAbstractEventHandler *handler : DFMEventDispatcherData::eventFilter) { + if (!handler) + continue; + if (handler->fmEventFilter(event, target, &result)) + return result; + } + + if (target) { + target->fmEvent(event, &result); + } else { + for (DFMAbstractEventHandler *handler : DFMEventDispatcherData::eventHandler) { + if (handler->fmEvent(event, &result)) + return result; + } + } + + d->setState(Normal); + + return result; +} + +DFMEventFuture DFMEventDispatcher::processEventAsync(const QSharedPointer &event, DFMAbstractEventHandler *target) +{ + QThreadPool *pool = DFMEventDispatcherData::threadPool; + + if (pool->maxThreadCount() <= pool->activeThreadCount()) { + pool->setMaxThreadCount(pool->maxThreadCount() + 2); + } + + return DFMEventFuture(QtConcurrent::run(pool, this, static_cast&, DFMAbstractEventHandler *)>(&DFMEventDispatcher::processEvent), event, target)); +} + +QVariant DFMEventDispatcher::processEventWithEventLoop(const QSharedPointer &event, DFMAbstractEventHandler *target) +{ + const DFMEventFuture &future = processEventAsync(event, target); + + future.waitForFinishedWithEventLoop(); + + return future.result(); +} + +void DFMEventDispatcher::installEventFilter(DFMAbstractEventHandler *handler) +{ + if (!DFMEventDispatcherData::eventFilter.contains(handler)) { + DFMEventDispatcherData::eventFilter.append(handler); + } +} + +void DFMEventDispatcher::removeEventFilter(DFMAbstractEventHandler *handler) +{ + DFMEventDispatcherData::eventFilter.removeOne(handler); +} + +DFMEventDispatcher::State DFMEventDispatcher::state() const +{ + Q_D(const DFMEventDispatcher); + + return d->state; +} + +DFMEventDispatcher::DFMEventDispatcher() + : d_ptr(new DFMEventDispatcherPrivate(this)) +{ + +} + +void DFMEventDispatcher::installEventHandler(DFMAbstractEventHandler *handler) +{ + if (!DFMEventDispatcherData::eventHandler.contains(handler)) + DFMEventDispatcherData::eventHandler.append(handler); +} + +void DFMEventDispatcher::removeEventHandler(DFMAbstractEventHandler *handler) +{ + DFMEventDispatcherData::eventHandler.removeOne(handler); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmeventdispatcher.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmeventdispatcher.h new file mode 100644 index 0000000..faba1b9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmeventdispatcher.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMEVENTDISPATCHER_H +#define DFMEVENTDISPATCHER_H + +#include "dfmglobal.h" +#include "dfmevent.h" + +#include +#include + +class DFMEvent; +DFM_BEGIN_NAMESPACE + +class DFMEventFuture +{ +public: + explicit DFMEventFuture(const QFuture &future); + DFMEventFuture(const DFMEventFuture &other); + + void cancel(); + bool isCanceled() const; + + bool isStarted() const; + bool isFinished() const; + bool isRunning() const; + + void waitForFinished(); + int waitForFinishedWithEventLoop(QEventLoop::ProcessEventsFlags flags = QEventLoop::EventLoopExec) const; + + QVariant result() const; + template + inline T result() const + { return qvariant_cast(result());} + + void operator =(const DFMEventFuture &other); + +private: + QFuture m_future; +}; + +class DFMAbstractEventHandler; +class DFMEventDispatcherPrivate; +class DFMEventDispatcher : public QObject +{ + Q_OBJECT + + Q_PROPERTY(State state READ state NOTIFY stateChanged) + +public: + enum State { + Normal, + Busy + }; + + Q_ENUM(State) + + static DFMEventDispatcher *instance(); + ~DFMEventDispatcher(); + + QVariant processEvent(const QSharedPointer &event, DFMAbstractEventHandler *target = nullptr); + template + QVariant processEvent(Args&&... args) + { + return processEvent(dMakeEventPointer(std::forward(args)...)); + } + DFMEventFuture processEventAsync(const QSharedPointer &event, DFMAbstractEventHandler *target = nullptr); + template + DFMEventFuture processEventAsync(Args&&... args) + { + return processEventAsync(dMakeEventPointer(std::forward(args)...)); + } + QVariant processEventWithEventLoop(const QSharedPointer &event, DFMAbstractEventHandler *target = nullptr); + template + QVariant processEventWithEventLoop(Args&&... args) + { + return processEventWithEventLoop(dMakeEventPointer(std::forward(args)...)); + } + + void installEventFilter(DFMAbstractEventHandler *handler); + void removeEventFilter(DFMAbstractEventHandler *handler); + + State state() const; + +signals: + void stateChanged(State state); + +protected: + DFMEventDispatcher(); + +private: + QScopedPointer d_ptr; + + void installEventHandler(DFMAbstractEventHandler *handler); + void removeEventHandler(DFMAbstractEventHandler *handler); + + friend class DFMAbstractEventHandler; + + Q_DECLARE_PRIVATE(DFMEventDispatcher) +}; + +DFM_END_NAMESPACE + +#endif // DFMEVENTDISPATCHER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmfilepreview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmfilepreview.cpp new file mode 100644 index 0000000..df22d53 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmfilepreview.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dfmfilepreview.h" +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +DFMFilePreview::DFMFilePreview(QObject *parent) + : QObject(parent) +{ + +} + +void DFMFilePreview::initialize(QWidget *window, QWidget *statusBar) +{ + Q_UNUSED(window) + Q_UNUSED(statusBar) +} + +QWidget *DFMFilePreview::statusBarWidget() const +{ + return 0; +} + +Qt::Alignment DFMFilePreview::statusBarWidgetAlignment() const +{ + return Qt::AlignCenter; +} + +QString DFMFilePreview::title() const +{ + return QString(); +} + +bool DFMFilePreview::showStatusBarSeparator() const +{ + return false; +} + +void DFMFilePreview::DoneCurrent() +{ + +} + +void DFMFilePreview::play() +{ + +} + +void DFMFilePreview::pause() +{ + +} + +void DFMFilePreview::stop() +{ + +} + +void DFMFilePreview::copyFile() const +{ + DFMGlobal::setUrlsToClipboard({fileUrl()}, DFMGlobal::CopyAction); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmfilepreview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmfilepreview.h new file mode 100644 index 0000000..2259c5d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmfilepreview.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMFILEPREVIEWDIALOG_H +#define DFMFILEPREVIEWDIALOG_H + +#include + +#include "dfmglobal.h" + +class DUrl; + +DFM_BEGIN_NAMESPACE + +class DFMFilePreview : public QObject +{ + Q_OBJECT +public: + explicit DFMFilePreview(QObject *parent = 0); + + virtual void initialize(QWidget *window, QWidget *statusBar); + virtual bool setFileUrl(const DUrl &url) = 0; + virtual DUrl fileUrl() const = 0; + + virtual QWidget *contentWidget() const = 0; + virtual QWidget *statusBarWidget() const; + virtual Qt::Alignment statusBarWidgetAlignment() const; + + virtual QString title() const; + virtual bool showStatusBarSeparator() const; + + /** + * @brief DoneCurrent 释放surface + */ + virtual void DoneCurrent(); + + virtual void play(); /*play media if file is music or video*/ + virtual void pause(); /*pause playing if file is music or video*/ + virtual void stop(); /*stop playing if file is music or video*/ + + virtual void copyFile() const; + +signals: + void titleChanged(); +}; + +DFM_END_NAMESPACE + +#endif // DFMFILEPREVIEWDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmglobal.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmglobal.cpp new file mode 100644 index 0000000..7cef98f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmglobal.cpp @@ -0,0 +1,1579 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmglobal.h" +#include "chinese2pinyin.h" +#include "dfmstandardpaths.h" +#include "dfileservices.h" +#include "dthumbnailprovider.h" +#include "singleton.h" +#include "dfileiconprovider.h" +#include "dialogs/dialogmanager.h" +#include "app/define.h" +#include "plugins/pluginmanager.h" +#include "app/filesignalmanager.h" +#include "shutil/mimesappsmanager.h" +#include "controllers/searchhistroymanager.h" +#include "controllers/bookmarkmanager.h" +#include "interfaces/dfilemenumanager.h" +#include "controllers/pathmanager.h" +#include "gvfs/gvfsmountmanager.h" +#include "gvfs/networkmanager.h" +#include "gvfs/secretmanager.h" +#include "controllers/appcontroller.h" +#include "../deviceinfo/udisklistener.h" +#include "../usershare/usersharemanager.h" +#include "models/desktopfileinfo.h" +#include "controllers/operatorrevocation.h" +#include "tag/tagmanager.h" +#include "shutil/mimetypedisplaymanager.h" +#include "dabstractfilewatcher.h" +#include +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "bluetooth/bluetoothmanager.h" +#include "drootfilemanager.h" +#include "plugins/schemepluginmanager.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +DWIDGET_USE_NAMESPACE; + +#ifdef __cplusplus +extern "C" +{ +#endif //__cplusplus + +#include + +#ifdef __cplusplus +} +#endif //__cplusplus + +namespace GlobalData { +static QList clipboardFileUrls; +static QMutex clipboardFileUrlsMutex; +static QList clipbordFileinode; +static QAtomicInt remoteCurrentCount = 0; +static DFMGlobal::ClipboardAction clipboardAction = DFMGlobal::UnknowAction; + +void onClipboardDataChanged() +{ + { + QMutexLocker lk(&clipboardFileUrlsMutex); + clipboardFileUrls.clear(); + } + clipbordFileinode.clear(); + const QMimeData *mimeData = qApp->clipboard()->mimeData(); + if (!mimeData || mimeData->formats().isEmpty()) { + qWarning() << "get null mimeData from QClipBoard or remote formats is null!"; + return; + } + if (mimeData->hasFormat("uos/remote-copy")) { + qInfo() << "clipboard use other !"; + clipboardAction = DFMGlobal::RemoteAction; + remoteCurrentCount++; + return; + } + const QByteArray &data = mimeData->data("x-special/gnome-copied-files"); + + if (data.startsWith("cut")) { + clipboardAction = DFMGlobal::CutAction; + } else if (data.startsWith("copy")) { + clipboardAction = DFMGlobal::CopyAction; + } else { + clipboardAction = DFMGlobal::UnknowAction; + } + + for (QUrl &_url : mimeData->urls()) { + if (_url.scheme().isEmpty()) + _url.setScheme("file"); + { + QMutexLocker lk(&clipboardFileUrlsMutex); + clipboardFileUrls << _url; + } + //链接文件的inode不加入clipbordFileinode,只用url判断clip,避免多个同源链接文件的逻辑误判 + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(nullptr, DUrl(_url)); + if (!fileInfo || fileInfo->isSymLink()) + continue; + + struct stat statInfo; + int fileStat = stat(_url.path().toStdString().c_str(), &statInfo); + if (0 == fileStat) + clipbordFileinode << statInfo.st_ino; + } +} + +class DFMGlobalPrivate : public DFMGlobal {}; +Q_GLOBAL_STATIC(DFMGlobalPrivate, dfmGlobal) +} + +QStringList DFMGlobal::PluginLibraryPaths; +bool DFMGlobal::IsFileManagerDiloagProcess = false; +QAtomicInteger DFMGlobal::IsInitAppOver = false; +QAtomicInteger DFMGlobal::IsAppQuiting = false; + +DFMGlobal *DFMGlobal::instance() +{ + return GlobalData::dfmGlobal; +} + +QString DFMGlobal::organizationName() +{ + return QMAKE_ORGANIZATION_NAME; +} + +QString DFMGlobal::applicationName() +{ + return QMAKE_TARGET; +} + +QString DFMGlobal::applicationVersion() +{ + return QMAKE_VERSION; +} + +bool DFMGlobal::installTranslator() +{ + QTranslator *translator = new QTranslator(QGuiApplication::instance()); + QTranslator *translatorMusic = new QTranslator(QGuiApplication::instance()); + + QString transLatorPath = DFMStandardPaths::location(DFMStandardPaths::TranslationPath) + + QDir::separator() + DFMGlobal::applicationName() + "_" + QLocale::system().name(); + + QString transLatorPathMusic = DFMStandardPaths::location(DFMStandardPaths::TranslationPath) + + QDir::separator() + "dde-file-manager-plugins" + "_" + QLocale::system().name(); + qDebug() << "transLatorPath1" << transLatorPathMusic; + + translatorMusic->load(transLatorPathMusic); + qApp->installTranslator(translatorMusic); + + if (translator->load(transLatorPath)) { + return qApp->installTranslator(translator); + } + + return false; +} + +void DFMGlobal::setUrlsToClipboard(const QList &list, DFMGlobal::ClipboardAction action, QMimeData *mimeData) +{ + if (action == UnknowAction) + return; + + if (!mimeData) + mimeData = new QMimeData; + + QByteArray ba = (action == DFMGlobal::CutAction) ? "cut" : "copy"; + QString text; + QByteArray iconBa; + QDataStream stream(&iconBa, QIODevice::WriteOnly); + + int maxIconsNum = 3; + for (const QUrl &qurl : list) { + ba.append("\n"); + ba.append(qurl.toString()); + + const QString &path = qurl.toLocalFile(); + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(nullptr, DUrl(qurl)); + + if (!info) + continue; + if (maxIconsNum-- > 0) { + QStringList iconList; + if (info->isSymLink()) { + iconList << "emblem-symbolic-link"; + } + if (!info->isWritable()) { + iconList << "emblem-readonly"; + } + if (!info->isReadable()) { + iconList << "emblem-unreadable"; + } + + // 多文件时只显示文件图标, 一个文件时显示缩略图(如果有的话) + DFileInfo *fi = dynamic_cast(info.data()); + QIcon icon = fi ? DFileIconProvider::globalProvider()->icon(*fi) : + DFileIconProvider::globalProvider()->icon(info->toQFileInfo()); + DAbstractFileInfo::FileType fileType = mimeTypeDisplayManager->displayNameToEnum(info->mimeTypeName()); + if (list.size() == 1 && fileType == DAbstractFileInfo::FileType::Images) { + QIcon thumb(DThumbnailProvider::instance()->thumbnailFilePath(info->toQFileInfo(), DThumbnailProvider::Large)); + if (thumb.isNull()) { + //qWarning() << "thumbnail file faild " << fileInfo->absoluteFilePath(); + } else { + icon = thumb; + } + } + stream << iconList << icon; + } + + if (!path.isEmpty()) { + text += path + '\n'; + } + } + + mimeData->setText(text.endsWith('\n') ? text.left(text.length() - 1) : text); + mimeData->setData("x-special/gnome-copied-files", ba); + mimeData->setData("x-dfm-copied/file-icons", iconBa); + mimeData->setUrls(list); + // fix bug 63441 + // 如果是剪切操作,则禁止跨用户的粘贴操作 + if (DFMGlobal::CutAction == action) { + QByteArray userId; + userId.append(QString::number(getUserId())); + mimeData->setData("userId", userId); + } + + qApp->clipboard()->setMimeData(mimeData); +} + +const QList DFMGlobal::fetchUrlsFromClipboard() +{ + if (qApp->clipboard()) { + const QMimeData *mimeData = qApp->clipboard()->mimeData(); + if (mimeData) { + return mimeData->urls(); + } + } + + return QList(); +} + +DFMGlobal::ClipboardAction DFMGlobal::fetchClipboardAction() +{ + if (qApp->clipboard()) { + const QMimeData *mimeData = qApp->clipboard()->mimeData(); + if (mimeData) { + QByteArray ba = mimeData->data("x-special/gnome-copied-files"); + QString tStr(ba); + if (tStr.startsWith("cut")) { + return DFMGlobal::CutAction; + } + if (tStr.startsWith("copy")) { + return DFMGlobal::CopyAction; + } + } + } + + return DFMGlobal::UnknowAction; +} + +void DFMGlobal::clearClipboard() +{ + qApp->clipboard()->setText(QString()); +} + +void DFMGlobal::clearTrash() +{ + appController->actionClearTrash(); +} + +void DFMGlobal::addPluginLibraryPath(const QString &path) +{ + PluginLibraryPaths.append(path); + refreshPlugins(); +} + +void DFMGlobal::addPluginLibraryPaths(const QStringList &paths) +{ + foreach (QString path, paths) { + PluginLibraryPaths.append(path); + } + refreshPlugins(); +} + +void DFMGlobal::autoLoadDefaultPlugins() +{ + addPluginLibraryPath(PluginManager::PluginDir()); +} + +void DFMGlobal::initPluginManager() +{ + refreshPlugins(); +} + +//NOTE [XIAO] DFMGlobal::initSchemePluginManager +void DFMGlobal::initSchemePluginManager() +{ + SchemePluginManager::instance()->loadSchemePlugin(); +} + +void DFMGlobal::initSearchHistoryManager() +{ + searchHistoryManager; +} + +void DFMGlobal::initBookmarkManager() +{ + bookmarkManager; +} + +void DFMGlobal::initFileMenuManager() +{ + fileMenuManger; +} + +void DFMGlobal::initFileSiganlManager() +{ + fileSignalManager; +} + +void DFMGlobal::initMimesAppsManager() +{ + QTimer::singleShot(100, mimeAppsManager, &MimesAppsManager::requestUpdateCache); +} + +void DFMGlobal::initSystemPathManager() +{ + systemPathManager; +} + +void DFMGlobal::initMimeTypeDisplayManager() +{ + mimeAppsManager; +} + +void DFMGlobal::initNetworkManager() +{ + networkManager; +} + +void DFMGlobal::initGvfsMountManager() +{ + QtConcurrent::run(QThreadPool::globalInstance(), gvfsMountManager, + &GvfsMountManager::startMonitor); +} + +void DFMGlobal::initSecretManager() +{ + secretManager; +} + +void DFMGlobal::initDialogManager() +{ + dialogManager; +} + +void DFMGlobal::initFileService() +{ + fileService; +} + +void DFMGlobal::initAppcontroller() +{ + appController; +} + +void DFMGlobal::initDeviceListener() +{ + deviceListener; +} + +void DFMGlobal::initUserShareManager() +{ + userShareManager; +} + +void DFMGlobal::initOperatorRevocation() +{ + Q_UNUSED(OperatorRevocation::instance()) +} + +void DFMGlobal::initTagManagerConnect() +{ + connect(TagManager::instance(), static_cast&)>(&TagManager::changeTagColor), + [](const QMap &tag_and_new_color) { + for (auto i = tag_and_new_color.constBegin(); i != tag_and_new_color.constEnd(); ++i) { + const QString &tag_name = i.key(); + const QStringList &files = TagManager::instance()->getFilesThroughTag(tag_name); + + for (const QString &file : files) { + DUrl durl = DUrl::fromLocalFile(file); + DAbstractFileWatcher::ghostSignal(durl.parentUrl(), &DAbstractFileWatcher::fileAttributeChanged, durl); + } + + // for tag watcher + const DUrl &file_url = DUrl::fromUserTaggedFile(tag_name, QString()); + + DAbstractFileWatcher::ghostSignal(DUrl(TAG_ROOT), &DAbstractFileWatcher::fileAttributeChanged, file_url); + } + }); + connect(TagManager::instance(), &TagManager::filesWereTagged, [](const QMap> &files_were_tagged) { + for (auto i = files_were_tagged.constBegin(); i != files_were_tagged.constEnd(); ++i) { + // is trash files + if (i.key().startsWith(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))) + return; + + DUrl durl = DUrl::fromLocalFile(i.key()); + //主目录文件被标记同时要通知数据盘的home目录 + if (durl.path().startsWith("/home")) { + DUrl dataUrl(durl); + dataUrl.setPath("/data" + durl.path()); + DAbstractFileWatcher::ghostSignal(dataUrl.parentUrl(), &DAbstractFileWatcher::fileAttributeChanged, dataUrl); + } + DAbstractFileWatcher::ghostSignal(durl.parentUrl(), &DAbstractFileWatcher::fileAttributeChanged, durl); + + // for tag watcher + for (const QString &tag : i.value()) { + const DUrl &parent_url = DUrl::fromUserTaggedFile(tag, QString()); + const DUrl &file_url = DUrl::fromUserTaggedFile(tag, i.key()); + + DAbstractFileWatcher::ghostSignal(parent_url, &DAbstractFileWatcher::subfileCreated, file_url); + } + } + }); + connect(TagManager::instance(), &TagManager::untagFiles, [](const QMap> &tag_be_removed_files) { + for (auto i = tag_be_removed_files.constBegin(); i != tag_be_removed_files.constEnd(); ++i) { + DUrl durl = DUrl::fromLocalFile(i.key()); + //主目录文件被取消标记同时要通知数据盘的home目录 + if (durl.path().startsWith("/home")) { + DUrl dataUrl(durl); + dataUrl.setPath("/data" + durl.path()); + DAbstractFileWatcher::ghostSignal(dataUrl.parentUrl(), &DAbstractFileWatcher::fileAttributeChanged, dataUrl); + } + + DAbstractFileWatcher::ghostSignal(durl.parentUrl(), &DAbstractFileWatcher::fileAttributeChanged, durl); + + // for tag watcher + for (const QString &tag : i.value()) { + const DUrl &parent_url = DUrl::fromUserTaggedFile(tag, QString()); + const DUrl &file_url = DUrl::fromUserTaggedFile(tag, i.key()); + + DAbstractFileWatcher::ghostSignal(parent_url, &DAbstractFileWatcher::fileDeleted, file_url); + } + } + }); + + // for tag watcher + connect(TagManager::instance(), &TagManager::addNewTag, [](const QList &new_tags) { + for (const QString &tag : new_tags) { + DAbstractFileWatcher::ghostSignal(DUrl(TAG_ROOT), &DAbstractFileWatcher::subfileCreated, DUrl::fromUserTaggedFile(tag, QString())); + } + }); + connect(TagManager::instance(), &TagManager::deleteTag, [](const QList &new_tags) { + for (const QString &tag : new_tags) { + DAbstractFileWatcher::ghostSignal(DUrl(TAG_ROOT), &DAbstractFileWatcher::fileDeleted, DUrl::fromUserTaggedFile(tag, QString())); + } + }); + connect(TagManager::instance(), static_cast&)>(&TagManager::changeTagName), + [](const QMap &old_and_new_name) { + for (auto i = old_and_new_name.constBegin(); i != old_and_new_name.constEnd(); ++i) { + const DUrl &old_url = DUrl::fromUserTaggedFile(i.key(), QString()); + const DUrl &new_url = DUrl::fromUserTaggedFile(i.value(), QString()); + + DAbstractFileWatcher::ghostSignal(DUrl(TAG_ROOT), &DAbstractFileWatcher::fileMoved, old_url, new_url); + } + }); +} + +void DFMGlobal::initThumbnailConnection() +{ + connect(DThumbnailProvider::instance(), &DThumbnailProvider::createThumbnailFinished, [ = ](const QString & filePath) { + const DUrl &durl = DUrl::fromLocalFile(filePath); + + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(nullptr, durl); + + if (!info) + return; + + DAbstractFileWatcher::ghostSignal(info->parentUrl(), &DAbstractFileWatcher::fileAttributeChanged, durl); + }); +} + +void DFMGlobal::initBluetoothManager() +{ + bluetoothManager; +} + +void DFMGlobal::initRootFileManager() +{ + rootFileManager; +} + +QString DFMGlobal::getUser() +{ + static QString user = QString::fromLocal8Bit(qgetenv("USER")); + + return user; +} + +int DFMGlobal::getUserId() +{ + return static_cast(getuid()); +} + +bool DFMGlobal::isRootUser() +{ + return getUserId() == 0; +} + +bool DFMGlobal::isServerSys() +{ + return DSysInfo::deepinType() == DSysInfo::DeepinServer; +} + +bool DFMGlobal::isDesktopSys() +{ + return !(DFMGlobal::isServerSys()); +} + +bool DFMGlobal::isOpenAsAdmin() +{ + return DFMGlobal::isRootUser() && DFMGlobal::isDesktopSys(); +} + +bool DFMGlobal::isDeveloperMode() +{ + // 为了性能,开发者模式仅需获取一次,不必每次请求 dbus,因此此处使用静态变量 + static bool hasAcquireDevMode = false; + static bool developerModel = false; + + if (Q_UNLIKELY(!hasAcquireDevMode)) { + hasAcquireDevMode = true; + QString service("com.deepin.sync.Helper"); + QString path("/com/deepin/sync/Helper"); + QString interfaceName("com.deepin.sync.Helper"); + + QDBusInterface interface(service, path, interfaceName, QDBusConnection::systemBus()); + + QString func("IsDeveloperMode"); + QDBusReply reply = interface.call(func); + developerModel = reply.value(); + } + + return developerModel; +} + +bool DFMGlobal::isProfessional() +{ + return DSysInfo::deepinType() == DSysInfo::DeepinProfessional; +} + +QList DFMGlobal::clipboardFileUrlList() const +{ + return GlobalData::clipboardFileUrls; +} + +QList DFMGlobal::clipboardFileInodeList() const +{ + return GlobalData::clipbordFileinode; +} + +DFMGlobal::ClipboardAction DFMGlobal::clipboardAction() const +{ + return GlobalData::clipboardAction; +} + +QIcon DFMGlobal::standardIcon(DFMGlobal::Icon iconType) const +{ + static QIcon linkIcon(QIcon::fromTheme("emblem-symbolic-link")); + static QIcon lockIcon(QIcon::fromTheme("emblem-locked")); + static QIcon unreadableIcon(QIcon::fromTheme("emblem-unreadable")); + static QIcon shareIcon(QIcon::fromTheme("emblem-shared")); + + switch (iconType) { + case LinkIcon: + return linkIcon; + case LockIcon: + return lockIcon; + case UnreadableIcon: + return unreadableIcon; + case ShareIcon: + return shareIcon; + } + + return QIcon(); +} + +QString DFMGlobal::wordWrapText(const QString &text, qreal width, QTextOption::WrapMode wrapMode, + const QFont &font, qreal lineHeight, qreal *height) +{ + QTextLayout layout(text); + + layout.setFont(font); + + QStringList lines; + + wordWrapText(&layout, width, wrapMode, lineHeight, &lines); + + if (height) + *height = lines.count() * lineHeight; + + return lines.join('\n'); +} + +DFMGlobal::DFMGlobal() +{ + connect(qApp->clipboard(), &QClipboard::dataChanged, this, &DFMGlobal::onClipboardDataChanged); + GlobalData::onClipboardDataChanged(); +} + +void DFMGlobal::onClipboardDataChanged() +{ + GlobalData::onClipboardDataChanged(); + + emit clipboardDataChanged(); +} + +void DFMGlobal::refreshPlugins() +{ + PluginManager::instance()->loadPlugin(); +} + +void DFMGlobal::wordWrapText(QTextLayout *layout, qreal width, QTextOption::WrapMode wrapMode, + qreal lineHeight, QStringList *lines) +{ + elideText(layout, QSize(static_cast(width), INT_MAX), wrapMode, Qt::ElideNone, lineHeight, 0, lines); +} + +void DFMGlobal::elideText(QTextLayout *layout, const QSizeF &size, QTextOption::WrapMode wordWrap, + Qt::TextElideMode mode, qreal lineHeight, int flags, QStringList *lines, + QPainter *painter, QPointF offset, const QColor &shadowColor, const QPointF &shadowOffset, + const QBrush &background, qreal backgroundRadius, QList *boundingRegion) +{ + qreal height = 0; + bool drawBackground = background.style() != Qt::NoBrush; + bool drawShadow = shadowColor.isValid(); + + QString text = layout->engine()->hasFormats() ? layout->engine()->block.text() : layout->text(); + QTextOption &text_option = *const_cast(&layout->textOption()); + + text_option.setWrapMode(wordWrap); + + if (flags & Qt::AlignRight) + text_option.setAlignment(Qt::AlignRight); + else if (flags & Qt::AlignHCenter) + text_option.setAlignment(Qt::AlignHCenter); + + if (painter) { + text_option.setTextDirection(painter->layoutDirection()); + layout->setFont(painter->font()); + } else { + // dont paint + layout->engine()->ignoreBidi = true; + } + + auto naturalTextRect = [&](const QRectF rect) { + QRectF new_rect = rect; + + new_rect.setHeight(lineHeight); + + return new_rect; + }; + + auto drawShadowFun = [&](const QTextLine & line) { + const QPen pen = painter->pen(); + + painter->setPen(shadowColor); + line.draw(painter, shadowOffset); + + // restore + painter->setPen(pen); + }; + + layout->beginLayout(); + + QTextLine line = layout->createLine(); + QRectF lastLineRect; + + while (line.isValid()) { + height += lineHeight; + if (height + lineHeight > size.height()) { + const QString &end_str = layout->engine()->elidedText(mode, qRound(size.width()), flags, line.textStart()); + + layout->endLayout(); + layout->setText(end_str); + + if (layout->engine()->block.docHandle()) { + const_cast(layout->engine()->block.document())->setPlainText(end_str); + } + + text_option.setWrapMode(QTextOption::NoWrap); + layout->beginLayout(); + line = layout->createLine(); + line.setLineWidth(size.width() - 1); + text = end_str; + } else { + line.setLineWidth(size.width()); + } + + line.setPosition(offset); + + const QRectF rect = naturalTextRect(line.naturalTextRect()); + + if (painter) { + if (drawBackground) { + const QMarginsF margins(backgroundRadius, 0, backgroundRadius, 0); + QRectF backBounding = rect; + QPainterPath path; + + if (lastLineRect.isValid()) { + if (qAbs(rect.width() - lastLineRect.width()) < backgroundRadius * 2) { + backBounding.setWidth(lastLineRect.width()); + backBounding.moveCenter(rect.center()); + path.moveTo(lastLineRect.x() - backgroundRadius, lastLineRect.bottom() - backgroundRadius); + path.lineTo(lastLineRect.x(), lastLineRect.bottom() - 1); + path.lineTo(lastLineRect.right(), lastLineRect.bottom() - 1); + path.lineTo(lastLineRect.right() + backgroundRadius, lastLineRect.bottom() - backgroundRadius); + path.lineTo(lastLineRect.right() + backgroundRadius, backBounding.bottom() - backgroundRadius); + path.arcTo(backBounding.right() - backgroundRadius, backBounding.bottom() - backgroundRadius * 2, backgroundRadius * 2, backgroundRadius * 2, 0, -90); + path.lineTo(backBounding.x(), backBounding.bottom()); + path.arcTo(backBounding.x() - backgroundRadius, backBounding.bottom() - backgroundRadius * 2, backgroundRadius * 2, backgroundRadius * 2, 270, -90); + lastLineRect = backBounding; + } else if (lastLineRect.width() > rect.width()) { + backBounding += margins; + path.moveTo(backBounding.x() - backgroundRadius, backBounding.y() - 1); + path.arcTo(backBounding.x() - backgroundRadius * 2, backBounding.y() - 1, backgroundRadius * 2, backgroundRadius * 2 + 1, 90, -90); + path.lineTo(backBounding.x(), backBounding.bottom() - backgroundRadius); + path.arcTo(backBounding.x(), backBounding.bottom() - backgroundRadius * 2, backgroundRadius * 2, backgroundRadius * 2, 180, 90); + path.lineTo(backBounding.right() - backgroundRadius, backBounding.bottom()); + path.arcTo(backBounding.right() - backgroundRadius * 2, backBounding.bottom() - backgroundRadius * 2, backgroundRadius * 2, backgroundRadius * 2, 270, 90); + path.lineTo(backBounding.right(), backBounding.top() + backgroundRadius); + path.arcTo(backBounding.right(), backBounding.top() - 1, backgroundRadius * 2, backgroundRadius * 2 + 1, 180, -90); + path.closeSubpath(); + lastLineRect = rect; + } else { + backBounding += margins; + path.moveTo(lastLineRect.x() - backgroundRadius * 2, lastLineRect.bottom()); + path.arcTo(lastLineRect.x() - backgroundRadius * 3, lastLineRect.bottom() - backgroundRadius * 2, backgroundRadius * 2, backgroundRadius * 2, 270, 90); + path.lineTo(lastLineRect.x(), lastLineRect.bottom() - 1); + path.lineTo(lastLineRect.right(), lastLineRect.bottom() - 1); + path.lineTo(lastLineRect.right() + backgroundRadius, lastLineRect.bottom() - backgroundRadius * 2); + path.arcTo(lastLineRect.right() + backgroundRadius, lastLineRect.bottom() - backgroundRadius * 2, backgroundRadius * 2, backgroundRadius * 2, 180, 90); + +// path.arcTo(lastLineRect.x() - backgroundReaius, lastLineRect.bottom() - backgroundReaius * 2, backgroundReaius * 2, backgroundReaius * 2, 180, 90); +// path.lineTo(lastLineRect.x() - backgroundReaius * 3, lastLineRect.bottom()); +// path.moveTo(lastLineRect.right(), lastLineRect.bottom()); +// path.arcTo(lastLineRect.right() - backgroundReaius, lastLineRect.bottom() - backgroundReaius * 2, backgroundReaius * 2, backgroundReaius * 2, 270, 90); +// path.arcTo(lastLineRect.right() + backgroundReaius, lastLineRect.bottom() - backgroundReaius * 2, backgroundReaius * 2, backgroundReaius * 2, 180, 90); +// path.lineTo(lastLineRect.right(), lastLineRect.bottom()); + + path.addRoundedRect(backBounding, backgroundRadius, backgroundRadius); + lastLineRect = rect; + } + } else { + lastLineRect = backBounding; + path.addRoundedRect(backBounding + margins, backgroundRadius, backgroundRadius); + } + + bool a = painter->testRenderHint(QPainter::Antialiasing); + qreal o = painter->opacity(); + + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setOpacity(1); + painter->fillPath(path, background); + painter->setRenderHint(QPainter::Antialiasing, a); + painter->setOpacity(o); + } + + if (drawShadow) { + drawShadowFun(line); + } + + line.draw(painter, QPointF(0, 0)); + } + + if (boundingRegion) { + boundingRegion->append(rect); + } + + offset.setY(offset.y() + lineHeight); + +// // find '\n' +// int text_length_line = line.textLength(); +// for (int start = line.textStart(); start < line.textStart() + text_length_line; ++start) { +// if (text.at(start) == '\n') +// height += lineHeight; +// } + + if (lines) { + lines->append(text.mid(line.textStart(), line.textLength())); + } + + if (height + lineHeight > size.height()) + break; + + line = layout->createLine(); + } + + layout->endLayout(); +} + +void DFMGlobal::setToolTip(QLabel *label, bool bAlwaysShow) +{ + if (!label) + return; + + QString fullText = label->text(); + + QString elideText = label->fontMetrics().elidedText(fullText, Qt::ElideMiddle, label->width()); + label->setText(elideText); + + if (bAlwaysShow || fullText != elideText) + label->setToolTip(fullText); +} + +void DFMGlobal::showAlertMessage(QPoint globalPoint, const QColor &backgroundColor, const QString &text, int duration) +{ + static DArrowRectangle* tooltip = nullptr; + if (!tooltip) { + tooltip = new DArrowRectangle(DArrowRectangle::ArrowTop, nullptr); + tooltip->setObjectName("AlertTooltip"); + QLabel *label = new QLabel(tooltip); + label->setWordWrap(true); + label->setMaximumWidth(500); + tooltip->setContent(label); + tooltip->setBackgroundColor(backgroundColor); + tooltip->setArrowX(15); + tooltip->setArrowHeight(5); + + QTimer::singleShot(duration, DFMGlobal::instance(), [=] { + delete tooltip; + tooltip = nullptr; + }); + + label->setText(text); + label->adjustSize(); + + tooltip->show(static_cast(globalPoint.x()),static_cast(globalPoint.y())); + } +} + +QString DFMGlobal::elideText(const QString &text, const QSizeF &size, + QTextOption::WrapMode wordWrap, const QFont &font, + Qt::TextElideMode mode, qreal lineHeight, qreal flags) +{ + QTextLayout textLayout(text); + + textLayout.setFont(font); + + QStringList lines; + + elideText(&textLayout, size, wordWrap, mode, lineHeight, static_cast(flags), &lines); + + return lines.join('\n'); +} + +QString DFMGlobal::toPinyin(const QString &text) +{ + return Pinyin::Chinese2Pinyin(text); +} + +bool DFMGlobal::startWithHanzi(const QString &text) +{ + if (text.isEmpty()) + return false; + + return text.at(0).script() == QChar::Script_Han; +} + +bool DFMGlobal::startWithSymbol(const QString &text) +{ + if (text.isEmpty()) + return false; + + //匹配字母、数字和中文开头的字符串 + QRegExp regExp("^[a-zA-Z0-9\u4e00-\u9fa5].*$"); + return !regExp.exactMatch(text); +} + +#if 0 +static QString textDecoder(const QByteArray &ba, const QByteArray &codecName) +{ + QTextDecoder decoder(QTextCodec::codecForName(codecName)); + + const QString &text = decoder.toUnicode(ba); + + return decoder.hasFailure() ? QString() : text; +} +#endif + +///###: forward-declare. +static float codecConfidenceForData(const QTextCodec *codec, const QByteArray &data, const QLocale::Country &country); + +QByteArray DFMGlobal::detectCharset(const QByteArray &data, const QString &fileName) +{ + // Return local encoding if nothing in file. + if (data.isEmpty()) { + return QTextCodec::codecForLocale()->name(); + } + + if (QTextCodec *c = QTextCodec::codecForUtfText(data, nullptr)) { + return c->name(); + } + + QMimeDatabase mime_database; + const QMimeType &mime_type = fileName.isEmpty() ? mime_database.mimeTypeForData(data) : mime_database.mimeTypeForFileNameAndData(fileName, data); + const QString &mimetype_name = mime_type.name(); + KEncodingProber::ProberType proberType = KEncodingProber::Universal; + + if (mimetype_name == QStringLiteral("application/xml") + || mimetype_name == QStringLiteral("text/html") + || mimetype_name == QStringLiteral("application/xhtml+xml")) { + const QString &_data = QString::fromLatin1(data); + QRegularExpression pattern("<\\bmeta.+\\bcharset=(?'charset'\\S+?)\\s*['\"/>]"); + + pattern.setPatternOptions(QRegularExpression::DontCaptureOption | QRegularExpression::CaseInsensitiveOption); + const QString &charset = pattern.match(_data, 0, QRegularExpression::PartialPreferFirstMatch, + QRegularExpression::DontCheckSubjectStringMatchOption).captured("charset"); + + if (!charset.isEmpty()) { + return charset.toLatin1(); + } + + pattern.setPattern("<\\bmeta\\s+http-equiv=\"Content-Language\"\\s+content=\"(?'language'[a-zA-Z-]+)\""); + + const QString &language = pattern.match(_data, 0, QRegularExpression::PartialPreferFirstMatch, + QRegularExpression::DontCheckSubjectStringMatchOption).captured("language"); + + if (!language.isEmpty()) { + QLocale l(language); + + switch (l.script()) { + case QLocale::ArabicScript: + proberType = KEncodingProber::Arabic; + break; + case QLocale::SimplifiedChineseScript: + proberType = KEncodingProber::ChineseSimplified; + break; + case QLocale::TraditionalChineseScript: + proberType = KEncodingProber::ChineseTraditional; + break; + case QLocale::CyrillicScript: + proberType = KEncodingProber::Cyrillic; + break; + case QLocale::GreekScript: + proberType = KEncodingProber::Greek; + break; + case QLocale::HebrewScript: + proberType = KEncodingProber::Hebrew; + break; + case QLocale::JapaneseScript: + proberType = KEncodingProber::Japanese; + break; + case QLocale::KoreanScript: + proberType = KEncodingProber::Korean; + break; + case QLocale::ThaiScript: + proberType = KEncodingProber::Thai; + break; + default: + break; + } + } + } else if (mimetype_name == "text/x-python") { + QRegularExpression pattern("^#coding\\s*:\\s*(?'coding'\\S+)$"); + QTextStream stream(data); + + pattern.setPatternOptions(QRegularExpression::DontCaptureOption | QRegularExpression::CaseInsensitiveOption); + stream.setCodec("latin1"); + + while (!stream.atEnd()) { + const QString &_data = stream.readLine(); + const QString &coding = pattern.match(_data, 0).captured("coding"); + + if (!coding.isEmpty()) { + return coding.toLatin1(); + } + } + } + + // for CJK + const QList> fallback_list { + {KEncodingProber::ChineseSimplified, QLocale::China}, + {KEncodingProber::ChineseTraditional, QLocale::China}, + {KEncodingProber::Japanese, QLocale::Japan}, + {KEncodingProber::Korean, QLocale::NorthKorea}, + {KEncodingProber::Cyrillic, QLocale::Russia}, + {KEncodingProber::Greek, QLocale::Greece}, + {proberType, QLocale::system().country()} + }; + + KEncodingProber prober(proberType); + prober.feed(data); + float pre_confidence = prober.confidence(); + QByteArray pre_encoding = prober.encoding(); + + QTextCodec *def_codec = QTextCodec::codecForLocale(); + QByteArray encoding; + float confidence = 0; + + for (auto i : fallback_list) { + prober.setProberType(i.first); + prober.feed(data); + + float prober_confidence = prober.confidence(); + QByteArray prober_encoding = prober.encoding(); + + if (i.first != proberType && qFuzzyIsNull(prober_confidence)) { + prober_confidence = pre_confidence; + prober_encoding = pre_encoding; + } + + confidence: + if (QTextCodec *codec = QTextCodec::codecForName(prober_encoding)) { + if (def_codec == codec) + def_codec = nullptr; + + float c = codecConfidenceForData(codec, data, i.second); + + if (prober_confidence > 0.5) { + c = c / 2 + prober_confidence / 2; + } else { + c = c / 3 * 2 + prober_confidence / 3; + } + + if (c > confidence) { + confidence = c; + encoding = prober_encoding; + } + + if (i.first == KEncodingProber::ChineseTraditional && c < 0.5) { + // test Big5 + c = codecConfidenceForData(QTextCodec::codecForName("Big5"), data, i.second); + + if (c > 0.5 && c > confidence) { + confidence = c; + encoding = "Big5"; + } + } + } + + if (i.first != proberType) { + // 使用 proberType 类型探测出的结果结合此国家再次做编码检查 + i.first = proberType; + prober_confidence = pre_confidence; + prober_encoding = pre_encoding; + goto confidence; + } + } + + if (def_codec && codecConfidenceForData(def_codec, data, QLocale::system().country()) > confidence) { + return def_codec->name(); + } + + return encoding; +} + +bool DFMGlobal::keyShiftIsPressed() +{ + return qApp->keyboardModifiers() == Qt::ShiftModifier; +} + +bool DFMGlobal::keyCtrlIsPressed() +{ + return qApp->keyboardModifiers() == Qt::ControlModifier; +} + +bool DFMGlobal::fileNameCorrection(const QString &filePath) +{ + QFileInfo info(filePath); + QProcess ls; + + ls.start("ls", QStringList() << "-1" << "--color=never" << info.absolutePath()); + ls.waitForFinished(); + + const QByteArray &request = ls.readAllStandardOutput(); + + for (const QByteArray &name : request.split('\n')) { + QString strFileName{ DFMGlobal::toUnicode(name) }; + + if (strFileName == info.fileName() && strFileName.toLocal8Bit() != name) { + const QByteArray &path = info.absolutePath().toLocal8Bit() + QDir::separator().toLatin1() + name; + + return fileNameCorrection(path); + } + } + + return false; +} + +bool DFMGlobal::fileNameCorrection(const QByteArray &filePath) +{ + const QByteArray &newFilePath = QString::fromLocal8Bit(filePath).toLocal8Bit(); + + if (filePath == newFilePath) + return true; + + return std::rename(filePath.constData(), newFilePath.constData()); +} + +bool DFMGlobal::isDesktopFile(const DUrl &url) +{ + return url.toLocalFile().endsWith(".desktop"); +} + +bool DFMGlobal::isTrashDesktopFile(const DUrl &url) +{ + if (isDesktopFile(url)) { + DesktopFile df(url.toLocalFile()); + return df.getDeepinId() == DDE_TRASH_ID; + } + return false; +} + +bool DFMGlobal::isComputerDesktopFile(const DUrl &url) +{ + if (isDesktopFile(url)) { + DesktopFile df(url.toLocalFile()); + return df.getDeepinId() == DDE_COMPUTER_ID; + } + return false; +} + +bool DFMGlobal::isTrashDesktopFileUrl(const DUrl &url) +{ + if (DesktopFileInfo::trashDesktopFileUrl() == url) + return isTrashDesktopFile(url); + return false; +} + +bool DFMGlobal::isComputerDesktopFileUrl(const DUrl &url) +{ + if (DesktopFileInfo::computerDesktopFileUrl() == url) + return isComputerDesktopFile(url); + return false; +} + +bool DFMGlobal::isWayLand() +{ + //! 该函数只能在QApplication之后调用才能返回有效的值,在此之前会返回空值 + Q_ASSERT(qApp); + return QApplication::platformName() == "wayland"; +} + +void DFMGlobal::showMultiFilesRenameDialog(const QList &selectedFiles) +{ + dialogManager->showMultiFilesRenameDialog(selectedFiles); +} + +void DFMGlobal::showFilePreviewDialog(const DUrlList &selectUrls, const DUrlList &entryUrls) +{ + emit fileSignalManager->requestShowFilePreviewDialog(selectUrls, entryUrls); +} + +void DFMGlobal::showPropertyDialog(QObject *const sender, const QList &selectedFiles) +{ + dialogManager->showPropertyDialog(DFMUrlListBaseEvent{sender, selectedFiles}); +} + +QString DFMGlobal::preprocessingFileName(QString name) +{ + // eg: [\\:*\"?<>|\r\n] + const QString &value = DFMApplication::genericObtuselySetting()->value("FileName", "non-allowableCharacters").toString(); + + if (value.isEmpty()) + return name; + + return name.remove(QRegularExpression(value)); +} + +void DFMGlobal::setMimeDataUserID(QMimeData *mime) +{ + QByteArray userId; + QString strUserID = QString::number(getUserId()); + userId.append(strUserID); + mime->setData(MIME_USER_ID, userId); + // 组装用户ID的Key值 + QString strKey = QString(MIME_USER_ID) + "_" + strUserID; + mime->setData(strKey, userId); +} + +bool DFMGlobal::isMimeDatafromCurrentUser(const QMimeData *mime) +{ + // 组装用户ID的Key值 + QString strKey = QString(MIME_USER_ID) + "_" + QString::number(getUserId()); + return mime->hasFormat(strKey); +} + +void DFMGlobal::setInitAppOver() +{ + IsInitAppOver = true; +} + +bool DFMGlobal::isInitAppOver() +{ + return IsInitAppOver.load(); +} + +void DFMGlobal::setAppQuiting() +{ + IsAppQuiting.store(true); +} + +bool DFMGlobal::isAppQuiting() +{ + return IsAppQuiting.load(); +} + + +QList DFMGlobal::getUrlsByX11() +{ + QAtomicInt currentCount = GlobalData::remoteCurrentCount; + const QMimeData *mimedata = qApp->clipboard()->mimeData(); + if (!mimedata) { + qWarning() << "the clipboard mimedata is invalid!"; + return QList(); + } + if (GlobalData::clipboardAction != RemoteAction) { + qWarning() << "current action is not RemoteAction ,error action " << GlobalData::clipboardAction; + return QList(); + } + //使用x11创建一个窗口去阻塞获取URl + Display *display = XOpenDisplay(nullptr); + unsigned long color = BlackPixel(display, DefaultScreen(display)); + Window window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0,0, 1,1, 0, color, color); + + char *result = nullptr; + unsigned long ressize = 0, restail = 0; + int resbits; + Atom bufid = XInternAtom(display, "CLIPBOARD", False), + fmtid = XInternAtom(display, "text/uri-list", False), + propid = XInternAtom(display, "XSEL_DATA", False), + incrid = XInternAtom(display, "INCR", False); + XEvent event; + + QList urls; + QString results; + QAtomicInteger isCanceled = false; + + XSelectInput (display, window, PropertyChangeMask); + XConvertSelection(display, bufid, fmtid, propid, window, CurrentTime); + do { + XNextEvent(display, &event); + } while (event.type != SelectionNotify || event.xselection.selection != bufid); + if (event.xselection.property) { + XGetWindowProperty(display, window, propid, 0, LONG_MAX/4, True, AnyPropertyType, + &fmtid, &resbits, &ressize, &restail, (unsigned char**)&result); + if (fmtid != incrid) { + qInfo() << QString(result); + urls += QUrl::fromStringList(QString(result).split("\n")); + } + + XFree(result); + + if (fmtid == incrid) { + do { + do { + XNextEvent(display, &event); + if (event.type == SelectionNotify) { + isCanceled = true; + break; + } + } while (event.type != PropertyNotify || event.xproperty.atom != propid || event.xproperty.state != PropertyNewValue); + if (isCanceled) + break; + XGetWindowProperty(display, window, propid, 0, LONG_MAX/4, True, AnyPropertyType, &fmtid, &resbits, &ressize, &restail, (unsigned char**)&result); + if (QString(result) != "/") + results += QString(result); + XFree(result); + } while (ressize > 0); + } + } + XDestroyWindow(display, window); + XCloseDisplay(display); + + if (isCanceled) { + qWarning() << "user cancel remote download !"; + return QList(); + } + urls += QUrl::fromStringList(results.split("\n")); + + QList clipboardFileUrls; + for (QUrl url : urls) { + //链接文件的inode不加入clipbordFileinode,只用url判断clip,避免多个同源链接文件的逻辑误判 + if (url.toString() == "copy") + continue; + + QString path = url.path(); + path = path.replace(QRegExp("/*/"),"/"); + if (path.isEmpty() || path == "/") + continue; + QUrl temp; + temp.setScheme("file"); + temp.setPath(path); + clipboardFileUrls << temp; + } + qInfo() << results << urls << clipboardFileUrls; + + if (GlobalData::clipboardAction == RemoteAction && currentCount == GlobalData::remoteCurrentCount) { + QMutexLocker lk(&GlobalData::clipboardFileUrlsMutex); + GlobalData::clipboardFileUrls.clear(); + GlobalData::clipboardFileUrls = clipboardFileUrls; + GlobalData::clipboardAction = CopyAction; + GlobalData::remoteCurrentCount = 0; + } + + return clipboardFileUrls; +} + +QList DFMGlobal::getUrlsByQt() +{ + QAtomicInt currentCount = GlobalData::remoteCurrentCount; + const QMimeData *mimedata = qApp->clipboard()->mimeData(); + if (!mimedata) { + qWarning() << "the clipboard mimedata is invalid!"; + return QList(); + } + if (GlobalData::clipboardAction != RemoteAction) { + qWarning() << "current action is not RemoteAction ,error action " << GlobalData::clipboardAction; + return QList(); + } + + QList urls = mimedata->urls(); + + QList clipboardFileUrls; + for (QUrl url : urls) { + //链接文件的inode不加入clipbordFileinode,只用url判断clip,避免多个同源链接文件的逻辑误判 + if (url.toString() == "copy") + continue; + + QString path = url.path(); + path = path.replace(QRegExp("/*/"),"/"); + if (path.isEmpty() || path == "/") + continue; + QUrl temp; + temp.setScheme("file"); + temp.setPath(path); + clipboardFileUrls << temp; + } + + qInfo() << urls << clipboardFileUrls; + + if (GlobalData::clipboardAction == RemoteAction && currentCount == GlobalData::remoteCurrentCount) { + QMutexLocker lk(&GlobalData::clipboardFileUrlsMutex); + GlobalData::clipboardFileUrls.clear(); + GlobalData::clipboardFileUrls = clipboardFileUrls; + GlobalData::clipboardAction = CopyAction; + GlobalData::remoteCurrentCount = 0; + } + + return clipboardFileUrls; +} + +QList DFMGlobal::getRemoteUrls() +{ + if (isWayLand()) + return getUrlsByQt(); + return getUrlsByX11(); +} + +QString DFMGlobal::toUnicode(const QByteArray &data, const QString &fileName) +{ + if (data.isEmpty()) + return QString(); + + const QByteArray &encoding = detectCharset(data, fileName); + + if (QTextCodec *codec = QTextCodec::codecForName(encoding)) { + return codec->toUnicode(data); + } + + return QString::fromLocal8Bit(data); +} + +QString DFMGlobal::cutString(const QString &text, int dataByteSize, const QTextCodec *codec) +{ + QString new_text; + int bytes = 0; + + for (int i = 0; i < text.size(); ++i) { + const QChar &ch = text.at(i); + QByteArray data; + QString full_char; + + if (ch.isSurrogate()) { + if ((++i) >= text.size()) + break; + + const QChar &next_ch = text.at(i); + + if (!ch.isHighSurrogate() || !next_ch.isLowSurrogate()) + break; + + data = codec->fromUnicode(text.data() + i - 1, 2); + full_char.setUnicode(text.data() + i - 1, 2); + } else { + data = codec->fromUnicode(text.data() + i, 1); + full_char.setUnicode(text.data() + i, 1); + } + + if (codec->toUnicode(data) != full_char) { + qWarning() << "Failed convert" << full_char << "to" << codec->name() << "coding"; + continue; + } + + bytes += data.size(); + + if (bytes > dataByteSize) + break; + + new_text.append(ch); + + if (ch.isSurrogate()) + new_text.append(text.at(i)); + } + + return new_text; +} + +namespace DThreadUtil { +FunctionCallProxy::FunctionCallProxy(QThread *thread) +{ + connect(this, &FunctionCallProxy::callInLiveThread, this, [](FunctionType * func) { + (*func)(); + delete func; + }, Qt::QueuedConnection); + connect(thread, &QThread::finished, this, [this] { + qWarning() << sender() << "the thread finished"; + }, Qt::DirectConnection); +} +} // end namespace DThreadUtil + + +///###: Do not modify it. +///###: it's auxiliary. +float codecConfidenceForData(const QTextCodec *codec, const QByteArray &data, const QLocale::Country &country) +{ + qreal hep_count = 0; + int non_base_latin_count = 0; + qreal unidentification_count = 0; + int replacement_count = 0; + + QTextDecoder decoder(codec); + const QString &unicode_data = decoder.toUnicode(data); + + for (int i = 0; i < unicode_data.size(); ++i) { + const QChar &ch = unicode_data.at(i); + + if (ch.unicode() > 0x7f) + ++non_base_latin_count; + + switch (ch.script()) { + case QChar::Script_Hiragana: + case QChar::Script_Katakana: + hep_count += country == QLocale::Japan ? 1.2 : 0.5; + unidentification_count += country == QLocale::Japan ? 0 : 0.3; + break; + case QChar::Script_Han: + hep_count += country == QLocale::China ? 1.2 : 0.5; + unidentification_count += country == QLocale::China ? 0 : 0.3; + break; + case QChar::Script_Hangul: + hep_count += (country == QLocale::NorthKorea) || (country == QLocale::SouthKorea) ? 1.2 : 0.5; + unidentification_count += (country == QLocale::NorthKorea) || (country == QLocale::SouthKorea) ? 0 : 0.3; + break; + case QChar::Script_Cyrillic: + hep_count += (country == QLocale::Russia) ? 1.2 : 0.5; + unidentification_count += (country == QLocale::Russia) ? 0 : 0.3; + break; + case QChar::Script_Greek: + hep_count += (country == QLocale::Greece) ? 1.2 : 0.5; + unidentification_count += (country == QLocale::Greece) ? 0 : 0.3; + break; + default: + // full-width character, emoji, 常用标点, 拉丁文补充1,天城文及其补充,CJK符号和标点符号(如:【】) + if ((ch.unicode() >= 0xff00 && ch <= 0xffef) + || (ch.unicode() >= 0x2600 && ch.unicode() <= 0x27ff) + || (ch.unicode() >= 0x2000 && ch.unicode() <= 0x206f) + || (ch.unicode() >= 0x80 && ch.unicode() <= 0xff) + || (ch.unicode() >= 0xa8e0 && ch.unicode() <= 0xa8ff) + || (ch.unicode() >= 0x0900 && ch.unicode() <= 0x097f) + || (ch.unicode() >= 0x3000 && ch.unicode() <= 0x303f)) { + ++hep_count; + } else if (ch.isSurrogate() && ch.isHighSurrogate()) { + ++i; + + if (i < unicode_data.size()) { + const QChar &next_ch = unicode_data.at(i); + + if (!next_ch.isLowSurrogate()) { + --i; + break; + } + + uint unicode = QChar::surrogateToUcs4(ch, next_ch); + + // emoji + if (unicode >= 0x1f000 && unicode <= 0x1f6ff) { + hep_count += 2; + } + } + } else if (ch.unicode() == QChar::ReplacementCharacter) { + ++replacement_count; + } else if (ch.unicode() > 0x7f) { + // 因为UTF-8编码的容错性很低,所以未识别的编码只需要判断是否为 QChar::ReplacementCharacter 就能排除 + if (codec->name() != "UTF-8") + ++unidentification_count; + } + break; + } + } + + // blumia: not sure why original author assume non_base_latin_count must greater than zero... + if (non_base_latin_count == 0) { + return 1.0f; + } + + float c = static_cast(qreal(hep_count) / non_base_latin_count / 1.2); + + c -= static_cast(qreal(replacement_count) / non_base_latin_count); + c -= static_cast(qreal(unidentification_count) / non_base_latin_count); + + return qMax(0.0f, c); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmglobal.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmglobal.h new file mode 100644 index 0000000..c27d52f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmglobal.h @@ -0,0 +1,605 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMGLOBAL_H +#define DFMGLOBAL_H + +#include "durl.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define CEIL(x) (static_cast(std::ceil(x))) +#define FLOOR(x) (static_cast(std::floor(x))) + +// begin file item global define +#define TEXT_LINE_HEIGHT 18 +#define MAX_THREAD_COUNT 1000 +#define MAX_FILE_NAME_CHAR_COUNT 255 +#define DDE_TRASH_ID "dde-trash" +#define DDE_COMPUTER_ID "dde-computer" +#define REVOCATION_TIMES 2 +#define MIME_USER_ID "userID_for_MoveAction" + +#define ASYN_CALL(Fun, Code, captured...) {\ + QDBusPendingCallWatcher * watcher = new QDBusPendingCallWatcher(Fun);\ + auto onFinished = [watcher, captured]{\ + const QVariantList & args = watcher->reply().arguments();\ + Q_UNUSED(args);\ + Code;\ + watcher->deleteLater();\ + };\ + if(watcher->isFinished()) onFinished();\ + else QObject::connect(watcher, &QDBusPendingCallWatcher::finished, watcher, onFinished);} + +#if QT_VERSION >= 0x050500 +#define TIMER_SINGLESHOT(Time, Code, captured...){ \ + QTimer::singleShot(Time, [captured] {Code;});\ + } +#else +#define TIMER_SINGLESHOT(Time, Code, captured...){ \ + QTimer *timer = new QTimer;\ + timer->setSingleShot(true);\ + timer->setInterval(Time);\ + timer->moveToThread(qApp->thread());\ + QObject::connect(timer, &QTimer::timeout, timer, [timer, captured] {\ + timer->deleteLater();\ + Code;\ + });\ + if (QThread::currentThread() == qApp->thread()) timer->start();\ + else QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection);\ + } +#endif + +#define TIMER_SINGLESHOT_CONNECT_TYPE(Obj, Time, Code, ConnectType, captured...){ \ + QTimer *timer = new QTimer;\ + timer->setSingleShot(true);\ + timer->setInterval(Time);\ + timer->moveToThread(qApp->thread());\ + QObject::connect(timer, &QTimer::timeout, Obj, [timer, captured] {\ + timer->deleteLater();\ + Code;\ + }, ConnectType);\ + if (QThread::currentThread() == qApp->thread()) timer->start();\ + else QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection);\ + } + +#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0) +#define TIMER_SINGLESHOT_OBJECT(Obj, Time, Code, captured...)\ + TIMER_SINGLESHOT_CONNECT_TYPE(Obj, Time, Code, Qt::AutoConnection, captured) +#else +#define TIMER_SINGLESHOT_OBJECT(Obj, Time, Code, captured...)\ + QTimer::singleShot(Time, Obj, [captured]{Code;}); +#endif + +#define ASYN_CALL_SLOT(obj, fun, args...) \ + TIMER_SINGLESHOT_CONNECT_TYPE(obj, 0, {obj->fun(args);}, Qt::QueuedConnection, obj, args) + +#ifdef QT_STRINGIFY +#undef QT_STRINGIFY +#endif +#define QT_STRINGIFY(x...) #x + +#define DFM_NAMESPACE dde_file_manager +#define DFM_BEGIN_NAMESPACE namespace DFM_NAMESPACE { +#define DFM_END_NAMESPACE } +#define DFM_USE_NAMESPACE using namespace DFM_NAMESPACE; + +class DFMGlobal : public QObject +{ + Q_OBJECT + +public: + enum ClipboardAction { + CutAction, + CopyAction, + DeleteAction, + RemoteAction, + UnknowAction = 255 + }; + + enum Icon { + LinkIcon, + LockIcon, + UnreadableIcon, + ShareIcon + }; + + enum MenuExtension { + SingleFile, + MultiFiles, + SingleDir, + MultiDirs, + MultiFileDirs, + EmptyArea, + UnknowMenuExtension + }; + + Q_ENUM(MenuExtension) + + enum MenuAction { + Unknow, + Open, + OpenDisk, + OpenInNewWindow, + OpenInNewTab, + OpenDiskInNewWindow, + OpenDiskInNewTab, + OpenAsAdmin, + OpenWith, + OpenWithCustom, + OpenFileLocation, + Compress, + Decompress, + DecompressHere, + Cut, + Copy, + Paste, + Rename, + BookmarkRename, + BookmarkRemove, + CreateSymlink, + SendToDesktop, + SendToRemovableDisk, + SendToBluetooth, + AddToBookMark, + Delete, + Property, + NewFolder, + NewWindow, + SelectAll, + Separator, + ClearRecent, + ClearTrash, + DisplayAs, /// sub menu + SortBy, /// sub menu + NewDocument, /// sub menu + NewWord, /// sub menu + NewExcel, /// sub menu + NewPowerpoint, /// sub menu + NewText, /// sub menu + OpenInTerminal, + Restore, + RestoreAll, + CompleteDeletion, + Mount, + Unmount, + Eject, + SafelyRemoveDrive, + Name, + Size, + Type, + CreatedDate, + LastModifiedDate, + LastRead, + DeletionDate, + SourcePath, + AbsolutePath, + Settings, + Exit, + IconView, + ListView, + ExtendView, + SetAsWallpaper, + ForgetPassword, + Share, + UnShare, + SetUserSharePassword, + FormatDevice, + OpticalBlank, + Vault, + ConnectToServer, + + ///###: tag protocol. + TagInfo, + TagFilesUseColor, + ChangeTagColor, + DeleteTags, + RenameTag, + +#ifdef SW_LABEL + SetLabel, + ViewLabel, + EditLabel, + PrivateFileToPublic, +#endif + + // recent + RemoveFromRecent, + + MountImage, + StageFileForBurning, + + // Vault + LockNow, + AutoLock, + Never, + FiveMinutes, + TenMinutes, + TwentyMinutes, + DeleteVault, + + UnLock, + UnLockByKey, + + RemoveStashedRemoteConn, + RefreshView, + UserMenuAction = Unknow + 2000 + }; + + Q_ENUM(MenuAction) + + static DFMGlobal *instance(); + + static QStringList PluginLibraryPaths; + static bool IsFileManagerDiloagProcess; + static QAtomicInteger IsInitAppOver; + static QAtomicInteger IsAppQuiting; + + static QString organizationName(); + static QString applicationName(); + // libdde-file-manager version + static QString applicationVersion(); + static bool installTranslator(); + + static void setUrlsToClipboard(const QList &list, DFMGlobal::ClipboardAction action, QMimeData *mimeData = nullptr); + static const QList fetchUrlsFromClipboard(); + static DFMGlobal::ClipboardAction fetchClipboardAction(); + static void clearClipboard(); + static void clearTrash(); + + static void addPluginLibraryPath(const QString &path); + static void addPluginLibraryPaths(const QStringList &paths); + + static void autoLoadDefaultPlugins(); + + /* Global instance initialization */ + static void initPluginManager(); + // NOTE [XIAO] static void initSchemePluginManager(); + static void initSchemePluginManager(); + static void initSearchHistoryManager(); + static void initBookmarkManager(); + static void initFileMenuManager(); + static void initFileSiganlManager(); + static void initDialogManager(); + static void initAppcontroller(); + static void initFileService(); + static void initDeviceListener(); + static void initMimesAppsManager(); + static void initSystemPathManager(); + static void initMimeTypeDisplayManager(); + static void initNetworkManager(); + static void initGvfsMountManager(); + static void initSecretManager(); + static void initUserShareManager(); + static void initOperatorRevocation(); + static void initTagManagerConnect(); + static void initThumbnailConnection(); + static void initBluetoothManager(); + static void initRootFileManager(); + + static QString getUser(); + static int getUserId(); + static bool isRootUser(); + static bool isServerSys(); + static bool isDesktopSys(); + static bool isOpenAsAdmin(); + static bool isDeveloperMode(); + static bool isProfessional(); + + //check if is trash/computer desktop file containing Deepin_id of dde-trash/dde-computer + static bool isDesktopFile(const DUrl &url); + static bool isTrashDesktopFile(const DUrl &url); + static bool isComputerDesktopFile(const DUrl &url); + + //check the unique trash/computer dekstop file on desktop + static bool isTrashDesktopFileUrl(const DUrl &url); + static bool isComputerDesktopFileUrl(const DUrl &url); + + /** + * @brief isWayLand 判断是否是wayland + * @return true or false + */ + static bool isWayLand(); + + QList clipboardFileUrlList() const; + QList clipboardFileInodeList() const; + ClipboardAction clipboardAction() const; + QIcon standardIcon(Icon iconType) const; + + static QString wordWrapText(const QString &text, qreal width, + QTextOption::WrapMode wrapMode, + const QFont &font, + qreal lineHeight, + qreal *height = nullptr); + + static QString elideText(const QString &text, const QSizeF &size, + QTextOption::WrapMode wordWrap, + const QFont &font, + Qt::TextElideMode mode, + qreal lineHeight, + qreal flags = 0); + + static void wordWrapText(QTextLayout *layout, qreal width, + QTextOption::WrapMode wrapMode, + qreal lineHeight, + QStringList *lines = nullptr); + + static void elideText(QTextLayout *layout, const QSizeF &size, + QTextOption::WrapMode wordWrap, + Qt::TextElideMode mode, qreal lineHeight, + int flags = 0, QStringList *lines = nullptr, + QPainter *painter = nullptr, QPointF offset = QPoint(0, 0), + const QColor &shadowColor = QColor(), + const QPointF &shadowOffset = QPointF(0, 1), + const QBrush &background = QBrush(Qt::NoBrush), + qreal backgroundRadius = 4, + QList *boundingRegion = nullptr); + + + /** + * @brief setToolTip 设置tooltip显示 + * @param label 需要显示的控件 + * @param bAlwaysShow 是否总是显示 + */ + static void setToolTip(QLabel* label, bool bAlwaysShow = false); + + /** + * @brief showAlertMessage 显示气泡提示信息 + * @param globalPoint 气泡框展示的全局坐标 + * @param backgroundColor 气泡框的背景色 + * @param text 气泡框展示的文字 + * @param duration 显示时间,默认3秒 + */ + static void showAlertMessage(QPoint globalPoint, + const QColor &backgroundColor, + const QString &text, + int duration = 3000); + + static QString toPinyin(const QString &text); + static bool startWithHanzi(const QString &text); + template + static bool startWithHanzi(T) + { return false;} + /** + * @brief startWithSymbol 判断字符串是由符号开头 + * @param text + * @return + */ + static bool startWithSymbol(const QString &text); + + static bool keyShiftIsPressed(); + static bool keyCtrlIsPressed(); + static bool fileNameCorrection(const QString &filePath); + static bool fileNameCorrection(const QByteArray &filePath); + + + static void showMultiFilesRenameDialog(const QList &selectedFiles); + + static void showFilePreviewDialog(const DUrlList &selectUrls, const DUrlList &entryUrls); + + ///###: this function is special, if select files is more than 16 show a dialog for multiple files. + static void showPropertyDialog(QObject *const sender, const QList &selectedFiles); + + static QString toUnicode(const QByteArray &data, const QString &fileName = QString()); + static QString cutString(const QString &text, int dataByteSize, const QTextCodec *codec); + + ///###: this function detect what the charset of str is. + static QByteArray detectCharset(const QByteArray &data, const QString &fileName = QString{}); + static QString preprocessingFileName(QString name); + + static void setMimeDataUserID(QMimeData *mime); + static bool isMimeDatafromCurrentUser(const QMimeData *mime); + static void setInitAppOver(); + static bool isInitAppOver(); + static void setAppQuiting(); + static bool isAppQuiting(); + //download remote files + static QList getUrlsByX11(); + static QList getUrlsByQt(); + static QList getRemoteUrls(); +signals: + void clipboardDataChanged(); + +protected: + DFMGlobal(); + +private: + void onClipboardDataChanged(); + static void refreshPlugins(); +}; + +Q_DECLARE_METATYPE(DFMGlobal::ClipboardAction) +Q_DECLARE_METATYPE(DFMGlobal::MenuAction) + +namespace DThreadUtil { +typedef std::function FunctionType; + +class FunctionCallProxy : public QObject +{ + Q_OBJECT +public: + explicit FunctionCallProxy(QThread *thread); + +signals: + void callInLiveThread(FunctionType *func); +}; + +template +class _TMP +{ +public: + template + static ReturnType runInThread(QSemaphore *s, QThread *thread, Fun fun, Args &&... args) + { + if (QThread::currentThread() == thread) + return fun(std::forward(args)...); + + ReturnType result; + QSharedPointer cancle(new bool(false)); + QSharedPointer mtx(new QMutex); + FunctionCallProxy *proxy = new FunctionCallProxy(thread); + FunctionType *proxyFun = new FunctionType([&, proxy, cancle, mtx]() { + mtx->lock(); + if (!*cancle.get()) { + result = fun(std::forward(args)...); + s->release(); + } + mtx->unlock(); + proxy->deleteLater(); + }); + + proxy->moveToThread(thread); + + if (thread->loopLevel() <= 0) { + qWarning() << thread << ", the thread no event loop"; + } + + proxy->callInLiveThread(proxyFun); + s->acquire(); + mtx->lock(); + *cancle.get() = true; + mtx->unlock(); + return result; + } +}; +template <> +class _TMP +{ +public: + template + static void runInThread(QSemaphore *s, QThread *thread, Fun fun, Args &&... args) + { + if (QThread::currentThread() == thread) + return fun(std::forward(args)...); + + QSharedPointer cancle(new bool(false)); + QSharedPointer mtx(new QMutex); + FunctionCallProxy *proxy = new FunctionCallProxy(thread); + FunctionType *proxyFun = new FunctionType([&, proxy, cancle, mtx]() { + mtx->lock(); + if (!*cancle.get()) { + fun(std::forward(args)...); + s->release(); + } + mtx->unlock(); + proxy->deleteLater(); + }); + + proxy->moveToThread(thread); + + if (thread->loopLevel() <= 0) { + qWarning() << thread << ", the thread no event loop"; + } + + proxy->callInLiveThread(proxyFun); + s->acquire(); + mtx->lock(); + *cancle.get() = true; + mtx->unlock(); + } +}; + +template +auto runInThread(QSemaphore *s, QThread *thread, Fun fun, Args &&... args) -> decltype(fun(args...)) +{ + return _TMP::runInThread(s, thread, fun, std::forward(args)...); +} +template +typename QtPrivate::FunctionPointer::ReturnType runInThread(QSemaphore *s, QThread *thread, typename QtPrivate::FunctionPointer::Object *obj, Fun fun, Args &&... args) +{ + return _TMP::ReturnType>::runInThread(s, thread, [&] { + return (obj->*fun)(std::forward(args)...); + }); +} + +template +auto runInThread(QThread *thread, Fun fun, Args &&... args) -> decltype(fun(args...)) +{ + QSemaphore s; + + return runInThread(&s, thread, fun, std::forward(args)...); +} +template +typename QtPrivate::FunctionPointer::ReturnType runInThread(QThread *thread, typename QtPrivate::FunctionPointer::Object *obj, Fun fun, Args &&... args) +{ + QSemaphore s; + + return runInThread(&s, thread, obj, fun, std::forward(args)...); +} + +template +auto runInMainThread(Fun fun, Args &&... args) -> decltype(fun(args...)) +{ + if (!QCoreApplication::instance()) { + return fun(std::forward(args)...); + } + + return runInThread(QCoreApplication::instance()->thread(), fun, std::forward(args)...); +} +template +typename QtPrivate::FunctionPointer::ReturnType runInMainThread(typename QtPrivate::FunctionPointer::Object *obj, Fun fun, Args &&... args) +{ + if (!QCoreApplication::instance()) { + return (obj->*fun)(std::forward(args)...); + } + + return runInThread(QCoreApplication::instance()->thread(), obj, fun, std::forward(args)...); +} +} + +// namespace dfm_util: 通用的工具 +namespace dfm_util { +template +// 工具函数:判断一个值是否在一个集合中 +inline bool isContains(const T &source) +{ + (void)source; + return false; +} + +template +inline bool isContains(const T &source, const T &cmp, const Args &...args) +{ + if (source == cmp) + return true; + else + return isContains(source, args...); +} +} + + +#endif // DFMGLOBAL_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsettings.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsettings.cpp new file mode 100644 index 0000000..f7c30fa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsettings.cpp @@ -0,0 +1,775 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dfmsettings.h" +#ifndef DFM_NO_FILE_WATCHER +#include "dfilewatcher.h" +#endif +#include "dfmstandardpaths.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +DFM_BEGIN_NAMESPACE + +class DFMSettingsPrivate +{ +public: + explicit DFMSettingsPrivate(DFMSettings *qq); + + bool autoSync = false; + bool watchChanges = false; + bool settingFileIsDirty = false; + + QTimer *syncTimer = nullptr; + + QString fallbackFile; + QString settingFile; +#ifndef DFM_NO_FILE_WATCHER + DFileWatcher *settingFileWatcher = nullptr; +#endif + + DFMSettings *q_ptr; + + struct Data { + QHash values; + QHash privateValues; + + QVariant value(const QString &group, const QString &key, const QVariant &dv = QVariant()) const + { + return values.value(group).value(key, dv); + } + + void setValue(const QString group, const QString &key, const QVariant &value) + { + if (!values.contains(group)) { + values.insert(group, {{key, value}}); + + return; + } + + values[group][key] = value; + } + + QVariantMap groupMetaData(const QString &group) const + { + return privateValues.value("__metadata__").value(group).toMap(); + } + + QStringList groupKeyOrderedList(const QString &group) const + { + return groupMetaData(group).value("keyOrdered").toStringList(); + } + }; + + Data defaultData; + Data fallbackData; + Data writableData; + + void fromJsonFile(const QString &fileName, Data *data); + void fromJson(const QByteArray &json, Data *data); + QByteArray toJson(const Data &data); + + void makeSettingFileToDirty(bool dirty) + { + if (settingFileIsDirty == dirty) { + return; + } + + settingFileIsDirty = dirty; + + if (!autoSync) { + return; + } + + Q_ASSERT(syncTimer); + + if (QThread::currentThread() == syncTimer->thread()) { + if (dirty) { + syncTimer->start(); + } else { + syncTimer->stop(); + } + } else { + syncTimer->metaObject()->invokeMethod(syncTimer, dirty ? "start" : "stop", Qt::QueuedConnection); + } + } + + QString urlToKey(const DUrl &url) const + { + if (url.isLocalFile()) { + const DUrl &new_url = DFMStandardPaths::toStandardUrl(url.toLocalFile()); + + if (new_url.isValid()) { + return new_url.toString(); + } + } + + return url.toString(); + } + + void _q_onFileChanged(const DUrl &url); +}; + +DFMSettingsPrivate::DFMSettingsPrivate(DFMSettings *qq) + : q_ptr(qq) +{ + +} + +void DFMSettingsPrivate::fromJsonFile(const QString &fileName, Data *data) +{ + QFile file(fileName); + + if (!file.exists()) { + return; + } + + if (!file.open(QFile::ReadOnly)) { + qWarning() << file.errorString(); + + return; + } + + const QByteArray &json = file.readAll(); + + if (json.isEmpty()) { + return; + } + + fromJson(json, data); +} + +void DFMSettingsPrivate::fromJson(const QByteArray &json, Data *data) +{ + QJsonParseError error; + const QJsonDocument &doc = QJsonDocument::fromJson(json, &error); + + if (error.error != QJsonParseError::NoError) { + qWarning() << error.errorString(); + return; + } + + if (!doc.isObject()) { + qWarning() << QString(); + return; + } + + const QJsonObject &groups_object = doc.object(); + + for (auto begin = groups_object.constBegin(); begin != groups_object.constEnd(); ++begin) { + const QJsonValue &value = begin.value(); + + if (!value.isObject()) { + qWarning() << QString(); + continue; + } + + const QJsonObject &value_object = value.toObject(); + QVariantHash hash; + + for (auto iter = value_object.constBegin(); iter != value_object.constEnd(); ++iter) { + hash[iter.key()] = iter.value().toVariant(); + } + + // private groups + if (begin.key().startsWith("__") && begin.key().endsWith("__")) + data->privateValues[begin.key()] = hash; + else + data->values[begin.key()] = hash; + } +} + +QByteArray DFMSettingsPrivate::toJson(const Data &data) +{ + QJsonObject root_object; + + for (auto begin = data.values.constBegin(); begin != data.values.constEnd(); ++begin) { + root_object.insert(begin.key(), QJsonValue(QJsonObject::fromVariantHash(begin.value()))); + } + + return QJsonDocument(root_object).toJson(); +} + +void DFMSettingsPrivate::_q_onFileChanged(const DUrl &url) +{ + if (url.toLocalFile() != settingFile) { + return; + } + + const auto old_values = writableData.values; + + writableData.values.clear(); + fromJsonFile(settingFile, &writableData); + makeSettingFileToDirty(false); + + for (auto begin = writableData.values.constBegin(); begin != writableData.values.constEnd(); ++begin) { + for (auto i = begin.value().constBegin(); i != begin.value().constEnd(); ++i) { + if (old_values.value(begin.key()).contains(i.key())) { + if (old_values.value(begin.key()).value(i.key()) == i.value()) { + continue; + } + } else { + if (fallbackData.values.value(begin.key()).contains(i.key())) { + if (fallbackData.values.value(begin.key()).value(i.key()) == i.value()) { + continue; + } + } + + if (defaultData.values.value(begin.key()).value(i.key()) == i.value()) { + continue; + } + } + + Q_EMIT q_ptr->valueEdited(begin.key(), i.key(), i.value()); + Q_EMIT q_ptr->valueChanged(begin.key(), i.key(), i.value()); + } + } + + for (auto begin = old_values.constBegin(); begin != old_values.constEnd(); ++begin) { + for (auto i = begin.value().constBegin(); i != begin.value().constEnd(); ++i) { + if (writableData.values.value(begin.key()).contains(i.key())) { + continue; + } + + const QVariant &new_value = q_ptr->value(begin.key(), i.key()); + + if (new_value != old_values.value(begin.key()).value(i.key())) { + Q_EMIT q_ptr->valueEdited(begin.key(), i.key(), new_value); + Q_EMIT q_ptr->valueChanged(begin.key(), i.key(), new_value); + } + } + } +} + +/*! + * \class DFMSettings + * \inmodule dde-file-manager-lib + * + * \brief DFMSettings provide interfaces to access and modify the file manager setting options. + */ +DFMSettings::DFMSettings(const QString &defaultFile, const QString &fallbackFile, const QString &settingFile, QObject *parent) + : QObject(parent) + , d_ptr(new DFMSettingsPrivate(this)) +{ + d_ptr->fallbackFile = fallbackFile; + d_ptr->settingFile = settingFile; + + d_ptr->fromJsonFile(defaultFile, &d_ptr->defaultData); + d_ptr->fromJsonFile(fallbackFile, &d_ptr->fallbackData); + d_ptr->fromJsonFile(settingFile, &d_ptr->writableData); +} + +static QString getConfigFilePath(QStandardPaths::StandardLocation type, const QString &fileName, bool writable) +{ + if (writable) { + QString path = QStandardPaths::writableLocation(type); + + if (path.isEmpty()) { + path = QDir::home().absoluteFilePath(QString(".config/%1/%2").arg(qApp->organizationName()).arg(qApp->applicationName())); + } + + return path.append(QString("/%1.json").arg(fileName)); + } + + const QStringList &list = QStandardPaths::standardLocations(type); + + QString path = list.isEmpty() ? QString("/etc/xdg/%1/%2").arg(qApp->organizationName()).arg(qApp->applicationName()) : list.last(); + + return path.append(QString("/%1.json").arg(fileName)); +} + +DFMSettings::DFMSettings(const QString &name, ConfigType type, QObject *parent) + : DFMSettings(QString(":/config/%1.json").arg(name), + getConfigFilePath(type == AppConfig + ? QStandardPaths::AppConfigLocation + : QStandardPaths::GenericConfigLocation, + name, false), + getConfigFilePath(type == AppConfig + ? QStandardPaths::AppConfigLocation + : QStandardPaths::GenericConfigLocation, + name, true), + parent) +{ + +} + +DFMSettings::~DFMSettings() +{ + Q_D(DFMSettings); + + if (d->syncTimer) { + d->syncTimer->stop(); + } + + if (d->settingFileIsDirty) { + sync(); + } +} + +bool DFMSettings::contains(const QString &group, const QString &key) const +{ + Q_D(const DFMSettings); + + if (key.isEmpty()) { + if (d->writableData.values.contains(group)) { + return true; + } + + if (d->fallbackData.values.contains(group)) { + return true; + } + + return d->defaultData.values.contains(group); + } + + if (d->writableData.values.value(group).contains(key)) { + return true; + } + + if (d->fallbackData.values.value(group).contains(key)) { + return true; + } + + return d->defaultData.values.value(group).contains(key); +} + +QSet DFMSettings::groups() const +{ + Q_D(const DFMSettings); + + QSet groups; + + groups.reserve(d->writableData.values.size() + d->fallbackData.values.size() + d->defaultData.values.size()); + + for (auto begin = d->writableData.values.constBegin(); begin != d->writableData.values.constEnd(); ++begin) { + groups << begin.key(); + } + + for (auto begin = d->fallbackData.values.constBegin(); begin != d->fallbackData.values.constEnd(); ++begin) { + groups << begin.key(); + } + + for (auto begin = d->defaultData.values.constBegin(); begin != d->defaultData.values.constEnd(); ++begin) { + groups << begin.key(); + } + + return groups; +} + +QSet DFMSettings::keys(const QString &group) const +{ + Q_D(const DFMSettings); + + QSet keys; + + const auto &&wg = d->writableData.values.value(group); + const auto &&fg = d->fallbackData.values.value(group); + const auto &&dg = d->defaultData.values.value(group); + + keys.reserve(wg.size() + fg.size() + dg.size()); + + for (auto begin = wg.constBegin(); begin != wg.constEnd(); ++begin) { + keys << begin.key(); + } + + for (auto begin = fg.constBegin(); begin != fg.constEnd(); ++begin) { + keys << begin.key(); + } + + for (auto begin = dg.constBegin(); begin != dg.constEnd(); ++begin) { + keys << begin.key(); + } + + return keys; +} + +/*! + * \brief DFMSettings::keysList + * \param group name + * \return An ordered key list of the group + */ +QStringList DFMSettings::keyList(const QString &group) const +{ + Q_D(const DFMSettings); + + QStringList keyList; + QSet keys = this->keys(group); + + for (const QString &ordered_key : d->defaultData.groupKeyOrderedList(group)) { + if (keys.contains(ordered_key)) { + keyList << ordered_key; + keys.remove(ordered_key); + } + } + + for (const QString &ordered_key : d->fallbackData.groupKeyOrderedList(group)) { + if (keys.contains(ordered_key)) { + keyList << ordered_key; + keys.remove(ordered_key); + } + } + + for (const QString &ordered_key : d->writableData.groupKeyOrderedList(group)) { + if (keys.contains(ordered_key)) { + keyList << ordered_key; + keys.remove(ordered_key); + } + } + + keyList << keys.toList(); + + return keyList; +} + +DUrl DFMSettings::toUrlValue(const QVariant &url) +{ + const QString &url_string = url.toString(); + + if (url_string.isEmpty()) { + return DUrl(); + } + + const QString &path = DFMStandardPaths::fromStandardUrl(DUrl(url_string)); + + if (!path.isEmpty()) { + return DUrl::fromLocalFile(path); + } + + return DUrl::fromUserInput(url_string); +} + +QVariant DFMSettings::value(const QString &group, const QString &key, const QVariant &defaultValue) const +{ + Q_D(const DFMSettings); + + QVariant value = d->writableData.values.value(group).value(key, QVariant::Invalid); + + if (value.isValid()) { + return value; + } + + value = d->fallbackData.values.value(group).value(key, QVariant::Invalid); + + if (value.isValid()) { + return value; + } + + return d->defaultData.values.value(group).value(key, defaultValue); +} + +QVariant DFMSettings::value(const QString &group, const DUrl &key, const QVariant &defaultValue) const +{ + Q_D(const DFMSettings); + + return value(group, d->urlToKey(key), defaultValue); +} + +DUrl DFMSettings::urlValue(const QString &group, const QString &key, const DUrl &defaultValue) const +{ + return toUrlValue(value(group, key, defaultValue)); +} + +DUrl DFMSettings::urlValue(const QString &group, const DUrl &key, const DUrl &defaultValue) const +{ + Q_D(const DFMSettings); + + return urlValue(group, d->urlToKey(key), defaultValue); +} + +void DFMSettings::setValue(const QString &group, const QString &key, const QVariant &value) +{ + if (setValueNoNotify(group, key, value)) { + Q_EMIT valueChanged(group, key, value); + } +} + +void DFMSettings::setValue(const QString &group, const DUrl &key, const QVariant &value) +{ + Q_D(DFMSettings); + + setValue(group, d->urlToKey(key), value); +} + +bool DFMSettings::setValueNoNotify(const QString &group, const QString &key, const QVariant &value) +{ + Q_D(DFMSettings); + + bool changed = false; + + if (isRemovable(group, key)) { + if (d->writableData.value(group, key) == value) { + return false; + } + + changed = true; + } else { + changed = this->value(group, key, value) != value; + } + + d->writableData.setValue(group, key, value); + d->makeSettingFileToDirty(true); + + return changed; +} + +bool DFMSettings::setValueNoNotify(const QString &group, const DUrl &key, const QVariant &value) +{ + Q_D(DFMSettings); + + return setValueNoNotify(group, d->urlToKey(key), value); +} + +void DFMSettings::removeGroup(const QString &group) +{ + Q_D(DFMSettings); + + if (!d->writableData.values.contains(group)) { + return; + } + + const QVariantHash &group_values = d->writableData.values.take(group); + + d->makeSettingFileToDirty(true); + + for (auto begin = group_values.constBegin(); begin != group_values.constEnd(); ++begin) { + const QVariant &new_value = value(group, begin.key()); + + if (new_value != begin.value()) { + Q_EMIT valueChanged(group, begin.key(), new_value); + } + } +} + +bool DFMSettings::isRemovable(const QString &group, const QString &key) const +{ + Q_D(const DFMSettings); + + return d->writableData.values.value(group).contains(key); +} + +bool DFMSettings::isRemovable(const QString &group, const DUrl &key) const +{ + Q_D(const DFMSettings); + + return isRemovable(group, d->urlToKey(key)); +} + +void DFMSettings::remove(const QString &group, const QString &key) +{ + Q_D(DFMSettings); + + if (!d->writableData.values.value(group).contains(key)) { + return; + } + + const QVariant &old_value = d->writableData.values[group].take(key); + d->makeSettingFileToDirty(true); + + const QVariant &new_value = value(group, key); + + if (old_value == new_value) { + return; + } + + Q_EMIT valueChanged(group, key, new_value); +} + +void DFMSettings::remove(const QString &group, const DUrl &key) +{ + Q_D(DFMSettings); + + remove(group, d->urlToKey(key)); +} + +void DFMSettings::clear() +{ + Q_D(DFMSettings); + + if (d->writableData.values.isEmpty()) { + return; + } + + const QHash old_values = d->writableData.values; + + d->writableData.values.clear(); + d->makeSettingFileToDirty(true); + + for (auto begin = old_values.constBegin(); begin != old_values.constEnd(); ++begin) { + const QVariantHash &values = begin.value(); + + for (auto i = values.constBegin(); i != values.constEnd(); ++i) { + const QVariant &new_value = value(begin.key(), i.key()); + + if (new_value != i.value()) { + Q_EMIT valueChanged(begin.key(), i.key(), new_value); + } + } + } +} + +/*! + * \brief Reload config file. + * + * This will be needed if file watcher is disabled, or say, you defined the + * DFM_NO_FILE_WATCHER marco. + */ +void DFMSettings::reload() +{ + Q_D(DFMSettings); + + d->fallbackData.privateValues.clear(); + d->fallbackData.values.clear(); + d->fromJsonFile(d->fallbackFile, &d_ptr->fallbackData); + + d->writableData.privateValues.clear(); + d->writableData.values.clear(); + d->fromJsonFile(d->settingFile, &d_ptr->writableData); +} + +bool DFMSettings::sync() +{ + Q_D(DFMSettings); + + if (!d->settingFileIsDirty) { + return true; + } + + const QByteArray &json = d->toJson(d->writableData); + + QFile file(d->settingFile); + + if (!file.open(QFile::WriteOnly)) { + return false; + } + + bool ok = file.write(json) == json.size(); + + if (ok) { + d->makeSettingFileToDirty(false); + } + file.close(); + + return ok; +} + +bool DFMSettings::autoSync() const +{ + Q_D(const DFMSettings); + + return d->autoSync; +} + +#ifndef DFM_NO_FILE_WATCHER +bool DFMSettings::watchChanges() const +{ + Q_D(const DFMSettings); + + return d->watchChanges; +} +#endif + +void DFMSettings::setAutoSync(bool autoSync) +{ + Q_D(DFMSettings); + + if (d->autoSync == autoSync) { + return; + } + + d->autoSync = autoSync; + + if (autoSync) { + if (d->settingFileIsDirty) { + sync(); + } + + if (!d->syncTimer) { + d->syncTimer = new QTimer(this); + d->syncTimer->moveToThread(thread()); + d->syncTimer->setSingleShot(true); + d->syncTimer->setInterval(1000); + + connect(d->syncTimer, &QTimer::timeout, this, &DFMSettings::sync); + } + } else { + if (d->syncTimer) { + d->syncTimer->stop(); + d->syncTimer->deleteLater(); + d->syncTimer = nullptr; + } + } +} + +#ifndef DFM_NO_FILE_WATCHER +void DFMSettings::onFileChanged(const DUrl &url) +{ + Q_D(DFMSettings); + + d->_q_onFileChanged(url); +} + +void DFMSettings::setWatchChanges(bool watchChanges) +{ + Q_D(DFMSettings); + + if (d->watchChanges == watchChanges) { + return; + } + + d->watchChanges = watchChanges; + + if (watchChanges) { + { + QFileInfo info(d->settingFile); + + if (!info.exists()) { + if (info.absoluteDir().mkpath(info.absolutePath())) { + QFile file(d->settingFile); + + file.open(QFile::WriteOnly); + } + } + } + + d->settingFileWatcher = new DFileWatcher(d->settingFile, this); + d->settingFileWatcher->moveToThread(thread()); + + connect(d->settingFileWatcher, &DFileWatcher::fileModified, this, &DFMSettings::onFileChanged); + + d->settingFileWatcher->startWatcher(); + } else { + if (d->settingFileWatcher) { + d->settingFileWatcher->deleteLater(); + d->settingFileWatcher = nullptr; + } + } +} +#endif + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsettings.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsettings.h new file mode 100644 index 0000000..3e67ae5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsettings.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMSETTINGS_H +#define DFMSETTINGS_H + +#include +#include + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMSettingsPrivate; +class DFMSettings : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DFMSettings) + + Q_PROPERTY(bool autoSync READ autoSync WRITE setAutoSync) +#ifndef DFM_NO_FILE_WATCHER + Q_PROPERTY(bool watchChanges READ watchChanges WRITE setWatchChanges) +#endif + +public: + enum ConfigType { + AppConfig, + GenericConfig + }; + + explicit DFMSettings(const QString &defaultFile, const QString &fallbackFile, const QString &settingFile, QObject *parent = nullptr); + explicit DFMSettings(const QString &name, ConfigType type = AppConfig, QObject *parent = nullptr); + ~DFMSettings(); + + bool contains(const QString &group, const QString &key) const; + + QSet groups() const; + QSet keys(const QString &group) const; + QStringList keyList(const QString &group) const; + + static DUrl toUrlValue(const QVariant &url); + + QVariant value(const QString &group, const QString &key, const QVariant &defaultValue = QVariant()) const; + QVariant value(const QString &group, const DUrl &key, const QVariant &defaultValue = QVariant()) const; + DUrl urlValue(const QString &group, const QString &key, const DUrl &defaultValue = DUrl()) const; + DUrl urlValue(const QString &group, const DUrl &key, const DUrl &defaultValue = DUrl()) const; + void setValue(const QString &group, const QString &key, const QVariant &value); + void setValue(const QString &group, const DUrl &key, const QVariant &value); + // if changed return true + bool setValueNoNotify(const QString &group, const QString &key, const QVariant &value); + bool setValueNoNotify(const QString &group, const DUrl &key, const QVariant &value); + + void removeGroup(const QString &group); + bool isRemovable(const QString &group, const QString &key) const; + bool isRemovable(const QString &group, const DUrl &key) const; + void remove(const QString &group, const QString &key); + void remove(const QString &group, const DUrl &key); + void clear(); + void reload(); + + bool sync(); + + bool autoSync() const; +#ifndef DFM_NO_FILE_WATCHER + bool watchChanges() const; +#endif + +public Q_SLOTS: + void setAutoSync(bool autoSync); +#ifndef DFM_NO_FILE_WATCHER + void setWatchChanges(bool watchChanges); +#endif + +Q_SIGNALS: + void valueChanged(const QString &group, const QString &key, const QVariant &value); + void valueEdited(const QString &group, const QString &key, const QVariant &value); + +private: + QScopedPointer d_ptr; + +#ifndef DFM_NO_FILE_WATCHER + void onFileChanged(const DUrl &); +#endif +}; + +DFM_END_NAMESPACE + +#endif // DFMSETTINGS_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebaritem.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebaritem.cpp new file mode 100644 index 0000000..14bf8af --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebaritem.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmsidebaritem.h" +#include "dfmsidebarmanager.h" + +#include +#include +#include + +DFM_BEGIN_NAMESPACE + +DFMSideBarItem::DFMSideBarItem(const QIcon &icon, const QString &text, const DUrl &url, const QString &groupName) + : DStandardItem (icon, text) +{ + setUrl(url); + setGroupName(groupName); + this->setData(SidebarItem, ItemTypeRole); + this->setData("none", ItemUseRegisteredHandlerRole); + // setToolTip(text); + this->setData(QUuid::createUuid().toString(), ItemUniqueKeyRole); + this->setData(url.path().remove("/").remove(".localdisk"), ItemVolTagRole); +} + +/*! + * \internal + * \brief DFMSideBarItem::createSeparatorItem + * + * This is more likely a group header for the group \a groupName . + * Since QListView itself doesn't support grouping, so we need draw something as an + * identifier of the group. This separator located act as "first item of the group + * but not clickable", and once we found the group is empty, we should hide it. + * + * We should not remove a separator unless we actually would like to remove a group. + * For add/insert/append item to a group, we need find the correct group location, if + * there are no item in the group, the separator is the "placeholder" of the group. + */ +DFMSideBarItem * DFMSideBarItem::createSeparatorItem(const QString &groupName) +{ + DFMSideBarItem * item = new DFMSideBarItem(DUrl(), groupName); + + item->setData(Separator, ItemTypeRole); + item->setFlags(Qt::NoItemFlags); + + return item; +} + +DUrl DFMSideBarItem::url() const +{ + return this->data(ItemUrlRole).value(); +} + +QString DFMSideBarItem::groupName() const +{ + return this->data(ItemGroupNameRole).toString(); +} + +int DFMSideBarItem::itemType() const +{ + return this->data(ItemTypeRole).toInt(); +} + +/*! + * \brief Returns the type of this item. + * + * The type is used to distinguish custom items from the base class, don't confused + * with the Roles::ItemTypeRole data role, they are NOT the same thing, for that purpose + * please use itemType() instead. + * + * \sa itemType() + */ +int DFMSideBarItem::type() const +{ + return DFMSideBarItem::SidebarItemType; +} + +bool DFMSideBarItem::useRegisteredHandler() const +{ + return this->registeredHandler() == "none"; +} + +QString DFMSideBarItem::registeredHandler(const QString &fallback) const +{ + QString identifier = this->data(ItemUseRegisteredHandlerRole).toString(); + if (identifier != "none") { + return identifier; + } else { + return fallback.isEmpty() ? identifier : fallback; + } +} + +void DFMSideBarItem::setUrl(const DUrl &url) +{ + this->setData(QVariant::fromValue(url), ItemUrlRole); +} + +void DFMSideBarItem::setGroupName(const QString &groupName) +{ + this->setData(groupName, ItemGroupNameRole); +} + +void DFMSideBarItem::setRegisteredHandler(const QString &identifier) +{ + this->setData(identifier, ItemUseRegisteredHandlerRole); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebaritem.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebaritem.h new file mode 100644 index 0000000..a1239e0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebaritem.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#pragma once + +#include + +#include "durl.h" +#include "dfmglobal.h" + +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE + +class DFMSideBarItem : public DStandardItem +{ +public: + enum Roles { + ItemTypeRole = Dtk::UserRole + 1, + ItemUrlRole, + ItemGroupNameRole, + ItemUseRegisteredHandlerRole, + ItemUniqueKeyRole, + ItemVolTagRole, + ItemUserCustomRole = Dtk::UserRole + 0x0100 + }; + + enum ItemTypes { + SidebarItem, + Separator + }; + + enum CdAction { + ChangeDirectory, + MountPartitionThenCd, + UserCustom = 0x0100 + }; + + DFMSideBarItem(const DUrl &url = DUrl(), const QString &groupName = "default") : DFMSideBarItem (QIcon(), QString(), url, groupName) {} + DFMSideBarItem(const QIcon &icon, const QString &text, const DUrl &url = DUrl(), const QString &groupName = "default"); + + static DFMSideBarItem *createSeparatorItem(const QString &groupName); + + DUrl url() const; + QString groupName() const; + int itemType() const; + int type() const; + bool useRegisteredHandler() const; + QString registeredHandler(const QString &fallback = QString()) const; + + void setUrl(const DUrl &url); + void setGroupName(const QString &groupName); + void setRegisteredHandler(const QString &identifier); + + constexpr static int SidebarItemType = QStandardItem::UserType + 1; + +private: + void initModelData(); +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebariteminterface.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebariteminterface.cpp new file mode 100644 index 0000000..fdd691d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebariteminterface.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmsidebariteminterface.h" + +#include "singleton.h" +#include "app/filesignalmanager.h" +#include "views/dfilemanagerwindow.h" +#include "views/dfmsidebar.h" +#include "views/windowmanager.h" +#include "interfaces/dfmsidebaritem.h" +#include "interfaces/dfilemenu.h" +#include "controllers/vaultcontroller.h" + + +DFMSideBarItemInterface::DFMSideBarItemInterface(QObject *parent) : QObject(parent) +{ + +} + +void DFMSideBarItemInterface::cdAction(const DFMSideBar *sidebar, const DFMSideBarItem* item) +{ + DFileManagerWindow *wnd = qobject_cast(sidebar->topLevelWidget()); + if (item->itemType() != DFMSideBarItem::Separator) { + qDebug() << " item->url() " << item->url(); + + wnd->cd(item->url()); // don't `setChecked` here, wait for a signal. + } +} + +QMenu *DFMSideBarItemInterface::contextMenu(const DFMSideBar *sidebar, const DFMSideBarItem *item) +{ + DFileMenu *menu = new DFileMenu(); + + DFileManagerWindow *wnd = qobject_cast(sidebar->topLevelWidget()); + bool shouldDisable = !WindowManager::tabAddableByWinId(wnd->windowId()); + + menu->addAction(QObject::tr("Open in new window"), [item]() { + WindowManager::instance()->showNewWindow(item->url(), true); + }); + + menu->addAction(QObject::tr("Open in new tab"), [wnd, item]() { + wnd->openNewTab(item->url()); + })->setDisabled(shouldDisable); + + menu->addSeparator(); + + menu->addAction(QObject::tr("Properties"), [item]() { + DUrlList list; + list.append(item->url()); + Singleton::instance()->requestShowPropertyDialog(DFMUrlListBaseEvent(nullptr, list)); + }); + + return menu; +} + +void DFMSideBarItemInterface::rename(const DFMSideBarItem *item, QString name) +{ + Q_UNUSED(item) + Q_UNUSED(name) + //no-op +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebariteminterface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebariteminterface.h new file mode 100644 index 0000000..4bbd4eb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebariteminterface.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMSideBar; +class DFMSideBarItem; +class DFMSideBarItemInterface : public QObject +{ + Q_GADGET +public: + explicit DFMSideBarItemInterface(QObject *parent = nullptr); + + virtual void cdAction(const DFMSideBar *sidebar, const DFMSideBarItem* item); + virtual QMenu * contextMenu(const DFMSideBar *sidebar, const DFMSideBarItem* item); + virtual void rename(const DFMSideBarItem *item, QString name); +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebarmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebarmanager.cpp new file mode 100644 index 0000000..6c331f6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebarmanager.cpp @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmsidebarmanager.h" + +#include "interfaces/dfmsidebariteminterface.h" +#include "controllers/dfmsidebardefaultitemhandler.h" +#include "controllers/dfmsidebardeviceitemhandler.h" +#include "controllers/dfmsidebartagitemhandler.h" +#include "controllers/dfmsidebarbookmarkitemhandler.h" +#include "controllers/dfmsidebarvaultitemhandler.h" + +#include "plugins/schemepluginmanager.h" + +DFM_BEGIN_NAMESPACE + +class DFMSideBarManagerPrivate +{ +public: + explicit DFMSideBarManagerPrivate(DFMSideBarManager *qq); + + QMultiHash controllerCreatorHash; + + DFMSideBarManager *q_ptr; +}; + +DFMSideBarManagerPrivate::DFMSideBarManagerPrivate(DFMSideBarManager *qq) + : q_ptr(qq) +{ + +} + +DFMSideBarManager *DFMSideBarManager::instance() +{ + static DFMSideBarManager manager; + + return &manager; +} + +bool DFMSideBarManager::isRegisted(const QString &scheme, const std::type_info &info) const +{ + Q_D(const DFMSideBarManager); + + const KeyType &type = KeyType(scheme); + + foreach (const SideBarInterfaceCreaterType &value, d->controllerCreatorHash.values(type)) { + if (value.first == info.name()) + return true; + } + + return false; +} + +DFMSideBarItemInterface *DFMSideBarManager::createByIdentifier(const QString &identifier) +{ + Q_D(const DFMSideBarManager); + + KeyType theType(identifier); + + const QList creatorList = d->controllerCreatorHash.values(theType); + + if (!creatorList.isEmpty()) { + DFMSideBarItemInterface *i = (creatorList.first().second)(); + return i; + } + + return nullptr; +} + +DFMSideBarManager::DFMSideBarManager(QObject *parent) + : QObject(parent) + , d_private(new DFMSideBarManagerPrivate(this)) +{ + // register built-in + dRegisterSideBarInterface(QStringLiteral(SIDEBAR_ID_INTERNAL_FALLBACK)); + dRegisterSideBarInterface(QStringLiteral(SIDEBAR_ID_DEFAULT)); + dRegisterSideBarInterface(QStringLiteral(SIDEBAR_ID_DEVICE)); + dRegisterSideBarInterface(QStringLiteral(SIDEBAR_ID_TAG)); + dRegisterSideBarInterface(QStringLiteral(SIDEBAR_ID_BOOKMARK)); + dRegisterSideBarInterface(QStringLiteral(SIDEBAR_ID_VAULT)); + + //NOTE [XIAO] 从PLGUIN中加载SideBarItemHandler + initSideBarItemHandlerFromPlugin(); +} + +DFMSideBarManager::~DFMSideBarManager() +{ + +} + +void DFMSideBarManager::insertToCreatorHash(const DFMSideBarManager::KeyType &type, const SideBarInterfaceCreaterType &creator) +{ + Q_D(DFMSideBarManager); + + d->controllerCreatorHash.insertMulti(type, creator); +} + +//NOTE [XIAO] 从PLGUIN中加载SideBarItemHandler +void DFMSideBarManager::initSideBarItemHandlerFromPlugin() +{ + qInfo() << "[PLUGIN]" << "try to load plugin of sidebar item handler"; + for (auto plugin : SchemePluginManager::instance()->schemePlugins()) { + qWarning() << "[PLUGIN]" << "load sidebar item handler from plugin:" << plugin.first; + insertToCreatorHash(QString("__%1").arg(plugin.first), plugin.second->createSideBarInterfaceTypeFunc()); + } +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebarmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebarmanager.h new file mode 100644 index 0000000..9294242 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmsidebarmanager.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#pragma once + +#include + +#include + +#include "dfmglobal.h" + +#define SIDEBAR_ID_INTERNAL_FALLBACK "__internal" + +DFM_BEGIN_NAMESPACE + +class DFMSideBarItemInterface; +class DFMSideBarManagerPrivate; +class DFMSideBarManager : public QObject +{ + Q_OBJECT + + typedef QString KeyType; + typedef QPair> SideBarInterfaceCreaterType; + +public: + static DFMSideBarManager *instance(); + + template + void dRegisterSideBarInterface(const QString &identifier) { + if (isRegisted(identifier)) + return; + + insertToCreatorHash(KeyType(identifier), SideBarInterfaceCreaterType(typeid(T).name(), [=] () { + return static_cast(new T()); + })); + } + + bool isRegisted(const QString &scheme, const std::type_info &info) const; + + template + bool isRegisted(const QString &scheme) const { + return isRegisted(scheme, typeid(T)); + } + + DFMSideBarItemInterface * createByIdentifier(const QString& identifier); + +private: + explicit DFMSideBarManager(QObject *parent = nullptr); + ~DFMSideBarManager(); + + //NOTE [XIAO] 从PLGUIN中加载SideBarItemHandler + void initSideBarItemHandlerFromPlugin(); + + void insertToCreatorHash(const KeyType &type, const SideBarInterfaceCreaterType &creator); + + QScopedPointer d_private; + + Q_DECLARE_PRIVATE_D(d_private, DFMSideBarManager) +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmstandardpaths.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmstandardpaths.cpp new file mode 100644 index 0000000..98334fd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmstandardpaths.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmstandardpaths.h" +#include "durl.h" + +#include +#include +#include +#include + +QString DFMStandardPaths::location(DFMStandardPaths::StandardLocation type) +{ + switch (type) { + case TrashPath: + return QDir::homePath() + "/.local/share/Trash"; + case TrashExpungedPath: + return QDir::homePath() + "/.local/share/Trash/expunged"; + case TrashFilesPath: + return QDir::homePath() + "/.local/share/Trash/files"; + case TrashInfosPath: + return QDir::homePath() + "/.local/share/Trash/info"; +#ifdef APPSHAREDIR + case TranslationPath: { + QString path = APPSHAREDIR"/translations"; + if (!QDir(path).exists()) { + path = qApp->applicationDirPath() + "/translations"; + } + return path; + } + case TemplatesPath: { + QString path = APPSHAREDIR"/templates"; + if (!QDir(path).exists()) { + path = qApp->applicationDirPath() + "/templates"; + } + return path; + } + case MimeTypePath: { + QString path = APPSHAREDIR"/mimetypes"; + if (!QDir(path).exists()) { + path = qApp->applicationDirPath() + "/mimetypes"; + } + return path; + } + case ExtensionsPath: { + QString path = APPSHAREDIR"/extensions"; + if (!QDir(path).exists()) { + path = qApp->applicationDirPath() + "/extensions"; + } + return path; + } + case ExtensionsAppEntryPath: { + QString path = APPSHAREDIR"/extensions/appEntry"; + if (!QDir(path).exists()) { + path = qApp->applicationDirPath() + "/extensions/appEntry"; + } + return path; + } +#endif +#ifdef PLUGINDIR + case PluginsPath: { + QString path = PLUGINDIR; + if (!QDir(path).exists()) { + path = QString::fromLocal8Bit(PLUGINDIR).split(':').last(); + } + return path; + } +#endif +#ifdef QMAKE_TARGET + case ApplicationConfigPath: + return getConfigPath(); +#endif + case ThumbnailPath: + return QDir::homePath() + "/.cache/thumbnails"; + case ThumbnailFailPath: + return location(ThumbnailPath) + "/fail"; + case ThumbnailLargePath: + return location(ThumbnailPath) + "/large"; + case ThumbnailNormalPath: + return location(ThumbnailPath) + "/normal"; + case ThumbnailSmallPath: + return location(ThumbnailPath) + "/small"; +#ifdef APPSHAREDIR + case ApplicationSharePath: + return APPSHAREDIR; +#endif + case RecentPath: + return "recent:///"; + case HomePath: + return QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first(); + case DesktopPath: + return QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first(); + case VideosPath: + return QStandardPaths::standardLocations(QStandardPaths::MoviesLocation).first(); + case MusicPath: + return QStandardPaths::standardLocations(QStandardPaths::MusicLocation).first(); + case PicturesPath: + return QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).first(); + case DocumentsPath: + return QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first(); + case DownloadsPath: + return QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first(); + case CachePath: + return getCachePath(); + case DiskPath: + return QDir::rootPath(); +#ifdef NETWORK_ROOT + case NetworkRootPath: + return NETWORK_ROOT; +#endif +#ifdef USERSHARE_ROOT + case UserShareRootPath: + return USERSHARE_ROOT; +#endif +#ifdef COMPUTER_ROOT + case ComputerRootPath: + return COMPUTER_ROOT; +#endif + case Root: + return "/"; + case Vault: + return DFMVAULT_ROOT; // 根据需求确定使用哪种类型 + default: + return QStringLiteral("bug://dde-file-manager-lib/interface/dfmstandardpaths.cpp#") + QT_STRINGIFY(type); + } +} + +QString DFMStandardPaths::fromStandardUrl(const DUrl &standardUrl) +{ + if (standardUrl.scheme() != "standard") + return QString(); + + static QMap path_convert { + {"home", location(HomePath)}, + {"desktop", location(DesktopPath)}, + {"videos", location(VideosPath)}, + {"music", location(MusicPath)}, + {"pictures", location(PicturesPath)}, + {"documents", location(DocumentsPath)}, + {"downloads", location(DownloadsPath)} + }; + + const QString &path = path_convert.value(standardUrl.host()); + + if (path.isEmpty()) + return path; + + const QString &url_path = standardUrl.path(); + + if (url_path.isEmpty() || url_path == "/") + return path; + + return path + standardUrl.path(); +} + +DUrl DFMStandardPaths::toStandardUrl(const QString &localPath) +{ + static QList> path_convert { + {location(DesktopPath), "desktop"}, + {location(VideosPath), "videos"}, + {location(MusicPath), "music"}, + {location(PicturesPath), "pictures"}, + {location(DocumentsPath), "documents"}, + {location(DownloadsPath), "downloads"}, + {location(HomePath), "home"} + }; + + for (auto begin : path_convert) { + if (localPath.startsWith(begin.first)) { + const QString &path = localPath.mid(begin.first.size()); + + if (!path.isEmpty() && !path.startsWith("/")) + continue; + + DUrl url; + + url.setScheme("standard"); + url.setHost(begin.second); + + if (!path.isEmpty() && path != "/") + url.setPath(path); + + return url; + } + } + + return DUrl(); +} + +#ifdef QMAKE_TARGET +QString DFMStandardPaths::getConfigPath() +{ + QString projectName = QMAKE_TARGET; + QDir::home().mkpath(".config"); + QDir::home().mkpath(QString("%1/deepin/%2/").arg(".config", projectName)); + QString defaultPath = QString("%1/%2/deepin/%3").arg(QDir::homePath(), ".config", projectName); + return defaultPath; +} +#endif + +QString DFMStandardPaths::getCachePath() +{ + QString projectName = qApp->applicationName(); + QDir::home().mkpath(".cache"); + QDir::home().mkpath(QString("%1/deepin/%2/").arg(".cache", projectName)); + QString defaultPath = QString("%1/%2/deepin/%3").arg(QDir::homePath(), ".cache", projectName); + return defaultPath; +} + +DFMStandardPaths::DFMStandardPaths() +{ +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmstandardpaths.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmstandardpaths.h new file mode 100644 index 0000000..a546465 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmstandardpaths.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMSTANDARDPATHS_H +#define DFMSTANDARDPATHS_H + +#include +#include + +class DUrl; +class DFMStandardPaths +{ +public: + enum StandardLocation { + TrashPath, + TrashExpungedPath, + TrashFilesPath, + TrashInfosPath, + TranslationPath, + TemplatesPath, + MimeTypePath, + PluginsPath, + ExtensionsPath, + ExtensionsAppEntryPath, + ThumbnailPath, + ThumbnailFailPath, + ThumbnailLargePath, + ThumbnailNormalPath, + ThumbnailSmallPath, + ApplicationConfigPath, /* ~/.config */ + ApplicationSharePath, /* /usr/share/dde-file-manager */ + RecentPath, + HomePath, + DesktopPath, + VideosPath, + MusicPath, + PicturesPath, + DocumentsPath, + DownloadsPath, + CachePath, /* ~/.cache/dde-file-manager */ + DiskPath, + NetworkRootPath, + UserShareRootPath, + ComputerRootPath, + Root, + Vault + }; + + static QString location(StandardLocation type); + static QString fromStandardUrl(const DUrl &standardUrl); + static DUrl toStandardUrl(const QString &localPath); + +#ifdef QMAKE_TARGET + static QString getConfigPath(); +#endif + static QString getCachePath(); + +private: + DFMStandardPaths(); +}; + +#endif // DFMSTANDARDPATHS_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmstyleditemdelegate.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmstyleditemdelegate.cpp new file mode 100644 index 0000000..b035b92 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmstyleditemdelegate.cpp @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmstyleditemdelegate.h" +#include "dfileviewhelper.h" +#include "dfilesystemmodel.h" +#include "private/dstyleditemdelegate_p.h" + +#include +#include +#include +#include +#include +#include +#include + +DFMStyledItemDelegate::DFMStyledItemDelegate(DFileViewHelper *parent) + : DFMStyledItemDelegate(*new DFMStyledItemDelegatePrivate(this), parent) +{ + +} + +DFMStyledItemDelegate::~DFMStyledItemDelegate() +{ + +} + +DFileViewHelper *DFMStyledItemDelegate::parent() const +{ + return dynamic_cast(QStyledItemDelegate::parent()); +} + +QModelIndex DFMStyledItemDelegate::editingIndex() const +{ + Q_D(const DFMStyledItemDelegate); + + return d->editingIndex; +} + +QWidget *DFMStyledItemDelegate::editingIndexWidget() const +{ + Q_D(const DFMStyledItemDelegate); + + return parent()->indexWidget(d->editingIndex); +} + +QSize DFMStyledItemDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const +{ + Q_D(const DFMStyledItemDelegate); + + return d->itemSizeHint; +} + +void DFMStyledItemDelegate::destroyEditor(QWidget *editor, const QModelIndex &index) const +{ + Q_D(const DFMStyledItemDelegate); + + QStyledItemDelegate::destroyEditor(editor, index); + + d->editingIndex = QModelIndex(); +} + +QString DFMStyledItemDelegate::displayText(const QVariant &value, const QLocale &locale) const +{ + if (value.type() == QVariant::String) + return value.toString(); + + return QStyledItemDelegate::displayText(value, locale); +} + +QModelIndexList DFMStyledItemDelegate::hasWidgetIndexs() const +{ + Q_D(const DFMStyledItemDelegate); + + if (!d->editingIndex.isValid()) + return QModelIndexList(); + + return QModelIndexList() << d->editingIndex; +} + +void DFMStyledItemDelegate::hideAllIIndexWidget() +{ + Q_D(const DFMStyledItemDelegate); + + hideNotEditingIndexWidget(); + + if (d->editingIndex.isValid()) { + parent()->setIndexWidget(d->editingIndex, 0); + + d->editingIndex = QModelIndex(); + } +} + +void DFMStyledItemDelegate::hideNotEditingIndexWidget() +{ + +} + +void DFMStyledItemDelegate::commitDataAndCloseActiveEditor() +{ + Q_D(const DFMStyledItemDelegate); + + QWidget *editor = parent()->indexWidget(d->editingIndex); + + if (!editor) + return; + + QMetaObject::invokeMethod(this, "_q_commitDataAndCloseEditor", + Qt::DirectConnection, Q_ARG(QWidget *, editor)); +} + +QRect DFMStyledItemDelegate::fileNameRect(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + const QList &rects = paintGeomertys(option, index); + + //根据实际文件名所在列返回rect + const QList roleList = parent()->columnRoleList(); + int fileNameIndex = 0; + for (int i = 0; i < roleList.length(); ++i) { + if (roleList.at(i) == DFileSystemModel::FileDisplayNameRole || + roleList.at(i) == DFileSystemModel::FileNameRole ) { + fileNameIndex = i; + break; + } + } + + //第0个是icon的rect + if (rects.count() > 1) + return rects.at(fileNameIndex + 1); + + return QRect(); +} +int DFMStyledItemDelegate::iconSizeLevel() const +{ + return -1; +} + +int DFMStyledItemDelegate::minimumIconSizeLevel() const +{ + return -1; +} + +int DFMStyledItemDelegate::maximumIconSizeLevel() const +{ + return -1; +} + +int DFMStyledItemDelegate::increaseIcon() +{ + return -1; +} + +int DFMStyledItemDelegate::decreaseIcon() +{ + return -1; +} + +int DFMStyledItemDelegate::setIconSizeByIconSizeLevel(int level) +{ + Q_UNUSED(level) + + return -1; +} + +QList DFMStyledItemDelegate::drawText(const QModelIndex &index, QPainter *painter, QTextLayout *layout, const QRectF &boundingRect, + qreal radius, const QBrush &background, QTextOption::WrapMode wordWrap, + Qt::TextElideMode mode, int flags, const QColor &shadowColor) const +{ + initTextLayout(index, layout); + + QList boundingRegion; + DFMGlobal::elideText(layout, boundingRect.size(), wordWrap, mode, d_func()->textLineHeight, flags, nullptr, + painter, boundingRect.topLeft(), shadowColor, QPointF(0, 1), + background, radius, &boundingRegion); + + return boundingRegion; +} + +QList DFMStyledItemDelegate::drawText(const QModelIndex &index, QPainter *painter, const QString &text, const QRectF &boundingRect, + qreal radius, const QBrush &background, QTextOption::WrapMode wordWrap, + Qt::TextElideMode mode, int flags, const QColor &shadowColor) const +{ + QTextLayout layout; + + layout.setText(text); + + if (painter) + layout.setFont(painter->font()); + + return drawText(index, painter, &layout, boundingRect, radius, background, wordWrap, mode, flags, shadowColor); +} + +DFMStyledItemDelegate::DFMStyledItemDelegate(DFMStyledItemDelegatePrivate &dd, DFileViewHelper *parent) + : QStyledItemDelegate(parent) + , d_ptr(&dd) +{ + dd.init(); +} + +void DFMStyledItemDelegate::initTextLayout(const QModelIndex &index, QTextLayout *layout) const +{ + Q_UNUSED(index) + Q_UNUSED(layout) +} + +void DFMStyledItemDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const +{ + QStyledItemDelegate::initStyleOption(option, index); + parent()->initStyleOption(option, index); +} + +QList DFMStyledItemDelegate::getCornerGeometryList(const QRectF &baseRect, const QSizeF &cornerSize) const +{ + QList list; + double offset = baseRect.width() / 8; + const QSizeF &offset_size = cornerSize / 2; + + list.append(QRectF(QPointF(baseRect.right() - offset - offset_size.width(), + baseRect.bottom() - offset - offset_size.height()), cornerSize)); + list.append(QRectF(QPointF(baseRect.left() + offset - offset_size.width(), list.first().top()), cornerSize)); + list.append(QRectF(QPointF(list.at(1).left(), baseRect.top() + offset - offset_size.height()), cornerSize)); + list.append(QRectF(QPointF(list.first().left(), list.at(2).top()), cornerSize)); + + return list; +} + +QPixmap DFMStyledItemDelegate::getIconPixmap(const QIcon &icon, const QSize &size, qreal pixelRatio = 1.0, QIcon::Mode mode, QIcon::State state) +{ + // ###(zccrs): 开启Qt::AA_UseHighDpiPixmaps后,QIcon::pixmap会自动执行 pixmapSize *= qApp->devicePixelRatio() + // 而且,在有些QIconEngine的实现中,会去调用另一个QIcon::pixmap,导致 pixmapSize 在这种嵌套调用中越来越大 + // 最终会获取到一个是期望大小几倍的图片,由于图片太大,会很快将 QPixmapCache 塞满,导致后面再调用QIcon::pixmap + // 读取新的图片时无法缓存,非常影响图片绘制性能。此处在获取图片前禁用 Qt::AA_UseHighDpiPixmaps,自行处理图片大小问题 + bool useHighDpiPixmaps = qApp->testAttribute(Qt::AA_UseHighDpiPixmaps); + qApp->setAttribute(Qt::AA_UseHighDpiPixmaps, false); + + if (icon.isNull()) + return QPixmap(); + + //确保当前参数参入获取图片大小大于0 + if (size.width() <= 0 || size.height() <= 0) + return QPixmap(); + + QSize icon_size = icon.actualSize(size, mode, state); + //取出icon的真实大小 + QList iconSizeList = icon.availableSizes(); + QSize iconRealSize; + if (iconSizeList.count() > 0) + iconRealSize = iconSizeList.first(); + else + iconRealSize = icon_size; + if (iconRealSize.width() <= 0 || iconRealSize.height() <= 0) { +// return icon.pixmap(iconRealSize); + return icon.pixmap(icon_size); + } + + //确保特殊比例icon的高或宽不为0 + bool isSpecialSize = false; + QSize tempSize(size.width(), size.height()); + while (icon_size.width() < 1) { + tempSize.setHeight(tempSize.height() * 2); + icon_size = icon.actualSize(tempSize, mode, state); + isSpecialSize = true; + } + while (icon_size.height() < 1) { + tempSize.setWidth(tempSize.width() * 2); + icon_size = icon.actualSize(tempSize, mode, state); + isSpecialSize = true; + } + + if ((icon_size.width() > size.width() || icon_size.height() > size.height()) && !isSpecialSize) + icon_size.scale(size, Qt::KeepAspectRatio); + + QSize pixmapSize = icon_size * pixelRatio; + QPixmap px = icon.pixmap(pixmapSize, mode, state); + + // restore the value + qApp->setAttribute(Qt::AA_UseHighDpiPixmaps, useHighDpiPixmaps); + +// if (icon_size.width() == 0) { +// icon_size.setWidth(1); +// } +// if (icon_size.height() == 0) { +// icon_size.setHeight(1); +// } + +// icon_size = icon_size * pixelRatio; +// px = px.scaled(icon_size.width(), icon_size.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + + //约束特殊比例icon的尺寸 + if (isSpecialSize) { + if (px.width() > size.width() * pixelRatio) { + px = px.scaled(size.width() * CEIL(pixelRatio), px.height(), Qt::IgnoreAspectRatio); + } else if (px.height() > size.height() * pixelRatio) { + px = px.scaled(px.width(), size.height() * CEIL(pixelRatio), Qt::IgnoreAspectRatio); + } + } + + //类型限定符的更改会导致缩放小数点丢失,从而引发缩放因子的bug + if (px.width() > icon_size.width() * pixelRatio) { + px.setDevicePixelRatio(px.width() / qreal(icon_size.width())); + } else if (px.height() > icon_size.height() * pixelRatio) { + px.setDevicePixelRatio(px.height() / qreal(icon_size.height())); + } else { + px.setDevicePixelRatio(pixelRatio); + } + + return px; +} + +void DFMStyledItemDelegate::paintDragIcon(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, const QSize &size) const +{ + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + + QRectF icon_rect = opt.rect; + icon_rect.setSize(size); + + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setRenderHint(QPainter::SmoothPixmapTransform, true); + paintIcon(painter, opt.icon, icon_rect, Qt::AlignCenter, QIcon::Normal); +} + +QSize DFMStyledItemDelegate::getIndexIconSize(const QStyleOptionViewItem &option, const QModelIndex &index, const QSize &size) const +{ + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + + QRectF icon_rect = opt.rect; + icon_rect.setSize(size); + + QSize iconSize = opt.icon.actualSize(icon_rect.size().toSize(), QIcon::Normal, QIcon::Off); + if (iconSize.width() > size.width() || iconSize.height() > size.height()) + iconSize.scale(size, Qt::KeepAspectRatio); + + return iconSize; +} + +static inline Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment) +{ + if (!(alignment & Qt::AlignHorizontal_Mask)) + alignment |= Qt::AlignLeft; + if (!(alignment & Qt::AlignAbsolute) && (alignment & (Qt::AlignLeft | Qt::AlignRight))) { + if (direction == Qt::RightToLeft) + alignment ^= (Qt::AlignLeft | Qt::AlignRight); + alignment |= Qt::AlignAbsolute; + } + return alignment; +} + +void DFMStyledItemDelegate::paintIcon(QPainter *painter, const QIcon &icon, const QRectF &rect, Qt::Alignment alignment, QIcon::Mode mode, QIcon::State state) +{ + // Copy of QStyle::alignedRect + alignment = visualAlignment(painter->layoutDirection(), alignment); + const qreal pixel_ratio = painter->device()->devicePixelRatioF(); + const QPixmap &px = getIconPixmap(icon, rect.size().toSize(), pixel_ratio, mode, state); + qreal x = rect.x(); + qreal y = rect.y(); + qreal w = px.width() / px.devicePixelRatio(); + qreal h = px.height() / px.devicePixelRatio(); + if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter) + y += (rect.size().height() - h) / 2.0; + else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom) + y += rect.size().height() - h; + if ((alignment & Qt::AlignRight) == Qt::AlignRight) + x += rect.size().width() - w; + else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter) + x += (rect.size().width() - w) / 2.0; + + painter->drawPixmap(qRound(x), qRound(y), px); +} + +void DFMStyledItemDelegate::paintCircleList(QPainter *painter, QRectF boundingRect, qreal diameter, const QList &colors, const QColor &borderColor) +{ + bool antialiasing = painter->testRenderHint(QPainter::Antialiasing); + const QPen pen = painter->pen(); + const QBrush brush = painter->brush(); + + painter->setRenderHint(QPainter::Antialiasing); + painter->setPen(QPen(borderColor, 1)); + + for (const QColor &color : colors) { + QPainterPath circle; + + //根据tag颜色设置笔刷 + painter->setBrush(QBrush(color)); + circle.addEllipse(QRectF(QPointF(boundingRect.right() - diameter, boundingRect.top()), boundingRect.bottomRight())); +// painter->fillPath(circle, color); + painter->drawPath(circle); + boundingRect.setRight(boundingRect.right() - diameter / 2); + } + + painter->setPen(pen); + painter->setBrush(brush); + painter->setRenderHint(QPainter::Antialiasing, antialiasing); +} + +void DFMStyledItemDelegatePrivate::init() +{ + Q_Q(DFMStyledItemDelegate); + + q->connect(q, &DFMStyledItemDelegate::commitData, q->parent(), &DFileViewHelper::handleCommitData); + q->connect(q->parent()->parent(), &QAbstractItemView::iconSizeChanged, q, &DFMStyledItemDelegate::updateItemSizeHint); + + QAbstractItemModel *model = q->parent()->parent()->model(); + Q_ASSERT(model); + + q->connect(model, SIGNAL(rowsInserted(QModelIndex, int, int)), SLOT(_q_onRowsInserted(QModelIndex, int, int))); + q->connect(model, SIGNAL(rowsRemoved(QModelIndex, int, int)), SLOT(_q_onRowsRemoved(QModelIndex, int, int))); + + textLineHeight = q->parent()->parent()->fontMetrics().lineSpacing(); +} + +void DFMStyledItemDelegatePrivate::_q_onRowsInserted(const QModelIndex &parent, int first, int last) +{ + if (editingIndex.isValid() && first <= editingIndex.row() && !editingIndex.parent().isValid()) { + editingIndex = parent.child(editingIndex.row() + last - first + 1, editingIndex.column()); + } +} + +void DFMStyledItemDelegatePrivate::_q_onRowsRemoved(const QModelIndex &parent, int first, int last) +{ + if (editingIndex.isValid() && first <= editingIndex.row() && !editingIndex.parent().isValid()) { + editingIndex = parent.child(editingIndex.row() - last + first - 1, editingIndex.column()); + } +} + +#include "moc_dfmstyleditemdelegate.cpp" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmstyleditemdelegate.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmstyleditemdelegate.h new file mode 100644 index 0000000..7e69d1f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmstyleditemdelegate.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include + +#include "dfmglobal.h" + +QT_BEGIN_NAMESPACE +class QTextLayout; +QT_END_NAMESPACE + +class DFileViewHelper; +class DFMStyledItemDelegatePrivate; +class DFMStyledItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + explicit DFMStyledItemDelegate(DFileViewHelper *parent); + ~DFMStyledItemDelegate() override; + + DFileViewHelper *parent() const; + + QModelIndex editingIndex() const; + QWidget *editingIndexWidget() const; + + QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const override; + void destroyEditor(QWidget *editor, const QModelIndex &index) const override; + QString displayText(const QVariant &value, const QLocale &locale) const override; + + virtual QModelIndexList hasWidgetIndexs() const; + virtual void hideAllIIndexWidget(); + virtual void hideNotEditingIndexWidget(); + virtual void commitDataAndCloseActiveEditor(); + virtual QRect fileNameRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; + virtual QList paintGeomertys(const QStyleOptionViewItem &option, const QModelIndex &index, bool sizeHintMode = false) const = 0; + + virtual int iconSizeLevel() const; + virtual int minimumIconSizeLevel() const; + virtual int maximumIconSizeLevel() const; + + virtual int increaseIcon(); + virtual int decreaseIcon(); + virtual int setIconSizeByIconSizeLevel(int level); + + virtual void updateItemSizeHint() = 0; + + virtual QList drawText(const QModelIndex &index, QPainter *painter, QTextLayout *layout, + const QRectF &boundingRect, qreal radius, const QBrush &background, + QTextOption::WrapMode wordWrap = QTextOption::WrapAtWordBoundaryOrAnywhere, + Qt::TextElideMode mode = Qt::ElideMiddle, int flags = Qt::AlignCenter, + const QColor &shadowColor = QColor()) const; + + QList drawText(const QModelIndex &index, QPainter *painter, const QString &text, + const QRectF &boundingRect, qreal radius, const QBrush &background, + QTextOption::WrapMode wordWrap = QTextOption::WrapAtWordBoundaryOrAnywhere, + Qt::TextElideMode mode = Qt::ElideMiddle, int flags = Qt::AlignCenter, + const QColor &shadowColor = QColor()) const; + + static void paintCircleList(QPainter *painter, QRectF boundingRect, qreal diameter, const QList &colors, const QColor &borderColor); + static QPixmap getIconPixmap(const QIcon &icon, const QSize &size, qreal pixelRatio, QIcon::Mode mode = QIcon::Normal, QIcon::State state = QIcon::Off); + void paintDragIcon(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, const QSize &size) const; + QSize getIndexIconSize(const QStyleOptionViewItem &option, const QModelIndex &index, const QSize &size) const; + +protected: + DFMStyledItemDelegate(DFMStyledItemDelegatePrivate &dd, DFileViewHelper *parent); + + virtual void initTextLayout(const QModelIndex &index, QTextLayout *layout) const; + void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override; + QList getCornerGeometryList(const QRectF &baseRect, const QSizeF &cornerSize) const; + + static void paintIcon(QPainter *painter, const QIcon &icon, const QRectF &rect, Qt::Alignment alignment = Qt::AlignCenter, + QIcon::Mode mode = QIcon::Normal, QIcon::State state = QIcon::Off); + + QScopedPointer d_ptr; + + Q_PRIVATE_SLOT(d_ptr, void _q_onRowsInserted(const QModelIndex &parent, int first, int last)) + Q_PRIVATE_SLOT(d_ptr, void _q_onRowsRemoved(const QModelIndex &parent, int first, int last)) + + Q_DECLARE_PRIVATE(DFMStyledItemDelegate) + Q_DISABLE_COPY(DFMStyledItemDelegate) +}; diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmviewmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmviewmanager.cpp new file mode 100644 index 0000000..56fb4c5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmviewmanager.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfmviewmanager.h" +#include "dfmbaseview.h" + +#include "dfmviewfactory.h" +#include "dfileservices.h" + +#include "views/dfileview.h" +#include "views/computerview.h" +#include "views/dfmvaultfileview.h" +#include "plugins/schemepluginmanager.h" +#include + +DFM_BEGIN_NAMESPACE + +class DFMViewManagerPrivate +{ +public: + explicit DFMViewManagerPrivate(DFMViewManager *qq); + + DFMViewManager *q_ptr; + + QMultiHash controllerCreatorHash; +}; + +DFMViewManagerPrivate::DFMViewManagerPrivate(DFMViewManager *qq) + : q_ptr(qq) +{ + +} + +DFMViewManager *DFMViewManager::instance() +{ + static DFMViewManager manager; + + return &manager; +} + +bool DFMViewManager::isRegisted(const QString &scheme, const QString &host, const std::type_info &info) const +{ + Q_D(const DFMViewManager); + + const KeyType &type = KeyType(scheme, host); + auto values = d->controllerCreatorHash.values(type); + auto ret = std::any_of(values.begin(), values.end(), [&info](const ViewCreatorType & value) { + return value.first == info.name(); + }); + if (ret) + return true; + + return info == typeid(DFileView) && DFileService::instance()->isRegisted(scheme, host); +} + +void DFMViewManager::clearUrlView(const QString &scheme, const QString &host) +{ + Q_D(DFMViewManager); + + const KeyType handler(scheme, host); + + d->controllerCreatorHash.remove(handler); +} + +//NOTE [XIAO] 添加手机的DFileView +DFMBaseView *DFMViewManager::createViewByUrl(const DUrl &fileUrl) const +{ + Q_D(const DFMViewManager); + QList handlerTypeList; + + handlerTypeList << KeyType(fileUrl.scheme(), fileUrl.host()); + handlerTypeList << KeyType(QString(), fileUrl.host()); + handlerTypeList << KeyType(fileUrl.scheme(), QString()); + + for (const KeyType &handlerType : handlerTypeList) { + const QList creatorList = d->controllerCreatorHash.values(handlerType); + + if (!creatorList.isEmpty()) { + return (creatorList.first().second)(); + } + + if (DFileService::instance()->isRegisted(handlerType.first, handlerType.second)) { + return new DFileView(); + } + } + return nullptr; +} + +QString DFMViewManager::suitedViewTypeNameByUrl(const DUrl &fileUrl) const +{ + Q_D(const DFMViewManager); + QList handlerTypeList; + + handlerTypeList << KeyType(fileUrl.scheme(), fileUrl.host()); + handlerTypeList << KeyType(QString(), fileUrl.host()); + handlerTypeList << KeyType(fileUrl.scheme(), QString()); + for (const KeyType &handlerType : handlerTypeList) { + const QList creatorList = d->controllerCreatorHash.values(handlerType); + + if (!creatorList.isEmpty()) { + return creatorList.first().first; + } + + if (DFileService::instance()->isRegisted(handlerType.first, handlerType.second)) { + return typeid(DFileView).name(); + } + } + + return QString(); +} + +bool DFMViewManager::isSuited(const DUrl &fileUrl, const DFMBaseView *view) const +{ + const QString &type_name = suitedViewTypeNameByUrl(fileUrl); + + if (type_name == typeid(*view).name()) + return true; + + // plugin is suited + return DFMViewFactory::viewIsSuitedWithUrl(view, fileUrl); +} + +DFMViewManager::DFMViewManager(QObject *parent) + : QObject(parent) + , d_ptr(new DFMViewManagerPrivate(this)) +{ + + setObjectName(AC_FM_VIEW_MANAGER); + + dRegisterUrlView(COMPUTER_SCHEME, QString()); + + // vault view. + dRegisterUrlView(DFMVAULT_SCHEME, ""); + dRegisterUrlView(DFMVAULT_SCHEME, "setup"); + dRegisterUrlView(DFMVAULT_SCHEME, "delete"); + dRegisterUrlView(DFMVAULT_SCHEME, "unlock"); + dRegisterUrlView(DFMVAULT_SCHEME, "certificate"); + + // register plugins + // NOTE [XIAO] 注册手机的View + for (const QString &key : DFMViewFactory::keys()) { + const DUrl durl(key); + + insertToCreatorHash(KeyType(durl.scheme(), durl.host()), ViewCreatorType(typeid(DFMViewFactory).name(), [key] { + return DFMViewFactory::create(key); + })); + } + + //NOTE [XIAO] 从PLGUIN中加载View + initViewFromPlugin(); +} + +//NOTE [XIAO] 从PLGUIN中加载View +void DFMViewManager::initViewFromPlugin() +{ + qWarning() << "[PLUGIN]" << "try to load plugin of view"; + for (auto plugin : SchemePluginManager::instance()->schemePlugins()) { + qWarning() << "[PLUGIN]" << "load view from plugin:" << plugin.first; + insertToCreatorHash(KeyType(PLUGIN_SCHEME, plugin.first), plugin.second->createViewTypeFunc()); + } +} + +DFMViewManager::~DFMViewManager() +{ + +} + +void DFMViewManager::insertToCreatorHash(const DFMViewManager::KeyType &type, const DFMViewManager::ViewCreatorType &creator) +{ + Q_D(DFMViewManager); + + d->controllerCreatorHash.insertMulti(type, creator); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmviewmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmviewmanager.h new file mode 100644 index 0000000..82de7c6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dfmviewmanager.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFMVIEWMANAGER_H +#define DFMVIEWMANAGER_H + +#include "dfmglobal.h" + +#include + +#include + +DFM_BEGIN_NAMESPACE + +class DFMBaseView; +class DFMViewManagerPrivate; +class DFMViewManager : public QObject +{ + Q_OBJECT + + typedef QPair KeyType; + typedef QPair> ViewCreatorType; + +public: + static DFMViewManager *instance(); + + template + void dRegisterUrlView(const QString &scheme, const QString &host) + { + if (isRegisted(scheme, host)) + return; + + insertToCreatorHash(KeyType(scheme, host), ViewCreatorType(typeid(T).name(), [=] () { + return (DFMBaseView*)new T(); + })); + } + bool isRegisted(const QString &scheme, const QString &host, const std::type_info &info) const; + template + bool isRegisted(const QString &scheme, const QString &host) const + { + return isRegisted(scheme, host, typeid(T)); + } + + void clearUrlView(const QString &scheme, const QString &host); + + DFMBaseView *createViewByUrl(const DUrl &fileUrl) const; + QString suitedViewTypeNameByUrl(const DUrl &fileUrl) const; + bool isSuited(const DUrl &fileUrl, const DFMBaseView *view) const; + template + inline bool isSuited(const DUrl &fileUrl) const + { return suitedViewTypeNameByUrl(fileUrl) == typeid(T).name();} + +private: + explicit DFMViewManager(QObject *parent = 0); + ~DFMViewManager(); + //NOTE [XIAO] 从PLGUIN中加载View + void initViewFromPlugin(); + void insertToCreatorHash(const KeyType &type, const ViewCreatorType &creator); + + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(DFMViewManager) +}; + +DFM_END_NAMESPACE + +#endif // DFMVIEWMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dgvfsfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dgvfsfileinfo.cpp new file mode 100644 index 0000000..8327d17 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dgvfsfileinfo.cpp @@ -0,0 +1,570 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "dgvfsfileinfo.h" +#include "private/dgvfsfileinfo_p.h" +#include "app/define.h" + +#include "shutil/fileutils.h" + +#include "controllers/pathmanager.h" +#include "controllers/filecontroller.h" +#include "controllers/vaultcontroller.h" + +#include "app/define.h" +#include "singleton.h" +#include "usershare/usersharemanager.h" +#include "deviceinfo/udisklistener.h" +#include "tag/tagmanager.h" + +#include "dfileservices.h" +#include "dthumbnailprovider.h" +#include "dfileiconprovider.h" +#include "dmimedatabase.h" +#include "dabstractfilewatcher.h" +#include "dstorageinfo.h" +#include "shutil/danythingmonitorfilter.h" +#include "dfmapplication.h" + +#ifdef SW_LABEL +#include "sw_label/filemanagerlibrary.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +DFM_USE_NAMESPACE + + +int countFileCount(const char *name, bool isloop = false) +{ + DIR *dir; + struct dirent *entry; + int fileCount = 0; + + if (!(dir = opendir(name))) + return fileCount; + + while ((entry = readdir(dir))) { + //文件路径加名称最长支持为4k + char path[FILENAME_MAX + 1]; + int len = snprintf(path, sizeof(path)-1, "%s/%s", name, entry->d_name); + path[len] = 0; + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + continue; + if (entry->d_type == DT_DIR) { + if (isloop) { + fileCount += countFileCount(path, isloop); + } + else { + fileCount++; + } + } + else { + fileCount++; + } + } + + closedir(dir); + return fileCount; +} + + + +DGvfsFileInfoPrivate::DGvfsFileInfoPrivate(const DUrl &url, DGvfsFileInfo *qq, bool hasCache) + : DFileInfoPrivate(url, qq, hasCache) +{ + gvfsMountFile = true; +} + +DGvfsFileInfoPrivate::~DGvfsFileInfoPrivate() +{ +} + +DGvfsFileInfo::DGvfsFileInfo(const QString &filePath, bool hasCache) + : DGvfsFileInfo(DUrl::fromLocalFile(filePath), hasCache) +{ +} + +DGvfsFileInfo::DGvfsFileInfo(const DUrl &fileUrl, bool hasCache) + : DFileInfo(*new DGvfsFileInfoPrivate(fileUrl, this, hasCache)) +{ + //fix bug 27828 打开挂载文件(有很多的文件夹和文件)在断网的情况下,滑动鼠标或者滚动鼠标滚轮时文管卡死,做缓存 + refreshCachesByStat(); + canRename(); + isWritable(); + isSymLink(); + mimeType(); + size(); + //fix bug 35448 【文件管理器】【5.1.2.2-1】【sp2】预览ftp路径下某个文件夹后,文管卡死,访问特殊系统文件卡死 + //ftp挂载的系统proc中的文件夹获取filesCount,调用QDir和调用QDirIterator时,是gvfs文件的权限变成??? + //所以ftp和smb挂载点没有了,显示文件已被删除 + // filesCount(); +} + +DGvfsFileInfo::DGvfsFileInfo(const DUrl &fileUrl, const QMimeType &mimetype, bool hasCache) + : DFileInfo(*new DGvfsFileInfoPrivate(fileUrl, this, hasCache)) +{ + Q_D(const DGvfsFileInfo); + + if (mimetype.isValid()) { + d->mimeType = mimetype; + d->mimeTypeMode = QMimeDatabase::MatchExtension; + } + //fix bug 27828 打开挂载文件(有很多的文件夹和文件)在断网的情况下,滑动鼠标或者滚动鼠标滚轮时文管卡死,做缓存 + refreshCachesByStat(); + canRename(); + isWritable(); + isSymLink(); + exists(); + //必须在isWritable之后 + if (!mimetype.isValid()) { + mimeType(); + } + size(); + + //filesCount(); + //fix bug 35448 【文件管理器】【5.1.2.2-1】【sp2】预览ftp路径下某个文件夹后,文管卡死,访问特殊系统文件卡死 + //ftp挂载的系统proc中的文件夹获取filesCount,调用QDir和调用QDirIterator时,是gvfs文件的权限变成??? + //所以ftp和smb挂载点没有了,显示文件已被删除 +} + +DGvfsFileInfo::DGvfsFileInfo(const QFileInfo &fileInfo, bool hasCache) + : DGvfsFileInfo(DUrl::fromLocalFile(fileInfo.absoluteFilePath()), hasCache) +{ + +} + +DGvfsFileInfo::DGvfsFileInfo(const QFileInfo &fileInfo, const QMimeType &mimetype, bool hasCache) + : DGvfsFileInfo(DUrl::fromLocalFile(fileInfo.absoluteFilePath()), mimetype, hasCache) +{ + +} + +DGvfsFileInfo::~DGvfsFileInfo() +{ + +} + +bool DGvfsFileInfo::exists() const +{ + Q_D(const DGvfsFileInfo); + + if (d->cacheFileExists < 0) + d->cacheFileExists = d->fileInfo.exists() || d->fileInfo.isSymLink(); + + if (d->cacheFileExists >= 0) + return d->cacheFileExists; + + return d->fileInfo.exists() || d->fileInfo.isSymLink(); +} + +bool DGvfsFileInfo::canRename() const +{ + if (systemPathManager->isSystemPath(absoluteFilePath())) + return false; + Q_D(const DGvfsFileInfo); + //fix bug 27828 修改gvfsMountFile属性时,也要缓存属性,才不会造成ftp和smb卡死 + if (d->cacheCanRename < 0) { + d->cacheCanRename = DFileInfo::fileIsWritable(d->fileInfo.absolutePath(), static_cast(inode())); + } + + if (d->cacheCanRename >= 0) + return d->cacheCanRename; + + return fileIsWritable(d->fileInfo.absolutePath(), d->fileInfo.ownerId()); +} + +bool DGvfsFileInfo::isWritable() const +{ + if (isPrivate()) + return false; + + Q_D(const DGvfsFileInfo); + //fix bug 27828 打开挂载文件(有很多的文件夹和文件)在断网的情况下,滑动鼠标或者滚动鼠标滚轮时文管卡死,做缓存 + if (d->cacheCanWrite < 0) { + d->cacheCanWrite = access(d->fileInfo.absoluteFilePath().toStdString().c_str(), W_OK) == 0 ? 1 : 0; + } + return d->cacheCanWrite; +} + +bool DGvfsFileInfo::makeAbsolute() +{ + Q_D(DGvfsFileInfo); + + return d->fileInfo.makeAbsolute(); +} + +bool DGvfsFileInfo::isSymLink() const +{ + Q_D(const DGvfsFileInfo); + //fix bug 27828 修改gvfsMountFile属性时,也要缓存属性,才不会造成ftp和smb卡死 + if (d->cacheIsSymLink < 0) { + d->cacheIsSymLink = d->fileInfo.isSymLink(); + } + + if (d->cacheIsSymLink >= 0) { + return d->cacheIsSymLink != 0; + } + + return d->fileInfo.isSymLink(); +} + +bool DGvfsFileInfo::isDir() const +{ + Q_D(const DGvfsFileInfo); + + if (d->cacheIsDir > -1) { + return d->cacheIsDir; + } + + const_cast(this)->refreshCachesByStat(); + + if (d->cacheIsDir > -1) { + return d->cacheIsDir; + } + + return d->fileInfo.isDir(); +} + +QDateTime DGvfsFileInfo::lastRead() const +{ + Q_D(const DGvfsFileInfo); + if (d->cacheReadTime > -1) { + return QDateTime::fromTime_t(static_cast(d->cacheReadTime)); + } + + const_cast(this)->refreshCachesByStat(); + + if (d->cacheReadTime > -1) { + return QDateTime::fromTime_t(static_cast(d->cacheReadTime)); + } + + return d->fileInfo.lastRead(); +} + +QDateTime DGvfsFileInfo::lastModified() const +{ + Q_D(const DGvfsFileInfo); + if (d->cacheModifyTime > -1) { + return QDateTime::fromTime_t(static_cast(d->cacheModifyTime)); + } + + const_cast(this)->refreshCachesByStat(); + + if (d->cacheModifyTime > -1) { + return QDateTime::fromTime_t(static_cast(d->cacheModifyTime)); + } + + return d->fileInfo.lastModified(); +} + + +uint DGvfsFileInfo::ownerId() const +{ + Q_D(const DGvfsFileInfo); + + if (-1 != d->ownerid) { + return static_cast(d->ownerid); + } + + return d->fileInfo.ownerId(); +} + + +qint64 DGvfsFileInfo::size() const +{ + Q_D(const DGvfsFileInfo); + + if (d->cacheFileSize < 0) { + d->cacheFileSize = d->fileInfo.size(); + } + + if (d->cacheFileSize >= 0) { + return d->cacheFileSize; + } + + return d->fileInfo.size(); +} + +int DGvfsFileInfo::filesCount() const +{ + Q_D(const DGvfsFileInfo); + + if (d->cacheFileCount < 0) { + if (isDir()) { + d->cacheFileCount = countFileCount(absoluteFilePath().toUtf8().toStdString().c_str()); + } + else + return -1; + } + return d->cacheFileCount; +} + +QMimeType DGvfsFileInfo::mimeType(QMimeDatabase::MatchMode mode) const +{ + Q_D(const DGvfsFileInfo); + Q_UNUSED(mode) + + if (!d->mimeType.isValid()) { + //优化是苹果的就用新的minetype + DUrl url = fileUrl(); + //这里必须先缓存inod + if (d->inode > 0) { + QString inode = fileUrl().path() + QString::number(d->inode); + d->mimeType = DFileInfo::mimeType(fileUrl().path(), QMimeDatabase::MatchExtension, inode); + } + else { + d->mimeType = DFileInfo::mimeType(fileUrl().path(), QMimeDatabase::MatchExtension); + } + d->mimeTypeMode = QMimeDatabase::MatchExtension; + } + + return d->mimeType; +} + +void DGvfsFileInfo::refresh(const bool isForce) +{ + if (!isForce) { + return; + } + Q_D(DGvfsFileInfo); + DFileInfo::refresh(isForce); + + //fix bug 27828 打开挂载文件(有很多的文件夹和文件)在断网的情况下,滑动鼠标或者滚动鼠标滚轮时文管卡死,做缓存 + d->cacheCanWrite = -1; + d->cacheCanRename = -1; + d->cacheIsSymLink = -1; + //fix bug 35831 cacheFileExists也需要清空 否则文件存在会被误判 + d->cacheFileExists = -1; + d->ownerid = -1; + d->cacheIsDir = -1; + quint64 oldinod = d->inode; + refreshCachesByStat(); + + canRename(); + isWritable(); + isSymLink(); + if (!(oldinod > 0 && oldinod == d->inode)){ + mimeType(); + } + size(); + filesCount(); + //fix bug 35448 【文件管理器】【5.1.2.2-1】【sp2】预览ftp路径下某个文件夹后,文管卡死,访问特殊系统文件卡死 + //ftp挂载的系统proc中的文件夹获取filesCount,调用QDir和调用QDirIterator时,是gvfs文件的权限变成??? + //所以ftp和smb挂载点没有了,显示文件已被删除 +} + + +void DGvfsFileInfo::makeToActive() +{ + Q_D(DGvfsFileInfo); + + d->fileInfo.refresh(); + + DAbstractFileInfo::makeToActive(); +} + +quint64 DGvfsFileInfo::inode() const +{ + Q_D(const DGvfsFileInfo); + return d->inode; +} +//用stat刷新所有的缓存 +void DGvfsFileInfo::refreshCachesByStat() +{ + Q_D(DGvfsFileInfo); + + struct stat statinfo; + int filestat = stat(d->fileInfo.absoluteFilePath().toStdString().c_str(), &statinfo); + if (filestat != 0) { + d->ownerid = static_cast(getuid()); + return; + } + d->cacheCanWrite = access(d->fileInfo.absoluteFilePath().toStdString().c_str(), W_OK) == 0 ? 1 : 0; + d->cacheIsSymLink = S_ISLNK(statinfo.st_mode); + d->cacheFileSize = statinfo.st_size; + d->inode = statinfo.st_ino; + d->ownerid = static_cast(statinfo.st_uid); + d->cacheIsDir = S_ISDIR(statinfo.st_mode); + d->cacheModifyTime = statinfo.st_mtim.tv_sec; + d->cacheReadTime = statinfo.st_atim.tv_sec; +} + +bool DGvfsFileInfo::canDragCompress() const +{ + // gvfs(smb/ftp/sftp/手机)文件不支持拖拽压缩 + return false; +} + +DGvfsFileInfo::DGvfsFileInfo(DGvfsFileInfoPrivate &dd) + : DFileInfo(dd) +{ + +} + +QIcon DGvfsFileInfo::fileIcon() const +{ + Q_D(const DFileInfo); + + if (!d->icon.isNull() && !d->needThumbnail && (!d->iconFromTheme || !d->icon.name().isEmpty())) { + return d->icon; + } + + d->iconFromTheme = false; + + const DUrl &fileUrl = this->fileUrl(); + +#ifdef DFM_MINIMUM + d->hasThumbnail = 0; +#else + if (fileUrl.toString().contains(VaultController::makeVaultLocalPath())) { + d->hasThumbnail = DThumbnailProvider::instance()->hasThumbnail(d->fileInfo) && !DStorageInfo::isCdRomDevice(absoluteFilePath()); + } else { + d->hasThumbnail = false; + } +#endif + if (d->needThumbnail || d->hasThumbnail > 0) { + d->needThumbnail = true; + + const QIcon icon(DThumbnailProvider::instance()->thumbnailFilePath(d->fileInfo, DThumbnailProvider::Large)); + + if (!icon.isNull()) { + QPixmap pixmap = icon.pixmap(DThumbnailProvider::Large, DThumbnailProvider::Large); + QPainter pa(&pixmap); + + pa.setPen(Qt::gray); + pa.drawPixmap(0, 0, pixmap); + d->icon.addPixmap(pixmap); + d->iconFromTheme = false; + d->needThumbnail = false; + + return d->icon; + } + + if (d->getIconTimer) { + QMetaObject::invokeMethod(d->getIconTimer, "start", Qt::QueuedConnection); + } else if (isActive()) { + QTimer *timer = new QTimer(); + const QExplicitlySharedDataPointer me(const_cast(this)); + + d->getIconTimer = timer; + timer->setSingleShot(true); + timer->moveToThread(qApp->thread()); + timer->setInterval(500); + + QObject::connect(timer, &QTimer::timeout, timer, [fileUrl, timer, me] { + DThumbnailProvider::instance()->appendToProduceQueue(me->d_func()->fileInfo, DThumbnailProvider::Large, + [me](const QString & path) + { + DThreadUtil::runInMainThread([me, path]() { + if (path.isEmpty()) { + me->d_func()->iconFromTheme = true; + } else { + // clean old icon + me->d_func()->icon = QIcon(); + } + + me->d_func()->needThumbnail = false; + }); + + }); + me->d_func()->requestingThumbnail = true; + timer->deleteLater(); + }); + + QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection); + } + + if (d->icon.isNull()) + d->icon = DFileIconProvider::globalProvider()->icon(*this); + + return d->icon; + } else { + d->needThumbnail = false; + } + + if (isSymLink()) { + const DUrl &symLinkTarget = this->symLinkTarget(); + + if (symLinkTarget != fileUrl) { + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, symLinkTarget); + + if (fileInfo) { + d->icon = fileInfo->fileIcon(); + d->iconFromTheme = false; + + return d->icon; + } + } + } + + d->icon = DFileIconProvider::globalProvider()->icon(*this); + d->iconFromTheme = true; + + return d->icon; +} + + +QList DGvfsFileInfo::additionalIcon() const +{ + Q_D(const DFileInfo); + + if (d->proxy) + return d->proxy->additionalIcon(); + + QList icons; + + // wayland TASK-38720 修复重命名文件时,文件图标有小锁显示的问题, + // 当为快捷方式时,有源文件文件不存在的情况,所以增加特殊判断 + if (!isSymLink()) { + if (exists()) + return icons; + } + + if (isSymLink()) { + icons << QIcon::fromTheme("emblem-symbolic-link", DFMGlobal::instance()->standardIcon(DFMGlobal::LinkIcon)); + } + + if (isShared()) { + icons << QIcon::fromTheme("emblem-shared", DFMGlobal::instance()->standardIcon(DFMGlobal::ShareIcon)); + } + +#ifdef SW_LABEL + QString labelIconPath = getLabelIcon(); + if (!labelIconPath.isEmpty()) { + icons << QIcon(labelIconPath); + } +#endif + + return icons; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dgvfsfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dgvfsfileinfo.h new file mode 100644 index 0000000..7b740ce --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dgvfsfileinfo.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DGVFSFILEINFO_H +#define DGVFSFILEINFO_H + + +#include "dfileinfo.h" + +class DGvfsFileInfoPrivate; +class DGvfsFileInfo : public DFileInfo +{ +public: + explicit DGvfsFileInfo(const QString &filePath, bool hasCache = true); + explicit DGvfsFileInfo(const DUrl &fileUrl, bool hasCache = true); + explicit DGvfsFileInfo(const DUrl &fileUrl, const QMimeType &mimetype, bool hasCache = true); + explicit DGvfsFileInfo(const QFileInfo &fileInfo, bool hasCache = true); + explicit DGvfsFileInfo(const QFileInfo &fileInfo, const QMimeType &mimetype, bool hasCache = true); + ~DGvfsFileInfo() override; + + bool exists() const override; + bool canRename() const override; + bool isWritable() const override; + bool makeAbsolute() override; + bool isSymLink() const override; + bool isDir() const override; + QDateTime lastRead() const override; + QDateTime lastModified() const override; + uint ownerId() const override; + qint64 size() const override; + int filesCount() const override; + QMimeType mimeType(QMimeDatabase::MatchMode mode = QMimeDatabase::MatchDefault) const override; + + void refresh(const bool isForce = false) override; + void makeToActive() override; + quint64 inode() const override; + QIcon fileIcon() const override; + QList additionalIcon() const override; + + void refreshCachesByStat(); + + /** + * @brief canDragCompress 是否支持拖拽压缩 + * @return + */ + bool canDragCompress() const override; + + +protected: + explicit DGvfsFileInfo(DGvfsFileInfoPrivate &dd); + +private: + Q_DECLARE_PRIVATE(DGvfsFileInfo) + + friend class RequestGvfsEP; +}; +#endif // DGVFSFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/diconitemdelegate.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/diconitemdelegate.cpp new file mode 100644 index 0000000..2c0c367 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/diconitemdelegate.cpp @@ -0,0 +1,1422 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "diconitemdelegate.h" +#include "dfileviewhelper.h" +#include "views/fileitem.h" +#include "private/dstyleditemdelegate_p.h" +#include "dfmapplication.h" +#include "dfilesystemmodel.h" +#include "tag/tagmanager.h" +#include "app/define.h" +#include "dfmglobal.h" + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE +DFM_USE_NAMESPACE + +#define ICON_SPACING 16 +#define ICON_MODE_RECT_RADIUS TEXT_PADDING +#define ICON_MODE_BACK_RADIUS 18 + +QRectF boundingRect(const QList &rects) +{ + QRectF bounding; + + if (rects.isEmpty()) + return bounding; + + bounding = rects.first(); + + for (const QRectF &r : rects) { + if (r.top() < bounding.top()) { + bounding.setTop(r.top()); + } + + if (r.left() < bounding.left()) { + bounding.setLeft(r.left()); + } + + if (r.right() > bounding.right()) { + bounding.setRight(r.right()); + } + + if (r.bottom() > bounding.bottom()) { + bounding.setBottom(r.bottom()); + } + } + + return bounding; +} + +QPainterPath boundingPath(QList rects, qreal radius, qreal padding) +{ + QPainterPath path; + const QMarginsF margins(radius + padding, 0, radius + padding, 0); + + if (rects.count() == 1) { + path.addRoundedRect(rects.first().marginsAdded(margins).adjusted(0, -padding, 0, padding), radius, radius); + + return path; + } + + auto joinRightCorner = [&](const QRectF & rect, const QRectF & prevRect, const QRectF & nextRect) { + if (Q_LIKELY(prevRect.isValid())) { + qreal new_radius = qMin(radius, qAbs(prevRect.right() - rect.right()) / 2); + + if (rect.right() > prevRect.right()) { + path.arcTo(rect.right() - new_radius * 2, rect.y() - padding, new_radius * 2, new_radius * 2, 90, -90); + } else if (rect.right() < prevRect.right()) { + path.arcTo(rect.right(), rect.y() + padding, new_radius * 2, new_radius * 2, 90, 90); + } + } else { + path.arcTo(rect.right() - radius * 2, rect.y() - padding, radius * 2, radius * 2, 90, -90); + } + + if (Q_LIKELY(nextRect.isValid())) { + qreal new_radius = qMin(radius, qAbs(nextRect.right() - rect.right()) / 2); + + if (rect.right() > nextRect.right()) { + path.arcTo(rect.right() - new_radius * 2, rect.bottom() - new_radius * 2 + padding, new_radius * 2, new_radius * 2, 0, -90); + } else if (rect.right() < nextRect.right()) { + path.arcTo(rect.right(), rect.bottom() - new_radius * 2 - padding, new_radius * 2, new_radius * 2, 180, 90); + } + } else { + path.arcTo(rect.right() - radius * 2, rect.bottom() - radius * 2 + padding, radius * 2, radius * 2, 0, -90); + } + }; + + auto joinLeftCorner = [&](const QRectF & rect, const QRectF & prevRect, const QRectF & nextRect) { + if (Q_LIKELY(nextRect.isValid())) { + qreal new_radius = qMin(radius, qAbs(nextRect.x() - rect.x()) / 2); + + if (rect.x() > nextRect.x()) { + path.arcTo(rect.x() - new_radius * 2, rect.bottom() - new_radius * 2 - padding, new_radius * 2, new_radius * 2, 270, 90); + } else if (rect.x() < nextRect.x()) { + path.arcTo(rect.x(), rect.bottom() - new_radius * 2 + padding, new_radius * 2, new_radius * 2, 270, -90); + } + } else { + path.arcTo(rect.x(), rect.bottom() - radius * 2 + padding, radius * 2, radius * 2, 270, -90); + } + + if (Q_LIKELY(prevRect.isValid())) { + qreal new_radius = qMin(radius, qAbs(prevRect.x() - rect.x()) / 2); + + if (rect.x() > prevRect.x()) { + path.arcTo(rect.x() - new_radius * 2, rect.y() + padding, new_radius * 2, new_radius * 2, 0, 90); + } else if (rect.x() < prevRect.x()) { + path.arcTo(rect.x(), rect.y() - padding, new_radius * 2, new_radius * 2, 180, -90); + } + } else { + path.arcTo(rect.x(), rect.y() - padding, radius * 2, radius * 2, 180, -90); + } + }; + + auto preproccess = [&](QRectF & rect, const QRectF & prev) { + if (qAbs(rect.x() - prev.x()) < radius) { + rect.setLeft(prev.x()); + } + + if (qAbs(rect.right() - prev.right()) < radius) { + rect.setRight(prev.right()); + } + }; + + for (int i = 1; i < rects.count(); ++i) { + preproccess(rects[i], rects.at(i - 1)); + } + + const QRectF &first = rects.first().marginsAdded(margins); + + path.arcMoveTo(first.right() - radius * 2, first.y() - padding, radius * 2, radius * 2, 90); + joinRightCorner(first, QRectF(), rects.at(1).marginsAdded(margins)); + + for (int i = 1; i < rects.count() - 1; ++i) { + joinRightCorner(rects.at(i) + margins, rects.at(i - 1).marginsAdded(margins), rects.at(i + 1).marginsAdded(margins)); + } + + QRectF last = rects.last(); + const QRectF &prevRect = rects.at(rects.count() - 2); + + joinRightCorner(last.marginsAdded(margins), prevRect.marginsAdded(margins), QRectF()); + joinLeftCorner(last.marginsAdded(margins), prevRect.marginsAdded(margins), QRectF()); + + for (int i = rects.count() - 2; i > 0; --i) { + joinLeftCorner(rects.at(i) + margins, rects.at(i - 1).marginsAdded(margins), rects.at(i + 1).marginsAdded(margins)); + } + + joinLeftCorner(first, QRectF(), rects.at(1).marginsAdded(margins)); + + path.closeSubpath(); + + return path; +} + +class TagTextFormat : public QTextCharFormat +{ +public: + TagTextFormat(int objectType, const QList &colors, const QColor &borderColor); + + QList colors() const; + QColor borderColor() const; + qreal diameter() const; +}; + +TagTextFormat::TagTextFormat(int objectType, const QList &colors, const QColor &borderColor) +{ + setObjectType(objectType); + setProperty(QTextFormat::UserProperty + 1, QVariant::fromValue(colors)); + setProperty(QTextFormat::UserProperty + 2, borderColor); +} + +QList TagTextFormat::colors() const +{ + return qvariant_cast>(property(QTextFormat::UserProperty + 1)); +} + +QColor TagTextFormat::borderColor() const +{ + return colorProperty(QTextFormat::UserProperty + 2); +} + +qreal TagTextFormat::diameter() const +{ + return 12; +} + +class FileTagObjectInterface : public QObject, public QTextObjectInterface +{ + Q_OBJECT + Q_INTERFACES(QTextObjectInterface) + +public: + explicit FileTagObjectInterface() + : QObject() + { + + } + + QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, + const QTextFormat &format) override; + + void drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc, + int posInDocument, const QTextFormat &format) override; +}; + +QSizeF FileTagObjectInterface::intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format) +{ + Q_UNUSED(posInDocument) + Q_UNUSED(doc) + + const TagTextFormat &f = static_cast(format); + const QList &colors = f.colors(); + const double diameter = f.diameter(); + + if (colors.size() == 1) + return QSizeF(diameter, diameter); + + return QSizeF(diameter + (colors.size() - 1) * diameter / 2.0, diameter); +} + +void FileTagObjectInterface::drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format) +{ + Q_UNUSED(posInDocument) + Q_UNUSED(doc) + + const TagTextFormat &f = static_cast(format); + const QList &colors = f.colors(); + const QColor borderColor = f.borderColor(); + qreal diameter = f.diameter(); + const qreal padding = diameter / 10.0; + QRectF bounding_rect = rect.marginsRemoved(QMarginsF(padding, padding, padding, padding)); + + diameter -= padding * 2; + + DFMStyledItemDelegate::paintCircleList(painter, bounding_rect, diameter, colors, borderColor); +} + +class ExpandedItem : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) + +public: + explicit ExpandedItem(DIconItemDelegate *d, QWidget *parent = nullptr) + : QWidget(parent) + , delegate(d) + { + + } + + bool event(QEvent *ee) override + { + if (ee->type() == QEvent::DeferredDelete) { + if (!canDeferredDelete) { + ee->accept(); + + return true; + } + } + + return QWidget::event(ee); + } + + qreal opacity() const + { + return m_opactity; + } + + void setOpacity(qreal opacity) + { + if (qFuzzyCompare(opacity, m_opactity)) + return; + + m_opactity = opacity; + + update(); + } + + void paintEvent(QPaintEvent *) override + { + QPainter pa(this); + + pa.setOpacity(m_opactity); + pa.setPen(option.palette.color(QPalette::BrightText)); + pa.setFont(option.font); + + if (!iconPixmap.isNull()) { + pa.drawPixmap(iconGeometry().topLeft().toPoint(), iconPixmap); + } + + if (option.text.isEmpty()) + return; + + const QMargins &margins = contentsMargins(); + + QRect label_rect(TEXT_PADDING + margins.left(), + margins.top() + iconHeight + TEXT_PADDING + ICON_MODE_ICON_SPACING, + width() - TEXT_PADDING * 2 - margins.left() - margins.right(), + INT_MAX); + + QString str = index.data(DFileSystemModel::FileDisplayNameRole).toString(); + const QList &lines = delegate->drawText(index, &pa, str, label_rect, ICON_MODE_RECT_RADIUS, + option.palette.brush(QPalette::Normal, QPalette::Highlight), + QTextOption::WrapAtWordBoundaryOrAnywhere, + option.textElideMode, Qt::AlignCenter); + + textBounding = boundingRect(lines).toRect(); + } + + QSize sizeHint() const override + { + return QSize(width(), FLOOR(textGeometry().bottom() + contentsMargins().bottom())); + } + + int heightForWidth(int width) const override + { + if (width != this->width()) { + textBounding = QRect(); + } + + return FLOOR(textGeometry(width).bottom() + contentsMargins().bottom()); + } + + void setIconPixmap(const QPixmap &pixmap, int height) + { + iconPixmap = pixmap; + iconHeight = height; + update(); + } + + QRectF iconGeometry() const + { + const QRect &content_rect = contentsRect(); + + if (iconPixmap.isNull()) { + QRectF rect(content_rect); + + rect.setHeight(iconHeight); + + return rect; + } + + QRectF icon_rect(QPointF((content_rect.width() - iconPixmap.width() / iconPixmap.devicePixelRatio()) / 2.0, + (iconHeight - iconPixmap.height() / iconPixmap.devicePixelRatio()) / 2.0 + content_rect.top()), + iconPixmap.size() / iconPixmap.devicePixelRatio()); + + return icon_rect; + } + + QRectF textGeometry(int width = -1) const + { + if (textBounding.isEmpty() && !option.text.isEmpty()) { + const QMargins &margins = contentsMargins(); + + if (width < 0) + width = this->width(); + + width -= (margins.left() + margins.right()); + + QRect label_rect(TEXT_PADDING + margins.left(), + iconHeight + TEXT_PADDING + ICON_MODE_ICON_SPACING + margins.top(), + width - TEXT_PADDING * 2, + INT_MAX); + + QString str = index.data(DFileSystemModel::FileDisplayNameRole).toString(); + const QList &lines = delegate->drawText(index, nullptr, str, label_rect, ICON_MODE_RECT_RADIUS, Qt::NoBrush, + QTextOption::WrapAtWordBoundaryOrAnywhere, option.textElideMode, Qt::AlignCenter); + + textBounding = boundingRect(lines); + } + + return textBounding;; + } + + QPixmap iconPixmap; + int iconHeight = 0; + mutable QRectF textBounding; + QModelIndex index; + QStyleOptionViewItem option; + qreal m_opactity = 1; + bool canDeferredDelete = true; + DIconItemDelegate *delegate; +}; + +class DIconItemDelegatePrivate : public DFMStyledItemDelegatePrivate +{ +public: + explicit DIconItemDelegatePrivate(DIconItemDelegate *qq) + : DFMStyledItemDelegatePrivate(qq) + {} + + QSize textSize(const QString &text, const QFontMetrics &metrics, int lineHeight = -1) const; + QPixmap getFileIconPixmap(const QModelIndex &index, const QIcon &icon, const QSize &icon_size, QIcon::Mode mode, qreal devicePixelRatio) const; + + QPointer expandedItem; + + // mutable QHash elideMap; + // mutable QHash wordWrapMap; + // mutable QHash textHeightMap; + mutable QModelIndex expandedIndex; + mutable QModelIndex lastAndExpandedInde; + + QList iconSizes; + /// default icon size is 64px. + int currentIconSizeIndex = 1; + + QColor focusTextBackgroundBorderColor; + bool enabledTextShadow = false; + // 最后一次绘制item时是否画了背景 + mutable bool drawTextBackgroundOnLast = true; + + QTextDocument *document = nullptr; + + static int textObjectType; + static FileTagObjectInterface *textObjectInterface; + + Q_DECLARE_PUBLIC(DIconItemDelegate) +}; + +int DIconItemDelegatePrivate::textObjectType = QTextFormat::UserObject + 1; +FileTagObjectInterface *DIconItemDelegatePrivate::textObjectInterface = new FileTagObjectInterface(); + +QSize DIconItemDelegatePrivate::textSize(const QString &text, const QFontMetrics &metrics, int lineHeight) const +{ + QString str = text; + + if (str.endsWith('\n')) + str.chop(1); + + int max_width = 0; + int height = 0; + + for (const QString &line : str.split('\n')) { + max_width = qMax(metrics.width(line), max_width); + + if (lineHeight > 0) + height += lineHeight; + else + height += metrics.height(); + } + + return QSize(max_width, height); +} +QPixmap DIconItemDelegatePrivate::getFileIconPixmap(const QModelIndex &index, const QIcon &icon, const QSize &icon_size, QIcon::Mode mode, qreal devicePixelRatio) const +{ + Q_Q(const DIconItemDelegate); + + QPixmap pixmap = q->getIconPixmap(icon, icon_size, devicePixelRatio, mode); + QPainter painter(&pixmap); + + /// draw file additional icon + + QList cornerGeometryList = q->getCornerGeometryList(QRect(QPoint(0, 0), icon_size), icon_size / 3); + const QList &cornerIconList = q->parent()->additionalIcon(index); + + for (int i = 0; i < cornerIconList.count(); ++i) { + if (cornerIconList.at(i).isNull()) { + continue; + } + cornerIconList.at(i).paint(&painter, cornerGeometryList.at(i).toRect()); + } + + return pixmap; +} + +DIconItemDelegate::DIconItemDelegate(DFileViewHelper *parent) + : DFMStyledItemDelegate(*new DIconItemDelegatePrivate(this), parent) + , m_checkedIcon(QIcon::fromTheme("emblem-checked")) +{ + QMutexLocker lk(&m_mutex); + Q_D(DIconItemDelegate); + + d->expandedItem = new ExpandedItem(this, parent->parent()->viewport()); + d->expandedItem->setAttribute(Qt::WA_TransparentForMouseEvents); + d->expandedItem->canDeferredDelete = false; + d->expandedItem->setContentsMargins(0, 0, 0, 0); + /// prevent flash when first call show() + d->expandedItem->setFixedWidth(0); + + d->iconSizes << 48 << 64 << 96 << 128 << 256; + + connect(parent, &DFileViewHelper::triggerEdit, this, &DIconItemDelegate::onTriggerEdit); + + parent->parent()->setIconSize(iconSizeByIconSizeLevel()); +} + +DIconItemDelegate::~DIconItemDelegate() +{ + QMutexLocker lk(&m_mutex); + Q_D(DIconItemDelegate); + + if (d->expandedItem) { + d->expandedItem->setParent(nullptr); + d->expandedItem->canDeferredDelete = true; + d->expandedItem->deleteLater(); + } +} + +QT_BEGIN_NAMESPACE +Q_WIDGETS_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0); +QT_END_NAMESPACE + +void DIconItemDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QMutexLocker lk(&(const_cast(this)->m_mutex)); + Q_D(const DIconItemDelegate); + + bool isCanvas = parent()->property("isCanvasViewHelper").toBool(); + /// judgment way of the whether drag model(another way is: painter.devType() != 1) + bool isDragMode = (static_cast(parent()->parent()->viewport()) != painter->device()); + bool isEnabled = option.state & QStyle::State_Enabled; + bool hasFocus = option.state & QStyle::State_HasFocus; + + if (index == d->expandedIndex && !parent()->isSelected(index)) + const_cast(this)->hideNotEditingIndexWidget(); + + painter->setOpacity(parent()->isTransparent(index) ? 0.3 : 1.0); + + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + painter->setFont(opt.font); + + static QFont old_font = opt.font; + + if (old_font != opt.font) { + if (d->expandedItem) + d->expandedItem->setFont(opt.font); + + QWidget *editing_widget = editingIndexWidget(); + + if (editing_widget) + editing_widget->setFont(opt.font); + + const_cast(this)->updateItemSizeHint(); + // parent()->parent()->updateEditorGeometries(); + } + + old_font = opt.font; + + bool isSelected = !isDragMode && (opt.state & QStyle::State_Selected) && opt.showDecorationSelected; + bool isDropTarget = parent()->isDropTarget(index); + + DPalette pl(DApplicationHelper::instance()->palette(option.widget)); + QColor c = pl.color(DPalette::ColorGroup::Active, DPalette::ColorType::ItemBackground); + QColor base_color = c; + if (option.widget) { + DPalette pa = DApplicationHelper::instance()->palette(option.widget); + base_color = option.widget->palette().base().color(); + DGuiApplicationHelper::ColorType ct = DGuiApplicationHelper::toColorType(base_color); + if (ct == DGuiApplicationHelper::DarkType) { + base_color = DGuiApplicationHelper::adjustColor(base_color, 0, 0, +5, 0, 0, 0, 0); + } + } + + if ((isDropTarget && !isSelected) || option.state & QStyle::StateFlag::State_Selected) { + if (isCanvas) { + c = pl.color(DPalette::ColorGroup::Active, QPalette::ColorRole::Highlight); + } else { + c.setAlpha(c.alpha() + 30); + } + } else if (option.state & QStyle::StateFlag::State_MouseOver) { + DGuiApplicationHelper::ColorType ct = DGuiApplicationHelper::toColorType(base_color); + if (ct == DGuiApplicationHelper::DarkType) { + base_color = DGuiApplicationHelper::adjustColor(base_color, 0, 0, +5, 0, 0, 0, 0); + c = base_color; + } + else + c = c.lighter(); + } else if (!isCanvas) { + c = base_color; + } + + QRectF rect = opt.rect; + int backgroundMargin = isCanvas ? 0 : COLUMU_PADDING; + if (!isCanvas) + rect.adjust(backgroundMargin, backgroundMargin, -backgroundMargin, -backgroundMargin); // 为了让对勾右上角, 缩小框框 + + QPainterPath path; + rect.moveTopLeft(QPointF(0.5, 0.5) + rect.topLeft()); + path.addRoundedRect(rect, ICON_MODE_BACK_RADIUS, ICON_MODE_BACK_RADIUS); + + if (!isCanvas && !isDragMode) { // 桌面和拖拽的图标不画背景 + painter->setRenderHint(QPainter::Antialiasing, true); + painter->fillPath(path, c); + painter->setRenderHint(QPainter::Antialiasing, false); + } + + if (isDropTarget && !isSelected) { + painter->setPen(c); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->drawPath(path); + painter->setRenderHint(QPainter::Antialiasing, false); + } + + /// init icon geomerty + QRectF icon_rect = opt.rect; + + icon_rect.setSize(parent()->parent()->iconSize()); + double iconTopOffset = isCanvas ? 0 : (opt.rect.height() - icon_rect.height()) / 3.0; + icon_rect.moveLeft(opt.rect.left() + (opt.rect.width() - icon_rect.width()) / 2.0); + icon_rect.moveTop(opt.rect.top() + iconTopOffset); // move icon down + + /// draw icon + if (isSelected) { + paintIcon(painter, opt.icon, icon_rect, Qt::AlignCenter, isEnabled ? QIcon::Normal : QIcon::Disabled); + } else if (isDropTarget) { + QPixmap pixmap = opt.icon.pixmap(icon_rect.size().toSize()); + QPainter p(&pixmap); + + p.setCompositionMode(QPainter::CompositionMode_SourceAtop); + p.fillRect(QRect(QPoint(0, 0), icon_rect.size().toSize()), QColor(0, 0, 0, CEIL(255 * 0.1))); + p.end(); + + painter->drawPixmap(icon_rect.toRect(), pixmap); + } else { + paintIcon(painter, opt.icon, icon_rect, Qt::AlignCenter, isEnabled ? QIcon::Normal : QIcon::Disabled); + } + + /// draw file additional icon + + const QSizeF &cornerBaseSize = icon_rect.size() / 3; + QList cornerGeometryList = getCornerGeometryList(icon_rect, QSizeF(qMin(24.0, cornerBaseSize.width()), qMin(24.0, cornerBaseSize.height()))); + const QList &cornerIconList = parent()->additionalIcon(index); + + for (int i = 0; i < cornerIconList.count(); ++i) { + if (cornerIconList.at(i).isNull()) { + continue; + } + cornerIconList.at(i).paint(painter, cornerGeometryList.at(i).toRect()); + } + + if (!isCanvas && isSelected) { + QRect rc = option.rect; + rc.setSize({20, 20}); + rc.moveTopRight(QPoint(option.rect.right() - 5, option.rect.top() + 5)); + + DStyleOptionButton check; + check.state = DStyle::State_Enabled | DStyle::State_On; + check.rect = rc; + + DApplication::style()->drawPrimitive(DStyle::PE_IndicatorItemViewItemCheck, &check, painter); + } + + if (index == d->editingIndex && !isDragMode) { + // 正在编辑的item,不重绘text + return; + } + + if (index == d->expandedIndex && !isDragMode + && d->expandedItem && d->expandedItem->index == index + && d->expandedItem->option.rect == opt.rect) { + // fixbug65053 屏幕数据变化后,桌面展开图标的文本位置错误 + // 被展开的item,且rect未改变时,不重绘text + d->expandedItem->option = opt; + return; + } + + //icon模式下固定展示文件名 + QString str = index.data(DFileSystemModel::FileDisplayNameRole).toString(); + + /// init file name geometry + QRectF label_rect = opt.rect; + label_rect.setTop(icon_rect.bottom() + TEXT_PADDING + ICON_MODE_ICON_SPACING); + if (isCanvas) { + label_rect.setWidth(opt.rect.width() - 2 * TEXT_PADDING); + label_rect.moveLeft(label_rect.left() + TEXT_PADDING); + } else { + label_rect.setWidth(opt.rect.width() - 2 * TEXT_PADDING - 2 * backgroundMargin - ICON_MODE_BACK_RADIUS); + label_rect.moveLeft(label_rect.left() + TEXT_PADDING + backgroundMargin + ICON_MODE_BACK_RADIUS / 2); + } + + //限制当前文字在圆角背景之内,否则字体将超出背景绘制框 + label_rect.setBottom(path.boundingRect().toRect().bottom()); + + //文管窗口拖拽时的字体保持白色 + if ((isSelected && isCanvas) || isDragMode) { + painter->setPen(opt.palette.color(QPalette::BrightText)); + } else { + painter->setPen(opt.palette.color(QPalette::Text)); + } + + /// if has selected show all file name else show elide file name. + bool singleSelected = parent()->selectedIndexsCount() < 2; + + if (isSelected && singleSelected) { + const_cast(this)->hideNotEditingIndexWidget(); + + /// init file name text + const QList &lines = drawText(index, nullptr, str, label_rect.adjusted(0, 0, 0, 99999), 0, QBrush(Qt::NoBrush)); + qreal height = boundingRect(lines).height(); + + // we don't expend item in dde-fm but expand item on desktop && manager + bool shouldExpend = true; + + if (shouldExpend && height > label_rect.height()) { + /// use widget(FileIconItem) show file icon and file name label. + d->expandedIndex = index; + + setEditorData(d->expandedItem, index); + parent()->setIndexWidget(index, d->expandedItem); + + // 重设item状态 + d->expandedItem->index = index; + d->expandedItem->option = opt; + d->expandedItem->textBounding = QRectF(); + d->expandedItem->setFixedWidth(0); + d->expandedItem->setContentsMargins(backgroundMargin, CEIL(iconTopOffset), backgroundMargin, 0); + + if (parent()->indexOfRow(index) == parent()->rowCount() - 1) { + d->lastAndExpandedInde = index; + } + + parent()->updateGeometries(); + + return; + } + } else { + if (!singleSelected) { + const_cast(this)->hideNotEditingIndexWidget(); + } + } + + if (isSelected || !d->enabledTextShadow || isDragMode) {// do not draw text background color + + //图标拖拽时保持活动色 + auto tempBackground = isDragMode ? (opt.palette.brush(QPalette::Normal, QPalette::Highlight)) : (isCanvas ? opt.palette.brush(QPalette::Normal, QPalette::Highlight) : QBrush(Qt::NoBrush)); + const QList &lines = drawText(index, painter, str, label_rect, ICON_MODE_RECT_RADIUS, tempBackground, + QTextOption::WrapAtWordBoundaryOrAnywhere, opt.textElideMode, Qt::AlignCenter); + + const QColor &border_color = focusTextBackgroundBorderColor(); + + if (hasFocus && !singleSelected && border_color.isValid()) { + QPainterPath line_path = boundingPath(lines, ICON_MODE_RECT_RADIUS, 1); + + painter->setPen(QPen(border_color, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); + painter->drawPath(line_path); + } + } else { + qreal pixel_ratio = painter->device()->devicePixelRatioF(); + QImage text_image((label_rect.size() * pixel_ratio).toSize(), QImage::Format_ARGB32_Premultiplied); + text_image.fill(Qt::transparent); + text_image.setDevicePixelRatio(pixel_ratio); + + QPainter p(&text_image); + p.setPen(painter->pen()); + p.setFont(painter->font()); + drawText(index, &p, str, QRectF(QPoint(0, 0), QSizeF(text_image.size()) / pixel_ratio), + ICON_MODE_RECT_RADIUS, QBrush(Qt::NoBrush), + QTextOption::WrapAtWordBoundaryOrAnywhere, opt.textElideMode, Qt::AlignCenter); + p.end(); + + QPixmap text_pixmap = QPixmap::fromImage(text_image); + text_pixmap.setDevicePixelRatio(pixel_ratio); + qt_blurImage(text_image, 6, false); + + p.begin(&text_image); + p.setCompositionMode(QPainter::CompositionMode_SourceIn); + p.fillRect(text_image.rect(), opt.palette.color(QPalette::Shadow)); + p.end(); + + painter->drawImage(label_rect.translated(0, 1), text_image); + painter->drawPixmap(label_rect.topLeft(), text_pixmap); + } + + painter->setOpacity(1); +} + +bool DIconItemDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if (event->type() == QEvent::ToolTip) { + const QString tooltip = index.data(DFileSystemModel::Roles::FileIconModelToolTipRole).toString(); + + if (tooltip.isEmpty()) { // 当从一个需要显示tooltip的icon上移动光标到不需要显示的icon上时立即隐藏当前tooltip + QWidgetList qwl = QApplication::topLevelWidgets(); + for (QWidget *qw : qwl) { + if (QStringLiteral("QTipLabel") == qw->metaObject()->className()) { + qw->close(); + } + } + } else { + int tooltipsize = tooltip.size(); + const int nlong = 32; + int lines = tooltipsize / nlong + 1; + QString strtooltip; + for (int i = 0; i < lines; ++i) { + strtooltip.append(tooltip.mid(i * nlong, nlong)); + strtooltip.append("\n"); + } + strtooltip.chop(1); + QToolTip::showText(event->globalPos(), strtooltip, view); + } + + return true; + } + + return DFMStyledItemDelegate::helpEvent(event, view, option, index); +} + +QSize DIconItemDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &index) const +{ + Q_D(const DIconItemDelegate); + + const QSize &size = d->itemSizeHint; + + if (index.isValid() && index == d->lastAndExpandedInde) { + d->expandedItem->iconHeight = parent()->parent()->iconSize().height(); + + return QSize(size.width(), d->expandedItem->heightForWidth(size.width())); + } + + return size; +} + +QWidget *DIconItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const +{ + Q_D(const DIconItemDelegate); + + d->editingIndex = index; + + FileIconItem *item = new FileIconItem(parent); + + //此处更改逻辑不再保持焦点离开后依然保持的item编辑态,将会提交相关的编辑框(与桌面保持一致) + connect(item, &FileIconItem::inputFocusOut, + this, &DIconItemDelegate::commitDataAndCloseActiveEditor, + Qt::UniqueConnection); + + connect(item, &FileIconItem::destroyed, this, [this, d] { + Q_UNUSED(this) + QWidget *editor = this->parent()->indexWidget(d->editingIndex); + if (!editor || editor == sender()) { + d->editingIndex = QModelIndex(); + } else { + qInfo() << d->editingIndex << "new edit create so not set d->editingIndex!"; + } + }); + + //编辑框的字符变更处理 + connect(item->edit, &QTextEdit::textChanged, this, [=](){ + + //阻塞信号等待当前函数 + const QSignalBlocker blocker(sender()); + + if (!item->edit || item->edit->isReadOnly()) + return; + + //获取之前的文件名称 + QString srcText = item->edit->toPlainText(); + + //清空了当前所有文本 + if (srcText.isEmpty()) { + //根据文本调整edit高度 + item->resizeFromEditTextChanged(); + return; + } + + //得到处理之后的文件名称 + QString dstText = DFMGlobal::preprocessingFileName(srcText); + + //如果存在非法字符且更改了当前的文本文件 + if (srcText != dstText) { + + // 修改文件的命名规则 弹出提示框(气泡提示) + if ( !this->parent() || !this->parent()->parent()) { + qInfo() << "parent is nullptr"; + return; + } + + auto view = this->parent()->parent(); + auto showPoint = view->mapToGlobal( QPoint( item->pos().x() + item->width() / 2, + item->pos().y() + item->height() - ICON_MODE_RECT_RADIUS )); + //背板主题一致 + auto color = view->palette().background().color(); + + DFMGlobal::showAlertMessage(showPoint, + color, + QObject::tr("%1 are not allowed").arg("|[/\\*:\"']?<>")); + //之前的光标Pos + int srcCursorPos = item->edit->textCursor().position(); + QSignalBlocker blocker(item->edit); + item->edit->setPlainText(dstText); + int endPos = srcCursorPos + (dstText.length() - srcText.length()); + //此处调整光标位置 + QTextCursor cursor = item->edit->textCursor(); + cursor.setPosition(endPos); + item->edit->setTextCursor(cursor); + item->edit->setAlignment(Qt::AlignHCenter); + } + + //编辑字符的长度控制 + int editTextMaxLen = item->maxCharSize(); + int editTextCurrLen = dstText.toLocal8Bit().size(); + int editTextRangeOutLen = editTextCurrLen - editTextMaxLen; + if (editTextRangeOutLen > 0 && editTextMaxLen != INT_MAX) { + // fix bug 69627 + QVector list = dstText.toUcs4(); + int cursor_pos = item->edit->textCursor().position(); + while (dstText.toLocal8Bit().size() > editTextMaxLen && cursor_pos > 0) { + list.removeAt(--cursor_pos); + dstText = QString::fromUcs4(list.data(), list.size()); + } + QSignalBlocker blocker(item->edit); + item->edit->setPlainText(dstText); + QTextCursor cursor = item->edit->textCursor(); + cursor.setPosition(cursor_pos); + item->edit->setTextCursor(cursor); + item->edit->setAlignment(Qt::AlignHCenter); + } + + //根据文本调整edit高度 + item->resizeFromEditTextChanged(); + + //添加到stack中 + if (item->editTextStackCurrentItem() != item->edit->toPlainText()) { + item->pushItemToEditTextStack(item->edit->toPlainText()); + } + }, Qt::UniqueConnection); + + //设置字体居中 + //注: 此处经过查阅发现FileItem中editUndo中没有相关设置 + //触发撤销将不会产生字体对其,这里稍微提及,方便以后更改 + item->edit->setAlignment(Qt::AlignHCenter); + item->edit->document()->setTextWidth(d->itemSizeHint.width()); + item->setOpacity(this->parent()->isTransparent(index) ? 0.3 : 1); + + return item; +} + +void DIconItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_D(const DIconItemDelegate); + + const QSize &icon_size = parent()->parent()->iconSize(); + + editor->move(option.rect.topLeft()); + editor->setMinimumHeight(option.rect.height()); + + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + + if (editor == d->expandedItem) { + //重置textBounding,使其在adjustSize重新计算,否则在调整图标大小时使用旧的textBounding计算导致显示不全 + d->expandedItem->textBounding = QRect(); + + editor->setFixedWidth(option.rect.width()); + d->expandedItem->iconHeight = icon_size.height(); + editor->adjustSize(); + return; + } + + editor->setFixedWidth(option.rect.width()); + + FileIconItem *item = qobject_cast(editor); + + if (!item) + return; + + QLabel *icon = item->icon; + + if (icon_size.height() != icon->size().height()) { + bool isCanvas = parent()->property("isCanvasViewHelper").toBool(); + int topoffset = isCanvas ? 0 : (opt.rect.height() - icon_size.height()) / 3;//update edit pos + icon->setFixedHeight(icon_size.height() + topoffset); + } +} + +//item->edit->setPlainText会触发textChanged连接槽进行相关的字符处理 +void DIconItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + QStyleOptionViewItem opt; + + initStyleOption(&opt, index); + + const QSize &icon_size = parent()->parent()->iconSize(); + + if (ExpandedItem *item = qobject_cast(editor)) { + item->iconHeight = icon_size.height(); + item->setOpacity(parent()->isTransparent(index) ? 0.3 : 1); + + return; + } + + FileIconItem *item = qobject_cast(editor); + + if (!item || !item->edit) + return; + + //获取当前是否显示文件后缀 + bool donot_show_suffix{ DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowedFileSuffixOnRename).toBool() }; + + if (item->edit->isReadOnly()) { + item->edit->setPlainText(index.data(DFileSystemModel::FileDisplayNameRole).toString()); + } else { + if (donot_show_suffix) { + const QString &suffix = index.data(DFileSystemModel::FileSuffixOfRenameRole).toString(); + + editor->setProperty("_d_whether_show_suffix", suffix); + + item->setMaxCharSize(MAX_FILE_NAME_CHAR_COUNT - suffix.toLocal8Bit().size() - (suffix.isEmpty() ? 0 : 1)); + item->edit->setPlainText(index.data(DFileSystemModel::FileBaseNameOfRenameRole).toString()); + } else { + item->setMaxCharSize(MAX_FILE_NAME_CHAR_COUNT); + item->edit->setPlainText(index.data(DFileSystemModel::FileNameOfRenameRole).toString()); + } + } + + // 源文件名称不存在更改,此处会受到textChanged的更改出现光标重新计算(更改此处请慎重) + QString srcText; + if (donot_show_suffix) { + srcText = index.data(DFileSystemModel::FileBaseNameOfRenameRole).toString(); + } else { + srcText = index.data(DFileSystemModel::FileNameOfRenameRole).toString(); + } + + int baseNameLength = index.data(DFileSystemModel::FileBaseNameOfRenameRole).toString().length(); + + QString dstText = DFMGlobal::preprocessingFileName(srcText); + if (srcText == dstText) { + //初始化选中任意文件基本名称 + QTextCursor cursor = item->edit->textCursor(); + cursor.setPosition(0); + cursor.setPosition(baseNameLength, QTextCursor::KeepAnchor); + item->edit->setTextCursor(cursor); + } else { + // 修改文件的命名规则 弹出提示框(气泡提示) + if (!this->parent() || !this->parent()->parent()) { + return; + } + + auto view = this->parent()->parent(); + auto showPoint = view->mapToGlobal(QPoint(item->pos().x() + item->width()/2, + item->pos().y() + item->height() - ICON_MODE_RECT_RADIUS )); + //背板主题一致 + auto color = view->palette().background().color(); + + DFMGlobal::showAlertMessage(showPoint, + color, + QObject::tr("%1 are not allowed").arg("|[/\\*:\"']?<>")); + + item->edit->setPlainText(dstText); + + int endPos = baseNameLength + (dstText.length() - srcText.length()); + + QTextCursor cursor = item->edit->textCursor(); + cursor.setPosition(0); + cursor.setPosition(endPos,QTextCursor::KeepAnchor); + item->edit->setTextCursor(cursor); + } + + item->edit->setAlignment(Qt::AlignHCenter); +} + +QList DIconItemDelegate::paintGeomertys(const QStyleOptionViewItem &option, const QModelIndex &index, bool sizeHintMode) const +{ + Q_UNUSED(sizeHintMode) + Q_D(const DIconItemDelegate); + + QList geometries; + + if (index == d->expandedIndex) { + QRect geometry = d->expandedItem->iconGeometry().toRect(); + + geometry.moveTopLeft(geometry.topLeft() + d->expandedItem->pos()); + + geometries << geometry; + + geometry = d->expandedItem->textGeometry().toRect(); + geometry.moveTopLeft(geometry.topLeft() + d->expandedItem->pos()); + geometry.setTop(geometries.first().bottom()); + + geometries << geometry; + + return geometries; + } + + /// init icon geomerty + + QRect icon_rect = option.rect; + + icon_rect.setSize(parent()->parent()->iconSize()); + icon_rect.moveCenter(option.rect.center()); + icon_rect.moveTop(option.rect.top()); + + geometries << icon_rect; + + QString str = index.data(Qt::DisplayRole).toString(); + + if (str.isEmpty()) { + return geometries; + } + + /// init file name geometry + + QRect label_rect = option.rect; + bool isCanvas = parent()->property("isCanvasViewHelper").toBool(); + int backgroundMargin = isCanvas ? 0 : COLUMU_PADDING; + if (isCanvas) { + label_rect.setWidth(label_rect.width() - 2 * TEXT_PADDING); + label_rect.moveLeft(label_rect.left() + TEXT_PADDING); + } else { + label_rect.setWidth(label_rect.width() - 2 * TEXT_PADDING - 2 * backgroundMargin - ICON_MODE_BACK_RADIUS); + label_rect.moveLeft(label_rect.left() + TEXT_PADDING + backgroundMargin + ICON_MODE_BACK_RADIUS / 2); + } + label_rect.setTop(icon_rect.bottom() + TEXT_PADDING + ICON_MODE_ICON_SPACING); + + QStyleOptionViewItem opt = option; + // initStyleOption(&opt, index); + + bool isSelected = parent()->isSelected(index) && opt.showDecorationSelected; + /// if has selected show all file name else show elide file name. + bool singleSelected = parent()->selectedIndexsCount() < 2; + + QTextLayout text_layout; + + text_layout.setFont(option.font); + text_layout.setText(str); + + bool elide = (!isSelected || !singleSelected); + + //此处慎重更改 auto lines会同步document属性,更改后导致行数的计算错误影响绘制 + auto lines = drawText(index, nullptr, str, QRect(label_rect.topLeft(), QSize(label_rect.width(), INT_MAX)), + ICON_MODE_RECT_RADIUS, isSelected ? opt.backgroundBrush : QBrush(Qt::NoBrush), + QTextOption::WrapAtWordBoundaryOrAnywhere, elide ? opt.textElideMode : Qt::ElideNone, + Qt::AlignCenter); + + label_rect = boundingRect(lines).toRect(); + label_rect.setTop(icon_rect.bottom()); + + geometries << label_rect; + + // background rect + QRect background_rect = option.rect; + if (!isCanvas) { + // 为了让对勾右上角, 缩小框框 + background_rect.adjust(backgroundMargin, backgroundMargin, -backgroundMargin, -backgroundMargin); + geometries << background_rect; + } + + return geometries; +} + +QModelIndexList DIconItemDelegate::hasWidgetIndexs() const +{ + const QModelIndex &index = expandedIndex(); + + if (!index.isValid()) + return DFMStyledItemDelegate::hasWidgetIndexs(); + + return DFMStyledItemDelegate::hasWidgetIndexs() << index; +} + +void DIconItemDelegate::hideNotEditingIndexWidget() +{ + Q_D(DIconItemDelegate); + + if (d->expandedIndex.isValid()) { + parent()->setIndexWidget(d->expandedIndex, nullptr); + d->expandedItem->hide(); + d->expandedIndex = QModelIndex(); + d->lastAndExpandedInde = QModelIndex(); + } +} + +QModelIndex DIconItemDelegate::expandedIndex() const +{ + Q_D(const DIconItemDelegate); + + return d->expandedIndex; +} + +QWidget *DIconItemDelegate::expandedIndexWidget() const +{ + Q_D(const DIconItemDelegate); + + return d->expandedItem; +} + +int DIconItemDelegate::iconSizeLevel() const +{ + Q_D(const DIconItemDelegate); + + return d->currentIconSizeIndex; +} + +int DIconItemDelegate::minimumIconSizeLevel() const +{ + return 0; +} + +int DIconItemDelegate::maximumIconSizeLevel() const +{ + Q_D(const DIconItemDelegate); + + return d->iconSizes.count() - 1; +} + +/*! + * \brief Return current icon level if icon can increase; otherwise return -1. + * \return + */ +int DIconItemDelegate::increaseIcon() +{ + Q_D(const DIconItemDelegate); + + return setIconSizeByIconSizeLevel(d->currentIconSizeIndex + 1); +} + +/*! + * \brief Return current icon level if icon can decrease; otherwise return -1. + * \return + */ +int DIconItemDelegate::decreaseIcon() +{ + Q_D(const DIconItemDelegate); + + return setIconSizeByIconSizeLevel(d->currentIconSizeIndex - 1); +} + +/*! + * \brief Return current icon level if level is vaild; otherwise return -1. + * \param level + * \return + */ +int DIconItemDelegate::setIconSizeByIconSizeLevel(int level) +{ + Q_D(DIconItemDelegate); + + if (level == d->currentIconSizeIndex) + return level; + + if (level >= minimumIconSizeLevel() && level <= maximumIconSizeLevel()) { + d->currentIconSizeIndex = level; + + parent()->parent()->setIconSize(iconSizeByIconSizeLevel()); + + return d->currentIconSizeIndex; + } + + return -1; +} + +void DIconItemDelegate::updateItemSizeHint() +{ + Q_D(DIconItemDelegate); + + // d->elideMap.clear(); + // d->wordWrapMap.clear(); + // d->textHeightMap.clear(); + d->textLineHeight = parent()->parent()->fontMetrics().lineSpacing(); + + int width = parent()->parent()->iconSize().width() + 30; + int height = parent()->parent()->iconSize().height() + 2 * COLUMU_PADDING + + 2 * TEXT_PADDING + ICON_MODE_ICON_SPACING + 3 * d->textLineHeight; + int size = qMax(width, height); + d->itemSizeHint = QSize(size, size); + //d->itemSizeHint = QSize(width, parent()->parent()->iconSize().height() + 2 * TEXT_PADDING + ICON_MODE_ICON_SPACING + 3 * d->textLineHeight); +} + +QColor DIconItemDelegate::focusTextBackgroundBorderColor() const +{ + Q_D(const DIconItemDelegate); + + return d->focusTextBackgroundBorderColor; +} + +bool DIconItemDelegate::enabledTextShadow() const +{ + Q_D(const DIconItemDelegate); + + return d->enabledTextShadow; +} + +void DIconItemDelegate::setFocusTextBackgroundBorderColor(QColor focusTextBackgroundBorderColor) +{ + Q_D(DIconItemDelegate); + + d->focusTextBackgroundBorderColor = focusTextBackgroundBorderColor; + + // if (d->expandedItem) + // d->expandedItem->setBorderColor(focusTextBackgroundBorderColor); +} + +void DIconItemDelegate::setEnabledTextShadow(bool enabledTextShadow) +{ + Q_D(DIconItemDelegate); + + d->enabledTextShadow = enabledTextShadow; +} + +void DIconItemDelegate::initTextLayout(const QModelIndex &index, QTextLayout *layout) const +{ + Q_D(const DIconItemDelegate); + + const QVariantHash &ep = index.data(DFileSystemModel::ExtraProperties).toHash(); + const QList &colors = qvariant_cast>(ep.value("colored")); + + if (!colors.isEmpty()) { + if (!layout->engine()->block.docHandle()) { + if (!d->document) + const_cast(d)->document = new QTextDocument(const_cast(this)); + + d->document->setPlainText(layout->text()); + d->document->setDefaultFont(layout->font()); + layout->engine()->block = d->document->firstBlock(); + } + + layout->engine()->docLayout()->registerHandler(d->textObjectType, d->textObjectInterface); + QTextCursor cursor(layout->engine()->docLayout()->document()); + TagTextFormat format(d->textObjectType, colors, (d->drawTextBackgroundOnLast || colors.size() > 1) ? Qt::white : QColor(0, 0, 0, 25)); + + cursor.setPosition(0); + cursor.insertText(QString(QChar::ObjectReplacementCharacter), format); + } +} + +bool DIconItemDelegate::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) { + QKeyEvent *e = static_cast(event); + + if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) { + e->accept(); + + return true; + } + } /*else if (event->type() == QEvent::FocusOut) { + onEditWidgetFocusOut(); + + return true; + }*/ + + return QStyledItemDelegate::eventFilter(object, event); +} + +QList DIconItemDelegate::drawText(const QModelIndex &index, QPainter *painter, QTextLayout *layout, + const QRectF &boundingRect, qreal radius, const QBrush &background, + QTextOption::WrapMode wordWrap, Qt::TextElideMode mode, + int flags, const QColor &shadowColor) const +{ + Q_D(const DIconItemDelegate); + + const_cast(d)->drawTextBackgroundOnLast = background != Qt::NoBrush; + + return DFMStyledItemDelegate::drawText(index, painter, layout, boundingRect, radius, background, wordWrap, mode, flags, shadowColor); +} + +void DIconItemDelegate::onEditWidgetFocusOut() +{ + //这里判断是为了保持编辑框的状态,使编辑框一直存在。类似setEnable的状态 + if (qApp->focusWidget() && qApp->focusWidget()->window() == parent()->parent()->window() + && qApp->focusWidget() != parent()->parent()) { + + hideAllIIndexWidget(); + } +} + +void DIconItemDelegate::onTriggerEdit(const QModelIndex &index) +{ + Q_D(DIconItemDelegate); + m_focusWindow = qApp->focusWindow(); + if (index == d->expandedIndex) { + parent()->setIndexWidget(index, nullptr); + d->expandedItem->hide(); + d->expandedIndex = QModelIndex(); + d->lastAndExpandedInde = QModelIndex(); + parent()->parent()->edit(index); + } +} + + +QSize DIconItemDelegate::iconSizeByIconSizeLevel() const +{ + Q_D(const DIconItemDelegate); + + int size = d->iconSizes.at(d->currentIconSizeIndex); + + return QSize(size, size); +} + +#include "diconitemdelegate.moc" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/diconitemdelegate.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/diconitemdelegate.h new file mode 100644 index 0000000..42d9607 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/diconitemdelegate.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILEITEMDELEGATE_H +#define DFILEITEMDELEGATE_H + +#include "dfmstyleditemdelegate.h" + +#include +#include + +class FileIconItem; +QT_BEGIN_NAMESPACE +class QTextDocument; +QT_END_NAMESPACE + +class DIconItemDelegatePrivate; +class DIconItemDelegate : public DFMStyledItemDelegate +{ + Q_OBJECT + + Q_PROPERTY(QColor focusTextBackgroundBorderColor READ focusTextBackgroundBorderColor WRITE setFocusTextBackgroundBorderColor) + Q_PROPERTY(bool enabledTextShadow READ enabledTextShadow WRITE setEnabledTextShadow) + +public: + explicit DIconItemDelegate(DFileViewHelper *parent); + ~DIconItemDelegate() override; + + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const override; + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const override; + + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const override; + void setEditorData(QWidget *editor, const QModelIndex &index) const override; + + QList paintGeomertys(const QStyleOptionViewItem &option, const QModelIndex &index, bool sizeHintMode = false) const override; + + QModelIndexList hasWidgetIndexs() const override; + void hideNotEditingIndexWidget() override; + + QModelIndex expandedIndex() const; + QWidget *expandedIndexWidget() const; + + int iconSizeLevel() const override; + int minimumIconSizeLevel() const override; + int maximumIconSizeLevel() const override; + + int increaseIcon() override; + int decreaseIcon() override; + int setIconSizeByIconSizeLevel(int level) override; + + void updateItemSizeHint() override; + + QColor focusTextBackgroundBorderColor() const; + bool enabledTextShadow() const; + +public slots: + void setFocusTextBackgroundBorderColor(QColor focusTextBackgroundBorderColor); + void setEnabledTextShadow(bool enabledTextShadow); + +protected: + void initTextLayout(const QModelIndex &index, QTextLayout *layout) const override; + + bool eventFilter(QObject *object, QEvent *event) override; + + QList drawText(const QModelIndex &index, QPainter *painter, QTextLayout *layout, + const QRectF &boundingRect, qreal radius, const QBrush &background, + QTextOption::WrapMode wordWrap = QTextOption::WrapAtWordBoundaryOrAnywhere, + Qt::TextElideMode mode = Qt::ElideMiddle, int flags = Qt::AlignCenter, + const QColor &shadowColor = QColor()) const override; + + using DFMStyledItemDelegate::drawText; + + bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) override; + +private: + void onEditWidgetFocusOut(); + void onTriggerEdit(const QModelIndex &index); + QSize iconSizeByIconSizeLevel() const; + QIcon m_checkedIcon; + QMutex m_mutex; //析构和构造索 + QWindow* m_focusWindow = nullptr; + + Q_DECLARE_PRIVATE(DIconItemDelegate) + + friend class ExpandedItem; +}; + +#endif // DFILEITEMDELEGATE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dlistitemdelegate.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dlistitemdelegate.cpp new file mode 100644 index 0000000..18971c4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dlistitemdelegate.cpp @@ -0,0 +1,818 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dlistitemdelegate.h" +#include "dfileviewhelper.h" +#include "views/dfileview.h" +#include "app/define.h" +#include "dfilesystemmodel.h" +#include "private/dstyleditemdelegate_p.h" +#include "dfmapplication.h" +#include "controllers/vaultcontroller.h" +#include "dfmglobal.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define ICON_SPACING 16 +#define LIST_MODE_RECT_RADIUS 8 +#define LIST_EDITER_HEIGHT 22 +#define LIST_MODE_EDITOR_LEFT_PADDING -3 +#define LIST_VIEW_ICON_SIZE 24 + +DFM_USE_NAMESPACE +DWIDGET_USE_NAMESPACE + +class DListItemDelegatePrivate : public DFMStyledItemDelegatePrivate +{ +public: + explicit DListItemDelegatePrivate(DListItemDelegate *qq) + : DFMStyledItemDelegatePrivate(qq) {} +}; + +DListItemDelegate::DListItemDelegate(DFileViewHelper *parent) : + DFMStyledItemDelegate(parent) +{ + parent->parent()->setIconSize(QSize(LIST_VIEW_ICON_SIZE, LIST_VIEW_ICON_SIZE)); +} + +void DListItemDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + Q_D(const DListItemDelegate); + + painter->save();//保存之前的绘制样式 + + //反走样抗锯齿 + painter->setRenderHints(QPainter::Antialiasing + |QPainter::TextAntialiasing + |QPainter::SmoothPixmapTransform); + //绘制新的背景交替 + if(option.widget){ + //调色板获取 + DPalette pl(DApplicationHelper::instance()->palette(option.widget)); + //背板颜色获取 + QColor baseColor = pl.color(DPalette::ColorGroup::Active, DPalette::ColorType::ItemBackground); + //获取item范围 + auto itemRect = parent()->parent()->visualRect(index); + //左右间隔10 px UI设计要求 选中与交替渐变背景 + QRect dstRect(itemRect.x() + LIST_MODE_LEFT_MARGIN, + itemRect.y(), + itemRect.width() - (LIST_MODE_LEFT_MARGIN + LIST_MODE_RIGHT_MARGIN), + itemRect.height()); + //取模设置当前的交替变化 + if (index.row() % 2 == 1) { + //如果hover则设置高亮,不绘制交替色 + if (option.state & QStyle::StateFlag::State_MouseOver) { + QColor adjustHoverItemColor = baseColor;//hover色 默认调整色保持背板颜色 + //hover色保持背板%8 + adjustHoverItemColor = DGuiApplicationHelper::adjustColor(baseColor, 0, 0, 0, 0, 0, 0, +8); + QPainterPath path; + path.addRoundedRect(dstRect, LIST_MODE_RECT_RADIUS, LIST_MODE_RECT_RADIUS); + painter->fillPath(path, adjustHoverItemColor); + } else { //绘制交替色 + QColor adjustItemAlterColor = baseColor;//交替色 默认调整色保持背板颜色 + //交替色保持背板色%5 + adjustItemAlterColor = DGuiApplicationHelper::adjustColor(baseColor, 0, 0, 0, 0, 0, 0, +5); + QPainterPath path; + path.addRoundedRect(dstRect, LIST_MODE_RECT_RADIUS, LIST_MODE_RECT_RADIUS);//圆角8 UI要求 + painter->fillPath(path, adjustItemAlterColor); + } + } else { + //如果hover则设置高亮,不保持默认背板 + if (option.state & QStyle::StateFlag::State_MouseOver) {//设置hover高亮 + QColor adjustHoverItemColor = baseColor;//hover色 默认调整色保持背板颜色 + adjustHoverItemColor = DGuiApplicationHelper::adjustColor(baseColor, 0, 0, 0, 0, 0, 0, +8); + QPainterPath path; + path.addRoundedRect(dstRect, LIST_MODE_RECT_RADIUS, LIST_MODE_RECT_RADIUS); + //hover色保持背板%8 + painter->fillPath(path, adjustHoverItemColor); + } else { //保持默认背板颜色 + painter->setBrush(baseColor); + } + } + } + painter->restore(); //恢复之前的绘制,防止在此逻辑前的绘制丢失 + + /// judgment way of the whether drag model(another way is: painter.devType() != 1) + bool isDragMode = ((QPaintDevice *)parent()->parent()->viewport() != painter->device()); + bool isDropTarget = parent()->isDropTarget(index); + bool isEnabled = option.state & QStyle::State_Enabled; + + if (parent()->isTransparent(index)) { + painter->setOpacity(0.3); + } + + const QList &columnRoleList = parent()->columnRoleList(); + + int column_x = 0; + + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + painter->setFont(opt.font); + + static QFont old_font = opt.font; + + if (old_font != opt.font) { + QWidget *editing_widget = editingIndexWidget(); + + if (editing_widget) { + editing_widget->setFont(opt.font); + } + + const_cast(this)->updateItemSizeHint(); + } + + old_font = opt.font; + + opt.rect += QMargins(-LIST_MODE_LEFT_MARGIN, 0, -LIST_MODE_RIGHT_MARGIN, 0); + + /// draw background + //列表拖拽时要绘制活动色 + bool drawBackground =/* !isDragMode &&*/ (opt.state & QStyle::State_Selected) && opt.showDecorationSelected; + + QPalette::ColorGroup cg = (option.widget ? option.widget->isEnabled() : (option.state & QStyle::State_Enabled)) + ? QPalette::Normal : QPalette::Disabled; + if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) + cg = QPalette::Inactive; + + bool isSelected = (opt.state & QStyle::State_Selected) && opt.showDecorationSelected; + QPalette::ColorRole colorRole = QPalette::Background; + if ((isSelected || isDropTarget)) { + colorRole = QPalette::Highlight; + } + + if (drawBackground) { + QPainterPath path; + path.addRoundedRect(opt.rect, LIST_MODE_RECT_RADIUS, LIST_MODE_RECT_RADIUS); + painter->save(); + painter->setOpacity(1); + painter->setRenderHint(QPainter::Antialiasing); + painter->fillPath(path, option.palette.color(cg, colorRole)); + painter->restore(); + } else if (isDropTarget) { + QRectF rect = opt.rect; + QPainterPath path; + rect += QMarginsF(-0.5, -0.5, -0.5, -0.5); + path.addRoundedRect(rect, LIST_MODE_RECT_RADIUS, LIST_MODE_RECT_RADIUS); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->fillPath(path, option.palette.color(cg, colorRole)); + painter->setRenderHint(QPainter::Antialiasing, false); + } + + opt.rect.setLeft(opt.rect.left() + LEFT_PADDING); + opt.rect.setRight(opt.rect.right() - RIGHT_PADDING); + + /// draw icon + QRect icon_rect = opt.rect; + + icon_rect.setSize(parent()->parent()->iconSize()); + icon_rect.moveTop(icon_rect.top() + (opt.rect.bottom() - icon_rect.bottom()) / 2); + + if (isDropTarget) { + QPixmap pixmap = opt.icon.pixmap(icon_rect.size()); + + QPainter p(&pixmap); + + p.setCompositionMode(QPainter::CompositionMode_SourceAtop); + p.fillRect(QRect(QPoint(0, 0), icon_rect.size()), QColor(0, 0, 0, 255 * 0.1)); + p.end(); + + painter->drawPixmap(icon_rect, pixmap); + } else { + paintIcon(painter, opt.icon, icon_rect, Qt::AlignCenter, isEnabled ? QIcon::Normal : QIcon::Disabled); + } + + /// draw file additional icon + + QList cornerGeometryList = getCornerGeometryList(icon_rect, icon_rect.size() / 2); + const QList &cornerIconList = parent()->additionalIcon(index); + + for (int i = 0; i < cornerIconList.count(); ++i) { + if (cornerIconList.at(i).isNull()) { + continue; + } + cornerIconList.at(i).paint(painter, cornerGeometryList.at(i).toRect()); + } + + if (columnRoleList.isEmpty()) + return; + + column_x = icon_rect.right(); + + + //绘制拖拽时的行 + if (isDragMode) { + QRect rect = opt.rect; + rect.setLeft(column_x); + column_x = option.rect.x() + parent()->columnWidth(0) - 1 - parent()->fileViewViewportMargins().left(); + rect.setRight(qMin(column_x, opt.rect.right())); + + for(const int &role : columnRoleList) { + if (role == DFileSystemModel::FileNameRole || role == DFileSystemModel::FileDisplayNameRole) { + paintFileName(painter, opt, index, role, rect, d->textLineHeight); + break; + } + } + return; + } + + const DFileSystemModel *model = qobject_cast(index.model()); + + + for (int i = 0; i < columnRoleList.count(); ++i) { + int column_width = parent()->columnWidth(i); + + if (column_width <= 0) { + continue; + } + + int rol = columnRoleList.at(i); + + QRect rec = opt.rect; + rec.setLeft(column_x + COLUMU_PADDING); + + if (rec.left() >= rec.right()) { + break; + } + + if (i == 0) { + column_x = option.rect.x() + column_width - 1 - parent()->fileViewViewportMargins().left(); + } else { + column_x += column_width; + } + rec.setRight(qMin(column_x, opt.rect.right())); + + + if (rol == DFileSystemModel::FileNameRole || rol == DFileSystemModel::FileDisplayNameRole) { + //绘制标记 + const QVariantHash &ep = index.data(DFileSystemModel::ExtraProperties).toHash(); + const QList &colors = qvariant_cast>(ep.value("colored")); + if (!colors.isEmpty()) { + qreal diameter = 10; + QRectF tag_boundingRect(0, 0, (colors.size() + 1) * diameter / 2, diameter); + + tag_boundingRect.moveCenter(rec.center()); + tag_boundingRect.moveRight(rec.right()); + + paintCircleList(painter, tag_boundingRect, diameter, colors, + (drawBackground || colors.size() > 1) ? Qt::white : QColor(0, 0, 0, 25)); + rec.setRight(tag_boundingRect.left() - ICON_SPACING); + } + + paintFileName(painter, opt, index, rol, rec, d->textLineHeight); + } else { + if (isSelected) + painter->setPen(opt.palette.color(QPalette::Active, QPalette::HighlightedText)); + else + painter->setPen(opt.palette.color(QPalette::Inactive, QPalette::Text)); + + QModelIndex tmp_index = model->createIndex(index.row(), model->roleToColumn(rol), index.internalId()); + + const QVariant &data = index.data(rol); + + if (data.canConvert()) { + QString strInfo(index.data(rol).toString()); + // 如果是文件路径项 + if(rol == DFileSystemModel::FilePathRole) { + // 如果是保险箱路径,则不显示真实路径 + if(VaultController::isVaultFile(strInfo)) + strInfo = VaultController::localPathToVirtualPath(index.data(rol).toString()); + } + const QString &text = DFMGlobal::elideText(strInfo, rec.size(), + QTextOption::NoWrap, opt.font, + Qt::ElideRight, d->textLineHeight); + + painter->drawText(rec, Qt::Alignment(tmp_index.data(Qt::TextAlignmentRole).toInt()), text); + } else { + drawNotStringData(opt, d->textLineHeight, rec, data, drawBackground, painter, i); + } + } + } + + if (isDropTarget && !drawBackground) { + QPen pen; + QRectF rec = opt.rect; + + rec += QMarginsF(-0.5 + LEFT_PADDING, -0.5, -0.5 + RIGHT_PADDING, -0.5); + + pen.setColor(opt.backgroundBrush.color()); + + painter->setPen(pen); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->drawRoundedRect(rec, LIST_MODE_RECT_RADIUS, LIST_MODE_RECT_RADIUS); + painter->setRenderHint(QPainter::Antialiasing, false); + painter->setPen(Qt::black); + } + + painter->setOpacity(1); +} + + +void DListItemDelegate::drawNotStringData(const QStyleOptionViewItem &opt, int lineHeight, const QRect &rect, const QVariant &data, + bool drawBackground, QPainter *painter, const int &column) const +{ + + const DFileSystemModel *model = parent()->model(); + const DAbstractFileInfoPointer &fileInfo = model->fileInfo(model->rootUrl()); + + int sortRole = model->sortRole(); + int sortRoleIndexByColumnChildren = fileInfo->userColumnChildRoles(column).indexOf(sortRole); + + const QColor &active_color = opt.palette.color(QPalette::Active, drawBackground ? QPalette::BrightText : QPalette::Text); + const QColor &normal_color = opt.palette.color(QPalette::Inactive, drawBackground ? QPalette::BrightText : QPalette::Text); + + if (data.canConvert>()) { + QPair name_path = qvariant_cast>(data); + + const QString &file_name = DFMGlobal::elideText(name_path.first.remove('\n'), + QSize(rect.width(), rect.height() / 2), QTextOption::NoWrap, + opt.font, Qt::ElideRight, + lineHeight); + painter->setPen(sortRoleIndexByColumnChildren == 0 ? active_color : normal_color); + painter->drawText(rect.adjusted(0, 0, 0, -rect.height() / 2), Qt::AlignBottom, file_name); + + const QString &file_path = DFMGlobal::elideText(name_path.second.remove('\n'), + QSize(rect.width(), rect.height() / 2), QTextOption::NoWrap, + opt.font, Qt::ElideRight, + lineHeight); + + painter->setPen(sortRoleIndexByColumnChildren == 1 ? active_color : normal_color); + painter->drawText(rect.adjusted(0, rect.height() / 2, 0, 0), Qt::AlignTop, file_path); + } else if (data.canConvert>>()) { + QRect new_rect = rect; + + const QPair> &dst = qvariant_cast>>(data); + + const QString &date = DFMGlobal::elideText(dst.first, QSize(rect.width(), rect.height() / 2), + QTextOption::NoWrap, opt.font, + Qt::ElideRight, lineHeight); + + painter->setPen(sortRoleIndexByColumnChildren == 0 ? active_color : normal_color); + painter->drawText(new_rect.adjusted(0, 0, 0, -new_rect.height() / 2), Qt::AlignBottom, date, &new_rect); + + new_rect = QRect(rect.left(), rect.top(), new_rect.width(), rect.height()); + + const QString &size = DFMGlobal::elideText(dst.second.first, QSize(new_rect.width() / 2, new_rect.height() / 2), + QTextOption::NoWrap, opt.font, + Qt::ElideRight, lineHeight); + + painter->setPen(sortRoleIndexByColumnChildren == 1 ? active_color : normal_color); + painter->drawText(new_rect.adjusted(0, new_rect.height() / 2, 0, 0), Qt::AlignTop | Qt::AlignLeft, size); + + const QString &type = DFMGlobal::elideText(dst.second.second, QSize(new_rect.width() / 2, new_rect.height() / 2), + QTextOption::NoWrap, opt.font, + Qt::ElideLeft, lineHeight); + painter->setPen(sortRoleIndexByColumnChildren == 2 ? active_color : normal_color); + painter->drawText(new_rect.adjusted(0, new_rect.height() / 2, 0, 0), Qt::AlignTop | Qt::AlignRight, type); + } +} + + +QSize DListItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + const DAbstractFileInfoPointer &file_info = parent()->fileInfo(index); + + if (!file_info) { + return DFMStyledItemDelegate::sizeHint(option, index); + } + + Q_D(const DListItemDelegate); + + return QSize(d->itemSizeHint.width(), qMax(file_info->userRowHeight(option.fontMetrics), d->itemSizeHint.height())); +} + +QWidget *DListItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option); + Q_D(const DListItemDelegate); + + d->editingIndex = index; + + QLineEdit *edit = new QLineEdit(parent); + + const DAbstractFileInfoPointer &file_info = this->parent()->fileInfo(index); + if (file_info->fileUrl().isSearchFile()) { + edit->setFixedHeight(LIST_EDITER_HEIGHT * 2 - 10); + } else { + edit->setFixedHeight(LIST_EDITER_HEIGHT); + } + edit->setObjectName("DListItemDelegate_Editor"); + + connect(edit, &QLineEdit::destroyed, this, [this, d] { + Q_UNUSED(this); + d->editingIndex = QModelIndex(); + }); + + connect(edit, &QLineEdit::textChanged, this, [this, edit, d] { + //在此处处理的逻辑是因为默认QAbstractItemView的QLineEdit重命名会被SelectAll + //const 防止被改变 + const QString srcText = edit->text(); + //得到处理之后的文件名称 + QString dstText = DFMGlobal::preprocessingFileName(srcText); + + //超出长度将不再被支持输入获取当前 + bool donot_show_suffix{ DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowedFileSuffixOnRename).toBool() }; + + //获取当前编辑框支持的最大文字长度 + int textMaxLen = INT_MAX; + if (donot_show_suffix) { + const QString &suffix = d->editingIndex.data(DFileSystemModel::FileSuffixOfRenameRole).toString(); + edit->setProperty("_d_whether_show_suffix", suffix); + textMaxLen = MAX_FILE_NAME_CHAR_COUNT - suffix.toLocal8Bit().size() - (suffix.isEmpty() ? 0 : 1); + } else { + textMaxLen = MAX_FILE_NAME_CHAR_COUNT; + } + + //如果存在非法字符且更改了当前的文本文件 + if (srcText != dstText) { + int currPos = edit->cursorPosition(); + //气泡提示 + if (!this->parent()) { + return; + } + + auto view = this->parent()->parent(); + + if(!view) + return; + + auto showPoint = view->mapToGlobal( QPoint( edit->pos().x() + edit->width() / 2, + edit->pos().y() + edit->height() * 2)); + //背板主题一致 + auto color = view->palette().background().color(); + + DFMGlobal::showAlertMessage(showPoint, + color, + QObject::tr("%1 are not allowed").arg("|[/\\*:\"']?<>")); + + currPos += dstText.length() - srcText.length(); + QSignalBlocker blocker(edit); + edit->setText(dstText); + edit->setCursorPosition(currPos); + } + + int textCurrLen = dstText.toLocal8Bit().size(); + int textRangeOutLen = textCurrLen - textMaxLen; + //最大输入框字符控制逻辑 + if (textRangeOutLen > 0) { + // fix bug 69627 + QVector list = dstText.toUcs4(); + int cursor_pos = edit->cursorPosition(); + while (dstText.toLocal8Bit().size() > textMaxLen && cursor_pos > 0) { + list.removeAt(--cursor_pos); + dstText = QString::fromUcs4(list.data(), list.size()); + } + QSignalBlocker blocker(edit); + edit->setText(dstText); + edit->setCursorPosition(cursor_pos); + } + }); + + edit->setFrame(false); + edit->setAttribute(Qt::WA_TranslucentBackground); + edit->setContentsMargins(0, 0, 0, 0); + + return edit; +} + +void DListItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index); + const QSize &icon_size = parent()->parent()->iconSize(); + int column_x = 0; + + /// draw icon + //计算编辑框左侧位置 + const QRect &opt_rect = option.rect + QMargins(-LIST_MODE_LEFT_MARGIN - LEFT_PADDING, 0, -LIST_MODE_RIGHT_MARGIN - RIGHT_PADDING, 0); + QRect icon_rect = opt_rect; + icon_rect.setSize(icon_size); + + const QList roleList = parent()->columnRoleList(); + QRect rect = opt_rect; + for (int i = 0; i < roleList.length(); ++i) { + if (roleList.at(i) == DFileSystemModel::FileNameRole || roleList.at(i) == DFileSystemModel::FileDisplayNameRole) { + int iconOffset = i == 0 ? icon_rect.right() + 1: 0; + + rect.setLeft(column_x + iconOffset); + column_x += parent()->columnWidth(i) - 1 - parent()->fileViewViewportMargins().left(); + + rect.setRight(qMin(column_x, opt_rect.right())); + rect.setTop(opt_rect.y() + (opt_rect.height() - editor->height()) / 2); + break; + } else { + column_x += parent()->columnWidth(i); + } + } + + editor->setGeometry(rect); +} + +void DListItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + QLineEdit *edit = qobject_cast(editor); + + if (!edit) { + return; + } + + bool donot_show_suffix{ DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowedFileSuffixOnRename).toBool() }; + QString text; + + if (donot_show_suffix) { + edit->setProperty("_d_whether_show_suffix", index.data(DFileSystemModel::FileSuffixOfRenameRole)); + text = index.data(DFileSystemModel::FileBaseNameOfRenameRole).toString(); + } else { + text = index.data(DFileSystemModel::FileNameOfRenameRole).toString(); + } + + edit->setText(text); +} + +static int dataWidth(const QStyleOptionViewItem &option, const QModelIndex &index, int role) +{ + const QVariant &data = index.data(role); + Qt::Alignment alignment = Qt::Alignment(index.data(Qt::TextAlignmentRole).toInt()); + + if (data.canConvert()) { + return option.fontMetrics.width(data.toString(), -1, alignment); + } + + if (data.canConvert>()) { + const QPair &string_string = qvariant_cast>(data); + + return qMax(option.fontMetrics.width(string_string.first, -1, alignment), option.fontMetrics.width(string_string.second, -1, alignment)); + } + + if (data.canConvert>>()) { + const QPair> &string_p_string = qvariant_cast>>(data); + + return option.fontMetrics.width(string_p_string.first, -1, alignment); + } + + return -1; +} + +// sizeHintMode为true时,计算列的宽度时计算的为此列真实需要的宽度,而不受实际列宽所限制 +QList DListItemDelegate::paintGeomertys(const QStyleOptionViewItem &option, const QModelIndex &index, bool sizeHintMode) const +{ + QList geomertys; + const QList &columnRoleList = parent()->columnRoleList(); + int column_x = 0; + + /// draw icon + + const QRect &opt_rect = option.rect + QMargins(-LIST_MODE_LEFT_MARGIN - LEFT_PADDING, 0, -LIST_MODE_RIGHT_MARGIN - RIGHT_PADDING, 0); + + QRect icon_rect = opt_rect; + + icon_rect.setSize(parent()->parent()->iconSize()); + + geomertys << icon_rect; + + column_x = icon_rect.right() + ICON_SPACING; + + QRect rect = opt_rect; + + rect.setLeft(column_x); + + int role = columnRoleList.at(0); + + if (sizeHintMode) { + rect.setWidth(dataWidth(option, index, role)); + column_x = rect.right(); + } else { + column_x = parent()->columnWidth(0) - 1 - parent()->fileViewViewportMargins().left(); + + rect.setRight(qMin(column_x, opt_rect.right())); + /// draw file name label + rect.setWidth(qMin(rect.width(), dataWidth(option, index, role))); + } + + geomertys << rect; + + for (int i = 1; i < columnRoleList.count(); ++i) { + QRect rec = opt_rect; + + rec.setLeft(column_x + COLUMU_PADDING); + + if (rec.left() >= opt_rect.right()) { + return geomertys; + } + + int rol = columnRoleList.at(i); + + if (sizeHintMode) { + rec.setWidth(dataWidth(option, index, rol)); + column_x += rec.width(); + } else { + column_x += parent()->columnWidth(i) - 1; + + rec.setRight(qMin(column_x, opt_rect.right())); + rec.setWidth(qMin(rec.width(), dataWidth(option, index, rol))); + } + + geomertys << rec; + } + + return geomertys; +} + +void DListItemDelegate::updateItemSizeHint() +{ + Q_D(DListItemDelegate); + + d->textLineHeight = parent()->parent()->fontMetrics().lineSpacing(); + d->itemSizeHint = QSize(-1, qMax(int(parent()->parent()->iconSize().height() * 1.1), d->textLineHeight)); +} + +bool DListItemDelegate::eventFilter(QObject *object, QEvent *event) +{ + Q_D(DListItemDelegate); + + if (event->type() == QEvent::Show) { + QLineEdit *edit = qobject_cast(object); + //在此处处理的逻辑是因为默认QAbstractItemView的QLineEdit重命名会被SelectAll + //const 防止被改变 + if (!edit) + return false; + + bool notShowSuffix = DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowedFileSuffixOnRename).toBool(); + QString srcText; + if (notShowSuffix) + { + srcText = d->editingIndex.data(DFileSystemModel::FileBaseNameOfRenameRole).toString(); + } else { + srcText = d->editingIndex.data(DFileSystemModel::FileNameOfRenameRole).toString(); + } + + //得到处理之后的文件名称 + QString dstText = DFMGlobal::preprocessingFileName(srcText); + //如果存在非法字符且更改了当前的文本文件 + if (srcText != dstText){ + //气泡提示 + DFMGlobal::showAlertMessage(edit->mapToGlobal(edit->pos()), + parent()->parent()->palette().background().color(), + QObject::tr("%1 are not allowed").arg("|[/\\*:\"']?<>")); + + //移动坐标 + auto srcBaseNameLength = d->editingIndex.data(DFileSystemModel::FileBaseNameOfRenameRole).toString().length(); + edit->setText(dstText); + int movePosCount = dstText.length() - srcText.length(); + edit->setText(dstText); + edit->setCursorPosition(srcBaseNameLength + movePosCount); + edit->setSelection(0, srcBaseNameLength + movePosCount); + } else { + int selectLength = d->editingIndex.data(DFileSystemModel::FileBaseNameOfRenameRole).toString().length(); + edit->setText(srcText); + edit->setCursorPosition(selectLength); + edit->setSelection(0, selectLength); + } + + } else if (event->type() == QEvent::KeyPress) { + QKeyEvent *e = static_cast(event); + + if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) { + e->accept(); + + QLineEdit *edit = qobject_cast(object); + + if (edit) { + edit->close(); + edit->parentWidget()->setFocus(); + } + + return true; + } + } + + return QStyledItemDelegate::eventFilter(object, event); +} + +static void hideTooltipImmediately() +{ + QWidgetList qwl = QApplication::topLevelWidgets(); + for (QWidget *qw : qwl) { + if (QStringLiteral("QTipLabel") == qw->metaObject()->className()) { + qw->close(); + } + } +} + +bool DListItemDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if (event->type() == QEvent::ToolTip) { + const QString tooltip = index.data(Qt::ToolTipRole).toString(); + + if (tooltip.isEmpty()) { +// QToolTip::hideText(); + hideTooltipImmediately(); + } else { + int tooltipsize = tooltip.size(); + const int nlong = 32; + int lines = tooltipsize / nlong + 1; + QString strtooltip; + for (int i = 0; i < lines; ++i) { + strtooltip.append(tooltip.mid(i * nlong, nlong)); + strtooltip.append("\n"); + } + strtooltip.chop(1); + + // fix bug 81894 + const QList &geometries = paintGeomertys(option, index); + const QList colRoles = parent()->columnRoleList(); + const QPoint &curPos = parent()->parent()->mapFromGlobal(event->globalPos()); + for (int i = 1; i < geometries.length() && i <= colRoles.length(); ++i) { + auto curRect = geometries.at(i); + + if (curRect.left() <= curPos.x() && curRect.right() >= curPos.x()) { + // 真实的rect位置需要下移表头高度的距离 + int headerViewHeight = qobject_cast(parent()->parent())->headerViewHeight(); + const QRect realRect(curRect.left(), curRect.top() + headerViewHeight, curRect.width(), curRect.height()); + QToolTip::showText(event->globalPos(), strtooltip, view, realRect); + break; + } + } + } + + return true; + } + + return DFMStyledItemDelegate::helpEvent(event, view, option, index); +} + +void DListItemDelegate::paintFileName(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, const int &role, const QRect &rect, const int &textLineHeight) const +{ + bool drawBackground =(option.state & QStyle::State_Selected) && option.showDecorationSelected; + const QVariant &data = index.data(role); + painter->setPen(option.palette.color(drawBackground ? QPalette::BrightText : QPalette::Text)); + if (data.canConvert()) { + QString file_name; + + do { + if (role != DFileSystemModel::FileNameRole && role != DFileSystemModel::FileDisplayNameRole) + break; + + if (role == DFileSystemModel::FileDisplayNameRole) { + const auto fileName = index.data(DFileSystemModel::FileNameRole); + const auto file_display_name = index.data(DFileSystemModel::FileDisplayNameRole); + + if (fileName != file_display_name) + break; + } + + const QString &suffix = "." + index.data(DFileSystemModel::FileSuffixRole).toString(); + if (suffix == ".") + break; + + file_name = DFMGlobal::elideText(index.data(DFileSystemModel::FileBaseNameRole).toString().remove('\n'), + QSize(rect.width() - option.fontMetrics.width(suffix), rect.height()), QTextOption::WrapAtWordBoundaryOrAnywhere, + option.font, Qt::ElideRight, + textLineHeight); + file_name.append(suffix); + } while (false); + + if (file_name.isEmpty()) { + file_name = DFMGlobal::elideText(index.data(role).toString().remove('\n'), + rect.size(), QTextOption::WrapAtWordBoundaryOrAnywhere, + option.font, Qt::ElideRight, + textLineHeight); + } + + painter->drawText(rect, Qt::Alignment(index.data(Qt::TextAlignmentRole).toInt()), file_name); + } else { + drawNotStringData(option, textLineHeight, rect, data, drawBackground, painter, 0); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dlistitemdelegate.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dlistitemdelegate.h new file mode 100644 index 0000000..eebcfd8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dlistitemdelegate.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DLISTITEMDELEGATE_H +#define DLISTITEMDELEGATE_H + +#include "dfmstyleditemdelegate.h" + +class DListItemDelegatePrivate; +class DListItemDelegate : public DFMStyledItemDelegate +{ +public: + explicit DListItemDelegate(DFileViewHelper *parent); + + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + void drawNotStringData(const QStyleOptionViewItem &opt, int lineHeight, const QRect &rect, const QVariant &data, + bool drawBackground, QPainter *painter, const int &column) const; + + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &) const override; + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void setEditorData(QWidget *editor, const QModelIndex &index) const override; + + QList paintGeomertys(const QStyleOptionViewItem &option, const QModelIndex &index, bool sizeHintMode = false) const override; + + void updateItemSizeHint() override; + +protected: + bool eventFilter(QObject *object, QEvent *event) override; + bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) override; + +private: + Q_DECLARE_PRIVATE(DListItemDelegate) + + void paintFileName(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index, const int &role, const QRect &rect, const int &textLineHeight) const; +}; + +#endif // DLISTITEMDELEGATE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dmimedatabase.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dmimedatabase.cpp new file mode 100644 index 0000000..5e00a7c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dmimedatabase.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dmimedatabase.h" +#include "shutil/fileutils.h" +#include "dstorageinfo.h" +#include "controllers/vaultcontroller.h" + +#include + +DFM_BEGIN_NAMESPACE + +DMimeDatabase::DMimeDatabase() +{ + +} + +QMimeType DMimeDatabase::mimeTypeForFile(const QString &fileName, QMimeDatabase::MatchMode mode) const +{ + return mimeTypeForFile(QFileInfo(fileName), mode); +} + +QMimeType DMimeDatabase::mimeTypeForFile(const QFileInfo &fileInfo, QMimeDatabase::MatchMode mode) const +{ + // 如果是低速设备,则先从扩展名去获取mime信息;对于本地文件,保持默认的获取策略 + QMimeType result; + QString path = fileInfo.path(); + bool isMatchExtension = mode == QMimeDatabase::MatchExtension; + // fix bug#93843 + // 保险箱属于低速设备,故使用扩展模式,提高保险箱中获取icon图标的速度 + if (VaultController::isVaultFile(path)) + isMatchExtension = true; + if (!isMatchExtension) { + //fix bug 35448 【文件管理器】【5.1.2.2-1】【sp2】预览ftp路径下某个文件夹后,文管卡死,访问特殊系统文件卡死 + if (fileInfo.fileName().endsWith(".pid") || path.endsWith("msg.lock") + || fileInfo.fileName().endsWith(".lock") || fileInfo.fileName().endsWith("lockfile")) { + QRegularExpression regExp("^/run/user/\\d+/gvfs/(?\\w+(-?)\\w+):\\S*", + QRegularExpression::DotMatchesEverythingOption + | QRegularExpression::DontCaptureOption + | QRegularExpression::OptimizeOnFirstUsageOption); + + const QRegularExpressionMatch &match = regExp.match(path, 0, QRegularExpression::NormalMatch, + QRegularExpression::DontCheckSubjectStringMatchOption); + + isMatchExtension = match.hasMatch(); + } else { + // filemanger will be blocked when blacklist contais the filepath. + static const QStringList blacklist {"/sys/kernel/security/apparmor/revision", "/sys/kernel/security/apparmor/policy/revision", "/sys/power/wakeup_count", "/proc/kmsg"}; + QString filePath = fileInfo.absoluteFilePath(); + if (fileInfo.isSymLink()) { + filePath = fileInfo.symLinkTarget(); + } + isMatchExtension = blacklist.contains(filePath); + } + } + + if (isMatchExtension || DStorageInfo::isLowSpeedDevice(path)) { + result = QMimeDatabase::mimeTypeForFile(fileInfo, QMimeDatabase::MatchExtension); + } else { + result = QMimeDatabase::mimeTypeForFile(fileInfo, mode); + } + + // temporary dirty fix, once WPS get installed, the whole mimetype database thing get fscked up. + // we used to patch our Qt to fix this issue but the patch no longer works, we don't have time to + // look into this issue ATM. + // https://bugreports.qt.io/browse/QTBUG-71640 + // https://codereview.qt-project.org/c/qt/qtbase/+/244887 + // `file` command works but libmagic didn't even comes with any pkg-config support.. + static QStringList officeSuffixList { + "docx", "xlsx", "pptx", "doc", "ppt", "xls", "wps" + }; + static QStringList wrongMimeTypeNames { + "application/x-ole-storage", "application/zip" + }; + + if (officeSuffixList.contains(fileInfo.suffix()) && wrongMimeTypeNames.contains(result.name())) { + QList results = QMimeDatabase::mimeTypesForFileName(fileInfo.fileName()); + if (!results.isEmpty()) { + return results.first(); + } + } + return result; +} + +QMimeType DMimeDatabase::mimeTypeForFile(const QString &fileName, QMimeDatabase::MatchMode mode, const QString& inod, const bool isgvfs) const +{ + + if (!inod.isEmpty() && inodmimetypecache.contains(inod)) { + return inodmimetypecache.value(inod); + } + return mimeTypeForFile(QFileInfo(fileName), mode, inod, isgvfs); + +} + +QMimeType DMimeDatabase::mimeTypeForFile(const QFileInfo &fileInfo, QMimeDatabase::MatchMode mode, const QString& inod, const bool isgvfs) const +{ + Q_UNUSED(isgvfs) + // 如果是低速设备,则先从扩展名去获取mime信息;对于本地文件,保持默认的获取策略 + bool cancache = !inod.isEmpty(); + if (!inod.isEmpty() && inodmimetypecache.contains(inod)) { + return inodmimetypecache.value(inod); + } + if (fileInfo.isDir()) { + return QMimeDatabase::mimeTypeForFile(QFileInfo("/home"), mode); + } + QMimeType result; + QString path = fileInfo.path(); + + bool isMatchExtension = mode == QMimeDatabase::MatchExtension; + + //fix bug 35448 【文件管理器】【5.1.2.2-1】【sp2】预览ftp路径下某个文件夹后,文管卡死,访问特殊系统文件卡死 + if (!isMatchExtension) { + if(fileInfo.fileName().endsWith(".pid") || path.endsWith("msg.lock") + || fileInfo.fileName().endsWith(".lock") || fileInfo.fileName().endsWith("lockfile")) { + QRegularExpression regExp("^/run/user/\\d+/gvfs/(?\\w+(-?)\\w+):\\S*", + QRegularExpression::DotMatchesEverythingOption + | QRegularExpression::DontCaptureOption + | QRegularExpression::OptimizeOnFirstUsageOption); + + const QRegularExpressionMatch &match = regExp.match(path, 0, QRegularExpression::NormalMatch, + QRegularExpression::DontCheckSubjectStringMatchOption); + + isMatchExtension = match.hasMatch(); + } + else { + // filemanger will be blocked when blacklist contais the filepath. + // fix task #29124, bug #108805 + static const QStringList blacklist {"/sys/kernel/security/apparmor/revision", "/sys/kernel/security/apparmor/policy/revision", "/sys/power/wakeup_count", "/proc/kmsg"}; + QString filePath = fileInfo.absoluteFilePath(); + if (fileInfo.isSymLink()) { + filePath = fileInfo.symLinkTarget(); + } + isMatchExtension = blacklist.contains(filePath); + } + } + if (isMatchExtension || DStorageInfo::isLowSpeedDevice(path)) { + result = QMimeDatabase::mimeTypeForFile(fileInfo, QMimeDatabase::MatchExtension); + } else { + result = QMimeDatabase::mimeTypeForFile(fileInfo, mode); + } + + // temporary dirty fix, once WPS get installed, the whole mimetype database thing get fscked up. + // we used to patch our Qt to fix this issue but the patch no longer works, we don't have time to + // look into this issue ATM. + // https://bugreports.qt.io/browse/QTBUG-71640 + // https://codereview.qt-project.org/c/qt/qtbase/+/244887 + // `file` command works but libmagic didn't even comes with any pkg-config support.. + static QStringList officeSuffixList { + "docx", "xlsx", "pptx", "doc", "ppt", "xls" + }; + static QStringList wrongMimeTypeNames { + "application/x-ole-storage", "application/zip" + }; + + if (officeSuffixList.contains(fileInfo.suffix()) && wrongMimeTypeNames.contains(result.name())) { + QList results = QMimeDatabase::mimeTypesForFileName(fileInfo.fileName()); + if (!results.isEmpty()) { + if (cancache) { + const_cast(this)->inodmimetypecache.insert(inod,results.first()); + } + return results.first(); + } + } + if (cancache) { + const_cast(this)->inodmimetypecache.insert(inod,result); + } + return result; +} + +QMimeType DMimeDatabase::mimeTypeForUrl(const QUrl &url) const +{ + if (url.isLocalFile()) + return mimeTypeForFile(url.toLocalFile()); + + return QMimeDatabase::mimeTypeForUrl(url); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dmimedatabase.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dmimedatabase.h new file mode 100644 index 0000000..5060488 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dmimedatabase.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DMIMEDATABASE_H +#define DMIMEDATABASE_H + +#include + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DMimeDatabase : public QMimeDatabase +{ + Q_DISABLE_COPY(DMimeDatabase) + +public: + DMimeDatabase(); + + QMimeType mimeTypeForFile(const QString &fileName, MatchMode mode = MatchDefault) const; + QMimeType mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode = MatchDefault) const; + QMimeType mimeTypeForFile(const QString &fileName, MatchMode mode, const QString& inod,const bool isgvfs = false) const; + QMimeType mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode, const QString& inod,const bool isgvfs = false) const; + QMimeType mimeTypeForUrl(const QUrl &url) const; + +private: + QHash inodmimetypecache; +}; + +DFM_END_NAMESPACE + +#endif // DMIMEDATABASE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/drootfilemanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/drootfilemanager.cpp new file mode 100644 index 0000000..322d4d5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/drootfilemanager.cpp @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "drootfilemanager.h" +#include "dfileservices.h" +#include "dabstractfileinfo.h" +#include "dabstractfilewatcher.h" +#include "dfiledevice.h" + +#include "app/filesignalmanager.h" +#include "app/define.h" +#include "controllers/jobcontroller.h" +#include "dfileinfo.h" + +#include "shutil/fileutils.h" +#include "shutil/filebatchprocess.h" +#include "interfaces/dfmglobal.h" +#include "singleton.h" +#include "models/dfmrootfileinfo.h" +#include "utils.h" +#include "dfmapplication.h" +#include "plugins/schemepluginmanager.h" + +#include +#include +#include + + +class DRootFileManagerPrivate +{ +public: + + static QMap rootfilelist; + static QMutex rootfileMtx; + QAtomicInteger m_bRootFileInited = false; + QAtomicInteger bstartonce = false; + DAbstractFileWatcher *m_rootFileWatcher = nullptr; + + QHash m_rootsmbftpurllist; + JobController *m_jobcontroller = nullptr; + + volatile bool m_rootChanged = true; //用于判断是否需要发送查询完毕信号,通知外部刷新。 +}; + +QMap DRootFileManagerPrivate::rootfilelist; //本地跟踪root目录,本地磁盘,外部磁盘挂载,网络文件挂载 +QMutex DRootFileManagerPrivate::rootfileMtx; + +DRootFileManager::DRootFileManager(QObject *parent) + : QObject(parent) + , d_ptr(new DRootFileManagerPrivate()) +{ + connect(fileSignalManager, &FileSignalManager::requestHideSystemPartition, this, &DRootFileManager::hideSystemPartition); + connect(DFMApplication::instance(), &DFMApplication::reloadComputerModel, this, &DRootFileManager::hideSystemPartition); +} + +DRootFileManager::~DRootFileManager() +{ + d_ptr->m_rootsmbftpurllist.clear(); +} + +QList DRootFileManager::getRootFile() +{ + QMutexLocker lk(&d_ptr->rootfileMtx); + QList ret = d_ptr->rootfilelist.values(); + lk.unlock(); + // fix bug 63220 排序算法中,个数低于20个时第一次调用比对函数时,传入a,b分别时是QList的第二个和第一个元素 + // 当传入元素大于20,采用了二分法,第一次调用比对函数时,传入a,b分别时是QList的第二个和元素个数的一半的元素, + // 视频和桌面是同一级别,所以桌面就在最后了。先排一次序。 + std::sort(ret.begin(), ret.end(), &DFMRootFileInfo::typeCompareByUrl); + + if (!ret.isEmpty()) { + // fix 25778 每次打开文管,"我的目录" 顺序随机排列 + static const QList udir = {"desktop", "videos", "music", "pictures", "documents", "downloads"}; + for (int i = 0; i < udir.count(); i++) { + for (int j = 0; j < ret.count(); j++) { + if (ret[j]->fileUrl().path().contains(udir[i]) && ret[j]->suffix() == SUFFIX_USRDIR && i != j) { + ret.move(j, i); + break; + } + } + } + } + + return ret; +} + +DRootFileManager *DRootFileManager::instance() +{ + static DRootFileManager services; + + return &services; +} + +bool DRootFileManager::isRootFileInited() const +{ + return d_ptr->m_bRootFileInited.load(); +} + +void DRootFileManager::changeRootFile(const DUrl &fileurl, const bool bcreate) +{ + QMutexLocker lk(&d_ptr->rootfileMtx); + if (bcreate) { + if (!d_ptr->rootfilelist.contains(fileurl)) { + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, fileurl); + if (info && info->exists()) { + d_ptr->rootfilelist.insert(fileurl, info); + qInfo() << " insert " << fileurl; + } + } + } else { + qDebug() << " remove " << d_ptr->rootfilelist; + if (d_ptr->rootfilelist.contains(fileurl)) { + qInfo() << " remove " << fileurl; + d_ptr->rootfilelist.remove(fileurl); + } + } +} + +void DRootFileManager::startQuryRootFile() +{ + if (!d_ptr->bstartonce) { + d_ptr->bstartonce = true; + + //NOTE [XIAO] 加载插件 + SchemePluginManager::instance()->loadSchemePlugin(); + + DAbstractFileWatcher *devicesWatcher = DFileService::instance()->createFileWatcher(nullptr, DUrl(DFMROOT_ROOT), this); + Q_CHECK_PTR(devicesWatcher); + if (d_ptr->m_rootFileWatcher) { + delete d_ptr->m_rootFileWatcher; + d_ptr->m_rootFileWatcher = nullptr; + } + d_ptr->m_rootFileWatcher = devicesWatcher; + if (qApp->thread() != devicesWatcher->thread()) { + devicesWatcher->moveToThread(qApp->thread()); + devicesWatcher->setParent(this); + } + + QTimer::singleShot(1000, devicesWatcher, [devicesWatcher]() { + devicesWatcher->startWatcher(); + }); + + connect(devicesWatcher, &DAbstractFileWatcher::subfileCreated, this, [this](const DUrl & url) { + changeRootFile(url); + }); + + connect(devicesWatcher, &DAbstractFileWatcher::fileDeleted, this, [this](const DUrl & url) { + changeRootFile(url, false); + }); + } + + bool openAsAdmin = DFMGlobal::isOpenAsAdmin(); + QMutexLocker lk(&d_ptr->rootfileMtx); + + if (openAsAdmin && d_ptr->m_jobcontroller && d_ptr->m_jobcontroller->isRunning()) { + qInfo() << "startQuryRootFile thread is running" << d_ptr->m_jobcontroller->currentThread(); + return; + } + + if (!openAsAdmin && d_ptr->m_jobcontroller) { + qInfo() << "startQuryRootFile thread is running" << d_ptr->m_jobcontroller->currentThread(); + return; + } + + //启用异步线程去读取 + d_ptr->m_jobcontroller = fileService->getChildrenJob(this, DUrl(DFMROOT_ROOT), QStringList(), QDir::AllEntries); + + lk.unlock(); + + connect(d_ptr->m_jobcontroller, &JobController::addChildren, this, [this](const DAbstractFileInfoPointer & chi) { + QMutexLocker locker(&d_ptr->rootfileMtx); + if (!d_ptr->rootfilelist.contains(chi->fileUrl()) && chi->exists()) { + d_ptr->rootfilelist.insert(chi->fileUrl(), chi); + d_ptr->m_rootChanged = true; + locker.unlock(); + emit rootFileChange(chi); // 其实中间结果没有必要,直接拿最终结果就行了,但保留接口,以后便于扩展 + } + }, Qt::DirectConnection); + + connect(d_ptr->m_jobcontroller, &JobController::addChildrenList, this, [this](QList ch) { + for (auto chi : ch) { + QMutexLocker locker(&d_ptr->rootfileMtx); + if (!d_ptr->rootfilelist.contains(chi->fileUrl()) && chi->exists()) { + d_ptr->rootfilelist.insert(chi->fileUrl(), chi); + d_ptr->m_rootChanged = true; + locker.unlock(); + emit rootFileChange(chi); // 其实中间结果没有必要,直接拿最终结果就行了,但保留接口,以后便于扩展 + } + } + }, Qt::DirectConnection); + connect(d_ptr->m_jobcontroller, &JobController::finished, this, [this]() { + QMutexLocker locker(&d_ptr->rootfileMtx); + d_ptr->m_jobcontroller->deleteLater(); + qInfo() << "get root file info thread jobcontroller finished " << QThread::currentThreadId() << d_ptr->rootfilelist.size(); + d_ptr->m_jobcontroller = nullptr; + d_ptr->m_bRootFileInited.store(true); + locker.unlock(); + + d_ptr->m_bRootFileInited.store(true); + if (d_ptr->m_rootChanged) + emit queryRootFileFinsh(); + + d_ptr->m_rootChanged = false; + + emit serviceHideSystemPartition(); // 刷新计算机页面,去掉无用块设备 + }, openAsAdmin ? Qt::DirectConnection : Qt::AutoConnection); + d_ptr->m_jobcontroller->start(); +} + + +DAbstractFileWatcher *DRootFileManager::rootFileWather() const +{ + return d_ptr->m_rootFileWatcher; +} + +void DRootFileManager::clearThread() +{ + if (d_ptr->m_jobcontroller && !d_ptr->m_jobcontroller->isFinished()) { + d_ptr->m_jobcontroller->wait(); + } +} + +void DRootFileManager::changRootFile(const QList &rootinfo) +{ + QMutexLocker lk(&d_ptr->rootfileMtx); + for (const DAbstractFileInfoPointer &fi : rootinfo) { + DUrl durl = fi->fileUrl(); + if (!d_ptr->rootfilelist.contains(durl) && fi->exists()) { + d_ptr->rootfilelist.insert(durl, fi); + } + } +} + +bool DRootFileManager::isRootFileContain(const DUrl &url) +{ + QMutexLocker lk(&d_ptr->rootfileMtx); + return d_ptr->rootfilelist.contains(url); +} + +const DAbstractFileInfoPointer DRootFileManager::getFileInfo(const DUrl &fileUrl) +{ + QMutexLocker lk(&DRootFileManagerPrivate::rootfileMtx); + return DRootFileManagerPrivate::rootfilelist.value(fileUrl); +} + +bool DRootFileManager::isRootFileContainSmb(const DUrl &smburl) +{ + if (smburl.scheme() != SMB_SCHEME) + return false; + QString host = smburl.host(); + QString shareName = smburl.path(); + if (host.isEmpty() || shareName.isEmpty()) + return false; + shareName = shareName.mid(1); + shareName = shareName.mid(0, shareName.indexOf("/")); + if (shareName.isEmpty()) + return false; + QMutexLocker lock(&d_ptr->rootfileMtx); + for (auto url : d_ptr->rootfilelist.keys()) { + QString strUrl = url.path(); + if (strUrl.contains(QUrl::toPercentEncoding("/run/user/")) + && strUrl.contains(QUrl::toPercentEncoding("/gvfs/smb-share:server=")) + && strUrl.contains(host) + && strUrl.endsWith(shareName + "." + SUFFIX_GVFSMP)) + return true; + } + return false; +} + +// sometimes we can use this function to relaod computer model. +// and i think this function called reloadComputerModel could be better. + +void DRootFileManager::hideSystemPartition() +{ + QList fileist = DFileService::instance()->\ + getChildren(this, DUrl(DFMROOT_ROOT), QStringList(), QDir::AllEntries, QDirIterator::NoIteratorFlags, false); + d_ptr->rootfileMtx.lock(); + d_ptr->rootfilelist.clear(); + d_ptr->rootfileMtx.unlock(); + changRootFile(fileist); + + emit serviceHideSystemPartition(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/drootfilemanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/drootfilemanager.h new file mode 100644 index 0000000..05165d7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/drootfilemanager.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * 2020 max-lv + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * max-lv + * + * + * 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 + * 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 . + */ + +#ifndef FROOTFILEMANAGER_H +#define FROOTFILEMANAGER_H + +#include "dabstractfilecontroller.h" +#include "durl.h" + +#include +#include +#include +#include +#include + +#include + +DFM_USE_NAMESPACE + +class JobController; +class DRootFileManagerPrivate; + +class DRootFileManager : public QObject +{ + Q_OBJECT + +public: + static DRootFileManager *instance(); + + QList getRootFile(); + bool isRootFileInited() const; + void changeRootFile(const DUrl &fileurl,const bool bcreate = true); + void startQuryRootFile(); + DAbstractFileWatcher *rootFileWather() const; + void clearThread(); + //chang rootfile + void changRootFile(const QList &rootinfo); + //处理rootfilelist中是否包含某个durl + bool isRootFileContain(const DUrl &url); + //get root file info cache + static const DAbstractFileInfoPointer getFileInfo(const DUrl &fileUrl); + bool isRootFileContainSmb(const DUrl &smburl); +signals: + void rootFileChange(const DAbstractFileInfoPointer &chi) const; + void queryRootFileFinsh() const; + void serviceHideSystemPartition() const; + +public Q_SLOTS: + void hideSystemPartition(); + +private: + explicit DRootFileManager(QObject *parent = nullptr); + ~DRootFileManager(); + + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(DRootFileManager) +}; + +#endif // FROOTFILEMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dthumbnailprovider.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dthumbnailprovider.cpp new file mode 100644 index 0000000..0fb40f3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dthumbnailprovider.cpp @@ -0,0 +1,787 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dthumbnailprovider.h" +#include "dfmstandardpaths.h" +#include "dmimedatabase.h" +#include "shutil/fileutils.h" +#include "app/define.h" +#include "singleton.h" +#include "shutil/mimetypedisplaymanager.h" +#include "fileoperations/filejob.h" +#include "dfmapplication.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// use original poppler api +#include +#include +#include +#include +#include + +#include + +DFM_BEGIN_NAMESPACE + +#define FORMAT ".png" +//#define CREATE_VEDIO_THUMB "CreateVedioThumbnail" + +inline QByteArray dataToMd5Hex(const QByteArray &data) +{ + return QCryptographicHash::hash(data, QCryptographicHash::Md5).toHex(); +} + +class DThumbnailProviderPrivate +{ +public: + explicit DThumbnailProviderPrivate(DThumbnailProvider *qq); + + void init(); + + QString sizeToFilePath(DThumbnailProvider::Size size) const; + + DThumbnailProvider *q_ptr; + QString errorString; + // 5MB + qint64 defaultSizeLimit = 1024 * 1024 * 20; + QHash sizeLimitHash; + DMimeDatabase mimeDatabase; + + static QSet hasThumbnailMimeHash; + + struct ProduceInfo { + QFileInfo fileInfo; + DThumbnailProvider::Size size; + DThumbnailProvider::CallBack callback; + }; + + QQueue produceQueue; + QQueue m_produceAbsoluteFilePathQueue; + QSet> discardedProduceInfos; + + bool running = true; + + QWaitCondition waitCondition; + QReadWriteLock dataReadWriteLock; + + QHash keyToThumbnailTool; + + Q_DECLARE_PUBLIC(DThumbnailProvider) +}; + +QSet DThumbnailProviderPrivate::hasThumbnailMimeHash; + +DThumbnailProviderPrivate::DThumbnailProviderPrivate(DThumbnailProvider *qq) + : q_ptr(qq) +{ + +} + +void DThumbnailProviderPrivate::init() +{ + sizeLimitHash.reserve(28); + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("text/plain"), 1024 * 1024); + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("application/pdf"), INT64_MAX); +// sizeLimitHash.insert(mimeDatabase.mimeTypeForName("application/vnd.adobe.flash.movie"), INT64_MAX); + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("application/vnd.rn-realmedia"), INT64_MAX); + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("application/vnd.ms-asf"), INT64_MAX); + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("application/mxf"), INT64_MAX); + + //images + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("image/ief"), 1024 * 1024 * 80); + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("image/tiff"), 1024 * 1024 * 80); + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("image/x-tiff-multipage"), 1024 * 1024 * 80); + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("image/vnd.djvu+multipage"), 1024 * 1024 * 80); + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("image/x-adobe-dng"), 1024 * 1024 * 80); + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("image/jpeg"), 1024 * 1024 * 30); + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("image/png"), 1024 * 1024 * 30); + sizeLimitHash.insert(mimeDatabase.mimeTypeForName("image/pipeg"), 1024 * 1024 * 30); +} + +QString DThumbnailProviderPrivate::sizeToFilePath(DThumbnailProvider::Size size) const +{ + switch (size) { + case DThumbnailProvider::Small: + return DFMStandardPaths::location(DFMStandardPaths::ThumbnailSmallPath); + case DThumbnailProvider::Normal: + return DFMStandardPaths::location(DFMStandardPaths::ThumbnailNormalPath); + case DThumbnailProvider::Large: + return DFMStandardPaths::location(DFMStandardPaths::ThumbnailLargePath); + } + return ""; //默认返回空字符 warning项 +} + +class DFileThumbnailProviderPrivate : public DThumbnailProvider {}; +Q_GLOBAL_STATIC(DFileThumbnailProviderPrivate, ftpGlobal) + +DThumbnailProvider *DThumbnailProvider::instance() +{ + return ftpGlobal; +} + +bool DThumbnailProvider::hasThumbnail(const QFileInfo &info) const +{ + Q_D(const DThumbnailProvider); + + if (!info.isReadable() || !info.isFile()) + return false; + + qint64 fileSize = info.size(); + + if (fileSize <= 0) + return false; + + const QMimeType &mime = d->mimeDatabase.mimeTypeForFile(info); + + if (mime.name().startsWith("video/") && FileJob::CopyingFiles.contains(DUrl::fromLocalFile(info.filePath()))) + return false; + + if (mime.name().startsWith("video/") && FileUtils::isGvfsMountFile(info.absoluteFilePath())) + return false; + + if (fileSize > sizeLimit(mime) && !mime.name().startsWith("video/")) + return false; + + return hasThumbnail(mime); +} + +bool DThumbnailProvider::hasThumbnail(const QMimeType &mimeType) const +{ + const QString &mime = mimeType.name(); + QStringList mimeTypeList = {mime}; + mimeTypeList.append(mimeType.parentMimeTypes()); + + if (mime.startsWith("image") && !DFMApplication::instance()->genericAttribute(DFMApplication::GA_PreviewImage).toBool()) + return false; + + if ((mime.startsWith("video") || mimeTypeDisplayManager->supportVideoMimeTypes().contains(mime)) + && !DFMApplication::instance()->genericAttribute(DFMApplication::GA_PreviewVideo).toBool()) + return false; + + if (mime == "text/plain" && !DFMApplication::instance()->genericAttribute(DFMApplication::GA_PreviewTextFile).toBool()) + return false; + + if (Q_LIKELY(mimeTypeList.contains("application/pdf") + || mime == "application/cnd.rn-realmedia" + || mime == "application/mxf") + && !DFMApplication::instance()->genericAttribute(DFMApplication::GA_PreviewDocumentFile).toBool()) { + return false; + } + + if (DThumbnailProviderPrivate::hasThumbnailMimeHash.contains(mime)) + return true; + + if (Q_LIKELY(mime.startsWith("image") || mime.startsWith("video/"))) { + DThumbnailProviderPrivate::hasThumbnailMimeHash.insert(mime); + + return true; + } + + if (Q_LIKELY(mime == "text/plain" || mimeTypeList.contains("application/pdf") +// || mime == "application/vnd.adobe.flash.movie" + || mime == "application/vnd.rn-realmedia" + || mime == "application/vnd.ms-asf" + || mime == "application/mxf")) { + DThumbnailProviderPrivate::hasThumbnailMimeHash.insert(mime); + + return true; + } + + if (DTK_GUI_NAMESPACE::DThumbnailProvider::instance()->hasThumbnail(mimeType)) + return true; + + return false; +} + +QString DThumbnailProvider::thumbnailFilePath(const QFileInfo &info, Size size) const +{ + Q_D(const DThumbnailProvider); + + const QString &absolutePath = info.absolutePath(); + const QString &absoluteFilePath = info.absoluteFilePath(); + + if (absolutePath == d->sizeToFilePath(Small) + || absolutePath == d->sizeToFilePath(Normal) + || absolutePath == d->sizeToFilePath(Large) + || absolutePath == DFMStandardPaths::location(DFMStandardPaths::ThumbnailFailPath)) { + return absoluteFilePath; + } + struct stat st; + ulong inode = 0; + QByteArray pathArry = absoluteFilePath.toUtf8(); + std::string pathStd = pathArry.toStdString(); + if (stat(pathStd.c_str(), &st) == 0) + inode = st.st_ino; + + const QString thumbnailName = dataToMd5Hex((QUrl::fromLocalFile(absoluteFilePath). + toString(QUrl::FullyEncoded) + QString::number(inode)).toLocal8Bit()) + FORMAT; + QString thumbnail = d->sizeToFilePath(size) + QDir::separator() + thumbnailName; + + if (!QFile::exists(thumbnail)) { + return QString(); + } + + QImageReader ir(thumbnail, QByteArray(FORMAT).mid(1)); + if (!ir.canRead()) { + QFile::remove(thumbnail); + emit thumbnailChanged(absoluteFilePath, QString()); + return QString(); + } + ir.setAutoDetectImageFormat(false); + + const QImage image = ir.read(); + + if (!image.isNull() && image.text(QT_STRINGIFY(Thumb::MTime)).toInt() != (int)info.lastModified().toTime_t()) { + QFile::remove(thumbnail); + + emit thumbnailChanged(absoluteFilePath, QString()); + + return QString(); + } + + return thumbnail; +} + +static QString generalKey(const QString &key) +{ + const QStringList &_tmp = key.split('/'); + + if (_tmp.size() > 1) + return _tmp.first() + "/*"; + + return key; +} + +QString DThumbnailProvider::createThumbnail(const QFileInfo &info, DThumbnailProvider::Size size) +{ + Q_D(DThumbnailProvider); + + d->errorString.clear(); + + const QString &absolutePath = info.absolutePath(); + const QString &absoluteFilePath = info.absoluteFilePath(); + + if (absolutePath == d->sizeToFilePath(Small) + || absolutePath == d->sizeToFilePath(Normal) + || absolutePath == d->sizeToFilePath(Large) + || absolutePath == DFMStandardPaths::location(DFMStandardPaths::ThumbnailFailPath)) { + return absoluteFilePath; + } + + if (!hasThumbnail(info)) { + d->errorString = QStringLiteral("This file has not support thumbnail: ") + absoluteFilePath; + + //!Warnning: Do not store thumbnails to the fail path + return QString(); + } + + const QString fileUrl = QUrl::fromLocalFile(absoluteFilePath).toString(QUrl::FullyEncoded); + struct stat st; + ulong inode = 0; + QByteArray pathArry = absoluteFilePath.toUtf8(); + std::string pathStd = pathArry.toStdString(); + if (stat(pathStd.c_str(), &st) == 0) + inode = st.st_ino; + const QString thumbnailName = dataToMd5Hex((fileUrl + QString::number(inode)).toLocal8Bit()) + FORMAT; + + // the file is in fail path + QString thumbnail = DFMStandardPaths::location(DFMStandardPaths::ThumbnailFailPath) + QDir::separator() + thumbnailName; + +// if (QFile::exists(thumbnail)) { +// QImage image(thumbnail); + +// if (image.text(QT_STRINGIFY(Thumb::MTime)).toInt() != (int)info.lastModified().toTime_t()) { +// QFile::remove(thumbnail); +// } else { +// return QString(); +// } +// }// end + + QMimeType mime = d->mimeDatabase.mimeTypeForFile(info); + QScopedPointer image(new QImage()); + + QStringList mimeTypeList = {mime.name()}; + mimeTypeList.append(mime.parentMimeTypes()); + + //! 新增djvu格式文件缩略图预览 + if (mime.name().contains("image/vnd.djvu")) { + thumbnail = DTK_GUI_NAMESPACE::DThumbnailProvider::instance()->createThumbnail(info, (DTK_GUI_NAMESPACE::DThumbnailProvider::Size)size); + d->errorString = DTK_GUI_NAMESPACE::DThumbnailProvider::instance()->errorString(); + + if (d->errorString.isEmpty()) { + emit createThumbnailFinished(absoluteFilePath, thumbnail); + emit thumbnailChanged(absoluteFilePath, thumbnail); + + return thumbnail; + } else { + QString readerBinary = QStandardPaths::findExecutable("deepin-reader"); + if (readerBinary.isEmpty()) + return thumbnail; + //! 使用子进程来调用deepin-reader程序生成djvu格式文件缩略图 + QProcess process; + QStringList arguments; + //! 生成缩略图缓存地址 + QString saveImage = d->sizeToFilePath(size) + QDir::separator() + thumbnailName; + arguments << "--thumbnail" << "-f" << absoluteFilePath << "-t" << saveImage; + process.start(readerBinary, arguments); + + if (!process.waitForFinished()) { + d->errorString = process.errorString(); + + goto _return; + } + + if (process.exitCode() != 0) { + const QString &error = process.readAllStandardError(); + + if (error.isEmpty()) { + d->errorString = QString("get thumbnail failed from the \"%1\" application").arg(readerBinary); + } else { + d->errorString = error; + } + + goto _return; + } + + QFile file(saveImage); + if (file.open(QIODevice::ReadOnly)) { + QByteArray output = file.readAll(); + //QByteArray png_data = QByteArray::fromBase64(output); + Q_ASSERT(!output.isEmpty()); + + if (image->loadFromData(output, "png")) { + d->errorString.clear(); + } + file.close(); + } + } + } else if (mime.name().startsWith("image/")) { +// mime = d->mimeDatabase.mimeTypeForFile(info, QMimeDatabase::MatchContent); +// QImageReader reader(absoluteFilePath, mime.preferredSuffix().toLatin1()); + + //! fix bug#49451 因为使用mime.preferredSuffix(),会导致后续image.save崩溃,具体原因还需进一步跟进 + //! QImageReader构造时不传format参数,让其自行判断 + //! fix bug #53200 QImageReader构造时不传format参数,会造成没有读取不了真实的文件 类型比如将png图标后缀修改为jpg,读取的类型不对 + + QString mimeType = d->mimeDatabase.mimeTypeForFile(info, QMimeDatabase::MatchContent).name(); + QString suffix = mimeType.replace("image/", ""); + + QImageReader reader(absoluteFilePath, suffix.toLatin1()); + if (!reader.canRead()) { + d->errorString = reader.errorString(); + goto _return; + } + + const QSize &imageSize = reader.size(); + + //fix 读取损坏icns文件(可能任意损坏的image类文件也有此情况)在arm平台上会导致递归循环的问题 + //这里先对损坏文件(imagesize无效)做处理,不再尝试读取其image数据 + if (!imageSize.isValid()) { + d->errorString = "Fail to read image file attribute data:" + info.absoluteFilePath(); + goto _return; + } + + if (imageSize.width() > size || imageSize.height() > size || mime.name() == "image/svg+xml") { + reader.setScaledSize(reader.size().scaled(size, size, Qt::KeepAspectRatio)); + } + + reader.setAutoTransform(true); + + if (!reader.read(image.data())) { + d->errorString = reader.errorString(); + goto _return; + } + + if (image->width() > size || image->height() > size) { + image->operator =(image->scaled(size, size, Qt::KeepAspectRatio)); + } + } else if (mime.name() == "text/plain") { + //FIXME(zccrs): This should be done using the image plugin? + QFile file(absoluteFilePath); + + if (!file.open(QIODevice::ReadOnly)) { + d->errorString = file.errorString(); + goto _return; + } + + QString text{ DFMGlobal::toUnicode(file.read(2000), file.fileName()) }; + file.close(); + + QFont font; + font.setPixelSize(12); + + QPen pen; + pen.setColor(Qt::black); + + *image = QImage(0.70707070 * size, size, QImage::Format_ARGB32_Premultiplied); + image->fill(Qt::white); + + QPainter painter(image.data()); + painter.setFont(font); + painter.setPen(pen); + + QTextOption option; + + option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + painter.drawText(image->rect(), text, option); + } else if (mimeTypeList.contains("application/pdf")) { + //FIXME(zccrs): This should be done using the image plugin? + QScopedPointer doc(poppler::document::load_from_file(absoluteFilePath.toStdString())); + + if (!doc || doc->is_locked()) { + d->errorString = QStringLiteral("Cannot read this pdf file: ") + absoluteFilePath; + goto _return; + } + + if (doc->pages() < 1) { + d->errorString = QStringLiteral("This stream is invalid"); + goto _return; + } + + QScopedPointer page(doc->create_page(0)); + + if (!page) { + d->errorString = QStringLiteral("Cannot get this page at index 0"); + goto _return; + } + + poppler::page_renderer pr; + pr.set_render_hint(poppler::page_renderer::antialiasing, true); + pr.set_render_hint(poppler::page_renderer::text_antialiasing, true); + + poppler::image imageData = pr.render_page(page.data(), 72, 72, -1, -1, -1, size); + + if (!imageData.is_valid()) { + d->errorString = QStringLiteral("Render error"); + goto _return; + } + + poppler::image::format_enum format = imageData.format(); + QImage img; + + switch (format) { + case poppler::image::format_invalid: + d->errorString = QStringLiteral("Image format is invalid"); + goto _return; + case poppler::image::format_mono: + img = QImage((uchar *)imageData.data(), imageData.width(), imageData.height(), QImage::Format_Mono); + break; + case poppler::image::format_rgb24: + img = QImage((uchar *)imageData.data(), imageData.width(), imageData.height(), QImage::Format_ARGB6666_Premultiplied); + break; + case poppler::image::format_argb32: + img = QImage((uchar *)imageData.data(), imageData.width(), imageData.height(), QImage::Format_ARGB32); + break; + default: + break; + } + + if (img.isNull()) { + d->errorString = QStringLiteral("Render error"); + goto _return; + } + + *image = img.scaled(QSize(size, size), Qt::KeepAspectRatio, Qt::SmoothTransformation); + } else { + thumbnail = DTK_GUI_NAMESPACE::DThumbnailProvider::instance()->createThumbnail(info, (DTK_GUI_NAMESPACE::DThumbnailProvider::Size)size); + d->errorString = DTK_GUI_NAMESPACE::DThumbnailProvider::instance()->errorString(); + + if (d->errorString.isEmpty()) { + emit createThumbnailFinished(absoluteFilePath, thumbnail); + emit thumbnailChanged(absoluteFilePath, thumbnail); + + return thumbnail; + } else { // fallback to thumbnail tool + if (d->keyToThumbnailTool.isEmpty()) { + d->keyToThumbnailTool["Initialized"] = QString(); + + for (const QString &path : QString(TOOLDIR).split(":")) { + const QString &thumbnail_tool_path = path + QDir::separator() + "/thumbnail"; + QDirIterator dir(thumbnail_tool_path, {"*.json"}, QDir::NoDotAndDotDot | QDir::Files); + + while (dir.hasNext()) { + const QString &file_path = dir.next(); + const QFileInfo &file_info = dir.fileInfo(); + + QFile file(file_path); + + if (!file.open(QFile::ReadOnly)) { + continue; + } + + const QJsonDocument document = QJsonDocument::fromJson(file.readAll()); + file.close(); + + const QStringList keys = document.object().toVariantMap().value("Keys").toStringList(); + const QString &tool_file_path = file_info.absoluteDir().filePath(file_info.baseName()); + + if (!QFile::exists(tool_file_path)) { + continue; + } + + for (const QString &key : keys) { + if (d->keyToThumbnailTool.contains(key)) + continue; + + d->keyToThumbnailTool[key] = tool_file_path; + } + } + } + } + + QString mime_name = mime.name(); + QString tool = d->keyToThumbnailTool.value(mime_name); + + if (tool.isEmpty()) { + mime_name = generalKey(mime_name); + tool = d->keyToThumbnailTool.value(mime_name); + } + + if (tool.isEmpty()) { + return thumbnail; + } + + QProcess process; + process.start(tool, {QString::number(size), absoluteFilePath}, QIODevice::ReadOnly); + + if (!process.waitForFinished()) { + d->errorString = process.errorString(); + + goto _return; + } + + if (process.exitCode() != 0) { + const QString &error = process.readAllStandardError(); + + if (error.isEmpty()) { + d->errorString = QString("get thumbnail failed from the \"%1\" application").arg(tool); + } else { + d->errorString = error; + } + + goto _return; + } + + const QByteArray output = process.readAllStandardOutput(); + const QByteArray png_data = QByteArray::fromBase64(output); + Q_ASSERT(!png_data.isEmpty()); + + if (image->loadFromData(png_data, "png")) { + d->errorString.clear(); + } else { + //过滤video tool的其他输出信息 + QString processResult(output); + processResult = processResult.split(QRegExp("[\n]"), QString::SkipEmptyParts).last(); + const QByteArray pngData = QByteArray::fromBase64(processResult.toUtf8()); + Q_ASSERT(!pngData.isEmpty()); + if (image->loadFromData(pngData, "png")) { + d->errorString.clear(); + } else { + d->errorString = QString("load png image failed from the \"%1\" application").arg(tool); + } + } + } + } + +_return: + // successful + if (d->errorString.isEmpty()) { + thumbnail = d->sizeToFilePath(size) + QDir::separator() + thumbnailName; + } else { + //fail + image.reset(new QImage(1, 1, QImage::Format_Mono)); + } + + image->setText(QT_STRINGIFY(Thumb::URL), fileUrl); + image->setText(QT_STRINGIFY(Thumb::MTime), QString::number(info.lastModified().toTime_t())); + + // create path + QFileInfo(thumbnail).absoluteDir().mkpath("."); + + if (!image->save(thumbnail, Q_NULLPTR, 80)) { + d->errorString = QStringLiteral("Can not save image to ") + thumbnail; + } + + if (d->errorString.isEmpty()) { + emit createThumbnailFinished(absoluteFilePath, thumbnail); + emit thumbnailChanged(absoluteFilePath, thumbnail); + + return thumbnail; + } + + // fail + emit createThumbnailFailed(absoluteFilePath); + + return QString(); +} + +void DThumbnailProvider::appendToProduceQueue(const QFileInfo &info, DThumbnailProvider::Size size, DThumbnailProvider::CallBack callback) +{ + DThumbnailProviderPrivate::ProduceInfo produceInfo; + + produceInfo.fileInfo = info; + produceInfo.size = size; + produceInfo.callback = callback; + + Q_D(DThumbnailProvider); + + if (isRunning()) { + QWriteLocker locker(&d->dataReadWriteLock); + // fix bug 62540 这里在没生成缩略图的情况下,(触发刷新,文件大小改变)同一个文件会多次生成缩略图的情况, + // 缓存当前队列中生成的缩略图文件的路劲没有就加入队里生成 + if (!d->m_produceAbsoluteFilePathQueue.contains(info.absoluteFilePath())) { + d->produceQueue.append(std::move(produceInfo)); + d->m_produceAbsoluteFilePathQueue << info.absoluteFilePath(); + } + locker.unlock(); + d->waitCondition.wakeAll(); + } else { + // fix bug 62540 这里在没生成缩略图的情况下,(触发刷新,文件大小改变)同一个文件会多次生成缩略图的情况, + // 缓存当前队列中生成的缩略图文件的路劲没有就加入队里生成 + if (!d->m_produceAbsoluteFilePathQueue.contains(info.absoluteFilePath())) { + d->produceQueue.append(std::move(produceInfo)); + d->m_produceAbsoluteFilePathQueue << info.absoluteFilePath(); + } + start(); + } +} + +void DThumbnailProvider::removeInProduceQueue(const QFileInfo &info, DThumbnailProvider::Size size) +{ + Q_D(DThumbnailProvider); + + if (isRunning()) { + QWriteLocker locker(&d->dataReadWriteLock); + Q_UNUSED(locker) + } + + d->discardedProduceInfos.insert(qMakePair(info.absoluteFilePath(), size)); +} + +QString DThumbnailProvider::errorString() const +{ + Q_D(const DThumbnailProvider); + + return d->errorString; +} + +qint64 DThumbnailProvider::defaultSizeLimit() const +{ + Q_D(const DThumbnailProvider); + + return d->defaultSizeLimit; +} + +void DThumbnailProvider::setDefaultSizeLimit(qint64 size) +{ + Q_D(DThumbnailProvider); + + d->defaultSizeLimit = size; +} + +qint64 DThumbnailProvider::sizeLimit(const QMimeType &mimeType) const +{ + Q_D(const DThumbnailProvider); + + return d->sizeLimitHash.value(mimeType, d->defaultSizeLimit); +} + +void DThumbnailProvider::setSizeLimit(const QMimeType &mimeType, qint64 size) +{ + Q_D(DThumbnailProvider); + + d->sizeLimitHash[mimeType] = size; +} + +DThumbnailProvider::DThumbnailProvider(QObject *parent) + : QThread(parent) + , d_ptr(new DThumbnailProviderPrivate(this)) +{ + d_func()->init(); +} + +DThumbnailProvider::~DThumbnailProvider() +{ + Q_D(DThumbnailProvider); + + d->running = false; + d->waitCondition.wakeAll(); + wait(); +} + +void DThumbnailProvider::run() +{ + Q_D(DThumbnailProvider); + + forever { + QWriteLocker locker(&d->dataReadWriteLock); + + if (d->produceQueue.isEmpty()) { + d->waitCondition.wait(&d->dataReadWriteLock); + } + + if (!d->running) + return; + + const DThumbnailProviderPrivate::ProduceInfo &task = d->produceQueue.dequeue(); + const QPair &tmpKey = qMakePair(task.fileInfo.absoluteFilePath(), task.size); + + if (d->discardedProduceInfos.contains(tmpKey)) { + d->discardedProduceInfos.remove(tmpKey); + //fix 62540 去除缓存 + d->m_produceAbsoluteFilePathQueue.removeOne(task.fileInfo.absoluteFilePath()); + locker.unlock(); + continue; + } + + locker.unlock(); + + const QString &thumbnail = createThumbnail(task.fileInfo, task.size); + + locker.relock(); + //fix 62540 生成结束了去除缓存 + d->m_produceAbsoluteFilePathQueue.removeOne(task.fileInfo.absoluteFilePath()); + locker.unlock(); + + if (task.callback) + task.callback(thumbnail); + } +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dthumbnailprovider.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dthumbnailprovider.h new file mode 100644 index 0000000..7305f37 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dthumbnailprovider.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFM_DFILETHUMBNAILPROVIDER_H +#define DFM_DFILETHUMBNAILPROVIDER_H + +#include +#include + +#include "dfmglobal.h" + +#include + +QT_BEGIN_NAMESPACE +class QMimeType; +QT_END_NAMESPACE + +DFM_BEGIN_NAMESPACE + +class DThumbnailProviderPrivate; +class DThumbnailProvider : public QThread +{ + Q_OBJECT + +public: + enum Size { + Small = 64, + Normal = 128, + Large = 256, + }; + + static DThumbnailProvider *instance(); + + bool hasThumbnail(const QFileInfo &info) const; + bool hasThumbnail(const QMimeType &mimeType) const; + + QString thumbnailFilePath(const QFileInfo &info, Size size) const; + + typedef std::function CallBack; + QString createThumbnail(const QFileInfo &info, Size size); + void appendToProduceQueue(const QFileInfo &info, Size size, CallBack callback = 0); + void removeInProduceQueue(const QFileInfo &info, Size size); + + QString errorString() const; + + qint64 defaultSizeLimit() const; + void setDefaultSizeLimit(qint64 size); + + qint64 sizeLimit(const QMimeType &mimeType) const; + void setSizeLimit(const QMimeType &mimeType, qint64 size); + +signals: + void thumbnailChanged(const QString &sourceFilePath, const QString &thumbnailPath) const; + void createThumbnailFinished(const QString &sourceFilePath, const QString &thumbnailPath) const; + void createThumbnailFailed(const QString &sourceFilePath) const; + +protected: + explicit DThumbnailProvider(QObject *parent = 0); + ~DThumbnailProvider() override; + + void run() override; + +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(DThumbnailProvider) +}; + +DFM_END_NAMESPACE + +#endif // DFM_DFILETHUMBNAILPROVIDER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dumountmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dumountmanager.cpp new file mode 100644 index 0000000..59a8e74 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dumountmanager.cpp @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "interfaces/dumountmanager.h" +#include "interfaces/defenderinterface.h" + +#include "dblockdevice.h" +#include "ddiskdevice.h" +#include "ddiskmanager.h" + +#include +#include +#include + +DUMountManager::DUMountManager(QObject *parent) + :QObject(parent) +{ + m_defenderInterface.reset(new DefenderInterface); +} + +DUMountManager::~DUMountManager() +{ +} + +QString DUMountManager::getDriveName(const QString &blkName) +{ + QScopedPointer blkd(DDiskManager::createBlockDevice(blkName)); + return blkd ? blkd->drive() : QString(); +} + +bool DUMountManager::isScanningBlock(const QString &blkName) +{ + QUrl url = getMountPathForBlock(blkName); + return m_defenderInterface->isScanning(url); +} + +bool DUMountManager::isScanningDrive(const QString &driveName) +{ + QList urls; + if (driveName.isNull() || driveName.isEmpty()) + urls = getMountPathForAllDrive(); + else + urls = getMountPathForDrive(driveName); + return m_defenderInterface->isScanning(urls); +} + +bool DUMountManager::stopScanBlock(const QString &blkName) +{ + const QUrl &url = getMountPathForBlock(blkName); + if (!m_defenderInterface->stopScanning(url)) { + errorMsg = "stop scanning timeout."; + return false; + } + + clearError(); + return true; +} + +bool DUMountManager::stopScanDrive(const QString &driveName) +{ + const QList &urls = getMountPathForDrive(driveName); + if (!m_defenderInterface->stopScanning(urls)) { + errorMsg = "stop scanning timeout."; + return false; + } + + clearError(); + return true; +} + +bool DUMountManager::stopScanAllDrive() +{ + const QList &urls = getMountPathForAllDrive(); + if (!m_defenderInterface->stopScanning(urls)) { + errorMsg = "stop scanning timeout."; + return false; + } + + clearError(); + return true; +} + +bool DUMountManager::umountBlock(const QString &blkName) +{ + QScopedPointer blkdev(DDiskManager::createBlockDevice(blkName)); + if (!blkdev) { + errorMsg = "invalid blk device"; + qWarning() << "invalid blk device:" << blkName; + return false; + } + + if (blkdev->isEncrypted()) + blkdev.reset(DDiskManager::createBlockDevice(blkdev->cleartextDevice())); + + qInfo() << "umount start:" << blkName; + if (!blkdev->mountPoints().empty()) + blkdev->unmount({}); + + qInfo() << "umount done:" << blkName; + + QDBusError err = blkdev->lastError(); + if (blkdev->cryptoBackingDevice().length() > 1) { + QScopedPointer cbblk(DDiskManager::createBlockDevice(blkdev->cryptoBackingDevice())); + if (cbblk) { + cbblk->lock({}); + if (cbblk->lastError().isValid()) + err = cbblk->lastError(); + } + } + + // 检查挂载点移除代表卸载成功 + if (blkdev->mountPoints().empty()) + return true; + + errorMsg = checkMountErrorMsg(err); + return false; +} + +bool DUMountManager::umountBlocksOnDrive(const QString &driveName) +{ + if (driveName.isNull() || driveName.isEmpty()) { + qWarning() << "invalid drive name:" << driveName; + errorMsg = "invalid drive name" ; + return false; + } + + qInfo() << "start umount blocks on drive:" << driveName; + for (const QString &blkStr : DDiskManager::blockDevices({})) { + QScopedPointer blkd(DDiskManager::createBlockDevice(blkStr)); + if (blkd && blkd->drive() == driveName) { + if (!umountBlock(blkStr)) { + qWarning() << "umountBlock failed: drive = " << driveName << ", block str = " << blkStr; + errorMsg = "umount block failed"; + return false; + } + } + } + return true; +} + +QString DUMountManager::checkMountErrorMsg(const QDBusError &dbsError) +{ + if (!dbsError.isValid()) + return QString(); + + if (dbsError.type() == QDBusError::NoReply) + return tr("Authentication timed out"); + + return tr("Disk is busy, cannot unmount now"); +} + +QString DUMountManager::checkEjectErrorMsg(const QDBusError &dbsError) +{ + if (!dbsError.isValid()) + return QString(); + + if (dbsError.type() == QDBusError::NoReply) + return tr("Authentication timed out"); + + // 其他错误,统一提示,设备繁忙 + return tr("Disk is busy, cannot eject now"); +} + +bool DUMountManager::removeDrive(const QString &driveName) +{ + QScopedPointer drv(DDiskManager::createDiskDevice(driveName)); + if (!drv) { + errorMsg = "invalid drive."; + return false; + } + + // 尝试性卸载, 错误处理依赖后续流程 + umountBlocksOnDrive(driveName); + + qInfo() << "start remove drive:" << driveName; + if (drv->canPowerOff()) { + drv->powerOff({}); + + if (drv->lastError().isValid()) { + qWarning() << drv->lastError() << "id:" << drv->lastError().type(); + errorMsg = tr("The device is busy, cannot remove now"); + } + } + + DDiskManager diskManager; + QStringList devices = diskManager.diskDevices(); + qInfo() << "rest devices:" << devices; + + // 磁盘已经不在磁盘列表, 代表移除成功 + if (!devices.contains(driveName)) + return true; + + // 处理错误 + errorMsg = checkEjectErrorMsg(drv->lastError()); + return false; +} + +bool DUMountManager::ejectDrive(const QString &driveName) +{ + QScopedPointer drv(DDiskManager::createDiskDevice(driveName)); + if (!drv) { + errorMsg = "invalid drive."; + return false; + } + + // 尝试性卸载, 错误处理依赖后续流程 + umountBlocksOnDrive(driveName); + + qInfo() << "start eject drive:" << driveName; + if (drv->optical()) { + if (drv->ejectable()) { + drv->eject({}); + + if (drv->lastError().isValid()) { + qWarning() << drv->lastError() << "id:" << drv->lastError().type(); + errorMsg = tr("The device is busy, cannot eject now"); + return false; + } + + qInfo() << "eject done:" << driveName; + return true; + } + } + + if (drv->removable()) { + drv->eject({}); + + if (drv->lastError().isValid()) { + qWarning() << drv->lastError() << "id:" << drv->lastError().type(); + errorMsg = tr("The device is busy, cannot remove now"); + return false; + } + } + + if (drv->canPowerOff()) { + drv->powerOff({}); + + if (drv->lastError().isValid()) { + qWarning() << drv->lastError() << "id:" << drv->lastError().type(); + errorMsg = tr("The device is busy, cannot remove now"); + return false; + } + } + + return true; +} + +bool DUMountManager::ejectAllDrive() +{ + DDiskManager diskManager; + QStringList blockDevices = diskManager.blockDevices({}); + QSet removableDrives; + + for (const QString &blDevStr : blockDevices) { + QScopedPointer blDev(DDiskManager::createBlockDevice(blDevStr)); + if (!blDev) + continue; + + const QString &driveName = blDev->drive(); + if (driveName.isNull() || driveName.isEmpty()) + continue; + + // 只对可以移除块设备进行处理 + QScopedPointer drv(DDiskManager::createDiskDevice(blDev->drive())); + if (drv && drv->removable()) + removableDrives.insert(driveName); + } + + // 记录最后错误, 尽可能将能弹出的移动盘弹出 + bool allSuccess = true; + foreach (const QString &drive, removableDrives) { + if (!ejectDrive(drive)) + allSuccess = false; + } + + return allSuccess; +} + +QUrl DUMountManager::getMountPathForBlock(const QString &blkName) +{ + QScopedPointer blk(DDiskManager::createBlockDevice(blkName)); + if (!blk) + return QUrl(); + + const QList &mountPoints = blk->mountPoints(); + if (mountPoints.empty()) + return QUrl(); + + return QUrl::fromLocalFile(mountPoints.first()); +} + +QList DUMountManager::getMountPathForDrive(const QString &driveName) +{ + QList urls; + + for (const QString &blkStr : DDiskManager::blockDevices({})) { + QScopedPointer blkd(DDiskManager::createBlockDevice(blkStr)); + if (blkd && blkd->drive() == driveName) { + const QUrl &url = getMountPathForBlock(blkStr); + if (url.isValid()) + urls << url; + } + } + return urls; +} + +QList DUMountManager::getMountPathForAllDrive() +{ + const QStringList &blockDevices = DDiskManager::blockDevices({}); + QList urls; + foreach (const QString blkName, blockDevices) { + const QUrl &url = getMountPathForBlock(blkName); + urls << url; + } + return urls; +} + +void DUMountManager::clearError() +{ + errorMsg = QString(); +} + +QString DUMountManager::getErrorMsg() +{ + return errorMsg; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dumountmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dumountmanager.h new file mode 100644 index 0000000..599e8ab --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/dumountmanager.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DUMOUNT_MANAGER_H +#define DUMOUNT_MANAGER_H + +#include +#include + +class DefenderInterface; + +class DUMountManager : public QObject +{ + Q_OBJECT + +public: + DUMountManager(QObject *parent = nullptr); + ~DUMountManager(); + + QString getDriveName(const QString &blkName); + + bool isScanningBlock(const QString &blkName); + bool isScanningDrive(const QString &driveName = QString("")); + bool stopScanBlock(const QString &blkName); + bool stopScanDrive(const QString &driveName); + bool stopScanAllDrive(); + + bool umountBlock(const QString &blkName); + bool umountBlocksOnDrive(const QString &driveName); + bool removeDrive(const QString &driveName); + bool ejectDrive(const QString &driveName); + bool ejectAllDrive(); + + QString getErrorMsg(); + +private: + QString checkMountErrorMsg(const QDBusError &dbsError); + QString checkEjectErrorMsg(const QDBusError &dbsError); + QUrl getMountPathForBlock(const QString &blkName); + QList getMountPathForDrive(const QString &driveName); + QList getMountPathForAllDrive(); + void clearError(); + +private: + QScopedPointer m_defenderInterface; + QString errorMsg; +}; + +#endif //DUMOUNT_MANAGER_H + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/durl.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/durl.cpp new file mode 100644 index 0000000..415e08c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/durl.cpp @@ -0,0 +1,864 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "durl.h" +#include "interfaces/dfmstandardpaths.h" + +#include + +#include +#include +#include +#include +#include + +QRegularExpression DUrl::burn_rxp = QRegularExpression("^(.*?)/(" BURN_SEG_ONDISC "|" BURN_SEG_STAGING ")(.*)$"); + +static inline QString parseDecodedComponent(const QString &data) +{ + return QString(data).replace(QLatin1Char('%'), QStringLiteral("%25")); +} + +QSet schemeList = QSet() << QString(TRASH_SCHEME) + << QString(RECENT_SCHEME) + << QString(BOOKMARK_SCHEME) + << QString(FILE_SCHEME) + << QString(COMPUTER_SCHEME) + << QString(SEARCH_SCHEME) + << QString(NETWORK_SCHEME) + << QString(SMB_SCHEME) + << QString(AFC_SCHEME) + << QString(MTP_SCHEME) + << QString(USERSHARE_SCHEME) + << QString(AVFS_SCHEME) + << QString(FTP_SCHEME) + << QString(SFTP_SCHEME) + << QString(DAV_SCHEME) + << QString(TAG_SCHEME) + << QString(DFMVAULT_SCHEME) // 文件保险柜 + << QString(BURN_SCHEME) + << QString(PLUGIN_SCHEME); // NOTE [XIAO] + +DUrl::DUrl() + : QUrl() +{ + +} + +DUrl::DUrl(const QUrl ©) + : QUrl(copy) +{ + updateVirtualPath(); +} + + +DUrl::DUrl(const DUrl &other) + : QUrl{other}, + m_virtualPath{other.m_virtualPath} +{ + //###copy constructor +} + + +DUrl::DUrl(DUrl &&other) + : QUrl{ std::move(other) }, + m_virtualPath{ std::move(other.m_virtualPath) } +{ + //###move constructor +} + + +//###copy operator= +DUrl &DUrl::operator=(const DUrl &other) +{ + QUrl::operator=(other); + m_virtualPath = other.m_virtualPath; + + return *this; +} + + +//###move operator= +DUrl &DUrl::operator=(DUrl &&other) +{ + QUrl::operator=(std::move(other)); + m_virtualPath = std::move(other.m_virtualPath); + return *this; +} + +QDataStream &DUrl::operator<<(QDataStream &out) +{ + QByteArray u; + if (this->isValid()) + u = this->toEncoded(); + out << u << m_virtualPath; + return out; +} + +QDataStream &DUrl::operator>>(QDataStream &in) +{ + QByteArray u; + QString virtualPath; + in >> u >> virtualPath; + this->setUrl(QString::fromLatin1(u)); + this->m_virtualPath = virtualPath; + return in; +} + + +DUrl::DUrl(const QString &url, QUrl::ParsingMode mode) + : QUrl(url, mode) +{ + updateVirtualPath(); +} + +void DUrl::setPath(const QString &path, QUrl::ParsingMode mode, bool makeAbsolutePath) +{ + QUrl::setPath(path, mode); + + if (makeAbsolutePath) { + this->makeAbsolutePath(); + } + + updateVirtualPath(); +} + +void DUrl::setScheme(const QString &scheme, bool makeAbsolute) +{ + QUrl::setScheme(scheme); + + if (makeAbsolute) { + this->makeAbsolutePath(); + } + + updateVirtualPath(); +} + +void DUrl::setUrl(const QString &url, QUrl::ParsingMode parsingMode, bool makeAbsolute) +{ + QUrl::setUrl(url, parsingMode); + + if (makeAbsolute) { + this->makeAbsolutePath(); + } + + updateVirtualPath(); +} + +bool DUrl::isTrashFile() const +{ + return scheme() == TRASH_SCHEME; +} + +bool DUrl::isRecentFile() const +{ + return scheme() == RECENT_SCHEME; +} + +bool DUrl::isBookMarkFile() const +{ + return scheme() == BOOKMARK_SCHEME; +} + +bool DUrl::isSearchFile() const +{ + return scheme() == SEARCH_SCHEME; +} + +bool DUrl::isComputerFile() const +{ + return scheme() == COMPUTER_SCHEME; +} + +bool DUrl::isNetWorkFile() const +{ + return scheme() == NETWORK_SCHEME; +} + +bool DUrl::isSMBFile() const +{ + return scheme() == SMB_SCHEME; +} + +bool DUrl::isAFCFile() const +{ + return scheme() == AFC_SCHEME; +} + +bool DUrl::isMTPFile() const +{ + return scheme() == MTP_SCHEME; +} + +bool DUrl::isUserShareFile() const +{ + return scheme() == USERSHARE_SCHEME; +} + +bool DUrl::isAVFSFile() const +{ + return scheme() == AVFS_SCHEME; +} + +bool DUrl::isFTPFile() const +{ + return scheme() == FTP_SCHEME; +} + +bool DUrl::isSFTPFile() const +{ + return scheme() == SFTP_SCHEME; +} + + +///###: Judge whether current the scheme of current url is equal to TAG_SCHEME. +bool DUrl::isTaggedFile() const +{ + return (this->scheme() == QString{TAG_SCHEME}); +} + +bool DUrl::isVaultFile() const +{ + return (this->scheme() == DFMVAULT_SCHEME); +} + +bool DUrl::isPluginFile() const +{ + return this->scheme() == PLUGIN_SCHEME; +} + +QString DUrl::toString(QUrl::FormattingOptions options) const +{ + if (!isValid()) { + return m_virtualPath; + } + + if (isLocalFile() || !schemeList.contains(scheme())) { + return QUrl::toString(options); + } + + QUrl url(*this); + + url.setScheme(FILE_SCHEME); + + return url.toString(options).replace(0, 4, scheme()); +} + +QString DUrl::searchKeyword() const +{ + if (!isSearchFile()) { + return QString(); + } + + QUrlQuery query(this->query()); + + return query.queryItemValue("keyword", FullyDecoded); +} + +DUrl DUrl::searchTargetUrl() const +{ + if (!isSearchFile()) { + return DUrl(); + } + + QUrlQuery query(this->query()); + + return DUrl(query.queryItemValue("url", FullyDecoded)); +} + +DUrl DUrl::searchedFileUrl() const +{ + if (!isSearchFile()) { + return DUrl(); + } + + return DUrl(fragment(FullyDecoded)); +} + +///###: tag:///tagA#real file path(fregment). +///###: so I get the true path from fregment of Uri. +QString DUrl::taggedLocalFilePath() const noexcept +{ + if (this->isTaggedFile()) { + QString localFilePath{ this->QUrl::fragment(FullyDecoded) }; + + return localFilePath; + } + + return QString{}; +} + +QString DUrl::tagName() const noexcept +{ + if (this->isTaggedFile()) { + QUrlQuery qq(query()); + return qq.hasQueryItem("tagname") ? qq.queryItemValue("tagname") : QUrl::fileName(); + //return this->fileName(); + } + + return QString{}; +} + +QString DUrl::fileName(QUrl::ComponentFormattingOptions options) const +{ + return isTaggedFile() ? tagName() : QUrl::fileName(options); +} + +QString DUrl::deviceId() const +{ + if (scheme() != DEVICE_SCHEME) + return QString(); + + return path(); +} + +DUrl DUrl::bookmarkTargetUrl() const +{ + if (scheme() != BOOKMARK_SCHEME) + return DUrl(); + + return DUrl(path()); +} + +QString DUrl::bookmarkName() const +{ + if (scheme() != BOOKMARK_SCHEME) + return QString(); + + return fragment(FullyDecoded); +} + +QString DUrl::burnDestDevice() const +{ + QRegularExpressionMatch m; + if (scheme() != BURN_SCHEME || !path().contains(burn_rxp, &m)) { + return ""; + } + return m.captured(1); +} + +QString DUrl::burnFilePath() const +{ + QRegularExpressionMatch m; + if (scheme() != BURN_SCHEME || !path().contains(burn_rxp, &m)) { + return ""; + } + return m.captured(3); +} + +bool DUrl::burnIsOnDisc() const +{ + QRegularExpressionMatch m; + if (scheme() != BURN_SCHEME || !path().contains(burn_rxp, &m)) { + return false; + } + return m.captured(2) == BURN_SEG_ONDISC; +} + +DUrl DUrl::parentUrl() const +{ + return parentUrl(*this); +} + +void DUrl::setSearchKeyword(const QString &keyword) +{ + if (!isSearchFile()) { + return; + } + + QUrlQuery query(this->query()); + + query.removeQueryItem("keyword"); + query.addQueryItem("keyword", parseDecodedComponent(keyword)); + + setQuery(query); +} + +void DUrl::setSearchTargetUrl(const DUrl &url) +{ + if (!isSearchFile()) { + return; + } + + QUrlQuery query(this->query()); + + query.removeQueryItem("url"); + query.addQueryItem("url", parseDecodedComponent(url.toString())); + + setQuery(query); +} + +void DUrl::setSearchedFileUrl(const DUrl &url) +{ + if (!isSearchFile()) { + return; + } + + setFragment(url.toString(), QUrl::DecodedMode); +} + + +///###: the real path of file was puted in fragment field of Uri. +void DUrl::setTaggedFileUrl(const QString &localFilePath) noexcept +{ + if (this->isTaggedFile()) { + this->QUrl::setFragment(localFilePath, QUrl::DecodedMode); + } +} + +void DUrl::setBookmarkName(const QString &name) +{ + if (this->scheme() != BOOKMARK_SCHEME) + return; + + setFragment(name, DecodedMode); +} + +DUrl DUrl::fromLocalFile(const QString &filePath) +{ + return DUrl(QUrl::fromLocalFile(filePath)); +} + +DUrl DUrl::fromTrashFile(const QString &filePath) +{ + DUrl url; + + url.setScheme(TRASH_SCHEME, false); + url.setPath(filePath); + + return url; +} + +DUrl DUrl::fromRecentFile(const QString &filePath) +{ + DUrl url; + + url.setScheme(RECENT_SCHEME, false); + url.setPath(filePath); + + return url; +} + +DUrl DUrl::fromBookMarkFile(const DUrl &targetUrl, const QString &name) +{ + DUrl url; + + url.setScheme(BOOKMARK_SCHEME, false); + url.setPath(targetUrl.toString()); + url.setBookmarkName(name); + + return url; +} + +DUrl DUrl::fromSearchFile(const QString &filePath) +{ + DUrl url; + + url.setScheme(SEARCH_SCHEME, false); + url.setPath(filePath); + + return url; +} + +DUrl DUrl::fromSearchFile(const DUrl &targetUrl, const QString &keyword, const DUrl &searchedFileUrl) +{ + DUrl url = fromSearchFile(QString()); + + QUrlQuery query; + + query.addQueryItem("url", parseDecodedComponent(targetUrl.toString())); + query.addQueryItem("keyword", parseDecodedComponent(keyword)); + + url.setQuery(query); + + if (searchedFileUrl.isValid()) { + url.setFragment(searchedFileUrl.toString(), DecodedMode); + } + + return url; +} + +DUrl DUrl::fromComputerFile(const QString &filePath) +{ + DUrl url; + + url.setScheme(COMPUTER_SCHEME, false); + url.setPath(filePath); + + return url; +} + +DUrl DUrl::fromNetworkFile(const QString &filePath) +{ + DUrl url; + + url.setScheme(NETWORK_SCHEME, false); + url.setPath(filePath); + + return url; +} + +DUrl DUrl::fromSMBFile(const QString &filePath) +{ + DUrl url; + + url.setScheme(SMB_SCHEME, false); + url.setPath(filePath); + + return url; +} + +DUrl DUrl::fromAFCFile(const QString &filePath) +{ + DUrl url; + + url.setScheme(AFC_SCHEME, false); + url.setPath(filePath); + + return url; +} + +DUrl DUrl::fromMTPFile(const QString &filePath) +{ + DUrl url; + + url.setScheme(MTP_SCHEME, false); + url.setPath(filePath); + + return url; +} + +DUrl DUrl::fromUserShareFile(const QString &filePath) +{ + DUrl url; + + url.setScheme(USERSHARE_SCHEME); + url.setPath(filePath); + + return url; +} + +DUrl DUrl::fromAVFSFile(const QString &filePath) +{ + DUrl url; + + url.setScheme(AVFS_SCHEME); + url.setPath(filePath); + + return url; +} + + +DUrl DUrl::fromUserTaggedFile(const QString &tag_name, const QString &localFilePath)noexcept +{ + DUrl uri{}; + uri.setScheme(TAG_SCHEME); + uri.setPath(QString{"/"} + tag_name); + uri.setQuery("tagname=" + tag_name); + + if (!localFilePath.isEmpty()) { + uri.setFragment(localFilePath, QUrl::DecodedMode); + } + + return uri; +} + +DUrl DUrl::fromDeviceId(const QString &deviceId) +{ + DUrl url; + url.setScheme(DEVICE_SCHEME); + url.setPath(deviceId); + + return url; +} + +DUrl DUrl::fromBurnFile(const QString &filePath) +{ + DUrl ret; + ret.setScheme(BURN_SCHEME); + ret.setPath(filePath); + return ret; +} + +DUrl DUrl::fromVaultFile(const QString &filePath) +{ + DUrl url; + url.setScheme(DFMVAULT_SCHEME, false); + url.setPath(filePath); + + return url; +} + +DUrlList DUrl::fromStringList(const QStringList &urls, QUrl::ParsingMode mode) +{ + QList urlList; + + for (const QString &string : urls) { + urlList << DUrl(string, mode); + } + + return urlList; +} + +DUrlList DUrl::fromQUrlList(const QList &urls) +{ + QList urlList; + + for (const QUrl &url : urls) { + urlList << DUrl(url); + } + + return urlList; +} + +DUrl DUrl::fromUserInput(const QString &userInput, bool preferredLocalPath) +{ + return fromUserInput(userInput, QString(), preferredLocalPath); +} + +DUrl DUrl::fromUserInput(const QString &userInput, QString workingDirectory, + bool preferredLocalPath, QUrl::UserInputResolutionOptions options) +{ + if (options != AssumeLocalFile) { + return DUrl(QUrl::fromUserInput(userInput, workingDirectory, options)); + } + + if ((userInput.startsWith("~") && preferredLocalPath) || userInput.startsWith("~/")) { + return DUrl::fromLocalFile(QDir::homePath() + userInput.mid(1)); + } else if ((preferredLocalPath && QDir().exists(userInput)) || userInput.startsWith("./") + || userInput.startsWith("../") || userInput.startsWith("/")) { + QDir dir(userInput); + + return DUrl::fromLocalFile(dir.absolutePath()); + } else { + DUrl url(userInput); + + // NOTE(zccrs): 保证数据传入QUrl还能使用toString返回数据 + if (!url.isValid() || (url.scheme().isEmpty() && url.toString() != userInput)) { + DUrl durl; + + durl.m_virtualPath = userInput; + + return durl; + } + + return url; + } +} + +QStringList DUrl::toStringList(const DUrlList &urls, QUrl::FormattingOptions options) +{ + QStringList urlList; + + for (const DUrl &url : urls) { + urlList << url.toString(options); + } + + return urlList; +} + +QList DUrl::toQUrlList(const DUrlList &urls) +{ + QList urlList; + + for (const DUrl &url : urls) { + urlList << url; + } + + return urlList; +} + +DUrl::DUrlList DUrl::childrenList(const DUrl &url) +{ + DUrlList children; + QStringList paths = url.path().split("/"); + paths.removeAt(0); + QString _path; + foreach (QString p, paths) { + DUrl _url; + _url.setScheme(url.scheme()); + _path += "/" + p; + _url.setPath(_path); + children.append(_url); + } + + return children; +} + +DUrl DUrl::parentUrl(const DUrl &url) +{ + DUrl _url; + const QString &path = url.path(); + + if (path == "/") { + return DUrl(); + } + + _url.setScheme(url.scheme()); + QStringList paths = path.split("/"); + paths.removeAt(0); + if (!paths.isEmpty() && paths.last().isEmpty()) { + paths.removeLast(); + } + if (!paths.isEmpty()) { + paths.removeLast(); + } + QString _path; + foreach (QString p, paths) { + _path += "/" + p; + } + if (_path.isEmpty()) { + _path += "/"; + } + _url.setPath(_path); + + return _url; +} + +bool DUrl::hasScheme(const QString &scheme) +{ + return schemeList.contains(scheme); +} + +bool DUrl::operator ==(const DUrl &url) const +{ + if (!hasScheme(url.scheme())) { + return QUrl::operator ==(url); + } + + QString path1 = m_virtualPath; + QString path2 = url.m_virtualPath; + + return path1 == path2 && + scheme() == url.scheme() && + fragment() == url.fragment() && + query() == url.query() && + userName() == url.userName() && + password() == url.password() && + host() == url.host() && + port() == url.port(); +} + +void DUrl::makeAbsolutePath() +{ + if (!hasScheme(this->scheme())) { + return; + } + + if (isLocalFile()) { + const QString &path = toLocalFile(); + + if (path.startsWith("~")) { + QUrl::setPath(QDir::homePath() + path.mid(1)); + } else { + QUrl::setPath(QFileInfo(path).absoluteFilePath()); + } + } else { + const QString &path = this->path(); + + if (path.startsWith('/')) { + QUrl::setPath(QFileInfo(this->path()).absoluteFilePath()); + } + } +} + +DUrl DUrl::toAbsolutePathUrl() const +{ + DUrl url = *this; + + url.makeAbsolutePath(); + + return url; +} + +QString DUrl::toLocalFile() const +{ + if (isTrashFile()) { + return DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath) + path(); + } else if (isSearchFile()) { + return searchedFileUrl().toLocalFile(); + } else if (isAVFSFile()) { + return path(); + } else if (isTaggedFile()) { + return taggedLocalFilePath(); + } else if (isUserShareFile()) { + return QString(path()).remove(USERSHARE_ROOT); + } else if (isVaultFile()) { + return path(); + } else { + return QUrl::toLocalFile(); + } +} + +void DUrl::updateVirtualPath() +{ + m_virtualPath = toAbsolutePathUrl().path(); + + if (m_virtualPath.endsWith('/') && m_virtualPath.count() != 1) { + m_virtualPath.remove(m_virtualPath.count() - 1, 1); + } +} + +QT_BEGIN_NAMESPACE +QDebug operator<<(QDebug deg, const DUrl &url) +{ + QDebugStateSaver saver(deg); + + Q_UNUSED(saver) + + deg.nospace() << "DUrl(" << url.toString() << ")"; + + return deg; +} + +uint qHash(const DUrl &url, uint seed) Q_DECL_NOTHROW { + return qHash(url.scheme()) ^ + qHash(url.userName()) ^ + qHash(url.password()) ^ + qHash(url.host()) ^ + qHash(url.port(), seed) ^ + qHash(url.m_virtualPath) ^ + qHash(url.query()) ^ + qHash(url.fragment()); +} + +QDataStream &operator<<(QDataStream &out, const DUrl &url) +{ + QByteArray u; + if (url.isValid()) + u = url.toEncoded(); + out << u << url.m_virtualPath; + return out; +} + +QDataStream &operator>>(QDataStream &in, DUrl &url) +{ + QByteArray u; + QString virtualPath; + in >> u >> virtualPath; + url.setUrl(QString::fromLatin1(u)); + url.m_virtualPath = virtualPath; + return in; +} +QT_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/durl.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/durl.h new file mode 100644 index 0000000..0da0bd0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/durl.h @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef ZURL_H +#define ZURL_H + +#include +#include +#include + + +#define TRASH_SCHEME "trash" +#define RECENT_SCHEME "recent" +#define BOOKMARK_SCHEME "bookmark" +#define FILE_SCHEME "file" +#define COMPUTER_SCHEME "computer" +#define SEARCH_SCHEME "search" +#define NETWORK_SCHEME "network" +#define SMB_SCHEME "smb" +#define AFC_SCHEME "afc" +#define MTP_SCHEME "mtp" +#define DAV_SCHEME "dav" +#define GPHOTO2_SCHEME "gphoto2" +#define USERSHARE_SCHEME "usershare" +#define AVFS_SCHEME "avfs" +#define FTP_SCHEME "ftp" +#define SFTP_SCHEME "sftp" +#define TAG_SCHEME "tag" +#define DEVICE_SCHEME "device" +#define MOUNT_SCHEME "mount" +#define BURN_SCHEME "burn" +//NOTE [XIAO] #define PLUGIN_SCHEME "plugin" +#define PLUGIN_SCHEME "plugin" + +#define TRASH_ROOT "trash:///" +#define RECENT_ROOT "recent:///" +#define BOOKMARK_ROOT "bookmark:///" +#define FILE_ROOT "file:///" +#define COMPUTER_ROOT "computer:///" +#define NETWORK_ROOT "network:///" +#define SMB_ROOT "smb:///" +#define USERSHARE_ROOT "usershare:///" +#define AVFS_ROOT "avfs:///" +#define TAG_ROOT "tag:///" +#define DEVICE_ROOT "device:///" +#define MOUNT_ROOT "mount:///" +#define BURN_ROOT "burn:///" +//NOTE [XIAO] #define PLUGIN_ROOT "plugin:///" +#define PLUGIN_ROOT "plugin:///" + +#define APPENTRY_ROOT "appentry:///" +#define APPENTRY_SCHEME "appentry" + +// internal scheme, don't rely on this scheme outside the file manager app. +#define DFMMD_SCHEME "dfmmd" +#define DFMMD_ROOT "dfmmd:///" +#define DFMROOT_SCHEME "dfmroot" +#define DFMROOT_ROOT "dfmroot:///" +#define DFMVAULT_SCHEME "dfmvault" +#define DFMVAULT_ROOT "dfmvault:///" +// internal scheme end. + +// Auxiliary path segment strings for the burn scheme +#define BURN_SEG_ONDISC "disc_files" +#define BURN_SEG_STAGING "staging_files" + +#define GVFS_ROOT_MATCH "(^//run/user/\\d+/gvfs/|^//root/.gvfs/)" +#define GVFS_MATCH "(^/run/user/\\d+/gvfs/|^/root/.gvfs/)" +#define FTP_HOST "ftp:host=" +#define GVFS_MATCH_EX "(^/run/user/\\d+/gvfs/.+$|^/root/.gvfs/.+$)" + +class DUrl; + +QT_BEGIN_NAMESPACE +Q_CORE_EXPORT uint qHash(const DUrl &url, uint seed = 0) Q_DECL_NOTHROW; +QT_END_NAMESPACE + +class DUrl : public QUrl +{ + typedef QList DUrlList; + +public: + DUrl(); + explicit DUrl(const QUrl ©); + + virtual ~DUrl() = default; + DUrl(const DUrl &other); + DUrl(DUrl &&other); + DUrl &operator=(const DUrl &other); + DUrl &operator=(DUrl &&other); + + QDataStream &operator<<(QDataStream &out); + QDataStream &operator>>(QDataStream &in); + + DUrl(const QString &url, ParsingMode mode = TolerantMode); + + void setPath(const QString &path, ParsingMode mode = DecodedMode, bool makeAbsolutePath = true); + void setScheme(const QString &scheme, bool makeAbsolutePath = true); + void setUrl(const QString &url, ParsingMode parsingMode = TolerantMode, bool makeAbsolutePath = true); + + bool isTrashFile() const; + bool isRecentFile() const; + bool isBookMarkFile() const; + bool isSearchFile() const; + bool isComputerFile() const; + bool isNetWorkFile() const; + bool isSMBFile() const; + bool isAFCFile() const; + bool isMTPFile() const; + bool isUserShareFile() const; + bool isAVFSFile() const; + bool isFTPFile() const; + bool isSFTPFile() const; + bool isTaggedFile() const; + bool isVaultFile() const; + //NOTE [XIAO] bool isPluginFile() const; + bool isPluginFile() const; + + QString toString(FormattingOptions options = FormattingOptions(PrettyDecoded)) const; + + QString searchKeyword() const; + DUrl searchTargetUrl() const; + DUrl searchedFileUrl() const; + QString taggedLocalFilePath() const noexcept; + QString tagName() const noexcept; + QString fileName(ComponentFormattingOptions options = FullyDecoded) const; // not virtual + QString deviceId() const; + DUrl bookmarkTargetUrl() const; + QString bookmarkName() const; + QString burnDestDevice() const; + QString burnFilePath() const; + bool burnIsOnDisc() const; + + DUrl parentUrl() const; + + void setSearchKeyword(const QString &keyword); + void setSearchTargetUrl(const DUrl &url); + void setSearchedFileUrl(const DUrl &url); + void setTaggedFileUrl(const QString &localFilePath) noexcept; + void setBookmarkName(const QString &name); + + static DUrl fromLocalFile(const QString &filePath); + static DUrl fromTrashFile(const QString &filePath); + static DUrl fromRecentFile(const QString &filePath); + static DUrl fromBookMarkFile(const DUrl &targetUrl, const QString &name); + static DUrl fromSearchFile(const QString &filePath); + static DUrl fromSearchFile(const DUrl &targetUrl, const QString &keyword, const DUrl &searchedFileUrl = DUrl()); + static DUrl fromComputerFile(const QString &filePath); + static DUrl fromNetworkFile(const QString &filePath); + static DUrl fromSMBFile(const QString &filePath); + static DUrl fromAFCFile(const QString &filePath); + static DUrl fromMTPFile(const QString &filePath); + static DUrl fromUserShareFile(const QString &filePath); + static DUrl fromAVFSFile(const QString &filePath); + static DUrl fromUserTaggedFile(const QString &tag_name, const QString &localFilePath) noexcept; + static DUrl fromDeviceId(const QString &deviceId); + static DUrl fromBurnFile(const QString &filePath); + static DUrl fromVaultFile(const QString &filePath); + + static DUrlList fromStringList(const QStringList &urls, ParsingMode mode = TolerantMode); + static DUrlList fromQUrlList(const QList &urls); + static DUrl fromUserInput(const QString &userInput, bool preferredLocalPath = true); + + // Return "file://$CURRENT_DIR/userInput" if preferredLocalPath is true and directory exists + static DUrl fromUserInput(const QString &userInput, QString workingDirectory, + bool preferredLocalPath = true, UserInputResolutionOptions options = AssumeLocalFile); + static QStringList toStringList(const DUrlList &urls, + FormattingOptions options = FormattingOptions(PrettyDecoded)); + static QList toQUrlList(const DUrlList &urls); + + static DUrlList childrenList(const DUrl &url); + static DUrl parentUrl(const DUrl &url); + static bool hasScheme(const QString &scheme); + + bool operator ==(const DUrl &url) const; + inline bool operator !=(const DUrl &url) const + { + return !operator ==(url); + } + friend Q_CORE_EXPORT uint qHash(const DUrl &url, uint seed) Q_DECL_NOTHROW; + + void makeAbsolutePath(); + DUrl toAbsolutePathUrl() const; + QString toLocalFile() const; + + friend QDataStream &operator<<(QDataStream &out, const DUrl &url); + friend QDataStream &operator>>(QDataStream &in, DUrl &url); + +private: + void updateVirtualPath(); + + QString m_virtualPath; + + static QRegularExpression burn_rxp; +}; + +typedef QList DUrlList; + +Q_DECLARE_METATYPE(DUrl) +Q_DECLARE_METATYPE(DUrlList) + +QT_BEGIN_NAMESPACE +QDebug operator<<(QDebug deg, const DUrl &url); +QDataStream &operator<<(QDataStream &out, const DUrl &url); +QDataStream &operator>>(QDataStream &in, DUrl &url); +QT_END_NAMESPACE + +#endif // ZURL_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmcrumbfactory.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmcrumbfactory.cpp new file mode 100644 index 0000000..0263021 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmcrumbfactory.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmcrumbfactory.h" +#include "dfmcrumbplugin.h" +#include "dfmfactoryloader.h" + +DFM_BEGIN_NAMESPACE + +#ifndef QT_NO_LIBRARY +Q_GLOBAL_STATIC_WITH_ARGS(DFMFactoryLoader, loader, + (DFMCrumbFactoryInterface_iid, QLatin1String("/crumbs"), Qt::CaseInsensitive)) +#endif + +QStringList DFMCrumbFactory::keys() +{ + QStringList list; +#ifndef QT_NO_LIBRARY + typedef QMultiMap PluginKeyMap; + + const PluginKeyMap keyMap = loader()->keyMap(); + const PluginKeyMap::const_iterator cend = keyMap.constEnd(); + for (PluginKeyMap::const_iterator it = keyMap.constBegin(); it != cend; ++it) + list.append(it.value()); +#endif + return list; +} + +DFMCrumbInterface *DFMCrumbFactory::create(const QString &key) +{ + return dLoadPlugin(loader(), key); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmcrumbfactory.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmcrumbfactory.h new file mode 100644 index 0000000..3d554c2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmcrumbfactory.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMCRUMBFACTORY_H +#define DFMCRUMBFACTORY_H + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMCrumbInterface; +class DFMCrumbFactory +{ +public: + static QStringList keys(); + static DFMCrumbInterface *create(const QString &key); +}; + +DFM_END_NAMESPACE + + +#endif // DFMCRUMBFACTORY_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmcrumbplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmcrumbplugin.cpp new file mode 100644 index 0000000..c664848 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmcrumbplugin.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmcrumbplugin.h" + +DFM_BEGIN_NAMESPACE + +DFMCrumbPlugin::DFMCrumbPlugin(QObject *parent) : QObject(parent) +{ + +} + +DFMCrumbPlugin::~DFMCrumbPlugin() +{ + +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmcrumbplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmcrumbplugin.h new file mode 100644 index 0000000..221ea82 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmcrumbplugin.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMCRUMBPLUGIN_H +#define DFMCRUMBPLUGIN_H + +#include + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE +#define DFMCrumbFactoryInterface_iid "com.deepin.filemanager.DFMCrumbFactoryInterface_iid" + +class DFMCrumbInterface; +class DFMCrumbPlugin : public QObject +{ + Q_OBJECT +public: + explicit DFMCrumbPlugin(QObject *parent = 0); + ~DFMCrumbPlugin(); + + virtual DFMCrumbInterface *create(const QString &key) = 0; +}; +DFM_END_NAMESPACE + +#endif // DFMCRUMBPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfactoryloader.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfactoryloader.cpp new file mode 100644 index 0000000..8671be0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfactoryloader.cpp @@ -0,0 +1,332 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmfactoryloader.h" +#include "private/dfmfactoryloader_p.h" + +#include +#include +#include +#include + +DFM_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC(QList, qt_factory_loaders) + +Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_factoryloader_mutex, (QMutex::Recursive)) + +QStringList DFMFactoryLoaderPrivate::pluginPaths; + +DFMFactoryLoaderPrivate::DFMFactoryLoaderPrivate() +{ + if (pluginPaths.isEmpty()) { + if (QT_PREPEND_NAMESPACE(qEnvironmentVariableIsEmpty)("DFM_PLUGIN_PATH")) + pluginPaths.append(QString::fromLocal8Bit(PLUGINDIR).split(':')); + else + pluginPaths = QString::fromLocal8Bit(qgetenv("DFM_PLUGIN_PATH")).split(':'); + } +} + +DFMFactoryLoaderPrivate::~DFMFactoryLoaderPrivate() +{ + +} + +DFMFactoryLoader::DFMFactoryLoader(const char *iid, + const QString &suffix, + Qt::CaseSensitivity cs, + bool repetitiveKeyInsensitive) + : QObject(*new DFMFactoryLoaderPrivate) +{ + moveToThread(QCoreApplicationPrivate::mainThread()); + Q_D(DFMFactoryLoader); + d->iid = iid; + d->suffix = suffix; + d->cs = cs; + d->rki = repetitiveKeyInsensitive; + + QMutexLocker locker(qt_factoryloader_mutex()); + update(); + qt_factory_loaders()->append(this); +} + +/* Internal, for debugging */ +static bool dfm_debug_component() +{ +#ifdef QT_DEBUG + return true; +#endif + + static int debug_env = QT_PREPEND_NAMESPACE(qEnvironmentVariableIntValue)("DFM_DEBUG_PLUGINS"); + return debug_env != 0; +} + +void DFMFactoryLoader::update() +{ + // Disable plugins on root user + if (DFMGlobal::isRootUser()) { + qWarning() << "Disable plugins for root user"; + + return; + } + +#ifdef QT_SHARED + Q_D(DFMFactoryLoader); + qDebug() << "DFMFactoryLoader::DFMFactoryLoader() checking directory path"; + const QStringList &paths = d->pluginPaths; + for (int i = 0; i < paths.count(); ++i) { + const QString &pluginDir = paths.at(i); + // Already loaded, skip it... + if (d->loadedPaths.contains(pluginDir)) + continue; + d->loadedPaths << pluginDir; + + QString path = pluginDir + d->suffix; + + if (dfm_debug_component()) + qDebug() << "DFMFactoryLoader::DFMFactoryLoader() checking directory path" << path << "..."; + + if (!QDir(path).exists(QLatin1String("."))) + continue; + + QStringList plugins = QDir(path).entryList(QDir::Files); + QPluginLoader *loader = nullptr; + +#ifdef Q_OS_MAC + // Loading both the debug and release version of the cocoa plugins causes the objective-c runtime + // to print "duplicate class definitions" warnings. Detect if DFMFactoryLoader is about to load both, + // skip one of them (below). + // + // ### FIXME find a proper solution + // + const bool isLoadingDebugAndReleaseCocoa = plugins.contains(QStringLiteral("libqcocoa_debug.dylib")) + && plugins.contains(QStringLiteral("libqcocoa.dylib")); +#endif + for (int j = 0; j < plugins.count(); ++j) { + QString fileName = QDir::cleanPath(path + QLatin1Char('/') + plugins.at(j)); + +#ifdef Q_OS_MAC + if (isLoadingDebugAndReleaseCocoa) { +#ifdef QT_DEBUG + if (fileName.contains(QStringLiteral("libqcocoa.dylib"))) + continue; // Skip release plugin in debug mode +#else + if (fileName.contains(QStringLiteral("libqcocoa_debug.dylib"))) + continue; // Skip debug plugin in release mode +#endif + } +#endif + if (dfm_debug_component()) { + qDebug() << "DFMFactoryLoader::DFMFactoryLoader() looking at" << fileName; + } + loader = new QPluginLoader(fileName, this); + if (!loader->load()) { + if (dfm_debug_component()) { + qDebug() << loader->errorString(); + } + loader->deleteLater(); + continue; + } + + QStringList keys; + bool metaDataOk = false; + + QString iid = loader->metaData().value(iidKeyLiteral()).toString(); + if (iid == QLatin1String(d->iid.constData(), d->iid.size())) { + QJsonObject object = loader->metaData().value(metaDataKeyLiteral()).toObject(); + metaDataOk = true; + + QJsonArray k = object.value(keysKeyLiteral()).toArray(); + for (int m = 0; m < k.size(); ++m) + keys += d->cs ? k.at(m).toString() : k.at(m).toString().toLower(); + } + if (dfm_debug_component()) + qDebug() << "Got keys from plugin meta data" << keys; + + + if (!metaDataOk) { + loader->deleteLater(); + continue; + } + + int keyUsageCount = 0; + for (int k = 0; k < keys.count(); ++k) { + // first come first serve, unless the first + // library was built with a future Qt version, + // whereas the new one has a Qt version that fits + // better + const QString &key = keys.at(k); + + if (d->rki) { + d->keyMap.insertMulti(key, loader); + ++keyUsageCount; + } else { + QPluginLoader *previous = d->keyMap.value(key); + int prev_dfm_version = 0; + if (previous) { + prev_dfm_version = (int)previous->metaData().value(versionKeyLiteral()).toDouble(); + } + int dfm_version = (int)loader->metaData().value(versionKeyLiteral()).toDouble(); + if (!previous || (prev_dfm_version > QString(QMAKE_VERSION).toDouble() && dfm_version <= QString(QMAKE_VERSION).toDouble())) { + d->keyMap.insertMulti(key, loader); + ++keyUsageCount; + } + } + } + if (keyUsageCount || keys.isEmpty()) + d->pluginLoaderList += loader; + else + loader->deleteLater(); + } + } +#else + Q_D(DFMFactoryLoader); + if (dfm_debug_component()) { + qDebug() << "DFMFactoryLoader::DFMFactoryLoader() ignoring" << d->iid + << "since plugins are disabled in static builds"; + } +#endif +} + +DFMFactoryLoader::~DFMFactoryLoader() +{ + Q_D(DFMFactoryLoader); + + QMutexLocker locker(qt_factoryloader_mutex()); + qt_factory_loaders()->removeAll(this); + + for (int i = 0; i < d->pluginLoaderList.count(); ++i) { + QPluginLoader *loader = d->pluginLoaderList.at(i); + loader->unload(); + } +} + +QList DFMFactoryLoader::metaData() const +{ + Q_D(const DFMFactoryLoader); + QMutexLocker locker(&d->mutex); + QList metaData; + for (int i = 0; i < d->pluginLoaderList.size(); ++i) + metaData.append(d->pluginLoaderList.at(i)->metaData()); + + return metaData; +} + +QObject *DFMFactoryLoader::instance(int index) const +{ + Q_D(const DFMFactoryLoader); + if (index < 0) + return 0; + + if (index < d->pluginLoaderList.size()) { + QPluginLoader *loader = d->pluginLoaderList.at(index); + if (loader->instance()) { + QObject *obj = loader->instance(); + if (obj) { + if (!obj->parent()) + obj->moveToThread(QCoreApplicationPrivate::mainThread()); + return obj; + } + } + return 0; + } + + return 0; +} + +#if defined(Q_OS_UNIX) && !defined (Q_OS_MAC) +QPluginLoader *DFMFactoryLoader::pluginLoader(const QString &key) const +{ + Q_D(const DFMFactoryLoader); + return d->keyMap.value(d->cs ? key : key.toLower()); +} + +QList DFMFactoryLoader::pluginLoaderList(const QString &key) const +{ + Q_D(const DFMFactoryLoader); + return d->keyMap.values(d->cs ? key : key.toLower()); +} +#endif + +void DFMFactoryLoader::refreshAll() +{ + QMutexLocker locker(qt_factoryloader_mutex()); + QList *loaders = qt_factory_loaders(); + for (QList::const_iterator it = loaders->constBegin(); + it != loaders->constEnd(); ++it) { + (*it)->update(); + } +} + +QMultiMap DFMFactoryLoader::keyMap() const +{ + QMultiMap result; + const QString metaDataKey = metaDataKeyLiteral(); + const QString keysKey = keysKeyLiteral(); + const QList metaDataList = metaData(); + for (int i = 0; i < metaDataList.size(); ++i) { + const QJsonObject metaData = metaDataList.at(i).value(metaDataKey).toObject(); + const QJsonArray keys = metaData.value(keysKey).toArray(); + const int keyCount = keys.size(); + for (int k = 0; k < keyCount; ++k) + result.insert(i, keys.at(k).toString()); + } + return result; +} + +int DFMFactoryLoader::indexOf(const QString &needle) const +{ + const QString metaDataKey = metaDataKeyLiteral(); + const QString keysKey = keysKeyLiteral(); + const QList metaDataList = metaData(); + for (int i = 0; i < metaDataList.size(); ++i) { + const QJsonObject metaData = metaDataList.at(i).value(metaDataKey).toObject(); + const QJsonArray keys = metaData.value(keysKey).toArray(); + const int keyCount = keys.size(); + for (int k = 0; k < keyCount; ++k) { + if (!keys.at(k).toString().compare(needle, Qt::CaseInsensitive)) + return i; + } + } + return -1; +} + +QList DFMFactoryLoader::getAllIndexByKey(const QString &needle) const +{ + QList list; + + const QString metaDataKey = metaDataKeyLiteral(); + const QString keysKey = keysKeyLiteral(); + const QList metaDataList = metaData(); + for (int i = 0; i < metaDataList.size(); ++i) { + const QJsonObject metaData = metaDataList.at(i).value(metaDataKey).toObject(); + const QJsonArray keys = metaData.value(keysKey).toArray(); + const int keyCount = keys.size(); + for (int k = 0; k < keyCount; ++k) { + if (!keys.at(k).toString().compare(needle, Qt::CaseInsensitive)) + list << i; + } + } + return list; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfactoryloader.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfactoryloader.h new file mode 100644 index 0000000..2ef2fb1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfactoryloader.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMFACTORYLOADER_H +#define DFMFACTORYLOADER_H + +#include "dfmglobal.h" + +#include +#include + +DFM_BEGIN_NAMESPACE + +class DFMFactoryLoaderPrivate; +class DFMFactoryLoader : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DFMFactoryLoader) +public: + explicit DFMFactoryLoader(const char *iid, + const QString &suffix = QString(), + Qt::CaseSensitivity = Qt::CaseSensitive, + bool repetitiveKeyInsensitive = false); + ~DFMFactoryLoader(); + + QList metaData() const; + QObject *instance(int index) const; + +#if defined(Q_OS_UNIX) && !defined (Q_OS_MAC) + QPluginLoader *pluginLoader(const QString &key) const; + QList pluginLoaderList(const QString &key) const; +#endif + + QMultiMap keyMap() const; + int indexOf(const QString &needle) const; + QList getAllIndexByKey(const QString &needle) const; + + void update(); + + static void refreshAll(); +}; + +template + PluginInterface *dLoadPlugin(const DFMFactoryLoader *loader, const QString &key) +{ + const int index = loader->indexOf(key); + if (index != -1) { + QObject *factoryObject = loader->instance(index); + if (FactoryInterface *factory = qobject_cast(factoryObject)) + if (PluginInterface *result = factory->create(key)) + return result; + } + return 0; +} + +template + QList dLoadPluginList(const DFMFactoryLoader *loader, const QString &key) +{ + QList list; + + for (int index : loader->getAllIndexByKey(key)) { + if (index != -1) { + QObject *factoryObject = loader->instance(index); + if (FactoryInterface *factory = qobject_cast(factoryObject)) + if (PluginInterface *result = factory->create(key)) + list << result; + } + } + + return list; +} + +template +PluginInterface *dLoadPlugin(const DFMFactoryLoader *loader, + const QString &key, + const Parameter1 ¶meter1) +{ + const int index = loader->indexOf(key); + if (index != -1) { + QObject *factoryObject = loader->instance(index); + if (FactoryInterface *factory = qobject_cast(factoryObject)) + if (PluginInterface *result = factory->create(key, parameter1)) + return result; + } + return 0; +} + +DFM_END_NAMESPACE + +#endif // DFMFACTORYLOADER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilecontrollerfactory.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilecontrollerfactory.cpp new file mode 100644 index 0000000..ffa8b6a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilecontrollerfactory.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmfilecontrollerfactory.h" +#include "dfmfilecontrollerplugin.h" +#include "dfmfactoryloader.h" + +DFM_BEGIN_NAMESPACE + +#ifndef QT_NO_LIBRARY +Q_GLOBAL_STATIC_WITH_ARGS(DFMFactoryLoader, loader, + (DFMFileControllerFactoryInterface_iid, QLatin1String("/controllers"), Qt::CaseInsensitive)) +#endif + +QStringList DFMFileControllerFactory::keys() +{ + QStringList list; +#ifndef QT_NO_LIBRARY + typedef QMultiMap PluginKeyMap; + + const PluginKeyMap keyMap = loader()->keyMap(); + const PluginKeyMap::const_iterator cend = keyMap.constEnd(); + for (PluginKeyMap::const_iterator it = keyMap.constBegin(); it != cend; ++it) + list.append(it.value()); +#endif + return list; +} + +DAbstractFileController *DFMFileControllerFactory::create(const QString &key) +{ + return dLoadPlugin(loader(), key); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilecontrollerfactory.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilecontrollerfactory.h new file mode 100644 index 0000000..ce9b8b2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilecontrollerfactory.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMFILECONTROLLERFACTORY_H +#define DFMFILECONTROLLERFACTORY_H + +#include "dfmglobal.h" + +class DAbstractFileController; + +DFM_BEGIN_NAMESPACE + +class DFMFileControllerFactory +{ +public: + static QStringList keys(); + static DAbstractFileController *create(const QString &key); +}; + +DFM_END_NAMESPACE + +#endif // DFMFILECONTROLLERFACTORY_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilecontrollerplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilecontrollerplugin.cpp new file mode 100644 index 0000000..ec6d14a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilecontrollerplugin.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmfilecontrollerplugin.h" + +DFM_BEGIN_NAMESPACE + +DFMFileControllerPlugin::DFMFileControllerPlugin(QObject *parent) + : QObject(parent) +{ + +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilecontrollerplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilecontrollerplugin.h new file mode 100644 index 0000000..c349429 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilecontrollerplugin.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMFILECONTROLLERPLUGIN_H +#define DFMFILECONTROLLERPLUGIN_H + +#include + +#include "dfmglobal.h" + +class DAbstractFileController; + +DFM_BEGIN_NAMESPACE +#define DFMFileControllerFactoryInterface_iid "com.deepin.filemanager.DFMFileControllerFactoryInterface_iid" + +class DFMFileControllerPlugin : public QObject +{ + Q_OBJECT +public: + explicit DFMFileControllerPlugin(QObject *parent = 0); + + virtual DAbstractFileController *create(const QString &key) = 0; +}; + +DFM_END_NAMESPACE + +#endif // DFMFILECONTROLLERPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilepreviewfactory.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilepreviewfactory.cpp new file mode 100644 index 0000000..9755139 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilepreviewfactory.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmfilepreviewfactory.h" +#include "private/dfmfilepreviewfactory_p.h" +#include "dfmfilepreviewplugin.h" +#include "dfmfactoryloader.h" +#include "dfmfilepreview.h" + +DFM_BEGIN_NAMESPACE + +#ifndef QT_NO_LIBRARY +Q_GLOBAL_STATIC_WITH_ARGS(DFMFactoryLoader, loader, + (DFMFilePreviewFactoryInterface_iid, QLatin1String("/previews"), Qt::CaseInsensitive)) +#endif + +QMap DFMFilePreviewFactoryPrivate::previewToLoaderIndex; + +QStringList DFMFilePreviewFactory::keys() +{ + QStringList list; +#ifndef QT_NO_LIBRARY + typedef QMultiMap PluginKeyMap; + + const PluginKeyMap keyMap = loader()->keyMap(); + const PluginKeyMap::const_iterator cend = keyMap.constEnd(); + for (PluginKeyMap::const_iterator it = keyMap.constBegin(); it != cend; ++it) + list.append(it.value()); +#endif + return list; +} + +DFMFilePreview *DFMFilePreviewFactory::create(const QString &key) +{ + if (DFMFilePreview *view = dLoadPlugin(loader(), key)) { + DFMFilePreviewFactoryPrivate::previewToLoaderIndex[view] = loader()->indexOf(key); + + QObject::connect(view, &DFMFilePreview::destroyed, view, [view] { + DFMFilePreviewFactoryPrivate::previewToLoaderIndex.remove(view); + }); + + return view; + } + + return Q_NULLPTR; +} + +bool DFMFilePreviewFactory::isSuitedWithKey(const DFMFilePreview *view, const QString &key) +{ + int index = DFMFilePreviewFactoryPrivate::previewToLoaderIndex.value(view, -1); + + if (index == -1) + return false; + + return index == loader()->indexOf(key); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilepreviewfactory.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilepreviewfactory.h new file mode 100644 index 0000000..b728af3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilepreviewfactory.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMFILEPREVIEWFACTORY_H +#define DFMFILEPREVIEWFACTORY_H + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMFilePreview; +class DFMFilePreviewFactory +{ +public: + static QStringList keys(); + static DFMFilePreview *create(const QString &key); + static bool isSuitedWithKey(const DFMFilePreview *view, const QString &key); +}; + +DFM_END_NAMESPACE + +#endif // DFMFILEPREVIEWFACTORY_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilepreviewplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilepreviewplugin.cpp new file mode 100644 index 0000000..97b59ab --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilepreviewplugin.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + + +#include "dfmfilepreviewplugin.h" + +DFM_BEGIN_NAMESPACE + +DFMFilePreviewPlugin::DFMFilePreviewPlugin(QObject *parent) + : QObject(parent) +{ + +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilepreviewplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilepreviewplugin.h new file mode 100644 index 0000000..e0b51a0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmfilepreviewplugin.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMFILEPREVIEWPLUGIN_H +#define DFMFILEPREVIEWPLUGIN_H + +#include + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE +#define DFMFilePreviewFactoryInterface_iid "com.deepin.filemanager.DFMFilePreviewFactoryInterface_iid" + +class DFMFilePreview; +class DFMFilePreviewPlugin : public QObject +{ + Q_OBJECT + +public: + explicit DFMFilePreviewPlugin(QObject *parent = 0); + + virtual DFMFilePreview *create(const QString &key) = 0; +}; + +DFM_END_NAMESPACE + +#endif // DFMFILEPREVIEWPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmgenericfactory.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmgenericfactory.cpp new file mode 100644 index 0000000..e1002d1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmgenericfactory.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmgenericfactory.h" +#include "dfmgenericplugin.h" +#include "dfmfactoryloader.h" + +DFM_BEGIN_NAMESPACE + +#ifndef QT_NO_LIBRARY +Q_GLOBAL_STATIC_WITH_ARGS(DFMFactoryLoader, loader, + (DFMGenericFactoryInterface_iid, QLatin1String("/generics"), Qt::CaseInsensitive, true)) +#endif + +DFMGenericFactory::DFMGenericFactory() +{ + +} + +QStringList DFMGenericFactory::keys() +{ + QStringList list; +#ifndef QT_NO_LIBRARY + typedef QMultiMap PluginKeyMap; + + const PluginKeyMap keyMap = loader()->keyMap(); + const PluginKeyMap::const_iterator cend = keyMap.constEnd(); + for (PluginKeyMap::const_iterator it = keyMap.constBegin(); it != cend; ++it) + list.append(it.value()); +#endif + return list; +} + +QObject *DFMGenericFactory::create(const QString &key) +{ + return dLoadPlugin(loader(), key); +} + +QObjectList DFMGenericFactory::createAll(const QString &key) +{ + return dLoadPluginList(loader(), key); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmgenericfactory.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmgenericfactory.h new file mode 100644 index 0000000..f257714 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmgenericfactory.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMGENERICFACTORY_H +#define DFMGENERICFACTORY_H + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMGenericFactory +{ +public: + DFMGenericFactory(); + + static QStringList keys(); + static QObject *create(const QString &key); + static QObjectList createAll(const QString &key); +}; + +DFM_END_NAMESPACE + +#endif // DFMGENERICFACTORY_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmgenericplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmgenericplugin.cpp new file mode 100644 index 0000000..ed22d55 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmgenericplugin.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmgenericplugin.h" + +DFM_BEGIN_NAMESPACE + +DFMGenericPlugin::DFMGenericPlugin(QObject *parent) + : QObject(parent) +{ + +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmgenericplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmgenericplugin.h new file mode 100644 index 0000000..fa66a3a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmgenericplugin.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMGENERICPLUGIN_H +#define DFMGENERICPLUGIN_H + +#include + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +#define DFMGenericFactoryInterface_iid "com.deepin.filemanager.DFMGenericFactoryInterface_iid" + +class DFMGenericPlugin : public QObject +{ + Q_OBJECT +public: + explicit DFMGenericPlugin(QObject *parent = 0); + + virtual QObject *create(const QString &key) = 0; +}; + +DFM_END_NAMESPACE + +#endif // DFMGENERICPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmviewfactory.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmviewfactory.cpp new file mode 100644 index 0000000..0cac9b1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmviewfactory.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmviewfactory.h" +#include "dfmviewplugin.h" +#include "dfmfactoryloader.h" + +#include "durl.h" +#include "dfmbaseview.h" +#include "private/dfmviewfactory_p.h" + +#include + +DFM_BEGIN_NAMESPACE + +#ifndef QT_NO_LIBRARY +Q_GLOBAL_STATIC_WITH_ARGS(DFMFactoryLoader, loader, + (DFMViewFactoryInterface_iid, QLatin1String("/views"), Qt::CaseInsensitive)) +#endif + +QMap DFMViewFactoryPrivate::viewToLoaderIndex; + +QStringList DFMViewFactory::keys() +{ + QStringList list; +#ifndef QT_NO_LIBRARY + typedef QMultiMap PluginKeyMap; + + const PluginKeyMap keyMap = loader()->keyMap(); + const PluginKeyMap::const_iterator cend = keyMap.constEnd(); + for (PluginKeyMap::const_iterator it = keyMap.constBegin(); it != cend; ++it) + list.append(it.value()); +#endif + return list; +} + +DFMBaseView *DFMViewFactory::create(const QString &key) +{ + if (DFMBaseView *view = dLoadPlugin(loader(), key)) { + DFMViewFactoryPrivate::viewToLoaderIndex[view] = loader()->indexOf(key); + + QObject *object = dynamic_cast(view); + + if (!object) + object = view->widget(); + + QObject::connect(object, &QObject::destroyed, object, [view] { + DFMViewFactoryPrivate::viewToLoaderIndex.remove(view); + }); + + return view; + } + + return Q_NULLPTR; +} + +bool DFMViewFactory::viewIsSuitedWithUrl(const DFMBaseView *view, const DUrl &url) +{ + int index = DFMViewFactoryPrivate::viewToLoaderIndex.value(view, -1); + + if (index != -1) { + QStringList key_list; + + key_list << url.scheme() + "://" + url.host(); + key_list << "://" + url.host(); + key_list << url.scheme() + "://"; + + for (const QString &key : key_list) { + int i = loader()->indexOf(key); + + if (i < 0) + continue; + + return i == index; + } + } + + return false; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmviewfactory.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmviewfactory.h new file mode 100644 index 0000000..684603a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmviewfactory.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMVIEWFACTORY_H +#define DFMVIEWFACTORY_H + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMBaseView; +class DFMViewFactory +{ +public: + static QStringList keys(); + static DFMBaseView *create(const QString &key); + static bool viewIsSuitedWithUrl(const DFMBaseView *view, const DUrl &url); +}; + +DFM_END_NAMESPACE + +#endif // DFMVIEWFACTORY_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmviewplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmviewplugin.cpp new file mode 100644 index 0000000..2141223 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmviewplugin.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmviewplugin.h" + +DFM_BEGIN_NAMESPACE +DFMViewPlugin::DFMViewPlugin(QObject *parent) + : QObject(parent) +{ + +} + +DFMViewPlugin::~DFMViewPlugin() +{ + +} +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmviewplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmviewplugin.h new file mode 100644 index 0000000..2dbf341 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/dfmviewplugin.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + + +#ifndef DFMVIEWPLUGIN_H +#define DFMVIEWPLUGIN_H + +#include + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE +#define DFMViewFactoryInterface_iid "com.deepin.filemanager.DFMViewFactoryInterface_iid" + +class DFMBaseView; +class DFMViewPlugin : public QObject +{ + Q_OBJECT +public: + explicit DFMViewPlugin(QObject *parent = 0); + ~DFMViewPlugin(); + + virtual DFMBaseView *create(const QString &key) = 0; +}; +DFM_END_NAMESPACE + +#endif // DFMVIEWPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/private/dfmfactoryloader_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/private/dfmfactoryloader_p.h new file mode 100644 index 0000000..8052ccc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/private/dfmfactoryloader_p.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMFACTORYLOADER_P_H +#define DFMFACTORYLOADER_P_H + +#include +#include +#include +#include +#include + +#include "dfmglobal.h" +#include "dfmfactoryloader.h" + +DFM_BEGIN_NAMESPACE + +namespace { + +// avoid duplicate QStringLiteral data: +inline QString iidKeyLiteral() { return QStringLiteral("IID"); } +#ifdef QT_SHARED +inline QString versionKeyLiteral() { return QStringLiteral("version"); } +#endif +inline QString metaDataKeyLiteral() { return QStringLiteral("MetaData"); } +inline QString keysKeyLiteral() { return QStringLiteral("Keys"); } + +} + +class DFMFactoryLoaderPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(DFMFactoryLoader) +public: + DFMFactoryLoaderPrivate(); + ~DFMFactoryLoaderPrivate(); + mutable QMutex mutex; + QByteArray iid; + QList pluginLoaderList; + QMultiMap keyMap; + QString suffix; + Qt::CaseSensitivity cs; + bool rki = false; + QStringList loadedPaths; + + static QStringList pluginPaths; +}; + + +DFM_END_NAMESPACE + +#endif // DFMFACTORYLOADER_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/private/dfmfilepreviewfactory_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/private/dfmfilepreviewfactory_p.h new file mode 100644 index 0000000..e8f5b71 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/private/dfmfilepreviewfactory_p.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . + */ + +#ifndef DFMFILEPREVIEWFACTORY_P_H +#define DFMFILEPREVIEWFACTORY_P_H + +#include + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DFMFilePreview; +class DFMFilePreviewFactoryPrivate +{ +public: + static QMap previewToLoaderIndex; +}; + +DFM_END_NAMESPACE + +#endif // DFMFILEPREVIEWFACTORY_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/private/dfmviewfactory_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/private/dfmviewfactory_p.h new file mode 100644 index 0000000..bccca90 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/plugins/private/dfmviewfactory_p.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + + +#ifndef DFMVIEWFACTORY_P_H +#define DFMVIEWFACTORY_P_H + +#include "dfmglobal.h" + +#include + +DFM_BEGIN_NAMESPACE + +class DFMBaseView; +class DFMViewFactoryPrivate +{ +public: + static QMap viewToLoaderIndex; +}; + +DFM_END_NAMESPACE + +#endif // DFMVIEWFACTORY_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dabstractfileinfo_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dabstractfileinfo_p.h new file mode 100644 index 0000000..34f036a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dabstractfileinfo_p.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DABSTRACTFILEINFO_P_H +#define DABSTRACTFILEINFO_P_H + +#include "dabstractfileinfo.h" +#include "dmimedatabase.h" + +#include + +QT_BEGIN_NAMESPACE +class QReadWriteLock; +QT_END_NAMESPACE + +DFM_USE_NAMESPACE + +class DAbstractFileInfoPrivate +{ +public: + DAbstractFileInfoPrivate(const DUrl &url, DAbstractFileInfo *qq, bool hasCache); + virtual ~DAbstractFileInfoPrivate(); + + void setUrl(const DUrl &url, bool hasCache); + static DAbstractFileInfo *getFileInfo(const DUrl &fileUrl); + + DAbstractFileInfo *q_ptr = Q_NULLPTR; + + mutable QString pinyinName; + bool active = false; + qint8 gvfsMountFile = -1; + + DAbstractFileInfoPointer proxy; + static DMimeDatabase mimeDatabase; + + bool columnCompact = false; + + Q_DECLARE_PUBLIC(DAbstractFileInfo) + +private: + DUrl fileUrl; + static QReadWriteLock *urlToFileInfoMapLock; + static QMap urlToFileInfoMap; +}; + +#endif // DABSTRACTFILEINFO_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dabstractfilewatcher_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dabstractfilewatcher_p.h new file mode 100644 index 0000000..3057f45 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dabstractfilewatcher_p.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DABSTRACTFILEWATCHER_P_H +#define DABSTRACTFILEWATCHER_P_H + +#include "durl.h" +#include "dabstractfilewatcher.h" + +class DAbstractFileWatcherPrivate +{ +public: + explicit DAbstractFileWatcherPrivate(DAbstractFileWatcher *qq); + virtual ~DAbstractFileWatcherPrivate() {} + virtual bool start() = 0; + virtual bool stop() = 0; + virtual bool handleGhostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType1 signal, const DUrl &arg1); + virtual bool handleGhostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType2 signal, const DUrl &arg1, const DUrl &arg2); + virtual bool handleGhostSignal(const DUrl &targetUrl, DAbstractFileWatcher::SignalType3 signal, const DUrl &arg1, int isExternalSource); + + DAbstractFileWatcher *q_ptr; + + DUrl url; + bool started = false; + static QList watcherList; + + Q_DECLARE_PUBLIC(DAbstractFileWatcher) +}; + +#endif // DABSTRACTFILEWATCHER_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dfileinfo_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dfileinfo_p.h new file mode 100644 index 0000000..50f1360 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dfileinfo_p.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILEINFO_P_H +#define DFILEINFO_P_H + +#include "dabstractfileinfo_p.h" + +#include +#include +#include +#include +#include + +class DFileInfo; +class RequestEP; +class DFileInfoPrivate : public DAbstractFileInfoPrivate +{ +public: + DFileInfoPrivate(const DUrl &fileUrl, DFileInfo *qq, bool hasCache = true); + ~DFileInfoPrivate(); + + bool isLowSpeedFile() const; + + QFileInfo fileInfo; + mutable QMimeType mimeType; + mutable QMimeDatabase::MatchMode mimeTypeMode; + mutable QIcon icon; + mutable bool iconFromTheme = false; + mutable QPointer getIconTimer; + bool requestingThumbnail = false; + mutable bool needThumbnail = false; + // 小于0时表示此值未初始化,0表示不支持,1表示支持 + mutable qint8 hasThumbnail = -1; + mutable qint8 lowSpeedFile = -1; + mutable quint64 inode = 0; + + mutable QVariantHash extraProperties; + mutable bool epInitialized = false; + mutable QPointer getEPTimer; + mutable QPointer requestEP; +}; + +Q_DECLARE_METATYPE(DFileInfoPrivate*) + +#endif // DFILEINFO_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dfilesystemwatcher_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dfilesystemwatcher_p.h new file mode 100644 index 0000000..9f0d5b7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dfilesystemwatcher_p.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILESYSTEMWATCHER_P_H +#define DFILESYSTEMWATCHER_P_H + +#include "dfilesystemwatcher.h" + +#include +#include +#include + +class DFileSystemWatcherPrivate +{ + Q_DECLARE_PUBLIC(DFileSystemWatcher) + +public: + DFileSystemWatcherPrivate(int fd, DFileSystemWatcher *qq); + ~DFileSystemWatcherPrivate(); + + QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories); + QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories); + + DFileSystemWatcher *q_ptr; + + QStringList files, directories; + int inotifyFd; + QHash pathToID; + QMultiHash idToPath; + QSocketNotifier notifier; + + // private slots + void _q_readFromInotify(); + +private: + void onFileChanged(const QString &path, bool removed); + void onDirectoryChanged(const QString &path, bool removed); +}; + +#endif // DFILESYSTEMWATCHER_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dfmapplication_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dfmapplication_p.h new file mode 100644 index 0000000..f025d5a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dfmapplication_p.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMAPPLICATION_P_H +#define DFMAPPLICATION_P_H + +#include + +DFM_BEGIN_NAMESPACE + +class DFMApplication; +class DFMApplicationPrivate +{ +public: + explicit DFMApplicationPrivate(dde_file_manager::DFMApplication *qq); + + void _q_onSettingsValueChanged(const QString &group, const QString &key, const QVariant &value, bool edited = false); + void _q_onSettingsValueEdited(const QString &group, const QString &key, const QVariant &value); + + static DFMApplication *self; +}; + +DFM_END_NAMESPACE + +#endif // DFMAPPLICATION_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dfmcrumbbar_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dfmcrumbbar_p.h new file mode 100644 index 0000000..be3da22 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dfmcrumbbar_p.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFMCRUMBBAR_P_H +#define DFMCRUMBBAR_P_H + +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE +DFM_BEGIN_NAMESPACE + +class DFMCrumbBar; +class DFMCrumbListviewModel; +class DFMAddressBar; +class DFMCrumbInterface; +class DFMCrumbBarPrivate +{ + Q_DECLARE_PUBLIC(DFMCrumbBar) + +public: + explicit DFMCrumbBarPrivate(DFMCrumbBar *qq); + ~DFMCrumbBarPrivate(); + + // UI + QPushButton leftArrow; + QPushButton rightArrow; + DListView crumbListView; + DFMCrumbListviewModel *crumbListviewModel = nullptr; + QHBoxLayout *crumbBarLayout; + QPoint clickedPos; + DFMAddressBar *addressBar = nullptr; + + // Scheme support + DFMCrumbInterface *crumbController = nullptr; + + // Misc + bool clickableAreaEnabled = false; + + DFMCrumbBar *q_ptr = nullptr; + + void clearCrumbs(); + void checkArrowVisiable(); + void updateController(const DUrl &url); + void setClickableAreaEnabled(bool enabled); + +private: + void initUI(); + void initData(); + void initConnections(); +}; + +DFM_END_NAMESPACE + +#endif // DFMCRUMBBAR_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dgvfsfileinfo_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dgvfsfileinfo_p.h new file mode 100644 index 0000000..73409d8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dgvfsfileinfo_p.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DGVFSFILEINFO_P_H +#define DGVFSFILEINFO_P_H + +#include "dfileinfo_p.h" + +#include +#include +#include +#include +#include + +class DGvfsFileInfo; +class RequestGvfsEP; +class DGvfsFileInfoPrivate : public DFileInfoPrivate +{ +public: + DGvfsFileInfoPrivate(const DUrl &url, DGvfsFileInfo *qq, bool hasCache = true); + ~DGvfsFileInfoPrivate(); + + mutable qint8 cacheFileExists = -1; + mutable qint8 cacheCanRename = -1; + mutable qint8 cacheIsSymLink = -1; + mutable qint8 cacheCanWrite = -1;//fix bug 27828 打开挂载文件(有很多的文件夹和文件)在断网的情况下,滑动鼠标或者滚动鼠标滚轮时文管卡死,做缓存 + mutable qint8 cacheIsDir = -1;// 缓存是否是dir + mutable long cacheModifyTime = -1;// bug 27247 远程连接FTP,使用大小排序反应很慢 + mutable long cacheReadTime = -1;// bug 27247 远程连接FTP,使用大小排序反应很慢 + mutable qint32 cacheFileCount = -1;// bug 27247 远程连接FTP,使用大小排序反应很慢 + mutable qint64 cacheFileSize = -1; // bug 27247 远程连接FTP,使用大小排序反应很慢 + + + mutable int ownerid = -1;//当前文件的所以 +}; + +Q_DECLARE_METATYPE(DGvfsFileInfoPrivate *) + +#endif // DGVFSFILEINFO_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dstyleditemdelegate_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dstyleditemdelegate_p.h new file mode 100644 index 0000000..3756077 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/dstyleditemdelegate_p.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DSTYLEDITEMDELEGATE_P_H +#define DSTYLEDITEMDELEGATE_P_H + +#include "dfmstyleditemdelegate.h" + +class DFMStyledItemDelegatePrivate +{ +public: + explicit DFMStyledItemDelegatePrivate(DFMStyledItemDelegate *qq) + : q_ptr(qq) {} + + void init(); + void _q_onRowsInserted(const QModelIndex &parent, int first, int last); + void _q_onRowsRemoved(const QModelIndex &parent, int first, int last); + + DFMStyledItemDelegate *q_ptr; + mutable QModelIndex editingIndex; + QSize itemSizeHint; + int textLineHeight = -1; + + Q_DECLARE_PUBLIC(DFMStyledItemDelegate) +}; + +#endif // DSTYLEDITEMDELEGATE_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/mergeddesktop_common_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/mergeddesktop_common_p.h new file mode 100644 index 0000000..b99464d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/private/mergeddesktop_common_p.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef MERGEDDESKTOP_COMMON_P_H +#define MERGEDDESKTOP_COMMON_P_H + +#define VIRTUALENTRY_FOLDER "entry/" +#define VIRTUALENTRY_PATH "/" VIRTUALENTRY_FOLDER + +#define VIRTUALFOLDER_FOLDER "folder/" +#define VIRTUALFOLDER_PATH "/" VIRTUALFOLDER_FOLDER + +#define MERGEDDESKTOP_FOLDER "mergeddesktop/" +#define MERGEDDESKTOP_PATH "/" MERGEDDESKTOP_FOLDER + +#endif // MERGEDDESKTOP_COMMON_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsabstracteventhandler.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsabstracteventhandler.cpp new file mode 100644 index 0000000..e1b7011 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsabstracteventhandler.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "dfmvfsabstracteventhandler.h" + +DFM_BEGIN_NAMESPACE + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsabstracteventhandler.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsabstracteventhandler.h new file mode 100644 index 0000000..5504e77 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsabstracteventhandler.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef DFMVFSABSTRACTEVENTHANDLER_H +#define DFMVFSABSTRACTEVENTHANDLER_H + +#include +#include +#include + +DFM_BEGIN_NAMESPACE + +class DFMVfsAbstractEventHandler +{ +public: + virtual ~DFMVfsAbstractEventHandler() {} + virtual int handleAskQuestion(QString message, QStringList choiceList) = 0; + virtual QJsonObject handleAskPassword(QJsonObject defaultFields) = 0; + virtual void handleMountError(int gioErrorCode, QString errorMessage) = 0; + virtual void handleUnmountError(int gioErrorCode, QString errorMessage) = 0; + + QPointer eventLoop; +}; + +DFM_END_NAMESPACE + +#endif // DFMVFSABSTRACTEVENTHANDLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsdevice.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsdevice.cpp new file mode 100644 index 0000000..620d2f9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsdevice.cpp @@ -0,0 +1,669 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "private/dfmvfsdevice_p.h" + +#include +#include +#include +#include +#include + +#ifdef QT_DEBUG +Q_LOGGING_CATEGORY(vfsDevice, "vfs.device") +#else +Q_LOGGING_CATEGORY(vfsDevice, "vfs.device", QtInfoMsg) +#endif + +DFM_BEGIN_NAMESPACE + +DFMVfsDevicePrivate::DFMVfsDevicePrivate(const QUrl &url, void *gmountObjectPtr, DFMVfsDevice *qq) + : q_ptr(qq) +{ + m_setupUrl = url.scheme() == "device" ? url.path() : url.toString(); + c_GMount.reset((GMount *)gmountObjectPtr); +} + +DFMVfsDevicePrivate::DFMVfsDevicePrivate(const QUrl &url, DFMVfsDevice *qq) + : m_setupUrl(url.scheme() == "device" ? url.path() : url.toString()) + , q_ptr(qq) +{ + +} + +DFMVfsDevicePrivate::~DFMVfsDevicePrivate() +{ + if (m_handler) { + delete m_handler; + } +} + +GMount *DFMVfsDevicePrivate::createGMount() const +{ + QByteArray urlBa = m_setupUrl.toLatin1(); + const char *urlCStr = urlBa.data(); + + GError *error = nullptr; + DFMGFile file(g_file_new_for_uri(urlCStr)); + DFMGMount mount(g_file_find_enclosing_mount(file.data(), nullptr, &error)); + if (!mount || error) { + qWarning() << "Error when creating GMount from GFile with this url: " << m_setupUrl; + qWarning() << "Reason: " << QString::fromLocal8Bit(error->message); + g_error_free(error); + } + + if (!mount) { + throw "DFMVfsDevicePrivate::createGMount() Method get called but create failed."; + } + + return mount.take(); +} + +QUrl DFMVfsDevice::defaultUri() const +{ + Q_D(const DFMVfsDevice); + + DFMGFile defaultUriFile(g_mount_get_default_location(d->getGMount())); + DFMGCChar defaultUriCStr(g_file_get_uri(defaultUriFile.data())); + return QUrl(QString::fromLocal8Bit(defaultUriCStr.data())); +} + + +// caller should free the return value by calling `g_object_unref` or using `DFMGFile`. +GFile *DFMVfsDevicePrivate::createRootFile() const +{ + DFMGFile file(g_mount_get_root(getGMount())); + if (!file) { + throw "DFMVfsDevicePrivate::getRootFile() Method get called which requires DFMVfsDevice is attached but it's not attached"; + } + return file.take(); +} + +// caller should free the return value by calling `g_object_unref` or using `DFMGFileInfo`. +GFileInfo *DFMVfsDevicePrivate::createRootFileInfo() const +{ + GError *error = nullptr; + DFMGFileInfo fileInfo(g_file_query_filesystem_info(getGFile(), "filesystem::*", nullptr, &error)); + if (!fileInfo || error) { + qWarning() << "Error when creating DFMVfsDevicePrivate::m_GFileInfo"; + qWarning() << "Reason: " << QString::fromLocal8Bit(error->message); + g_error_free(error); + } + if (!fileInfo) { + throw "DFMVfsDevicePrivate::createRootFileInfo() Method get called but fileinfo create failed."; + } + + return fileInfo.take(); +} + +GMount *DFMVfsDevicePrivate::getGMount() const +{ + if (!c_GMount) { + c_GMount.reset(createGMount()); + } + + return c_GMount.data(); +} + +GFile *DFMVfsDevicePrivate::getGFile() const +{ + if (!c_GFile) { + c_GFile.reset(createRootFile()); + } + + return c_GFile.data(); +} + +GFileInfo *DFMVfsDevicePrivate::getGFileInfo() const +{ + if (!c_GFileInfo) { + c_GFileInfo.reset(createRootFileInfo()); + } + + return c_GFileInfo.data(); +} + +QStringList DFMVfsDevicePrivate::getThemedIconName(GThemedIcon *icon) +{ + QStringList iconNames; + if (icon) { + char **names = nullptr; + char **iter = nullptr; + g_object_get(icon, "names", &names, NULL); + for (iter = names; *iter; iter++) { + iconNames.append(QString(*iter)); + } + g_strfreev(names); + } + return iconNames; +} + +// FIXME: who takes the ownership of the return value, should we `g_object_unref` it? +GMountOperation *DFMVfsDevicePrivate::GMountOperationNewMountOp(DFMVfsDevice *devicePtr) +{ + GMountOperation *op; + + op = g_mount_operation_new(); + + g_signal_connect(op, "ask_password", (GCallback)&DFMVfsDevicePrivate::GMountOperationAskPasswordCb, devicePtr); + g_signal_connect(op, "ask_question", (GCallback)&DFMVfsDevicePrivate::GMountOperationAskQuestionCb, devicePtr); + + /* dragondjf: we *should* also connect to the "aborted" signal but since the + * main thread is blocked handling input we won't get that signal + * anyway... + */ + return op; +} + +void DFMVfsDevicePrivate::GMountOperationAskPasswordCb(GMountOperation *op, const char *message, const char *default_user, + const char *default_domain, GAskPasswordFlags flags, gpointer vfsDevicePtr) +{ + DFMVfsDevice *device = static_cast(vfsDevicePtr); + bool anonymous = g_mount_operation_get_anonymous(op); + GPasswordSave passwordSave = g_mount_operation_get_password_save(op); + + const char *default_password = g_mount_operation_get_password(op); + + QJsonObject obj; + obj.insert("message", message); + obj.insert("anonymous", anonymous); + obj.insert("username", default_user); + obj.insert("domain", default_domain); + obj.insert("password", default_password); + obj.insert("GAskPasswordFlags", flags); + obj.insert("passwordSave", passwordSave); + + qCDebug(vfsDevice()) << "GMountOperationAskPasswordCb() Default fields data" << obj; + + QJsonObject loginObj; + if (device && device->eventHandler()) { + DFMVfsAbstractEventHandler *handler = static_cast(device->eventHandler()); + loginObj = handler->handleAskPassword(obj); + } else { + qCDebug(vfsDevice()) << "GMountOperationAskPasswordCb(): No event handler registered to DFMVfsManager, use the default action."; + } + + if (!loginObj.isEmpty()) { + anonymous = loginObj.value("anonymous").toBool(); + QString username = loginObj.value("username").toString(); + QString domain = loginObj.value("domain").toString(); + QString password = loginObj.value("password").toString(); + GPasswordSave passwordsaveFlag = static_cast(loginObj.value("passwordSave").toInt()); + + if ((flags & G_ASK_PASSWORD_ANONYMOUS_SUPPORTED) && anonymous) { + g_mount_operation_set_anonymous(op, TRUE); + } else { + if (flags & G_ASK_PASSWORD_NEED_USERNAME) { + g_mount_operation_set_username(op, username.toLocal8Bit().constData()); + } + + if (flags & G_ASK_PASSWORD_NEED_DOMAIN) { + g_mount_operation_set_domain(op, domain.toLocal8Bit().constData()); + } + + if (flags & G_ASK_PASSWORD_NEED_PASSWORD) { + g_mount_operation_set_password(op, password.toLocal8Bit().constData()); + } + + if (flags & G_ASK_PASSWORD_SAVING_SUPPORTED) { + g_mount_operation_set_password_save(op, passwordsaveFlag); + } + } + + /* Only try anonymous access once. */ + if (anonymous) { + g_mount_operation_reply(op, G_MOUNT_OPERATION_ABORTED); + } else { + g_mount_operation_reply(op, G_MOUNT_OPERATION_HANDLED); + } + + } else { + qCDebug(vfsDevice()) << "cancel connect"; + g_mount_operation_reply(op, G_MOUNT_OPERATION_ABORTED); + } +} + +// blumia: This callback is mainly for sftp fingerprint identity dialog, but should works on any ask-question signal. +// ref: https://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/gio/GMountOperation.html#GMountOperation-ask-question +void DFMVfsDevicePrivate::GMountOperationAskQuestionCb(GMountOperation *op, const char *message, const GStrv choices, gpointer vfsDevicePtr) +{ + char **ptr = choices; + int choice = 0; + QStringList choiceList; + DFMVfsDevice *device = static_cast(vfsDevicePtr); + + QString oneMessage(message); + qCDebug(vfsDevice()) << "GMountOperationAskQuestionCb() message: " << message; + + while (ptr && *ptr) { + QString oneOption = QString::asprintf("%s", *ptr++); + qCDebug(vfsDevice()) << "GMountOperationAskQuestionCb() - option(s): " << oneOption; + choiceList << oneOption; + } + + if (device && device->eventHandler()) { + DFMVfsAbstractEventHandler *handler = static_cast(device->eventHandler()); + choice = handler->handleAskQuestion(oneMessage, choiceList); + } else { + qCDebug(vfsDevice()) << "GMountOperationAskQuestionCb(): No event handler registered to DFMVfsManager, use the default action."; + } + + qCDebug(vfsDevice()) << "GMountOperationAskQuestionCb() user choice(start at 0): " << choice; + + // check if choose is invalid + if (choice < 0 && choice >= choiceList.count()) { + g_mount_operation_reply(op, G_MOUNT_OPERATION_ABORTED); + return; + } + + g_mount_operation_set_choice(op, choice); + g_mount_operation_reply(op, G_MOUNT_OPERATION_HANDLED); + + return; +} + +void DFMVfsDevicePrivate::GFileMountDoneCb(GObject *object, GAsyncResult *res, gpointer vfsDevicePtr) +{ + gboolean succeeded; + GError *error = NULL; + DFMVfsDevice *device = static_cast(vfsDevicePtr); + + succeeded = g_file_mount_enclosing_volume_finish(G_FILE(object), res, &error); + + if (!succeeded && error) { + Q_ASSERT(error->domain == G_IO_ERROR); + + int errorCode = error->code; + QString errorMsg(error->message); + + if (device->eventHandler()) { + DFMVfsAbstractEventHandler *handler = static_cast(device->eventHandler()); + handler->handleMountError(errorCode, errorMsg); + } else { + qCDebug(vfsDevice()) << "GFileMountDoneCb(): No event handler registered to DFMVfsManager, use the default action."; + + switch (error->code) { + case G_IO_ERROR_FAILED_HANDLED: // Operation failed and a helper program has already interacted with the user. Do not display any error dialog. + break; + default: + qCDebug(vfsDevice()) << "GFileMountDoneCb() mount failed. reason: " << errorMsg; + break; + } + } + + g_error_free(error); + } + + if (device->d_ptr->m_eventLoop) { + device->d_ptr->m_eventLoop->exit(succeeded ? 0 : -1); + } +} + +void DFMVfsDevicePrivate::GFileUnmountDoneCb(GObject *object, GAsyncResult *res, gpointer vfsDevicePtr) +{ + gboolean succeeded; + GError *error = NULL; + DFMVfsDevice *device = static_cast(vfsDevicePtr); + + succeeded = g_mount_unmount_with_operation_finish(G_MOUNT(object), res, &error); + + if (!succeeded && error) { + if (error->domain != G_IO_ERROR) return; + + int errorCode = error->code; + QString errorMsg(error->message); + + if (device->eventHandler()) { + DFMVfsAbstractEventHandler *handler = static_cast(device->eventHandler()); + handler->handleUnmountError(errorCode, errorMsg); + } else { + qCDebug(vfsDevice()) << "GFileUnmountDoneCb(): No event handler registered to DFMVfsManager, use the default action."; + qCDebug(vfsDevice()) << "GFileUnmountDoneCb() unmount failed. reason: " << errorMsg; + } + + g_error_free(error); + } +} + +/*! \class DFMVfsDevice + + \brief DFMVfsDevice allowed you query and manage a VFS mountpoint. + + Once a virtual filesystem (i.e. a remote/network device) got mounted. You can then manage this VFS by + creating a new DFMVfsDevice instance. Since we use the mount URI as an identifier, it may failed when + creating DFMVfsDevice instance, so using DFMVfsDevice::create() for creating and don't forget to check + if create failed. + + DFMVfsManager::getVfsList() will return a full list with all attached(i.e. mounted) VFSes, using url + from that function's return value is the recommend way to create a DFMVfsDevice instance. + + DFMVfsDevice is actually a GMount and GFileInfo wrapper for a GMount mountpoint, but it's designed for + virtual filesystem here. For local filesystem management, use DDiskManager instead. + + \sa DFMVfsManager, DDiskManager + */ + +DFMVfsDevice::DFMVfsDevice(const QUrl &url, void *gmountObjectPtr, QObject *parent) + : QObject(parent) + , d_ptr(new DFMVfsDevicePrivate(url, gmountObjectPtr, this)) +{ + +} + +/*! + * \brief Create a new DFMVfsDevice instance. + * + * Create a DFMVfsDevice instance with the given mountpoint URI. like `sftp://blumia@127.0.0.1/` or similar. + * You can use DFMVfsManager::getVfsList to get a list of mounted VFS devices' URI which is ready for use to + * create DFMVfsDevice instance. + * + * \param url mountpoint URI. + * + * \param parent useless for now, probably will be used later. + * + * \return the created DFMVfsDevice instance, or nullptr if failed. + * + * \sa DFMVfsManager::getVfsList + */ +DFMVfsDevice *DFMVfsDevice::create(const QUrl &url, QObject *parent) +{ + if (!url.isValid() || url.scheme() == "file" || url.scheme().isEmpty()) { + return nullptr; + } + + QString deviceId = url.scheme() == "device" ? url.path() : url.toString(); + + QByteArray ba = deviceId.toLatin1(); + const char *urlCStr = ba.data(); + + GError *error = nullptr; + DFMGFile file(g_file_new_for_uri(urlCStr)); + DFMGMount mount(g_file_find_enclosing_mount(file.data(), nullptr, &error)); + if (!mount || error) { + qWarning() << "Error when creating DFMVfsDevice with this url: " << url; + qWarning() << "Reason: " << QString::fromLocal8Bit(error->message); + g_error_free(error); + return nullptr; + } + + return new DFMVfsDevice(url, mount.take(), parent); +} + +/*! + * \brief Create a new DFMVfsDevice instance. + * + * This method create a DFMVfsDevice instance without checking if there is already a + * attached vfs device. This can be used to create a vfs device to attach a new vfs + * mountpoint to local. + * + * \note it's dangerous if you are creating a unmounted device and calling functions + * which requires device existed and mounted. You can use createUnsafe() to create a + * DFMVfsDevice instance even if the given url is not related to a devive (e.g. + * `smb://10.0.12.161:445/` is not a url for device, `smb://10.0.12.161:445/share/` + * is). It's useful for mounting a GFile with uri like this. + * + * \param url mountpoint URI. + * + * \param parent parent useless for now, probably will be used later. + * + * \return the created DFMVfsDevice instance, or nullptr if \a url is a file scheme url. + */ +DFMVfsDevice *DFMVfsDevice::createUnsafe(const QUrl &url, QObject *parent) +{ + if (url.scheme() == "file" || url.scheme().isEmpty()) { + return nullptr; + } + + if (url.scheme() != "device") { + QUrl newUrl; + newUrl.setScheme("device"); + newUrl.setPath(url.toString()); + return new DFMVfsDevice(newUrl, parent); + } + + return new DFMVfsDevice(url, parent); +} + +DFMVfsDevice::~DFMVfsDevice() +{ + +} + +/*! + * \brief Attach the device. + * + * This method should be called by DFMVfsManager in the most case, and it's okay to call + * even if the SFMVfsDevice instance is not yet attached. (of course, this function is + * to do the attach job). + * + * You can also use this function to mount uri like `smb://10.0.12.161:445/` , but this + * kinds of mount won't trigger a DFMVfsManager::vfsAttached() (i.e. vfs device mounted) + * signal. + * + * \return + */ +bool DFMVfsDevice::attach() +{ + Q_D(DFMVfsDevice); + + QPointer oldEventLoop = d->m_eventLoop; + QEventLoop eventLoop; + + d->m_eventLoop = &eventLoop; + + DFMGFile file(g_file_new_for_uri(d->m_setupUrl.toUtf8().constData())); + if (!file) { + return false; + } + + GMountOperation *op = DFMVfsDevicePrivate::GMountOperationNewMountOp(this); + g_file_mount_enclosing_volume(file.data(), static_cast(0), + op, nullptr, (GAsyncReadyCallback)&DFMVfsDevicePrivate::GFileMountDoneCb, this); + + int ret = d->m_eventLoop->exec(); + if (oldEventLoop) { + oldEventLoop->exit(ret); + } + + return ret == 0; +} + +/*! + * \brief Async detach device. + * + * \return if we start to do detach. will be false if it's not detachable. + */ +bool DFMVfsDevice::detachAsync() +{ + Q_D(DFMVfsDevice); + + if (!canDetach()) { + return false; + } + + GMountOperation *op = DFMVfsDevicePrivate::GMountOperationNewMountOp(this); + g_mount_unmount_with_operation(d->getGMount(), G_MOUNT_UNMOUNT_NONE, + op, nullptr, (GAsyncReadyCallback)&DFMVfsDevicePrivate::GFileUnmountDoneCb, this); + + return true; +} + +DFMVfsAbstractEventHandler *DFMVfsDevice::eventHandler() const +{ + Q_D(const DFMVfsDevice); + + return d->m_handler; +} + +void DFMVfsDevice::setEventHandler(DFMVfsAbstractEventHandler *handler, QThread *threadOfHandler) +{ + Q_D(DFMVfsDevice); + + d->m_handler = handler; + d->m_threadOfEventHandler = threadOfHandler; +} + +bool DFMVfsDevice::isReadOnly() const +{ + Q_D(const DFMVfsDevice); + + return g_file_info_get_attribute_boolean(d->getGFileInfo(), G_FILE_ATTRIBUTE_FILESYSTEM_READONLY); +} + +bool DFMVfsDevice::canDetach() const +{ + Q_D(const DFMVfsDevice); + + return g_mount_can_unmount(d->getGMount()); +} + +quint64 DFMVfsDevice::totalBytes() const +{ + Q_D(const DFMVfsDevice); + + quint64 result; + + try { + result = g_file_info_get_attribute_uint64(d->getGFileInfo(), G_FILE_ATTRIBUTE_FILESYSTEM_SIZE); + } catch (const char *) { + result = 0; + } + + return result; +} + +quint64 DFMVfsDevice::usedBytes() const +{ + Q_D(const DFMVfsDevice); + + quint64 result; + + try { + result = g_file_info_get_attribute_uint64(d->getGFileInfo(), G_FILE_ATTRIBUTE_FILESYSTEM_USED); + } catch (const char *) { + result = 0; + } + + return result; +} + +quint64 DFMVfsDevice::freeBytes() const +{ + Q_D(const DFMVfsDevice); + + quint64 result; + + try { + result = g_file_info_get_attribute_uint64(d->getGFileInfo(), G_FILE_ATTRIBUTE_FILESYSTEM_FREE); + } catch (const char *) { + result = 0; + } + + return result; +} + +/*! + * \brief Get the root path of the mount point + * + * e.g. "/run/user/1002/gvfs/smb-share:server=10.0.12.161,share=share" + */ +QString DFMVfsDevice::rootPath() const +{ + Q_D(const DFMVfsDevice); + + DFMGCChar rootUriCStr(g_file_get_path(d->getGFile())); + return QString::fromLocal8Bit(rootUriCStr.data()); +} + +/*! + * \brief Get the root uri of the mount point + * + * e.g. QUrl("smb://10.0.12.161/share/") + */ +QUrl DFMVfsDevice::rootUri() const +{ + Q_D(const DFMVfsDevice); + + DFMGCChar rootUriCStr(g_file_get_uri(d->getGFile())); + return QUrl(QString::fromLocal8Bit(rootUriCStr.data())); +} + + + + +QString DFMVfsDevice::defaultPath() const +{ + Q_D(const DFMVfsDevice); + + DFMGFile defaultUriFile(g_mount_get_default_location(d->getGMount())); + DFMGCChar defaultUriCStr(g_file_get_path(defaultUriFile.data())); + return QString::fromLocal8Bit(defaultUriCStr.data()); +} + +QString DFMVfsDevice::name() const +{ + Q_D(const DFMVfsDevice); + + DFMGCChar vfsName(g_mount_get_name(d->getGMount())); + return QString::fromLocal8Bit(vfsName.data()); +} + +/*! + * \brief Get icon theme name with a fallback list + */ +QStringList DFMVfsDevice::iconList() const +{ + Q_D(const DFMVfsDevice); + + DFMGIcon icon(g_mount_get_icon(d->getGMount())); + + if (icon && G_IS_THEMED_ICON(icon.data())) { + // blumia: QIcon::fromTheme accept the full name and will do the fallback when needed, so + // maybe we doesn't need such a list. + return DFMVfsDevicePrivate::getThemedIconName(G_THEMED_ICON(icon.data())); + } + + // use `gchar * g_icon_to_string ()` can get a path if it's not a GThemedIcon. + // if it is, the result of `g_icon_to_string()` is simply the name (such as network-server). + return {}; +} + +/*! + * \brief Get symbolic icon name with a fallback list + * + * TODO: What's the differences between `g_mount_get_icon` and `g_mount_get_symbolic_icon`? + */ +QStringList DFMVfsDevice::symbolicIconList() const +{ + Q_D(const DFMVfsDevice); + + DFMGIcon icon(g_mount_get_symbolic_icon(d->getGMount())); + + if (icon && G_IS_THEMED_ICON(icon.data())) { + return DFMVfsDevicePrivate::getThemedIconName(G_THEMED_ICON(icon.data())); + } + + return {}; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsdevice.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsdevice.h new file mode 100644 index 0000000..cd8ecc1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsdevice.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef DFMVFSDEVICE_H +#define DFMVFSDEVICE_H + +#include "dfmvfsabstracteventhandler.h" +#include + +#include +#include + +DFM_BEGIN_NAMESPACE + +class DFMVfsDevicePrivate; +class DFMVfsDevice : public QObject { + Q_OBJECT + + Q_PROPERTY(bool isReadOnly READ isReadOnly) + Q_PROPERTY(bool canDetach READ canDetach) + Q_PROPERTY(quint64 totalBytes READ totalBytes) + Q_PROPERTY(quint64 usedBytes READ usedBytes) + Q_PROPERTY(quint64 freeBytes READ freeBytes) + Q_PROPERTY(QUrl rootUri READ rootPath) + Q_PROPERTY(QUrl defaultUri READ defaultPath) + Q_PROPERTY(QString rootPath READ rootPath) + Q_PROPERTY(QString defaultPath READ defaultPath) + Q_PROPERTY(QString name READ name) + +private: + explicit DFMVfsDevice(const QUrl &url, void* gmountObjectPtr, QObject *parent = nullptr); + +public: + static DFMVfsDevice* create(const QUrl& url, QObject *parent = nullptr); + static DFMVfsDevice* createUnsafe(const QUrl& url, QObject *parent = nullptr); + ~DFMVfsDevice(); + + bool attach(); // 挂载 + bool detachAsync(); // 卸载 + + DFMVfsAbstractEventHandler *eventHandler() const; + void setEventHandler(DFMVfsAbstractEventHandler *handler, QThread *threadOfHandle = nullptr); + + bool isReadOnly() const; + bool canDetach() const; + quint64 totalBytes() const; + quint64 usedBytes() const; + quint64 freeBytes() const; + QUrl rootUri() const; + QUrl defaultUri() const; + QString rootPath() const; + QString defaultPath() const; + QString name() const; + QStringList iconList() const; + QStringList symbolicIconList() const; + + /* 各种属性:忘记密码? */ + +private: + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(DFMVfsDevice) +}; + +DFM_END_NAMESPACE + +#endif // DFMVFSDEVICE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsmanager.cpp new file mode 100644 index 0000000..fdedeb4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsmanager.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#include "private/dfmvfsmanager_p.h" + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef QT_DEBUG +Q_LOGGING_CATEGORY(vfsManager, "vfs.manager") +#else +Q_LOGGING_CATEGORY(vfsManager, "vfs.manager", QtInfoMsg) +#endif + +DFM_BEGIN_NAMESPACE + +DFMVfsManagerPrivate::DFMVfsManagerPrivate(DFMVfsManager *qq) + : q_ptr(qq) +{ + m_GVolumeMonitor.reset(g_volume_monitor_get()); + initConnect(); +} + +DFMVfsManagerPrivate::~DFMVfsManagerPrivate() +{ + Q_Q(DFMVfsManager); + + if (m_handler) { + delete m_handler; + } + + g_signal_handlers_disconnect_by_data(m_GVolumeMonitor.data(), q); +} + +void DFMVfsManagerPrivate::GVolumeMonitorMountAddedCb(GVolumeMonitor *, GMount *mount, DFMVfsManager* managerPointer) +{ + DFMGFile rootFile(g_mount_get_root(mount)); + DFMGCChar rootUriCStr(g_file_get_uri(rootFile.data())); + QString rootUrlStr(rootUriCStr.data()); + QUrl url(rootUrlStr); + if (url.scheme() == "file") return; +// if (g_mount_is_shadowed(mount)) return; // is_shadowed + + QUrl deviceUrl; + deviceUrl.setScheme("device"); + deviceUrl.setPath(rootUrlStr); + + emit managerPointer->vfsAttached(deviceUrl); + emit managerPointer->vfsDeviceListInfoChanged(); +} + +void DFMVfsManagerPrivate::GVolumeMonitorMountRemovedCb(GVolumeMonitor *, GMount *mount, DFMVfsManager* managerPointer) +{ + DFMGFile rootFile(g_mount_get_root(mount)); + DFMGCChar rootUriCStr(g_file_get_uri(rootFile.data())); + QString rootUrlStr(rootUriCStr.data()); + QUrl url(rootUrlStr); + if (url.scheme() == "file") return; +// if (g_mount_is_shadowed(mount)) return; // is_shadowed + + QUrl deviceUrl; + deviceUrl.setScheme("device"); + deviceUrl.setPath(rootUrlStr); + + emit managerPointer->vfsDetached(deviceUrl); + emit managerPointer->vfsDeviceListInfoChanged(); +} + +void DFMVfsManagerPrivate::GVolumeMonitorMountChangedCb(GVolumeMonitor *, GMount *mount, DFMVfsManager* managerPointer) +{ + Q_UNUSED(managerPointer); + + DFMGFile rootFile(g_mount_get_root(mount)); + DFMGCChar rootUriCStr(g_file_get_uri(rootFile.data())); + QString rootUrlStr(rootUriCStr.data()); + QUrl url(rootUrlStr); + if (url.scheme() == "file") return; + + emit managerPointer->vfsDeviceListInfoChanged(); +} + +void DFMVfsManagerPrivate::initConnect() +{ + Q_Q(DFMVfsManager); + + // check if is not root. + if (getuid() != 0) { + g_signal_connect(m_GVolumeMonitor.data(), "mount-added", (GCallback)&DFMVfsManagerPrivate::GVolumeMonitorMountAddedCb, q); + g_signal_connect(m_GVolumeMonitor.data(), "mount-removed", (GCallback)&DFMVfsManagerPrivate::GVolumeMonitorMountRemovedCb, q); + g_signal_connect(m_GVolumeMonitor.data(), "mount-changed", (GCallback)&DFMVfsManagerPrivate::GVolumeMonitorMountChangedCb, q); + } +} + +/*! + * \brief Get a list of all attached virtual filesystem. + * + * Only virtual filesystems (i.e. remote/network locations) will be returned. + * + * \return QList of attached virtual filesystem with their root url. + */ +const QList DFMVfsManager::getVfsList() +{ + Q_D(DFMVfsManager); + + QSet result; + + DFMGMountList mountList(g_volume_monitor_get_mounts(d->m_GVolumeMonitor.data())); + GMount* mount = nullptr; + GList* iter; + for (iter = mountList.data(); iter != nullptr; iter = iter->next) { + mount = (GMount*)iter->data; + DFMGFile rootFile(g_mount_get_root(mount)); + DFMGCChar rootUriCStr(g_file_get_uri(rootFile.data())); + QString rootUrlStr(rootUriCStr.data()); + QUrl urlForCheck(rootUrlStr); + if (urlForCheck.scheme() == "file") continue; + if (g_mount_is_shadowed(mount)) continue; + QUrl url; + url.setScheme("device"); + url.setPath(rootUrlStr); + result << url; + } + + return result.toList(); +} + +/*! \class DFMVfsManager + + \brief DFMVfsManager manage all virtual filesystem. + + Virtual filesystem here means it's not a physical device in local computer, i.e. it's a remote/network + device. DFMVfsManager manage the state of already mounted devices and provide signal when a new vfs is + mounted(attached) to the computer or a vfs mount point get unmounted(detached). + + We use the word attach and detach rather than mount and unmount because one *network* location will + always comes with one available mount point, so a drive / partition / volume mount / unmount event will + always consider as a same event. + + We use the URI which is used to mount the device as a identifier, use DFMVfsManager::getVfsList() to + get a list of already attached vfs list, and use DFMVfsDevice to manage them when needed. + + \sa DFMVfsDevice, DDiskManager + */ + +DFMVfsManager::DFMVfsManager(QObject *parent) + : QObject(parent) + , d_ptr(new DFMVfsManagerPrivate(this)) +{ + +} + +DFMVfsManager::~DFMVfsManager() +{ + +} + + +bool DFMVfsManager::attach(const QUrl &url) +{ + if (!url.isValid() || url.scheme() == "file" || url.scheme().isEmpty()) { + return false; + } + + QScopedPointer dev(DFMVfsDevice::createUnsafe(url, nullptr)); + + if (eventHandler()) { + dev->setEventHandler(eventHandler()); + } + + return dev->attach(); +} + +DFMVfsAbstractEventHandler *DFMVfsManager::eventHandler() const +{ + Q_D(const DFMVfsManager); + + return d->m_handler; +} + +void DFMVfsManager::setEventHandler(DFMVfsAbstractEventHandler *handler, QThread *threadOfHandler) +{ + Q_D(DFMVfsManager); + + d->m_handler = handler; + d->m_threadOfEventHandler = threadOfHandler; +} + + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsmanager.h new file mode 100644 index 0000000..b1058f3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/dfmvfsmanager.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef DFMVFSMANAGER_H +#define DFMVFSMANAGER_H + +#include "dfmvfsabstracteventhandler.h" +#include +#include + +DFM_BEGIN_NAMESPACE + +class DFMVfsManagerPrivate; +class DFMVfsManager : public QObject { + Q_OBJECT +public: + explicit DFMVfsManager(QObject *parent = nullptr); + ~DFMVfsManager(); + + const QList getVfsList(); // 已经挂载的所有网络设备列表 + + bool attach(const QUrl& url); + + DFMVfsAbstractEventHandler *eventHandler() const; + void setEventHandler(DFMVfsAbstractEventHandler *handler, QThread *threadOfHandle = nullptr); + +signals: + void vfsAttached(const QUrl& url); // 参数为挂载点 url ,可以直接通过挂载点 url ,当存在 shadow 挂载点时一个设备可能有多个挂载信号 + void vfsDetached(const QUrl& url); // 来创建一个 DFMVfsDevice ,存在 shadow 挂载点时也可能有多个卸载信号 + void vfsDeviceListInfoChanged(); // 有 vfs 的设备信息改变的通知,改变也包括类如多了个 shadow 挂载点之类的属性等 + +private: + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(DFMVfsManager) +}; + +DFM_END_NAMESPACE + +#endif // DFMVFSMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/private/dfmgiowrapper_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/private/dfmgiowrapper_p.h new file mode 100644 index 0000000..5b2d9c8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/private/dfmgiowrapper_p.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef DFMGIOWRAPPER_P_H +#define DFMGIOWRAPPER_P_H + +#undef signals +extern "C" { + #include +} +#define signals public + +// this struct calls "g_object_unref" to `delete` the pointer +struct ScopedPointerGObjectUnrefDeleter +{ + static inline void cleanup(void* pointer) { + if (pointer != nullptr) { + g_object_unref(pointer); + } + } +}; + +// this struct calls "g_free" to free the pointer +struct ScopedPointerGFreeDeleter +{ + static inline void cleanup(void* pointer) { + if (pointer != nullptr) { + g_free(pointer); + } + } +}; + +// this struct calls "g_list_free_full" with "g_object_unref" to free the pointer +struct ScopedPointerGListGObjectUnrefDeleter +{ + static inline void cleanup(GList* pointer) { + if (pointer != nullptr) { + g_list_free_full(pointer, g_object_unref); + } + } +}; + +using DFMGFile = QScopedPointer; +using DFMGMount = QScopedPointer; +using DFMGIcon = QScopedPointer; +using DFMGCChar = QScopedPointer; +using DFMGFileInfo = QScopedPointer; +using DFMGMountList = QScopedPointer; + +#endif // DFMGIOWRAPPER_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/private/dfmvfsdevice_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/private/dfmvfsdevice_p.h new file mode 100644 index 0000000..228a6d6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/private/dfmvfsdevice_p.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef DFMVFSDEVICE_P_H +#define DFMVFSDEVICE_P_H + +#include "dfmvfsdevice.h" +#include "private/dfmgiowrapper_p.h" + +DFM_BEGIN_NAMESPACE + +class DFMVfsDevicePrivate +{ + Q_DECLARE_PUBLIC(DFMVfsDevice) + +public: + explicit DFMVfsDevicePrivate(const QUrl &url, void *gmountObjectPtr, DFMVfsDevice *qq); + explicit DFMVfsDevicePrivate(const QUrl &url, DFMVfsDevice *qq); + ~DFMVfsDevicePrivate(); + + GMount* createGMount() const; + GFile* createRootFile() const; + GFileInfo* createRootFileInfo() const; + + GMount* getGMount() const; // promise will always return a value, or throw an exception + GFile* getGFile() const; // promise will always return a value, or throw an exception + GFileInfo* getGFileInfo() const; // promise will always return a value, or throw an exception + + static QStringList getThemedIconName(GThemedIcon *icon); + + static GMountOperation *GMountOperationNewMountOp(DFMVfsDevice *devicePtr); + static void GMountOperationAskPasswordCb(GMountOperation *op, const char *message, const char *default_user, const char *default_domain, GAskPasswordFlags flags, gpointer vfsDevicePtr); + static void GMountOperationAskQuestionCb(GMountOperation *op, const char *message, const GStrv choices, gpointer vfsDevicePtr); + static void GFileMountDoneCb(GObject *object, GAsyncResult *res, gpointer vfsDevicePtr); + static void GFileUnmountDoneCb(GObject *object, GAsyncResult *res, gpointer vfsDevicePtr); + + QString m_setupUrl; // url used to setup this DFMVfsDevice. + QPointer m_eventLoop; // to make async event sync. + + DFMVfsAbstractEventHandler *m_handler = nullptr; + QPointer m_threadOfEventHandler; + + DFMVfsDevice *q_ptr = nullptr; + +private: + mutable DFMGMount c_GMount; // cached value, default null, mountpoint file. + mutable DFMGFile c_GFile; // cached value, default null, mountpoint file. + mutable DFMGFileInfo c_GFileInfo; // cached value, default null, mountpoint fileinfo. +}; + +DFM_END_NAMESPACE + +#endif // DFMVFSDEVICE_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/private/dfmvfsmanager_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/private/dfmvfsmanager_p.h new file mode 100644 index 0000000..8a2c0aa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/private/dfmvfsmanager_p.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: zhangsheng + * + * Maintainer: dengkeyun + * xushitong + * max-lv + * + * 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 + * 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 . + */ + +#ifndef DFMVFSMANAGER_P_H +#define DFMVFSMANAGER_P_H + +#include "dfmvfsmanager.h" +#include "dfmvfsdevice.h" +#include "private/dfmgiowrapper_p.h" + +DFM_BEGIN_NAMESPACE + +class DFMVfsManagerPrivate +{ + Q_DECLARE_PUBLIC(DFMVfsManager) + +public: + explicit DFMVfsManagerPrivate(DFMVfsManager *qq); + ~DFMVfsManagerPrivate(); + + QScopedPointer m_GVolumeMonitor; + DFMVfsAbstractEventHandler *m_handler = nullptr; + QPointer m_threadOfEventHandler; + + static void GVolumeMonitorMountAddedCb(GVolumeMonitor *, GMount *mount, DFMVfsManager* managerPointer); + static void GVolumeMonitorMountRemovedCb(GVolumeMonitor *, GMount *mount, DFMVfsManager* managerPointer); + static void GVolumeMonitorMountChangedCb(GVolumeMonitor *, GMount *mount, DFMVfsManager* managerPointer); + + + DFMVfsManager *q_ptr = nullptr; + +private: + void initConnect(); +}; + +DFM_END_NAMESPACE + +#endif // DFMVFSMANAGER_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/private/private.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/private/private.pri new file mode 100644 index 0000000..64edddd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/private/private.pri @@ -0,0 +1,4 @@ +HEADERS += \ + $$PWD/dfmgiowrapper_p.h \ + $$PWD/dfmvfsdevice_p.h \ + $$PWD/dfmvfsmanager_p.h diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/vfs.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/vfs.pri new file mode 100644 index 0000000..b3aad6b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/interfaces/vfs/vfs.pri @@ -0,0 +1,13 @@ +SOURCES += \ + $$PWD/dfmvfsmanager.cpp \ + $$PWD/dfmvfsdevice.cpp \ + $$PWD/dfmvfsabstracteventhandler.cpp + +HEADERS += \ + $$PWD/dfmvfsmanager.h \ + $$PWD/dfmvfsdevice.h \ + $$PWD/dfmvfsabstracteventhandler.h + +include($$PWD/private/private.pri) + +INCLUDEPATH += $$PWD diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilecopymovejob.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilecopymovejob.cpp new file mode 100644 index 0000000..686fc9f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilecopymovejob.cpp @@ -0,0 +1,4540 @@ + /* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dfilecopymovejob.h" +#include "private/dfilecopymovejob_p.h" + +#include "dfileservices.h" +#include "dabstractfileinfo.h" +#include "dfiledevice.h" +#include "dfilehandler.h" +#include "ddiriterator.h" +#include "dfilestatisticsjob.h" +#include "dlocalfiledevice.h" +#include "models/trashfileinfo.h" +#include "controllers/vaultcontroller.h" +#include "controllers/masteredmediacontroller.h" +#include "controllers/avfsfilecontroller.h" +#include "interfaces/dfmstandardpaths.h" +#include "shutil/fileutils.h" +#include "dgiofiledevice.h" +#include "deviceinfo/udisklistener.h" +#include "app/define.h" +#include "dialogs/dialogmanager.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef signals +extern "C" { +#include +} +#define signals public + +DFM_BEGIN_NAMESPACE + +#ifdef QT_DEBUG +Q_LOGGING_CATEGORY(fileJob, "file.job") +#else +Q_LOGGING_CATEGORY(fileJob, "file.job", QtInfoMsg) +#endif +// == +#if defined(Q_OS_LINUX) && (defined(__GLIBC__) || QT_HAS_INCLUDE()) +# include + +# if defined(Q_OS_ANDROID) && !defined(SYS_gettid) +# define SYS_gettid __NR_gettid +# endif + + +#define MAX_BUFFER_LEN 1024 * 1024 * 1 +#define BIG_FILE_SIZE 500 * 1024 * 1024 +#define THREAD_SLEEP_TIME 200 +QQueue DFileCopyMoveJobPrivate::CopyLargeFileOnDiskQueue; +QMutex DFileCopyMoveJobPrivate::CopyLargeFileOnDiskMutex; + +static long qt_gettid() +{ + // no error handling + // this syscall has existed since Linux 2.4.11 and cannot fail + return syscall(SYS_gettid); +} +#elif defined(Q_OS_DARWIN) +# include +static int qt_gettid() +{ + // no error handling: this call cannot fail + __uint64_t tid; + pthread_threadid_np(NULL, &tid); + return tid; +} +#elif defined(Q_OS_FREEBSD_KERNEL) && defined(__FreeBSD_version) && __FreeBSD_version >= 900031 +# include +static int qt_gettid() +{ + return pthread_getthreadid_np(); +} +#else +static QT_PREPEND_NAMESPACE(qint64) qt_gettid() +{ + QT_USE_NAMESPACE + return qintptr(QThread::currentThreadId()); +} +#endif + +static QByteArray fileReadAll(const QString &file_path) +{ + QFile file(file_path); + + if (file.open(QIODevice::ReadOnly)) { + return file.readAll(); + } + + return QByteArray(); +} + +class ElapsedTimer +{ +public: + inline void start() + { + invalidElapsed = 0; + elapsedOfPause = -1; + timer.start(); + } + + void togglePause() + { + if (!timer.isValid()) { + return; + } + + if (elapsedOfPause < 0) { + elapsedOfPause = timer.elapsed(); + } else { + invalidElapsed += (timer.elapsed() - elapsedOfPause); + elapsedOfPause = -1; + } + } + + inline bool isPaused() const + { + return elapsedOfPause > 0; + } + + inline bool isRunning() const + { + return timer.isValid(); + } + + inline qint64 elapsed() const + { + return timer.elapsed() - invalidElapsed; + } + + inline qint64 totalElapsed() const + { + return timer.elapsed(); + } + +private: + qint64 elapsedOfPause = -1; + qint64 invalidElapsed = 0; + + QElapsedTimer timer; +}; + +DFileCopyMoveJobPrivate::DFileCopyMoveJobPrivate(DFileCopyMoveJob *qq) + : q_ptr(qq) + , updateSpeedElapsedTimer(new ElapsedTimer()) +{ + m_pool.setMaxThreadCount(FileUtils::getCpuProcessCount()); +} + +DFileCopyMoveJobPrivate::~DFileCopyMoveJobPrivate() +{ + if (updateSpeedElapsedTimer) { + delete updateSpeedElapsedTimer; + updateSpeedElapsedTimer = nullptr; + } + if (fileStatistics) { + fileStatistics->stop(); + fileStatistics->deleteLater(); + fileStatistics = nullptr; + } + if (updateSpeedTimer) { + QMetaObject::invokeMethod(updateSpeedTimer, "stop"); + updateSpeedTimer->deleteLater(); + updateSpeedTimer = nullptr; + } + stopAllDeviceOperation(); +} + +QString DFileCopyMoveJobPrivate::errorToString(DFileCopyMoveJob::Error error) +{ + switch (error) { + case DFileCopyMoveJob::PermissionError: + return qApp->translate("DFileCopyMoveJob", "Permission error"); + case DFileCopyMoveJob::SpecialFileError: + return qApp->translate("DFileCopyMoveJob", "The action is denied"); + case DFileCopyMoveJob::FileExistsError: + return "Target file is exists"; + case DFileCopyMoveJob::DirectoryExistsError: + return "Target directory is exists"; + case DFileCopyMoveJob::OpenError: + return qApp->translate("DFileCopyMoveJob", "Failed to open the file"); + case DFileCopyMoveJob::ReadError: + return qApp->translate("DFileCopyMoveJob", "Failed to read the file"); + case DFileCopyMoveJob::WriteError: + return qApp->translate("DFileCopyMoveJob", "Failed to write the file"); + case DFileCopyMoveJob::MkdirError: + return qApp->translate("DFileCopyMoveJob", "Failed to create the directory"); + case DFileCopyMoveJob::RemoveError: + return qApp->translate("DFileCopyMoveJob", "Failed to delete the file"); + case DFileCopyMoveJob::RenameError: + return qApp->translate("DFileCopyMoveJob", "Failed to move the file"); + case DFileCopyMoveJob::NonexistenceError: + return qApp->translate("DFileCopyMoveJob", "Original file does not exist"); + case DFileCopyMoveJob::FileSizeTooBigError: + return qApp->translate("DFileCopyMoveJob", "Failed, file size must be less than 4GB"); + case DFileCopyMoveJob::NotEnoughSpaceError: + return qApp->translate("DFileCopyMoveJob", "Not enough free space on the target disk"); + case DFileCopyMoveJob::IntegrityCheckingError: + return qApp->translate("DFileCopyMoveJob", "File integrity was damaged"); + case DFileCopyMoveJob::TargetReadOnlyError: + return qApp->translate("DFileCopyMoveJob", "The target device is read only"); + case DFileCopyMoveJob::TargetIsSelfError: + return qApp->translate("DFileCopyMoveJob", "Target folder is inside the source folder"); + case DFileCopyMoveJob::NotSupportedError: + return qApp->translate("DFileCopyMoveJob", "The action is not supported"); + case DFileCopyMoveJob::PermissionDeniedError: + return qApp->translate("DFileCopyMoveJob", "You do not have permission to traverse files in it"); + case DFileCopyMoveJob::SeekError: + return qApp->translate("DFileCopyMoveJob", "Failed to position the file pointer!"); + default: + break; + } + + return QString(); +} + +qint64 DFileCopyMoveJobPrivate::getWriteBytes(long tid) +{ + QFile file(QStringLiteral("/proc/self/task/%1/io").arg(tid)); + + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "Failed on open the" << file.fileName() << ", will be not update the job speed and progress"; + + return 0; + } + + const QByteArray &line_head = QByteArrayLiteral("write_bytes: "); + const QByteArray &all_data = file.readAll(); + + file.close(); + + QTextStream text_stream(all_data); + + while (!text_stream.atEnd()) { + const QByteArray &line = text_stream.readLine().toLatin1(); + + if (line.startsWith(line_head)) { + bool ok = false; + qint64 size = line.mid(line_head.size()).toLongLong(&ok); + + if (!ok) { + qWarning() << "Failed to convert to qint64, line string=" << line; + + return 0; + } + +// qCDebug(fileJob(), "Did Write size on block device: %lld", size); + + return size; + } + } + + qWarning() << "Failed to find \"" << line_head << "\" from the" << file.fileName(); + + return 0; +} + +qint64 DFileCopyMoveJobPrivate::getWriteBytes() const +{ + return getWriteBytes(tid); +} + +qint64 DFileCopyMoveJobPrivate::getSectorsWritten() const +{ + const QByteArray data = fileReadAll(targetSysDevPath + "/stat"); + //fix: 删除文件时出现报错(回收箱和光驱处理删除文件),获取data为空指针 + if (data == nullptr) { + return 0; + } else { + return data.simplified().split(' ').value(6).toLongLong(); + } +} + +qint64 DFileCopyMoveJobPrivate::getCompletedDataSize() const +{ + if (canUseWriteBytes) { + return getWriteBytes(); + } + + if (targetDeviceStartSectorsWritten >= 0) { + if ((getSectorsWritten() == 0) && (targetDeviceStartSectorsWritten > 0)) { + return 0; + } else { + return (getSectorsWritten() - targetDeviceStartSectorsWritten) * targetLogSecionSize; + } + } + + return completedDataSize; +} + +void DFileCopyMoveJobPrivate::setState(DFileCopyMoveJob::State s) +{ + if (state == s) { + return; + } + + state = s; + + Q_Q(DFileCopyMoveJob); + + if (updateSpeedTimer->thread()->loopLevel() <= 0) { + qWarning() << "The thread of update speed timer no event loop" << updateSpeedTimer->thread(); + } + + if (s == DFileCopyMoveJob::RunningState) { + if (updateSpeedElapsedTimer->isRunning()) { + if (updateSpeedElapsedTimer->isPaused()) + updateSpeedElapsedTimer->togglePause(); + } else { + updateSpeedElapsedTimer->start(); + } + _q_updateProgress(); + QMetaObject::invokeMethod(updateSpeedTimer, "start", Q_ARG(int, 500)); + } else if (s == DFileCopyMoveJob::StoppedState) { + cansetnoerror = true; + } else if (s != DFileCopyMoveJob::IOWaitState) { + updateSpeedElapsedTimer->togglePause(); + + QMetaObject::invokeMethod(updateSpeedTimer, "stop"); + } + + Q_EMIT q->stateChanged(s); + + qCDebug(fileJob()) << "state changed, new state:" << s; +} + +void DFileCopyMoveJobPrivate::setError(DFileCopyMoveJob::Error e, const QString &es) +{ + if (DFileCopyMoveJob::CancelError <= error && error == e) { + return; + } + + if (DFileCopyMoveJob::CancelError < error && !cansetnoerror && DFileCopyMoveJob::StoppedState != state) { + QThread::msleep(10); + } + if (DFileCopyMoveJob::CancelError < e) { + cansetnoerror = false; + } else { + cansetnoerror = true; + } + + error = e; + errorString = es.isEmpty() ? errorToString(e) : es; + + Q_Q(DFileCopyMoveJob); + + if (actionOfError[error] == DFileCopyMoveJob::NoAction) { + Q_EMIT q->errorChanged(e); + } + if (DFileCopyMoveJob::CancelError < e) { + qCDebug(fileJob()) << "new error, type=" << e << ", message=" << es << QThread::currentThreadId(); + } +} + +void DFileCopyMoveJobPrivate::unsetError() +{ + setError(DFileCopyMoveJob::NoError); +} + +DFileCopyMoveJob::Action DFileCopyMoveJobPrivate::handleError(const DAbstractFileInfoPointer sourceInfo, + const DAbstractFileInfoPointer targetInfo) +{ + //当任务对话框结束返回cancel + auto lastErrorHandleAction = DFileCopyMoveJob::NoAction; + if (error == DFileCopyMoveJob::NoError) { + cansetnoerror = true; + emit q_ptr->errorCanClear(); + return lastErrorHandleAction; + } + if (m_bTaskDailogClose) { + return DFileCopyMoveJob::CancelAction; + } + if (actionOfError[error] != DFileCopyMoveJob::NoAction) { + lastErrorHandleAction = actionOfError[error]; + cansetnoerror = true; + unsetError(); + qCDebug(fileJob()) << "from actionOfError list," << "action:" << lastErrorHandleAction + << "source url:" << sourceInfo->fileUrl() + << "target url:" << (targetInfo ? targetInfo->fileUrl() : DUrl()); + + // not update speed onerror + if (updateSpeedTimer->isActive()) { + //updateSpeedTimer->stop(); +// QMetaObject::invokeMethod(updateSpeedTimer, "stop"); + } + updateProgress(); + + return lastErrorHandleAction; + } + + if (!handle) { + switch (error) { + case DFileCopyMoveJob::PermissionError: + case DFileCopyMoveJob::UnknowUrlError: + case DFileCopyMoveJob::TargetIsSelfError: + lastErrorHandleAction = DFileCopyMoveJob::SkipAction; + cansetnoerror = true; + emit q_ptr->errorCanClear(); + unsetError(); + break; + case DFileCopyMoveJob::FileExistsError: + case DFileCopyMoveJob::DirectoryExistsError: + lastErrorHandleAction = DFileCopyMoveJob::CoexistAction; + cansetnoerror = true; + emit q_ptr->errorCanClear(); + unsetError(); + break; + default: + lastErrorHandleAction = DFileCopyMoveJob::CancelAction; + cansetnoerror = true; + emit q_ptr->errorCanClear(); + setError(DFileCopyMoveJob::CancelError); + break; + } + + qCDebug(fileJob()) << "no handle," << "default action:" << lastErrorHandleAction + << "source url:" << (sourceInfo ? sourceInfo->fileUrl() : DUrl()) + << "target url:" << (targetInfo ? targetInfo->fileUrl() : DUrl()); + + return lastErrorHandleAction; + } + + setState(DFileCopyMoveJob::SleepState); + //暂停所有线程池的线程 + do { + + if (threadOfErrorHandle && threadOfErrorHandle->loopLevel() > 0) { + lastErrorHandleAction = DThreadUtil::runInThread(threadOfErrorHandle, handle, &DFileCopyMoveJob::Handle::handleError, + q_ptr, error, sourceInfo, targetInfo); + } else { + lastErrorHandleAction = handle->handleError(q_ptr, error, sourceInfo, targetInfo); + } + if (!stateCheck()) { + lastErrorHandleAction = DFileCopyMoveJob::CancelAction; + break; + } + } while (lastErrorHandleAction == DFileCopyMoveJob::NoAction); + emit q_ptr->errorCanClear(); + qCDebug(fileJob()) << "from user," << "action:" << lastErrorHandleAction; + cansetnoerror = true; + + if (state == DFileCopyMoveJob::SleepState) { + setState(DFileCopyMoveJob::RunningState); + } + + unsetError(); + + if (lastErrorHandleAction == DFileCopyMoveJob::CancelAction) { + setError(DFileCopyMoveJob::CancelError); + } + + qCDebug(fileJob()) << "from user," << "action:" << lastErrorHandleAction + << "source url:" << (sourceInfo ? sourceInfo->fileUrl() : DUrl()) + << "target url:" << (targetInfo ? targetInfo->fileUrl() : DUrl()); + + return lastErrorHandleAction; +} + +DFileCopyMoveJob::Action DFileCopyMoveJobPrivate::setAndhandleError(DFileCopyMoveJob::Error e, + const DAbstractFileInfoPointer sourceInfo, + const DAbstractFileInfoPointer targetInfo, + const QString &es) +{ + if (!stateCheck()) { + setLastErrorAction(DFileCopyMoveJob::CancelAction); + return DFileCopyMoveJob::CancelAction; + } + if ((DFileCopyMoveJob::FileExistsError == e || DFileCopyMoveJob::DirectoryExistsError == e) + && (sourceInfo->fileUrl() == targetInfo->fileUrl() || DStorageInfo::isSameFile(sourceInfo->fileUrl().path(), targetInfo->fileUrl().path()))) { + setLastErrorAction(DFileCopyMoveJob::CoexistAction); + return DFileCopyMoveJob::CoexistAction; + } + setError(e, es); + if (DFileCopyMoveJob::NoError == e) { + setLastErrorAction(DFileCopyMoveJob::NoAction); + return DFileCopyMoveJob::NoAction; + } + if (DFileCopyMoveJob::CancelError == e) { + setLastErrorAction(DFileCopyMoveJob::CancelAction); + return DFileCopyMoveJob::CancelAction; + } + auto action = handleError(sourceInfo, targetInfo); + setLastErrorAction(action); + return action; +} + +#define TASK_RUNNING_MAX_COUNT 5 + +bool DFileCopyMoveJobPrivate::isRunning() +{ + return (this->state == DFileCopyMoveJob::RunningState);//&& (m_taskRunningCount <= TASK_RUNNING_MAX_COUNT ) ; +} + +bool DFileCopyMoveJobPrivate::jobWait() +{ + QMutex lock; + + lock.lock(); + waitCondition.wait(&lock); + lock.unlock(); + + return state == DFileCopyMoveJob::RunningState; +} + +bool DFileCopyMoveJobPrivate::stateCheck() +{ + Q_Q(DFileCopyMoveJob); + if (state == DFileCopyMoveJob::RunningState) { + if (needUpdateProgress) { + needUpdateProgress = false; + + updateProgress(); + updateSpeed(); + } + + return true; + } + + if (state == DFileCopyMoveJob::PausedState) { + qInfo() << "Will be suspended"; + Q_EMIT q->stateChanged(DFileCopyMoveJob::PausedState); + if (!jobWait()) { + QMutexLocker lk(&m_checkStatMutex); + qInfo() << "Will be abort = " << (state != DFileCopyMoveJob::StoppedState); + + return state != DFileCopyMoveJob::StoppedState; + } + } else if (state == DFileCopyMoveJob::StoppedState) { + QMutexLocker lk(&m_checkStatMutex); + cansetnoerror = true; + setError(DFileCopyMoveJob::CancelError); + qCDebug(fileJob()) << "Will be abort"; + + //! re-calculate vault size. + bool isVaultFile = VaultController::isVaultFile(targetUrl.toLocalFile()); + DUrlList::iterator it = sourceUrlList.begin(); + while (!isVaultFile && it != sourceUrlList.end()) { + isVaultFile = VaultController::isVaultFile(it->toLocalFile()); + it++; + } + if (isVaultFile) { + QMetaObject::invokeMethod(VaultController::ins(), "refreshTotalSize", Qt::QueuedConnection); + } + + return false; + } + + return true; +} + +bool DFileCopyMoveJobPrivate::checkFileSize(qint64 size) const +{ + if (directoryStack.count() <= 0) { + return true; + } + const DStorageInfo &targetStorageInfo = directoryStack.top().targetStorageInfo; + + if (!targetStorageInfo.isValid()) { + return true; + } + + const QString &fs_type = targetStorageInfo.fileSystemType(); + + // for vfat file system + if (fs_type == "vfat") { + // 4GB + if (size >= 4l * 1024 * 1024 * 1024) { + return false; + } + } + + return true; +} + +bool DFileCopyMoveJobPrivate::checkFreeSpace(qint64 needSize) +{ + if (directoryStack.isEmpty()) { + qWarning() << "directoryStack.isEmpty() return true"; + return true; + } + DStorageInfo &targetStorageInfo = directoryStack.top().targetStorageInfo; + + if (!targetStorageInfo.isValid()) { + return true; + } + + targetStorageInfo.refresh(); + + // invalid size info + if (targetStorageInfo.bytesTotal() <= 0) { + return true; + } + + //fix:修正文件发送到光盘时会报磁盘空间不足的问题,这里实现分类处理(常规可挂载移动存储设备和光驱设备) + const QString &fs_type = targetStorageInfo.fileSystemType(); + + if (fs_type == "iso9660") { + return true; + } else { + return targetStorageInfo.bytesAvailable() >= needSize; + } +} + +QString DFileCopyMoveJobPrivate::formatFileName(const QString &name) const +{ + if (fileHints.testFlag(DFileCopyMoveJob::DontFormatFileName)) { + return name; + } + if (directoryStack.count() <= 0) { + return name; + } + const DStorageInfo &targetStorageInfo = directoryStack.top().targetStorageInfo; + + if (!targetStorageInfo.isValid()) { + return name; + } + + const QString &fs_type = targetStorageInfo.fileSystemType(); + + if (fs_type == "vfat") { + QString new_name = name; + + return new_name.replace(QRegExp("[\"*:<>?\\|]"), "_"); + } + + return name; +} + +QString DFileCopyMoveJobPrivate::getNewFileName(const DAbstractFileInfoPointer sourceFileInfo, const DAbstractFileInfoPointer targetDirectory) +{ + const QString ©_text = QCoreApplication::translate("DFileCopyMoveJob", "copy", + "Extra name added to new file name when used for file name."); + + DAbstractFileInfoPointer target_file_info; + QString file_base_name = sourceFileInfo->baseName(); + QString suffix = sourceFileInfo->suffix(); + QString filename = sourceFileInfo->fileName(); + //在7z分卷压缩后的名称特殊处理7z.003 + if (filename.contains(QRegularExpression(".7z.[0-9]{3,10}$"))) { + file_base_name = filename.left(filename.indexOf(QRegularExpression(".7z.[0-9]{3,10}$"))); + suffix = filename.mid(filename.indexOf(QRegularExpression(".7z.[0-9]{3,10}$")) + 1); + } + + int number = 0; + + QString new_file_name; + + do { + new_file_name = number > 0 ? QString("%1(%2 %3)").arg(file_base_name, copy_text).arg(number) : QString("%1(%2)").arg(file_base_name, copy_text); + + if (!suffix.isEmpty()) { + new_file_name.append('.').append(suffix); + } + + ++number; + target_file_info = DFileService::instance()->createFileInfo(nullptr, targetDirectory->getUrlByChildFileName(new_file_name), false); + } while (target_file_info->exists()); + + return new_file_name; +} + +bool DFileCopyMoveJobPrivate::doProcess(const DUrl &from, const DAbstractFileInfoPointer source_info, const DAbstractFileInfoPointer target_info, const bool isNew) +{ +// Q_Q(DFileCopyMoveJob); + bool isErrorOccur = false; + + if (!source_info) { + //错误队列处理 + errorQueueHandling(); + bool ok = setAndhandleError(DFileCopyMoveJob::UnknowUrlError, source_info, DAbstractFileInfoPointer(nullptr), + QObject::tr("Failed to create file info")) == DFileCopyMoveJob::SkipAction; + //当前错误处理完成 + errorQueueHandled(ok); + return ok; + } + + if (!source_info->exists()) { + DFileCopyMoveJob::Error errortype = (source_info->path().startsWith("/root/") && !target_info->path().startsWith("/root/")) ? + DFileCopyMoveJob::PermissionError : DFileCopyMoveJob::NonexistenceError; + errortype = source_info->path().startsWith(MOBILE_ROOT_PATH) ? DFileCopyMoveJob::NotSupportedError : errortype; + //错误队列处理 + errorQueueHandling(); + bool ok = setAndhandleError(errortype, source_info, + DAbstractFileInfoPointer(nullptr)) == DFileCopyMoveJob::SkipAction; + //当前错误处理完成 + errorQueueHandled(ok); + return ok; + } + + switch (source_info->fileType()) { + case DAbstractFileInfo::CharDevice: + case DAbstractFileInfo::BlockDevice: + case DAbstractFileInfo::FIFOFile: + case DAbstractFileInfo::SocketFile: { + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + bool ok = setAndhandleError(DFileCopyMoveJob::SpecialFileError, source_info, + DAbstractFileInfoPointer(nullptr)) == DFileCopyMoveJob::SkipAction; + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(ok); + isErrorOccur = false; + } + if (ok) { + //跳过文件大小统计 + if (source_info->isSymLink()) { + skipFileSize += FileUtils::getMemoryPageSize(); + } else if (source_info->isDir()) { + skipFileSize += m_currentDirSize <= 0 ? FileUtils::getMemoryPageSize() : m_currentDirSize; + } else { + skipFileSize += source_info->size() <= 0 ? FileUtils::getMemoryPageSize() : source_info->size(); + } + } + return ok; + } + default: + break; + } + + QSharedPointer handler(DFileService::instance()->createFileHandler(nullptr, from)); + + if (!handler) { + //错误队列处理 + errorQueueHandling(); + bool ok = setAndhandleError(DFileCopyMoveJob::UnknowUrlError, source_info, + DAbstractFileInfoPointer(nullptr), QObject::tr("Failed to create file handler")) == DFileCopyMoveJob::SkipAction; + //当前错误处理完成 + errorQueueHandled(ok); + if (ok) { + //跳过文件大小统计 + if (source_info->isSymLink()) { + skipFileSize += FileUtils::getMemoryPageSize(); + } else if (source_info->isDir()) { + skipFileSize += m_currentDirSize <= 0 ? FileUtils::getMemoryPageSize() : m_currentDirSize; + } else { + skipFileSize += source_info->size() <= 0 ? FileUtils::getMemoryPageSize() : source_info->size(); + } + } + return ok; + } + + // only remove + if (!target_info) { + auto fileInfo = source_info; + if (source_info->fileUrl().parentUrl() == DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))) + convertTrashFile(fileInfo); + + // BUG 59250 回收站文件夹下删除子文件会受到上级目录的权限管控 + DUrl parentUrl; + QFile::Permissions parentUrlPermissions; + // 权限更改标识 + bool permissionChangedFlag = false; + + // 确定当前是从回收站强制删除且没有写权限(trashRemoveFlag 流控只针对回收站) + if (fileHints.testFlag(DFileCopyMoveJob::ForceDeleteFile) + && fileInfo->path().contains("/.local/share/Trash")) { + // 获取上级目录路径,获取缓存权限,判断当前是否进行权限更改 + parentUrl = fileInfo->fileUrl().parentUrl(); + + //获取上层目录的Info对象 + DAbstractFileInfoPointer parentInfo = DFileService::instance()->createFileInfo(nullptr, parentUrl, false); + if (parentInfo) { + parentUrlPermissions = parentInfo->permissions(); + } else { + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + bool ok = setAndhandleError(DFileCopyMoveJob::UnknowUrlError, + parentInfo,DAbstractFileInfoPointer(nullptr), + QObject::tr("Failed to create file info")) == DFileCopyMoveJob::SkipAction; + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(ok); + isErrorOccur = false; + } + return ok; + } + + //没有写权限则不可操作子目录 + permissionChangedFlag = !parentUrlPermissions.testFlag(QFileDevice::WriteUser); + // 触发当前权限更改可写入的流程操作 + if (permissionChangedFlag) { + // 设置上级目录加入当前用户可写 + handler->setPermissions(parentUrl, parentUrlPermissions | QFileDevice::WriteUser); + } + } + + + bool ok = false; + //可以显示进度条 + m_isNeedShowProgress = true; + qint64 size = fileInfo->isSymLink() ? 0 : fileInfo->size(); + + if (fileInfo->isFile() || fileInfo->isSymLink()) { + ok = removeFile(handler, fileInfo); + if (ok) { + joinToCompletedFileList(from, DUrl(), size); + } + } else { + // 删除文件夹时先设置其权限 + if (fileHints.testFlag(DFileCopyMoveJob::ForceDeleteFile)) { + handler->setPermissions(fileInfo->fileUrl(), QFileDevice::ReadUser | QFileDevice::WriteUser | QFileDevice::ExeUser); + } + + ok = mergeDirectory(handler, fileInfo, DAbstractFileInfoPointer(nullptr)); + if (ok) { + joinToCompletedDirectoryList(from, DUrl(), size); + } + } + + //上级目录权限回设 + if (permissionChangedFlag) { + handler->setPermissions(parentUrl,parentUrlPermissions); + } + + return ok; + } + + QString file_name; + //! 是否退回到回收站 + if (m_fileNameList.isEmpty()) { + file_name = isNew ? source_info->fileName() : + (handle ? handle->getNewFileName(q_ptr, source_info) : source_info->fileName()); + } else { + file_name = m_fileNameList.dequeue().split('/').last(); + } + + // 回收站可能重名文件,因此回收站中的文件实际filename是经过处理的,这里需要取真正需要展示的filename + if (source_info->filePath().startsWith(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath))) { + QExplicitlySharedDataPointer info(new TrashFileInfo(DUrl::fromTrashFile("/" + source_info->fileName()))); + + // fix bug45213 从回收站复制/剪切2个计算机图标到桌面,计算机图标变成普通文件 + QFileInfo actual_info(info->sourceFilePath()); + if (!actual_info.isSymLink() && FileUtils::isDesktopFile(actual_info)) { + //目标文件是桌面程序文件时,需要使用原名字作为文件名来创建文件(createFileInfo),否则将导致新创建的文件不是桌面程序文件 + file_name = actual_info.fileName(); + } else { + file_name = info->fileDisplayName(); + } + } +create_new_file_info: + const DAbstractFileInfoPointer &new_file_info = DFileService::instance()->createFileInfo(nullptr, target_info->getUrlByChildFileName(file_name), false); + + if (!new_file_info) { + qWarning() << "fileinfo create failed!" << target_info->getUrlByChildFileName(file_name); + return false; + } + + if (new_file_info->exists()) { + //忽略DStorageInfo::isSameFile判断链接文件的结果 + if ((mode == DFileCopyMoveJob::MoveMode || mode == DFileCopyMoveJob::CutMode) && + (new_file_info->fileUrl() == from || (DStorageInfo::isSameFile(from.path(), new_file_info->fileUrl().path()) && !new_file_info->isSymLink()))) { + // 不用再进行后面的操作 + //跳过文件大小统计 + if (source_info->isSymLink()) { + skipFileSize += FileUtils::getMemoryPageSize(); + } else if (source_info->isDir()) { + skipFileSize += m_currentDirSize <= 0 ? FileUtils::getMemoryPageSize() : m_currentDirSize; + } else { + skipFileSize += source_info->size() <= 0 ? FileUtils::getMemoryPageSize() : source_info->size(); + } + return true; + } + //可以显示进度条 + m_isNeedShowProgress = true; + + // 禁止目录复制/移动到自己里面 + if (new_file_info->isAncestorsUrl(source_info->fileUrl())) { + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + DFileCopyMoveJob::Action action = setAndhandleError(DFileCopyMoveJob::TargetIsSelfError, + source_info, new_file_info); + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::EnforceAction); + isErrorOccur = false; + } + if (action == DFileCopyMoveJob::SkipAction) { + //跳过文件大小统计 + if (source_info->isSymLink()) { + skipFileSize += FileUtils::getMemoryPageSize(); + } else if (source_info->isDir()) { + skipFileSize += m_currentDirSize <= 0 ? FileUtils::getMemoryPageSize() : m_currentDirSize; + } else { + skipFileSize += source_info->size() <= 0 ? FileUtils::getMemoryPageSize() : source_info->size(); + } + return true; + } + + if (action != DFileCopyMoveJob::EnforceAction) { + return false; + } + } + + bool source_is_file = source_info->isFile() || source_info->isSymLink(); + bool target_is_file = new_file_info->isFile() || new_file_info->isSymLink(); + //如果目标目录有相同名称的文件,但是拷贝的是目录,或者相反,就直接创建一个新的名称 + if (source_is_file != target_is_file) { + file_name = handle ? handle->getNonExistsFileName(source_info, target_info) + : getNewFileName(source_info, target_info); + goto create_new_file_info; + } + DFileCopyMoveJob::Error errortype = target_is_file ? + DFileCopyMoveJob::FileExistsError : DFileCopyMoveJob::DirectoryExistsError; + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + switch (setAndhandleError(errortype, source_info, new_file_info)) { + case DFileCopyMoveJob::ReplaceAction: + if (new_file_info->fileUrl() == from) { + // 不用再进行后面的操作 + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + return true; + } + + if (source_is_file && source_is_file == target_is_file) { + break; + } else { + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(false); + isErrorOccur = false; + } + return false; + } + case DFileCopyMoveJob::MergeAction: + if (!source_is_file && source_is_file == target_is_file) { + break; + } else { + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(false); + isErrorOccur = false; + } + return false; + } + case DFileCopyMoveJob::SkipAction: + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + //跳过文件大小统计 + if (source_info->isSymLink()) { + skipFileSize += FileUtils::getMemoryPageSize(); + } else if (source_info->isDir()) { + skipFileSize += m_currentDirSize <= 0 ? FileUtils::getMemoryPageSize() : m_currentDirSize; + } else { + skipFileSize += source_info->size() <= 0 ? FileUtils::getMemoryPageSize() : source_info->size(); + } + return true; + case DFileCopyMoveJob::CoexistAction: + // fix bug 62226 + // 回收站的同名文件是以uuid形式存在的,如果这里使用source_info去构建副本的话,就会造成 + // file_name的值为uuid(副本)的情况,因此修改为new_file_info,getNonExistsFileName + // 接口中只会使用到new_file_info的filename相关属性,因此对非回收站的文件也不会存在影响 + file_name = handle ? handle->getNonExistsFileName(new_file_info, target_info) + : getNewFileName(new_file_info, target_info); + goto create_new_file_info; + default: + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(false); + isErrorOccur = false; + } + return false; + } + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + } + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + + m_isNeedShowProgress = true; + + if (source_info->isSymLink()) { + bool ok = false; + + if (mode == DFileCopyMoveJob::CopyMode) { + DAbstractFileInfoPointer new_source_info = source_info; + if (fileHints.testFlag(DFileCopyMoveJob::FollowSymlink)) { + do { + const DAbstractFileInfoPointer &symlink_target = DFileService::instance()->createFileInfo(nullptr, source_info->symLinkTarget(), false); + + if (!symlink_target->exists()) { + break; + } + + new_source_info = symlink_target; + } while (new_source_info->isSymLink()); + + if (new_source_info->exists()) { + goto process_file; + } + } + + ok = linkFile(handler, new_file_info, new_source_info->symlinkTargetPath()); + } else { + ok = renameFile(handler, source_info, new_file_info); + } + + if (ok) { + joinToCompletedFileList(from, new_file_info->fileUrl(), 0); + } + + countrefinesize(FileUtils::getMemoryPageSize()); + + return ok; + } + +process_file: + if (source_info->isFile()) { + bool ok = false; + qint64 size = source_info->size(); + + while (!checkFreeSpace(size)) { + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + DFileCopyMoveJob::Action action = setAndhandleError(DFileCopyMoveJob::NotEnoughSpaceError, + source_info, new_file_info); + if (action == DFileCopyMoveJob::RetryAction) { + continue; + } + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::EnforceAction); + isErrorOccur = false; + } + if (action == DFileCopyMoveJob::SkipAction) { + //跳过文件大小统计 + if (source_info->isSymLink()) { + skipFileSize += FileUtils::getMemoryPageSize(); + } else if (source_info->isDir()) { + skipFileSize += m_currentDirSize <= 0 ? FileUtils::getMemoryPageSize() : m_currentDirSize; + } else { + skipFileSize += source_info->size() <= 0 ? FileUtils::getMemoryPageSize() : source_info->size(); + } + return true; + } + + if (action == DFileCopyMoveJob::EnforceAction) { + break; + } + + return false; + } + + if (!checkFileSize(size)) { + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + DFileCopyMoveJob::Action action = setAndhandleError(DFileCopyMoveJob::FileSizeTooBigError, + source_info, new_file_info); + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::EnforceAction); + isErrorOccur = false; + } + if (action == DFileCopyMoveJob::SkipAction) { + //跳过文件大小统计 + if (source_info->isSymLink()) { + skipFileSize += FileUtils::getMemoryPageSize(); + } else if (source_info->isDir()) { + skipFileSize += m_currentDirSize <= 0 ? FileUtils::getMemoryPageSize() : m_currentDirSize; + } else { + skipFileSize += source_info->size() <= 0 ? FileUtils::getMemoryPageSize() : source_info->size(); + } + return true; + } + + if (action != DFileCopyMoveJob::EnforceAction) { + return false; + } + } + + if (mode == DFileCopyMoveJob::CopyMode) { + if (new_file_info->isSymLink() || fileHints.testFlag(DFileCopyMoveJob::RemoveDestination)) { + if (!removeFile(handler, new_file_info)) { + return false; + } + } else if (new_file_info->exists()) { + // 复制文件时,如果需要覆盖,必须添加可写入权限 + handler->setPermissions(new_file_info->fileUrl(), QFileDevice::WriteUser | QFileDevice::ReadUser); + } + + ok = copyFile(source_info, new_file_info, handler); + } else { + // 光盘中的文件不能进行写操作,因此复制它 + const QString &sourcePath = source_info->fileUrl().toLocalFile(); + if (deviceListener->isFileFromDisc(sourcePath)) { + qInfo() << "canRename : " << source_info->canRename(); + ok = copyFile(source_info, new_file_info, handler); + } else { + ok = renameFile(handler, source_info, new_file_info); + } + } + + if (ok) { + joinToCompletedFileList(from, new_file_info->fileUrl(), size); + } + + return ok; + } else if (source_info->isDir()) { + // 禁止目录复制/移动到自己里面 + // fix bug 99308,转换网络smb挂载到本地路径,在判断是否目录复制/移动到自己里面 + bool isNewGvfsMountFile = new_file_info->isGvfsMountFile(); + bool isSourceGvfsMountFile = source_info->isGvfsMountFile(); + bool isAncestorsUrl = false; + if ((isNewGvfsMountFile && !isSourceGvfsMountFile) || + (!isNewGvfsMountFile && isSourceGvfsMountFile)) { + isAncestorsUrl = FileUtils::isNetworkAncestorUrl(new_file_info->fileUrl(), isNewGvfsMountFile, + source_info->fileUrl(), isSourceGvfsMountFile); + } + // 禁止目录复制/移动到自己里面 + if (new_file_info->isAncestorsUrl(source_info->fileUrl()) || isAncestorsUrl) { + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + DFileCopyMoveJob::Action action = setAndhandleError(DFileCopyMoveJob::TargetIsSelfError, + source_info, new_file_info); + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::EnforceAction); + isErrorOccur = false; + } + if (action == DFileCopyMoveJob::SkipAction) { + skipFileSize += m_currentDirSize <= 0 ? FileUtils::getMemoryPageSize() : m_currentDirSize; + return true; + } + + if (action != DFileCopyMoveJob::EnforceAction) { + return false; + } + } + + bool ok = true; + qint64 size = source_info->size(); + const QDateTime si_last_read = source_info->lastRead(); + const QDateTime si_last_modified = source_info->lastModified(); + + if (mode == DFileCopyMoveJob::CopyMode) { + ok = mergeDirectory(handler, source_info, new_file_info); + } else if (!handler->rename(source_info->fileUrl(), new_file_info->fileUrl())) { // 尝试直接rename操作 + qCDebug(fileJob(), "Failed on rename, Well be copy and delete the directory"); + ok = mergeDirectory(handler, source_info, new_file_info); + } + + if (ok) { + handler->setFileTime(new_file_info->fileUrl(), si_last_read, si_last_modified); + joinToCompletedDirectoryList(from, new_file_info->fileUrl(), size); + } + + return ok; + } + + return false; +} + +bool DFileCopyMoveJobPrivate::mergeDirectory(const QSharedPointer &handler, const DAbstractFileInfoPointer fromInfo, const DAbstractFileInfoPointer toInfo) +{ + bool isNew = false; + bool isErrorOccur = false; + if (toInfo && !toInfo->exists()) { + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + + do { + // 当为保险箱路径时,判断目录名的长度,如果长度大于85,则不让其创建成功,并报错“文件名过长” + QString strPath = toInfo->fileUrl().toString(); + if (VaultController::isVaultFile(strPath)) { + // 获得目录名 + QString strDirName = strPath.section("/", -1, -1); + if (strDirName.toUtf8().length() > 255) { + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(DFileCopyMoveJob::MkdirError, fromInfo, toInfo, + qApp->translate("DFileCopyMoveJob", "Failed to open the directory, cause: file name too long")); + break; + } + } + + if (!handler->mkdir(toInfo->fileUrl())) { + const DAbstractFileInfoPointer &parent_info = DFileService::instance()->createFileInfo(nullptr, toInfo->parentUrl(), false); + DFileCopyMoveJob::Error errortype = (!parent_info->exists() || parent_info->isWritable()) ? + DFileCopyMoveJob::MkdirError : DFileCopyMoveJob::PermissionError; + QString errorstr = (!parent_info->exists() || parent_info->isWritable()) ? + qApp->translate("DFileCopyMoveJob", "Failed to create the directory, cause: %1").arg(handler->errorString()) : QString(); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(errortype, fromInfo, toInfo, errorstr); + } + isNew = true; + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + isErrorOccur = false; + } + if (action != DFileCopyMoveJob::NoAction) { + if (action == DFileCopyMoveJob::SkipAction) + skipFileSize += m_currentDirSize <= 0 ? FileUtils::getMemoryPageSize() : m_currentDirSize; + return action == DFileCopyMoveJob::SkipAction; + } + } + + if (toInfo && fromInfo->filesCount() <= 0 && mode == DFileCopyMoveJob::CopyMode) { + QFileDevice::Permissions permissions = fromInfo->permissions(); + QString filePath = fromInfo->fileUrl().toLocalFile(); + if (VaultController::ins()->isVaultFile(filePath)) { + permissions = VaultController::ins()->getPermissions(filePath); + } else if (deviceListener->isFileFromDisc(fromInfo->path())) { + permissions |= MasteredMediaController::getPermissionsCopyToLocal(); + } + + //权限为0000时,源文件已经被删除,无需修改新建的文件的权限为0000 + if (permissions != 0000) + handler->setPermissions(toInfo->fileUrl(), permissions); + return true; + } + + bool sortInode = toInfo && !fileHints.testFlag(DFileCopyMoveJob::DontSortInode); + const DDirIteratorPointer &iterator = DFileService::instance()->createDirIterator(nullptr, fromInfo->fileUrl(), QStringList(), + QDir::AllEntries | QDir::NoDotAndDotDot | QDir::System | QDir::Hidden, + sortInode ? static_cast(DDirIterator::SortINode) + : QDirIterator::NoIteratorFlags, true); + + if (!iterator) { + setError(DFileCopyMoveJob::UnknowUrlError, "Failed on create dir iterator"); + return false; + } + + bool existsSkipFile = false; + bool enter_dir = toInfo; + + if (enter_dir) { + enterDirectory(fromInfo->fileUrl(), toInfo->fileUrl()); + } + + //目录没有执行权限时不能正确的遍历到子文件的信息,后续删除或剪切复制逻辑无法成立 + //弹出错误弹窗,提示无权限 + if (!fromInfo->isExecutable() && iterator->hasNext()) { + //错误队列处理 + errorQueueHandling(); + bool ok = setAndhandleError(DFileCopyMoveJob::PermissionDeniedError, fromInfo, DAbstractFileInfoPointer(nullptr)) == DFileCopyMoveJob::SkipAction; + //当前错误处理完成 + errorQueueHandled(ok); + return ok; + } + + while (iterator->hasNext()) { + if (!stateCheck()) { + return false; + } + + const DUrl &url = iterator->next(); + const DAbstractFileInfoPointer &info = iterator->fileInfo(); + + if (!process(url, info, toInfo, isNew)) { + return false; + } + + if (getLastErrorAction() == DFileCopyMoveJob::SkipAction) { + existsSkipFile = true; + } + } + + if (enter_dir) { + leaveDirectory(); + } + + if (toInfo) { + // vault file fetch permissons separately. + QFileDevice::Permissions permissions = fromInfo->permissions(); + QString filePath = fromInfo->fileUrl().toLocalFile(); + if (VaultController::ins()->isVaultFile(filePath)) { + permissions = VaultController::ins()->getPermissions(filePath); + } else if (deviceListener->isFileFromDisc(fromInfo->path())) { + permissions |= MasteredMediaController::getPermissionsCopyToLocal(); + } + // 修复bug-59124 + // 权限为0000时,源文件已经被删除,无需修改新建的文件的权限为0000 + if (permissions != 0000) { + if (m_refineStat == DFileCopyMoveJob::RefineBlock) { + FileCopyInfoPointer copyinfo(new FileCopyInfo()); + copyinfo->isdir = true; + copyinfo->permission = permissions; + copyinfo->handler = handler; + copyinfo->toinfo = toInfo; + copyinfo->frominfo = fromInfo; + writeQueueEnqueue(copyinfo); + } else if (m_refineStat == DFileCopyMoveJob::RefineLocal) { + QSharedPointer dirinfo(new DirSetPermissonInfo); + dirinfo->handler = handler; + dirinfo->target = toInfo->fileUrl(); + dirinfo->permission = permissions; + m_dirPermissonList.push_front(dirinfo); + } else { + handler->setPermissions(toInfo->fileUrl(), permissions); + } + } + } + + if (mode == DFileCopyMoveJob::CopyMode) { + return true; + } + + if (existsSkipFile) { + return true; + } + + // 光盘中的目录不能被删除 + if (!fromInfo->canRename() || deviceListener->isFileFromDisc(fromInfo->fileUrl().toLocalFile())) { + qInfo() << "canReaname : " << fromInfo->canRename(); + return true; + } + // 完成操作后删除原目录 + return removeFile(handler, fromInfo); +} + +bool DFileCopyMoveJobPrivate::doCopyFile(const DAbstractFileInfoPointer fromInfo, const DAbstractFileInfoPointer toInfo, const QSharedPointer &handler, int blockSize) +{ + //多线程拷贝时发送当前拷贝信息 + if (m_refineStat != DFileCopyMoveJob::NoRefine){ + sendCopyInfo(fromInfo, toInfo); + } + //预先读取 + readAheadSourceFile(fromInfo); + + QSharedPointer fromDevice = nullptr; + if (fromInfo->isGvfsMountFile()) { + fromDevice.reset(new DGIOFileDevice(fromInfo->fileUrl())); + } else { + DLocalFileDevice *localDevice = new DLocalFileDevice(); + localDevice->setFileUrl(fromInfo->fileUrl()); + fromDevice.reset(localDevice); + } + + if (!fromDevice) + return handleUnknowUrlError(fromInfo, toInfo); + + QSharedPointer toDevice = nullptr; + if (toInfo->exists() && !toInfo->isGvfsMountFile()) { + DLocalFileDevice *localDevice = new DLocalFileDevice(); + localDevice->setFileUrl(toInfo->fileUrl()); + toDevice.reset(localDevice); + } else { + toDevice.reset(new DGIOFileDevice(toInfo->fileUrl())); + } + + if (!toDevice) + return handleUnknowUrlError(fromInfo, toInfo); + + bool isErrorOccur = false; +open_file: { + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + + do { + // 如果打开文件在保险箱内 + QString strPath = toInfo->fileUrl().toString(); + if (VaultController::isVaultFile(strPath)) { + QString strFileName = strPath.section("/", -1, -1); + if (strFileName.toUtf8().length() > 255) { + qCDebug(fileJob()) << "open error:" << fromInfo->fileUrl(); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(DFileCopyMoveJob::OpenError, fromInfo, toInfo, + qApp->translate("DFileCopyMoveJob", "Failed to open the file, cause: file name too long")); + break; + } + } + + if (fromDevice->open(QIODevice::ReadOnly)) { + action = DFileCopyMoveJob::NoAction; + } else { + qCDebug(fileJob()) << "open error:" << fromInfo->fileUrl(); + DFileCopyMoveJob::Error errortype = fromInfo->isReadable() ? DFileCopyMoveJob::OpenError : + DFileCopyMoveJob::PermissionError; + QString errorstr = fromInfo->isReadable() ? + qApp->translate("DFileCopyMoveJob", "Failed to open the file, cause: %1").arg(fromDevice->errorString()) : + QString(); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(errortype, fromInfo, toInfo, errorstr); + } + //防止卡死 + if (action == DFileCopyMoveJob::RetryAction) { + QThread::msleep(THREAD_SLEEP_TIME); + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); // bug: 26333, while set the stop status shoule break the process! + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + isErrorOccur = false; + } + + if (action == DFileCopyMoveJob::SkipAction) { + return true; + } else if (action != DFileCopyMoveJob::NoAction) { + return false; + } + + do { + if (toDevice->open(QIODevice::WriteOnly | QIODevice::Truncate)) { + action = DFileCopyMoveJob::NoAction; + } else { + qCDebug(fileJob()) << "open error:" << toInfo->fileUrl() << QThread::currentThreadId(); + DFileCopyMoveJob::Error errortype = (!toInfo->exists() || toInfo->isWritable()) ? DFileCopyMoveJob::OpenError : + DFileCopyMoveJob::PermissionError; + // task-36496 "Permission denied"没有被翻译 翻译为“没有权限” + QString errorstr(""); + if ("Permission denied" == toDevice->errorString()) { + errorstr = (!toInfo->exists() || toInfo->isWritable()) ? + qApp->translate("DFileCopyMoveJob", "Failed to open the file, cause: Permission denied") : + QString(); + } else { + errorstr = (!toInfo->exists() || toInfo->isWritable()) ? + qApp->translate("DFileCopyMoveJob", "Failed to open the file, cause: %1").arg(toDevice->errorString()) : + QString(); + } + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(errortype, fromInfo, toInfo, errorstr); + if (action == DFileCopyMoveJob::RetryAction) { + QThread::msleep(THREAD_SLEEP_TIME); + } + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + isErrorOccur = false; + } + if (action == DFileCopyMoveJob::SkipAction) { + return true; + } else if (action != DFileCopyMoveJob::NoAction) { + return false; + } + + if (fileHints.testFlag(DFileCopyMoveJob::ResizeDestinationFile)) { + do { + if (toDevice->resize(fromInfo->size())) { + action = DFileCopyMoveJob::NoAction; + } else { + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(DFileCopyMoveJob::ResizeError, fromInfo, toInfo, toDevice->errorString()); + } + //防止卡死 + if (action == DFileCopyMoveJob::RetryAction) { + QThread::msleep(THREAD_SLEEP_TIME); + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + isErrorOccur = false; + } + if (action == DFileCopyMoveJob::SkipAction) { + fromDevice->close(); + toDevice->close(); + return true; + } else if (action != DFileCopyMoveJob::NoAction) { + fromDevice->close(); + toDevice->close(); + return false; + } + } + } + +#ifdef Q_OS_LINUX + // 开启读取优化,告诉内核,我们将顺序读取此文件 + + if (fromDevice->handle() > 0) { + posix_fadvise(fromDevice->handle(), 0, 0, POSIX_FADV_SEQUENTIAL); + } + + if (toDevice->handle() > 0) { + posix_fadvise(toDevice->handle(), 0, 0, POSIX_FADV_SEQUENTIAL); + } +#endif + + currentJobDataSizeInfo.first = fromInfo->size(); + currentJobFileHandle = toDevice->handle(); + uLong source_checksum = adler32(0L, nullptr, 0); + DGIOFileDevice *fromgio = qobject_cast(fromDevice.data()); + DGIOFileDevice *togio = qobject_cast(toDevice.data()); + if (fromgio) { + saveCurrentDevice(fromInfo->fileUrl(),fromDevice); + } + if (togio) { + saveCurrentDevice(toInfo->fileUrl(),toDevice); + } + + qint64 block_Size = fromInfo->size() > MAX_BUFFER_LEN ? MAX_BUFFER_LEN : fromInfo->size(); + + char *data = new char[block_Size + 1]; + + Q_FOREVER { + qint64 current_pos = fromDevice->pos(); + read_data: + if (Q_UNLIKELY(!stateCheck())) { + cleanDoCopyFileSource(data, fromInfo, toInfo, fromDevice, toDevice); + return false; + } + + qint64 size_read = fromDevice->read(data, block_Size); + if (Q_UNLIKELY(!stateCheck())) { + cleanDoCopyFileSource(data, fromInfo, toInfo, fromDevice, toDevice); + return false; + } + + if (Q_UNLIKELY(size_read <= 0)) { + if (size_read == 0 && fromDevice->atEnd()) { + break; + } + + const_cast(fromInfo.data())->refresh(); + + DFileCopyMoveJob::Error errortype = fromInfo->exists() ? DFileCopyMoveJob::ReadError : + DFileCopyMoveJob::NonexistenceError; + QString errorstr = fromInfo->exists() ? + qApp->translate("DFileCopyMoveJob", "Failed to read the file, cause: %1").arg(fromDevice->errorString()) : + QString(); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + switch (setAndhandleError(errortype, fromInfo, toInfo, errorstr)) { + case DFileCopyMoveJob::RetryAction: { + //处理网络文件是否是可以访问的 + DFileCopyMoveJob::GvfsRetryType retryType = gvfsFileRetry(data, isErrorOccur, current_pos, fromInfo, toInfo, fromDevice, toDevice, false); + if (DFileCopyMoveJob::GvfsRetrySkipAction == retryType) { + return true; + } else if (DFileCopyMoveJob::GvfsRetryCancelAction == retryType) { + return false; + } else if (DFileCopyMoveJob::GvfsRetryNoAction == retryType) { + goto read_data; + } + + if (!fromDevice->seek(current_pos)) { + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return handleUnknowError(fromInfo, toInfo, fromDevice->errorString()); + } + + goto read_data; + } + case DFileCopyMoveJob::SkipAction: + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return true; + default: + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return false; + } + } + + current_pos = toDevice->pos(); + write_data: + if (Q_UNLIKELY(!stateCheck())) { + cleanDoCopyFileSource(data, fromInfo, toInfo, fromDevice, toDevice); + return false; + } + qint64 size_write = toDevice->write(data, size_read); + if (Q_UNLIKELY(!stateCheck())) { + cleanDoCopyFileSource(data, fromInfo, toInfo, fromDevice, toDevice); + return false; + } + //如果写失败了,直接推出 + if (size_write < 0) { + if (!stateCheck()) { + cleanDoCopyFileSource(data, fromInfo, toInfo, fromDevice, toDevice); + return false; + } + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + switch (setAndhandleError(DFileCopyMoveJob::WriteError, fromInfo, toInfo, + qApp->translate("DFileCopyMoveJob", "Failed to write the file, cause: %1").arg(toDevice->errorString()))) { + case DFileCopyMoveJob::RetryAction: { + //处理网络文件是否是可以访问的 + DFileCopyMoveJob::GvfsRetryType retryType = gvfsFileRetry(data, isErrorOccur, current_pos, fromInfo, toInfo, fromDevice, toDevice, true); + if (DFileCopyMoveJob::GvfsRetrySkipAction == retryType) { + return true; + } else if (DFileCopyMoveJob::GvfsRetryCancelAction == retryType) { + return false; + } else if (DFileCopyMoveJob::GvfsRetryNoAction == retryType) { + goto read_data; + } + + if (!toDevice->seek(current_pos)) { + cleanDoCopyFileSource(data, fromInfo, toInfo, fromDevice, toDevice); + return handleUnknowError(fromInfo, toInfo, fromDevice->errorString()); + } + + goto write_data; + } + case DFileCopyMoveJob::SkipAction: + cleanDoCopyFileSource(data, fromInfo, toInfo, fromDevice, toDevice); + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + return true; + default: + cleanDoCopyFileSource(data, fromInfo, toInfo, fromDevice, toDevice); + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(false); + isErrorOccur = false; + } + return false; + } + } + + //fix 修复vfat格式u盘卡死问题,写入数据后立刻同步 + if (m_isEveryReadAndWritesSnc && size_write > 0) { + toDevice->inherits(""); + toDevice->syncToDisk(m_isVfat); + } + countrefinesize(size_write); + + if (Q_UNLIKELY(size_write != size_read)) { + do { + // 在某些情况下(往sftp挂载目录写入),可能一次未能写入那么多数据 + // 但不代表写入失败,应该继续尝试,直到所有数据全部写入 + if (size_write > 0) { + const char *surplus_data = data; + qint64 surplus_size = size_read; + + do { + currentJobDataSizeInfo.second += size_write; + completedDataSize += size_write; + // writtenDataSize += size_write; + + surplus_data += size_write; + surplus_size -= size_write; + size_write = toDevice->write(surplus_data, surplus_size); + if (Q_UNLIKELY(!stateCheck())) { + return false; + } + } while (size_write > 0 && size_write != surplus_size); + + // 表示全部数据写入完成 + if (size_write > 0) { + break; + } + } + + DFileCopyMoveJob::Error errortype = DFileCopyMoveJob::WriteError; + QString errorstr = qApp->translate("DFileCopyMoveJob", "Failed to write the file, cause: %1").arg(toDevice->errorString()); + if (!checkFreeSpace(currentJobDataSizeInfo.first - currentJobDataSizeInfo.second)) { + errortype = DFileCopyMoveJob::NotEnoughSpaceError; + errorstr = QString(); + } + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + switch (setAndhandleError(errortype, fromInfo, toInfo, errorstr)) { + case DFileCopyMoveJob::RetryAction: { + if (!toDevice->seek(current_pos)) { + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(false); + isErrorOccur = false; + } + cleanDoCopyFileSource(data, fromInfo, toInfo, fromDevice, toDevice); + return handleUnknowError(fromInfo, toInfo, fromDevice->errorString()); + } + + goto write_data; + } + case DFileCopyMoveJob::SkipAction: + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + cleanDoCopyFileSource(data, fromInfo, toInfo, fromDevice, toDevice); + return true; + default: + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(false); + isErrorOccur = false; + } + cleanDoCopyFileSource(data, fromInfo, toInfo, fromDevice, toDevice); + return false; + } + } while (false); + } + + currentJobDataSizeInfo.second += size_write; + completedDataSize += size_write; + completedDataSizeOnBlockDevice += size_write; + + if (Q_LIKELY(!fileHints.testFlag(DFileCopyMoveJob::DontIntegrityChecking))) { + source_checksum = adler32(source_checksum, reinterpret_cast(data), static_cast(size_read)); + } + + } + delete[] data; + data = nullptr; + fromDevice->close(); + toDevice->close(); + countrefinesize(fromInfo->size() <= 0 ? FileUtils::getMemoryPageSize() : 0); + + //对文件加权 + handler->setFileTime(toInfo->fileUrl(), fromInfo->lastRead(), fromInfo->lastModified()); + + QFileDevice::Permissions permissions = fromInfo->permissions(); + //! use stat function to read vault file permission. + QString path = fromInfo->fileUrl().path(); + if (VaultController::isVaultFile(path)) { + permissions = VaultController::getPermissions(path); + } else if (deviceListener->isFileFromDisc(fromInfo->path())) { // fix bug 52610: 从光盘中复制出来的文件权限为只读,与 ubuntu 策略保持一致,拷贝出来权限为 rw-rw-r-- + permissions |= MasteredMediaController::getPermissionsCopyToLocal(); + } + //权限为0000时,源文件已经被删除,无需修改新建的文件的权限为0000 + if (permissions != 0000) + handler->setPermissions(toInfo->fileUrl(), permissions); + + + if (Q_UNLIKELY(!stateCheck())) { + return false; + } + + if (fileHints.testFlag(DFileCopyMoveJob::DontIntegrityChecking)) { + return true; + } + + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + + do { + if (toDevice->open(QIODevice::ReadOnly)) { + break; + } else { + QString errorstr = "Unable to open file for integrity check, , cause: " + toDevice->errorString(); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(DFileCopyMoveJob::OpenError, toInfo, DAbstractFileInfoPointer(nullptr), errorstr); + //防止卡死 + if (action == DFileCopyMoveJob::RetryAction) { + QThread::msleep(THREAD_SLEEP_TIME); + } + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + isErrorOccur = false; + } + if (action == DFileCopyMoveJob::SkipAction) { + return true; + } + //当打开目标文件失败了,就不去校验数据完整性 + else if (action == DFileCopyMoveJob::CancelAction) { + return false; + } + //校验数据完整性 + + char *data1 = new char[blockSize + 1]; + ulong target_checksum = adler32(0L, nullptr, 0); + + qint64 elapsed_time_checksum = 0; + + if (fileJob().isDebugEnabled()) { + elapsed_time_checksum = updateSpeedElapsedTimer->elapsed(); + } + + Q_FOREVER { + qint64 size = toDevice->read(data1, blockSize); + + if (Q_UNLIKELY(size <= 0)) { + if (size == 0 && toDevice->atEnd()) { + break; + } + + QString errorstr = qApp->translate("DFileCopyMoveJob", "File integrity was damaged, cause: %1").arg(toDevice->errorString()); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + switch (setAndhandleError(DFileCopyMoveJob::IntegrityCheckingError, fromInfo, toInfo, errorstr)) { + case DFileCopyMoveJob::RetryAction: { + continue; + } + case DFileCopyMoveJob::SkipAction: + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + delete [] data1; + return true; + default: + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(false); + isErrorOccur = false; + } + delete [] data1; + return false; + } + } + + target_checksum = adler32(target_checksum, reinterpret_cast(data1), static_cast(size)); + + if (Q_UNLIKELY(!stateCheck())) { + delete [] data1; + return false; + } + } + delete [] data1; + + qCDebug(fileJob(), "Time spent of integrity check of the file: %lld", updateSpeedElapsedTimer->elapsed() - elapsed_time_checksum); + + if (source_checksum != target_checksum) { + qCWarning(fileJob(), "Failed on file integrity checking, source file: 0x%lx, target file: 0x%lx", source_checksum, target_checksum); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + DFileCopyMoveJob::Action action = setAndhandleError(DFileCopyMoveJob::IntegrityCheckingError, fromInfo, toInfo); + + if (action == DFileCopyMoveJob::RetryAction) { + goto open_file; + } + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction); + isErrorOccur = false; + } + + if (action == DFileCopyMoveJob::SkipAction) { + return true; + } + + return false; + } + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + qCDebug(fileJob(), "adler value: 0x%lx", source_checksum); + + return true; +} + +bool DFileCopyMoveJobPrivate::doCopySmallFilesOnDisk(const DAbstractFileInfoPointer fromInfo, const DAbstractFileInfoPointer toInfo, + const QSharedPointer &fromDevice, const QSharedPointer &toDevice, + const QSharedPointer &handler) +{ + sendCopyInfo(fromInfo, toInfo); + //预先读取 + readAheadSourceFile(fromInfo); + + bool isErrorOccur = false; + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + if (!fromDevice) { + return handleUnknowUrlError(fromInfo, toInfo); + } + + if (!toDevice) { + return handleUnknowUrlError(fromInfo, toInfo); + } + +open_file:{ + do { + // 如果打开文件在保险箱内 + QString strPath = toInfo->fileUrl().toString(); + + if (fromDevice->open(QIODevice::ReadOnly)) { + action = DFileCopyMoveJob::NoAction; + } else { + qCDebug(fileJob()) << "open error:" << fromInfo->fileUrl(); + DFileCopyMoveJob::Error errortype = fromInfo->isReadable() ? DFileCopyMoveJob::OpenError : + DFileCopyMoveJob::PermissionError; + QString errorstr = fromInfo->isReadable() ? + qApp->translate("DFileCopyMoveJob", "Failed to open the file, cause: %1").arg(fromDevice->errorString()) : + QString(); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(errortype, fromInfo, DAbstractFileInfoPointer(nullptr), errorstr); + } + //防止卡死 + if (action == DFileCopyMoveJob::RetryAction) { + QThread::msleep(THREAD_SLEEP_TIME); + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); // bug: 26333, while set the stop status shoule break the process! + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + isErrorOccur = false; + } + + if (action == DFileCopyMoveJob::SkipAction) { + return true; + } else if (action != DFileCopyMoveJob::NoAction) { + return false; + } + + do { + if (toDevice->open(QIODevice::WriteOnly | QIODevice::Truncate)) { + action = DFileCopyMoveJob::NoAction; + } else { + qCDebug(fileJob()) << "open error:" << toInfo->fileUrl() << QThread::currentThreadId(); + DFileCopyMoveJob::Error errortype = (!toInfo->exists() || toInfo->isWritable()) ? DFileCopyMoveJob::OpenError : + DFileCopyMoveJob::PermissionError; + // task-36496 "Permission denied"没有被翻译 翻译为“没有权限” + QString errorstr(""); + if ("Permission denied" == toDevice->errorString()) { + errorstr = (!toInfo->exists() || toInfo->isWritable()) ? + qApp->translate("DFileCopyMoveJob", "Failed to open the file, cause: Permission denied") : + QString(); + } else { + errorstr = (!toInfo->exists() || toInfo->isWritable()) ? + qApp->translate("DFileCopyMoveJob", "Failed to open the file, cause: %1").arg(toDevice->errorString()) : + QString(); + } + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(errortype, toInfo, DAbstractFileInfoPointer(nullptr), errorstr); + if (action == DFileCopyMoveJob::RetryAction) { + QThread::msleep(THREAD_SLEEP_TIME); + } + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + isErrorOccur = false; + } + if (action == DFileCopyMoveJob::SkipAction) { + return true; + } else if (action != DFileCopyMoveJob::NoAction) { + return false; + } + + if (fileHints.testFlag(DFileCopyMoveJob::ResizeDestinationFile)) { + do { + if (toDevice->resize(fromInfo->size())) { + action = DFileCopyMoveJob::NoAction; + } else { + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(DFileCopyMoveJob::ResizeError, toInfo, DAbstractFileInfoPointer(nullptr), + toDevice->errorString()); + } + //防止卡死 + if (action == DFileCopyMoveJob::RetryAction) { + QThread::msleep(THREAD_SLEEP_TIME); + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + isErrorOccur = false; + } + if (action == DFileCopyMoveJob::SkipAction) { + fromDevice->close(); + toDevice->close(); + return true; + } else if (action != DFileCopyMoveJob::NoAction) { + fromDevice->close(); + toDevice->close(); + return false; + } + } + } + +#ifdef Q_OS_LINUX + // 开启读取优化,告诉内核,我们将顺序读取此文件 + + if (fromDevice->handle() > 0) { + posix_fadvise(fromDevice->handle(), 0, 0, POSIX_FADV_SEQUENTIAL); + } + + if (toDevice->handle() > 0) { + posix_fadvise(toDevice->handle(), 0, 0, POSIX_FADV_SEQUENTIAL); + } +#endif + + currentJobDataSizeInfo.first = fromInfo->size(); + currentJobFileHandle = toDevice->handle(); + DGIOFileDevice *fromgio = qobject_cast(fromDevice.data()); + DGIOFileDevice *togio = qobject_cast(toDevice.data()); + if (fromgio) { + saveCurrentDevice(fromInfo->fileUrl(),fromDevice); + } + if (togio) { + saveCurrentDevice(toInfo->fileUrl(),toDevice); + } + + qint64 block_Size = fromInfo->size() > MAX_BUFFER_LEN ? MAX_BUFFER_LEN : fromInfo->size(); + uLong source_checksum = adler32(0L, nullptr, 0); + char *data = new char[block_Size + 1]; + + Q_FOREVER { + qint64 current_pos = fromDevice->pos(); + read_data: + if (Q_UNLIKELY(!stateCheck())) { + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return false; + } + + qint64 size_read = fromDevice->read(data, block_Size); + if (Q_UNLIKELY(!stateCheck())) { + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return false; + } + + if (Q_UNLIKELY(size_read <= 0)) { + if (size_read == 0 && fromDevice->atEnd()) { + break; + } + + const_cast(fromInfo.data())->refresh(); + + DFileCopyMoveJob::Error errortype = fromInfo->exists() ? DFileCopyMoveJob::ReadError : + DFileCopyMoveJob::NonexistenceError; + QString errorstr = fromInfo->exists() ? + qApp->translate("DFileCopyMoveJob", "Failed to read the file, cause: %1").arg(fromDevice->errorString()) : + QString(); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + switch (setAndhandleError(errortype, fromInfo, toInfo, errorstr)) { + case DFileCopyMoveJob::RetryAction: { + if (!fromDevice->seek(current_pos)) { + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return handleUnknowError(fromInfo, toInfo, fromDevice->errorString()); + } + + goto read_data; + } + case DFileCopyMoveJob::SkipAction: + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return true; + default: + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return false; + } + } + + current_pos = toDevice->pos(); + write_data: + if (Q_UNLIKELY(!stateCheck())) { + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return false; + } + qint64 size_write = toDevice->write(data, size_read); + if (Q_UNLIKELY(!stateCheck())) { + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return false; + } + //如果写失败了,直接推出 + if (size_write < 0) { + if (!stateCheck()) { + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return false; + } + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + switch (setAndhandleError(DFileCopyMoveJob::WriteError, fromInfo, toInfo, + qApp->translate("DFileCopyMoveJob", "Failed to write the file, cause: %1").arg(toDevice->errorString()))) { + case DFileCopyMoveJob::RetryAction: { + if (!toDevice->seek(current_pos)) { + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return handleUnknowError(fromInfo, toInfo, fromDevice->errorString()); + } + + goto write_data; + } + case DFileCopyMoveJob::SkipAction: + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return true; + default: + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return false; + } + } + + countrefinesize(size_write); + + if (Q_UNLIKELY(size_write != size_read)) { + do { + // 在某些情况下(往sftp挂载目录写入),可能一次未能写入那么多数据 + // 但不代表写入失败,应该继续尝试,直到所有数据全部写入 + if (size_write > 0) { + const char *surplus_data = data; + qint64 surplus_size = size_read; + + do { + currentJobDataSizeInfo.second += size_write; + completedDataSize += size_write; + + surplus_data += size_write; + surplus_size -= size_write; + size_write = toDevice->write(surplus_data, surplus_size); + if (Q_UNLIKELY(!stateCheck())) { + return false; + } + } while (size_write > 0 && size_write != surplus_size); + + // 表示全部数据写入完成 + if (size_write > 0) { + break; + } + } + + DFileCopyMoveJob::Error errortype = DFileCopyMoveJob::WriteError; + QString errorstr = qApp->translate("DFileCopyMoveJob", "Failed to write the file, cause: %1").arg(toDevice->errorString()); + if (!checkFreeSpace(currentJobDataSizeInfo.first - currentJobDataSizeInfo.second)) { + errortype = DFileCopyMoveJob::NotEnoughSpaceError; + errorstr = QString(); + } + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + switch (setAndhandleError(errortype, fromInfo, toInfo, errorstr)) { + case DFileCopyMoveJob::RetryAction: { + if (!toDevice->seek(current_pos)) { + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return handleUnknowError(fromInfo, toInfo, fromDevice->errorString()); + } + + goto write_data; + } + case DFileCopyMoveJob::SkipAction: + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return true; + default: + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return false; + } + } while (false); + } + + currentJobDataSizeInfo.second += size_write; + completedDataSize += size_write; + completedDataSizeOnBlockDevice += size_write; + if (Q_LIKELY(!fileHints.testFlag(DFileCopyMoveJob::DontIntegrityChecking))) { + source_checksum = adler32(source_checksum, reinterpret_cast(data), static_cast(size_read)); + } + } + delete[] data; + fromDevice->close(); + toDevice->close(); + countrefinesize(fromInfo->size() <= 0 ? FileUtils::getMemoryPageSize() : 0); + + //对文件加权 + handler->setFileTime(toInfo->fileUrl(), fromInfo->lastRead(), fromInfo->lastModified()); + + QFileDevice::Permissions permissions = fromInfo->permissions(); + //! use stat function to read vault file permission. + QString path = fromInfo->fileUrl().path(); + if (VaultController::isVaultFile(path)) { + permissions = VaultController::getPermissions(path); + } else if (deviceListener->isFileFromDisc(fromInfo->path())) { // fix bug 52610: 从光盘中复制出来的文件权限为只读,与 ubuntu 策略保持一致,拷贝出来权限为 rw-rw-r-- + permissions |= MasteredMediaController::getPermissionsCopyToLocal(); + } + //权限为0000时,源文件已经被删除,无需修改新建的文件的权限为0000 + if (permissions != 0000) + handler->setPermissions(toInfo->fileUrl(), permissions); + + if (Q_UNLIKELY(!stateCheck())) { + return false; + } + + if (fileHints.testFlag(DFileCopyMoveJob::DontIntegrityChecking)) { + return true; + } + + do { + if (toDevice->open(QIODevice::ReadOnly)) { + break; + } else { + QString errorstr = "Unable to open file for integrity check, , cause: " + toDevice->errorString(); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(DFileCopyMoveJob::OpenError, toInfo, DAbstractFileInfoPointer(nullptr), errorstr); + //防止卡死 + if (action == DFileCopyMoveJob::RetryAction) { + QThread::msleep(THREAD_SLEEP_TIME); + } + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction); + isErrorOccur = false; + } + if (action == DFileCopyMoveJob::SkipAction) { + return true; + } + //当打开目标文件失败了,就不去校验数据完整性 + else if (action == DFileCopyMoveJob::CancelAction) { + return false; + } + //校验数据完整性 + + char *data1 = new char[block_Size + 1]; + ulong target_checksum = adler32(0L, nullptr, 0); + + qint64 elapsed_time_checksum = 0; + + if (fileJob().isDebugEnabled()) { + elapsed_time_checksum = updateSpeedElapsedTimer->elapsed(); + } + + Q_FOREVER { + qint64 size = toDevice->read(data1, block_Size); + + if (Q_UNLIKELY(size <= 0)) { + if (size == 0 && toDevice->atEnd()) { + break; + } + + QString errorstr = qApp->translate("DFileCopyMoveJob", "File integrity was damaged, cause: %1").arg(toDevice->errorString()); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + switch (setAndhandleError(DFileCopyMoveJob::IntegrityCheckingError, fromInfo, toInfo, errorstr)) { + case DFileCopyMoveJob::RetryAction: { + continue; + } + case DFileCopyMoveJob::SkipAction: + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + delete [] data1; + return true; + default: + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(false); + isErrorOccur = false; + } + delete [] data1; + return false; + } + } + + target_checksum = adler32(target_checksum, reinterpret_cast(data1), static_cast(size)); + + if (Q_UNLIKELY(!stateCheck())) { + delete [] data1; + return false; + } + } + delete [] data1; + + qCDebug(fileJob(), "Time spent of integrity check of the file: %lld", updateSpeedElapsedTimer->elapsed() - elapsed_time_checksum); + + if (source_checksum != target_checksum) { + qCWarning(fileJob(), "Failed on file integrity checking, source file: 0x%lx, target file: 0x%lx", source_checksum, target_checksum); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + DFileCopyMoveJob::Action action = setAndhandleError(DFileCopyMoveJob::IntegrityCheckingError, fromInfo, toInfo); + + if (action == DFileCopyMoveJob::RetryAction) { + goto open_file; + } + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction); + isErrorOccur = false; + } + + if (action == DFileCopyMoveJob::SkipAction) { + return true; + } + + return false; + } + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + qCDebug(fileJob(), "adler value: 0x%lx", source_checksum); + + return true; +} + +bool DFileCopyMoveJobPrivate::doThreadPoolCopyFile() +{ + setLastErrorAction(DFileCopyMoveJob::NoAction); + if (!stateCheck()) { + q_ptr->stop(); + return false; + } + + QSharedPointer threadInfo(nullptr); + { + QMutexLocker lk(&m_threadMutex); + if (m_threadInfos.count() <= 0) { + q_ptr->stop(); + return false; + } + threadInfo = m_threadInfos.dequeue(); + } + + if (!threadInfo) + return false; + + const DAbstractFileInfoPointer fromInfo = threadInfo->fromInfo; + const DAbstractFileInfoPointer toInfo = threadInfo->toInfo; + const QSharedPointer handler = threadInfo->handler; + bool ok = doCopySmallFilesOnDisk(fromInfo, toInfo, threadInfo->fromDevice, threadInfo->toDevice, threadInfo->handler); + removeCurrentDevice(fromInfo->fileUrl()); + removeCurrentDevice(toInfo->fileUrl()); + if (!ok) + q_ptr->stop(); + return ok; +} + +bool DFileCopyMoveJobPrivate::doCopyFileOnBlock(const DAbstractFileInfoPointer fromInfo, const DAbstractFileInfoPointer toInfo, const QSharedPointer &handler, int blockSize) +{ + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + int fromfd = -1; + + do { + // 如果打开文件在保险箱内 + QString strPath = toInfo->fileUrl().toString(); + if (VaultController::isVaultFile(strPath)) { + QString strFileName = strPath.section("/", -1, -1); + if (strFileName.toUtf8().length() > 255) { + action = setAndhandleError(DFileCopyMoveJob::OpenError, fromInfo, DAbstractFileInfoPointer(nullptr), + qApp->translate("DFileCopyMoveJob", "Failed to open the file, cause: file name too long")); + break; + } + } + fromfd = open(fromInfo->fileUrl().toLocalFile().toUtf8().toStdString().data(), O_RDONLY); + if (-1 != fromfd) { + action = DFileCopyMoveJob::NoAction; + } else { + qCDebug(fileJob()) << "open error:" << fromInfo->fileUrl(); + DFileCopyMoveJob::Error errortype = DFileCopyMoveJob::PermissionError; + QString errorstr; + if (fromInfo->isReadable()) { + errorstr = qApp->translate("DFileCopyMoveJob", "Failed to open the file, cause: ")/*.arg(fromDevice->errorString())*/; + errortype = DFileCopyMoveJob::OpenError; + } + + action = setAndhandleError(errortype, fromInfo, DAbstractFileInfoPointer(nullptr), errorstr); + //防止卡死 + if (action == DFileCopyMoveJob::RetryAction) { + QThread::msleep(THREAD_SLEEP_TIME); + } + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + + if (action == DFileCopyMoveJob::SkipAction) { + completedProgressDataSize += fromInfo->size() <= 0 ? FileUtils::getMemoryPageSize() : fromInfo->size(); + countrefinesize(fromInfo->size() <= 0 ? FileUtils::getMemoryPageSize() : fromInfo->size()); + return true; + } else if (action != DFileCopyMoveJob::NoAction) { + //出错就停止 + q_ptr->stop(); + return false; + } +#ifdef Q_OS_LINUX + // 开启读取优化,告诉内核,我们将顺序读取此文件 + + if (fromfd > 0) { + posix_fadvise(fromfd, 0, 0, POSIX_FADV_SEQUENTIAL); + } + +#endif + qint64 size_block = fromInfo->size() > MAX_BUFFER_LEN ? MAX_BUFFER_LEN : fromInfo->size(); + size_block = blockSize; + FileCopyInfoPointer copyinfo(new FileCopyInfo()); + copyinfo->handler = handler; + copyinfo->frominfo = fromInfo; + copyinfo->toinfo = toInfo; + lseek(fromfd, 0, SEEK_SET); + qint64 current_pos = 0; + while (true) { + while(checkWritQueueCount()) { + QThread::msleep(1); + } + copyinfo->currentpos = current_pos; + char *buffer = new char[size_block + 1]; + + if (Q_UNLIKELY(!stateCheck())) { + delete[] buffer; + close(fromfd); + return false; + } + + if (skipReadFileDealWriteThread(fromInfo->fileUrl())) + { + completedProgressDataSize += fromInfo->size() <= 0 + ? FileUtils::getMemoryPageSize() : fromInfo->size() - current_pos; + countrefinesize(fromInfo->size() <= 0 + ? FileUtils::getMemoryPageSize() : fromInfo->size() - current_pos); + delete[] buffer; + close(fromfd); + return true; + } + + qint64 size_read = read(fromfd, buffer, static_cast(size_block)); + + if (Q_UNLIKELY(!stateCheck())) { + delete[] buffer; + close(fromfd); + return false; + } + + if (Q_UNLIKELY(size_read <= 0)) { + if (size_read == 0 && current_pos == fromInfo->size()) { + copyinfo->buffer = buffer; + copyinfo->size = size_read; + break; + } + + const_cast(copyinfo->frominfo.data())->refresh(); + DFileCopyMoveJob::Error errortype = DFileCopyMoveJob::NonexistenceError; + QString errorstr; + if (copyinfo->frominfo->exists()) { + errortype = DFileCopyMoveJob::ReadError; + errorstr = qApp->translate("DFileCopyMoveJob", "Failed to read the file, cause: ")/*.arg(fromDevice->errorString())*/; + } + switch (setAndhandleError(errortype, copyinfo->frominfo, copyinfo->toinfo, errorstr)) { + case DFileCopyMoveJob::RetryAction: { + if (!lseek(fromfd, current_pos, SEEK_SET)) { + setError(DFileCopyMoveJob::UnknowError, ""); + delete[] buffer; + close(fromfd); + q_ptr->stop(); + return false; + } + break; + } + case DFileCopyMoveJob::SkipAction: + m_skipFileQueueMutex.lock(); + m_skipFileQueue.push_back(fromInfo->fileUrl()); + m_skipFileQueueMutex.unlock(); + completedProgressDataSize += fromInfo->size() <= 0 + ? FileUtils::getMemoryPageSize() : fromInfo->size() - current_pos; + countrefinesize(fromInfo->size() <= 0 + ? FileUtils::getMemoryPageSize() : fromInfo->size() - current_pos); + delete[] buffer; + return true; + default: + close(fromfd); + q_ptr->stop(); + delete[] buffer; + return false; + } + } else { + FileCopyInfoPointer tmpinfo(new FileCopyInfo); + tmpinfo->closeflag = false; + tmpinfo->frominfo = copyinfo->frominfo; + tmpinfo->toinfo = copyinfo->toinfo; + tmpinfo->currentpos = current_pos; + tmpinfo->buffer = buffer; + tmpinfo->size = size_read; + current_pos += size_read; + + writeQueueEnqueue(tmpinfo); + if (!m_isWriteThreadStart.load()) { + m_isWriteThreadStart.store(true); + m_writeResult = QtConcurrent::run([this]() { + writeRefineThread(); + }); + } + } + } + + if (fromInfo->size() <= 0) { + completedProgressDataSize += FileUtils::getMemoryPageSize(); + countrefinesize(FileUtils::getMemoryPageSize()); + } + + writeQueueEnqueue(copyinfo); + if (!m_isWriteThreadStart.load()) { + m_isWriteThreadStart.store(true); + m_writeResult = QtConcurrent::run([this]() { + writeRefineThread(); + }); + } + + close(fromfd); + + return true; +} + +bool DFileCopyMoveJobPrivate::doRemoveFile(const QSharedPointer &handler, const DAbstractFileInfoPointer fileInfo, const DAbstractFileInfoPointer &toInfo) +{ + if (!fileInfo->exists()) { + return true; + } + + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + bool is_file = fileInfo->isFile() || fileInfo->isSymLink(); + + do { + //! vault file without writable permission cannot processed by system function. + bool canRemove = true; + QString absolutePath = fileInfo->absolutePath(); + DFileCopyMoveJob::Error errortype = DFileCopyMoveJob::PermissionError; + if (VaultController::isVaultFile(absolutePath)) { + VaultController::FileBaseInfo fbi = VaultController::ins()->getFileInfo(VaultController::localToVault(absolutePath)); + if (!fbi.isWritable) { + canRemove = false; + } + } + QString errorstr; + if (canRemove) { + if (is_file ? handler->remove(fileInfo->fileUrl()) : handler->rmdir(fileInfo->fileUrl())) { + return true; + } + + if (fileInfo->absoluteFilePath().startsWith(DFMStandardPaths::location(DFMStandardPaths::TrashExpungedPath))) + return true; + + if (fileInfo->canRename()) { + errortype = DFileCopyMoveJob::RemoveError; + errorstr = qApp->translate("DFileCopyMoveJob", "Failed to delete the file, cause: %1").arg(handler->errorString()); + } + } + + action = setAndhandleError(errortype, fileInfo, toInfo, errorstr); + if (action == DFileCopyMoveJob::RetryAction) { // 仅在选择重试时触发休眠 + QThread::msleep(THREAD_SLEEP_TIME); // fix bug 44436 高频执行循环高频发送信号导致主界面卡死 + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + + return action == DFileCopyMoveJob::SkipAction; +} + +bool DFileCopyMoveJobPrivate::doRenameFile(const QSharedPointer &handler, const DAbstractFileInfoPointer oldInfo, const DAbstractFileInfoPointer newInfo) +{ + const DStorageInfo &storage_source = directoryStack.top().sourceStorageInfo; + const DStorageInfo &storage_target = directoryStack.top().targetStorageInfo; + + if (storage_target.device() != "gvfsd-fuse" || storage_source == storage_target) { + // 先尝试直接rename + if (handler->rename(oldInfo->fileUrl(), newInfo->fileUrl())) { + // 剪切合并需要更新进度条 + currentJobDataSizeInfo.first = oldInfo->size(); + currentJobDataSizeInfo.second += newInfo->size(); + completedDataSize += newInfo->size(); + completedDataSizeOnBlockDevice += newInfo->size(); + needUpdateProgress = true; + if (Q_UNLIKELY(!stateCheck())) { + return false; + } + return true; + } else { // bug-35066 添加对保险箱的判断 + if (oldInfo->isSymLink()) { // 如果为链接文件 + + // 判断当前目录是否存在该名称的链接文件,如果存在,则删除 + if (newInfo->exists()) { + if (!removeFile(handler, newInfo)) { + return false; + } + } + + // 新建链接文件 + if (!handler->link(oldInfo->symlinkTargetPath(), newInfo->fileUrl())) { + //错误队列处理 + errorQueueHandling(); + bool ok = setAndhandleError(DFileCopyMoveJob::SymlinkToGvfsError, oldInfo, newInfo, + handler->errorString()) == DFileCopyMoveJob::SkipAction; + //当前错误处理完成 + errorQueueHandled(); + return ok; + } + + // 删除旧的链接文件 + if (!doRemoveFile(handler, oldInfo, newInfo)) { + return false; + } + + return true; + + } + } + } + + qCDebug(fileJob(), "Failed on rename, Well be copy and delete the file"); + + // 先复制再删除 + if (!doCopyFile(oldInfo, newInfo, handler)) { + return false; + } + + if (getLastErrorAction() == DFileCopyMoveJob::SkipAction) { + // 说明复制文件过程被跳过 + return true; + } + + handler->setFileTime(newInfo->fileUrl(), oldInfo->lastRead(), oldInfo->lastModified()); + + if (!doRemoveFile(handler, oldInfo, newInfo)) { + return false; + } + + return true; +} + +bool DFileCopyMoveJobPrivate::doLinkFile(const QSharedPointer &handler, const DAbstractFileInfoPointer fileInfo, const QString &linkPath) +{ + Q_Q(DFileCopyMoveJob); + if (fileInfo->exists()) { + if (!removeFile(handler, fileInfo)) { + return false; + } + } + + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + + do { + if (handler->link(linkPath, fileInfo->fileUrl())) { + return true; + } + action = setAndhandleError(DFileCopyMoveJob::SymlinkError, fileInfo, DAbstractFileInfoPointer(nullptr), + qApp->translate("DFileCopyMoveJob", "Fail to create symlink, cause: %1").arg(handler->errorString())); + if (action == DFileCopyMoveJob::RetryAction) {// 仅在用户重试时休眠 + q->msleep(THREAD_SLEEP_TIME); + } // fix bug#30091 文件操作失败的时候,点击对话框的“不再提示+重试”,会导致不停失败不停发送信号通知主线程更新ui,这里加个延时控制响应频率 + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + + return action == DFileCopyMoveJob::SkipAction; +} + +void DFileCopyMoveJobPrivate::convertTrashFile(DAbstractFileInfoPointer &fileInfo) +{ + // 创建一个用于暂存即将被删除文件的目录 + QDir expungedDir(DFMStandardPaths::location(DFMStandardPaths::TrashExpungedPath)); + if (!expungedDir.exists()) + expungedDir.mkdir(DFMStandardPaths::location(DFMStandardPaths::TrashExpungedPath)); + + // 获取文件名以及创建文件名 + const QString srcPath = fileInfo->absoluteFilePath(); + const QString tmpPath = DFMStandardPaths::location(DFMStandardPaths::TrashExpungedPath) + "/" + QUuid::createUuid().toString(); + + // 将文件移动到expunged目录下 + QByteArray srcPathBytes(srcPath.toLocal8Bit()); + QByteArray tmpPathBytes(tmpPath.toLocal8Bit()); + if (::rename(srcPathBytes.data(), tmpPathBytes.data()) == 0) { + DAbstractFileInfoPointer tmpFileInfo = fileService->createFileInfo(nullptr, DUrl::fromLocalFile(tmpPath), false); + if (tmpFileInfo && tmpFileInfo->exists()) + fileInfo = tmpFileInfo; + } +} + +bool DFileCopyMoveJobPrivate::process(const DUrl from, const DAbstractFileInfoPointer target_info) +{ + const DAbstractFileInfoPointer &source_info = DFileService::instance()->createFileInfo(nullptr, from, false); + + return process(from, source_info, target_info); +} + +bool DFileCopyMoveJobPrivate::process(const DUrl from, const DAbstractFileInfoPointer source_info, const DAbstractFileInfoPointer target_info, const bool isNew) +{ + // reset error and action + if (m_refineStat == DFileCopyMoveJob::NoRefine) { + unsetError(); + } + setLastErrorAction(DFileCopyMoveJob::NoAction); + + beginJob(JobInfo::Preprocess, from, (source_info && target_info) ? target_info->getUrlByChildFileName(source_info->fileName()) : DUrl(), source_info->isDir()); + bool ok = doProcess(from, source_info, target_info, isNew); + endJob(); + + return ok; +} + +bool DFileCopyMoveJobPrivate::copyFile(const DAbstractFileInfoPointer fromInfo, const DAbstractFileInfoPointer toInfo, const QSharedPointer &handler, int blockSize) +{ + qint64 elapsed = 0; + if (fileJob().isDebugEnabled()) { + elapsed = updateSpeedElapsedTimer->elapsed(); + updateSpeedElapsedTimer->elapsed(); + } + beginJob(JobInfo::Copy, fromInfo->fileUrl(), toInfo->fileUrl()); + bool ok = true; + if (m_refineStat == DFileCopyMoveJob::NoRefine) { + ok = doCopyFile(fromInfo, toInfo, handler, blockSize); + //fix bug 62202 不执行优化拷贝结束后直接返回 + removeCurrentDevice(fromInfo->fileUrl()); + removeCurrentDevice(toInfo->fileUrl()); + endJob(); + qCDebug(fileJob(), "Time spent of copy the file: %lld", updateSpeedElapsedTimer->elapsed() - elapsed); + return ok; + } + const static int bigFileSize = 500 * 1024 * 1024; + //判读目标目录和本地目录是不是同盘,并且是大文件 + if (m_refineStat == DFileCopyMoveJob::RefineLocal) { + if (fromInfo->size() > bigFileSize) { + while (m_pool.activeThreadCount() > 0) { + QThread::msleep(10); + } + ok = doCopyFile(fromInfo,toInfo,handler,blockSize); + } + //1.判断源文件是本地,目标文件也是本地执行读写线程分离处理 + //2.判断源文件是本地,目标文件是(除光盘外的)块设备, + else { + if (!stateCheck()) + return false; + QSharedPointer threadInfo(new ThreadCopyInfo); + threadInfo->fromInfo = fromInfo; + threadInfo->toInfo = toInfo; + threadInfo->toDevice.reset(DFileService::instance()->createFileDevice(nullptr, toInfo->fileUrl())); + threadInfo->fromDevice.reset(DFileService::instance()->createFileDevice(nullptr, fromInfo->fileUrl())); + threadInfo->handler = handler; + { + QMutexLocker lk(&m_threadMutex); + m_threadInfos << threadInfo; + } + QtConcurrent::run(&m_pool, this, static_cast + (&DFileCopyMoveJobPrivate::doThreadPoolCopyFile)); + endJob(); + qCDebug(fileJob(), "Time spent of copy the file: %lld", updateSpeedElapsedTimer->elapsed() - elapsed); + return ok; + } + } + else { + ok = doCopyFileOnBlock(fromInfo, toInfo, handler, blockSize); + } + removeCurrentDevice(fromInfo->fileUrl()); + removeCurrentDevice(toInfo->fileUrl()); + endJob(); + qCDebug(fileJob(), "Time spent of copy the file: %lld", updateSpeedElapsedTimer->elapsed() - elapsed); + return ok; +} + +bool DFileCopyMoveJobPrivate::removeFile(const QSharedPointer &handler, const DAbstractFileInfoPointer fileInfo) +{ + beginJob(JobInfo::Remove, fileInfo->fileUrl(), DUrl()); + bool ok = doRemoveFile(handler, fileInfo); + endJob(); + + return ok; +} + +bool DFileCopyMoveJobPrivate::renameFile(const QSharedPointer &handler, const DAbstractFileInfoPointer oldInfo, const DAbstractFileInfoPointer newInfo) +{ + Q_UNUSED(handler); + + beginJob(JobInfo::Move, oldInfo->fileUrl(), newInfo->fileUrl()); + bool ok = doRenameFile(handler, oldInfo, newInfo); + endJob(); + + return ok; +} + +bool DFileCopyMoveJobPrivate::linkFile(const QSharedPointer &handler, const DAbstractFileInfoPointer fileInfo, const QString &linkPath) +{ + beginJob(JobInfo::Link, DUrl(linkPath), fileInfo->fileUrl()); + bool ok = doLinkFile(handler, fileInfo, linkPath); + endJob(); + + return ok; +} + +void DFileCopyMoveJobPrivate::beginJob(JobInfo::Type type, const DUrl from, const DUrl target, const bool isDir) +{ +// qCDebug(fileJob(), "job begin, Type: %d, from: %s, to: %s", type, qPrintable(from.toString()), qPrintable(target.toString())); + jobStack.push({type, QPair(from, target)}); + currentJobDataSizeInfo = qMakePair(-1, 0); + currentJobFileHandle = -1; + if (isDir || m_refineStat == DFileCopyMoveJob::NoRefine) + Q_EMIT q_ptr->currentJobChanged(from, target, false); +} + +void DFileCopyMoveJobPrivate::endJob(const bool isNew) +{ + if (isNew) { + return; + } + jobStack.pop(); + currentJobFileHandle = -1; + +// qCDebug(fileJob()) << "job end, error:" << error << "last error handle action:" << lastErrorHandleAction; +} + +void DFileCopyMoveJobPrivate::enterDirectory(const DUrl from, const DUrl to) +{ + DirectoryInfo info; + + info.url = qMakePair(from, to); + + if (from.isLocalFile()) { + info.sourceStorageInfo.setPath(from.toLocalFile()); + } + + if (to.isLocalFile()) { + if (!directoryStack.isEmpty()) { + if (directoryStack.top().url.second == to) { + info.targetStorageInfo = directoryStack.top().targetStorageInfo; + } else { + info.targetStorageInfo.setPath(to.toLocalFile()); + } + } else { + info.targetStorageInfo.setPath(to.toLocalFile()); + } + } + + directoryStack.push(info); +} + +void DFileCopyMoveJobPrivate::leaveDirectory() +{ + directoryStack.pop(); +} + +void DFileCopyMoveJobPrivate::joinToCompletedFileList(const DUrl from, const DUrl target, qint64 dataSize) +{ +// qCDebug(fileJob(), "file. from: %s, target: %s, data size: %lld", qPrintable(from.toString()), qPrintable(target.toString()), dataSize); + + if (currentJobDataSizeInfo.first < 0) { + completedDataSize += dataSize; + } + + completedProgressDataSize += dataSize <= 0 ? FileUtils::getMemoryPageSize() : 0; + + ++completedFilesCount; + + Q_EMIT q_ptr->completedFilesCountChanged(completedFilesCount); + + if (getLastErrorAction() == DFileCopyMoveJob::SkipAction) { + return; + } + + completedFileList << qMakePair(from, target); +} + +void DFileCopyMoveJobPrivate::joinToCompletedDirectoryList(const DUrl from, const DUrl target, qint64 dataSize) +{ + Q_UNUSED(dataSize) +// qCDebug(fileJob(), "directory. from: %s, target: %s, data size: %lld", qPrintable(from.toString()), qPrintable(target.toString()), dataSize); + + // warning: isFromLocalUrls 对于外部挂载存储设备返回true,如果要修改 isFromLocalUrls 的含义 + // 将会影响到以下判断逻辑 + qint64 dirSize = (m_isFileOnDiskUrls && targetUrl.isValid()) ? m_currentDirSize : FileUtils::getMemoryPageSize(); + completedProgressDataSize += (dirSize <= 0 ? FileUtils::getMemoryPageSize() : dirSize); + ++completedFilesCount; + + countrefinesize(dirSize); + + Q_EMIT q_ptr->completedFilesCountChanged(completedFilesCount); + + if (getLastErrorAction() == DFileCopyMoveJob::SkipAction) { + return; + } + + completedDirectoryList << qMakePair(from, target); +} + +void DFileCopyMoveJobPrivate::updateProgress() +{ + switch (mode) { + case DFileCopyMoveJob::CopyMode: + case DFileCopyMoveJob::CutMode: + updateCopyProgress(); + break; + case DFileCopyMoveJob::MoveMode: + updateMoveProgress(); + break; + } + +} + +void DFileCopyMoveJobPrivate::updateCopyProgress() +{ + // 网络文件使用统计线程的值获取总大小. 非网络文件使用 fts_* 系统 API 统计函数同步统计总大小 + bool fromLocal = (m_isFileOnDiskUrls && targetUrl.isValid()); + const qint64 totalSize = fromLocal ? totalsize : fileStatistics->totalProgressSize(); + //通过getCompletedDataSize取出的已传输的数据大小后期会远超实际数据大小,这种情况下直接使用completedDataSize + qint64 dataSize(getCompletedDataSize()); + // completedDataSize 可能一直为 0 + if (dataSize > completedDataSize && completedDataSize > 0) { + dataSize = completedDataSize; + } + + dataSize += completedProgressDataSize; + dataSize -= m_gvfsFileInnvliadProgress; + + //优化 + dataSize = m_bDestLocal ? m_refineCopySize : dataSize; + + dataSize += skipFileSize; + + if (totalSize == 0) + return; + + if ((fromLocal && m_isCountSizeOver) || fileStatistics->isFinished()) { + qreal realProgress = qreal(dataSize) / totalSize; + if (realProgress > lastProgress) + lastProgress = realProgress; + qCDebug(fileJob(), "completed data size: %lld, total data size: %lld,m_refineCopySize = %lld", dataSize, totalSize, completedProgressDataSize); + } else { + //预设一个总大小,让前期进度平滑一些(目前阈值取1mb) + qreal virtualSize = totalSize < 1000000 ? 1000000 : totalSize; + if (dataSize < virtualSize /*&& total_size > 0*/) { + // 取一个时时的总大小来计算一个模糊进度 + qreal fuzzyProgress = qreal(dataSize) / virtualSize; + if (fuzzyProgress < 0.3 && fuzzyProgress > lastProgress) + lastProgress = fuzzyProgress; + } + } + // 保证至少出现%1 + if (lastProgress < 0.02) { + lastProgress = 0.01; + } + + Q_EMIT q_ptr->progressChanged(qMin(lastProgress, 1.0), dataSize); + + if (currentJobDataSizeInfo.first > 0) { + Q_EMIT q_ptr->currentFileProgressChanged(qMin(qreal(currentJobDataSizeInfo.second) / currentJobDataSizeInfo.first, 1.0), currentJobDataSizeInfo.second); + } +} + + +// use count calculate progress when mode is move +void DFileCopyMoveJobPrivate::updateMoveProgress() +{ + Q_Q(DFileCopyMoveJob); + int totalCount = q->totalFilesCount(); + if (totalCount > 0) { + qreal realProgress = qreal(completedFilesCount) / totalCount; + if (realProgress > lastProgress) + lastProgress = realProgress; + } else if (countStatisticsFinished && totalMoveFilesCount > 0) { + qreal realProgress = qreal(completedFilesCount) / totalMoveFilesCount; + if (realProgress > lastProgress) + lastProgress = realProgress; + } else { + if (completedFilesCount < totalMoveFilesCount && totalMoveFilesCount > 0) { + qreal fuzzyProgress = qreal(completedFilesCount) / totalMoveFilesCount; + if (fuzzyProgress < 0.5 && fuzzyProgress > lastProgress) + lastProgress = fuzzyProgress; + } + } + // 保证至少出现%1 + if (lastProgress < 0.02) { + lastProgress = 0.01; + } + Q_EMIT q_ptr->progressChanged(qMin(lastProgress, 1.0), 0); +} + +void DFileCopyMoveJobPrivate::updateSpeed() +{ + const qint64 time = updateSpeedElapsedTimer->elapsed(); + const qint64 total_size = m_bDestLocal ? m_refineCopySize : getCompletedDataSize(); + if (time == 0) + return; + + qint64 speed = total_size / time * 1000; + + // 如果进度已经是100%,则不应该再有速度波动 + if (fileStatistics->isFinished() && total_size >= fileStatistics->totalSize()) { + speed = 0; + } + + // 复制和剪切文件时显示速度 + if (mode != DFileCopyMoveJob::MoveMode) { + Q_EMIT q_ptr->speedUpdated(speed); + } +} + +void DFileCopyMoveJobPrivate::_q_updateProgress() +{ + ++timeOutCount; + + updateSpeed(); + updateProgress(); + + // 因为sleep状态时可能会导致进度信息长时间无法得到更新,故在此处直接更新进度信息 + if (state == DFileCopyMoveJob::IOWaitState) { + updateProgress(); + } else { + needUpdateProgress = true; + } +} + +void DFileCopyMoveJobPrivate::countrefinesize(const qint64 &size) +{ + QMutexLocker lock(&m_refineMutex); + m_refineCopySize += size; +} + +void DFileCopyMoveJobPrivate::checkTagetNeedSync() +{ + if (!targetUrl.isValid()) { + return; + } + m_isEveryReadAndWritesSnc = m_isTagGvfsFile; + DStorageInfo targetStorageInfo(targetUrl.toLocalFile()); + if (!m_isEveryReadAndWritesSnc && targetStorageInfo.isValid()) { + const QString &fs_type = targetStorageInfo.fileSystemType(); + m_isVfat = fs_type.contains("vfat"); + m_isEveryReadAndWritesSnc = (fs_type == "cifs" || fs_type == "vfat"); + } +} + +void DFileCopyMoveJobPrivate::checkTagetIsFromBlockDevice() +{ + if (!targetUrl.isValid()) { + return; + } + m_isTagFromBlockDevice.store(!deviceListener->isFileFromDisc(targetUrl.toLocalFile()) && + deviceListener->isBlockFile(targetUrl.toLocalFile())); +} + +bool DFileCopyMoveJobPrivate::checkWritQueueEmpty() +{ + QMutexLocker lk(&m_copyInfoQueueMutex); + return m_writeFileQueue.isEmpty(); +} + +bool DFileCopyMoveJobPrivate::checkWritQueueCount() +{ + QMutexLocker lk(&m_copyInfoQueueMutex); + return m_writeFileQueue.count() > 300; +} + +QSharedPointer DFileCopyMoveJobPrivate::writeQueueDequeue() +{ + QMutexLocker lk(&m_copyInfoQueueMutex); + return m_writeFileQueue.dequeue(); +} + +void DFileCopyMoveJobPrivate::writeQueueEnqueue(const QSharedPointer ©info) +{ + QMutexLocker lk(&m_copyInfoQueueMutex); + m_writeFileQueue.enqueue(copyinfo); +} + +void DFileCopyMoveJobPrivate::errorQueueHandling() +{ + if (!stateCheck()) + return; + bool isLoop = false; + { + QMutexLocker lk(&m_errorQueueMutex); + if (!stateCheck()) + return; + if ((m_errorQueue.count() <= 0 || m_errorQueue.first() != QThread::currentThreadId()) && stateCheck()) + m_errorQueue.enqueue(QThread::currentThreadId()); + + isLoop = m_errorQueue.count() > 1 && m_errorQueue.first() != QThread::currentThreadId(); + qDebug() << "new error comming " << m_errorQueue << isLoop << QThread::currentThreadId(); + } + while (isLoop && stateCheck()) { + QMutex mutex; + mutex.lock(); + m_errorCondition.wait(&mutex); + mutex.unlock(); + { + QMutexLocker lk(&m_errorQueueMutex); + isLoop = m_errorQueue.count() > 1 && m_errorQueue.first() != QThread::currentThreadId(); + } + } +} + +void DFileCopyMoveJobPrivate::errorQueueHandled(const bool &isNotCancel) +{ + if (!isNotCancel) + q_ptr->stop(); + QMutexLocker lk(&m_errorQueueMutex); + if (!m_errorQueue.isEmpty()) { + m_errorQueue.removeAll(QThread::currentThreadId()); + qDebug() << "error handler over === " << QThread::currentThreadId() << m_errorQueue; + } + if (m_errorQueue.count() > 0) + m_errorCondition.wakeAll(); +} + +void DFileCopyMoveJobPrivate::releaseCopyInfo(const DFileCopyMoveJobPrivate::FileCopyInfoPointer &info) +{ + if (info->buffer) { + delete [] info->buffer; + info->buffer = nullptr; + } + for (auto fd : m_writeOpenFd) { + close(fd); + } + m_writeOpenFd.clear(); +} + +bool DFileCopyMoveJobPrivate::writeRefineThread() +{ + bool ok = true; + while (checkRefineCopyProccessSate(DFileCopyMoveJob::ReadFileProccessOver)) { + ok = writeToFileByQueue(); + if (!ok) { + break; + } + } + if (ok && stateCheck()) { + ok = writeToFileByQueue(); + } else { + q_ptr->stop(); + } + cancelReadFileDealWriteThread(); + qInfo() << "write thread finish!"; + return true; +} + +//为考虑线程之间的同步问题(错误同步,假如,读线程出错了, +//1.重试时写线程是不是要全部停住(已暂停) +//2.重试失败,跳过当前文件应该怎么处理(加入一个跳过写入队列,写线程检查当前的写队列,移除都所有的要移除的选项) +//3.重试失败,直接退出拷贝怎么处理(处理所有的写入队列,清理掉)。 +//写线程出错时,1.弹出提示框时,是否要暂停读线程2.点击跳过应该怎么处理,清理掉有相同的文件描述符的写队列、关闭文件读文件是否要暂停3.关闭拷贝时,要怎么处理) +bool DFileCopyMoveJobPrivate::writeToFileByQueue() +{ + while (!checkWritQueueEmpty()) { + auto info = writeQueueDequeue(); + if (Q_UNLIKELY(!stateCheck())) { + releaseCopyInfo(info); + return false; + } + //检查info的有效性 + if (!info->frominfo || !info->toinfo) { + releaseCopyInfo(info); + return false; + } + //对文件夹加权 + if (info->isdir) { + info->handler->setPermissions(info->toinfo->fileUrl(), info->permission); \ + continue; + } + if (skipReadFileDealWriteThread(info->frominfo->fileUrl())) { + completedProgressDataSize += info->size; + countrefinesize(info->size); + releaseCopyInfo(info); + continue; + } + int toFd = -1; + bool isErrorOccur = false; + //获取目标文件描述符 + if (!m_writeOpenFd.contains(info->toinfo->fileUrl())) { + DUrl fromUrl = info->frominfo->fileUrl(); + DUrl toUrl = info->toinfo->fileUrl(); + Q_EMIT q_ptr->currentJobChanged(fromUrl, toUrl, false); + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + do { + std::string path = info->toinfo->fileUrl().path().toStdString(); + toFd = open(path.c_str(), m_openFlag, 0777); + if (toFd > -1) { + m_writeOpenFd.insert(info->toinfo->fileUrl(), toFd); + action = DFileCopyMoveJob::NoAction; + } else { + qCDebug(fileJob()) << "open error:" << info->toinfo->fileUrl() << QThread::currentThreadId(); + DFileCopyMoveJob::Error errortype = (!info->toinfo->exists() || info->toinfo->isWritable()) ? DFileCopyMoveJob::OpenError : + DFileCopyMoveJob::PermissionError; + // task-36496 "Permission denied"没有被翻译 翻译为“没有权限” + QString errorstr(""); + + errorstr = (!info->toinfo->exists() || info->toinfo->isWritable()) ? + qApp->translate("DFileCopyMoveJob", "Failed to open the file, cause: Permission denied") : + QString("Failed to open the file!"); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(errortype, info->toinfo, DAbstractFileInfoPointer(nullptr), errorstr); + if (action == DFileCopyMoveJob::RetryAction) { + QThread::msleep(THREAD_SLEEP_TIME); + } + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + isErrorOccur = false; + } + if (action == DFileCopyMoveJob::SkipAction) { + countrefinesize(info->size); + completedProgressDataSize += info->size; + releaseCopyInfo(info); + QMutexLocker lk(&m_skipFileQueueMutex); + m_skipFileQueue.enqueue(info->frominfo->fileUrl()); + continue; + } else if (action != DFileCopyMoveJob::NoAction) { + releaseCopyInfo(info); + return false; + } + } + else { + toFd = m_writeOpenFd.value(info->toinfo->fileUrl()); + } + + bool bSkiped = false; + +write_data: { + qint64 size_write = write(toFd, info->buffer, static_cast(info->size)); + QString errorstr = strerror(errno); + if (Q_UNLIKELY(!stateCheck())) { + releaseCopyInfo(info); + return false; + } + //如果写失败了,直接推出 + if (size_write < 0) { + if (!stateCheck()) { + releaseCopyInfo(info); + return false; + } + + //错误队列处理 + if (!isErrorOccur) + errorQueueHandling(); + isErrorOccur = true; + switch (setAndhandleError(DFileCopyMoveJob::WriteError, info->frominfo, info->toinfo, + qApp->translate("DFileCopyMoveJob", "Failed to write the file, cause:"). + arg(errorstr))) { + case DFileCopyMoveJob::RetryAction: { + if (!lseek(toFd, info->currentpos, SEEK_SET)) { + setError(DFileCopyMoveJob::UnknowError, ""); + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(false); + isErrorOccur = false; + } + releaseCopyInfo(info); + return false; + } + goto write_data; + } + case DFileCopyMoveJob::SkipAction: { + //临时处理 fix + //判断是否是网络文件,是,就去调用closeWriteReadFailed,不去调用g_output_stream_close(d->output_stream, nullptr, nullptr); + //在失去网络,网络文件调用gio 的 g_output_stream_close 关闭 output_stream,会卡很久 + completedProgressDataSize += info->size; + countrefinesize(info->size); + releaseCopyInfo(info); + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + bSkiped = true; + + QMutexLocker lk(&m_skipFileQueueMutex); + m_skipFileQueue.push_back(info->frominfo->fileUrl()); + break; + } + default: + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(false); + isErrorOccur = false; + } + releaseCopyInfo(info); + + return false; + } + } + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + + if (bSkiped) + continue; + + if (Q_UNLIKELY(size_write != info->size)) { + do { + // 在某些情况下(往sftp挂载目录写入),可能一次未能写入那么多数据 + // 但不代表写入失败,应该继续尝试,直到所有数据全部写入 + if (size_write > 0) { + const char *surplus_data = info->buffer; + qint64 surplus_size = info->size; + + do { + currentJobDataSizeInfo.second += size_write; + completedDataSize += size_write; + + surplus_data += size_write; + surplus_size -= size_write; + + size_write = write(toFd, surplus_data, static_cast(surplus_size)); + } while (size_write > 0 && size_write != surplus_size); + + // 表示全部数据写入完成 + if (size_write > 0) { + break; + } + } + + DFileCopyMoveJob::Error errortype = DFileCopyMoveJob::NotEnoughSpaceError; + QString errorstr; + + if (checkFreeSpace(currentJobDataSizeInfo.first - currentJobDataSizeInfo.second)) { + errortype = DFileCopyMoveJob::WriteError; + errorstr = qApp->translate("DFileCopyMoveJob", "Failed to write the file, cause:").arg(strerror(errno)); + } + + switch (setAndhandleError(errortype, info->frominfo, info->toinfo, errorstr)) { + case DFileCopyMoveJob::RetryAction: { + if (!lseek(toFd, info->currentpos, SEEK_SET)) { + setError(DFileCopyMoveJob::UnknowError, ""); + releaseCopyInfo(info); + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(false); + isErrorOccur = false; + } + + return false; + } + + goto write_data; + } + case DFileCopyMoveJob::SkipAction:{ + releaseCopyInfo(info); + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(); + isErrorOccur = false; + } + + QMutexLocker lk(&m_skipFileQueueMutex); + m_skipFileQueue.push_back(info->frominfo->fileUrl()); + break; + } + default: + //当前错误处理完成 + releaseCopyInfo(info); + if (isErrorOccur) { + errorQueueHandled(false); + isErrorOccur = false; + } + return false; + } + } while (false); + } + + if (bSkiped) + continue; + + currentJobDataSizeInfo.second += size_write; + completedDataSize += size_write; + completedDataSizeOnBlockDevice += size_write; + + countrefinesize(size_write); + if (info->buffer) { + delete [] info->buffer; + info->buffer = nullptr; + } + } + //异步执行同步 + syncfs(toFd); + //关闭文件并加权 + if (info->closeflag) { + close(toFd); + m_writeOpenFd.remove(info->toinfo->fileUrl()); + QSharedPointer handler = info->handler ? info->handler : + QSharedPointer(DFileService::instance()->createFileHandler(nullptr, info->frominfo->fileUrl())); + handler->setFileTime(info->toinfo->fileUrl(), info->frominfo->lastRead(), info->frominfo->lastModified()); + + QFileDevice::Permissions permissions = info->frominfo->permissions(); + //! use stat function to read vault file permission. + QString path = info->frominfo->fileUrl().path(); + if (VaultController::isVaultFile(path)) { + permissions = VaultController::getPermissions(path); + } else if (deviceListener->isFileFromDisc(info->frominfo->path())) { // fix bug 52610: 从光盘中复制出来的文件权限为只读,与 ubuntu 策略保持一致,拷贝出来权限为 rw-rw-r-- + permissions |= MasteredMediaController::getPermissionsCopyToLocal(); + } + if (permissions != 0000) + handler->setPermissions(info->toinfo->fileUrl(), permissions); + } + } + qDebug() << "write queue over!"; + return true; +} + +bool DFileCopyMoveJobPrivate::skipReadFileDealWriteThread(const DUrl &url) +{ + QMutexLocker lk(&m_skipFileQueueMutex); + + return m_skipFileQueue.contains(url); +} + + +void DFileCopyMoveJobPrivate::cancelReadFileDealWriteThread() +{ + QMutexLocker lk(&m_copyInfoQueueMutex); + for (auto fd : m_writeOpenFd) { + close(fd); + } + m_writeOpenFd.clear(); + while (!m_writeFileQueue.isEmpty()) { + auto info = m_writeFileQueue.dequeue(); + if (info->buffer) + delete[] info->buffer; + } +} + +void DFileCopyMoveJobPrivate::setRefineCopyProccessSate(const DFileCopyMoveJob::RefineCopyProccessSate &stat) +{ + m_copyRefineFlag = stat; +} + +bool DFileCopyMoveJobPrivate::checkRefineCopyProccessSate(const DFileCopyMoveJob::RefineCopyProccessSate &stat) +{ + return m_copyRefineFlag < stat; +} + +void DFileCopyMoveJobPrivate::setCutTrashData(QVariant fileNameList) +{ + for (DUrl temp : qvariant_cast(fileNameList)) { + m_fileNameList.enqueue(temp.path()); + } +} + +void DFileCopyMoveJobPrivate::saveCurrentDevice(const DUrl &url, const QSharedPointer device) +{ + QMutexLocker lk(&m_currentDeviceMutex); + m_currentDevice[url] = device; +} + +void DFileCopyMoveJobPrivate::removeCurrentDevice(const DUrl &url) +{ + QMutexLocker lk(&m_currentDeviceMutex); + m_currentDevice.remove(url); +} + +void DFileCopyMoveJobPrivate::stopAllDeviceOperation() +{ + QMutexLocker lk(&m_currentDeviceMutex); + for (auto url : m_currentDevice.keys()) { + m_currentDevice.value(url)->cancelAllOperate(); + } + m_currentDevice.clear(); +} + +void DFileCopyMoveJobPrivate::clearThreadPool() +{ + QMutexLocker lk(&m_threadMutex); + m_threadInfos.clear(); +} + +DFileCopyMoveJob::DFileCopyMoveJob(QObject *parent) + : DFileCopyMoveJob(new DFileCopyMoveJobPrivate(this), parent) +{ +} + +DFileCopyMoveJob::~DFileCopyMoveJob() +{ + stop(); + + Q_D(DFileCopyMoveJob); + //停止清理掉自己的大文件拷贝 + copyBigFileOnDiskJobRun(); + + d->stopAllDeviceOperation(); + + d->clearThreadPool(); + + d->cancelReadFileDealWriteThread(); + qDebug() << "release DFileCopyMoveJob!" << this << QThread::currentThread(); +} + +DFileCopyMoveJob::Handle *DFileCopyMoveJob::errorHandle() const +{ + Q_D(const DFileCopyMoveJob); + + return d->handle; +} + +void DFileCopyMoveJob::setErrorHandle(DFileCopyMoveJob::Handle *handle, QThread *threadOfHandle) +{ + Q_D(DFileCopyMoveJob); + + d->handle = handle; + d->threadOfErrorHandle = threadOfHandle; +} + +void DFileCopyMoveJob::setActionOfErrorType(DFileCopyMoveJob::Error error, DFileCopyMoveJob::Action action) +{ + Q_D(DFileCopyMoveJob); + Q_ASSERT(d->state != RunningState); + + d->actionOfError[error] = action; +} + +DFileCopyMoveJob::Mode DFileCopyMoveJob::mode() const +{ + Q_D(const DFileCopyMoveJob); + + return d->mode; +} + +DFileCopyMoveJob::State DFileCopyMoveJob::state() const +{ + Q_D(const DFileCopyMoveJob); + + return static_cast(d->state.load()); +} + +DFileCopyMoveJob::Error DFileCopyMoveJob::error() const +{ + Q_D(const DFileCopyMoveJob); + + return d->error; +} + +DFileCopyMoveJob::FileHints DFileCopyMoveJob::fileHints() const +{ + Q_D(const DFileCopyMoveJob); + + return d->fileHints; +} + +QString DFileCopyMoveJob::errorString() const +{ + Q_D(const DFileCopyMoveJob); + + return d->errorString; +} + +DUrlList DFileCopyMoveJob::sourceUrlList() const +{ + Q_D(const DFileCopyMoveJob); + + return d->sourceUrlList; +} + +DUrlList DFileCopyMoveJob::targetUrlList() const +{ + Q_D(const DFileCopyMoveJob); + + return d->targetUrlList; +} + +DUrl DFileCopyMoveJob::targetUrl() const +{ + Q_D(const DFileCopyMoveJob); + + return d->targetUrl; +} + +bool DFileCopyMoveJob::fileStatisticsIsFinished() const +{ + Q_D(const DFileCopyMoveJob); + + return d->fileStatistics->isFinished(); +} + +qint64 DFileCopyMoveJob::totalDataSize() const +{ + Q_D(const DFileCopyMoveJob); + + if (d->m_isFileOnDiskUrls) { + if (!d->m_isCountSizeOver) { + return -1; + } + return d->totalsize; + } + + if (d->fileStatistics->isRunning()) { + return -1; + } + + return d->fileStatistics->totalSize(); +} + +int DFileCopyMoveJob::totalFilesCount() const +{ + Q_D(const DFileCopyMoveJob); + + if (d->fileStatistics->isRunning()) { + return -1; + } + + return d->fileStatistics->filesCount() + d->fileStatistics->directorysCount(); +} + +QList> DFileCopyMoveJob::completedFiles() const +{ + Q_D(const DFileCopyMoveJob); + Q_ASSERT(d->state != RunningState); + + return d->completedFileList; +} + +QList> DFileCopyMoveJob::completedDirectorys() const +{ + Q_D(const DFileCopyMoveJob); + Q_ASSERT(d->state != RunningState); + + return d->completedDirectoryList; +} +//获取当前是否可以显示进度条 +bool DFileCopyMoveJob::isCanShowProgress() const +{ + Q_D(const DFileCopyMoveJob); + return d->m_isNeedShowProgress; +} + +void DFileCopyMoveJob::setRefine(const RefineState &refinestat) +{ + Q_D(DFileCopyMoveJob); + + d->m_refineStat = refinestat; +} + +void DFileCopyMoveJobPrivate::waitRefineThreadFinish() +{ + qDebug() << "wait thread pool finished!"; + while (m_pool.activeThreadCount() > 0) { + if (state == DFileCopyMoveJob::StoppedState) + q_ptr->stop(); + QThread::msleep(50); + } + qDebug() << "wait write thread finished!"; + if (m_isWriteThreadStart.load()) { + while (!m_writeResult.isFinished()) { + if (state == DFileCopyMoveJob::StoppedState) { + cancelReadFileDealWriteThread(); + m_writeResult.waitForFinished(); + return; + } + QThread::msleep(50); + } + } + qDebug() << "add Permisson to dir!"; + for (auto info : m_dirPermissonList) + { + info->handler->setPermissions(info->target, info->permission); + } +} + +void DFileCopyMoveJobPrivate::setLastErrorAction(const DFileCopyMoveJob::Action &action) +{ + QMutexLocker lk(&m_lastErrorHandleActionMutex); + m_lastErrorHandleAction.insert(QThread::currentThread(), action); +} + +DFileCopyMoveJob::Action DFileCopyMoveJobPrivate::getLastErrorAction() +{ + QMutexLocker lk(&m_lastErrorHandleActionMutex); + QThread *current = QThread::currentThread(); + if (m_lastErrorHandleAction.contains(current) ) + return m_lastErrorHandleAction.value(current); + return DFileCopyMoveJob::NoAction; +} +/*! + * \brief DFileCopyMoveJobPrivate::reopenGvfsFiles 拷贝文件到网络文件或者从网络文件上拷贝文件, + * 在拷贝途中断网再恢复后才能调用,不然就会卡死。主要功能是调整断点续传时重新打开远程文件,调整文件位置,方便再次拷贝写入 + * \param fromInfo 源文件的信息 + * \param toInfo 目标文件的信息 + * \param fromDevice 源文件的iodevice + * \param toDevice 目标文件的iodevice + * \param isWriteError 是否是写时错误 + * \return qint64 返回当前文件拷贝到的位置 + */ +qint64 DFileCopyMoveJobPrivate::reopenGvfsFiles(const DAbstractFileInfoPointer &fromInfo, const DAbstractFileInfoPointer &toInfo, QSharedPointer &fromDevice, + QSharedPointer &toDevice, const bool &isWriteError) +{ + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + if (isWriteError) { + toInfo->refresh(true); + toDevice->close(); + action = openGvfsFile(toInfo, toDevice, (QIODevice::WriteOnly | QIODevice::Truncate)); + } else { + fromInfo->refresh(true); + toInfo->refresh(true); + fromDevice->close(); + action = openGvfsFile(fromInfo, fromDevice, QIODevice::ReadOnly); + } + + if (action == DFileCopyMoveJob::SkipAction) { + return -1; + } else if (action != DFileCopyMoveJob::NoAction) { + return -2; + } + fromInfo->refresh(true); + toInfo->refresh(true); + m_gvfsFileInnvliadProgress = const_cast(this)->getCompletedDataSize(); + qint64 currentPos = 0; + if (isWriteError) { + action = seekFile(fromInfo, fromDevice, currentPos); + } else { + action = seekFile(toInfo, toDevice, currentPos); + } + + if (action == DFileCopyMoveJob::SkipAction) { + return -1; + } else if (action != DFileCopyMoveJob::NoAction) { + return -2; + } + + return currentPos; +} + +/*! + * \brief DFileCopyMoveJobPrivate::seekFile seek文件指针到指定位置,错误就阻塞弹窗重试就继续 + * 需要注意的是调用此接口必须是文件打开的情况 + * \param fileInfo 文件信息 + * \param device 文件的iodevice + * \param pos 要seek的位置 + * \return DFileCopyMoveJob::Action 拷贝操作 + */ +DFileCopyMoveJob::Action DFileCopyMoveJobPrivate::seekFile(const DAbstractFileInfoPointer &fileInfo, + QSharedPointer &device, const qint64 &pos) +{ + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + bool isErrorOccur = false; + do { + if (device->seek(pos)) { + action = DFileCopyMoveJob::NoAction; + } else { + QString errorstr = qApp->translate("DFileCopyMoveJob", "Failed to position the file pointer, cause: %1").arg(device->errorString()); + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + DFileCopyMoveJob::Error errortype = DFileCopyMoveJob::OpenError; + action = setAndhandleError(errortype, fileInfo, DAbstractFileInfoPointer(nullptr), errorstr); + if (action == DFileCopyMoveJob::RetryAction) { + QThread::msleep(THREAD_SLEEP_TIME); + } + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + isErrorOccur = false; + } + return action; +} + +/*! + * \brief DFileCopyMoveJobPrivate::openGvfsFile 打开文件,错误就阻塞弹窗重试就继续 + * \param fileInfo 文件信息 + * \param device 文件的iodevice + * \param flags 打开文件的描述符 + * \return DFileCopyMoveJob::Action 拷贝操作 + */ +DFileCopyMoveJob::Action DFileCopyMoveJobPrivate::openGvfsFile(const DAbstractFileInfoPointer &fileInfo, + QSharedPointer &device, const QIODevice::OpenMode &flags) +{ + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + bool isErrorOccur = false; + do { + if (device->open(flags)) { + action = DFileCopyMoveJob::NoAction; + } else { + qCDebug(fileJob()) << "open error:" << fileInfo->fileUrl() << QThread::currentThreadId(); + DFileCopyMoveJob::Error errortype = (!fileInfo->exists() || fileInfo->isWritable()) ? + DFileCopyMoveJob::OpenError : + DFileCopyMoveJob::PermissionError; + // task-36496 "Permission denied"没有被翻译 翻译为“没有权限” + QString errorstr(""); + if ("Permission denied" == device->errorString()) { + errorstr = (!fileInfo->exists() || fileInfo->isWritable()) ? + qApp->translate("DFileCopyMoveJob", "Failed to open the file, cause: Permission denied") : + QString(); + } else { + errorstr = (!fileInfo->exists() || fileInfo->isWritable()) ? + qApp->translate("DFileCopyMoveJob", "Failed to open the file, cause: %1").arg(device->errorString()) : + QString(); + } + isErrorOccur = true; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(errortype, fileInfo, DAbstractFileInfoPointer(nullptr), errorstr); + if (action == DFileCopyMoveJob::RetryAction) { + QThread::msleep(THREAD_SLEEP_TIME); + } + } + } while (action == DFileCopyMoveJob::RetryAction && this->isRunning()); + + //当前错误处理完成 + if (isErrorOccur) { + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + isErrorOccur = false; + } + return action; +} +/*! + * \brief DFileCopyMoveJobPrivate::cleanCopySources 清理掉拷贝失败后的资源 + * \param data 拷贝时的缓存buffer + * \param fromDevice 源文件的iodevice + * \param toDevice 目标文件的iodevice + * \param isError 是否正在处理错误 + */ +void DFileCopyMoveJobPrivate::cleanCopySources(char *data, const QSharedPointer &fromDevice, + const QSharedPointer &toDevice, bool &isError) +{ + delete[] data; + data = nullptr; + fromDevice->close(); + toDevice->close(); + //当前错误处理完成 + if (isError) { + errorQueueHandled(); + isError = false; + } +} +/*! + * \brief DFileCopyMoveJobPrivate::gvfsFileRetry 处理smb文件在拷贝过程中断网,网络恢复后点击重试处理 + * \param data 拷贝的data + * \param isErrorOccur 是否当前在错误处理 + * \param currentPos 当前的文件文职 + * \param fromInfo 源文件的文件信息 + * \param toInfo 目标文件的文件信息 + * \param fromDevice 源文件的iodevice + * \param toDevice 目标文件的iodevice + * \param isWriteError 是写遇到错误重试 + * \return DFileCopyMoveJob::GvfsRetryType 网络文件重试的操作 + */ +DFileCopyMoveJob::GvfsRetryType DFileCopyMoveJobPrivate::gvfsFileRetry(char *data, bool &isErrorOccur, qint64 ¤tPos, const DAbstractFileInfoPointer &fromInfo, const DAbstractFileInfoPointer &toInfo, QSharedPointer &fromDevice, QSharedPointer &toDevice, const bool &isWriteError) +{ + if (fromInfo->isGvfsMountFile() + && !DFileService::instance()->checkGvfsMountfileBusy(toInfo->fileUrl(), false)) { + currentPos = reopenGvfsFiles(fromInfo, toInfo, fromDevice, toDevice, isWriteError); + if (currentPos == -1) { + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return DFileCopyMoveJob::GvfsRetrySkipAction; + } else if (currentPos == -2) { + cleanCopySources(data, fromDevice, toDevice, isErrorOccur); + return DFileCopyMoveJob::GvfsRetryCancelAction; + } else { + DUrl fromurl = fromInfo->fileUrl(); + DUrl tourl = toInfo->fileUrl(); + { + QMutexLocker lk(&m_emitUrlMutex); + m_emitUrl.insert(fromurl,tourl); + Q_EMIT q_ptr->currentJobChanged(m_emitUrl.lastKey(), m_emitUrl.last(), false); + } + return DFileCopyMoveJob::GvfsRetryNoAction; + } + } + return DFileCopyMoveJob::GvfsRetryDefault; +} +/*! + * \brief DFileCopyMoveJobPrivate::readAheadSourceFile 预读源文件 + * \param fromInfo 源文件的文件信息 + */ +void DFileCopyMoveJobPrivate::readAheadSourceFile(const DAbstractFileInfoPointer &fromInfo) +{ + if (!fromInfo) + return; + std::string stdStr = fromInfo->fileUrl().path().toUtf8().toStdString(); + int fromfd = open(stdStr.data(), O_RDONLY); + if (-1 != fromfd) { + readahead(fromfd, 0, static_cast(fromInfo->size())); + close(fromfd); + } +} +/*! + * \brief DFileCopyMoveJobPrivate::handleUnknowUrlError 阻塞处理UnknowUrlError的错误 + * \param fromInfo 源文件的文件信息 + * \param toInfo 目标文件的文件信息 + * \return + */ +bool DFileCopyMoveJobPrivate::handleUnknowUrlError(const DAbstractFileInfoPointer &fromInfo, const DAbstractFileInfoPointer &toInfo) +{ + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(DFileCopyMoveJob::UnknowUrlError, fromInfo, toInfo, "Failed on create file device"); + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + if (action == DFileCopyMoveJob::SkipAction) { + return true; + } else { + return false; + } +} +/*! + * \brief DFileCopyMoveJobPrivate::handleUnknowError 阻塞处理UnknowError的错误 + * \param fromInfo 源文件的文件信息 + * \param toInfo 目标文件的文件信息 + * \return + */ +bool DFileCopyMoveJobPrivate::handleUnknowError(const DAbstractFileInfoPointer &fromInfo, const DAbstractFileInfoPointer &toInfo, const QString &errorStr) +{ + DFileCopyMoveJob::Action action = DFileCopyMoveJob::NoAction; + //错误队列处理 + errorQueueHandling(); + action = setAndhandleError(DFileCopyMoveJob::UnknowError, fromInfo, toInfo, errorStr); + errorQueueHandled(action == DFileCopyMoveJob::SkipAction || + action == DFileCopyMoveJob::NoAction); + if (action == DFileCopyMoveJob::SkipAction) { + return true; + } else { + return false; + } +} +/*! + * \brief DFileCopyMoveJobPrivate::sendCopyInfo 发送当前拷贝的信息 + * \param fromInfo 源文件的信息 + * \param toInfo 目标文件的信息 + */ +void DFileCopyMoveJobPrivate::sendCopyInfo(const DAbstractFileInfoPointer &fromInfo, const DAbstractFileInfoPointer &toInfo) +{ + //多线程拷贝时发送当前拷贝信息 + if (m_refineStat != DFileCopyMoveJob::NoRefine){ + DUrl fromurl = fromInfo ? fromInfo->fileUrl() : DUrl(); + DUrl tourl = toInfo ? toInfo->fileUrl() : DUrl(); + QMutexLocker lk(&m_emitUrlMutex); + m_emitUrl.insert(fromurl,tourl); + Q_EMIT q_ptr->currentJobChanged(m_emitUrl.lastKey(), m_emitUrl.last(), false); + } +} + +void DFileCopyMoveJobPrivate::cleanDoCopyFileSource(char *data,const DAbstractFileInfoPointer &fromInfo,const DAbstractFileInfoPointer &toInfo, const QSharedPointer &fromDevice, const QSharedPointer &toDevice) +{ + if (!fromInfo || !toInfo || !toDevice || !fromDevice) { + qWarning() << "clean doCopyFile fun source failed! target url = " << targetUrl; + return; + } + // fix bug 63290 只有网络文件断开了网络才使用这个函数 + if (toInfo->isGvfsMountFile() && DFileService::instance()->checkGvfsMountfileBusy(toInfo->fileUrl(), false)) { + toDevice->closeWriteReadFailed(true); + } else { + toDevice->close(); + } + if (fromInfo->isGvfsMountFile() && DFileService::instance()->checkGvfsMountfileBusy(fromInfo->fileUrl(), false)) { + fromDevice->closeWriteReadFailed(true); + } else { + fromDevice->close(); + } + delete[] data; + data = nullptr; +} + +void DFileCopyMoveJobPrivate::initRefineState() +{ + // 不是优化就直接退出 + if (m_refineStat == DFileCopyMoveJob::NoRefine) + return; + // 不是拷贝mode就直接为NoRefine,走以前 + if (mode != DFileCopyMoveJob::CopyMode) { + m_refineStat = DFileCopyMoveJob::NoRefine; + return; + } + // 拷贝到移动设备 + if (m_isFileOnDiskUrls && !m_bDestLocal && m_isTagFromBlockDevice.load()) { + m_refineStat = DFileCopyMoveJob::RefineBlock; + return; + } + // 和系统同磁盘的目录 + if (m_isFileOnDiskUrls && m_bDestLocal) { + m_refineStat = DFileCopyMoveJob::RefineLocal; + return; + } + // 其他都走以前的流程 + m_refineStat = DFileCopyMoveJob::NoRefine; + return; +} + +//! 用于保存回收站剪切出去的文件在回收站的原始路径 +void DFileCopyMoveJob::setCurTrashData(QVariant fileNameList) +{ + Q_D(DFileCopyMoveJob); + d->setCutTrashData(fileNameList); +} + +void DFileCopyMoveJob::setProgressShow(const bool &isShow) +{ + Q_D(DFileCopyMoveJob); + d->m_isProgressShow.store(isShow); +} + +void DFileCopyMoveJob::copyBigFileOnDiskJobWait() +{ + Q_D(DFileCopyMoveJob); + + d->m_isCopyLargeFileOnDiskWait = true; +} + +void DFileCopyMoveJob::copyBigFileOnDiskJobRun() +{ + Q_D(DFileCopyMoveJob); + + d->m_isCopyLargeFileOnDiskWait = false; + d->m_waitConditionCopyLargeFileOnDisk.wakeAll(); +} + +DFileCopyMoveJob::Actions DFileCopyMoveJob::supportActions(DFileCopyMoveJob::Error error) +{ + switch (error) { + case PermissionError: + case OpenError: + case ReadError: + case WriteError: + case SymlinkError: + case MkdirError: + case ResizeError: + case RemoveError: + case RenameError: + case SeekError: + case IntegrityCheckingError: + return SkipAction | RetryAction | CancelAction; + case UnknowError: + case SymlinkToGvfsError: + case SpecialFileError: + return SkipAction | CancelAction; + case FileSizeTooBigError: + return SkipAction | CancelAction | EnforceAction; + case NotEnoughSpaceError: + return SkipAction | RetryAction | CancelAction | EnforceAction; + case FileExistsError: + return SkipAction | ReplaceAction | CoexistAction | CancelAction; + case DirectoryExistsError: + return SkipAction | MergeAction | CoexistAction | CancelAction; + case TargetReadOnlyError: + return SkipAction | EnforceAction; + case TargetIsSelfError: + return SkipAction | EnforceAction; + default: + break; + } + + return CancelAction; +} + +void DFileCopyMoveJob::start(const DUrlList &sourceUrls, const DUrl &targetUrl) +{ + Q_ASSERT(!isRunning()); + Q_D(DFileCopyMoveJob); + + if (d->mode == UnknowMode) { + qInfo() << "error mode UnknowMode!"; + return; + } + + d->sourceUrlList = sourceUrls; + d->targetUrl = targetUrl; + d->m_isFileOnDiskUrls = sourceUrls.isEmpty() ? true : + FileUtils::isFileOnDisk(sourceUrls.first().path()); + if (!d->m_isFileOnDiskUrls) { + if (d->fileStatistics->isRunning()) { + d->fileStatistics->stop(); + d->fileStatistics->wait(); + } + d->fileStatistics->start(sourceUrls); + } + + // DFileStatisticsJob 统计数量很慢,自行统计 + QPointer dp = this; + QtConcurrent::run([sourceUrls, dp, d]() { + if (dp.isNull()) + return; + if (d->mode == MoveMode || d->mode == CutMode) { + d->countStatisticsFinished = false; + for (const auto &url : sourceUrls) { + QStringList list; + FileUtils::recurseFolder(url.toLocalFile(), "", &list); + if (!dp.isNull()) + d->totalMoveFilesCount += (list.size() + 1); // +1 的目的是当前选中的目录要统计到 + else + break; + } + if (!dp.isNull()) + d->countStatisticsFinished = true; + } + }); + + QThread::start(); +} + +void DFileCopyMoveJob::stop() +{ + + Q_D(DFileCopyMoveJob); + + QMutexLocker lk(&d->m_stopMutex); + + if (d->state == StoppedState) { + return; + } + + d->fileStatistics->stop(); + + QMetaObject::invokeMethod(d->updateSpeedTimer, "stop"); + + d->setState(StoppedState); + d->waitCondition.wakeAll(); + //停止清理掉自己的大文件拷贝 + copyBigFileOnDiskJobRun(); + + //清理所有的拷贝小文件的错误队列 + { + QMutexLocker lk(&d->m_errorQueueMutex); + d->m_errorQueue.clear(); + d->m_errorCondition.wakeAll(); + } + + d->stopAllDeviceOperation(); + + d->clearThreadPool(); + + d->cancelReadFileDealWriteThread(); +} + +void DFileCopyMoveJob::togglePause() +{ + Q_D(DFileCopyMoveJob); + + if (d->state == StoppedState) { + return; + } + + d->updateProgress(); + + d->fileStatistics->togglePause(); + + if (d->state == PausedState) { + d->setState(RunningState); + d->waitCondition.wakeAll(); + } else { + d->setState(PausedState); + } +} + +void DFileCopyMoveJob::setMode(DFileCopyMoveJob::Mode mode) +{ + Q_ASSERT(!isRunning()); + Q_D(DFileCopyMoveJob); + + d->mode = mode; +} + +void DFileCopyMoveJob::setFileHints(FileHints fileHints) +{ + Q_D(DFileCopyMoveJob); + Q_ASSERT(d->state != RunningState); + + d->fileHints = fileHints; + d->fileStatistics->setFileHints(fileHints.testFlag(FollowSymlink) ? DFileStatisticsJob::FollowSymlink : DFileStatisticsJob::FileHints()); +} + +void DFileCopyMoveJob::taskDailogClose() +{ + Q_D(DFileCopyMoveJob); + + d->m_bTaskDailogClose = true; +} + +DFileCopyMoveJob::DFileCopyMoveJob(DFileCopyMoveJobPrivate *dd, QObject *parent) + : QThread(parent) + , d_d_ptr(dd) +{ + dd->fileStatistics = new DFileStatisticsJob(this); + dd->updateSpeedTimer = new QTimer(this); + + connect(dd->fileStatistics, &DFileStatisticsJob::finished, this, &DFileCopyMoveJob::fileStatisticsFinished, Qt::DirectConnection); + connect(dd->updateSpeedTimer, SIGNAL(timeout()), this, SLOT(_q_updateProgress()), Qt::DirectConnection); +} + +void DFileCopyMoveJob::run() +{ + Q_D(DFileCopyMoveJob); + + //记录关键信息 + qInfo() << "start job, mode:" << d->mode << "file url list:" << d->sourceUrlList << ", target url:" << d->targetUrl; + qint64 timesec = QDateTime::currentMSecsSinceEpoch(); + d->m_sart = timesec; + d->unsetError(); + d->setState(RunningState); + //远程下载 + if (d->mode == RemoteMode) { + d->sourceUrlList = DUrl::fromQUrlList(DFMGlobal::instance()->getRemoteUrls()); + qInfo() << "remote copy source urls list:" << d->sourceUrlList; + d->mode = CopyMode; + } + + // 本地文件使用 countAllCopyFile 统计大小非常快, 因此不必开辟线程去统计大小. 同步等待文件大小统计完成 + // 网络文件使用以下方式反而会更慢, 因此使用线程统计类 + if (d->targetUrl.isValid() && d->m_isFileOnDiskUrls) { + d->totalsize = FileUtils::totalSize(d->sourceUrlList,d->m_currentDirSize,d->totalfilecount); + d->m_isCountSizeOver = true; + emit fileStatisticsFinished(); + } + + d->completedDirectoryList.clear(); + d->completedFileList.clear(); + d->targetUrlList.clear(); + d->completedDataSize = 0; + d->completedDataSizeOnBlockDevice = 0; + d->completedFilesCount = 0; + d->tid = qt_gettid(); + + DAbstractFileInfoPointer target_info; + bool mayExecSync = false; + QPointer me = this; + + if (d->targetUrl.isValid()) { + target_info = DFileService::instance()->createFileInfo(nullptr, d->targetUrl, false); + + if (!target_info) { + d->setError(UnknowUrlError); + stop(); + goto end; + } + + if (!target_info->exists()) { + d->setError(NonexistenceError, "The target directory non-exists or not permission"); + stop(); + goto end; + } + + if (!target_info->isDir()) { + d->setError(UnknowError, "The target url is not directory"); + stop(); + goto end; + } + + // reset + d->canUseWriteBytes = 0; + d->targetIsRemovable = 0; + d->targetLogSecionSize = 512; + d->targetDeviceStartSectorsWritten = -1; + d->targetSysDevPath.clear(); + d->targetRootPath.clear(); + d->m_isTagGvfsFile = target_info->isGvfsMountFile(); + + //检查是否需要每次读写都去同步 + d->checkTagetNeedSync(); + //检查目标目录是否是块设备 + d->checkTagetIsFromBlockDevice(); + + + QScopedPointer targetStorageInfo(DFileService::instance()->createStorageInfo(nullptr, d->targetUrl)); + + if (targetStorageInfo) { + d->targetRootPath = targetStorageInfo->rootPath(); + QString rootpath = d->targetRootPath; + d->m_bDestLocal = FileUtils::isFileOnDisk(rootpath); + + qCDebug(fileJob(), "Target block device: \"%s\", Root Path: \"%s\"", + targetStorageInfo->device().constData(), qPrintable(d->targetRootPath)); + + if (targetStorageInfo->isLocalDevice()) { + d->canUseWriteBytes = targetStorageInfo->fileSystemType().startsWith("ext"); + if (targetStorageInfo->fileSystemType().startsWith("vfat") + || targetStorageInfo->fileSystemType().startsWith("ntfs") + || targetStorageInfo->fileSystemType().startsWith("btrfs") + || targetStorageInfo->fileSystemType().startsWith("fuseblk")) + d->m_openFlag = d->m_openFlag | O_DIRECT; + + if (d->canUseWriteBytes && !d->m_bDestLocal) + d->m_refineStat = NoRefine; + + if (!d->canUseWriteBytes) { + const QByteArray dev_path = targetStorageInfo->device(); + + QProcess process; + + process.start("lsblk", {"-niro", "MAJ:MIN,HOTPLUG,LOG-SEC", dev_path}, QIODevice::ReadOnly); + + if (process.waitForFinished(3000)) { + if (process.exitCode() == 0) { + const QByteArray &data = process.readAllStandardOutput(); + const QByteArrayList &list = data.split(' '); + + qCDebug(fileJob(), "lsblk result data: \"%s\"", data.constData()); + + if (list.size() == 3) { + d->targetSysDevPath = "/sys/dev/block/" + list.first(); + d->targetIsRemovable = list.at(1) == "1"; + + bool ok = false; + d->targetLogSecionSize = static_cast(list.at(2).toInt(&ok)); + + if (!ok) { + d->targetLogSecionSize = 512; + + qCWarning(fileJob(),); + } + + if (d->targetIsRemovable) { + d->targetDeviceStartSectorsWritten = d->getSectorsWritten(); + } + + qCDebug(fileJob(), "Block device path: \"%s\", Sys dev path: \"%s\", Is removable: %d, Log-Sec: %d", + qPrintable(dev_path), qPrintable(d->targetSysDevPath), bool(d->targetIsRemovable), d->targetLogSecionSize); + } else { + qCWarning(fileJob(), "Failed on parse the lsblk result data, data: \"%s\"", data.constData()); + } + } else { + qCWarning(fileJob(), "Failed on exec lsblk command, exit code: %d, error message: \"%s\"", process.exitCode(), process.readAllStandardError().constData()); + } + } + } + + qCDebug(fileJob(), "canUseWriteBytes = %d, targetIsRemovable = %d", bool(d->canUseWriteBytes), bool(d->targetIsRemovable)); + } + } + } else if (d->mode == CopyMode || d->mode == CutMode) { + d->setError(UnknowError, "Invalid target url"); + goto end; + } else { + // remove mode + qCDebug(fileJob(), "remove mode"); + } + //初始化优化状态 + d->initRefineState(); + + for (DUrl &source : d->sourceUrlList) { + if (!d->stateCheck()) { + goto end; + } + + // fix: 搜索列表中的文件路径需要转化为原始路径 + if (source.isSearchFile()) { + source = source.searchedFileUrl(); + } + + //! fix: 将保险箱路径转换为本地路径 + if (source.isVaultFile()) { + source = VaultController::vaultToLocalUrl(source); + } + + //! fix: 将avfs转化为本地路径 + if (source.isAVFSFile()) { + source = AVFSFileController::realUrl(source); + } + + const DAbstractFileInfoPointer &source_info = DFileService::instance()->createFileInfo(nullptr, source, false); + if (!source_info) { + qWarning() << "Url not yet supported: " << source; + continue; + } + const DUrl &parent_url = source_info->parentUrl(); + bool enter_dir = d->targetUrl.isValid() && (d->directoryStack.isEmpty() || d->directoryStack.top().url.first != parent_url); + + if (enter_dir) { + d->enterDirectory(source, d->targetUrl); + } + if (!d->process(source, source_info, target_info)) { + stop(); + goto end; + } + + // 只要有一个不是skip或者cancel就执行一下sync + if (!mayExecSync && d->getLastErrorAction() != SkipAction && + d->getLastErrorAction() != CancelAction) { + mayExecSync = true; + } + + if (enter_dir) { + d->leaveDirectory(); + } + + DUrl target_url; + + if (!d->completedFileList.isEmpty()) { + if (d->completedFileList.last().first == source) { + target_url = d->completedFileList.last().second; + } + } + + if (!d->completedDirectoryList.isEmpty()) { + if (d->completedDirectoryList.last().first == source) { + target_url = d->completedDirectoryList.last().second; + } + } + + d->targetUrlList << target_url; + + Q_EMIT finished(source, target_url); + + } + if (d->m_refineStat == NoRefine) + d->setError(NoError); + +end: + //设置优化拷贝线程结束 + d->setRefineCopyProccessSate(ReadFileProccessOver); + //等待线程池结束,等待异步写线程结束 + d->waitRefineThreadFinish(); + + if (!d->m_bDestLocal && d->targetIsRemovable && mayExecSync && + d->state != DFileCopyMoveJob::StoppedState) { //主动取消时state已经被设置为stop了 + // 任务完成后执行 sync 同步数据到硬盘, 同时将状态改为 SleepState,用于定时器更新进度和速度信息 + if (d->m_isVfat) { + d->setState(IOWaitState); + int syncRet = 0; + d->m_syncResult = QtConcurrent::run([me, &d, &syncRet]() { + //! 外设或远程设备在同步数据时发送sendDataSyncing信号在拷贝任务对话框中显示数据同步种与即将完成 + Q_EMIT me->sendDataSyncing(tr("Syncing data"), tr("Please wait")); + qInfo() << "sync to block disk and target path = " << d->targetRootPath; + syncRet = QProcess::execute("sync", {"-f", d->targetRootPath}); + }); + // 检测同步时是否被停止,若停止则立即跳出 + while (!d->m_syncResult.isFinished()) { + if (d->state == DFileCopyMoveJob::StoppedState) { + qDebug() << "stop sync"; + goto end; + } + QThread::msleep(10); + } + + // 同步结果检查只针对拷贝 + if (d->mode == CopyMode && syncRet != 0) { + DFileCopyMoveJob::Action action = d->setAndhandleError(DFileCopyMoveJob::OpenError, target_info, DAbstractFileInfoPointer(nullptr), + "Failed to synchronize to disk u!"); + + if (action == DFileCopyMoveJob::RetryAction) { + goto end; + } + } + // 恢复状态 + if (d->state == IOWaitState) { + d->setState(RunningState); + } + } + else if (d->mode == CopyMode){ + while (d->state != DFileCopyMoveJob::StoppedState && d->lastProgress < 1) { + QThread::msleep(100); + } + } + } + + d->fileStatistics->stop(); + d->setState(StoppedState); + + if (d->error == NoError) { + d->updateSpeedTimer->stop(); + Q_EMIT progressChanged(1, d->completedDataSize); + // fix bug 62822 如果进度条显示了,才沉睡0.3秒,来显示进度都100% + if (d->m_isProgressShow.load()) + QThread::msleep(300); + + } + + qInfo() << "job finished, error:" << error() << ", message:" << errorString() << QDateTime::currentMSecsSinceEpoch() - timesec; +} + +QString DFileCopyMoveJob::Handle::getNewFileName(DFileCopyMoveJob *job, const DAbstractFileInfoPointer sourceInfo) +{ + Q_UNUSED(job) + + static QMutex mutex; + QMutexLocker lk(&mutex); + + return job->d_func()->formatFileName(sourceInfo->fileName()); +} + +QString DFileCopyMoveJob::Handle::getNonExistsFileName(const DAbstractFileInfoPointer sourceInfo, const DAbstractFileInfoPointer targetDirectory) +{ + return DFileCopyMoveJobPrivate::getNewFileName(sourceInfo, targetDirectory); +} + +DFM_END_NAMESPACE + +#include "moc_dfilecopymovejob.cpp" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilecopymovejob.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilecopymovejob.h new file mode 100644 index 0000000..7c71086 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilecopymovejob.h @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFILECOPYMOVEJOB_H +#define DFILECOPYMOVEJOB_H + +#include +#include +#include "dabstractfileinfo.h" + +typedef QExplicitlySharedDataPointer DAbstractFileInfoPointer; + +DFM_BEGIN_NAMESPACE + +class DFileCopyMoveJobPrivate; +class DFileCopyMoveJob : public QThread +{ + Q_OBJECT + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_d_ptr), DFileCopyMoveJob) + + Q_PROPERTY(Mode mode READ mode WRITE setMode) +// Q_PROPERTY(State state READ state NOTIFY stateChanged) + Q_PROPERTY(Error error READ error NOTIFY errorChanged) + Q_PROPERTY(FileHints fileHints READ fileHints WRITE setFileHints) + Q_PROPERTY(QString errorString READ errorString CONSTANT) + +public: + enum Mode { + CopyMode, + MoveMode, + CutMode, + RemoteMode, + UnknowMode = 255 + }; + + Q_ENUM(Mode) + + enum State { + StoppedState, + RunningState, + PausedState, + SleepState, + IOWaitState // 可能会长时间等待io的状态 + }; + + Q_ENUM(State) + + enum RefineState { + NoRefine, + RefineLocal, + RefineBlock + }; + + Q_ENUM(RefineState) + + enum RefineCopyProccessSate { + NoProccess, + OpenFromFileProccessOver, + ReadFileProccessOver, + }; + + Q_ENUM(RefineCopyProccessSate) + + + enum Error { + NoError, + CancelError, + PermissionError, + SpecialFileError, + FileExistsError, + DirectoryExistsError, + OpenError, + ReadError, + WriteError, + SymlinkError, + MkdirError, + ResizeError, + MmapError, + RemoveError, + RenameError, + SymlinkToGvfsError, + UnknowUrlError, + NonexistenceError, + IntegrityCheckingError, + FileSizeTooBigError, + NotEnoughSpaceError, + TargetReadOnlyError, + TargetIsSelfError, + NotSupportedError, + PermissionDeniedError, + SeekError, + UnknowError, + }; + + Q_ENUM(Error) + + enum FileHint { + NoHint = 0x00, + FollowSymlink = 0x01, + Attributes = 0x02, // 复制文件时携带它的扩展属性 + AttributesOnly = 0x04, // 只复制文件的扩展属性 +// CreateParents = 0x08, // 复制前在目标文件夹创建来源文件路径中的所有目录 + RemoveDestination = 0x10, // 复制文件前先删除已存在的 + ResizeDestinationFile = 0x20, // 复制文件前对目标文件执行resize操作 + DontIntegrityChecking = 0x40, // 复制文件时不进行完整性校验 + DontFormatFileName = 0x80, // 不要自动处理文件名中的非法字符 + DontSortInode = 0x100, // 不要对目录中的文件按inode排序 + ForceDeleteFile = 0x200 // 强制删除文件夹(去除文件夹的只读权限) + }; + + Q_ENUM(FileHint) + Q_DECLARE_FLAGS(FileHints, FileHint) + + enum Action { + NoAction = 0x00, + RetryAction = 0x01, + ReplaceAction = 0x02, + MergeAction = 0x04, + SkipAction = 0x08, + CoexistAction = 0x10, + CancelAction = 0x20, + EnforceAction = 0x40 + }; + + Q_ENUM(Action) + Q_DECLARE_FLAGS(Actions, Action) + + enum GvfsRetryType { + GvfsRetryNoAction = 0x01, + GvfsRetrySkipAction = 0x02, + GvfsRetryCancelAction = 0x03, + GvfsRetryDefault = 0x04 + }; + + Q_ENUM(GvfsRetryType) + Q_DECLARE_FLAGS(GvfsRetryTypes, Action) + + class Handle + { + public: + virtual ~Handle() {} + virtual Action handleError(DFileCopyMoveJob *job, Error error, + const DAbstractFileInfoPointer sourceInfo, + const DAbstractFileInfoPointer targetInfo) = 0; + virtual QString getNewFileName(DFileCopyMoveJob *job, const DAbstractFileInfoPointer sourceInfo); + virtual QString getNonExistsFileName(const DAbstractFileInfoPointer sourceInfo, + const DAbstractFileInfoPointer targetDirectory); + }; + + explicit DFileCopyMoveJob(QObject *parent = nullptr); + ~DFileCopyMoveJob() override; + + Handle *errorHandle() const; + void setErrorHandle(Handle *handle, QThread *threadOfHandle = nullptr); + + void setActionOfErrorType(Error error, Action action); + + Mode mode() const; + State state() const; + Error error() const; + FileHints fileHints() const; + QString errorString() const; + + DUrlList sourceUrlList() const; + DUrlList targetUrlList() const; + DUrl targetUrl() const; + + bool fileStatisticsIsFinished() const; + qint64 totalDataSize() const; + int totalFilesCount() const; + QList > completedFiles() const; + QList > completedDirectorys() const; + //获取当前是否可以显示进度条 + bool isCanShowProgress() const; + + void setRefine(const RefineState &refinestat); + + void setCurTrashData(QVariant fileNameList); + //设置当前拷贝显示了进度条 + void setProgressShow(const bool &isShow); + void copyBigFileOnDiskJobWait(); + void copyBigFileOnDiskJobRun(); + + static Actions supportActions(Error error); + +public Q_SLOTS: + void start(const DUrlList &sourceUrls, const DUrl &targetUrl); + void stop(); + void togglePause(); + + void setMode(Mode mode); + void setFileHints(FileHints fileHints); + void taskDailogClose(); + +Q_SIGNALS: + // 此类工作在一个新的线程中,信号不要以引用的方式传递参数,容易出现一些较为诡异的崩溃问题 + // 问题现象一般为,槽函数中的参数是个无效的对象(内存中已被销毁),不知是否和槽函数形参也为 + // 引用类型有关 + void stateChanged(State state); + void errorCanClear(); + void errorChanged(Error error); + void currentJobChanged(const DUrl from, const DUrl to, const bool iserroeroc); + void finished(const DUrl from, const DUrl to); + void completedFilesCountChanged(int count); + void fileStatisticsFinished(); + void progressChanged(qreal progress, qint64 writeData); + void currentFileProgressChanged(qreal progress, qint64 writeData); + void speedUpdated(qint64 speed); + void stopAllGioDervic(); + + // 拷贝进度条显示100%时提示数据同步 信号 + void sendDataSyncing(QString syncTip, QString over); + +protected: + DFileCopyMoveJob(DFileCopyMoveJobPrivate *dd, QObject *parent); + + void run() override; + + QScopedPointer d_d_ptr; + +private: + using QThread::start; + using QThread::terminate; + using QThread::quit; + using QThread::exit; + + Q_PRIVATE_SLOT(d_func(), void _q_updateProgress()) +}; + +DFM_END_NAMESPACE + +Q_DECLARE_OPERATORS_FOR_FLAGS(DFM_NAMESPACE::DFileCopyMoveJob::Actions) +Q_DECLARE_METATYPE(DFM_NAMESPACE::DFileCopyMoveJob::Error) + +#endif // DFILECOPYMOVEJOB_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfiledevice.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfiledevice.cpp new file mode 100644 index 0000000..64c609e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfiledevice.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dfiledevice.h" +#include "private/dfiledevice_p.h" + +DFM_BEGIN_NAMESPACE + +DFileDevice::~DFileDevice() +{ + +} + +DUrl DFileDevice::fileUrl() const +{ + Q_D(const DFileDevice); + + return d->url; +} + +bool DFileDevice::setFileUrl(const DUrl &url) +{ + Q_D(DFileDevice); + + d->url = url; + + return true; +} + +int DFileDevice::handle() const +{ + return -1; +} + +bool DFileDevice::resize(qint64 size) +{ + Q_UNUSED(size) + + return false; +} + +bool DFileDevice::flush() +{ + return false; +} + +bool DFileDevice::syncToDisk(bool isVfat) +{ + Q_UNUSED(isVfat); + return false; +} + +void DFileDevice::closeWriteReadFailed(const bool bwrite) +{ + Q_UNUSED(bwrite); +} + +void DFileDevice::cancelAllOperate() +{ + +} + +DFileDevice::DFileDevice(QObject *parent) + : DFileDevice(*new DFileDevicePrivate(this), parent) +{ + +} + +DFileDevice::DFileDevice(DFileDevicePrivate &dd, QObject *parent) + : QIODevice(parent) + , d_ptr(&dd) +{ + +} + +DFileDevicePrivate::DFileDevicePrivate(DFileDevice *qq) + : q_ptr(qq) +{ + +} + +DFileDevicePrivate::~DFileDevicePrivate() +{ + +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfiledevice.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfiledevice.h new file mode 100644 index 0000000..6d245d2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfiledevice.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFILEDEVICE_H +#define DFILEDEVICE_H + +#include + +#include + +DFM_BEGIN_NAMESPACE + +class DFileDevicePrivate; +class DFileDevice : public QIODevice +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DFileDevice) + +public: + ~DFileDevice(); + + DUrl fileUrl() const; + + virtual int handle() const; + virtual bool resize(qint64 size); + virtual bool flush(); + virtual bool syncToDisk(bool isVfat = false); + virtual void closeWriteReadFailed(const bool bwrite); + virtual void cancelAllOperate(); + +protected: + virtual bool setFileUrl(const DUrl &url); + + explicit DFileDevice(QObject *parent = nullptr); + DFileDevice(DFileDevicePrivate &dd, QObject *parent = nullptr); + + QScopedPointer d_ptr; +}; + +DFM_END_NAMESPACE + +#endif // DFILEDEVICE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilehandler.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilehandler.cpp new file mode 100644 index 0000000..452a57f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilehandler.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dfilehandler.h" +#include "private/dfilehandler_p.h" + +DFM_BEGIN_NAMESPACE + +DFileHandlerPrivate::DFileHandlerPrivate(DFileHandler *qq) + : q_ptr(qq) +{ + +} + +void DFileHandlerPrivate::setErrorString(const QString &es) +{ + errorString = es; +} + +DFileHandler::~DFileHandler() +{ + +} + +QString DFileHandler::errorString() const +{ + Q_D(const DFileHandler); + + return d->errorString; +} + +DFileHandler::DFileHandler() + : DFileHandler(*new DFileHandlerPrivate(this)) +{ + +} + +DFileHandler::DFileHandler(DFileHandlerPrivate &dd) + : d_ptr(&dd) +{ + +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilehandler.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilehandler.h new file mode 100644 index 0000000..a91a007 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilehandler.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFILEHANDLER_H +#define DFILEHANDLER_H + +#include + +DFM_BEGIN_NAMESPACE + +class DFileHandlerPrivate; +class DFileHandler +{ +public: + virtual ~DFileHandler(); + + QString errorString() const; + + virtual bool exists(const DUrl &url) = 0; + virtual bool touch(const DUrl &url) = 0; + virtual bool mkdir(const DUrl &url) = 0; + virtual bool mkpath(const DUrl &url) = 0; + virtual bool link(const QString &path, const DUrl &linkUrl) = 0; + virtual bool remove(const DUrl &url) = 0; + virtual bool rmdir(const DUrl &url) = 0; + virtual bool rename(const DUrl &url, const DUrl &newUrl) = 0; + virtual bool setPermissions(const DUrl &url, QFileDevice::Permissions permissions) = 0; + virtual bool setFileTime(const DUrl &url, const QDateTime &accessDateTime, const QDateTime &lastModifiedTime) = 0; + +protected: + DFileHandler(); + explicit DFileHandler(DFileHandlerPrivate &dd); + + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(DFileHandler) +}; + +DFM_END_NAMESPACE +Q_DECLARE_METATYPE(DFM_NAMESPACE::DFileHandler*) + +#endif // DFILEHANDLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfileiodeviceproxy.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfileiodeviceproxy.cpp new file mode 100644 index 0000000..7a916b9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfileiodeviceproxy.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dfileiodeviceproxy.h" +#include "private/dfileiodeviceproxy_p.h" + +DFM_BEGIN_NAMESPACE + +DFileIODeviceProxyPrivate::DFileIODeviceProxyPrivate(DFileIODeviceProxy *qq) + : DFileDevicePrivate(qq) +{ + +} + +DFileIODeviceProxy::DFileIODeviceProxy(QIODevice *device, QObject *parent) + : DFileIODeviceProxy(*new DFileIODeviceProxyPrivate(this), parent) +{ + d_func()->device = device; +} + +DFileIODeviceProxy::~DFileIODeviceProxy() +{ + close(); +} + +void DFileIODeviceProxy::setDevice(QIODevice *device) +{ + Q_D(DFileIODeviceProxy); + + d->device = device; +} + +QIODevice *DFileIODeviceProxy::device() const +{ + Q_D(const DFileIODeviceProxy); + + return d->device; +} + +#define CALL_PROXY(fun, ...)\ + const auto && ret = d_func()->device->fun(__VA_ARGS__);\ + setErrorString(d_func()->device->errorString());\ + return ret; + +#define CALL_PROXY_CONST(fun, ...)\ + return d_func()->device->fun(__VA_ARGS__); + +bool DFileIODeviceProxy::isSequential() const +{ + CALL_PROXY_CONST(isSequential) +} + +bool DFileIODeviceProxy::open(QIODevice::OpenMode mode) +{ + Q_D(DFileIODeviceProxy); + + if (d->device) { + if (!d->device->open(mode)) { + setErrorString(d->device->errorString()); + + return false; + } + } + + return DFileDevice::open(mode); +} + +void DFileIODeviceProxy::close() +{ + Q_D(DFileIODeviceProxy); + + DFileDevice::close(); + if (d->device) { + d->device->close(); + setErrorString(d->device->errorString()); + } +} + +qint64 DFileIODeviceProxy::pos() const +{ + CALL_PROXY_CONST(pos) +} + +qint64 DFileIODeviceProxy::size() const +{ + CALL_PROXY_CONST(size) +} + +bool DFileIODeviceProxy::seek(qint64 pos) +{ + CALL_PROXY(seek, pos) +} + +bool DFileIODeviceProxy::atEnd() const +{ + CALL_PROXY_CONST(atEnd) +} + +bool DFileIODeviceProxy::reset() +{ + CALL_PROXY(reset) +} + +qint64 DFileIODeviceProxy::bytesAvailable() const +{ + CALL_PROXY_CONST(bytesAvailable) +} + +qint64 DFileIODeviceProxy::bytesToWrite() const +{ + CALL_PROXY_CONST(bytesToWrite) +} + +bool DFileIODeviceProxy::waitForReadyRead(int msecs) +{ + CALL_PROXY(waitForReadyRead, msecs) +} + +bool DFileIODeviceProxy::waitForBytesWritten(int msecs) +{ + CALL_PROXY(waitForBytesWritten, msecs) +} + +DFileIODeviceProxy::DFileIODeviceProxy(DFileIODeviceProxyPrivate &dd, QObject *parent) + : DFileDevice(dd, parent) +{ + +} + +qint64 DFileIODeviceProxy::readData(char *data, qint64 maxlen) +{ + CALL_PROXY(read, data, maxlen) +} + +qint64 DFileIODeviceProxy::readLineData(char *data, qint64 maxlen) +{ + CALL_PROXY(readLine, data, maxlen) +} + +qint64 DFileIODeviceProxy::writeData(const char *data, qint64 len) +{ + CALL_PROXY(write, data, len) +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfileiodeviceproxy.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfileiodeviceproxy.h new file mode 100644 index 0000000..781b8f6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfileiodeviceproxy.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFILEIODEVICEPROXY_H +#define DFILEIODEVICEPROXY_H + +#include + +DFM_BEGIN_NAMESPACE + +class DFileIODeviceProxyPrivate; +class DFileIODeviceProxy : public DFileDevice +{ + Q_DECLARE_PRIVATE(DFileIODeviceProxy) + +public: + explicit DFileIODeviceProxy(QIODevice *device = nullptr, QObject *parent = nullptr); + ~DFileIODeviceProxy() override; + + void setDevice(QIODevice *device); + QIODevice *device() const; + + bool isSequential() const override; + + bool open(OpenMode mode) override; + void close() override; + + qint64 pos() const override; + qint64 size() const override; + bool seek(qint64 pos) override; + bool atEnd() const override; + bool reset() override; + + qint64 bytesAvailable() const override; + qint64 bytesToWrite() const override; + + bool waitForReadyRead(int msecs) override; + bool waitForBytesWritten(int msecs) override; + +protected: + DFileIODeviceProxy(DFileIODeviceProxyPrivate &dd, QObject *parent = nullptr); + + qint64 readData(char *data, qint64 maxlen) override; + qint64 readLineData(char *data, qint64 maxlen) override; + qint64 writeData(const char *data, qint64 len) override; +}; + +DFM_END_NAMESPACE + +#endif // DFILEIODEVICEPROXY_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilestatisticsjob.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilestatisticsjob.cpp new file mode 100644 index 0000000..ec62314 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilestatisticsjob.cpp @@ -0,0 +1,474 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dfilestatisticsjob.h" +#include "dfileservices.h" +#include "dabstractfileinfo.h" +#include "dstorageinfo.h" +#include "shutil/fileutils.h" +#include + +#include +#include +#include +#include + + +DFM_BEGIN_NAMESPACE + +class DFileStatisticsJobPrivate +{ +public: + DFileStatisticsJobPrivate(DFileStatisticsJob *qq); + ~DFileStatisticsJobPrivate(); + + void setState(DFileStatisticsJob::State s); + + bool jobWait(); + bool stateCheck(); + + void processFile(const DUrl &url, QQueue &directoryQueue); + + DFileStatisticsJob *q_ptr; + QTimer *notifyDataTimer; + + QAtomicInt state = DFileStatisticsJob::StoppedState; + DFileStatisticsJob::FileHints fileHints; + + DUrlList sourceUrlList; + QWaitCondition waitCondition; + + QAtomicInteger totalSize = 0; + // fix bug 30548 ,以为有些文件大小为0,文件夹为空,size也为零,重新计算显示大小 + QAtomicInteger totalProgressSize = 0; + QAtomicInt filesCount = 0; + QAtomicInt directoryCount = 0; +}; + +DFileStatisticsJobPrivate::DFileStatisticsJobPrivate(DFileStatisticsJob *qq) + : q_ptr(qq) + , notifyDataTimer(nullptr) +{ + +} + +DFileStatisticsJobPrivate::~DFileStatisticsJobPrivate() +{ + if (notifyDataTimer) { + notifyDataTimer->stop(); + notifyDataTimer->deleteLater(); + } +} + +void DFileStatisticsJobPrivate::setState(DFileStatisticsJob::State s) +{ + if (s == state) { + return; + } + + state = s; + + if (notifyDataTimer->thread() && notifyDataTimer->thread()->loopLevel() <= 0) { + qWarning() << "The thread of notify data timer no event loop" << notifyDataTimer->thread(); + } + + if (s == DFileStatisticsJob::RunningState) { + QMetaObject::invokeMethod(notifyDataTimer, "start", Q_ARG(int, 500)); + } else { + QMetaObject::invokeMethod(notifyDataTimer, "stop"); + + if (s == DFileStatisticsJob::StoppedState) { + Q_EMIT q_ptr->dataNotify(totalSize, filesCount, directoryCount); + } + } + + Q_EMIT q_ptr->stateChanged(s); +} + +bool DFileStatisticsJobPrivate::jobWait() +{ + QMutex lock; + + lock.lock(); + waitCondition.wait(&lock); + lock.unlock(); + + return state == DFileStatisticsJob::RunningState; +} + +bool DFileStatisticsJobPrivate::stateCheck() +{ + if (state == DFileStatisticsJob::RunningState) { + return true; + } + + if (state == DFileStatisticsJob::PausedState) { + if (!jobWait()) { + return false; + } + } else if (state == DFileStatisticsJob::StoppedState) { + return false; + } + + return true; +} + +void DFileStatisticsJobPrivate::processFile(const DUrl &url, QQueue &directoryQueue) +{ + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, url); + + if (!info) { + qDebug() << "Url not yet supported: " << url; + return; + } + + qint64 size = 0; + + if (info->isFile()) { + do { + // ###(zccrs): skip the file,os file + if (info->fileUrl() == DUrl::fromLocalFile("/proc/kcore") || info->fileUrl() == DUrl::fromLocalFile("/dev/core")) { + break; + } + //skip os file Shortcut + if (info->isSymLink() && (info->symlinkTargetPath() == QStringLiteral("/proc/kcore") || info->symlinkTargetPath() == QStringLiteral("/dev/core"))) + { + break; + } + + const DAbstractFileInfo::FileType type = info->fileType(); + + if (type == DAbstractFileInfo::CharDevice && !fileHints.testFlag(DFileStatisticsJob::DontSkipCharDeviceFile)) { + break; + } + + if (type == DAbstractFileInfo::BlockDevice && !fileHints.testFlag(DFileStatisticsJob::DontSkipBlockDeviceFile)) { + break; + } + + if (type == DAbstractFileInfo::FIFOFile && !fileHints.testFlag(DFileStatisticsJob::DontSkipFIFOFile)) { + break; + } + + if (type == DAbstractFileInfo::SocketFile && !fileHints.testFlag(DFileStatisticsJob::DontSkipSocketFile)) { + break; + } + if (type == DAbstractFileInfo::Unknown) + { + break; + } + + size = info->size(); + if (size > 0) { + totalSize += size; + + Q_EMIT q_ptr->sizeChanged(totalSize); + } + // fix bug 30548 ,以为有些文件大小为0,文件夹为空,size也为零,重新计算显示大小 + // fix bug 202007010033【文件管理器】【5.1.2.10-1】【sp2】复制软连接的文件,进度条显示1% + // 判断文件是否是链接文件 + totalProgressSize += (size <= 0 || info->isSymLink()) ? FileUtils::getMemoryPageSize() : size; + } while (false); + + ++filesCount; + + Q_EMIT q_ptr->fileFound(url); + } else { + // fix bug 30548 ,以为有些文件大小为0,文件夹为空,size也为零,重新计算显示大小 + totalProgressSize += FileUtils::getMemoryPageSize(); + if (info->isSymLink()) { + if (!fileHints.testFlag(DFileStatisticsJob::FollowSymlink)) { + ++filesCount; + Q_EMIT q_ptr->fileFound(url); + return; + } + + info = DFileService::instance()->createFileInfo(nullptr, info->rootSymLinkTarget()); + + if (info->isSymLink()) { + ++filesCount; + Q_EMIT q_ptr->fileFound(url); + return; + } + } + +// size = info->size(); + ++directoryCount; + + if (!(fileHints & (DFileStatisticsJob::DontSkipAVFSDStorage | DFileStatisticsJob::DontSkipPROCStorage)) && info->fileUrl().isLocalFile()) { + do { + DStorageInfo si(info->fileUrl().toLocalFile()); + + if (si.rootPath() == info->fileUrl().toLocalFile()) { + if (!fileHints.testFlag(DFileStatisticsJob::DontSkipPROCStorage) + && si.device() == "proc") { + break; + } + + if (!fileHints.testFlag(DFileStatisticsJob::DontSkipAVFSDStorage) + && si.device() == "avfsd") { + break; + } + } + + if (!fileHints.testFlag(DFileStatisticsJob::SingleDepth)) + directoryQueue << url; + } while (false); + } else if (!fileHints.testFlag(DFileStatisticsJob::SingleDepth)) { + directoryQueue << url; + } + + Q_EMIT q_ptr->directoryFound(url); + } + +} + +DFileStatisticsJob::DFileStatisticsJob(QObject *parent) + : QThread(parent) + , d_ptr(new DFileStatisticsJobPrivate(this)) +{ + d_ptr->notifyDataTimer = new QTimer(this); + + connect(d_ptr->notifyDataTimer, &QTimer::timeout, this, [this] { + Q_EMIT dataNotify(d_ptr->totalSize, d_ptr->filesCount, d_ptr->directoryCount); + }, Qt::DirectConnection); +} + +DFileStatisticsJob::~DFileStatisticsJob() +{ + stop(); + wait(); +} + +DFileStatisticsJob::State DFileStatisticsJob::state() const +{ + Q_D(const DFileStatisticsJob); + + return static_cast(d->state.load()); +} + +DFileStatisticsJob::FileHints DFileStatisticsJob::fileHints() const +{ + Q_D(const DFileStatisticsJob); + + return d->fileHints; +} + +qint64 DFileStatisticsJob::totalSize() const +{ + Q_D(const DFileStatisticsJob); + + return d->totalSize.load(); +} +// fix bug 30548 ,以为有些文件大小为0,文件夹为空,size也为零,重新计算显示大小 +qint64 DFileStatisticsJob::totalProgressSize() const +{ + Q_D(const DFileStatisticsJob); + + return d->totalProgressSize; +} + +int DFileStatisticsJob::filesCount() const +{ + Q_D(const DFileStatisticsJob); + + return d->filesCount.load(); +} + +int DFileStatisticsJob::directorysCount(bool includeSelf) const +{ + Q_D(const DFileStatisticsJob); + + if (includeSelf) { + return d->directoryCount.load(); + } else { + return qMax(d->directoryCount.load() - 1, 0); + } +} + +void DFileStatisticsJob::start(const DUrlList &sourceUrls) +{ + if (isRunning()) { + qDebug() << "current thread is running... reject to start."; + return; + } + Q_D(DFileStatisticsJob); + d->sourceUrlList = sourceUrls; + + if (d->sourceUrlList.count() <= 0) { + return; + } + //fix bug 35044 【文件管理器】【5.1.2-1】【sp2】我的共享和标记栏目下,预览文件夹,文件大小和文件个数显示错误 + // 传入的scheme为USERSHARE_SCHEME设置为FILE_SCHEME,传入的scheme是TAG_SCHEME判断taggedLocalFilePath是否为空, + //判断path()是否为“/”,(因为这两个在tagcontroller中处理了)设置为FILE_SCHEME,设置setScheme为FILE_SCHEME,url为taggedLocalFilePath + QList::iterator it = d->sourceUrlList.begin(); + while(it != d->sourceUrlList.end()) + { + if (it->scheme() == USERSHARE_SCHEME) { + it->setScheme(FILE_SCHEME); + } + if (it->scheme() == TAG_SCHEME && it->path() != QString("/") && !it->taggedLocalFilePath().isEmpty()) { + it->setUrl(it->taggedLocalFilePath()); + it->setScheme(FILE_SCHEME); + } + if (it->scheme() == SEARCH_SCHEME && !it->fragment().isEmpty()) { + it->setUrl(it->fragment()); + } + it++; + } + + QThread::start(); +} + +void DFileStatisticsJob::stop() +{ + Q_D(DFileStatisticsJob); + + if (d->state == StoppedState) { + return; + } + + d->setState(StoppedState); + d->waitCondition.wakeAll(); +} + +void DFileStatisticsJob::togglePause() +{ + Q_D(DFileStatisticsJob); + + if (d->state == StoppedState) { + return; + } + + if (d->state == PausedState) { + d->setState(RunningState); + d->waitCondition.wakeAll(); + } else { + d->setState(PausedState); + } +} + +void DFileStatisticsJob::setFileHints(FileHints fileHints) +{ + Q_D(DFileStatisticsJob); + Q_ASSERT(d->state != RunningState); + + d->fileHints = fileHints; +} + +void DFileStatisticsJob::run() +{ + Q_D(DFileStatisticsJob); + + d->setState(RunningState); + d_ptr->totalSize = 0; + d_ptr->filesCount = 0; + d_ptr->directoryCount = 0; + + Q_EMIT dataNotify(0, 0, 0); + + QQueue directory_queue; + int fileCount = 0; + if (d->fileHints.testFlag(ExcludeSourceFile)) { + for (const DUrl &url : d->sourceUrlList) { + if (!d->stateCheck()) { + d->setState(StoppedState); + + return; + } + + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, url); + + if (!info) { + qDebug() << "Url not yet supported: " << url; + continue; + } + + if (info->isDir() && d->fileHints.testFlag(SingleDepth)) { + fileCount += info->filesCount(); + } else { + fileCount++; + } + + if (info->isSymLink()) { + if (!d->fileHints.testFlag(DFileStatisticsJob::FollowSymlink)) { + continue; + } + + info = DFileService::instance()->createFileInfo(nullptr, info->rootSymLinkTarget()); + + if (info->isSymLink()) { + continue; + } + } + + if (info->isDir()) { + directory_queue << url; + } + } + } else { + for (const DUrl &url : d->sourceUrlList) { + // 选择的列表中包含avfsd/proc挂载路径时禁用过滤 + FileHints save_file_hints = d->fileHints; + d->fileHints = d->fileHints | DontSkipAVFSDStorage | DontSkipPROCStorage; + d->processFile(url, directory_queue); + d->fileHints = save_file_hints; + + if (!d->stateCheck()) { + d->setState(StoppedState); + + return; + } + } + } + + if (d->fileHints.testFlag(SingleDepth)) { + d->filesCount = fileCount; + directory_queue.clear(); + return; + } + + while (!directory_queue.isEmpty()) { + const DUrl &directory_url = directory_queue.dequeue(); + const DDirIteratorPointer &iterator = DFileService::instance()->createDirIterator(nullptr, directory_url, QStringList(), + QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot, nullptr, true); + + if (!iterator) { + qWarning() << "Failed on create dir iterator, for url:" << directory_url; + continue; + } + while (iterator->hasNext()) { + DUrl url = iterator->next(); + d->processFile(url, directory_queue); + + if (!d->stateCheck()) { + d->setState(StoppedState); + + return; + } + } + } + + d->setState(StoppedState); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilestatisticsjob.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilestatisticsjob.h new file mode 100644 index 0000000..af1ac53 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dfilestatisticsjob.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFILESTATISTICSJOB_H +#define DFILESTATISTICSJOB_H + +#include + +#include + +DFM_BEGIN_NAMESPACE + +class DFileStatisticsJobPrivate; +class DFileStatisticsJob : public QThread +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DFileStatisticsJob) + + Q_PROPERTY(State state READ state NOTIFY stateChanged) + Q_PROPERTY(FileHints fileHints READ fileHints WRITE setFileHints) + +public: + explicit DFileStatisticsJob(QObject *parent = nullptr); + ~DFileStatisticsJob() override; + + enum State { + StoppedState, + RunningState, + PausedState + }; + + Q_ENUM(State) + + enum FileHint { + FollowSymlink = 0x01, + DontSkipAVFSDStorage = 0x02, + DontSkipPROCStorage = 0x04, + DontSkipCharDeviceFile = 0x08, + DontSkipBlockDeviceFile = 0x10, + DontSkipFIFOFile = 0x20, + DontSkipSocketFile = 0x40, + ExcludeSourceFile = 0x80, // 不计算传入的文件列表 + SingleDepth = 0x100 // 深度为1 + }; + + Q_ENUM(FileHint) + Q_DECLARE_FLAGS(FileHints, FileHint) + + State state() const; + FileHints fileHints() const; + + qint64 totalSize() const; + qint64 totalProgressSize() const; + int filesCount() const; + int directorysCount(bool includeSelf = true) const; + +public Q_SLOTS: + void start(const DUrlList &sourceUrls); + void stop(); + void togglePause(); + + void setFileHints(FileHints fileHints); + +Q_SIGNALS: + void stateChanged(State state); + void sizeChanged(qint64 size); + void fileFound(const DUrl &url); + void directoryFound(const DUrl &url); + void dataNotify(qint64 size, int filesCount, int directoryCount); + +private: + void run() override; + + using QThread::start; + using QThread::terminate; + using QThread::quit; + using QThread::exit; + + QScopedPointer d_ptr; +}; + +DFM_END_NAMESPACE + +Q_DECLARE_OPERATORS_FOR_FLAGS(DFM_NAMESPACE::DFileStatisticsJob::FileHints) + +#endif // DFILESTATISTICSJOB_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dgiofiledevice.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dgiofiledevice.cpp new file mode 100644 index 0000000..597a449 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dgiofiledevice.cpp @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include + +#include "dgiofiledevice.h" +#include "private/dfiledevice_p.h" +#include "dabstractfilewatcher.h" + +DFM_BEGIN_NAMESPACE + +class DGIOFileDevicePrivate : public DFileDevicePrivate +{ +public: + explicit DGIOFileDevicePrivate(DGIOFileDevice *qq); + ~DGIOFileDevicePrivate() override; + + Q_DECLARE_PUBLIC(DGIOFileDevice) + + GFile *file = nullptr; + GInputStream *input_stream = nullptr; + GOutputStream *output_stream = nullptr; + GIOStream *total_stream = nullptr; + GCancellable *m_writeCancel = nullptr; + GCancellable *m_readCancel = nullptr; +}; + +DGIOFileDevicePrivate::DGIOFileDevicePrivate(DGIOFileDevice *qq) + : DFileDevicePrivate(qq) +{ + m_writeCancel = g_cancellable_new(); + m_readCancel = g_cancellable_new(); +} + +DGIOFileDevicePrivate::~DGIOFileDevicePrivate() +{ + //在使用完后要析构所有的gioobject + if (m_writeCancel) { + g_object_unref(m_writeCancel); + m_writeCancel = nullptr; + } + if (m_readCancel) { + g_object_unref(m_readCancel); + m_readCancel = nullptr; + } +} + +DGIOFileDevice::DGIOFileDevice(const DUrl &url, QObject *parent) + : DFileDevice(*new DGIOFileDevicePrivate(this), parent) +{ + setFileUrl(url); +} + +DGIOFileDevice::~DGIOFileDevice() +{ + close(); + + Q_D(DGIOFileDevice); + + if (d->file) { + g_object_unref(d->file); + } +} + +bool DGIOFileDevice::open(QIODevice::OpenMode mode) +{ + if (isOpen()) + return false; + if ((mode & ~(ReadWrite | Append | Truncate)) != 0) + return false; + + Q_D(DGIOFileDevice); + + GError *error = nullptr; + if (mode.testFlag(ReadWrite) && !mode.testFlag(Append)) { + if (mode.testFlag(Truncate)) { + d->total_stream = G_IO_STREAM(g_file_replace_readwrite(d->file, nullptr, false, G_FILE_CREATE_NONE, nullptr, &error)); + } else { + d->total_stream = G_IO_STREAM(g_file_open_readwrite(d->file, nullptr, &error)); + } + if (error) { + setErrorString(QString::fromLocal8Bit(error->message)); + + g_error_free(error); + + return false; + } + d->input_stream = g_io_stream_get_input_stream(d->total_stream); + d->output_stream = g_io_stream_get_output_stream(d->total_stream); + + return DFileDevice::open(mode); + } + + if (mode.testFlag(ReadOnly)) { + d->input_stream = G_INPUT_STREAM(g_file_read(d->file, nullptr, &error)); + + if (error) { + setErrorString(QString::fromLocal8Bit(error->message)); + + g_error_free(error); + + return false; + } + } else { + d->input_stream = nullptr; + } + + if ((mode & (WriteOnly | Append | Truncate))) { + bool exists = g_file_query_exists(d->file, nullptr); + if (mode.testFlag(Append)) { + d->output_stream = G_OUTPUT_STREAM(g_file_append_to(d->file, G_FILE_CREATE_NONE, nullptr, &error)); + } else { + d->output_stream = G_OUTPUT_STREAM(g_file_replace(d->file, nullptr, false, G_FILE_CREATE_NONE, nullptr, &error)); + } + + if (error) { + do { + if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_FOUND) { + g_error_free(error); + error = nullptr; + // 文件不存在, 尝试创建 + d->output_stream = G_OUTPUT_STREAM(g_file_create(d->file, G_FILE_CREATE_NONE, nullptr, &error)); + + if (!error) { + break; + } + } + + setErrorString(QString::fromLocal8Bit(error->message)); + + g_error_free(error); + + if (d->input_stream) { + g_input_stream_close(d->input_stream, nullptr, nullptr); + g_object_unref(d->input_stream); + } + + return false; + } while (false); + } + + if (!exists) { + DAbstractFileWatcher::ghostSignal(d->url.parentUrl(), &DAbstractFileWatcher::subfileCreated, d->url); + } else if (!mode.testFlag(Append) || mode.testFlag(Truncate)) { + if (g_seekable_tell(G_SEEKABLE(d->output_stream)) > 0) { + if (!g_seekable_can_seek(G_SEEKABLE(d->output_stream))) { + setErrorString("Can not seek the file, only append write mode"); + } else if (!g_seekable_seek(G_SEEKABLE(d->output_stream), 0, G_SEEK_SET, nullptr, &error)) { + if (error) { + setErrorString(QString::fromLocal8Bit(error->message)); + + g_error_free(error); + } else { + setErrorString("Failed on seek to start"); + } + } else { + return DFileDevice::open(mode); + } + + if (d->input_stream) { + g_input_stream_close(d->input_stream, nullptr, nullptr); + g_object_unref(d->input_stream); + } + g_output_stream_close(d->output_stream, nullptr, nullptr); + g_object_unref(d->output_stream); + + return false; + } + } + } else { + d->output_stream = nullptr; + } + + return DFileDevice::open(mode); +} + +void DGIOFileDevice::close() +{ + if (!isOpen()) + return; + DFileDevice::close(); + + Q_D(DGIOFileDevice); + + if (d->total_stream) { + g_io_stream_close(d->total_stream, nullptr, nullptr); + g_object_unref(d->total_stream); + + d->total_stream = nullptr; + d->input_stream = nullptr; + d->output_stream = nullptr; + } else { + if (d->input_stream) { + g_input_stream_close(d->input_stream, nullptr, nullptr); + g_object_unref(d->input_stream); + d->input_stream = nullptr; + } + if (d->output_stream) { + //todo vfat文件格式的U盘在close的时候耗时很长,卡死的根源 + g_output_stream_close(d->output_stream, nullptr, nullptr); + g_object_unref(d->output_stream); + d->output_stream = nullptr; + } + } +} + +bool DGIOFileDevice::setFileUrl(const DUrl &url) +{ + Q_ASSERT(!isOpen()); + DFileDevice::setFileUrl(url); + + Q_D(DGIOFileDevice); + + if (d->file) { + g_object_unref(d->file); + } + + if (url.isLocalFile()) { + d->file = g_file_new_for_path(QFile::encodeName(url.toLocalFile())); + } else { + d->file = g_file_new_for_uri(QFile::encodeName(url.toString())); + } + + return d->file; +} + +int DGIOFileDevice::handle() const +{ + return -1; +} + +qint64 DGIOFileDevice::size() const +{ + Q_D(const DGIOFileDevice); + + GFileInfo *info = g_file_query_info(d->file, nullptr, G_FILE_QUERY_INFO_NONE, nullptr, nullptr); + + if (!info) { + return -1; + } + + qint64 size = g_file_info_get_size(info); + + g_object_unref(info); + + return size; +} + +bool DGIOFileDevice::resize(qint64 size) +{ + Q_D(DGIOFileDevice); + + GError *error = nullptr; + + if (!g_seekable_truncate(G_SEEKABLE(d->output_stream), size, nullptr, &error)) { + if (error) { + setErrorString(QString::fromLocal8Bit(error->message)); + g_error_free(error); + } else { + setErrorString("Failed on resize"); + } + + return false; + } + + return true; +} + +bool DGIOFileDevice::isSequential() const +{ + Q_D(const DGIOFileDevice); + + if (d->input_stream) + return !g_seekable_can_seek(G_SEEKABLE(d->input_stream)); + + return !g_seekable_can_seek(G_SEEKABLE(d->output_stream)); +} + +qint64 DGIOFileDevice::pos() const +{ + Q_D(const DGIOFileDevice); + + if (d->input_stream) + return g_seekable_tell(G_SEEKABLE(d->input_stream)); + + return g_seekable_tell(G_SEEKABLE(d->output_stream)); +} + +bool DGIOFileDevice::seek(qint64 pos) +{ + Q_D(DGIOFileDevice); + + GError *error = nullptr; + + if (d->input_stream) { + if (!g_seekable_seek(G_SEEKABLE(d->input_stream), pos, G_SEEK_SET, nullptr, &error)) { + if (error) { + setErrorString(QString::fromLocal8Bit(error->message)); + g_error_free(error); + } else { + setErrorString("Failed on seek input stream"); + } + + return false; + } + } + + if (d->output_stream) { + if (!g_seekable_seek(G_SEEKABLE(d->output_stream), pos, G_SEEK_SET, nullptr, &error)) { + if (error) { + setErrorString(QString::fromLocal8Bit(error->message)); + g_error_free(error); + } else { + setErrorString("Failed on seek output stream"); + } + + return false; + } + } + + return true; +} + +bool DGIOFileDevice::flush() +{ + Q_D(DGIOFileDevice); + + GError *error = nullptr; + bool ok = g_output_stream_flush(d->output_stream, nullptr, &error); + + if (error) { + setErrorString(QString::fromLocal8Bit(error->message)); + + g_error_free(error); + + return false; + } + + return ok; +} + +bool DGIOFileDevice::syncToDisk(bool isVfat) +{ + if(!isVfat) { + //fix 函数g_io_stream_close()后并没有如期望的(官方API描述)那样同步文件. 在特殊情况(vfat文件系统)下,仍用g_output_stream_flush进行同步 + return flush(); + } else { + //fix 修复卡死问题,在vfat格式的U盘g_output_stream_flush无效,使用关闭再打开强制刷新 + close(); + if (!open(QIODevice::WriteOnly | QIODevice::Append)) { + return false; + } + return true; + } +} + +void DGIOFileDevice::closeWriteReadFailed(const bool bwrite) +{ + if (!isOpen()) + return; + + DFileDevice::close(); + + + Q_D(DGIOFileDevice); + if (d->total_stream) { + g_io_stream_close(d->total_stream, nullptr, nullptr); + g_object_unref(d->total_stream); + + d->total_stream = nullptr; + d->input_stream = nullptr; + d->output_stream = nullptr; + } else { + if (d->input_stream) { + if (bwrite) { + g_input_stream_close(d->input_stream, nullptr, nullptr); + g_object_unref(d->input_stream); + } + + d->input_stream = nullptr; + } + + if (d->output_stream) { + //todo vfat文件格式的U盘在close的时候耗时很长,卡死的根源 + if (!bwrite) { + g_output_stream_close(d->output_stream, nullptr, nullptr); + g_object_unref(d->output_stream); + } + + d->output_stream = nullptr; + } + } +} + +void DGIOFileDevice::cancelAllOperate() +{ + Q_D(DGIOFileDevice); + if (d->m_writeCancel) + g_cancellable_cancel(d->m_writeCancel); + if (d->m_readCancel) + g_cancellable_cancel(d->m_readCancel); + qDebug() << "stop all cancels" << this << QThread::currentThreadId(); +} + +qint64 DGIOFileDevice::readData(char *data, qint64 maxlen) +{ + Q_D(DGIOFileDevice); + + GError *error = nullptr; + + qint64 size = g_input_stream_read(d->input_stream, data, static_cast(maxlen), d->m_readCancel, &error); + + if (error) { + setErrorString(QString::fromLocal8Bit(error->message)); + + g_error_free(error); + + return -1; + } + + return size; +} + +qint64 DGIOFileDevice::writeData(const char *data, qint64 len) +{ + Q_D(DGIOFileDevice); + + GError *error = nullptr; + + qint64 size = g_output_stream_write(d->output_stream, data, static_cast(len), d->m_writeCancel, &error); + if (error) { + setErrorString(QString::fromLocal8Bit(error->message)); + + g_error_free(error); + + return -1; + } + + return size; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dgiofiledevice.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dgiofiledevice.h new file mode 100644 index 0000000..385d92a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dgiofiledevice.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DGIOFILEDEVICE_H +#define DGIOFILEDEVICE_H + +#include + +DFM_BEGIN_NAMESPACE + +class DGIOFileDevicePrivate; +class DGIOFileDevice : public DFileDevice +{ + Q_OBJECT + Q_DECLARE_PRIVATE(DGIOFileDevice) + +public: + explicit DGIOFileDevice(const DUrl &url, QObject *parent = nullptr); + ~DGIOFileDevice() override; + + bool setFileUrl(const DUrl &url) override; + + bool open(OpenMode mode) override; + void close() override; + int handle() const override; + qint64 size() const override; + bool resize(qint64 size) override; + bool isSequential() const override; + qint64 pos() const override; + bool seek(qint64 pos) override; + bool flush() override; + bool syncToDisk(bool isVfat = false) override; + void closeWriteReadFailed(const bool bwrite) override; + void cancelAllOperate() override; + +protected: + qint64 readData(char *data, qint64 maxlen) override; + qint64 writeData(const char *data, qint64 len) override; +}; + +DFM_END_NAMESPACE + +#endif // DGIOFILEDEVICE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dlocalfiledevice.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dlocalfiledevice.cpp new file mode 100644 index 0000000..835d994 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dlocalfiledevice.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dlocalfiledevice.h" +#include "private/dlocalfiledevice_p.h" + +#include + +DFM_BEGIN_NAMESPACE + +DLocalFileDevicePrivate::DLocalFileDevicePrivate(DLocalFileDevice *qq) + : DFileIODeviceProxyPrivate(qq) + , file(new QFile()) +{ +} + +DLocalFileDevicePrivate::~DLocalFileDevicePrivate() +{ + if (file) { + file->close(); + delete file; + } +} + +DLocalFileDevice::DLocalFileDevice(QObject *parent) + : DFileIODeviceProxy(*new DLocalFileDevicePrivate(this), parent) +{ + setDevice(d_func()->file); +} + +bool DLocalFileDevice::setFileUrl(const DUrl &url) +{ + Q_D(DLocalFileDevice); + + if (!url.isLocalFile() || !d->file) + return false; + QString filename = url.toLocalFile(); + + d->file->setFileName(filename); + + return DFileDevice::setFileUrl(url); +} + +bool DLocalFileDevice::setFileName(const QString &absoluteFilePath) +{ + return setFileUrl(DUrl::fromLocalFile(absoluteFilePath)); +} + +int DLocalFileDevice::handle() const +{ + Q_D(const DLocalFileDevice); + + if (!d->file) { + return -1; + } + + return d->file->handle(); +} + +bool DLocalFileDevice::resize(qint64 size) +{ + Q_D(DLocalFileDevice); + + if (!d->file) { + return false; + } + + return d->file->resize(size); +} + +bool DLocalFileDevice::flush() +{ + Q_D(DLocalFileDevice); + + if (!d->file) { + return false; + } + + return d->file->flush(); +} + +bool DLocalFileDevice::syncToDisk(bool isVfat) +{ + Q_UNUSED(isVfat); + Q_D(DLocalFileDevice); + + if (!d->file) { + return false; + } + + int ret = fdatasync(d->file->handle()); + + if (ret != 0) { + setErrorString(QString::fromLocal8Bit(strerror(errno))); + + return false; + } + + return true; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dlocalfiledevice.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dlocalfiledevice.h new file mode 100644 index 0000000..9f97ea8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dlocalfiledevice.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DLOCALFILEDEVICE_H +#define DLOCALFILEDEVICE_H + +#include + +DFM_BEGIN_NAMESPACE + +class DLocalFileDevicePrivate; +class DLocalFileDevice : public DFileIODeviceProxy +{ + Q_DECLARE_PRIVATE(DLocalFileDevice) + +public: + explicit DLocalFileDevice(QObject *parent = nullptr); + + bool setFileUrl(const DUrl &url) override; + bool setFileName(const QString &absoluteFilePath); + + int handle() const override; + bool resize(qint64 size) override; + bool flush() override; + bool syncToDisk(bool isVfat = false) override; + +private: + using DFileIODeviceProxy::setDevice; +}; + +DFM_END_NAMESPACE + +#endif // DLOCALFILEDEVICE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dlocalfilehandler.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dlocalfilehandler.cpp new file mode 100644 index 0000000..8e3702b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dlocalfilehandler.cpp @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include "dlocalfilehandler.h" +#include "private/dfilehandler_p.h" +#include "../controllers/vaultcontroller.h" +#include "dfmstandardpaths.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "utils/singleton.h" + +#include +#include +#include +#include + +#include +#include +#include + +DFM_BEGIN_NAMESPACE + +DLocalFileHandler::DLocalFileHandler() +{ + +} + +bool DLocalFileHandler::exists(const DUrl &url) +{ + Q_ASSERT(url.isLocalFile()); + + QFileInfo info(url.toLocalFile()); + + return info.exists() || info.isSymLink(); +} + +bool DLocalFileHandler::touch(const DUrl &url) +{ + Q_ASSERT(url.isLocalFile()); + + QFile file(url.toLocalFile()); + + if (file.exists()) + return false; + + if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + file.close(); + return true; + } + + Q_D(DFileHandler); + + d->setErrorString(file.errorString()); + + return false; +} + +bool DLocalFileHandler::mkdir(const DUrl &url) +{ + Q_ASSERT(url.isLocalFile()); + + Q_D(DFileHandler); + + if (QDir::current().mkdir(url.toLocalFile())) { + return true; + } + + d->setErrorString(QString::fromLocal8Bit(strerror(errno))); + + return false; +} + +bool DLocalFileHandler::mkpath(const DUrl &url) +{ + Q_ASSERT(url.isLocalFile()); + + if (QDir::current().mkpath(url.toLocalFile())) { + return true; + } + + Q_D(DFileHandler); + + d->setErrorString(QString::fromLocal8Bit(strerror(errno))); + + return false; +} + +bool DLocalFileHandler::link(const QString &path, const DUrl &linkUrl) +{ + Q_ASSERT(linkUrl.isLocalFile()); + + if (::symlink(path.toLocal8Bit().constData(), linkUrl.toLocalFile().toLocal8Bit().constData()) == 0) + return true; + + Q_D(DFileHandler); + + d->setErrorString(QString::fromLocal8Bit(strerror(errno))); + + return false; +} + +bool DLocalFileHandler::remove(const DUrl &url) +{ + Q_ASSERT(url.isLocalFile()); + + if (url.path().contains(MTP_STAGING) && url.path().startsWith(MOBILE_ROOT_PATH)) + fileSignalManager->requestCloseMediaInfo(url.path()); + + if (::remove(url.toLocalFile().toLocal8Bit()) == 0) + return true; + + Q_D(DFileHandler); + + d->setErrorString(QString::fromLocal8Bit(strerror(errno))); + + return false; +} + +bool DLocalFileHandler::rmdir(const DUrl &url) +{ + Q_ASSERT(url.isLocalFile()); + + if (::rmdir(url.toLocalFile().toLocal8Bit()) == 0) + return true; + + Q_D(DFileHandler); + + d->setErrorString(QString::fromLocal8Bit(strerror(errno))); + + return false; +} + +bool DLocalFileHandler::rename(const DUrl &url, const DUrl &newUrl) +{ + Q_ASSERT(url.isLocalFile()); + Q_ASSERT(newUrl.isLocalFile()); + Q_D(DFileHandler); + + const QByteArray &source_file = url.toLocalFile().toLocal8Bit(); + const QByteArray &target_file = newUrl.toLocalFile().toLocal8Bit(); + + if (::rename(source_file.constData(), target_file.constData()) == 0) + return true; + + d->setErrorString(QString::fromLocal8Bit(strerror(errno))); + + return false; +} + +bool DLocalFileHandler::setPermissions(const DUrl &url, QFileDevice::Permissions permissions) +{ + Q_ASSERT(url.isLocalFile()); + + QFile file(url.toLocalFile()); + + if (file.setPermissions(permissions)) + return true; + + Q_D(DFileHandler); + + d->setErrorString(file.errorString()); + + return false; +} + +bool DLocalFileHandler::setFileTime(const DUrl &url, const QDateTime &accessDateTime, const QDateTime &lastModifiedTime) +{ + Q_ASSERT(url.isLocalFile()); + + utimbuf buf = { + .actime = accessDateTime.toTime_t(), + .modtime = lastModifiedTime.toTime_t() + }; + + if (::utime(url.toLocalFile().toLocal8Bit(), &buf) == 0) { + return true; + } + + Q_D(DFileHandler); + + d->setErrorString(QString::fromLocal8Bit(strerror(errno))); + + return false; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dlocalfilehandler.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dlocalfilehandler.h new file mode 100644 index 0000000..9a7711e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dlocalfilehandler.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DLOCALFILEHANDLER_H +#define DLOCALFILEHANDLER_H + +#include + +DFM_BEGIN_NAMESPACE + +class DLocalFileHandler : public DFileHandler +{ +public: + DLocalFileHandler(); + + bool exists(const DUrl &url) override; + bool touch(const DUrl &url) override; + bool mkdir(const DUrl &url) override; + bool mkpath(const DUrl &url) override; + bool link(const QString &path, const DUrl &linkUrl) override; + bool remove(const DUrl &url) override; + bool rmdir(const DUrl &url) override; + bool rename(const DUrl &url, const DUrl &newUrl) override; + bool setPermissions(const DUrl &url, QFileDevice::Permissions permissions) override; + bool setFileTime(const DUrl &url, const QDateTime &accessDateTime, const QDateTime &lastModifiedTime) override; +}; + +DFM_END_NAMESPACE + +#endif // DLOCALFILEHANDLER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dstorageinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dstorageinfo.cpp new file mode 100644 index 0000000..5789b21 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dstorageinfo.cpp @@ -0,0 +1,425 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#include +#include + +#include "dstorageinfo.h" +#include "controllers/vaultcontroller.h" +#include "dfmglobal.h" + +#include +#include + +DFM_BEGIN_NAMESPACE + +static QString preprocessPath(const QString &path, DStorageInfo::PathHints hints) +{ + QFileInfo info(path); + + if (info.isSymLink()) { + if (!info.exists() || !hints.testFlag(DStorageInfo::FollowSymlink)) + return info.dir().path(); + } + + return path; +} + +class DStorageInfoPrivate : public QSharedData +{ +public: + ~DStorageInfoPrivate() { + if (gioInfo) { + g_object_unref(gioInfo); + } + } + + GFileInfo *gioInfo = nullptr; + QString rootPath; + QByteArray device; +}; + +DStorageInfo::DStorageInfo() + : QStorageInfo() + , d_ptr(new DStorageInfoPrivate()) +{ + +} + +DStorageInfo::DStorageInfo(const QString &path, PathHints hints) + : DStorageInfo() +{ + //! 如果是保险箱就不进行setpath处理,增加访问速度 + if(!VaultController::isVaultFile(path)) + setPath(path, hints); +} + +DStorageInfo::DStorageInfo(const QDir &dir, PathHints hints) + : DStorageInfo() +{ + setPath(dir.path(), hints); +} + +DStorageInfo::DStorageInfo(const DStorageInfo &other) + : QStorageInfo(other) + , d_ptr(other.d_ptr) +{ + +} + +DStorageInfo::~DStorageInfo() +{ + +} + +DStorageInfo &DStorageInfo::operator=(const DStorageInfo &other) +{ + d_ptr = other.d_ptr; + + return *this; +} + +void DStorageInfo::setPath(const QString &path, PathHints hints) +{ + static QMutex mutex; + QMutexLocker lk(&mutex); + + QStorageInfo::setPath(preprocessPath(path, hints)); + + Q_D(DStorageInfo); + + d_ptr.detach(); + + if (QStorageInfo::bytesTotal() <= 0) { + GFile *file = g_file_new_for_path(QFile::encodeName(path).constData()); + GError *error = nullptr; + + // 如果为拷贝构造,之前的d对象setPath后会存在gfileinfo,此处做初始化判断。 + // 如果存在info 对象则先释放 + if (d->gioInfo) { + g_object_unref(d->gioInfo); + d->gioInfo =nullptr; + } + + d->gioInfo = g_file_query_filesystem_info(file, "filesystem::*", nullptr, &error); + + if (error) { +// qWarning() << QString::fromLocal8Bit(error->message); + + g_error_free(error); + error = nullptr; + } + + GMount *mount = g_file_find_enclosing_mount(file, nullptr, &error); + + if (error) { +// qWarning() << QString::fromLocal8Bit(error->message); + + g_error_free(error); + } else if (mount) { + GFile *root_file = g_mount_get_root(mount); + char *root_path = g_file_get_path(root_file); + + d->rootPath = QFile::decodeName(root_path); + d->device = QStorageInfo::device(); + + if (d->device == QByteArrayLiteral("gvfsd-fuse")) { + char *uri = g_file_get_uri(root_file); + + d->device = QByteArray(uri); + g_free(uri); + } + + g_free(root_path); + g_object_unref(root_file); + g_object_unref(mount); + } + + g_object_unref(file); + } +} + +QString DStorageInfo::rootPath() const +{ + Q_D(const DStorageInfo); + + if (d->gioInfo && !d->rootPath.isEmpty()) { + return d->rootPath; + } + + return QStorageInfo::rootPath(); +} + +QByteArray DStorageInfo::device() const +{ + Q_D(const DStorageInfo); + + if (d->device.isEmpty()) + return QStorageInfo::device(); + + return d->device; +} + +QByteArray DStorageInfo::fileSystemType() const +{ + Q_D(const DStorageInfo); + + if (d->gioInfo) { + return g_file_info_get_attribute_string(d->gioInfo, G_FILE_ATTRIBUTE_FILESYSTEM_TYPE); + } + + return QStorageInfo::fileSystemType(); +} + +qint64 DStorageInfo::bytesTotal() const +{ + Q_D(const DStorageInfo); + + if (d->gioInfo) + return static_cast(g_file_info_get_attribute_uint64(d->gioInfo, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE)); + + return QStorageInfo::bytesTotal(); +} + +qint64 DStorageInfo::bytesFree() const +{ + Q_D(const DStorageInfo); + + if (d->gioInfo) { + quint64 used = g_file_info_get_attribute_uint64(d->gioInfo, G_FILE_ATTRIBUTE_FILESYSTEM_USED); + + return bytesTotal() - static_cast(used); + } + + return QStorageInfo::bytesFree(); +} + +qint64 DStorageInfo::bytesAvailable() const +{ + Q_D(const DStorageInfo); + + if (d->gioInfo) { + return static_cast(g_file_info_get_attribute_uint64(d->gioInfo, G_FILE_ATTRIBUTE_FILESYSTEM_FREE)); + } + + return QStorageInfo::bytesAvailable(); +} + +bool DStorageInfo::isReadOnly() const +{ + Q_D(const DStorageInfo); + + if (d->gioInfo) { + return g_file_info_get_attribute_boolean(d->gioInfo, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY); + } + + return QStorageInfo::isReadOnly(); +} + +bool DStorageInfo::isLocalDevice() const +{ + return device().startsWith("/dev/"); +} + +bool DStorageInfo::isLowSpeedDevice() const +{ + const QString &device = this->device(); + + return device.startsWith("mtp://") + || device.startsWith("gphoto://") + || device.startsWith("gphoto2://") + || device.startsWith("smb-share://") + || device.startsWith("smb://"); +} + +bool DStorageInfo::isValid() const +{ + return QStorageInfo::isValid(); +} + +void DStorageInfo::refresh() +{ + QStorageInfo::refresh(); + setPath(rootPath()); +} + +bool DStorageInfo::inSameDevice(QString path1, QString path2, PathHints hints) +{ + path1 = QFileInfo(preprocessPath(path1, hints)).absoluteFilePath(); + path2 = QFileInfo(preprocessPath(path2, hints)).absoluteFilePath(); + + DStorageInfo info1(path1, hints); + + // for avfs + if (info1.fileSystemType() == "avfsd") { + info1.setPath(path1.mid(info1.rootPath().length())); + } + + DStorageInfo info2(path2, hints); + + // for avfs + if (info2.fileSystemType() == "avfsd") { + info2.setPath(path2.mid(info1.rootPath().length())); + } + + if (info1 != info2) + return false; + + // for gvfs + if (info1.fileSystemType() == "gvfsd-fuse") { + path1 = path1.mid(info1.rootPath().length() + 1); + path2 = path2.mid(info2.rootPath().length() + 1); + + int seporator_index1 = path1.indexOf(QDir::separator()); + int seporator_index2 = path2.indexOf(QDir::separator()); + + if (seporator_index1 != seporator_index2) + return false; + + if (seporator_index1 == -1) + return false; + + return path1.left(seporator_index1) == path2.left(seporator_index2); + } + + return info1 == info2; +} + +bool DStorageInfo::inSameDevice(const DUrl &url1, const DUrl &url2, PathHints hints) +{ + if (url1.scheme() != url2.scheme()) + return false; + + if (url1.isLocalFile()) { + return inSameDevice(url1.toLocalFile(), url2.toLocalFile(), hints); + } + + return url1.host() == url2.host() && url1.port() == url1.port(); +} + +bool DStorageInfo::isLocalDevice(const QString &path, const bool &isEx) +{ + static QRegularExpression regExp("^/run/user/\\d+/gvfs/.+$", + QRegularExpression::DotMatchesEverythingOption + | QRegularExpression::DontCaptureOption + | QRegularExpression::OptimizeOnFirstUsageOption); + + if (regExp.match(path, 0, QRegularExpression::NormalMatch, QRegularExpression::DontCheckSubjectStringMatchOption).hasMatch()) + return false; + + // 保险箱路径直接返回真 + if (VaultController::isVaultFile(path)){ + return true; + } + + QString device = DStorageInfo(path).device(); + if (isEx && device.isEmpty()) { + return true; + } + return (device.startsWith("/dev/")); +} + +bool DStorageInfo::isLowSpeedDevice(const QString &path) +{ + static QMutex mutex; + QMutexLocker lk(&mutex); + static QRegularExpression regExp("^/run/user/\\d+/gvfs/(?\\w+(-?)\\w+):\\S*", + QRegularExpression::DotMatchesEverythingOption + | QRegularExpression::DontCaptureOption + | QRegularExpression::OptimizeOnFirstUsageOption); + + const QRegularExpressionMatch &match = regExp.match(path, 0, QRegularExpression::NormalMatch, + QRegularExpression::DontCheckSubjectStringMatchOption); + + if (match.hasMatch()) { + const QString &scheme = match.captured("scheme"); + + return dfm_util::isContains(scheme, + QString(MTP_SCHEME), + QString(GPHOTO2_SCHEME), + QString("gphoto"), + QString("smb-share"), + QString(SMB_SCHEME), + QString(SFTP_SCHEME), + QString(FTP_SCHEME)); + } + + return DStorageInfo(path).isLowSpeedDevice(); +} + +bool DStorageInfo::isCdRomDevice(const QString &path) +{ + return DStorageInfo(path).device().startsWith("/dev/sr"); +} + +bool DStorageInfo::isSameFile(const QString &filePath1, const QString &filePath2) +{ + struct stat statFromInfo; + struct stat statToInfo; + int fromStat = stat(filePath1.toStdString().c_str(), &statFromInfo); + int toStat = stat(filePath2.toStdString().c_str(), &statToInfo); + if (0 == fromStat && 0 == toStat) { + // 通过inode判断是否是同一个文件 + if (statFromInfo.st_ino == statToInfo.st_ino + && statFromInfo.st_dev == statToInfo.st_dev) { //! 需要判断设备号 + return true; + } + } + return false; +} + +DFM_END_NAMESPACE + +QT_BEGIN_NAMESPACE +QDebug operator<<(QDebug debug, const DFM_NAMESPACE::DStorageInfo &info) +{ + QDebugStateSaver saver(debug); + Q_UNUSED(saver) + debug.nospace(); + debug.noquote(); + debug << "DStorageInfo("; + if (info.isValid()) { + debug << '"' << info.rootPath() << '"'; + if (!info.fileSystemType().isEmpty()) + debug << ", type=" << info.fileSystemType(); + if (!info.name().isEmpty()) + debug << ", name=\"" << info.name() << '"'; + if (!info.device().isEmpty()) + debug << ", device=\"" << info.device() << '"'; +#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) + if (!info.subvolume().isEmpty()) + debug << ", subvolume=\"" << info.subvolume() << '"'; +#endif + if (info.isReadOnly()) + debug << " [read only]"; + debug << (info.isReady() ? " [ready]" : " [not ready]"); + if (info.bytesTotal() > 0) { + debug << ", bytesTotal=" << info.bytesTotal() << ", bytesFree=" << info.bytesFree() + << ", bytesAvailable=" << info.bytesAvailable(); + } + } else { + debug << "invalid"; + } + debug<< ')'; + return debug; +} +QT_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dstorageinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dstorageinfo.h new file mode 100644 index 0000000..5d08b05 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/dstorageinfo.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DSTORAGEINFO_H +#define DSTORAGEINFO_H + +#include + +#include + +DFM_BEGIN_NAMESPACE + +class DStorageInfoPrivate; +class DStorageInfo : public QStorageInfo +{ + Q_DECLARE_PRIVATE(DStorageInfo) + +public: + enum PathHint { + NoHint = 0x00, + FollowSymlink = 0x01, + }; + + Q_DECLARE_FLAGS(PathHints, PathHint) + + DStorageInfo(); + explicit DStorageInfo(const QString &path, PathHints hints = PathHint::NoHint); + explicit DStorageInfo(const QDir &dir, PathHints hints = PathHint::NoHint); + DStorageInfo(const DStorageInfo &other); + ~DStorageInfo(); + + DStorageInfo &operator=(const DStorageInfo &other); +#ifdef Q_COMPILER_RVALUE_REFS + DStorageInfo &operator=(DStorageInfo &&other) Q_DECL_NOTHROW { swap(other); return *this; } +#endif + + inline void swap(DStorageInfo &other) Q_DECL_NOTHROW + { qSwap(d_ptr, other.d_ptr); } + + void setPath(const QString &path, PathHints hints = PathHint::NoHint); + + QString rootPath() const; + QByteArray device() const; + QByteArray fileSystemType() const; + + qint64 bytesTotal() const; + qint64 bytesFree() const; + qint64 bytesAvailable() const; + + bool isReadOnly() const; + bool isLocalDevice() const; + bool isLowSpeedDevice() const; + + bool isValid() const; + void refresh(); + + static bool inSameDevice(QString path1, QString path2, PathHints hints = PathHint::NoHint); + static bool inSameDevice(const DUrl &url1, const DUrl &url2, PathHints hints = PathHint::NoHint); + static bool isLocalDevice(const QString &path,const bool &isEx = false); + static bool isLowSpeedDevice(const QString &path); + static bool isCdRomDevice(const QString &path); + static bool isSameFile(const QString &filePath1, const QString &filePath2); //通过文件(文件夹)的inode,判断是否是同一个文件(文件夹) + +private: + friend bool operator==(const DStorageInfo &first, const DStorageInfo &second); + + QExplicitlySharedDataPointer d_ptr; +}; + +inline bool operator==(const DStorageInfo &first, const DStorageInfo &second) +{ + if (first.d_ptr == second.d_ptr) + return true; + + return first.device() == second.device() && first.rootPath() == second.rootPath(); +} + +inline bool operator!=(const DStorageInfo &first, const DStorageInfo &second) +{ + return !(first == second); +} + +DFM_END_NAMESPACE + +QT_BEGIN_NAMESPACE +#ifndef QT_NO_DEBUG_STREAM +Q_CORE_EXPORT QDebug operator<<(QDebug debug, const DFM_NAMESPACE::DStorageInfo &info); +#endif +QT_END_NAMESPACE + +Q_DECLARE_SHARED(DFM_NAMESPACE::DStorageInfo) +Q_DECLARE_METATYPE(DFM_NAMESPACE::DStorageInfo*) + +#endif // DSTORAGEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/io.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/io.pri new file mode 100644 index 0000000..e57902b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/io.pri @@ -0,0 +1,25 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/dlocalfiledevice.h \ + $$PWD/dfileiodeviceproxy.h \ + $$PWD/dfilecopymovejob.h \ + $$PWD/dfilehandler.h \ + $$PWD/dfiledevice.h \ + $$PWD/dlocalfilehandler.h \ + $$PWD/dfilestatisticsjob.h \ + $$PWD/dstorageinfo.h \ + $$PWD/dgiofiledevice.h + +SOURCES += \ + $$PWD/dlocalfiledevice.cpp \ + $$PWD/dfileiodeviceproxy.cpp \ + $$PWD/dfilecopymovejob.cpp \ + $$PWD/dfilehandler.cpp \ + $$PWD/dfiledevice.cpp \ + $$PWD/dlocalfilehandler.cpp \ + $$PWD/dfilestatisticsjob.cpp \ + $$PWD/dstorageinfo.cpp \ + $$PWD/dgiofiledevice.cpp + +include(private/private.pri) diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dfilecopymovejob_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dfilecopymovejob_p.h new file mode 100644 index 0000000..390074a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dfilecopymovejob_p.h @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFILECOPYMOVEJOB_P_H +#define DFILECOPYMOVEJOB_P_H + +#include "dfilecopymovejob.h" +#include "dstorageinfo.h" + +#include "private/qobject_p.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dfiledevice.h" + +typedef QExplicitlySharedDataPointer DAbstractFileInfoPointer; + +DFM_BEGIN_NAMESPACE + +class DFileHandler; +class DFileStatisticsJob; +class ElapsedTimer; +class DFileCopyMoveJobPrivate +{ +public: + struct JobInfo { + enum Type { + Preprocess, + Copy, + Move, + Remove, + Link + }; + + Type action; + QPair targetUrl; + }; + + struct DirectoryInfo { + DStorageInfo sourceStorageInfo; + DStorageInfo targetStorageInfo; + QPair url; + }; + + struct FileCopyInfo { + bool closeflag; + bool isdir; + QSharedPointer handler; + DAbstractFileInfoPointer frominfo; + DAbstractFileInfoPointer toinfo; + char *buffer; + qint64 size; + qint64 currentpos; + QFileDevice::Permissions permission; + FileCopyInfo() : closeflag(true) + , isdir(false) + , handler(nullptr) + , frominfo(nullptr) + , toinfo(nullptr) + , buffer(nullptr) + , size(0) + , currentpos(0) + , permission(QFileDevice::ReadOwner) + { + + } + FileCopyInfo(const FileCopyInfo &other) : closeflag(other.closeflag) + , isdir(other.isdir) + , handler(other.handler) + , frominfo(other.frominfo) + , toinfo(other.toinfo) + , buffer(other.buffer) + , size(other.size) + , currentpos(other.currentpos) + , permission(other.permission) + { + + } + }; + + struct ThreadCopyInfo { + QSharedPointer handler = nullptr; + DAbstractFileInfoPointer fromInfo; + DAbstractFileInfoPointer toInfo; + QSharedPointer fromDevice = nullptr; + QSharedPointer toDevice = nullptr; + }; + + struct DirSetPermissonInfo { + QSharedPointer handler = nullptr; + QFileDevice::Permissions permission; + DUrl target; + }; + + typedef QSharedPointer FileCopyInfoPointer; + + explicit DFileCopyMoveJobPrivate(DFileCopyMoveJob *qq); + ~DFileCopyMoveJobPrivate(); + + static QString errorToString(DFileCopyMoveJob::Error error); + // 返回当前线程已经往block设备写入的数据,返回的是本次和上次间隔时间内写入的大小 + static qint64 getWriteBytes(long tid); + qint64 getWriteBytes() const; + // 返回当前目标设备已写入扇区总数 + // /sys/dev/block/[x:x]/stat 的第7个字段 + // https://www.kernel.org/doc/Documentation/iostats.txt + qint64 getSectorsWritten() const; + // 返回已写入数据大小,根据多种情况,用不同的方式获取此数据 + qint64 getCompletedDataSize() const; + + void setState(DFileCopyMoveJob::State s); + void setError(DFileCopyMoveJob::Error e, const QString &es = QString()); + void unsetError(); + DFileCopyMoveJob::Action handleError(const DAbstractFileInfoPointer sourceInfo, const DAbstractFileInfoPointer targetInfo); + DFileCopyMoveJob::Action setAndhandleError(DFileCopyMoveJob::Error e, const DAbstractFileInfoPointer sourceInfo, + const DAbstractFileInfoPointer targetInfo, const QString &es = QString()); + + bool isRunning(); // bug 26333, add state function to check the job status + bool jobWait(); + bool stateCheck(); + bool checkFileSize(qint64 size) const; + bool checkFreeSpace(qint64 needSize); + QString formatFileName(const QString &name) const; + + static QString getNewFileName(const DAbstractFileInfoPointer sourceFileInfo, const DAbstractFileInfoPointer targetDirectory); + + bool doProcess(const DUrl &from, const DAbstractFileInfoPointer source_info, const DAbstractFileInfoPointer target_info, const bool isNew = false); + bool mergeDirectory(const QSharedPointer &handler, const DAbstractFileInfoPointer fromInfo, const DAbstractFileInfoPointer toInfo); + bool doCopyFile(const DAbstractFileInfoPointer fromInfo, const DAbstractFileInfoPointer toInfo, const QSharedPointer &handler, int blockSize = 1048576); + bool doCopySmallFilesOnDisk(const DAbstractFileInfoPointer fromInfo, const DAbstractFileInfoPointer toInfo, + const QSharedPointer &fromDevice, const QSharedPointer &toDevice, + const QSharedPointer &handler); + //线程池中拷贝大量小文件 + bool doThreadPoolCopyFile(); + //拷贝文件到块设备(除光驱和系统所在的磁盘) + bool doCopyFileOnBlock(const DAbstractFileInfoPointer fromInfo, const DAbstractFileInfoPointer toInfo, const QSharedPointer &handler, int blockSize = 1048576); + bool doRemoveFile(const QSharedPointer &handler, const DAbstractFileInfoPointer fileInfo, + const DAbstractFileInfoPointer &toInfo = DAbstractFileInfoPointer(nullptr)); + bool doRenameFile(const QSharedPointer &handler, const DAbstractFileInfoPointer oldInfo, const DAbstractFileInfoPointer newInfo); + bool doLinkFile(const QSharedPointer &handler, const DAbstractFileInfoPointer fileInfo, const QString &linkPath); + + /** + * @brief convertTrashFile 对回收站根目录下的文件进行转换,将其移动到上级expunged目录下 + * @param fileInfo 文件信息 + */ + void convertTrashFile(DAbstractFileInfoPointer &fileInfo); + + bool process(const DUrl from, const DAbstractFileInfoPointer target_info); + bool process(const DUrl from, const DAbstractFileInfoPointer source_info, const DAbstractFileInfoPointer target_info, const bool isNew = false); + bool copyFile(const DAbstractFileInfoPointer fromInfo, const DAbstractFileInfoPointer toInfo, const QSharedPointer &handler, int blockSize = 1048576); + bool removeFile(const QSharedPointer &handler, const DAbstractFileInfoPointer fileInfo); + bool renameFile(const QSharedPointer &handler, const DAbstractFileInfoPointer oldInfo, const DAbstractFileInfoPointer newInfo); + bool linkFile(const QSharedPointer &handler, const DAbstractFileInfoPointer fileInfo, const QString &linkPath); + + void beginJob(JobInfo::Type type, const DUrl from, const DUrl target, const bool isNew = false); + void endJob(const bool isNew = false); + void enterDirectory(const DUrl from, const DUrl to); + void leaveDirectory(); + void joinToCompletedFileList(const DUrl from, const DUrl target, qint64 dataSize); + void joinToCompletedDirectoryList(const DUrl from, const DUrl target, qint64 dataSize); + void updateProgress(); + void updateCopyProgress(); + void updateMoveProgress(); + void updateSpeed(); + void _q_updateProgress(); + void countrefinesize(const qint64 &size); + + //第二版优化 + bool writeRefineThread(); + bool writeToFileByQueue(); + bool skipReadFileDealWriteThread(const DUrl &url); + void cancelReadFileDealWriteThread(); + void setRefineCopyProccessSate(const DFileCopyMoveJob::RefineCopyProccessSate &stat); + bool checkRefineCopyProccessSate(const DFileCopyMoveJob::RefineCopyProccessSate &stat); + void checkTagetNeedSync();//检测目标目录是网络文件就每次拷贝去同步,否则网络很卡时会因为同步卡死 + void checkTagetIsFromBlockDevice();//检查目标文件是否是块设备 + bool checkWritQueueEmpty(); + bool checkWritQueueCount(); + QSharedPointer writeQueueDequeue(); + void writeQueueEnqueue(const QSharedPointer ©info); + //错误队列处理 + void errorQueueHandling(); + //当前错误队列处理完成 + void errorQueueHandled(const bool &isNotCancel = true); + //清理当前拷贝信息 + void releaseCopyInfo(const FileCopyInfoPointer &info); + /** + * @brief setCutTrashData 保存剪切回收站文件路径 + * @param fileNameList 文件路径 + */ + void setCutTrashData(QVariant fileNameList); + //fix bug 61565 + //线程安全保存当前工作的device + void saveCurrentDevice(const DUrl &url,const QSharedPointer device); + //线程安全移出当前工作的device + void removeCurrentDevice(const DUrl &url); + //线程安全移出当前工作的device + void stopAllDeviceOperation(); + //清理线程池资源 + void clearThreadPool(); + + void waitRefineThreadFinish(); + void setLastErrorAction(const DFileCopyMoveJob::Action &action); + DFileCopyMoveJob::Action getLastErrorAction(); + qint64 reopenGvfsFiles(const DAbstractFileInfoPointer &fromInfo, const DAbstractFileInfoPointer &toInfo, + QSharedPointer &fromDevice, QSharedPointer &toDevice, + const bool &isWriteError = true); + DFileCopyMoveJob::Action seekFile(const DAbstractFileInfoPointer &fileInfo, + QSharedPointer &device, const qint64 &pos); + DFileCopyMoveJob::Action openGvfsFile(const DAbstractFileInfoPointer &fileInfo, + QSharedPointer &device, + const QIODevice::OpenMode &flags); + void cleanCopySources(char *data, const QSharedPointer &fromDevice, + const QSharedPointer &toDevice, bool &isError); + DFileCopyMoveJob::GvfsRetryType gvfsFileRetry(char * data, bool &isErrorOccur, qint64 ¤tPos, const DAbstractFileInfoPointer &fromInfo, const DAbstractFileInfoPointer &toInfo, + QSharedPointer &fromDevice, QSharedPointer &toDevice, + const bool &isWriteError = true); + void readAheadSourceFile(const DAbstractFileInfoPointer &fromInfo); + bool handleUnknowUrlError(const DAbstractFileInfoPointer &fromInfo,const DAbstractFileInfoPointer &toInfo); + bool handleUnknowError(const DAbstractFileInfoPointer &fromInfo, const DAbstractFileInfoPointer &toInfo, const QString &errorStr); + void sendCopyInfo(const DAbstractFileInfoPointer &fromInfo,const DAbstractFileInfoPointer &toInfo); + void cleanDoCopyFileSource(char *data, const DAbstractFileInfoPointer &fromInfo,const DAbstractFileInfoPointer &toInfo, const QSharedPointer &fromDevice, + const QSharedPointer &toDevice); + // 初始化优化状态 + void initRefineState(); + //! 剪切回收站文件路径 + QQueue m_fileNameList; + + DFileCopyMoveJob *q_ptr; + + QWaitCondition waitCondition; + QWaitCondition m_waitConditionCopyLargeFileOnDisk; + + DFileCopyMoveJob::Handle *handle = nullptr; + DFileCopyMoveJob::Mode mode = DFileCopyMoveJob::CopyMode; + DFileCopyMoveJob::Error error = DFileCopyMoveJob::NoError; + DFileCopyMoveJob::FileHints fileHints = DFileCopyMoveJob::NoHint; + QString errorString; + QAtomicInt state = DFileCopyMoveJob::StoppedState; + QMap m_lastErrorHandleAction; + QMutex m_lastErrorHandleActionMutex; + + DUrlList sourceUrlList; + DUrlList targetUrlList; + DUrl targetUrl; + + + qint64 totalsize = 0; + qint32 totalfilecount = 0; + QAtomicInteger m_isCountSizeOver = false; + QAtomicInteger cansetnoerror = true; + QAtomicInteger m_isFileOnDiskUrls = false; + + qint64 m_tatol = 0; + qint64 m_sart = 0; + + QQueue m_writeFileQueue; + QAtomicInt m_copyRefineFlag = DFileCopyMoveJob::NoProccess; + QFuture m_writeResult, m_syncResult; + + + // 是否可以使用 /pric/[pid]/task/[tid]/io 文件中的的 writeBytes 字段的值作为判断已写入数据的依据 + qint8 canUseWriteBytes : 1; + // 目标磁盘设备是不是可移除或者热插拔设备 + qint8 targetIsRemovable : 1; + // 逻辑扇区大小 + qint16 targetLogSecionSize = 512; + // 记录任务开始时目标磁盘设备已写入扇区数 + qint64 targetDeviceStartSectorsWritten; + // /sys/dev/block/x:x + QString targetSysDevPath; + // 目标设备所挂载的根目录 + QString targetRootPath; + + QPointer threadOfErrorHandle; + DFileCopyMoveJob::Action actionOfError[DFileCopyMoveJob::UnknowError] = {DFileCopyMoveJob::NoAction}; + DFileStatisticsJob *fileStatistics = nullptr; + + QStack jobStack; + QStack directoryStack; + QList> completedFileList; + QList> completedDirectoryList; + int completedFilesCount = 0; + int totalMoveFilesCount = 1; + qint64 completedDataSize = 0; + qint64 completedProgressDataSize = 0; + //跳过文件大小统计 + qint64 skipFileSize = 0; + // 已经写入到block设备的总大小 + qint64 completedDataSizeOnBlockDevice = 0; + QPair currentJobDataSizeInfo; + int currentJobFileHandle = -1; + ElapsedTimer *updateSpeedElapsedTimer = nullptr; + QTimer *updateSpeedTimer = nullptr; + int timeOutCount = 0; + QAtomicInteger needUpdateProgress = false; + QAtomicInteger countStatisticsFinished = false; + // 线程id + long tid = -1; + + qreal lastProgress = 0.01; // 上次刷新的进度 + + int currentThread = 0; + + QAtomicInteger m_bTaskDailogClose = false; + + QAtomicInt m_refineStat = DFileCopyMoveJob::RefineLocal; + //优化盘内拷贝,启用的线程池 + QThreadPool m_pool; + QAtomicInteger m_bDestLocal = false; + qint64 m_refineCopySize = 0; + QMutex m_refineMutex; + //是否需要显示进度条 + QAtomicInteger m_isNeedShowProgress = false; + //是否需要每读写一次同步 + bool m_isEveryReadAndWritesSnc = false; + QAtomicInteger m_isVfat = false; + QAtomicInt m_openFlag = O_CREAT | O_WRONLY | O_TRUNC; + //分断拷贝的线程数量 + QAtomicInt m_bigFileThreadCount = 0; + QAtomicInteger m_isWriteThreadStart = false; + //目标目录是否是来自块设备 + QAtomicInteger m_isTagFromBlockDevice = false; + //读线程跳过的文件 + QQueue m_skipFileQueue; + //目标文件是否是gvfs目录 + QAtomicInteger m_isTagGvfsFile = false; + //拷贝信息的队列锁 + QMutex m_copyInfoQueueMutex; + QMutex m_skipFileQueueMutex; + //当前拷贝的device + QMap> m_currentDevice; + QMutex m_currentDeviceMutex; + //当前本地目录大小 + qint32 m_currentDirSize = 0; + //当前拷贝进程是否显示了进度条 + QAtomicInteger m_isProgressShow = false; + + QMutex m_checkStatMutex; + + //拷贝本地大文件中 + QAtomicInteger m_isCopyLargeFileOnDiskWait = false; + static QQueue CopyLargeFileOnDiskQueue; + static QMutex CopyLargeFileOnDiskMutex; + + //多线程拷贝小文件错误处理变量 + QQueue m_errorQueue; + QWaitCondition m_errorCondition; + QMutex m_errorQueueMutex; + QMutex m_stopMutex; + QMutex m_clearThreadPoolMutex; + QQueue> m_threadInfos; + QMutex m_threadMutex; + QMap m_emitUrl; + QMutex m_emitUrlMutex; + + //打开写入文件的fd + QMap m_writeOpenFd; + QList> m_dirPermissonList; + + qint64 m_gvfsFileInnvliadProgress = 0; + + Q_DECLARE_PUBLIC(DFileCopyMoveJob) +}; + +DFM_END_NAMESPACE + +#endif // DFILECOPYMOVEJOB_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dfiledevice_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dfiledevice_p.h new file mode 100644 index 0000000..9c593f4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dfiledevice_p.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFILEDEVICE_P_H +#define DFILEDEVICE_P_H + +#include "dfmglobal.h" +#include "dfiledevice.h" + +DFM_BEGIN_NAMESPACE + +class DFileDevicePrivate +{ +public: + explicit DFileDevicePrivate(DFileDevice *qq); + virtual ~DFileDevicePrivate(); + + DFileDevice *q_ptr; + DUrl url; + + Q_DECLARE_PUBLIC(DFileDevice) +}; + +DFM_END_NAMESPACE + +#endif // DFILEDEVICE_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dfilehandler_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dfilehandler_p.h new file mode 100644 index 0000000..51f136c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dfilehandler_p.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFILEHANDLER_P_H +#define DFILEHANDLER_P_H + +#include "dfilehandler.h" + +DFM_BEGIN_NAMESPACE + +class DFileHandlerPrivate +{ +public: + explicit DFileHandlerPrivate(DFileHandler *qq); + + void setErrorString(const QString &es); + + DFileHandler *q_ptr; + QString errorString; +}; + +DFM_END_NAMESPACE + +#endif // DFILEHANDLER_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dfileiodeviceproxy_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dfileiodeviceproxy_p.h new file mode 100644 index 0000000..64e30f5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dfileiodeviceproxy_p.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DFILEIODEVICEPROXY_P_H +#define DFILEIODEVICEPROXY_P_H + +#include "dfileiodeviceproxy.h" +#include "dfiledevice_p.h" + +#include + +DFM_BEGIN_NAMESPACE +class DFileIODeviceProxyPrivate : public DFileDevicePrivate +{ +public: + explicit DFileIODeviceProxyPrivate(DFileIODeviceProxy *qq); + + QPointer device = nullptr; +}; +DFM_END_NAMESPACE + +#endif // DFILEIODEVICEPROXY_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dlocalfiledevice_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dlocalfiledevice_p.h new file mode 100644 index 0000000..002f501 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/dlocalfiledevice_p.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef DLOCALFILEDEVICE_P_H +#define DLOCALFILEDEVICE_P_H + +#include "dfileiodeviceproxy_p.h" + +DFM_BEGIN_NAMESPACE + +class DLocalFileDevicePrivate : public DFileIODeviceProxyPrivate +{ +public: + explicit DLocalFileDevicePrivate(dde_file_manager::DLocalFileDevice *qq); + + ~DLocalFileDevicePrivate() override; + + QPointer file = nullptr; + + Q_DECLARE_PUBLIC(DLocalFileDevice) +}; + +DFM_END_NAMESPACE + +#endif // DLOCALFILEDEVICE_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/private.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/private.pri new file mode 100644 index 0000000..1edf51a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/io/private/private.pri @@ -0,0 +1,6 @@ +HEADERS += \ + $$PWD/dlocalfiledevice_p.h \ + $$PWD/dfileiodeviceproxy_p.h \ + $$PWD/dfilecopymovejob_p.h \ + $$PWD/dfiledevice_p.h \ + $$PWD/dfilehandler_p.h diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/dfmLogManager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/dfmLogManager.cpp new file mode 100644 index 0000000..e3cf4dc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/dfmLogManager.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "dfmLogManager.h" +#include +#include +#include "filterAppender.h" +#include +#include + + +DCORE_USE_NAMESPACE +/** + * \class DFMLogManager + * + * \brief DFMLogManager is the deepin user application log manager + */ + +DFM_BEGIN_NAMESPACE +DFMLogManager::DFMLogManager() + : m_filterAppender(nullptr) +{ +} + +void DFMLogManager::initFilterAppender() +{ + if (m_filterAppender) + return; + + m_filterAppender = new FilterAppender(DLogManager::getlogFilePath()); + m_filterAppender->setFormat( + "%{time}{yyyy-MM-dd, HH:mm:ss.zzz} [%{type:-7}] [%{file:-20} %{function:-35} %{line}] %{message}\n"); + m_filterAppender->setLogFilesLimit(5); + m_filterAppender->setDatePattern(FilterAppender::DailyRollover); + logger->registerAppender(m_filterAppender); +} + +FilterAppender *DFMLogManager::filterAppender() +{ + if (!m_filterAppender) { + initFilterAppender(); + } + return m_filterAppender; +} + +//! Registers the appender to write the log records to the Console +/** + * \sa registerFileAppender + */ +void DFMLogManager::registerConsoleAppender() +{ + DLogManager::registerConsoleAppender(); +} + +//! Registers the appender to write the log records to the file +/** + * \sa getlogFilePath + * \sa registerConsoleAppender + */ +void DFMLogManager::registerFileAppender() +{ + DFMLogManager::instance()->initFilterAppender(); +} + +//! Return the path file log storage +/** + * \sa registerFileAppender + */ +QString DFMLogManager::getlogFilePath() +{ + return DLogManager::getlogFilePath(); +} + +void DFMLogManager::setlogFilePath(const QString &logFilePath) +{ + DLogManager::setlogFilePath(logFilePath); +} + +void DFMLogManager::setLogFormat(const QString &format) +{ + DLogManager::setLogFormat(format); +} + +Logger *DFMLogManager::getLogger() +{ + return Logger::globalInstance(); +} + +FilterAppender *DFMLogManager::getFilterAppender() +{ + return DFMLogManager::instance()->filterAppender(); +} + +DFMLogManager::~DFMLogManager() +{ +} +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/dfmLogManager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/dfmLogManager.h new file mode 100644 index 0000000..d4039b0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/dfmLogManager.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef DFMLOGMANAGER_H +#define DFMLOGMANAGER_H + +#include +#include + +class ConsoleAppender; +class FilterAppender; +namespace Dtk { + namespace Core { + class Logger; + } +} + +DFM_BEGIN_NAMESPACE +/** + * @brief The DFMLogManager class + * re-wrap the log function of dtk, add filter function. + */ +class DFMLogManager +{ +public: + static void registerConsoleAppender(); + static void registerFileAppender(); + + static QString getlogFilePath(); + + /*! + * \brief setlogFilePath will change log file path of registerFileAppender + * \param logFilePath is the full path of file appender log + */ + static void setlogFilePath(const QString& logFilePath); + + static void setLogFormat(const QString& format); + + static Dtk::Core::Logger *getLogger(); + + static FilterAppender *getFilterAppender(); + +private: + FilterAppender* m_filterAppender; + + void initFilterAppender(); + FilterAppender *filterAppender(); + + inline static DFMLogManager* instance(){ + static DFMLogManager instance; + return &instance; + } + explicit DFMLogManager(); + ~DFMLogManager(); + DFMLogManager(const DFMLogManager &); + DFMLogManager & operator = (const DFMLogManager &); +}; +DFM_END_NAMESPACE + +#endif // DFMLOGMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/filterAppender.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/filterAppender.cpp new file mode 100644 index 0000000..55237e5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/filterAppender.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include +#include +#include + +#include "filterAppender.h" + +DCORE_USE_NAMESPACE + +FilterAppender::FilterAppender(const QString &fileName) + : FileAppender(fileName) + , m_frequency(MinutelyRollover) + , m_logFilesLimit(0) + , m_logSizeLimit(1024 * 1024 * 20) +{} + +void FilterAppender::append(const QDateTime &timeStamp, Logger::LogLevel logLevel, const char *file, int line, + const char *function, const QString &category, const QString &message) +{ + QMutexLocker locker(&m_filterMutex); + + //! 关键字过滤 + Q_FOREACH (auto filter, m_filters) { + if (message.contains(filter)) + return; + } + locker.unlock(); + + if (!m_rollOverTime.isNull() && QDateTime::currentDateTime() > m_rollOverTime) + rollOver(); + + if (size() > m_logSizeLimit) + rollOver(); + + FileAppender::append(timeStamp, logLevel, file, line, function, category, message); +} + + +FilterAppender::DatePattern FilterAppender::datePattern() const +{ + QMutexLocker locker(&m_rollingMutex); + return m_frequency; +} + + +QString FilterAppender::datePatternString() const +{ + QMutexLocker locker(&m_rollingMutex); + return m_datePatternString; +} + + +void FilterAppender::setDatePattern(DatePattern datePattern) +{ + setDatePatternString(QLatin1String("'.'yyyy-MM-dd-hh-mm-zzz")); + + QMutexLocker locker(&m_rollingMutex); + m_frequency = datePattern; + + computeRollOverTime(); +} + + +void FilterAppender::setDatePattern(const QString &datePattern) +{ + setDatePatternString(datePattern); + computeFrequency(); + + computeRollOverTime(); +} + + +void FilterAppender::setDatePatternString(const QString &datePatternString) +{ + QMutexLocker locker(&m_rollingMutex); + m_datePatternString = datePatternString; +} + + +void FilterAppender::computeFrequency() +{ + QMutexLocker locker(&m_rollingMutex); + + const QDateTime startTime(QDate(1999, 1, 1), QTime(0, 0)); + const QString startString = startTime.toString(m_datePatternString); + + if (startString != startTime.addSecs(60).toString(m_datePatternString)) + m_frequency = MinutelyRollover; + else if (startString != startTime.addSecs(60 * 60).toString(m_datePatternString)) + m_frequency = HourlyRollover; + else if (startString != startTime.addSecs(60 * 60 * 12).toString(m_datePatternString)) + m_frequency = HalfDailyRollover; + else if (startString != startTime.addDays(1).toString(m_datePatternString)) + m_frequency = DailyRollover; + else if (startString != startTime.addDays(7).toString(m_datePatternString)) + m_frequency = WeeklyRollover; + else if (startString != startTime.addMonths(1).toString(m_datePatternString)) + m_frequency = MonthlyRollover; + else { + Q_ASSERT_X(false, "DailyRollingFileAppender::computeFrequency", "The pattern '%1' does not specify a frequency"); + return; + } +} + + +void FilterAppender::removeOldFiles() +{ + if (m_logFilesLimit <= 1) + return; + + QFileInfo fileInfo(fileName()); + QDir logDirectory(fileInfo.absoluteDir()); + logDirectory.setFilter(QDir::Files); + logDirectory.setNameFilters(QStringList() << fileInfo.fileName() + "*"); + QFileInfoList logFiles = logDirectory.entryInfoList(); + + QMap fileDates; + for (int i = 0; i < logFiles.length(); ++i) { + QString name = logFiles[i].fileName(); + QString suffix = name.mid(name.indexOf(fileInfo.fileName()) + fileInfo.fileName().length()); + QDateTime fileDateTime = QDateTime::fromString(suffix, datePatternString()); + + if (fileDateTime.isValid()) + fileDates.insert(fileDateTime, logFiles[i].absoluteFilePath()); + } + + QList fileDateNames = fileDates.values(); + for (int i = 0; i < fileDateNames.length() - m_logFilesLimit + 1; ++i) + QFile::remove(fileDateNames[i]); +} + + +void FilterAppender::computeRollOverTime() +{ + Q_ASSERT_X(!m_datePatternString.isEmpty(), "DailyRollingFileAppender::computeRollOverTime()", "No active date pattern"); + + QDateTime now = QDateTime::currentDateTime(); + QDate nowDate = now.date(); + QTime nowTime = now.time(); + QDateTime start; + + switch (m_frequency) { + case MinutelyRollover: { + start = QDateTime(nowDate, nowTime); + m_rollOverTime = start.addSecs(60); + } + break; + case HourlyRollover: { + start = QDateTime(nowDate, nowTime); + m_rollOverTime = start.addSecs(60 * 60); + } + break; + case HalfDailyRollover: { + int hour = nowTime.hour(); + if (hour >= 12) + hour = 12; + else + hour = 0; + start = QDateTime(nowDate, nowTime); + m_rollOverTime = start.addSecs(60 * 60 * 12); + } + break; + case DailyRollover: { + start = QDateTime(nowDate, nowTime); + m_rollOverTime = start.addDays(1); + } + break; + case WeeklyRollover: { + // Qt numbers the week days 1..7. The week starts on Monday. + // Change it to being numbered 0..6, starting with Sunday. + int day = nowDate.dayOfWeek(); + if (day == Qt::Sunday) + day = 0; + start = QDateTime(nowDate, nowTime).addDays(-1 * day); + m_rollOverTime = start.addDays(7); + } + break; + case MonthlyRollover: { + start = QDateTime(QDate(nowDate.year(), nowDate.month(), 1), nowTime); + m_rollOverTime = start.addMonths(1); + } + break; + default: + Q_ASSERT_X(false, "DailyRollingFileAppender::computeInterval()", "Invalid datePattern constant"); + m_rollOverTime = QDateTime::fromTime_t(0); + } + + m_rollOverSuffix = start.toString(m_datePatternString); + Q_ASSERT_X(m_rollOverSuffix != m_rollOverTime.toString(m_datePatternString), + "DailyRollingFileAppender::computeRollOverTime()", "File name does not change with rollover"); +} + + +void FilterAppender::rollOver() +{ + Q_ASSERT_X(!m_datePatternString.isEmpty(), "DailyRollingFileAppender::rollOver()", "No active date pattern"); + + QString rollOverSuffix = m_rollOverSuffix; + computeRollOverTime(); + if (rollOverSuffix == m_rollOverSuffix) + return; + + closeFile(); + + QString targetFileName = fileName() + rollOverSuffix; + QFile f(targetFileName); + if (f.exists() && !f.remove()) + return; + f.setFileName(fileName()); + if (!f.rename(targetFileName)) + return; + + openFile(); + removeOldFiles(); +} + + +void FilterAppender::setLogFilesLimit(int limit) +{ + QMutexLocker locker(&m_rollingMutex); + m_logFilesLimit = limit; +} + + +int FilterAppender::logFilesLimit() const +{ + QMutexLocker locker(&m_rollingMutex); + return m_logFilesLimit; +} + +void FilterAppender::addFilter(const QString &filterField) +{ + QMutexLocker locker(&m_filterMutex); + m_filters << filterField; +} + +void FilterAppender::removeFilter(const QString &filterField) +{ + QMutexLocker locker(&m_filterMutex); + m_filters.removeAll(filterField); +} + +const QStringList &FilterAppender::getFilters() const +{ + return m_filters; +} + +void FilterAppender::clearFilters() +{ + QMutexLocker locker(&m_filterMutex); + m_filters.clear(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/filterAppender.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/filterAppender.h new file mode 100644 index 0000000..999cd32 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/filterAppender.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef FILTERAPPENDER_H +#define FILTERAPPENDER_H + +#include + +#include + +/*! + * \brief The RollingFileAppender(modifed as FilterAppender) class extends FileAppender so that the underlying file is rolled over at a user chosen frequency. + * + * The class is based on Log4Qt.DailyRollingFileAppender class (http://log4qt.sourceforge.net/) + * and has the same date pattern format. + * + * For example, if the fileName is set to /foo/bar and the DatePattern set to the daily rollover ('.'yyyy-MM-dd'.log'), on 2014-02-16 at midnight, + * the logging file /foo/bar.log will be copied to /foo/bar.2014-02-16.log and logging for 2014-02-17 will continue in /foo/bar + * until it rolls over the next day. + * + * The logFilesLimit parameter is used to automatically delete the oldest log files in the directory during rollover + * (so no more than logFilesLimit recent log files exist in the directory at any moment). + * \sa setDatePattern(DatePattern), setLogFilesLimit(int) + */ +class CUTELOGGERSHARED_EXPORT FilterAppender : public DTK_CORE_NAMESPACE::FileAppender +{ +public: + /*! + * The enum DatePattern defines constants for date patterns. + * \sa setDatePattern(DatePattern) + */ + enum DatePattern { + /*! The minutely date pattern string is "'.'yyyy-MM-dd-hh-mm". */ + MinutelyRollover = 0, + /*! The hourly date pattern string is "'.'yyyy-MM-dd-hh". */ + HourlyRollover, + /*! The half-daily date pattern string is "'.'yyyy-MM-dd-a". */ + HalfDailyRollover, + /*! The daily date pattern string is "'.'yyyy-MM-dd". */ + DailyRollover, + /*! The weekly date pattern string is "'.'yyyy-ww". */ + WeeklyRollover, + /*! The monthly date pattern string is "'.'yyyy-MM". */ + MonthlyRollover + }; + + explicit FilterAppender(const QString &fileName = QString()); + + DatePattern datePattern() const; + void setDatePattern(DatePattern datePattern); + void setDatePattern(const QString &datePattern); + + QString datePatternString() const; + + void setLogFilesLimit(int limit); + int logFilesLimit() const; + + /** + * @brief addFilter 添加过滤关键字 + * @param filterField 需要过滤的关键字 + */ + void addFilter(const QString &filterField); + + /** + * @brief removeFilter 移除过滤关键字 + * @param filterField 需要移除的关键字 + */ + void removeFilter(const QString &filterField); + + /** + * @brief getFilters 获取所有的关键字 + * @return + */ + const QStringList &getFilters() const; + + /** + * @brief clearFilters 清除所有需要的关键字 + */ + void clearFilters(); + +protected: + virtual void append(const QDateTime &timeStamp, DTK_CORE_NAMESPACE::Logger::LogLevel logLevel, const char *file, int line, + const char *function, const QString &category, const QString &message); + +private: + void rollOver(); + void computeRollOverTime(); + void computeFrequency(); + void removeOldFiles(); + void setDatePatternString(const QString &datePatternString); + + QString m_datePatternString; + DatePattern m_frequency; + + QDateTime m_rollOverTime; + QString m_rollOverSuffix; + int m_logFilesLimit; + qint64 m_logSizeLimit; + mutable QMutex m_rollingMutex; + + QStringList m_filters; //! 过滤字段 + mutable QMutex m_filterMutex; +}; + +#endif // FILTERAPPENDER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/log.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/log.pri new file mode 100644 index 0000000..ec81686 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/log/log.pri @@ -0,0 +1,8 @@ + +HEADERS += \ + $$PWD/filterAppender.h \ + $$PWD/dfmLogManager.h + +SOURCES += \ + $$PWD/filterAppender.cpp \ + $$PWD/dfmLogManager.cpp diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/mediainfo/dfmmediainfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mediainfo/dfmmediainfo.cpp new file mode 100644 index 0000000..d956d11 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mediainfo/dfmmediainfo.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#include "dfmmediainfo.h" +#include "MediaInfo/MediaInfo.h" +#include +#include +#include +#include + +#define MediaInfo_State_Finished 10000 +using namespace MediaInfoLib; +Q_GLOBAL_STATIC(QQueue, queueDestoryMediaInfo) + +DFM_BEGIN_NAMESPACE +class DFMMediaInfoPrivate : public QSharedData +{ +public: + DFMMediaInfoPrivate(DFMMediaInfo *qq, const QString &file) : q_ptr(qq) + , m_isStopStat(false) + { + m_isWorking.store(false); + m_file = file; + m_mediaInfo = new MediaInfo; + m_timer = new QTimer(qq); + } + + ~DFMMediaInfoPrivate() + { + if (m_timer) + m_timer->stop(); + if (m_mediaInfo) { + // 由于当远程文件夹下存在大量图片文件时,析构mediainfo对象耗时会很长,造成文管卡 + // 所以将对象添加到队列中,开启线程去释放对象 + static QMutex lock; + lock.lock(); + queueDestoryMediaInfo->enqueue(m_mediaInfo); + lock.unlock(); + + static bool isRunning = false; + if (!isRunning) { + isRunning = true; + std::thread thread( + []() { + while (!queueDestoryMediaInfo->isEmpty()) { + lock.lock(); + MediaInfo *mediaInfo = queueDestoryMediaInfo->dequeue(); + lock.unlock(); + + // 这里会很慢 + delete mediaInfo; + mediaInfo = nullptr; + } + isRunning = false; + }); + thread.detach(); + } + } + } + + /** + * @brief bug-35165, 将构造时读取media信息的方式改为独立的方法 + * 以免造成构造对象时直接卡住 + */ + void start() + { + if (m_isStopStat.load()) + return; + Q_Q(DFMMediaInfo); + if (m_isWorking.load()) + return; +// m_isWorking.store(true); + m_mediaInfo->Option(__T("Thread"), __T("1")); // open file in thread.. + m_mediaInfo->Option(__T("Inform"), __T("Text")); + if (m_mediaInfo->Open(m_file.toStdWString()) == 0) { // 可能耗时 + m_timer->setInterval(200); + m_timer->start(); + QObject::connect(m_timer, &QTimer::timeout, q, [this]() { + if (m_mediaInfo) { + if (m_mediaInfo->State_Get() == MediaInfo_State_Finished) { + emit q_ptr->Finished(); + m_timer->stop(); + return ; + } + // if (m_mediaInfo->Count_Get(Stream_Image)>0) + // emit q_ptr->typeFinished("image"); + // if (m_mediaInfo->Count_Get(Stream_Video)>0) + // emit q_ptr->typeFinished("video"); + // if (m_mediaInfo->Count_Get(Stream_Audio)>0) + // emit q_ptr->typeFinished("audio"); + } + }); + } + m_isWorking.store(false); + } + + QString Inform() + { + //m_mediaInfo->Option(__T("Inform"), __T("Text")); + qDebug() << "state:" << m_mediaInfo->State_Get(); // 10000 is ok? + QString info = QString::fromStdWString(m_mediaInfo->Inform()); + return info; + } + + QString Value(const QString &key, stream_t type) + { + QString info = QString::fromStdWString(m_mediaInfo->Get(type, 0, key.toStdWString())); + return info; + } + +private: + std::atomic m_isWorking; + std::atomic m_isStopStat; + QMutex m_mutex; + QString m_file; + MediaInfo *m_mediaInfo {nullptr}; + QTimer *m_timer {nullptr}; + DFMMediaInfo *q_ptr{ nullptr }; + Q_DECLARE_PUBLIC(DFMMediaInfo) +}; + +DFMMediaInfo::DFMMediaInfo(const QString &filename, QObject *parent) + : QObject (parent) + , d_private(new DFMMediaInfoPrivate(this, filename)) +{ + +} + +DFMMediaInfo::~DFMMediaInfo() +{ + +} + +QString DFMMediaInfo::Value(const QString &key, MeidiaType meidiaType/* = General*/) +{ + Q_D(DFMMediaInfo); + return d->Value(key, static_cast(meidiaType)); +} + +void DFMMediaInfo::startReadInfo() +{ + Q_D(DFMMediaInfo); + QMutexLocker lk(&d->m_mutex); + d->start(); +} + +void DFMMediaInfo::stopReadInfo() +{ + Q_D(DFMMediaInfo); + QMutexLocker lk(&d->m_mutex); + d->m_isStopStat.store(true); + if (d->m_timer) + d->m_timer->stop(); + if (d->m_mediaInfo) + d->m_mediaInfo->Close(); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/mediainfo/dfmmediainfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mediainfo/dfmmediainfo.h new file mode 100644 index 0000000..005aeda --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mediainfo/dfmmediainfo.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: dengkeyun + * max-lv + * zhangsheng + * + * 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 + * 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 . + */ + +#pragma once +#include "dfmglobal.h" +#include + +DFM_BEGIN_NAMESPACE +class DFMMediaInfoPrivate; +class DFMMediaInfo : public QObject +{ + Q_OBJECT +public: + enum MeidiaType{ + General, + Video, + Audio, + Text, + Other, + Image, + Menu, + Max, + }; + + DFMMediaInfo(const QString &filename, QObject *parent=nullptr); + ~DFMMediaInfo(); + QString Value(const QString &key, MeidiaType meidiaType = General); + void startReadInfo(); + void stopReadInfo(); +signals: + void Finished(); + +private: + QScopedPointer d_private; + Q_DECLARE_PRIVATE_D(d_private, DFMMediaInfo) +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/mediainfo/mediainfo.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mediainfo/mediainfo.pri new file mode 100644 index 0000000..9e01373 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mediainfo/mediainfo.pri @@ -0,0 +1,9 @@ +HEADERS += \ + $$PWD/dfmmediainfo.h + +SOURCES += \ + $$PWD/dfmmediainfo.cpp + +# make the 'stdlib.h' not exist errors go away when adding the setting QMAKE_CFLAGS_ISYSTEM=-I +QMAKE_CFLAGS_ISYSTEM=-I +PKGCONFIG += libmediainfo diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypeassociations/mimetypeassociations.json b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypeassociations/mimetypeassociations.json new file mode 100644 index 0000000..41948f2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypeassociations/mimetypeassociations.json @@ -0,0 +1,35 @@ +{ + "associations":[ + { + "application/x-zerosize": "text/plain" + }, + { + "text/markdown": "text/plain" + }, + { + "application/json": "text/plain" + }, + { + "text/x-python": "text/plain" + }, + { + "text/css": "text/plain" + }, + { + "text/x-go": "text/plain" + }, + { + "application/javascript": "text/plain" + }, + { + "application/vnd.coffeescript": "text/plain" + }, + { + "text/x-qml": "text/plain" + }, + { + "text/x-log": "text/plain" + } + + ] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/archive.mimetype b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/archive.mimetype new file mode 100644 index 0000000..077bab7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/archive.mimetype @@ -0,0 +1,53 @@ +application/x-7z-compressed +application/x-ace +application/x-alz +application/x-ar +application/x-arj +application/x-stuffit +application/x-bzip +application/x-bzip1 +application/x-bzip1-compressed-tar +application/x-bzip2 +application/vnd.ms-cab-compressed +application/x-cbr +application/x-cbz +application/x-cpio +application/x-deb +application/x-ear +application/x-ms-dos-executable +application/x-cd-image +application/x-java-archive +application/x-lha +application/x-lzip +application/x-lzma +application/x-lzop +application/x-rar +application/x-rpm +application/x-rzip +application/x-tar +application/x-bzip-compressed-tar +application/x-compressed-tar +application/x-lzma-compressed-tar +application/x-lzop-compressed-tar +application/x-7z-compressed-tar +application/x-xz-compressed-tar +application/x-tarz +application/x-lzip-compressed-tar +application/x-war +application/x-webarchive +application/x-xz +application/x-gzip +application/x-compress +application/zip +application/x-zoo +application/vnd.debian.binary-package +application/x-debian-package +application/x-lrzip +application/x-lrzip-compressed-tar +application/x-ms-wim +application/x-rzip-compressed-tar +application/x-xar +application/x-archive +application/gzip +application/x-tzo +application/vnd.rar diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/audio.mimetype b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/audio.mimetype new file mode 100644 index 0000000..e69de29 diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/backup.mimetype b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/backup.mimetype new file mode 100644 index 0000000..c1e5cc5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/backup.mimetype @@ -0,0 +1 @@ +application/x-deepinclone-dim diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/executable.mimetype b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/executable.mimetype new file mode 100644 index 0000000..ad36044 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/executable.mimetype @@ -0,0 +1,5 @@ +application/x-executable +application/x-shellscript +application/x-sharedlib +application/x-iso9660-appimage +application/vnd.appimage diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/image.mimetype b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/image.mimetype new file mode 100644 index 0000000..e69de29 diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/text.mimetype b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/text.mimetype new file mode 100644 index 0000000..95b2191 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/text.mimetype @@ -0,0 +1,39 @@ +application/pdf +application/ofd +application/json +application/postscript +application/x-dvi +application/x-latex +application/msword +application/vnd.ms-powerpoint +application/vnd.ms-excel +application/wps-office.doc +application/wps-office.docx +application/wps-office.dot +application/wps-office.dotx +application/wps-office.dps +application/wps-office.dpt +application/wps-office.et +application/wps-office.ett +application/wps-office.pot +application/wps-office.potx +application/wps-office.ppt +application/wps-office.pptx +application/wps-office.wps +application/wps-office.wpt +application/wps-office.xls +application/wps-office.xlsx +application/wps-office.xlt +application/wps-office.xltx +application/wps-office.pdf +application/octet-stream +application/vnd.ms-htmlhelp +application/x-zerosize +application/vnd.openxmlformats-officedocument.wordprocessingml.document +application/vnd.openxmlformats-officedocument.spreadsheetml.sheet +application/vnd.oasis.opendocument.text +application/vnd.oasis.opendocument.presentation +application/vnd.oasis.opendocument.spreadsheet +application/uot +application/uop +application/uos diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/video.mimetype b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/video.mimetype new file mode 100644 index 0000000..3debcf1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/mimetypes/video.mimetype @@ -0,0 +1,4 @@ +application/vnd.adobe.flash.movie +application/vnd.rn-realmedia +application/vnd.ms-asf +application/mxf \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/avfsfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/avfsfileinfo.cpp new file mode 100644 index 0000000..57323b4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/avfsfileinfo.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "avfsfileinfo.h" + +#include "dfileinfo.h" +#include "private/dabstractfileinfo_p.h" +#include "dfilesystemmodel.h" +#include "controllers/avfsfilecontroller.h" +#include "shutil/fileutils.h" + +#include +#include +#include + +class AVFSFileInfoPrivate : public DAbstractFileInfoPrivate +{ +public: + AVFSFileInfoPrivate(const DUrl &url, AVFSFileInfo *qq) + : DAbstractFileInfoPrivate(url, qq, true) + { + } +}; + +AVFSFileInfo::AVFSFileInfo(const DUrl &avfsUrl): + DAbstractFileInfo(*new AVFSFileInfoPrivate(avfsUrl, this)) +{ + + setProxy(DAbstractFileInfoPointer(new DFileInfo(realFileUrl(avfsUrl)))); +} + +bool AVFSFileInfo::canRename() const +{ + return false; +} + +bool AVFSFileInfo::isWritable() const +{ + return false; +} + +bool AVFSFileInfo::canShare() const +{ + return false; +} + +QVector AVFSFileInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + + QVector actions; + if (type == DAbstractFileInfo::SingleFile) { + actions << MenuAction::Open; + if (!isDir()) + actions << MenuAction::OpenWith; + actions << MenuAction::Separator; + actions << MenuAction::Copy + << MenuAction::Property; + + } else if (type == DAbstractFileInfo::SpaceArea) { + actions << MenuAction::SortBy + << MenuAction::DisplayAs + << MenuAction::Property; + } else { + actions << MenuAction::Open + << MenuAction::Separator + << MenuAction::Copy + << MenuAction::Property; + } + return actions; +} + +bool AVFSFileInfo::canIteratorDir() const +{ + return true; +} + +bool AVFSFileInfo::isDir() const +{ + Q_D(const AVFSFileInfo); + //Temporarily just support one lay arch file parser + QString realFilePath = realFileUrl(fileUrl()).toLocalFile(); + if (FileUtils::isArchive(realFilePath)) { + realFilePath += "#/"; + return QFileInfo(realFilePath).isDir(); + } + return d->proxy->isDir(); +} + +bool AVFSFileInfo::canManageAuth() const +{ + //压缩包内的文件不提供权限管理 + return false; +} + +QString AVFSFileInfo::toLocalFile() const +{ + return fileUrl().path(); +} + +DUrl AVFSFileInfo::parentUrl() const +{ + DUrl durl = DAbstractFileInfo::parentUrl(); + if (fileType() == FileType::Directory) { + durl.setScheme(FILE_SCHEME); + } + return durl; +} + +AVFSFileInfo::AVFSFileInfo(AVFSFileInfoPrivate &dd): + DAbstractFileInfo(dd) +{ +} + +DUrl AVFSFileInfo::realFileUrl(const DUrl &avfsUrl) +{ + QString avfsPath = avfsUrl.path(); + + if (avfsPath.endsWith("/")) + avfsPath.chop(1); + + QString mountPath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first(); + mountPath = mountPath + "/.avfs"; + + QString virtualPath = mountPath + avfsPath; + QStringList pathItems = virtualPath.split("/"); + QString iterPath = "/"; + int archLength = 0; + foreach (QString item, pathItems) { + if (item == "") + continue; + iterPath += item; + if (FileUtils::isArchive(iterPath)) { + archLength++; + iterPath += "#/"; + } else + iterPath += "/"; + } + + if (archLength > 1) { + if (iterPath.endsWith("#/")) + iterPath.chop(2); + else + iterPath.chop(1); + } else + iterPath.chop(1); + + return DUrl::fromLocalFile(iterPath); +} + +DUrl AVFSFileInfo::realDirUrl(const DUrl &avfsUrl) +{ + QString avfsPath = avfsUrl.path(); + + if (avfsPath.endsWith("/")) + avfsPath.chop(1); + + QString mountPath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first(); + mountPath = mountPath + "/.avfs"; + + QString virtualPath = mountPath + avfsPath; + QStringList pathItems = virtualPath.split("/"); + QString iterPath = "/"; + foreach (QString item, pathItems) { + if (item == "") + continue; + iterPath += item; + if (FileUtils::isArchive(iterPath)) + iterPath += "#/"; + else + iterPath += "/"; + } + + iterPath.chop(1); + + return DUrl::fromLocalFile(iterPath); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/avfsfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/avfsfileinfo.h new file mode 100644 index 0000000..5fd25eb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/avfsfileinfo.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef AVFSFILEINFO_H +#define AVFSFILEINFO_H + +#include "interfaces/dabstractfileinfo.h" + +class AVFSFileInfoPrivate; +class AVFSFileInfo : public DAbstractFileInfo +{ +public: + explicit AVFSFileInfo(const DUrl &avfsUrl); + + bool canRename() const override; + bool isWritable() const override; + bool canShare() const override; + bool canIteratorDir() const override; + bool isDir() const override; + bool canManageAuth() const override; + + QString toLocalFile() const override; + DUrl parentUrl() const override; + QVector menuActionList(MenuType type) const override; + + static DUrl realFileUrl(const DUrl &avfsUrl); + static DUrl realDirUrl(const DUrl &avfsUrl); +protected: + explicit AVFSFileInfo(AVFSFileInfoPrivate &dd); + + Q_DECLARE_PRIVATE(AVFSFileInfo) +}; + +#endif // AVFSFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/bookmark.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/bookmark.cpp new file mode 100644 index 0000000..b56b1bb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/bookmark.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "bookmark.h" +#include "dfileservices.h" +#include "ddiskmanager.h" +#include "dblockdevice.h" +#include "dstorageinfo.h" +#include "private/dabstractfileinfo_p.h" + +#include +#include + +BookMark::BookMark(const DUrl &url) + : DAbstractFileInfo(url) +{ + DUrl target = url.bookmarkTargetUrl(); + + if (target.isValid()) { + setProxy(DFileService::instance()->createFileInfo(nullptr, target)); + } +} + +BookMark::BookMark(const QString &name, const DUrl &sourceUrl) + : BookMark(DUrl::fromBookMarkFile(sourceUrl, name)) +{ + +} + +BookMark::~BookMark() +{ + +} + +DUrl BookMark::sourceUrl() const +{ + return fileUrl().bookmarkTargetUrl(); +} + +QString BookMark::getName() const +{ + return fileUrl().bookmarkName(); +} + +QString BookMark::getMountPoint() const +{ + return udisksMountPoint; +} + +/*! + * \brief Check if bookmark target file exist + * + * This is a known interface misunderstand, it should be implemented as check + * if a bookmark is exist. This behavior should be fixed later. + * + * \return bookmark target file exist or not. + */ +bool BookMark::exists() const +{ + // Check if it is a local file first + if (!mountPoint.isEmpty() && !locateUrl.isEmpty()) { + DUrl mountPointUrl(mountPoint); + QString mountPointPath = mountPointUrl.path(); + + if (mountPointUrl.scheme() == DEVICE_SCHEME && mountPointPath.startsWith("/dev")) { + QStringList paths = DDiskManager::resolveDeviceNode(mountPointUrl.path(),{}); + if (paths.isEmpty()) { + return false; + } + udisksDBusPath = paths.first(); + QScopedPointer blDev(DDiskManager::createBlockDevice(udisksDBusPath)); + udisksMountPoint.clear(); + for (auto& mp : blDev->mountPoints()) { + QString mps(mp); + if (sourceUrl().path().startsWith(mps)) { + udisksMountPoint = mps; + break; + } + } + } + } + + if (!udisksMountPoint.isEmpty()) { + const DAbstractFileInfoPointer &sourceInfo = DFileService::instance()->createFileInfo(nullptr, sourceUrl()); + return sourceInfo->exists(); + } + + // not a local file, assume it's exist. + return true; +} + +QString BookMark::fileDisplayName() const +{ + return getName(); +} + +bool BookMark::canRedirectionFileUrl() const +{ + //书签指向目录就是挂载目录本身时locateUrl为空,属于正常逻辑,这里无需判断locateUrl + if (!mountPoint.isEmpty() /*&& !locateUrl.isEmpty()*/ && udisksMountPoint.isEmpty() && !udisksDBusPath.isEmpty()) { + QScopedPointer blDev(DDiskManager::createBlockDevice(udisksDBusPath)); + udisksMountPoint = blDev->mount({}); + } + + return fileUrl() != DUrl(BOOKMARK_ROOT); +} + +DUrl BookMark::redirectedFileUrl() const +{ + //书签指向目录就是挂载目录本身时locateUrl为空,属于正常逻辑,这里无需判断locateUrl + if (!mountPoint.isEmpty() /*&& !locateUrl.isEmpty()*/) { + DUrl mountPointUrl(mountPoint); + QString schemeStr = mountPointUrl.scheme(); + //为防止locateUrl传入QUrl被转码,locateUrl统一保存为base64,这里需要从base64转回来。 + QByteArray ba = QByteArray::fromBase64(locateUrl.toLocal8Bit()); + + if (!udisksDBusPath.isEmpty() && !udisksMountPoint.isEmpty()) { +// return DUrl::fromLocalFile(udisksMountPoint + locateUrl); + return DUrl::fromLocalFile(udisksMountPoint + QString(ba)); + } + + if (schemeStr == SMB_SCHEME || schemeStr == FTP_SCHEME || schemeStr == SFTP_SCHEME) { +// mountPointUrl.setPath(mountPointUrl.path() + locateUrl); + mountPointUrl.setPath(mountPointUrl.path() + QString(ba)); + return mountPointUrl; + } + } + + return sourceUrl(); +} + +DUrl BookMark::parentUrl() const +{ + return DUrl(BOOKMARK_ROOT); +} + +DUrl BookMark::getUrlByNewFileName(const QString &name) const +{ + DUrl new_url = fileUrl(); + new_url.setBookmarkName(name); + + return new_url; +} + +QDateTime BookMark::created() const +{ + return m_created; +} + +QDateTime BookMark::lastModified() const +{ + return m_lastModified; +} + +bool BookMark::canDrop() const +{ + Q_D(const DAbstractFileInfo); + if (d->proxy && d->proxy->isDir() && !d->proxy->isWritable()) + return false; + return DAbstractFileInfo::canDrop(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/bookmark.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/bookmark.h new file mode 100644 index 0000000..cfa89b9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/bookmark.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef BOOKMARK_H +#define BOOKMARK_H + +#include +#include "debugobejct.h" +#include +#include +#include "dfileinfo.h" + +class BookMark; +typedef QExplicitlySharedDataPointer BookMarkPointer; + +class BookMark : public DAbstractFileInfo +{ +public: + explicit BookMark(const DUrl &url); + BookMark(const QString &name, const DUrl &sourceUrl); + ~BookMark() override; + + DUrl sourceUrl() const; + QString getName() const; + QString getMountPoint() const; + + bool exists() const override; + + QString fileDisplayName() const override; + + bool canRedirectionFileUrl() const override; + DUrl redirectedFileUrl() const override; + + DUrl parentUrl() const override; + + DUrl getUrlByNewFileName(const QString &name) const override; + + QDateTime created() const override; + QDateTime lastModified() const override; + + bool canDrop() const override; + +public: + QDateTime m_created; + QDateTime m_lastModified; + QString mountPoint; + QString locateUrl; + // AbstractFileInfo interface + +private: + // always care about these two value when using it. + // related functions: exists(), canRedirectionFileUrl(), redirectionFileUrl() + mutable QString udisksDBusPath; + mutable QString udisksMountPoint; +}; + +#endif // BOOKMARK_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/computermodel.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/computermodel.cpp new file mode 100644 index 0000000..af60f60 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/computermodel.cpp @@ -0,0 +1,870 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lanxuesong + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +//fixed:CD display size error +#include "views/dfmopticalmediawidget.h" +#include "gvfs/gvfsmountmanager.h" + +#include "singleton.h" +#include "dblockdevice.h" +#include "ddiskdevice.h" +#include "controllers/dfmrootcontroller.h" +#include "controllers/dfmappentrycontroller.h" +#include "controllers/vaultcontroller.h" +#include "controllers/pathmanager.h" +#include "dfmrootfileinfo.h" +#include "dfmappentryfileinfo.h" +#include "app/define.h" +#include "dfileservices.h" +#include "dabstractfileinfo.h" +#include "deviceinfoparser.h" +#include "drootfilemanager.h" + +#include "views/computerview.h" +#include "shutil/fileutils.h" +#include "vault/vaulthelper.h" +#include "computermodel.h" + +#include + +//#define SPLIT_APP_ENTRY // enable it to split appentry and disks + +bool ComputerModel::m_isQueryRootFileFinshed = false; +ComputerModel::ComputerModel(QObject *parent) + : QAbstractItemModel(parent) + , m_diskm(new DDiskManager(this)) +{ + m_diskm->setWatchChanges(true); + par = qobject_cast(parent); + m_nitems = 0; + m_appEntryWatcher.reset(fileService->createFileWatcher(nullptr, DUrl(APPENTRY_ROOT), this)); + + // 光驱事件 + connect(this, &ComputerModel::opticalChanged, this, &ComputerModel::onOpticalChanged, Qt::QueuedConnection); + +#ifdef ENABLE_ASYNCINIT + m_initThread.first = false; + m_initThread.second = QtConcurrent::run([=](){ +#endif + addItem(makeSplitterUrl(MyDirectories)); + auto rootInit = [=](const QList &ch){ + QMutexLocker lx(&m_initItemMutex); + bool opticalchanged = false; + for (auto chi : ch) { +#ifdef ENABLE_ASYNCINIT + //线程退出 + if (m_initThread.first) + return; +#endif + if (chi->scheme() == DFMROOT_SCHEME && chi->suffix() == SUFFIX_USRDIR) { + addItem(chi->fileUrl()); + } else { + addRootItem(chi); + if (chi->fileUrl().path().contains("sr")) + opticalchanged = true; + } + } + + if (!m_isQueryRootFileFinshed) { + // 获取完根目录信息后刷新光驱信息,用于区分内外置光驱。 + if (opticalchanged) { + emit opticalChanged(); + } + m_isQueryRootFileFinshed = true; + } + }; + + connect(DRootFileManager::instance(),&DRootFileManager::queryRootFileFinsh,this,[this,rootInit](){ + QList ch = rootFileManager->getRootFile(); + if (!g_isFileDialogMode) { + DFMAppEntryController appEntryController; + ch << appEntryController.getChildren({}); + } + qDebug() << "DFileService::queryRootFileFinsh computer mode get " << ch.size(); + rootInit(ch); + + // 判断是否启用保险箱 + if ( VaultHelper::isVaultEnabled() ) { + const DUrl &vaultUrl = VaultController::makeVaultUrl(); + const DUrl &vaultSplitterUrl = makeSplitterUrl(FileVault); + const int vaultIndex = findItem(vaultSplitterUrl); + //保险箱不是最后一个则移除,再添加,保证在最后一个 + if (vaultIndex != rowCount() - 1){ + removeItem(vaultUrl); + removeItem(vaultSplitterUrl); + } + + addItem(vaultSplitterUrl); + addItem(vaultUrl); + } + }); + + connect(DRootFileManager::instance(),&DRootFileManager::serviceHideSystemPartition,this,[this,rootInit](){ + beginResetModel(); + m_items.clear(); + endResetModel(); + m_nitems = 0; + addItem(makeSplitterUrl(MyDirectories)); + QList ch = rootFileManager->getRootFile(); + if (!g_isFileDialogMode) { + DFMAppEntryController appEntryController; + ch << appEntryController.getChildren({}); + } + qDebug() << "DFileService::queryRootFileFinsh computer mode get " << ch.size(); + rootInit(ch); + + if ( VaultHelper::isVaultEnabled() ) { + // 保险柜 + addItem(makeSplitterUrl(FileVault)); + addItem(VaultController::makeVaultUrl()); + } + }); + + if (DRootFileManager::instance()->isRootFileInited()) { + + QList ch = rootFileManager->getRootFile(); + if (!g_isFileDialogMode) { + DFMAppEntryController appEntryController; + ch << appEntryController.getChildren({}); + } + qDebug() << "get root file now" << ch.size(); + rootInit(ch); + +#ifdef ENABLE_ASYNCINIT + //线程退出 + if (m_initThread.first) + return; +#endif + // 根据系统类型,判断是否启用保险柜 + if ( VaultHelper::isVaultEnabled() ) { + // 保险柜 + addItem(makeSplitterUrl(FileVault)); + addItem(VaultController::makeVaultUrl()); + } + } + //使用分区工具,不显示磁盘问题,再刷一次 + DRootFileManager::instance()->startQuryRootFile(); + + auto addComputerItem = [this](const DUrl &url) { + DAbstractFileInfoPointer fi = fileService->createFileInfo(this, url); + addRootItem(fi); + }; + m_watcher = DRootFileManager::instance()->rootFileWather(); + connect(m_watcher, &DAbstractFileWatcher::fileDeleted, this, &ComputerModel::removeItem); + connect(m_watcher, &DAbstractFileWatcher::subfileCreated, this, [this, addComputerItem](const DUrl &url) { + addComputerItem(url); + if (url.path().contains("sr")) + emit opticalChanged(); + }); + connect(m_watcher, &DAbstractFileWatcher::fileAttributeChanged, this,[this](const DUrl &url) { + int p = findItem(url); + if (p >= m_items.size() || p < 0) + return; + QModelIndex idx = index(p, 0); + static_cast(m_items[p].fi.data())->checkCache(); + emit dataChanged(idx, idx, {Qt::ItemDataRole::DisplayRole}); + }); + + if (!g_isFileDialogMode && m_appEntryWatcher) { + connect(m_appEntryWatcher.data(), &DAbstractFileWatcher::fileDeleted, this, &ComputerModel::removeItem); + connect(m_appEntryWatcher.data(), &DAbstractFileWatcher::subfileCreated, this, [this, addComputerItem](const DUrl &url){ + int appEntrySplitterIdx = findItem(makeSplitterUrl(QuickAccess)); + if (appEntrySplitterIdx < 0) { + addComputerItem(url); + return; + } + + auto newEntry = fileService->createFileInfo(nullptr, url); + auto entryInfo = dynamic_cast(newEntry.data()); + if (!entryInfo) + return; + auto cmd = entryInfo->cmd(); + + // find if there is a item which's command is equals to the new one. + for (int i = appEntrySplitterIdx; i < m_items.count(); i++) { + const auto &item = m_items.at(i); + auto info = fileService->createFileInfo(nullptr, item.url); + auto entryInfo = dynamic_cast(info.data()); + if (!entryInfo) + continue; + if (cmd == entryInfo->cmd()) + return; + } + + addComputerItem(url); + }); + connect(m_appEntryWatcher.data(), &DAbstractFileWatcher::fileAttributeChanged, this, [this](const DUrl &url){ + int pos = findItem(url); + if (pos < 0 || pos >= m_items.size()) + return; + QModelIndex idx = index(pos, 0); + emit dataChanged(idx, idx, { Qt::ItemDataRole::DisplayRole }); + }); + m_appEntryWatcher->startWatcher(); + } +#ifdef ENABLE_ASYNCINIT + }); +#endif +} + +ComputerModel::~ComputerModel() +{ +#ifdef ENABLE_ASYNCINIT + m_initThread.first = true; //强制退出 + m_initThread.second.waitForFinished(); +#endif +} + +QModelIndex ComputerModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent); + if (row >= rowCount() || row < 0) { + return QModelIndex(); + } + return createIndex(row, column, const_cast(&m_items[row])); +} + +QModelIndex ComputerModel::parent(const QModelIndex &index) const +{ + Q_UNUSED(index); + return QModelIndex(); +} + +int ComputerModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return m_items.size(); +} + +int ComputerModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return 1; +} + +QVariant ComputerModel::data(const QModelIndex &index, int role) const +{ + if (static_cast(index.internalPointer())->cat == ComputerModelItemData::Category::cat_widget) { + par->view()->setIndexWidget(index, static_cast(index.internalPointer())->widget); + } + + if (m_items.count() <= index.row()) return QVariant(); + const ComputerModelItemData *pitmdata = &m_items[index.row()]; + + if (role == Qt::DisplayRole) { + if (index.data(DataRoles::ICategoryRole) == ComputerModelItemData::Category::cat_splitter) { + return pitmdata->sptext; + } + if (pitmdata->fi) { + return pitmdata->fi->fileDisplayName(); + } + } + + if (role == Qt::DecorationRole) { + if (pitmdata->fi) { + + DFMRootFileInfo::ItemType itemType = static_cast(pitmdata->fi->fileType()); + if (itemType == DFMRootFileInfo::UDisksOptical) { + QString udisk = pitmdata->fi->extraProperties()["udisksblk"].toString(); + QStringList strList = udisk.split("/"); + QString device = strList.back(); + + bool isInternal = DeviceInfoParser::Instance().isInternalDevice(device); + if (!isInternal) { + return QIcon::fromTheme("media-external"); + } + } + + return QIcon::fromTheme(pitmdata->fi->iconName()); + } + } + + if (role == DataRoles::IconNameRole) { + return pitmdata->fi ? pitmdata->fi->iconName() : QVariant(); + } + + if (role == DataRoles::FileSystemRole) { + QString fs_type = ""; + if (pitmdata->fi) { + //! 添加文件系统格式数据 + bool bMounted = pitmdata->fi->extraProperties()["mounted"].toBool(); + if (bMounted) { + fs_type = pitmdata->fi->extraProperties()["fsType"].toString().toUpper(); + } + } + + return fs_type; + } + + if (role == DataRoles::SizeInUseRole) { + if (pitmdata->fi) { + //fixed:CD display size error + if (static_cast(pitmdata->fi->fileType()) == DFMRootFileInfo::ItemType::UDisksOptical) { + DFMRootFileInfo *pFileInfo = dynamic_cast(pitmdata->fi.data()); + QString strVolTag; + if (pFileInfo) + strVolTag = pFileInfo->getVolTag(); + //fix: 探测光盘推进,弹出和挂载状态机标识 + bool bVolFlag = DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].bVolFlag; + bool bMntFlag = DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].bMntFlag; + if (!bVolFlag && !bMntFlag) { //CD/DVD + return 0; + } else { + return DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].nUsage; + } + } else { + if (pitmdata->fi->fileUrl().scheme() == DFMVAULT_SCHEME) { + return QString::number(pitmdata->fi->size()); + } + return pitmdata->fi->extraProperties()["fsUsed"]; + } + } + } + + if (role == DataRoles::SizeTotalRole) { + if (pitmdata->fi) { + //fixed:CD display size error + if (static_cast(pitmdata->fi->fileType()) == DFMRootFileInfo::ItemType::UDisksOptical) { + DFMRootFileInfo *pFileInfo = dynamic_cast(pitmdata->fi.data()); + QString strVolTag; + if (pFileInfo) + strVolTag = pFileInfo->getVolTag(); + //fix: 探测光盘推进,弹出和挂载状态机标识 + bool bVolFlag = DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].bVolFlag; + bool bMntFlag = DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].bMntFlag; + if (!bVolFlag && !bMntFlag) { //CD/DVD + return 0; + } else { + return DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].nTotal; + } + } else { + return pitmdata->fi->extraProperties()["fsSize"]; + } + } + } + + if (role == DataRoles::ICategoryRole) { + return m_items.at(index.row()).cat; + } + + if (role == DataRoles::OpenUrlRole) { + if (pitmdata->fi) { + // 用保险柜根目录 + if (pitmdata->fi->scheme() == DFMVAULT_SCHEME) { + return QVariant::fromValue(pitmdata->fi->fileUrl()); + } + return QVariant::fromValue(pitmdata->fi->redirectedFileUrl()); + } + } + + if (role == DataRoles::MountOpenUrlRole) { + if (pitmdata->fi) { + QSharedPointer blkdev(DDiskManager::createBlockDevice(pitmdata->fi->extraProperties()["udisksblk"].toString())); + if (pitmdata->fi->suffix() == SUFFIX_UDISKS && blkdev && blkdev->mountPoints().size() == 0) { + blkdev->mount({}); + } + return QVariant::fromValue(pitmdata->fi->redirectedFileUrl()); + } + } + + if (role == DataRoles::ActionVectorRole) { + if (pitmdata->fi) { + return QVariant::fromValue(pitmdata->fi->menuActionList()); + } + } + + if (role == DataRoles::DFMRootUrlRole) { + if (pitmdata->fi) { + return QVariant::fromValue(pitmdata->fi->fileUrl()); + } + } + + if (role == DataRoles::VolumeTagRole) { + DFMRootFileInfo *file = dynamic_cast(pitmdata->fi.data()); + if (file) + return file->getVolTag(); + } + + if (role == DataRoles::ProgressRole) { + + bool bProgressVisible = true; + if (pitmdata->fi) { + QString scheme = pitmdata->fi->fileUrl().scheme(); + if (scheme == DFMVAULT_SCHEME) { + // vault not show progress. + bProgressVisible = false; + } else if (scheme == APPENTRY_SCHEME) { + bProgressVisible = false; + } else { + // optical and removable device not show progress when unmounted. + DFMRootFileInfo::ItemType itemType = static_cast(pitmdata->fi->fileType()); + if (itemType == DFMRootFileInfo::ItemType::UDisksOptical + || itemType == DFMRootFileInfo::ItemType::UDisksRemovable) { + + bProgressVisible = pitmdata->fi->extraProperties()["mounted"].toBool(); + } + } + } + return QVariant::fromValue(bProgressVisible); + } + + if (role == DataRoles::SizeRole) { + + bool bSizeVisible = true; + if (pitmdata->fi) { + // optical and removable device not show size when unmounted. + DFMRootFileInfo::ItemType itemType = static_cast(pitmdata->fi->fileType()); + if (itemType == DFMRootFileInfo::ItemType::UDisksOptical + || itemType == DFMRootFileInfo::ItemType::UDisksRemovable) { + + bSizeVisible = pitmdata->fi->extraProperties()["mounted"].toBool(); + + } else if (pitmdata->url.isVaultFile()) { + // not show vault size when locked or not created. + VaultController::VaultState state = VaultController::ins()->state(); + if (state == VaultController::Encrypted + || state == VaultController::NotExisted) { + bSizeVisible = false; + } + } else if (itemType == DFMRootFileInfo::AppEntry) { + bSizeVisible = false; + } + } + + return QVariant::fromValue(bSizeVisible); + } + + if (role == DataRoles::SchemeRole) { + if (pitmdata->fi) { + return QVariant::fromValue(pitmdata->fi->fileUrl().scheme()); + } + } + if (role == DataRoles::DiscUUIDRole) { + if (!pitmdata->fi) + return QVariant(); + QSharedPointer blkdev(DDiskManager::createBlockDevice(pitmdata->fi->extraProperties()["udisksblk"].toString())); + return blkdev->idUUID(); + } + + if (role == DataRoles::DiscOpticalRole) { + if (!pitmdata->fi) + return QVariant(); + QSharedPointer blkdev(DDiskManager::createBlockDevice(pitmdata->fi->extraProperties()["udisksblk"].toString())); + QScopedPointer drv(DDiskManager::createDiskDevice(blkdev->drive())); + return drv->opticalBlank(); + } + + if (role == DataRoles::EditorLengthRole) { + if (pitmdata->fi) { + // 普通文件系统限制最长输入字符为 40, vfat exfat 由于文件系统的原因,只能输入 11 个字节 + // todo: ext filesystems only allow 16 bytes/charactors for label length, and vfat is 11, ntfs is 32, + // make a static map to storage it, do it later... + const QString &fs = pitmdata->fi->extraProperties()["fsType"].toString().toLower(); + return fs.endsWith("fat") ? 11 : 40; + } + } + + if (role == DataRoles::AppEntryDescription) { +#if 0 // PO says, show fixed words here + if (pitmdata->fi) { + auto appEntryInfo = dynamic_cast(pitmdata->fi.data()); + if (appEntryInfo) + return appEntryInfo->appComment(); + } +#endif + return tr("Double click to open it"); + } + + if (role == DataRoles::IsEditingRole) { + return pitmdata->isEditing; + } + return QVariant(); +} + +bool ComputerModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (m_items.count() <= index.row() || index.row() < 0) + return false; + ComputerModelItemData *pitmdata = &m_items[index.row()]; + + if (role == Qt::EditRole) { + if (!pitmdata || !pitmdata->fi) + return false; + if (!pitmdata->fi->canRename()) { + return false; + } + + DUrl newUrl; + newUrl.setPath(value.toString()); // 直接构造 URL 会忽略掉一些特殊符号,因此使用 setPath + fileService->renameFile(this, pitmdata->fi->fileUrl(), newUrl); + emit dataChanged(index, index, {Qt::DisplayRole}); + return true; + } + if (role == DataRoles::IsEditingRole) { + if (!pitmdata) + return false; + pitmdata->isEditing = value.toBool(); + return true; + } + return false; +} + +Qt::ItemFlags ComputerModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags ret = Qt::ItemFlag::ItemNeverHasChildren; + if (index.data(DataRoles::ICategoryRole) != ComputerModelItemData::Category::cat_splitter) { + ret |= Qt::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable; + } + + if (m_items.count() < index.row()) return ret; + const ComputerModelItemData *pitmdata = &m_items[index.row()]; + if (pitmdata->fi && pitmdata->fi->canRename()) { + ret |= Qt::ItemFlag::ItemIsEditable; + } + return ret; +} + +QModelIndex ComputerModel::findIndex(const DUrl &url) const +{ + for (int row = 0; row < m_items.size(); ++row) { + if (m_items[row].url == url) { + return index(row, 0); + } + } + return QModelIndex(); +} + +int ComputerModel::itemCount() const +{ + return m_nitems; +} + +void ComputerModel::addItem(const DUrl &url, QWidget* w) +{ + if (findItem(url) != -1) { + return; + } + + beginInsertRows(QModelIndex(), rowCount(), rowCount() + 1); + ComputerModelItemData id; + initItemData(id, url, w); + m_items.append(id); + endInsertRows(); + if (url.scheme() != SPLITTER_SCHEME && url.scheme() != WIDGET_SCHEME) { + Q_EMIT itemCountChanged(++m_nitems); + } +} + +void ComputerModel::insertAfter(const DUrl &url, const DUrl &ref, QWidget *w) +{ + if (findItem(url) != -1) { + return; + } + + int p = findItem(ref); + if (p == -1) { + return; + } + + beginInsertRows(QModelIndex(), p + 1, p + 2); + ComputerModelItemData id; + initItemData(id, url, w); + m_items.insert(p + 1, id); + endInsertRows(); + if (url.scheme() != SPLITTER_SCHEME && url.scheme() != WIDGET_SCHEME) { + Q_EMIT itemCountChanged(++m_nitems); + } +} + +void ComputerModel::insertBefore(const DUrl &url, const DUrl &ref, QWidget *w) +{ + if (findItem(url) != -1) { + return; + } + + int p = findItem(ref); + if (p == -1) { + return; + } + + beginInsertRows(QModelIndex(), p, p + 1); + ComputerModelItemData id; + initItemData(id, url, w); + m_items.insert(p, id); + endInsertRows(); + if (url.scheme() != SPLITTER_SCHEME && url.scheme() != WIDGET_SCHEME) { + Q_EMIT itemCountChanged(++m_nitems); + } +} + +void ComputerModel::removeItem(const DUrl &url) +{ + int p = findItem(url); + if (p == -1) { + return; + } + beginRemoveRows(QModelIndex(), p, p); + m_items.removeAt(p); + endRemoveRows(); + +#ifdef SPLIT_APP_ENTRY + auto splitterUrl = url.scheme() == APPENTRY_SCHEME + ? makeSplitterUrl(QuickAccess) + : makeSplitterUrl(Disks); +#else + auto splitterUrl = makeSplitterUrl(Disks); +#endif + //fix bug PPMS20200213,在移除最后一个磁盘时,移除磁盘这个项 + int ndiskindex = findItem(splitterUrl); + int nextspliter = findNextSplitter(ndiskindex); + //磁盘的分割线的ndiskindex和从磁盘到下一个分割线nextspliter,如果没有下一个分割线并且磁盘分割线ndiskindex是最后一项 + //或者磁盘分割线ndiskindex到从磁盘到下一个分割线nextspliter之间的item为0就移除磁盘的分割线 + if ((nextspliter == -1 && ndiskindex != -1 && m_items.size() - 1 == ndiskindex) || + (ndiskindex != -1 && nextspliter != -1 && (nextspliter - ndiskindex) == 1)) { + beginRemoveRows(QModelIndex(), ndiskindex, ndiskindex); + m_items.removeAt(ndiskindex); + endRemoveRows(); + } + + if (url.scheme() != SPLITTER_SCHEME && url.scheme() != WIDGET_SCHEME) { + Q_EMIT itemCountChanged(--m_nitems); + } +} + +void ComputerModel::onGetRootFile(const DAbstractFileInfoPointer &chi) +{ + if (!chi) + return; + bool splt = false; + if(!chi->exists()) + { + return; + } + + const auto &diskSplitterUrl = makeSplitterUrl(Disks); + if (chi->suffix() != SUFFIX_USRDIR && !splt) { + addItem(diskSplitterUrl); + splt = true; + } + if (splt) { + auto r = std::upper_bound(m_items.begin() + findItem(diskSplitterUrl) + 1, m_items.end(), chi, + [](const DAbstractFileInfoPointer &a, const ComputerModelItemData &b) { + return DFMRootFileInfo::typeCompare(a, b.fi); + }); + if (r == m_items.end()) { + addItem(chi->fileUrl()); + } else { + insertBefore(chi->fileUrl(), r->url); + } + } else { + addItem(chi->fileUrl()); + } +} + +void ComputerModel::onOpticalChanged() +{ + std::thread thread([](){ + DeviceInfoParser::Instance().refreshDabase(); + }); + thread.detach(); +} + +void ComputerModel::getRootFile() +{ + QList ch = rootFileManager->getRootFile(); + qDebug() << "获取 ComputerModel getRootFile start" << ch.size() << QThread::currentThread() << qApp->thread(); + if (ch.isEmpty()) + return; + + bool splt = false; + m_nitems = 0; + const auto &diskSplitterUrl = makeSplitterUrl(Disks); + for (auto chi : ch) { + if (chi->suffix() != SUFFIX_USRDIR && !splt) { + addItem(diskSplitterUrl); + splt = true; + } + if (splt) { + auto r = std::upper_bound(m_items.begin() + findItem(diskSplitterUrl) + 1, m_items.end(), chi, + [](const DAbstractFileInfoPointer &a, const ComputerModelItemData &b) { + return DFMRootFileInfo::typeCompare(a, b.fi); + }); + if (r == m_items.end()) { + addItem(chi->fileUrl()); + } else { + insertBefore(chi->fileUrl(), r->url); + } + } else { + addItem(chi->fileUrl()); + } + } +} + +void ComputerModel::addRootItem(const DAbstractFileInfoPointer &info) +{ + if (!info || !info->exists()) + return; + if (!Singleton::instance()->isVisiblePartitionPath(info)) + return; + +#ifdef SPLIT_APP_ENTRY + auto splitterUrl = info->scheme() == DFMROOT_SCHEME + ? makeSplitterUrl(Disks) + : makeSplitterUrl(QuickAccess); +#else + auto splitterUrl = makeSplitterUrl(Disks); +#endif + int splitterIdx = findItem(splitterUrl); + int vaultSplitterIdx = findItem(makeSplitterUrl(FileVault)); + if (vaultSplitterIdx < 0) + vaultSplitterIdx = m_items.count(); + + // [firstDisk, vaultSplitter) + auto start = m_items.begin() + splitterIdx + 1; + auto end = m_items.begin() + vaultSplitterIdx; + if (splitterIdx > 0) { + auto r = std::upper_bound(start, end, info, + [](const DAbstractFileInfoPointer &a, const ComputerModelItemData &b) { + return DFMRootFileInfo::typeCompare(a, b.fi); + }); + if (r == m_items.end()) { + addItem(info->fileUrl()); + } else { + insertBefore(info->fileUrl(), r->url); + } + } else { + // if newInfo is disk, insert from top (my directories) + if (info->scheme() == DFMROOT_SCHEME) { + if (m_items.count() < 7) { // `My Directories` and 6 user directories + addItem(splitterUrl); + addItem(info->fileUrl()); + } else { // in normal case, index 6 refers to the Downloads directory + insertAfter(info->fileUrl(), m_items[6].url); + insertAfter(splitterUrl, m_items[6].url); + } + } else { // if newInfo is appentry, insert from bottom (vault) + auto vaultIdx = findItem(makeSplitterUrl(FileVault)); + if (vaultIdx > 0) { + insertBefore(splitterUrl, makeSplitterUrl(FileVault)); + insertBefore(info->fileUrl(), makeSplitterUrl(FileVault)); + } else { + addItem(splitterUrl); + addItem(info->fileUrl()); + } + } + } +} + + +void ComputerModel::initItemData(ComputerModelItemData &data, const DUrl &url, QWidget *w) +{ + data.url = url; + if (url.scheme() == SPLITTER_SCHEME) { + data.cat = ComputerModelItemData::Category::cat_splitter; + data.sptext = url.fragment(); + } else if (url.scheme() == WIDGET_SCHEME) { + data.cat = ComputerModelItemData::Category::cat_widget; + data.widget = w; + } else { + //这里不用去创建fileinfo,已经缓存了rootfileinfo //get root file info cache + if (url.toString().endsWith(SUFFIX_GVFSMP)) + { + const DAbstractFileInfoPointer &info = DRootFileManager::getFileInfo(url); + if (info) { + info->refresh(); + data.fi = info; + } + else { + data.fi = fileService->createFileInfo(this, url); + } + } + else { + data.fi = fileService->createFileInfo(this, url); + } + if (data.fi->suffix() == SUFFIX_USRDIR) { + data.cat = ComputerModelItemData::Category::cat_user_directory; + } else { + data.cat = ComputerModelItemData::Category::cat_internal_storage; + } + } +} + +int ComputerModel::findItem(const DUrl &url) +{ + int p; + for (p = 0; p < m_items.size(); ++p) { + if (m_items[p].url == url) { + break; + } + } + if (p >= m_items.size()) { + return -1; + } + return p; +} + +DUrl ComputerModel::makeSplitterUrl(QString text) +{ + DUrl ret; + ret.setScheme(SPLITTER_SCHEME); + ret.setFragment(text); + return ret; +} + +DUrl ComputerModel::makeSplitterUrl(SplitterType type) +{ + QString text; + switch (type) { + case MyDirectories: + text = tr("My Directories"); + break; + case Disks: + text = tr("Disks"); + break; + case FileVault: + text = tr("File Vault"); + break; + case QuickAccess: + text = tr("Quick Access"); + break; + } + return makeSplitterUrl(text); +} + +int ComputerModel::findNextSplitter(const int &index) +{ + int p = index + 1; + if (m_items.size() <= index || -1 == index) { + return -1; + } + for (; p < m_items.size(); ++p) { + if (m_items[p].url.scheme() == SPLITTER_SCHEME) { + break; + } + } + if (p >= m_items.size()) { + return -1; + } + return p; +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/computermodel.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/computermodel.h new file mode 100644 index 0000000..9f7ffc3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/computermodel.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lanxuesong + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef COMPUTERMODEL_H +#define COMPUTERMODEL_H + +#include "ddiskmanager.h" +#include "deviceinfo/udisklistener.h" + +#include +#include + +#include "durl.h" +#include "interfaces/dabstractfileinfo.h" + +//url schemes internal to ComputerModel +#define SPLITTER_SCHEME "splitter" +#define WIDGET_SCHEME "widget" + +class ComputerView; + +struct ComputerModelItemData +{ + enum Category + { + cat_user_directory, + cat_internal_storage, + cat_external_storage, + cat_splitter, + cat_widget + }; + DAbstractFileInfoPointer fi; + DUrl url; + QString sptext; + QWidget* widget = nullptr; + Category cat; + bool isEditing = false; +}; + +class ComputerModel : public QAbstractItemModel +{ + Q_OBJECT +public: + enum DataRoles + { + SizeTotalRole = Qt::UserRole + 1, // uint64_t + SizeInUseRole = Qt::UserRole + 2, // uint64_t + FileSystemRole = Qt::UserRole + 3, // QString + UsgWidgetRole = Qt::UserRole + 4, // No longer used + ICategoryRole = Qt::UserRole + 5, // ComputerModelItemData::Category + OpenUrlRole = Qt::UserRole + 6, // DUrl + MountOpenUrlRole = Qt::UserRole + 7, // DUrl + ActionVectorRole = Qt::UserRole + 8, // QVector + DFMRootUrlRole = Qt::UserRole + 9, // DUrl + VolumeTagRole = Qt::UserRole + 10, // 卷标 sr0 + IconNameRole = Qt::UserRole + 11, // 图标名称 + SchemeRole = Qt::UserRole + 12, // QString + ProgressRole = Qt::UserRole + 13, // Bool(Progress visible) + SizeRole = Qt::UserRole + 14, // Bool(Size visible) + DiscUUIDRole = Qt::UserRole + 15, // 设备UUID + DiscOpticalRole = Qt::UserRole + 16, // 光盘是否是空盘 + EditorLengthRole = Qt::UserRole + 17,// 重命名LineEditor的最大长度 + AppEntryDescription, // the Comment field of an app entry + IsEditingRole, // if this device is editing name + }; + Q_ENUM(DataRoles) + + explicit ComputerModel(QObject* parent = nullptr); + ~ComputerModel() override; + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + + QModelIndex findIndex(const DUrl &url) const; + int itemCount() const; + void getRootFile(); + +protected: + void addRootItem(const DAbstractFileInfoPointer &info); + +public Q_SLOTS: + void addItem(const DUrl &url, QWidget *w = nullptr); + void insertAfter(const DUrl &url, const DUrl &ref, QWidget *w = nullptr); + void insertBefore(const DUrl &url, const DUrl &ref, QWidget *w = nullptr); + void removeItem(const DUrl &url); + void onGetRootFile(const DAbstractFileInfoPointer &chi); + void onOpticalChanged(); + +Q_SIGNALS: + void itemCountChanged(int nitems); + void opticalChanged(); + +private: + ComputerView* par; + QScopedPointer m_diskm; + QScopedPointer m_appEntryWatcher; + QList m_items; + DAbstractFileWatcher* m_watcher; + int m_nitems; + QMutex m_initItemMutex; + static bool m_isQueryRootFileFinshed; // 查询跟目录是否完成 + +#ifdef ENABLE_ASYNCINIT + QPair> m_initThread; //初始化线程,first为是否强制结束线程 +#endif + void initItemData(ComputerModelItemData &data, const DUrl &url, QWidget *w); + int findItem(const DUrl &url); + + enum SplitterType { + MyDirectories, + Disks, + FileVault, + QuickAccess, + }; + + static DUrl makeSplitterUrl(QString text); + static DUrl makeSplitterUrl(SplitterType type); + int findNextSplitter(const int &index); +}; + + +#endif // COMPUTERMODEL_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/desktopfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/desktopfileinfo.cpp new file mode 100644 index 0000000..1877b58 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/desktopfileinfo.cpp @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "desktopfileinfo.h" +#include "private/dfileinfo_p.h" +#include "app/define.h" +#include "controllers/trashmanager.h" + +#include "shutil/properties.h" +#include "shutil/fileutils.h" +#include "interfaces/dfmstandardpaths.h" +#include "interfaces/dfileservices.h" +#include "interfaces/dfmstandardpaths.h" + +#include "singleton.h" + +#include +#include + +class DesktopFileInfoPrivate : public DFileInfoPrivate +{ +public: + DesktopFileInfoPrivate(const DUrl &url, DesktopFileInfo *qq) + : DFileInfoPrivate(url, qq) + { + updateInfo(url); + } + + QString name; + QString genericName; + QString exec; + QString iconName; + QString type; + QStringList categories; + QStringList mimeType; + QString deepinID; + QString deepinVendor; + + void updateInfo(const DUrl &fileUrl); +}; + +DesktopFileInfo::DesktopFileInfo(const DUrl &fileUrl) + : DFileInfo(*new DesktopFileInfoPrivate(fileUrl, this)) +{ + +} + +DesktopFileInfo::DesktopFileInfo(const QFileInfo &fileInfo) + : DesktopFileInfo(DUrl::fromLocalFile(fileInfo.absoluteFilePath())) +{ + d_func()->fileInfo = fileInfo; +} + +DesktopFileInfo::~DesktopFileInfo() +{ + +} + +QString DesktopFileInfo::getName() const +{ + Q_D(const DesktopFileInfo); + + if (d->deepinVendor == QStringLiteral("deepin") && !(d->genericName.isEmpty())) { + return d->genericName; + } + + return d->name; +} + +QString DesktopFileInfo::getExec() const +{ + Q_D(const DesktopFileInfo); + + return d->exec; +} + +QString DesktopFileInfo::getIconName() const +{ + Q_D(const DesktopFileInfo); + + //special handling for trash desktop file which has tash datas + if (d->iconName == "user-trash") { + if (!TrashManager::isEmpty()) + return "user-trash-full"; + } + + return d->iconName; +} + +QString DesktopFileInfo::getType() const +{ + Q_D(const DesktopFileInfo); + + return d->type; +} + +QStringList DesktopFileInfo::getCategories() const +{ + Q_D(const DesktopFileInfo); + + return d->categories; +} + +QIcon DesktopFileInfo::fileIcon() const +{ + Q_D(const DesktopFileInfo); + + if (Q_LIKELY(!d->icon.isNull())) { + if (Q_LIKELY(!d->icon.availableSizes().isEmpty())) + return d->icon; + + d->icon = QIcon(); + } + + const QString &iconName = this->iconName(); + + if (iconName.startsWith("data:image/")) { + int first_semicolon = iconName.indexOf(';', 11); + + if (first_semicolon > 11) { + // iconPath is a string representing an inline image. +// const QString &format = iconName.mid(11, first_semicolon - 11); + + int base64str_pos = iconName.indexOf("base64,", first_semicolon); + + if (base64str_pos > 0) { + QPixmap pixmap; + + bool ok = pixmap.loadFromData(QByteArray::fromBase64(iconName.mid(base64str_pos + 7).toLatin1())/*, format.toLatin1().constData()*/); + + if (ok) { + d->icon = QIcon(pixmap); + } else { + d->icon = QIcon::fromTheme("application-default-icon"); + } + } + } + } else { + const QString ¤tDir = QDir::currentPath(); + + QDir::setCurrent(absolutePath()); + + QFileInfo fileInfo(iconName.startsWith("~") ? (QDir::homePath() + iconName.mid(1)) : iconName); + + if (!fileInfo.exists()) + fileInfo.setFile(QUrl::fromUserInput(iconName).toLocalFile()); + + if (fileInfo.exists()) { + d->icon = QIcon(fileInfo.absoluteFilePath()); + } + + QDir::setCurrent(currentDir); + + if (!d->icon.isNull() && QPixmap(fileInfo.absoluteFilePath()).isNull()) + d->icon = QIcon(); + } + + if (d->icon.isNull()) + return DFileInfo::fileIcon(); + + return d->icon; +} + +void DesktopFileInfo::refresh(const bool isForce) +{ + Q_D(DesktopFileInfo); + + DFileInfo::refresh(isForce); + d->updateInfo(fileUrl()); +} + +QString DesktopFileInfo::iconName() const +{ + return getIconName(); +} + +QString DesktopFileInfo::genericIconName() const +{ + return QStringLiteral("application-default-icon"); +} + +QString DesktopFileInfo::fileDisplayName() const +{ + if (getName().isEmpty()) { + // if desktop file has no name section + return DFileInfo::fileDisplayName(); + } + + return getName(); +} + +QString DesktopFileInfo::fileNameOfRename() const +{ + return fileDisplayName(); +} + +QString DesktopFileInfo::baseNameOfRename() const +{ + return fileDisplayName(); +} + +QString DesktopFileInfo::suffixOfRename() const +{ + return QString(); +} + +QMap DesktopFileInfo::getDesktopFileInfo(const DUrl &fileUrl) +{ + QMap map; + QSettings settings(fileUrl.path(), QSettings::IniFormat); + + settings.setIniCodec("utf-8"); + settings.beginGroup("Desktop Entry"); + // Loads .desktop file (read from 'Desktop Entry' group) + Properties desktop(fileUrl.path(), "Desktop Entry"); + + //由于获取的系统语言简写与.desktop的语言简写存在不对应关系,经决定先采用获取的系统值匹配 + //若没匹配到则采用系统值"_"左侧的字符串进行匹配,均为匹配到,才走原未匹配流程 + auto getValueFromSys = [&desktop,&settings](const QString &type, const QString &sysName)->QString { + const QString key = QString("%0[%1]").arg(type).arg(sysName); + return desktop.value(key, settings.value(key)).toString(); + }; + + auto getNameByType = [&desktop,&settings,&getValueFromSys](const QString &type)->QString{ + QString tempSysName = QLocale::system().name(); + QString targetName = getValueFromSys(type, tempSysName); + if (targetName.isEmpty()) { + auto strSize = tempSysName.trimmed().split("_"); + if (!strSize.isEmpty()){ + tempSysName = strSize.first(); + targetName = getValueFromSys(type,tempSysName); + } + + if (targetName.isEmpty()) + targetName = desktop.value(type, settings.value(type)).toString(); + } + + return targetName; + }; + + map["Name"] = getNameByType("Name"); + map["GenericName"] = getNameByType("GenericName"); + + map["Exec"] = desktop.value("Exec", settings.value("Exec")); + map["Icon"] = desktop.value("Icon", settings.value("Icon")); + map["Type"] = desktop.value("Type", settings.value("Type", "Application")); + map["Categories"] = desktop.value("Categories", settings.value("Categories")).toString().remove(" ").split(";"); + map["MimeType"] = desktop.value("MimeType", settings.value("MimeType")).toString().remove(" ").split(";"); + map["DeepinID"] = desktop.value("X-Deepin-AppID", settings.value("X-Deepin-AppID")).toString(); + map["DeepinVendor"] = desktop.value("X-Deepin-Vendor", settings.value("X-Deepin-Vendor")).toString(); + + return map; +} + +QVector DesktopFileInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + Q_D(const DesktopFileInfo); + + + if (d->deepinID == "dde-trash" + || d->deepinID == "dde-home" + || d->deepinID == "dde-computer" + || (d->deepinID == "dde-file-manager" && d->exec.contains("-O"))) { + QVector actions; + actions << MenuAction::Open + << MenuAction::Separator; + + if (d->deepinID == "dde-trash") { + actions << MenuAction::ClearTrash + << MenuAction::Separator; + } + + if (type == SingleFile) + actions << MenuAction::CreateSymlink; + + actions << MenuAction::Property; + + return actions; + } else { + return DFileInfo::menuActionList(type); + } +} + +QSet DesktopFileInfo::disableMenuActionList() const +{ + Q_D(const DesktopFileInfo); + if (d->deepinID == "dde-trash") { + QSet actions; + if (FileUtils::filesCount(DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath)) <= 0) + actions << MenuAction::ClearTrash; + return actions; + } + return DFileInfo::disableMenuActionList(); +} + +QList DesktopFileInfo::additionalIcon() const +{ + return QList(); +} + +Qt::DropActions DesktopFileInfo::supportedDragActions() const +{ + Q_D(const DesktopFileInfo); + if (d->deepinID == "dde-trash" || d->deepinID == "dde-computer") { + return Qt::IgnoreAction; + } + + return DFileInfo::supportedDragActions(); +} + +bool DesktopFileInfo::canDrop() const +{ + //ignore drop event for computer desktop file + Q_D(const DesktopFileInfo); + if (d->deepinID == "dde-computer") + return false; + + return DFileInfo::canDrop(); +} + +bool DesktopFileInfo::canTag() const +{ + Q_D(const DesktopFileInfo); + if (d->deepinID == "dde-trash" || d->deepinID == "dde-computer") + return false; + + //桌面主目录不支持添加tag功能 + if (d->deepinID == "dde-file-manager" && d->exec.contains(" -O ")) + return false; + + return DFileInfo::canTag(); +} + +bool DesktopFileInfo::canMoveOrCopy() const +{ + //部分桌面文件不允许复制或剪切 + Q_D(const DesktopFileInfo); + if (d->deepinID == "dde-trash" || d->deepinID == "dde-computer") + return false; + + //exec执行字符串中“-O”参数表示打开主目录 + if (d->deepinID == "dde-file-manager" && d->exec.contains(" -O ")) + return false; + + return true; +} + +DUrl DesktopFileInfo::trashDesktopFileUrl() +{ + //TODO 存在终端修改文件名之后url变更的情况,暂不考虑 + return DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::DesktopPath) + "/dde-trash.desktop"); +} + +DUrl DesktopFileInfo::computerDesktopFileUrl() +{ + //TODO 存在终端修改文件名之后url变更的情况,暂不考虑 + return DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::DesktopPath) + "/dde-computer.desktop"); +} + +DUrl DesktopFileInfo::homeDesktopFileUrl() +{ + //TODO 存在终端修改文件名之后url变更的情况,暂不考虑 + return DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::DesktopPath) + "/dde-home.desktop"); +} + +void DesktopFileInfoPrivate::updateInfo(const DUrl &fileUrl) +{ + const QMap &map = DesktopFileInfo::getDesktopFileInfo(fileUrl); + + name = map.value("Name").toString(); + genericName = map.value("GenericName").toString(); + exec = map.value("Exec").toString(); + iconName = map.value("Icon").toString(); + type = map.value("Type").toString(); + categories = map.value("Categories").toStringList(); + mimeType = map.value("MimeType").toStringList(); + deepinID = map.value("DeepinID").toString(); + deepinVendor = map.value("DeepinVendor").toString(); + // Fix categories + if (categories.first().compare("") == 0) { + categories.removeFirst(); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/desktopfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/desktopfileinfo.h new file mode 100644 index 0000000..434837b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/desktopfileinfo.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DESKTOPFILEINFO_H +#define DESKTOPFILEINFO_H + +#include "dfileinfo.h" + +#include + +#define DESKTOP_SURRIX "desktop" + +class DesktopFileInfoPrivate; +class DesktopFileInfo : public DFileInfo +{ +public: + explicit DesktopFileInfo(const DUrl &fileUrl); + explicit DesktopFileInfo(const QFileInfo &fileInfo); + + ~DesktopFileInfo() override; + + QString getName() const; + QString getExec() const; + QString getIconName() const; + QString getType() const; + QStringList getCategories() const; + + QIcon fileIcon() const override; + QString fileDisplayName() const override; + QString fileNameOfRename() const override; + QString baseNameOfRename() const override; + QString suffixOfRename() const override; + + void refresh(const bool isForce = false) override; + + QString iconName() const override; + QString genericIconName() const override; + + static QMap getDesktopFileInfo(const DUrl &fileUrl); + + QVector menuActionList(MenuType type = SingleFile) const override; + QSet disableMenuActionList() const override; + QList additionalIcon() const; + Qt::DropActions supportedDragActions() const override; + + bool canDrop() const override; + bool canTag() const override; + bool canMoveOrCopy() const override; + + static DUrl trashDesktopFileUrl(); + static DUrl computerDesktopFileUrl(); + static DUrl homeDesktopFileUrl(); + +private: + Q_DECLARE_PRIVATE(DesktopFileInfo) +}; + +#endif // DESKTOPFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/deviceinfoparser.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/deviceinfoparser.cpp new file mode 100644 index 0000000..0c6aae4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/deviceinfoparser.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "deviceinfoparser.h" +#include +#include "Logger.h" + + +const QString Deviceype_Computer = "Computer"; +const QString Devicetype_Name = "Name"; +const QString Devicetype_lshw_Class_Prefix = "*-"; +const char Devicetype_Separator = ':'; +const QString Devicetype_Stitching_Symbol = "_"; + + +DCORE_USE_NAMESPACE +DeviceInfoParser::DeviceInfoParser(): QObject() +{ + +} + +DeviceInfoParser::~DeviceInfoParser() +{ + +} + +void DeviceInfoParser::refreshDabase() +{ + loadLshwDatabase(); + + emit loadFinished(); +} + +const QString &DeviceInfoParser::queryData(const QString &toolname, const QString &firstKey, const QString &secondKey) +{ + static QString result(""); + if (false == m_toolDatabase.contains(toolname)) { + return result; + } + + if (false == m_toolDatabase[toolname].contains(firstKey)) { + return result; + } + + if (false == m_toolDatabase[toolname][firstKey].contains(secondKey)) { + return result; + } + + return m_toolDatabase[toolname][firstKey][secondKey]; +} + +QStringList DeviceInfoParser::getLshwCDRomList() +{ + QStringList cdromList; + + if (false == m_toolDatabaseSecondOrder.contains("lshw")) { + return cdromList; + } + + foreach (const QString &fk, m_toolDatabaseSecondOrder["lshw"]) { + if (fk.contains("cdrom")) { + cdromList.push_back(fk); + continue; + } + } + + return cdromList; +} + +bool DeviceInfoParser::isInternalDevice(const QString &device) +{ + QStringList cdromList = getLshwCDRomList(); + + bool isInternalDevice = true; + foreach (QString cdrom, cdromList) { + const QString logicalName = queryData("lshw", cdrom, "logical name"); + if (logicalName.contains(device)) { + if (!cdrom.contains("sata")) { + isInternalDevice = false; + } + } + } + return isInternalDevice; +} + +bool DeviceInfoParser::loadLshwDatabase() +{ + if (false == executeProcess("lshw")) { + return false; + } + + QString lshwOut = m_standOutput; + + // lshw + DatabaseMap lshwDatabase_; + QStringList secondOrder; + + int startIndex = 0; + int lineNumber = -1; + QStringList deviceType; + QMap DeviceInfoMap; + + for (int i = 0; i < lshwOut.size(); ++i) { + if (lshwOut[i] != '\n' && i != lshwOut.size() - 1) { + continue; + } + + ++lineNumber; + + QString line = lshwOut.mid(startIndex, i - startIndex); + startIndex = i + 1; + + if (line.trimmed().isEmpty()) { + dWarning("DeviceInfoParser::loadLshwDatabase lshw output contains empty line!"); + continue; + } + + if (lineNumber == 0) { + DeviceInfoMap[Devicetype_Name] = line.trimmed(); + deviceType.push_back(Devicetype_lshw_Class_Prefix + Deviceype_Computer); + continue; + } + + if (line.contains(Devicetype_lshw_Class_Prefix)) { + QString deviceTypeName; + foreach (auto dt, deviceType) { + if (deviceTypeName.isEmpty() == false) { + deviceTypeName += Devicetype_Stitching_Symbol; + } + deviceTypeName += dt.trimmed().remove(Devicetype_lshw_Class_Prefix); + continue; + } + + lshwDatabase_[deviceTypeName] = DeviceInfoMap; + secondOrder.push_back(deviceTypeName); + + DeviceInfoMap.clear(); + + QString typeStr = line; + DeviceInfoMap["Type"] = typeStr.remove(Devicetype_lshw_Class_Prefix).trimmed(); + + while (deviceType.size() > 0) { + if (deviceType.last().indexOf(Devicetype_lshw_Class_Prefix) >= line.indexOf(Devicetype_lshw_Class_Prefix)) { + deviceType.pop_back(); + } else { + break; + } + } + + if (line.contains(Devicetype_Separator)) { + QStringList strList = line.split(Devicetype_Separator); + if (DeviceInfoMap.contains(strList.first().trimmed().remove(Devicetype_lshw_Class_Prefix))) { + DeviceInfoMap[strList.first().trimmed().remove(Devicetype_lshw_Class_Prefix)] += ", "; + DeviceInfoMap[strList.first().trimmed().remove(Devicetype_lshw_Class_Prefix)] += strList.last().trimmed(); + } else { + DeviceInfoMap[strList.first().trimmed().remove(Devicetype_lshw_Class_Prefix)] = strList.last().trimmed(); + } + } + deviceType.push_back(line); + continue; + } + + int index = line.indexOf(Devicetype_Separator); + if (index > 0) { + QString name = line.mid(0, index).trimmed().remove(Devicetype_lshw_Class_Prefix); + if (name == "configuration" || name == "resources") { + QChar splitChar = name == "configuration" ? '=' : ':'; + + QStringList lst = line.mid(index + 1).trimmed().split(splitChar); + if (lst.size() < 2) { + if (DeviceInfoMap.contains(name)) { + DeviceInfoMap[name] += ", "; + DeviceInfoMap[name] += line.mid(index + 1).trimmed(); + } else { + DeviceInfoMap[name] = line.mid(index + 1).trimmed(); + } + + } else { + for (int ind = 0; ind < lst.size() - 1; ++ind) { + QString tempName = lst[ind].split(" ").last(); + int spaceIndex = lst[ind + 1].lastIndexOf(" "); + if (spaceIndex < 0) { + if (DeviceInfoMap.contains(tempName)) { + DeviceInfoMap[tempName] += ", "; + DeviceInfoMap[tempName] += lst[ind + 1]; + } else { + DeviceInfoMap[tempName] = lst[ind + 1]; + } + } else { + if (DeviceInfoMap.contains(tempName)) { + DeviceInfoMap[tempName] += ", "; + DeviceInfoMap[tempName] += lst[ind + 1].mid(0, spaceIndex); + } else { + DeviceInfoMap[tempName] = lst[ind + 1].mid(0, spaceIndex); + } + } + } + } + } else { + if (DeviceInfoMap.contains(name)) { + DeviceInfoMap[name] += ", "; + DeviceInfoMap[name] += line.mid(index + 1).trimmed(); + } else { + DeviceInfoMap[name] = line.mid(index + 1).trimmed(); + } + } + continue; + } + } + + //last device + { + QString deviceTypeName; + foreach (auto deviceType, deviceType) { + if (deviceTypeName.isEmpty() == false) { + deviceTypeName += Devicetype_Stitching_Symbol; + } + deviceTypeName += deviceType.trimmed().remove(Devicetype_lshw_Class_Prefix); + } + + lshwDatabase_[deviceTypeName] = DeviceInfoMap; + secondOrder.push_back(deviceTypeName); + } + + m_toolDatabase["lshw"] = lshwDatabase_; + secondOrder.removeDuplicates(); + m_toolDatabaseSecondOrder["lshw"] = secondOrder; + + return true; +} + +bool DeviceInfoParser::executeProcess(const QString &cmd) +{ + QProcess process; + process.start(cmd); + bool res = process.waitForFinished(10000); + m_standOutput = process.readAllStandardOutput(); + + return res; +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/deviceinfoparser.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/deviceinfoparser.h new file mode 100644 index 0000000..8f01893 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/deviceinfoparser.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include +#include + + +typedef QMap> DatabaseMap; + +class DeviceInfoParser: public QObject +{ + Q_OBJECT + +public: + static DeviceInfoParser &Instance() + { + static DeviceInfoParser _instance; + return _instance; + } + + // 刷新硬件数据 + void refreshDabase(); + + // 获取cdrom个数 + QStringList getLshwCDRomList(); + + // cdrom是否是内部设备 + bool isInternalDevice(const QString &device); + +signals: + void loadFinished(); + +protected: + const QString &queryData(const QString &toolname, const QString &firstKey, const QString &secondKey); + bool loadLshwDatabase(); + bool executeProcess(const QString &cmd); + +private: + DeviceInfoParser(); + ~DeviceInfoParser(); + + QString m_standOutput; // 存储命令输出 + + QMap m_toolDatabase; + QMap m_toolDatabaseSecondOrder; +}; + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfileselectionmodel.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfileselectionmodel.cpp new file mode 100644 index 0000000..69d778f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfileselectionmodel.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "dfileselectionmodel.h" + +#include + +DFileSelectionModel::DFileSelectionModel(QAbstractItemModel *model) + : QItemSelectionModel(model) +{ + m_timer.setSingleShot(true); + + connect(&m_timer, &QTimer::timeout, this, &DFileSelectionModel::updateSelecteds); +} + +DFileSelectionModel::DFileSelectionModel(QAbstractItemModel *model, QObject *parent) + : QItemSelectionModel(model, parent) +{ + m_timer.setSingleShot(true); + + connect(&m_timer, &QTimer::timeout, this, &DFileSelectionModel::updateSelecteds); +} + +bool DFileSelectionModel::isSelected(const QModelIndex &index) const +{ + if (m_currentCommand != QItemSelectionModel::SelectionFlags(Current | Rows | ClearAndSelect)) + return QItemSelectionModel::isSelected(index); + + auto ret = std::any_of(m_selection.begin(), m_selection.end(), [index](const QItemSelectionRange & range) { + return range.contains(index); + }); + + if (ret) { + Qt::ItemFlags flags = index.flags(); + return (flags & Qt::ItemIsSelectable); + } + + return false; +} + +int DFileSelectionModel::selectedCount() const +{ + if (m_currentCommand != QItemSelectionModel::SelectionFlags(Current | Rows | ClearAndSelect)) + return selectedIndexes().count(); + + return m_lastSelectedIndex.isValid() ? (m_lastSelectedIndex.row() - m_firstSelectedIndex.row() + 1) : 0; +} + +QModelIndexList DFileSelectionModel::selectedIndexes() const +{ + if (m_selectedList.isEmpty()) { + if (m_currentCommand != QItemSelectionModel::SelectionFlags(Current | Rows | ClearAndSelect)) { + m_selectedList = QItemSelectionModel::selectedIndexes(); + } else { + for (const QItemSelectionRange &range : m_selection) { + m_selectedList << range.indexes(); + } + } + } + + return m_selectedList; +} + +void DFileSelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) +{ + if (!command.testFlag(NoUpdate)) + m_selectedList.clear(); + + if (command != QItemSelectionModel::SelectionFlags(Current | Rows | ClearAndSelect)) { + if (m_timer.isActive()) { + m_timer.stop(); + updateSelecteds(); + } + + m_currentCommand = command; + + QItemSelectionModel::select(selection, command); + + return; + } + + + if (selection.isEmpty()) { + m_firstSelectedIndex = QModelIndex(); + m_lastSelectedIndex = QModelIndex(); + } else { + m_firstSelectedIndex = selection.first().topLeft(); + m_lastSelectedIndex = selection.last().bottomRight(); + } + + QItemSelection newSelection(m_firstSelectedIndex, m_lastSelectedIndex); + + emitSelectionChanged(newSelection, m_selection); + + m_currentCommand = command; + m_selection = newSelection; + + m_timer.start(20); +} + +void DFileSelectionModel::clear() +{ + m_timer.stop(); + m_selectedList.clear(); + m_selection.clear(); + + QItemSelectionModel::clear(); +} + +void DFileSelectionModel::updateSelecteds() +{ + QItemSelectionModel::select(m_selection, m_currentCommand); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfileselectionmodel.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfileselectionmodel.h new file mode 100644 index 0000000..ba204ce --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfileselectionmodel.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DFILESELECTIONMODEL_H +#define DFILESELECTIONMODEL_H + +#include +#include + +class DFileSelectionModel : public QItemSelectionModel +{ +public: + explicit DFileSelectionModel(QAbstractItemModel *model = 0); + explicit DFileSelectionModel(QAbstractItemModel *model, QObject *parent); + + bool isSelected(const QModelIndex &index) const; + int selectedCount() const; + + QModelIndexList selectedIndexes() const; + +protected: + void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override; + void clear() override; + +private: + void updateSelecteds(); + + mutable QModelIndexList m_selectedList; + + QItemSelection m_selection; + QModelIndex m_firstSelectedIndex; + QModelIndex m_lastSelectedIndex; + QItemSelectionModel::SelectionFlags m_currentCommand; + QTimer m_timer; + + friend class DFileView; +}; + +#endif // DFILESELECTIONMODEL_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmappentryfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmappentryfileinfo.cpp new file mode 100644 index 0000000..4c254ed --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmappentryfileinfo.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2021 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: lanxuesong + * zhangsheng + * max-lv + * + * 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 + * 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 . + */ + +#include "dfmappentryfileinfo.h" +#include "dfmappentryfileinfo_p.h" +#include "dfmstandardpaths.h" + +DFMAppEntryFileInfo::DFMAppEntryFileInfo(const DUrl &url) + : DFMRootFileInfo (url), + d_ptr(new DFMAppEntryFileInfoPrivate(this)) +{ + QString desktopFilePath = DFMStandardPaths::location(DFMStandardPaths::ExtensionsAppEntryPath) + "/" + url.path(); + QDir filePath(desktopFilePath); + if (!filePath.exists()) + desktopFilePath.append(".desktop"); + + entryFile = DesktopFile(desktopFilePath); + + qDebug() << "appentry: " << url.path() << url; +} + +QString DFMAppEntryFileInfo::fileDisplayName() const +{ + return entryFile.getDisplayName(); +} + +QString DFMAppEntryFileInfo::iconName() const +{ + return entryFile.getIcon(); +} + +bool DFMAppEntryFileInfo::exists() const +{ + if (!QFile(entryFile.getFileName()).exists()) + return false; + if (entryFile.getDisplayName().isEmpty()) // empty name cause UI error. + return false; + auto binPath = executableBin(); + if (!QFile(binPath).exists()) { + // if the executable is short cmd, combine it with $PATH and check again + auto pathEnv = QString(qgetenv("PATH")); + auto envs = pathEnv.split(":", QString::SkipEmptyParts); + for (const auto &env: envs) { + QFile executablePath(env + "/" + binPath); + if (executablePath.exists()) + return true; + } + return false; + } + return true; +} + +DAbstractFileInfo::FileType DFMAppEntryFileInfo::fileType() const +{ + return static_cast(ItemType::AppEntry); +} + +QVector DFMAppEntryFileInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + Q_UNUSED(type); + return QVector() << MenuAction::Open; +} + +QString DFMAppEntryFileInfo::cmd() const +{ + // no parameters transfered + static const QStringList unsupportedParams { + "%U", // A list of Urls + "%u", // A Url + "%F", // A list of files + "%f" // A file + }; + auto cmd = entryFile.getExec(); + for (const auto ¶m: unsupportedParams) + cmd.remove(param); + return cmd.remove("\"").remove("'"); +} + +QString DFMAppEntryFileInfo::executableBin() const +{ + auto cmd = this->cmd(); + auto cmdArgs = cmd.split(" ", QString::SkipEmptyParts); + auto bin = cmdArgs.count() > 0 ? cmdArgs.at(0) : QString(); + bin.remove("\"").remove("'"); + return bin; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmappentryfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmappentryfileinfo.h new file mode 100644 index 0000000..2c5d407 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmappentryfileinfo.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: lanxuesong + * zhangsheng + * max-lv + * + * 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 + * 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 . + */ + +#ifndef DFMAPPENTRYFILEINFO_H +#define DFMAPPENTRYFILEINFO_H + +#include "dfmrootfileinfo.h" +#include "shutil/desktopfile.h" + +class DFMAppEntryFileInfoPrivate; +class DFMAppEntryFileInfo : public DFMRootFileInfo +{ +public: + explicit DFMAppEntryFileInfo(const DUrl &url); + inline QString suffix() const override { + return SUFFIX_APP_ENTRY; + } + QString fileDisplayName() const override; + QString iconName() const override; + bool exists() const override; + FileType fileType() const override; + QVector menuActionList(MenuType type) const override; + + QString cmd() const; + QString executableBin() const; + +private: + DesktopFile entryFile; + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(DFMAppEntryFileInfo) +}; + +#endif // DFMAPPENTRYFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmappentryfileinfo_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmappentryfileinfo_p.h new file mode 100644 index 0000000..895a675 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmappentryfileinfo_p.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: xushitong + * + * Maintainer: lanxuesong + * zhangsheng + * max-lv + * + * 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 + * 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 . + */ + +#ifndef DFMAPPENTRYFILEINFO_P_H +#define DFMAPPENTRYFILEINFO_P_H + +#include "dfmrootfileinfo_p.h" +#include "dfmappentryfileinfo.h" + +class DFMAppEntryFileInfoPrivate: public DFMRootFileInfoPrivate { +public: + DFMAppEntryFileInfoPrivate(DFMAppEntryFileInfo *qq) + : q_ptr(qq){} + +private: + DFMAppEntryFileInfo *q_ptr; + Q_DECLARE_PUBLIC(DFMRootFileInfo) +}; + + +#endif // DFMAPPENTRYFILEINFO_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmrootfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmrootfileinfo.cpp new file mode 100644 index 0000000..31a9ad8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmrootfileinfo.cpp @@ -0,0 +1,890 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "dfmrootfileinfo.h" +#include "shutil/fileutils.h" +#include "app/define.h" +#include "utils/singleton.h" +#include "controllers/pathmanager.h" +#include "app/filesignalmanager.h" +#include "deviceinfo/udisklistener.h" +#include "dfmrootfileinfo_p.h" +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +DFM_USE_NAMESPACE + +QMap DFMRootFileInfo::DiskInfoMap = QMap(); + +DFMRootFileInfo::DFMRootFileInfo(const DUrl &url) : + DAbstractFileInfo(url), + d_ptr(new DFMRootFileInfoPrivate) +{ +// loadDiskInfo(); + if (suffix() == SUFFIX_USRDIR) { + QStandardPaths::StandardLocation loc = QStandardPaths::StandardLocation::HomeLocation; + if (baseName() == "desktop") { + loc = QStandardPaths::StandardLocation::DesktopLocation; + } else if (baseName() == "videos") { + loc = QStandardPaths::StandardLocation::MoviesLocation; + } else if (baseName() == "music") { + loc = QStandardPaths::StandardLocation::MusicLocation; + } else if (baseName() == "pictures") { + loc = QStandardPaths::StandardLocation::PicturesLocation; + } else if (baseName() == "documents") { + loc = QStandardPaths::StandardLocation::DocumentsLocation; + } else if (baseName() == "downloads") { + loc = QStandardPaths::StandardLocation::DownloadLocation; + } + + d_ptr->stdloc = loc; + if (QStandardPaths::writableLocation(loc) == QStandardPaths::writableLocation(QStandardPaths::StandardLocation::HomeLocation)) { + d_ptr->backer_url = ""; + } else { + FileUtils::mkpath(DUrl::fromLocalFile(QStandardPaths::writableLocation(loc))); + d_ptr->backer_url = QStandardPaths::writableLocation(loc); + } + } else if (suffix() == SUFFIX_GVFSMP) { + QString mpp = QUrl::fromPercentEncoding(fileUrl().path().mid(1).chopped(QString("." SUFFIX_GVFSMP).length()).toUtf8()); + QExplicitlySharedDataPointer mp(DGioMount::createFromPath(mpp)); + if (mp && mp->getRootFile() && mp->getRootFile()->path() == mpp) { + QExplicitlySharedDataPointer fi = mp->getRootFile()->createFileInfo("*", FILE_QUERY_INFO_NONE, 2000); + if (fi && fi->fileType() == DGioFileType::FILE_TYPE_DIRECTORY) { + QString mpurl = mp->getRootFile()->path(); + d_ptr->backer_url = mpurl; + d_ptr->gmnt = mp; + d_ptr->gfsi = mp->getRootFile()->createFileSystemInfo(); + } + } + } else if (suffix() == SUFFIX_UDISKS) { + QStringList pathList = DDiskManager::resolveDeviceNode("/dev" + url.path().chopped(QString("." SUFFIX_UDISKS).length()), {}); + if (pathList.size() == 0) { + qWarning() << url << "not existed"; + //fix 临时解决方案,彻底解决需要DDiskManager::resolveDeviceNode往下追踪 + for (int i = 0; i < 20; ++i) { + QThread::msleep(50); + + pathList = DDiskManager::resolveDeviceNode("/dev" + url.path().chopped(QString("." SUFFIX_UDISKS).length()), {}); + if (pathList.size() != 0) + break; + qWarning() << url << "not existed" << i; + } + if (pathList.size() == 0) + return; + //old + //return; + //endl + } + + //note: fix the U disk quickly installed and removed into two U disk, last valid + QString udiskspath; + if (pathList.size() > 0) { + udiskspath = pathList.last(); + } + QSharedPointer blk(DDiskManager::createBlockDevice(udiskspath)); + if (blk->path().length() != 0) { + QSharedPointer drv(DDiskManager::createDiskDevice(blk->drive())); + d_ptr->isod = drv->mediaCompatibility().join(" ").contains("optical"); + d_ptr->backer_url = udiskspath; + d_ptr->blk = blk; + d_ptr->blk->setWatchChanges(true); + checkCache(); + QObject::connect(d_ptr->blk.data(), &DBlockDevice::idLabelChanged, [this] {this->checkCache();}); + QObject::connect(d_ptr->blk.data(), &DBlockDevice::mountPointsChanged, [this] { +// this->loadDiskInfo(); + this->checkCache(); + }); + QObject::connect(d_ptr->blk.data(), &DBlockDevice::sizeChanged, [this] {this->checkCache();}); + QObject::connect(d_ptr->blk.data(), &DBlockDevice::idTypeChanged, [this] {this->checkCache();}); + QObject::connect(d_ptr->blk.data(), &DBlockDevice::cleartextDeviceChanged, [this] {this->checkCache();}); + } + } +} + +bool DFMRootFileInfo::exists() const +{ + Q_D(const DFMRootFileInfo); + if (suffix() == SUFFIX_USRDIR) { + return d->backer_url.length() != 0; + } else if (suffix() == SUFFIX_GVFSMP) { + if (!d->gmnt) { + return false; + } + QExplicitlySharedDataPointer fi = d->gmnt->getRootFile()->createFileInfo("*", FILE_QUERY_INFO_NONE, 2000); + return fi && fi->fileType() == DGioFileType::FILE_TYPE_DIRECTORY; + } else if (suffix() == SUFFIX_UDISKS) { + if (d->blk) { + return d->blk->path().length() != 0; + } else { + return false; + } + } else if (suffix() == SUFFIX_STASHED_REMOTE) { + return true; + } + return false; //默认返回false warning项 +} + +QString DFMRootFileInfo::suffix() const +{ + QRegularExpression re(".*\\.(.*)$"); + auto rem = re.match(fileName()); + if (!rem.hasMatch()) { + return ""; + } + return rem.captured(1); +} + +QString DFMRootFileInfo::fileDisplayName() const +{ + Q_D(const DFMRootFileInfo); + + if (suffix() == SUFFIX_USRDIR) { + QString namekey = baseName(); + namekey[0] = namekey[0].toUpper(); + return systemPathManager->getSystemPathDisplayName(namekey); + } else if (suffix() == SUFFIX_GVFSMP) { + return d->gmnt ? d->gmnt->name() : ""; + } else if (suffix() == SUFFIX_UDISKS) { + return d->udispname; + } else if (suffix() == SUFFIX_STASHED_REMOTE) { + auto path = fileUrl().path(); + path = RemoteMountsStashManager::normalizeConnUrl(path); + return RemoteMountsStashManager::getDisplayNameByConnUrl(path); + } + return baseName(); +} + +bool DFMRootFileInfo::canRename() const +{ + Q_D(const DFMRootFileInfo); + + if (suffix() != SUFFIX_UDISKS || !d->blk) + return false; + + if (d->blk->readOnly()) + return false; + + if (extraProperties()["fsType"].toString().toLower() == "swap") + return false; + + if (d->mps.size() > 0) + return canSetAlias(); + + return true; +} + +bool DFMRootFileInfo::canShare() const +{ + return false; +} + +bool DFMRootFileInfo::canFetch() const +{ + return false; +} + +bool DFMRootFileInfo::isReadable() const +{ + return true; +} + +bool DFMRootFileInfo::isWritable() const +{ + return false; +} + +bool DFMRootFileInfo::isExecutable() const +{ + return false; +} + +bool DFMRootFileInfo::isHidden() const +{ + return false; +} + +bool DFMRootFileInfo::isRelative() const +{ + return false; +} + +bool DFMRootFileInfo::isAbsolute() const +{ + return true; +} + +bool DFMRootFileInfo::isShared() const +{ + return false; +} + +bool DFMRootFileInfo::isTaged() const +{ + return false; +} + +bool DFMRootFileInfo::isWritableShared() const +{ + return false; +} + +bool DFMRootFileInfo::isAllowGuestShared() const +{ + return false; +} + +bool DFMRootFileInfo::isFile() const +{ + return true; +} + +bool DFMRootFileInfo::isDir() const +{ + return false; +} + +DAbstractFileInfo::FileType DFMRootFileInfo::fileType() const +{ + Q_D(const DFMRootFileInfo); + + ItemType ret; + + if (suffix() == SUFFIX_USRDIR) { + ret = ItemType::UserDirectory; + } else if (suffix() == SUFFIX_GVFSMP) { + ret = ItemType::GvfsGeneric; + if (d->gmnt && d->gmnt->getRootFile()) { + DUrl url(d->gmnt->getRootFile()->uri()); + if (url.scheme() == FTP_SCHEME) { + ret = ItemType::GvfsFTP; + } else if (url.scheme() == SMB_SCHEME) { + ret = ItemType::GvfsSMB; + } else if (url.scheme() == MTP_SCHEME) { + ret = ItemType::GvfsMTP; + } else if (url.scheme() == GPHOTO2_SCHEME) { + ret = ItemType::GvfsGPhoto2; + } + } + } else if (suffix() == SUFFIX_STASHED_REMOTE) { + ret = ItemType::NotConnRemote; + } else if (d->mps.contains(QByteArray("/\0", 2))) { + ret = ItemType::UDisksRoot; + } else if (d->label == "_dde_data") { + ret = ItemType::UDisksData; + } else { + if (d->blk) { + QScopedPointer drv(DDiskManager::createDiskDevice(d->blk->drive())); + if (d->isod) { + ret = ItemType::UDisksOptical; + } else { + ret = ItemType::UDisksFixed; + if (drv->media() == "thumb" || drv->removable() || drv->mediaRemovable() || drv->ejectable()) { + ret = ItemType::UDisksRemovable; + } + } + } else { + ret = ItemType::UDisksRemovable; + } + } + return static_cast(ret); +} + +int DFMRootFileInfo::filesCount() const +{ + return 0; +} + +QString DFMRootFileInfo::iconName() const +{ + Q_D(const DFMRootFileInfo); + if (suffix() == SUFFIX_USRDIR) { + return systemPathManager->getSystemPathIconNameByPath(redirectedFileUrl().path()); + } else if (suffix() == SUFFIX_GVFSMP) { + if (!d->gmnt || d->gmnt->themedIconNames().size() == 0) { + return ""; + } + return d->gmnt ? d->gmnt->themedIconNames().front() : ""; + } else if (suffix() == SUFFIX_UDISKS) { + if (d->blk) { + QScopedPointer drv(DDiskManager::createDiskDevice(d->blk->drive())); + if (drv->mediaCompatibility().join(" ").contains("optical")) { + return "media-optical"; + } + if (static_cast(fileType()) == ItemType::UDisksRemovable) { + return QString("drive-removable-media") + (d->encrypted ? "-encrypted" : ""); + } + if (d->mps.contains(QByteArray("/\0", 2))) { + return "drive-harddisk-root"; + } + } + return QString("drive-harddisk") + (d->encrypted ? "-encrypted" : ""); + } else if (suffix() == SUFFIX_STASHED_REMOTE) { + return "folder-remote"; + } + return ""; +} + +QVector DFMRootFileInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + Q_D(const DFMRootFileInfo); + Q_UNUSED(type) + bool protectUnmountOrEject = false; + DGioSettings gsettings("com.deepin.dde.filemanager.general", "/com/deepin/dde/filemanager/general/"); + QVector ret; + if (suffix() == SUFFIX_USRDIR) { + ret.push_back(MenuAction::OpenInNewWindow); + ret.push_back(MenuAction::OpenInNewTab); + } else if (suffix() != SUFFIX_STASHED_REMOTE) { // DO NOT SHOW THESE ACTIONS FOR NOT CONNECTED REMOTE CONNECTION + ret.push_back(MenuAction::OpenDiskInNewWindow); + ret.push_back(MenuAction::OpenDiskInNewTab); + } + + ret.push_back(MenuAction::Separator); + + QScopedPointer drv(DDiskManager::createDiskDevice(d->blk ? d->blk->drive() : "")); + DBlockDevice *blk = d->ctblk ? d->ctblk.data() : d->blk.data(); + + if (suffix() == SUFFIX_UDISKS && blk && !blk->mountPoints().empty()) { + if (gsettings.value("protect-non-media-mounts").toBool()) { + QList mountPoints = blk->mountPoints(); + for (auto &mountPoint : mountPoints) { + if (!mountPoint.startsWith("/media/")) { + protectUnmountOrEject = true; + break; + } + } + } + + if (gsettings.value("protect-root-device-mounts").toBool() && !protectUnmountOrEject) { + QStorageInfo qsi("/"); + QStringList rootDevNodes = DDiskManager::resolveDeviceNode(qsi.device(), {}); + if (!rootDevNodes.isEmpty()) { + if (DDiskManager::createBlockDevice(rootDevNodes.first())->drive() == blk->drive()) { + protectUnmountOrEject = true; + } + } + } + } + + //cleartextDevice has hintSystem = true regardless of its backer's value ... + if (suffix() == SUFFIX_GVFSMP || (suffix() == SUFFIX_UDISKS && blk && ((!blk->mountPoints().empty() && !d->blk->hintSystem())))) { + if (!protectUnmountOrEject) { + ret.push_back(MenuAction::Unmount); + } + } + + // swap 是特殊的分区,不能重命名 + QString &&fs = extraProperties()["fsType"].toString().toLower(); + if (suffix() == SUFFIX_UDISKS && blk && blk->mountPoints().empty()) { + ret.push_back(MenuAction::Mount); + if (!blk->readOnly()) { + if (fs != "swap") + ret.push_back(MenuAction::Rename); + ret.push_back(MenuAction::FormatDevice); + } + if (drv->optical() && drv->media().contains(QRegularExpression("_r(w|e)"))) { + ret.push_back(MenuAction::OpticalBlank); + } + } + + if (!ret.contains(MenuAction::Rename) && canRename() && fs != "swap") { + ret.push_back(MenuAction::Rename); + } + + if (drv && drv->ejectable() && (!drv->canPowerOff() || drv->mediaCompatibility().join(" ").contains("optical"))) { + if (!protectUnmountOrEject) { + ret.push_back(MenuAction::Eject); + } + } + if (drv && drv->canPowerOff()) { + ret.push_back(MenuAction::SafelyRemoveDrive); + } + + if (suffix() == SUFFIX_GVFSMP && d->gmnt && d->gmnt->getRootFile()) { + QString scheme = QUrl(d->gmnt->getRootFile()->uri()).scheme(); + if (QSet({SMB_SCHEME, FTP_SCHEME, SFTP_SCHEME, DAV_SCHEME}).contains(scheme)) { + ret.push_back(MenuAction::ForgetPassword); + } + } + + if (suffix() == SUFFIX_STASHED_REMOTE) { + ret.push_back(MenuAction::Mount); + ret.push_back(MenuAction::RemoveStashedRemoteConn); + } + + ret.push_back(MenuAction::Separator); + + ret.push_back(MenuAction::Property); + return ret; +} + +bool DFMRootFileInfo::canRedirectionFileUrl() const +{ + return true; +} + +DUrl DFMRootFileInfo::redirectedFileUrl() const +{ + Q_D(const DFMRootFileInfo); + if (suffix() == SUFFIX_USRDIR) { + return DUrl::fromLocalFile(d->backer_url); + } else if (suffix() == SUFFIX_GVFSMP) { + return DUrl::fromLocalFile(d->backer_url); + } else if (suffix() == SUFFIX_UDISKS) { + if (d->blk) { + QScopedPointer drv(DDiskManager::createDiskDevice(d->blk->drive())); + if (drv->optical()) { + return DUrl::fromBurnFile(QString(d->blk->device()) + "/" + BURN_SEG_ONDISC + "/"); + } + } + if (d->mps.size()) { + DUrl rootUrl = DUrl::fromLocalFile(d->mps.first()); + + //点击数据盘直接跳转到主目录 + if (rootUrl == DUrl::fromLocalFile("/data")) { + QString userPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); + //确认/data目录下是否挂载了home目录 + QDir dir("/data" + userPath); + if (dir.exists()) + rootUrl = DUrl::fromLocalFile("/data" + userPath); + } + return rootUrl; + } + } + return DUrl(); +} + +bool DFMRootFileInfo::canDrop() const +{ + return false; +} + +Qt::DropActions DFMRootFileInfo::supportedDragActions() const +{ + return Qt::DropAction::IgnoreAction; +} + +Qt::DropActions DFMRootFileInfo::supportedDropActions() const +{ + return Qt::DropAction::IgnoreAction; +} + +QVariantHash DFMRootFileInfo::extraProperties() const +{ + Q_D(const DFMRootFileInfo); + QVariantHash ret; + ret["fsFreeSize"] = 0; + if (suffix() == SUFFIX_GVFSMP) { + if (d->gfsi) { + ret["fsUsed"] = d->gfsi->fsTotalBytes() - d->gfsi->fsFreeBytes(); + ret["fsSize"] = d->gfsi->fsTotalBytes(); + ret["fsType"] = d->gfsi->fsType(); + } + ret["rooturi"] = d->gmnt && d->gmnt->getRootFile() ? d->gmnt->getRootFile()->uri() : ""; + ret["mounted"] = true; + ret["backer_url"] = d->backer_url; + } else if (suffix() == SUFFIX_UDISKS) { + if (d->mps.empty()) { + ret["fsUsed"] = ~0ULL; + } else { + QStorageInfo si(d->mps.front()); + ret["fsUsed"] = quint64(d->size) - quint64(si.bytesAvailable()); + ret["fsFreeSize"] = quint64(si.bytesAvailable()); + } + ret["fsSize"] = quint64(d->size); + ret["fsType"] = d->fs; + ret["fsVersion"] = d->fsVersion; + ret["encrypted"] = d->encrypted; + ret["unlocked"] = !d->encrypted || d->ctblk; + if (d->ctblk) { + ret["udisksblk"] = d->ctblk->path(); + } else if (d->blk) { + ret["udisksblk"] = d->blk->path(); + } + ret["mounted"] = !d->mps.empty(); + } + return ret; +} + +void DFMRootFileInfo::refresh(const bool isForce) +{ + Q_UNUSED(isForce) + //udisk的refresh函数中的proxy为空指针,没有实际意义 + //由于优化性能后,u盘挂载文件信息会被缓存,因此需要在此增加刷新U盘的挂载数据 + if (suffix() == SUFFIX_UDISKS) + checkCache(); + + DAbstractFileInfo::refresh(); +} + +bool DFMRootFileInfo::canSetAlias() const +{ + // 系统盘、数据盘均可设置别名 + auto type = static_cast(fileType()); + if (dfm_util::isContains(type, ItemType::UDisksRoot, ItemType::UDisksData)) { + return true; + } + + // 其他数据盘通过 /etc/fstab 判断是否为本地磁盘 + if (type == ItemType::UDisksFixed) { + return deviceListener->isFromNativeDisk(d_ptr->idUUID); + } + + return false; +} + +void DFMRootFileInfo::checkCache() +{ + Q_D(DFMRootFileInfo); + if (!d->blk) { + return; + } + + d->encrypted = d->blk->isEncrypted(); + if (d->encrypted) { + if (d->blk->cleartextDevice().length() > 1) { + d->ctblk.reset(DDiskManager::createBlockDevice(d->blk->cleartextDevice())); + } else { + d->ctblk.clear(); + } + } + + DBlockDevice *blk = d->ctblk ? d->ctblk.data() : d->blk.data(); + d->mps = blk->mountPoints(); + d->size = blk->size(); + d->label = blk->idLabel(); + + loadDiskInfo(); + d->fs = blk->idType(); + d->fsVersion = blk->idVersion(); + d->idUUID = blk->idUUID(); + d->udispname = canSetAlias() ? udisksDispalyAlias() : udisksDisplayName(); + + // udisksDispalyAlias 异常情况下可能返回空值, + // 这种情况下使用 udisksDisplayName 恢复默认卷名 + if (Q_UNLIKELY(d->udispname.isEmpty())) + d->udispname = udisksDisplayName(); +} + +QString DFMRootFileInfo::udisksDispalyAlias() +{ + Q_D(DFMRootFileInfo); + // read alias + const QVariantList &list = DFMApplication::genericSetting()->value(DISKALIAS_GROUP, DISKALIAS_ITEMS).toList(); + QString name; + + for (const QVariant &v : list) { + const QVariantMap &map = v.toMap(); + if (map.value(DISKALIAS_ITEM_UUID).toString() == d->idUUID) { + name = map.value(DISKALIAS_ITEM_ALIAS).toString(); + break; + } + } + + return name; +} + +QString DFMRootFileInfo::udisksDisplayName() +{ + Q_D(DFMRootFileInfo); + + //windows分区需要显示该分区在windows下的盘符或卷标 + if (DFMRootFileInfo::DiskInfoMap.contains(d->idUUID)) { + const DiskInfoStr info = DFMRootFileInfo::DiskInfoMap.value(d->idUUID); + if (!info.label.isEmpty()) { + return info.label; + } else { + return info.driver; + } + } + + static QMap i18nMap { + {"data", "Data Disk"} + }; + const QString ddeI18nSym = QStringLiteral("_dde_"); + + static std::initializer_list> opticalmediakeys { + {"optical", "Optical"}, + {"optical_cd", "CD-ROM"}, + {"optical_cd_r", "CD-R"}, + {"optical_cd_rw", "CD-RW"}, + {"optical_dvd", "DVD-ROM"}, + {"optical_dvd_r", "DVD-R"}, + {"optical_dvd_rw", "DVD-RW"}, + {"optical_dvd_ram", "DVD-RAM"}, + {"optical_dvd_plus_r", "DVD+R"}, + {"optical_dvd_plus_rw", "DVD+RW"}, + {"optical_dvd_plus_r_dl", "DVD+R/DL"}, + {"optical_dvd_plus_rw_dl", "DVD+RW/DL"}, + {"optical_bd", "BD-ROM"}, + {"optical_bd_r", "BD-R"}, + {"optical_bd_re", "BD-RE"}, + {"optical_hddvd", "HD DVD-ROM"}, + {"optical_hddvd_r", "HD DVD-R"}, + {"optical_hddvd_rw", "HD DVD-RW"}, + {"optical_mo", "MO"} + }; + static QVector> opticalmediakv(opticalmediakeys); + static QMap opticalmediamap(opticalmediakeys); + + if (d->label.startsWith(ddeI18nSym)) { + QString i18nKey = d->label.mid(ddeI18nSym.size(), d->label.size() - ddeI18nSym.size()); + auto &&bytes = i18nKey.toUtf8(); + auto ret = qApp->translate("DeepinStorage", i18nMap.value(i18nKey, bytes.data())); + return ret; + } + + if (d->mps.contains(QByteArray("/\0", 2))) { + return QCoreApplication::translate("PathManager", "System Disk"); + } else if (!d->idUUID.isEmpty()) { + if (d->currentUUID.isEmpty() || d->backupUUID.isEmpty()) { + QFile recoveryFile(QString("/etc/%1/ab-recovery.json").arg(qApp->organizationName())); + + if (recoveryFile.open(QIODevice::ReadOnly)) { + + QByteArray recoveryData = recoveryFile.readAll(); + recoveryFile.close(); + + QJsonParseError parseJsonErr; + QJsonDocument jsonDoc(QJsonDocument::fromJson(recoveryData, &parseJsonErr)); + if (!(parseJsonErr.error == QJsonParseError::NoError)) { + qDebug() << "decode json file error, create new json data!"; + } else { + QJsonObject rootObj = jsonDoc.object(); + const QString currentcurrentUUIDKey = "Current"; + const QString backupUUIDKey = "Backup"; + if (rootObj.contains(currentcurrentUUIDKey)) { + d->currentUUID = rootObj[currentcurrentUUIDKey].toString(); + } + if (rootObj.contains(backupUUIDKey)) { + d->backupUUID = rootObj[backupUUIDKey].toString(); + } + } + } + } + if (d->currentUUID == d->idUUID || d->backupUUID == d->idUUID) { + return QCoreApplication::translate("PathManager", "System Disk"); + } + } + + if (d->label.length() == 0) { + QScopedPointer drv(DDiskManager::createDiskDevice(d->blk->drive())); + if (drv->opticalBlank()) { + return QCoreApplication::translate("DeepinStorage", "Blank %1 Disc").arg(opticalmediamap[drv->media()]); + } + // TODO xust,暂时先屏蔽判定uuid的语句,该语句会导致无法正常挂载的盘连盘符都不显示,引入该改动是为解决自动光驱弹出托盘后界面不刷新的问题,此处之后再找其他的方式调整。 + if ((!drv->mediaAvailable()/* || d->idUUID.isEmpty()*/) && drv->mediaCompatibility().join(" ").contains("optical")) { // uuid 为空认为光盘未挂载或已卸载(托盘已弹出),此时强制使用无光盘的名称 + d->blk->unmount({}); + d->size = 0; + QTimer::singleShot(100, [] { + emit fileSignalManager->requestUpdateComputerView(); + }); + QString maxmediacompat; + for (auto i = opticalmediakv.rbegin(); i != opticalmediakv.rend(); ++i) { + if (drv->mediaCompatibility().contains(i->first)) { + maxmediacompat = i->second; + break; + } + } + return QCoreApplication::translate("DeepinStorage", "%1 Drive").arg(maxmediacompat); + } + if (d->blk->isEncrypted() && !d->ctblk) { + return QCoreApplication::translate("DeepinStorage", "%1 Encrypted").arg(FileUtils::formatSize(d->size)); + } + return QCoreApplication::translate("DeepinStorage", "%1 Volume").arg(FileUtils::formatSize(d->size)); + } + + return d->label; +} + +QString DFMRootFileInfo::getVolTag() +{ + Q_D(DFMRootFileInfo); + int nIdx = d->backer_url.lastIndexOf("/"); + return nIdx < 0 ? QString() : d->backer_url.mid(nIdx + 1); +} + +QString DFMRootFileInfo::getUUID() +{ + Q_D(DFMRootFileInfo); + return d->idUUID; +} + +bool DFMRootFileInfo::checkMpsStr(const QString &path) const +{ + Q_D(const DFMRootFileInfo); + + for (QByteArray ba : d->mps) { + QString baStr(ba.data()); + if (baStr == path) + return true; + } + + return false; +} + +bool DFMRootFileInfo::typeCompare(const DAbstractFileInfoPointer &a, const DAbstractFileInfoPointer &b) +{ + static const QHash priomap = { + {ItemType::UserDirectory, -1}, + {ItemType::UDisksRoot, 0}, + {ItemType::UDisksData, 1}, + {ItemType::UDisksFixed, 2}, + {ItemType::UDisksRemovable, 3}, + {ItemType::UDisksOptical, 4}, + {ItemType::GvfsSMB, 5}, + {ItemType::NotConnRemote, 5}, + {ItemType::GvfsFTP, 5}, + {ItemType::GvfsMTP, 6}, + {ItemType::GvfsGPhoto2, 6}, + {ItemType::GvfsGeneric, 7}, + {ItemType::AppEntry, 10} + }; + // fix bug 64147 网络文件不去判断exists会卡顿 + if (!a) + return false; + DFMRootFileInfo::ItemType aType = static_cast(a->fileType()); + if (aType != ItemType::GvfsSMB && aType != ItemType::GvfsFTP && aType != ItemType::GvfsGeneric && !a->exists()) { + return false; + } + if (!b) + return true; + DFMRootFileInfo::ItemType bType = static_cast(b->fileType()); + if (bType != ItemType::GvfsSMB && bType != ItemType::GvfsFTP && bType != ItemType::GvfsGeneric && !b->exists()) { + return true; + } + return priomap[aType] < priomap[bType]; +} + +bool DFMRootFileInfo::typeCompareByUrl(const DAbstractFileInfoPointer &a, const DAbstractFileInfoPointer &b) +{ + static const QHash priomap = { + {ItemType::UserDirectory, -1}, + {ItemType::UDisksRoot, 0}, + {ItemType::UDisksData, 1}, + {ItemType::UDisksFixed, 2}, + {ItemType::UDisksRemovable, 3}, + {ItemType::UDisksOptical, 4}, + {ItemType::GvfsMTP, 5}, + {ItemType::GvfsGPhoto2, 5}, + {ItemType::GvfsGeneric, 6}, + {ItemType::GvfsSMB, 7}, + {ItemType::GvfsFTP, 7}, + {ItemType::NotConnRemote, 7}, + {ItemType::AppEntry, 10} + }; + // fix bug 64147 网络文件不去判断exists会卡顿 + if (!a) + return false; + DFMRootFileInfo::ItemType aType = static_cast(a->fileType()); + if (aType != ItemType::GvfsSMB && aType != ItemType::GvfsFTP && aType != ItemType::GvfsGeneric && !a->exists()) { + return false; + } + if (!b) + return true; + DFMRootFileInfo::ItemType bType = static_cast(b->fileType()); + if (bType != ItemType::GvfsSMB && bType != ItemType::GvfsFTP && bType != ItemType::GvfsGeneric && !b->exists()) { + return true; + } + return priomap[aType] < priomap[bType]; +} + +void DFMRootFileInfo::loadDiskInfo() +{ + Q_D(const DFMRootFileInfo); + + if (d->mps.empty()) + return; + + if (d->blk) { + auto drv = DDiskManager::createDiskDevice(d->blk->drive()); + if (drv && drv->optical()) + return; + } + QDir dir(QString(d->mps.front()) + "/UOSICON"); + if (!dir.exists()) { + return; + } + + QString jsonPath = dir.absolutePath(); + //不存在该目录 + if (jsonPath.isEmpty()) { + return; + } + + //读取本地json文件 + QFile file(jsonPath + "/diskinfo.json"); + if (!file.open(QIODevice::ReadWrite)) { + return; + } + + //解析json文件 + QJsonParseError jsonParserError; + QJsonDocument jsonDocument = QJsonDocument::fromJson(file.readAll(), &jsonParserError); + if (jsonDocument.isNull() || jsonParserError.error != QJsonParseError::NoError) { + return; + } + + if (jsonDocument.isObject()) { + QJsonObject jsonObject = jsonDocument.object(); + if (jsonObject.contains("DISKINFO") && jsonObject.value("DISKINFO").isArray()) { + QJsonArray jsonArray = jsonObject.value("DISKINFO").toArray(); + for (int i = 0; i < jsonArray.size(); i++) { + if (jsonArray[i].isObject()) { + QJsonObject jsonObjectInfo = jsonArray[i].toObject(); + DiskInfoStr str; + if (jsonObjectInfo.contains("uuid")) + str.uuid = jsonObjectInfo.value("uuid").toString(); + if (jsonObjectInfo.contains("drive")) + str.driver = jsonObjectInfo.value("drive").toString(); + if (jsonObjectInfo.contains("label")) + str.label = jsonObjectInfo.value("label").toString(); + + DFMRootFileInfo::DiskInfoMap[str.uuid] = str; + } + } + } + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmrootfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmrootfileinfo.h new file mode 100644 index 0000000..b21b436 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmrootfileinfo.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lanxuesong + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DFMROOTFILEINFO_H +#define DFMROOTFILEINFO_H + +#include "dfileinfo.h" + +#define DISKALIAS_GROUP "LocalDiskAlias" +#define DISKALIAS_ITEMS "Items" +#define DISKALIAS_ITEM_UUID "uuid" +#define DISKALIAS_ITEM_NAME "name" +#define DISKALIAS_ITEM_ALIAS "alias" + + +class DFMRootFileInfoPrivate; + +typedef struct { + QString driver; //盘符 + QString label; //标签 + QString uuid; //id +} DiskInfoStr; + +class DFMRootFileInfo : public DAbstractFileInfo +{ +public: + + enum ItemType { + UserDirectory = DAbstractFileInfo::FileType::CustomType + 1, + GvfsGeneric, + GvfsSMB, + GvfsMTP, + GvfsGPhoto2, + GvfsFTP, + GvfsCamera, + UDisksRoot, + UDisksData, + UDisksFixed, + UDisksRemovable, + UDisksOptical, + NotConnRemote, + AppEntry, + }; + + explicit DFMRootFileInfo(const DUrl &url); + bool exists() const override; + + QString suffix() const override; + QString fileDisplayName() const override; + + bool canRename() const override; + bool canShare() const override; + bool canFetch() const override; + bool isReadable() const override; + bool isWritable() const override; + bool isExecutable() const override; + bool isHidden() const override; + bool isRelative() const override; + bool isAbsolute() const override; + bool isShared() const override; + bool isTaged() const override; + bool isWritableShared() const override; + bool isAllowGuestShared() const override; + + bool isFile() const override; + bool isDir() const override; + FileType fileType() const override; + int filesCount() const override; + QString iconName() const override; + + QVector menuActionList(MenuType type = SingleFile) const override; + + bool canRedirectionFileUrl() const override; + DUrl redirectedFileUrl() const override; + bool canDrop() const override; + Qt::DropActions supportedDragActions() const override; + Qt::DropActions supportedDropActions() const override; + + QVariantHash extraProperties() const override; + + void refresh(const bool isForce = false) override; + + bool canSetAlias() const; + void checkCache(); + QString udisksDispalyAlias(); + QString udisksDisplayName(); + QString getVolTag(); // ....../dev/sr0 -> sr0 + QString getUUID(); + + bool checkMpsStr(const QString &path) const override; + + static bool typeCompare(const DAbstractFileInfoPointer &a, const DAbstractFileInfoPointer &b); + //fix bug 49348 if unable network,ftp smb sort the last + static bool typeCompareByUrl(const DAbstractFileInfoPointer &a, const DAbstractFileInfoPointer &b); + + static QMap DiskInfoMap; +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(DFMRootFileInfo) + + /** + * @brief loadDiskInfo 加载盘符信息 + */ + void loadDiskInfo(); +}; + +#endif // DFMROOTFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmrootfileinfo_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmrootfileinfo_p.h new file mode 100644 index 0000000..f231351 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmrootfileinfo_p.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lanxuesong + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DFMROOTFILEINFO_P_H +#define DFMROOTFILEINFO_P_H +#include "dfmrootfileinfo.h" +#include +#include +#include +#include + +class DFMRootFileInfoPrivate +{ +public: + QStandardPaths::StandardLocation stdloc; + QSharedPointer blk; + QSharedPointer ctblk; + QExplicitlySharedDataPointer gmnt; + QExplicitlySharedDataPointer gfsi; + QString backer_url; + QByteArrayList mps; /* mountpoints */ + qulonglong size; + QString label; + QString fs; + QString fsVersion; + QString udispname; + QString idUUID; + QString currentUUID; + QString backupUUID; + bool isod; + bool encrypted; + +private: + DFMRootFileInfo *q_ptr; + Q_DECLARE_PUBLIC(DFMRootFileInfo) +}; + + +#endif // DFMROOTFILEINFO_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmsidebarmodel.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmsidebarmodel.cpp new file mode 100644 index 0000000..8ce5edc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmsidebarmodel.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "dfmsidebarmodel.h" + +#include "views/dfmsidebaritemdelegate.h" +#include "interfaces/dfmsidebaritem.h" + +#include +#include + +#define MODELITEM_MIMETYPE "application/x-dfmsidebaritemmodeldata" + +DFM_BEGIN_NAMESPACE + +DFMSideBarModel::DFMSideBarModel(QObject *parent) + : QStandardItemModel(parent) +{ + +} + +bool DFMSideBarModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const +{ + // when drag onto the empty space of the area, just return false. + if (column == -1 || row == -1 || !data) + return false; + + Q_ASSERT(column == 0); + + auto isSeparator = [](DFMSideBarItem *item)->bool{ + return item && item->itemType()==DFMSideBarItem::Separator; + }; + auto isItemDragEnabled = [](DFMSideBarItem *item)->bool{ + return item && item->flags().testFlag(Qt::ItemIsDragEnabled); + }; + auto isTheSameGroup = [](DFMSideBarItem *item1, DFMSideBarItem *item2)->bool{ + return item1 && item2 && item1->groupName() == item2->groupName(); + }; + + DFMSideBarItem * targetItem = this->itemFromIndex(row); + DFMSideBarItem * sourceItem = nullptr; + + // check if is item internal move by action and mimetype: + if (action == Qt::MoveAction && data->formats().contains(MODELITEM_MIMETYPE)) { + int oriRowIndex = getRowIndexFromMimeData(data->data(MODELITEM_MIMETYPE)); + if (oriRowIndex >= 0) { + sourceItem = this->itemFromIndex(oriRowIndex); + } + + // normal drag tag or bookmark + if (isItemDragEnabled(targetItem) && isTheSameGroup(sourceItem, targetItem)) { + return true; + } + + DFMSideBarItem * prevItem = itemFromIndex(row-1); + // drag tag item to bottom, targetItem is null + // drag bookmark item on the bookmark bottom separator, targetItem is Separator + if ((!targetItem || isSeparator(targetItem)) && sourceItem != prevItem) { + return isItemDragEnabled(prevItem) && isTheSameGroup(prevItem, sourceItem); + } + + return false; + } + + return QStandardItemModel::canDropMimeData(data, action, row, column, parent); +} + +QMimeData *DFMSideBarModel::mimeData(const QModelIndexList &indexes) const +{ + QMimeData * data = QStandardItemModel::mimeData(indexes); + if (!data) + return nullptr; + data->setData(MODELITEM_MIMETYPE, generateMimeData(indexes)); + return data; +} + +QModelIndex DFMSideBarModel::indexFromItem(const DFMSideBarItem *item) const +{ + return QStandardItemModel::indexFromItem(item); +} + +DFMSideBarItem *DFMSideBarModel::itemFromIndex(const QModelIndex &index) const +{ + QStandardItem *item = QStandardItemModel::itemFromIndex(index); + DFMSideBarItem* castedItem = static_cast(item); + + return castedItem; +} + +DFMSideBarItem *DFMSideBarModel::itemFromIndex(int index) const +{ + return itemFromIndex(this->index(index, 0)); +} + +QByteArray DFMSideBarModel::generateMimeData(const QModelIndexList &indexes) const +{ + if (indexes.isEmpty()) + return QByteArray(); + QByteArray encoded; + QDataStream stream(&encoded, QIODevice::WriteOnly); + stream << indexes.first().row(); + + return encoded; +} + +int DFMSideBarModel::getRowIndexFromMimeData(const QByteArray &data) const +{ + int row; + QDataStream stream(data); + stream >> row; + + return row; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmsidebarmodel.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmsidebarmodel.h new file mode 100644 index 0000000..8027dc0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/dfmsidebarmodel.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#pragma once + +#include "dfmglobal.h" +#include + +DFM_BEGIN_NAMESPACE + +class DFMSideBarItem; +class DFMSideBarModel : public QStandardItemModel +{ +public: + explicit DFMSideBarModel(QObject *parent = nullptr); + + bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override; + QMimeData *mimeData(const QModelIndexList &indexes) const override; + QModelIndex indexFromItem(const DFMSideBarItem * item) const; + DFMSideBarItem *itemFromIndex(const QModelIndex &index) const; + DFMSideBarItem *itemFromIndex(int index) const; + +private: + QByteArray generateMimeData(const QModelIndexList &indexes) const; + int getRowIndexFromMimeData(const QByteArray &data) const; +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/fileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/fileinfo.cpp new file mode 100644 index 0000000..a952df4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/fileinfo.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "fileinfo.h" + +#include "app/define.h" + +#include "shutil/iconprovider.h" + +#include "controllers/pathmanager.h" +#include "deviceinfo/udisklistener.h" +#include "singleton.h" + +#include "app/define.h" +#include "singleton.h" +#include "usershare/usersharemanager.h" +#include "shutil/dmimedatabase.h" + +#include +#include + + +QMap FileInfo::canRenameCacheMap; + +FileInfo::FileInfo() + : DAbstractFileInfo() +{ + +} + +FileInfo::FileInfo(const QString &fileUrl) + : DAbstractFileInfo(fileUrl) +{ + +} + +FileInfo::FileInfo(const DUrl &fileUrl) + : DAbstractFileInfo(fileUrl) +{ + +} + +FileInfo::FileInfo(const QFileInfo &fileInfo) + : DAbstractFileInfo(QUrl::fromLocalFile(fileInfo.absoluteFilePath())) +{ + +} + +bool FileInfo::exists(const DUrl &fileUrl) +{ + return QFileInfo::exists(fileUrl.toLocalFile()); +} + +QMimeType FileInfo::mimeType(const QString &filePath) +{ + DMimeDatabase db; + + return db.mimeTypeForFile(filePath); +} + +bool FileInfo::isCanRename() const +{ + if (systemPathManager->isSystemPath(absoluteFilePath())) + return false; + + bool canRename = FileInfo(absolutePath()).isWritable(); + + canRenameCacheMap[fileUrl()] = canRename; + + return canRename; +} + +bool FileInfo::isCanShare() const +{ + if (isDir() && isReadable()){ + bool isInDeviceFolder = deviceListener->isInDeviceFolder(absolutePath()); + bool isCanShare = isInDeviceFolder || fileUrl().path().startsWith(QDir::homePath()); + return isCanShare; + } + return false; +} + +bool FileInfo::isShared() const +{ + return userShareManager->isShareFile(absoluteFilePath()); +} + +QMimeType FileInfo::mimeType() const +{ + if (!data->mimeType.isValid()) + data->mimeType = mimeType(absoluteFilePath()); + + return data->mimeType; +} + +QIcon FileInfo::fileIcon() const +{ + return fileIconProvider->getFileIcon(fileUrl(), mimeTypeName()); +} + +bool FileInfo::canIteratorDir() const +{ + return true; +} + +QString FileInfo::subtitleForEmptyFloder() const +{ + if (!DAbstractFileInfo::exists()) { + return QObject::tr("File has been moved or deleted"); + } else if (!isReadable()) { + return QObject::tr("You do not have permission to access this folder"); + } + + return QObject::tr("Folder is empty"); +} + +QString FileInfo::displayName() const +{ + if (systemPathManager->isSystemPath(filePath())) { + QString displayName = systemPathManager->getSystemPathDisplayNameByPath(filePath()); + + if (displayName.isEmpty()) + return fileName(); + else + return displayName; + + } else { + return fileName(); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/masteredmediafileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/masteredmediafileinfo.cpp new file mode 100644 index 0000000..27bd792 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/masteredmediafileinfo.cpp @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "masteredmediafileinfo.h" +#include "private/dabstractfileinfo_p.h" +#include "app/define.h" +#include "deviceinfo/udisklistener.h" +#include "dfileservices.h" +#include "disomaster.h" +#include "dblockdevice.h" +#include "ddiskdevice.h" +#include "ddiskmanager.h" +#include +#include "controllers/masteredmediacontroller.h" +#include "views/dfmopticalmediawidget.h" + +MasteredMediaFileInfo::MasteredMediaFileInfo(const DUrl &url) + : DAbstractFileInfo(url) +{ + backupInfo(url); +} + +bool MasteredMediaFileInfo::exists() const +{ + Q_D(const DAbstractFileInfo); + + if (fileUrl().isEmpty() || !m_backerUrl.isValid() || m_backerUrl.isEmpty()) { + return false; + } + if (fileUrl().fragment() == "dup") { + return false; + } + + return d->proxy && d->proxy->exists(); +} + +bool MasteredMediaFileInfo::isReadable() const +{ + Q_D(const DAbstractFileInfo); + + if (!d->proxy) + return true; + + return d->proxy->isReadable(); +} + +bool MasteredMediaFileInfo::isWritable() const +{ + if (!m_backerUrl.burnIsOnDisc()) + return true; + return ISOMaster->getDevicePropertyCached(fileUrl().burnDestDevice()).avail > 0; +} + +bool MasteredMediaFileInfo::isDir() const +{ + Q_D(const DAbstractFileInfo); + + return !d->proxy || d->proxy->isDir(); +} + +int MasteredMediaFileInfo::filesCount() const +{ + Q_D(const DAbstractFileInfo); + + if (!d->proxy) + return 0; + + return d->proxy->filesCount(); +} + +QString MasteredMediaFileInfo::fileDisplayName() const +{ + Q_D(const DAbstractFileInfo); + + if (fileUrl().burnFilePath().contains(QRegularExpression("^(/*)$"))) { + const QStringList &nodes = DDiskManager::resolveDeviceNode(fileUrl().burnDestDevice(), {}); + if (nodes.isEmpty()) { + qWarning() << "can't get the node list from: " << fileUrl().path(); + return ""; + } + + QString udiskspath = nodes.first(); + QSharedPointer blkdev(DDiskManager::createBlockDevice(udiskspath)); + return blkdev->idLabel(); + } + + if (!d->proxy) + return ""; + return d->proxy->fileDisplayName(); +} + +QVariantHash MasteredMediaFileInfo::extraProperties() const +{ + Q_D(const DAbstractFileInfo); + + QVariantHash ret; + if (d->proxy) { + ret = d->proxy->extraProperties(); + } + ret["mm_backer"] = m_backerUrl.path(); + return ret; +} + +QVector MasteredMediaFileInfo::menuActionList(MenuType type) const +{ + QVector ret = DAbstractFileInfo::menuActionList(type); + ret.removeAll(MenuAction::TagInfo); + ret.removeAll(MenuAction::TagFilesUseColor); + ret.removeAll(MenuAction::Cut); + ret.removeAll(MenuAction::Rename); + ret.removeAll(MenuAction::NewFolder); + ret.removeAll(MenuAction::NewText); + ret.removeAll(MenuAction::NewWord); + ret.removeAll(MenuAction::NewExcel); + ret.removeAll(MenuAction::NewDocument); + ret.removeAll(MenuAction::NewPowerpoint); + ret.removeAll(MenuAction::DecompressHere); + if (!fileUrl().burnIsOnDisc() || !m_backerUrl.isValid() || m_backerUrl.isEmpty()) { + ret.removeAll(MenuAction::OpenInTerminal); + ret.removeAll(MenuAction::OpenAsAdmin); + ret.removeAll(MenuAction::Copy); + ret.removeAll(MenuAction::SendToRemovableDisk); + ret.removeAll(MenuAction::StageFileForBurning); + ret.removeAll(MenuAction::Compress); + ret.removeAll(MenuAction::CreateSymlink); + ret.removeAll(MenuAction::SendToDesktop); + ret.removeAll(MenuAction::AddToBookMark); + ret.removeAll(MenuAction::Share); + } + if (fileUrl().burnIsOnDisc()) { + ret.removeAll(MenuAction::Delete); + ret.removeAll(MenuAction::CompleteDeletion); + } + return ret; +} + +bool MasteredMediaFileInfo::canRedirectionFileUrl() const +{ + if (isDir()) + return isSymLink(); // fix bug 202007010021 当光驱刻录的文件夹中存在文件夹的链接时,要跳转到链接对应的目标文件夹 + return !isDir(); +} + +DUrl MasteredMediaFileInfo::redirectedFileUrl() const +{ + Q_D(const DAbstractFileInfo); + if (d->proxy) { + return d->proxy->fileUrl(); + } + + return DAbstractFileInfo::fileUrl(); +} + +DUrl MasteredMediaFileInfo::mimeDataUrl() const +{ + Q_D(const DAbstractFileInfo); + if (d->proxy) { + return d->proxy->mimeDataUrl(); + } + + return DAbstractFileInfo::mimeDataUrl(); +} + +bool MasteredMediaFileInfo::canIteratorDir() const +{ + return true; // fix 27116 光驱中使用搜索无效。通过这种方式,点击搜索结果中的文件夹将会跳转到文件的实际挂载目录,如果要回到刻录页面,需要点击返回或者侧边栏,点击顶部的面包屑导航也只能到挂载根目录 +// return !d->proxy; +} + +DUrl MasteredMediaFileInfo::parentUrl() const +{ + if (fileUrl().burnFilePath().contains(QRegularExpression("^(/*)$"))) { + return DUrl::fromLocalFile(QDir::homePath()); + } + return DAbstractFileInfo::parentUrl(); +} + +DUrl MasteredMediaFileInfo::goToUrlWhenDeleted() const +{ + const auto &fUrl = fileUrl(); + + QStringList rootDeviceNode = DDiskManager::resolveDeviceNode(fUrl.burnDestDevice(), {}); + if (rootDeviceNode.isEmpty() || this->m_backerUrl.isEmpty()) { + return DUrl(COMPUTER_ROOT); + } + + QString volTotag = getVolTag(rootDeviceNode.first()); + CdStatusInfo *pStatusInfo = DFMOpticalMediaWidget::getCdStatusInfo(volTotag); + + if (!fUrl.burnFilePath().isEmpty() && pStatusInfo != nullptr && !pStatusInfo->bReadyToBurn) { // 光盘路径是不能被删除的,有删除动作一般是弹出了,所以直接到homepath + return DUrl(COMPUTER_ROOT); + } + return DAbstractFileInfo::goToUrlWhenDeleted(); +} + +QString MasteredMediaFileInfo::toLocalFile() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->toLocalFile(); + + return ""; +} + +bool MasteredMediaFileInfo::canDrop() const +{ + return isWritable(); +} + +bool MasteredMediaFileInfo::canTag() const +{ + return false; +} + +bool MasteredMediaFileInfo::canRename() const +{ + return false; +} + +QSet MasteredMediaFileInfo::disableMenuActionList() const +{ + QSet list; + + if (!isWritable()) { + list << MenuAction::NewFolder + << MenuAction::NewDocument + << MenuAction::Paste; + } + + list << MenuAction::Cut << MenuAction::Rename;// << MenuAction::Delete; + + if (isVirtualEntry()) { + list << MenuAction::Copy; + } + + return list; +} + +void MasteredMediaFileInfo::refresh(const bool isForce) +{ + Q_UNUSED(isForce) + Q_D(const DAbstractFileInfo); + + DAbstractFileInfo::refresh(); + if (d->proxy) { + return; + } + + backupInfo(fileUrl()); +} + +bool MasteredMediaFileInfo::canDragCompress() const +{ + // 光盘不支持拖拽压缩 + return false; +} + +QString MasteredMediaFileInfo::subtitleForEmptyFloder() const +{ + return QObject::tr("Folder is empty"); +} + + +QString MasteredMediaFileInfo::getVolTag(const QString &burnPath) const +{ + QString strKey; + QStringList lst = burnPath.split("/", QString::SkipEmptyParts); // /dev/sr0 -> { dev, sr0 } + if (lst.count() >= 1) + strKey = lst[lst.count() - 1]; // strKey = + return strKey; +} + +void MasteredMediaFileInfo::backupInfo(const DUrl &url) +{ + if (url.burnDestDevice().length() == 0) { + return; + } + + QStringList rootDeviceNode = DDiskManager::resolveDeviceNode(url.burnDestDevice(), {}); + if (rootDeviceNode.isEmpty()) { + return; + } + QString udiskspath = rootDeviceNode.first(); + QSharedPointer blkdev(DDiskManager::createBlockDevice(udiskspath)); + QSharedPointer diskdev(DDiskManager::createDiskDevice(blkdev->drive())); + + if (url.burnIsOnDisc()) { + if (diskdev->opticalBlank()) { + //blank media contains no files on disc, duh! + return; + } + + auto points = blkdev->mountPoints(); + if (!points.isEmpty()) { + QString mntpoint = QString(points.front()); + while (*mntpoint.rbegin() == '/') { + mntpoint.chop(1); + } + + m_backerUrl = DUrl::fromLocalFile(mntpoint + url.burnFilePath()); + } else m_backerUrl = DUrl(); + } else { + m_backerUrl = MasteredMediaController::getStagingFile(url); + } + setProxy(DFileService::instance()->createFileInfo(Q_NULLPTR, m_backerUrl)); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/masteredmediafileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/masteredmediafileinfo.h new file mode 100644 index 0000000..5748ed4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/masteredmediafileinfo.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef MASTEREDMEDIAFILEINFO_H +#define MASTEREDMEDIAFILEINFO_H + +#include "dfileinfo.h" + +class MasteredMediaFileInfo : public DAbstractFileInfo +{ +public: + explicit MasteredMediaFileInfo(const DUrl &url); + + bool exists() const override; + bool isReadable() const override; + bool isWritable() const override; + bool isDir() const override; + + int filesCount() const override; + QString fileDisplayName() const override; + + QVariantHash extraProperties() const override; + QVector menuActionList(MenuType type) const override; + + bool canRedirectionFileUrl() const override; + DUrl redirectedFileUrl() const override; + DUrl mimeDataUrl() const override; + + bool canIteratorDir() const override; + DUrl parentUrl() const override; + DUrl goToUrlWhenDeleted() const override; + QString toLocalFile() const override; + + bool canDrop() const override; + bool canTag() const override; + bool canRename() const override; + QSet disableMenuActionList() const override; + void refresh(const bool isForce = false) override; + bool canDragCompress() const override; + + virtual QString subtitleForEmptyFloder() const override; + +private: + QString getVolTag(const QString &burnPath) const; + + void backupInfo(const DUrl &url); + +private: + DUrl m_backerUrl; +}; + +#endif // MASTEREDMEDIAFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/mergeddesktopfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/mergeddesktopfileinfo.cpp new file mode 100644 index 0000000..776a046 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/mergeddesktopfileinfo.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "mergeddesktopfileinfo.h" +#include "virtualentryinfo.h" +#include "controllers/mergeddesktopcontroller.h" +#include "dfileservices.h" + +#include "private/dabstractfileinfo_p.h" +#include "private/mergeddesktop_common_p.h" + +#include +#include + + +VirtualEntryInfo::VirtualEntryInfo(const DUrl &url) : DAbstractFileInfo(url) {} + +QString VirtualEntryInfo::iconName() const +{ + switch (MergedDesktopController::entryTypeByName(fileName())) { + case DMD_APPLICATION: + return QStringLiteral("folder-applications-stack"); + case DMD_DOCUMENT: + return QStringLiteral("folder-documents-stack"); + case DMD_MUSIC: + return QStringLiteral("folder-music-stack"); + case DMD_PICTURE: + return QStringLiteral("folder-images-stack"); + case DMD_VIDEO: + return QStringLiteral("folder-video-stack"); + case DMD_OTHER: + return QStringLiteral("folder-stack"); + default: + qWarning() << "VirtualEntryInfo::iconName() no matched branch (it can be a bug!)"; + qWarning() << "Url: " << fileUrl(); + } + return QStringLiteral("folder-stack"); +} + +bool VirtualEntryInfo::exists() const +{ + return true; +} + +bool VirtualEntryInfo::isDir() const +{ + return true; +} + +bool VirtualEntryInfo::isVirtualEntry() const +{ + return true; +} + +bool VirtualEntryInfo::canShare() const +{ + return false; +} + +bool VirtualEntryInfo::isReadable() const +{ + return true; +} + +bool VirtualEntryInfo::isWritable() const +{ + return true; +} + +QString VirtualEntryInfo::fileName() const +{ + QString path = fileUrl().path(); + + if (path.startsWith(VIRTUALENTRY_PATH)) { + if (path != VIRTUALENTRY_PATH) { + return DAbstractFileInfo::fileName(); + } else { + return "Entry"; + } + } else if (path.startsWith(VIRTUALFOLDER_PATH)) { + if (path != VIRTUALFOLDER_PATH) { + return DAbstractFileInfo::fileName(); + } else { + return "Folder"; + } + } else if (path.startsWith(MERGEDDESKTOP_PATH)) { + return "Merged Desktop"; + } + + return DAbstractFileInfo::fileName() + "(?)"; +} + +Qt::ItemFlags VirtualEntryInfo::fileItemDisableFlags() const +{ + return Qt::ItemIsDragEnabled; +} + +DAbstractFileInfo::CompareFunction VirtualEntryInfo::compareFunByColumn(int) const +{ + return nullptr; +} + +class MergedDesktopFileInfoPrivate : public DAbstractFileInfoPrivate +{ +public: + MergedDesktopFileInfoPrivate(const DUrl &url, MergedDesktopFileInfo *qq) + : DAbstractFileInfoPrivate(url, qq, true) {} + + DUrl m_parentUrl; +}; + +MergedDesktopFileInfo::MergedDesktopFileInfo(const DUrl &url, const DUrl &parentUrl) + : DAbstractFileInfo(*new MergedDesktopFileInfoPrivate(url, this)) +{ + Q_D(MergedDesktopFileInfo); + d->m_parentUrl = parentUrl; + + QString path = url.path(); + QString fileName = url.fileName(); + QString desktopPath = QStandardPaths::standardLocations(QStandardPaths::DesktopLocation).first(); + QString realPath = desktopPath + QDir::separator() + fileName; + + if (path.startsWith(VIRTUALENTRY_PATH)) { + if (path.split('/', QString::SkipEmptyParts).count() != 2) { + setProxy(DAbstractFileInfoPointer(DFileService::instance()->createFileInfo(nullptr, DUrl::fromLocalFile(realPath)))); + } else { + setProxy(DAbstractFileInfoPointer(new VirtualEntryInfo(url))); + } + } else if (path.startsWith(VIRTUALFOLDER_PATH)) { + if (path != VIRTUALFOLDER_PATH) { + setProxy(DAbstractFileInfoPointer(DFileService::instance()->createFileInfo(nullptr, DUrl::fromLocalFile(realPath)))); + } else { + setProxy(DAbstractFileInfoPointer(new VirtualEntryInfo(url))); + } + } else if (path.startsWith(MERGEDDESKTOP_PATH)) { + if (path == MERGEDDESKTOP_PATH) { + setProxy(DAbstractFileInfoPointer(DFileService::instance()->createFileInfo(nullptr, DUrl::fromLocalFile(desktopPath)))); + } else { + setProxy(DAbstractFileInfoPointer(new VirtualEntryInfo(url))); + } + } +} + +DUrl MergedDesktopFileInfo::parentUrl() const +{ + Q_D(const MergedDesktopFileInfo); + return d->m_parentUrl; +} + +QString MergedDesktopFileInfo::iconName() const +{ + Q_D(const MergedDesktopFileInfo); + if (d->proxy) { + return d->proxy->iconName(); + } + + return DAbstractFileInfo::iconName(); +} + +QString MergedDesktopFileInfo::genericIconName() const +{ + Q_D(const MergedDesktopFileInfo); + if (d->proxy) { + return d->proxy->genericIconName(); + } + + return DAbstractFileInfo::genericIconName(); +} + +DUrl MergedDesktopFileInfo::mimeDataUrl() const +{ + Q_D(const MergedDesktopFileInfo); + if (d->proxy) { + return d->proxy->mimeDataUrl(); + } + + return DAbstractFileInfo::mimeDataUrl(); +} + +bool MergedDesktopFileInfo::canRedirectionFileUrl() const +{ + Q_D(const MergedDesktopFileInfo); + if (d->proxy) { + return true; + } + + return DAbstractFileInfo::canRedirectionFileUrl(); +} + +DUrl MergedDesktopFileInfo::redirectedFileUrl() const +{ + Q_D(const MergedDesktopFileInfo); + if (d->proxy) { + return d->proxy->fileUrl(); + } + + return DAbstractFileInfo::redirectedFileUrl(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/mergeddesktopfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/mergeddesktopfileinfo.h new file mode 100644 index 0000000..af11611 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/mergeddesktopfileinfo.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef MERGEDDESKTOPFILEINFO_H +#define MERGEDDESKTOPFILEINFO_H + +#include "dabstractfileinfo.h" + +class MergedDesktopFileInfoPrivate; +class MergedDesktopFileInfo : public DAbstractFileInfo +{ +public: + MergedDesktopFileInfo(const DUrl &url, const DUrl &parentUrl); + + DUrl parentUrl() const override; + QString iconName() const override; + QString genericIconName() const override; + + DUrl mimeDataUrl() const override; + + bool canRedirectionFileUrl() const override; + DUrl redirectedFileUrl() const override; + +private: + Q_DECLARE_PRIVATE(MergedDesktopFileInfo) +}; + +#endif // MERGEDDESKTOPFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/mountfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/mountfileinfo.cpp new file mode 100644 index 0000000..60e657d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/mountfileinfo.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "mountfileinfo.h" + + +MountFileInfo::MountFileInfo(const DUrl &url) + : DAbstractFileInfo(url) +{ + +} + +MountFileInfo::~MountFileInfo() +{ + +} + +bool MountFileInfo::canFetch() const +{ + return true; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/mountfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/mountfileinfo.h new file mode 100644 index 0000000..3ffff67 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/mountfileinfo.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef MOUNTFILEINFO_H +#define MOUNTFILEINFO_H + +#include "dfileinfo.h" + +class MountFileInfo : public DAbstractFileInfo +{ +public: + explicit MountFileInfo(const DUrl &url); + ~MountFileInfo(); + + bool canFetch() const override; +}; + +#endif // MOUNTFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/networkfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/networkfileinfo.cpp new file mode 100644 index 0000000..e461d56 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/networkfileinfo.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "networkfileinfo.h" + +#include "app/define.h" + +#include "singleton.h" + +#include "controllers/pathmanager.h" + +#include "views/dfileview.h" + +#include + +NetworkFileInfo::NetworkFileInfo(const DUrl &url): + DAbstractFileInfo(url) +{ + +} + +NetworkFileInfo::~NetworkFileInfo() +{ + +} + +QString NetworkFileInfo::filePath() const +{ + return m_networkNode.url(); +} + +QString NetworkFileInfo::absoluteFilePath() const +{ + return m_networkNode.url(); +} + +bool NetworkFileInfo::exists() const +{ + return true; +} + +bool NetworkFileInfo::isReadable() const +{ + return true; +} + +bool NetworkFileInfo::isWritable() const +{ + return true; +} + +bool NetworkFileInfo::isVirtualEntry() const +{ + if (fileUrl() == DUrl(SMB_ROOT) || fileUrl() == DUrl(NETWORK_ROOT)) + return true; + + return DAbstractFileInfo::isVirtualEntry(); +} + +bool NetworkFileInfo::canDrop() const +{ + if (fileUrl() == DUrl(SMB_ROOT) || fileUrl() == DUrl(NETWORK_ROOT)) + return false; + + return DAbstractFileInfo::canDrop(); +} + +bool NetworkFileInfo::canRename() const +{ + return false; +} + +bool NetworkFileInfo::canIteratorDir() const +{ +// return fileUrl() == DUrl(NETWORK_ROOT); + return false; +} + +//QIcon NetworkFileInfo::fileIcon() const +//{ +// return QIcon(fileIconProvider->getThemeIconPath(mimeTypeName(), 256)); +//} + +bool NetworkFileInfo::isDir() const +{ + return true; +} + +DUrl NetworkFileInfo::parentUrl() const +{ + return DUrl(); +} + +QString NetworkFileInfo::fileDisplayName() const +{ + + if (systemPathManager->isSystemPath(fileUrl().toString())) + return systemPathManager->getSystemPathDisplayNameByPath(fileUrl().toString()); + + return m_networkNode.displayName(); +} + +//QString NetworkFileInfo::mimeTypeName(QMimeDatabase::MatchMode mode) const +//{ +// Q_UNUSED(mode) + +// return m_networkNode.iconType(); +//} +NetworkNode NetworkFileInfo::networkNode() const +{ + return m_networkNode; +} + +void NetworkFileInfo::setNetworkNode(const NetworkNode &networkNode) +{ + m_networkNode = networkNode; +} + +QVector NetworkFileInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + QVector actionKeys; + if(type == SpaceArea) { + + } else if (type == SingleFile){ + actionKeys << MenuAction::Open; + actionKeys << MenuAction::OpenInNewWindow; + }else if (type == MultiFiles){ + + } + return actionKeys; +} + +QList NetworkFileInfo::supportSelectionModes() const +{ + return QList() << SingleSelection; +} + +Qt::ItemFlags NetworkFileInfo::fileItemDisableFlags() const +{ + return Qt::ItemIsDragEnabled | Qt::ItemIsEditable; +} + +quint8 NetworkFileInfo::supportViewMode() const +{ + return DFileView::IconMode; +} + +int NetworkFileInfo::filesCount() const +{ + return -1; +} + +QString NetworkFileInfo::iconName() const +{ + return m_networkNode.iconType(); +} + +bool NetworkFileInfo::canRedirectionFileUrl() const +{ + if (!mountPoint.isEmpty()) { + return true; + } + + const DUrl &url = fileUrl(); + + if (url.isNetWorkFile()) { + return false; + } + + // for samba file + GFile *gio_file = g_file_new_for_uri(QFile::encodeName(url.toString())); + + if (!gio_file) + return false; + + char *local_path = g_file_get_path(gio_file); + + mountPoint = QFile::decodeName(local_path); + + g_free(local_path); + g_object_unref(gio_file); + + return !mountPoint.isEmpty(); +} + +DUrl NetworkFileInfo::redirectedFileUrl() const +{ + if (mountPoint.isEmpty()) + return DUrl(); + + return DUrl::fromLocalFile(mountPoint); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/networkfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/networkfileinfo.h new file mode 100644 index 0000000..89fd92f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/networkfileinfo.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef NETWORKFILEINFO_H +#define NETWORKFILEINFO_H + + +#include "dfileinfo.h" +#include "gvfs/networkmanager.h" + + +class NetworkFileInfo: public DAbstractFileInfo +{ +public: + explicit NetworkFileInfo(const DUrl &url); + ~NetworkFileInfo() override; + + QString filePath() const override; + QString absoluteFilePath() const override; + bool exists() const override; + + bool isReadable() const override; + bool isWritable() const override; + bool isVirtualEntry() const override; + virtual bool canDrop() const override; + + bool canRename() const override; + bool canIteratorDir() const override; +// QIcon fileIcon() const override; + bool isDir() const override; + DUrl parentUrl() const override; + QString fileDisplayName() const override; + +// QString mimeTypeName(DMimeDatabase::MatchMode mode = QMimeDatabase::MatchDefault) const override; + + NetworkNode networkNode() const; + void setNetworkNode(const NetworkNode &networkNode); + + QVector menuActionList(MenuType type) const override; + + QList supportSelectionModes() const override; + Qt::ItemFlags fileItemDisableFlags() const override; + + quint8 supportViewMode() const override; + + int filesCount() const override; + + QString iconName() const override; + + bool canRedirectionFileUrl() const override; + DUrl redirectedFileUrl() const override; + +private: + NetworkNode m_networkNode; + mutable QString mountPoint; +}; + +#endif // NETWORKFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/recentfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/recentfileinfo.cpp new file mode 100644 index 0000000..3c56b86 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/recentfileinfo.cpp @@ -0,0 +1,349 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "recentfileinfo.h" +#include "dfileservices.h" +#include "dfilesystemmodel.h" +#include "private/dabstractfileinfo_p.h" +#include "app/define.h" +#include "singleton.h" +#include "controllers/pathmanager.h" +#include "shutil/mimetypedisplaymanager.h" +#include +#include + +namespace FileSortFunction +{ +COMPARE_FUN_DEFINE(readDateTime, LastReadTime, RecentFileInfo) +COMPARE_FUN_DEFINE(toLocalFile, RecentFilePath, RecentFileInfo) +} + +RecentFileInfo::RecentFileInfo(const DUrl &url) + : DAbstractFileInfo(url) +{ + QMutexLocker lk(&m_mutex); + if (url.path() != "/") { + setProxy(DFileService::instance()->createFileInfo(nullptr, DUrl::fromLocalFile(url.path()))); + } + updateInfo(); + checkMountFile(); +} + +RecentFileInfo::~RecentFileInfo() +{ + QMutexLocker lk(&m_mutex); +} + +bool RecentFileInfo::makeAbsolute() +{ + return true; +} + +bool RecentFileInfo::exists() const +{ + if (fileUrl() == DUrl(RECENT_ROOT)) + return true; + + return DAbstractFileInfo::exists(); +} + +bool RecentFileInfo::isDir() const +{ + return fileUrl() == DUrl(RECENT_ROOT); +} + +bool RecentFileInfo::isReadable() const +{ + return permissions().testFlag(QFile::Permission::ReadUser); +} + +bool RecentFileInfo::isWritable() const +{ + if (isGvfsMountFile()) { + if (m_isWriteAble == -1) + const_cast(this)->m_isWriteAble = + permissions().testFlag(QFile::Permission::WriteUser); + return m_isWriteAble > 0; + } + return permissions().testFlag(QFile::Permission::WriteUser); +} + +bool RecentFileInfo::canIteratorDir() const +{ + return true; +} + +bool RecentFileInfo::canDrop() const +{ + return false; +} + +bool RecentFileInfo::canRedirectionFileUrl() const +{ + return d_ptr->proxy; +} + +bool RecentFileInfo::canRename() const +{ + return false; +} + +DUrl RecentFileInfo::redirectedFileUrl() const +{ + return d_ptr->proxy ? d_ptr->proxy->fileUrl() : fileUrl(); +} + +DUrl RecentFileInfo::getUrlByNewFileName(const QString &fileName) const +{ + Q_D(const DAbstractFileInfo); + + return d->proxy ? d->proxy->getUrlByNewFileName(fileName) : + DAbstractFileInfo::getUrlByNewFileName(fileName); +} + +QFileDevice::Permissions RecentFileInfo::permissions() const +{ + if (fileUrl() == DUrl(RECENT_ROOT)) { + return QFileDevice::ReadGroup | QFileDevice::ReadOwner | QFileDevice::ReadOther; + } + + QFileDevice::Permissions p = DAbstractFileInfo::permissions(); + + return p; +} + +QVector RecentFileInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + Q_D(const DAbstractFileInfo); + + QVector actions; + + if (type == SpaceArea) { + actions << MenuAction::DisplayAs; + actions << MenuAction::SortBy; + actions << MenuAction::SelectAll; + + return actions; + } + + actions = d->proxy->menuActionList(type); + + qDebug() << actions; + + actions.insert(1, MenuAction::OpenFileLocation); + int indexOfDeleteMenuAction = actions.indexOf(MenuAction::Delete); + if (indexOfDeleteMenuAction == -1) { + int indexOfCompleteDelectionMenuAction = actions.indexOf(MenuAction::CompleteDeletion); + if (indexOfCompleteDelectionMenuAction != -1) { + actions.insert(indexOfCompleteDelectionMenuAction, MenuAction::RemoveFromRecent); + } + } else { + actions.insert(indexOfDeleteMenuAction, MenuAction::RemoveFromRecent); + } + actions.removeOne(MenuAction::Cut); + actions.removeOne(MenuAction::Rename); + actions.removeOne(MenuAction::Delete); + actions.removeOne(MenuAction::CompleteDeletion); + actions.removeOne(MenuAction::DecompressHere); + actions.removeOne(MenuAction::StageFileForBurning); + + return actions; +} + +QSet RecentFileInfo::disableMenuActionList() const +{ + Q_D(const DAbstractFileInfo); + + if (fileUrl() == DUrl(RECENT_ROOT)) + return {}; + + return d->proxy->disableMenuActionList(); +} + +QList RecentFileInfo::userColumnRoles() const +{ + static QList userColumnRoles = QList() << DFileSystemModel::FileDisplayNameRole + << DFileSystemModel::FileUserRole + 1 + << DFileSystemModel::FileLastReadRole + << DFileSystemModel::FileSizeRole + << DFileSystemModel::FileMimeTypeRole; + + return userColumnRoles; +} + +QVariant RecentFileInfo::userColumnData(int userColumnRole) const +{ + if (userColumnRole == DFileSystemModel::FileLastReadRole) { + return m_lastReadTimeStr; + } + + if (userColumnRole == DFileSystemModel::FileUserRole + 1) { + return toLocalFile(); + } + + return DAbstractFileInfo::userColumnData(userColumnRole); +} + + +QVariant RecentFileInfo::userColumnDisplayName(int userColumnRole) const +{ + if (userColumnRole == DFileSystemModel::FileUserRole + 1){ + return qApp->translate("DFileSystemModel", "Path"); + } + + return DAbstractFileInfo::userColumnDisplayName(userColumnRole); +} + +MenuAction RecentFileInfo::menuActionByColumnRole(int userColumnRole) const +{ + if (userColumnRole == DFileSystemModel::FileUserRole + 1) { + return MenuAction::AbsolutePath; + } + + return DAbstractFileInfo::menuActionByColumnRole(userColumnRole); +} + + +int RecentFileInfo::userColumnWidth(int userColumnRole, const QFontMetrics &fontMetrics) const +{ + if (userColumnRole == DFileSystemModel::FileNameRole) + return -1; + + return DAbstractFileInfo::userColumnWidth(userColumnRole, fontMetrics); +} + +DUrl RecentFileInfo::mimeDataUrl() const +{ + return fileUrl(); +} + +DUrl RecentFileInfo::parentUrl() const +{ + return DUrl(RECENT_ROOT); +} + +DAbstractFileInfo::CompareFunction RecentFileInfo::compareFunByColumn(int columnRole) const +{ + // see RecentFileInfo::userColumnRoles for role function + if (columnRole == DFileSystemModel::FileLastReadRole) { + return FileSortFunction::compareFileListByLastReadTime; + } else if (columnRole == DFileSystemModel::FileUserRole + 1) { + return FileSortFunction::compareFileListByRecentFilePath; + } else { + return DAbstractFileInfo::compareFunByColumn(columnRole); + } +} + +QString RecentFileInfo::toLocalFile() const +{ + return fileUrl().path(); +} + +QString RecentFileInfo::subtitleForEmptyFloder() const +{ + return QObject::tr("Folder is empty"); +} + +DUrl RecentFileInfo::goToUrlWhenDeleted() const +{ + return DUrl::fromLocalFile(QDir::homePath()); +} + +QString RecentFileInfo::fileDisplayName() const +{ + Q_D(const DAbstractFileInfo); + + if (fileUrl() == DUrl(RECENT_ROOT)) + return systemPathManager->getSystemPathDisplayName("Recent"); + + return d->proxy->fileDisplayName(); +} + +QString RecentFileInfo::mimeTypeDisplayName() const +{ + Q_D(const DAbstractFileInfo); + + if (fileUrl() == DUrl(RECENT_ROOT)) + return mimeTypeDisplayManager->displayName(""); + + return d->proxy->mimeTypeDisplayName(); +} + +bool RecentFileInfo::isVirtualEntry() const +{ + Q_D(const DAbstractFileInfo); + + if (fileUrl() == DUrl(RECENT_ROOT)) + return true; + + return d->proxy->isVirtualEntry(); +} + +const QDateTime RecentFileInfo::getReadTime() const +{ + return m_lastReadTime; +} + +void RecentFileInfo::updateReadTime(const QDateTime &date) +{ + setReadDateTime(date.toString(Qt::ISODate)); +} + +void RecentFileInfo::updateInfo() +{ + QFile file(QDir::homePath() + "/.local/share/recently-used.xbel"); + + if (file.open(QIODevice::ReadOnly)) { + QXmlStreamReader reader(&file); + + while (!reader.atEnd()) { + if (!reader.readNextStartElement() || + reader.name() != "bookmark") { + continue; + } + + const QStringRef &location = reader.attributes().value("href"); + const QStringRef &dateTime = reader.attributes().value("modified"); + + if (!location.isEmpty()) { + DUrl findUrl = DUrl(location.toString()); + + if (findUrl.toLocalFile() == fileUrl().path()) { + setReadDateTime(dateTime.toString()); + break; + } + } + } + } +} + +void RecentFileInfo::setReadDateTime(const QString &time) +{ + m_lastReadTime = QDateTime::fromString(time, Qt::ISODate).toLocalTime(); + m_lastReadTimeStr = m_lastReadTime.toString(dateTimeFormat()); +} + +QDateTime RecentFileInfo::readDateTime() const +{ + return m_lastReadTime; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/recentfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/recentfileinfo.h new file mode 100644 index 0000000..3e66bef --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/recentfileinfo.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef RECENTFILEINFO_H +#define RECENTFILEINFO_H + +#include "dabstractfileinfo.h" +#include + +class RecentFileInfo; +typedef QExplicitlySharedDataPointer RecentPointer; + +class RecentFileInfo : public DAbstractFileInfo +{ +public: + explicit RecentFileInfo(const DUrl &url); + ~RecentFileInfo() override; + + bool makeAbsolute() override; + bool exists() const override; + bool isDir() const override; + bool isReadable() const override; + bool isWritable() const override; + bool canIteratorDir() const override; + bool canDrop() const override; + bool canRedirectionFileUrl() const override; + bool canRename() const override; + DUrl redirectedFileUrl() const override; + DUrl getUrlByNewFileName(const QString &fileName) const override; + + QFileDevice::Permissions permissions() const override; + QVector menuActionList(MenuType type) const override; + QSet disableMenuActionList() const override; + QList userColumnRoles() const override; + QVariant userColumnData(int userColumnRole) const override; + QVariant userColumnDisplayName(int userColumnRole) const override; + MenuAction menuActionByColumnRole(int userColumnRole) const override; + int userColumnWidth(int userColumnRole, const QFontMetrics &fontMetrics) const override; + DUrl mimeDataUrl() const override; + DUrl parentUrl() const override; + + CompareFunction compareFunByColumn(int columnRole) const override; + + QString toLocalFile() const override; + QString subtitleForEmptyFloder() const override; + DUrl goToUrlWhenDeleted() const override; + virtual QString fileDisplayName() const override; + virtual QString mimeTypeDisplayName() const override; + virtual bool isVirtualEntry() const override; + //获取最近访问时间 + virtual const QDateTime getReadTime() const override; + //更新最近访问时间 + virtual void updateReadTime(const QDateTime &) override; + + void updateInfo(); + void setReadDateTime(const QString &time); + QDateTime readDateTime() const; + +private: + QDateTime m_lastReadTime; + QString m_lastReadTimeStr; + QMutex m_mutex; + qint8 m_isWriteAble = -1; +}; + +#endif // RECENTFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/searchfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/searchfileinfo.cpp new file mode 100644 index 0000000..425e994 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/searchfileinfo.cpp @@ -0,0 +1,410 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "searchfileinfo.h" +#include "private/dabstractfileinfo_p.h" +#include "views/dfileview.h" + +#include "dfileservices.h" + +#include "dfilesystemmodel.h" + +#include "app/define.h" + +#include +#include +#include + +namespace FileSortFunction { +COMPARE_FUN_DEFINE(absoluteFilePath, FilePath, SearchFileInfo) +} + +SearchFileInfo::SearchFileInfo(const DUrl &url) + : DAbstractFileInfo(url) +{ + d_func()->columnCompact = false; + + if (url.searchedFileUrl().isValid()) { + m_parentUrl = url; + m_parentUrl.setSearchedFileUrl(DUrl()); + + setProxy(DFileService::instance()->createFileInfo(Q_NULLPTR, url.searchedFileUrl())); + } +} + +bool SearchFileInfo::exists() const +{ + Q_D(const DAbstractFileInfo); + + return !d->proxy || d->proxy->exists(); +} + +bool SearchFileInfo::isReadable() const +{ + Q_D(const DAbstractFileInfo); + + if (!d->proxy) + return true; + + return d->proxy->isReadable(); +} + +bool SearchFileInfo::isDir() const +{ + Q_D(const DAbstractFileInfo); + + if (!d->proxy) + return true; + + return d->proxy->isDir(); +} + +bool SearchFileInfo::isVirtualEntry() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->isVirtualEntry(); + + return true; +} + +int SearchFileInfo::filesCount() const +{ + Q_D(const DAbstractFileInfo); + + if (!d->proxy) + return 0; + + return d->proxy->filesCount(); +} + +DUrl SearchFileInfo::parentUrl() const +{ + return m_parentUrl; +} + +void SearchFileInfo::setColumnCompact(bool) +{ + +} + +QList SearchFileInfo::userColumnRoles() const +{ + static QList userColumnRoles = QList() << DFileSystemModel::FileDisplayNameRole +// << DFileSystemModel::FileUserRole + 1 +// << DFileSystemModel::FileUserRole + 2 + << DFileSystemModel::FilePathRole + << DFileSystemModel::FileLastModifiedRole + << DFileSystemModel::FileSizeRole + << DFileSystemModel::FileMimeTypeRole; + + return userColumnRoles; +} + +QVariant SearchFileInfo::userColumnDisplayName(int userColumnRole) const +{ + if (userColumnRole == DFileSystemModel::FileUserRole + 1) + return qApp->translate("DFileSystemModel", "Path"); + if (userColumnRole == DFileSystemModel::FileUserRole + 2) + return qApp->translate("DFileSystemModel", "Time modified"); + + if (userColumnRole == DFileSystemModel::FilePathRole) { + return qApp->translate("DFileSystemModel", "Path"); + } + + return DAbstractFileInfo::userColumnDisplayName(userColumnRole); +} + +QVariant SearchFileInfo::userColumnData(int userColumnRole) const +{ + Q_D(const DAbstractFileInfo); + + if (userColumnRole == DFileSystemModel::FileUserRole + 2) { + return QVariant::fromValue(qMakePair(lastModifiedDisplayName(), qMakePair(sizeDisplayName(), mimeTypeDisplayName()))); + } else if (userColumnRole == DFileSystemModel::FilePathRole) { + QString file_path; + + const DUrl &fileUrl = d->proxy->fileUrl(); + + if (fileUrl.isLocalFile()) { + file_path = absolutePath(); + } else { + file_path = d->proxy->parentUrl().toString(); + } + + return file_path; +// return QVariant::fromValue(QPair(fileDisplayName(), file_path)); + } + + return DAbstractFileInfo::userColumnData(userColumnRole); +} + +QList SearchFileInfo::userColumnChildRoles(int column) const +{ + Q_UNUSED(column) + + QList userColumnRoles{}; +// if (column == 0){ +// userColumnRoles << DFileSystemModel::FileDisplayNameRole +// << DFileSystemModel::FilePathRole; +// }else if (column == 1){ +// userColumnRoles << DFileSystemModel::FileLastModifiedRole +// << DFileSystemModel::FileSizeRole +// << DFileSystemModel::FileMimeTypeRole; +// } + return userColumnRoles; +} + +bool SearchFileInfo::columnDefaultVisibleForRole(int role) const +{ + Q_UNUSED(role) + + return true; +// return (role == DFileSystemModel::FileUserRole + 1 || role == DFileSystemModel::FileUserRole + 2); +} + +int SearchFileInfo::userColumnWidth(int userColumnRole, const QFontMetrics &fontMetrics) const +{ + if (userColumnRole == DFileSystemModel::FileUserRole + 1) + return -1; + + return fontMetrics.width("0000/00/00 00:00:00");; +} + +//int SearchFileInfo::userRowHeight(const QFontMetrics &fontMetrics) const +//{ +// return fontMetrics.height() * 2 + 10; +//} + +MenuAction SearchFileInfo::menuActionByColumnRole(int userColumnRole) const +{ + if (userColumnRole == DFileSystemModel::FilePathRole) { + return MenuAction::AbsolutePath; + } + return DAbstractFileInfo::menuActionByColumnRole(userColumnRole); +} + +QList SearchFileInfo::sortSubMenuActionUserColumnRoles() const +{ + QList roles; + roles << DFileSystemModel::FileDisplayNameRole + << DFileSystemModel::FilePathRole + << DFileSystemModel::FileLastModifiedRole + << DFileSystemModel::FileSizeRole + << DFileSystemModel::FileMimeTypeRole; + return roles; +} + +bool SearchFileInfo::canRedirectionFileUrl() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return true; + + const DAbstractFileInfoPointer &targetFileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, fileUrl().searchTargetUrl()); + + return targetFileInfo && !targetFileInfo->canIteratorDir(); +} + +DUrl SearchFileInfo::redirectedFileUrl() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->redirectedFileUrl(); + + return fileUrl().searchTargetUrl(); +} + +bool SearchFileInfo::canIteratorDir() const +{ + Q_D(const DAbstractFileInfo); + + return !d->proxy; +} + +QVector SearchFileInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + Q_D(const DAbstractFileInfo); + + QVector actions; + + if (!d->proxy && type == SpaceArea) { + actions << MenuAction::DisplayAs; + actions << MenuAction::SortBy; + actions << MenuAction::SelectAll; + + return actions; + } + + actions = d->proxy->menuActionList(type); + actions.insert(1, MenuAction::OpenFileLocation); + + return actions; +} + +QSet SearchFileInfo::disableMenuActionList() const +{ + Q_D(const DAbstractFileInfo); + + if (!d->proxy) + return QSet(); + + QSet actions = d->proxy->disableMenuActionList(); + + actions << MenuAction::DecompressHere; + + if (path().isEmpty()) + actions << MenuAction::Property << MenuAction::OpenInTerminal; + + return actions; +} + +bool SearchFileInfo::isEmptyFloder(const QDir::Filters &filters) const +{ + if (path().isEmpty()) + return false; + + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, fileUrl().searchedFileUrl()); + + return fileInfo && fileInfo->isEmptyFloder(filters); +} + +DAbstractFileInfo::CompareFunction SearchFileInfo::compareFunByColumn(int columnRole) const +{ + if (columnRole == DFileSystemModel::FilePathRole) + return FileSortFunction::compareFileListByFilePath; + + return DAbstractFileInfo::compareFunByColumn(columnRole); +} + +bool SearchFileInfo::hasOrderly() const +{ + return false; +} + +DUrl SearchFileInfo::getUrlByNewFileName(const QString &fileName) const +{ + Q_D(const DAbstractFileInfo); + + DUrl url = fileUrl(); + + if (d->proxy) + url.setSearchedFileUrl(d->proxy->getUrlByNewFileName(fileName)); + + return url; +} + +QString SearchFileInfo::loadingTip() const +{ + return QObject::tr("Searching..."); +} + +QString SearchFileInfo::subtitleForEmptyFloder() const +{ + return QObject::tr("No results"); +} + +QString SearchFileInfo::fileDisplayName() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->fileDisplayName(); + + if (fileUrl().isSearchFile()) { + return qApp->translate("Shortcut", "Search"); + } + + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, fileUrl().searchTargetUrl()); + + if (fileInfo) + return fileInfo->fileDisplayName(); + + return QString(); +} + +DUrl SearchFileInfo::mimeDataUrl() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->mimeDataUrl(); + + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(Q_NULLPTR, fileUrl().searchedFileUrl()); + + if (info) + return info->mimeDataUrl(); + + return fileUrl().searchedFileUrl(); +} + +QString SearchFileInfo::toLocalFile() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->toLocalFile(); + + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(Q_NULLPTR, fileUrl().searchedFileUrl()); + + if (info) + return info->toLocalFile(); + + return fileUrl().searchedFileUrl().toLocalFile(); +} + +QIcon SearchFileInfo::fileIcon() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->fileIcon(); + + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(Q_NULLPTR, fileUrl().searchedFileUrl()); + + if (info) + return info->fileIcon(); + + + return QIcon::fromTheme("search"); +} + +bool SearchFileInfo::canRename() const +{ + Q_D(const DAbstractFileInfo); + if (d->proxy) + return d->proxy->canRename(); + return DAbstractFileInfo::canRename(); +} + +bool SearchFileInfo::canDrop() const +{ + Q_D(const DAbstractFileInfo); + //tag的虚拟目录不能drop + if (d->proxy && d->proxy->fileUrl().isTaggedFile() && isVirtualEntry()) + return false; + return DAbstractFileInfo::canDrop(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/searchfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/searchfileinfo.h new file mode 100644 index 0000000..e442336 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/searchfileinfo.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef SEARCHFILEINFO_H +#define SEARCHFILEINFO_H + +#include "dfileinfo.h" + +class SearchFileInfo : public DAbstractFileInfo +{ +public: + explicit SearchFileInfo(const DUrl &url); + + bool exists() const override; + bool isReadable() const override; + bool isDir() const override; + virtual bool isVirtualEntry() const override; + + int filesCount() const override; + + DUrl parentUrl() const override; + + void setColumnCompact(bool) override; + QList userColumnRoles() const override; + QVariant userColumnDisplayName(int userColumnRole) const override; + /// get custom column data + QVariant userColumnData(int userColumnRole) const override; + QList userColumnChildRoles(int column) const override; + bool columnDefaultVisibleForRole(int role) const override; + + bool canRedirectionFileUrl() const override; + DUrl redirectedFileUrl() const override; + + bool canIteratorDir() const override; + + QVector menuActionList(MenuType type = SingleFile) const override; + QSet disableMenuActionList() const override; + int userColumnWidth(int userColumnRole, const QFontMetrics &fontMetrics) const override; +// int userRowHeight(const QFontMetrics &fontMetrics) const override; + + MenuAction menuActionByColumnRole(int userColumnRole) const override; + QList sortSubMenuActionUserColumnRoles() const override; + + bool isEmptyFloder(const QDir::Filters &filters = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::System) const override; + + CompareFunction compareFunByColumn(int columnRole) const override; + bool hasOrderly() const override; + + DUrl getUrlByNewFileName(const QString &fileName) const override; + + QString loadingTip() const override; + QString subtitleForEmptyFloder() const override; + + QString fileDisplayName() const override; + + DUrl mimeDataUrl() const override; + + QString toLocalFile() const override; + virtual QIcon fileIcon() const override; + virtual bool canDrop() const override; + + virtual bool canRename() const override; + +private: + DUrl m_parentUrl; + +}; + +#endif // SEARCHFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/searchhistory.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/searchhistory.cpp new file mode 100644 index 0000000..b149ba4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/searchhistory.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "searchhistory.h" + +SearchHistory::SearchHistory(QObject *parent) : DebugObejct(parent) +{ + +} + +SearchHistory::SearchHistory(QDateTime time, QString keyword, QObject *parent) + : DebugObejct(parent) + , m_time(time) + , m_keyword(keyword) +{ + +} + +QDateTime SearchHistory::getDateTime() +{ + return m_time; +} + +QString SearchHistory::getKeyword() +{ + return m_keyword; +} + +void SearchHistory::setDateTime(QDateTime time) +{ + m_time = time; +} + +void SearchHistory::setKeyword(QString keyword) +{ + m_keyword = keyword; +} + +SearchHistory::~SearchHistory() +{ + +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/searchhistory.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/searchhistory.h new file mode 100644 index 0000000..a0d927a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/searchhistory.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef SEARCHHISTORY_H +#define SEARCHHISTORY_H + +#include +#include +#include "debugobejct.h" + +class SearchHistory : public DebugObejct +{ + Q_OBJECT +public: + explicit SearchHistory(QObject *parent = 0); + SearchHistory(QDateTime time, QString keyword, QObject *parent = 0); + QDateTime getDateTime(); + QString getKeyword(); + void setDateTime(QDateTime time); + void setKeyword(QString keyword); + ~SearchHistory(); +private: + QDateTime m_time; + QString m_keyword; +signals: + +public slots: +}; + +#endif // SEARCHHISTORY_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/sharefileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/sharefileinfo.cpp new file mode 100644 index 0000000..c85576e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/sharefileinfo.cpp @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "sharefileinfo.h" +#include "private/dabstractfileinfo_p.h" +#include "usershare/usersharemanager.h" +#include "dfileservices.h" +#include "singleton.h" + +#include "controllers/trashmanager.h" +#include "dfileservices.h" +#include "controllers/pathmanager.h" +#include "controllers/bookmarkmanager.h" + +#include "app/define.h" +#include "interfaces/dfmstandardpaths.h" +#include "dfilesystemmodel.h" +#include "singleton.h" + +#include +#include + +ShareFileInfo::ShareFileInfo(const DUrl &url): + DAbstractFileInfo(url) +{ + if (url.path() != "/") + setProxy(DFileService::instance()->createFileInfo(Q_NULLPTR, DUrl::fromLocalFile(url.path()))); +} + +ShareFileInfo::~ShareFileInfo() +{ + +} + +bool ShareFileInfo::exists() const +{ + Q_D(const DAbstractFileInfo); + + return !d->proxy || d->proxy->exists(); +} + +bool ShareFileInfo::isDir() const +{ + Q_D(const DAbstractFileInfo); + + return !d->proxy || d->proxy->isDir(); +} + +bool ShareFileInfo::canRename() const +{ + return false; +} + +bool ShareFileInfo::isReadable() const +{ + return true; +} + +bool ShareFileInfo::isWritable() const +{ + return false; +} + +QString ShareFileInfo::fileDisplayName() const +{ + Q_D(const DAbstractFileInfo); + if (systemPathManager->isSystemPath(fileUrl().toString())) + return systemPathManager->getSystemPathDisplayNameByPath(fileUrl().toString()); + ShareInfo info = userShareManager->getShareInfoByPath(fileUrl().path()); + QString displayName = info.shareName(); + if (!displayName.isEmpty()) { + return displayName; + } else { + if (d->proxy) { + return d->proxy->fileDisplayName(); + } + } + return QString(""); +} + +//QFileDevice::Permissions ShareFileInfo::vpermissions() const +//{ +// QFileDevice::Permissions p = AbstractFileInfo::permissions(); + +// p &= ~QFileDevice::WriteOwner; +// p &= ~QFileDevice::WriteUser; +// p &= ~QFileDevice::WriteGroup; +// p &= ~QFileDevice::WriteOther; + +// return p; +//} + +QVector ShareFileInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + QVector actionKeys; + + if(type == SpaceArea) { + actionKeys << MenuAction::DisplayAs + << MenuAction::SortBy; + } else if (type == SingleFile){ + if(isDir()){ + bool useRemoveBookmarkAction = false; + DUrl schemeAlteredUrl = fileUrl(); + schemeAlteredUrl.setScheme(FILE_SCHEME); + // FIXME: reimplement BookMark::exist() 's behavior and use it for check bookmark existance. + // after doing this, don't forget to remove the "bookmarkmanager.h" header file include. + // if (DFileService::instance()->createFileInfo(nullptr, DUrl::fromBookMarkFile(fileUrl(), QString()))) { + if (Singleton::instance()->checkExist(DUrl::fromBookMarkFile(schemeAlteredUrl, QString()))) { + useRemoveBookmarkAction = true; + } + actionKeys << MenuAction::Open + << MenuAction::OpenInNewWindow + << MenuAction::OpenInNewTab + << MenuAction::Separator + << (useRemoveBookmarkAction ? MenuAction::BookmarkRemove : MenuAction::AddToBookMark) + << MenuAction::UnShare; + } + actionKeys << MenuAction::Separator + << MenuAction::Property; + + }else if (type == MultiFiles || type == MultiFilesSystemPathIncluded){ + actionKeys << MenuAction::Open + << MenuAction::Separator + << MenuAction::Property; + } + + return actionKeys; +} + +QSet ShareFileInfo::disableMenuActionList() const +{ + QSet list; + + return list; +} + +//QVariant ShareFileInfo::userColumnData(int userColumnRole) const +//{ +// if (userColumnRole == DFileSystemModel::FileUserRole + 1) +// return displayDeletionDate; + +// if (userColumnRole == DFileSystemModel::FileUserRole + 2) +// return originalFilePath; + +// return AbstractFileInfo::userColumnData(userColumnRole); +//} + +//QVariant ShareFileInfo::userColumnDisplayName(int userColumnRole) const +//{ +// if (userColumnRole == DFileSystemModel::FileUserRole + 1) +// return QObject::tr("Time deleted"); + +// if (userColumnRole == DFileSystemModel::FileUserRole + 2) +// return QObject::tr("Path", "TrashFileInfo"); + +// return AbstractFileInfo::userColumnDisplayName(userColumnRole); +//} + +//int ShareFileInfo::userColumnWidth(int userColumnRole) const +//{ +// if (userColumnRole == DFileSystemModel::FileUserRole + 2) +// return -1; + +// return AbstractFileInfo::userColumnWidth(userColumnRole); +//} + +//AbstractFileInfo::sortFunction ShareFileInfo::sortFunByColumn(int columnRole) const +//{ +// if (columnRole == DFileSystemModel::FileUserRole + 1) +// return FileSortFunction::sortFileListByDeletionDate; +// else if (columnRole == DFileSystemModel::FileUserRole + 2) +// return FileSortFunction::sortFileListBySourceFilePath; +// else +// return AbstractFileInfo::sortFunByColumn(columnRole); +//} + +bool ShareFileInfo::columnDefaultVisibleForRole(int userColumnRole) const +{ + if (userColumnRole == DFileSystemModel::FileLastModifiedRole) + return false; + + return DAbstractFileInfo::columnDefaultVisibleForRole(userColumnRole); +} + +MenuAction ShareFileInfo::menuActionByColumnRole(int userColumnRole) const +{ + if (userColumnRole == DFileSystemModel::FileUserRole + 1) + return MenuAction::DeletionDate; + + if (userColumnRole == DFileSystemModel::FileUserRole + 2) + return MenuAction::SourcePath; + + return DAbstractFileInfo::menuActionByColumnRole(userColumnRole); +} + +bool ShareFileInfo::canIteratorDir() const +{ + return false; +} + +bool ShareFileInfo::makeAbsolute() +{ + return true; +} + +DUrl ShareFileInfo::mimeDataUrl() const +{ + return DUrl::fromLocalFile(absoluteFilePath()); +} + +DUrl ShareFileInfo::parentUrl() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return DUrl::fromUserShareFile("/"); + + return DUrl(); +} + +bool ShareFileInfo::isShared() const +{ + return true; +} + +bool ShareFileInfo::canTag() const +{ + return false; +} + +bool ShareFileInfo::isVirtualEntry() const +{ + Q_D(const DAbstractFileInfo); + + if (fileUrl() == DUrl(USERSHARE_ROOT)) + return true; + + return d->proxy && d->proxy->isVirtualEntry(); +} + +bool ShareFileInfo::canDrop() const +{ + Q_D(const DAbstractFileInfo); + + //if (fileUrl() == DUrl(USERSHARE_ROOT)) + //return false; + + return d->proxy && d->proxy->canDrop(); +} + +Qt::ItemFlags ShareFileInfo::fileItemDisableFlags() const +{ + return Qt::ItemIsDragEnabled | Qt::ItemIsEditable; +} + +QList ShareFileInfo::additionalIcon() const +{ + QList icons; + icons << QIcon::fromTheme("emblem-shared", DFMGlobal::instance()->standardIcon(DFMGlobal::ShareIcon)); + if (isSymLink()) { + icons << QIcon::fromTheme("emblem-symbolic-link", DFMGlobal::instance()->standardIcon(DFMGlobal::LinkIcon)); + } + + return icons; +} + +bool ShareFileInfo::canRedirectionFileUrl() const +{ + Q_D(const DAbstractFileInfo); + + return d->proxy; +} + +DUrl ShareFileInfo::redirectedFileUrl() const +{ + Q_D(const DAbstractFileInfo); + + return d->proxy ? d->proxy->fileUrl() : DUrl(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/sharefileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/sharefileinfo.h new file mode 100644 index 0000000..7969310 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/sharefileinfo.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef SHAREFILEINFO_H +#define SHAREFILEINFO_H + +#include +#include "dabstractfileinfo.h" + +class ShareFileInfo : public DAbstractFileInfo +{ +public: + explicit ShareFileInfo(const DUrl &url); + ~ShareFileInfo() override; + bool exists() const override; + bool isDir() const override; + bool canRename() const override; + bool isReadable() const override; + bool isWritable() const override; + + QString fileDisplayName() const override; + + QVector menuActionList(MenuType type) const override; + QSet disableMenuActionList() const override; + + bool columnDefaultVisibleForRole(int userColumnRole) const override; + + MenuAction menuActionByColumnRole(int userColumnRole) const override; + + bool canIteratorDir() const override; + bool makeAbsolute() override; + + DUrl mimeDataUrl() const override; + DUrl parentUrl() const override; + + bool isShared() const override; + bool canTag() const override; + bool isVirtualEntry() const override; + virtual bool canDrop() const override; + + Qt::ItemFlags fileItemDisableFlags() const override; + QList additionalIcon() const override; + + virtual bool canRedirectionFileUrl() const override; + virtual DUrl redirectedFileUrl() const override; + +private: + QString m_displayName; + +}; + +#endif // SHAREFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/tagfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/tagfileinfo.cpp new file mode 100644 index 0000000..c5f3aa6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/tagfileinfo.cpp @@ -0,0 +1,359 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "tagfileinfo.h" +#include "dfileservices.h" +#include "dfilesystemmodel.h" +#include "dabstractfileinfo.h" +#include "durl.h" +#include "private/dfileinfo_p.h" +#include "tag/tagmanager.h" +#include "shutil/fileutils.h" + +TagFileInfo::TagFileInfo(const DUrl &url) + : DAbstractFileInfo{ url, false } //###: Do not cache. +{ + ///###: if the true url of file is put into fragment field of Uri. Then setup proxy. + if (!url.taggedLocalFilePath().isEmpty()) { + DAbstractFileInfoPointer infoPointer{ DFileService::instance()->createFileInfo(nullptr, DUrl::fromLocalFile(url.fragment(QUrl::FullyDecoded))) }; + this->DAbstractFileInfo::setProxy(infoPointer); + } +} + +bool TagFileInfo::isDir() const +{ + const DAbstractFileInfoPrivate *const d{ d_func() }; + + return ((!static_cast(d->proxy)) || d->proxy->isDir()); +} + +bool TagFileInfo::makeAbsolute() +{ + return true; +} + +bool TagFileInfo::exists() const +{ + const DAbstractFileInfoPrivate *const d{ d_func() }; + + if (d->proxy) { + return d->proxy->exists(); + } + + if (fileUrl() == DUrl(TAG_ROOT)) { + return true; + } + + const QMap &tag_map = TagManager::instance()->getAllTags(); + + return tag_map.contains(fileUrl().tagName()); +} + +bool TagFileInfo::canRename() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) { + return d->proxy->canRename(); + } + + return fileUrl() != DUrl(TAG_ROOT); +} + +bool TagFileInfo::isTaged() const +{ + return true; +} + +bool TagFileInfo::isWritable() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->isWritable(); + + return true; +} + +bool TagFileInfo::canRedirectionFileUrl() const +{ + const DAbstractFileInfoPrivate *const d{ d_func() }; + + return static_cast(d->proxy); +} + +int TagFileInfo::filesCount() const +{ + //Tag数据查询会返回很多无效的Path,需要在计算数量时判断Path是否存在 + //TODO: 这种做法不是最优解,在文管重构时需要重写Tag数据库相关的读写逻辑,保证返回有效Path + QList files(TagManager::instance()->getFilesThroughTag(fileUrl().tagName())); + + int fileCount = 0; + for(const QString& localFilePath : files){ + DUrl url{ fileUrl() }; + url.setTaggedFileUrl(localFilePath); + DAbstractFileInfoPointer fileInfo{ new TagFileInfo(url) }; + + if (fileInfo->exists()) + ++fileCount; + } + + return fileCount; +} + +QFileDevice::Permissions TagFileInfo::permissions() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->permissions(); + + return QFile::ReadGroup | QFile::ReadOwner | QFile::ReadUser | QFile::ReadOther + | QFile::WriteGroup | QFile::WriteOwner | QFile::WriteUser | QFile::WriteOther; +} + + +DUrl TagFileInfo::redirectedFileUrl() const +{ + const DAbstractFileInfoPrivate *const d{ d_func() }; + + //d-proxy可能为空,需要先判断 + if (d->proxy) + return d->proxy->fileUrl(); + + return fileUrl(); +} + +Qt::ItemFlags TagFileInfo::fileItemDisableFlags() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->fileItemDisableFlags(); + + return fileUrl() != DUrl(TAG_ROOT) ? Qt::ItemIsDragEnabled : Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; +} + +QVector TagFileInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + Q_D(const DAbstractFileInfo); + + QVector actions; + + if (!d->proxy) { + if (type == SpaceArea) { + actions << MenuAction::DisplayAs; + actions << MenuAction::SortBy; + } else { + actions << MenuAction::Open; + actions << MenuAction::OpenInNewWindow; + actions << MenuAction::OpenInNewTab; + actions << MenuAction::Rename; + actions << MenuAction::ChangeTagColor; + } + + return actions; + } + + actions = d->proxy->menuActionList(type); + actions.insert(1, MenuAction::OpenFileLocation); + + return actions; +} + +DUrl TagFileInfo::getUrlByNewFileName(const QString &name) const +{ + DUrl new_url = fileUrl(); + const QString &local_file = new_url.taggedLocalFilePath(); + + if (local_file.isEmpty()) + return DAbstractFileInfo::getUrlByNewFileName(name); + + QFileInfo file_info(local_file); + + new_url.setTaggedFileUrl(file_info.absoluteDir().absoluteFilePath(name)); + + return new_url; +} + +bool TagFileInfo::canIteratorDir() const +{ + Q_D(const DAbstractFileInfo); + + if (!d->proxy) + return true; + + return d->proxy->canIteratorDir(); +} + +QVariantHash TagFileInfo::extraProperties() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->extraProperties(); + + QVariantHash hash; + + if (fileUrl() == DUrl(TAG_ROOT)) + return hash; + + const QString &tag_name = fileUrl().tagName(); + const QColor &tag_color = TagManager::instance()->getTagColor({tag_name}).value(tag_name); + + hash["tag_name_list"] = QStringList{tag_name}; + hash["colored"] = QVariant::fromValue(QList {tag_color}); + + return hash; +} + +QList TagFileInfo::userColumnRoles() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->userColumnRoles(); + + if (fileUrl() == DUrl(TAG_ROOT)) { + return QList { + DFileSystemModel::FileDisplayNameRole, + DFileSystemModel::FileSizeRole + }; + } + + return DAbstractFileInfo::userColumnRoles(); +} + +DUrl TagFileInfo::mimeDataUrl() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->mimeDataUrl(); + + return DUrl(); +} + +Qt::DropActions TagFileInfo::supportedDragActions() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->supportedDragActions(); + + return DAbstractFileInfo::supportedDragActions(); +} + +Qt::DropActions TagFileInfo::supportedDropActions() const +{ + Q_D(const DAbstractFileInfo); + + if (d->proxy) + return d->proxy->supportedDropActions(); + + if (fileUrl().tagName().isEmpty()) + return Qt::IgnoreAction; + + return Qt::CopyAction; +} + +bool TagFileInfo::canDrop() const +{ + return DAbstractFileInfo::canDrop(); +} + +bool TagFileInfo::isVirtualEntry() const +{ + Q_D(const DAbstractFileInfo); + return !d->proxy; +} + +QString TagFileInfo::sizeDisplayName() const +{ + // 如果是文件夹,不去遍历下面的文件数量,否则大文件数量时界面会很卡 + // 原因是因为model会一直刷新,获取size + if (isDir()) { + return QStringLiteral("-"); + } + + return FileUtils::formatSize(size()); +} + +bool TagFileInfo::canDragCompress() const +{ + // 标记文件不支持追加压缩 + return false; +} + +DUrl TagFileInfo::parentUrl() const +{ + DUrl url = fileUrl(); + + if (url.taggedLocalFilePath().isEmpty()) { + return DAbstractFileInfo::parentUrl(); + } + + return DUrl::fromUserTaggedFile(url.tagName(), QString{}); +} + +QString TagFileInfo::iconName() const +{ + DUrl current_url{ this->fileUrl() }; + + if (current_url.isTaggedFile()) { + return QString{"folder"}; + } + + return DAbstractFileInfo::iconName(); +} + +DUrl TagFileInfo::goToUrlWhenDeleted() const +{ + const DAbstractFileInfoPrivate *d{ d_func() }; + + DUrl current_url{ this->fileUrl() }; + QString parent_url{ current_url.parentUrl().path()}; + + ///###: if there current file-info do not have a proxy! + ///###: it shows that current item is a tag-dir(tag:///tag-name). + if (current_url.isTaggedFile() && parent_url == QString{"/"} && !d->proxy) { + return DUrl::fromLocalFile(QDir::homePath()); + } + + return DAbstractFileInfo::goToUrlWhenDeleted(); +} + + + +//bool TagFileInfo::columnDefaultVisibleForRole(int role) const +//{ +// if(role == DFileSystemModel::FileLastModifiedRole){ +// return false; +// } + +// return DAbstractFileInfo::columnDefaultVisibleForRole(role); +//} + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/tagfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/tagfileinfo.h new file mode 100644 index 0000000..a2ab32c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/tagfileinfo.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ +#ifndef TAGFILEINFO_H +#define TAGFILEINFO_H + +#include + +#include "dabstractfileinfo.h" + +class TagFileInfo : public DAbstractFileInfo +{ +public: + explicit TagFileInfo(const DUrl &url); + virtual ~TagFileInfo() = default; + + virtual bool isDir() const override; + virtual bool makeAbsolute() override; + virtual bool exists() const override; + + bool canRename() const override; + + virtual bool isTaged() const override; + virtual bool isWritable() const override; + virtual bool canRedirectionFileUrl() const override; +// virtual bool columnDefaultVisibleForRole(int role) const override; + + virtual int filesCount() const override; + QFileDevice::Permissions permissions() const override; + + virtual DUrl parentUrl() const override; + virtual QString iconName() const override; + virtual DUrl goToUrlWhenDeleted() const override; + virtual DUrl redirectedFileUrl() const override; + virtual Qt::ItemFlags fileItemDisableFlags() const override; + virtual QVector menuActionList(MenuType type) const override; + + DUrl getUrlByNewFileName(const QString &name) const override; + + bool canIteratorDir() const override; + + QVariantHash extraProperties() const override; + + QList userColumnRoles() const override; + + DUrl mimeDataUrl() const override; + Qt::DropActions supportedDragActions() const override; + Qt::DropActions supportedDropActions() const override; + bool canDrop() const override; + bool isVirtualEntry() const override; + + /** + * @brief sizeDisplayName 列表模式下,获取大小 + * @return + */ + QString sizeDisplayName() const override; + + /** + * @brief canDragCompress 是否支持拖拽压缩 + * @return + */ + bool canDragCompress() const override; +}; + + + +#endif // TAGFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/trashfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/trashfileinfo.cpp new file mode 100644 index 0000000..4371bb8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/trashfileinfo.cpp @@ -0,0 +1,530 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "trashfileinfo.h" +#include "dfileinfo.h" +#include "private/dabstractfileinfo_p.h" +#include "controllers/trashmanager.h" +#include "dfileservices.h" +#include "controllers/pathmanager.h" +#include "trashfileinfo_p.h" + +#include "app/define.h" +#include "interfaces/dfmstandardpaths.h" +#include "dfilesystemmodel.h" +#include "singleton.h" +#include "fileoperations/filejob.h" +#include "dialogs/dialogmanager.h" +#include "desktopfileinfo.h" + +#include +#include +#include + +namespace FileSortFunction { +COMPARE_FUN_DEFINE(deletionDate, DeletionDate, TrashFileInfo) +COMPARE_FUN_DEFINE(sourceFilePath, SourceFilePath, TrashFileInfo) +} + + +void TrashFileInfoPrivate::updateInfo() +{ + const QString &filePath = proxy->absoluteFilePath(); + const QString &basePath = DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath); + const QString &fileBaseName = filePath.mid(basePath.size()); + + QString location(DFMStandardPaths::location(DFMStandardPaths::TrashInfosPath) + fileBaseName + ".trashinfo"); + if (QFile::exists(location)) { + QSettings setting(location, QSettings::NativeFormat); + + setting.beginGroup("Trash Info"); + setting.setIniCodec("utf-8"); + + originalFilePath = QByteArray::fromPercentEncoding(setting.value("Path").toByteArray()) + filePath.mid(basePath.size() + fileBaseName.size()); + + displayName = originalFilePath.mid(originalFilePath.lastIndexOf('/') + 1); + + deletionDate = QDateTime::fromString(setting.value("DeletionDate").toString(), Qt::ISODate); + displayDeletionDate = deletionDate.toString(DAbstractFileInfo::dateTimeFormat()); + + if (displayDeletionDate.isEmpty()) { + displayDeletionDate = setting.value("DeletionDate").toString(); + } + + const QString &tag_name_list = setting.value("TagNameList").toString(); + + if (!tag_name_list.isEmpty()) { + tagNameList = tag_name_list.split(","); + } + } else { + //inherits from parent trash info + inheritParentTrashInfo(); + + // is trash root path + if (filePath == basePath || filePath == basePath + "/") { + displayName = QCoreApplication::translate("PathManager", "Trash"); + + return; + } + + if (systemPathManager->isSystemPath(filePath)) { + displayName = systemPathManager->getSystemPathDisplayNameByPath(filePath); + } else { + displayName = proxy->fileName(); + } + } +} + +void TrashFileInfoPrivate::inheritParentTrashInfo() +{ + const QString &filePath = proxy->absoluteFilePath(); + QString nameLayer = filePath.right(filePath.length() - DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath).length() - 1); + QStringList names = nameLayer.split("/"); + + QString name = names.takeFirst(); + QString restPath; + foreach (QString str, names) { + restPath += "/" + str; + } + + if (QFile::exists(DFMStandardPaths::location(DFMStandardPaths::TrashInfosPath) + QDir::separator() + name + ".trashinfo")) { + QSettings setting(DFMStandardPaths::location(DFMStandardPaths::TrashInfosPath) + QDir::separator() + name + ".trashinfo", QSettings::NativeFormat); + + setting.beginGroup("Trash Info"); + setting.setIniCodec("utf-8"); + + originalFilePath = QByteArray::fromPercentEncoding(setting.value("Path").toByteArray()) + restPath; + + deletionDate = QDateTime::fromString(setting.value("DeletionDate").toString(), Qt::ISODate); + displayDeletionDate = deletionDate.toString(DAbstractFileInfo::dateTimeFormat()); + + if (displayDeletionDate.isEmpty()) { + displayDeletionDate = setting.value("DeletionDate").toString(); + } + } +} + +TrashFileInfo::TrashFileInfo(const DUrl &url) + : DAbstractFileInfo(*new TrashFileInfoPrivate(url, this)) +{ + Q_D(TrashFileInfo); + + const QString &trashFilesPath = DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath); + + if (!QDir().mkpath(trashFilesPath)) { + qWarning() << "mkpath trash files path failed, path =" << trashFilesPath; + } + + setProxy(DAbstractFileInfoPointer(new DFileInfo(trashFilesPath + url.path()))); + d->updateInfo(); +} + +bool TrashFileInfo::exists() const +{ + return DAbstractFileInfo::exists() || fileUrl() == DUrl::fromTrashFile("/"); +} + +bool TrashFileInfo::canRename() const +{ + return false; +} + +bool TrashFileInfo::isReadable() const +{ + return true; +} + +bool TrashFileInfo::isWritable() const +{ + return true; +} + +bool TrashFileInfo::canShare() const +{ + return false; +} + +bool TrashFileInfo::isDir() const +{ + if (fileUrl() == DUrl::fromTrashFile("/")) { + return true; + } + + return DAbstractFileInfo::isDir(); +} + +QString TrashFileInfo::fileDisplayName() const +{ + Q_D(const TrashFileInfo); + if (isDesktopFile()) { + QFileInfo f(absoluteFilePath()); + DesktopFileInfo dfi(f); + return dfi.fileDisplayName(); + } + return d->displayName; +} + +QFileDevice::Permissions TrashFileInfo::permissions() const +{ + QFileDevice::Permissions p = DAbstractFileInfo::permissions(); + + p &= ~QFileDevice::WriteOwner; + p &= ~QFileDevice::WriteUser; + p &= ~QFileDevice::WriteGroup; + p &= ~QFileDevice::WriteOther; + + return p; +} + +QVector TrashFileInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + QVector actionKeys; + + if (type == SpaceArea) { + actionKeys.reserve(7); + + actionKeys << MenuAction::RestoreAll + << MenuAction::ClearTrash + << MenuAction::Separator + << MenuAction::DisplayAs + << MenuAction::SortBy + << MenuAction::Separator + << MenuAction::Property; + } else if (type == SingleFile) { + actionKeys.reserve(12); + if (isDir()) { + + actionKeys << MenuAction::Open + << MenuAction::OpenInNewWindow + << MenuAction::Separator; + } + actionKeys << MenuAction::Restore + << MenuAction::CompleteDeletion + << MenuAction::Cut // 添加回收站剪切菜单 + << MenuAction::Copy + << MenuAction::Separator + << MenuAction::Property; + + } else if (type == MultiFiles) { + actionKeys.reserve(12); + if (isDir()) { + actionKeys << MenuAction::Open + //<< MenuAction::OpenInNewWindow + << MenuAction::Separator; + } + actionKeys << MenuAction::Restore + << MenuAction::CompleteDeletion + << MenuAction::Cut // 添加回收站剪切菜单 + << MenuAction::Copy + << MenuAction::Separator + << MenuAction::Property; + } + + return actionKeys; +} + +QSet TrashFileInfo::disableMenuActionList() const +{ + QSet list; + + if (TrashManager::isEmpty()) { + list << MenuAction::RestoreAll; + list << MenuAction::ClearTrash; + } + + if (fileUrl() != DUrl::fromTrashFile("/")) { + list << MenuAction::RestoreAll; + list << MenuAction::ClearTrash; + } + + if (parentUrl() != DUrl::fromTrashFile("/")) { + list << MenuAction::Restore; + list << MenuAction::CompleteDeletion; + list << MenuAction::Cut; + } + + return list; +} + +void TrashFileInfo::setColumnCompact(bool) +{ + +} + +QList TrashFileInfo::userColumnRoles() const +{ + static QList userColumnRoles = QList() /*<< DFileSystemModel::FileUserRole + 1 + << DFileSystemModel::FileUserRole + 2*/ + << DFileSystemModel::FileDisplayNameRole + << DFileSystemModel::FileUserRole + 3 // originalFilePath + << DFileSystemModel::FileUserRole + 4 // displayDeletionDate + << DFileSystemModel::FileSizeRole + << DFileSystemModel::FileMimeTypeRole; + + return userColumnRoles; +} + +QVariant TrashFileInfo::userColumnData(int userColumnRole) const +{ + Q_D(const TrashFileInfo); + if (userColumnRole == DFileSystemModel::FileUserRole + 1) { + QString sourcePath; + if (d->originalFilePath.isEmpty()) { + sourcePath = d->originalFilePath; + } else { + sourcePath = QFileInfo(d->originalFilePath).absolutePath(); + } + return QVariant::fromValue(QPair(fileDisplayName(), sourcePath)); + } + if (userColumnRole == DFileSystemModel::FileUserRole + 2) { + return QVariant::fromValue(qMakePair(d->displayDeletionDate, qMakePair(sizeDisplayName(), mimeTypeDisplayName()))); + } + + if (userColumnRole == DFileSystemModel::FileUserRole + 3) { + if (d->originalFilePath.isEmpty()) { + return d->originalFilePath; + } + + return QFileInfo(d->originalFilePath).absolutePath(); + } + + if (userColumnRole == DFileSystemModel::FileUserRole + 4) { + return d->displayDeletionDate; + } + + return DAbstractFileInfo::userColumnData(userColumnRole); +} + +QVariant TrashFileInfo::userColumnDisplayName(int userColumnRole) const +{ + if (userColumnRole == DFileSystemModel::FileUserRole + 1) { + return qApp->translate("DFileSystemModel", "Name"); + } + + if (userColumnRole == DFileSystemModel::FileUserRole + 2) { + return QObject::tr("Time deleted"); + } + + if (userColumnRole == DFileSystemModel::FileUserRole + 3) { + return QObject::tr("Source Path", "TrashFileInfo"); + } + + if (userColumnRole == DFileSystemModel::FileUserRole + 4) { + return QObject::tr("Time deleted"); + } + + return DAbstractFileInfo::userColumnDisplayName(userColumnRole); +} + +QList TrashFileInfo::userColumnChildRoles(int column) const +{ + Q_UNUSED(column) + + QList userColumnRoles{}; +// if (column == 0) { +// userColumnRoles << DFileSystemModel::FileDisplayNameRole +// << DFileSystemModel::FileUserRole + 3; +// } else if (column == 1) { +// userColumnRoles << DFileSystemModel::FileUserRole + 4 +// << DFileSystemModel::FileSizeRole +// << DFileSystemModel::FileMimeTypeRole; +// } + return userColumnRoles; +} + +int TrashFileInfo::userColumnWidth(int userColumnRole, const QFontMetrics &fontMetrics) const +{ + if (userColumnRole == DFileSystemModel::FileUserRole + 1) { + return -1; + } + + return DAbstractFileInfo::userColumnWidth(userColumnRole, fontMetrics); +} + +QString TrashFileInfo::subtitleForEmptyFloder() const +{ + return QObject::tr("Folder is empty"); +} + +//int TrashFileInfo::userRowHeight(const QFontMetrics &fontMetrics) const +//{ +// return fontMetrics.height() * 2 + 10; +//} + +bool TrashFileInfo::columnDefaultVisibleForRole(int userColumnRole) const +{ + Q_UNUSED(userColumnRole); + + return true; +// return (userColumnRole == DFileSystemModel::FileUserRole + 1 || +// userColumnRole == DFileSystemModel::FileUserRole + 2); +} + +MenuAction TrashFileInfo::menuActionByColumnRole(int userColumnRole) const +{ + if (userColumnRole == DFileSystemModel::FileUserRole + 3) { + return MenuAction::SourcePath; + } + + if (userColumnRole == DFileSystemModel::FileUserRole + 4) { + return MenuAction::DeletionDate; + } + + + return DAbstractFileInfo::menuActionByColumnRole(userColumnRole); +} + +QList TrashFileInfo::sortSubMenuActionUserColumnRoles() const +{ + QList roles; + roles << DFileSystemModel::FileDisplayNameRole + << DFileSystemModel::FileUserRole + 3 /*Source Path*/ + << DFileSystemModel::FileUserRole + 4 /*Time Deleted*/ + << DFileSystemModel::FileSizeRole + << DFileSystemModel::FileMimeTypeRole; + return roles; +} + +bool TrashFileInfo::canIteratorDir() const +{ + return true; +} + +bool TrashFileInfo::makeAbsolute() +{ + return true; +} + +DUrl TrashFileInfo::originUrl() const +{ + Q_D(const TrashFileInfo); + + return DUrl::fromLocalFile(d->originalFilePath); +} + +DUrl TrashFileInfo::mimeDataUrl() const +{ + return DUrl::fromLocalFile(absoluteFilePath()); +} + +Qt::DropActions TrashFileInfo::supportedDragActions() const +{ + return Qt::CopyAction | Qt::MoveAction; +} + +Qt::DropActions TrashFileInfo::supportedDropActions() const +{ + const QString &path = fileUrl().path(); + + return path.isEmpty() || path == "/" ? Qt::MoveAction : Qt::IgnoreAction; +} + +QIcon TrashFileInfo::fileIcon() const +{ + if (isDesktopFile()) { + QFileInfo f(absoluteFilePath()); + DesktopFileInfo dfi(f); + return dfi.fileIcon(); + } + + return DAbstractFileInfo::fileIcon(); +} + +QList TrashFileInfo::additionalIcon() const +{ + QList icons; + + if (isSymLink()) { + icons << QIcon::fromTheme("emblem-symbolic-link", DFMGlobal::instance()->standardIcon(DFMGlobal::LinkIcon)); + } + + return icons; +} + +DUrl TrashFileInfo::goToUrlWhenDeleted() const +{ + if (fileUrl() == DUrl::fromTrashFile("/")) { + return fileUrl(); + } + + return DAbstractFileInfo::goToUrlWhenDeleted(); +} + +DAbstractFileInfo::CompareFunction TrashFileInfo::compareFunByColumn(int columnRole) const +{ + // see TrashFileInfo::userColumnRoles for role function + if (columnRole == DFileSystemModel::FileUserRole + 3) { + return FileSortFunction::compareFileListBySourceFilePath; + } else if (columnRole == DFileSystemModel::FileUserRole + 4) { + return FileSortFunction::compareFileListByDeletionDate; + } else { + return DAbstractFileInfo::compareFunByColumn(columnRole); + } +} + +bool TrashFileInfo::restore(QSharedPointer job) const +{ + Q_D(const TrashFileInfo); + + if (d->originalFilePath.isEmpty()) { + qDebug() << "OriginalFile path ie empty."; + + return false; + } + + QDir dir(d->originalFilePath.left(d->originalFilePath.lastIndexOf('/'))); + + if (dir.isAbsolute() && !dir.mkpath(dir.absolutePath())) { + qDebug() << "mk" << dir.absolutePath() << "failed!"; + + return false; + } + + bool ok = job->doTrashRestore(absoluteFilePath(), d->originalFilePath); + bool isAbortedOrSkipped = job->isAborted() || job->getIsSkip(); + ok = ok || isAbortedOrSkipped; // ok==false will show error dialog + + // restore the file tag infos + if (ok && !isAbortedOrSkipped && !d->tagNameList.isEmpty()) { + //若还原后文件名被改变,则使用改变后的路径作为还原标记数据的文件路径 + QString tarFilePath = d->originalFilePath; + job->getRestoreTargetPath(tarFilePath); + DFileService::instance()->setFileTags(nullptr, DUrl::fromLocalFile(tarFilePath), d->tagNameList); + } + + return ok; +} + +QDateTime TrashFileInfo::deletionDate() const +{ + Q_D(const TrashFileInfo); + + return d->deletionDate; +} + +QString TrashFileInfo::sourceFilePath() const +{ + Q_D(const TrashFileInfo); + + return d->originalFilePath; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/trashfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/trashfileinfo.h new file mode 100644 index 0000000..63c3ad3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/trashfileinfo.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef TRASHFILEINFO_H +#define TRASHFILEINFO_H + +#include "dabstractfileinfo.h" + +class FileJob; +class DFMEvent; +class TrashFileInfoPrivate; +class TrashFileInfo : public DAbstractFileInfo +{ +public: + explicit TrashFileInfo(const DUrl &url); + + bool exists() const override; + bool canRename() const override; + bool isReadable() const override; + bool isWritable() const override; + bool canShare() const override; + bool isDir() const override; + + QString fileDisplayName() const override; + QFile::Permissions permissions() const override; + + QVector menuActionList(MenuType type) const override; + QSet disableMenuActionList() const override; + + void setColumnCompact(bool) override; + QList userColumnRoles() const override; + QVariant userColumnData(int userColumnRole) const override; + QVariant userColumnDisplayName(int userColumnRole) const override; + + QList userColumnChildRoles(int column) const override; + + int userColumnWidth(int userColumnRole, const QFontMetrics &fontMetrics) const override; + QString subtitleForEmptyFloder() const override; +// int userRowHeight(const QFontMetrics &fontMetrics) const override; + + CompareFunction compareFunByColumn(int columnRole) const override; + bool columnDefaultVisibleForRole(int userColumnRole) const override; + + + MenuAction menuActionByColumnRole(int userColumnRole) const override; + QList sortSubMenuActionUserColumnRoles() const override; + + bool canIteratorDir() const override; + bool makeAbsolute() override; + + DUrl originUrl() const; + DUrl mimeDataUrl() const override; + Qt::DropActions supportedDragActions() const override; + Qt::DropActions supportedDropActions() const override; + + QIcon fileIcon() const override; + QList additionalIcon() const override; + + DUrl goToUrlWhenDeleted() const override; + + bool restore(QSharedPointer job) const; + QDateTime deletionDate() const; + QString sourceFilePath() const; + +private: + Q_DECLARE_PRIVATE(TrashFileInfo) +}; + +#endif // TRASHFILEINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/trashfileinfo_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/trashfileinfo_p.h new file mode 100644 index 0000000..32d928a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/trashfileinfo_p.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef TRASHFILEINFO_P_H +#define TRASHFILEINFO_P_H + +#include "private/dabstractfileinfo_p.h" +#include "trashfileinfo.h" +# + +class TrashFileInfoPrivate : public DAbstractFileInfoPrivate +{ +public: + TrashFileInfoPrivate(const DUrl &url, TrashFileInfo *qq) + : DAbstractFileInfoPrivate(url, qq, true) + { + columnCompact = false; + } + + QString desktopIconName; + QString displayName; + QString originalFilePath; + QString displayDeletionDate; + QDateTime deletionDate; + QStringList tagNameList; + + void updateInfo(); + void inheritParentTrashInfo(); +}; + + +#endif // TRASHFILEINFO_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/vaultfileinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/vaultfileinfo.cpp new file mode 100644 index 0000000..75c0b1e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/vaultfileinfo.cpp @@ -0,0 +1,397 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include +#include "vaultfileinfo.h" +#include "private/dabstractfileinfo_p.h" +#include "dfileservices.h" +#include "controllers/vaultcontroller.h" +#include "dfilesystemmodel.h" + +#include +#include +#include + +class VaultFileInfoPrivate : public DAbstractFileInfoPrivate +{ +public: + VaultFileInfoPrivate(const DUrl &url, VaultFileInfo *qq) : DAbstractFileInfoPrivate(url, qq, true) {} +}; + +VaultFileInfo::VaultFileInfo(const DUrl &url) + : DAbstractFileInfo(url, true) +{ + // normal file map to.. + DUrl actualUrl = DUrl::fromLocalFile(VaultController::vaultToLocal(url)); + setProxy(DAbstractFileInfoPointer(DFileService::instance()->createFileInfo(nullptr, actualUrl))); +} + +VaultFileInfo::~VaultFileInfo() +{ +} + +bool VaultFileInfo::exists() const +{ + Q_D(const VaultFileInfo); + if (d->proxy) { + return d->proxy->exists(); + } + + return DAbstractFileInfo::exists(); +} + +DUrl VaultFileInfo::parentUrl() const +{ + Q_D(const VaultFileInfo); + + if (fileUrl().path() == "/") return DAbstractFileInfo::parentUrl(); + + if (d->proxy) { + return VaultController::localUrlToVault(d->proxy->parentUrl()); + } + + return DAbstractFileInfo::parentUrl(); +} + +QString VaultFileInfo::iconName() const +{ + Q_D(const VaultFileInfo); + + QString iconName = "dfm_safebox"; // 如果是根目录,用保险柜图标 + + if (!isRootDirectory()) { + if (d->proxy) { + iconName = d->proxy->iconName(); + } + } else if (!iconName.isEmpty()) { + return iconName; + } + + return DAbstractFileInfo::iconName(); +} + +QString VaultFileInfo::genericIconName() const +{ + Q_D(const VaultFileInfo); + if (d->proxy) { + return d->proxy->genericIconName(); + } + + return "drive-harddisk-encrypted"; +} + +DUrl VaultFileInfo::mimeDataUrl() const +{ + Q_D(const VaultFileInfo); + if (d->proxy) { + // 自定义保险箱的url + return VaultController::makeVaultUrl(d->proxy->fileUrl().toLocalFile()); + } + + return DAbstractFileInfo::mimeDataUrl(); +} + +bool VaultFileInfo::canRedirectionFileUrl() const +{ + Q_D(const VaultFileInfo); + if (d->proxy) { + return !d->proxy->isDir(); + } + + return DAbstractFileInfo::canRedirectionFileUrl(); +} + +DUrl VaultFileInfo::redirectedFileUrl() const +{ + Q_D(const VaultFileInfo); + if (d->proxy) { + return d->proxy->fileUrl(); + } + + return DAbstractFileInfo::redirectedFileUrl(); +} + +// 解决保险箱无法搜索的问题 +bool VaultFileInfo::canIteratorDir() const +{ + return true; +} + +QString VaultFileInfo::subtitleForEmptyFloder() const +{ + return QObject::tr("Folder is empty"); +} + +DUrl VaultFileInfo::getUrlByNewFileName(const QString &fileName) const +{ + DUrl url(parentUrl()); + url.setPath(url.path() + QDir::separator() + fileName); + return url; +} + +QList VaultFileInfo::additionalIcon() const +{ + QList icons; + + if (isSymLink()) + icons << QIcon::fromTheme("emblem-symbolic-link", DFMGlobal::instance()->standardIcon(DFMGlobal::LinkIcon)); + + return icons; +} + +bool VaultFileInfo::isWritable() const +{ + VaultController::FileBaseInfo fbi = VaultController::ins()->getFileInfo(fileUrl()); + if (fbi.isExist) { + return fbi.isWritable; + } + + return DAbstractFileInfo::isWritable(); +} + +bool VaultFileInfo::isSymLink() const +{ + VaultController::FileBaseInfo fbi = VaultController::ins()->getFileInfo(fileUrl()); + if (fbi.isExist) { + return fbi.isSymLink; + } + + bool flg = DAbstractFileInfo::isSymLink(); + return flg; +} + +QFileDevice::Permissions VaultFileInfo::permissions() const +{ + return VaultController::ins()->getPermissions(fileUrl().toLocalFile()); +} + +QSet VaultFileInfo::disableMenuActionList() const +{ + return DAbstractFileInfo::disableMenuActionList(); +} + +QVector VaultFileInfo::menuActionList(DAbstractFileInfo::MenuType type) const +{ + if (type != SpaceArea) { + if (isRootDirectory()) { + + VaultController::VaultState vaultState = VaultController::ins()->state(); + + QVector actions; + if (vaultState == VaultController::Unlocked) { + + actions << MenuAction::Open + << MenuAction::OpenInNewWindow + << MenuAction::Separator + << MenuAction::LockNow + << MenuAction::AutoLock + << MenuAction::Separator + << MenuAction::DeleteVault + << MenuAction::Separator + << MenuAction::Property; + } else if (vaultState == VaultController::Encrypted) { + actions << MenuAction::UnLock; + if(!VaultController::getVaultVersion()) + actions << MenuAction::UnLockByKey; + } + + return actions; + } + } + + // 保险箱内不使用共享、取消共享、创建链接、发送到桌面、添加书签菜单、标记、提权操作、挂载操作、打开终端 + QVector unusedList; + unusedList << MenuAction::Share << MenuAction::UnShare << MenuAction::CreateSymlink + << MenuAction::SendToDesktop << MenuAction::AddToBookMark << MenuAction::TagInfo + << MenuAction::TagFilesUseColor << MenuAction::Compress << MenuAction::Decompress + << MenuAction::DecompressHere << MenuAction::OpenAsAdmin << MenuAction::MountImage + << MenuAction::OpenInTerminal << MenuAction::SetAsWallpaper; + + QVector menuActions = DAbstractFileInfo::menuActionList(type); + + foreach (MenuAction action, unusedList) { + menuActions.removeAll(action); + } + + return menuActions; +} + +QMap > VaultFileInfo::subMenuActionList(MenuType type) const +{ + if (type != SpaceArea) { + if (isRootDirectory()) { + + QMap > actions; + QVector vecActions; + + vecActions << MenuAction::Never + << MenuAction::Separator + << MenuAction::FiveMinutes + << MenuAction::TenMinutes + << MenuAction::TwentyMinutes; + + actions.insert(MenuAction::AutoLock, vecActions); + + return actions; + } + } + + return DAbstractFileInfo::subMenuActionList(); +} + +QString VaultFileInfo::fileDisplayName() const +{ + if (isRootDirectory()) { + return QObject::tr("My Vault"); + } + + return DAbstractFileInfo::fileDisplayName(); +} + +bool VaultFileInfo::canRename() const +{ + if (isRootDirectory()) { + return false; + } + + // 如果父目录为只读权限,则不能重命名 + VaultController::FileBaseInfo fbi = VaultController::ins()->getFileInfo(parentUrl()); + if (fbi.isExist && !fbi.isWritable) { + return false; + } + + return true; +} + +bool VaultFileInfo::canShare() const +{ + return false; +} + +bool VaultFileInfo::canTag() const +{ + // 修复bug-58965 保险箱文件不能被标记 + return false; +} + +QIcon VaultFileInfo::fileIcon() const +{ + QIcon icon; + if (isRootDirectory()) { + icon = QIcon::fromTheme(iconName()); + } else { + icon = DAbstractFileInfo::fileIcon(); + } + + return icon; +} + +qint64 VaultFileInfo::size() const +{ + if (isRootDirectory()) { + + qint64 totoalSize = VaultController::ins()->totalsize(); + return totoalSize; + } + + return DAbstractFileInfo::size(); +} + +bool VaultFileInfo::isDir() const +{ + // resolved the issue when directory not exist + QString path = this->filePath(); + QString local = VaultController::vaultToLocal(VaultController::makeVaultUrl()); + if (local.endsWith("/")) { + local.chop(1); + } + + if (path.endsWith("/") || path == local) { + return true; + } + return DAbstractFileInfo::isDir(); +} + +bool VaultFileInfo::canDrop() const +{ + // 保险箱处于开锁状态下,可以拖拽文件到保险箱,否则,不支持拖拽 + if (VaultController::VaultState::Unlocked == VaultController::ins()->getVaultState()) { + // 如果是目录且可写 + if (isDir() && isWritable()) + return true; + else + return false; + } else { + return false; + } +} + +bool VaultFileInfo::canDragCompress() const +{ + // 保险箱内文件不支持拖拽压缩 + return false; +} + +bool VaultFileInfo::isAncestorsUrl(const DUrl &url, QList *ancestors) const +{ + Q_UNUSED(url) + DUrl parentUrl = this->parentUrl(); + + forever { + if (ancestors && parentUrl.isValid()) { + ancestors->append(parentUrl); + } + + if (parentUrl == VaultController::makeVaultUrl("/")) { + return true; + } + + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, parentUrl); + + if (!fileInfo) { + break; + } + + const DUrl &pu = fileInfo->parentUrl(); + + if (pu == parentUrl) { + break; + } + + parentUrl = pu; + } + + return false; +} + +bool VaultFileInfo::isRootDirectory() const +{ + bool bRootDir = false; + QString localFilePath = VaultController::ins()->makeVaultLocalPath(); + QString vrfilePath = DUrl::fromVaultFile("/").toString(); + QString path = DAbstractFileInfo::filePath(); + if (localFilePath == path || vrfilePath == path || localFilePath + "/" == path || localFilePath == path + "/") { + bRootDir = true; + } + return bRootDir; +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/vaultfileinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/vaultfileinfo.h new file mode 100644 index 0000000..e6e8bfa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/vaultfileinfo.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#pragma once + +#include "dabstractfileinfo.h" +#include + + + +class VaultFileInfoPrivate; +class VaultFileInfo : public DAbstractFileInfo +{ +public: + explicit VaultFileInfo(const DUrl &url); + ~VaultFileInfo() override; + + bool exists() const override; + + DUrl parentUrl() const override; + QString iconName() const override; + QString genericIconName() const override; + + DUrl mimeDataUrl() const override; + + bool canRedirectionFileUrl() const override; + DUrl redirectedFileUrl() const override; + bool canIteratorDir() const override; + + QString subtitleForEmptyFloder() const override; + + DUrl getUrlByNewFileName(const QString &fileName) const override; + + QList additionalIcon() const override; + bool isWritable() const override; + bool isSymLink() const override; + + QFile::Permissions permissions() const override; + QSet disableMenuActionList() const override; + + // 右键菜单 + QVector menuActionList(MenuType type = SingleFile) const override; + QMap > subMenuActionList(MenuType type = SingleFile) const override; + + bool canRename() const override; + bool canShare() const override; + bool canTag() const override; + QIcon fileIcon() const override; + QString fileDisplayName() const override; + qint64 size() const override; + bool isDir() const override; + bool canDrop() const override; + // 是否支持拖拽压缩 + bool canDragCompress() const override; + + /** + * @brief isAncestorsUrl 拆分路径 + * @param url 文件路径信息 + * @param ancestors 拆分后的路径列表 + * @return 拆分是否成功 + */ + bool isAncestorsUrl(const DUrl &url, QList *ancestors) const override; + +private: + bool isRootDirectory() const; + + Q_DECLARE_PRIVATE(VaultFileInfo) +}; diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/virtualentryinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/virtualentryinfo.h new file mode 100644 index 0000000..ddd4bff --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/models/virtualentryinfo.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: dengkeyun + * + * Maintainer: max-lv + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef VIRTUALENTRYINFO_H +#define VIRTUALENTRYINFO_H + +#include "dabstractfileinfo.h" +#include "durl.h" + +class VirtualEntryInfo : public DAbstractFileInfo +{ +public: + explicit VirtualEntryInfo(const DUrl &url); + + QString iconName() const override; + + bool exists() const override; + + bool isDir() const override; + + bool isVirtualEntry() const override; + + bool canShare() const override; + + bool isReadable() const override; + + bool isWritable() const override; + + QString fileName() const override; + + Qt::ItemFlags fileItemDisableFlags() const override; + + DAbstractFileInfo::CompareFunction compareFunByColumn(int) const override; +}; + +#endif // VIRTUALENTRYINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/pkexec/com.deepin.pkexec.dde-file-manager.policy b/dde-file-manager-5.5.3/src/dde-file-manager-lib/pkexec/com.deepin.pkexec.dde-file-manager.policy new file mode 100644 index 0000000..d3a2a0b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/pkexec/com.deepin.pkexec.dde-file-manager.policy @@ -0,0 +1,22 @@ + + + + LinuxDeepin + https://www.deepin.com/ + + Password required to view the folder + 查看文件夹需要输入密码 + 查看文件夾需要輸入密碼 + folder + + no + no + auth_admin_keep + + /usr/bin/dde-file-manager + true + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/pkexec/dde-file-manager-pkexec b/dde-file-manager-5.5.3/src/dde-file-manager-lib/pkexec/dde-file-manager-pkexec new file mode 100755 index 0000000..ab7ab0c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/pkexec/dde-file-manager-pkexec @@ -0,0 +1,2 @@ +#!/bin/bash +pkexec dde-file-manager "$@" \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/.readme b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/.readme new file mode 100644 index 0000000..870684d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/.readme @@ -0,0 +1 @@ +This is a context menu extensions directory, do not delete! \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/dfmadditionalmenu.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/dfmadditionalmenu.cpp new file mode 100644 index 0000000..c4e5cae --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/dfmadditionalmenu.cpp @@ -0,0 +1,424 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Mike Chen + * + * Maintainer: Mike Chen + * + * 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 + * 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 . + */ +#include "dfmadditionalmenu_p.h" +#include "dfmadditionalmenu.h" +#include "dfileservices.h" +#include "controllers/vaultcontroller.h" +#include "shutil/fileutils.h" + +#include +#include +#include +#include +#include +#include +#include "interfaces/dfilemenu.h" +DFM_BEGIN_NAMESPACE + +#define MENUEXTENSIONS_PATH "/usr/share/deepin/dde-file-manager/oem-menuextensions/" + +#define SET_PROPERTY_IFEXIST(action, file, key)\ + do{\ + QStringList values = d->getValues(file, key);\ + if (file.contains(key)) {\ + action->setProperty(key.data(), values);\ + }\ + }while(false) + +#define MIME_TYPE_KEY "MimeType" + +DFMAdditionalMenuPrivate::DFMAdditionalMenuPrivate(DFMAdditionalMenu *qq) + : q_ptr(qq) +{ + m_delayedLoadFileTimer = new QTimer(qq); + m_delayedLoadFileTimer->setSingleShot(true); + m_delayedLoadFileTimer->setInterval(500); + QObject::connect(m_delayedLoadFileTimer, &QTimer::timeout, qq, &DFMAdditionalMenu::loadDesktopFile); + DUrl url = DUrl::fromLocalFile(MENUEXTENSIONS_PATH); + DAbstractFileWatcher *dirWatch = DFileService::instance()->createFileWatcher(qq, url, qq); + if (dirWatch) { + dirWatch->startWatcher(); + } + + QObject::connect(dirWatch, &DAbstractFileWatcher::fileDeleted, m_delayedLoadFileTimer, [ = ]() { + m_delayedLoadFileTimer->start(); + }); + + QObject::connect(dirWatch, &DAbstractFileWatcher::subfileCreated, m_delayedLoadFileTimer, [ = ]() { + m_delayedLoadFileTimer->start(); + }); +} + +QStringList DFMAdditionalMenuPrivate::getValues(XdgDesktopFile &file, const QLatin1String &key, const QStringList &whiteList) +{ + QStringList values; + if (file.contains(key)) { + values = file.value(key).toString().split(';', QString::SkipEmptyParts); + for (const QString &one : values) { + if (whiteList.size() > 0 && !whiteList.contains(one)) { + values.removeAll(one); + } + } + } else { + values = whiteList; + } + return values; +} + +bool DFMAdditionalMenuPrivate::isMimeTypeSupport(const QString &mt, const QStringList &fileMimeTypes) +{ + foreach (const QString &fmt, fileMimeTypes) { + if (fmt.contains(mt, Qt::CaseInsensitive)) { + return true; + } + } + return false; +} + +bool DFMAdditionalMenuPrivate::isMimeTypeMatch(const QStringList &fileMimeTypes, const QStringList &supportMimeTypes) +{ + bool match = false; + for (QString mt : supportMimeTypes) { + if (fileMimeTypes.contains(mt, Qt::CaseInsensitive)) { + match = true; + break; + } + + int starPos = mt.indexOf("*"); + if (starPos >= 0 && isMimeTypeSupport(mt.left(starPos), fileMimeTypes)) { + match = true; + break; + } + } + return match; +} + +bool DFMAdditionalMenuPrivate::isActionShouldShow(QAction *action, bool onDesktop) +{ + if (!action) { + return false; + } + + // X-DFM-NotShowIn not exist + if (!action->property(MENU_HIDDEN_KEY.data()).isValid()) { + return true; + } + + // is menu triggered on desktop + QStringList notShowInList = action->property(MENU_HIDDEN_KEY.data()).toStringList(); + return (onDesktop && !notShowInList.contains("Desktop", Qt::CaseInsensitive)) || + (!onDesktop && !notShowInList.contains("Filemanager", Qt::CaseInsensitive)); +} + +bool DFMAdditionalMenuPrivate::isSchemeSupport(QAction *action, const DUrl &url) +{ + // X-DFM-SupportSchemes not exist + if (!action || !action->property(SUPPORT_SCHEMES_KEY.data()).isValid()) { + return true; + } + QStringList supportList = action->property(SUPPORT_SCHEMES_KEY.data()).toStringList(); + return supportList.contains(url.scheme(), Qt::CaseInsensitive); +} + +bool DFMAdditionalMenuPrivate::isSuffixSupport(QAction *action, const DUrl &url, const bool ballEx7z) +{ + Q_Q(DFMAdditionalMenu); + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(q, url); + // X-DFM-SupportSuffix not exist + if (!fileInfo || fileInfo->isDir() || !action || !action->property(SUPPORT_SUFFIX_KEY.data()).isValid()) { + if (ballEx7z) { + return false; + } + return true; + } + + QFileInfo info(url.toLocalFile()); + QStringList supportList = action->property(SUPPORT_SUFFIX_KEY.data()).toStringList(); + // 7z.001,7z.002, 7z.003 ... 7z.xxx + QString cs = info.completeSuffix(); + if (supportList.contains(cs, Qt::CaseInsensitive)) { + return true; + } + + bool match = false; + for (QString suffix : supportList) { + int endPos = suffix.lastIndexOf("*"); // 7z.* + if (endPos >= 0 && cs.length() > endPos && suffix.left(endPos) == cs.left(endPos)) { + match = true; + break; + } + } + return match; +} + +//都是7z分卷压缩文件 +bool DFMAdditionalMenuPrivate::isAllEx7zFile(const QStringList &files) +{ + if (files.size() <= 1) { + return false; + } + for (const QString &f : files) { + QFileInfo info(f); + // 7z.001,7z.002, 7z.003 ... 7z.xxx + QString cs = info.completeSuffix(); + if (!cs.startsWith(QString("7z."))) { + return false; + } + } + return true; +} + +QListDFMAdditionalMenuPrivate::emptyAreaActoins(const QString ¤tDir, bool onDesktop) +{ + QString menuType = "EmptyArea"; + QList actions = actionListByType[menuType]; + for (auto it = actions.begin(); it != actions.end();) { + QAction *action = *it; + if (!action || !isActionShouldShow(action, onDesktop) || + !isSchemeSupport(action, DUrl(currentDir)) || + !isSuffixSupport(action, DUrl(currentDir))) { + it = actions.erase(it); + continue; + } + + // Add file list data. + action->setData(currentDir); + if (action->menu()) { + for (QAction *subAction : action->menu()->actions()) { + subAction->setData(currentDir); + } + } + + ++it; + } + + return actions; +} + +DFMAdditionalMenuPrivate::~DFMAdditionalMenuPrivate() +{ + for (DFileMenu *menu : menuList) { + delete menu; + menu = nullptr; + } +} + +void DFMAdditionalMenu::loadDesktopFile() +{ + Q_D(DFMAdditionalMenu); + qDebug() << d->actionList; + + if (d->menuActionHolder) { + d->menuActionHolder->deleteLater(); + } + for (DFileMenu *menu : d->menuList) { + menu->deleteLater(); + } + + d->menuActionHolder = new QObject(this); + + d->actionList.clear(); + d->actionListByType.clear(); + + QDir oemPath(MENUEXTENSIONS_PATH); + if (oemPath.exists()) { + for (const QFileInfo &fileInfo : oemPath.entryInfoList({"*.desktop"})) { + XdgDesktopFile file; + file.load(fileInfo.filePath()); + if (!file.isValid()) { + continue; + } + + QStringList menuTypes = d->getValues(file, d->MENU_TYPE_KEY, d->AllMenuTypes); + if (!file.contains(d->MENU_TYPE_KEY)) { + qDebug() << "[OEM Menu Support] Entry will probably not be shown due to empty or have no valid" + << d->MENU_TYPE_KEY << "key in the desktop file."; + qDebug() << "[OEM Menu Support] Details:" << fileInfo.filePath() << "with entry name" << file.name(); + } + + // the XdgDesktopFile::icon() empty fallback is not really an empty fallback, so we need to check it manually. + QString iconStr = file.localizedValue("Icon").toString(); + QAction *action = new QAction(iconStr.isEmpty() ? QIcon() : file.icon(), file.name(), d->menuActionHolder); + QStringList entryActionList = file.actions(); + if (!entryActionList.isEmpty()) { + DFileMenu *menu = new DFileMenu(); + d->menuList.append(menu); + for (const QString &actionName : entryActionList) { + QAction *subAction = new QAction(file.actionIcon(actionName), file.actionName(actionName), d->menuActionHolder); + connect(subAction, &QAction::triggered, this, [subAction, actionName, file]() { + QStringList files = subAction->data().toStringList(); + file.actionActivate(actionName, files); + }); + menu->addAction(subAction); + } + action->setMenu(menu); + } + + connect(action, &QAction::triggered, this, [action, file]() { + QStringList files = action->data().toStringList(); + file.startDetached(files); + }); + + d->actionList.append(action); + + SET_PROPERTY_IFEXIST(action, file, QLatin1String(MIME_TYPE_KEY)); + SET_PROPERTY_IFEXIST(action, file, d->MENU_HIDDEN_KEY); + SET_PROPERTY_IFEXIST(action, file, d->MIMETYPE_EXCLUDE_KEY); + SET_PROPERTY_IFEXIST(action, file, d->SUPPORT_SCHEMES_KEY); + SET_PROPERTY_IFEXIST(action, file, d->SUPPORT_SUFFIX_KEY); + + for (const QString &oneType : menuTypes) { + d->actionListByType[oneType].append(action); + } + } + } +} + +DFMAdditionalMenu::DFMAdditionalMenu(QObject *parent) + : QObject(parent) + , d_private(new DFMAdditionalMenuPrivate(this)) +{ + loadDesktopFile(); +} + +DFMAdditionalMenu::~DFMAdditionalMenu() +{ + +} + +void DFMAdditionalMenu::appendParentMineType(const QStringList &parentmimeTypes, QStringList &mimeTypes) +{ + if (parentmimeTypes.size() == 0) + return; + + for (const QString &mtName : parentmimeTypes) { + QMimeDatabase db; + QMimeType mt = db.mimeTypeForName(mtName); + mimeTypes.append(mt.name()); + mimeTypes.append(mt.aliases()); + QStringList pmts = mt.parentMimeTypes(); + appendParentMineType(pmts, mimeTypes); + } +} + +QList DFMAdditionalMenu::actions(const QStringList &files, const QString ¤tDir, bool onDesktop/* = false*/) +{ + Q_D(DFMAdditionalMenu); + QString menuType = "EmptyArea"; + if (files.size() == 0) { + return d->emptyAreaActoins(currentDir, onDesktop); + } + + if (files.count() == 1) { + menuType = QFileInfo(DUrl(files.first()).toLocalFile()).isDir() ? "SingleDir" : "SingleFile"; + } else { + menuType = "MultiFileDirs"; + } + QList actions = d->actionListByType[menuType]; + bool bex7z = d->isAllEx7zFile(files); + for (const QString &f : files) { + DAbstractFileInfoPointer fileInfo; + DUrl url = DUrl(f); + fileInfo = DFileService::instance()->createFileInfo(this, url); + + if (!fileInfo) { + qWarning() << "createFileInfo failed: " << f; + continue; + } + + if (actions.size() == 0) { + break; + } + + QStringList fileMimeTypes, fmts; + fileMimeTypes.append(fileInfo->mimeType().name()); + fileMimeTypes.append(fileInfo->mimeType().aliases()); + const QMimeType &mt = fileInfo->mimeType(); + fmts = fileMimeTypes; + appendParentMineType(mt.parentMimeTypes(), fileMimeTypes); + fileMimeTypes.removeAll({}); + fmts.removeAll({}); + + for (auto it = actions.begin(); it != actions.end();) { + QAction *action = *it; + if (!action || !d->isActionShouldShow(action, onDesktop) || + !d->isSchemeSupport(action, url) || + !d->isSuffixSupport(action, url, bex7z)) { + it = actions.erase(it); + continue; + } + //fix bug 63917 ftp上不支持压缩,所以这里去掉压缩 + if (action->text() == QObject::tr("Compress") && + FileUtils::isFtpFile(url)){ + it = actions.erase(it); + continue; + } + + // match exclude mime types + QStringList excludeMimeTypes = action->property(d->MIMETYPE_EXCLUDE_KEY.data()).toStringList(); + excludeMimeTypes.removeAll({}); + // 排除时不包含 parentMimeTypes 不然容易误伤, 比如xlsx的 parentMimeTypes 是application/zip + bool match = d->isMimeTypeMatch(fmts, excludeMimeTypes); + if (match) { + it = actions.erase(it); + continue; + } + + // MimeType not exist == MimeType=* + if (!action->property(MIME_TYPE_KEY).isValid()) { + ++it; + continue; + } + + // match support mime types + QStringList supportMimeTypes = action->property(MIME_TYPE_KEY).toStringList(); + supportMimeTypes.removeAll({}); + match = d->isMimeTypeMatch(fileMimeTypes, supportMimeTypes); + + //部分mtp挂载设备目录下文件属性不符合规范(普通目录mimetype被认为是octet-stream),暂时做特殊处理 + if (url.path().contains("/mtp:host") && supportMimeTypes.contains("application/octet-stream") && fileMimeTypes.contains("application/octet-stream")) { + match = false; + } + + if (!match) { + it = actions.erase(it); + continue; + } + + ++it; + } + } + + // Add file list data. + for (QAction *action : actions) { + action->setData(files); + if (action->menu()) { + for (QAction *subAction : action->menu()->actions()) { + subAction->setData(files); + } + } + } + + return actions; +} + + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/dfmadditionalmenu.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/dfmadditionalmenu.h new file mode 100644 index 0000000..45ad723 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/dfmadditionalmenu.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Mike Chen + * + * Maintainer: Mike Chen + * + * 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 + * 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 . + */ +#pragma once + +#include +#include + +DFM_BEGIN_NAMESPACE + +class DFMAdditionalMenuPrivate; +class DFMAdditionalMenu : public QObject +{ + Q_OBJECT +public: + explicit DFMAdditionalMenu(QObject *parent = nullptr); + ~DFMAdditionalMenu(); + + // files.size() == 0 is emptyArea + QList actions(const QStringList &files, const QString ¤tDir = QString(), bool onDesktop = false); +protected: + void appendParentMineType(const QStringList &parentmimeTypes, QStringList& mimeTypes); + + void loadDesktopFile(); + +private: + + QScopedPointer d_private; + Q_DECLARE_PRIVATE_D(d_private, DFMAdditionalMenu) + + Q_DISABLE_COPY(DFMAdditionalMenu) +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/dfmadditionalmenu_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/dfmadditionalmenu_p.h new file mode 100644 index 0000000..081a036 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/dfmadditionalmenu_p.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Mike Chen + * + * Maintainer: Mike Chen + * + * 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 + * 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 . + */ +#ifndef DFMADDITIONALMENU_P_H +#define DFMADDITIONALMENU_P_H + +#include +#include +#include +#include + +DFM_BEGIN_NAMESPACE + +class DFMAdditionalMenu; +class DFMAdditionalMenuPrivate : public QSharedData +{ + Q_DECLARE_PUBLIC(DFMAdditionalMenu) +public: + const QStringList AllMenuTypes { + "SingleFile", + "SingleDir", + "MultiFileDirs", + "EmptyArea" + }; + + const QLatin1String MENU_TYPE_KEY {"X-DFM-MenuTypes"}; + const QLatin1String MIMETYPE_EXCLUDE_KEY {"X-DFM-ExcludeMimeTypes"}; + const QLatin1String MENU_HIDDEN_KEY {"X-DFM-NotShowIn"}; // "Desktop", "Filemanager" + const QLatin1String SUPPORT_SCHEMES_KEY {"X-DFM-SupportSchemes"}; // file, trash, tag.. + const QLatin1String SUPPORT_SUFFIX_KEY {"X-DFM-SupportSuffix"}; // for deepin-compress *.7z.001,*.7z.002,*.7z.003... + + explicit DFMAdditionalMenuPrivate(DFMAdditionalMenu *qq); + ~DFMAdditionalMenuPrivate(); + + QStringList getValues(XdgDesktopFile &file, const QLatin1String &key, const QStringList &whiteList = {}); + bool isMimeTypeSupport(const QString &mt, const QStringList &fileMimeTypes); + bool isMimeTypeMatch(const QStringList &fileMimeTypes, const QStringList &supportMimeTypes); + bool isActionShouldShow(QAction *action, bool onDesktop); + bool isSchemeSupport(QAction *action, const DUrl &url); + bool isSuffixSupport(QAction *action, const DUrl &url, const bool ballEx7z = false); + //都是7z分卷压缩文件 + bool isAllEx7zFile(const QStringList &files); + QList emptyAreaActoins(const QString ¤tDir, bool onDesktop); +private: + QList actionList; + QMap > actionListByType; + QObject *menuActionHolder {nullptr}; + QList menuList; + QTimer *m_delayedLoadFileTimer; + + DFMAdditionalMenu *q_ptr; +}; + +DFM_END_NAMESPACE + +#endif // DFMADDITIONALMENU_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/pluginmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/pluginmanager.cpp new file mode 100644 index 0000000..039030f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/pluginmanager.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "pluginmanager.h" +#include "preview/previewinterface.h" +#include +#include "view/viewinterface.h" +#include "interfaces/dfmglobal.h" +#include "interfaces/dfmstandardpaths.h" +#include +#include +#include +#include + +PluginManagerPrivate::PluginManagerPrivate(PluginManager *parent): + q_ptr(parent) +{ + +} + + +PluginManager::PluginManager(QObject *parent) : + QObject(parent), + d_ptr(new PluginManagerPrivate(this)) +{ + +} + +PluginManager::~PluginManager() +{ + +} + +QString PluginManager::PluginDir() +{ + return DFMStandardPaths::location(DFMStandardPaths::PluginsPath); +} + +void PluginManager::loadPlugin() +{ + Q_D(PluginManager); + QStringList pluginChildDirs; + d->expandInfoInterfaces.clear(); + d->viewInterfaces.clear(); + d->previewInterfaces.clear(); + + QStringList pluginDirs = DFMGlobal::PluginLibraryPaths; + + foreach (QString dir, pluginDirs) { + QDir pluginDir(dir); + qDebug() << dir; + pluginChildDirs << "view" << "preview"; + foreach (QString childDir, pluginChildDirs) { + QDir childPluginDir(pluginDir.absoluteFilePath(childDir)); + qDebug() << "load plugin in: " << childPluginDir.absolutePath(); + foreach (QString fileName, childPluginDir.entryList(QDir::Files)) { + QPluginLoader pluginLoader(childPluginDir.absoluteFilePath(fileName)); + QObject *plugin = pluginLoader.instance(); + if (plugin) { + qDebug() << plugin; + + PropertyDialogExpandInfoInterface *expandInfoInterface = qobject_cast(plugin); + if (expandInfoInterface) { + d->expandInfoInterfaces.append(expandInfoInterface); + } + + ViewInterface *viewInterface = qobject_cast(plugin); + if (viewInterface) { + d->viewInterfaces.append(viewInterface); + d->viewInterfacesMap.insert(viewInterface->scheme(), viewInterface); + } + + PreviewInterface *previewInterface = qobject_cast (plugin); + if (previewInterface) { + static int counter = 0; + counter ++; + d->previewInterfaces << previewInterface; + } + } + } + } + } + qDebug() << "expand info size:" << d->expandInfoInterfaces.size(); + qDebug() << "view size:" << d->viewInterfaces.size(); +} + +QList PluginManager::getExpandInfoInterfaces() +{ + Q_D(PluginManager); + return d->expandInfoInterfaces; +} + +QList PluginManager::getViewInterfaces() +{ + Q_D(PluginManager); + return d->viewInterfaces; +} + +QMap PluginManager::getViewInterfacesMap() +{ + Q_D(PluginManager); + return d->viewInterfacesMap; +} + +QList PluginManager::getPreviewInterfaces() +{ + Q_D(PluginManager); + return d->previewInterfaces; +} + +ViewInterface *PluginManager::getViewInterfaceByScheme(const QString &scheme) +{ + Q_D(PluginManager); + if (d->viewInterfacesMap.contains(scheme)) { + return d->viewInterfacesMap.value(scheme); + } + return nullptr; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/pluginmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/pluginmanager.h new file mode 100644 index 0000000..3b018e9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/pluginmanager.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef PLUGINMANAGER_H +#define PLUGINMANAGER_H + +#include +#include +#include + +class MenuInterface; +class PluginManager; +class PropertyDialogExpandInfoInterface; +class ViewInterface; +class PreviewInterface; + +class PluginManagerPrivate { + +public: + explicit PluginManagerPrivate(PluginManager* parent); + + QList expandInfoInterfaces; + QList viewInterfaces; + QMap viewInterfacesMap; + QList previewInterfaces; + +private: + PluginManager* q_ptr {nullptr}; + Q_DECLARE_PUBLIC(PluginManager) +}; + + +class PluginManager : public QObject +{ + Q_OBJECT + +public: + inline static PluginManager* instance(){ + static PluginManager* instance = new PluginManager(); + return instance; + } + + static QString PluginDir(); + + + void loadPlugin(); + QList getExpandInfoInterfaces(); + QList getViewInterfaces(); + QMap getViewInterfacesMap(); + QList getPreviewInterfaces(); + ViewInterface* getViewInterfaceByScheme(const QString& scheme); + +signals: + +public slots: + +private: + explicit PluginManager(QObject *parent = nullptr); + ~PluginManager(); + + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(PluginManager) +}; + +#endif // PLUGINMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/schemeplugininterface.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/schemeplugininterface.h new file mode 100644 index 0000000..179f91b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/schemeplugininterface.h @@ -0,0 +1,64 @@ +/* +* Copyright (C) 2019 ~ 2021 Deepin Technology Co., Ltd. +* +* Author: Xiao Zhiguo +* Maintainer: Xiao Zhiguo +* +* 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 +* 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 . +*/ + +#ifndef SCHEMEPLUGININTERFACE_H +#define SCHEMEPLUGININTERFACE_H + +#include "dfmbaseview.h" +#include "dfmsidebariteminterface.h" +#include "dfmsidebaritem.h" + +#include "dfmcrumbinterface.h" +#include "dfmcrumbmanager.h" + +#define DFMFileSchemePluginInterface_iid "com.deepin.filemanager.DFMFileSchemePluginInterface_iid" + +typedef QPair> CrumbCreaterFunc; +typedef QPair> ViewCreatorFunc; +typedef QPair> SideBarInterfaceCreaterFunc; + +class SchemePluginInterface +{ +public: + virtual ~SchemePluginInterface() = default; + + // 创建SiseBarItem对应的右侧BaseView的回调函数 + virtual ViewCreatorFunc createViewTypeFunc() = 0; + + // 初始化SideBarItem,添加自定义的图标,文字,URL等构造信息 + virtual dde_file_manager::DFMSideBarItem *createSideBarItem() = 0; + + // 初始化SideBarItem对应的Handler,可重载右键菜单功能 + virtual SideBarInterfaceCreaterFunc createSideBarInterfaceTypeFunc() = 0; + + // 初始化面包屑控制器CrumbControl + virtual CrumbCreaterFunc createCrumbCreaterTypeFunc() = 0; + + // 返回插件的名称,用于判断插件的类型,与SideBarItem、DFMBaseView、CrumbControl关联起来 + // [protocol]://[host]:[port]/[path]?[query]#[hash] 对应于QUrl::host()返回的Url + virtual QString pluginName() = 0; + + // 查询插件SideBarItem是否支持拖拽 + virtual bool isSideBarItemSupportedDrop() = 0; + // 向SideBarItem拖拽文件调用DBus接口 + virtual bool dropFileToPlugin(QList srcUrls, DUrl desUrl) = 0; +}; + +Q_DECLARE_INTERFACE(SchemePluginInterface, DFMFileSchemePluginInterface_iid) + +#endif // SCHEMEPLUGININTERFACE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/schemepluginmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/schemepluginmanager.cpp new file mode 100644 index 0000000..46c47da --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/schemepluginmanager.cpp @@ -0,0 +1,67 @@ + +/* +* Copyright (C) 2019 ~ 2019 Deepin Technology Co., Ltd. +* +* Author: Xiao Zhiguo +* Maintainer: Xiao Zhiguo +* +* 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 +* 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 . +*/ +// NOTE [XIAO] +#include "schemepluginmanager.h" +#include "schemeplugininterface.h" +#include "interfaces/dfmstandardpaths.h" +#include +#include +Q_GLOBAL_STATIC(SchemePluginManager, manager); +SchemePluginManager::SchemePluginManager(QObject *parent) + : QObject(parent) +{ +} +SchemePluginManager *SchemePluginManager::instance() +{ + return manager; +} +QString SchemePluginManager::schemePluginDir() +{ + return QString("/usr/lib/dde-file-manager/addons"); +} +void SchemePluginManager::loadSchemePlugin() +{ + qWarning() << schemePluginDir(); + QDir pluginDir(schemePluginDir()); + qWarning() << pluginDir.entryList(QDir::Files); + for (auto pluginFile : pluginDir.entryList(QDir::Files)) { + QPluginLoader pluginLoader(pluginDir.absoluteFilePath(pluginFile)); + QObject *plugin = pluginLoader.instance(); + if (plugin) { + SchemePluginInterface *schemePlugin = qobject_cast(plugin); + if (schemePlugin) { + QString pluginName = schemePlugin->pluginName(); + schemePluginList << qMakePair(pluginName, schemePlugin); + schemePluginPahtList << qMakePair(pluginName, pluginDir.absoluteFilePath(pluginFile)); + qInfo() << "Scheme plugin name:" << pluginName; + qInfo() << "Scheme plugin path:" << pluginDir.absoluteFilePath(pluginFile); + } + } else { + qInfo() << pluginLoader.errorString(); + } + } +} +void SchemePluginManager::unloadSchemePlugin(QString schemeName) +{ + Q_UNUSED(schemeName); +} +SchemePluginList SchemePluginManager::schemePlugins() +{ + return schemePluginList; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/schemepluginmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/schemepluginmanager.h new file mode 100644 index 0000000..fa48268 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/plugins/schemepluginmanager.h @@ -0,0 +1,49 @@ +/* +* Copyright (C) 2019 ~ 2019 Deepin Technology Co., Ltd. +* +* Author: Xiao Zhiguo +* Maintainer: Xiao Zhiguo +* +* 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 +* 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 . +*/ + +// NOTE [XIAO] + +#ifndef SCHEMEPLUGINMANAGER_H +#define SCHEMEPLUGINMANAGER_H + +#include "schemeplugininterface.h" +#include + +typedef QList> SchemePluginList; +typedef QList> SchemePluginPathList; + +class SchemePluginManager : public QObject +{ + Q_OBJECT +public: + explicit SchemePluginManager(QObject *parent = nullptr); + + static SchemePluginManager *instance(); + QString schemePluginDir(); + void loadSchemePlugin(); + void unloadSchemePlugin(QString schemeName); + SchemePluginList schemePlugins(); + +private: + Q_DISABLE_COPY(SchemePluginManager) + + SchemePluginList schemePluginList; + SchemePluginPathList schemePluginPahtList; +}; + +#endif // SCHEMEPLUGINMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/actions/dfm_view_filter_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/actions/dfm_view_filter_16px.svg new file mode 100644 index 0000000..34b36ea --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/actions/dfm_view_filter_16px.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/bluetooth_computer_dark.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/bluetooth_computer_dark.svg new file mode 100644 index 0000000..854690a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/bluetooth_computer_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/bluetooth_phone_dark.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/bluetooth_phone_dark.svg new file mode 100644 index 0000000..54cae05 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/bluetooth_phone_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_add_server_44px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_add_server_44px.svg new file mode 100644 index 0000000..521045b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_add_server_44px.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_addressbar_glowing_128px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_addressbar_glowing_128px.svg new file mode 100644 index 0000000..df2a268 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_addressbar_glowing_128px.svg @@ -0,0 +1,20 @@ + + + + glowing_dark + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_bluetooth_empty_dark.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_bluetooth_empty_dark.svg new file mode 100644 index 0000000..9d0a754 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_bluetooth_empty_dark.svg @@ -0,0 +1,7 @@ + + + icon_ bluetooth/dark + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_deepin_logo_128px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_deepin_logo_128px.svg new file mode 100644 index 0000000..f8a971e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_deepin_logo_128px.svg @@ -0,0 +1,20 @@ + + + + logo + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_del_server_44px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_del_server_44px.svg new file mode 100644 index 0000000..5438963 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_del_server_44px.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_lock_128px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_lock_128px.svg new file mode 100644 index 0000000..32d5bee --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_lock_128px.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_safebox_64px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_safebox_64px.svg new file mode 100644 index 0000000..809f768 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_safebox_64px.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_search_pause_24px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_search_pause_24px.svg new file mode 100644 index 0000000..3b2a6a5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_search_pause_24px.svg @@ -0,0 +1,22 @@ + + + button/stop-dark + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tab_new_24px.svg/normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tab_new_24px.svg/normal.svg new file mode 100644 index 0000000..05a93d4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tab_new_24px.svg/normal.svg @@ -0,0 +1,27 @@ + + + + button_add_normal_dark + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tab_new_24px.svg/pressed.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tab_new_24px.svg/pressed.svg new file mode 100644 index 0000000..49e9ae9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tab_new_24px.svg/pressed.svg @@ -0,0 +1,27 @@ + + + + button_add_press_dark + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_16px.svg new file mode 100644 index 0000000..6acfe5c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_16px.svg @@ -0,0 +1,11 @@ + + + + tag + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_deepblue_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_deepblue_16px.svg new file mode 100644 index 0000000..ee671f6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_deepblue_16px.svg @@ -0,0 +1,15 @@ + + + + tag_deepblue_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_gray_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_gray_16px.svg new file mode 100644 index 0000000..2038ff9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_gray_16px.svg @@ -0,0 +1,15 @@ + + + + tag_gray_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_green_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_green_16px.svg new file mode 100644 index 0000000..20671f7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_green_16px.svg @@ -0,0 +1,15 @@ + + + + tag_green_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_lightblue_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_lightblue_16px.svg new file mode 100644 index 0000000..e24702d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_lightblue_16px.svg @@ -0,0 +1,15 @@ + + + + tag_lightblue_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_orange_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_orange_16px.svg new file mode 100644 index 0000000..5175d8e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_orange_16px.svg @@ -0,0 +1,15 @@ + + + + tag_orange_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_purple_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_purple_16px.svg new file mode 100644 index 0000000..27d6cd3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_purple_16px.svg @@ -0,0 +1,15 @@ + + + + tag_purple_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_red_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_red_16px.svg new file mode 100644 index 0000000..7cf2a27 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_red_16px.svg @@ -0,0 +1,15 @@ + + + + tag_red_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_yellow_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_yellow_16px.svg new file mode 100644 index 0000000..9eacc2e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_tag_yellow_16px.svg @@ -0,0 +1,15 @@ + + + + tag_yellow_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_task_pause_24px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_task_pause_24px.svg new file mode 100644 index 0000000..d53276b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_task_pause_24px.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_task_start_24px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_task_start_24px.svg new file mode 100644 index 0000000..fda183c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_task_start_24px.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_task_stop_24px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_task_stop_24px.svg new file mode 100644 index 0000000..fbdd96b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_task_stop_24px.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_vault_active_encrypt_128px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_vault_active_encrypt_128px.svg new file mode 100644 index 0000000..fc1df00 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_vault_active_encrypt_128px.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_vault_active_start_128px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_vault_active_start_128px.svg new file mode 100644 index 0000000..e077010 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/dfm_vault_active_start_128px.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/media-external-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/media-external-256px.svg new file mode 100644 index 0000000..880f591 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/dark/icons/media-external-256px.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_close_round_normal_24px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_close_round_normal_24px.svg new file mode 100644 index 0000000..e64a22c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_close_round_normal_24px.svg @@ -0,0 +1,15 @@ + + + + close_round_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_vault_210px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_vault_210px.svg new file mode 100644 index 0000000..d5b5258 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_vault_210px.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_vault_32px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_vault_32px.svg new file mode 100644 index 0000000..b7044cf --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_vault_32px.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_vault_active_finish_128px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_vault_active_finish_128px.svg new file mode 100644 index 0000000..409561f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_vault_active_finish_128px.svg @@ -0,0 +1,31 @@ + + + + success + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_vault_active_finish_30px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_vault_active_finish_30px.svg new file mode 100644 index 0000000..1a7f207 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/icons/dfm_vault_active_finish_30px.svg @@ -0,0 +1,35 @@ + + + + icon_toast_sucess + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/actions/dfm_view_filter_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/actions/dfm_view_filter_16px.svg new file mode 100644 index 0000000..dfd01cb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/actions/dfm_view_filter_16px.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/bluetooth_computer_light.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/bluetooth_computer_light.svg new file mode 100644 index 0000000..be57cfd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/bluetooth_computer_light.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/bluetooth_phone_light.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/bluetooth_phone_light.svg new file mode 100644 index 0000000..5c75b1a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/bluetooth_phone_light.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_add_server_44px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_add_server_44px.svg new file mode 100644 index 0000000..0c64b0c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_add_server_44px.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_addressbar_glowing_128px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_addressbar_glowing_128px.svg new file mode 100644 index 0000000..643a968 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_addressbar_glowing_128px.svg @@ -0,0 +1,18 @@ + + + + glowing_light + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_bluetooth_empty_light.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_bluetooth_empty_light.svg new file mode 100644 index 0000000..9fe2cb7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_bluetooth_empty_light.svg @@ -0,0 +1,7 @@ + + + icon_ bluetooth/light + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_deepin_logo_128px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_deepin_logo_128px.svg new file mode 100644 index 0000000..f8a971e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_deepin_logo_128px.svg @@ -0,0 +1,20 @@ + + + + logo + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_del_server_44px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_del_server_44px.svg new file mode 100644 index 0000000..5ccbabe --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_del_server_44px.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_lock_128px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_lock_128px.svg new file mode 100644 index 0000000..32d5bee --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_lock_128px.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_safebox_64px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_safebox_64px.svg new file mode 100644 index 0000000..809f768 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_safebox_64px.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_search_pause_24px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_search_pause_24px.svg new file mode 100644 index 0000000..5703d20 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_search_pause_24px.svg @@ -0,0 +1,22 @@ + + + button/stop + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tab_new_24px.svg/normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tab_new_24px.svg/normal.svg new file mode 100644 index 0000000..f7dfeaa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tab_new_24px.svg/normal.svg @@ -0,0 +1,26 @@ + + + + button_add + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tab_new_24px.svg/pressed.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tab_new_24px.svg/pressed.svg new file mode 100644 index 0000000..0424cc7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tab_new_24px.svg/pressed.svg @@ -0,0 +1,26 @@ + + + + button_add_press + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_16px.svg new file mode 100644 index 0000000..6acfe5c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_16px.svg @@ -0,0 +1,11 @@ + + + + tag + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_deepblue_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_deepblue_16px.svg new file mode 100644 index 0000000..ee671f6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_deepblue_16px.svg @@ -0,0 +1,15 @@ + + + + tag_deepblue_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_gray_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_gray_16px.svg new file mode 100644 index 0000000..2038ff9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_gray_16px.svg @@ -0,0 +1,15 @@ + + + + tag_gray_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_green_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_green_16px.svg new file mode 100644 index 0000000..20671f7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_green_16px.svg @@ -0,0 +1,15 @@ + + + + tag_green_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_lightblue_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_lightblue_16px.svg new file mode 100644 index 0000000..e24702d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_lightblue_16px.svg @@ -0,0 +1,15 @@ + + + + tag_lightblue_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_orange_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_orange_16px.svg new file mode 100644 index 0000000..5175d8e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_orange_16px.svg @@ -0,0 +1,15 @@ + + + + tag_orange_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_purple_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_purple_16px.svg new file mode 100644 index 0000000..27d6cd3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_purple_16px.svg @@ -0,0 +1,15 @@ + + + + tag_purple_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_red_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_red_16px.svg new file mode 100644 index 0000000..7cf2a27 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_red_16px.svg @@ -0,0 +1,15 @@ + + + + tag_red_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_yellow_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_yellow_16px.svg new file mode 100644 index 0000000..9eacc2e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_tag_yellow_16px.svg @@ -0,0 +1,15 @@ + + + + tag_yellow_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_task_pause_24px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_task_pause_24px.svg new file mode 100644 index 0000000..c26f9e5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_task_pause_24px.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_task_start_24px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_task_start_24px.svg new file mode 100644 index 0000000..4cabbbd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_task_start_24px.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_task_stop_24px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_task_stop_24px.svg new file mode 100644 index 0000000..3871fd0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_task_stop_24px.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_vault_active_encrypt_128px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_vault_active_encrypt_128px.svg new file mode 100644 index 0000000..885db5c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_vault_active_encrypt_128px.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_vault_active_start_128px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_vault_active_start_128px.svg new file mode 100644 index 0000000..dde2bce --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/dfm_vault_active_start_128px.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/media-external-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/media-external-256px.svg new file mode 100644 index 0000000..880f591 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/light/icons/media-external-256px.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/texts/dfm_rightview_detail_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/texts/dfm_rightview_detail_16px.svg new file mode 100644 index 0000000..6f5eec8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/texts/dfm_rightview_detail_16px.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/texts/dfm_viewlist_details_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/texts/dfm_viewlist_details_16px.svg new file mode 100644 index 0000000..615a574 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/texts/dfm_viewlist_details_16px.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/texts/dfm_viewlist_icons_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/texts/dfm_viewlist_icons_16px.svg new file mode 100644 index 0000000..ec07c4d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/icons/deepin/builtin/texts/dfm_viewlist_icons_16px.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/resources.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/resources.qrc new file mode 100644 index 0000000..60111e6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/resources/resources.qrc @@ -0,0 +1,66 @@ + + + icons/deepin/builtin/light/icons/dfm_tag_deepblue_16px.svg + icons/deepin/builtin/light/icons/dfm_tag_green_16px.svg + icons/deepin/builtin/light/icons/dfm_tag_lightblue_16px.svg + icons/deepin/builtin/light/icons/dfm_tag_orange_16px.svg + icons/deepin/builtin/light/icons/dfm_tag_purple_16px.svg + icons/deepin/builtin/light/icons/dfm_tag_red_16px.svg + icons/deepin/builtin/light/icons/dfm_tag_yellow_16px.svg + icons/deepin/builtin/light/icons/dfm_tag_16px.svg + icons/deepin/builtin/dark/icons/dfm_tag_deepblue_16px.svg + icons/deepin/builtin/dark/icons/dfm_tag_green_16px.svg + icons/deepin/builtin/dark/icons/dfm_tag_lightblue_16px.svg + icons/deepin/builtin/dark/icons/dfm_tag_orange_16px.svg + icons/deepin/builtin/dark/icons/dfm_tag_purple_16px.svg + icons/deepin/builtin/dark/icons/dfm_tag_red_16px.svg + icons/deepin/builtin/dark/icons/dfm_tag_yellow_16px.svg + icons/deepin/builtin/dark/icons/dfm_tag_16px.svg + icons/deepin/builtin/dark/icons/dfm_tag_gray_16px.svg + icons/deepin/builtin/light/icons/dfm_tag_gray_16px.svg + icons/deepin/builtin/light/actions/dfm_view_filter_16px.svg + icons/deepin/builtin/dark/actions/dfm_view_filter_16px.svg + icons/deepin/builtin/light/icons/dfm_addressbar_glowing_128px.svg + icons/deepin/builtin/dark/icons/dfm_addressbar_glowing_128px.svg + icons/deepin/builtin/light/icons/dfm_safebox_64px.svg + icons/deepin/builtin/dark/icons/dfm_safebox_64px.svg + icons/deepin/builtin/dark/icons/dfm_lock_128px.svg + icons/deepin/builtin/light/icons/dfm_lock_128px.svg + icons/deepin/builtin/dark/icons/dfm_deepin_logo_128px.svg + icons/deepin/builtin/light/icons/dfm_deepin_logo_128px.svg + icons/deepin/builtin/light/icons/dfm_task_start_24px.svg + icons/deepin/builtin/dark/icons/dfm_task_start_24px.svg + icons/deepin/builtin/light/icons/dfm_task_stop_24px.svg + icons/deepin/builtin/dark/icons/dfm_task_stop_24px.svg + icons/deepin/builtin/light/icons/dfm_task_pause_24px.svg + icons/deepin/builtin/dark/icons/dfm_task_pause_24px.svg + icons/deepin/builtin/icons/dfm_close_round_normal_24px.svg + icons/deepin/builtin/light/icons/dfm_add_server_44px.svg + icons/deepin/builtin/dark/icons/dfm_add_server_44px.svg + icons/deepin/builtin/light/icons/dfm_del_server_44px.svg + icons/deepin/builtin/dark/icons/dfm_del_server_44px.svg + icons/deepin/builtin/light/icons/dfm_tab_new_24px.svg + icons/deepin/builtin/dark/icons/dfm_tab_new_24px.svg + icons/deepin/builtin/texts/dfm_viewlist_icons_16px.svg + icons/deepin/builtin/texts/dfm_viewlist_details_16px.svg + icons/deepin/builtin/texts/dfm_rightview_detail_16px.svg + icons/deepin/builtin/dark/icons/media-external-256px.svg + icons/deepin/builtin/light/icons/media-external-256px.svg + icons/deepin/builtin/icons/dfm_vault_210px.svg + icons/deepin/builtin/icons/dfm_vault_active_finish_30px.svg + icons/deepin/builtin/icons/dfm_vault_active_finish_128px.svg + icons/deepin/builtin/icons/dfm_vault_32px.svg + icons/deepin/builtin/light/icons/dfm_vault_active_encrypt_128px.svg + icons/deepin/builtin/light/icons/dfm_vault_active_start_128px.svg + icons/deepin/builtin/dark/icons/dfm_vault_active_encrypt_128px.svg + icons/deepin/builtin/dark/icons/dfm_vault_active_start_128px.svg + icons/deepin/builtin/dark/icons/dfm_bluetooth_empty_dark.svg + icons/deepin/builtin/light/icons/dfm_bluetooth_empty_light.svg + icons/deepin/builtin/dark/icons/bluetooth_phone_dark.svg + icons/deepin/builtin/light/icons/bluetooth_phone_light.svg + icons/deepin/builtin/light/icons/bluetooth_computer_light.svg + icons/deepin/builtin/dark/icons/bluetooth_computer_dark.svg + icons/deepin/builtin/dark/icons/dfm_search_pause_24px.svg + icons/deepin/builtin/light/icons/dfm_search_pause_24px.svg + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/search/dfsearch.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/search/dfsearch.cpp new file mode 100644 index 0000000..f3832bc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/search/dfsearch.cpp @@ -0,0 +1,153 @@ +/* +* Copyright (C) 2019 ~ 2020 Uniontech Technology Co., Ltd. +* +* Author: hujianzhong +* +* Maintainer: hujianzhong +* +* 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 +* 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 . +* +* This program is the full text search at dde-file-manager. +*/ +#include "dfsearch.h" +#include +#include +#include + +extern "C" +{ +#include "fsearch_config.h" +} + + +DFSearch::DFSearch(const QString &searchPath, void *parent) + : caller(parent) + , pathForSearching(searchPath) +{ + app = (FsearchApplication *) calloc(1, sizeof(FsearchApplication)); + app->config = (FsearchConfig *)calloc(1, sizeof(FsearchConfig)); + if (!config_load_default(app->config)) { + } + app->db = nullptr; + app->search = nullptr; + app->config->locations = nullptr; + g_mutex_init(&app->mutex); + app->pool = fsearch_thread_pool_init(); //初始化线程池 + app->search = db_search_new(fsearch_application_get_thread_pool(app)); +} + +DFSearch::~DFSearch() +{ + FsearchApplication *fsearch = app; + if (app == nullptr) { + return; + } + + if (fsearch->db) { +// db_save_locations (fsearch->db); + db_clear(fsearch->db); + db_free(fsearch->db);//内存数据库释放 + } + if (fsearch->pool) { + fsearch_thread_pool_free(fsearch->pool); + } +// config_save (fsearch->config); + config_free(fsearch->config); + db_search_free(fsearch->search); + g_mutex_clear(&fsearch->mutex); + free(app); + app = nullptr; +} + +void DFSearch::searchByKeyWord(const QString &key, void (*callback)(void *, void *)) +{ + // 防止在db_search_results_clear中触发断言,导致文管退出,先自行判断一下 + if (app->search == nullptr) return; + + QByteArray pathBytes(pathForSearching.toLocal8Bit()); + load_database(app, pathBytes.data(), &state);//加载数据库 + if (!state) + return; + + cbFunc = callback; + db_search_results_clear(app->search); + Database *db = app->db; + if (!db_try_lock(db)) { + return ; + } + if (app->search) { + db_search_update(app->search, + db_get_entries(db), + db_get_num_entries(db), + 50000, + FsearchFilter::FSEARCH_FILTER_NONE, + key.toStdString().c_str(), + app->config->hide_results_on_empty_search, + app->config->match_case, + app->config->enable_regex, + app->config->auto_search_in_path, + app->config->search_in_path); + + db_perform_search(app->search, fsearch_application_window_update_results, app, this); + } + db_unlock(db); + return ; +} + +void DFSearch::stop() +{ + state = false; +} + +bool DFSearch::isSupportFSearch(const QString &path) +{ + if (path.isEmpty()) + return false; + + QByteArray searchPath = path.toLocal8Bit(); + return db_support(searchPath.data(), path.startsWith("/data")); +} + +void DFSearch::fsearch_application_window_update_results(void *data, void *sender) +{ +// g_idle_add (update_model_cb, data); + update_model_cb(data, sender); +} + +gboolean DFSearch::update_model_cb(gpointer user_data, gpointer sender) +{ + DatabaseSearchResult *result = static_cast(user_data); + DFSearch *self = static_cast(sender); + // 防止在db_search_results_clear中触发断言,导致文管退出,先自行判断一下 + if (self->app->search == nullptr) return FALSE; + db_search_results_clear(self->app->search); + self->results = nullptr; + self->num_results = 0; + self->results = result->results; + if (self->results) { + self->app->search->results = self->results; + self->app->search->num_folders = result->num_folders;; + self->app->search->num_files = result->num_files; + self->num_results = self->results->len; + self->cbFunc(self->app->search, self->caller); + } else { + self->app->search->results = nullptr; + self->app->search->num_folders = 0; + self->app->search->num_files = 0; + self->num_results = 0; + } + free(result); + result = nullptr; + return FALSE; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/search/dfsearch.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/search/dfsearch.h new file mode 100644 index 0000000..c2a55bb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/search/dfsearch.h @@ -0,0 +1,65 @@ +/* +* Copyright (C) 2019 ~ 2020 Uniontech Technology Co., Ltd. +* +* Author: hujianzhong +* +* Maintainer: hujianzhong +* +* 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 +* 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 . +*/ +#ifndef __DFSEARCH_H__ +#define __DFSEARCH_H__ + +#include + +extern "C" +{ +#include "fsearch.h" +} + +class DFSearch +{ + typedef void (*callbackFunc)(void *, void *); +public: + DFSearch(const QString &searchPath, void *parent = nullptr); + + ~DFSearch(); + + DFSearch(DFSearch &) = delete; + DFSearch &operator=(DFSearch &) = delete; + + void searchByKeyWord(const QString &key, void (*callback)(void *, void *)); + + void stop(); + + static bool isSupportFSearch(const QString &path); + +private: + static void fsearch_application_window_update_results(void *data, void *sender); + + static gboolean update_model_cb(gpointer user_data, gpointer sender); +private: + FsearchApplication *app = nullptr; + callbackFunc cbFunc = nullptr; + GPtrArray *results = nullptr; + uint num_results = 0; + void *caller = nullptr; + /** + * @brief state 搜索状态值,用于打断后续遍历文件夹 + */ + bool state = true; + QString pathForSearching; +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/search/dfsearch.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/search/dfsearch.pri new file mode 100644 index 0000000..2286de5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/search/dfsearch.pri @@ -0,0 +1,53 @@ +# Copyright (C) 2019 ~ 2020 Uniontech Technology Co., Ltd. + +#Author: hujianzhong + +#Maintainer: hujianzhong + +#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 +#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 . + +#This program is the full text search at dde-file-manager. +#------------------------------------------------- +# +# Project created by QtCreator 2020-05-12T16:00:00 +#这个搜索引擎是利用C语言和GTK代码编写,文件搜索速度相当快,是移植的开源代码fsearch的核心部分 +#------------------------------------------------- +HEADERS += \ + $$PWD/dfsearch.h \ + $$PWD/../../../3rdparty/fsearch/array.h \ + $$PWD/../../../3rdparty/fsearch/btree.h \ + $$PWD/../../../3rdparty/fsearch/database_search.h \ + $$PWD/../../../3rdparty/fsearch/database.h \ + $$PWD/../../../3rdparty/fsearch/fsearch_config.h \ + $$PWD/../../../3rdparty/fsearch/fsearch_limits.h \ + $$PWD/../../../3rdparty/fsearch/fsearch_thread_pool.h \ + $$PWD/../../../3rdparty/fsearch/fsearch.h \ + $$PWD/../../../3rdparty/fsearch/query.h \ + $$PWD/../../../3rdparty/fsearch/string_utils.h \ + $$PWD/../../../3rdparty/fsearch/utf8.h + +SOURCES += \ + $$PWD/dfsearch.cpp \ + $$PWD/../../../3rdparty/fsearch/array.c \ + $$PWD/../../../3rdparty/fsearch/btree.c \ + $$PWD/../../../3rdparty/fsearch/database_search.c \ + $$PWD/../../../3rdparty/fsearch/database.c \ + $$PWD/../../../3rdparty/fsearch/fsearch_config.c \ + $$PWD/../../../3rdparty/fsearch/fsearch_thread_pool.c \ + $$PWD/../../../3rdparty/fsearch/fsearch.c \ + $$PWD/../../../3rdparty/fsearch/query.c \ + $$PWD/../../../3rdparty/fsearch/string_utils.c + +CONFIG += link_pkgconfig + +INCLUDEPATH += $$PWD/../../../3rdparty/fsearch/ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/settings_dialog_json.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/settings_dialog_json.pri new file mode 100644 index 0000000..01c7b39 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/settings_dialog_json.pri @@ -0,0 +1,6 @@ +lupdate_only { + SOURCES += \ + configure/global-setting-template.js \ + configure/global-setting-template-pro.js \ + configure/global-setting-template-fedora.js \ +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/checknetwork.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/checknetwork.cpp new file mode 100644 index 0000000..9543587 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/checknetwork.cpp @@ -0,0 +1,47 @@ +#include "checknetwork.h" + +#include +#include +#include +#include + +CheckNetwork::CheckNetwork(QObject *parent) : QObject(parent) +{ + +} + +bool CheckNetwork::isHostAndPortConnect(const QString &host, const QString &port) +{ + addrinfo *result; + addrinfo hints{}; + hints.ai_family = AF_UNSPEC; // either IPv4 or IPv6 + hints.ai_socktype = SOCK_STREAM; + char addressString[INET6_ADDRSTRLEN]; + const char *retval = nullptr; + if (0 != getaddrinfo(host.toUtf8().toStdString().c_str(), port.toUtf8().toStdString().c_str(), &hints, &result)) { + return false; + } + for (addrinfo *addr = result; addr != nullptr; addr = addr->ai_next) { + int handle = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + if (handle == -1) { + continue; + } + if (::connect(handle, addr->ai_addr, addr->ai_addrlen) != -1) { + switch(addr->ai_family) { + case AF_INET: + retval = inet_ntop(addr->ai_family, &(reinterpret_cast(addr->ai_addr)->sin_addr), addressString, INET6_ADDRSTRLEN); + break; + case AF_INET6: + retval = inet_ntop(addr->ai_family, &(reinterpret_cast(addr->ai_addr)->sin6_addr), addressString, INET6_ADDRSTRLEN); + break; + default: + // unknown family + retval = nullptr; + } + close(handle); + break; + } + } + freeaddrinfo(result); + return retval != nullptr; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/checknetwork.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/checknetwork.h new file mode 100644 index 0000000..d07d09c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/checknetwork.h @@ -0,0 +1,26 @@ +#ifndef CHECKNETWORK_H +#define CHECKNETWORK_H + +#include +#include +#include +#include +#include + +#include + +class CheckNetwork : public QObject +{ + Q_OBJECT +public: + explicit CheckNetwork(QObject *parent = nullptr); + bool isHostAndPortConnect(const QString &host, const QString &port); +signals: + +public slots: + +private: + //save host and port +}; + +#endif // CHECKNETWORK_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/danythingmonitor.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/danythingmonitor.cpp new file mode 100644 index 0000000..878cba6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/danythingmonitor.cpp @@ -0,0 +1,228 @@ + +#include "danythingmonitor.h" +#include "tag/tagmanager.h" +#include "dfileinfo.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +} +#endif + +#include + + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +typedef struct __vc_ioctl_readdata_args__ { + int size; + char *data; +} ioctl_rd_args; + +typedef struct __vc_ioctl_readstat_args__ { + int total_changes; + int cur_changes; + int discarded; + int cur_memory; +} ioctl_rs_args; + +#define VC_IOCTL_MAGIC 0x81 +#define VC_IOCTL_READDATA _IOR(VC_IOCTL_MAGIC, 0, long) +#define VC_IOCTL_READSTAT _IOR(VC_IOCTL_MAGIC, 1, long) + +#ifdef __cplusplus +} +#endif + + +enum : int { + ACT_NEW_FILE = 0, + ACT_NEW_LINK, + ACT_NEW_SYMLINK, + ACT_NEW_FOLDER, + ACT_DEL_FILE, + ACT_DEL_FOLDER, + ACT_RENAME_FILE, + ACT_RENAME_FOLDER + +}; + +//PROTOCOL_HEAD与act_names暂时未使用,为了避免未用警告,暂时屏蔽之 +//static const char *const PROTOCOL_HEAD{ "file://" }; +static const char *const PROCFS_PATH{ "/proc/vfs_changes" }; +//constexpr static const char *const act_names[] {"file_created", "link_created", +// "symlink_created", "dir_created", +// "file_deleted", "dir_deleted", +// "file_renamed", "dir_renamed" +//}; + + + +static QString StartPoint{}; + +DAnythingMonitor::DAnythingMonitor(QObject *const parent) + : QObject{ parent } +{ + ///###: constructor. +} + + +void DAnythingMonitor::doWork() +{ + std::unique_lock raiiLock{ m_mutex }; + + m_conditionVar.wait(raiiLock, [this] { + bool expected{ true }; + return this->m_readyFlag.compare_exchange_strong(expected, false, std::memory_order_seq_cst); + }); + + if (!m_changedFiles.empty()) { + std::deque>::const_iterator cbeg{ m_changedFiles.cbegin() }; + std::deque>::const_iterator cend{ m_changedFiles.cend() }; + + + for (; cbeg != cend; ++cbeg) { + + if (cbeg->first.isEmpty()) { + +#ifdef QT_DEBUG + qDebug() << cbeg->second; +#endif + TagManager::instance()->deleteFiles({DUrl::fromLocalFile(cbeg->second)}); + + continue; + } + + QPair oldAndNewFileName{ cbeg->first.toLocal8Bit(), cbeg->second.toLocal8Bit() }; + +#ifdef QT_DEBUG + qDebug() << oldAndNewFileName; +#endif + + TagManager::instance()->changeFilesName({ oldAndNewFileName }); + } + + m_changedFiles.clear(); + } +} + +void DAnythingMonitor::notify() noexcept +{ + bool excepted{ false }; + if (this->m_readyFlag.compare_exchange_strong(excepted, true, std::memory_order_seq_cst)) { + this->m_conditionVar.notify_one(); + } +} + +void DAnythingMonitor::workSignal() +{ + + std::lock_guard raiiLock{ m_mutex }; + + int fd = open(PROCFS_PATH, O_RDONLY); + if (fd < 0) { + notify(); + + return; + } + + ioctl_rs_args irsa; + if (ioctl(fd, VC_IOCTL_READSTAT, &irsa) != 0) { + close(fd); + notify(); + + return; + } + + if (irsa.cur_changes == 0) { + close(fd); + notify(); + + return; + } + + char buf[1 << 20] {}; + ioctl_rd_args ira ; + ira.data = buf; + + + while (true) { + ira.size = sizeof(buf); + if (ioctl(fd, VC_IOCTL_READDATA, &ira) != 0) { + break; + } + + // no more changes + if (ira.size == 0) { + break; + } + + int off = 0; + for (int i = 0; i < ira.size; i++) { + unsigned char action = static_cast(*(ira.data + off)); + off++; + char *src = ira.data + off, *dst = nullptr; + off += strlen(src) + 1; + + switch (action) { + ///###: do not delete this. + // case ACT_NEW_FILE: + // case ACT_NEW_SYMLINK: + // case ACT_NEW_LINK: + // case ACT_NEW_FOLDER: + // { + // qDebug()<< act_names[action] << "-------->" << src; + // } + case ACT_DEL_FILE: + case ACT_DEL_FOLDER: { + m_changedFiles.emplace_back(QString{}, QString{src}); + //#ifdef QT_DEBUG + // qDebug()<< act_names[action] << "--------->" << src; + //#endif + break; + } + case ACT_RENAME_FILE: + case ACT_RENAME_FOLDER: { + dst = ira.data + off; + off += strlen(dst) + 1; + m_changedFiles.emplace_back(QString{src}, + QString{dst}); + //#ifdef QT_DEBUG + // qDebug()<< act_names[action] << src << "--------->" << dst; + //#endif + break; + } + default: + break; + } + } + } + close(fd); + + + notify(); +} + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/danythingmonitor.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/danythingmonitor.h new file mode 100644 index 0000000..76601f2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/danythingmonitor.h @@ -0,0 +1,65 @@ +#ifndef FILEMONITOR_H +#define FILEMONITOR_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif //__cplusplus + +#include + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +QT_DEPRECATED class DAnythingMonitor final : public QObject +{ + Q_OBJECT +public: + explicit DAnythingMonitor(QObject* const parent = nullptr); + DAnythingMonitor(const DAnythingMonitor& other)=delete; + DAnythingMonitor& operator=(const DAnythingMonitor& other)=delete; + virtual ~DAnythingMonitor()=default; + + + void workSignal(); + void doWork(); + +private: + + void notify() noexcept; + + ///###: why delete and rename operation use the same data structure. + ///###: if use different data structure. Maybe the deleting was previous of renaming. + ///### but we synchronize with sqlite through these data tructure. Maybe the renamed files were deleted. + ///### Or, reverse. + std::deque> m_changedFiles{}; + + std::mutex m_mutex{}; + std::condition_variable m_conditionVar{}; + + std::atomic m_readyFlag{ false }; +}; + +#endif // FILEMONITOR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/danythingmonitorfilter.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/danythingmonitorfilter.cpp new file mode 100644 index 0000000..9ada093 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/danythingmonitorfilter.cpp @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: shihua + * + * Maintainer: shihua + * + * 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 + * 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 . + */ + +#include +#include +#include +#include + +#include "dfmsettings.h" +#include "dfmapplication.h" +#include "danythingmonitorfilter.h" + +#include +#include +#include +#include +#include +#include +#include + + +namespace detail { + +static const std::map StrTableOfEscapeChar{ + {"\\007", "\a"}, + {"\\010", "\b"}, + {"\\014", "\f"}, + {"\\012", "\n"}, + {"\\015", "\r"}, + {"\\011", "\t"}, + {"\\013", "\v"}, + {"\\134", "\\"}, + {"\\047", "\'"}, + {"\\042", "\""}, + {"\\040", " "} +}; + + +static QString restoreEscapedChar(const QString &value) +{ + QString tempValue{ value }; + + if (!tempValue.isEmpty() && !tempValue.isNull()) { + std::map::const_iterator table_beg{ StrTableOfEscapeChar.cbegin() }; + std::map::const_iterator table_end{ StrTableOfEscapeChar.cend() }; + + for (; table_beg != table_end; ++table_beg) { + int pos = tempValue.indexOf(table_beg->first); + + if (pos != -1) { + + while (pos != -1) { + tempValue = tempValue.replace(table_beg->first, table_beg->second); + pos = tempValue.indexOf(table_beg->first); + } + } + } + } + + return tempValue; +} + +} + + +class DAnythingMonitorFilterPrivate +{ +public: + + explicit DAnythingMonitorFilterPrivate(DAnythingMonitorFilter *const q_q); + ~DAnythingMonitorFilterPrivate() = default; + DAnythingMonitorFilterPrivate(const DAnythingMonitorFilterPrivate &) = delete; + DAnythingMonitorFilterPrivate &operator=(const DAnythingMonitorFilterPrivate &) = delete; + + QList whiteList(); + QList blackList(); + + ///###: jundge whether the url should be monitored. + bool whetherFilterThePath(const QByteArray &local_path); + + void read_setting(); + void get_home_path_of_all_users(); + + DAnythingMonitorFilter *q_ptr{ nullptr }; + + std::map m_user_name_and_home_path{}; + std::unique_ptr> m_black_list{ nullptr }; + std::unique_ptr> m_white_list{ nullptr }; + std::unique_ptr m_fm_setting{ nullptr }; +}; + +DAnythingMonitorFilterPrivate::DAnythingMonitorFilterPrivate(DAnythingMonitorFilter *const q_q) + : q_ptr{ q_q }, + m_black_list{ new QList }, +m_white_list{ new QList }, +m_fm_setting{ dde_file_manager::DFMApplication::genericSetting() } +{ + this->read_setting(); +} + +bool DAnythingMonitorFilterPrivate::whetherFilterThePath(const QByteArray &local_path) +{ + QString local_file{ QString::fromLocal8Bit(local_path) }; + + //从数据盘进入主目录的路径在判断之前需要先处理成/home路径 + if (local_file.startsWith("/data/home/")) + local_file.remove(0, sizeof("/data") - 1); + + bool result{ false }; + + for (const QString &path : *m_white_list) { + + if (local_file == path || local_file.startsWith(path)) { + result = true; + } + } + + for (const QString &path : *m_black_list) { + + if (local_file == path || local_file.startsWith(path)) { + result = false; + } + } + + return result; +} + +void DAnythingMonitorFilterPrivate::get_home_path_of_all_users() +{ + if (QFileInfo::exists("/etc/passwd")) { + QFile i_file{"/etc/passwd"}; + + if (!i_file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qFatal("Can not open /etc/passwd!"); + return; + } + + QTextStream in(&i_file); + + while (!in.atEnd()) { + QString line_content{ in.readLine() }; + if (line_content.isEmpty()) continue; + QList contents{ line_content.split(':') }; + if (contents.size() < 2) { + continue; + } + QString path_remove_ESC{ detail::restoreEscapedChar(contents[contents.size() - 2]) }; + m_user_name_and_home_path[contents[0]] = path_remove_ESC; + } + } +} + + +void DAnythingMonitorFilterPrivate::read_setting() +{ + + QVariant white_list{ m_fm_setting->value("AnythingMonitorFilterPath", "WhiteList") }; + QVariant black_list{ m_fm_setting->value("AnythingMonitorFilterPath", "BlackList") }; + *m_white_list = white_list.toStringList(); + *m_black_list = black_list.toStringList(); + QList invalid_path{}; + QList removed_tilde{}; + + +#ifdef QT_DEBUG + qDebug() << "white-list:" << *m_white_list; + qDebug() << "black-list: " << *m_black_list; +#endif //QT_DEBUG + + this->get_home_path_of_all_users(); + + for (QString &path : *m_black_list) { + + if (path.startsWith("~/")) { + removed_tilde.push_back(path); + continue; + } + } + + for (const QString &path : removed_tilde) { + m_black_list->removeAll(path); + } + + for (QString &path : removed_tilde) { + path.remove(0, 1); + + for (const std::pair &user_name_and_home_path : m_user_name_and_home_path) { + m_black_list->push_back(user_name_and_home_path.second + path); + } + } + + for (const QString &path : *m_black_list) { + + if (!QFileInfo::exists(path)) { + invalid_path.push_back(path); + } + } + + for (const QString &path : invalid_path) { + m_black_list->removeAll(path); + } + + invalid_path.clear(); + ///###: above this. + ///###: remove '~' in configure. And replace '~' by the home path of every user. + ///###: remove invalid path in the black-list. + + + + ///###: remove invalid path in white-list. + ///###: make sure every in black-list is subdirectory of white-list. + for (const QString &path : *m_white_list) { + + if (!QFileInfo::exists(path)) { + invalid_path.push_back(path); + } + } + + for (const QString &path : invalid_path) { + m_white_list->removeAll(path); + } + + QList::const_iterator itr_beg{}; + QList::const_iterator itr_end{}; + invalid_path.clear(); + + ///###: here, start to jundge whether directories in black-list are subdirectories in white-list. + for (const QString &dir_in_black_list : *m_black_list) { + itr_beg = m_white_list->cbegin(); + itr_end = m_white_list->cend(); + + for (; itr_beg != itr_end; ++itr_beg) { + + if (dir_in_black_list.startsWith(*itr_beg)) { + break; + } + } + + if (itr_beg == itr_end) { + invalid_path.push_back(dir_in_black_list); + } + } + + for (const QString &path : invalid_path) { + m_black_list->removeAll(path); + } + + + ///###:at last, maybe there are files in configure. So delete these. + invalid_path.clear(); + + std::function>& list)> reserve_dir{ + [](std::unique_ptr> &list) + { + std::list path_invalid{}; + + for (const QString &path : *list) { + QFileInfo file_info{ path }; + + if (!file_info.isDir()) { + path_invalid.push_back(path); + } + } + + for (const QString &path : path_invalid) { + list->removeAll(path); + } + } + }; + + reserve_dir(std::ref(m_white_list)); + reserve_dir(std::ref(m_black_list)); + + +#ifdef QT_DEBUG + qDebug() << "white-list: " << *m_white_list; + qDebug() << "black-list: " << *m_black_list; +#endif //QT_DEBUG +} + +DAnythingMonitorFilter::DAnythingMonitorFilter(QObject *const parent) + : QObject{ parent }, + d_ptr{ new DAnythingMonitorFilterPrivate{this} } +{ + //###:constructor. +} + +DAnythingMonitorFilter::~DAnythingMonitorFilter() +{ + //###: destructor. must be defined in .cpp. + //###: if not, QScopedPointer can not use a incomplete type as it's type. +} + +bool DAnythingMonitorFilter::whetherFilterCurrentPath(const QByteArray &local_path) +{ + DAnythingMonitorFilterPrivate *const d{ d_func() }; + return d->whetherFilterThePath(local_path); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/danythingmonitorfilter.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/danythingmonitorfilter.h new file mode 100644 index 0000000..d67672d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/danythingmonitorfilter.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: shihua + * + * Maintainer: shihua + * + * 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 + * 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 . + */ + +#ifndef DANYTHINGMONITORFILTER_H +#define DANYTHINGMONITORFILTER_H + + +#include +#include + +#include "durl.h" + + +class DAnythingMonitorFilterPrivate; +class DAnythingMonitorFilter final : public QObject +{ + Q_OBJECT +public: + explicit DAnythingMonitorFilter(QObject *const parent = nullptr); + virtual ~DAnythingMonitorFilter(); + + DAnythingMonitorFilter(const DAnythingMonitorFilter &) = delete; + DAnythingMonitorFilter &operator=(const DAnythingMonitorFilter &) = delete; + + bool whetherFilterCurrentPath(const QByteArray &local_path); + + static inline DAnythingMonitorFilter *instance() + { + static DAnythingMonitorFilter *singleton{ new DAnythingMonitorFilter }; + return singleton; + } + +private: + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), DAnythingMonitorFilter) +}; + +#endif // DANYTHINGMONITORFILTER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/desktopfile.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/desktopfile.cpp new file mode 100644 index 0000000..4be555f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/desktopfile.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "desktopfile.h" +#include "properties.h" +#include +#include +#include + +/** + * @brief Loads desktop file + * @param fileName + */ +DesktopFile::DesktopFile(const QString &fileName) + : m_fileName(fileName) +{ + // File validity + if (m_fileName.isEmpty() || !QFile::exists(fileName)) { + return; + } + + QSettings settings(fileName, QSettings::IniFormat); + settings.beginGroup("Desktop Entry"); + // Loads .desktop file (read from 'Desktop Entry' group) + Properties desktop(fileName, "Desktop Entry"); + + if (desktop.contains("X-Deepin-AppID")) { + m_deepinId = desktop.value("X-Deepin-AppID", settings.value("X-Deepin-AppID")).toString(); + } + + if (desktop.contains("X-Deepin-Vendor")) { + m_deepinVendor = desktop.value("X-Deepin-Vendor", settings.value("X-Deepin-Vendor")).toString(); + } + + if (desktop.contains("NoDisplay")) { + m_noDisplay = desktop.value("NoDisplay", settings.value("NoDisplay").toBool()).toBool(); + } + if (desktop.contains("Hidden")) { + m_hidden = desktop.value("Hidden", settings.value("Hidden").toBool()).toBool(); + } + + //由于获取的系统语言简写与.desktop的语言简写存在不对应关系,经决定先采用获取的系统值匹配 + //若没匹配到则采用系统值"_"左侧的字符串进行匹配,均为匹配到,才走原未匹配流程 + auto getValueFromSys = [&desktop, &settings](const QString & type, const QString & sysName)->QString { + const QString key = QString("%0[%1]").arg(type).arg(sysName); + return desktop.value(key, settings.value(key)).toString(); + }; + + auto getNameByType = [&desktop, &settings, &getValueFromSys](const QString & type)->QString{ + QString tempSysName = QLocale::system().name(); + QString targetName = getValueFromSys(type, tempSysName); + if (targetName.isEmpty()) + { + auto strSize = tempSysName.trimmed().split("_"); + if (!strSize.isEmpty()) { + tempSysName = strSize.first(); + targetName = getValueFromSys(type, tempSysName); + } + + if (targetName.isEmpty()) + targetName = desktop.value(type, settings.value(type)).toString(); + } + + return targetName; + }; + m_localName = getNameByType("Name"); + m_genericName = getNameByType("GenericName"); + + m_exec = desktop.value("Exec", settings.value("Exec")).toString(); + m_icon = desktop.value("Icon", settings.value("Icon")).toString(); + m_type = desktop.value("Type", settings.value("Type", "Application")).toString(); + m_categories = desktop.value("Categories", settings.value("Categories").toString()).toString().remove(" ").split(";"); + + QString mime_type = desktop.value("MimeType", settings.value("MimeType").toString()).toString().remove(" "); + + if (!mime_type.isEmpty()) + m_mimeType = mime_type.split(";"); + // Fix categories + if (m_categories.first().compare("") == 0) { + m_categories.removeFirst(); + } +} +//--------------------------------------------------------------------------- + +QString DesktopFile::getFileName() const +{ + return m_fileName; +} +//--------------------------------------------------------------------------- + +QString DesktopFile::getPureFileName() const +{ + return m_fileName.split("/").last().remove(".desktop"); +} +//--------------------------------------------------------------------------- + +QString DesktopFile::getName() const +{ + return m_name; +} + +QString DesktopFile::getLocalName() const +{ + return m_localName; +} + +QString DesktopFile::getDisplayName() const +{ + if (m_deepinVendor == QStringLiteral("deepin") && !m_genericName.isEmpty()) { + return m_genericName; + } + return m_localName.isEmpty() ? m_name : m_localName; +} +//--------------------------------------------------------------------------- + +QString DesktopFile::getExec() const +{ + return m_exec; +} +//--------------------------------------------------------------------------- + +QString DesktopFile::getIcon() const +{ + return m_icon; +} +//--------------------------------------------------------------------------- + +QString DesktopFile::getType() const +{ + return m_type; +} + +QString DesktopFile::getDeepinId() const +{ + return m_deepinId; +} + +QString DesktopFile::getDeepinVendor() const +{ + return m_deepinVendor; +} + +bool DesktopFile::getNoShow() const +{ + return m_noDisplay || m_hidden; +} + +//--------------------------------------------------------------------------- + +QStringList DesktopFile::getCategories() const +{ + return m_categories; +} +//--------------------------------------------------------------------------- + +QStringList DesktopFile::getMimeType() const +{ + return m_mimeType; +} +//--------------------------------------------------------------------------- diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/desktopfile.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/desktopfile.h new file mode 100644 index 0000000..3789975 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/desktopfile.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + + +#ifndef DESKTOPFILE_H +#define DESKTOPFILE_H + +#include + +/** + * @class DesktopFile + * @brief Represents a linux desktop file + * @author Michal Rost + * @date 13.1.2013 + */ +class DesktopFile { +public: + explicit DesktopFile(const QString &fileName = ""); + QString getFileName() const; + QString getPureFileName() const; + QString getName() const; + QString getLocalName() const; + QString getDisplayName() const; + QString getExec() const; + QString getIcon() const; + QString getType() const; + QString getDeepinId() const; + QString getDeepinVendor() const; + bool getNoShow() const; + QStringList getCategories() const; + QStringList getMimeType() const; +private: + QString m_fileName; + QString m_name; + QString m_genericName; + QString m_localName; + QString m_exec; + QString m_icon; + QString m_type; + QStringList m_categories; + QStringList m_mimeType; + QString m_deepinId; + QString m_deepinVendor; + bool m_noDisplay = false; + bool m_hidden = false; +}; + +#endif // DESKTOPFILE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dfmfilelistfile.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dfmfilelistfile.cpp new file mode 100644 index 0000000..b0c7efd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dfmfilelistfile.cpp @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "dfmfilelistfile.h" +#include "dfmapplication.h" + +#include "gvfs/gvfsmountmanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +class DFMFileListFilePrivate +{ +public: + DFMFileListFilePrivate(const QString &dirPath, DFMFileListFile *qq); + ~DFMFileListFilePrivate(); + + bool isWritable() const; + bool write(QIODevice &device) const; + + QString filePath() const; + + bool loadFile(); + bool loadFileWithoutCreateHidden(const QString &path); + bool loadFileWithCreateHidden(const QString &path); + bool parseData(const QByteArray &data); + void setStatus(const DFMFileListFile::Status &newStatus) const; + +protected: + QString dirPath; + QSet fileListSet; + mutable DFMFileListFile::Status status = DFMFileListFile::NoError; + +private: + char __padding[4] = {0}; + DFMFileListFile *q_ptr = nullptr; + + Q_DECLARE_PUBLIC(DFMFileListFile) +}; + +DFMFileListFilePrivate::DFMFileListFilePrivate(const QString &dirPath, DFMFileListFile *qq) + : dirPath(dirPath), q_ptr(qq) +{ + loadFile(); +} + +DFMFileListFilePrivate::~DFMFileListFilePrivate() +{ + +} + +bool DFMFileListFilePrivate::isWritable() const +{ + Q_Q(const DFMFileListFile); + + QFileInfo fileInfo(filePath()); + +#ifndef QT_NO_TEMPORARYFILE + if (fileInfo.exists()) { +#endif + QFile file(q->filePath()); + /*fix bug45741 smb的时候勾选文件夹里面的隐藏文件夹不能生效*/ + return file.open(QFile::WriteOnly); +#ifndef QT_NO_TEMPORARYFILE + } else { + // Create the directories to the file. + QDir dir(fileInfo.absolutePath()); + if (!dir.exists()) { + if (!dir.mkpath(dir.absolutePath())) + return false; + } + + // we use a temporary file to avoid race conditions + QTemporaryFile file(filePath()); + return file.open(); + } +#endif +} + +bool DFMFileListFilePrivate::write(QIODevice &device) const +{ + QStringList lines(fileListSet.toList()); + QString dataStr = lines.join('\n'); + QByteArray data; + data.append(dataStr); + qint64 ret = device.write(data); + + if (ret == -1) return false; + + return true; +} + +QString DFMFileListFilePrivate::filePath() const +{ + QString strPath = QDir(dirPath).absoluteFilePath(".hidden"); + return strPath; +} + +bool DFMFileListFilePrivate::loadFile() +{ + bool autoCreate = false; + const QString &path = filePath(); + + // mtp 文件夹是否显示底部统计信息 + const auto showInfo = dde_file_manager::DFMApplication::genericAttribute(dde_file_manager::DFMApplication::GA_MTPShowBottomInfo).toBool(); + if (!showInfo) { + static const QString &mtpType = "gvfs/mtp:host"; + autoCreate = path.contains(mtpType); + } + + // 采用直接访问是否存在方式 + if (!autoCreate) { + return loadFileWithoutCreateHidden(path); + } else { + // mtp 采用自动创建.hidden文件 + return loadFileWithCreateHidden(path); + } +} + +bool DFMFileListFilePrivate::loadFileWithoutCreateHidden(const QString &path) +{ + bool ret = false; + + GFile *gfile = g_file_new_for_path(path.toLocal8Bit().data()); + const bool exist = g_file_query_exists(gfile, nullptr); + if (exist) { + // exist, read content + char *contents = nullptr; //need g_free release memory + GError *error = nullptr; + gsize len = 0; + const bool succ = g_file_load_contents(gfile, nullptr, &contents, &len, nullptr, &error); + if (succ) { + if (contents && len > 0) { + parseData(contents); + } + ret = true; + } else { + if (error) + g_error_free(error); + setStatus(DFMFileListFile::AccessError); + } + // Loads the content of the file into memory. + // The data is always zero-terminated, but this is not included in the resultant length. + // The returned contents should be freed with g_free() when no longer needed. + // link : https://docs.gtk.org/gio/method.File.load_contents.html + g_free(contents); + } else { + setStatus(DFMFileListFile::NotExisted); + } + g_object_unref(gfile); + + return ret; +} + +bool DFMFileListFilePrivate::loadFileWithCreateHidden(const QString &path) +{ + bool ret = false; + + GError *error = nullptr; + GFile *gfile = g_file_new_for_path(path.toLocal8Bit().data()); + GFileOutputStream *outputStream = g_file_create(gfile, G_FILE_CREATE_NONE, nullptr, &error); + if (outputStream) { + // 创建成功了 就表示原来没有 直接析构stream就行 + g_object_unref(outputStream); + } else { + // 否则表示创建失败 代表原来文件夹下有hidden文件 准备进行读取 + if (error) + g_error_free(error); + // exist, read content + char *contents = nullptr; + GError *error = nullptr; + gsize len = 0; + bool succ = g_file_load_contents(gfile, nullptr, &contents, &len, nullptr, &error); + if (succ) { + if (contents && len > 0) { + parseData(contents); + } + ret = true; + } else { + g_error_free(error); + setStatus(DFMFileListFile::AccessError); + } + g_free(contents); + } + g_object_unref(gfile); + + return ret; +} + +bool DFMFileListFilePrivate::parseData(const QByteArray &data) +{ + QString dataStr(data); + fileListSet = QSet::fromList(dataStr.split('\n', QString::SkipEmptyParts)); + + return true; +} + +void DFMFileListFilePrivate::setStatus(const DFMFileListFile::Status &newStatus) const +{ + if (newStatus == DFMFileListFile::NoError || this->status == DFMFileListFile::NoError) { + this->status = newStatus; + } +} + + +DFMFileListFile::DFMFileListFile(const QString &dirPath, QObject *parent) + : QObject(parent) + , d_ptr(new DFMFileListFilePrivate(dirPath, this)) + +{ + +} + +DFMFileListFile::~DFMFileListFile() +{ + // save on ~ ? +} + +QString DFMFileListFile::filePath() const +{ + Q_D(const DFMFileListFile); + + return d->filePath(); +} + +QString DFMFileListFile::dirPath() const +{ + Q_D(const DFMFileListFile); + + return d->dirPath; +} + +bool DFMFileListFile::save() const +{ + Q_D(const DFMFileListFile); + + // write to file. + if (d->isWritable()) { + bool ok = false; + QFileInfo fileInfo(d->dirPath); + //!使用QFile实现,QSaveFile会导致filewatcher无法监视到.hidden文件改变 + //!导致界面无法实时响应文件显示隐藏 + QFile sf(filePath()); + if (!sf.open(QIODevice::WriteOnly)) { + d->setStatus(DFMFileListFile::AccessError); + return false; + } + ok = d->write(sf); + sf.close(); + if (ok) { + return true; + } else { + d->setStatus(DFMFileListFile::AccessError); + return false; + } + } + + return false; +} + +bool DFMFileListFile::contains(const QString &fileName) const +{ + Q_D(const DFMFileListFile); + + return d->fileListSet.contains(fileName); +} + +void DFMFileListFile::insert(const QString &fileName) +{ + Q_D(DFMFileListFile); + + d->fileListSet.insert(fileName); +} + +bool DFMFileListFile::remove(const QString &fileName) +{ + Q_D(DFMFileListFile); + + return d->fileListSet.remove(fileName); +} + +QSet DFMFileListFile::getHiddenFiles() +{ + Q_D(DFMFileListFile); + + return d->fileListSet; +} + +// Should we show the "Hide this file" checkbox? +bool DFMFileListFile::supportHideByFile(const QString &fileFullPath) +{ + QFileInfo fileInfo(fileFullPath); + if (!fileInfo.exists()) return false; + if (fileInfo.fileName().startsWith('.')) return false; + + return true; +} + +// Can user check or uncheck the "Hide this file" checkbox? +bool DFMFileListFile::canHideByFile(const QString &fileFullPath) +{ + QFileInfo fileInfo(fileFullPath); + QFileInfo dirInfo(fileInfo.absolutePath()); + + return dirInfo.isWritable(); +} + +bool DFMFileListFile::reload() +{ + Q_D(DFMFileListFile); + + d->fileListSet.clear(); + + return d->loadFile(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dfmfilelistfile.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dfmfilelistfile.h new file mode 100644 index 0000000..f7656e4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dfmfilelistfile.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#pragma once + +#include +#include + +class DFMFileListFilePrivate; +class DFMFileListFile : public QObject +{ + Q_OBJECT +public: + enum Status { + NoError = 0, //!< No error occurred. + NotExisted, //!< Not existed when try to read/parse the file. + AccessError, //!< An access error occurred (e.g. trying to write to a read-only file). + FormatError //!< A format error occurred (e.g. loading a malformed desktop entry file). + }; + Q_ENUM(Status) + +public: + // argument is a path, without filename. + explicit DFMFileListFile(const QString &dirPath, QObject *parent = nullptr); + ~DFMFileListFile(); + + QString filePath() const; + QString dirPath() const; + + bool save() const; + + bool contains(const QString &fileName) const; + void insert(const QString &fileName); + bool remove(const QString &fileName); + QSet getHiddenFiles(); + + static bool supportHideByFile(const QString &fileFullPath); + static bool canHideByFile(const QString &fileFullPath); + +public slots: + bool reload(); + +private: + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(DFMFileListFile) +}; diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dfmregularexpression.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dfmregularexpression.cpp new file mode 100644 index 0000000..415e852 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dfmregularexpression.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "dfmregularexpression.h" + +#include + + + +QString DFMRegularExpression::checkWildcardAndToRegularExpression(const QString &pattern) +{ + if (!pattern.contains('*') && !pattern.contains('?')) { + return DFMRegularExpression::wildcardToRegularExpression('*' + pattern + '*'); + } + + return DFMRegularExpression::wildcardToRegularExpression(pattern); +} + +QString DFMRegularExpression::wildcardToRegularExpression(const QString &pattern) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) + return QRegularExpression::wildcardToRegularExpression(pattern); +#endif // (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) + + const int wclen = pattern.length(); + QString rx; + rx.reserve(wclen + wclen / 16); + int i = 0; + const QChar *wc = pattern.unicode(); +#ifdef Q_OS_WIN + const QLatin1Char nativePathSeparator('\\'); + const QLatin1String starEscape("[^/\\\\]*"); + const QLatin1String questionMarkEscape("[^/\\\\]"); +#else + const QLatin1Char nativePathSeparator('/'); + const QLatin1String starEscape("[^/]*"); + const QLatin1String questionMarkEscape("[^/]"); +#endif + while (i < wclen) { + const QChar c = wc[i++]; + switch (c.unicode()) { + case '*': + rx += starEscape; + break; + case '?': + rx += questionMarkEscape; + break; + case '\\': +#ifdef Q_OS_WIN + case '/': + rx += QLatin1String("[/\\\\]"); + break; +#endif + case '$': + case '(': + case ')': + case '+': + case '.': + case '^': + case '{': + case '|': + case '}': + rx += QLatin1Char('\\'); + rx += c; + break; + case '[': + rx += c; + // Support for the [!abc] or [!a-c] syntax + if (i < wclen) { + if (wc[i] == QLatin1Char('!')) { + rx += QLatin1Char('^'); + ++i; + } + if (i < wclen && wc[i] == QLatin1Char(']')) + rx += wc[i++]; + while (i < wclen && wc[i] != QLatin1Char(']')) { + // The '/' appearing in a character class invalidates the + // regular expression parsing. It also concerns '\\' on + // Windows OS types. + if (wc[i] == QLatin1Char('/') || wc[i] == nativePathSeparator) + return rx; + if (wc[i] == QLatin1Char('\\')) + rx += QLatin1Char('\\'); + rx += wc[i++]; + } + } + break; + default: + rx += c; + break; + } + } + return anchoredPattern(rx); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dfmregularexpression.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dfmregularexpression.h new file mode 100644 index 0000000..71b653e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dfmregularexpression.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + + +#ifndef DFMREGULAREXPRESSION_H +#define DFMREGULAREXPRESSION_H + +#include + +// Backport some static function. +// This class should be removed after dropping support for old Qt version. + +class DFMRegularExpression +{ +public: + static QString checkWildcardAndToRegularExpression(const QString &pattern); + static QString wildcardToRegularExpression(const QString &pattern); + static inline QString anchoredPattern(const QString &expression) { + return QLatin1String("\\A(?:") + + expression + + QLatin1String(")\\z"); + } +}; + +#endif // DFMREGULAREXPRESSION_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dsqlitehandle.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dsqlitehandle.cpp new file mode 100644 index 0000000..af8a9ce --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dsqlitehandle.cpp @@ -0,0 +1,3720 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "singleton.h" +#include "tag/tagutil.h" +#include "dsqlitehandle.h" + +#include "ddiskmanager.h" +#include "dblockdevice.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /*__cplusplus*/ + +#include "pwd.h" +#include "unistd.h" + +#ifdef __cplusplus +} +#endif /*__cplusplus*/ + + + +namespace std { + +template<> +struct less { + typedef bool result_type; + typedef QString first_argument_type; + typedef QString second_argument_type; + ///###: delete the codes above. When in c++17. + + + bool operator()(const QString &lhs, const QString &rhs) const + { + std::string lhStr{ lhs.toStdString() }; + std::string rhStr{ rhs.toStdString() }; + + return (std::less {}(lhStr, rhStr)); + } +}; + +} + + +namespace impl { + +#define has_member_function(member)\ + template\ + struct has_member_##member\ + {\ + private:\ + template\ + static auto check(int)->decltype((std::declval<__TR>().member(), std::true_type{}));\ + template\ + static std::false_type check(...);\ + public:\ + enum { value = std::is_same(0)), std::true_type>::value };\ + }; + + +has_member_function(insert) +has_member_function(cbegin) +has_member_function(cend) +has_member_function(push_back) + + + + +template < typename __Ty, typename __TR, typename = typename std::enable_if < + std::is_same<__Ty, __Ty &>::value && + std::is_same::type>::type, QMap>>::value + >::type > + __Ty & operator+=(__Ty && lh, const __TR &rh)noexcept +{ + if (rh.isEmpty()) { + return lh; + } + + auto itr_beg{ rh.cbegin() }; + auto itr_end{ rh.cend() }; + + for (; itr_beg != itr_end; ++itr_beg) { + lh.insert(itr_beg.key(), itr_beg.value()); + } + + return lh; +} + + +template < typename __Ty, typename __TR, typename std::enable_if < + std::is_same<__Ty, __Ty &>::value && + has_member_cbegin::type>::type>::value && + has_member_cend::type>::type>::value && + has_member_push_back::type>::type>::value + >::type > +__Ty &operator+=(__Ty &&lh, const __TR &rh)noexcept +{ + auto itr_beg{ rh.cbegin() }; + auto itr_end{ rh.cend() }; + + for (; itr_beg != itr_end; ++itr_beg) { + lh.push_back(*itr_beg); + } + + return lh; +} + +} + + +static std::once_flag flag{};//###: flag for instance. +static std::atomic counter{ 0 }; + +static constexpr const char *const MOUNTTABLE{"/proc/mounts"}; +static constexpr const char *const ROOTPATH{"/"}; +static constexpr const std::size_t MAXTHREAD{ 3 }; +static constexpr const char *const CONNECTIONNAME{ "deep" }; +static constexpr const char *const USERNAME{"username"}; +static constexpr const char *const PASSWORD{"password"}; + + +static const std::map StrTableOfEscapeChar{ + {"\\007", "\a"}, + {"\\010", "\b"}, + {"\\014", "\f"}, + {"\\012", "\n"}, + {"\\015", "\r"}, + {"\\011", "\t"}, + {"\\013", "\v"}, + {"\\134", "\\"}, + {"\\047", "\'"}, + {"\\042", "\""}, + {"\\040", " "} +}; + + +static const std::multimap SqlTypeWithStrs { + { + DSqliteHandle::SqlType::BeforeTagFiles, "SELECT COUNT(tag_property.tag_name) AS counter " + "FROM tag_property WHERE tag_property.tag_name = \'%1\'" + }, + { + DSqliteHandle::SqlType::BeforeTagFiles, "INSERT INTO tag_property (tag_name, tag_color) " + "VALUES(\'%1\', \'%2\')" + }, + + { + DSqliteHandle::SqlType::TagFiles, "SELECT COUNT (tag_with_file.file_name) AS counter " + "FROM tag_with_file WHERE tag_with_file.file_name = \'%1\' " + "AND tag_with_file.tag_name = \'%2\'" + }, + {DSqliteHandle::SqlType::TagFiles, "INSERT INTO tag_with_file (file_name, tag_name) VALUES (\'%1\', \'%2\')"}, + { + DSqliteHandle::SqlType::TagFiles, "DELETE FROM tag_with_file WHERE tag_with_file.tag_name = \'%1\' " + "AND tag_with_file.file_name = \'%2\'" + }, + {DSqliteHandle::SqlType::TagFiles, "DELETE FROM file_property WHERE file_property.file_name = \'%1\'"}, + { + DSqliteHandle::SqlType::TagFiles, "SELECT tag_with_file.tag_name FROM tag_with_file " + "WHERE tag_with_file.file_name = \'%1\'" + }, + { + DSqliteHandle::SqlType::TagFiles, "UPDATE file_property SET tag_1 = \'%1\', tag_2 = \'%2\', tag_3 = \'%3\' " + "WHERE file_property.file_name = \'%4\'" + }, + { + DSqliteHandle::SqlType::TagFiles, "SELECT COUNT (file_property.file_name) AS counter " + "FROM file_property WHERE file_property.file_name = \'%1\'" + }, + { + DSqliteHandle::SqlType::TagFiles, "INSERT INTO file_property (file_name, tag_1, tag_2, tag_3) " + "VALUES(\'%1\', \'%2\', \'%3\', \'%4\')" + }, + + { + DSqliteHandle::SqlType::ChangeFilesName, "UPDATE file_property SET file_name = \'%1\' " + "WHERE file_property.file_name = \'%2\'" + }, + { + DSqliteHandle::SqlType::ChangeFilesName, "UPDATE tag_with_file SET file_name = \'%1\' " + "WHERE tag_with_file.file_name = \'%2\'" + }, + + { + DSqliteHandle::SqlType::ChangeFilesName2, "SELECT tag_with_file.tag_name FROM tag_with_file " + "WHERE tag_with_file.file_name = \'%1\'" + }, + + { + DSqliteHandle::SqlType::ChangeTagsName, "UPDATE file_property SET tag_1 = \'%1\' " + "WHERE file_property.tag_1 = \'%2\'" + }, + { + DSqliteHandle::SqlType::ChangeTagsName, "UPDATE file_property SET tag_2 = \'%1\' " + "WHERE file_property.tag_2 = \'%2\'" + }, + { + DSqliteHandle::SqlType::ChangeTagsName, "UPDATE file_property SET tag_3 = \'%1\' " + "WHERE file_property.tag_3 = \'%2\'" + }, + { + DSqliteHandle::SqlType::ChangeTagsName, "UPDATE tag_with_file SET tag_name = \'%1\' " + "WHERE tag_with_file.tag_name = \'%2\'" + }, + { + DSqliteHandle::SqlType::ChangeTagsName2, "UPDATE tag_property SET tag_name = \'%1\' " + "WHERE tag_property.tag_name = \'%2\'" + }, + + {DSqliteHandle::SqlType::DeleteFiles, "DELETE FROM tag_with_file WHERE tag_with_file.file_name = \'%1\'"}, + {DSqliteHandle::SqlType::DeleteFiles, "DELETE FROM file_property WHERE file_property.file_name = \'%1\'"}, + + { + DSqliteHandle::SqlType::DeleteFiles2, "SELECT tag_with_file.tag_name FROM tag_with_file " + "WHERE tag_with_file.file_name = \'%1\'" + }, + + {DSqliteHandle::SqlType::DeleteTags, "DELETE FROM tag_with_file WHERE tag_with_file.tag_name = \'%1\'"}, + + { + DSqliteHandle::SqlType::DeleteTags2, "SELECT file_property.file_name FROM file_property WHERE file_property.tag_1 = \'%1\' " + "OR file_property.tag_2 = \'%1\' " + "OR file_property.tag_3 = \'%1\'" + }, + {DSqliteHandle::SqlType::DeleteTags2, "SELECT tag_with_file.tag_name FROM tag_with_file WHERE tag_with_file.file_name = \'%1\'"}, + { + DSqliteHandle::SqlType::DeleteTags2, "UPDATE file_property SET tag_1 = \'%1\', tag_2 =\'%2\', tag_3=\'%3\' " + "WHERE file_name = \'%4\'" + }, + {DSqliteHandle::SqlType::DeleteTags3, "DELETE FROM tag_property WHERE tag_name = \'%1\'"}, + + { + DSqliteHandle::SqlType::DeleteTags4, "SELECT tag_with_file.file_name FROM tag_with_file " + "WHERE tag_with_file.tag_name = \'%1\'" + }, + + { + DSqliteHandle::SqlType::UntagSamePartionFiles, "DELETE FROM tag_with_file WHERE tag_with_file.file_name = \'%1\' " + "AND tag_with_file.tag_name = \'%2\'" + }, + + { + DSqliteHandle::SqlType::UntagSamePartionFiles2, "SELECT COUNT(tag_with_file.tag_name) AS counter " + "FROM tag_with_file WHERE tag_with_file.file_name = \'%1\'" + }, + { + DSqliteHandle::SqlType::UntagSamePartionFiles2, "SELECT tag_with_file.tag_name FROM tag_with_file " + "WHERE tag_with_file.file_name = \'%1\'" + }, + { + DSqliteHandle::SqlType::UntagSamePartionFiles2, "UPDATE file_property SET tag_1 = \'%1\', tag_2 = \'%2\', tag_3 = \'%3' " + "WHERE file_property.file_name = \'%4\'" + }, + {DSqliteHandle::SqlType::UntagSamePartionFiles2, "DELETE FROM file_property WHERE file_property.file_name = \'%1\'"}, + + { + DSqliteHandle::SqlType::UntagDiffPartionFiles, "DELETE FROM tag_with_file WHERE tag_with_file.file_name = \'%1\' " + "AND tag_with_file.tag_name = \'%2\'" + }, + { + DSqliteHandle::SqlType::UntagDiffPartionFiles, "SELECT COUNT(tag_with_file.file_name) AS counter " + "FROM tag_with_file WHERE tag_with_file.file_name = \'%1\'" + }, + {DSqliteHandle::SqlType::UntagDiffPartionFiles, "DELETE FROM file_property WHERE file_property.file_name = \'%1\'"}, + + { + DSqliteHandle::SqlType::GetTagsThroughFile, "SELECT tag_with_file.tag_name FROM tag_with_file " + "WHERE tag_with_file.file_name = \'%1\'" + }, + { + DSqliteHandle::SqlType::GetFilesThroughTag, "SELECT tag_with_file.file_name FROM tag_with_file " + "WHERE tag_with_file.tag_name = \'%1\'" + }, + + { + DSqliteHandle::SqlType::TagFilesThroughColor, "SELECT COUNT(tag_with_file.tag_name) AS counter FROM tag_with_file " + "WHERE tag_with_file.tag_name = \'%1\' AND tag_with_file.file_name = \'%2\'" + }, + {DSqliteHandle::SqlType::TagFilesThroughColor, "INSERT INTO tag_with_file (tag_name, file_name) VALUES(\'%1\', \'%2\')"}, + { + DSqliteHandle::SqlType::TagFilesThroughColor, "SELECT tag_with_file.tag_name FROM tag_with_file " + "WHERE tag_with_file.file_name = \'%1\'" + }, + { + DSqliteHandle::SqlType::TagFilesThroughColor, "INSERT INTO file_property (file_name, tag_1, tag_2, tag_3) " + "VALUES (\'%1\', \'%2\', \'%3\', \'%4\')" + }, + + { + DSqliteHandle::SqlType::TagFilesThroughColor2, "SELECT COUNT(file_property.file_name) AS counter FROM file_property " + "WHERE file_name = \'%1\'" + }, + { + DSqliteHandle::SqlType::TagFilesThroughColor2, "UPDATE file_property SET tag_1 = \'%1\', tag_2 = \'%2\', tag_3 = \'%3' " + "WHERE file_property.file_name = \'%4\'" + }, + { + DSqliteHandle::SqlType::TagFilesThroughColor3, "SELECT COUNT(tag_property.tag_name) AS counter FROM tag_property " + "WHERE tag_name = \'%1\'" + }, + {DSqliteHandle::SqlType::TagFilesThroughColor3, "INSERT INTO tag_property(tag_name, tag_color) VALUES(\'%1\', \'%2\')"}, + + + {DSqliteHandle::SqlType::GetAllTags, "SELECT * FROM tag_property"}, + + {DSqliteHandle::SqlType::GetTagColor, "SELECT * FROM tag_property WHERE tag_property.tag_name = \'%1\'" }, + + { + DSqliteHandle::SqlType::ChangeTagColor, "UPDATE tag_property SET tag_color = \'%1\' " + "WHERE tag_property.tag_name = \'%2\'" + } +}; + + +DSqliteHandle::DSqliteHandle(QObject *const parent) + : QObject{ parent }, + m_sqlDatabasePtr{ new QSqlDatabase } +{ + std::lock_guard raiiLock{ m_mutex }; + std::map> partionsAndMounPoints{ DSqliteHandle::queryPartionsInfoOfDevices() }; + + if (!partionsAndMounPoints.empty()) { + m_partionsOfDevices.reset(new std::map> { partionsAndMounPoints }); + } + + this->initializeConnect(); +} + + +///###: this is a auxiliary function. so do nont need a mutex. +QPair DSqliteHandle::getMountPointOfFile(DUrl url, + std::unique_ptr>> &partionsAndMountPoints) +{ + while (!DFileInfo::exists(url)) { + const DUrl &parent_url = url.parentUrl(); + + if (!parent_url.isValid() || parent_url == url) { + break; + } + + url = parent_url; + } + + QPair partionAndMountPoint{}; + + if (DFileInfo::exists(url) && partionsAndMountPoints + && !partionsAndMountPoints->empty()) { + QString path = url.path(); + std::pair rootPathPartionAndMountpoint{}; + std::map>::const_iterator cbeg{ partionsAndMountPoints->cbegin() }; + std::map>::const_iterator cend{ partionsAndMountPoints->cend() }; + bool flg{ false }; + + for (; cbeg != cend; ++cbeg) { + std::multimap::const_iterator itrOfPartionAndMountpoint{ cbeg->second.cbegin() }; + std::multimap::const_iterator itrOfPartionAndMountpointEnd{ cbeg->second.cend() }; + + for (; itrOfPartionAndMountpoint != itrOfPartionAndMountpointEnd; ++itrOfPartionAndMountpoint) { + + if (itrOfPartionAndMountpoint->second == ROOTPATH) { + rootPathPartionAndMountpoint = *itrOfPartionAndMountpoint; + } + + if (itrOfPartionAndMountpoint->second != ROOTPATH && path.startsWith(itrOfPartionAndMountpoint->second)) { + partionAndMountPoint.first = itrOfPartionAndMountpoint->first; + partionAndMountPoint.second = itrOfPartionAndMountpoint->second; + flg = true; + break; + } + } + + if (flg) { + break; + } + } + + if (!flg && path.startsWith(ROOTPATH)) { + partionAndMountPoint.first = rootPathPartionAndMountpoint.first; + partionAndMountPoint.second = rootPathPartionAndMountpoint.second; + } + } + + return partionAndMountPoint; +} + + + + +///###: this is a auxiliary function. so do not need a mutex. +std::map> DSqliteHandle::queryPartionsInfoOfDevices() +{ + std::map> partionsAndMountpoints{}; + + if (DFileInfo::exists(DUrl::fromLocalFile(MOUNTTABLE))) { + std::basic_ifstream iFstream{MOUNTTABLE}; + std::list> partionInfoAndMountpoint{}; + std::basic_regex matchNumber{ "[0-9]+" }; + + if (iFstream.is_open()) { + std::basic_string str{}; + + + while (std::getline(iFstream, str)) { + + if (!str.empty()) { + std::basic_string::size_type pos{ str.find("/dev/") }; + + if (pos != std::string::npos) { + partionInfoAndMountpoint.push_back(str); + } + } + } + } + + for (const std::basic_string &theStr : partionInfoAndMountpoint) { + QString qsTr{ QString::fromStdString(theStr) }; + QString deviceName{}; + QString partionName{}; + QString mountpoint{}; + + QList subsTrs{ qsTr.split(' ') }; + partionName = subsTrs[0]; + mountpoint = subsTrs[1]; + + std::match_results::const_iterator> matchedResult{}; + std::basic_string partionNameStd{ partionName.toStdString() }; + + if (std::regex_search(partionNameStd, matchedResult, matchNumber)) { + deviceName = QString::fromStdString(matchedResult.prefix()); + + if (!deviceName.isEmpty() && !deviceName.isNull()) { + mountpoint = DSqliteHandle::restoreEscapedChar(mountpoint); + + ///###: do not delete this. +// qDebug()<< deviceName << partionName << mountpoint; + + partionsAndMountpoints[deviceName].emplace(std::move(partionName), mountpoint); + } + } + } + } + + ///###: do not delete this. It is convenient for testing. +// for(const auto& item : partionsAndMountpoints){ +// qDebug()<< item.first; + +// for(const auto& itm : item.second){ +// qDebug()<< itm.first << "=====" < raiiLock{ m_mutex }; + std::map> partionsAndMountPoints{ DSqliteHandle::queryPartionsInfoOfDevices() }; + m_partionsOfDevices.reset(nullptr); + + if (!partionsAndMountPoints.empty()) { + m_partionsOfDevices = std::unique_ptr>> { + new std::map>{ partionsAndMountPoints } + }; + } + m_flag.store(false, std::memory_order_release); +} + +void DSqliteHandle::onMountRemoved(UDiskDeviceInfoPointer infoPointer) +{ + (void)infoPointer; + + m_flag.store(true, std::memory_order_release); + std::lock_guard raiiLock{ m_mutex }; + std::map> partionsAndMountPoints{ DSqliteHandle::queryPartionsInfoOfDevices() }; + m_partionsOfDevices.reset(nullptr); + + if (!partionsAndMountPoints.empty()) { + m_partionsOfDevices = std::unique_ptr>> { + new std::map>{ partionsAndMountPoints } + }; + } + m_flag.store(false, std::memory_order_release); +} + + +QString DSqliteHandle::restoreEscapedChar(const QString &value) +{ + QString tempValue{ value }; + + if (!tempValue.isEmpty() && !tempValue.isNull()) { + + std::map::const_iterator tableCBeg{ StrTableOfEscapeChar.cbegin() }; + std::map::const_iterator tableCEnd{ StrTableOfEscapeChar.cend() }; + + for (; tableCBeg != tableCEnd; ++tableCBeg) { + int pos = tempValue.indexOf(tableCBeg->first); + + if (pos != -1) { + + while (pos != -1) { + tempValue = tempValue.replace(tableCBeg->first, tableCBeg->second); + + pos = tempValue.indexOf(tableCBeg->first); + } + } + } + } + + return tempValue; +} + + +///#:-----------------------------------------> >>. +QVariant DSqliteHandle::disposeClientData(const QMap> &filesAndTags, const unsigned long long &type) +{ + QVariant var{}; + + if (counter.load(std::memory_order_consume) != 0) { + return var; + } + + if (!filesAndTags.isEmpty() && type != 0) { + std::size_t numberOfType{ static_cast(type) }; + switch (numberOfType) { + case 1: { ///###: tag files!!!! + std::lock_guard raiiLock{ m_mutex }; + bool value{ this->execSqlstr(filesAndTags) }; + var.setValue(value); + + break; + } + case 2: { + std::lock_guard raiiLock{ m_mutex }; + QStringList files{ this->execSqlstr>(filesAndTags) }; + var.setValue(files); + + break; + } + case 3: { + std::lock_guard raiiLock{ m_mutex }; + QStringList tags{ this->execSqlstr>(filesAndTags) }; + var.setValue(tags); + + break; + } + case 4: { ///###: untag files(support different partion). + std::lock_guard raiiLock{ m_mutex }; + bool value{ this->execSqlstr(filesAndTags) }; + var.setValue(value); + + break; + } + case 5: { + std::lock_guard raiiLock{ m_mutex }; + bool value{ this->execSqlstr(filesAndTags) };//###: do not be confused by the name of variant. + var.setValue(value); + + break; + } + case 6: { + std::lock_guard raiiLock{ m_mutex }; + bool value{ this->execSqlstr(filesAndTags) }; + var.setValue(value); + + break; + } + case 7: { + std::lock_guard raiiLock{ m_mutex }; + bool value{ this->execSqlstr(filesAndTags) }; + var.setValue(value); + + break; + } + case 8: { + std::lock_guard raiiLock{ m_mutex }; + bool value{ this->execSqlstr(filesAndTags) }; + var.setValue(value); + + break; + } + case 9: { + std::lock_guard raillLock{ m_mutex }; + bool value{ this->execSqlstr(filesAndTags) }; + var.setValue(value); + + break; + } + case 10: { + std::lock_guard raillLock{ m_mutex }; + QMap tag_and_color{ this->execSqlstr>(filesAndTags) }; + var.setValue(tag_and_color); + + break; + } + case 11: { + std::lock_guard raii_lock{ m_mutex }; + bool result{ this->execSqlstr(filesAndTags) }; + var.setValue(result); + + break; + } + case 12: { + std::lock_guard raii_lock{ m_mutex }; + QMap tag_and_color{ this->execSqlstr>(filesAndTags) }; + var.setValue(tag_and_color); + + break; + } + case 13: { + std::lock_guard raii_lock{ m_mutex }; + bool result{ this->execSqlstr(filesAndTags) }; + var.setValue(result); + + break; + } + default: + break; + } + } + + return var; +} + +DSqliteHandle::ReturnCode DSqliteHandle::checkDBFileExist(const QString &path, const QString &db_name) +{ + QDir dir(path); + + if (!dir.exists()) { + return ReturnCode::NoThisDir; + } + + if (dir.exists(db_name)) { + return ReturnCode::Exist; + } + + return ReturnCode::NoExist; +} + +void DSqliteHandle::initializeConnect() +{ + QObject::connect(deviceListener, &UDiskListener::mountAdded, this, &DSqliteHandle::onMountAdded); + QObject::connect(deviceListener, &UDiskListener::mountRemoved, this, &DSqliteHandle::onMountRemoved); +} + +void DSqliteHandle::connectToSqlite(const QString &path, const QString &db_name) +{ + DSqliteHandle::ReturnCode code = this->checkDBFileExist(path, db_name); + std::function initDatabasePtr{ [&]{ + if (m_sqlDatabasePtr->isOpen()) + { + m_sqlDatabasePtr->close(); + } + + if (QSqlDatabase::contains(CONNECTIONNAME)) + { + m_sqlDatabasePtr.reset(nullptr); + QSqlDatabase::removeDatabase(CONNECTIONNAME); + } + + m_sqlDatabasePtr = std::unique_ptr{new QSqlDatabase{ QSqlDatabase::addDatabase(R"foo(QSQLITE)foo", CONNECTIONNAME)} }; + QString DBName{path + QString{"/"} + db_name}; + + ///###: for debugging. +// qDebug() << DBName; + + m_sqlDatabasePtr->setDatabaseName(DBName); + m_sqlDatabasePtr->setUserName(USERNAME); + m_sqlDatabasePtr->setPassword(PASSWORD); + } }; + + if (code == DSqliteHandle::ReturnCode::NoExist) { + initDatabasePtr(); + + if (m_sqlDatabasePtr->open()) { + if (m_sqlDatabasePtr->transaction()) { + QSqlQuery sqlQuery{ *m_sqlDatabasePtr }; + + if (db_name != QString{".__main.db"}) { + QString createFileProperty{ + "CREATE TABLE IF NOT EXISTS \"file_property\" " + " (" + " `file_name` TEXT NOT NULL UNIQUE," + " `tag_1` TEXT NOT NULL," + " `tag_2` TEXT," + " `tag_3` TEXT" + " )" + }; + + QString createTagWithFile{ + "CREATE TABLE IF NOT EXISTS \"tag_with_file\" " + " (" + " `tag_name` TEXT NOT NULL," + " `file_name` TEXT NOT NULL " + " )" + }; + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(createFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + } + + if (!sqlQuery.exec(createTagWithFile)) { + qWarning() << sqlQuery.lastError().text(); + } + + } else { + DSqliteHandle::ReturnCode return_code{ this->checkDBFileExist(path) }; + + if (return_code != DSqliteHandle::ReturnCode::NoThisDir) { + + if (!sqlQuery.exec(createFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + } + + if (!sqlQuery.exec(createTagWithFile)) { + qWarning() << sqlQuery.lastError().text(); + } + } + } + + } else { + + QString createTagProperty{ + "CREATE TABLE IF NOT EXISTS \"tag_property\" " + " (" + "`tag_index` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE," + "`tag_name` TEXT NOT NULL UNIQUE," + "`tag_color` TEXT NOT NULL" + ")" + }; + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(createTagProperty)) { + qWarning() << sqlQuery.lastError().text(); + } + + } else { + DSqliteHandle::ReturnCode return_code{ this->checkDBFileExist(path) }; + + if (return_code != DSqliteHandle::ReturnCode::NoThisDir) { + + if (!sqlQuery.exec(createTagProperty)) { + qWarning() << sqlQuery.lastError().text(); + } + } + } + } + + if (!m_sqlDatabasePtr->commit()) { + m_sqlDatabasePtr->rollback(); + } + + } else { + qWarning() << "failed to open transaction!!!!!!"; + m_sqlDatabasePtr->close(); + } + + QString udiskspath = ""; + for (auto &dev : DDiskManager::blockDevices({})) { + QScopedPointer blk(DDiskManager::createBlockDevice(dev)); + bool match = false; + for (auto &mp : blk->mountPoints()) { + if (path == QString(mp)) { + match = true; + break; + } + } + if (match) { + udiskspath = dev; + break; + } + } + QScopedPointer blk(DDiskManager::createBlockDevice(udiskspath)); + if (blk->idType() == "ntfs") { + QString db_path(path + QString("/") + db_name); + QByteArray pathBytes(db_path.toUtf8()); + const char *db_path_cs(pathBytes.data()); + Q_UNUSED(db_path_cs) + quint32 attr; + pathBytes = db_path.toUtf8(); + getxattr(pathBytes.data(), "system.ntfs_attrib_be", static_cast(&attr), 4); +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + attr = __builtin_bswap32(attr); +#endif + attr |= 0x2; // ATTR_HIDDEN +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + attr = __builtin_bswap32(attr); +#endif + pathBytes = db_path.toUtf8(); + setxattr(pathBytes.data(), "system.ntfs_attrib_be", static_cast(&attr), 4, 0); + } + + } else { + qWarning() << "errors occured when creating a DB in a partion."; + } + + } else if (code == DSqliteHandle::ReturnCode::Exist) { + initDatabasePtr(); + } + + this->closeSqlDatabase(); +} + +void DSqliteHandle::connectToShareSqlite(const QString &path, const QString &db_name) +{ + //检查share目录中是否已有数据库存在 + DSqliteHandle::ReturnCode code = this->checkDBFileExist(DATABASE_PATH, db_name); + + //如果目录不存在则创建该目录 + if (code == DSqliteHandle::ReturnCode::NoThisDir) { + int mkdRet = QProcess::execute(QString("mkdir %1").arg(DATABASE_PATH)); + if (mkdRet) { + code = this->checkDBFileExist(DATABASE_PATH, db_name); + } else { + qDebug() << "errors occured when make user local folder"; + } + } + + if (code == DSqliteHandle::ReturnCode::NoExist) { + //先判断/home目录下是否有对应数据库文件 + DSqliteHandle::ReturnCode homeCode = this->checkDBFileExist(path, db_name); + QString mountDBPath = path + "/" + db_name; + QString shareDBPath = DATABASE_PATH; + shareDBPath.append("/" + db_name); + + if (homeCode == DSqliteHandle::ReturnCode::Exist) { + //将旧的db文件迁移到文管共享目录下 + int moveRet = QProcess::execute(QString("mv %1 %2").arg(mountDBPath, shareDBPath)); + if (moveRet) { + //连接移动后的db + connectToSqlite(DATABASE_PATH, db_name); + } else { + qDebug() << "errors occured when move old db to user path"; + } + } else if (homeCode == DSqliteHandle::ReturnCode::NoExist) { + connectToSqlite(DATABASE_PATH, db_name); + } + } else if (code == DSqliteHandle::ReturnCode::Exist) { + connectToSqlite(DATABASE_PATH, db_name); + } +} + +///###:this is also a auxiliary function. do not need a mutex. +template<> +bool DSqliteHandle::helpExecSql>, bool>(const QMap> &forDecreasing, const QString &mountPoint) +{ + if (!forDecreasing.isEmpty() && !mountPoint.isEmpty()) { + QMap>::const_iterator cbeg{ forDecreasing.cbegin() }; + QMap>::const_iterator cend{ forDecreasing.cend() }; + std::pair::const_iterator, + std::multimap::const_iterator> itrOfSqlForDeleting{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::TagFiles) }; + std::multimap::const_iterator itr{ itrOfSqlForDeleting.first }; + ++itr; ++itr; + QSqlQuery sqlQuery{ *m_sqlDatabasePtr }; + + + for (; cbeg != cend; ++cbeg) { + + for (const QString &tagName : cbeg.value()) { + QString sql{ itr->second.arg(tagName) }; + sql = sql.arg(cbeg.key()); + + if (!m_flag.load(std::memory_order_acquire)) { + + ///###: delete redundant item in tag_with_file. + if (!sqlQuery.exec(sql)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPoint) }; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(sql)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + + return false; + } + } + } + } + + return true; + } + + return false; +} + +///###:this is also a auxiliary function. do not need a mutex. +template<> +bool DSqliteHandle::helpExecSql>, bool>( + const QMap> &forIncreasing, const QString &mountPoint) +{ + if (!forIncreasing.isEmpty() && !mountPoint.isEmpty()) { + QMap>::const_iterator cbeg{ forIncreasing.cbegin() }; + QMap>::const_iterator cend{ forIncreasing.cend() }; + std::pair::const_iterator, + std::multimap::const_iterator> itrOfSqlForDeleting{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::TagFiles) }; + std::multimap::const_iterator itr{ itrOfSqlForDeleting.first }; + ++itr; + QSqlQuery sqlQuery{ *m_sqlDatabasePtr }; + + for (; cbeg != cend; ++cbeg) { + + for (const QString &tagName : cbeg.value()) { + QString sql{ itr->second.arg(cbeg.key()) }; + sql = sql.arg(tagName); + + if (!m_flag.load(std::memory_order_acquire)) { + + ///###: tag files + if (!sqlQuery.exec(sql)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPoint) }; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(sql)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + + return false; + } + } + } + } + + return true; + } + + return false; +} + + + +template<> +bool DSqliteHandle::helpExecSql, bool>(const QList &forUpdating, + const QString &mountPoint) +{ + if (!forUpdating.isEmpty() && !mountPoint.isEmpty()) { + QList::const_iterator cbeg{ forUpdating.cbegin() }; + QList::const_iterator cend{ forUpdating.cend() }; + std::pair::const_iterator, + std::multimap::const_iterator> itrOfSqlForDeleting{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::TagFiles) }; + std::multimap::const_iterator itr{ itrOfSqlForDeleting.first }; + ++itr; ++itr; ++itr; ++itr; + QSqlQuery sqlQuery{ *m_sqlDatabasePtr }; + + for (; cbeg != cend; ++cbeg) { + QString sqlForGettingTag{ itr->second.arg(*cbeg) }; + std::vector leftTags{}; + + if (!m_flag.load(std::memory_order_acquire)) { + + if (sqlQuery.exec(sqlForGettingTag)) { + + while (sqlQuery.next()) { + QString tagName{ sqlQuery.value("tag_name").toString() }; + leftTags.push_back(tagName); + } + } + + } else { + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPoint) }; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (sqlQuery.exec(sqlForGettingTag)) { + + while (sqlQuery.next()) { + QString tagName{ sqlQuery.value("tag_name").toString() }; + leftTags.push_back(tagName); + } + } + + } else { + return false; + } + } + + if (leftTags.empty()) { + std::multimap::const_iterator itrForDelRowInFileProperty{itr}; + --itrForDelRowInFileProperty; + QString sqlForDelRowInFileProperty{ itrForDelRowInFileProperty->second.arg(*cbeg) }; + + + if (!m_flag.load(std::memory_order_acquire)) { + + if (!sqlQuery.exec(sqlForDelRowInFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPoint) }; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(sqlForDelRowInFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + return false; + } + } + + } else { + + std::multimap::const_iterator itrForCounterFileInFP{ itr }; + ++itrForCounterFileInFP; ++itrForCounterFileInFP; + QString sqlOfCountingFileInFP{ itrForCounterFileInFP->second.arg(*cbeg) }; + + int cnter{ 0 }; + + if (!m_flag.load(std::memory_order_acquire)) { + + if (sqlQuery.exec(sqlOfCountingFileInFP)) { + + if (sqlQuery.next()) { + cnter = sqlQuery.value("counter").toInt(); + } + } + + } else { + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPoint) }; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (sqlQuery.exec(sqlOfCountingFileInFP)) { + cnter = sqlQuery.value("counter").toInt(); + } + + } else { + return false; + } + } + + std::size_t size{ leftTags.size() }; + + if (size < 3) { + std::size_t differenceValue{ 3u - size }; + + for (std::size_t index = 0; index < differenceValue; ++index) { + leftTags.push_back(QString{}); + } + } + + + if (cnter > 0) { + std::multimap::const_iterator itrForUpdating{itr}; + ++itrForUpdating; + + std::size_t sizeOfTags{ leftTags.size() }; + + QString sqlForUpdatingFileProperty{itrForUpdating->second.arg(leftTags[sizeOfTags - 3])}; + sqlForUpdatingFileProperty = sqlForUpdatingFileProperty.arg(leftTags[sizeOfTags - 2]); + sqlForUpdatingFileProperty = sqlForUpdatingFileProperty.arg(leftTags[sizeOfTags - 1]); + sqlForUpdatingFileProperty = sqlForUpdatingFileProperty.arg(*cbeg); + + if (!m_flag.load(std::memory_order_acquire)) { + + if (!sqlQuery.exec(sqlForUpdatingFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPoint) }; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(sqlForUpdatingFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + return false; + } + + } + + } else { + + std::multimap::const_iterator itrForInsertRowInFP{ itr }; + ++itrForInsertRowInFP; + ++itrForInsertRowInFP; + ++itrForInsertRowInFP; + std::size_t sizeOfTags{ leftTags.size() }; + QString sqlForInsertRowInFP{ itrForInsertRowInFP->second.arg(*cbeg) }; + sqlForInsertRowInFP = sqlForInsertRowInFP.arg(leftTags[sizeOfTags - 3]); + sqlForInsertRowInFP = sqlForInsertRowInFP.arg(leftTags[sizeOfTags - 2]); + sqlForInsertRowInFP = sqlForInsertRowInFP.arg(leftTags[sizeOfTags - 1]); + + + if (!m_flag.load(std::memory_order_acquire)) { + + if (!sqlQuery.exec(sqlForInsertRowInFP)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPoint) }; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(sqlForInsertRowInFP)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + return false; + } + } + } + } + } + + return true; + } + + return false; +} + + +template<> +bool DSqliteHandle::helpExecSql>, + bool>(const std::list> &sqlStrs, + const QString &mountPoint) +{ + if (!m_flag.load(std::memory_order_consume) && !sqlStrs.empty() && !mountPoint.isEmpty()) { + std::list>::const_iterator cbeg{ sqlStrs.cbegin() }; + std::list>::const_iterator cend{ sqlStrs.cend() }; + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::TagFilesThroughColor2) }; + + + QSqlQuery sqlQuery{ *m_sqlDatabasePtr }; + bool result{ true }; + + for (; cbeg != cend; ++cbeg) { + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(std::get<0>(*cbeg))) { + qWarning() << sqlQuery.lastError().text(); + } + + int cnter{ 0 }; + + if (sqlQuery.next()) { + cnter = sqlQuery.value("counter").toInt(); + } + + + if (cnter == 0) { + bool flg{ true }; + + if (!sqlQuery.exec(std::get<1>(*cbeg))) { + flg = false; + qWarning() << sqlQuery.lastError().text(); + } + + if (flg) { + + if (!sqlQuery.exec(std::get<2>(*cbeg))) { + qWarning() << sqlQuery.lastError().text(); + } + + std::list tagNames{}; + + while (sqlQuery.next()) { + QString tagName{ sqlQuery.value("tag_name").toString() }; + tagNames.emplace_back(std::move(tagName)); + } + + if (!tagNames.empty()) { + + std::size_t size{ tagNames.size() }; + + if (size < 3) { + std::size_t redundant{ 3 - size }; + + for (std::size_t index = 0; index < redundant; ++index) { + tagNames.emplace_back(QString{""}); + } + } + + QString sqlForCounting{ range.first->second }; + sqlForCounting = sqlForCounting.arg(std::get<4>(*cbeg)); + std::list::const_iterator tagNameItr{ tagNames.cbegin() }; + + if (!sqlQuery.exec(sqlForCounting)) { + qWarning() << sqlQuery.lastError().text(); + result = false; + break; + } + + if (sqlQuery.next()) { + int cter{ sqlQuery.value("counter").toInt() }; + + if (cter == 0) { + QString sqlForInsertingNewRow{ std::get<3>(*cbeg) }; + sqlForInsertingNewRow = sqlForInsertingNewRow.arg(std::get<4>(*cbeg)); + sqlForInsertingNewRow = sqlForInsertingNewRow.arg(*tagNameItr); + sqlForInsertingNewRow = sqlForInsertingNewRow.arg(*(++tagNameItr)); + sqlForInsertingNewRow = sqlForInsertingNewRow.arg(*(++tagNameItr)); + + if (!sqlQuery.exec(sqlForInsertingNewRow)) { + qWarning() << sqlQuery.lastError().text(); + result = false; + break; + } + continue; + + } else { + std::multimap::const_iterator sqlItrForUpdating{ range.first }; + ++sqlItrForUpdating; + QString sqlForUpdating{ sqlItrForUpdating->second }; + sqlForUpdating = sqlForUpdating.arg(*tagNameItr); + sqlForUpdating = sqlForUpdating.arg(*(++tagNameItr)); + sqlForUpdating = sqlForUpdating.arg(*(++tagNameItr)); + sqlForUpdating = sqlForUpdating.arg(std::get<4>(*cbeg)); + + if (!sqlQuery.exec(sqlForUpdating)) { + qWarning() << sqlQuery.lastError().text(); + result = false; + break; + } + continue; + } + } + } + } + result = false; + break; + } + + } else { + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPoint) }; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(std::get<0>(*cbeg))) { + qWarning() << sqlQuery.lastError().text(); + } + + int cnter{ 0 }; + + if (sqlQuery.next()) { + cnter = sqlQuery.value("counter").toInt(); + } + + + if (cnter == 0) { + bool flg{ true }; + + if (!sqlQuery.exec(std::get<1>(*cbeg))) { + flg = false; + qWarning() << sqlQuery.lastError().text(); + } + + if (flg) { + + if (!sqlQuery.exec(std::get<2>(*cbeg))) { + qWarning() << sqlQuery.lastError().text(); + } + + std::list tagNames{}; + + while (sqlQuery.next()) { + QString tagName{ sqlQuery.value("tag_name").toString() }; + tagNames.emplace_back(std::move(tagName)); + } + + if (!tagNames.empty()) { + QString sqlForInsertingNewRow{ std::get<3>(*cbeg) }; + std::size_t size{ tagNames.size() }; + + if (size < 3) { + std::size_t redundant{ 3 - size }; + + for (std::size_t index = 0; index < redundant; ++index) { + tagNames.emplace_back(QString{""}); + } + } + + if (sqlQuery.next()) { + int cter{ sqlQuery.value("counter").toInt() }; + std::list::const_iterator tagNameItr{ tagNames.cbegin() }; + + if (cter == 0) { + QString sql_for_inserting_new_row{ std::get<3>(*cbeg) }; + sql_for_inserting_new_row = sql_for_inserting_new_row.arg(*tagNameItr); + sql_for_inserting_new_row = sql_for_inserting_new_row.arg(*(++tagNameItr)); + sql_for_inserting_new_row = sql_for_inserting_new_row.arg(*(++tagNameItr)); + sql_for_inserting_new_row = sql_for_inserting_new_row.arg(std::get<4>(*cbeg)); + + if (!sqlQuery.exec(sql_for_inserting_new_row)) { + qWarning() << sqlQuery.lastError().text(); + result = false; + break; + } + continue; + + } else { + std::multimap::const_iterator sqlItrForUpdating{ range.first }; + ++sqlItrForUpdating; + QString sqlForUpdating{ sqlItrForUpdating->second }; + sqlForUpdating = sqlForUpdating.arg(*tagNameItr); + sqlForUpdating = sqlForUpdating.arg(*(++tagNameItr)); + sqlForUpdating = sqlForUpdating.arg(*(++tagNameItr)); + sqlForUpdating = sqlForUpdating.arg(std::get<4>(*cbeg)); + + if (!sqlQuery.exec(sqlForInsertingNewRow)) { + qWarning() << sqlQuery.lastError().text(); + result = false; + break; + } + continue; + } + } + } + } + result = false; + break; + } + continue; + } + result = false; + break; + } + } + return result; + } + return false; +} + + +template<> +bool DSqliteHandle::helpExecSql(const QString &tag_name, const QString &mountPoint) +{ + if (!tag_name.isEmpty() && mountPoint == QString{"/home"}) { + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::TagFilesThroughColor3) }; + QSqlQuery sql_query{ *m_sqlDatabasePtr }; + QString sql_counting{ range.first->second.arg(tag_name) }; + QString sql_inserting{ (++range.first)->second.arg(tag_name) }; + + if (sql_query.exec(sql_counting)) { + + if (sql_query.next()) { + int number{ sql_query.value("counter").toInt() }; + + if (number == 0) { + sql_query.clear(); + + if (!sql_query.exec(sql_inserting)) { + qWarning() << sql_query.lastError().text(); + + return false; + } + + emit addNewTags(QVariant{QList{tag_name}}); + } + + return true; + } + } + } + + return false; +} + + + +template<> +bool DSqliteHandle::helpExecSql>(const std::list &sqlStrs, const QString &mountPoint) +{ + if (!m_flag.load(std::memory_order_consume) && !sqlStrs.empty() && !mountPoint.isEmpty()) { + std::list::const_iterator cbeg{ sqlStrs.cbegin() }; + std::list::const_iterator cend{ sqlStrs.cend() }; + QSqlQuery sqlQuery{*m_sqlDatabasePtr}; + + for (; cbeg != cend; ++cbeg) { + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(*cbeg)) { + qWarning() << sqlQuery.lastError().text(); + } + + } else { + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPoint) }; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(*cbeg)) { + qWarning() << sqlQuery.lastError().text(); + } + + } else { + return false; + } + } + } + + return true; + } + + return false; +} + + +template<> +bool DSqliteHandle::helpExecSql>>(const QMap> &fileNameAndTagNames, + const QString &mountPoint) +{ + if (!fileNameAndTagNames.isEmpty() && !mountPoint.isEmpty() && static_cast(m_sqlDatabasePtr)) { + QMap>::const_iterator cbeg{ fileNameAndTagNames.cbegin() }; + QMap>::const_iterator cend{ fileNameAndTagNames.cend() }; + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::UntagSamePartionFiles2) }; + QSqlQuery sqlQuery{ *m_sqlDatabasePtr }; + + for (; cbeg != cend; ++cbeg) { + std::multimap::const_iterator rangeBeg{ range.first }; + QString countTagNamesInTagWithFile{ rangeBeg->second.arg(cbeg.key()) }; + + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(countTagNamesInTagWithFile)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + if (sqlQuery.next()) { + int size{ sqlQuery.value(0).toInt() }; + + if (size == 0) { + std::multimap::const_iterator rangeEnd{ range.second }; + QString deleteRowInFileProperty{ (--rangeEnd)->second.arg(cbeg.key()) }; + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(deleteRowInFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPoint) }; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(deleteRowInFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + return false; + } + } + + + } else { + + QString sqlForGetingLeftTag{ (++rangeBeg)->second.arg(cbeg.key()) }; + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(sqlForGetingLeftTag)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + std::deque leftTags{}; + + while (sqlQuery.next()) { + leftTags.push_back(sqlQuery.value("tag_name").toString()); + } + + std::size_t sizeOfLeftTags{ leftTags.size() }; + std::deque::const_iterator leftTagsCbeg{ leftTags.cbegin() }; + + if (sizeOfLeftTags >= 3u) { + leftTags.erase(leftTagsCbeg, leftTagsCbeg + (sizeOfLeftTags - 3u)); + + } else { + + for (; size < 3; ++size) { + leftTags.push_back(QString{}); + } + } + + std::multimap::const_iterator itrForUpdateRow{ (--range.second) }; + leftTagsCbeg = leftTags.cbegin(); + QString updateRowInFileProperty{ (--itrForUpdateRow)->second.arg(*leftTagsCbeg) }; + updateRowInFileProperty = updateRowInFileProperty.arg(*(++leftTagsCbeg)); + updateRowInFileProperty = updateRowInFileProperty.arg(*(++leftTagsCbeg)); + updateRowInFileProperty = updateRowInFileProperty.arg(cbeg.key()); + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(updateRowInFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPoint) }; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(updateRowInFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + return false; + } + + } + } + } + } + + } else { + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPoint) }; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (sqlQuery.exec(countTagNamesInTagWithFile)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + if (sqlQuery.next()) { + + int size{ sqlQuery.value(0).toInt() }; + + if (size == 0) { + std::multimap::const_iterator rangeEnd{ range.second }; + QString deleteRowInFileProperty{ (--rangeEnd)->second.arg(cbeg.key()) }; + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(deleteRowInFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + + DSqliteHandle::ReturnCode return_code{ this->checkDBFileExist(mountPoint) }; + + if (return_code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(deleteRowInFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + return false; + } + } + + + } else { + + QString sqlForGetingLeftTag{ (++rangeBeg)->second }; + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(sqlForGetingLeftTag)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + std::deque leftTags{}; + int sizeOfTags{ sqlQuery.size() }; + + for (long int index = 0; index < sizeOfTags; ++index) { + leftTags.push_back(sqlQuery.value(index).toString()); + } + + std::size_t sizeOfLeftTags{ leftTags.size() }; + std::deque::const_iterator leftTagsCbeg{ leftTags.cbegin() }; + + if (sizeOfLeftTags >= 3u) { + leftTags.erase(leftTagsCbeg, leftTagsCbeg + (sizeOfLeftTags - 3u)); + + } else { + + for (; size < 3; ++size) { + leftTags.push_back(QString{}); + } + } + + std::multimap::const_iterator itrForUpdateRow{ (--range.second) }; + leftTagsCbeg = leftTags.cbegin(); + QString updateRowInFileProperty{ (--itrForUpdateRow)->second.arg(*leftTagsCbeg) }; + updateRowInFileProperty = updateRowInFileProperty.arg(*(++leftTagsCbeg)); + updateRowInFileProperty = updateRowInFileProperty.arg(*(++leftTagsCbeg)); + updateRowInFileProperty = updateRowInFileProperty.arg(cbeg.key()); + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(updateRowInFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + + DSqliteHandle::ReturnCode return_code{ this->checkDBFileExist(mountPoint) }; + + if (return_code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(updateRowInFileProperty)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + } else { + return false; + } + + } + + } + } + } + } + } + } + + return true; + } + + return false; +} + +template<> +bool DSqliteHandle::helpExecSql, bool>(const std::list &files, const QString &mount_point) +{ + + if (!files.empty() && !mount_point.isEmpty()) { + std::list::const_iterator file_itr_beg{ files.cbegin() }; + std::list::const_iterator file_itr_end{ files.cend() }; + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::DeleteFiles) }; + QSqlQuery sql_query{ *m_sqlDatabasePtr }; + + if (!m_flag.load(std::memory_order_acquire)) { + + for (; file_itr_beg != file_itr_end; ++file_itr_beg) { + std::multimap::const_iterator range_beg{ range.first }; + QString clear_tag_with_file_table{ range_beg->second.arg(*file_itr_beg) }; + QString clear_file_property_table{ (++range_beg)->second.arg(*file_itr_beg) }; + + if (!sql_query.exec(clear_file_property_table)) { + qWarning() << sql_query.lastError().text(); + + return false; + } + + if (!sql_query.exec(clear_tag_with_file_table)) { + qWarning() << sql_query.lastError().text(); + + return false; + } + } + + return true; + + } else { + + DSqliteHandle::ReturnCode code{this->checkDBFileExist(mount_point)}; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + for (; file_itr_beg != file_itr_end; ++file_itr_beg) { + std::multimap::const_iterator range_beg{ range.first }; + QString clear_tag_with_file_table{ range_beg->second.arg(*file_itr_beg) }; + QString clear_file_property_table{ (++range_beg)->second.arg(*file_itr_beg) }; + + if (sql_query.exec(clear_file_property_table)) { + qWarning() << sql_query.lastError().text(); + + return false; + } + + if (sql_query.exec(clear_tag_with_file_table)) { + qWarning() << sql_query.lastError().text(); + + return false; + } + } + + return true; + } + } + } + + return false; +} + +template<> +QMap> DSqliteHandle::helpExecSql, QMap>>(const std::list &files, const QString &mount_point) +{ + QMap> file_and_tags{}; + + if (!files.empty() && !mount_point.isEmpty()) { + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::DeleteFiles2) }; + QSqlQuery sql_query{ *m_sqlDatabasePtr }; + + + if (!m_flag.load(std::memory_order_acquire)) { + + for (const QString &file : files) { + QString sql_for_getting_tags{ range.first->second.arg(file) }; + + if (sql_query.exec(sql_for_getting_tags)) { + + while (sql_query.next()) { + QString tag_name{ sql_query.value("tag_name").toString() }; + file_and_tags[file].push_back(tag_name); + } + } + } + + } else { + + DSqliteHandle::ReturnCode code{this->checkDBFileExist(mount_point)}; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + for (const QString &file : files) { + QString sql_for_getting_tags{ range.first->second.arg(file) }; + + if (sql_query.exec(sql_for_getting_tags)) { + + while (sql_query.next()) { + QString tag_name{ sql_query.value("tag_name").toString() }; + file_and_tags[file].push_back(tag_name); + } + } + } + + } + } + } + + return file_and_tags; +} + + + + +template<> +bool DSqliteHandle::helpExecSql>(const std::list &sqlStrs, + const QString &mountPoint) +{ + if (!sqlStrs.empty() && !mountPoint.isEmpty()) { + std::list::const_iterator sqlCBeg{ sqlStrs.cbegin() }; + std::list::const_iterator sqlCEnd{ sqlStrs.cend() }; + QSqlQuery sqlQuery{ *m_sqlDatabasePtr }; + + for (; sqlCBeg != sqlCEnd; ++sqlCBeg) { + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(*sqlCBeg)) { + qWarning() << sqlQuery.lastError().text(); + } + + } else { + DSqliteHandle::ReturnCode code{this->checkDBFileExist(mountPoint)}; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(*sqlCBeg)) { + qWarning() << sqlQuery.lastError().text(); + } + + } else { + + return false; + } + } + } + + return true; + } + + return false; +} + +template<> +bool DSqliteHandle::helpExecSql>>(const QMap> &fileNameAndTagNames, const QString &mountPoint) +{ + + if (!fileNameAndTagNames.isEmpty() && !mountPoint.isEmpty()) { + QMap>::const_iterator cbeg{ fileNameAndTagNames.cbegin() }; + QMap>::const_iterator cend{ fileNameAndTagNames.cend() }; + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::DeleteTags2) }; + std::list gettingFileNamesThroughTagName{}; + + for (; cbeg != cend; ++cbeg) { + std::multimap::const_iterator rangeBeg{ range.first }; + QString sqlForGettingFileNames{ rangeBeg->second.arg(cbeg.key()) }; + gettingFileNamesThroughTagName.emplace_back(std::move(sqlForGettingFileNames)); + } + + QSqlQuery sqlQuery{ *m_sqlDatabasePtr }; + std::map> filesNameAndTagsName{}; + + if (!gettingFileNamesThroughTagName.empty()) { + std::list::const_iterator sqlCBeg{ gettingFileNamesThroughTagName.cbegin() }; + std::list::const_iterator sqlCEnd{ gettingFileNamesThroughTagName.cend() }; + + for (; sqlCBeg != sqlCEnd; ++sqlCBeg) { + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(*sqlCBeg)) { + qWarning() << sqlQuery.lastError().text(); + } + + while (sqlQuery.next()) { + QString fileName{ sqlQuery.value("file_name").toString() }; + filesNameAndTagsName[fileName] = std::deque {}; + } + + + } else { + + DSqliteHandle::ReturnCode code{this->checkDBFileExist(mountPoint)}; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(*sqlCBeg)) { + qWarning() << sqlQuery.lastError().text(); + } + + while (sqlQuery.next()) { + QString fileName{ sqlQuery.value("file_name").toString() }; + filesNameAndTagsName[fileName] = std::deque {}; + } + + } else { + return false; + } + } + } + } + + if (!filesNameAndTagsName.empty()) { + std::map> transcript{}; + std::map>::const_iterator filesAndTagsItrBeg{ filesNameAndTagsName.cbegin() }; + std::map>::const_iterator filesAndTagsItrEnd{ filesNameAndTagsName.cend() }; + + for (; filesAndTagsItrBeg != filesAndTagsItrEnd; ++filesAndTagsItrBeg) { + + if (!m_flag.load(std::memory_order_consume)) { + std::multimap::const_iterator rangeBeg{ range.first }; + ++rangeBeg; + QString sqlForGettingTagsOfFile{ rangeBeg->second.arg(filesAndTagsItrBeg->first) }; + + if (!sqlQuery.exec(sqlForGettingTagsOfFile)) { + qWarning() << sqlQuery.lastError().text(); + } + + while (sqlQuery.next()) { + QString tagName{ sqlQuery.value("tag_name").toString() }; + transcript[filesAndTagsItrBeg->first].emplace_back(std::move(tagName)); + } + + } else { + DSqliteHandle::ReturnCode code{this->checkDBFileExist(mountPoint)}; + + if (code == DSqliteHandle::ReturnCode::Exist) { + std::multimap::const_iterator rangeBeg{ range.first }; + ++rangeBeg; + QString sqlForGettingTagsOfFile{ rangeBeg->second.arg(filesAndTagsItrBeg->first) }; + + if (!sqlQuery.exec(sqlForGettingTagsOfFile)) { + qWarning() << sqlQuery.lastError().text(); + continue; + } + + while (sqlQuery.next()) { + QString tagName{ sqlQuery.value("tag_name").toString() }; + transcript[filesAndTagsItrBeg->first].emplace_back(std::move(tagName)); + } + } + } + } + + if (!transcript.empty()) { + filesNameAndTagsName = std::move(transcript); + } + } + + + if (!filesNameAndTagsName.empty()) { + std::map>::const_iterator itrForUpdatingOrDeleting{ filesNameAndTagsName.cbegin() }; + std::map>::const_iterator itrForUpdatingOrDeletingEnd{ filesNameAndTagsName.cend() }; + std::multimap::const_iterator rangeLast{ --(range.second) }; + + for (; itrForUpdatingOrDeleting != itrForUpdatingOrDeletingEnd; ++itrForUpdatingOrDeleting) { + std::multimap::const_iterator sqlItr{ rangeLast }; + QString sqlForUpdatingOrDeleting{}; + std::size_t tagAmount{ itrForUpdatingOrDeleting->second.size() }; + + if (tagAmount >= 3) { + sqlForUpdatingOrDeleting = sqlItr->second.arg(itrForUpdatingOrDeleting->first); + } else if (tagAmount == 0) { + QString sqlForDeletingRowInFileProperty{ "DELETE FROM file_property WHERE file_property.file_name = \'%1\'" }; + sqlForUpdatingOrDeleting = sqlForDeletingRowInFileProperty.arg(itrForUpdatingOrDeleting->first); + + } else { + std::size_t difference{ 3u - tagAmount }; + std::deque::const_iterator tagNameBeg{ itrForUpdatingOrDeleting->second.cbegin() }; + std::deque::const_iterator tagNameEnd{ itrForUpdatingOrDeleting->second.cend() }; + + sqlForUpdatingOrDeleting = sqlItr->second.arg(*tagNameBeg); + ++tagNameBeg; + + for (; tagNameBeg != tagNameEnd; ++tagNameBeg) { + sqlForUpdatingOrDeleting = sqlForUpdatingOrDeleting.arg(*tagNameBeg); + } + + for (std::size_t index = 0; index < difference; ++index) { + sqlForUpdatingOrDeleting = sqlForUpdatingOrDeleting.arg(QString{}); + } + sqlForUpdatingOrDeleting = sqlForUpdatingOrDeleting.arg(itrForUpdatingOrDeleting->first); + } + + + if (!m_flag.load(std::memory_order_consume) && !sqlForUpdatingOrDeleting.isEmpty()) { + + if (!sqlQuery.exec(sqlForUpdatingOrDeleting)) { + qWarning() << sqlQuery.lastError().text(); + } + + } else if (m_flag.load(std::memory_order_consume) && !sqlForUpdatingOrDeleting.isEmpty()) { + DSqliteHandle::ReturnCode code{this->checkDBFileExist(mountPoint)}; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(sqlForUpdatingOrDeleting)) { + qWarning() << sqlQuery.lastError().text(); + } + + } else { + return false; + } + + } + } + } + return true; + } + return false; +} + + +template<> +bool DSqliteHandle::helpExecSql, bool>(const QList &tag_name, const QString &mountPoint) +{ + if (!tag_name.isEmpty() && mountPoint == QString{"/home"} && QFileInfo::exists("/home")) { + QList::const_iterator c_beg{ tag_name.cbegin() }; + QList::const_iterator c_end{ tag_name.cend() }; + QSqlQuery sql_query{ *m_sqlDatabasePtr }; + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::DeleteTags3) }; + + for (; c_beg != c_end; ++c_beg) { + QString sql_str{ range.first->second }; + sql_str = sql_str.arg(*c_beg); + + if (!sql_query.exec(sql_str)) { + qWarning() << sql_query.lastError().text(); + return false; + } + } + + return true; + } + + return false; +} + + + +template<> +bool DSqliteHandle::helpExecSql>(const std::map &sqlStrs, const QString &mountPoint) +{ + if (!sqlStrs.empty() && !mountPoint.isEmpty()) { + std::map::const_iterator sqlCBeg{ sqlStrs.cbegin() }; + std::map::const_iterator sqlCEnd{ sqlStrs.cend() }; + QSqlQuery sqlQuery{ *m_sqlDatabasePtr }; + + for (; sqlCBeg != sqlCEnd; ++sqlCBeg) { + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(sqlCBeg->first)) { + qWarning() << sqlQuery.lastError().text(); + } + + if (!sqlQuery.exec(sqlCBeg->second)) { + qWarning() << sqlQuery.lastError().text(); + } + + } else { + DSqliteHandle::ReturnCode code{this->checkDBFileExist(mountPoint)}; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(sqlCBeg->first)) { + qWarning() << sqlQuery.lastError().text(); + } + + if (!sqlQuery.exec(sqlCBeg->second)) { + qWarning() << sqlQuery.lastError().text(); + } + + } else { + return false; + } + } + } + return true; + } + return false; +} + +template<> +QMap> DSqliteHandle::helpExecSql, + QMap>>(const std::map &files, const QString &mount_point) +{ + QMap> file_with_tags{}; + + if (!files.empty()) { + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(SqlType::ChangeFilesName2) }; + std::map::const_iterator file_beg{ files.cbegin() }; + std::map::const_iterator file_end{ files.cend() }; + QSqlQuery sql_query{ *m_sqlDatabasePtr }; + + + if (!m_flag.load(std::memory_order_consume)) { + + for (; file_beg != file_end; ++file_beg) { + + if (sql_query.exec(range.first->second.arg(file_beg->first))) { + + while (sql_query.next()) { + QString tag_name{ sql_query.value("tag_name").toString() }; + file_with_tags[file_beg->first].push_back(tag_name); + } + } + } + + } else { + + DSqliteHandle::ReturnCode code{this->checkDBFileExist(mount_point)}; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + for (; file_beg != file_end; ++file_beg) { + + if (sql_query.exec(range.first->second.arg(file_beg->first))) { + + while (sql_query.next()) { + QString tag_name{ sql_query.value("tag_name").toString() }; + file_with_tags[file_beg->first].push_back(tag_name); + } + } + } + } + } + } + + return file_with_tags; +} + + +template<> +bool DSqliteHandle::helpExecSql>>(const std::list> &sqlStrs, + const QString &mountPoint) +{ + if (!sqlStrs.empty() && !mountPoint.isEmpty()) { + std::list>::const_iterator sqlCBeg{ sqlStrs.cbegin() }; + std::list>::const_iterator sqlCEnd{ sqlStrs.cend() }; + QSqlQuery sqlQuery{ *m_sqlDatabasePtr }; + + + for (; sqlCBeg != sqlCEnd; ++sqlCBeg) { + + if (!m_flag.load(std::memory_order_consume)) { + + QSqlQuery sql_query(*m_sqlDatabasePtr); + + if (!sql_query.exec(std::get<0>(*sqlCBeg))) { + qWarning() << sql_query.lastError().text(); + } + + if (!sql_query.exec(std::get<1>(*sqlCBeg))) { + qWarning() << sql_query.lastError().text(); + } + + if (!sql_query.exec(std::get<2>(*sqlCBeg))) { + qWarning() << sql_query.lastError().text(); + } + + if (!sql_query.exec(std::get<3>(*sqlCBeg))) { + qWarning() << sql_query.lastError().text(); + } + + } else { + DSqliteHandle::ReturnCode code{this->checkDBFileExist(mountPoint)}; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(std::get<0>(*sqlCBeg))) { + qWarning() << sqlQuery.lastError().text(); + } + + if (!sqlQuery.exec(std::get<1>(*sqlCBeg))) { + qWarning() << sqlQuery.lastError().text(); + } + + if (!sqlQuery.exec(std::get<2>(*sqlCBeg))) { + qWarning() << sqlQuery.lastError().text(); + } + + if (!sqlQuery.exec(std::get<3>(*sqlCBeg))) { + qWarning() << sqlQuery.lastError().text(); + } + + } else { + return false; + } + } + } + return true; + } + return false; +} + + +template<> +bool DSqliteHandle::helpExecSql>, bool>(const QMap> &old_and_new, + const QString &mountPoint) +{ + if (!old_and_new.empty() && mountPoint == QString{"/home"} && QFileInfo::exists("/home")) { + QMap>::const_iterator c_beg{ old_and_new.cbegin() }; + QMap>::const_iterator c_end{ old_and_new.cend() }; + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(SqlType::ChangeTagsName2) }; + QSqlQuery sql_query{ *m_sqlDatabasePtr }; + + for (; c_beg != c_end; ++c_beg) { + QString sql_str{ range.first->second.arg(c_beg.value().first()) }; + sql_str = sql_str.arg(c_beg.key()); + + if (!sql_query.exec(sql_str)) { + qWarning() << sql_query.lastError().text(); + return false; + } + } + + return true; + } + + return false; +} + + +template<> +QList DSqliteHandle::helpExecSql>(const QString &sqlStr, const QString &mountPoint) +{ + QList tagNames{}; + + if (!sqlStr.isEmpty() && !mountPoint.isEmpty()) { + QSqlQuery sqlQuery{ *m_sqlDatabasePtr }; + + if (!m_flag.load(std::memory_order_consume)) { + + if (!sqlQuery.exec(sqlStr)) { + qWarning() << sqlQuery.lastError().text(); + } + + while (sqlQuery.next()) { + QString tagName{ sqlQuery.value("tag_name").toString() }; + tagNames.push_back(tagName); + } + + } else { + + DSqliteHandle::ReturnCode code{this->checkDBFileExist(mountPoint)}; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (!sqlQuery.exec(sqlStr)) { + qWarning() << sqlQuery.lastError().text(); + } + + while (sqlQuery.next()) { + QString tagName{ sqlQuery.value("tag_name").toString() }; + tagNames.push_back(tagName); + } + } + } + } + + return tagNames; +} + + +template<> +QList DSqliteHandle::helpExecSql>(const QString &sqlStr, const QString &mountPoint) +{ + QList files{}; + + if (!sqlStr.isEmpty() && !mountPoint.isEmpty()) { + QSqlQuery sqlQuery{ *m_sqlDatabasePtr }; + + if (!m_flag.load(std::memory_order_consume)) { + + if (sqlQuery.exec(sqlStr)) { + + while (sqlQuery.next()) { + QString fileName{ sqlQuery.value("file_name").toString() }; + files.push_back(mountPoint + fileName); + } + } + + } else { + + DSqliteHandle::ReturnCode code{this->checkDBFileExist(mountPoint)}; + + if (code == DSqliteHandle::ReturnCode::Exist) { + + if (sqlQuery.exec(sqlStr)) { + + while (sqlQuery.next()) { + QString fileName{ sqlQuery.value("file_name").toString() }; + files.push_back(mountPoint + fileName); + } + } + + } + } + } + return files; +} + + +template<> +QMap> DSqliteHandle::helpExecSql, QMap>>(const QList &tag_names, const QString &mount_point) +{ + (void)mount_point; + QMap> file_and_tags{}; + + if (!tag_names.isEmpty()) { + + if (m_partionsOfDevices && !m_partionsOfDevices->empty()) { + std::map>::const_iterator device_itr_beg{ m_partionsOfDevices->cbegin() }; + std::map>::const_iterator device_itr_end{ m_partionsOfDevices->cend() }; + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::DeleteTags4) }; + + for (; device_itr_beg != device_itr_end; ++device_itr_beg) { + std::multimap::const_iterator partion_itr_beg{ device_itr_beg->second.cbegin() }; + std::multimap::const_iterator partion_itr_end{ device_itr_beg->second.cend() }; + + for (; partion_itr_beg != partion_itr_end; ++partion_itr_beg) { + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(partion_itr_beg->second) }; + + if (code == DSqliteHandle::ReturnCode::NoExist || code == DSqliteHandle::ReturnCode::Exist) { + this->connectToShareSqlite(partion_itr_beg->second); + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open()) { + QSqlQuery sql_query{ *m_sqlDatabasePtr }; + + for (const QString &tag_name : tag_names) { + QString sqlForGetFilesThroughTag{ range.first->second.arg(tag_name) }; + + + if (!m_flag.load(std::memory_order_consume)) { + + if (sql_query.exec(sqlForGetFilesThroughTag)) { + + while (sql_query.next()) { + QString fileName{ sql_query.value("file_name").toString() }; + + if (!fileName.isEmpty()) { + QString complete_file_name{ partion_itr_beg->second + fileName }; + file_and_tags[complete_file_name].push_back(tag_name); + } + } + } + + } else { + + DSqliteHandle::ReturnCode return_code{this->checkDBFileExist(partion_itr_beg->second)}; + + if (return_code == DSqliteHandle::ReturnCode::Exist) { + + if (sql_query.exec(sqlForGetFilesThroughTag)) { + + while (sql_query.next()) { + QString fileName{ sql_query.value("file_name").toString() }; + + if (!fileName.isEmpty()) { + QString complete_file_name{ partion_itr_beg->second + fileName }; + file_and_tags[complete_file_name].push_back(tag_name); + } + } + } + + } else { + continue; + } + } + } + } + } + } + } + } + } + + this->closeSqlDatabase(); + + return file_and_tags; +} + + + + +template<> ///###: +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags) +{ + if (!filesAndTags.isEmpty()) { + int size{ filesAndTags.size() }; + QList mutualTags{}; + QList currentTags{ filesAndTags.cbegin().value() }; + + if (size == 1) { + mutualTags = this->execSqlstr>(filesAndTags); + } + + if (size > 1) { + mutualTags = this->execSqlstr>(filesAndTags); + } + + QPair unixDeviceAndMountPoint{ DSqliteHandle::getMountPointOfFile( + DUrl::fromLocalFile(filesAndTags.cbegin().key()), m_partionsOfDevices) }; + + if (unixDeviceAndMountPoint.second.isEmpty() || unixDeviceAndMountPoint.second.isNull()) { + return false; + } + + ///###: remove the info of mount-point. + QMap> file_with_tags{}; + QMap>::const_iterator itr_cbeg{ filesAndTags.cbegin() }; + QMap>::const_iterator itr_cend{ filesAndTags.cend() }; + + for (; itr_cbeg != itr_cend; ++itr_cbeg) { + QString file{ itr_cbeg.key() }; + QString file_backup{ this->remove_mount_point(file, unixDeviceAndMountPoint.second) }; + + file_with_tags[file_backup] = itr_cbeg.value(); + } + +//#ifdef QT_DEBUG +// qDebug()<< "mount point: " << unixDeviceAndMountPoint.second; +// qDebug()<< "file_with_tags: " << file_with_tags; +//#endif + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(unixDeviceAndMountPoint.second) }; + + ///###: when tag files through many tags. + ///###: if these files have mutual do this. + if (!mutualTags.isEmpty()) { + + if (code == DSqliteHandle::ReturnCode::Exist || code == DSqliteHandle::ReturnCode::NoExist) { + this->connectToShareSqlite(unixDeviceAndMountPoint.second); + QList newTags{}; + QList existingTags{}; + QList decreased{}; + + for (const QString &tagName : currentTags) { + + if (mutualTags.contains(tagName)) { + existingTags.push_back(tagName); + } else { + newTags.push_back(tagName); + } + } + + if (existingTags.size() < mutualTags.size()) { + + for (const QString &tagName : mutualTags) { + + if (!existingTags.contains(tagName)) { + decreased << tagName; + } + } + } + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open() && m_sqlDatabasePtr->transaction()) { + bool valueOfDelRedundant{ true }; + + if (!decreased.isEmpty()) { + QMap> mapForDelRedundant{}; + QMap>::const_iterator cbegOfFiles{ file_with_tags.cbegin() }; + QMap>::const_iterator cendOfFiles{ file_with_tags.cend() }; + + for (; cbegOfFiles != cendOfFiles; ++cbegOfFiles) { + mapForDelRedundant[cbegOfFiles.key()] = decreased; + } + + valueOfDelRedundant = this->helpExecSql>, + bool>(mapForDelRedundant, unixDeviceAndMountPoint.second); + } + + bool valueOfInsertNew{ true }; + + if (!newTags.isEmpty()) { + QMap>::const_iterator cbegOfFiles{ file_with_tags.cbegin() }; + QMap>::const_iterator cendOfFiles{ file_with_tags.cend() }; + QMap> mapForInsertingNew{}; + + + for (; cbegOfFiles != cendOfFiles; ++cbegOfFiles) { + mapForInsertingNew[cbegOfFiles.key()] = newTags; + } + + valueOfInsertNew = this->helpExecSql>, + bool>(mapForInsertingNew, unixDeviceAndMountPoint.second); + } + + + bool valueOfUpdating{ true }; + QList files{ file_with_tags.keys() }; + valueOfUpdating = this->helpExecSql, + bool>(files, unixDeviceAndMountPoint.second); + + if (!(valueOfDelRedundant && valueOfInsertNew && valueOfUpdating && m_sqlDatabasePtr->commit())) { + m_sqlDatabasePtr->rollback(); + this->closeSqlDatabase(); + + return false; + } + + this->closeSqlDatabase(); + + ///###: emit signal. which files were tagged and which files were untagged. + QMap> file_and_tags_backup{ filesAndTags }; + + if (!decreased.isEmpty()) { + QMap>::iterator itr_beg{ file_and_tags_backup.begin() }; + QMap>::iterator itr_end{ file_and_tags_backup.end() }; + + for (; itr_beg != itr_end; ++itr_beg) { + + for (const QString &tag_name : decreased) { + file_and_tags_backup[itr_beg.key()].removeAll(tag_name); + } + } + } + + QMap var_map{}; + QMap>::const_iterator the_beg{ file_and_tags_backup.cbegin() }; + QMap>::const_iterator the_end{ file_and_tags_backup.cend() }; + + for (; the_beg != the_end; ++the_beg) { + var_map[the_beg.key()] = QVariant{ the_beg.value() }; + } + + emit filesWereTagged(var_map); + + var_map.clear(); + the_beg = file_and_tags_backup.cbegin(); + the_end = file_and_tags_backup.cend(); + + for (; the_beg != the_end; ++the_beg) { + var_map[the_beg.key()] = QVariant{ decreased }; + } + + emit untagFiles(var_map); + ///###: end of emmitting signal. + + return true; + } + } + + ///###: if these files dont have mutual tag(s). + } else { + + if (code == DSqliteHandle::ReturnCode::Exist || code == DSqliteHandle::ReturnCode::NoExist) { + this->connectToShareSqlite(unixDeviceAndMountPoint.second); + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open() && m_sqlDatabasePtr->transaction()) { + + bool valueOfInsertNew{ true }; + valueOfInsertNew = this->helpExecSql>, + bool>(file_with_tags, unixDeviceAndMountPoint.second); + + bool valueOfUpdating{ true }; + QList files{ file_with_tags.keys() }; + valueOfUpdating = this->helpExecSql, + bool>(files, unixDeviceAndMountPoint.second); + + if (!(valueOfInsertNew && valueOfUpdating && m_sqlDatabasePtr->commit())) { + m_sqlDatabasePtr->rollback(); + this->closeSqlDatabase(); + + return false; + } + + this->closeSqlDatabase(); + QMap var_map{}; + QMap>::const_iterator the_beg{ filesAndTags.cbegin() }; + QMap>::const_iterator the_end{ filesAndTags.cend() }; + + for (; the_beg != the_end; ++the_beg) { + var_map[the_beg.key()] = QVariant{ the_beg.value() }; + } + + emit filesWereTagged(var_map); + + return true; + } + } + } + + } + + this->closeSqlDatabase(); + + return false; +} + + + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags) +{ + ///##: log! but you need specify the path of file. +// std::basic_ofstream outStream{ "", std::ios_base::out | std::ios_base::app }; + + if (!filesAndTags.isEmpty()) { + +// DSqliteHandle::ReturnCode return_code{ this->checkDBFileExist("/home", ".__main.db") }; + +// if (return_code != DSqliteHandle::ReturnCode::Exist) { +// return false; +// } + + this->connectToShareSqlite("/home", ".__main.db"); + bool the_result{ true }; + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open() && m_sqlDatabasePtr->transaction()) { + the_result = this->helpExecSql(filesAndTags.cbegin().key(), "/home"); + } + + if (!(the_result && m_sqlDatabasePtr->commit())) { + m_sqlDatabasePtr->rollback(); + this->closeSqlDatabase(); + + return false; + } + + QMap> mount_point_and_files{}; + QMap>::const_iterator cbeg{ filesAndTags.cbegin() }; + QMap>::const_iterator cend{ filesAndTags.cend() }; + QString tag_name{ cbeg.value().first() }; + + if (!(m_partionsOfDevices && m_partionsOfDevices->empty())) { + return false; + } + + for (; cbeg != cend; ++cbeg) { + QPair unixDeviceAndMountPoint{ DSqliteHandle::getMountPointOfFile(DUrl::fromLocalFile(cbeg.key()), m_partionsOfDevices) }; + + if (!unixDeviceAndMountPoint.second.isEmpty()) { + QString file_were_removed_mount_point{ this->remove_mount_point(cbeg.key(), unixDeviceAndMountPoint.second) }; + mount_point_and_files[unixDeviceAndMountPoint.second].push_back(file_were_removed_mount_point); + } + } + + ///###: log! +// outStream << "LANG: " << qgetenv("LANG").toStdString() +// << ", LANGUAGE: " << qgetenv("LANGUAGE").toStdString() << std::endl; + + + + cbeg = mount_point_and_files.cbegin(); + cend = mount_point_and_files.cend(); + bool result{ true }; + + for (; cbeg != cend; ++cbeg) { + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(SqlType::TagFilesThroughColor) }; + std::list> sqlStrs{}; + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(cbeg.key()) }; + + if (code == DSqliteHandle::ReturnCode::Exist || code == DSqliteHandle::ReturnCode::NoExist) { + this->connectToShareSqlite(cbeg.key()); + + if (static_cast(m_sqlDatabasePtr)) { + QList::const_iterator files_cbeg{ cbeg.value().cbegin() }; + QList::const_iterator files_cend{ cbeg.value().cend() }; + + for (; files_cbeg != files_cend; ++files_cbeg) { + std::multimap::const_iterator sqlItrBeg{ range.first }; + QString sqlForCounting{sqlItrBeg->second.arg(tag_name)}; + sqlForCounting = sqlForCounting.arg(*files_cbeg); + + ++sqlItrBeg; + + QString sqlForInserting{sqlItrBeg->second.arg(tag_name)}; + sqlForInserting = sqlForInserting.arg(*files_cbeg); + + ++sqlItrBeg; + + QString sqlForSelectingTagName{ sqlItrBeg->second.arg(*files_cbeg) }; + + ++sqlItrBeg; + + QString sqlForInsertingNewRow{ sqlItrBeg->second }; + + std::tuple sqlTuple{ sqlForCounting, sqlForInserting, sqlForSelectingTagName, + sqlForInsertingNewRow, *files_cbeg, tag_name }; + sqlStrs.push_back(std::move(sqlTuple)); + + } + + if (!sqlStrs.empty()) { + if (m_sqlDatabasePtr->open() && m_sqlDatabasePtr->transaction()) { + bool value = this->helpExecSql>, bool>(sqlStrs, cbeg.key()); + + if (value) { + + if (!m_sqlDatabasePtr->commit()) { + m_sqlDatabasePtr->rollback(); + this->closeSqlDatabase(); + result = false; + + continue; + } + + this->closeSqlDatabase(); + QMap var_map{}; + + for (const QString &file_name : cbeg.value()) { + var_map[file_name] = QVariant{ QList{ tag_name } }; + } + + emit filesWereTagged(var_map); + } + } + } + } + } + } + + this->closeSqlDatabase(); + + return result; + } + + this->closeSqlDatabase(); + + return false; +} + + + + + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags) +{ + if (!filesAndTags.isEmpty()) { + QMap>::const_iterator cbeg{ filesAndTags.cbegin() }; + QMap>::const_iterator cend{ filesAndTags.cend() }; + QPair unixDeviceAndMountPoint{ DSqliteHandle::getMountPointOfFile(DUrl::fromLocalFile(cbeg.key()), m_partionsOfDevices) }; + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(unixDeviceAndMountPoint.second) }; + + if (code == DSqliteHandle::ReturnCode::Exist || code == DSqliteHandle::ReturnCode::NoExist) { + + ///###: remove mount-point of files. + QMap> file_with_tags{}; + QMap>::const_iterator itr_cbeg{ filesAndTags.cbegin() }; + QMap>::const_iterator itr_cend{ filesAndTags.cend() }; + + for (; itr_cbeg != itr_cend; ++itr_cbeg) { + QString file_were_removed_mount_point{ this->remove_mount_point(itr_cbeg.key(), unixDeviceAndMountPoint.second) }; + file_with_tags[file_were_removed_mount_point] = itr_cbeg.value(); + } + ///###: end to remove. + + this->connectToShareSqlite(unixDeviceAndMountPoint.second); + + if (static_cast(m_sqlDatabasePtr)) { + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(SqlType::UntagSamePartionFiles) }; + + if (range.first != range.second) { + + ///###: [sql]. + std::list sqlForDeletingRowOfTagWithFile{}; + cbeg = file_with_tags.cbegin(); //###:!!!!!!!! + cend = file_with_tags.cend();//###:!!!!!!!!! + + for (; cbeg != cend; ++cbeg) { + std::multimap::const_iterator rangeCBeg{ range.first }; + QString fileLocalName{ cbeg.key() }; + QList::const_iterator cTagBeg{ cbeg.value().cbegin() }; + QList::const_iterator cTagEnd{ cbeg.value().cend() }; + + for (; cTagBeg != cTagEnd; ++cTagBeg) { + QString deletingRowOfTagWithFile{ rangeCBeg->second.arg(fileLocalName) }; + deletingRowOfTagWithFile = deletingRowOfTagWithFile.arg(*cTagBeg); + sqlForDeletingRowOfTagWithFile.push_back(deletingRowOfTagWithFile); + } + } + + if (!sqlForDeletingRowOfTagWithFile.empty() && m_sqlDatabasePtr->open() + && m_sqlDatabasePtr->transaction()) { + bool resultOfDeleteRowInTagWithFile{ this->helpExecSql, bool>(sqlForDeletingRowOfTagWithFile, unixDeviceAndMountPoint.second) }; + bool resultOfUpdateFileProperty{ false }; + + if (resultOfDeleteRowInTagWithFile) { + resultOfUpdateFileProperty = this->helpExecSql>, bool>(file_with_tags, unixDeviceAndMountPoint.second); + } + + if (!(resultOfDeleteRowInTagWithFile && resultOfUpdateFileProperty + && m_sqlDatabasePtr->commit())) { + m_sqlDatabasePtr->rollback(); + this->closeSqlDatabase(); + + return false; + } + + this->closeSqlDatabase(); + + return true; + } + } + } + + } else { + + qWarning("A partion was unmounted just now!"); + this->closeSqlDatabase(); + + return false; + } + } + + this->closeSqlDatabase(); + + return false; +} + + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags) +{ + + if (!filesAndTags.isEmpty()) { + QMap>::const_iterator cbeg{ filesAndTags.cbegin() }; + QMap>::const_iterator cend{ filesAndTags.cend() }; + + ///###: ]> + std::unordered_map>> untagFilesInSpecifyPartion{}; + + ///###: classify the files through mount-point. + for (; cbeg != cend; ++cbeg) { + QPair unixDeviceAndMountPoint{ DSqliteHandle::getMountPointOfFile(DUrl::fromLocalFile(cbeg.key()), m_partionsOfDevices) }; + + for (const QString &tag_name : cbeg.value()) { + untagFilesInSpecifyPartion[unixDeviceAndMountPoint.second][cbeg.key()].push_back(tag_name); + } + } + + if (!untagFilesInSpecifyPartion.empty()) { + std::unordered_map>>::const_iterator partionItrBeg{ untagFilesInSpecifyPartion.cbegin() }; + std::unordered_map>>::const_iterator partionItrEnd{ untagFilesInSpecifyPartion.cend() }; + bool result{ true }; + + for (; partionItrBeg != partionItrEnd; ++partionItrBeg) { + bool val{ this->execSqlstr(partionItrBeg->second) }; + result = (val && result); + } + + this->closeSqlDatabase(); + QMap var_map{}; + QMap>::const_iterator the_beg{ filesAndTags.cbegin() }; + QMap>::const_iterator the_end{ filesAndTags.cend() }; + + for (; the_beg != the_end; ++the_beg) { + var_map[the_beg.key()] = QVariant{ the_beg.value() }; + } + + emit untagFiles(var_map); + + return true; + } + } + + this->closeSqlDatabase(); + + return false; +} + + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags) +{ + if (!filesAndTags.isEmpty()) { + QMap>::const_iterator cbeg{ filesAndTags.cbegin() }; + QMap>::const_iterator cend{ filesAndTags.cend() }; + std::pair::const_iterator, + std::map::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::DeleteFiles) }; + + ///###: + std::map> filesOfPartions{}; + + ///###: classify files through the mount-point of every file. + for (; cbeg != cend; ++cbeg) { + QPair unixDeviceAndMountPoint{ + DSqliteHandle::getMountPointOfFile(DUrl::fromLocalFile(cbeg.key()), m_partionsOfDevices) }; + + if (!unixDeviceAndMountPoint.second.isEmpty() && !unixDeviceAndMountPoint.second.isNull()) { + QString file_were_removed_mount_point{ this->remove_mount_point(cbeg.key(), unixDeviceAndMountPoint.second) }; + filesOfPartions[unixDeviceAndMountPoint.second].push_back(file_were_removed_mount_point); + } + } + +//#ifdef QT_DEBUG + +// for(const std::pair>& item : filesOfPartions){ +// qDebug()<< item.first; + +// for(const QString& file_name : item.second){ +// qDebug()<< file_name; +// } + +// qDebug()<< "\n"; +// } + +//#endif //QT_DEBUG + + std::map>::const_iterator itr_partion_and_files{ filesOfPartions.cbegin() }; + std::map>::const_iterator itr_partion_and_files_end{ filesOfPartions.cend() }; + QMap> file_and_tags{}; + + for (; itr_partion_and_files != itr_partion_and_files_end; ++itr_partion_and_files) { + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(itr_partion_and_files->first) }; + + if (code == DSqliteHandle::ReturnCode::NoExist || code == DSqliteHandle::ReturnCode::Exist) { + this->connectToShareSqlite(itr_partion_and_files->first); + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open()) { + QMap> file_and_tags_partion{ + this->helpExecSql, QMap>>(itr_partion_and_files->second, itr_partion_and_files->first) + }; + + if (!file_and_tags_partion.isEmpty()) { + QMap>::const_iterator itr_beg{ file_and_tags_partion.cbegin() }; + QMap>::const_iterator itr_end{ file_and_tags_partion.cend() }; + + for (; itr_beg != itr_end; ++itr_beg) { + file_and_tags[itr_beg.key()] = itr_beg.value(); + } + } + } + } + } + + this->closeSqlDatabase(); + + if (file_and_tags.isEmpty()) { + return false; + } + + QMap result_of_emit{}; + itr_partion_and_files = filesOfPartions.cbegin(); + itr_partion_and_files_end = filesOfPartions.cend(); + bool result_of_return{ true }; + + for (; itr_partion_and_files != itr_partion_and_files_end; ++itr_partion_and_files) { + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(itr_partion_and_files->first) }; + + if (code == DSqliteHandle::ReturnCode::NoExist || code == DSqliteHandle::ReturnCode::Exist) { + this->connectToShareSqlite(itr_partion_and_files->first); + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open() && m_sqlDatabasePtr->transaction()) { + + bool result{ this->helpExecSql, bool>(itr_partion_and_files->second, itr_partion_and_files->first) }; + + if (!(result && m_sqlDatabasePtr->commit())) { + m_sqlDatabasePtr->rollback(); + result_of_return = false; + + qWarning() << "Failed to delete files. So there some dirty data in sqlite."; + } + + if (result) { + + for (const QString &file : itr_partion_and_files->second) { + result_of_emit[itr_partion_and_files->first + file] = QVariant{ file_and_tags[file] }; + } + + emit untagFiles(result_of_emit); + } + } + } + } + + this->closeSqlDatabase(); + + return result_of_return; + } + + this->closeSqlDatabase(); + + return false; +} + + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags) +{ + if (!filesAndTags.isEmpty()) { + this->connectToShareSqlite("/home", ".__main.db"); + bool the_result{ true }; + QList the_tags_for_deleting{ filesAndTags.keys() }; + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open() && m_sqlDatabasePtr->transaction()) { + the_result = this->helpExecSql, bool>(the_tags_for_deleting, "/home"); + } + + if (!(the_result && m_sqlDatabasePtr->commit())) { + m_sqlDatabasePtr->rollback(); + this->closeSqlDatabase(); + + return false; + } + + ///###: the second parameter is a placeholder. + ///###: you can transmit any string. + ///###: do not affect function. + QMap> file_and_tags{ this->helpExecSql, QMap>>(the_tags_for_deleting, QString{"placeholder_str"}) }; + + std::list sqlStrs{}; + QMap>::const_iterator cbeg{ filesAndTags.cbegin() }; + QMap>::const_iterator cend{ filesAndTags.cend() }; + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::DeleteTags) }; + + for (; cbeg != cend; ++cbeg) { + std::multimap::const_iterator rangeBeg{ range.first }; + QString deleteRowOfTagWithFile{ rangeBeg->second.arg(cbeg.key()) }; + sqlStrs.emplace_back(std::move(deleteRowOfTagWithFile)); + } + + + if (m_partionsOfDevices && !m_partionsOfDevices->empty()) { + std::map>::const_iterator deviceItr{ m_partionsOfDevices->cbegin() }; + std::map>::const_iterator deviceItrEnd{ m_partionsOfDevices->cend() }; + + bool result{ true }; + + for (; deviceItr != deviceItrEnd; ++deviceItr) { + std::multimap::const_iterator mountPointItr{ deviceItr->second.cbegin() }; + std::multimap::const_iterator mountPointItrEnd{ deviceItr->second.cend() }; + + for (; mountPointItr != mountPointItrEnd; ++mountPointItr) { + + if (!mountPointItr->second.isEmpty() && !mountPointItr->second.isNull()) { + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPointItr->second) }; + + if (code == DSqliteHandle::ReturnCode::NoExist || code == DSqliteHandle::ReturnCode::Exist) { + this->connectToShareSqlite(mountPointItr->second); + bool flagForDeleteInTagWithFile{ false }; + bool flagForUpdatingFileProperty{ false }; + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open() && m_sqlDatabasePtr->transaction()) { + flagForDeleteInTagWithFile = this->helpExecSql, bool>(sqlStrs, mountPointItr->second); + + if (flagForDeleteInTagWithFile) { + flagForUpdatingFileProperty = this->helpExecSql>, bool>(filesAndTags, mountPointItr->second); + } + } + + if (!(flagForDeleteInTagWithFile && flagForUpdatingFileProperty && m_sqlDatabasePtr && m_sqlDatabasePtr->commit())) { + m_sqlDatabasePtr->rollback(); + result = false; + } + } + } + } + } + + this->closeSqlDatabase(); + + if (result) { + emit deleteTags(QVariant{the_tags_for_deleting}); + + if (!file_and_tags.isEmpty()) { + QMap>::const_iterator the_beg{ file_and_tags.cbegin() }; + QMap>::const_iterator the_end{ file_and_tags.cend() }; + QMap tag_with_files{}; + + for (; the_beg != the_end; ++the_beg) { + tag_with_files[the_beg.key()] = QVariant{ the_beg.value() }; + } + + emit untagFiles(tag_with_files); + } + } + + return result; + } + } + + this->closeSqlDatabase(); + + return false; +} + + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags) +{ + if (!filesAndTags.isEmpty()) { + QMap>::const_iterator cbeg{ filesAndTags.cbegin() }; + QMap>::const_iterator cend{ filesAndTags.cend() }; + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::ChangeFilesName) }; + + std::map> partionsAndFileNames{}; + + for (; cbeg != cend; ++cbeg) { + QPair unixDeviceAndMountPoint{ DSqliteHandle::getMountPointOfFile(DUrl::fromLocalFile(cbeg.key()), m_partionsOfDevices) }; + + if (!unixDeviceAndMountPoint.second.isEmpty() && !unixDeviceAndMountPoint.second.isNull()) { + QString old_name_removed_mount_point{ this->remove_mount_point(cbeg.key(), unixDeviceAndMountPoint.second) }; + QString new_name_removed_mount_point{ this->remove_mount_point(cbeg.value().first(), unixDeviceAndMountPoint.second) }; + + partionsAndFileNames[unixDeviceAndMountPoint.second][old_name_removed_mount_point] = new_name_removed_mount_point; + } + } + + QMap>> file_with_tags_in_partion{}; + + for (const std::pair> &partion_and_file_names : partionsAndFileNames) { + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(partion_and_file_names.first) }; + + if (code == DSqliteHandle::ReturnCode::NoExist || code == DSqliteHandle::ReturnCode::Exist) { + this->connectToShareSqlite(partion_and_file_names.first); + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open()) { + QMap> file_with_tags{ + this->helpExecSql, + QMap>>(partion_and_file_names.second, partion_and_file_names.first) + }; + + if (!file_with_tags.isEmpty()) { + file_with_tags_in_partion[partion_and_file_names.first] = file_with_tags; + } + } + } + } + + this->closeSqlDatabase(); + + if (file_with_tags_in_partion.isEmpty()) { + return false; + } + + + std::map> sqlForChangingFilesName{}; + std::map> partionsAndFileNames_backup{ partionsAndFileNames }; + + if (!partionsAndFileNames.empty()) { + std::map>::const_iterator partionBeg{ partionsAndFileNames.cbegin() }; + std::map>::const_iterator partionEnd{ partionsAndFileNames.cend() }; + + for (; partionBeg != partionEnd; ++partionBeg) { + + for (const std::pair &oldAndNewName : partionBeg->second) { + std::map::const_iterator rangeBeg{ range.first }; + QString updateFileProperty{ rangeBeg->second.arg(oldAndNewName.second)}; + updateFileProperty = updateFileProperty.arg(oldAndNewName.first); + + QString updateTagWithFile{ (++rangeBeg)->second.arg(oldAndNewName.second) }; + updateTagWithFile = updateTagWithFile.arg(oldAndNewName.first); + sqlForChangingFilesName[partionBeg->first].emplace(updateFileProperty, updateTagWithFile); + } + } + + if (!sqlForChangingFilesName.empty()) { + bool result{ true }; + + for (const std::pair> &mountPointAndSqls : sqlForChangingFilesName) { + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPointAndSqls.first) }; + + if (code == DSqliteHandle::ReturnCode::NoExist || code == DSqliteHandle::ReturnCode::Exist) { + this->connectToShareSqlite(mountPointAndSqls.first); + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open() && m_sqlDatabasePtr->transaction()) { + bool resultOfExecSql{ this->helpExecSql, bool>(mountPointAndSqls.second, mountPointAndSqls.first) }; + + if (!(resultOfExecSql && m_sqlDatabasePtr->commit())) { + m_sqlDatabasePtr->rollback(); + result = false; + + partionsAndFileNames_backup.erase(mountPointAndSqls.first); + file_with_tags_in_partion.remove(mountPointAndSqls.first); + } + } + } + } + + this->closeSqlDatabase(); + + QMap> file_with_tags_new{}; + + for (const std::pair> &mount_point_and_file_names : partionsAndFileNames_backup) { + std::map new_and_old_names{}; + + for (const std::pair &old_and_new_name : mount_point_and_file_names.second) { + new_and_old_names[old_and_new_name.second] = old_and_new_name.first; + } + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mount_point_and_file_names.first) }; + + if (code == DSqliteHandle::ReturnCode::NoExist || code == DSqliteHandle::ReturnCode::Exist) { + this->connectToShareSqlite(mount_point_and_file_names.first); + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open()) { + QMap> file_with_tags{ + this->helpExecSql, + QMap>>(new_and_old_names, mount_point_and_file_names.first) + }; + + using namespace impl; + file_with_tags_new += file_with_tags; + } + } + } + + QMap> file_with_tags_old{}; + QMap>>::const_iterator itr_beg{ file_with_tags_in_partion.cbegin() }; + QMap>>::const_iterator itr_end{ file_with_tags_in_partion.cend() }; + + for (; itr_beg != itr_end; ++itr_beg) { + using namespace impl; + file_with_tags_old += itr_beg.value(); + } + + QMap file_with_tags_var{}; + QMap>::iterator file_with_tags_beg{ file_with_tags_old.begin() }; + QMap>::iterator file_with_tags_end{ file_with_tags_old.end() }; + + for (; file_with_tags_beg != file_with_tags_end; ++file_with_tags_beg) { + file_with_tags_var[file_with_tags_beg.key()] = QVariant{ file_with_tags_beg.value() }; + } + + emit untagFiles(file_with_tags_var); + + file_with_tags_var.clear(); + file_with_tags_beg = file_with_tags_new.begin(); + file_with_tags_end = file_with_tags_new.end(); + + for (; file_with_tags_beg != file_with_tags_end; ++file_with_tags_beg) { + file_with_tags_var[file_with_tags_beg.key()] = QVariant{ file_with_tags_beg.value() }; + } + + emit filesWereTagged(file_with_tags_var); + this->closeSqlDatabase(); + + return result; + } + } + } + + this->closeSqlDatabase(); + + return false; +} + + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags) +{ + if (!filesAndTags.isEmpty()) { +// DSqliteHandle::ReturnCode return_code{ this->checkDBFileExist("/home", ".__main.db") }; + +// if (return_code != DSqliteHandle::ReturnCode::Exist) { +// return false; +// } + + this->connectToShareSqlite("/home", ".__main.db"); + bool the_result{ true }; + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open() && m_sqlDatabasePtr->transaction()) { + the_result = this->helpExecSql>, bool>(filesAndTags, "/home"); + } + + if (!(the_result && m_sqlDatabasePtr->commit())) { + m_sqlDatabasePtr->rollback(); + return false; + } + + QMap>::const_iterator tagNameBeg{ filesAndTags.cbegin() }; + QMap>::const_iterator tagNameCend{ filesAndTags.cend() }; + std::list> sqlStrs{}; + std::pair::const_iterator, + std::map::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::ChangeTagsName) }; + + for (; tagNameBeg != tagNameCend; ++tagNameBeg) { + std::map::const_iterator rangeBeg{ range.first }; + QString updateTag1{ rangeBeg->second.arg(tagNameBeg.value().first()) }; + updateTag1 = updateTag1.arg(tagNameBeg.key()); + + QString updateTag2{ (++rangeBeg)->second.arg(tagNameBeg.value().first()) }; + updateTag2 = updateTag2.arg(tagNameBeg.key()); + + QString updateTag3{ (++rangeBeg)->second.arg(tagNameBeg.value().first()) }; + updateTag3 = updateTag3.arg(tagNameBeg.key()); + + QString updateTagWithFile{ (++rangeBeg)->second.arg(tagNameBeg.value().first()) }; + updateTagWithFile = updateTagWithFile.arg(tagNameBeg.key()); + + sqlStrs.emplace_back(std::move(updateTag1), std::move(updateTag2), std::move(updateTag3), std::move(updateTagWithFile)); + } + + if (m_partionsOfDevices && !m_partionsOfDevices->empty()) { + std::map>::const_iterator deviceItr{ m_partionsOfDevices->cbegin() }; + std::map>::const_iterator deviceItrEnd{ m_partionsOfDevices->cend() }; + bool result{ true }; + + for (; deviceItr != deviceItrEnd; ++deviceItr) { + std::multimap::const_iterator mountPointItr{ deviceItr->second.cbegin() }; + std::multimap::const_iterator mountPointItrEnd{ deviceItr->second.cend() }; + + for (; mountPointItr != mountPointItrEnd; ++mountPointItr) { + + if (!mountPointItr->second.isEmpty() && !mountPointItr->second.isNull()) { + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPointItr->second) }; + + if (code == DSqliteHandle::ReturnCode::NoExist || code == DSqliteHandle::ReturnCode::Exist) { + this->connectToShareSqlite(mountPointItr->second); + bool resultOfChangeNameOfTag{ true }; + bool flagOfTransaction{ true }; + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open()) { + flagOfTransaction = m_sqlDatabasePtr->transaction(); + + if (flagOfTransaction) { + resultOfChangeNameOfTag = this->helpExecSql>, bool>(sqlStrs, mountPointItr->second); + } + } + + if (!(resultOfChangeNameOfTag && flagOfTransaction && m_sqlDatabasePtr && m_sqlDatabasePtr->commit())) { + m_sqlDatabasePtr->rollback(); + result = false; + } + } + } + } + } + + this->closeSqlDatabase(); + + if (result) { + QMap>::const_iterator c_beg{ filesAndTags.cbegin() }; + QMap>::const_iterator c_end{ filesAndTags.cend() }; + QMap old_and_new_name{}; + + for (; c_beg != c_end; ++c_beg) { + old_and_new_name[c_beg.key()] = QVariant{c_beg.value().first()}; + } + + emit changeTagName(old_and_new_name); + } + + return result; + } + } + + this->closeSqlDatabase(); + + return false; +} + + + + +template<> +QList DSqliteHandle::execSqlstr>(const QMap> &filesAndTags) +{ + QList tags{}; + + if (!filesAndTags.isEmpty()) { + QMap>::const_iterator cbeg{ filesAndTags.cbegin() }; + QPair partionAndMountPoint{ DSqliteHandle::getMountPointOfFile(DUrl::fromLocalFile(cbeg.key()), m_partionsOfDevices) }; + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::GetTagsThroughFile) }; + + if (partionAndMountPoint.second.isEmpty() || partionAndMountPoint.second.isNull()) { + return tags; + } + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(partionAndMountPoint.second) }; + + if (code == DSqliteHandle::ReturnCode::NoExist || code == DSqliteHandle::ReturnCode::Exist) { + QString file{ cbeg.key() }; + file = this->remove_mount_point(file, partionAndMountPoint.second); + QString sqlForGetTagsThroughFile{range.first->second.arg(file)}; + this->connectToShareSqlite(partionAndMountPoint.second); + + ///###: no transaction. + if (m_sqlDatabasePtr->open()) { + tags = this->helpExecSql>(sqlForGetTagsThroughFile, partionAndMountPoint.second); + } + } + } + + this->closeSqlDatabase(); + QList tags_backup{}; + + std::transform(tags.begin(), tags.end(), std::back_inserter(tags_backup), + [](const QString & tag) { + return Tag::restore_escaped_en_skim(tag); + }); + + return tags_backup; +} + +template<> +QList DSqliteHandle::execSqlstr>(const QMap> &filesAndTags) +{ + QList files{}; + + if (!filesAndTags.isEmpty()) { + QMap>::const_iterator cbeg{ filesAndTags.cbegin() }; + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::GetFilesThroughTag) }; + QString sqlForGetFilesThroughTag{ range.first->second.arg(cbeg.key()) }; + + if (m_partionsOfDevices && !m_partionsOfDevices->empty()) { + std::map>::const_iterator deviceItr{ m_partionsOfDevices->cbegin() }; + std::map>::const_iterator deviceItrEnd{ m_partionsOfDevices->cend() }; + + for (; deviceItr != deviceItrEnd; ++deviceItr) { + std::multimap::const_iterator mountPointItr{ deviceItr->second.cbegin() }; + std::multimap::const_iterator mountPointItrEnd{ deviceItr->second.cend() }; + + for (; mountPointItr != mountPointItrEnd; ++mountPointItr) { + + if (!mountPointItr->second.isEmpty() && !mountPointItr->second.isNull()) { + + DSqliteHandle::ReturnCode code{ this->checkDBFileExist(mountPointItr->second) }; + + if (code == DSqliteHandle::ReturnCode::NoExist || code == DSqliteHandle::ReturnCode::Exist) { + this->connectToShareSqlite(mountPointItr->second); + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open()) { + + QList filesOfPartion{ this->helpExecSql>(sqlForGetFilesThroughTag, mountPointItr->second) }; + + if (!filesOfPartion.isEmpty()) { + files += filesOfPartion; + } + } + } + } + } + } + } + } + + this->closeSqlDatabase(); + QList files_backup{}; + + std::transform(files.begin(), files.end(), std::back_inserter(files_backup), + [](const QString & file) { + return Tag::restore_escaped_en_skim(file); + }); + + return files_backup; +} + + +template<> +QList DSqliteHandle::execSqlstr>(const QMap> &filesAndTags) +{ + QList totalTagsNames{}; + std::map countForTags{}; + + if (!filesAndTags.isEmpty()) { + QMap>::const_iterator cbeg{ filesAndTags.cbegin() }; + QMap>::const_iterator cend{ filesAndTags.cend() }; + + for (; cbeg != cend; ++cbeg) { + QMap> file{}; + file.insert(cbeg.key(), cbeg.value()); + + QList tagsNames{ this->execSqlstr>(file) }; + for (const QString &tagName : tagsNames) { + ++countForTags[tagName]; + } + } + } + + int size{ filesAndTags.size() }; + + for (const std::pair &pair : countForTags) { + + if (pair.second == static_cast(size)) { + totalTagsNames.push_back(pair.first); + } + } + +//#ifdef QT_DEBUG +// qDebug()<< totalTagsNames; +//#endif //QT_DEBUG + + QList total_tags_names_backup{}; + std::transform(totalTagsNames.begin(), totalTagsNames.end(), std::back_inserter(total_tags_names_backup), + [](const QString & tag_name) { + return Tag::restore_escaped_en_skim(tag_name); + }); + + return total_tags_names_backup; +} + + +template<> +QMap DSqliteHandle::execSqlstr>(const QMap> &filesAndTags) +{ + (void)filesAndTags; + QMap tag_and_color{}; + + if (QFileInfo::exists("/home")) { + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::GetAllTags) }; + this->connectToShareSqlite("/home", ".__main.db"); + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open()) { + QSqlQuery sql_query{ *m_sqlDatabasePtr }; + + if (sql_query.exec(range.first->second)) { + + while (sql_query.next()) { + QString tag_name{ sql_query.value("tag_name").toString() }; + QString tag_color{ sql_query.value("tag_color").toString() }; + + tag_name = Tag::restore_escaped_en_skim(tag_name); +// tag_color = Tag::restore_escaped_en_skim(tag_color); //###: color can not contain skim. + + tag_and_color[tag_name] = QVariant{ tag_color }; + } + } + } + } + + return tag_and_color; +} + + +template<> +QMap DSqliteHandle::execSqlstr>(const QMap> &fileAndTags) +{ + QMap tag_and_color{}; + + if (QFileInfo::exists("/home") && !fileAndTags.isEmpty()) { + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::GetTagColor) }; + this->connectToShareSqlite("/home", ".__main.db"); + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open()) { + QMap>::const_iterator c_beg{ fileAndTags.cbegin() }; + QMap>::const_iterator c_end{ fileAndTags.cend() }; + QString sql_str{ range.first->second }; + QSqlQuery sql_query{ *m_sqlDatabasePtr }; + + for (; c_beg != c_end; ++c_beg) { + + if (sql_query.exec(sql_str.arg(c_beg.key()))) { + + if (sql_query.next()) { + QString tag_color{ sql_query.value("tag_color").toString() }; + tag_and_color[c_beg.key()] = tag_color; + } + } + } + } + } + + return tag_and_color; +} + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags) +{ + bool result{ true }; + QMap tag_and_new_color{}; + + if (QFileInfo::exists("/home") && !filesAndTags.isEmpty()) { + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::ChangeTagColor) }; + this->connectToShareSqlite("/home", ".__main.db"); + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open() && m_sqlDatabasePtr->transaction()) { + QMap>::const_iterator c_beg{ filesAndTags.cbegin() }; + QMap>::const_iterator c_end{ filesAndTags.cend() }; + QSqlQuery sql_query{ *m_sqlDatabasePtr }; + + for (; c_beg != c_end; ++c_beg) { + QString sql_str{ range.first->second }; + sql_str = sql_str.arg(c_beg.value().first()); + sql_str = sql_str.arg(c_beg.key()); + + if (!sql_query.exec(sql_str)) { + qWarning() << sql_query.lastError().text(); + result = false; + + break; + } + + tag_and_new_color[c_beg.key()] = QVariant{c_beg.value().first()}; + } + + if (!(result && m_sqlDatabasePtr->commit())) { + m_sqlDatabasePtr->rollback(); + } + } + } + + if (result) { + emit changeTagColor(tag_and_new_color); + } + + return result; +} + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags) +{ + if (QFileInfo::exists("/home") && !filesAndTags.isEmpty()) { + std::pair::const_iterator, + std::multimap::const_iterator> range{ SqlTypeWithStrs.equal_range(DSqliteHandle::SqlType::BeforeTagFiles) }; + this->connectToShareSqlite("/home", ".__main.db"); + + if (m_sqlDatabasePtr && m_sqlDatabasePtr->open() && m_sqlDatabasePtr->transaction()) { + + QMap>::const_iterator c_beg{ filesAndTags.cbegin() }; + QMap>::const_iterator c_end{ filesAndTags.cend() }; + QSqlQuery sql_query{ *m_sqlDatabasePtr }; + QString sql_counting{ range.first->second }; + QString sql_inserting{ (++(range.first))->second }; + + for (; c_beg != c_end; ++c_beg) { + QString counting{ sql_counting.arg(c_beg.key()) }; + + if (sql_query.exec(counting)) { + + if (sql_query.next()) { + int number{ sql_query.value("counter").toInt() }; + + if (number == 0) { + sql_query.clear(); + QString inserting{ sql_inserting.arg(c_beg.key()) }; + inserting = inserting.arg(c_beg.value().first()); + + if (!sql_query.exec(inserting)) { + qWarning() << sql_query.lastError().text(); + m_sqlDatabasePtr->rollback(); + + this->closeSqlDatabase(); + + return false; + } + + m_newAddedTags.push_back(c_beg.key()); + } + } + } + } + + if (!m_sqlDatabasePtr->commit()) { + m_sqlDatabasePtr->rollback(); + } + + this->closeSqlDatabase(); + + ///###: emit signal when new tag was added. + if (!m_newAddedTags.isEmpty()) { + emit addNewTags(QVariant{m_newAddedTags}); + m_newAddedTags.clear(); + } + + return true; + } + } + + this->closeSqlDatabase(); + + return false; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dsqlitehandle.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dsqlitehandle.h new file mode 100644 index 0000000..c4e12d4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/dsqlitehandle.h @@ -0,0 +1,340 @@ +#ifndef DSQLITEHANDLE_H +#define DSQLITEHANDLE_H + +#include "durl.h" +#include "app/define.h" +#include "deviceinfo/udisklistener.h" +#include "deviceinfo/udiskdeviceinfo.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DATABASE_PATH "/usr/share/dde-file-manager/database" + +#if QT_VERSION < QT_VERSION_CHECK(5,14,0) +namespace std { + +template<> +struct hash { + inline std::size_t operator()(const QString &str)const noexcept + { + return (std::hash {}(str.toStdString())); + } +}; + +} +#endif + + +class DSqliteHandle : public QObject +{ + Q_OBJECT +public: + + ///###: some value of enum of SqlType has "2/3" suffix. + ///###: It shows that this operation increment/delete/modify/query the 2 tables in current sqlite. + ///###: so, if there is not "2/3" suffix show that this operation do work in a table of current sqlite. + enum class SqlType : std::size_t { + None = 0, + + BeforeTagFiles, + TagFiles, + TagFiles2, + TagFiles3, + + DeleteTags, + DeleteTags2, + DeleteTags3, + DeleteTags4, + + DeleteFiles, + DeleteFiles2, + + ChangeTagsName, + ChangeTagsName2, + + ChangeFilesName, + ChangeFilesName2, + + TagFilesThroughColor, + TagFilesThroughColor2, + TagFilesThroughColor3, + + GetFilesThroughTag, + + GetTagsThroughFile, + GetSameTagsOfDiffFiles, + + UntagDiffPartionFiles, + + UntagSamePartionFiles, + UntagSamePartionFiles2, + + GetAllTags, + GetTagColor, + ChangeTagColor + }; + + enum class ReturnCode : std::size_t { + Exist = 0, + NoExist, + NoThisDir, + PlaceHolder, + FailedExecSql + }; + + explicit DSqliteHandle(QObject *const parent = nullptr); + virtual ~DSqliteHandle() = default; + DSqliteHandle(const DSqliteHandle &other) = delete; + DSqliteHandle &operator=(const DSqliteHandle &other) = delete; + + ///####:----------------------> > + QVariant disposeClientData(const QMap> &filesAndTags, const unsigned long long &type); + + static DSqliteHandle *instance(); + static std::map> queryPartionsInfoOfDevices(); + static QPair getMountPointOfFile(DUrl url, std::unique_ptr>> &partionsAndMountPoints); + +signals: + void addNewTags(const QVariant &new_tags); + void deleteTags(const QVariant &be_deleted_tags); + void changeTagColor(const QVariantMap &old_and_new_color); + void changeTagName(const QVariantMap &old_and_new_name); + void filesWereTagged(const QVariantMap &files_were_tagged); + void untagFiles(const QVariantMap &del_tags_of_file); + +private slots: + void onMountAdded(UDiskDeviceInfoPointer infoPointer); + void onMountRemoved(UDiskDeviceInfoPointer infoPointer); + +private: + static QString restoreEscapedChar(const QString &value); + + inline void closeSqlDatabase()noexcept + { + if (m_sqlDatabasePtr && m_sqlDatabasePtr->isOpen()) { + m_sqlDatabasePtr->close(); + } + } + + inline QString remove_mount_point(const QString &file, const QString &mount_point) noexcept + { + int index{ file.indexOf(mount_point) }; + QString file_be_removed_mount_point{file}; + + if (index == 0) { + int size{ mount_point.size() }; + file_be_removed_mount_point = file_be_removed_mount_point.remove(0, size); + } + + return file_be_removed_mount_point; + } + + + template + inline T execSqlstr(const QMap> &filesAndTags) + { + (void)filesAndTags; + return; + } + + + template + inline T helpExecSql(const Ty &sqlStrs, const QString &mountPoint) + { + (void)sqlStrs; + (void)mountPoint; + return; + } + + /** + * @brief checkDBFileExist 检查db文件是否存在 + * @param path 所在目录 + * @param db_name db文件名 + * @return 文件存在 Exist = 0, 文件不存在 NoExist = 1, 所在目录不存在 NoThisDir = 2 + */ + ReturnCode checkDBFileExist(const QString &path, const QString &db_name = ".__deepin.db"); + + void initializeConnect(); + + /** + * @brief connectToSqlite 创建数据库连接 + * 旧逻辑,正常连接数据库的逻辑 + * @param path 所在目录 + * @param db_name db文件名 + */ + void connectToSqlite(const QString &path, const QString &db_name = QString{".__deepin.db"}); + + /** + * @brief connectToShareSqlite 创建连接到share目录的数据库 + * 判断数据库位置,如果之前版本在/home目录下创建过数据库,将数据库移动到/usr/share/dde-file-manager/database目录下 + * 在确保数据库在share目录后,调用connectToSqlite正常连接数据库 + * @param path 所在目录 + * @param db_name db文件名 + */ + void connectToShareSqlite(const QString &path, const QString &db_name = ".__deepin.db"); + + std::unique_ptr>> m_partionsOfDevices{ nullptr }; + std::unique_ptr m_sqlDatabasePtr{ nullptr }; + std::atomic m_flag{ false }; + std::mutex m_mutex{}; + + QList m_newAddedTags{}; +}; + +///###: increase +/// +///###: there function will be invoked by TagFiles/TagFilesThroughColor in CLIENT only. +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags); + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags); + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags); + +///###: query +template<> +QList DSqliteHandle::execSqlstr>(const QMap> &filesAndTags); + +template<> +QList DSqliteHandle::execSqlstr>(const QMap> &filesAndTags); + +template<> +QList DSqliteHandle::execSqlstr>(const QMap> &filesAndTags); + +template<> +QMap DSqliteHandle::execSqlstr>(const QMap> &filesAndTags); + +template<> +QMap DSqliteHandle::execSqlstr>(const QMap> &fileAndTags); + +///###: modify +template<> ///###: -------------------------------------------------------------> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags); + +template<>///###: --------------------------------------------------------------> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags); + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags); + + +///###: delete +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags); + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags); + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags); + +template<> +bool DSqliteHandle::execSqlstr(const QMap> &filesAndTags); + + +///###:auxiliary function. +///###: tag files +template<> +bool DSqliteHandle::helpExecSql>, bool>(const QMap> &forDecreasing, + const QString &mountPoint); + +template<> +bool DSqliteHandle::helpExecSql>, bool>( + const QMap> &forIncreasing, const QString &mountPoint); + +template<> +bool DSqliteHandle::helpExecSql, bool>(const QList &forUpdating, + const QString &mountPoint); + + + +template<> +bool DSqliteHandle::helpExecSql>, bool>(const std::list> &sqlStrs, + const QString &mountPoint); +template<> +bool DSqliteHandle::helpExecSql(const QString &tag_name, const QString &mountPoint); + + +///###: untag files in same/diff partion. +template<> +bool DSqliteHandle::helpExecSql, bool>( + const std::list &sqlStrs, const QString &mountPoint); +template<> +bool DSqliteHandle::helpExecSql>, bool>(const QMap> &fileNameAndTagNames, + const QString &mountPoint); + + +///### delete files and delete row(s) in tag_with_file and file_property. +template<> +bool DSqliteHandle::helpExecSql, bool>(const std::list &files, const QString &mount_point); + +template<> +QMap> DSqliteHandle::helpExecSql, + QMap>>(const std::list &files, const QString &mount_point); + +///###: delete tag(s) +template<> +QMap> DSqliteHandle::helpExecSql, QMap>>(const QList &tag_names, const QString &mount_point); + +template<> +bool DSqliteHandle::helpExecSql, bool>(const std::list &sqlStrs, const QString &mountPoint); +template<> +bool DSqliteHandle::helpExecSql>, bool>(const QMap> &fileNameAndTagNames, const QString &mountPoint); + +template<> +bool DSqliteHandle::helpExecSql, bool>(const QList &tag_name, const QString &mountPoint); + + + +///###: change file(s) name. +template<> +bool DSqliteHandle::helpExecSql, bool>(const std::map &sqlStrs, const QString &mountPoint); + +template<> +QMap> DSqliteHandle::helpExecSql, + QMap>>(const std::map &files, const QString &mount_point); + +///###: change tag(s) name. +template<> +bool DSqliteHandle::helpExecSql>, bool>(const std::list> &sqlStrs, + const QString &mountPoint); +template<> +bool DSqliteHandle::helpExecSql>, bool>(const QMap> &old_and_new, + const QString &mountPoint); + + +///###: get tags through file. +template<> +QList DSqliteHandle::helpExecSql>(const QString &sqlStr, const QString &mountPoint); + + +///###: get files which was tagged by appointed tag. +template<> +QList DSqliteHandle::helpExecSql>(const QString &sqlStr, const QString &mountPoint); + + + +#endif // DSQLITEHANDLE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/filebatchprocess.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/filebatchprocess.cpp new file mode 100644 index 0000000..0273a4f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/filebatchprocess.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "dfmglobal.h" +#include "filebatchprocess.h" +#include "dfmeventdispatcher.h" + +#include +#include + +std::once_flag FileBatchProcess::flag; +const static QString MIMETYPE_APP_DESKTOP = "application/x-desktop"; + +QSharedMap FileBatchProcess::replaceText(const QList& originUrls, const QPair &pair) const +{ + if(originUrls.isEmpty() == true) { //###: here, judge whether there are fileUrls in originUrls. + return QSharedMap{ nullptr }; + } + + QSharedMap result{ new QMap{}}; + + for(auto url : originUrls){ + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(nullptr, url); + + if (!info) + continue; + + + // debug case 25414: failure to rename desktop app name + bool isDeskTopApp = info->mimeTypeName().contains(MIMETYPE_APP_DESKTOP); + + ///###: symlink is also processed here. + QString fileBaseName = isDeskTopApp? info->fileDisplayName(): info->baseName(); + const QString &suffix = info->suffix().isEmpty() ? QString() : QString(".") + info->suffix(); + fileBaseName.replace(pair.first, pair.second); + + if (fileBaseName.trimmed().isEmpty()) { + qWarning() << "replace fileBaseName(not include suffix) trimmed is empty string"; + continue; + } + + int max_length = MAX_FILE_NAME_CHAR_COUNT - suffix.toLocal8Bit().size(); + + if (fileBaseName.toLocal8Bit().size() > max_length) { + fileBaseName = DFMGlobal::cutString(fileBaseName, max_length, QTextCodec::codecForLocale()); + } + + if(!isDeskTopApp){ + fileBaseName += suffix; + } + DUrl changedUrl{ info->getUrlByNewFileName(fileBaseName) }; + + if (changedUrl != url) + result->insert(url, changedUrl); + } + + return result; +} + +QSharedMap FileBatchProcess::addText(const QList &originUrls, const QPair& pair) const +{ + if(originUrls.isEmpty()){ //###: here, judge whether there are fileUrls in originUrls. + return QSharedMap{ nullptr }; + } + + QSharedMap result{ new QMap{} }; + + for (auto url : originUrls) { + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(nullptr, url); + + if (!info) + continue; + + // debug case 25414: failure to rename desktop app name + bool isDeskTopApp = info->mimeTypeName().contains(MIMETYPE_APP_DESKTOP); + + QString fileBaseName = isDeskTopApp? info->fileDisplayName(): info->baseName();//{ info->baseName() }; + QString oldFileName = fileBaseName; + + QString add_text = pair.first; + const QString &suffix = info->suffix().isEmpty() ? QString() : QString(".") + info->suffix(); + int max_length = MAX_FILE_NAME_CHAR_COUNT - info->fileName().toLocal8Bit().size(); + + if (add_text.toLocal8Bit().size() > max_length) { + add_text = DFMGlobal::cutString(add_text, max_length, QTextCodec::codecForLocale()); + } + + if (pair.second == DFileService::AddTextFlags::Before) { + fileBaseName.insert(0, add_text); + } else { + fileBaseName.append(add_text); + } + + if(!isDeskTopApp){ + fileBaseName += suffix; + } + DUrl changedUrl = { info->getUrlByNewFileName(fileBaseName) }; + + if(isDeskTopApp) { + qDebug()<<"this is desktop app case,file name will be changed { "<< oldFileName << " } to { " << fileBaseName << " } for path:" << info->fileUrl(); + } + + if (changedUrl != url) + result->insert(url, changedUrl); + } + + return result; +} + +QSharedMap FileBatchProcess::customText(const QList &originUrls, const QPair &pair) const +{ + if(originUrls.isEmpty() == true || pair.first.isEmpty() == true || pair.second.isEmpty() == true){ //###: here, jundge whether there are fileUrls in originUrls. + return QSharedMap{ nullptr }; + } + + unsigned long long SNNumber{ pair.second.toULongLong() }; + unsigned long long index{ 0 }; + + if (SNNumber == ULONG_LONG_MAX) { //##: Maybe, this value will be equal to the max value of the type of unsigned long long + index = SNNumber - originUrls.size(); + } else { + index = SNNumber; + } + + QSharedMap result{new QMap{}}; + + QList modifyUrls; + + bool needRecombination = false; + for (auto url : originUrls) { + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(nullptr, url); + + if (!info) + continue; + + // debug case 25414: failure to rename desktop app name + bool isDeskTopApp = info->mimeTypeName().contains(MIMETYPE_APP_DESKTOP); + + QString fileBaseName{ pair.first }; + const QString &index_string = QString::number(index); + const QString &suffix = info->suffix().isEmpty() ? QString() : QString(".") + info->suffix(); + int max_length = MAX_FILE_NAME_CHAR_COUNT - index_string.toLocal8Bit().size() - suffix.toLocal8Bit().size(); + + if (fileBaseName.toLocal8Bit().size() > max_length) { + fileBaseName = DFMGlobal::cutString(fileBaseName, max_length, QTextCodec::codecForLocale()); + } + + fileBaseName = isDeskTopApp ? (fileBaseName + index_string) : (fileBaseName + index_string + suffix); + DUrl beModifieddUrl = { info->getUrlByNewFileName(fileBaseName) }; + result->insert(url, beModifieddUrl); + + modifyUrls << beModifieddUrl; + + // 如果源url包含了待修改的url 就需要重组结果 + if (originUrls.contains(beModifieddUrl)) + needRecombination = true; + + if(isDeskTopApp) { + qDebug()<<"this is desktop app case,file name will be changed as { "<< fileBaseName << " } for path:" << info->fileUrl(); + } + + ++index; + } + + // 重组map + if (needRecombination) { + QList originUrlsTemp = originUrls; + + auto it = modifyUrls.begin(); + while (it != modifyUrls.end()) { + DUrl url = *it; + if (originUrlsTemp.contains(url)) { + originUrlsTemp.removeOne(url); + it = modifyUrls.erase(it); + continue; + } + ++it; + } + + if (originUrlsTemp.size() == modifyUrls.size()) { + result.reset(new QMap{}); + for (int i = 0, end = originUrlsTemp.size(); i < end; ++i) { + result->insert(originUrlsTemp[i], modifyUrls[i]); + } + } + } + + return result; +} + + + +////###: use the value of map to rename the file who name is the key of map. +QMap FileBatchProcess::batchProcessFile(const QSharedMap &map) +{ + QMap cache; + + if (static_cast(map) == false) { //###: here, jundge whether there are fileUrls in map. + return cache; + } + + QMap::const_iterator beg = map->constBegin(); + QMap::const_iterator end = map->constEnd(); + + // 实现批量回退 + DFMEventDispatcher::instance()->processEvent(); + + for (; beg != end; ++beg) { + DUrl currentName{ beg.key() }; + DUrl hopedName{ beg.value() }; + + if (currentName == hopedName) { + continue; + } + + ///###: just cache files that rename successfully. + if (DFileService::instance()->renameFile(nullptr, currentName, hopedName) == true ) { + cache[currentName] = hopedName; + } + } + + // 实现批量回退 + DFMEventDispatcher::instance()->processEvent(); + + return cache; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/filebatchprocess.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/filebatchprocess.h new file mode 100644 index 0000000..7aaeb9b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/filebatchprocess.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef DFILEBATCHPROCESS_H +#define DFILEBATCHPROCESS_H + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + + +#include "durl.h" +#include "controllers/appcontroller.h" +#include "interfaces/dfileservices.h" + + +class FileBatchProcessPrivate; +class QFileInfo; + +template::value || + std::is_copy_constructible::value, + void>::type> +using QSharedMap = QSharedPointer>; + +class FileBatchProcess +{ +public: + explicit FileBatchProcess()=default; + ~FileBatchProcess() = default; + + + + ///###: in fact: you can not also use std::move! + FileBatchProcess(const FileBatchProcess&) =delete; + FileBatchProcess& operator=(const FileBatchProcess&)=delete; + + QSharedMap replaceText(const QList& originUrls, const QPair &pair)const; + QSharedMap addText(const QList& originUrls, const QPair& pair)const; + QSharedMap customText(const QList& originUrls, const QPair &pair)const; + + + + + static QMap batchProcessFile(const QSharedMap &map); + + ////###: this is thread safe. + inline static QSharedPointer instance() + { + static QSharedPointer batchProcess; + + std::call_once(FileBatchProcess::flag, + [&]{batchProcess = QSharedPointer{ new FileBatchProcess };}); + return batchProcess; + } + + +private: + ////###: there flag is very important. + static std::once_flag flag; +}; + + +#endif // DFILEBATCHPROCESS_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/fileutils.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/fileutils.cpp new file mode 100644 index 0000000..85c7dd1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/fileutils.cpp @@ -0,0 +1,1939 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +//fixed:CD display size error +#include "gvfs/gvfsmountmanager.h" + +#include "fileutils.h" + +#include "views/windowmanager.h" + +#include "app/define.h" +#include "singleton.h" +#include "mimetypedisplaymanager.h" +#include "dfmstandardpaths.h" +#include "dfileservices.h" +#include "dmimedatabase.h" +#include "mimesappsmanager.h" +#include "interfaces/dfmstandardpaths.h" +#include "controllers/appcontroller.h" +#include "dbusinterface/startmanager_interface.h" +#include "views/dfmopticalmediawidget.h" +#include "controllers/vaultcontroller.h" +#include "models/avfsfileinfo.h" +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "usershare/usersharemanager.h" +#include "usershare/shareinfo.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#undef signals +extern "C" { +#include +#include +} +#define signals public + +DFM_USE_NAMESPACE +DCORE_USE_NAMESPACE + +QString FileUtils::XDG_RUNTIME_DIR = ""; +QStringList FileUtils::CURRENT_ISGVFSFILE_PATH; + +/** + * @brief Recursive removes file or directory + * @param path path to file + * @param name name of file + * @return true if file/directory was successfully removed + */ +bool FileUtils::removeRecurse(const QString &path, const QString &name) +{ + // File location + QString url = path + QDir::separator() + name; + + // Check whether file or directory exists + QFileInfo file(url); + if (!file.exists()) { + return false; + } + + // List of files that will be deleted + QStringList files; + + // If given file is a directory, collect all children of given directory + if (file.isDir()) { + QDirIterator it(url, QDir::AllEntries | QDir::System | QDir::NoDotAndDotDot | QDir::Hidden, QDirIterator::Subdirectories); + while (it.hasNext()) { + files.prepend(it.next()); + } + } + + // Append given file to the list of files and delete all + files.append(url); + foreach (QString file, files) { + QFile(file).remove(); + } + return true; +} +//--------------------------------------------------------------------------- + +/** + * @brief Check ancestor + * @param + * @param + * @param + */ +bool FileUtils::isAncestorUrl(const DUrl &ancestor, const DUrl &url) +{ + DUrl parent = url; + while (parent.isValid()) { + if (parent == ancestor) { + return true; + } + parent = parent.parentUrl(); + } + return false; +} +/** + * @brief Check isNetworkAncestorUrl 检查挂载的目录是否是本机目录,是本地挂载转换为本地url,在判读是否是同一个目录 + * 两个参数一个是本地,一个网络挂载文件,必须是目标文件是原文的父文件,就返回true + * @param ancestor + * @param + * @param + */ +bool FileUtils::isNetworkAncestorUrl(const DUrl &dest, const bool isDestGvfs, const DUrl &source, const bool isSourceGvfs) +{ + if ((isDestGvfs && isSourceGvfs) || (!isDestGvfs && !isSourceGvfs)) + return false; + + QString gvfsUrlStr = isDestGvfs ? dest.path() : source.path(); + + static QRegularExpression regExp("^/run/user/\\d+/gvfs/smb-share:server=(?.*),share=(?[^/]+)(?.*)", + QRegularExpression::DotMatchesEverythingOption + | QRegularExpression::DontCaptureOption + | QRegularExpression::OptimizeOnFirstUsageOption); + + const QRegularExpressionMatch &match = regExp.match(gvfsUrlStr, 0, QRegularExpression::NormalMatch, + QRegularExpression::DontCheckSubjectStringMatchOption); + + if (!match.hasMatch()) + return false; + + const QString &host = match.captured("host"); + const QString &shareName = match.captured("shareName"); + const QString &path = match.captured("path"); + // 获取本机ip判断是否是自己 + bool selfIp = false; + const auto &allAddresses = QNetworkInterface::allAddresses(); + for (const auto &address : allAddresses) { + const QString &ipAddr = address.toString(); + if (ipAddr == host) { + selfIp = true; + break; + } + } + + if (!selfIp) + return false; + //获取自己的共享路径 + QString realPath; + if (!userShareManager->getsShareInfoByShareName(shareName).isValid()) + return false; + + realPath = userShareManager->getsShareInfoByShareName(shareName).path() + path; + DUrl realUrl = DUrl::fromLocalFile(realPath); + if (isDestGvfs && realUrl.parentUrl().path().contains(source.path())) + return true; + + if (isSourceGvfs && dest.path().contains(realUrl.parentUrl().path())) + return true; + + return false; +} + +/** + * @brief Collects all file names in given path (recursive) + * @param path path + * @param parent parent path + * @param list resulting list of files + */ +void FileUtils::recurseFolder(const QString &path, const QString &parent, + QStringList *list) +{ + // Get all files in this path + QDir dir(path); + //删出都是系统的链接文件时,这里统计不到,使用QDir::System标志 + QStringList files = dir.entryList(QDir::AllEntries | QDir::System + | QDir::NoDotAndDotDot | QDir::Hidden); + + // Go through all files in current directory + for (int i = 0; i < files.count(); i++) { + // If current file is folder perform this method again. Otherwise add file + // to list of results + QString current = parent + QDir::separator() + files.at(i); + QString next = path + QDir::separator() + files.at(i); + list->append(current); + + // fix bug#52386 【x86】【robot】【文件管理器】删除~/.deepinwine目录下的文件夹导致系统内存泄露 + if (QFileInfo(next).isDir() && !QFileInfo(next).isSymLink()) { + recurseFolder(next, current, list); + } + } +} + +int FileUtils::filesCount(const QString &dir) +{ + static QMutex mutex; + QMutexLocker lk(&mutex); + QDir d(dir); + QStringList entryList = d.entryList(QDir::AllEntries | QDir::System + | QDir::NoDotAndDotDot | QDir::Hidden); + return entryList.size(); +} + +QStringList FileUtils::filesList(const QString &dir) +{ + QStringList appNames; + QDirIterator it(dir, + QDir::Files | QDir::NoDotAndDotDot, + QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + appNames.append(it.filePath()); + } + return appNames; +} + +/** + * @brief 获取一个目录文件的大小 + * + * 通常情况下,一个空目录文件的大小是 4k (有文件的目录的大小随文件数量的增加而增加) + * 但是不同的文件系统下,目录的大小是不同的 (如 exfat 是 32k,vfat 是 8k) + * 跑CI时发现, 空文件夹size返回了64B + * + * @return fts_* 函数获取的结果,默认为 4096 + */ +qint64 FileUtils::singleDirSize(const DUrl &url) +{ + qint64 size = 0; + char *paths[2] = {nullptr, nullptr}; + QByteArray urlBytes = url.path().toUtf8(); + paths[0] = strdup(urlBytes.data()); + FTS *fts = fts_open(paths, 0, nullptr); + + if (fts) { + FTSENT *ent = fts_read(fts); + if (ent && ent->fts_info == FTS_D) + size = ent->fts_statp->st_size <= 0 ? 4096 : ent->fts_statp->st_size; + fts_close(fts); + } + + if (paths[0]) + free(paths[0]); + return size; +} + +qint64 FileUtils::totalSize(const QString &targetFile) +{ + qint64 total = 0; + QFileInfo targetInfo(targetFile); + if (targetInfo.exists()) { + if (targetInfo.isDir()) { + QDir d(targetFile); + QFileInfoList entryInfoList = d.entryInfoList(QDir::AllEntries | QDir::System + | QDir::NoDotAndDotDot | QDir::NoSymLinks + | QDir::Hidden); + foreach (QFileInfo file, entryInfoList) { + if (file.isFile()) { + total += file.size(); + } else { + QDirIterator it(file.absoluteFilePath(), QDir::AllEntries | QDir::System | QDir::NoDotAndDotDot | QDir::NoSymLinks | QDir::Hidden, QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + total += it.fileInfo().size(); + } + } + } + } else { + total += targetInfo.size(); + } + } + return total; +} +//--------------------------------------------------------------------------- + +/** + * @brief Returns size of all given files/dirs (including nested files/dirs) + * @param files + * @return total size + */ +qint64 FileUtils::totalSize(const DUrlList &files) +{ + qint64 total = 1; + foreach (QUrl url, files) { + QFileInfo file = url.path(); + if (file.isFile()) + total += file.size(); + else if (!file.isSymLink()) { + QDirIterator it(url.path(), QDir::AllEntries | QDir::System | QDir::NoDotAndDotDot | QDir::NoSymLinks | QDir::Hidden, QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + total += it.fileInfo().size(); + } + } + } + return total; +} +/** + * @brief Returns size of all given files/dirs (including local) by ftd,so fast in local + * @param files + * @param dirSize outputparam,dir size. + * @param fileCount outputparam,all file count + * @return total size + */ +qint64 FileUtils::totalSize(const DUrlList &files, qint32 &dirSize, qint32 &fileCount) +{ + qint64 total = 0; + dirSize = 0; + fileCount = 0; + for (auto url : files) { + char *paths[2] = {nullptr, nullptr}; + paths[0] = strdup(url.path().toUtf8().toStdString().data()); + FTS *fts = fts_open(paths, 0, nullptr); + if (paths[0]) + free(paths[0]); + if (nullptr == fts) { + perror("fts_open"); + continue; + } + while (1) { + FTSENT *ent = fts_read(fts); + if (ent == nullptr) { + break; + } + unsigned short flag = ent->fts_info; + if (flag != FTS_DP) + total += ent->fts_statp->st_size <= 0 ? getMemoryPageSize() : ent->fts_statp->st_size; + if (dirSize == 0 && flag == FTS_D) + dirSize = ent->fts_statp->st_size <= 0 ? getMemoryPageSize() : + static_cast(ent->fts_statp->st_size); + if (flag == FTS_F) + fileCount++; + } + fts_close(fts); + } + + dirSize = dirSize <= 0 ? getMemoryPageSize() : dirSize; + return total; +} + +qint64 FileUtils::totalSize(const DUrlList &files, const qint64 &maxLimit, bool &isInLimit) +{ + qint64 total = 1; + foreach (QUrl url, files) { + QFileInfo file = url.path(); + if (file.isFile()) + total += file.size(); + if (total > maxLimit) { + isInLimit = false; + return total; + } else { + QDirIterator it(url.path(), QDir::AllEntries | QDir::System | QDir::NoDotAndDotDot | QDir::NoSymLinks | QDir::Hidden, QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + total += it.fileInfo().size(); + if (total > maxLimit) { + isInLimit = false; + return total; + } + } + } + } + return total; +} + +bool FileUtils::isArchive(const QString &path) +{ + QFileInfo f(path); + if (f.exists()) { + return mimeTypeDisplayManager->supportArchiveMimetypes().contains(DMimeDatabase().mimeTypeForFile(f).name()); + } else { + return false; + } +} + +//--------------------------------------------------------------------------- + +/** + * @brief Returns names of available applications + * @return application name list + */ +QStringList FileUtils::getApplicationNames() +{ + QStringList appNames; + QDirIterator it("/usr/share/applications", QStringList("*.desktop"), + QDir::Files | QDir::NoDotAndDotDot, + QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + appNames.append(it.fileName()); + } + return appNames; +} + +//--------------------------------------------------------------------------- + +/** + * @brief Returns real suffix for given file + * @param name + * @return suffix + */ +QString FileUtils::getRealSuffix(const QString &name) +{ + // Strip version suffix + QStringList tmp = name.split("."); + bool ok; + while (tmp.size() > 1) { + tmp.last().toInt(&ok); + if (!ok) { + return tmp.last(); + } + tmp.removeLast(); + } + return ""; +} +//--------------------------------------------------------------------------- + +/** + * @brief Returns mime icon + * @param mime + * @return icon + */ +QIcon FileUtils::searchMimeIcon(QString mime, const QIcon &defaultIcon) +{ + QIcon icon = QIcon::fromTheme(mime.replace("/", "-"), defaultIcon); + return icon; +} +//--------------------------------------------------------------------------- + +/** + * @brief Searches for generic icon + * @param category + * @return icon + */ +QIcon FileUtils::searchGenericIcon(const QString &category, + const QIcon &defaultIcon) +{ + QIcon icon = QIcon::fromTheme(category + "-generic"); + if (!icon.isNull()) { + return icon; + } + icon = QIcon::fromTheme(category + "-x-generic"); + return icon.isNull() ? defaultIcon : icon; +} +//--------------------------------------------------------------------------- + +/** + * @brief Searches for application icon in the filesystem + * @param app + * @param defaultIcon + * @return icon + */ +QIcon FileUtils::searchAppIcon(const DesktopFile &app, + const QIcon &defaultIcon) +{ + // Resulting icon + QIcon icon; + + // First attempt, check whether icon is a valid file + if (QFile(app.getIcon()).exists()) { + icon = QIcon(app.getIcon()); + if (!icon.isNull()) { + return icon; + } + } + + // Second attempt, try load icon from theme + icon = QIcon::fromTheme(app.getIcon()); + if (!icon.isNull()) { + return icon; + } + + // Next, try luck with application name + QString name = app.getFileName().remove(".desktop").split("/").last(); + icon = QIcon::fromTheme(name); + if (!icon.isNull()) { + return icon; + } + + // Last chance + QDir appIcons("/usr/share/pixmaps", "", nullptr, QDir::Files | QDir::NoDotAndDotDot); + QStringList iconFiles = appIcons.entryList(); + QStringList searchIcons = iconFiles.filter(name); + if (searchIcons.count() > 0) { + return QIcon("/usr/share/pixmaps/" + searchIcons.at(0)); + } + + // Default icon + return defaultIcon; +} +//--------------------------------------------------------------------------- + +QString sizeString(const QString &str) +{ + int begin_pos = str.indexOf('.'); + + if (begin_pos < 0) + return str; + + QString size = str; + + while (size.count() - 1 > begin_pos) { + if (!size.endsWith('0')) + return size; + + size = size.left(size.count() - 1); + } + + return size.left(size.count() - 1); +} + +qreal dRound64(qreal num, int count = 1) +{ + if (count <= 0) + return qRound64(num); + + qreal base = qPow(10, count); + + return qRound64(num * base) / base; +} + +/*! + * \brief Display human readable file size. + * + * by default, will display size unit. like `1.2 GB` or `616 MB`. By using + * \a forceUnit argument we can also force to display a unit size with the + * required unit. 0 for bytes, 1 for KiB, 2 for MiB, 3 for GiB, etc. + * + * \param num The file size number. + * \param withUnitVisible Size unit visible or not. + * \param precision Precision for float number after the dot. + * \param forceUnit Force to use a unit. + * \return + */ +QString FileUtils::formatSize(qint64 num, bool withUnitVisible, int precision, int forceUnit, QStringList unitList) +{ + if (num < 0) { + qWarning() << "Negative number passed to formatSize():" << num; + num = 0; + } + + bool isForceUnit = (forceUnit >= 0); + QStringList list; + qreal fileSize(num); + + if (unitList.size() == 0) { + list << " B" << " KB" << " MB" << " GB" << " TB"; // should we use KiB since we use 1024 here? + } else { + list = unitList; + } + + QStringListIterator i(list); + QString unit = i.hasNext() ? i.next() : QStringLiteral(" B"); + + int index = 0; + while (i.hasNext()) { + if (fileSize < 1024 && !isForceUnit) { + break; + } + + if (isForceUnit && index == forceUnit) { + break; + } + + unit = i.next(); + fileSize /= 1024; + index++; + } + QString unitString = withUnitVisible ? unit : QString(); + return QString("%1%2").arg(sizeString(QString::number(fileSize, 'f', precision)), unitString); +} + +/*! + * \brief 计算机页面磁盘大小数据 + * \param usedSize 使用引用的原因是光驱的数据可能重置,若不重置则会影响进度条异常 + * \param totalSize 使用引用的原因是光驱的数据可能重置,若不重置则会影响进度条异常 + * \param strVolTag 这个标识符加入的用于判定是否为光驱 + * \return + */ +QString FileUtils::diskUsageString(quint64 &usedSize, quint64 &totalSize, QString strVolTag) +{ + const qint64 kb = 1024; + const qint64 mb = 1024 * kb; + const QStringList unitDisplayText = {"B", "K", "M", "G", "T"}; + + if (!~usedSize) { + return FileUtils::formatSize(static_cast(totalSize), true, 0, totalSize < mb ? 2 : -1, unitDisplayText); + } + + // todo: too ugly! should be beaufify + // fix: 探测光盘推进,弹出和挂载状态机标识 + bool bVolFlag = strVolTag.startsWith("sr") // 避免因传入非光驱挂载点而插入 CdStatusInfo 对象 + ? DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].bVolFlag + : false; + bool bMntFlag = strVolTag.startsWith("sr") + ? DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].bMntFlag + : false; + if (bVolFlag && (totalSize == 0)) { //CD/DVD + return QObject::tr("Unknown"); + } else if (!bVolFlag && !bMntFlag && (totalSize == 0)) { + if (strVolTag.startsWith("sr")) { //CD/DVD + return FileUtils::defaultOpticalSize(strVolTag, usedSize, totalSize); + } else { // special: totalsize == 0 + return QString("0M"); + } + } else if (!bVolFlag && !bMntFlag && (totalSize > 0) && (usedSize == 0)) { //blank CD/DVD + return QString("0M"); + } else { + return QString("%1/%2").arg(FileUtils::formatSize(static_cast(usedSize), true, 1, usedSize < mb ? 2 : -1, unitDisplayText), + FileUtils::formatSize(static_cast(totalSize), true, 1, totalSize < mb ? 2 : -1, unitDisplayText)); + } +} + + +/*! + * \brief 解析配置文件,获取光盘大小数据 + * 光盘打开后可以显示大小,并挂载然而关闭文管后再重新启动会导致之前的状态机失效(未持久化存储) + * 因此会显示为0M,且状态为已挂载的状态,而右下角插件则因为读取了配置而显示正确的大小 + * + * \return 挂载状态时返回配置文件中存储的光盘大小 + */ +QString FileUtils::defaultOpticalSize(const QString &tagName, quint64 &usedSize, quint64 &totalSize) +{ + QString size{"0M"}; + int burnStatus{DFMOpticalMediaWidget::BCSA_BurnCapacityStatusEjct}; + quint64 curTotalSize{0}; // 光盘总大小 + quint64 curUsedSize{0}; // 光盘已使用的大小 + + if (DFMApplication::genericSetting()->keys(BURN_CAPACITY_ATTRIBUTE).contains(tagName)) { + const QMap &info = DFMApplication::genericSetting()->value(BURN_CAPACITY_ATTRIBUTE, tagName).toMap(); + burnStatus = info.value(BURN_CAPACITY_STATUS).toInt(); + curTotalSize = static_cast(info.value(BURN_CAPACITY_TOTAL_SIZE).toDouble()); + curUsedSize = static_cast(info.value(BURN_CAPACITY_USED_SIZE).toDouble()); + + if (burnStatus == DFMOpticalMediaWidget::BCSA_BurnCapacityStatusAddMount && curUsedSize > 0 && curTotalSize > 8) { + const qint64 kb = 1024; + const qint64 mb = 1024 * kb; + const QStringList unitDisplayText = {"B", "K", "M", "G", "T"}; + // 重置原始的size数据 + usedSize = curUsedSize; + totalSize = curTotalSize; + size = QString("%1/%2").arg(FileUtils::formatSize(static_cast(usedSize), true, 1, usedSize < mb ? 2 : -1, unitDisplayText), + FileUtils::formatSize(static_cast(totalSize), true, 1, totalSize < mb ? 2 : -1, unitDisplayText)); + + } + } + + return size; +} + +DUrl FileUtils::newDocumentUrl(const DAbstractFileInfoPointer targetDirInfo, const QString &baseName, const QString &suffix) +{ + if (targetDirInfo->isVirtualEntry()) { + return DUrl(); + } + + int i = 0; + QString fileName = suffix.isEmpty() ? QString("%1").arg(baseName) : QString("%1.%2").arg(baseName, suffix); + DUrl fileUrl = targetDirInfo->getUrlByChildFileName(fileName); + while (true) { + DAbstractFileInfoPointer newInfo = DFileService::instance()->createFileInfo(nullptr, fileUrl); + if (newInfo && newInfo->exists()) { + ++i; + fileName = suffix.isEmpty() + ? QString("%1%2").arg(baseName, QString::number(i)) + : QString("%1%2.%3").arg(baseName, QString::number(i), suffix); + fileUrl = targetDirInfo->getUrlByChildFileName(fileName); + } else { + return fileUrl; + } + } +} + +QString FileUtils::newDocmentName(QString targetdir, const QString &baseName, const QString &suffix) +{ + if (targetdir.isEmpty()) + return QString(); + + if (targetdir.endsWith(QDir::separator())) + targetdir.chop(1); + + int i = 0; + QString filePath = suffix.isEmpty() ? QString("%1/%2").arg(targetdir, baseName) : QString("%1/%2.%3").arg(targetdir, baseName, suffix); + while (true) { + if (QFile(filePath).exists()) { + ++i; + filePath = suffix.isEmpty() + ? QString("%1/%2 %3").arg(targetdir, baseName, QString::number(i)) + : QString("%1/%2 %3.%4").arg(targetdir, baseName, QString::number(i), suffix); + } else { + return filePath; + } + } +} + +bool FileUtils::cpTemplateFileToTargetDir(const QString &targetdir, const QString &baseName, const QString &suffix, WId windowId) +{ + QString templateFile; + QDirIterator it(DFMStandardPaths::location(DFMStandardPaths::TemplatesPath), QDir::Files); + while (it.hasNext()) { + it.next(); + if (it.fileInfo().suffix() == suffix) { + templateFile = it.filePath(); + break; + } + } + + if (templateFile.isEmpty()) + return false; + +// QString targetFile = FileUtils::newDocmentName(targetdir, baseName, suffix); + +// if (targetFile.isEmpty()) +// return false; + +// return QFile::copy(templateFile, targetFile); + return !AppController::createFile(templateFile, targetdir, baseName, windowId).isEmpty(); +} + +bool FileUtils::openFile(const QString &filePath) +{ + bool result = false; + if (QFileInfo(filePath).suffix() == "desktop") { + result = FileUtils::launchApp(filePath); + return result; + } + + /*********************************************************/ + //解决空文本文件转其他非文本格式时打开仍然是文本方式打开的问题 + //QString mimetype = getFileMimetype(filePath); + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, DUrl(FILE_ROOT + filePath)); + QString mimetype; + if (info && info->size() == 0 && info->exists()) { + mimetype = info->mimeType().name(); + } else { + mimetype = getFileMimetype(filePath); + } + /*********************************************************/ + QAtomicInteger isOpenNow = false; + QString defaultDesktopFile = MimesAppsManager::getDefaultAppDesktopFileByMimeType(mimetype); + if (defaultDesktopFile.isEmpty()) { + if (isSmbUnmountedFile(DUrl::fromLocalFile(filePath))) { + mimetype = QString("inode/directory"); + defaultDesktopFile = MimesAppsManager::getDefaultAppDesktopFileByMimeType(mimetype); + isOpenNow = true; + mimetype = QString(); + } else { + qDebug() << "no default application for" << filePath; + return false; + } + } + //此处会排除执行段(Exec=)包含dde-file-manager的desktop文件,需要对目录(inode/directory)类型及dde-open.desktop例外处理 + if (!isOpenNow && isFileManagerSelf(defaultDesktopFile) && mimetype != "inode/directory" && !defaultDesktopFile.contains("/dde-open.desktop")) { + QStringList recommendApps = mimeAppsManager->getRecommendedApps(DUrl::fromLocalFile(filePath)); + recommendApps.removeOne(defaultDesktopFile); + if (recommendApps.count() > 0) { + defaultDesktopFile = recommendApps.first(); + } else { + qDebug() << "no default application for" << filePath; + return false; + } + } + result = launchApp(defaultDesktopFile, QStringList() << DUrl::fromLocalFile(filePath).toString()); + if (result) { + // workaround since DTK apps doesn't support the recent file spec. + // spec: https://www.freedesktop.org/wiki/Specifications/desktop-bookmark-spec/ + // the correct approach: let the app add it to the recent list. + // addToRecentFile(DUrl::fromLocalFile(filePath), mimetype); + DesktopFile df(defaultDesktopFile); + addRecentFile(filePath, df, mimetype); + return result; + } + + if (mimeAppsManager->getDefaultAppByFileName(filePath) == "org.gnome.font-viewer.desktop") { + QProcess::startDetached("gio", QStringList() << "open" << filePath); + QTimer::singleShot(200, [ = ] { + QProcess::startDetached("gio", QStringList() << "open" << filePath); + }); + return true; + } + + result = QProcess::startDetached("gio", QStringList() << "open" << filePath); + + if (!result) + return QDesktopServices::openUrl(QUrl::fromLocalFile(filePath)); + return result; +} + +bool FileUtils::openFiles(const QStringList &filePaths) +{ + QStringList rePath = filePaths; + bool ret = false; + for (const QString &filePath : filePaths) { + if (QFileInfo(filePath).suffix() == "desktop") { + ret = FileUtils::launchApp(filePath) || ret; //有一个成功就成功 + rePath.removeOne(filePath); + continue; + } + } + if (rePath.isEmpty()) + return ret; + + const QString filePath = rePath.first(); + + /*********************************************************/ + //解决空文本文件转其他非文本格式时打开仍然是文本方式打开的问题 + //QString mimetype = getFileMimetype(filePath); + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, DUrl(FILE_ROOT + filePath)); + QString mimetype; + if (info && info->size() == 0 && info->exists()) { + mimetype = info->mimeType().name(); + } else { + mimetype = getFileMimetype(filePath); + } + /*********************************************************/ + bool isOpenNow = false; + QString defaultDesktopFile = MimesAppsManager::getDefaultAppDesktopFileByMimeType(mimetype); + if (defaultDesktopFile.isEmpty()) { + if (isSmbUnmountedFile(DUrl::fromLocalFile(filePath))) { + mimetype = QString("inode/directory"); + defaultDesktopFile = MimesAppsManager::getDefaultAppDesktopFileByMimeType(mimetype); + isOpenNow = true; + mimetype = QString(); + } else { + qDebug() << "no default application for" << filePath; + return false; + } + } + + if (!isOpenNow && isFileManagerSelf(defaultDesktopFile) && mimetype != "inode/directory") { + QStringList recommendApps = mimeAppsManager->getRecommendedApps(DUrl::fromLocalFile(filePath)); + recommendApps.removeOne(defaultDesktopFile); + if (recommendApps.count() > 0) { + defaultDesktopFile = recommendApps.first(); + } else { + qDebug() << "no default application for" << rePath; + return false; + } + } + + QStringList appAgrs; + for (const QString &tmp : rePath) + appAgrs << DUrl::fromLocalFile(tmp).toString(); + bool result = launchApp(defaultDesktopFile, appAgrs); + if (result) { + // workaround since DTK apps doesn't support the recent file spec. + // spec: https://www.freedesktop.org/wiki/Specifications/desktop-bookmark-spec/ + // the correct approach: let the app add it to the recent list. + // addToRecentFile(DUrl::fromLocalFile(filePath), mimetype); + for (const QString &tmp : rePath) { + QString file_path = DUrl::fromLocalFile(tmp).toLocalFile(); + DesktopFile df(defaultDesktopFile); + addRecentFile(file_path, df, mimetype); + } + return result; + } else if (isSmbUnmountedFile(DUrl::fromLocalFile(rePath[0]))) { + return false; + } + + if (mimeAppsManager->getDefaultAppByFileName(filePath) == "org.gnome.font-viewer.desktop") { + QProcess::startDetached("gio", QStringList() << "open" << rePath); + QTimer::singleShot(200, [ = ] { + QProcess::startDetached("gio", QStringList() << "open" << rePath); + }); + return true; + } + + result = QProcess::startDetached("gio", QStringList() << "open" << rePath); + + if (!result) { + result = false; + for (const QString &tmp : rePath) + result = QDesktopServices::openUrl(QUrl::fromLocalFile(tmp)) || result; //有一个成功就成功 + } + return result; +} + +bool FileUtils::openEnterFiles(const QStringList &filePaths) +{ + QStringList rePath = filePaths; + bool ret = false; + for (const QString &filePath : filePaths) { + if (QFileInfo(filePath).suffix() == "desktop") { + ret = FileUtils::launchApp(filePath) || ret; //有一个成功就成功 + rePath.removeOne(filePath); + continue; + } + } + if (rePath.isEmpty()) + return ret; + //fix bug 33136 在选中3过文件,mimetype有3种不同,但是用enter键打开,这里只处理了 + //第一个文件的mimetype,根据mimetype,选定desktop,传入了3个文件地址,所以后面两个 + //打开失败,处理所有的文件的mimetype,相同的就用同一个desktop启动 + QHash openinfo; + QHash mimetypeinfo; + foreach (const QString &filePath, rePath) { + /*********************************************************/ + //解决空文本文件转其他非文本格式时打开仍然是文本方式打开的问题 + //QString mimetype = getFileMimetype(filePath); + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(nullptr, DUrl(FILE_ROOT + filePath)); + QString mimetype; + if (info && info->size() == 0 && info->exists()) { + mimetype = info->mimeType().name(); + } else { + mimetype = getFileMimetype(filePath); + } + mimetypeinfo.insert(DUrl::fromLocalFile(filePath).toString(), mimetype); + /*********************************************************/ + bool isOpenNow = false; + QString defaultDesktopFile = MimesAppsManager::getDefaultAppDesktopFileByMimeType(mimetype); + if (defaultDesktopFile.isEmpty()) { + if (isSmbUnmountedFile(DUrl::fromLocalFile(filePath))) { + mimetype = QString("inode/directory"); + defaultDesktopFile = MimesAppsManager::getDefaultAppDesktopFileByMimeType(mimetype); + isOpenNow = true; + mimetype = QString(); + } else { + qDebug() << "no default application for" << filePath; + continue; + } + } + + if (!isOpenNow && isFileManagerSelf(defaultDesktopFile) && mimetype != "inode/directory") { + QStringList recommendApps = mimeAppsManager->getRecommendedApps(DUrl::fromLocalFile(filePath)); + recommendApps.removeOne(defaultDesktopFile); + if (recommendApps.count() > 0) { + defaultDesktopFile = recommendApps.first(); + } else { + qDebug() << "no default application for" << rePath; + continue; + } + } + if (!defaultDesktopFile.isEmpty()) { + QStringList value = openinfo.contains(defaultDesktopFile) ? openinfo.value(defaultDesktopFile) : QStringList(); + value << DUrl::fromLocalFile(filePath).toString(); + openinfo.insert(defaultDesktopFile, value); + } + } + + //未找到默认打开应用,需要返回false,让上层逻辑走选择默认打开程序的流程 + if (openinfo.isEmpty()) { + return false; + } else if (isSmbUnmountedFile(DUrl::fromLocalFile(rePath[0]))) { + return false; + } + + QStringList appAgrs; + for (const QString &tmp : rePath) + appAgrs << DUrl::fromLocalFile(tmp).toString(); + bool result = false; + foreach (const QString &defaultDesktopFile, openinfo.keys()) { + bool temresult = launchApp(defaultDesktopFile, openinfo.value(defaultDesktopFile)); + if (temresult) { + // workaround since DTK apps doesn't support the recent file spec. + // spec: https://www.freedesktop.org/wiki/Specifications/desktop-bookmark-spec/ + // the correct approach: let the app add it to the recent list. + // addToRecentFile(DUrl::fromLocalFile(filePath), mimetype); + for (const QString &tmp : openinfo.value(defaultDesktopFile)) { + QString filePath = DUrl::fromUserInput(tmp).toLocalFile(); + DesktopFile df(defaultDesktopFile); + addRecentFile(filePath, df, mimetypeinfo.value(tmp)); + } + result = true; + } + } + //只要一次成功就返回 + if (result) { + return result; + } + + const QString filePath = rePath.first(); + if (mimeAppsManager->getDefaultAppByFileName(filePath) == "org.gnome.font-viewer.desktop") { + QProcess::startDetached("gio", QStringList() << "open" << rePath); + QTimer::singleShot(200, [ = ] { + QProcess::startDetached("gio", QStringList() << "open" << rePath); + }); + return true; + } + + result = QProcess::startDetached("gio", QStringList() << "open" << rePath); + + if (!result) { + result = false; + for (const QString &tmp : rePath) + result = QDesktopServices::openUrl(QUrl::fromLocalFile(tmp)) || result; //有一个成功就成功 + } + return result; +} + +bool FileUtils::launchApp(const QString &desktopFile, const QStringList &filePaths) +{ + QStringList newList(filePaths); + if (isFileManagerSelf(desktopFile) && filePaths.count() > 1) { + foreach (const QString &filePath, filePaths) { + // fix bug#33577在桌面上,多选文件夹不能打开 + DUrl t_file(filePath); + QString t_filePath = t_file.toString(); + if (t_file.isLocalFile()) { + t_filePath = t_file.toLocalFile(); + } + openFile(t_filePath); + } + return true; + } + + if (isFileManagerSelf(desktopFile) && filePaths.count() == 1) { + DUrl fileUrl(filePaths[0]); + if (isSmbUnmountedFile(fileUrl)) { + newList.clear(); + newList << smbFileUrl(filePaths[0]).toString(); + } + } + + bool ok = launchAppByDBus(desktopFile, newList); + if (!ok) { + ok = launchAppByGio(desktopFile, newList); + } + return ok; +} + +bool FileUtils::launchAppByDBus(const QString &desktopFile, const QStringList &filePaths) +{ + if (appController->checkLaunchAppInterface()) { + qDebug() << "launchApp by dbus:" << desktopFile << filePaths; + //多个wps文件同时打开应用会报出文件不存在的错误,而单个打开不会 + //对wps文件做特殊处理,一个一个分别打开 +// if (desktopFile.endsWith("wps-office-wps.desktop")) { +// DesktopFile deskfile(desktopFile); +// if (deskfile.getExec().contains("%U")) { //exc标志 为%F时也可以打开多个 %U不行 +// if (!filePaths.isEmpty()) +// { +// for (const QString &path : filePaths) { +// appController->startManagerInterface()->LaunchApp(desktopFile, static_cast(QX11Info::getTimestamp()), {path}); +// } +// return true; +// } +// } +// } + //以上改动有问题,暂时撤销 + + appController->startManagerInterface()->LaunchApp(desktopFile, static_cast(QX11Info::getTimestamp()), filePaths); + return true; + } + return false; +} + +bool FileUtils::launchAppByGio(const QString &desktopFile, const QStringList &filePaths) +{ + qDebug() << "launchApp by gio:" << desktopFile << filePaths; + + std::string stdDesktopFilePath = desktopFile.toStdString(); + const char *cDesktopPath = stdDesktopFilePath.data(); + + GDesktopAppInfo *appInfo = g_desktop_app_info_new_from_filename(cDesktopPath); + if (!appInfo) { + qDebug() << "Failed to open desktop file with gio: g_desktop_app_info_new_from_filename returns NULL. Check PATH maybe?"; + return false; + } + + GList *g_files = nullptr; + foreach (const QString &filePath, filePaths) { + std::string stdFilePath = filePath.toStdString(); + const char *cFilePath = stdFilePath.data(); + GFile *f = g_file_new_for_uri(cFilePath); + g_files = g_list_append(g_files, f); + } + + GError *gError = nullptr; + gboolean ok = g_app_info_launch(reinterpret_cast(appInfo), g_files, nullptr, &gError); + + if (gError) { + qWarning() << "Error when trying to open desktop file with gio:" << gError->message; + g_error_free(gError); + } + + if (!ok) { + qWarning() << "Failed to open desktop file with gio: g_app_info_launch returns false"; + } + g_object_unref(appInfo); + g_list_free(g_files); + + return ok; +} + +bool FileUtils::openFilesByApp(const QString &desktopFile, const QStringList &filePaths) +{ + bool ok = false; + + if (desktopFile.isEmpty()) { + qDebug() << "Failed to open desktop file with gio: app file path is empty"; + return ok; + } + + if (filePaths.isEmpty()) { + qDebug() << "Failed to open desktop file with gio: file path is empty"; + return ok; + } + + qDebug() << desktopFile << filePaths; + + GDesktopAppInfo *appInfo = g_desktop_app_info_new_from_filename(desktopFile.toLocal8Bit().constData()); + if (!appInfo) { + qDebug() << "Failed to open desktop file with gio: g_desktop_app_info_new_from_filename returns NULL. Check PATH maybe?"; + return false; + } + + QString terminalFlag = QString(g_desktop_app_info_get_string(appInfo, "Terminal")); + if (terminalFlag == "true") { + QString exec = QString(g_desktop_app_info_get_string(appInfo, "Exec")); + QStringList args; + args << "-e" << exec.split(" ").at(0) << filePaths; + QString termPath = defaultTerminalPath(); + qDebug() << termPath << args; + ok = QProcess::startDetached(termPath, args); + } else { + ok = launchApp(desktopFile, filePaths); + } + g_object_unref(appInfo); + + if (ok) { + // workaround since DTK apps doesn't support the recent file spec. + // spec: https://www.freedesktop.org/wiki/Specifications/desktop-bookmark-spec/ + // the correct approach: let the app add it to the recent list. + // addToRecentFile(DUrl::fromLocalFile(filePath), mimetype); + QString filePath = filePaths.first(); + filePath = DUrl::fromUserInput(filePath).path(); + QString mimetype = getFileMimetype(filePath); + for (const QString &tmp : filePaths) { + QString temFilePath = DUrl::fromUserInput(tmp).path(); + DesktopFile df(desktopFile); + addRecentFile(temFilePath, df, mimetype); + } + } + + return ok; +} + +bool FileUtils::isFileManagerSelf(const QString &desktopFile) +{ + /* + * return true if exec field contains dde-file-manager/file-manager.sh of dde-file-manager desktopFile + */ + DesktopFile d(desktopFile); + return d.getExec().contains("dde-file-manager") || d.getExec().contains("file-manager.sh"); +} + +QString FileUtils::defaultTerminalPath() +{ + const static QString dde_daemon_default_term = QStringLiteral("/usr/lib/deepin-daemon/default-terminal"); + const static QString debian_x_term_emu = QStringLiteral("/usr/bin/x-terminal-emulator"); + + if (QFileInfo::exists(dde_daemon_default_term)) { + return dde_daemon_default_term; + } else if (QFileInfo::exists(debian_x_term_emu)) { + return debian_x_term_emu; + } + + return QStandardPaths::findExecutable("xterm"); +} + +bool FileUtils::setBackground(const QString &pictureFilePath) +{ + QDBusMessage msgIntrospect = QDBusMessage::createMethodCall("com.deepin.daemon.Appearance", "/com/deepin/daemon/Appearance", "org.freedesktop.DBus.Introspectable", "Introspect"); + QDBusPendingCall call = QDBusConnection::sessionBus().asyncCall(msgIntrospect); + call.waitForFinished(); + if (call.isFinished()) { + QDBusReply reply = call.reply(); + QString value = reply.value(); + + if (value.contains("SetMonitorBackground")) { + QDBusMessage msg = QDBusMessage::createMethodCall("com.deepin.daemon.Appearance", "/com/deepin/daemon/Appearance", "com.deepin.daemon.Appearance", "SetMonitorBackground"); + if (DesktopInfo().waylandDectected()) { + QDBusInterface interface("com.deepin.daemon.Display", "/com/deepin/daemon/Display", "com.deepin.daemon.Display"); + QString screenname = qvariant_cast< QString >(interface.property("Primary")); + msg.setArguments({screenname, pictureFilePath}); + } + + else { + msg.setArguments({qApp->primaryScreen()->name(), pictureFilePath}); + } + + QDBusConnection::sessionBus().asyncCall(msg); + qDebug() << "FileUtils::setBackground call Appearance SetMonitorBackground"; + return true; + } + } + + QDBusMessage msg = QDBusMessage::createMethodCall("com.deepin.daemon.Appearance", "/com/deepin/daemon/Appearance", "com.deepin.daemon.Appearance", "Set"); + msg.setArguments({"Background", pictureFilePath}); + QDBusConnection::sessionBus().asyncCall(msg); + qDebug() << "FileUtils::setBackground call Appearance Set"; + + return true; +} + +QString FileUtils::md5(const QString &fpath) +{ + QFile file(fpath); + + if (file.open(QIODevice::ReadOnly)) { + return QCryptographicHash::hash(file.readAll(), QCryptographicHash::Md5).toHex(); + } + + return QCryptographicHash::hash(fpath.toLocal8Bit(), QCryptographicHash::Md5).toHex(); +} + +QByteArray FileUtils::md5(QFile *file, const QString &filePath) +{ + QByteArray md5 = filePath.toLocal8Bit() + QByteArray::number(file->size()); + + if (file->open(QIODevice::ReadOnly)) { + if (file->size() < 8192) { + md5 += file->readAll(); + } else { + char data[4097] = {}; + + file->read(data, 4096); + + md5.append(data); + + file->seek(file->size() - 4096); + + file->read(data, 4096); + + md5.append(data); + } + + file->close(); + } + + return QCryptographicHash::hash(md5, QCryptographicHash::Md5).toHex();; +} + +bool FileUtils::isFileExecutable(const QString &path) +{ + QFile file(path); + + // regard these type as unexecutable. + const static QStringList noValidateType {"txt", "md"}; + if (noValidateType.contains(QFileInfo(file).suffix())) + return false; + + bool isExeUser = false; + + // Vault file need to use stat function to read file permission. + if (VaultController::isVaultFile(path)) { + struct stat buf; + std::string stdStr = path.toStdString(); + stat(stdStr.c_str(), &buf); + if ((buf.st_mode & S_IXUSR)) { + isExeUser = true; + } + } else { + isExeUser = file.permissions() & QFile::ExeUser; + } + + return (file.permissions() & QFile::ReadUser) && isExeUser; +} + +// sort of.. duplicate with FileUtils::isFileRunnable +bool FileUtils::shouldAskUserToAddExecutableFlag(const QString &path) +{ + QString _path = path; + QFileInfo info(path); + QString mimetype = getFileMimetype(path); + if (info.isSymLink()) { + _path = QFile(path).symLinkTarget(); + mimetype = getFileMimetype(path); + } + + if (mimetype == "application/x-executable" + || mimetype == "application/x-sharedlib" + || mimetype == "application/x-iso9660-appimage" + || mimetype == "application/vnd.appimage") { + return !isFileExecutable(_path); + } + + return false; +} + +bool FileUtils::isFileRunnable(const QString &path) +{ + QString _path = path; + QFileInfo info(path); + QString mimetype = getFileMimetype(path); + qDebug() << info.isSymLink() << mimetype; + if (info.isSymLink()) { + _path = QFile(path).symLinkTarget(); + mimetype = getFileMimetype(path); + } + + // blumia: about AppImage mime type, please refer to: + // https://cgit.freedesktop.org/xdg/shared-mime-info/tree/freedesktop.org.xml.in + // btw, consider using MimeTypeDisplayManager::ExecutableMimeTypes(private) ? + if (mimetype == "application/x-executable" + || mimetype == "application/x-sharedlib" + || mimetype == "application/x-iso9660-appimage" + || mimetype == "application/vnd.appimage") { + return isFileExecutable(_path); + } + + return false; +} + + +bool FileUtils::isFileWindowsUrlShortcut(const QString &path) +{ + QString mimetype = getFileMimetype(path); + qDebug() << mimetype; + if (mimetype == "application/x-mswinurl") + return true; + return false; +} + +QString FileUtils::getInternetShortcutUrl(const QString &path) +{ + QSettings settings(path, QSettings::IniFormat); + settings.beginGroup("InternetShortcut"); + QString url = settings.value("URL").toString(); + settings.endGroup(); + return url; +} + + +QString FileUtils::getFileMimetype(const QString &path) +{ + GFile *file; + GFileInfo *info; + QString result; + + file = g_file_new_for_path(path.toUtf8()); + info = g_file_query_info(file, "standard::content-type", G_FILE_QUERY_INFO_NONE, nullptr, nullptr); + result = g_file_info_get_content_type(info); + + g_object_unref(file); + + return result; +} + +bool FileUtils::isExecutableScript(const QString &path) +{ + QString _path = path; + QFileInfo info(path); + QString mimetype = getFileMimetype(path); + qDebug() << info.isSymLink() << mimetype; + + // anke requirement +// if (info.size() == 0) { +// return false; +// } + + if (info.isSymLink()) { + _path = QFile(path).symLinkTarget(); + mimetype = getFileMimetype(path); + } + + // blumia: it's not a good idea to check if it is a executable script by just checking + // mimetype.startsWith("text/"), should be fixed later. + if (mimetype.startsWith("text/") || + (mimetype == "application/x-shellscript")) { + return isFileExecutable(_path); + } + + return false; +} + +bool FileUtils::openExcutableScriptFile(const QString &path, int flag) +{ + bool result = false; + switch (flag) { + case 0: + + break; + case 1: + result = runCommand(path, QStringList(), QUrl(path).adjusted(QUrl::RemoveFilename).toString()); + break; + case 2: { + QStringList args; + args << "-e" << path; + result = runCommand(FileUtils::defaultTerminalPath(), args, QUrl(path).adjusted(QUrl::RemoveFilename).toString()); + break; + } + case 3: + result = openFile(path); + break; + default: + break; + } + + return result; +} + +bool FileUtils::addExecutableFlagAndExecuse(const QString &path, int flag) +{ + bool result = false; + QFile file(path); + switch (flag) { + case 0: + break; + case 1: + file.setPermissions(file.permissions() | QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther); + result = runCommand(path, QStringList()); + break; + default: + break; + } + + return result; +} + +bool FileUtils::openExcutableFile(const QString &path, int flag) +{ + bool result = false; + switch (flag) { + case 0: + break; + case 1: { + QStringList args; + args << "-e" << path; + result = runCommand(FileUtils::defaultTerminalPath(), args, QUrl(path).adjusted(QUrl::RemoveFilename).toString()); + break; + } + case 2: + result = runCommand(path, QStringList(), QUrl(path).adjusted(QUrl::RemoveFilename).toString()); + break; + default: + break; + } + + return result; +} + +bool FileUtils::runCommand(const QString &cmd, const QStringList &args, const QString &wd) +{ + bool result = false; + if (appController->checkLaunchAppInterface()) { + qDebug() << "launch cmd by dbus:" << cmd << args; + if (wd.length()) { + QVariantMap opt = {{"dir", wd}}; + appController->startManagerInterface()->RunCommandWithOptions(cmd, args, opt); + } else + appController->startManagerInterface()->RunCommand(cmd, args); + result = true; + } else { + qDebug() << "launch cmd by qt:" << cmd << args; + result = QProcess::startDetached(cmd, args, wd); + } + return result; +} + +void FileUtils::mkpath(const DUrl &path) +{ + if (path.parentUrl() == path) { + return; + } + if (fileService->createFileInfo(nullptr, path)->isDir()) { + return; + } + if (fileService->mkdir(nullptr, path)) { + return; + } + mkpath(path.parentUrl()); + fileService->mkdir(nullptr, path); +} + +QString FileUtils::displayPath(const QString &pathStr) +{ + QString devicePath = pathStr; + QString homeDir = QDir::homePath(); + if (devicePath.startsWith(homeDir)) { + devicePath.replace(0, homeDir.length(), "~"); + } + + return devicePath; +} + +QByteArray FileUtils::imageFormatName(QImage::Format f) +{ + switch (f) { + case QImage::Format_ARGB32: + case QImage::Format_ARGB32_Premultiplied: + case QImage::Format_ARGB8565_Premultiplied: + case QImage::Format_ARGB6666_Premultiplied: + case QImage::Format_ARGB8555_Premultiplied: + case QImage::Format_ARGB4444_Premultiplied: + case QImage::Format_RGBA8888: + case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_A2RGB30_Premultiplied: + case QImage::Format_Alpha8: + return "png"; + default: + break; + } + + return "jpeg"; +} + + +QString FileUtils::getFileContent(const QString &file) +{ + QFile f(file); + QString fileContent = ""; + if (f.open(QFile::ReadOnly)) { + fileContent = QString(f.readAll()); + f.close(); + } else { + qDebug() << "Could not read file " << file << ":" << f.errorString(); + } + return fileContent; +} + +bool FileUtils::writeTextFile(const QString &filePath, const QString &content) +{ + QFile file(filePath); + if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream in(&file); + in << content << endl; + file.close(); + return true; + } else { + qDebug() << "Failed to write content to file " << filePath << ":" << file.errorString(); + } + return false; +} + +void FileUtils::migrateConfigFileFromCache(const QString &key) +{ + bool ret = false; + QString oldPath = QString("%1/%2/%3.%4").arg(QDir().homePath(), ".cache/dde-file-manager", key, "json"); + QString newPath = QString("%1/%2.%3").arg(DFMStandardPaths::location(DFMStandardPaths::ApplicationConfigPath), key.toLower(), "json"); + QFile srcFile(oldPath); + ret = srcFile.open(QIODevice::ReadOnly); + if (ret) { + QByteArray data = srcFile.readAll(); + srcFile.close(); + + QFile desFile(newPath); + ret = desFile.open(QIODevice::WriteOnly); + if (ret) { + qint64 code = desFile.write(data); + if (code < 0) { + qDebug() << "Error occurred when writing data"; + ret = false; + } else { + ret = srcFile.remove(); + if (!ret) { + qDebug() << "Failed to remove source file " << oldPath; + } + } + desFile.close(); + + } else { + qDebug() << "Failed to write data :" << desFile.errorString(); + } + + } else { + qDebug() << "Could not read source file " << oldPath << ":" << srcFile.errorString(); + } + + if (!ret) { + qDebug() << "Failed to migrate config file from cache"; + } +} + +QMap FileUtils::getKernelParameters() +{ + QFile cmdline("/proc/cmdline"); + cmdline.open(QIODevice::ReadOnly); + QByteArray content = cmdline.readAll(); + + QByteArrayList paraList(content.split(' ')); + + QMap result; + result.insert("_ori_proc_cmdline", content); + + for (const QByteArray &onePara : paraList) { + int equalsIdx = onePara.indexOf('='); + QString key = equalsIdx == -1 ? onePara.trimmed() : onePara.left(equalsIdx).trimmed(); + QString value = equalsIdx == -1 ? QString() : onePara.right(equalsIdx).trimmed(); + result.insert(key, value); + } + + return result; +} + +DFMGlobal::MenuExtension FileUtils::getMenuExtension(const DUrlList &urlList) +{ + int fileCount = 0; + int dirCount = 0; + foreach (DUrl url, urlList) { + QFileInfo info(url.toLocalFile()); + if (info.isDir()) { + dirCount += 1; + } else if (info.isFile()) { + fileCount += 1; + } + } + if (urlList.count() == 0) { + return DFMGlobal::MenuExtension::EmptyArea; + } else if (fileCount == 1 && dirCount == 0 && fileCount == urlList.count()) { + return DFMGlobal::MenuExtension::SingleFile; + } else if (fileCount > 1 && dirCount == 0 && fileCount == urlList.count()) { + return DFMGlobal::MenuExtension::MultiFiles; + } else if (fileCount == 0 && dirCount == 1 && dirCount == urlList.count()) { + return DFMGlobal::MenuExtension::SingleDir; + } else if (fileCount == 0 && dirCount > 1 && dirCount == urlList.count()) { + return DFMGlobal::MenuExtension::MultiDirs; + } else if (urlList.count() > 1) { + return DFMGlobal::MenuExtension::MultiFileDirs; + } else { + return DFMGlobal::MenuExtension::UnknowMenuExtension; + } +} + +bool FileUtils::isGvfsMountFile(const QString &filePath, const bool &isEx) +{ + static QMutex mutex; + QMutexLocker lk(&mutex); + if (filePath.isEmpty()) + return false; + + static const QString gvfsPath = QString("/run/user/") + QString::number(getuid()) + QString("/gvfs"); + + if (filePath.startsWith(gvfsPath) && filePath != gvfsPath) + return true; + if (filePath == gvfsPath) + return false; + + bool isgvfsfile = !DStorageInfo::isLocalDevice(filePath, isEx); + + return isgvfsfile; +} + +bool FileUtils::isFileExists(const QString &filePath) +{ + GFile *file; + std::string fstdPath = filePath.toStdString(); + file = g_file_new_for_path(fstdPath.data()); + bool isExists = g_file_query_exists(file, nullptr); + g_object_unref(file); + return isExists; +} + +QJsonObject FileUtils::getJsonObjectFromFile(const QString &filePath) +{ + QJsonObject obj; + QJsonDocument doc; + if (!QFile::exists(filePath)) + return obj; + + QFile file(filePath); + + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qDebug() << "cannot read file " << filePath << ":" << file.errorString(); + file.close(); + return obj; + } + QByteArray data = file.readAll(); + file.close(); + + QJsonParseError *jsError = nullptr; + doc = QJsonDocument::fromJson(data, jsError); + + if (jsError) { + qDebug() << "cache data pase error:" << jsError->errorString(); + return obj; + } + + obj = doc.object(); + return obj; +} + +QJsonArray FileUtils::getJsonArrayFromFile(const QString &filePath) +{ + QJsonArray array; + QJsonDocument doc; + if (!QFile::exists(filePath)) + return array; + + QFile file(filePath); + + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qDebug() << "cannot read file " << filePath << ":" << file.errorString(); + file.close(); + return array; + } + QByteArray data = file.readAll(); + file.close(); + + QJsonParseError *jsError = nullptr; + doc = QJsonDocument::fromJson(data, jsError); + + if (jsError) { + qDebug() << "cache data pase error:" << jsError->errorString(); + return array; + } + + array = doc.array(); + return array; +} + +bool FileUtils::writeJsonObjectFile(const QString &filePath, const QJsonObject &obj) +{ + QJsonDocument doc; + doc.setObject(obj); + return writeTextFile(filePath, doc.toJson().data()); +} + +bool FileUtils::writeJsonnArrayFile(const QString &filePath, const QJsonArray &array) +{ + QJsonDocument doc; + doc.setArray(array); + return writeTextFile(filePath, doc.toJson().data()); +} + +void FileUtils::mountAVFS() +{ + QProcess p; + p.start("/usr/bin/umountavfs"); + p.waitForFinished(); + QProcess::startDetached("/usr/bin/mountavfs"); +} + +void FileUtils::umountAVFS() +{ + QProcess::startDetached("/usr/bin/umountavfs"); +} + +void FileUtils::addRecentFile(const QString &filePath, const DesktopFile &desktopFile, const QString &mimetype) +{ + if (filePath.isEmpty()) { + return; + } + DRecentData recentData; + recentData.appName = desktopFile.getName(); + recentData.appExec = desktopFile.getExec(); + recentData.mimeType = mimetype; + DRecentManager::removeItem(filePath); + DRecentManager::addItem(filePath, recentData); +} + +bool FileUtils::appendCompress(const DUrl &toUrl, const DUrlList &fromUrlList) +{ + if (!fromUrlList.isEmpty()) { + QStringList arguments {toUrl.toLocalFile()}; + foreach (const DUrl &url, fromUrlList) { + // 如果是avfs文件,将路径转换为真实路径 + if (url.isAVFSFile()) { + arguments << AVFSFileInfo::realFileUrl(url).toLocalFile(); + } else { + arguments << url.toLocalFile(); + } + } + arguments << "dragdropadd"; + return QProcess::startDetached("deepin-compressor", arguments); + } + return false; +} +//获取当前內存页大小 +int FileUtils::getMemoryPageSize() +{ + static const int memoryPageSize = getpagesize(); + return memoryPageSize > 0 ? memoryPageSize : 4096; +} + +bool FileUtils::isFtpFile(const DUrl &url) +{ + static QRegularExpression regExp("^/run/user/\\d+/gvfs/.+$", + QRegularExpression::DotMatchesEverythingOption + | QRegularExpression::DontCaptureOption + | QRegularExpression::OptimizeOnFirstUsageOption); + + if (!regExp.match(url.path(), 0, QRegularExpression::NormalMatch, QRegularExpression::DontCheckSubjectStringMatchOption).hasMatch()) { + return false; + } + if (url.path().contains("/ftp:host=")) + return true; + return false; +} +/** + * @brief jugment file is local file(in system disk file)(使用gio判断挂载点是否可以卸载) + * @param url file url + */ +bool FileUtils::isFileOnDisk(const QString &path) +{ + if (path.isEmpty()) + return false; + bool isLocal = true; + GFile *dest_dir_file = g_file_new_for_path(path.toUtf8().constData()); + GMount *dest_dir_mount = g_file_find_enclosing_mount(dest_dir_file, nullptr, nullptr); + if (dest_dir_mount) { + isLocal = !g_mount_can_unmount(dest_dir_mount); + g_object_unref(dest_dir_mount); + } + g_object_unref(dest_dir_file); + return isLocal; +} +//获取cpu的核个数 +qint32 FileUtils::getCpuProcessCount() +{ + static const int cpuProcessCount = sysconf(_SC_NPROCESSORS_CONF) < 4 ? + 4 : static_cast(sysconf(_SC_NPROCESSORS_CONF)); + return cpuProcessCount; +} +/** + * @brief jugment file is mount 通过gioqt获取所有的挂载点,对比当前的url是否在挂载点中,只判断了smb和ftp + * @param url file url + */ +bool FileUtils::isNetworkUrlMounted(const DUrl &url) +{ + for (auto gvfsmp : DGioVolumeManager::getMounts()) { + auto rootFile = gvfsmp->getRootFile(); + if (!rootFile || (!rootFile->uri().contains("smb") + && !rootFile->uri().contains("ftp"))) + continue; + + DUrl mountUrl; + mountUrl.setScheme(DFMROOT_SCHEME); + mountUrl.setPath("/" + QUrl::toPercentEncoding(rootFile->path()) + "." SUFFIX_GVFSMP); + if (mountUrl == url) + return true; + } + return false; +} + +bool FileUtils::isSambaServiceRunning() +{ + QDBusInterface iface("org.freedesktop.systemd1", + "/org/freedesktop/systemd1/unit/smbd_2eservice", + "org.freedesktop.systemd1.Unit", + QDBusConnection::systemBus()); + + if (iface.isValid()) { + const QVariant &variantStatus = iface.property("SubState"); // 获取属性 SubState,等同于 systemctl status smbd 结果 Active 值 + if (variantStatus.isValid()) + return "running" == variantStatus.toString(); + } + return false; +} + +DUrl FileUtils::smbFileUrl(const QString &filePath) +{ + static QRegularExpression regExp("file:///run/user/\\d+/gvfs/smb-share:server=(?.*),share=(?.*)", + QRegularExpression::DotMatchesEverythingOption + | QRegularExpression::DontCaptureOption + | QRegularExpression::OptimizeOnFirstUsageOption); + + const QRegularExpressionMatch &match = regExp.match(filePath, 0, QRegularExpression::NormalMatch, + QRegularExpression::DontCheckSubjectStringMatchOption); + + if (!match.hasMatch()) + return DUrl::fromLocalFile(filePath); + + const QString &host = match.captured("host"); + const QString &path = match.captured("path"); + + DUrl newUrl; + newUrl.setScheme("smb"); + newUrl.setHost(host); + newUrl.setPath("/" + path.mid(0, path.lastIndexOf("/"))); + return newUrl; +} + +bool FileUtils::isSmbUnmountedFile(const DUrl &url) +{ + return url.path().startsWith("/run/user/") + && url.path().contains("/gvfs/smb-share:server=") + && DFileService::instance()->checkGvfsMountfileBusy(url, false); +} + +//优化苹果文件不卡显示,存在判断错误的可能,只能临时优化,需系统提升ios传输效率 +bool FileUtils::isDesktopFile(const QString &filePath) +{ + QMimeType mt = DMimeDatabase().mimeTypeForFile(filePath); + return mt.name() == "application/x-desktop" && mt.suffixes().contains("desktop", Qt::CaseInsensitive); +} + +bool FileUtils::isDesktopFile(const QFileInfo &fileInfo) +{ + QMimeType mt = DMimeDatabase().mimeTypeForFile(fileInfo); + return mt.name() == "application/x-desktop" && mt.suffixes().contains("desktop", Qt::CaseInsensitive); +} + +bool FileUtils::isDesktopFile(const QString &filePath, QMimeType &mimetype) +{ + QMimeType mt = DMimeDatabase().mimeTypeForFile(filePath, QMimeDatabase::MatchExtension); + mimetype = mt; + return mt.name() == "application/x-desktop" && + mt.suffixes().contains("desktop", Qt::CaseInsensitive); +} + +bool FileUtils::isDesktopFile(const QFileInfo &fileInfo, QMimeType &mimetyp) +{ + QMimeType mt = DMimeDatabase().mimeTypeForFile(fileInfo, QMimeDatabase::MatchExtension); + mimetyp = mt; + return mt.name() == "application/x-desktop" && + mt.suffixes().contains("desktop", Qt::CaseInsensitive); + +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/fileutils.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/fileutils.h new file mode 100644 index 0000000..a58ac31 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/fileutils.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef FILEUTILS_H +#define FILEUTILS_H + +#include +#include +#include +#include + +#include "desktopfile.h" +#include "properties.h" +#include "durl.h" +#include "dfmglobal.h" +#include "dabstractfileinfo.h" +#include "desktopinfo.h" + +/** + * @class FileUtils + * @brief Utility class providing static helper methods for file management + */ +class FileUtils +{ +public: + + static QString XDG_RUNTIME_DIR; + static QStringList CURRENT_ISGVFSFILE_PATH; + + static bool removeRecurse(const QString &path, const QString &name); + static bool isAncestorUrl(const DUrl &ancestor, const DUrl &url); + static bool isNetworkAncestorUrl(const DUrl &dest, const bool isDestGvfs, + const DUrl &source, const bool isSourceGvfs); + static void recurseFolder(const QString &path, const QString &parent, + QStringList *list); + static int filesCount(const QString &dir); + static QStringList filesList(const QString &dir); + static qint64 singleDirSize(const DUrl &url); + static qint64 totalSize(const QString &targetFile); + static qint64 totalSize(const DUrlList &files); + //计算本地文件的大小 + static qint64 totalSize(const DUrlList &files, qint32 &dirSize,qint32 &fileCount); + static qint64 totalSize(const DUrlList &files, const qint64 &maxLimit, bool &isInLimit); + static bool isArchive(const QString &path); + static bool canFastReadArchive(const QString &path); + static QStringList getApplicationNames(); + static QString getRealSuffix(const QString &name); + static QIcon searchGenericIcon(const QString &category, + const QIcon &defaultIcon = QIcon::fromTheme("unknown")); + static QIcon searchMimeIcon(QString mime, + const QIcon &defaultIcon = QIcon::fromTheme("unknown")); + static QIcon searchAppIcon(const DesktopFile &app, + const QIcon &defaultIcon = QIcon::fromTheme("application-x-executable")); + static QString formatSize(qint64 num, bool withUnitVisible = true, int precision = 1, int forceUnit = -1, QStringList unitList = QStringList()); + static QString diskUsageString(quint64 &usedSize, quint64 &totalSize, QString strVolTag = ""); + static QString defaultOpticalSize(const QString &tagName, quint64 &usedSize, quint64 &totalSize); + static DUrl newDocumentUrl(const DAbstractFileInfoPointer targetDirInfo, const QString &baseName, const QString &suffix); + static QString newDocmentName(QString targetdir, const QString &baseName, const QString &suffix); + static bool cpTemplateFileToTargetDir(const QString &targetdir, const QString &baseName, const QString &suffix, WId windowId); + + static bool openFile(const QString &filePath); + static bool openFiles(const QStringList &filePaths); + static bool openEnterFiles(const QStringList &filePaths); + static bool launchApp(const QString &desktopFile, const QStringList &filePaths = {}); // open filePaths by desktopFile + static bool launchAppByDBus(const QString &desktopFile, const QStringList &filePaths = {}); + static bool launchAppByGio(const QString &desktopFile, const QStringList &filePaths = {}); + + static bool openFilesByApp(const QString &desktopFile, const QStringList &filePaths); + static bool isFileManagerSelf(const QString &desktopFile); + static QString defaultTerminalPath(); + + static bool setBackground(const QString &pictureFilePath); + + static QString md5(const QString &fpath); + static QByteArray md5(QFile *file, const QString &filePath); + + static bool isFileExecutable(const QString &path); + static bool shouldAskUserToAddExecutableFlag(const QString &path); + static bool isFileRunnable(const QString &path); + static bool isFileWindowsUrlShortcut(const QString &path); /*check file is windows url shortcut*/ + static QString getInternetShortcutUrl(const QString &path);/*get InternetShortcut url of windows url shortcut*/ + + static QString getFileMimetype(const QString &path); + static bool isExecutableScript(const QString &path); + static bool openExcutableScriptFile(const QString &path, int flag); + static bool addExecutableFlagAndExecuse(const QString &path, int flag); + static bool openExcutableFile(const QString &path, int flag); + static bool runCommand(const QString &cmd, const QStringList &args, const QString &wd = QString()); + + static void mkpath(const DUrl &path); + static QString displayPath(const QString &pathStr); + + static QByteArray imageFormatName(QImage::Format f); + + static QString getFileContent(const QString &file); + static bool writeTextFile(const QString &filePath, const QString &content); + static void migrateConfigFileFromCache(const QString &key); + static QMap getKernelParameters(); + + static DFMGlobal::MenuExtension getMenuExtension(const DUrlList &urlList); + static bool isGvfsMountFile(const QString &filePath, const bool &isEx = false); + static bool isFileExists(const QString &filePath); + + static QJsonObject getJsonObjectFromFile(const QString &filePath); + static QJsonArray getJsonArrayFromFile(const QString &filePath); + static bool writeJsonObjectFile(const QString &filePath, const QJsonObject &obj); + static bool writeJsonnArrayFile(const QString &filePath, const QJsonArray &array); + + static void mountAVFS(); + static void umountAVFS(); + + static bool isDesktopFile(const QString &filePath); + static bool isDesktopFile(const QFileInfo &fileInfo); + static bool isDesktopFile(const QString &filePath, QMimeType &mimetype); + static bool isDesktopFile(const QFileInfo &fileInfo, QMimeType &mimetyp); + static void addRecentFile(const QString &filePath, const DesktopFile &desktopFile, const QString &mimetype); + + // 启用deepin-compressor追加压缩 + static bool appendCompress(const DUrl &toUrl, const DUrlList &fromUrlList); + //获取内存叶大小 + static int getMemoryPageSize(); + //判断是否是挂载ftp目录下的文件 + static bool isFtpFile(const DUrl &url); + //判断是否是操作系统同盘的本地文件 + static bool isFileOnDisk(const QString &path); + //获取线程cpu核个数 + static qint32 getCpuProcessCount(); + // 获取smbd服务是否打开 + static bool isSambaServiceRunning(); + // 判断当前的网络挂载路径是否挂载了 + static bool isNetworkUrlMounted(const DUrl &url); + + static DUrl smbFileUrl(const QString &filePath); + static bool isSmbUnmountedFile(const DUrl &url); +}; + +#endif // FILEUTILS_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/mimesappsmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/mimesappsmanager.cpp new file mode 100644 index 0000000..c590d90 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/mimesappsmanager.cpp @@ -0,0 +1,833 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "mimesappsmanager.h" +#include "dmimedatabase.h" + +#include "app/define.h" + +#include "singleton.h" +#include "desktopfile.h" +#include "interfaces/dfmstandardpaths.h" +#include "interfaces/dfmglobal.h" +#include "mimetypedisplaymanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "interfaces/durl.h" +#include "interfaces/dfileinfo.h" +#include "interfaces/dfileservices.h" +#include "fileutils.h" + +#undef signals +extern "C" { + #include + #include + #include +} +#define signals public + +DFM_USE_NAMESPACE + +QStringList MimesAppsManager::DesktopFiles = {}; +QMap MimesAppsManager::MimeApps = {}; +QMap MimesAppsManager::DDE_MimeTypes = {}; +QMap MimesAppsManager::VideoMimeApps = {}; +QMap MimesAppsManager::ImageMimeApps = {}; +QMap MimesAppsManager::TextMimeApps = {}; +QMap MimesAppsManager::AudioMimeApps = {}; + +QMap MimesAppsManager::DesktopObjs = {}; + +MimeAppsWorker::MimeAppsWorker(QObject *parent): QObject(parent) +{ + m_fileSystemWatcher = new QFileSystemWatcher; + m_updateCacheTimer = new QTimer(this); + m_updateCacheTimer->setInterval(2000); + m_updateCacheTimer->setSingleShot(true); + startWatch(); + initConnect(); +} + +MimeAppsWorker::~MimeAppsWorker() +{ + +} + +void MimeAppsWorker::initConnect() +{ + connect(m_fileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, &MimeAppsWorker::handleDirectoryChanged); + connect(m_fileSystemWatcher, &QFileSystemWatcher::fileChanged, this, &MimeAppsWorker::handleFileChanged); + connect(m_updateCacheTimer, &QTimer::timeout, this, &MimeAppsWorker::updateCache); +} + +void MimeAppsWorker::startWatch() +{ + m_fileSystemWatcher->addPaths(MimesAppsManager::getDesktopFiles()); + m_fileSystemWatcher->addPaths(MimesAppsManager::getApplicationsFolders()); +} + +void MimeAppsWorker::handleDirectoryChanged(const QString &filePath) +{ + Q_UNUSED(filePath) + + //for 1.4 +// if(QFile::exists(filePath)){ +// m_fileSystemWatcher->addPath(filePath); + +// QMap> mimeAppsSet; + +// DesktopFile desktopFile(filePath); +// MimesAppsManager::DesktopFiles.append(filePath); +// MimesAppsManager::DesktopObjs.insert(filePath, desktopFile); +// QStringList mimeTypes = desktopFile.getMimeType(); +// foreach (QString mimeType, mimeTypes) { +// if (!mimeType.isEmpty()){ +// QSet apps; +// if (mimeAppsSet.contains(mimeType)){ +// apps = mimeAppsSet.value(mimeType); +// apps.insert(filePath); +// }else{ +// apps.insert(filePath); +// } +// mimeAppsSet.insert(mimeType, apps); +// } +// } + +// foreach (QString key, mimeAppsSet.keys()) { +// QSet apps = mimeAppsSet.value(key); +// QStringList orderApps; +// if (apps.count() > 1){ +// QFileInfoList fileInfos; +// foreach (QString app, apps) { +// QFileInfo info(app); +// fileInfos.append(info); +// } + +// std::sort(fileInfos.begin(), fileInfos.end(), MimesAppsManager::lessByDateTime); + +// foreach (QFileInfo info, fileInfos) { +// orderApps.append(info.absoluteFilePath()); +// } +// }else{ +// orderApps.append(apps.toList()); +// } +// MimesAppsManager::MimeApps.insert(key, orderApps); +// } + +// foreach (QString desktopFile, MimesAppsManager::DesktopObjs.keys()) { +// QString iconName = MimesAppsManager::DesktopObjs.value(desktopFile).getIcon(); +// fileIconProvider->getDesktopIcon(iconName, 48); +// } + +// }else{ +// m_fileSystemWatcher->removePath(filePath); +// MimesAppsManager::DesktopFiles.removeOne(filePath); +// MimesAppsManager::DesktopObjs.remove(filePath); +// } +// updateCache(); + m_updateCacheTimer->start(); +} + +void MimeAppsWorker::handleFileChanged(const QString &filePath) +{ + Q_UNUSED(filePath) +// updateCache(); + m_updateCacheTimer->start(); + //for 1.4 +// DesktopFile desktopFile(filePath); +// MimesAppsManager::DesktopObjs.remove(filePath); +// MimesAppsManager::DesktopObjs.insert(filePath, desktopFile); + +// QMap> mimeAppsSet; + +// QStringList mimeTypes = desktopFile.getMimeType(); +// foreach (QString mimeType, mimeTypes) { +// if (!mimeType.isEmpty()){ +// QSet apps; +// if (mimeAppsSet.contains(mimeType)){ +// apps = mimeAppsSet.value(mimeType); +// apps.insert(filePath); +// }else{ +// apps.insert(filePath); +// } +// mimeAppsSet.insert(mimeType, apps); +// } +// } + +// foreach (QString key, mimeAppsSet.keys()) { +// QSet apps = mimeAppsSet.value(key); +// QStringList orderApps; +// if (apps.count() > 1){ +// QFileInfoList fileInfos; +// foreach (QString app, apps) { +// QFileInfo info(app); +// fileInfos.append(info); +// } + +// std::sort(fileInfos.begin(), fileInfos.end(), MimesAppsManager::lessByDateTime); + +// foreach (QFileInfo info, fileInfos) { +// orderApps.append(info.absoluteFilePath()); +// } +// }else{ +// orderApps.append(apps.toList()); +// } +// MimesAppsManager::MimeApps.insert(key, orderApps); +// } + +// foreach (QString desktopFile, MimesAppsManager::DesktopObjs.keys()) { +// QString iconName = MimesAppsManager::DesktopObjs.value(desktopFile).getIcon(); +// fileIconProvider->getDesktopIcon(iconName, 48); +// } + +} + +void MimeAppsWorker::updateCache() +{ + MimesAppsManager::initMimeTypeApps(); +} + +void MimeAppsWorker::writeData(const QString &path, const QByteArray &content) +{ + qDebug() << path; + QFile file(path); + if (file.open(QFile::WriteOnly)){ + file.write(content); + } + file.close(); +} + +QByteArray MimeAppsWorker::readData(const QString &path) +{ + QFile file(path); + if(!file.open(QFile::ReadOnly)) + { + qDebug() << path << "isn't exists!"; + } + QByteArray content = file.readAll(); + file.close(); + return content; +} + + +MimesAppsManager::MimesAppsManager(QObject *parent): QObject(parent) +{ + m_mimeAppsWorker = new MimeAppsWorker; + connect(this, &MimesAppsManager::requestUpdateCache, m_mimeAppsWorker, &MimeAppsWorker::updateCache); + QThread* mimeAppsThread = new QThread; + m_mimeAppsWorker->moveToThread(mimeAppsThread); + mimeAppsThread->start(); +} + +MimesAppsManager::~MimesAppsManager() +{ + +} + +QMimeType MimesAppsManager::getMimeType(const QString &fileName) +{ + DMimeDatabase db; + QMimeType mimeType = db.mimeTypeForFile(fileName); + return mimeType; +} + +QString MimesAppsManager::getMimeTypeByFileName(const QString &fileName) +{ + DMimeDatabase db; + QMimeType mimeType = db.mimeTypeForFile(fileName); + return mimeType.name(); +} + + +QString MimesAppsManager::getDefaultAppByFileName(const QString& fileName){ + DMimeDatabase db; + QMimeType mimeType = db.mimeTypeForFile(fileName); + return getDefaultAppByMimeType(mimeType); +} + +QString MimesAppsManager::getDefaultAppByMimeType(const QMimeType &mimeType) +{ + return getDefaultAppByMimeType(mimeType.name()); +} + +QString MimesAppsManager::getDefaultAppByMimeType(const QString &mimeType) +{ + GAppInfo* defaultApp = g_app_info_get_default_for_type(mimeType.toLocal8Bit().constData(), FALSE); + QString url = ""; + if(defaultApp){ + url = g_app_info_get_id(defaultApp); + } + return url; +} + +QString MimesAppsManager::getDefaultAppDisplayNameByMimeType(const QMimeType &mimeType) +{ + return getDefaultAppDisplayNameByGio(mimeType.name()); +} + +QString MimesAppsManager::getDefaultAppDisplayNameByGio(const QString &mimeType) +{ + /* + * + * We have the appsForMimeList. Now we need to filter some applications out as per user's choice and get the default value + * First check mimeapps.list/[Default Associations], then mimeapps.list/[Added Associations]. The entry corresponding to the mimetype in + * the first case and the first entry in the second case are the user defaults. + * If the mimetype is not listed, then check mimeinfo.cache + * Do the same for /usr/local/share/applications and /usr/share/applications + * + */ + + GAppInfo* defaultApp = g_app_info_get_default_for_type(mimeType.toLocal8Bit().constData(), FALSE); + QString appDisplayName = ""; + if(defaultApp){ + appDisplayName = g_app_info_get_name(defaultApp); + } + g_object_unref(defaultApp); + return appDisplayName; +} + +QString MimesAppsManager::getDefaultAppDesktopFileByMimeType(const QString &mimeType) +{ + GAppInfo* defaultApp = g_app_info_get_default_for_type(mimeType.toLocal8Bit().constData(), FALSE); + if(!defaultApp) + return ""; + + const char* desktop_id = g_app_info_get_id(defaultApp); + GDesktopAppInfo* desktopAppInfo = g_desktop_app_info_new(desktop_id); + if(!desktopAppInfo) + return ""; + QString desktopFile = g_desktop_app_info_get_filename(desktopAppInfo); + + g_object_unref(defaultApp); + g_object_unref(desktopAppInfo); + + return desktopFile; +} + +bool MimesAppsManager::setDefautlAppForTypeByGio(const QString &mimeType, const QString &appPath) +{ + GAppInfo* app = NULL; + GList* apps = NULL; + apps = g_app_info_get_all(); + + GList* iterator = apps; + + while (iterator) { + const char* desktop_id = g_app_info_get_id((GAppInfo*)iterator->data); + GDesktopAppInfo* desktopAppInfo = g_desktop_app_info_new(desktop_id); + + if (desktopAppInfo) { + if (appPath == g_desktop_app_info_get_filename(desktopAppInfo)) { + app = (GAppInfo*)iterator->data; + g_object_unref(desktopAppInfo); + break; + } + + g_object_unref(desktopAppInfo); + } + + if (appPath.endsWith("/" + QString::fromLocal8Bit(desktop_id))) { + app = (GAppInfo*)iterator->data; + break; + } + + iterator = iterator->next; + } + + g_list_free(apps); + + if (!app) { + qWarning() << "no app found name as:" << appPath; + return false; + } + + GError* error = NULL; + //如果是xml类型的文件,需要同时设置application/xml和text/xml字段 + if (mimeType == "application/xml") { + QString spMimeType = "text/xml"; + g_app_info_set_as_default_for_type(app, + spMimeType.toLocal8Bit().constData(), + &error); + } + g_app_info_set_as_default_for_type(app, + mimeType.toLocal8Bit().constData(), + &error); + if (error) { + qDebug () << "fail to set default app for type:" << error->message; + g_free(error); + return false; + } + + return true; +} + +QStringList MimesAppsManager::getRecommendedApps(const DUrl &url) +{ + if (!url.isValid()) { + return QStringList(); + } + QStringList recommendedApps; + QString mimeType; + + DAbstractFileInfoPointer info = fileService->createFileInfo(nullptr, url); + mimeType = info->mimeType().name(); + + QMimeDatabase db; + + recommendedApps = getRecommendedAppsByQio(db.mimeTypeForName(mimeType)); + + //use mime white list to find apps first of all +// if(recommendedApps.isEmpty() && info) { +// recommendedApps = getrecommendedAppsFromMimeWhiteList(info->fileUrl()); +// } + QString custom_app("%1/%2-custom-open-%3.desktop"); + QString default_app = getDefaultAppByMimeType(mimeType); + + custom_app = custom_app.arg(QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)).arg(qApp->applicationName()).arg(mimeType.replace("/", "-")); + + if (QFile::exists(custom_app)) { + MimesAppsManager::removeOneDupFromList(recommendedApps, custom_app); + recommendedApps.append(custom_app); + } + + GDesktopAppInfo *desktopAppInfo = g_desktop_app_info_new(default_app.toLocal8Bit().constData()); + + if (desktopAppInfo) { + default_app = QString::fromLocal8Bit(g_desktop_app_info_get_filename(desktopAppInfo)); + g_object_unref(desktopAppInfo); + MimesAppsManager::removeOneDupFromList(recommendedApps, default_app); + recommendedApps.prepend(default_app); + } + + return recommendedApps; +} + +QStringList MimesAppsManager::getRecommendedAppsByQio(const QMimeType &mimeType) +{ + QStringList recommendApps; + QList mimeTypeList; + QMimeDatabase mimeDatabase; + + mimeTypeList.append(mimeType); + + while (recommendApps.isEmpty()) { + for (const QMimeType &type : mimeTypeList) { + QStringList type_name_list; + + type_name_list.append(type.name()); + type_name_list.append(type.aliases()); + + foreach (const QString &name, type_name_list) { + foreach (const QString &app, mimeAppsManager->MimeApps.value(name)) { + bool app_exist = false; + + for (const QString &other : recommendApps) { + const DesktopFile &app_desktop = mimeAppsManager->DesktopObjs.value(app); + const DesktopFile &other_desktop = mimeAppsManager->DesktopObjs.value(other); + + if (app_desktop.getExec() == other_desktop.getExec() && app_desktop.getLocalName() == other_desktop.getLocalName()) { + app_exist = true; + break; + } + } + + // if desktop file was not existed do not recommend!! + if (!QFileInfo::exists(app)) { + qWarning() << app << "not exist anymore"; + continue; + } + + if (!app_exist) + recommendApps.append(app); + } + } + } + + if (!recommendApps.isEmpty()) + break; + + QList newMimeTypeList; + + for (const QMimeType &type : mimeTypeList) { + for (const QString &name : type.parentMimeTypes()) + newMimeTypeList.append(mimeDatabase.mimeTypeForName(name)); + } + + mimeTypeList = newMimeTypeList; + + if (mimeTypeList.isEmpty()) + break; + } + + return recommendApps; +} + +QStringList MimesAppsManager::getRecommendedAppsByGio(const QString &mimeType) +{ + QStringList recommendApps; + GList* recomendAppInfoList = g_app_info_get_recommended_for_type(mimeType.toLocal8Bit().constData()); + GList* iterator = recomendAppInfoList; + + while(iterator){ + GAppInfo* appInfo = (GAppInfo*)iterator->data; + if(appInfo){ + const char* desktopId = g_app_info_get_id(appInfo); + + GDesktopAppInfo* dekstopAppInfo = g_desktop_app_info_new(desktopId); + QString app = g_desktop_app_info_get_filename(dekstopAppInfo); + + recommendApps << app; + g_object_unref(dekstopAppInfo); + } + iterator = iterator->next; + } + g_list_free(recomendAppInfoList); + return recommendApps; +} + +QStringList MimesAppsManager::getrecommendedAppsFromMimeWhiteList(const DUrl &url) +{ + const DAbstractFileInfoPointer& info = fileService->createFileInfo(Q_NULLPTR, url); + QString aliasMimeType = info->mimeTypeName(); + QStringList recommendedApps; + QString mimeAssociationsFile = QString("%1/%2/%3").arg(DFMStandardPaths::location(DFMStandardPaths::ApplicationSharePath), + "mimetypeassociations", + "mimetypeassociations.json"); + QFile file(mimeAssociationsFile); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug () << "could not open file :" << mimeAssociationsFile << ", error:" << file.errorString(); + return recommendedApps; + } + const QByteArray data = file.readAll(); + file.close(); + + QJsonParseError* jsonPaserError = NULL; + QJsonDocument jsonDoc = QJsonDocument::fromJson(data, jsonPaserError); + if(jsonPaserError){ + qDebug () << "json file paser error:" << jsonPaserError->errorString(); + return recommendedApps; + } + QJsonObject obj = jsonDoc.object(); + + if(obj.contains("associations")){ + QJsonArray mimesArr = obj.value("associations").toArray(); + foreach (const QJsonValue& mime, mimesArr) { + if(mime.toObject().contains(info->mimeTypeName())){ + aliasMimeType = mime.toObject().value(info->mimeTypeName()).toString(); + recommendedApps = getRecommendedAppsByGio(aliasMimeType); + } + } + } + + return recommendedApps; +} + +QStringList MimesAppsManager::getApplicationsFolders() +{ + QStringList desktopFolders; + desktopFolders << QString("/usr/share/applications/") + << QString("/usr/local/share/applications/") + << QString("/usr/share/gnome/applications/") + << QString("/var/lib/flatpak/exports/share/applications") + << QDir::homePath() + QString("/.local/share/flatpak/exports/share/applications") + << QDir::homePath() + QString( "/.local/share/applications" ); + return desktopFolders; +} + +QString MimesAppsManager::getMimeAppsCacheFile() +{ + return QString("%1/%2").arg(DFMStandardPaths::location(DFMStandardPaths::CachePath), "MimeApps.json"); +} + +QString MimesAppsManager::getMimeInfoCacheFilePath() +{ + return "/usr/share/applications/mimeinfo.cache"; +} + +QString MimesAppsManager::getMimeInfoCacheFileRootPath() +{ + return "/usr/share/applications"; +} + +QString MimesAppsManager::getDesktopFilesCacheFile() +{ + return QString("%1/%2").arg(DFMStandardPaths::location(DFMStandardPaths::CachePath), "DesktopFiles.json"); +} + +QString MimesAppsManager::getDesktopIconsCacheFile() +{ + return QString("%1/%2").arg(DFMStandardPaths::location(DFMStandardPaths::CachePath), "DesktopIcons.json"); +} + +QStringList MimesAppsManager::getDesktopFiles() +{ + QStringList desktopFiles; + + foreach (QString desktopFolder, getApplicationsFolders()) { + QDirIterator it(desktopFolder, QStringList("*.desktop"), + QDir::Files | QDir::NoDotAndDotDot, + QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + desktopFiles.append(it.filePath()); + } + } + return desktopFiles; +} + +QString MimesAppsManager::getDDEMimeTypeFile() +{ + return QString("%1/%2/%3").arg(getMimeInfoCacheFileRootPath(), "deepin", "dde-mimetype.list"); +} + +QMap MimesAppsManager::getDesktopObjs() +{ + QMap desktopObjs; + foreach (QString f, getApplicationsFolders()) { + desktopObjs.insert(f, DesktopFile(f)); + } + return desktopObjs; +} + +void MimesAppsManager::initMimeTypeApps() +{ + qDebug() << "getMimeTypeApps in" << QThread::currentThread() << qApp->thread(); + DesktopFiles.clear(); + DesktopObjs.clear(); + DDE_MimeTypes.clear(); + + QMap> mimeAppsSet; + loadDDEMimeTypes(); + foreach (QString desktopFolder, getApplicationsFolders()) { + QDirIterator it(desktopFolder, QStringList("*.desktop"), + QDir::Files | QDir::NoDotAndDotDot, + QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + QString filePath = it.filePath(); + DesktopFile desktopFile(filePath); + DesktopFiles.append(filePath); + DesktopObjs.insert(filePath, desktopFile); + QStringList mimeTypes = desktopFile.getMimeType(); + QString fileName = QFileInfo(filePath).fileName(); + if (DDE_MimeTypes.contains(fileName)){ + mimeTypes.append(DDE_MimeTypes.value(fileName)); + } + + foreach (QString mimeType, mimeTypes) { + if (!mimeType.isEmpty()){ + QSet apps; + if (mimeAppsSet.contains(mimeType)){ + apps = mimeAppsSet.value(mimeType); + apps.insert(filePath); + }else{ + apps.insert(filePath); + } + mimeAppsSet.insert(mimeType, apps); + } + } + } + } + + foreach (QString key, mimeAppsSet.keys()) { + QSet apps = mimeAppsSet.value(key); + QStringList orderApps; + if (apps.count() > 1){ + QFileInfoList fileInfos; + foreach (QString app, apps) { + QFileInfo info(app); + fileInfos.append(info); + } + + std::sort(fileInfos.begin(), fileInfos.end(), MimesAppsManager::lessByDateTime); + + foreach (QFileInfo info, fileInfos) { + orderApps.append(info.absoluteFilePath()); + } + }else{ + orderApps.append(apps.toList()); + } + MimeApps.insert(key, orderApps); + } + + //check mime apps from cache + QFile f(getMimeInfoCacheFilePath()); + if(!f.open(QIODevice::ReadOnly)){ + qDebug () << "failed to read mime info cache file:" << f.errorString(); + return; + } + + QStringList audioDesktopList; + QStringList imageDeksopList; + QStringList textDekstopList; + QStringList videoDesktopList; + + while (!f.atEnd()) { + QString data = f.readLine(); + QString _desktops = data.split("=").last(); + QString mimeType = data.split("=").first(); + QStringList desktops = _desktops.split(";"); + + foreach (const QString desktop, desktops) { + if(desktop.isEmpty() || audioDesktopList.contains(desktop)) + continue; + + if(mimeType.startsWith("audio")){ + if(!audioDesktopList.contains(desktop)) + audioDesktopList << desktop; + } else if(mimeType.startsWith("image")){ + if(!imageDeksopList.contains(desktop)) + imageDeksopList << desktop; + } else if(mimeType.startsWith("text")){ + if(!textDekstopList.contains(desktop)) + textDekstopList << desktop; + } else if(mimeType.startsWith("video")){ + if(!videoDesktopList.contains(desktop)) + videoDesktopList << desktop; + } + } + } + f.close(); + + const QString mimeInfoCacheRootPath = getMimeInfoCacheFileRootPath(); + foreach (QString desktop, audioDesktopList) { + const QString path = QString("%1/%2").arg(mimeInfoCacheRootPath,desktop); + if(!QFile::exists(path)) + continue; + DesktopFile df(path); + AudioMimeApps.insert(path, df); + } + + foreach (QString desktop, imageDeksopList) { + const QString path = QString("%1/%2").arg(mimeInfoCacheRootPath,desktop); + if(!QFile::exists(path)) + continue; + DesktopFile df(path); + ImageMimeApps.insert(path, df); + } + + foreach (QString desktop, textDekstopList) { + const QString path = QString("%1/%2").arg(mimeInfoCacheRootPath,desktop); + if(!QFile::exists(path)) + continue; + DesktopFile df(path); + TextMimeApps.insert(path, df); + } + + foreach (QString desktop, videoDesktopList) { + const QString path = QString("%1/%2").arg(mimeInfoCacheRootPath,desktop); + if(!QFile::exists(path)) + continue; + DesktopFile df(path); + VideoMimeApps.insert(path, df); + } + + return; +} + +void MimesAppsManager::loadDDEMimeTypes() +{ + QSettings settings(getDDEMimeTypeFile(), QSettings::IniFormat); + qDebug() << settings.childGroups(); + + QFile file(getDDEMimeTypeFile()); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + return; + } + + // Read propeties + QTextStream in(&file); + QString desktopKey; + while (!in.atEnd()) { + + // Read new line + QString line = in.readLine(); + + // Skip empty line or line with invalid format + if (line.trimmed().isEmpty()) { + continue; + } + + // Read group + // NOTE: symbols '[' and ']' can be found not only in group names, but + // only group can start with '[' + + if (line.trimmed().startsWith("[") && line.trimmed().endsWith("]")) { + QString tmp = line.trimmed().replace("[", "").replace("]", ""); + desktopKey = tmp; + continue; + } + + // If we are in correct group and line contains assignment then read data + int first_equal = line.indexOf('='); + if (!desktopKey.isEmpty() && first_equal >= 0) { + QString value = line.mid(first_equal + 1); + QStringList mimetypes = value.split(";"); + DDE_MimeTypes.insert(desktopKey, mimetypes); + desktopKey.clear(); + } + } + file.close(); +} + +bool MimesAppsManager::lessByDateTime(const QFileInfo &f1, const QFileInfo &f2) +{ + return f1.created() < f2.created(); +} + +bool MimesAppsManager::removeOneDupFromList(QStringList &list, const QString desktopFilePath) +{ + if (list.removeOne(desktopFilePath)) { + return true; + } + + const DesktopFile target(desktopFilePath); + + QMutableStringListIterator iter(list); + while (iter.hasNext()) { + const DesktopFile source(iter.next()); + + if (source.getExec() == target.getExec() && source.getLocalName() == target.getLocalName()) { + iter.remove(); + return true; + } + } + + return false; +} + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/mimesappsmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/mimesappsmanager.h new file mode 100644 index 0000000..a6a0af7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/mimesappsmanager.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef MIMESAPPSMANAGER_H +#define MIMESAPPSMANAGER_H + + +#include +#include +#include +#include +#include +#include +#include +#include "desktopfile.h" +#include + +class DUrl; + +class MimeAppsWorker: public QObject +{ + Q_OBJECT + +public: + explicit MimeAppsWorker(QObject *parent = nullptr); + ~MimeAppsWorker(); + + void initConnect(); + +public slots: + void startWatch(); + void handleDirectoryChanged(const QString &filePath); + void handleFileChanged(const QString &filePath); + void updateCache(); + void writeData(const QString &path, const QByteArray &content); + QByteArray readData(const QString &path); + + +private: + QFileSystemWatcher *m_fileSystemWatcher = nullptr; + QTimer *m_updateCacheTimer; +}; + + +class MimesAppsManager: public QObject +{ + Q_OBJECT + +public: + explicit MimesAppsManager(QObject *parent = nullptr); + ~MimesAppsManager(); + + static QStringList DesktopFiles; + static QMap MimeApps; + static QMap DDE_MimeTypes; + //specially cache for video, image, text and audio + static QMap VideoMimeApps; + static QMap ImageMimeApps; + static QMap TextMimeApps; + static QMap AudioMimeApps; + static QMap DesktopObjs; + + static QMimeType getMimeType(const QString &fileName); + static QString getMimeTypeByFileName(const QString &fileName); + static QString getDefaultAppByFileName(const QString &fileName); + static QString getDefaultAppByMimeType(const QMimeType &mimeType); + static QString getDefaultAppByMimeType(const QString &mimeType); + static QString getDefaultAppDisplayNameByMimeType(const QMimeType &mimeType); + static QString getDefaultAppDisplayNameByGio(const QString &mimeType); + static QString getDefaultAppDesktopFileByMimeType(const QString &mimeType); + + static bool setDefautlAppForTypeByGio(const QString &mimeType, + const QString &appPath); + + static QStringList getRecommendedApps(const DUrl &url); + static QStringList getRecommendedAppsByQio(const QMimeType &mimeType); + static QStringList getRecommendedAppsByGio(const QString &mimeType); + static QStringList getrecommendedAppsFromMimeWhiteList(const DUrl &url); + + + static QStringList getApplicationsFolders(); + static QString getMimeAppsCacheFile(); + static QString getMimeInfoCacheFilePath(); + static QString getMimeInfoCacheFileRootPath(); + static QString getDesktopFilesCacheFile(); + static QString getDesktopIconsCacheFile(); + static QStringList getDesktopFiles(); + static QString getDDEMimeTypeFile(); + static QMap getDesktopObjs(); + static void initMimeTypeApps(); + static void loadDDEMimeTypes(); + static bool lessByDateTime(const QFileInfo &f1, const QFileInfo &f2); + static bool removeOneDupFromList(QStringList &list, const QString desktopFilePath); + +signals: + void requestUpdateCache(); + +private: + MimeAppsWorker *m_mimeAppsWorker = nullptr; + +}; + +#endif // MIMESAPPSMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/mimetypedisplaymanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/mimetypedisplaymanager.cpp new file mode 100644 index 0000000..b6d32ed --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/mimetypedisplaymanager.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "mimetypedisplaymanager.h" +#include +#include +#include +#include "dfmstandardpaths.h" + +QStringList MimeTypeDisplayManager::ArchiveMimeTypes; +QStringList MimeTypeDisplayManager::TextMimeTypes; +QStringList MimeTypeDisplayManager::VideoMimeTypes; +QStringList MimeTypeDisplayManager::AudioMimeTypes; +QStringList MimeTypeDisplayManager::ImageMimeTypes; +QStringList MimeTypeDisplayManager::ExecutableMimeTypes; +QStringList MimeTypeDisplayManager::BackupMimeTypes; + + +MimeTypeDisplayManager::MimeTypeDisplayManager(QObject *parent) : QObject(parent) +{ + initData(); + initConnect(); +} + +MimeTypeDisplayManager::~MimeTypeDisplayManager() +{ + +} + +void MimeTypeDisplayManager::initData() +{ + m_displayNames[FileType::Directory] = tr("Directory"); + m_displayNames[FileType::DesktopApplication] = tr("Application"); + m_displayNames[FileType::Videos] = tr("Video"); + m_displayNames[FileType::Audios] = tr("Audio"); + m_displayNames[FileType::Images] = tr("Image"); + m_displayNames[FileType::Archives] = tr("Archive"); + m_displayNames[FileType::Documents] = tr("Text"); + m_displayNames[FileType::Executable] = tr("Executable"); + m_displayNames[FileType::Backups] = tr("Backup file"); + m_displayNames[FileType::Unknown] = tr("Unknown"); + + + m_defaultIconNames[FileType::Directory] = "folder"; + m_defaultIconNames[FileType::DesktopApplication] = "application-default-icon"; + m_defaultIconNames[FileType::Videos] = "video"; + m_defaultIconNames[FileType::Audios] = "music"; + m_defaultIconNames[FileType::Images] = "image"; + m_defaultIconNames[FileType::Archives] = "application-x-archive"; + m_defaultIconNames[FileType::Documents] = "text-plain"; + m_defaultIconNames[FileType::Executable] = "application-x-executable"; + m_defaultIconNames[FileType::Backups] = "application-x-archive"; // generic backup file icon? + m_defaultIconNames[FileType::Unknown] = "application-default-icon"; + + loadSupportMimeTypes(); +} + +void MimeTypeDisplayManager::initConnect() +{ + +} + +QString MimeTypeDisplayManager::displayName(const QString &mimeType) +{ +#ifdef QT_DEBUG + return m_displayNames.value(displayNameToEnum(mimeType)) + " (" + mimeType + ")"; +#endif // Q_DEBUG + return m_displayNames.value(displayNameToEnum(mimeType)); +} + +DAbstractFileInfo::FileType MimeTypeDisplayManager::displayNameToEnum(const QString &mimeType) +{ + if (mimeType == "application/x-desktop") { + return FileType::DesktopApplication; + } else if (mimeType == "inode/directory") { + return FileType::Directory; + } else if (mimeType == "application/x-executable" || ExecutableMimeTypes.contains(mimeType)) { + return FileType::Executable; + } else if (mimeType.startsWith("video/") || VideoMimeTypes.contains(mimeType)) { + return FileType::Videos; + } else if (mimeType.startsWith("audio/") || AudioMimeTypes.contains(mimeType)) { + return FileType::Audios; + } else if (mimeType.startsWith("image/") || ImageMimeTypes.contains(mimeType)) { + return FileType::Images; + } else if (mimeType.startsWith("text/") || TextMimeTypes.contains(mimeType)) { + return FileType::Documents; + } else if (ArchiveMimeTypes.contains(mimeType)) { + return FileType::Archives; + } else if (BackupMimeTypes.contains(mimeType)) { + return FileType::Backups; + } else { + return FileType::Unknown; + } +} + +QString MimeTypeDisplayManager::defaultIcon(const QString &mimeType) +{ + return m_defaultIconNames.value(displayNameToEnum(mimeType)); +} + +QMap MimeTypeDisplayManager::displayNames() +{ + return m_displayNames; +} + +QStringList MimeTypeDisplayManager::readlines(const QString &path) +{ + QStringList result; + QFile file(path); + if (!file.open(QIODevice::ReadOnly)) { + return result; + } + QTextStream in(&file); + while (!in.atEnd()) { + // Read new line + QString line = in.readLine(); + // Skip empty line or line with invalid format + if (line.trimmed().isEmpty()) { + continue; + } + result.append(line.trimmed()); + } + file.close(); + return result; +} + +void MimeTypeDisplayManager::loadSupportMimeTypes() +{ + QString textPath = QString("%1/%2").arg(DFMStandardPaths::location(DFMStandardPaths::MimeTypePath), "text.mimetype"); + QString archivePath = QString("%1/%2").arg(DFMStandardPaths::location(DFMStandardPaths::MimeTypePath), "archive.mimetype"); + QString videoPath = QString("%1/%2").arg(DFMStandardPaths::location(DFMStandardPaths::MimeTypePath), "video.mimetype"); + QString audioPath = QString("%1/%2").arg(DFMStandardPaths::location(DFMStandardPaths::MimeTypePath), "audio.mimetype"); + QString imagePath = QString("%1/%2").arg(DFMStandardPaths::location(DFMStandardPaths::MimeTypePath), "image.mimetype"); + QString executablePath = QString("%1/%2").arg(DFMStandardPaths::location(DFMStandardPaths::MimeTypePath), "executable.mimetype"); + QString backupPath = QString("%1/%2").arg(DFMStandardPaths::location(DFMStandardPaths::MimeTypePath), "backup.mimetype"); + TextMimeTypes = readlines(textPath); + ArchiveMimeTypes = readlines(archivePath); + VideoMimeTypes = readlines(videoPath); + AudioMimeTypes = readlines(audioPath); + ImageMimeTypes = readlines(imagePath); + ExecutableMimeTypes = readlines(executablePath); + BackupMimeTypes = readlines(backupPath); +} + +QStringList MimeTypeDisplayManager::supportArchiveMimetypes() +{ + return ArchiveMimeTypes; +} + +QStringList MimeTypeDisplayManager::supportVideoMimeTypes() +{ + return VideoMimeTypes; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/mimetypedisplaymanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/mimetypedisplaymanager.h new file mode 100644 index 0000000..f51a1df --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/mimetypedisplaymanager.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef MIMETYPEDISPLAYMANAGER_H +#define MIMETYPEDISPLAYMANAGER_H + +#include +#include + +#include "dabstractfileinfo.h" + +class MimeTypeDisplayManager : public QObject +{ + Q_OBJECT + +public: + + typedef DAbstractFileInfo::FileType FileType; + + explicit MimeTypeDisplayManager(QObject *parent = nullptr); + ~MimeTypeDisplayManager(); + + void initData(); + void initConnect(); + + QString displayName(const QString& mimeType); + FileType displayNameToEnum(const QString& mimeType); + QString defaultIcon(const QString& mimeType); + + QMap displayNames(); + static QStringList readlines(const QString& path); + static void loadSupportMimeTypes(); + static QStringList supportArchiveMimetypes(); + static QStringList supportVideoMimeTypes(); + +private: + QMap m_displayNames; + QMap m_defaultIconNames; + static QStringList ArchiveMimeTypes; + static QStringList AvfsBlackList; + static QStringList TextMimeTypes; + static QStringList VideoMimeTypes; + static QStringList AudioMimeTypes; + static QStringList ImageMimeTypes; + static QStringList ExecutableMimeTypes; + static QStringList BackupMimeTypes; + + bool m_supportLoaded = false; +}; + +#endif // MIMETYPEDISPLAYMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/properties.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/properties.cpp new file mode 100644 index 0000000..9b8ed12 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/properties.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "properties.h" + +#include +#include +#include +#include + +/** + * @brief Creates properties + * @param fileName + * @param group + */ +Properties::Properties(const QString &fileName, const QString &group) +{ + if (!fileName.isEmpty()) { + load(fileName, group); + } +} +//--------------------------------------------------------------------------- + +/** + * @brief Creates properties + * @param other properies + */ +Properties::Properties(const Properties &other) + : data(other.data) +{ + +} +//--------------------------------------------------------------------------- + + +/** + * @brief Loads property file + * @param fileName + * @param group + * @return true if load was successful + */ +bool Properties::load(const QString &fileName, const QString &group) +{ + + // NOTE: This class is used for reading of property files instead of QSettings + // class, which considers separator ';' as comment + + // Try open file + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + return false; + } + + // Clear old data + data.clear(); + + // Indicator whether group was found or not, if name of group was not + // specified, groupFound is always true + bool groupFound = group.isEmpty(); + + // Read propeties + QTextStream in(&file); + while (!in.atEnd()) { + + // Read new line + QString line = in.readLine(); + + // Skip empty line or line with invalid format + if (line.trimmed().isEmpty()) { + continue; + } + + // Read group + // NOTE: symbols '[' and ']' can be found not only in group names, but + // only group can start with '[' + if (!group.isEmpty() && line.trimmed().startsWith("[")) { + QString tmp = line.trimmed().replace("[", "").replace("]", ""); + groupFound = group.trimmed().compare(tmp) == 0; + } + + // If we are in correct group and line contains assignment then read data + int first_equal = line.indexOf('='); + + if (groupFound && first_equal >= 0) { + data.insert(line.left(first_equal).trimmed(), line.mid(first_equal + 1).trimmed()); + } + } + file.close(); + + return true; +} +//--------------------------------------------------------------------------- + +/** + * @brief Saves properties to file + * @param fileName + * @param group + * @return true if success + */ +bool Properties::save(const QString &fileName, const QString &group) +{ + + // Try open file + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + return false; + } + + // Write group + QTextStream out(&file); + if (!group.isEmpty()) { + out << "[" + group + "]\n"; + } + + // Write data + foreach (QString key, data.keys()) { + out << key << "=" << data.value(key).toString() << "\n"; + } + + // Exit + file.close(); + return true; +} +//--------------------------------------------------------------------------- + +/** + * @brief Returns true if property with given key is present in properties + * @param key + * @return true if property with given key is present in properties + */ +bool Properties::contains(const QString &key) const +{ + return data.contains(key); +} +//--------------------------------------------------------------------------- + +/** + * @brief Returns value + * @param key + * @param defaultValue + * @return value + */ +QVariant Properties::value(const QString &key, const QVariant &defaultValue) +{ + return data.value(key, defaultValue); +} +//--------------------------------------------------------------------------- + +/** + * @brief Sets value to properties + * @param key + * @param value + */ +void Properties::set(const QString &key, const QVariant &value) +{ + if (data.contains(key)) { + data.take(key); + } + data.insert(key, value); +} +//--------------------------------------------------------------------------- + +/** + * @brief Returns keys (names of properties) + * @param key + * @param value + */ +QStringList Properties::getKeys() const +{ + return data.keys(); +} +//--------------------------------------------------------------------------- diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/properties.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/properties.h new file mode 100644 index 0000000..bdc7642 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/properties.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef PROPERTIES_H +#define PROPERTIES_H + +#include +#include +#include + +/** + * @class Properties + * @brief Read property files + * @author Michal Rost + * @date 26.1.2013 + */ +class Properties { +public: + explicit Properties(const QString &fileName = "", const QString &group = ""); + explicit Properties(const Properties &other); + QVariant value(const QString &key, const QVariant &defaultValue = QVariant()); + bool load(const QString &fileName, const QString &group = ""); + bool save(const QString &fileName, const QString &group = ""); + void set(const QString &key, const QVariant &value); + bool contains(const QString &key) const; + QStringList getKeys() const; +protected: + QMap data; +}; + +#endif // PROPERTIES_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/shortcut.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/shortcut.cpp new file mode 100644 index 0000000..b2801e6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/shortcut.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#include "shortcut.h" + +Shortcut::Shortcut(QObject *parent) : QObject(parent) +{ + ShortcutGroup group1; + ShortcutGroup group2; + ShortcutGroup group3; + ShortcutGroup group4; + ShortcutGroup group5; + group1.groupName = tr("Item"); + group1.groupItems << ShortcutItem(tr("Select to the first item"),tr("Shift + Home ")) + << ShortcutItem(tr("Select to the last item"),tr("Shift + End ")) + << ShortcutItem(tr("Select leftwards"),tr("Shift + Left ")) + << ShortcutItem(tr("Select rightwards"),tr("Shift + Right ")) + << ShortcutItem(tr("Select to upper row"),tr("Shift + Up ")) + << ShortcutItem(tr("Select to lower row"),tr("Shift + Down ")) + << ShortcutItem(tr("Open"),tr("Ctrl + Down ")) + << ShortcutItem(tr("To parent directory"),tr("Ctrl + Up ")) + << ShortcutItem(tr("Permanently delete"),tr("Shift + Delete ")) + << ShortcutItem(tr("Delete file"),tr("Delete")) + << ShortcutItem(tr("Select all"),tr("Ctrl + A ")) + << ShortcutItem(tr("Copy"),tr("Ctrl + C ")) + << ShortcutItem(tr("Cut"),tr("Ctrl + X ")) + << ShortcutItem(tr("Paste"),tr("Ctrl + V ")) + << ShortcutItem(tr("Rename"),tr("F2 ")); + group2.groupName = tr("New/Search"); + group2.groupItems << ShortcutItem(tr("New window"),tr("Ctrl + N ")) + << ShortcutItem(tr("New folder"),tr("Ctrl + Shift + N ")) + << ShortcutItem(tr("Search"),tr("Ctrl + F")) + << ShortcutItem(tr("New tab"),tr("Ctrl + T ")); + group3.groupName = tr("View"); + group3.groupItems << ShortcutItem(tr("Item information"),tr("Ctrl + I ")) + << ShortcutItem(tr("Help"),tr("F1 ")) + << ShortcutItem(tr("Keyboard shortcuts"),tr("Ctrl + Shift + / ")); + group4.groupName = tr("Switch display status"); + group4.groupItems << ShortcutItem(tr("Hide item"),tr("Ctrl + H ")) + << ShortcutItem(tr("Input in address bar"),tr("Ctrl + L ")) + << ShortcutItem(tr("Switch to icon view"),tr("Ctrl + 1 ")) + << ShortcutItem(tr("Switch to list view"),tr("Ctrl + 2 ")); + group5.groupName = tr("Others"); + group5.groupItems << ShortcutItem(tr("Close"),tr("Alt + F4 ")) + << ShortcutItem(tr("Close current tab"), tr("Ctrl + W")) + << ShortcutItem(tr("Back"),tr("Alt + Left ")) + << ShortcutItem(tr("Forward"),tr("Alt + Right ")) + << ShortcutItem(tr("Switch to next tab"),tr("Ctrl + Tab ")) + << ShortcutItem(tr("Switch to previous tab"),tr("Ctrl + Shift + Tab ")) + << ShortcutItem(tr("Next file"),tr("Tab ")) + << ShortcutItem(tr("Previous file"),tr("Shift + Tab ")) + << ShortcutItem(tr("Switch tab by specified number between 1 to 8"),tr("Alt + [1-8] ")); + + m_shortcutGroups << group1 << group2 << group3 << group4 << group5; + + //convert to json object + QJsonArray jsonGroups; + for(auto scg:m_shortcutGroups){ + QJsonObject jsonGroup; + jsonGroup.insert("groupName",scg.groupName); + QJsonArray jsonGroupItems; + for(auto sci:scg.groupItems){ + QJsonObject jsonItem; + jsonItem.insert("name",sci.name); + jsonItem.insert("value",sci.value); + jsonGroupItems.append(jsonItem); + } + jsonGroup.insert("groupItems",jsonGroupItems); + jsonGroups.append(jsonGroup); + } + m_shortcutObj.insert("shortcut",jsonGroups); +} +QString Shortcut::toStr(){ + QJsonDocument doc(m_shortcutObj); + return doc.toJson().data(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/shortcut.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/shortcut.h new file mode 100644 index 0000000..f6d5786 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/shutil/shortcut.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: max-lv + * + * Maintainer: dengkeyun + * xushitong + * zhangsheng + * + * 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 + * 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 . + */ + +#ifndef SHORTCUT_H +#define SHORTCUT_H + +#include +#include +#include +#include +struct ShortcutItem{ + QString name; + QString value; + ShortcutItem(QString n,QString v):name(n),value(v){} +}; + +struct ShortcutGroup{ + QString groupName; + QList groupItems; +}; + +class Shortcut : public QObject +{ + Q_OBJECT +public: + explicit Shortcut(QObject *parent = 0); + QString toStr(); + +signals: + +public slots: +private: + QJsonObject m_shortcutObj; + QList m_shortcutGroups; +}; + +#endif // SHORTCUT_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/filemanager.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/filemanager.qrc new file mode 100644 index 0000000..4fdbecb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/filemanager.qrc @@ -0,0 +1,363 @@ + + + qss/passwordAskDialog.qss + + + images/light/pencil_hover.svg + images/light/pencil_normal.svg + images/light/pencil_press.svg + images/light/select_deactive.png + images/Spinner/Spinner01.png + images/Spinner/Spinner02.png + images/Spinner/Spinner03.png + images/Spinner/Spinner04.png + images/Spinner/Spinner05.png + images/Spinner/Spinner06.png + images/Spinner/Spinner07.png + images/Spinner/Spinner08.png + images/Spinner/Spinner09.png + images/Spinner/Spinner10.png + images/Spinner/Spinner11.png + images/Spinner/Spinner12.png + images/Spinner/Spinner13.png + images/Spinner/Spinner14.png + images/Spinner/Spinner15.png + images/Spinner/Spinner16.png + images/Spinner/Spinner17.png + images/Spinner/Spinner18.png + images/Spinner/Spinner19.png + images/Spinner/Spinner20.png + images/Spinner/Spinner21.png + images/Spinner/Spinner22.png + images/Spinner/Spinner23.png + images/Spinner/Spinner24.png + images/Spinner/Spinner25.png + images/Spinner/Spinner26.png + images/Spinner/Spinner27.png + images/Spinner/Spinner28.png + images/Spinner/Spinner29.png + images/Spinner/Spinner30.png + images/Spinner/Spinner31.png + images/Spinner/Spinner32.png + images/Spinner/Spinner33.png + images/Spinner/Spinner34.png + images/Spinner/Spinner35.png + images/Spinner/Spinner36.png + images/Spinner/Spinner37.png + images/Spinner/Spinner38.png + images/Spinner/Spinner39.png + images/Spinner/Spinner40.png + images/Spinner/Spinner41.png + images/Spinner/Spinner42.png + images/Spinner/Spinner43.png + images/Spinner/Spinner44.png + images/Spinner/Spinner45.png + images/Spinner/Spinner46.png + images/Spinner/Spinner47.png + images/Spinner/Spinner48.png + images/Spinner/Spinner49.png + images/Spinner/Spinner50.png + images/Spinner/Spinner51.png + images/Spinner/Spinner52.png + images/Spinner/Spinner53.png + images/Spinner/Spinner54.png + images/Spinner/Spinner55.png + images/Spinner/Spinner56.png + images/Spinner/Spinner57.png + images/Spinner/Spinner58.png + images/Spinner/Spinner59.png + images/Spinner/Spinner60.png + images/Spinner/Spinner61.png + images/Spinner/Spinner62.png + images/Spinner/Spinner63.png + images/Spinner/Spinner64.png + images/Spinner/Spinner65.png + images/Spinner/Spinner66.png + images/Spinner/Spinner67.png + images/Spinner/Spinner68.png + images/Spinner/Spinner69.png + images/Spinner/Spinner70.png + images/Spinner/Spinner71.png + images/Spinner/Spinner72.png + images/Spinner/Spinner73.png + images/Spinner/Spinner74.png + images/Spinner/Spinner75.png + images/Spinner/Spinner76.png + images/Spinner/Spinner77.png + images/Spinner/Spinner78.png + images/Spinner/Spinner79.png + images/Spinner/Spinner80.png + images/Spinner/Spinner81.png + images/Spinner/Spinner82.png + images/Spinner/Spinner83.png + images/Spinner/Spinner84.png + images/Spinner/Spinner85.png + images/Spinner/Spinner86.png + images/Spinner/Spinner87.png + images/Spinner/Spinner88.png + images/Spinner/Spinner89.png + images/Spinner/Spinner90.png + images/link_large.png + images/link_small.png + images/lock_large.png + images/lock_small.png + images/application-x-shellscript.svg + images/share_large.png + images/share_small.png + images/light/select.png + images/light/space16.png + images/light/select@2x.png + + + images/icons/desktop_checked_16px.svg + images/icons/desktop_hover_16px.svg + images/icons/desktop_normal_16px.svg + images/icons/disk_checked_16px.svg + images/icons/disk_hover_16px.svg + images/icons/disk_normal_16px.svg + images/icons/documents_checked_16px.svg + images/icons/documents_hover_16px.svg + images/icons/documents_normal_16px.svg + images/icons/expanded_view_checked.svg + images/icons/expanded_view_hover.svg + images/icons/expanded_view_normal.svg + images/icons/file_checked_16px.svg + images/icons/file_hover_16px.svg + images/icons/file_normal_16px.svg + images/icons/hierarchical_view_checked.svg + images/icons/hierarchical_view_hover.svg + images/icons/hierarchical_view_normal.svg + images/icons/home_checked_16px.svg + images/icons/home_hover_16px.svg + images/icons/home_normal_16px.svg + images/icons/icon_view_checked.svg + images/icons/icon_view_hover.svg + images/icons/icon_view_normal.svg + images/icons/list_view_checked.svg + images/icons/list_view_hover.svg + images/icons/list_view_normal.svg + images/icons/music_checked_16px.svg + images/icons/music_hover_16px.svg + images/icons/music_normal_16px.svg + images/icons/phone_checked_16px.svg + images/icons/phone_hover_16px.svg + images/icons/phone_normal_16px.svg + images/icons/pictures_checked_16px.svg + images/icons/pictures_hover_16px.svg + images/icons/pictures_normal_16px.svg + images/icons/recent_checked_16px.svg + images/icons/recent_hover_16px.svg + images/icons/recent_normal_16px.svg + images/icons/trash_checked_16px.svg + images/icons/trash_hover_16px.svg + images/icons/trash_normal_16px.svg + images/icons/videos_checked_16px.svg + images/icons/videos_hover_16px.svg + images/icons/videos_normal_16px.svg + images/icons/close_hover.png + images/icons/close_normal.png + images/icons/close_press.png + images/icons/maximize_hover.png + images/icons/maximize_normal.png + images/icons/maximize_press.png + images/icons/menu_hover.png + images/icons/menu_normal.png + images/icons/menu_press.png + images/icons/minimise_hover.png + images/icons/minimise_normal.png + images/icons/minimise_press.png + images/icons/unmaximize_hover.png + images/icons/unmaximize_normal.png + images/icons/unmaximize_press.png + images/icons/backward_normal.png + images/icons/backward_press.png + images/icons/forward_normal.png + images/icons/forward_press.png + images/icons/bookmarks_checked_16px.svg + images/icons/bookmarks_hover_16px.svg + images/icons/bookmarks_normal_16px.svg + images/icons/favourite_normal.svg + images/icons/favourite_checked.svg + images/icons/favourite_hover.svg + images/icons/unmount_hover.svg + images/icons/unmount_normal.svg + images/icons/unmount_press.svg + images/icons/reordering_line.svg + images/icons/selectend.png + images/icons/selectstart.png + images/icons/android_checked_16px.svg + images/icons/android_hover_16px.svg + images/icons/android_normal_16px.svg + images/icons/dvd_checked_16px.svg + images/icons/dvd_hover_16px.svg + images/icons/dvd_normal_16px.svg + images/icons/iphone_checked_16px.svg + images/icons/iphone_hover_16px.svg + images/icons/iphone_normal_16px.svg + images/icons/network_checked_16px.svg + images/icons/network_hover_16px.svg + images/icons/network_normal_16px.svg + images/icons/usb_checked_16px.svg + images/icons/usb_hover_16px.svg + images/icons/usb_normal_16px.svg + images/icons/downloads_hover_16px.svg + images/icons/downloads_checked_16px.svg + images/icons/downloads_normal_16px.svg + images/icons/search_hover.svg + images/icons/search_normal.svg + images/icons/search_press.svg + images/icons/filter_hover.svg + images/icons/filter_normal.svg + images/icons/filter_active.svg + images/icons/icon_view_checked.png + images/icons/icon_view_hover.png + images/icons/icon_view_normal.png + images/icons/list_view_checked.png + images/icons/list_view_hover.png + images/icons/list_view_normal.png + images/icons/unmount_active.png + images/icons/unmount_hover.png + images/icons/unmount_normal.png + images/icons/unmount_press.png + images/icons/backward_hover.png + images/icons/forward_hover.png + images/icons/up.png + images/icons/down.png + images/icons/down_hover.png + images/icons/down_press.png + images/icons/up_hover.png + images/icons/up_press.png + images/icons/backward_disabled.png + images/icons/forward_disabled.png + images/icons/new_tab_disabled.png + images/icons/new_tab_press.png + images/icons/new_tab_hover.png + images/icons/new_tab_normal.png + images/icons/tab_close_hover.png + images/icons/tab_close_normal.png + images/icons/tab_close_press.png + images/icons/active_tab_close_hover.png + images/icons/active_tab_close_normal.png + images/icons/active_tab_close_press.png + images/icons/slider_handle.png + images/icons/usershare_checked_16px.svg + images/icons/usershare_hover_16px.svg + images/icons/usershare_normal_16px.svg + images/icons/input_clear_normal.svg + images/icons/input_clear_hover.svg + images/icons/input_clear_press.svg + images/icons/computer_checked_16px.svg + images/icons/computer_hover_16px.svg + images/icons/jump_to.svg + images/icons/search.svg + images/icons/empty_trash_press.png + images/icons/empty_trash_hover.png + images/icons/empty_trash_normal.png + images/icons/stop_press.png + images/icons/stop_normal.png + images/icons/stop_hover.png + images/icons/preview-dialog-close_round_press.png + images/icons/preview_dialog_close_round_hover.png + images/icons/preview-dialog-close_round_normal.png + images/icons/tab_close_hover@2x.png + images/icons/tab_close_normal@2x.png + images/icons/active_tab_close_normal@2x.png + images/icons/active_tab_close_hover@2x.png + images/icons/tab_close_press@2x.png + images/icons/active_tab_close_press@2x.png + images/icons/stop_hover@2x.png + images/icons/empty_trash_hover@2x.png + images/icons/empty_trash_normal@2x.png + images/icons/stop_press@2x.png + images/icons/empty_trash_press@2x.png + images/icons/stop_normal@2x.png + images/icons/backward_disabled@2x.png + images/icons/forward_disabled@2x.png + images/icons/backward_normal@2x.png + images/icons/forward_normal@2x.png + images/icons/icon_view_normal@2x.png + images/icons/icon_view_hover@2x.png + images/icons/icon_view_checked@2x.png + images/icons/backward_press@2x.png + images/icons/backward_hover@2x.png + images/icons/forward_press@2x.png + images/icons/forward_hover@2x.png + images/icons/list_view_normal@2x.png + images/icons/list_view_hover@2x.png + images/icons/list_view_checked@2x.png + images/icons/preview_dialog_close_round_hover@2x.png + images/icons/preview-dialog-close_round_normal@2x.png + images/icons/preview-dialog-close_round_press@2x.png + images/icons/next_disabled.svg + images/icons/next_hover.svg + images/icons/next_normal.svg + images/icons/next_press.svg + images/icons/previous_disabled.svg + images/icons/previous_hover.svg + images/icons/previous_normal.svg + images/icons/previous_press.svg + images/icons/tag_deepblue_active.svg + images/icons/tag_deepblue_normal.svg + images/icons/tag_gray_active.svg + images/icons/tag_gray_normal.svg + images/icons/tag_green_active.svg + images/icons/tag_green_normal.svg + images/icons/tag_lightblue_active.svg + images/icons/tag_lightblue_normal.svg + images/icons/tag_orange_active.svg + images/icons/tag_orange_normal.svg + images/icons/tag_purple_active.svg + images/icons/tag_purple_normal.svg + images/icons/tag_red_active.svg + images/icons/tag_red_normal.svg + images/icons/tag_yellow_active.svg + images/icons/tag_yellow_normal.svg + images/icons/tag_normal.svg + images/icons/light_32px.svg + images/icons/jump_to_copy.svg + + + images/leftsidebar/android_active_16px.svg + images/leftsidebar/android_normal_16px.svg + images/leftsidebar/bookmarks_active_16px.svg + images/leftsidebar/bookmarks_normal_16px.svg + images/leftsidebar/desktop_active_16px.svg + images/leftsidebar/desktop_normal_16px.svg + images/leftsidebar/disk_active_16px.svg + images/leftsidebar/disk_normal_16px.svg + images/leftsidebar/documents_active_16px.svg + images/leftsidebar/documents_normal_16px.svg + images/leftsidebar/downloads_active_16px.svg + images/leftsidebar/downloads_normal_16px.svg + images/leftsidebar/dvd_active_16px.svg + images/leftsidebar/dvd_normal_16px.svg + images/leftsidebar/file_active_16px.svg + images/leftsidebar/file_normal_16px.svg + images/leftsidebar/home_active_16px.svg + images/leftsidebar/home_normal_16px.svg + images/leftsidebar/iphone_active_16px.svg + images/leftsidebar/iphone_normal_16px.svg + images/leftsidebar/music_active_16px.svg + images/leftsidebar/music_normal_16px.svg + images/leftsidebar/network_active_16px.svg + images/leftsidebar/network_normal_16px.svg + images/leftsidebar/pictures_active_16px.svg + images/leftsidebar/pictures_normal_16px.svg + images/leftsidebar/recent_active_16px.svg + images/leftsidebar/recent_normal_16px.svg + images/leftsidebar/trash_active_16px.svg + images/leftsidebar/trash_normal_16px.svg + images/leftsidebar/usb_active_16px.svg + images/leftsidebar/usb_normal_16px.svg + images/leftsidebar/usershare_active_16px.svg + images/leftsidebar/usershare_normal_16px.svg + images/leftsidebar/videos_active_16px.svg + images/leftsidebar/videos_normal_16px.svg + images/leftsidebar/computer_active_16px.svg + images/leftsidebar/computer_normal_16px.svg + images/leftsidebar/unmount_hover_16px.svg + images/leftsidebar/unmount_normal_16px.svg + images/leftsidebar/unmount_press_16px.svg + images/leftsidebar/unmount_active_16px.svg + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner01.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner01.png new file mode 100644 index 0000000..ff49b85 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner01.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner02.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner02.png new file mode 100644 index 0000000..3c318b6 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner02.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner03.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner03.png new file mode 100644 index 0000000..92d21f3 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner03.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner04.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner04.png new file mode 100644 index 0000000..589100f Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner04.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner05.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner05.png new file mode 100644 index 0000000..ba5682c Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner05.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner06.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner06.png new file mode 100644 index 0000000..cbd6b2f Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner06.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner07.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner07.png new file mode 100644 index 0000000..fb14db0 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner07.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner08.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner08.png new file mode 100644 index 0000000..c7850c6 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner08.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner09.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner09.png new file mode 100644 index 0000000..8096595 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner09.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner10.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner10.png new file mode 100644 index 0000000..ab7893a Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner10.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner11.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner11.png new file mode 100644 index 0000000..c27fd9a Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner11.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner12.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner12.png new file mode 100644 index 0000000..b15ef62 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner12.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner13.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner13.png new file mode 100644 index 0000000..e61d34d Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner13.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner14.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner14.png new file mode 100644 index 0000000..f545156 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner14.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner15.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner15.png new file mode 100644 index 0000000..24a4d7c Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner15.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner16.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner16.png new file mode 100644 index 0000000..f7fc0a4 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner16.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner17.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner17.png new file mode 100644 index 0000000..2efc813 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner17.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner18.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner18.png new file mode 100644 index 0000000..5d086a1 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner18.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner19.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner19.png new file mode 100644 index 0000000..1009817 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner19.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner20.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner20.png new file mode 100644 index 0000000..f51c964 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner20.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner21.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner21.png new file mode 100644 index 0000000..582162a Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner21.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner22.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner22.png new file mode 100644 index 0000000..0d66644 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner22.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner23.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner23.png new file mode 100644 index 0000000..e357af5 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner23.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner24.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner24.png new file mode 100644 index 0000000..b482a6c Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner24.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner25.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner25.png new file mode 100644 index 0000000..fbcd4a0 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner25.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner26.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner26.png new file mode 100644 index 0000000..5ed2ede Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner26.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner27.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner27.png new file mode 100644 index 0000000..0947526 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner27.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner28.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner28.png new file mode 100644 index 0000000..7dd2d79 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner28.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner29.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner29.png new file mode 100644 index 0000000..bbe82c1 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner29.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner30.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner30.png new file mode 100644 index 0000000..773547b Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner30.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner31.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner31.png new file mode 100644 index 0000000..7e0b93d Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner31.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner32.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner32.png new file mode 100644 index 0000000..2c41bd1 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner32.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner33.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner33.png new file mode 100644 index 0000000..3026547 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner33.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner34.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner34.png new file mode 100644 index 0000000..7166fad Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner34.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner35.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner35.png new file mode 100644 index 0000000..82ef7c2 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner35.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner36.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner36.png new file mode 100644 index 0000000..df6d478 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner36.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner37.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner37.png new file mode 100644 index 0000000..e430370 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner37.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner38.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner38.png new file mode 100644 index 0000000..733f33c Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner38.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner39.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner39.png new file mode 100644 index 0000000..81176a1 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner39.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner40.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner40.png new file mode 100644 index 0000000..ddd7c18 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner40.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner41.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner41.png new file mode 100644 index 0000000..b03b1d9 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner41.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner42.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner42.png new file mode 100644 index 0000000..3a16d93 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner42.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner43.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner43.png new file mode 100644 index 0000000..1f89d67 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner43.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner44.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner44.png new file mode 100644 index 0000000..cfb0ee5 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner44.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner45.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner45.png new file mode 100644 index 0000000..d9c52f3 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner45.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner46.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner46.png new file mode 100644 index 0000000..ca2a962 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner46.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner47.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner47.png new file mode 100644 index 0000000..cf51d58 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner47.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner48.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner48.png new file mode 100644 index 0000000..568f794 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner48.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner49.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner49.png new file mode 100644 index 0000000..fe74428 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner49.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner50.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner50.png new file mode 100644 index 0000000..f81e776 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner50.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner51.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner51.png new file mode 100644 index 0000000..3f92d19 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner51.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner52.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner52.png new file mode 100644 index 0000000..cfef142 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner52.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner53.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner53.png new file mode 100644 index 0000000..5f927c2 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner53.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner54.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner54.png new file mode 100644 index 0000000..c4ec009 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner54.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner55.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner55.png new file mode 100644 index 0000000..dab9313 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner55.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner56.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner56.png new file mode 100644 index 0000000..1180e03 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner56.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner57.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner57.png new file mode 100644 index 0000000..4ef8a54 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner57.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner58.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner58.png new file mode 100644 index 0000000..4e35ca0 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner58.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner59.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner59.png new file mode 100644 index 0000000..c483eae Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner59.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner60.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner60.png new file mode 100644 index 0000000..10239f9 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner60.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner61.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner61.png new file mode 100644 index 0000000..1f64de6 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner61.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner62.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner62.png new file mode 100644 index 0000000..b62e9af Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner62.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner63.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner63.png new file mode 100644 index 0000000..560deb1 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner63.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner64.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner64.png new file mode 100644 index 0000000..303b111 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner64.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner65.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner65.png new file mode 100644 index 0000000..a9489e6 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner65.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner66.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner66.png new file mode 100644 index 0000000..94eb334 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner66.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner67.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner67.png new file mode 100644 index 0000000..41ab226 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner67.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner68.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner68.png new file mode 100644 index 0000000..d227518 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner68.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner69.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner69.png new file mode 100644 index 0000000..60b2d22 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner69.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner70.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner70.png new file mode 100644 index 0000000..95edd4d Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner70.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner71.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner71.png new file mode 100644 index 0000000..292a90b Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner71.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner72.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner72.png new file mode 100644 index 0000000..852a61c Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner72.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner73.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner73.png new file mode 100644 index 0000000..1cdc642 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner73.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner74.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner74.png new file mode 100644 index 0000000..46434b8 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner74.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner75.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner75.png new file mode 100644 index 0000000..bb0d66c Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner75.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner76.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner76.png new file mode 100644 index 0000000..1868275 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner76.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner77.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner77.png new file mode 100644 index 0000000..2dac291 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner77.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner78.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner78.png new file mode 100644 index 0000000..e3b4111 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner78.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner79.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner79.png new file mode 100644 index 0000000..b1c449e Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner79.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner80.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner80.png new file mode 100644 index 0000000..49c3e9c Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner80.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner81.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner81.png new file mode 100644 index 0000000..32338cd Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner81.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner82.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner82.png new file mode 100644 index 0000000..a7c9a13 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner82.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner83.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner83.png new file mode 100644 index 0000000..e0a9698 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner83.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner84.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner84.png new file mode 100644 index 0000000..5f75e1b Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner84.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner85.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner85.png new file mode 100644 index 0000000..cee3613 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner85.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner86.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner86.png new file mode 100644 index 0000000..bc4b666 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner86.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner87.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner87.png new file mode 100644 index 0000000..be70cf3 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner87.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner88.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner88.png new file mode 100644 index 0000000..98bcad3 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner88.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner89.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner89.png new file mode 100644 index 0000000..811fb16 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner89.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner90.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner90.png new file mode 100644 index 0000000..a5b60c9 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/Spinner/Spinner90.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/application-x-shellscript.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/application-x-shellscript.svg new file mode 100644 index 0000000..e13c673 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/application-x-shellscript.svg @@ -0,0 +1,157 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager-admin.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager-admin.png new file mode 100644 index 0000000..f31741d Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager-admin.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager-admin@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager-admin@2x.png new file mode 100644 index 0000000..daad71e Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager-admin@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager.png new file mode 100644 index 0000000..b3f3a3f Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager.svg new file mode 100644 index 0000000..975a1b2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager.svg @@ -0,0 +1,32 @@ + + + + 文件管理器-48px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager@2x.png new file mode 100644 index 0000000..c6ae1a1 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager_96.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager_96.png new file mode 100644 index 0000000..1be297b Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager_96.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager_96.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager_96.svg new file mode 100644 index 0000000..83cc350 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager_96.svg @@ -0,0 +1,24 @@ + + + + 文件管理器-96px + Created with Sketch. + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager_96@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager_96@2x.png new file mode 100644 index 0000000..fd6c32e Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/dde-file-manager_96@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/android-device-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/android-device-256px.svg new file mode 100644 index 0000000..16d6ade --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/android-device-256px.svg @@ -0,0 +1,18 @@ + + + + android-device-256px + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/camera-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/camera-256px.svg new file mode 100644 index 0000000..935c2fd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/camera-256px.svg @@ -0,0 +1,58 @@ + + + + camera-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-256px.svg new file mode 100644 index 0000000..ec30f00 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-256px.svg @@ -0,0 +1,39 @@ + + + + drive-harddisk-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-Windows-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-Windows-256px.svg new file mode 100644 index 0000000..aa0ddb8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-Windows-256px.svg @@ -0,0 +1,40 @@ + + + + drive-harddisk-Windows-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-deepin-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-deepin-256px.svg new file mode 100644 index 0000000..6461886 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-deepin-256px.svg @@ -0,0 +1,40 @@ + + + + drive-harddisk-deepin-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-ieee1394-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-ieee1394-256px.svg new file mode 100644 index 0000000..5ecb3c0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-ieee1394-256px.svg @@ -0,0 +1,47 @@ + + + + drive-harddisk-ieee1394-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-linux-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-linux-256px.svg new file mode 100644 index 0000000..7565fb2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-linux-256px.svg @@ -0,0 +1,40 @@ + + + + drive-harddisk-linux-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-mac-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-mac-256px.svg new file mode 100644 index 0000000..0b1c587 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-mac-256px.svg @@ -0,0 +1,57 @@ + + + + drive-harddisk-mac-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-scsi-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-scsi-256px.svg new file mode 100644 index 0000000..6147c84 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-scsi-256px.svg @@ -0,0 +1,43 @@ + + + + drive-harddisk-scsi-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-usb-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-usb-256px.svg new file mode 100644 index 0000000..d837371 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-harddisk-usb-256px.svg @@ -0,0 +1,48 @@ + + + + drive-harddisk-usb-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-network-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-network-256px.svg new file mode 100644 index 0000000..b8dfbda --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-network-256px.svg @@ -0,0 +1,49 @@ + + + + drive-network-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-optical-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-optical-256px.svg new file mode 100644 index 0000000..3ecaaf8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-optical-256px.svg @@ -0,0 +1,40 @@ + + + + drive-optical-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-removable-media-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-removable-media-256px.svg new file mode 100644 index 0000000..d933bc5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-removable-media-256px.svg @@ -0,0 +1,41 @@ + + + + drive-removable-media-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-removable-media-ieee1394-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-removable-media-ieee1394-256px.svg new file mode 100644 index 0000000..31fdb7d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-removable-media-ieee1394-256px.svg @@ -0,0 +1,45 @@ + + + + drive-removable-media-ieee1394-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-removable-media-scsi-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-removable-media-scsi-256px.svg new file mode 100644 index 0000000..ef6f6ea --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-removable-media-scsi-256px.svg @@ -0,0 +1,41 @@ + + + + drive-removable-media-scsi-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-removable-media-usb-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-removable-media-usb-256px.svg new file mode 100644 index 0000000..d8bf9f5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/drive-removable-media-usb-256px.svg @@ -0,0 +1,46 @@ + + + + drive-removable-media-usb-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/ios-device-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/ios-device-256px.svg new file mode 100644 index 0000000..7e20001 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/ios-device-256px.svg @@ -0,0 +1,20 @@ + + + + ios-device-256px + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-cdr-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-cdr-256px.svg new file mode 100644 index 0000000..30df38e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-cdr-256px.svg @@ -0,0 +1,27 @@ + + + + media-cdr-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-cdrw-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-cdrw-256px.svg new file mode 100644 index 0000000..cfbc915 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-cdrw-256px.svg @@ -0,0 +1,27 @@ + + + + media-cdrw-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-dvd-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-dvd-256px.svg new file mode 100644 index 0000000..f315cdd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-dvd-256px.svg @@ -0,0 +1,27 @@ + + + + media-dvd-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-flash-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-flash-256px.svg new file mode 100644 index 0000000..9d21495 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-flash-256px.svg @@ -0,0 +1,34 @@ + + + + media-flash-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-optical-256px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-optical-256px.svg new file mode 100644 index 0000000..ebe75a7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/device/media-optical-256px.svg @@ -0,0 +1,26 @@ + + + + media-optical-256px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/diban.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/diban.svg new file mode 100644 index 0000000..ad5a376 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/diban.svg @@ -0,0 +1,29 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_hover.png new file mode 100644 index 0000000..0d09889 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_hover@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_hover@2x.png new file mode 100644 index 0000000..7b4032c Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_hover@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_normal.png new file mode 100644 index 0000000..7e95566 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_normal@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_normal@2x.png new file mode 100644 index 0000000..6aad8d3 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_normal@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_press.png new file mode 100644 index 0000000..802755e Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_press@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_press@2x.png new file mode 100644 index 0000000..1333036 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/active_tab_close_press@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/android_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/android_checked_16px.svg new file mode 100644 index 0000000..6a7977d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/android_checked_16px.svg @@ -0,0 +1,18 @@ + + + + Android_phone_active_16px + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/android_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/android_hover_16px.svg new file mode 100644 index 0000000..6a7977d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/android_hover_16px.svg @@ -0,0 +1,18 @@ + + + + Android_phone_active_16px + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/android_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/android_normal_16px.svg new file mode 100644 index 0000000..3a544da --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/android_normal_16px.svg @@ -0,0 +1,16 @@ + + + + Android_phone_normal_16px + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_disabled.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_disabled.png new file mode 100644 index 0000000..161169b Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_disabled.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_disabled@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_disabled@2x.png new file mode 100644 index 0000000..4fb909b Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_disabled@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_hover.png new file mode 100644 index 0000000..d90a383 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_hover@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_hover@2x.png new file mode 100644 index 0000000..78c6321 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_hover@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_normal.png new file mode 100644 index 0000000..e50548b Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_normal@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_normal@2x.png new file mode 100644 index 0000000..a242235 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_normal@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_press.png new file mode 100644 index 0000000..d90a383 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_press@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_press@2x.png new file mode 100644 index 0000000..78c6321 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/backward_press@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/bookmarks_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/bookmarks_checked_16px.svg new file mode 100644 index 0000000..e479e31 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/bookmarks_checked_16px.svg @@ -0,0 +1,13 @@ + + + + bookmarks_active_16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/bookmarks_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/bookmarks_hover_16px.svg new file mode 100644 index 0000000..e479e31 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/bookmarks_hover_16px.svg @@ -0,0 +1,13 @@ + + + + bookmarks_active_16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/bookmarks_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/bookmarks_normal_16px.svg new file mode 100644 index 0000000..26c8985 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/bookmarks_normal_16px.svg @@ -0,0 +1,15 @@ + + + + bookmarks_normal_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/close_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/close_hover.png new file mode 100644 index 0000000..62da870 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/close_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/close_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/close_normal.png new file mode 100644 index 0000000..47deda8 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/close_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/close_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/close_press.png new file mode 100644 index 0000000..c42abbf Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/close_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/computer_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/computer_checked_16px.svg new file mode 100644 index 0000000..93fddbb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/computer_checked_16px.svg @@ -0,0 +1,24 @@ + + + + computer_checked + Created with Sketch. + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/computer_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/computer_hover_16px.svg new file mode 100644 index 0000000..93fddbb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/computer_hover_16px.svg @@ -0,0 +1,24 @@ + + + + computer_checked + Created with Sketch. + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/desktop_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/desktop_checked_16px.svg new file mode 100644 index 0000000..8726116 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/desktop_checked_16px.svg @@ -0,0 +1,15 @@ + + + + desktop_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/desktop_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/desktop_hover_16px.svg new file mode 100644 index 0000000..8726116 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/desktop_hover_16px.svg @@ -0,0 +1,15 @@ + + + + desktop_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/desktop_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/desktop_normal_16px.svg new file mode 100644 index 0000000..9336b7c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/desktop_normal_16px.svg @@ -0,0 +1,17 @@ + + + + desktop_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/disk_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/disk_checked_16px.svg new file mode 100644 index 0000000..8639a6e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/disk_checked_16px.svg @@ -0,0 +1,15 @@ + + + + disk_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/disk_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/disk_hover_16px.svg new file mode 100644 index 0000000..8639a6e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/disk_hover_16px.svg @@ -0,0 +1,15 @@ + + + + disk_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/disk_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/disk_normal_16px.svg new file mode 100644 index 0000000..c409438 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/disk_normal_16px.svg @@ -0,0 +1,17 @@ + + + + disk_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/documents_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/documents_checked_16px.svg new file mode 100644 index 0000000..97c69c9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/documents_checked_16px.svg @@ -0,0 +1,15 @@ + + + + documents_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/documents_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/documents_hover_16px.svg new file mode 100644 index 0000000..97c69c9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/documents_hover_16px.svg @@ -0,0 +1,15 @@ + + + + documents_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/documents_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/documents_normal_16px.svg new file mode 100644 index 0000000..e7e8ebf --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/documents_normal_16px.svg @@ -0,0 +1,19 @@ + + + + documents_normal_16px + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/down.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/down.png new file mode 100644 index 0000000..94e3eec Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/down.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/down_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/down_hover.png new file mode 100644 index 0000000..1babdc3 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/down_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/down_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/down_press.png new file mode 100644 index 0000000..1babdc3 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/down_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/downloads_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/downloads_checked_16px.svg new file mode 100644 index 0000000..75ad204 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/downloads_checked_16px.svg @@ -0,0 +1,17 @@ + + + + download_active_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/downloads_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/downloads_hover_16px.svg new file mode 100644 index 0000000..75ad204 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/downloads_hover_16px.svg @@ -0,0 +1,17 @@ + + + + download_active_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/downloads_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/downloads_normal_16px.svg new file mode 100644 index 0000000..b71e491 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/downloads_normal_16px.svg @@ -0,0 +1,17 @@ + + + + download_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/dvd_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/dvd_checked_16px.svg new file mode 100644 index 0000000..2dde7df --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/dvd_checked_16px.svg @@ -0,0 +1,14 @@ + + + + media_optical_symbolic_active_16px + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/dvd_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/dvd_hover_16px.svg new file mode 100644 index 0000000..2dde7df --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/dvd_hover_16px.svg @@ -0,0 +1,14 @@ + + + + media_optical_symbolic_active_16px + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/dvd_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/dvd_normal_16px.svg new file mode 100644 index 0000000..87be3b2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/dvd_normal_16px.svg @@ -0,0 +1,15 @@ + + + + media_optical_symbolic_normal_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_hover.png new file mode 100644 index 0000000..65c3295 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_hover@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_hover@2x.png new file mode 100644 index 0000000..242b6a4 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_hover@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_normal.png new file mode 100644 index 0000000..11b7847 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_normal@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_normal@2x.png new file mode 100644 index 0000000..b9060c8 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_normal@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_press.png new file mode 100644 index 0000000..328457e Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_press@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_press@2x.png new file mode 100644 index 0000000..6f733bc Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/empty_trash_press@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/expanded_view_checked.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/expanded_view_checked.svg new file mode 100644 index 0000000..d1a4332 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/expanded_view_checked.svg @@ -0,0 +1,13 @@ + + + + expanded_view_active + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/expanded_view_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/expanded_view_hover.svg new file mode 100644 index 0000000..d1a4332 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/expanded_view_hover.svg @@ -0,0 +1,13 @@ + + + + expanded_view_active + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/expanded_view_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/expanded_view_normal.svg new file mode 100644 index 0000000..a9574ed --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/expanded_view_normal.svg @@ -0,0 +1,13 @@ + + + + expanded_view_normal + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/favourite_checked.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/favourite_checked.svg new file mode 100644 index 0000000..8122255 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/favourite_checked.svg @@ -0,0 +1,13 @@ + + + + favourite_checked + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/favourite_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/favourite_hover.svg new file mode 100644 index 0000000..d6ca059 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/favourite_hover.svg @@ -0,0 +1,15 @@ + + + + favourite_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/favourite_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/favourite_normal.svg new file mode 100644 index 0000000..d6ca059 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/favourite_normal.svg @@ -0,0 +1,15 @@ + + + + favourite_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/file_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/file_checked_16px.svg new file mode 100644 index 0000000..d78afee --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/file_checked_16px.svg @@ -0,0 +1,17 @@ + + + + file_active_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/file_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/file_hover_16px.svg new file mode 100644 index 0000000..d78afee --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/file_hover_16px.svg @@ -0,0 +1,17 @@ + + + + file_active_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/file_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/file_normal_16px.svg new file mode 100644 index 0000000..f4a6ad7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/file_normal_16px.svg @@ -0,0 +1,17 @@ + + + + file_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/filter_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/filter_active.svg new file mode 100644 index 0000000..9b4676c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/filter_active.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/filter_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/filter_hover.svg new file mode 100644 index 0000000..c21af53 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/filter_hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/filter_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/filter_normal.svg new file mode 100644 index 0000000..dd1a5f7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/filter_normal.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_disabled.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_disabled.png new file mode 100644 index 0000000..feead70 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_disabled.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_disabled@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_disabled@2x.png new file mode 100644 index 0000000..3264b1c Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_disabled@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_hover.png new file mode 100644 index 0000000..6a4827f Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_hover@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_hover@2x.png new file mode 100644 index 0000000..7f0346f Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_hover@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_normal.png new file mode 100644 index 0000000..5e085d4 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_normal@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_normal@2x.png new file mode 100644 index 0000000..d0c8932 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_normal@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_press.png new file mode 100644 index 0000000..6a4827f Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_press@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_press@2x.png new file mode 100644 index 0000000..7f0346f Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/forward_press@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/hierarchical_view_checked.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/hierarchical_view_checked.svg new file mode 100644 index 0000000..b7c1b22 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/hierarchical_view_checked.svg @@ -0,0 +1,13 @@ + + + + hierarchical_view_active + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/hierarchical_view_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/hierarchical_view_hover.svg new file mode 100644 index 0000000..b7c1b22 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/hierarchical_view_hover.svg @@ -0,0 +1,13 @@ + + + + hierarchical_view_active + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/hierarchical_view_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/hierarchical_view_normal.svg new file mode 100644 index 0000000..f44c221 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/hierarchical_view_normal.svg @@ -0,0 +1,13 @@ + + + + hierarchical_view_normal + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/home_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/home_checked_16px.svg new file mode 100644 index 0000000..db7c0f4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/home_checked_16px.svg @@ -0,0 +1,15 @@ + + + + home_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/home_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/home_hover_16px.svg new file mode 100644 index 0000000..db7c0f4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/home_hover_16px.svg @@ -0,0 +1,15 @@ + + + + home_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/home_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/home_normal_16px.svg new file mode 100644 index 0000000..19e9f5a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/home_normal_16px.svg @@ -0,0 +1,16 @@ + + + + home_normal_16px + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_checked.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_checked.png new file mode 100644 index 0000000..cf91774 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_checked.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_checked.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_checked.svg new file mode 100644 index 0000000..8d56f1d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_checked.svg @@ -0,0 +1,13 @@ + + + + icon_view_active + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_checked@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_checked@2x.png new file mode 100644 index 0000000..c355215 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_checked@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_hover.png new file mode 100644 index 0000000..cf91774 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_hover.svg new file mode 100644 index 0000000..8d56f1d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_hover.svg @@ -0,0 +1,13 @@ + + + + icon_view_active + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_hover@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_hover@2x.png new file mode 100644 index 0000000..c355215 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_hover@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_normal.png new file mode 100644 index 0000000..9690930 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_normal.svg new file mode 100644 index 0000000..02a522e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_normal.svg @@ -0,0 +1,13 @@ + + + + icon_view_normal + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_normal@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_normal@2x.png new file mode 100644 index 0000000..c621d79 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/icon_view_normal@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/input_clear_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/input_clear_hover.svg new file mode 100644 index 0000000..c3952ea --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/input_clear_hover.svg @@ -0,0 +1,12 @@ + + + + input_clear_hover + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/input_clear_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/input_clear_normal.svg new file mode 100644 index 0000000..c5e4a4e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/input_clear_normal.svg @@ -0,0 +1,12 @@ + + + + input_clear_normal + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/input_clear_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/input_clear_press.svg new file mode 100644 index 0000000..2aa97dd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/input_clear_press.svg @@ -0,0 +1,12 @@ + + + + input_clear_press + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/iphone_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/iphone_checked_16px.svg new file mode 100644 index 0000000..ae11753 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/iphone_checked_16px.svg @@ -0,0 +1,14 @@ + + + + iphone_active_16px + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/iphone_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/iphone_hover_16px.svg new file mode 100644 index 0000000..ae11753 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/iphone_hover_16px.svg @@ -0,0 +1,14 @@ + + + + iphone_active_16px + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/iphone_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/iphone_normal_16px.svg new file mode 100644 index 0000000..3be5042 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/iphone_normal_16px.svg @@ -0,0 +1,17 @@ + + + + iphone_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/jump_to.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/jump_to.svg new file mode 100644 index 0000000..c063469 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/jump_to.svg @@ -0,0 +1,23 @@ + + + + jump_to + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/jump_to_copy.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/jump_to_copy.svg new file mode 100644 index 0000000..c063469 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/jump_to_copy.svg @@ -0,0 +1,23 @@ + + + + jump_to + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/light_32px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/light_32px.svg new file mode 100644 index 0000000..a66cf97 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/light_32px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_checked.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_checked.png new file mode 100644 index 0000000..f1d163b Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_checked.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_checked.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_checked.svg new file mode 100644 index 0000000..7360b1b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_checked.svg @@ -0,0 +1,13 @@ + + + + list_view_active + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_checked@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_checked@2x.png new file mode 100644 index 0000000..58ca3af Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_checked@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_hover.png new file mode 100644 index 0000000..f1d163b Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_hover.svg new file mode 100644 index 0000000..7360b1b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_hover.svg @@ -0,0 +1,13 @@ + + + + list_view_active + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_hover@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_hover@2x.png new file mode 100644 index 0000000..58ca3af Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_hover@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_normal.png new file mode 100644 index 0000000..2bd3c57 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_normal.svg new file mode 100644 index 0000000..3131b5f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_normal.svg @@ -0,0 +1,13 @@ + + + + list_view_normal + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_normal@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_normal@2x.png new file mode 100644 index 0000000..9aa56fe Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/list_view_normal@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/maximize_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/maximize_hover.png new file mode 100644 index 0000000..cb74fec Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/maximize_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/maximize_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/maximize_normal.png new file mode 100644 index 0000000..ec4432a Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/maximize_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/maximize_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/maximize_press.png new file mode 100644 index 0000000..08a6720 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/maximize_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/menu_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/menu_hover.png new file mode 100644 index 0000000..3ca2123 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/menu_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/menu_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/menu_normal.png new file mode 100644 index 0000000..f06487b Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/menu_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/menu_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/menu_press.png new file mode 100644 index 0000000..c1c4dfb Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/menu_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/minimise_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/minimise_hover.png new file mode 100644 index 0000000..3c18406 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/minimise_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/minimise_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/minimise_normal.png new file mode 100644 index 0000000..498ce18 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/minimise_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/minimise_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/minimise_press.png new file mode 100644 index 0000000..4b28323 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/minimise_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/music_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/music_checked_16px.svg new file mode 100644 index 0000000..302d730 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/music_checked_16px.svg @@ -0,0 +1,15 @@ + + + + music_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/music_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/music_hover_16px.svg new file mode 100644 index 0000000..302d730 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/music_hover_16px.svg @@ -0,0 +1,15 @@ + + + + music_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/music_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/music_normal_16px.svg new file mode 100644 index 0000000..d393010 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/music_normal_16px.svg @@ -0,0 +1,19 @@ + + + + music_normal_16px + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/network_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/network_checked_16px.svg new file mode 100644 index 0000000..4124169 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/network_checked_16px.svg @@ -0,0 +1,14 @@ + + + + network_server_symbolic_active_16px + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/network_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/network_hover_16px.svg new file mode 100644 index 0000000..4124169 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/network_hover_16px.svg @@ -0,0 +1,14 @@ + + + + network_server_symbolic_active_16px + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/network_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/network_normal_16px.svg new file mode 100644 index 0000000..f88d55d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/network_normal_16px.svg @@ -0,0 +1,20 @@ + + + + network_server_symbolic_normal_16px + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/new_tab_disabled.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/new_tab_disabled.png new file mode 100644 index 0000000..de5f060 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/new_tab_disabled.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/new_tab_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/new_tab_hover.png new file mode 100644 index 0000000..2d8f1ec Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/new_tab_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/new_tab_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/new_tab_normal.png new file mode 100644 index 0000000..32034c6 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/new_tab_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/new_tab_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/new_tab_press.png new file mode 100644 index 0000000..c751fba Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/new_tab_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/next_disabled.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/next_disabled.svg new file mode 100644 index 0000000..f2945ab --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/next_disabled.svg @@ -0,0 +1,36 @@ + + + + next_disabled + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/next_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/next_hover.svg new file mode 100644 index 0000000..1139eab --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/next_hover.svg @@ -0,0 +1,31 @@ + + + + next_hover + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/next_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/next_normal.svg new file mode 100644 index 0000000..00dda6d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/next_normal.svg @@ -0,0 +1,36 @@ + + + + next_normal + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/next_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/next_press.svg new file mode 100644 index 0000000..0457259 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/next_press.svg @@ -0,0 +1,31 @@ + + + + next_press + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/phone_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/phone_checked_16px.svg new file mode 100644 index 0000000..822b87a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/phone_checked_16px.svg @@ -0,0 +1,15 @@ + + + + phone_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/phone_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/phone_hover_16px.svg new file mode 100644 index 0000000..822b87a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/phone_hover_16px.svg @@ -0,0 +1,15 @@ + + + + phone_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/phone_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/phone_normal_16px.svg new file mode 100644 index 0000000..fb81fad --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/phone_normal_16px.svg @@ -0,0 +1,17 @@ + + + + phone_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/pictures_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/pictures_checked_16px.svg new file mode 100644 index 0000000..3521896 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/pictures_checked_16px.svg @@ -0,0 +1,15 @@ + + + + pictures_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/pictures_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/pictures_hover_16px.svg new file mode 100644 index 0000000..3521896 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/pictures_hover_16px.svg @@ -0,0 +1,15 @@ + + + + pictures_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/pictures_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/pictures_normal_16px.svg new file mode 100644 index 0000000..ac4ecaa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/pictures_normal_16px.svg @@ -0,0 +1,17 @@ + + + + pictures_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview-dialog-close_round_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview-dialog-close_round_normal.png new file mode 100644 index 0000000..9112441 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview-dialog-close_round_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview-dialog-close_round_normal@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview-dialog-close_round_normal@2x.png new file mode 100644 index 0000000..120e6db Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview-dialog-close_round_normal@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview-dialog-close_round_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview-dialog-close_round_press.png new file mode 100644 index 0000000..00e0b45 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview-dialog-close_round_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview-dialog-close_round_press@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview-dialog-close_round_press@2x.png new file mode 100644 index 0000000..6599688 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview-dialog-close_round_press@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview_dialog_close_round_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview_dialog_close_round_hover.png new file mode 100644 index 0000000..73e7184 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview_dialog_close_round_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview_dialog_close_round_hover@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview_dialog_close_round_hover@2x.png new file mode 100644 index 0000000..ccfe3fd Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/preview_dialog_close_round_hover@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/previous_disabled.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/previous_disabled.svg new file mode 100644 index 0000000..356fd77 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/previous_disabled.svg @@ -0,0 +1,36 @@ + + + + previous_disabled + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/previous_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/previous_hover.svg new file mode 100644 index 0000000..ad4fb81 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/previous_hover.svg @@ -0,0 +1,31 @@ + + + + previous_hover + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/previous_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/previous_normal.svg new file mode 100644 index 0000000..b62c35a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/previous_normal.svg @@ -0,0 +1,36 @@ + + + + previous_normal + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/previous_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/previous_press.svg new file mode 100644 index 0000000..fdbb1c8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/previous_press.svg @@ -0,0 +1,31 @@ + + + + previous_press + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/recent_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/recent_checked_16px.svg new file mode 100644 index 0000000..a7ff3b8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/recent_checked_16px.svg @@ -0,0 +1,13 @@ + + + + recent_active_16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/recent_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/recent_hover_16px.svg new file mode 100644 index 0000000..a7ff3b8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/recent_hover_16px.svg @@ -0,0 +1,13 @@ + + + + recent_active_16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/recent_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/recent_normal_16px.svg new file mode 100644 index 0000000..60675d9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/recent_normal_16px.svg @@ -0,0 +1,16 @@ + + + + recent_normal_16px + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/reordering_line.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/reordering_line.svg new file mode 100644 index 0000000..bd14e3b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/reordering_line.svg @@ -0,0 +1,20 @@ + + + + 横线 + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/search.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/search.svg new file mode 100644 index 0000000..6fd2f45 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/search.svg @@ -0,0 +1,15 @@ + + + + search + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/search_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/search_hover.svg new file mode 100644 index 0000000..00cab33 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/search_hover.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/search_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/search_normal.svg new file mode 100644 index 0000000..af90c44 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/search_normal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/search_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/search_press.svg new file mode 100644 index 0000000..2012980 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/search_press.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/selectend.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/selectend.png new file mode 100644 index 0000000..3000e76 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/selectend.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/selectstart.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/selectstart.png new file mode 100644 index 0000000..19d5ee5 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/selectstart.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/slider_handle.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/slider_handle.png new file mode 100644 index 0000000..0565e90 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/slider_handle.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_hover.png new file mode 100644 index 0000000..9ce34bc Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_hover@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_hover@2x.png new file mode 100644 index 0000000..cc3e2c7 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_hover@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_normal.png new file mode 100644 index 0000000..11fc79e Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_normal@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_normal@2x.png new file mode 100644 index 0000000..13c2d63 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_normal@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_press.png new file mode 100644 index 0000000..b5259a1 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_press@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_press@2x.png new file mode 100644 index 0000000..f8504da Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/stop_press@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_hover.png new file mode 100644 index 0000000..547a15c Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_hover@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_hover@2x.png new file mode 100644 index 0000000..2e4e822 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_hover@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_normal.png new file mode 100644 index 0000000..07a6491 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_normal@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_normal@2x.png new file mode 100644 index 0000000..6a734ec Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_normal@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_press.png new file mode 100644 index 0000000..b33e4f1 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_press@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_press@2x.png new file mode 100644 index 0000000..11b3151 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tab_close_press@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_deepblue_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_deepblue_active.svg new file mode 100644 index 0000000..5ae96a0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_deepblue_active.svg @@ -0,0 +1,15 @@ + + + + tag_deepblue_active + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_deepblue_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_deepblue_normal.svg new file mode 100644 index 0000000..ee671f6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_deepblue_normal.svg @@ -0,0 +1,15 @@ + + + + tag_deepblue_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_gray_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_gray_active.svg new file mode 100644 index 0000000..9c5ecf7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_gray_active.svg @@ -0,0 +1,15 @@ + + + + tag_gray_active + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_gray_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_gray_normal.svg new file mode 100644 index 0000000..2038ff9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_gray_normal.svg @@ -0,0 +1,15 @@ + + + + tag_gray_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_green_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_green_active.svg new file mode 100644 index 0000000..7de9365 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_green_active.svg @@ -0,0 +1,15 @@ + + + + tag_green_active + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_green_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_green_normal.svg new file mode 100644 index 0000000..20671f7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_green_normal.svg @@ -0,0 +1,15 @@ + + + + tag_green_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_lightblue_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_lightblue_active.svg new file mode 100644 index 0000000..707c5d3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_lightblue_active.svg @@ -0,0 +1,15 @@ + + + + tag_lightblue_active + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_lightblue_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_lightblue_normal.svg new file mode 100644 index 0000000..e24702d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_lightblue_normal.svg @@ -0,0 +1,15 @@ + + + + tag_lightblue_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_normal.svg new file mode 100644 index 0000000..6acfe5c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_normal.svg @@ -0,0 +1,11 @@ + + + + tag + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_orange_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_orange_active.svg new file mode 100644 index 0000000..ca4e8ca --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_orange_active.svg @@ -0,0 +1,15 @@ + + + + tag_orange_active + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_orange_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_orange_normal.svg new file mode 100644 index 0000000..5175d8e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_orange_normal.svg @@ -0,0 +1,15 @@ + + + + tag_orange_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_purple_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_purple_active.svg new file mode 100644 index 0000000..c1b1d26 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_purple_active.svg @@ -0,0 +1,15 @@ + + + + tag_purple_active + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_purple_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_purple_normal.svg new file mode 100644 index 0000000..27d6cd3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_purple_normal.svg @@ -0,0 +1,15 @@ + + + + tag_purple_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_red_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_red_active.svg new file mode 100644 index 0000000..80faf9f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_red_active.svg @@ -0,0 +1,15 @@ + + + + tag_red_active + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_red_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_red_normal.svg new file mode 100644 index 0000000..7cf2a27 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_red_normal.svg @@ -0,0 +1,15 @@ + + + + tag_red_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_yellow_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_yellow_active.svg new file mode 100644 index 0000000..ce52685 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_yellow_active.svg @@ -0,0 +1,15 @@ + + + + tag_yellow_active + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_yellow_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_yellow_normal.svg new file mode 100644 index 0000000..9eacc2e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/tag_yellow_normal.svg @@ -0,0 +1,15 @@ + + + + tag_yellow_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/trash_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/trash_checked_16px.svg new file mode 100644 index 0000000..fde8b76 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/trash_checked_16px.svg @@ -0,0 +1,15 @@ + + + + trash_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/trash_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/trash_hover_16px.svg new file mode 100644 index 0000000..fde8b76 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/trash_hover_16px.svg @@ -0,0 +1,15 @@ + + + + trash_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/trash_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/trash_normal_16px.svg new file mode 100644 index 0000000..a287c20 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/trash_normal_16px.svg @@ -0,0 +1,19 @@ + + + + trash_normal_16px + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmaximize_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmaximize_hover.png new file mode 100644 index 0000000..c60ea56 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmaximize_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmaximize_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmaximize_normal.png new file mode 100644 index 0000000..e962451 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmaximize_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmaximize_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmaximize_press.png new file mode 100644 index 0000000..ee4f705 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmaximize_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_active.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_active.png new file mode 100644 index 0000000..0907b34 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_active.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_hover.png new file mode 100644 index 0000000..ebdbdb2 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_hover.svg new file mode 100644 index 0000000..403615f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_hover.svg @@ -0,0 +1,13 @@ + + + + unmount_hover + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_normal.png new file mode 100644 index 0000000..72acfbc Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_normal.svg new file mode 100644 index 0000000..550a105 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_normal.svg @@ -0,0 +1,15 @@ + + + + unmount_normal + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_press.png new file mode 100644 index 0000000..f52029b Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_press.svg new file mode 100644 index 0000000..58a674a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/unmount_press.svg @@ -0,0 +1,13 @@ + + + + unmount_press + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/up.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/up.png new file mode 100644 index 0000000..dcf4b66 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/up.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/up_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/up_hover.png new file mode 100644 index 0000000..a05779f Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/up_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/up_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/up_press.png new file mode 100644 index 0000000..a05779f Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/up_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usb_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usb_checked_16px.svg new file mode 100644 index 0000000..6edd1bc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usb_checked_16px.svg @@ -0,0 +1,13 @@ + + + + drive_harddisk_usb_symbolic_active_16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usb_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usb_hover_16px.svg new file mode 100644 index 0000000..6edd1bc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usb_hover_16px.svg @@ -0,0 +1,13 @@ + + + + drive_harddisk_usb_symbolic_active_16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usb_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usb_normal_16px.svg new file mode 100644 index 0000000..803811a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usb_normal_16px.svg @@ -0,0 +1,19 @@ + + + + drive_harddisk_usb_symbolic_normal_16px + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usershare_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usershare_checked_16px.svg new file mode 100644 index 0000000..d9607f2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usershare_checked_16px.svg @@ -0,0 +1,17 @@ + + + + share-active-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usershare_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usershare_hover_16px.svg new file mode 100644 index 0000000..d9607f2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usershare_hover_16px.svg @@ -0,0 +1,17 @@ + + + + share-active-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usershare_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usershare_normal_16px.svg new file mode 100644 index 0000000..88e7c92 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/usershare_normal_16px.svg @@ -0,0 +1,17 @@ + + + + share-normal-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/videos_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/videos_checked_16px.svg new file mode 100644 index 0000000..1c4fbbc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/videos_checked_16px.svg @@ -0,0 +1,15 @@ + + + + videos_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/videos_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/videos_hover_16px.svg new file mode 100644 index 0000000..1c4fbbc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/videos_hover_16px.svg @@ -0,0 +1,15 @@ + + + + videos_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/videos_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/videos_normal_16px.svg new file mode 100644 index 0000000..541ae3f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/icons/videos_normal_16px.svg @@ -0,0 +1,22 @@ + + + + videos_normal_16px + Created with Sketch. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/android_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/android_active_16px.svg new file mode 100644 index 0000000..27b24fb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/android_active_16px.svg @@ -0,0 +1,18 @@ + + + + Android-phone-active-16px + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/android_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/android_normal_16px.svg new file mode 100644 index 0000000..a9b32b6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/android_normal_16px.svg @@ -0,0 +1,16 @@ + + + + Android-phone-normal-16px + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/bookmarks_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/bookmarks_active_16px.svg new file mode 100644 index 0000000..769b71a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/bookmarks_active_16px.svg @@ -0,0 +1,13 @@ + + + + bookmarks-active-16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/bookmarks_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/bookmarks_normal_16px.svg new file mode 100644 index 0000000..0b19ca7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/bookmarks_normal_16px.svg @@ -0,0 +1,17 @@ + + + + bookmarks-normal-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/computer_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/computer_active_16px.svg new file mode 100644 index 0000000..7c3b5a3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/computer_active_16px.svg @@ -0,0 +1,24 @@ + + + + computer_active + Created with Sketch. + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/computer_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/computer_normal_16px.svg new file mode 100644 index 0000000..304dec4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/computer_normal_16px.svg @@ -0,0 +1,23 @@ + + + + computer_normal + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/desktop_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/desktop_active_16px.svg new file mode 100644 index 0000000..be5ba61 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/desktop_active_16px.svg @@ -0,0 +1,15 @@ + + + + desktop-active-16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/desktop_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/desktop_normal_16px.svg new file mode 100644 index 0000000..cef7159 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/desktop_normal_16px.svg @@ -0,0 +1,17 @@ + + + + desktop-normal-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/disk_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/disk_active_16px.svg new file mode 100644 index 0000000..b539865 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/disk_active_16px.svg @@ -0,0 +1,15 @@ + + + + disk-active-16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/disk_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/disk_normal_16px.svg new file mode 100644 index 0000000..6e52018 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/disk_normal_16px.svg @@ -0,0 +1,17 @@ + + + + disk-normal-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/documents_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/documents_active_16px.svg new file mode 100644 index 0000000..721c081 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/documents_active_16px.svg @@ -0,0 +1,15 @@ + + + + documents-active-16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/documents_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/documents_normal_16px.svg new file mode 100644 index 0000000..b10de6a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/documents_normal_16px.svg @@ -0,0 +1,19 @@ + + + + documents-normal-16px + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/downloads_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/downloads_active_16px.svg new file mode 100644 index 0000000..ce3c86b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/downloads_active_16px.svg @@ -0,0 +1,17 @@ + + + + download-active-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/downloads_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/downloads_normal_16px.svg new file mode 100644 index 0000000..d15378b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/downloads_normal_16px.svg @@ -0,0 +1,17 @@ + + + + download-normal-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/dvd_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/dvd_active_16px.svg new file mode 100644 index 0000000..e40a059 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/dvd_active_16px.svg @@ -0,0 +1,13 @@ + + + + media-optical-symbolic-active-16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/dvd_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/dvd_normal_16px.svg new file mode 100644 index 0000000..a99f6e1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/dvd_normal_16px.svg @@ -0,0 +1,17 @@ + + + + media-optical-symbolic-normal-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/file_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/file_active_16px.svg new file mode 100644 index 0000000..714cb5b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/file_active_16px.svg @@ -0,0 +1,15 @@ + + + + file-active-16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/file_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/file_normal_16px.svg new file mode 100644 index 0000000..a22247e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/file_normal_16px.svg @@ -0,0 +1,17 @@ + + + + file-normal-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/home_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/home_active_16px.svg new file mode 100644 index 0000000..834257d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/home_active_16px.svg @@ -0,0 +1,15 @@ + + + + home-active-16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/home_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/home_normal_16px.svg new file mode 100644 index 0000000..ce7f834 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/home_normal_16px.svg @@ -0,0 +1,16 @@ + + + + home-normal-16px + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/iphone_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/iphone_active_16px.svg new file mode 100644 index 0000000..57105ae --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/iphone_active_16px.svg @@ -0,0 +1,14 @@ + + + + iphone-active-16px + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/iphone_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/iphone_normal_16px.svg new file mode 100644 index 0000000..57a68ff --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/iphone_normal_16px.svg @@ -0,0 +1,17 @@ + + + + iphone-normal-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/music_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/music_active_16px.svg new file mode 100644 index 0000000..5395d08 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/music_active_16px.svg @@ -0,0 +1,15 @@ + + + + music-active-16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/music_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/music_normal_16px.svg new file mode 100644 index 0000000..11fc1ac --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/music_normal_16px.svg @@ -0,0 +1,19 @@ + + + + music-normal-16px + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/network_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/network_active_16px.svg new file mode 100644 index 0000000..0c502c4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/network_active_16px.svg @@ -0,0 +1,14 @@ + + + + network-server-symbolic-active-16px + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/network_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/network_normal_16px.svg new file mode 100644 index 0000000..89f7382 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/network_normal_16px.svg @@ -0,0 +1,20 @@ + + + + network-server-symbolic-normal-16px + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/pictures_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/pictures_active_16px.svg new file mode 100644 index 0000000..e910398 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/pictures_active_16px.svg @@ -0,0 +1,15 @@ + + + + pictures-active-16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/pictures_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/pictures_normal_16px.svg new file mode 100644 index 0000000..e5d3b08 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/pictures_normal_16px.svg @@ -0,0 +1,17 @@ + + + + pictures-normal-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/recent_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/recent_active_16px.svg new file mode 100644 index 0000000..2fa0548 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/recent_active_16px.svg @@ -0,0 +1,13 @@ + + + + recent-active-16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/recent_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/recent_normal_16px.svg new file mode 100644 index 0000000..27c1b3b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/recent_normal_16px.svg @@ -0,0 +1,16 @@ + + + + recent-normal-16px + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/trash_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/trash_active_16px.svg new file mode 100644 index 0000000..8ab9d91 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/trash_active_16px.svg @@ -0,0 +1,15 @@ + + + + trash-active-16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/trash_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/trash_normal_16px.svg new file mode 100644 index 0000000..c3896be --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/trash_normal_16px.svg @@ -0,0 +1,19 @@ + + + + trash-normal-16px + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/unmount_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/unmount_active_16px.svg new file mode 100644 index 0000000..34e938e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/unmount_active_16px.svg @@ -0,0 +1,17 @@ + + + + unmount_active + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/unmount_hover_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/unmount_hover_16px.svg new file mode 100644 index 0000000..2ec2456 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/unmount_hover_16px.svg @@ -0,0 +1,23 @@ + + + + unmount_hover + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/unmount_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/unmount_normal_16px.svg new file mode 100644 index 0000000..1e9d8d7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/unmount_normal_16px.svg @@ -0,0 +1,17 @@ + + + + unmount_normal + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/unmount_press_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/unmount_press_16px.svg new file mode 100644 index 0000000..cdb0c36 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/unmount_press_16px.svg @@ -0,0 +1,23 @@ + + + + unmount_press + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/usb_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/usb_active_16px.svg new file mode 100644 index 0000000..084bb14 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/usb_active_16px.svg @@ -0,0 +1,13 @@ + + + + drive_harddisk_usb_symbolic_active_16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/usb_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/usb_normal_16px.svg new file mode 100644 index 0000000..49f2bb9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/usb_normal_16px.svg @@ -0,0 +1,21 @@ + + + + drive_harddisk_usb_symbolic_normal_16px + Created with Sketch. + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/usershare_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/usershare_active_16px.svg new file mode 100644 index 0000000..35e761a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/usershare_active_16px.svg @@ -0,0 +1,17 @@ + + + + share-active-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/usershare_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/usershare_normal_16px.svg new file mode 100644 index 0000000..8805393 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/usershare_normal_16px.svg @@ -0,0 +1,17 @@ + + + + share-normal-16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/videos_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/videos_active_16px.svg new file mode 100644 index 0000000..7b6aa01 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/videos_active_16px.svg @@ -0,0 +1,15 @@ + + + + videos-active-16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/videos_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/videos_normal_16px.svg new file mode 100644 index 0000000..d9b867e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/leftsidebar/videos_normal_16px.svg @@ -0,0 +1,22 @@ + + + + videos-normal-16px + Created with Sketch. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/pencil_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/pencil_hover.svg new file mode 100644 index 0000000..ef7349e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/pencil_hover.svg @@ -0,0 +1,12 @@ + + + + pencil_hover + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/pencil_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/pencil_normal.svg new file mode 100644 index 0000000..6ba7dba --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/pencil_normal.svg @@ -0,0 +1,12 @@ + + + + pencil_normal + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/pencil_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/pencil_press.svg new file mode 100644 index 0000000..495a740 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/pencil_press.svg @@ -0,0 +1,12 @@ + + + + pencil_press + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/select.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/select.png new file mode 100644 index 0000000..27413d5 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/select.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/select@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/select@2x.png new file mode 100644 index 0000000..7d97c51 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/select@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/select_deactive.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/select_deactive.png new file mode 100644 index 0000000..c80c23a Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/select_deactive.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/space16.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/space16.png new file mode 100644 index 0000000..7613586 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/light/space16.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/link@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/link@2x.png new file mode 100644 index 0000000..ee5dfdb Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/link@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/link_large.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/link_large.png new file mode 100644 index 0000000..ee5dfdb Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/link_large.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/link_small.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/link_small.png new file mode 100644 index 0000000..57ec4f6 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/link_small.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/lock@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/lock@2x.png new file mode 100644 index 0000000..e6b38bd Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/lock@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/lock_large.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/lock_large.png new file mode 100644 index 0000000..e6b38bd Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/lock_large.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/lock_small.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/lock_small.png new file mode 100644 index 0000000..0f588aa Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/lock_small.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/multiple_files.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/multiple_files.png new file mode 100644 index 0000000..360def0 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/multiple_files.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/multiple_files@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/multiple_files@2x.png new file mode 100644 index 0000000..0c43ba9 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/multiple_files@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/readonly.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/readonly.svg new file mode 100644 index 0000000..b4b7ddb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/readonly.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_hover.png new file mode 100644 index 0000000..f869351 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_hover@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_hover@2x.png new file mode 100644 index 0000000..d09436a Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_hover@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_normal.png new file mode 100644 index 0000000..ccbc0fb Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_normal@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_normal@2x.png new file mode 100644 index 0000000..d0cbb14 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_normal@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_press.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_press.png new file mode 100644 index 0000000..78af8fe Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_press.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_press@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_press@2x.png new file mode 100644 index 0000000..3297a8b Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/setting_press@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/share@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/share@2x.png new file mode 100644 index 0000000..2831b61 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/share@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/share_large.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/share_large.png new file mode 100644 index 0000000..2831b61 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/share_large.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/share_small.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/share_small.png new file mode 100644 index 0000000..8601ef5 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/share_small.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/textMask.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/textMask.png new file mode 100644 index 0000000..8c36251 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/textMask.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/textMask.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/textMask.svg new file mode 100644 index 0000000..da2eca5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/textMask.svg @@ -0,0 +1,74 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/textMask@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/textMask@2x.png new file mode 100644 index 0000000..770e3ee Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/textMask@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/trash.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/trash.png new file mode 100644 index 0000000..5e691a9 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/trash.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/trash@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/trash@2x.png new file mode 100644 index 0000000..a8be7f1 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/trash@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/trash_full.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/trash_full.png new file mode 100644 index 0000000..660a6f1 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/trash_full.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/trash_full@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/trash_full@2x.png new file mode 100644 index 0000000..15cec20 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/trash_full@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/unreadable.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/unreadable.svg new file mode 100644 index 0000000..46dced4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/unreadable.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/unreadable@2x.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/unreadable@2x.png new file mode 100644 index 0000000..8f7bb5e Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/unreadable@2x.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/unreadable_large.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/unreadable_large.png new file mode 100644 index 0000000..8f7bb5e Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/unreadable_large.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/unreadable_small.png b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/unreadable_small.png new file mode 100644 index 0000000..6666f0a Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/images/unreadable_small.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/qss/DesktopItem.qss b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/qss/DesktopItem.qss new file mode 100644 index 0000000..bb645e1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/qss/DesktopItem.qss @@ -0,0 +1,60 @@ +QFrame#DesktopFrame{ + background-color: rgba(0, 0, 0, 0); +} + +QFrame#DesktopItem { + background-color: rgba(0, 0, 0, 0); +/* border: 2px solid rgba(255, 255, 255, 100); + border-radius: 4px;*/ + color:white +} +QLabel#Icon { + background-color: rgba(0, 0, 0, 0); +/* border: 1px solid rgba(255, 255, 255, 255); + border-radius: 4px;*/ + color:white +} +QLabel#Name { + background-color: rgba(0, 0, 0, 0); + border: 1px solid rgba(255, 255, 255, 255); + border-radius: 4px; + color:white +} + +QTextEdit#Rename{ + border:1px solid black; +} + +QFrame#Border{ + background-color: transparent; + border: 2px solid rgba(0, 0, 0, 0); + border-radius: 4px; + color:white +} + +QFrame#AppGroupHover{ + background-color: rgba(255, 255, 255, 0.15); + border: 2px solid rgba(255, 255, 255, 0.15); + border-radius: 4px; + color:white +} + +QFrame#Cut{ + background-color: rgba(0, 0, 0, 0.35); + border: none; + color:white +} + + +QFrame#DragChecked{ + background-color: rgba(0, 0, 0, 0); + border: 2px solid rgba(0, 0, 0, 0); + border-radius: 4px; + color:white +} + +QLineEdit { + background-color: rgba(0, 0, 0, 0); + color:white; + border: None +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/qss/Tablewidget.qss b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/qss/Tablewidget.qss new file mode 100644 index 0000000..a6a96a1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/qss/Tablewidget.qss @@ -0,0 +1,74 @@ +QTableWidget{ + border:none; + background-color: rgba(0, 0, 0, 0); + selection-color: rgba(0, 0, 0, 0); + selection-background-color:rgba(0, 0, 0, 0); +} + +/*******************QScrollBar*****************************/ +QScrollBar:vertical { + border: none; + width: 5px; + margin: 0px 0px 0px 0px; + background: transparent; +} +QScrollBar::handle:vertical { + background: rgba(255, 255, 255, 0.5); + min-height: 5px; +} + +QScrollBar::add-line:vertical { + background: #252A31; + height: 0px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical { + background: #252A31; + height: 0px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +/*QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical { + width: 3px; + height: 3px; + background: #31394E; +}*/ + +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + background: none; +} + + +QScrollBar:horizontal { + border: none; + background: transparent; + height: 5px; + margin: 0px 0px 0px 0px; +} +QScrollBar::handle:horizontal { + background: rgba(255, 255, 255, 0.5); + min-width: 5px; +} +QScrollBar::add-line:horizontal { + background: #252A31; + width: 0px; + subcontrol-position: right; + subcontrol-origin: margin; +} +QScrollBar::sub-line:horizontal { + background: #252A31; + width: 0px; + subcontrol-position: left; + subcontrol-origin: margin; +} +/*QScrollBar:left-arrow:horizontal, QScrollBar::right-arrow:horizontal { + width: 3px; + height: 3px; + background: #31394E; +}*/ +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { + background: none; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/qss/passwordAskDialog.qss b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/qss/passwordAskDialog.qss new file mode 100644 index 0000000..2d7c451 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/qss/passwordAskDialog.qss @@ -0,0 +1,102 @@ +QPushButton#AnonymousButton{ + background-color:white; + border-left: 1px solid rgba(0, 0, 0, 0.1); + border-top: 1px solid rgba(0, 0, 0, 0.1); + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + color: black; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + padding-left: 20px; + padding-right: 20px; +} + +QPushButton#AnonymousButton:checked{ + background-color:#2ca7f8; + color:white; +} + +QPushButton#AnonymousButton:unchecked{ + background-color:white; +} + +QPushButton#RegisterButton{ + background-color:white; + border-top: 1px solid rgba(0, 0, 0, 0.1); + border-right: 1px solid rgba(0, 0, 0, 0.1); + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + color: black; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + padding-left: 20px; + padding-right: 20px; +} + +QPushButton#RegisterButton:checked{ + background-color:#2ca7f8; + color:white; +} + +QPushButton#RegisterButton:unchecked{ + background-color:white; +} + + +/*QCheckBox { + spacing: 5px; +} + +QCheckBox::indicator { + width: 13px; + height: 13px; +} + +QCheckBox::indicator:unchecked { + image: url(:/images/checkbox_unchecked.png); +} + +QCheckBox::indicator:unchecked:hover { + image: url(:/images/checkbox_unchecked_hover.png); +} + +QCheckBox::indicator:unchecked:pressed { + image: url(:/images/checkbox_unchecked_pressed.png); +} + +QCheckBox::indicator:checked { + image: url(:/images/checkbox_checked.png); +} + +QCheckBox::indicator:checked:hover { + image: url(:/images/checkbox_checked_hover.png); +} + +QCheckBox::indicator:checked:pressed { + image: url(:/images/checkbox_checked_pressed.png); +} + +QCheckBox::indicator:indeterminate:hover { + image: url(:/images/checkbox_indeterminate_hover.png); +} + +QCheckBox::indicator:indeterminate:pressed { + image: url(:/images/checkbox_indeterminate_pressed.png); +}*/ + +QLabel { + color: #606060; +} + +QLineEdit{ + background-color: #ffffff; + border: 1px solid rgba(0, 0, 0, 0.1); + padding-left:0px; + selection-background-color: #61B5F8; + border-radius: 4px; +} + +QLineEdit:focus +{ + border: 1px solid rgba(43, 167, 248, 1); +} + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/skin.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/skin.qrc new file mode 100644 index 0000000..5211594 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/skin.qrc @@ -0,0 +1,64 @@ + + + qss/DesktopItem.qss + qss/Tablewidget.qss + + + images/diban.svg + images/readonly.svg + images/textMask.png + images/textMask.svg + images/unreadable.svg + images/trash.png + images/dde-file-manager_96.png + images/dde-file-manager.png + images/dde-file-manager.svg + images/unreadable_small.png + images/unreadable_large.png + images/trash_full.png + images/setting_hover.png + images/setting_normal.png + images/setting_press.png + images/dde-file-manager-admin.png + images/multiple_files.png + images/multiple_files@2x.png + images/setting_press@2x.png + images/setting_normal@2x.png + images/setting_hover@2x.png + images/trash_full@2x.png + images/trash@2x.png + images/dde-file-manager_96@2x.png + images/textMask@2x.png + images/dde-file-manager@2x.png + images/share@2x.png + images/link@2x.png + images/unreadable@2x.png + images/lock@2x.png + images/dde-file-manager-admin@2x.png + images/dde-file-manager_96.svg + + + images/device/drive-harddisk-deepin-256px.svg + images/device/drive-harddisk-ieee1394-256px.svg + images/device/drive-harddisk-linux-256px.svg + images/device/drive-harddisk-mac-256px.svg + images/device/drive-harddisk-scsi-256px.svg + images/device/drive-harddisk-usb-256px.svg + images/device/drive-harddisk-Windows-256px.svg + images/device/drive-harddisk-256px.svg + images/device/drive-optical-256px.svg + images/device/drive-removable-media-ieee1394-256px.svg + images/device/drive-removable-media-scsi-256px.svg + images/device/drive-removable-media-usb-256px.svg + images/device/drive-removable-media-256px.svg + images/device/media-cdr-256px.svg + images/device/media-cdrw-256px.svg + images/device/media-dvd-256px.svg + images/device/media-flash-256px.svg + images/device/media-optical-256px.svg + images/device/android-device-256px.svg + images/device/camera-256px.svg + images/device/drive-network-256px.svg + images/device/ios-device-256px.svg + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newDoc.doc b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newDoc.doc new file mode 100644 index 0000000..7e65651 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newDoc.doc differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newDoc.wps b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newDoc.wps new file mode 100644 index 0000000..ea23e0d Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newDoc.wps differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newExcel.et b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newExcel.et new file mode 100644 index 0000000..5b09a25 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newExcel.et differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newExcel.xls b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newExcel.xls new file mode 100644 index 0000000..626425f Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newExcel.xls differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newPowerPoint.dps b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newPowerPoint.dps new file mode 100644 index 0000000..b15a29f Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newPowerPoint.dps differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newPowerPoint.ppt b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newPowerPoint.ppt new file mode 100644 index 0000000..00abed4 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newPowerPoint.ppt differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newTxt.txt b/dde-file-manager-5.5.3/src/dde-file-manager-lib/skin/templates/newTxt.txt new file mode 100644 index 0000000..e69de29 diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/src.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/src.pri new file mode 100644 index 0000000..47042dd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/src.pri @@ -0,0 +1,481 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-06-24T09:14:17 +# +#------------------------------------------------- +RESOURCES += \ + $$PWD/skin/skin.qrc \ + $$PWD/skin/filemanager.qrc \ + $$PWD/themes/themes.qrc \ + $$PWD/configure.qrc \ + $$PWD/resources/resources.qrc + +HEADERS += \ + $$PWD/controllers/appcontroller.h \ + $$PWD/controllers/dfmrootcontroller.h \ + $$PWD/controllers/dfmappentrycontroller.h \ + $$PWD/models/computermodel.h \ + $$PWD/models/dfmrootfileinfo.h \ + $$PWD/models/dfmappentryfileinfo.h \ + $$PWD/views/computerviewitemdelegate.h \ + $$PWD/views/dtoolbar.h \ + $$PWD/views/dfileview_p.h \ + $$PWD/views/dfileview.h \ + $$PWD/views/ddetailview.h \ + $$PWD/controllers/filecontroller.h \ + $$PWD/app/filesignalmanager.h \ + $$PWD/views/fileitem.h \ + $$PWD/models/desktopfileinfo.h \ + $$PWD/models/bookmark.h \ + $$PWD/models/searchhistory.h \ + $$PWD/controllers/bookmarkmanager.h \ + $$PWD/dialogs/dialogmanager.h \ + $$PWD/controllers/searchhistroymanager.h \ + $$PWD/views/windowmanager.h \ + $$PWD/shutil/desktopfile.h \ + $$PWD/shutil/fileutils.h \ + $$PWD/shutil/properties.h \ + $$PWD/views/dfilemanagerwindow_p.h \ + $$PWD/views/dfilemanagerwindow.h \ + $$PWD/views/historystack.h\ + $$PWD/dialogs/propertydialog.h \ + $$PWD/controllers/trashmanager.h \ + $$PWD/models/trashfileinfo.h \ + $$PWD/shutil/mimesappsmanager.h \ + $$PWD/dialogs/openwithdialog.h \ + $$PWD/controllers/searchcontroller.h \ + $$PWD/models/searchfileinfo.h\ + $$PWD/dialogs/basedialog.h \ + $$PWD/views/extendview.h \ + $$PWD/controllers/pathmanager.h \ + $$PWD/shutil/mimetypedisplaymanager.h \ + $$PWD/views/dstatusbar.h \ + $$PWD/controllers/subscriber.h \ + $$PWD/models/dfileselectionmodel.h \ + $$PWD/dialogs/closealldialogindicator.h \ + $$PWD/gvfs/mountaskpassworddialog.h \ + $$PWD/gvfs/networkmanager.h \ + $$PWD/gvfs/secretmanager.h \ + $$PWD/models/networkfileinfo.h \ + $$PWD/controllers/networkcontroller.h \ + $$PWD/dialogs/trashpropertydialog.h \ + $$PWD/controllers/jobcontroller.h \ + $$PWD/views/computerview.h \ + $$PWD/shutil/shortcut.h \ + $$PWD/views/dtabbar.h \ + $$PWD/views/dfiledialog.h \ + $$PWD/interfaces/dfiledialoghandle.h \ + $$PWD/dialogs/shareinfoframe.h \ + $$PWD/interfaces/dfmstandardpaths.h \ + $$PWD/interfaces/dfmglobal.h \ + $$PWD/controllers/sharecontroler.h \ + $$PWD/models/sharefileinfo.h \ + $$PWD/interfaces/dfileviewhelper.h \ + $$PWD/interfaces/diconitemdelegate.h \ + $$PWD/views/fileviewhelper.h \ + $$PWD/interfaces/dlistitemdelegate.h \ + $$PWD/interfaces/durl.h \ + $$PWD/interfaces/dfilemenu.h \ + $$PWD/interfaces/ddiriterator.h \ + $$PWD/interfaces/private/dstyleditemdelegate_p.h \ + $$PWD/interfaces/dfilesystemmodel.h \ + $$PWD/app/define.h \ + $$PWD/interfaces/dabstractfilecontroller.h \ + $$PWD/interfaces/dabstractfileinfo.h \ + $$PWD/interfaces/dfilemenumanager.h \ + $$PWD/interfaces/dfileservices.h \ + $$PWD/interfaces/dfmevent.h \ + $$PWD/dialogs/usersharepasswordsettingdialog.h\ + $$PWD/interfaces/private/dabstractfileinfo_p.h \ + $$PWD/interfaces/dfileinfo.h \ + $$PWD/interfaces/private/dfileinfo_p.h \ + $$PWD/interfaces/dfilesystemwatcher.h \ + $$PWD/interfaces/private/dfilesystemwatcher_p.h \ + $$PWD/interfaces/dabstractfilewatcher.h \ + $$PWD/interfaces/dfilewatcher.h \ + $$PWD/interfaces/private/dabstractfilewatcher_p.h \ + $$PWD/interfaces/dfileproxywatcher.h \ + $$PWD/plugins/pluginmanager.h \ + $$PWD/interfaces/dthumbnailprovider.h \ + $$PWD/controllers/avfsfilecontroller.h \ + $$PWD/models/avfsfileinfo.h \ + $$PWD/interfaces/dfileiconprovider.h \ + $$PWD/interfaces/dfilewatchermanager.h \ + $$PWD/dialogs/computerpropertydialog.h \ + $$PWD/interfaces/dmimedatabase.h \ + $$PWD/gvfs/qdrive.h \ + $$PWD/gvfs/qvolume.h \ + $$PWD/gvfs/qmount.h \ + $$PWD/gvfs/gvfsmountmanager.h \ + $$PWD/gvfs/qdiskinfo.h \ + $$PWD/interfaces/dfmeventdispatcher.h \ + $$PWD/interfaces/dfmabstracteventhandler.h \ + $$PWD/controllers/fileeventprocessor.h \ + $$PWD/interfaces/dfmbaseview.h \ + $$PWD/interfaces/dfmviewmanager.h \ + $$PWD/views/dfmactionbutton.h \ + $$PWD/interfaces/plugins/dfmviewplugin.h \ + $$PWD/interfaces/plugins/dfmviewfactory.h \ + $$PWD/interfaces/plugins/dfmfactoryloader.h \ + $$PWD/interfaces/plugins/dfmfilecontrollerplugin.h \ + $$PWD/interfaces/plugins/dfmfilecontrollerfactory.h \ + $$PWD/interfaces/plugins/dfmgenericplugin.h \ + $$PWD/interfaces/plugins/dfmgenericfactory.h \ + $$PWD/views/filedialogstatusbar.h \ + $$PWD/interfaces/plugins/dfmfilepreviewplugin.h \ + $$PWD/interfaces/plugins/dfmfilepreviewfactory.h \ + $$PWD/interfaces/dfmfilepreview.h \ + $$PWD/dialogs/filepreviewdialog.h \ + $$PWD/gvfs/mountsecretdiskaskpassworddialog.h \ + $$PWD/views/drenamebar.h \ + $$PWD/shutil/filebatchprocess.h \ + $$PWD/dialogs/ddesktoprenamedialog.h \ + $$PWD/dialogs/dmultifilepropertydialog.h \ + $$PWD/dialogs/movetotrashconflictdialog.h \ + $$PWD/dialogs/dfmsettingdialog.h \ + $$PWD/controllers/operatorrevocation.h \ + $$PWD/controllers/tagcontroller.h \ + $$PWD/models/tagfileinfo.h \ + $$PWD/views/dtagactionwidget.h \ + $$PWD/views/droundbutton.h \ + $$PWD/views/dtagedit.h \ + $$PWD/shutil/dsqlitehandle.h \ + $$PWD/shutil/danythingmonitorfilter.h \ + $$PWD/controllers/tagmanagerdaemoncontroller.h \ + $$PWD/controllers/interface/tagmanagerdaemon_interface.h \ + $$PWD/interfaces/dfmsettings.h \ + $$PWD/interfaces/dfmcrumbbar.h \ + $$PWD/interfaces/dfmcrumbinterface.h \ + $$PWD/interfaces/plugins/dfmcrumbplugin.h \ + $$PWD/interfaces/plugins/dfmcrumbfactory.h \ + $$PWD/interfaces/dfmcrumbmanager.h \ + $$PWD/controllers/dfmfilecrumbcontroller.h \ + $$PWD/controllers/dfmcomputercrumbcontroller.h \ + $$PWD/controllers/dfmbookmarkcrumbcontroller.h \ + $$PWD/controllers/dfmtagcrumbcontroller.h \ + $$PWD/controllers/dfmnetworkcrumbcontroller.h \ + $$PWD/controllers/dfmtrashcrumbcontroller.h \ + $$PWD/controllers/dfmusersharecrumbcontroller.h \ + $$PWD/controllers/dfmavfscrumbcontroller.h \ + $$PWD/controllers/dfmsmbcrumbcontroller.h \ + $$PWD/controllers/dfmmtpcrumbcontroller.h \ + $$PWD/views/dfmaddressbar.h \ + $$PWD/views/dcompleterlistview.h \ + $$PWD/interfaces/dfmapplication.h \ + $$PWD/interfaces/private/dfmapplication_p.h \ + $$PWD/controllers/dfmsearchcrumbcontroller.h \ + $$PWD/views/dfmheaderview.h \ + $$PWD/controllers/mountcontroller.h \ + $$PWD/models/mountfileinfo.h \ + $$PWD/models/recentfileinfo.h \ + $$PWD/controllers/recentcontroller.h \ + $$PWD/controllers/dfmrecentcrumbcontroller.h \ + $$PWD/views/dfmadvancesearchbar.h \ + $$PWD/shutil/dfmregularexpression.h \ + $$PWD/controllers/mergeddesktopcontroller.h \ + $$PWD/models/mergeddesktopfileinfo.h \ + $$PWD/controllers/dfmmdcrumbcontrooler.h \ + $$PWD/interfaces/private/mergeddesktop_common_p.h \ + $$PWD/controllers/masteredmediacontroller.h \ + $$PWD/controllers/dfmmasteredmediacrumbcontroller.h \ + $$PWD/models/masteredmediafileinfo.h \ + $$PWD/views/dfmopticalmediawidget.h \ + $$PWD/views/dfmrightdetailview.h \ + $$PWD/dialogs/burnoptdialog.h \ + $$PWD/interfaces/dfmcrumblistviewmodel.h \ + $$PWD/interfaces/dfmstyleditemdelegate.h \ + $$PWD/views/dfmsidebaritemdelegate.h \ + $$PWD/models/dfmsidebarmodel.h \ + $$PWD/views/dfmsidebarview.h \ + $$PWD/interfaces/dfmsidebariteminterface.h \ + $$PWD/interfaces/dfmsidebarmanager.h \ + $$PWD/controllers/dfmsidebardeviceitemhandler.h \ + $$PWD/controllers/dfmsidebartagitemhandler.h \ + $$PWD/controllers/dfmsidebardefaultitemhandler.h \ + $$PWD/controllers/dfmsidebarbookmarkitemhandler.h \ + $$PWD/interfaces/dfmsidebaritem.h \ + $$PWD/views/dfmsidebar.h \ + $$PWD/views/dfmfilebasicinfowidget.h \ + $$PWD/views/dfmtagwidget.h \ + $$PWD/controllers/vaultcontroller.h \ + $$PWD/models/vaultfileinfo.h \ + $$PWD/controllers/dfmvaultcrumbcontroller.h \ + $$PWD/views/dfmvaultunlockpages.h \ + $$PWD/views/dfmvaultfileview.h \ + $$PWD/views/dfmvaultrecoverykeypages.h \ + $$PWD/plugins/dfmadditionalmenu_p.h \ + $$PWD/plugins/dfmadditionalmenu.h \ + $$PWD/dialogs/connecttoserverdialog.h \ + $$PWD/shutil/dfmfilelistfile.h \ + $$PWD/views/dfmsplitter.h \ + $$PWD/dbus/dbussysteminfo.h \ + $$PWD/models/deviceinfoparser.h \ + $$PWD/controllers/dfmsidebarvaultitemhandler.h \ + $$PWD/controllers/vaulthandle.h \ + $$PWD/controllers/vaulterrorcode.h \ + $$PWD/views/dfmvaultremovepages.h \ + $$PWD/views/dfmvaultactiveview.h \ + $$PWD/views/dfmvaultactivestartview.h \ + $$PWD/views/dfmvaultactivesavekeyview.h \ + $$PWD/views/dfmvaultactivefinishedview.h \ + $$PWD/views/dfmvaultactivesetunlockmethodview.h \ + $$PWD/views/dfmvaultremoveprogressview.h \ + $$PWD/views/dfmvaultremovebypasswordview.h \ + $$PWD/views/dfmvaultremovebyrecoverykeyview.h \ + $$PWD/views/dfmvaultpagebase.h \ + $$PWD/bluetooth/bluetoothmanager.h \ + $$PWD/bluetooth/bluetoothadapter.h \ + $$PWD/bluetooth/bluetoothdevice.h \ + $$PWD/bluetooth/bluetoothmodel.h \ + $$PWD/bluetooth/bluetoothtransdialog.h \ + $$PWD/interfaces/drootfilemanager.h \ + $$PWD/interfaces/dgvfsfileinfo.h \ + $$PWD/interfaces/private/dgvfsfileinfo_p.h \ + $$PWD/shutil/checknetwork.h \ + $$PWD/accessibility/ac-lib-file-manager.h \ + $$PWD/accessibility/acintelfunctions.h \ + $$PWD/bluetooth/bluetoothmanager_p.h \ + $$PWD/models/virtualentryinfo.h \ + $$PWD/models/trashfileinfo_p.h \ + $$PWD/controllers/mergeddesktopcontroller_p.h \ + $$PWD/controllers/masteredmediacontroller_p.h \ + $$PWD/interfaces/plugins/private/dfmfactoryloader_p.h \ + $$PWD/interfaces/plugins/private/dfmfilepreviewfactory_p.h \ + $$PWD/dialogs/private/ddesktoprenamedialog_p.h \ + $$PWD/dialogs/private/dfmsettingdialog_p.h \ + $$PWD/interfaces/plugins/private/dfmviewfactory_p.h \ + $$PWD/models/dfmrootfileinfo_p.h \ + $$PWD/models/dfmappentryfileinfo_p.h \ + $$PWD/interfaces/private/dfmcrumbbar_p.h \ + $$PWD/interfaces/defenderinterface.h \ + $$PWD/interfaces/dumountmanager.h \ + $$PWD/controllers/dfmftpcrumbcontroller.h \ + $$PWD/controllers/dfmsftpcrumbcontroller.h \ + $$PWD/views/dfmvaultactivesavekeyfileview.h \ + $$PWD/views/dfmvaultretrievepassword.h \ + $$PWD/plugins/schemeplugininterface.h \ + $$PWD/plugins/schemepluginmanager.h + +SOURCES += \ + $$PWD/controllers/appcontroller.cpp \ + $$PWD/controllers/dfmrootcontroller.cpp \ + $$PWD/controllers/dfmappentrycontroller.cpp \ + $$PWD/models/computermodel.cpp \ + $$PWD/models/dfmrootfileinfo.cpp \ + $$PWD/models/dfmappentryfileinfo.cpp \ + $$PWD/views/computerviewitemdelegate.cpp \ + $$PWD/views/dtoolbar.cpp \ + $$PWD/views/dfileview.cpp \ + $$PWD/views/ddetailview.cpp \ + $$PWD/controllers/filecontroller.cpp \ + $$PWD/views/fileitem.cpp \ + $$PWD/models/desktopfileinfo.cpp \ + $$PWD/models/bookmark.cpp \ + $$PWD/models/searchhistory.cpp \ + $$PWD/controllers/bookmarkmanager.cpp \ + $$PWD/dialogs/dialogmanager.cpp \ + $$PWD/controllers/searchhistroymanager.cpp \ + $$PWD/views/windowmanager.cpp \ + $$PWD/shutil/desktopfile.cpp \ + $$PWD/shutil/fileutils.cpp \ + $$PWD/shutil/properties.cpp \ + $$PWD/views/dfilemanagerwindow.cpp \ + $$PWD/views/historystack.cpp\ + $$PWD/dialogs/propertydialog.cpp \ + $$PWD/controllers/trashmanager.cpp \ + $$PWD/models/trashfileinfo.cpp \ + $$PWD/shutil/mimesappsmanager.cpp \ + $$PWD/dialogs/openwithdialog.cpp \ + $$PWD/controllers/searchcontroller.cpp \ + $$PWD/models/searchfileinfo.cpp\ + $$PWD/dialogs/basedialog.cpp \ + $$PWD/views/extendview.cpp \ + $$PWD/controllers/pathmanager.cpp \ + $$PWD/shutil/mimetypedisplaymanager.cpp \ + $$PWD/views/dstatusbar.cpp \ + $$PWD/controllers/subscriber.cpp \ + $$PWD/models/dfileselectionmodel.cpp \ + $$PWD/dialogs/closealldialogindicator.cpp \ + $$PWD/gvfs/mountaskpassworddialog.cpp \ + $$PWD/gvfs/networkmanager.cpp \ + $$PWD/gvfs/secretmanager.cpp \ + $$PWD/models/networkfileinfo.cpp \ + $$PWD/controllers/networkcontroller.cpp \ + $$PWD/dialogs/trashpropertydialog.cpp \ + $$PWD/controllers/jobcontroller.cpp \ + $$PWD/views/computerview.cpp \ + $$PWD/shutil/shortcut.cpp \ + $$PWD/views/dtabbar.cpp \ + $$PWD/views/dfiledialog.cpp \ + $$PWD/interfaces/dfiledialoghandle.cpp \ + $$PWD/dialogs/shareinfoframe.cpp \ + $$PWD/interfaces/dfmstandardpaths.cpp \ + $$PWD/interfaces/dfmglobal.cpp \ + $$PWD/controllers/sharecontroler.cpp \ + $$PWD/models/sharefileinfo.cpp \ + $$PWD/interfaces/dfileviewhelper.cpp \ + $$PWD/interfaces/diconitemdelegate.cpp \ + $$PWD/views/fileviewhelper.cpp \ + $$PWD/interfaces/dlistitemdelegate.cpp \ + $$PWD/interfaces/durl.cpp \ + $$PWD/interfaces/dfilemenu.cpp \ + $$PWD/interfaces/dfilesystemmodel.cpp \ + $$PWD/app/define.cpp \ + $$PWD/interfaces/dabstractfilecontroller.cpp \ + $$PWD/interfaces/dabstractfileinfo.cpp \ + $$PWD/interfaces/dfilemenumanager.cpp \ + $$PWD/interfaces/dfileservices.cpp \ + $$PWD/interfaces/dfmevent.cpp \ + $$PWD/interfaces/dfileinfo.cpp \ + $$PWD/interfaces/dfilesystemwatcher.cpp \ + $$PWD/interfaces/dabstractfilewatcher.cpp \ + $$PWD/interfaces/dfilewatcher.cpp \ + $$PWD/interfaces/dfileproxywatcher.cpp \ + $$PWD/app/filesignalmanager.cpp \ + $$PWD/plugins/pluginmanager.cpp \ + $$PWD/interfaces/dthumbnailprovider.cpp \ + $$PWD/controllers/avfsfilecontroller.cpp \ + $$PWD/models/avfsfileinfo.cpp \ + $$PWD/interfaces/dfileiconprovider.cpp \ + $$PWD/interfaces/dfilewatchermanager.cpp \ + $$PWD/dialogs/computerpropertydialog.cpp \ + $$PWD/interfaces/dmimedatabase.cpp \ + $$PWD/gvfs/qdrive.cpp \ + $$PWD/gvfs/qvolume.cpp \ + $$PWD/gvfs/qmount.cpp \ + $$PWD/gvfs/gvfsmountmanager.cpp \ + $$PWD/gvfs/qdiskinfo.cpp \ + $$PWD/interfaces/dfmeventdispatcher.cpp \ + $$PWD/interfaces/dfmabstracteventhandler.cpp \ + $$PWD/controllers/fileeventprocessor.cpp \ + $$PWD/interfaces/dfmbaseview.cpp \ + $$PWD/interfaces/dfmviewmanager.cpp \ + $$PWD/views/dfmactionbutton.cpp \ + $$PWD/interfaces/plugins/dfmviewplugin.cpp \ + $$PWD/interfaces/plugins/dfmviewfactory.cpp \ + $$PWD/interfaces/plugins/dfmfactoryloader.cpp \ + $$PWD/interfaces/plugins/dfmfilecontrollerplugin.cpp \ + $$PWD/interfaces/plugins/dfmfilecontrollerfactory.cpp \ + $$PWD/interfaces/plugins/dfmgenericplugin.cpp \ + $$PWD/interfaces/plugins/dfmgenericfactory.cpp \ + $$PWD/views/filedialogstatusbar.cpp \ + $$PWD/interfaces/plugins/dfmfilepreviewplugin.cpp \ + $$PWD/interfaces/plugins/dfmfilepreviewfactory.cpp \ + $$PWD/interfaces/dfmfilepreview.cpp \ + $$PWD/dialogs/filepreviewdialog.cpp \ + $$PWD/dialogs/usersharepasswordsettingdialog.cpp\ + $$PWD/gvfs/mountsecretdiskaskpassworddialog.cpp \ + $$PWD/views/drenamebar.cpp \ + $$PWD/shutil/filebatchprocess.cpp \ + $$PWD/dialogs/ddesktoprenamedialog.cpp \ + $$PWD/dialogs/dmultifilepropertydialog.cpp \ + $$PWD/dialogs/movetotrashconflictdialog.cpp \ + $$PWD/dialogs/dfmsettingdialog.cpp \ + $$PWD/controllers/operatorrevocation.cpp \ + $$PWD/controllers/tagcontroller.cpp \ + $$PWD/models/tagfileinfo.cpp \ + $$PWD/views/dtagactionwidget.cpp \ + $$PWD/views/droundbutton.cpp \ + $$PWD/views/dtagedit.cpp \ + $$PWD/shutil/dsqlitehandle.cpp \ + $$PWD/shutil/danythingmonitorfilter.cpp \ + $$PWD/controllers/tagmanagerdaemoncontroller.cpp \ + $$PWD/controllers/interface/tagmanagerdaemon_interface.cpp \ + $$PWD/interfaces/dfmsettings.cpp \ + $$PWD/interfaces/dfmcrumbbar.cpp \ + $$PWD/interfaces/dfmcrumbinterface.cpp \ + $$PWD/interfaces/plugins/dfmcrumbplugin.cpp \ + $$PWD/interfaces/plugins/dfmcrumbfactory.cpp \ + $$PWD/interfaces/dfmcrumbmanager.cpp \ + $$PWD/controllers/dfmfilecrumbcontroller.cpp \ + $$PWD/controllers/dfmcomputercrumbcontroller.cpp \ + $$PWD/controllers/dfmbookmarkcrumbcontroller.cpp \ + $$PWD/controllers/dfmtagcrumbcontroller.cpp \ + $$PWD/controllers/dfmnetworkcrumbcontroller.cpp \ + $$PWD/controllers/dfmtrashcrumbcontroller.cpp \ + $$PWD/controllers/dfmusersharecrumbcontroller.cpp \ + $$PWD/controllers/dfmavfscrumbcontroller.cpp \ + $$PWD/controllers/dfmsmbcrumbcontroller.cpp \ + $$PWD/controllers/dfmmtpcrumbcontroller.cpp \ + $$PWD/views/dfmaddressbar.cpp \ + $$PWD/views/dcompleterlistview.cpp \ + $$PWD/interfaces/dfmapplication.cpp \ + $$PWD/controllers/dfmsearchcrumbcontroller.cpp\ + $$PWD/views/dfmheaderview.cpp \ + $$PWD/controllers/mountcontroller.cpp \ + $$PWD/models/mountfileinfo.cpp \ + $$PWD/models/recentfileinfo.cpp \ + $$PWD/controllers/recentcontroller.cpp \ + $$PWD/controllers/dfmrecentcrumbcontroller.cpp \ + $$PWD/views/dfmadvancesearchbar.cpp \ + $$PWD/shutil/dfmregularexpression.cpp \ + $$PWD/models/mergeddesktopfileinfo.cpp \ + $$PWD/controllers/dfmmdcrumbcontrooler.cpp \ + $$PWD/controllers/mergeddesktopcontroller.cpp \ + $$PWD/controllers/masteredmediacontroller.cpp \ + $$PWD/controllers/dfmmasteredmediacrumbcontroller.cpp \ + $$PWD/models/masteredmediafileinfo.cpp \ + $$PWD/views/dfmopticalmediawidget.cpp \ + $$PWD/views/dfmrightdetailview.cpp \ + $$PWD/dialogs/burnoptdialog.cpp \ + $$PWD/interfaces/dfmcrumblistviewmodel.cpp \ + $$PWD/interfaces/dfmstyleditemdelegate.cpp \ + $$PWD/views/dfmsidebaritemdelegate.cpp \ + $$PWD/models/dfmsidebarmodel.cpp \ + $$PWD/views/dfmsidebarview.cpp \ + $$PWD/interfaces/dfmsidebariteminterface.cpp \ + $$PWD/interfaces/dfmsidebarmanager.cpp \ + $$PWD/controllers/dfmsidebardeviceitemhandler.cpp \ + $$PWD/controllers/dfmsidebartagitemhandler.cpp \ + $$PWD/controllers/dfmsidebardefaultitemhandler.cpp \ + $$PWD/controllers/dfmsidebarbookmarkitemhandler.cpp \ + $$PWD/interfaces/dfmsidebaritem.cpp \ + $$PWD/views/dfmsidebar.cpp \ + $$PWD/views/dfmfilebasicinfowidget.cpp \ + $$PWD/views/dfmtagwidget.cpp \ + $$PWD/controllers/vaultcontroller.cpp \ + $$PWD/models/vaultfileinfo.cpp \ + $$PWD/controllers/dfmvaultcrumbcontroller.cpp \ + $$PWD/views/dfmvaultunlockpages.cpp \ + $$PWD/views/dfmvaultfileview.cpp \ + $$PWD/views/dfmvaultrecoverykeypages.cpp \ + $$PWD/plugins/dfmadditionalmenu.cpp \ + $$PWD/dialogs/connecttoserverdialog.cpp \ + $$PWD/shutil/dfmfilelistfile.cpp \ + $$PWD/views/dfmsplitter.cpp \ + $$PWD/dbus/dbussysteminfo.cpp \ + $$PWD/models/deviceinfoparser.cpp \ + $$PWD/controllers/dfmsidebarvaultitemhandler.cpp \ + $$PWD/controllers/vaulthandle.cpp \ + $$PWD/views/dfmvaultremovepages.cpp \ + $$PWD/views/dfmvaultactiveview.cpp \ + $$PWD/views/dfmvaultactivestartview.cpp \ + $$PWD/views/dfmvaultactivesavekeyview.cpp \ + $$PWD/views/dfmvaultactivefinishedview.cpp \ + $$PWD/views/dfmvaultactivesetunlockmethodview.cpp \ + $$PWD/views/dfmvaultremoveprogressview.cpp \ + $$PWD/views/dfmvaultremovebypasswordview.cpp \ + $$PWD/views/dfmvaultremovebyrecoverykeyview.cpp \ + $$PWD/views/dfmvaultpagebase.cpp \ + $$PWD/bluetooth/bluetoothmanager.cpp \ + $$PWD/bluetooth/bluetoothadapter.cpp \ + $$PWD/bluetooth/bluetoothdevice.cpp \ + $$PWD/bluetooth/bluetoothmodel.cpp \ + $$PWD/bluetooth/bluetoothtransdialog.cpp \ + $$PWD/interfaces/drootfilemanager.cpp \ + $$PWD/interfaces/dgvfsfileinfo.cpp \ + $$PWD/shutil/checknetwork.cpp \ + $$PWD/interfaces/defenderinterface.cpp \ + $$PWD/interfaces/dumountmanager.cpp \ + $$PWD/controllers/dfmftpcrumbcontroller.cpp \ + $$PWD/controllers/dfmsftpcrumbcontroller.cpp \ + $$PWD/views/dfmvaultactivesavekeyfileview.cpp \ + $$PWD/views/dfmvaultretrievepassword.cpp \ + $$PWD/plugins/schemepluginmanager.cpp + +!CONFIG(DISABLE_ANYTHING) { + HEADERS += $$PWD/shutil/danythingmonitor.h + SOURCES += $$PWD/shutil/danythingmonitor.cpp +} + +INCLUDEPATH += $$PWD diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/filemanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/filemanager.h new file mode 100644 index 0000000..ea270aa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/filemanager.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifdef __cplusplus +extern "C" +{ + /********************************************* + 函数功能:动态加载右键菜单 + 参数说明:path 文件全路径 + 返回值:如文件需要动态加载右键菜单,则返回值为Json格式的字符串, + 如不需要加载右键菜单,则返回值为字符串No。 + Json中的选项为:id,label,icon,tip,sub. + id为右键菜单的唯一标识,要求唯一,id用于识别哪个菜单触发点击事件。 + label为在右键菜单显示的文字或标识。 + icon为在右键菜单上显示的图标全路径。 + tip为提示性字符串,可为空。 + sub内容为子菜单,内容为Json格式(目前只使用到一级菜单) + **********************************************/ + char *auto_add_rightmenu(char *path); + /********************************************* + 函数功能: 点击右键操作函数 + 该函数根据strid,实现用户对选中文件进行的具体操作 + 参数说明:path 文件全路径 + strid:右键唯一标识码(该值在auto_add_rightmenu函数中设置) + 返回值:无 + **********************************************/ + void *auto_operation(char *path,char *strid); + /********************************************* + 函数功能:获取角标 + 参数说明:path 文件全路径 + 返回值:角标文件全路径 + *********************************************/ + char *auto_add_emblem(char *path); + /********************************************* + 函数功能:初始化标签系统(确保整个进程只调用一次) + 参数说明:无 + 返回值:无 + *********************************************/ + void InitLLSInfo(); + /********************************************* + 函数功能:释放内存(针对返回的数据内存,操作系统使用完成后,需要释放) + 参数说明:无 + 返回值:无 + *********************************************/ + void free_memory(void*); +} +#endif diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/filemanagerlibrary.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/filemanagerlibrary.cpp new file mode 100644 index 0000000..8a092bd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/filemanagerlibrary.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "filemanagerlibrary.h" +#include +#include + +FileManagerLibrary::FileManagerLibrary() +{ + loadLibrary(LibraryName()); +} + +void FileManagerLibrary::loadLibrary(const QString &fileName) +{ + QLibrary lib(fileName); + bool isLoaded = lib.load(); + if (isLoaded){ + m_auto_add_rightmenu = (func_auto_add_rightmenu) lib.resolve("auto_add_rightmenu"); + m_auto_operation = (func_auto_operation) lib.resolve("auto_operation"); + m_auto_add_emblem = (func_auto_add_emblem) lib.resolve("auto_add_emblem"); + m_InitLLSInfo = (func_InitLLSInfo) lib.resolve("InitLLSInfo"); + m_free_memory = (func_free_memory) lib.resolve("free_memory"); + + if (m_auto_add_rightmenu && m_auto_operation && m_auto_add_emblem && m_InitLLSInfo && m_free_memory){ + m_isCompletion = true; + } + }else{ + qDebug() << "load library " << LibraryName() << "failed: " << lib.errorString(); + } +} + +FileManagerLibrary::func_auto_add_rightmenu FileManagerLibrary::auto_add_rightmenu() const +{ + return m_auto_add_rightmenu; +} + +void FileManagerLibrary::setAuto_add_rightmenu(const func_auto_add_rightmenu &auto_add_rightmenu) +{ + m_auto_add_rightmenu = auto_add_rightmenu; +} + +FileManagerLibrary::func_auto_operation FileManagerLibrary::auto_operation() const +{ + return m_auto_operation; +} + +void FileManagerLibrary::setAuto_operation(const func_auto_operation &auto_operation) +{ + m_auto_operation = auto_operation; +} + +FileManagerLibrary::func_auto_add_emblem FileManagerLibrary::auto_add_emblem() const +{ + return m_auto_add_emblem; +} + +void FileManagerLibrary::setAuto_add_emblem(const func_auto_add_emblem &auto_add_emblem) +{ + m_auto_add_emblem = auto_add_emblem; +} + +FileManagerLibrary::func_InitLLSInfo FileManagerLibrary::InitLLSInfo() const +{ + return m_InitLLSInfo; +} + +void FileManagerLibrary::setInitLLSInfo(const func_InitLLSInfo &InitLLSInfo) +{ + m_InitLLSInfo = InitLLSInfo; +} + +FileManagerLibrary::func_free_memory FileManagerLibrary::free_memory() const +{ + return m_free_memory; +} + +void FileManagerLibrary::setFree_memory(const func_free_memory &free_memory) +{ + m_free_memory = free_memory; +} + +bool FileManagerLibrary::isCompletion() const +{ + return m_isCompletion; +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/filemanagerlibrary.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/filemanagerlibrary.h new file mode 100644 index 0000000..7bfdfaf --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/filemanagerlibrary.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef FILEMANAGERLIBRARY_H +#define FILEMANAGERLIBRARY_H + +#include + +class FileManagerLibrary +{ +public: + + static FileManagerLibrary* instance(){ + static FileManagerLibrary instance; + return &instance; + } + + inline static QString LibraryName(){ + return "/usr/lib/sw_64-linux-gnu/dde-file-manager/libfilemanager.so"; + } + + void loadLibrary(const QString& fileName); + + typedef char *(*func_auto_add_rightmenu)(char *path); + typedef void *(*func_auto_operation)(char *path,char *strid); + typedef char *(*func_auto_add_emblem)(char *path); + typedef void (*func_InitLLSInfo)(); + typedef void (*func_free_memory)(void*); + + func_auto_add_rightmenu auto_add_rightmenu() const; + void setAuto_add_rightmenu(const func_auto_add_rightmenu &auto_add_rightmenu); + + func_auto_operation auto_operation() const; + void setAuto_operation(const func_auto_operation &auto_operation); + + func_auto_add_emblem auto_add_emblem() const; + void setAuto_add_emblem(const func_auto_add_emblem &auto_add_emblem); + + func_InitLLSInfo InitLLSInfo() const; + void setInitLLSInfo(const func_InitLLSInfo &InitLLSInfo); + + func_free_memory free_memory() const; + void setFree_memory(const func_free_memory &free_memory); + + bool isCompletion() const; + +private: + FileManagerLibrary(); + FileManagerLibrary(const FileManagerLibrary &); + FileManagerLibrary & operator = (const FileManagerLibrary &); + + bool m_isCompletion = false; + func_auto_add_rightmenu m_auto_add_rightmenu = NULL; + func_auto_operation m_auto_operation = NULL; + func_auto_add_emblem m_auto_add_emblem = NULL; + func_InitLLSInfo m_InitLLSInfo = NULL; + func_free_memory m_free_memory = NULL; +}; + +#endif // FILEMANAGERLIBRARY_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/libinstall.sh b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/libinstall.sh new file mode 100755 index 0000000..6c9adf0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/libinstall.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +mkdir /usr/lib/sw_64-linux-gnu/dde-file-manager +cp libfilemanager.so libllsdeeplabel.so /usr/lib/sw_64-linux-gnu/dde-file-manager diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/llsdeepinlabellibrary.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/llsdeepinlabellibrary.cpp new file mode 100644 index 0000000..afee847 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/llsdeepinlabellibrary.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "llsdeepinlabellibrary.h" + +#include +#include + +LlsDeepinLabelLibrary::LlsDeepinLabelLibrary() +{ + loadLibrary(LibraryName()); +} + +void LlsDeepinLabelLibrary::loadLibrary(const QString &fileName) +{ + QLibrary lib(fileName); + bool isLoaded = lib.load(); + if (isLoaded){ + m_lls_simplechecklabel = (func_lls_simplechecklabel) lib.resolve("lls_simplechecklabel"); + m_lls_fullchecklabel = (func_lls_fullchecklabel) lib.resolve("lls_fullchecklabel"); + m_lls_checkprivilege = (func_lls_checkprivilege) lib.resolve("lls_checkprivilege"); + m_lls_geterrordesc = (func_lls_geterrordesc) lib.resolve("lls_geterrordesc"); + qDebug() << fileName << m_lls_simplechecklabel << m_lls_fullchecklabel << m_lls_checkprivilege << m_lls_geterrordesc << lib.errorString(); + if (m_lls_simplechecklabel && m_lls_fullchecklabel && m_lls_checkprivilege && m_lls_geterrordesc){ + m_isCompletion = true; + } + }else{ + qDebug() << "load library " << LibraryName() << "failed: " << lib.errorString(); + } +} + +bool LlsDeepinLabelLibrary::isCompletion() const +{ + return m_isCompletion; +} + +LlsDeepinLabelLibrary::func_lls_geterrordesc LlsDeepinLabelLibrary::lls_geterrordesc() const +{ + return m_lls_geterrordesc; +} + +void LlsDeepinLabelLibrary::setLls_geterrordesc(const func_lls_geterrordesc &lls_geterrordesc) +{ + m_lls_geterrordesc = lls_geterrordesc; +} + +LlsDeepinLabelLibrary::func_lls_checkprivilege LlsDeepinLabelLibrary::lls_checkprivilege() const +{ + return m_lls_checkprivilege; +} + +void LlsDeepinLabelLibrary::setLls_checkprivilege(const func_lls_checkprivilege &lls_checkprivilege) +{ + m_lls_checkprivilege = lls_checkprivilege; +} + +LlsDeepinLabelLibrary::func_lls_fullchecklabel LlsDeepinLabelLibrary::lls_fullchecklabel() const +{ + return m_lls_fullchecklabel; +} + +void LlsDeepinLabelLibrary::setLls_fullchecklabel(const func_lls_fullchecklabel &lls_fullchecklabel) +{ + m_lls_fullchecklabel = lls_fullchecklabel; +} + +LlsDeepinLabelLibrary::func_lls_simplechecklabel LlsDeepinLabelLibrary::lls_simplechecklabel() const +{ + return m_lls_simplechecklabel; +} + +void LlsDeepinLabelLibrary::setLls_simplechecklabel(const func_lls_simplechecklabel &lls_simplechecklabel) +{ + m_lls_simplechecklabel = lls_simplechecklabel; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/llsdeepinlabellibrary.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/llsdeepinlabellibrary.h new file mode 100644 index 0000000..1eb5332 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/llsdeepinlabellibrary.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef LLSDEEPINLABELLIBRARY_H +#define LLSDEEPINLABELLIBRARY_H + +#include +#include +using namespace std; + +//文件操作行为/操作权限 +enum FilePrivilege56 +{ + E_FILE_PRI_READ=1, //1、可读 + E_FILE_PRI_WRITE=2, //2、可写 + E_FILE_PRI_PRINT=3, //3、可打印 + E_FILE_PRI_COPY=4, //4、可复制 + E_FILE_PRI_DVD=5, //5、可刻光盘 + E_FILE_PRI_STORE=6, //6、可存储到移动介质 + E_FILE_PRI_RENAME=7, //7、可重命名 + E_FILE_PRI_DELETE=8, //8、可删除 + E_FILE_PRI_MOVE=9, //9、可移动 + E_FILE_PRI_COPY_CONTENT=10, //10、文件内容复制粘贴 + +}; + +//错误级别 +enum ErrorLevel +{ + ERR_INFO=1, //1、提示信息 + ERR_WARNING=2, //2、警告 + ERR_ERROR=3, //3、错误 +}; + +class LlsDeepinLabelLibrary +{ +public: + + static LlsDeepinLabelLibrary* instance(){ + static LlsDeepinLabelLibrary instance; + return &instance; + } + + inline static QString LibraryName(){ + return "/usr/lib/sw_64-linux-gnu/dde-file-manager/libllsdeeplabel.so"; + } + + void loadLibrary(const QString& fileName); + + typedef int (*func_lls_simplechecklabel)(char *filename); + typedef int (*func_lls_fullchecklabel)(char *filename); + typedef int (*func_lls_checkprivilege)(char *srcfilename, char *dstfilename, int iFilePrivilege56); + typedef int (*func_lls_geterrordesc)(int ierrorcode, string &serrordesc, int &ierrorlevel); + + bool isCompletion() const; + + func_lls_simplechecklabel lls_simplechecklabel() const; + void setLls_simplechecklabel(const func_lls_simplechecklabel &lls_simplechecklabel); + + func_lls_fullchecklabel lls_fullchecklabel() const; + void setLls_fullchecklabel(const func_lls_fullchecklabel &lls_fullchecklabel); + + func_lls_checkprivilege lls_checkprivilege() const; + void setLls_checkprivilege(const func_lls_checkprivilege &lls_checkprivilege); + + func_lls_geterrordesc lls_geterrordesc() const; + void setLls_geterrordesc(const func_lls_geterrordesc &lls_geterrordesc); + +private: + LlsDeepinLabelLibrary(); + LlsDeepinLabelLibrary(const LlsDeepinLabelLibrary &); + LlsDeepinLabelLibrary & operator = (const LlsDeepinLabelLibrary &); + + bool m_isCompletion = false; + func_lls_simplechecklabel m_lls_simplechecklabel = NULL; + func_lls_fullchecklabel m_lls_fullchecklabel = NULL; + func_lls_checkprivilege m_lls_checkprivilege = NULL; + func_lls_geterrordesc m_lls_geterrordesc = NULL; +}; + +#endif // LLSDEEPINLABELLIBRARY_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/llsdeeplabel.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/llsdeeplabel.h new file mode 100644 index 0000000..eabcb73 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/llsdeeplabel.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#pragma once +#include +using namespace std; + +//文件操作行为/操作权限 +enum FilePrivilege56 +{ + E_FILE_PRI_READ=1, //1、可读 + E_FILE_PRI_WRITE=2, //2、可写 + E_FILE_PRI_PRINT=3, //3、可打印 + E_FILE_PRI_COPY=4, //4、可复制 + E_FILE_PRI_DVD=5, //5、可刻光盘 + E_FILE_PRI_STORE=6, //6、可存储到移动介质 + E_FILE_PRI_RENAME=7, //7、可重命名 + E_FILE_PRI_DELETE=8, //8、可删除 + E_FILE_PRI_MOVE=9, //9、可移动 + E_FILE_PRI_COPY_CONTENT=10, //10、文件内容复制粘贴 + +}; + +//错误级别 +enum ErrorLevel +{ + ERR_INFO=1, //1、提示信息 + ERR_WARNING=2, //2、警告 + ERR_ERROR=3, //3、错误 +}; + + +//----------------------------------------------- +//功能描述:简单校验是否为标签文件(不准确,但效率高) +//参数:filename=文件全路径名称 +//返回:0=标签文件;其它=非标签文件 +//说明: +//----------------------------------------------- +int lls_simplechecklabel(char *filename); + +//----------------------------------------------- +//功能描述:完整检验是否为标签文件(准确,但效率低) +//参数:filename=文件全路径名称 +//返回:0=标签文件;其它=非标签文件 +//说明: +//----------------------------------------------- +int lls_fullchecklabel(char *filename); + +//----------------------------------------------- +//功能描述:判断文件是否允许执行该操作(是否具有操作权限) +//参数:srcfilename=文件全路径名称; +// dstfilename=目标文件全路径名称; +// iFilePrivilege56=文件操作权限/行为 +//返回:0=有权限;其它=错误码 +//说明: +//----------------------------------------------- +int lls_checkprivilege(char *srcfilename, char *dstfilename, int iFilePrivilege56); + +//----------------------------------------------- +//功能描述:根据错误码,获取“错误级别”和“错误描述” +//参数:ierrorcode=错误码; +// serrordesc=错误描述; +// iErrorLevel=错误级别 +//返回:0=成功;其它=失败 +//说明: +//----------------------------------------------- +int lls_geterrordesc(int ierrorcode, string &serrordesc, int &ierrorlevel); diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/sw_label.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/sw_label.pri new file mode 100644 index 0000000..12b7e8a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/sw_label/sw_label.pri @@ -0,0 +1,7 @@ +HEADERS += \ + $$PWD/filemanagerlibrary.h \ + $$PWD/llsdeepinlabellibrary.h + +SOURCES += \ + $$PWD/filemanagerlibrary.cpp \ + $$PWD/llsdeepinlabellibrary.cpp diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tag.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tag.pri new file mode 100644 index 0000000..30e04be --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tag.pri @@ -0,0 +1,11 @@ + +QT += sql + + +HEADERS += \ + $$PWD/tagmanager.h \ + $$PWD/tagutil.h + +SOURCES += \ + $$PWD/tagmanager.cpp \ + $$PWD/tagutil.cpp diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tagmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tagmanager.cpp new file mode 100644 index 0000000..67bcd98 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tagmanager.cpp @@ -0,0 +1,495 @@ + + +#include +#include +#include + +#include "tagmanager.h" +#ifndef DDE_ANYTHINGMONITOR +#include "singleton.h" +#include "tag/tagutil.h" +#include "shutil/dsqlitehandle.h" +#include "app/filesignalmanager.h" +#include "controllers/appcontroller.h" +#endif +#include "controllers/tagmanagerdaemoncontroller.h" + +#ifndef DDE_ANYTHINGMONITOR +#include "dfileservices.h" +#endif + +#include +#include +#include +#include +#include + +#ifndef DDE_ANYTHINGMONITOR +static QString randomColor() noexcept +{ + std::random_device device{}; + + ///###: Choose a random mean between 0 and 6 + std::default_random_engine engine(device()); + std::uniform_int_distribution uniform_dist(0, 6); + return Tag::ColorName[uniform_dist(engine)]; +} +#endif + +TagManager::TagManager() + : QObject{ nullptr } +{ +#ifndef DDE_ANYTHINGMONITOR + if (qApp) { + // to main thread + if (thread() != qApp->thread()) { + moveToThread(qApp->thread()); + DThreadUtil::runInMainThread(this, &TagManager::init_connect); + return; + } + } + + this->init_connect(); +#endif +} + +#ifndef DDE_ANYTHINGMONITOR +QMap TagManager::getAllTags() +{ + QMap placeholder_container{ { QString{" "}, QVariant{ QList{ QString{" "} } } } }; + QVariant var{ TagManagerDaemonController::instance()->disposeClientData(placeholder_container, Tag::ActionType::GetAllTags) }; + placeholder_container = var.toMap(); + + QMap::const_iterator c_beg{ placeholder_container.cbegin() }; + QMap::const_iterator c_end{ placeholder_container.cend() }; + QMap string_dual{}; + + for (; c_beg != c_end; ++c_beg) { + string_dual[c_beg.key()] = c_beg.value().toString(); + } + + return string_dual; +} + +QList TagManager::getTagsThroughFiles(const QList &files) +{ + QMap string_var{}; + + if (!files.isEmpty()) { + + for (const DUrl &url : files) { + string_var[url.toLocalFile()] = QVariant{ QList{} }; + } + + QVariant var{ TagManagerDaemonController::instance()->disposeClientData(string_var, Tag::ActionType::GetTagsThroughFile) }; + return var.toStringList(); + } + + return QList {}; +} + +QMap TagManager::getTagColor(const QList &tags) const +{ + QMap tag_and_color{}; + + if (!tags.isEmpty()) { + QMap string_var{}; + + for (const QString &tag_name : tags) { + string_var[tag_name] = QVariant{ QList{ QString{" "} } }; + } + + QVariant var{ TagManagerDaemonController::instance()->disposeClientData(string_var, Tag::ActionType::GetTagsColor) }; + string_var = var.toMap(); + QMap::const_iterator c_beg{ string_var.cbegin() }; + QMap::const_iterator c_end{ string_var.cend() }; + + for (; c_beg != c_end; ++c_beg) { + tag_and_color[c_beg.key()] = Tag::NamesWithColors[c_beg.value().toString()]; + } + } + + return tag_and_color; +} + +QString TagManager::getTagColorName(const QString &tag) const +{ + const QMap &map = getTagColor({tag}); + const QColor &color = map.value(tag); + + if (!color.isValid()) { + return QString(); + } + + return getColorNameByColor(color); +} + +QString TagManager::getTagIconName(const QString &tag) const +{ + QString colorName = getTagColorName(tag); + return Tag::ColorNameWithIconName.value(colorName); +} + +QString TagManager::getTagIconName(const QColor &color) const +{ + QString colorName = getColorNameByColor(color); + return Tag::ColorNameWithIconName.value(colorName); +} + +QList TagManager::getFilesThroughTag(const QString &tagName) +{ + QList file_list{}; + + if (!tagName.isEmpty()) { + QMap string_var{ {tagName, QVariant{QList{ QString{" "} }}} }; + QVariant var{ TagManagerDaemonController::instance()->disposeClientData(string_var, Tag::ActionType::GetFilesThroughTag) }; + file_list = var.toStringList(); + } + + return file_list; +} + +QString TagManager::getTagNameThroughColor(const QColor &color) const +{ + QString tag_name = Tag::ColorsWithNames.value(color.name()); + + return Tag::ActualAndFakerName().value(tag_name); +} + +QColor TagManager::getColorByColorName(const QString &colorName) const +{ + return Tag::NamesWithColors.value(colorName); +} + +QString TagManager::getColorByDisplayName(const QString &colorDisplayName) const +{ + auto color_map = Tag::ActualAndFakerName(); + + for (auto i = color_map.constBegin(); i != color_map.constEnd(); ++i) { + if (i.value() == colorDisplayName) { + return i.key(); + } + } + + return QString(); +} + +QString TagManager::getColorNameByColor(const QColor &color) const +{ + return Tag::ColorsWithNames.value(color.name()); +} + +QSet TagManager::allTagOfDefaultColors() const +{ + QSet tags; + + for (const QString &color : Tag::ColorName) { + tags << Tag::ActualAndFakerName().value(color); + } + + return tags; +} + +bool TagManager::makeFilesTags(const QList &tags, const QList &files) +{ + bool result{ true }; + + if (!tags.isEmpty() && !files.isEmpty()) { + QMap tag_and_file{}; + + for (const QString &tag_name : tags) { + QString color_name; + + // for default tags + for (const QString &color : Tag::ColorName) { + if (tag_name == Tag::ActualAndFakerName().value(color)) { + color_name = color; + break; + } + } + + if (color_name.isEmpty()) { + color_name = randomColor(); + } + + tag_and_file[tag_name] = QVariant{QList{ color_name }}; + } + + QVariant insert_tags_var{ TagManagerDaemonController::instance()->disposeClientData(tag_and_file, Tag::ActionType::BeforeMakeFilesTags) }; + QMap file_and_tag{}; + + for (const DUrl &url : files) { + file_and_tag[url.toLocalFile()] = QVariant{tags}; + } + + QVariant tag_files_var{}; + + if (insert_tags_var.toBool()) { + tag_files_var = TagManagerDaemonController::instance()->disposeClientData(file_and_tag, Tag::ActionType::MakeFilesTags); + } + + if (insert_tags_var.toBool()) { + + if (!tag_files_var.toBool()) { + qWarning() << "Create tags successfully! But failed to tag files"; + } + result = true; + } + } + + return result; +} + +bool TagManager::changeTagColor(const QString &tagName, const QString &new_tag_color) +{ + bool result{ true }; + + if (!tagName.isEmpty() && !new_tag_color.isEmpty()) { + QMap string_var{ { tagName, QVariant{ QList{ new_tag_color } } } }; + QVariant var{ TagManagerDaemonController::instance()->disposeClientData(string_var, Tag::ActionType::ChangeTagColor) }; + result = var.toBool(); + } + + return result; +} + +bool TagManager::removeTagsOfFiles(const QList &tags, const QList &files) +{ + bool result{ true }; + + if (!tags.isEmpty() && !files.isEmpty()) { + QMap file_and_tag{}; + + for (const DUrl &url : files) { + file_and_tag[url.toLocalFile()] = QVariant(tags); + } + + QVariant var{ TagManagerDaemonController::instance()->disposeClientData(file_and_tag, Tag::ActionType::RemoveTagsOfFiles) }; + result = var.toBool(); + } + + return result; +} + +bool TagManager::deleteTags(const QList &tags) +{ + bool result{ true }; + + if (!tags.isEmpty()) { + QMap tag_and_placeholder{}; + + for (const QString &tag_name : tags) { + tag_and_placeholder[tag_name] = QVariant{ QList{} }; + } + + QVariant var{ TagManagerDaemonController::instance()->disposeClientData(tag_and_placeholder, Tag::ActionType::DeleteTags) }; + result = var.toBool(); + } + + return result; +} +#endif + +bool TagManager::deleteFiles(const QList &fileList) +{ + bool result{ true }; + + if (!fileList.isEmpty()) { + QMap local_url_and_placeholder{}; + + for (const DUrl &url : fileList) { + local_url_and_placeholder[url.toLocalFile()] = QVariant{ QList{} }; + } + + QVariant var{ TagManagerDaemonController::instance()->disposeClientData(local_url_and_placeholder, Tag::ActionType::DeleteFiles) }; + result = var.toBool(); + } + + return result; +} + +#ifndef DDE_ANYTHINGMONITOR +void TagManager::init_connect()noexcept +{ + connect(DFileService::instance(), &DFileService::fileCopied, this, [ = ](const DUrl & source, const DUrl & target) { + const QStringList &tags = DFileService::instance()->getTagsThroughFiles(this, {source}); + + if (tags.isEmpty()) { + return; + } + + DFileService::instance()->setFileTags(this, target, tags); + }); + +// connect(DFileService::instance(), &DFileService::fileDeleted, this, [this] (const DUrl &file) { +// if (file.isLocalFile()) { +// deleteFiles({file}); +// } +// }); + + connect(DFileService::instance(), &DFileService::fileRenamed, this, [ = ](const DUrl & from, const DUrl & to) { + QFileInfo from_info{ from.toLocalFile() }; + QFileInfo to_info{ to.toLocalFile() }; + DUrl from_backup{ from }; + DUrl to_backup{ to }; + + if (from_info.isSymLink()) { + from_backup = from.parentUrl(); + } + + if (to_info.isSymLink()) { + to_backup = to.parentUrl(); + } + + QStorageInfo from_storage_info{ from_backup.toLocalFile() }; + QStorageInfo to_storage_info{ to_backup.toLocalFile() }; + + if (from_storage_info.rootPath() == to_storage_info.rootPath()) { + return; + } + + + const QStringList &tags = DFileService::instance()->getTagsThroughFiles(this, {from}); + + if (from.isLocalFile()) { + deleteFiles({from}); + } + + if (tags.isEmpty()) { + return; + } + + DFileService::instance()->setFileTags(this, to, tags); + }); + + connect(DFileService::instance(), &DFileService::fileMovedToTrash, this, [ = ](const DUrl & from, const DUrl & to) { + (void)from; + + if (from.isLocalFile()) { + deleteFiles({from}); + } + + // clean the "to" file tag info + QTimer::singleShot(1000, this, [to, this] { + DFileService::instance()->setFileTags(this, to, {}); + }); + }); + + connect(DFileService::instance(), &DFileService::fileDeleted, this, [](const DUrl & from) { + (void)from; + if (from.isLocalFile() ) { + deleteFiles({from}); + } + }); + + connect(TagManagerDaemonController::instance(), &TagManagerDaemonController::addNewTags, this, [ = ](const QVariant & new_tags) { + + emit this->addNewTag(new_tags.toStringList()); + }); + + connect(TagManagerDaemonController::instance(), &TagManagerDaemonController::deleteTags, this, [ = ](const QVariant & be_deleted_tags) { + + emit this->deleteTag(be_deleted_tags.toStringList()); + }); + + connect(TagManagerDaemonController::instance(), &TagManagerDaemonController::changeTagColor, this, [ = ](const QVariantMap & old_and_new_color) { + + QMap old_and_new{}; + QMap::const_iterator c_beg{ old_and_new_color.cbegin() }; + QMap::const_iterator c_end{ old_and_new_color.cend() }; + + for (; c_beg != c_end; ++c_beg) { + old_and_new[c_beg.key()] = c_beg.value().toString(); + } + + emit this->changeTagColor(old_and_new); + }); + + connect(TagManagerDaemonController::instance(), &TagManagerDaemonController::changeTagName, this, [ = ](const QVariantMap & old_and_new_name) { + QMap old_and_new{}; + QMap::const_iterator c_beg{ old_and_new_name.cbegin() }; + QMap::const_iterator c_end{ old_and_new_name.cend() }; + + for (; c_beg != c_end; ++c_beg) { + old_and_new[c_beg.key()] = c_beg.value().toString(); + } + + emit this->changeTagName(old_and_new); + }); + + connect(TagManagerDaemonController::instance(), &TagManagerDaemonController::filesWereTagged, this, [ = ](const QVariantMap & files_were_tagged) { + QMap> file_and_tags{}; + QMap::const_iterator the_beg{ files_were_tagged.cbegin() }; + QMap::const_iterator the_end{ files_were_tagged.cend() }; + + for (; the_beg != the_end; ++the_beg) { + file_and_tags[the_beg.key()] = the_beg.value().toStringList(); + } + + emit this->filesWereTagged(file_and_tags); + }); + + connect(TagManagerDaemonController::instance(), &TagManagerDaemonController::untagFiles, this, [ = ](const QVariantMap & tag_be_removed_files) { + QMap> file_and_tags{}; + QMap::const_iterator the_beg{ tag_be_removed_files.cbegin() }; + QMap::const_iterator the_end{ tag_be_removed_files.cend() }; + + for (; the_beg != the_end; ++the_beg) { + file_and_tags[the_beg.key()] = the_beg.value().toStringList(); + } + + emit this->untagFiles(file_and_tags); + }); +} + + +bool TagManager::changeTagName(const QPair &oldAndNewName) +{ + bool result{ true }; + + if (!oldAndNewName.first.isEmpty() && !oldAndNewName.second.isEmpty()) { + QMap tag_name{ {oldAndNewName.first, QVariant{oldAndNewName.second}} }; + QVariant var{ TagManagerDaemonController::instance()->disposeClientData(tag_name, Tag::ActionType::ChangeTagName) }; + result = var.toBool(); + } + + return result; +} + +bool TagManager::makeFilesTagThroughColor(const QString &color, const QList &files) +{ + bool result{ true }; + + if (!color.isEmpty() && !files.isEmpty()) { + QMap local_url_and_tag{}; + + for (const DUrl &url : files) { + local_url_and_tag[url.toLocalFile()] = QVariant{ Tag::ColorsWithNames[color] }; + } + + QVariant var{ TagManagerDaemonController::instance()->disposeClientData(local_url_and_tag, Tag::ActionType::MakeFilesTagThroughColor) }; + result = var.toBool(); + } + + return result; +} +#endif + +bool TagManager::changeFilesName(const QList> &oldAndNewFilesName) +{ + bool result{ true }; + + if (!oldAndNewFilesName.isEmpty()) { + QMap old_and_new_name{}; + + for (const QPair &old_new : oldAndNewFilesName) { + old_and_new_name[QString::fromLocal8Bit(old_new.first)] = QVariant{ QString::fromLocal8Bit(old_new.second) }; + } + + QVariant var{ TagManagerDaemonController::instance()->disposeClientData(old_and_new_name, Tag::ActionType::ChangeFilesName) }; + result = var.toBool(); + } + + return result; +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tagmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tagmanager.h new file mode 100644 index 0000000..7931201 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tagmanager.h @@ -0,0 +1,141 @@ +#ifndef TAGMANAGER_H +#define TAGMANAGER_H + + +#include +#include +#include +#include +#include +#include +#include + +#include "glob.h" + +#include + +#include +#include +#include + + + + +namespace impl { + + +///###: When in C++14/17/20 or later. +///###: You should use std::invoke_result to replace std::result_of. +template::type, + typename Func2 = typename std::result_of::type> +struct shared_mutex +{ + +public: + enum class Options{Read, Write}; + + shared_mutex(Lock& lck, shared_mutex::Options option = shared_mutex::Options::Read):lock{ &lck } + { + if(option == shared_mutex::Options::Read){ + lock->lockForRead(); + }else{ + lock->lockForWrite(); + } + } + + + ~shared_mutex() + { + lock->unlock(); + } + + shared_mutex(shared_mutex& other)=delete; + shared_mutex& operator=(const shared_mutex& other)=delete; + +private: + Lock* lock; +}; + +} + + + +class TagManager final : public QObject +{ + Q_OBJECT +public: + enum class SqlType : std::size_t + { + GetAllTags = 1, + MakeFilesTags, + GetTagsThroughFile, + GetFilesThroughTag, + MakeFilesTagThroughColor + }; + + + TagManager(); + virtual ~TagManager()=default; + + TagManager(const TagManager& other)=delete; + TagManager& operator=(const TagManager& other)=delete; + +#ifndef DDE_ANYTHINGMONITOR + ///###: query + QMap getAllTags(); + + QList getTagsThroughFiles(const QList& files); + + QMap getTagColor(const QList& tags) const; + QString getTagColorName(const QString &tag) const; + QString getTagIconName(const QString &tag) const; + QString getTagIconName(const QColor &color) const; + + QList getFilesThroughTag(const QString& tagName); + + QString getTagNameThroughColor(const QColor &color) const; + QColor getColorByColorName(const QString &colorName) const; + QString getColorByDisplayName(const QString &colorDisplayName) const; + QString getColorNameByColor(const QColor &color) const; + QSet allTagOfDefaultColors() const; + + ///###:modify + bool makeFilesTags(const QList& tags, const QList& files); + + bool changeTagColor(const QString& tagName, const QString& new_tag_color); + + bool removeTagsOfFiles(const QList& tags, const QList& files); + + bool changeTagName(const QPair& oldAndNewName); + + bool makeFilesTagThroughColor(const QString &color, const QList& files); +#endif + static bool changeFilesName(const QList > &oldAndNewFilesName); + +#ifndef DDE_ANYTHINGMONITOR + ///###:delete + bool deleteTags(const QList& tags); +#endif + static bool deleteFiles(const QList& urlList); + +#ifndef DDE_ANYTHINGMONITOR + static TagManager* instance() + { + static TagManager* tagManager{ new TagManager }; + return tagManager; + } + +signals: + void addNewTag(const QList& new_tags); + void changeTagColor(const QMap& old_and_new_color); + void changeTagName(const QMap& old_and_new_name); + void deleteTag(const QList& be_deleted_tags); + void filesWereTagged(const QMap>& files_were_tagged); + void untagFiles(const QMap>& tag_be_removed_files); + +private: + void init_connect()noexcept; +#endif +}; + +#endif // TAGMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tagutil.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tagutil.cpp new file mode 100644 index 0000000..42f00a5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tagutil.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "tagutil.h" + + +#include + +namespace Tag +{ + +const QMap ColorsWithNames{ + { "#ffa503", "Orange"}, + { "#ff1c49", "Red"}, + { "#9023fc", "Purple"}, + { "#3468ff", "Navy-blue"}, + { "#00b5ff", "Azure"}, + { "#58df0a", "Grass-green"}, + { "#fef144", "Yellow"}, + { "#cccccc", "Gray" } +}; + +const QMap NamesWithColors{ + {"Orange", "#ffa503"}, + {"Red", "#ff1c49"}, + {"Purple", "#9023fc"}, + {"Navy-blue", "#3468ff"}, + {"Azure", "#00b5ff"}, + {"Grass-green", "#58df0a"}, + {"Yellow", "#fef144"}, + {"Gray", "#cccccc"} +}; + +// +const QMap ColorNameWithIconName { + {"Orange", "dfm_tag_orange"}, + {"Red", "dfm_tag_red"}, + {"Purple", "dfm_tag_purple"}, + {"Navy-blue", "dfm_tag_deepblue"}, + {"Azure", "dfm_tag_lightblue"}, + {"Grass-green", "dfm_tag_green"}, + {"Yellow", "dfm_tag_yellow"}, + {"Gray", "dfm_tag_gray"} +}; + +std::vector ColorName{ + "Orange", + "Red", + "Purple", + "Navy-blue", + "Azure", + "Grass-green", + "Yellow", + "Gray" +}; + +const QMap &ActualAndFakerName() +{ + ///###: Why has a faker name? + ///###: pair.second represent the faker name, + ///###: and them are used in translation. + const static QMap ActualAndFakerName{ + {"Orange", QObject::tr("Orange")}, + {"Red", QObject::tr("Red")}, + {"Purple", QObject::tr("Purple")}, + {"Navy-blue", QObject::tr("Navy-blue")}, + {"Azure", QObject::tr("Azure")}, + {"Grass-green", QObject::tr("Green")}, + {"Yellow", QObject::tr("Yellow")}, + {"Gray", QObject::tr("Gray")} + }; + + return ActualAndFakerName; +} + + + + + + +static constexpr const char *const escaped_skim_str{ "\\039" }; +static constexpr const char skim_char{'\''}; + +QString escaping_en_skim(const QString &source) noexcept +{ + if (source.isEmpty()) { + return source; + } + + QByteArray local8bits_str{ source.toLocal8Bit() }; + QByteArray::const_iterator cbeg{ local8bits_str.cbegin() }; + QByteArray::const_iterator cend{ local8bits_str.cend() }; + + QByteArray::const_iterator pos{ std::find(cbeg, cend, skim_char) }; + + while (pos != cend) { + QByteArray::difference_type index{ pos - cbeg }; + local8bits_str.remove(index, 1); + + if (pos == local8bits_str.cbegin()) { + local8bits_str.push_front(escaped_skim_str); + cbeg = local8bits_str.cbegin(); + cend = local8bits_str.cend(); + pos = std::find(cbeg, cend, skim_char); + } else { + local8bits_str.insert(index, escaped_skim_str); + cbeg = local8bits_str.cbegin(); + cend = local8bits_str.cend(); + pos = std::find(cbeg, cend, skim_char); + } + } + +#ifdef QT_DEBUG + qDebug() << local8bits_str; +#endif //QT_DEBUG + + return QString::fromLocal8Bit(local8bits_str); +} + +QString restore_escaped_en_skim(const QString &source) noexcept +{ + if (source.isEmpty()) { + return source; + } + + QByteArray local8bits_str{ source.toLocal8Bit() }; + + while (local8bits_str.contains(escaped_skim_str)) { + int index{ local8bits_str.indexOf(escaped_skim_str) }; + local8bits_str.remove(index, 4); + + if (index != 0) { + local8bits_str.insert(index, skim_char); + } else { + local8bits_str.push_front(skim_char); + } + } + +#ifdef QT_DEBUG + qDebug() << local8bits_str; +#endif //QT_DEBUG + + return QString::fromLocal8Bit(local8bits_str); +} + +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tagutil.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tagutil.h new file mode 100644 index 0000000..192f99c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/tag/tagutil.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef TAGUTIL_H +#define TAGUTIL_H + + +#include +#include +#include +#include + +#include + + +///###: ODR! +namespace Tag +{ +enum class ActionType : std::size_t { + MakeFilesTags = 1, + GetFilesThroughTag, + GetTagsThroughFile, + RemoveTagsOfFiles, + DeleteTags, + ChangeTagName, + DeleteFiles, + MakeFilesTagThroughColor, + ChangeFilesName, + GetAllTags = 10, + BeforeMakeFilesTags, + GetTagsColor, + ChangeTagColor +}; + +extern const QMap ColorsWithNames; +extern const QMap NamesWithColors; +extern const QMap ColorNameWithIconName; // + +const QMap &ActualAndFakerName(); + +extern std::vector ColorName; + + +extern QString escaping_en_skim(const QString &source) noexcept; +extern QString restore_escaped_en_skim(const QString &source) noexcept; + + + +} + + +#endif // TAGUTIL_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/config.ini b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/config.ini new file mode 100644 index 0000000..582737f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/config.ini @@ -0,0 +1,394 @@ +[BookmarkItem] +background=transparent +color=#afafaf + +[BookmarkItem:pressed] +background=#332ca7f8 +color=#2ca7f8 + +[BookmarkItem:hover] +background=#1Affffff + +[BookmarkItem:checked] +background=#332ca7f8 +color=#2ca7f8 + +[BookmarkItem.DBookmarkLine] +background=#0dffffff + +[BookmarkItem.File] +icon=:/dark/icons/file_normal_16px.svg +[BookmarkItem.File:hover] +icon=:/dark/icons/file_normal_16px.svg +[BookmarkItem.File:checked] +icon=:/dark/icons/file_active_16px.svg + +[BookmarkItem.Recent] +icon=:/dark/icons/recent_normal_16px.svg +[BookmarkItem.Recent:hover] +icon=:/dark/icons/recent_normal_16px.svg +[BookmarkItem.Recent:checked] +icon=:/dark/icons/recent_active_16px.svg + +[BookmarkItem.Home] +icon=:/dark/icons/home_normal_16px.svg +[BookmarkItem.Home:hover] +icon=:/dark/icons/home_normal_16px.svg +[BookmarkItem.Home:checked] +icon=:/dark/icons/home_active_16px.svg + +[BookmarkItem.Desktop] +icon=:/dark/icons/desktop_normal_16px.svg +[BookmarkItem.Desktop:hover] +icon=:/dark/icons/desktop_normal_16px.svg +[BookmarkItem.Desktop:checked] +icon=:/dark/icons/desktop_active_16px.svg + +[BookmarkItem.Videos] +icon=:/dark/icons/videos_normal_16px.svg +[BookmarkItem.Videos:hover] +icon=:/dark/icons/videos_normal_16px.svg +[BookmarkItem.Videos:checked] +icon=:/dark/icons/videos_active_16px.svg + +[BookmarkItem.Music] +icon=:/dark/icons/music_normal_16px.svg +[BookmarkItem.Music:hover] +icon=:/dark/icons/music_normal_16px.svg +[BookmarkItem.Music:checked] +icon=:/dark/icons/music_active_16px.svg + +[BookmarkItem.Pictures] +icon=:/dark/icons/pictures_normal_16px.svg +[BookmarkItem.Pictures:hover] +icon=:/dark/icons/pictures_normal_16px.svg +[BookmarkItem.Pictures:checked] +icon=:/dark/icons/pictures_active_16px.svg + +[BookmarkItem.Documents] +icon=:/dark/icons/documents_normal_16px.svg +[BookmarkItem.Documents:hover] +icon=:/dark/icons/documents_normal_16px.svg +[BookmarkItem.Documents:checked] +icon=:/dark/icons/documents_active_16px.svg + +[BookmarkItem.Downloads] +icon=:/dark/icons/download_normal_16px.svg +[BookmarkItem.Downloads:hover] +icon=:/dark/icons/download_normal_16px.svg +[BookmarkItem.Downloads:checked] +icon=:/dark/icons/download_active_16px.svg + +[BookmarkItem.Trash] +icon=:/dark/icons/trash_normal_16px.svg +[BookmarkItem.Trash:hover] +icon=:/dark/icons/trash_normal_16px.svg +[BookmarkItem.Trash:checked] +icon=:/dark/icons/trash_active_16px.svg + +[BookmarkItem.Computer] +icon=:/dark/icons/computer_normal_16px.svg +[BookmarkItem.Computer:hover] +icon=:/dark/icons/computer_normal_16px.svg +[BookmarkItem.Computer:checked] +icon=:/dark/icons/computer_active_16px.svg + +[BookmarkItem.Disk] +icon=:/dark/icons/disk_normal_16px.svg +[BookmarkItem.Disk:hover] +icon=:/dark/icons/disk_normal_16px.svg +[BookmarkItem.Disk:checked] +icon=:/dark/icons/disk_active_16px.svg + +[BookmarkItem.Usb] +icon=:/dark/icons/usb_normal_16px.svg +[BookmarkItem.Usb:hover] +icon=:/dark/icons/usb_normal_16px.svg +[BookmarkItem.Usb:checked] +icon=:/dark/icons/usb_active_16px.svg + +[BookmarkItem.Iphone] +icon=:/dark/icons/iphone_normal_16px.svg +[BookmarkItem.Iphone:hover] +icon=:/dark/icons/iphone_normal_16px.svg +[BookmarkItem.Iphone:checked] +icon=:/dark/icons/iphone_active_16px.svg + +[BookmarkItem.Android] +icon=:/dark/icons/Android_phone_normal_16px.svg +[BookmarkItem.Android:hover] +icon=:/dark/icons/Android_phone_normal_16px.svg +[BookmarkItem.Android:checked] +icon=:/dark/icons/Android_phone_active_16px.svg + +[BookmarkItem.Network] +icon=:/dark/icons/network_normal_16px.svg +[BookmarkItem.Network:hover] +icon=:/dark/icons/network_normal_16px.svg +[BookmarkItem.Network:checked] +icon=:/dark/icons/network_active_16px.svg + +[BookmarkItem.UserShare] +icon=:/dark/icons/usershare_normal_16px.svg +[BookmarkItem.UserShare:hover] +icon=:/dark/icons/usershare_normal_16px.svg +[BookmarkItem.UserShare:checked] +icon=:/dark/icons/usershare_active_16px.svg + +[BookmarkItem.Dvd] +icon=:/dark/icons/media_normal_16px.svg +[BookmarkItem.Dvd:hover] +icon=:/dark/icons/media_normal_16px.svg +[BookmarkItem.Dvd:checked] +icon=:/dark/icons/media_active_16px.svg + +[BookmarkItem.System Disk] +icon=:/dark/icons/disk_normal_16px.svg +[BookmarkItem.System Disk:hover] +icon=:/dark/icons/disk_normal_16px.svg +[BookmarkItem.System Disk:checked] +icon=:/dark/icons/disk_active_16px.svg + +[BookmarkItem.BookMarks] +icon=:/dark/icons/bookmarks_normal_16px.svg +[BookmarkItem.BookMarks:hover] +icon=:/dark/icons/bookmarks_normal_16px.svg +[BookmarkItem.BookMarks:checked] +icon=:/dark/icons/bookmarks_active_16px.svg + +[BookmarkItem.MountedIndicator] +icon=:/dark/icons/unmount_normal.svg +[BookmarkItem.MountedIndicator:hover] +icon=:/dark/icons/unmount_hover.svg +[BookmarkItem.MountedIndicator:checked] +icon=:/dark/icons/unmount_active.svg + + +[CrumbIconButton.Recent] +icon=:/dark/icons/recent_normal_16px.svg +[CrumbIconButton.Recent:hover] +icon=:/dark/icons/recent_normal_16px.svg +[CrumbIconButton.Recent:checked] +icon=:/icons/images/icons/recent_checked_16px.svg + +[CrumbIconButton.Home] +icon=:/dark/icons/home_normal_16px.svg +[CrumbIconButton.Home:hover] +icon=:/dark/icons/home_normal_16px.svg +[CrumbIconButton.Home:checked] +icon=:/icons/images/icons/home_checked_16px.svg + +[CrumbIconButton.Trash] +icon=:/dark/icons/trash_normal_16px.svg +[CrumbIconButton.Trash:hover] +icon=:/dark/icons/trash_normal_16px.svg +[CrumbIconButton.Trash:checked] +icon=:/icons/images/icons/trash_checked_16px.svg + +[CrumbIconButton.Computer] +icon=:/dark/icons/computer_normal_16px.svg +[CrumbIconButton.Computer:hover] +icon=:/dark/icons/computer_normal_16px.svg +[CrumbIconButton.Computer:checked] +icon=:/icons/images/icons/computer_checked_16px.svg + +[CrumbIconButton.Disk] +icon=:/dark/icons/disk_normal_16px.svg +[CrumbIconButton.Disk:hover] +icon=:/dark/icons/disk_normal_16px.svg +[CrumbIconButton.Disk:checked] +icon=:/icons/images/icons/disk_checked_16px.svg + +[CrumbIconButton.Usb] +icon=:/dark/icons/usb_normal_16px.svg +[CrumbIconButton.Usb:hover] +icon=:/dark/icons/usb_normal_16px.svg +[CrumbIconButton.Usb:checked] +icon=:/icons/images/icons/usb_checked_16px.svg + +[CrumbIconButton.Iphone] +icon=:/dark/icons/iphone_normal_16px.svg +[CrumbIconButton.Iphone:hover] +icon=:/dark/icons/iphone_normal_16px.svg +[CrumbIconButton.Iphone:checked] +icon=:/icons/images/icons/iphone_checked_16px.svg + +[CrumbIconButton.Android] +icon=:/dark/icons/android_normal_16px.svg +[CrumbIconButton.Android:hover] +icon=:/dark/icons/android_normal_16px.svg +[CrumbIconButton.Android:checked] +icon=:/icons/images/icons/android_checked_16px.svg + +[CrumbIconButton.Network] +icon=:/dark/icons/network_normal_16px.svg +[CrumbIconButton.Network:hover] +icon=:/dark/icons/network_normal_16px.svg +[CrumbIconButton.Network:checked] +icon=:/icons/images/icons/network_checked_16px.svg + +[CrumbIconButton.UserShare] +icon=:/dark/icons/usershare_normal_16px.svg +[CrumbIconButton.UserShare:hover] +icon=:/dark/icons/usershare_normal_16px.svg +[CrumbIconButton.UserShare:checked] +icon=:/icons/images/icons/usershare_checked_16px.svg + +[CrumbIconButton.Dvd] +icon=:/dark/icons/dvd_normal_16px.svg +[CrumbIconButton.Dvd:hover] +icon=:/dark/icons/dvd_normal_16px.svg +[CrumbIconButton.Dvd:checked] +icon=:/icons/images/icons/dvd_checked_16px.svg + +[CrumbIconButton.System Disk] +icon=:/dark/icons/disk_normal_16px.svg +[CrumbIconButton.System Disk:hover] +icon=:/dark/icons/disk_normal_16px.svg +[CrumbIconButton.System Disk:checked] +icon=:/icons/images/icons/disk_checked_16px.svg + +[CrumbIconButton.Tags] +icon=:/icons/images/icons/tag_normal.svg +[CrumbIconButton.Tags:hover] +icon=:/icons/images/icons/tag_normal.svg +[CrumbIconButton.Tags:checked] +icon=:/icons/images/icons/tag_normal.svg + +[CrumbIconButton.Bookmarks] +icon=:/dark/icons/bookmarks_checked_16px.svg +[CrumbIconButton.Bookmarks:hover] +icon=:/dark/icons/bookmarks_checked_16px.svg +[CrumbIconButton.Bookmarks:checked] +icon=:/dark/icons/bookmarks_checked_16px.svg + + +[BookmarkItem.Orange] +icon=:/icons/images/icons/tag_orange_normal.svg +[BookmarkItem.Orange.:hover] +icon=:/icons/images/icons/tag_orange_active.svg +[BookmarkItem.Orange.checked] +icon=:/icons/images/icons/tag_orange_active.svg + +[BookmarkItem.Red] +icon=:/icons/images/icons/tag_red_normal.svg +[BookmarkItem.Red:hover] +icon=:/icons/images/icons/tag_red_active.svg +[BookmarkItem.Red:checked] +icon=:/icons/images/icons/tag_red_active.svg + +[BookmarkItem.Purple] +icon=:/icons/images/icons/tag_purple_normal.svg +[BookmarkItem.Purple:hover] +icon=:/icons/images/icons/tag_purple_active.svg +[BookmarkItem.Purple:checked] +icon=:/icons/images/icons/tag_purple_active.svg + +[BookmarkItem.Navy-blue] +icon=:/icons/images/icons/tag_deepblue_normal.svg +[BookmarkItem.Navy-blue:hover] +icon=:/icons/images/icons/tag_deepblue_active.svg +[BookmarkItem.Navy-blue:checked] +icon=:/icons/images/icons/tag_deepblue_active.svg + +[BookmarkItem.Azure] +icon=:/icons/images/icons/tag_lightblue_normal.svg +[BookmarkItem.Azure:hover] +icon=:/icons/images/icons/tag_lightblue_active.svg +[BookmarkItem.Azure:checked] +icon=:/icons/images/icons/tag_lightblue_active.svg + +[BookmarkItem.Grass-green] +icon=:/icons/images/icons/tag_green_normal.svg +[BookmarkItem.Grass-green:hover] +icon=:/icons/images/icons/tag_green_active.svg +[BookmarkItem.Grass-green:checked] +icon=:/icons/images/icons/tag_green_active.svg + +[BookmarkItem.Yellow] +icon=:/icons/images/icons/tag_yellow_normal.svg +[BookmarkItem.Yellow:hover] +icon=:/icons/images/icons/tag_yellow_active.svg +[BookmarkItem.Yellow:checked] +icon=:/icons/images/icons/tag_yellow_active.svg + +[BookmarkItem.Gray] +icon=:/icons/images/icons/tag_gray_normal.svg +[BookmarkItem.Gray:hover] +icon=:/icons/images/icons/tag_gray_active.svg +[BookmarkItem.Gray:checked] +icon=:/icons/images/icons/tag_gray_active.svg + + + +[FileView] +background=#2ca7f8 +color=#bdbdbd +shadow=#b2000000 +overlap=#202020 +non-overlap=#1a000000 +iconview.icon=:/dark/icons/icon_view_normal.svg +listview.icon=:/dark/icons/list_view_normal.svg +[FileView:hover] +iconview.icon=:/dark/icons/icon_view_hover.svg +listview.icon=:/dark/icons/list_view_hover.svg +[FileView::checked] +iconview.icon=:/dark/icons/icon_view_active.svg +listview.icon=:/dark/icons/list_view_active.svg +[FileView:focus] +background=#0076F9 +[FileView:disable] +color=#797979 +[FileView:inactive] +background=#234860 +color=#70ffffff +[FileView:inactive.checked] +color=white + +[Tab] +background=#1c1c1c +color=#949494 +border=#0d000000 +[Tab:hover] +background=#3e3e3e +color=#dddddd +[Tab:checked] +background=#313131 +color=#2ca7f8 + +[TabCloseButton] +icon=:/dark/icons/tab_close_normal.svg +[TabCloseButton:hover] +icon=:/dark/icons/tab_close_hover.svg +[TabCloseButton:pressed] +icon=:/dark/icons/tab_close_press.svg +[TabCloseButton:focus] +icon=:/dark/icons/active_tab_close_normal.svg +[TabCloseButton:hover.focus] +icon=:/dark/icons/active_tab_close_hover.svg +[TabCloseButton:pressed.focus] +icon=:/dark/icons/active_tab_close_press.svg + + +[DSearchBar.clearAction] +icon=:/dark/icons/input_clear_normal.svg +[DSearchBar.clearAction:hover] +icon=:/dark/icons/input_clear_hover.svg +[DSearchBar.clearAction:pressed] +icon=:/dark/icons/input_clear_press.svg + +[DSearchBar.searchAction] +icon=:/dark/icons/search.svg + +[DSearchBar.jumpToAction] +icon=:/dark/icons/jump_to.svg + +[DSearchBar.glowingAnimation] +image=:/dark/icons/glowing.svg + +[DFMCrumbBar] +background=#343434 + +[CrumbBar.BorderLine] +border-color=#00000000 + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/Android_phone_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/Android_phone_active_16px.svg new file mode 100644 index 0000000..4cc29a5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/Android_phone_active_16px.svg @@ -0,0 +1,18 @@ + + + + Android_phone_active_16px + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/Android_phone_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/Android_phone_normal_16px.svg new file mode 100644 index 0000000..db91939 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/Android_phone_normal_16px.svg @@ -0,0 +1,16 @@ + + + + Android_phone_normal_16px + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/active_tab_close_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/active_tab_close_hover.svg new file mode 100755 index 0000000..3df6ca1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/active_tab_close_hover.svg @@ -0,0 +1,19 @@ + + + + active_tab_close_hover + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/active_tab_close_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/active_tab_close_normal.svg new file mode 100755 index 0000000..d23d5a7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/active_tab_close_normal.svg @@ -0,0 +1,29 @@ + + + + active_tab_close_normal + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/active_tab_close_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/active_tab_close_press.svg new file mode 100755 index 0000000..4765844 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/active_tab_close_press.svg @@ -0,0 +1,23 @@ + + + + active_tab_close_press + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/backward_disabled.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/backward_disabled.svg new file mode 100644 index 0000000..e8b1ca0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/backward_disabled.svg @@ -0,0 +1,12 @@ + + + + backward_disabled + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/backward_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/backward_hover.svg new file mode 100644 index 0000000..82d3e1a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/backward_hover.svg @@ -0,0 +1,12 @@ + + + + backward_hover + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/backward_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/backward_normal.svg new file mode 100644 index 0000000..98b0257 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/backward_normal.svg @@ -0,0 +1,12 @@ + + + + backward_normal + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/backward_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/backward_press.svg new file mode 100644 index 0000000..38a8ce9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/backward_press.svg @@ -0,0 +1,12 @@ + + + + backward_press + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/bookmarks_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/bookmarks_active_16px.svg new file mode 100644 index 0000000..b9a0796 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/bookmarks_active_16px.svg @@ -0,0 +1,13 @@ + + + + bookmarks_active_16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/bookmarks_checked_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/bookmarks_checked_16px.svg new file mode 100644 index 0000000..a076aaf --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/bookmarks_checked_16px.svg @@ -0,0 +1,11 @@ + + + + bookmarks_active_16px + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/bookmarks_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/bookmarks_normal_16px.svg new file mode 100644 index 0000000..af9f4da --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/bookmarks_normal_16px.svg @@ -0,0 +1,17 @@ + + + + bookmarks_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/caution.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/caution.svg new file mode 100644 index 0000000..a4442e8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/caution.svg @@ -0,0 +1,19 @@ + + + icon_tips/caution + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/computer_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/computer_active_16px.svg new file mode 100644 index 0000000..eba8c28 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/computer_active_16px.svg @@ -0,0 +1,28 @@ + + + + computer_active_16px + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/computer_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/computer_normal_16px.svg new file mode 100644 index 0000000..7d19bde --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/computer_normal_16px.svg @@ -0,0 +1,15 @@ + + + + computer_normal_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/desktop_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/desktop_active_16px.svg new file mode 100644 index 0000000..37ce2a5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/desktop_active_16px.svg @@ -0,0 +1,15 @@ + + + + desktop_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/desktop_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/desktop_normal_16px.svg new file mode 100644 index 0000000..e45b226 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/desktop_normal_16px.svg @@ -0,0 +1,17 @@ + + + + desktop_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/disk_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/disk_active_16px.svg new file mode 100644 index 0000000..1cba90c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/disk_active_16px.svg @@ -0,0 +1,15 @@ + + + + disk_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/disk_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/disk_normal_16px.svg new file mode 100644 index 0000000..684ee65 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/disk_normal_16px.svg @@ -0,0 +1,17 @@ + + + + disk_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/documents_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/documents_active_16px.svg new file mode 100644 index 0000000..653d9cc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/documents_active_16px.svg @@ -0,0 +1,15 @@ + + + + documents_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/documents_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/documents_normal_16px.svg new file mode 100644 index 0000000..c2ac4e9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/documents_normal_16px.svg @@ -0,0 +1,19 @@ + + + + documents_normal_16px + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/down.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/down.svg new file mode 100644 index 0000000..f6f1c73 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/down.svg @@ -0,0 +1,12 @@ + + + + down + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/download_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/download_active_16px.svg new file mode 100644 index 0000000..ed849ba --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/download_active_16px.svg @@ -0,0 +1,17 @@ + + + + download_active_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/download_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/download_normal_16px.svg new file mode 100644 index 0000000..7fcfc9a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/download_normal_16px.svg @@ -0,0 +1,17 @@ + + + + download_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/file_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/file_active_16px.svg new file mode 100644 index 0000000..d22fa54 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/file_active_16px.svg @@ -0,0 +1,17 @@ + + + + file_active_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/file_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/file_normal_16px.svg new file mode 100644 index 0000000..ab0ba17 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/file_normal_16px.svg @@ -0,0 +1,17 @@ + + + + file_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/filter_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/filter_active.svg new file mode 100644 index 0000000..9b4676c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/filter_active.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/filter_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/filter_hover.svg new file mode 100644 index 0000000..c21af53 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/filter_hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/filter_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/filter_normal.svg new file mode 100644 index 0000000..bb77d9b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/filter_normal.svg @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/forward_disabled.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/forward_disabled.svg new file mode 100644 index 0000000..663f37b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/forward_disabled.svg @@ -0,0 +1,12 @@ + + + + forward_disabled + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/forward_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/forward_hover.svg new file mode 100644 index 0000000..bf5e1d8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/forward_hover.svg @@ -0,0 +1,12 @@ + + + + forward_hover + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/forward_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/forward_normal.svg new file mode 100644 index 0000000..afd8402 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/forward_normal.svg @@ -0,0 +1,12 @@ + + + + forward_normal + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/forward_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/forward_press.svg new file mode 100644 index 0000000..771a3e7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/forward_press.svg @@ -0,0 +1,12 @@ + + + + forward_press + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/glowing.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/glowing.svg new file mode 100644 index 0000000..df2a268 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/glowing.svg @@ -0,0 +1,20 @@ + + + + glowing_dark + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/home_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/home_active_16px.svg new file mode 100644 index 0000000..2d785a6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/home_active_16px.svg @@ -0,0 +1,15 @@ + + + + home_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/home_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/home_normal_16px.svg new file mode 100644 index 0000000..dbe053c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/home_normal_16px.svg @@ -0,0 +1,16 @@ + + + + home_normal_16px + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/icon_view_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/icon_view_active.svg new file mode 100644 index 0000000..a436e5c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/icon_view_active.svg @@ -0,0 +1,13 @@ + + + + icon_view_active + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/icon_view_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/icon_view_hover.svg new file mode 100755 index 0000000..ecb5665 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/icon_view_hover.svg @@ -0,0 +1,13 @@ + + + + icon_view_hover + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/icon_view_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/icon_view_normal.svg new file mode 100644 index 0000000..139662d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/icon_view_normal.svg @@ -0,0 +1,13 @@ + + + + icon_view_normal + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/input_clear_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/input_clear_hover.svg new file mode 100644 index 0000000..4ba0fd2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/input_clear_hover.svg @@ -0,0 +1,12 @@ + + + + input_clear_dark_hover + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/input_clear_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/input_clear_normal.svg new file mode 100644 index 0000000..2d08ecc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/input_clear_normal.svg @@ -0,0 +1,12 @@ + + + + input_clear_dark_normal + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/input_clear_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/input_clear_press.svg new file mode 100644 index 0000000..3f7df2e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/input_clear_press.svg @@ -0,0 +1,14 @@ + + + + input_clear_dark_press + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/iphone_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/iphone_active_16px.svg new file mode 100644 index 0000000..1952d48 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/iphone_active_16px.svg @@ -0,0 +1,14 @@ + + + + iphone_active_16px + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/iphone_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/iphone_normal_16px.svg new file mode 100644 index 0000000..c8cd6e5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/iphone_normal_16px.svg @@ -0,0 +1,16 @@ + + + + iphone_normal_16px + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/jump_to.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/jump_to.svg new file mode 100644 index 0000000..e3b062b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/jump_to.svg @@ -0,0 +1,15 @@ + + + + jump_to + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/list_view_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/list_view_active.svg new file mode 100644 index 0000000..067eb66 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/list_view_active.svg @@ -0,0 +1,13 @@ + + + + list_view_active + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/list_view_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/list_view_hover.svg new file mode 100755 index 0000000..989e451 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/list_view_hover.svg @@ -0,0 +1,13 @@ + + + + list_view_hover + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/list_view_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/list_view_normal.svg new file mode 100644 index 0000000..ec74565 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/list_view_normal.svg @@ -0,0 +1,13 @@ + + + + list_view_normal + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/media_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/media_active_16px.svg new file mode 100644 index 0000000..3eef064 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/media_active_16px.svg @@ -0,0 +1,14 @@ + + + + media_optical_symbolic_active_16px + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/media_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/media_normal_16px.svg new file mode 100644 index 0000000..9eade4d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/media_normal_16px.svg @@ -0,0 +1,17 @@ + + + + media_optical_symbolic_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/music_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/music_active_16px.svg new file mode 100644 index 0000000..55f3f69 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/music_active_16px.svg @@ -0,0 +1,15 @@ + + + + music_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/music_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/music_normal_16px.svg new file mode 100644 index 0000000..e591473 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/music_normal_16px.svg @@ -0,0 +1,19 @@ + + + + music_normal_16px + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/network_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/network_active_16px.svg new file mode 100644 index 0000000..66ad523 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/network_active_16px.svg @@ -0,0 +1,14 @@ + + + + network_server_symbolic_active_16px + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/network_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/network_normal_16px.svg new file mode 100644 index 0000000..7561f6c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/network_normal_16px.svg @@ -0,0 +1,20 @@ + + + + network_server_symbolic_normal_16px + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/new_tab_disabled.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/new_tab_disabled.svg new file mode 100644 index 0000000..fcaf615 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/new_tab_disabled.svg @@ -0,0 +1,23 @@ + + + + new_tab_disabled + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/new_tab_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/new_tab_hover.svg new file mode 100644 index 0000000..eba98b0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/new_tab_hover.svg @@ -0,0 +1,23 @@ + + + + new_tab_hover + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/new_tab_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/new_tab_normal.svg new file mode 100644 index 0000000..c2fcd56 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/new_tab_normal.svg @@ -0,0 +1,23 @@ + + + + new_tab_normal + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/new_tab_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/new_tab_press.svg new file mode 100644 index 0000000..115777d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/new_tab_press.svg @@ -0,0 +1,23 @@ + + + + new_tab_press + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/pictures_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/pictures_active_16px.svg new file mode 100644 index 0000000..8ccc8f6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/pictures_active_16px.svg @@ -0,0 +1,15 @@ + + + + pictures_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/pictures_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/pictures_normal_16px.svg new file mode 100644 index 0000000..7a9b17b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/pictures_normal_16px.svg @@ -0,0 +1,17 @@ + + + + pictures_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/recent_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/recent_active_16px.svg new file mode 100644 index 0000000..8a51b6e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/recent_active_16px.svg @@ -0,0 +1,13 @@ + + + + recent_active_16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/recent_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/recent_normal_16px.svg new file mode 100644 index 0000000..b40d46a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/recent_normal_16px.svg @@ -0,0 +1,16 @@ + + + + recent_normal_16px + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/search.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/search.svg new file mode 100644 index 0000000..ff0cd45 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/search.svg @@ -0,0 +1,15 @@ + + + + search + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/search_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/search_hover.svg new file mode 100644 index 0000000..2012980 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/search_hover.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/search_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/search_normal.svg new file mode 100644 index 0000000..a9d560f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/search_normal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/search_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/search_press.svg new file mode 100644 index 0000000..b74cc35 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/search_press.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/tab_close_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/tab_close_hover.svg new file mode 100755 index 0000000..5f09b83 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/tab_close_hover.svg @@ -0,0 +1,20 @@ + + + + tab_close_hover + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/tab_close_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/tab_close_normal.svg new file mode 100755 index 0000000..dab19dd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/tab_close_normal.svg @@ -0,0 +1,29 @@ + + + + tab_close_normal + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/tab_close_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/tab_close_press.svg new file mode 100755 index 0000000..4e7c829 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/tab_close_press.svg @@ -0,0 +1,23 @@ + + + + tab_close_press + Created with Sketch. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/trash_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/trash_active_16px.svg new file mode 100644 index 0000000..f54d930 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/trash_active_16px.svg @@ -0,0 +1,15 @@ + + + + trash_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/trash_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/trash_normal_16px.svg new file mode 100644 index 0000000..ac2fc52 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/trash_normal_16px.svg @@ -0,0 +1,19 @@ + + + + trash_normal_16px + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/unmount_active.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/unmount_active.svg new file mode 100644 index 0000000..0d94d9f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/unmount_active.svg @@ -0,0 +1,17 @@ + + + + unmount_active + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/unmount_hover.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/unmount_hover.svg new file mode 100644 index 0000000..8aff7f4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/unmount_hover.svg @@ -0,0 +1,18 @@ + + + + unmount_hover + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/unmount_normal.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/unmount_normal.svg new file mode 100644 index 0000000..3dd5886 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/unmount_normal.svg @@ -0,0 +1,17 @@ + + + + unmount_normal + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/unmount_press.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/unmount_press.svg new file mode 100644 index 0000000..e6fd5ba --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/unmount_press.svg @@ -0,0 +1,18 @@ + + + + unmount_press + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/up.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/up.svg new file mode 100644 index 0000000..7f9564c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/up.svg @@ -0,0 +1,12 @@ + + + + up + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/usb_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/usb_active_16px.svg new file mode 100644 index 0000000..c888ca0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/usb_active_16px.svg @@ -0,0 +1,13 @@ + + + + drive_harddisk_usb_symbolic_active_16px + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/usb_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/usb_normal_16px.svg new file mode 100644 index 0000000..6e20e75 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/usb_normal_16px.svg @@ -0,0 +1,20 @@ + + + + drive_harddisk_usb_symbolic_normal_16px + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/usershare_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/usershare_active_16px.svg new file mode 100644 index 0000000..67bb089 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/usershare_active_16px.svg @@ -0,0 +1,17 @@ + + + + share_active_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/usershare_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/usershare_normal_16px.svg new file mode 100644 index 0000000..c57d445 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/usershare_normal_16px.svg @@ -0,0 +1,17 @@ + + + + share_normal_16px + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/videos_active_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/videos_active_16px.svg new file mode 100644 index 0000000..21d5812 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/videos_active_16px.svg @@ -0,0 +1,15 @@ + + + + videos_active_16px + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/videos_normal_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/videos_normal_16px.svg new file mode 100644 index 0000000..9f5819f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/dark/icons/videos_normal_16px.svg @@ -0,0 +1,22 @@ + + + + videos_normal_16px + Created with Sketch. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/light/config.ini b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/light/config.ini new file mode 100644 index 0000000..41bb25a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/light/config.ini @@ -0,0 +1,392 @@ +[BookmarkItem] +background=transparent +color=black + +[BookmarkItem:pressed] +background=#332ca7f8 +color=#2ca7f8 + +[BookmarkItem:hover] +background=#0C000000 + +[BookmarkItem:checked] +background=#332ca7f8 +color=#2ca7f8 + +[BookmarkItem.DBookmarkLine] +background=#19000000 + +[BookmarkItem.File] +icon=:/leftsidebar/images/leftsidebar/file_normal_16px.svg +[BookmarkItem.File:hover] +icon=:/leftsidebar/images/leftsidebar/file_normal_16px.svg +[BookmarkItem.File:checked] +icon=:/leftsidebar/images/leftsidebar/file_active_16px.svg + +[BookmarkItem.Recent] +icon=:/leftsidebar/images/leftsidebar/recent_normal_16px.svg +[BookmarkItem.Recent:hover] +icon=:/leftsidebar/images/leftsidebar/recent_normal_16px.svg +[BookmarkItem.Recent:checked] +icon=:/leftsidebar/images/leftsidebar/recent_active_16px.svg + +[BookmarkItem.Home] +icon=:/leftsidebar/images/leftsidebar/home_normal_16px.svg +[BookmarkItem.Home:hover] +icon=:/leftsidebar/images/leftsidebar/home_normal_16px.svg +[BookmarkItem.Home:checked] +icon=:/leftsidebar/images/leftsidebar/home_active_16px.svg + +[BookmarkItem.Desktop] +icon=:/leftsidebar/images/leftsidebar/desktop_normal_16px.svg +[BookmarkItem.Desktop:hover] +icon=:/leftsidebar/images/leftsidebar/desktop_normal_16px.svg +[BookmarkItem.Desktop:checked] +icon=:/leftsidebar/images/leftsidebar/desktop_active_16px.svg + +[BookmarkItem.Videos] +icon=:/leftsidebar/images/leftsidebar/videos_normal_16px.svg +[BookmarkItem.Videos:hover] +icon=:/leftsidebar/images/leftsidebar/videos_normal_16px.svg +[BookmarkItem.Videos:checked] +icon=:/leftsidebar/images/leftsidebar/videos_active_16px.svg + +[BookmarkItem.Music] +icon=:/leftsidebar/images/leftsidebar/music_normal_16px.svg +[BookmarkItem.Music:hover] +icon=:/leftsidebar/images/leftsidebar/music_normal_16px.svg +[BookmarkItem.Music:checked] +icon=:/leftsidebar/images/leftsidebar/music_active_16px.svg + +[BookmarkItem.Pictures] +icon=:/leftsidebar/images/leftsidebar/pictures_normal_16px.svg +[BookmarkItem.Pictures:hover] +icon=:/leftsidebar/images/leftsidebar/pictures_normal_16px.svg +[BookmarkItem.Pictures:checked] +icon=:/leftsidebar/images/leftsidebar/pictures_active_16px.svg + +[BookmarkItem.Documents] +icon=:/leftsidebar/images/leftsidebar/documents_normal_16px.svg +[BookmarkItem.Documents:hover] +icon=:/leftsidebar/images/leftsidebar/documents_normal_16px.svg +[BookmarkItem.Documents:checked] +icon=:/leftsidebar/images/leftsidebar/documents_active_16px.svg + +[BookmarkItem.Downloads] +icon=:/leftsidebar/images/leftsidebar/downloads_normal_16px.svg +[BookmarkItem.Downloads:hover] +icon=:/leftsidebar/images/leftsidebar/downloads_normal_16px.svg +[BookmarkItem.Downloads:checked] +icon=:/leftsidebar/images/leftsidebar/downloads_active_16px.svg + +[BookmarkItem.Trash] +icon=:/leftsidebar/images/leftsidebar/trash_normal_16px.svg +[BookmarkItem.Trash:hover] +icon=:/leftsidebar/images/leftsidebar/trash_normal_16px.svg +[BookmarkItem.Trash:checked] +icon=:/leftsidebar/images/leftsidebar/trash_active_16px.svg + +[BookmarkItem.Computer] +icon=:/leftsidebar/images/leftsidebar/computer_normal_16px.svg +[BookmarkItem.Computer:hover] +icon=:/leftsidebar/images/leftsidebar/computer_normal_16px.svg +[BookmarkItem.Computer:checked] +icon=:/leftsidebar/images/leftsidebar/computer_active_16px.svg + +[BookmarkItem.Disk] +icon=:/leftsidebar/images/leftsidebar/disk_normal_16px.svg +[BookmarkItem.Disk:hover] +icon=:/leftsidebar/images/leftsidebar/disk_normal_16px.svg +[BookmarkItem.Disk:checked] +icon=:/leftsidebar/images/leftsidebar/disk_active_16px.svg + +[BookmarkItem.Usb] +icon=:/leftsidebar/images/leftsidebar/usb_normal_16px.svg +[BookmarkItem.Usb:hover] +icon=:/leftsidebar/images/leftsidebar/usb_normal_16px.svg +[BookmarkItem.Usb:checked] +icon=:/leftsidebar/images/leftsidebar/usb_active_16px.svg + +[BookmarkItem.Iphone] +icon=:/leftsidebar/images/leftsidebar/iphone_normal_16px.svg +[BookmarkItem.Iphone:hover] +icon=:/leftsidebar/images/leftsidebar/iphone_normal_16px.svg +[BookmarkItem.Iphone:checked] +icon=:/leftsidebar/images/leftsidebar/iphone_active_16px.svg + +[BookmarkItem.Android] +icon=:/leftsidebar/images/leftsidebar/android_normal_16px.svg +[BookmarkItem.Android:hover] +icon=:/leftsidebar/images/leftsidebar/android_normal_16px.svg +[BookmarkItem.Android:checked] +icon=:/leftsidebar/images/leftsidebar/android_active_16px.svg + +[BookmarkItem.Network] +icon=:/leftsidebar/images/leftsidebar/network_normal_16px.svg +[BookmarkItem.Network:hover] +icon=:/leftsidebar/images/leftsidebar/network_normal_16px.svg +[BookmarkItem.Network:checked] +icon=:/leftsidebar/images/leftsidebar/network_active_16px.svg + +[BookmarkItem.UserShare] +icon=:/leftsidebar/images/leftsidebar/usershare_normal_16px.svg +[BookmarkItem.UserShare:hover] +icon=:/leftsidebar/images/leftsidebar/usershare_normal_16px.svg +[BookmarkItem.UserShare:checked] +icon=:/leftsidebar/images/leftsidebar/usershare_active_16px.svg + +[BookmarkItem.Dvd] +icon=:/leftsidebar/images/leftsidebar/dvd_normal_16px.svg +[BookmarkItem.Dvd:hover] +icon=:/leftsidebar/images/leftsidebar/dvd_normal_16px.svg +[BookmarkItem.Dvd:checked] +icon=:/leftsidebar/images/leftsidebar/dvd_active_16px.svg + +[BookmarkItem.System Disk] +icon=:/leftsidebar/images/leftsidebar/disk_normal_16px.svg +[BookmarkItem.System Disk:hover] +icon=:/leftsidebar/images/leftsidebar/disk_normal_16px.svg +[BookmarkItem.System Disk:checked] +icon=:/leftsidebar/images/leftsidebar/disk_active_16px.svg + +[BookmarkItem.BookMarks] +icon=:/leftsidebar/images/leftsidebar/bookmarks_normal_16px.svg +[BookmarkItem.BookMarks:hover] +icon=:/leftsidebar/images/leftsidebar/bookmarks_normal_16px.svg +[BookmarkItem.BookMarks:checked] +icon=:/leftsidebar/images/leftsidebar/bookmarks_active_16px.svg + +[BookmarkItem.MountedIndicator] +icon=:/leftsidebar/images/leftsidebar/unmount_normal_16px.svg +[BookmarkItem.MountedIndicator:hover] +icon=:/leftsidebar/images/leftsidebar/unmount_hover_16px.svg +[BookmarkItem.MountedIndicator:checked] +icon=:/leftsidebar/images/leftsidebar/unmount_active_16px.svg + + +[CrumbIconButton.Recent] +icon=:/leftsidebar/images/leftsidebar/recent_normal_16px.svg +[CrumbIconButton.Recent:hover] +icon=:/leftsidebar/images/leftsidebar/recent_normal_16px.svg +[CrumbIconButton.Recent:checked] +icon=:/icons/images/icons/recent_checked_16px.svg + +[CrumbIconButton.Home] +icon=:/leftsidebar/images/leftsidebar/home_normal_16px.svg +[CrumbIconButton.Home:hover] +icon=:/leftsidebar/images/leftsidebar/home_normal_16px.svg +[CrumbIconButton.Home:checked] +icon=:/icons/images/icons/home_checked_16px.svg + +[CrumbIconButton.Trash] +icon=:/leftsidebar/images/leftsidebar/trash_normal_16px.svg +[CrumbIconButton.Trash:hover] +icon=:/leftsidebar/images/leftsidebar/trash_normal_16px.svg +[CrumbIconButton.Trash:checked] +icon=:/icons/images/icons/trash_checked_16px.svg + +[CrumbIconButton.Computer] +icon=:/leftsidebar/images/leftsidebar/computer_normal_16px.svg +[CrumbIconButton.Computer:hover] +icon=:/leftsidebar/images/leftsidebar/computer_normal_16px.svg +[CrumbIconButton.Computer:checked] +icon=:/icons/images/icons/computer_checked_16px.svg + +[CrumbIconButton.Disk] +icon=:/leftsidebar/images/leftsidebar/disk_normal_16px.svg +[CrumbIconButton.Disk:hover] +icon=:/leftsidebar/images/leftsidebar/disk_normal_16px.svg +[CrumbIconButton.Disk:checked] +icon=:/icons/images/icons/disk_checked_16px.svg + +[CrumbIconButton.Usb] +icon=:/leftsidebar/images/leftsidebar/usb_normal_16px.svg +[CrumbIconButton.Usb:hover] +icon=:/leftsidebar/images/leftsidebar/usb_normal_16px.svg +[CrumbIconButton.Usb:checked] +icon=:/icons/images/icons/usb_checked_16px.svg + +[CrumbIconButton.Iphone] +icon=:/leftsidebar/images/leftsidebar/iphone_normal_16px.svg +[CrumbIconButton.Iphone:hover] +icon=:/leftsidebar/images/leftsidebar/iphone_normal_16px.svg +[CrumbIconButton.Iphone:checked] +icon=:/icons/images/icons/iphone_checked_16px.svg + +[CrumbIconButton.Android] +icon=:/leftsidebar/images/leftsidebar/android_normal_16px.svg +[CrumbIconButton.Android:hover] +icon=:/leftsidebar/images/leftsidebar/android_normal_16px.svg +[CrumbIconButton.Android:checked] +icon=:/icons/images/icons/android_checked_16px.svg + +[CrumbIconButton.Network] +icon=:/leftsidebar/images/leftsidebar/network_normal_16px.svg +[CrumbIconButton.Network:hover] +icon=:/leftsidebar/images/leftsidebar/network_normal_16px.svg +[CrumbIconButton.Network:checked] +icon=:/icons/images/icons/network_checked_16px.svg + +[CrumbIconButton.UserShare] +icon=:/leftsidebar/images/leftsidebar/usershare_normal_16px.svg +[CrumbIconButton.UserShare:hover] +icon=:/leftsidebar/images/leftsidebar/usershare_normal_16px.svg +[CrumbIconButton.UserShare:checked] +icon=:/icons/images/icons/usershare_checked_16px.svg + +[CrumbIconButton.Dvd] +icon=:/leftsidebar/images/leftsidebar/dvd_normal_16px.svg +[CrumbIconButton.Dvd:hover] +icon=:/leftsidebar/images/leftsidebar/dvd_normal_16px.svg +[CrumbIconButton.Dvd:checked] +icon=:/icons/images/icons/dvd_checked_16px.svg + +[CrumbIconButton.System Disk] +icon=:/leftsidebar/images/leftsidebar/disk_normal_16px.svg +[CrumbIconButton.System Disk:hover] +icon=:/leftsidebar/images/leftsidebar/disk_normal_16px.svg +[CrumbIconButton.System Disk:checked] +icon=:/icons/images/icons/disk_checked_16px.svg + +[CrumbIconButton.Tags] +icon=:/icons/images/icons/tag_normal.svg +[CrumbIconButton.Tags:hover] +icon=:/icons/images/icons/tag_normal.svg +[CrumbIconButton.Tags:checked] +icon=:/icons/images/icons/tag_normal.svg + +[CrumbIconButton.Bookmarks] +icon=:/dark/icons/bookmarks_checked_16px.svg +[CrumbIconButton.Bookmarks:hover] +icon=:/dark/icons/bookmarks_checked_16px.svg +[CrumbIconButton.Bookmarks:checked] +icon=:/dark/icons/bookmarks_checked_16px.svg + + +[BookmarkItem.Orange] +icon=:/icons/images/icons/tag_orange_normal.svg +[BookmarkItem.Orange.:hover] +icon=:/icons/images/icons/tag_orange_active.svg +[BookmarkItem.Orange.checked] +icon=:/icons/images/icons/tag_orange_active.svg + +[BookmarkItem.Red] +icon=:/icons/images/icons/tag_red_normal.svg +[BookmarkItem.Red:hover] +icon=:/icons/images/icons/tag_red_active.svg +[BookmarkItem.Red:checked] +icon=:/icons/images/icons/tag_red_active.svg + +[BookmarkItem.Purple] +icon=:/icons/images/icons/tag_purple_normal.svg +[BookmarkItem.Purple:hover] +icon=:/icons/images/icons/tag_purple_active.svg +[BookmarkItem.Purple:checked] +icon=:/icons/images/icons/tag_purple_active.svg + +[BookmarkItem.Navy-blue] +icon=:/icons/images/icons/tag_deepblue_normal.svg +[BookmarkItem.Navy-blue:hover] +icon=:/icons/images/icons/tag_deepblue_active.svg +[BookmarkItem.Navy-blue:checked] +icon=:/icons/images/icons/tag_deepblue_active.svg + +[BookmarkItem.Azure] +icon=:/icons/images/icons/tag_lightblue_normal.svg +[BookmarkItem.Azure:hover] +icon=:/icons/images/icons/tag_lightblue_active.svg +[BookmarkItem.Azure:checked] +icon=:/icons/images/icons/tag_lightblue_active.svg + +[BookmarkItem.Grass-green] +icon=:/icons/images/icons/tag_green_normal.svg +[BookmarkItem.Grass-green:hover] +icon=:/icons/images/icons/tag_green_active.svg +[BookmarkItem.Grass-green:checked] +icon=:/icons/images/icons/tag_green_active.svg + +[BookmarkItem.Yellow] +icon=:/icons/images/icons/tag_yellow_normal.svg +[BookmarkItem.Yellow:hover] +icon=:/icons/images/icons/tag_yellow_active.svg +[BookmarkItem.Yellow:checked] +icon=:/icons/images/icons/tag_yellow_active.svg + +[BookmarkItem.Gray] +icon=:/icons/images/icons/tag_gray_normal.svg +[BookmarkItem.Gray:hover] +icon=:/icons/images/icons/tag_gray_active.svg +[BookmarkItem.Gray:checked] +icon=:/icons/images/icons/tag_gray_active.svg + + +[FileView] +background=#2da6f7 +color=#303030 +shadow=#b2000000 +overlap=#03000000 +iconview.icon=:/icons/images/icons/icon_view_normal.svg +listview.icon=:/icons/images/icons/list_view_normal.svg +[FileView:checked] +iconview.icon=:/icons/images/icons/icon_view_checked.svg +listview.icon=:/icons/images/icons/list_view_checked.svg +[FileView:hover] +iconview.icon=:/icons/images/icons/icon_view_hover.svg +listview.icon=:/icons/images/icons/list_view_hover.svg +[FileView:focus] +background=#0076F9 +[FileView:disable] +color=#797979 +[FileView:inactive] +background=#BFE4FC +color=#797979 +[FileView:inactive.checked] +color=#e9e9e9 + +[Tab] +background=#fafafa +color=#949494 +border=#21000000 +[Tab:hover] +background=#EDEDED +color=#303030 +[Tab:checked] +background=white +color=#2ca7f8 + +[TabCloseButton] +icon=:/icons/images/icons/tab_close_normal.png +[TabCloseButton:hover] +icon=:/icons/images/icons/tab_close_hover.png +[TabCloseButton:pressed] +icon=:/icons/images/icons/tab_close_press.png +[TabCloseButton:focus] +icon=:/icons/images/icons/active_tab_close_normal.png +[TabCloseButton:hover.focus] +icon=:/icons/images/icons/active_tab_close_hover.png +[TabCloseButton:pressed.focus] +icon=:/icons/images/icons/active_tab_close_press.png + + +[DSearchBar.clearAction] +icon=:/icons/images/icons/input_clear_normal.svg +[DSearchBar.clearAction:hover] +icon=:/icons/images/icons/input_clear_hover.svg +[DSearchBar.clearAction:pressed] +icon=:/icons/images/icons/input_clear_press.svg + +[DSearchBar.searchAction] +icon=:/icons/images/icons/search.svg + +[DSearchBar.jumpToAction] +icon=:/icons/images/icons/jump_to.svg + +[DSearchBar.glowingAnimation] +image=:/light/icons/glowing.svg + +[DFMCrumbBar] +background=#ffffff + +[CrumbBar.BorderLine] +border-color=#1e000000 + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/light/icons/glowing.svg b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/light/icons/glowing.svg new file mode 100644 index 0000000..643a968 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/light/icons/glowing.svg @@ -0,0 +1,18 @@ + + + + glowing_light + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/themes.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/themes.qrc new file mode 100644 index 0000000..de2f03b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/themes/themes.qrc @@ -0,0 +1,89 @@ + + + dark/config.ini + light/config.ini + dark/icons/Android_phone_active_16px.svg + dark/icons/Android_phone_normal_16px.svg + dark/icons/backward_disabled.svg + dark/icons/backward_hover.svg + dark/icons/backward_normal.svg + dark/icons/backward_press.svg + dark/icons/bookmarks_active_16px.svg + dark/icons/bookmarks_checked_16px.svg + dark/icons/bookmarks_normal_16px.svg + dark/icons/computer_active_16px.svg + dark/icons/computer_normal_16px.svg + dark/icons/desktop_active_16px.svg + dark/icons/desktop_normal_16px.svg + dark/icons/disk_active_16px.svg + dark/icons/disk_normal_16px.svg + dark/icons/documents_active_16px.svg + dark/icons/documents_normal_16px.svg + dark/icons/down.svg + dark/icons/download_active_16px.svg + dark/icons/download_normal_16px.svg + dark/icons/file_active_16px.svg + dark/icons/file_normal_16px.svg + dark/icons/forward_disabled.svg + dark/icons/forward_hover.svg + dark/icons/forward_normal.svg + dark/icons/forward_press.svg + dark/icons/home_active_16px.svg + dark/icons/home_normal_16px.svg + dark/icons/icon_view_active.svg + dark/icons/icon_view_normal.svg + dark/icons/iphone_active_16px.svg + dark/icons/iphone_normal_16px.svg + dark/icons/list_view_active.svg + dark/icons/list_view_normal.svg + dark/icons/music_active_16px.svg + dark/icons/music_normal_16px.svg + dark/icons/new_tab_disabled.svg + dark/icons/new_tab_hover.svg + dark/icons/new_tab_normal.svg + dark/icons/new_tab_press.svg + dark/icons/pictures_active_16px.svg + dark/icons/pictures_normal_16px.svg + dark/icons/recent_active_16px.svg + dark/icons/recent_normal_16px.svg + dark/icons/search_hover.svg + dark/icons/search_normal.svg + dark/icons/search_press.svg + dark/icons/filter_hover.svg + dark/icons/filter_normal.svg + dark/icons/filter_active.svg + dark/icons/trash_active_16px.svg + dark/icons/trash_normal_16px.svg + dark/icons/unmount_active.svg + dark/icons/unmount_hover.svg + dark/icons/unmount_normal.svg + dark/icons/unmount_press.svg + dark/icons/up.svg + dark/icons/videos_active_16px.svg + dark/icons/videos_normal_16px.svg + dark/icons/active_tab_close_hover.svg + dark/icons/active_tab_close_normal.svg + dark/icons/active_tab_close_press.svg + dark/icons/icon_view_hover.svg + dark/icons/list_view_hover.svg + dark/icons/tab_close_hover.svg + dark/icons/tab_close_normal.svg + dark/icons/tab_close_press.svg + dark/icons/network_normal_16px.svg + dark/icons/network_active_16px.svg + dark/icons/usb_active_16px.svg + dark/icons/usb_normal_16px.svg + dark/icons/media_active_16px.svg + dark/icons/media_normal_16px.svg + dark/icons/usershare_active_16px.svg + dark/icons/usershare_normal_16px.svg + dark/icons/input_clear_hover.svg + dark/icons/input_clear_normal.svg + dark/icons/input_clear_press.svg + dark/icons/jump_to.svg + dark/icons/search.svg + dark/icons/glowing.svg + light/icons/glowing.svg + dark/icons/caution.svg + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager.ts new file mode 100644 index 0000000..459b46b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + New Folder + + + + Mounting device error + Mounting device error + + + + The disc image was corrupted, cannot mount now, please erase the disc first + The disc image was corrupted, cannot mount now, please erase the disc first + + + + Mount error: unsupported image format + Mount error: unsupported image format + + + + + The device was not safely removed + The device was not safely removed + + + + + Click "Safely Remove" and then disconnect it next time + Click "Safely Remove" and then disconnect it next time + + + + The device was not ejected + The device was not ejected + + + + Disk is busy, cannot eject now + Disk is busy, cannot eject now + + + + Authentication timed out + Authentication timed out + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Bluetooth File Transfer + + + + File Transfer Successful + File Transfer Successful + + + + File Transfer Failed + File Transfer Failed + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Sending files to "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Failed to send files to "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Sent to "<b style="font-weight: 550;">%1</b>" successfully + + + + Select a Bluetooth device to receive files + Select a Bluetooth device to receive files + + + + Cannot find the connected Bluetooth device + Cannot find the connected Bluetooth device + + + + Waiting to be received... + Waiting to be received... + + + + Go to Bluetooth Settings + Go to Bluetooth Settings + + + + %1/%2 Sent + %1/%2 Sent + + + + Error: the Bluetooth device is disconnected + Error: the Bluetooth device is disconnected + + + + Unable to send the file more than 2 GB + Unable to send the file more than 2 GB + + + + Unable to send 0 KB files + Unable to send 0 KB files + + + + File doesn't exist + File doesn't exist + + + + Next + button + Next + + + + Cancel + button + Cancel + + + + Done + button + Done + + + + Retry + button + Retry + + + + OK + button + OK + + + + File sending request timed out + File sending request timed out + + + + The service is busy and unable to process the request + The service is busy and unable to process the request + + + + BurnOptDialog + + + Device error + Device error + + + + Optical device %1 doesn't exist + Optical device %1 doesn't exist + + + + Advanced settings + Advanced settings + + + + File system: + File system: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (For Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (For Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Compatible with Windows CD/DVD mode) + + + + ISO9660 Only + ISO9660 Only + + + + CloseAllDialogIndicator + + + Close all + Close all + + + + Total size: %1, %2 files + Total size: %1, %2 files + + + + ComputerModel + + + Double click to open it + Double click to open it + + + + My Directories + My Directories + + + + Disks + Disks + + + + File Vault + File Vault + + + + Quick Access + Quick Access + + + + ComputerPropertyDialog + + + Computer + Computer + + + + Basic Info + Basic Info + + + + + Computer Name + Computer Name + + + + + Edition + Edition + + + + + + Version + Version + + + + + Type + Type + + + + + + Processor + Processor + + + + + + Memory + Memory + + + + + + + Bit + Bit + + + + + Available + Available + + + + Obtaining... + Obtaining... + + + + ConnectToServerDialog + + + Connect to Server + Connect to Server + + + + Cancel + button + Cancel + + + + Connect + button + Connect + + + + My Favorites: + My Favorites: + + + + + Clear History + Clear History + + + + DFMAddressBar + + + Search or enter address + Search or enter address + + + + DFMAdvanceSearchBar + + + Search: + Search: + + + + File Type: + File Type: + + + + File Size: + File Size: + + + + Time Modified: + Time Modified: + + + + Time Accessed: + Time Accessed: + + + + Time Created: + Time Created: + + + + Reset + Reset + + + + All subdirectories + All subdirectories + + + + Current directory + Current directory + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Today + + + + Yesterday + Yesterday + + + + This week + This week + + + + Last week + Last week + + + + This month + This month + + + + Last month + Last month + + + + This year + This year + + + + Last year + Last year + + + + DFMOpticalMediaWidget + + + + No files to burn + No files to burn + + + + Unable to burn. Not enough free space on the target disk. + Unable to burn. Not enough free space on the target disk. + + + + %1 burning is not supported + %1 burning is not supported + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + + + + DFMTagCrumbController + + + Tag information + Tag information + + + + DFMTagWidget + + + Tag + Tag + + + + DFMTaskWidget + + + Do not ask again + Do not ask again + + + + Syncing data + Syncing data + + + + Please wait + Please wait + + + + + Time modified: %1 + Time modified: %1 + + + + + Contains: %1 + Contains: %1 + + + + + Size: %1 + Size: %1 + + + + Original folder + Original folder + + + + Keep both + button + Keep both + + + + Skip + button + Skip + + + + Replace + button + Replace + + + + Retry + button + Retry + + + + Original file + Original file + + + + Target folder + Target folder + + + + Target file + Target file + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Encrypt File Vault + + + + Click 'Encrypt' and input the user password. + Click 'Encrypt' and input the user password. + + + + Encrypting... + Encrypting... + + + + + + + Encrypt + Encrypt + + + + Failed to create file vault: %1 + Failed to create file vault: %1 + + + + OK + OK + + + + The setup is complete + The setup is complete + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Save Recovery Key + + + + Keep the key safe to retrieve the vault password later + Keep the key safe to retrieve the vault password later + + + + Save to default path + Save to default path + + + + Save to other locations + Save to other locations + + + + No permission, please reselect + No permission, please reselect + + + + Select a path + Select a path + + + + Next + Next + + + + The default path is invisible to other users, and the path information will not be shown. + The default path is invisible to other users, and the path information will not be shown. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Recovery Key + + + + Generate a recovery key in case that you forgot the password + Generate a recovery key in case that you forgot the password + + + + Key + Key + + + + QR code + QR code + + + + Scan QR code and save the key to another device + Scan QR code and save the key to another device + + + + Next + Next + + + + Recovery Key: + Recovery Key: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Set Vault Password + + + + Method + Method + + + + Manual + Manual + + + + Password + Password + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + + + + Repeat password + Repeat password + + + + Input the password again + Input the password again + + + + Password hint + Password hint + + + + Optional + Optional + + + + Next + Next + + + + + Passwords do not match + Passwords do not match + + + + DFMVaultActiveStartView + + + File Vault + File Vault + + + + Create your secure private space + Create your secure private space + + + + Advanced encryption technology + Advanced encryption technology + + + + Convenient and easy to use + Convenient and easy to use + + + + Create + Create + + + + DFMVaultFileView + + + Cannot open this path + Cannot open this path + + + + Hint + Hint + + + + OK + OK + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Unlock by Key + + + + Failed to unlock file vault + Failed to unlock file vault + + + + OK + OK + + + + Input the 32-digit recovery key + Input the 32-digit recovery key + + + + Cancel + button + Cancel + + + + Unlock + button + Unlock + + + + Wrong recovery key + Wrong recovery key + + + + DFMVaultRemoveByPasswordView + + + Password + Password + + + + Password hint: %1 + Password hint: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Input the 32-digit recovery key + + + + DFMVaultRemovePages + + + Delete File Vault + Delete File Vault + + + + Once deleted, the files in it will be permanently deleted + Once deleted, the files in it will be permanently deleted + + + + Use Key + Use Key + + + + Cancel + button + Cancel + + + + Use Key + button + Use Key + + + + Delete + button + Delete + + + + + OK + button + OK + + + + Use Password + Use Password + + + + Wrong password + Wrong password + + + + Wrong recovery key + Wrong recovery key + + + + Failed to delete file vault + Failed to delete file vault + + + + Deleted successfully + Deleted successfully + + + + Failed to delete + Failed to delete + + + + Removing... + Removing... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + Unable to get the key file + + + + Verification failed + Verification failed + + + + + Select a path + Select a path + + + + + Retrieve Password + Retrieve Password + + + + By key in the default path + By key in the default path + + + + By key in the specified path + By key in the specified path + + + + Verification Successful + Verification Successful + + + + Keep it safe + Keep it safe + + + + Back + button + Back + + + + Verify Key + button + Verify Key + + + + Go to Unlock + button + Go to Unlock + + + + Close + button + Close + + + + Vault password: %1 + Vault password: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Unlock File Vault + + + + Forgot password? + Forgot password? + + + + Password hint: %1 + Password hint: %1 + + + + Failed to unlock file vault + Failed to unlock file vault + + + + Cancel + button + Cancel + + + + Password + Password + + + + Unlock + button + Unlock + + + + Please try again %1 minutes later + Please try again %1 minutes later + + + + Wrong password, please try again %1 minutes later + Wrong password, please try again %1 minutes later + + + + Wrong password, one chance left + Wrong password, one chance left + + + + Wrong password, %1 chances left + Wrong password, %1 chances left + + + + Wrong password + Wrong password + + + + OK + button + OK + + + + DFileCopyMoveJob + + + Permission error + Permission error + + + + The action is denied + The action is denied + + + + Failed to open the file + Failed to open the file + + + + Failed to read the file + Failed to read the file + + + + Failed to write the file + Failed to write the file + + + + Failed to create the directory + Failed to create the directory + + + + Failed to delete the file + Failed to delete the file + + + + Failed to move the file + Failed to move the file + + + + Original file does not exist + Original file does not exist + + + + Failed, file size must be less than 4GB + Failed, file size must be less than 4GB + + + + Not enough free space on the target disk + Not enough free space on the target disk + + + + File integrity was damaged + File integrity was damaged + + + + The target device is read only + The target device is read only + + + + Target folder is inside the source folder + Target folder is inside the source folder + + + + The action is not supported + The action is not supported + + + + You do not have permission to traverse files in it + You do not have permission to traverse files in it + + + + Failed to position the file pointer! + Failed to position the file pointer! + + + + copy + Extra name added to new file name when used for file name. + copy + + + + Failed to open the directory, cause: file name too long + Failed to open the directory, cause: file name too long + + + + + Failed to open the file, cause: file name too long + Failed to open the file, cause: file name too long + + + + + Failed to write the file, cause: + Failed to write the file, cause: + + + + Failed to position the file pointer, cause: %1 + Failed to position the file pointer, cause: %1 + + + + Syncing data + Syncing data + + + + Please wait + Please wait + + + + Failed to create the directory, cause: %1 + Failed to create the directory, cause: %1 + + + + + + + + Failed to open the file, cause: %1 + Failed to open the file, cause: %1 + + + + + + + Failed to open the file, cause: Permission denied + Failed to open the file, cause: Permission denied + + + + + Failed to read the file, cause: %1 + Failed to read the file, cause: %1 + + + + + + + Failed to write the file, cause: %1 + Failed to write the file, cause: %1 + + + + + File integrity was damaged, cause: %1 + File integrity was damaged, cause: %1 + + + + Failed to open the file, cause: + Failed to open the file, cause: + + + + Failed to read the file, cause: + Failed to read the file, cause: + + + + Failed to delete the file, cause: %1 + Failed to delete the file, cause: %1 + + + + Fail to create symlink, cause: %1 + Fail to create symlink, cause: %1 + + + + DFileDialog + + + + Save + button + Save + + + + + Cancel + button + Cancel + + + + Confirm + button + Confirm + + + + %1 already exists, do you want to replace it? + %1 already exists, do you want to replace it? + + + + Replace + button + Replace + + + + Open + button + Open + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + + + + DFileManagerWindow + + + Trash + Trash + + + + Empty + Empty + + + + DFileSystemModel + + + + Name + Name + + + + + + Time modified + Time modified + + + + Size + Size + + + + Type + Type + + + + Time created + Time created + + + + + Last access + Last access + + + + + + + Path + Path + + + + DFileView + + + Disc mount error + Disc mount error + + + + The disc is in use, please end the running process and remount the disc. + The disc is in use, please end the running process and remount the disc. + + + + Mounting failed + Mounting failed + + + + (Reverse) + (Reverse) + + + + DFileViewHelper + + + Add tag "%1" + Add tag "%1" + + + + DStatusBar + + + %1 item + %1 item + + + + %1 items + %1 items + + + + %1 item selected + %1 item selected + + + + %1 items selected + %1 items selected + + + + %1 folder selected (contains %2) + %1 folder selected (contains %2) + + + + %1 folders selected (contains %2) + %1 folders selected (contains %2) + + + + %1 file selected (%2) + %1 file selected (%2) + + + + %1 files selected (%2) + %1 files selected (%2) + + + + %1 folder selected + %1 folder selected + + + + Filter + Filter + + + + Save as: + Save as: + + + + Loading... + Loading... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + Burning disc %1, please wait... + + + + Writing data... + Writing data... + + + + Verifying data... + Verifying data... + + + + Copying %1 + Copying %1 + + + + + + to %2 + to %2 + + + + %1 already exists in target folder + %1 already exists in target folder + + + + Original path %1 Target path %2 + Original path %1 Target path %2 + + + + Merge + button + Merge + + + + Replace + button + Replace + + + + Moving %1 + Moving %1 + + + + Removing file vault, please try later + Removing file vault, please try later + + + + Restoring %1 + Restoring %1 + + + + Deleting %1 + Deleting %1 + + + + Trashing %1 + Trashing %1 + + + + Calculating space, please wait + Calculating space, please wait + + + + DUMountManager + + + + Authentication timed out + Authentication timed out + + + + + + Disk is busy, cannot unmount now + Disk is busy, cannot unmount now + + + + Disk is busy, cannot eject now + Disk is busy, cannot eject now + + + + The device is busy, cannot eject now + The device is busy, cannot eject now + + + + + + The device is busy, cannot remove now + The device is busy, cannot remove now + + + + DeepinStorage + + + + + %1 Volume + %1 Volume + + + + Data Disk + Data Partition + Data Disk + + + + %1 Drive + %1 Drive + + + + Blank %1 Disc + Blank %1 Disc + + + + %1 Encrypted + %1 Encrypted + + + + DialogManager + + + + + + Operation failed! + Operation failed! + + + + Target folder is inside the source folder! + Target folder is inside the source folder! + + + + Do you want to run %1 or display its content? + Do you want to run %1 or display its content? + + + + It is an executable text file. + It is an executable text file. + + + + It is an executable file. + It is an executable file. + + + + This file is not executable, do you want to add the execute permission and run? + This file is not executable, do you want to add the execute permission and run? + + + + "%1" already exists, please use another name. + "%1" already exists, please use another name. + + + + The file name must not contain two dots (..) + The file name must not contain two dots (..) + + + + Device or resource busy + Device or resource busy + + + + Are you sure you want to erase all data on the disc? + Are you sure you want to erase all data on the disc? + + + + How do you want to use this disc? + How do you want to use this disc? + + + + Disc erase failed + Disc erase failed + + + + Burn process failed + Burn process failed + + + + %1: %2 + %1: %2 + + + + Show details + Show details + + + + Hide details + Hide details + + + + Error + Error + + + + Permanently delete %1? + Permanently delete %1? + + + + Permanently delete %1 items? + Permanently delete %1 items? + + + + Empty + Empty + + + + Do you want to delete %1? + Do you want to delete %1? + + + + Do you want to delete the selected %1 items? + Do you want to delete the selected %1 items? + + + + Sorry, unable to locate your bookmark directory, remove it? + Sorry, unable to locate your bookmark directory, remove it? + + + + Name: + Name: + + + + %1 that this shortcut refers to has been changed or moved + %1 that this shortcut refers to has been changed or moved + + + + Do you want to delete this shortcut? + Do you want to delete this shortcut? + + + + Failed, file size must be less than 4GB. + Failed, file size must be less than 4GB. + + + + Fail to create symlink, cause: + Fail to create symlink, cause: + + + + The selected files contain system file/directory, and it cannot be deleted + The selected files contain system file/directory, and it cannot be deleted + + + + Unable to find the original file + Unable to find the original file + + + + + You do not have permission to operate file/folder! + You do not have permission to operate file/folder! + + + + Failed to restore %1 file, the source file does not exist + Failed to restore %1 file, the source file does not exist + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Sorry, you don't have permission to operate the following %1 file/folder(s)! + + + + Unable to access %1 + Unable to access %1 + + + + + Sending files now, please try later + Sending files now, please try later + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + To access the device, you must format the disk first. Are you sure you want to format it now? + + + + Scanning the device, stop it? + Scanning the device, stop it? + + + + Share folder can't be named after the current username + Share folder can't be named after the current username + + + + Do you want to run %1? + Do you want to run %1? + + + + Burn image + button + Burn image + + + + Burn files + button + Burn files + + + + Are you sure you want to empty %1 item? + Are you sure you want to empty %1 item? + + + + Are you sure you want to empty %1 items? + Are you sure you want to empty %1 items? + + + + + This action cannot be undone + This action cannot be undone + + + + + + + + + + + + + + OK + button + OK + + + + + + + + + + + + + + + Cancel + button + Cancel + + + + + + Run + button + Run + + + + + Run in terminal + button + Run in terminal + + + + Display + button + Display + + + + + + + + + + + Confirm + button + Confirm + + + + Erase + button + Erase + + + + Data verification failed + Data verification failed + + + + Show details + button + Show details + + + + + Delete + button + Delete + + + + Remove + button + Remove + + + + Disk is busy, cannot unmount now + Disk is busy, cannot unmount now + + + + Force unmount + button + Force unmount + + + + Unable to copy. Not enough free space on the target disk. + Unable to copy. Not enough free space on the target disk. + + + + Failed to restore %1 file, the target folder is read-only + Failed to restore %1 file, the target folder is read-only + + + + Failed to restore %1 files, the target folder is read-only + Failed to restore %1 files, the target folder is read-only + + + + Failed to restore %1 files, the source files do not exist + Failed to restore %1 files, the source files do not exist + + + + Format + button + Format + + + + Stop + button + Stop + + + + FileController + + + + + + Unable to find the original file + Unable to find the original file + + + + + + Kindly Reminder + Kindly Reminder + + + + + + Please install File Roller first and then continue + Please install File Roller first and then continue + + + + + Unable to create files here: %1 + Unable to create files here: %1 + + + + Confirm + button + Confirm + + + + FileDialogStatusBar + + + File Name + File Name + + + + Format + Format + + + + Save + button + Save + + + + Open + button + Open + + + + Save File + button + Save File + + + + Open File + button + Open File + + + + + + Cancel + button + Cancel + + + + FileJob + + + copy + copy + + + + + + + Data verification successful. + Data verification successful. + + + + + + Burn process completed + Burn process completed + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 is a duplicate file. + + + + Insufficient disc space. + Insufficient disc space. + + + + Lost connection to drive. + Lost connection to drive. + + + + The CD/DVD drive is not ready. Try another disc. + The CD/DVD drive is not ready. Try another disc. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + Unknown error + Unknown error + + + + Device disconnected + Device disconnected + + + + GenerateSettingTranslate + + + + + Basic + Basic + + + + + + Open behavior + Open behavior + + + + + + Always open folder in new window + Always open folder in new window + + + + + + Open file: + Open file: + + + + + + Click + Click + + + + + + Double click + Double click + + + + + + New window and tab + New window and tab + + + + + + Open from default window: + Open from default window: + + + + + + + + + Computer + Computer + + + + + + + + + Home + Home + + + + + + + + + Desktop + Desktop + + + + + + + + + Videos + Videos + + + + + + + + + Music + Music + + + + + + + + + Pictures + Pictures + + + + + + + + + Documents + Documents + + + + + + + + + Downloads + Downloads + + + + + + Open in new tab: + Open in new tab: + + + + + + Current Directory + Current Directory + + + + + + View + View + + + + + + Default size: + Default size: + + + + + + Extra small + Extra small + + + + + + Small + Small + + + + + + Medium + Medium + + + + + + Large + Large + + + + + + Extra large + Extra large + + + + + + Default view: + Default view: + + + + + + Icon + Icon + + + + + + List + List + + + + + + Hidden files + Hidden files + + + + + + Show hidden files + Show hidden files + + + + + + Hide file extension when rename + Hide file extension when rename + + + + + + Advanced + Advanced + + + + + + Index + Index + + + + + + Auto index internal disk + Auto index internal disk + + + + + + Index external storage device after connected to computer + Index external storage device after connected to computer + + + + + + Full-Text search + Full-Text search + + + + + + Show item counts and sizes in the path of mounted MTP devices + Show item counts and sizes in the path of mounted MTP devices + + + + + + Keep showing the mounted Samba shares + Keep showing the mounted Samba shares + + + + + + Use the file chooser dialog of File Manager + Use the file chooser dialog of File Manager + + + + + + Ask for my confirmation when deleting files + Ask for my confirmation when deleting files + + + + + + Other + Other + + + + + + Hide system disk + Hide system disk + + + + + + Show file system on disk icon + Show file system on disk icon + + + + + + Show hidden files in search results + Show hidden files in search results + + + + + + Display recent file entry in left panel + Display recent file entry in left panel + + + + + + Preview + Preview + + + + + Compress file preview + Compress file preview + + + + + + Text preview + Text preview + + + + + + Document preview + Document preview + + + + + + Image preview + Image preview + + + + + + Video preview + Video preview + + + + + + Mount + Mount + + + + + + Auto mount + Auto mount + + + + + + Open after auto mount + Open after auto mount + + + + + + Dialog + Dialog + + + + Compressed file preview + Compressed file preview + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Can’t verify the identity of %1. + + + + This happens when you log in to a computer the first time. + This happens when you log in to a computer the first time. + + + + The identity sent by the remote computer is + The identity sent by the remote computer is + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + If you want to be absolutely sure it is safe to continue, contact the system administrator. + + + + + + + + Mounting device error + Mounting device error + + + + + Wrong username or password + Wrong username or password + + + + + + + + Confirm + button + Confirm + + + + + Cannot find the mounted device + Cannot find the mounted device + + + + No key available to unlock device + No key available to unlock device + + + + The disk is mounted by user "%1", you cannot unmount it. + The disk is mounted by user "%1", you cannot unmount it. + + + + Cannot unmount the device + Cannot unmount the device + + + + Cannot eject the device "%1" + Cannot eject the device "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Unable to burn. Not enough free space on the target disk. + + + + MergedDesktopController + + + + Pictures + Pictures + + + + + Music + Music + + + + + Applications + Applications + + + + + Videos + Videos + + + + + Documents + Documents + + + + + Others + Others + + + + MimeTypeDisplayManager + + + + Directory + Directory + + + + + + Application + Application + + + + + + Video + Video + + + + + + Audio + Audio + + + + + + Image + Image + + + + + Archive + Archive + + + + + + Text + Text + + + + + Executable + Executable + + + + + Backup file + Backup file + + + + + Unknown + Unknown + + + + MountAskPasswordDialog + + + Cancel + button + Cancel + + + + Connect + button + Connect + + + + Log in as + Log in as + + + + Anonymous + Anonymous + + + + Registered user + Registered user + + + + Username + Username + + + + Domain + Domain + + + + Password + Password + + + + Remember password + Remember password + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Cancel + + + + Unlock + button + Unlock + + + + Input password to decrypt the disk + Input password to decrypt the disk + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Are you sure you want to permanently delete %1? + + + + This file is too big for the trash + This file is too big for the trash + + + + The files are too big for the trash + The files are too big for the trash + + + + Are you sure you want to permanently delete %1 files? + Are you sure you want to permanently delete %1 files? + + + + Cancel + button + Cancel + + + + Delete + button + Delete + + + + OpenWithDialog + + + Open with + Open with + + + + Add other programs + Add other programs + + + + Set as default + Set as default + + + + Cancel + button + Cancel + + + + Confirm + button + Confirm + + + + Recommended Applications + Recommended Applications + + + + Other Applications + Other Applications + + + + PathManager + + + Home + Home + + + + Desktop + Desktop + + + + Videos + Videos + + + + Music + Music + + + + Pictures + Pictures + + + + Documents + Documents + + + + Downloads + Downloads + + + + + Trash + Trash + + + + + + System Disk + System Disk + + + + Computers in LAN + Computers in LAN + + + + My Shares + My Shares + + + + Computer + Computer + + + + Recent + Recent + + + + File Vault + File Vault + + + + PropertyDialog + + + Basic info + Basic info + + + + Open with + Open with + + + + Sharing + Sharing + + + + Permissions + Permissions + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Hide this folder + + + + Hide this file + Hide this file + + + + Allow to execute as program + Allow to execute as program + + + + QObject + + + + + + Size + Size + + + + + + Contains + Contains + + + + + + Type + Type + + + + + + + + Time modified + Time modified + + + + Free space + Free space + + + + Total space + Total space + + + + + Time locked + Time locked + + + + Access denied + Access denied + + + + + Executable + Executable + + + + + Write only + Write only + + + + + Read only + Read only + + + + + Read-write + Read-write + + + + Others + Others + + + + Owner + Owner + + + + Unconnected network shared directory + Unconnected network shared directory + + + + Device type + Device type + + + + File system + File system + + + + Group + Group + + + + + Open + Open + + + + Lock + Lock + + + + Auto lock + Auto lock + + + + Never + Never + + + + 5 minutes + 5 minutes + + + + 10 minutes + 10 minutes + + + + 20 minutes + 20 minutes + + + + Delete File Vault + Delete File Vault + + + + Unlock + Unlock + + + + Unlock by key + Unlock by key + + + + Open + button + Open + + + + + Size: %1 + Size: %1 + + + + Type: %1 + Type: %1 + + + + Size: 0 + Size: 0 + + + + Items: %1 + Items: %1 + + + + + + + + + + Open in new window + Open in new window + + + + + + + + + + Open in new tab + Open in new tab + + + + Open with + Open with + + + + + Compress + Compress + + + + Extract + Extract + + + + Extract here + Extract here + + + + Cut + Cut + + + + Copy + Copy + + + + Paste + Paste + + + + + + + + Rename + Rename + + + + + + + Remove + Remove + + + + Create link + Create link + + + + Send to desktop + Send to desktop + + + + Send to + Send to + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Add to bookmark + + + + + + + Properties + Properties + + + + New folder + New folder + + + + New window + New window + + + + Select all + Select all + + + + + Clear recent history + Clear recent history + + + + + + Empty Trash + Empty Trash + + + + Display as + Display as + + + + Sort by + Sort by + + + + New document + New document + + + + + Time created + Time created + + + + + + Source path + Source path + + + + Share folder + Share folder + + + + Cancel sharing + Cancel sharing + + + + Connect to Server + Connect to Server + + + + Set share password + Set share password + + + + Format + Format + + + + Tag information + Tag information + + + + Open as administrator + Open as administrator + + + + Select default program + Select default program + + + + Open file location + Open file location + + + + Remove bookmark + Remove bookmark + + + + + + Delete + Delete + + + + Office Text + Office Text + + + + Spreadsheets + Spreadsheets + + + + Plain Text + Plain Text + + + + Open in terminal + Open in terminal + + + + Restore + Restore + + + + Restore all + Restore all + + + + Clear saved password and unmount + Clear saved password and unmount + + + + File Vault + File Vault + + + + Add to disc + Add to disc + + + + Refresh + Refresh + + + + Auto mount + Auto mount + + + + Open after auto mount + Open after auto mount + + + + + Mount + Mount + + + + + Unmount + Unmount + + + + It does not support burning %1 discs + It does not support burning %1 discs + + + + Burn + Burn + + + + Disc name: + Disc name: + + + + + Maximum + Maximum + + + + Allow files to be added later + Allow files to be added later + + + + Verify data + Verify data + + + + Write speed: + Write speed: + + + + + + + Cancel + button + Cancel + + + + Burn + button + Burn + + + + + Eject + Eject + + + + Safely Remove + Safely Remove + + + + + Name + Name + + + + Settings + Settings + + + + Exit + Exit + + + + Icon + Icon + + + + List + List + + + + Extend + Extend + + + + Set as wallpaper + Set as wallpaper + + + + + + + Local disk + Local disk + + + + + Removable disk + Removable disk + + + + + + Network shared directory + Network shared directory + + + + + Android mobile device + Android mobile device + + + + + Apple mobile device + Apple mobile device + + + + + Camera + Camera + + + + + DVD + DVD + + + + + Unknown device + Unknown device + + + + + + %1 item + %1 item + + + + + + %1 items + %1 items + + + + Shortcut + Shortcut + + + + Create symlink + Create symlink + + + + Path + Path + + + + + + Time deleted + Time deleted + + + + Loading... + Loading... + + + + File has been moved or deleted + File has been moved or deleted + + + + You do not have permission to traverse files in it + You do not have permission to traverse files in it + + + + + + You do not have permission to access this folder + You do not have permission to access this folder + + + + + + + + Folder is empty + Folder is empty + + + + Searching... + Searching... + + + + No results + No results + + + + Source Path + TrashFileInfo + Source Path + + + + Document + Document + + + + Spreadsheet + Spreadsheet + + + + + Presentation + Presentation + + + + Text + Text + + + + 1 task in progress + 1 task in progress + + + + %1 tasks in progress + %1 tasks in progress + + + + Mode: + Mode: + + + + + Replace Text + Replace Text + + + + + Add Text + Add Text + + + + + Custom Text + Custom Text + + + + Find: + Find: + + + + Replace: + Replace: + + + + + Optional + Optional + + + + Add: + Add: + + + + Location: + Location: + + + + File name: + File name: + + + + Start at: + Start at: + + + + + Rename + button + Rename + + + + + + + + + + + Required + Required + + + + + Before file name + Before file name + + + + + After file name + After file name + + + + Find + Find + + + + Replace + Replace + + + + Add + Add + + + + Start at + Start at + + + + + + Location + Location + + + + File name + File name + + + + Dimension + Dimension + + + + Duration + Duration + + + + Tips: Sort by selected file order + Tips: Sort by selected file order + + + + Rename %1 Files + Rename %1 Files + + + + Multiple Files + Multiple Files + + + + Basic info + Basic info + + + + Total size + Total size + + + + Number of files + Number of files + + + + %1 file(s), %2 folder(s) + %1 file(s), %2 folder(s) + + + + + + Time accessed + Time accessed + + + + Orange + Orange + + + + Red + Red + + + + Purple + Purple + + + + Navy-blue + Navy-blue + + + + Azure + Azure + + + + Green + Green + + + + Yellow + Yellow + + + + Gray + Gray + + + + Input tag info, such as work, family. A comma is used between two tags. + Input tag info, such as work, family. A comma is used between two tags. + + + + Bookmarks + Bookmarks + + + + Erase + Erase + + + + Copy path + Copy path + + + + Edit address + Edit address + + + + Free Space %1 + Free Space %1 + + + + Files are being processed + Files are being processed + + + + + Unknown + Unknown + + + + My Vault + My Vault + + + + + Failed to create file info + Failed to create file info + + + + Failed to create file handler + Failed to create file handler + + + + Failed to open the file, cause: %1 + Failed to open the file, cause: %1 + + + + Original file does not exist + Original file does not exist + + + + Do you want to delete %1? + Do you want to delete %1? + + + + Confirm + button + Confirm + + + + + + + + %1 are not allowed + %1 are not allowed + + + + + Failed to start Samba services + Failed to start Samba services + + + + RecentController + + + Cancel + button + Cancel + + + + Remove + button + Remove + + + + Do you want to remove this item? + Do you want to remove this item? + + + + Do yout want to remove %1 items? + Do yout want to remove %1 items? + + + + It does not delete the original files + It does not delete the original files + + + + ShareInfoFrame + + + Share this folder + Share this folder + + + + Share name: + Share name: + + + + Permission: + Permission: + + + + Read and write + Read and write + + + + Read only + Read only + + + + Anonymous: + Anonymous: + + + + Not allow + Not allow + + + + Allow + Allow + + + + The share name must not be two dots (..) or one dot (.) + The share name must not be two dots (..) or one dot (.) + + + + The share name is used by another user. + The share name is used by another user. + + + + OK + button + OK + + + + Cancel + button + Cancel + + + + Replace + button + Replace + + + + The share name already exists. Do you want to replace the shared folder? + The share name already exists. Do you want to replace the shared folder? + + + + Shortcut + + + Item + Item + + + + Select to the first item + Select to the first item + + + + Shift + Home + Shift + Home + + + + Select to the last item + Select to the last item + + + + Shift + End + Shift + End + + + + Select leftwards + Select leftwards + + + + Shift + Left + Shift + Left + + + + Select rightwards + Select rightwards + + + + Shift + Right + Shift + Right + + + + Select to upper row + Select to upper row + + + + Shift + Up + Shift + Up + + + + Select to lower row + Select to lower row + + + + Shift + Down + Shift + Down + + + + Open + Open + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + To parent directory + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Permanently delete + + + + Shift + Delete + Shift + Delete + + + + Delete file + Delete file + + + + Delete + Delete + + + + Select all + Select all + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Copy + + + + Cut + Cut + + + + Paste + Paste + + + + Rename + Rename + + + + F2 + F2 + + + + New/Search + New/Search + + + + New window + New window + + + + New folder + New folder + + + + + Search + Search + + + + New tab + New tab + + + + View + View + + + + Item information + Item information + + + + Help + Help + + + + F1 + F1 + + + + Keyboard shortcuts + Keyboard shortcuts + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Switch display status + + + + Hide item + Hide item + + + + Input in address bar + Input in address bar + + + + Switch to icon view + Switch to icon view + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Switch to list view + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Others + + + + Close + Close + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Close current tab + + + + Back + Back + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Switch to next tab + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Switch to previous tab + + + + Next file + Next file + + + + Tab + Tab + + + + Previous file + Previous file + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Switch tab by specified number between 1 to 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Forward + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Unable to open items in the trash, please restore it first + + + + TrashPropertyDialog + + + Trash + Trash + + + + item + item + + + + items + items + + + + Contains %1 %2 + Contains %1 %2 + + + + UDiskListener + + + Failed to rename the label + Failed to rename the label + + + + UnmountWorker + + + + + The device was not safely unmounted + The device was not safely unmounted + + + + The device was not safely removed + The device was not safely removed + + + + UserShareManager + + + Kindly Reminder + Kindly Reminder + + + + Please firstly install samba to continue + Please firstly install samba to continue + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + + + + To protect the files, you cannot share this folder. + To protect the files, you cannot share this folder. + + + + Sharing failed + Sharing failed + + + + The computer name is too long + The computer name is too long + + + + You do not have permission to operate file/folder! + You do not have permission to operate file/folder! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Enter a password to protect shared folders + + + + Cancel + button + Cancel + + + + Confirm + button + Confirm + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_am_ET.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_am_ET.ts new file mode 100644 index 0000000..2df0a86 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_am_ET.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + አዲስ ፎልደር + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + ሁሉንም መዝጊያ + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + ኮምፒዩተር + + + + Basic Info + መሰረታዊ መረጃ + + + + Computer Name + የ ኮምፒዩተር ስም + + + + Version + እትም: + + + + Type + አይነት + + + + Processor + ሂደት + + + + Memory + ማስታወሻ + + + + Disk + ዲስክ + + + + Bit + ቢት + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + መፈለጊያ ወይንም አድራሻ ያስገቡ + + + + DFMAdvanceSearchBar + + + Search: + + + + + File Type: + + + + + File Size: + + + + + Time Modified: + + + + + Reset + + + + + All subdirectories + + + + + Current directory + + + + + 0 ~ 100 KB + + + + + 100 KB ~ 1 MB + + + + + 1 MB ~ 10 MB + + + + + 10 MB ~ 100 MB + + + + + 100 MB ~ 1 GB + + + + + > 1 GB + + + + + Today + + + + + Yesterday + + + + + This week + + + + + Last week + + + + + This month + + + + + Last month + + + + + This year + + + + + Last year + + + + + DFMTagCrumbController + + + Tag information + + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + + + + + The action is denied + + + + + Failed to open the file + + + + + Failed to read the file + + + + + Failed to write the file + + + + + Failed to create the directory + + + + + Failed to delete the file + + + + + Failed to move the file + + + + + Original file does not exist + + + + + Failed, file size must be less than 4GB + + + + + Not enough free space on the target disk + + + + + File integrity was damaged + + + + + The target device is read only + + + + + Target folder is inside the source folder + + + + + copy + Extra name added to new file name when used for file name. + ኮፒ + + + + Failed to create the directory, cause: %1 + + + + + + Failed to open the file, cause: %1 + + + + + Failed to read the file, cause: %1 + + + + + Failed to write the file, cause: %1 + + + + + File integrity was damaged, cause: %1 + + + + + Failed to delete the file, cause: %1 + + + + + Fail to create symlink, cause: %1 + + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + + + + + Cancel + መሰረዣ + + + + Replace + መቀየሪያ + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + ስም + + + + + + Time modified + የ ተሻሻለበት ጊዜ + + + + Size + መጠን + + + + Type + አይነት + + + + Time created + የ ተፈጠረበት ጊዜ + + + + + Last access + + + + + Path + መንገድ + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + (እንደ ነበር መመለሻ) + + + + DFileViewHelper + + + Add tag "%1" + + + + + DStatusBar + + + %1 item + %1 እቃ + + + + %1 items + %1 እቃዎች + + + + %1 item selected + %1 እቃ ተመርጧል + + + + %1 items selected + %1 እቃዎች ተመርጠዋል + + + + %1 folder selected (contains %2) + %1 ፎልደር ተመርጧል (የያዛቸው %2) + + + + %1 folders selected (contains %2) + %1 ፎልደሮች ተመርጠዋል (የያዙት %2) + + + + %1 file selected (%2) + %1 ፋይል ተመርጧል (%2) + + + + %1 files selected (%2) + %1 ፋይሎች ተመርጠዋል (%2) + + + + %1 folder selected + %1 ፎልደር ተመርጧል + + + + Filter + ማጣሪያ + + + + Save as: + ማስቀመጫ እንደ: + + + + Loading... + በ መጫን ላይ... + + + + DTaskDialog + + + This action is not supported + + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + + + + + Data Disk + Data Partition + + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + ተግባሩ አልተሳካም! + + + + Target folder is inside the source folder! + ኢላማው ፎልደር በ ምንጭ ፎልደር ውስጥ ነው! + + + + + + + + + + + + + OK + እሺ + + + + Do you want to run %1 or display its content? + እርስዎ ማስኬድ ነው %1 ወይንም ማሳየት የሚፈልጉት? + + + + It is an executable text file. + የሚፈጸም የ ጽሁፍ ፋይል ነው + + + + + + + + + + + + + + Cancel + መሰረዣ + + + + + + Run + ማስኬጃ + + + + + Run in terminal + በ ተርሚናል ውስጥ ማስኬጃ + + + + Display + ማሳያ + + + + It is an executable file. + የሚፈጸም የ ጽሁፍ ፋይል ነው + + + + This file is not executable, do you want to add the execute permission and run? + + + + + "%1" already exists, please use another name. + "%1" ቀደም ብሎ ነበር: እባክዎን ሌላ ስም ይጠቀሙ + + + + + + + + Confirm + ማረጋገጫ + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + በ ቋሚነት ላጥፋው %1? + + + + Permanently delete %1 items? + በ ቋሚነት ላጥፋ %1 እቃዎቹን? + + + + Delete + ማጥፊያ + + + + Empty + ባዶ + + + + Sorry, unable to locate your bookmark directory, remove it? + አዝናለሁ የ እርስዎን ምልክት ማድረጊያ ዳይሬክቶሪ ማግኘት አልተቻለም: ላስወግደው? + + + + Remove + ማስወገጃ + + + + Name: + ስም: + + + + Force unmount + አስገድዶ ማውረጃ + + + + %1 that this shortcut refers to has been changed or moved + %1 ይህ አቋራጭ የሚያመሳከረው ተቀይሯል ወይንም ተንቀሳቅሷል + + + + Do you want to delete this shortcut? + ይህን አቋራጭ ቁልፍ ማጥፋት ይፈልጋሉ? + + + + Failed, file size must be less than 4GB. + ወድቋል: የ ፋይል መጠን ከ 4ጌባ ማነስ አለበት + + + + Fail to create symlink, cause: + አገናኝ መፍጠር አልተቻለም: ምክንያቱም: + + + + The selected files contain system file/directory, and it cannot be deleted + የ ተመረጠው ፋይል የያዘው የ ስርአት ፋይል / ዳይሬክቶሪ ነው: እና ማጥፋት አይቻልም + + + + + You do not have permission to operate file/folder! + እዚህ ፋይል / ፎልደር ጋር ለ መድረስ በቂ ፍቃድ የሎትም + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + አዝናለሁ: እዚህ %1 ፋይል / ፎልደር(ሮች) ጋር ለ መድረስ በቂ ፍቃድ የሎትም + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + የሚካፈሉት ፋይል ከ አሁኑ ተጠቃሚ ስም ጋር ተመሳሳይ መሆን የለበትም + + + + View + መመልከቻ + + + + Do you want to run %1? + + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + ክፍልፋይ መጫኛ %1 ለ ንባብ ብቻ + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + ዲስኮች በ መስኮት ውስጥ ማንበብ እና መጻፍ አይችሉም በ መደበኛ መመርመሪያው "በፍጥነት ከ በራ በፍጥነት በሚያስጀምሩ ጊዜ (እንመክራለን)" በ ማጥፊያ ማሰናጃ ውስጥ + + + + Please restore by the following steps to normally access Windows disk + እባክዎን እንደ ነበር ይመልሱ በሚቀጥሉት ደረጃዎች በ መደበኛ የ መስኮቶች ዲስክ መድረሻ + + + + 1. Reboot to enter Windows + 1. እንደገና ያስጀምሩ ወደ መስኮት ውስጥ ለ መግባት + + + 3. Reboot and enter deepin + 3. እንደገና ያስጀምሩ ወደ ዲፕኢን ውስጥ ለ መግባት + + + + Reboot + እንደገና ማስጀመሪያ + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + የ ፋይል ስም + + + + Format + አቀራረብ + + + + Cancel + መሰረዣ + + + + Save + ማስቀመጫ + + + + Open + መክፈቻ + + + + Save File + ፋይል ማስቀመጫ + + + + Open File + ፋይል መክፈቻ + + + + FileJob + + + copy + ኮፒ + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + %1 ሰ + + + + %1 m %2 s + %1 ደ %2 ሰ + + + + %1 h %2 m %3 s + %1 ሰ %2 ደ %3 ሰ + + + + %1 d %2 h %3 m %4 s + %1 ቀ %2 ሰ %3 ደ %4 ሰ + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + መሰረታዊ + + + + + + Open behavior + ባህሪ መክፈቻ + + + + + + Always open folder in new window + ሁል ጊዜ ፎልደር በ አዲስ መስኮት ውስጥ መክፈቻ + + + + + + Open file: + ፋይል መክፈቻ + + + + + + Click + ይጫኑ + + + + + + Double click + ሁለት ጊዜ ይጫኑ + + + + + + New window and tab + አዲስ መስኮት እና tab + + + + + + Open from default window: + ከ ነባር መስኮት ውስጥ መክፈቻ + + + + + + + + + Computer + ኮምፒዩተር + + + + + + + + + Home + ቤት + + + + + + + + + Desktop + ዴስክቶፕ + + + + + + + + + Videos + ቪዲዮዎች + + + + + + + + + Music + ሙዚቃ + + + + + + + + + Pictures + ስእሎች + + + + + + + + + Documents + ሰነዶች + + + + + + + + + Downloads + የ ወረዱ + + + + + + Open in new tab: + በ አዲስ tab ውስጥ መክፈቻ + + + + + + Current Directory + የ አሁኑ ዳይሬክቶሪ + + + + + + View + መመልከቻ + + + + + + Default size: + ነባር መጠን: + + + + + + Extra small + በጣም ትንሽ + + + + + + Small + ትንሽ + + + + + + Medium + መካከለኛ + + + + + + Large + ትልቅ + + + + + + Extra large + በጣም ትልቅ + + + + + + Default view: + ነባር መመልከቻ + + + + + + Icon + ምልክት + + + + + + List + ዝርዝር + + + + + + Hidden files + የ ተደበቁ ፋይሎች + + + + + + Show hidden files + የ ተደበቁ ፋይሎች ማሳያ + + + + + + Hide file extension when rename + + + + + + + Advanced + የ ረቀቀ + + + + + + Index + + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + ሌላ + + + + + + Hide system disk + + + + + + + Show hidden files in search results + የ ተደበቁ ፋይሎች ማሳያ በ መፈለጊያ ውጤት ውስጥ + + + + + + Display recent file entry in left panel + + + + + + + Preview + ቅድመ እይታ + + + + + Compress file preview + ፋይል ማመቂያ ለ ቅድመ እይታ + + + + + + Text preview + የ ጽሁፍ ቅድመ እይታ + + + + + + Document preview + የ ሰነድ ቅድመ እይታ + + + + + + Image preview + የ ምስል ቅድመ እይታ + + + + + + Video preview + የ ቪዲዮ ቅድመ እይታ + + + + + + Mount + መጫኛ + + + + + + Auto mount + በራሱ መጫኛ + + + + + + Open after auto mount + በራሱ ከ ተጫነ በኋላ መክፈቻ + + + + + + Dialog + ንግግር + + + Use the file chooser dialog of Deepin File Manager + ይምረጡ የ ፋይል መምረጫ ንግግር ለ ዲፕኢን ፋይል አስተዳዳሪ + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + + + + + + + + + Confirm + ማረጋገጫ + + + + + Cannot find the mounting device + + + + + Cannot unmount the device + + + + + Cannot eject the device "%1" + + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + + + + + + + Application + + + + + + + Video + + + + + + + Audio + + + + + + + Image + + + + + + Archive + + + + + + + Text + ጽሁፍ + + + + + Executable + + + + + + Backup file + + + + + + Unknown + + + + + MountAskPasswordDialog + + + Cancel + መሰረዣ + + + + Connect + መገናኛ + + + + Log in as + መግቢያ እንደ + + + + Anonymous + የማይታወቅ + + + + Registered user + የ ተመዘገበ ተጠቃሚ + + + + Username + የ ተጠቃሚ ስም + + + + Domain + ግዛት + + + + Password + የ መግቢያ ቃል + + + + Remember password + የ መግቢያ ቃል አስታውስ + + + + MountSecretDiskAskPasswordDialog + + + Cancel + መሰረዣ + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + መዝለያ + + + Keep both + ሁለቱንም ማስቀመጫ + + + Replace + መቀየሪያ + + + Do not ask again + በድጋሚ አትጠይቀኝ + + + merge + ማዋሀጃ + + + Copying %1 + ኮፒ በ ማድረግ ላይ %1 + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + ኮፒ ማድረጊያ ወደ %2 + + + Moving %1 + በ ማንቀሳቀስ ላይ ወደ %1 + + + Move to %2 + ማንቀሳቀሻ ወደ %2 + + + Restoring %1 + እንደ ነበር በ መመለስ ላይ %1 + + + Restore to %2 + እንደ ነበር በ መመለስ ላይ ወደ %2 + + + Deleting %1 + በ ማጥፋት ላይ %1 + + + Trashing %1 + ወደ ቆሻሻ በ መጣል ላይ %1 + + + Calculating space, please wait + እባክዎን ይቆዩ ቦታውን በ ማስላት ላይ ነው + + + File named %1 already exists in target folder + ፋይል በዚህ ስም %1 ቀደም ብሎ ነበር በ ታለመው ፎልደር ውስጥ + + + Original path %1 target path %2 + ዋናው መንገድ %1 የ ታለመው መንገድ %2 + + + Retry + + + + Time modified:%1 + ሰአት ተሻሽሏል:%1 + + + Original folder + + + + Original file + + + + Target folder + + + + Target file + + + + Contains:%1 + የ ያዘው %1 + + + Size:%1 + መጠን:%1 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + መሰረዣ + + + + Delete + ማጥፊያ + + + + OpenWithDialog + + + Open with + መክፈቻ በ + + + + Add other programs + ሌላ ፕሮግራም መጨመሪያ + + + + Set as default + እንደ ነባር ማሰናጃ + + + + Cancel + መሰረዣ + + + + Confirm + + + + + Recommended Applications + የምንመክረው መተግበሪያዎች + + + + Other Applications + ሌሎች መተግበሪያዎች + + + + PathManager + + + Home + ቤት + + + + Desktop + ዴስክቶፕ + + + + Videos + ቪዲዮዎች + + + + Music + ሙዚቃ + + + + Pictures + ስእሎች + + + + Documents + ሰነዶች + + + + Downloads + የ ወረዱ + + + + + Trash + ቆሻሻ + + + + + System Disk + የ ስርአት ዲስክ + + + + Computers in LAN + ኮምፒዩተር በ LAN ውስጥ + + + + My Shares + እኔ የማካፍላቸው + + + + Computer + ኮምፒዩተር + + + + Recent + + + + + PropertyDialog + + + Basic info + መሰረታዊ መረጃ + + + + Open with + መክፈቻ በ + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + እንደ ፕሮግራም መፈጸሚያ ማስቻያ + + + + QObject + + + + + Size + መጠን + + + + + + Contains + የያዘው + + + + + + Type + አይነት + + + + + + + Time modified + የ ተሻሻለበት ጊዜ + + + + Free space + ነፃ ቦታ + + + + Total space + ጠቅላላ ቦታ + + + + Access denied + + + + + + Executable + + + + + + Write only + + + + + + Read only + ለ ንባብ ብቻ + + + + + Read-write + + + + + Others + ሌሎች + + + + Owner + ባለቤቱ + + + + Device type + + + + + File system + + + + + Group + ቡድን + + + + + + Open + መክፈቻ + + + + + Size: %1 + መጠን:%1 + + + + Type: %1 + አይነት: %1 + + + + Size: 0 + መጠን: 0 + + + + Items: %1 + እቃዎች: %1 + + + + + + + + + + + Open in new window + በ አዲስ መስኮት ውስጥ መክፈቻ + + + + + + + + + + + Open in new tab + በ አዲስ tab ውስጥ መክፈቻ + + + + Open with + መክፈቻ በ + + + + Compress + ማመቂያ + + + + Extract + ማራገፊያ + + + + Extract here + እዚህ ማራገፊያ + + + + Cut + መቁረጫ + + + + Copy + ኮፒ + + + + Paste + መለጠፊያ + + + + + + + + + + Rename + እንደገና መሰየሚያ + + + + + + Remove + ማስወገጃ + + + + Create link + አገናኝ መፍጠሪያ + + + + Send to desktop + ወደ ዴስክቶፕ መላኪያ + + + + Send to + መላኪያ ወደ + + + + Add to bookmark + ወደ ምልክት ማድረጊያ መላኪያ + + + + + + + Properties + ባህሪዎች + + + + New folder + አዲስ ፎልደር + + + + New window + አዲስ መስኮት + + + + Select all + ሁሉንም መምረጫ + + + + + Clear recent history + የ ቅርብ ጊዜ ታሪክ ማጽጃ + + + + + + Empty Trash + ቆሻሻ ባዶ ማድረጊያ + + + + Display as + ማሳያ እንደ + + + + Sort by + መለያ በ + + + + New document + አዲስ ሰነድ + + + + + Time created + የ ተፈጠረበት ጊዜ + + + + Log out and unmount + መውጫ እና ማውረጃ + + + + + + Source path + የ ምንጩ መንገድ + + + + Share folder + ፎልደር ማካፈያ + + + + Cancel sharing + ማካፈያ መሰረዣ + + + + Connect to Server + + + + + Set share password + የ ማካፈያ የ መግቢያ ቃል ማሰናጃ + + + + Format + አቀራረብ + + + + Tag information + + + + + Open in new window as admin + በ አዲስ መስኮት ውስጥ እንደ አስተዳዳሪ መክፈቻ + + + + Select default program + ነባር ፕሮግራም ይምረጡ + + + + Open file location + የ ፋይል አካባቢ መክፈቻ + + + + Remove bookmark + + + + + + + Delete + ማጥፊያ + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + በ ተርሚናል ውስጥ መክፈቻ + + + + Restore + እንደ ነበር መመለሻ + + + + Restore all + ሁሉንም እንደ ነበር መመለሻ + + + + File Vault + + + + + Auto mount + በራሱ መጫኛ + + + + Open after auto mount + በራሱ ከ ተጫነ በኋላ መክፈቻ + + + + + Mount + መጫኛ + + + + + Unmount + ማውረጃ + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + ማውጫ + + + + Safely Remove + በ ጥንቃቄ ማስወገጃ + + + + + Name + ስም + + + + Settings + ማሰናጃ + + + + Exit + መውጫ + + + + Icon + ምልክት + + + + List + ዝርዝር + + + + Extend + ማስፊያ + + + + Set as wallpaper + እንደ ግድግዳ ወረቀት ማሰናጃ + + + + + + + Local disk + የ አካባቢ ዲስክ + + + + + Removable disk + የሚወልቅ ዲስክ + + + + + + Network shared directory + ኔትዎርክ የሚካፈለው ዳይሬክቶሪ + + + + + Android mobile device + አንድሮይድ ተንቀሳቃሽ አካል + + + + + Apple mobile device + አፕል ተንቀሳቃሽ አካል + + + + + Camera + ካሜራ + + + + + DVD + + + + + + Unknown device + ያልታወቀ አካል + + + + + + %1 item + %1 እቃ + + + + + + %1 items + %1 እቃዎች + + + + Shortcut + አቋራጭ + + + + Create symlink + አገናኝ መፍጠሪያ + + + + Path + መንገድ + + + + + + Time deleted + የ ጠፋበት ጊዜ + + + + Loading... + በ መጫን ላይ... + + + + File has been moved or deleted + ፋይሉ ተንቀሳቅሷል ወይንም ጠፍቷል + + + + + + You do not have permission to access this folder + እዚህ ፎልደር ጋር ለ መድረስ በቂ ፍቃድ የሎትም + + + + + + + Folder is empty + ፎልደሩ ባዶ ነው + + + + Path + SearchFileInfo + መንገድ + + + + Searching... + በ መፈለግ ላይ... + + + + No results + ምንም ውጤት የለም + + + + Source Path + TrashFileInfo + የ ምንጩ መንገድ + + + + Document + ሰነድ + + + + Spreadsheet + ሰንጠረዥ + + + + + Presentation + ማቅረቢያ + + + + Text + ጽሁፍ + + + + 1 task in progress + 1 ስራ በ ሂደት ላይ + + + + %1 tasks in progress + %1 ስራዎች በ ሂደት ላይ + + + + Mode: + ዘዴ: + + + + + Replace Text + ጽሁፍ መቀየሪያ + + + + + Add Text + ጽሁፍ መጨመሪያ + + + + + Custom Text + ጽሁፍ ማስተካከያ + + + + Find: + መፈለጊያ: + + + + Replace: + መቀየሪያ + + + + + Optional + በ ምርጫ + + + + Add: + መጨመሪያ: + + + + Location: + አካባቢ: + + + + File name: + የ ፋይል ስም: + + + + +SN: + +SN: + + + + + + + + + + Required + ያስፈልጋል + + + + + Before file name + ከ ፋይል ስም በፊት: + + + + + After file name + ከ ፋይል ስም በኋላ: + + + + Find + መፈለጊያ: + + + + Replace + መቀየሪያ + + + + Add + መጨመሪያ: + + + + + + Location + አካባቢ: + + + + File name + የ ፋይል ስም: + + + + Dimension + + + + + Duration + + + + + +SN + +SN + + + + Tips: Sort by selected file order + ጠቃሚ ምክር: በ ተመረጠው ፋይል ቅደም ተከተል + + + + + + Cancel + መሰረዣ + + + + Rename %1 Files + እንደገና መሰየሚያ %1 ፋይሎች + + + + Multiple Files + በርካታ ፋይሎች + + + + Basic info + መሰረታዊ መረጃ + + + + Total size + ጠቅላላ መጠን + + + + Number of files + የ ፋይሎች ቁጥር + + + + %1 file(s), %2 folder(s) + %1 ፋይል(ሎች), %2 ፎልደር(ሮች) + + + + + + Time accessed + + + + + Orange + + + + + Red + + + + + Purple + + + + + Navy-blue + + + + + Azure + + + + + Green + + + + + Yellow + + + + + Gray + + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + + + + + Erase + + + + + + Copy path + + + + + + Edit address + + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + ይህን ፎልደር ማካፈያ + + + + Share name: + ስም ማካፈያ + + + + Permission: + ፍቃድ: + + + + Read and write + መጻፊያ እና ማንበቢያ + + + + Read only + ለ ንባብ ብቻ + + + + Anonymous: + የማይታወቅ: + + + + Not allow + አትፍቀድ + + + + Allow + መፍቀጃ + + + + Shortcut + + + Item + እቃ + + + + Select to the first item + የ መጀመሪያውን እቃ ይምረጡ + + + + Shift + Home + Shift + Home + + + + Select to the last item + የ መጨረሻውን እቃ ይምረጡ + + + + Shift + End + Shift + End + + + + Select leftwards + ይምረጡ ወደ ግራ በኩል + + + + Shift + Left + Shift + Left + + + + Select rightwards + ይምረጡ ወደ ቀኝ በኩል + + + + Shift + Right + Shift + Right + + + + Select to upper row + ይምረጡ የ ላይኛውን ረድፍ + + + + Shift + Up + Shift + Up + + + + Select to lower row + ይምረጡ የ ታችኛውን ረድፍ + + + + Shift + Down + Shift + Down + + + + Open + መክፈቻ + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + ወደ ወላጅ ዳይሬክቶሪ + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + በ ቋሚነት ማጥፊያ + + + + Shift + Delete + Shift + Delete + + + + Delete file + ፋይል ማጥፊያ + + + + Delete + ማጥፊያ + + + + Select all + ሁሉንም መምረጫ + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + ኮፒ + + + + Cut + መቁረጫ + + + + Paste + መለጠፊያ + + + + Rename + እንደገና መሰየሚያ + + + + F2 + F2 + + + + New/Search + አዲስ / መፈለጊያ + + + + New window + አዲስ መስኮት + + + + New folder + አዲስ ፎልደር + + + + + Search + መፈለጊያ + + + + New tab + አዲስ tab + + + + View + መመልከቻ + + + + Item information + የ እቃ መረጃ + + + + Help + እርዳታ + + + + F1 + F1 + + + + Keyboard shortcuts + የ ፊደል ገበታ አቋራጭ + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + የ ማሳያ ሁኔታ መቀየሪያ + + + + Hide item + እቃ መደበቂያ + + + + Input in address bar + በ አድራሻ መደርደሪያ ላይ ማስገቢያ + + + + Switch to icon view + + + + + Ctrl + 1 + + + + + Switch to list view + + + + + Ctrl + 2 + + + + + Others + ሌሎች + + + + Close + መዝጊያ + + + + Alt + F4 + Alt + F4 + + + + Close current tab + የ አሁኑን tab መዝጊያ + + + + Back + ወደ ኋላ + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + መቀየሪያ ወደሚቀጥለው tab + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + መቀየሪያ ወዳለፈው tab + + + + Next file + የሚቀጥለው ፋይል + + + + Tab + Tab + + + + Previous file + ያለፈው ፋይል + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + መቀየሪያ tab በ ተወነው ቁጥር በ 1 እስከ 8 መካከል + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + ወደ ፊት + + + + TrashPropertyDialog + + + Trash + ቆሻሻ + + + + item + እቃ + + + + items + እቃዎች + + + + Contains %1 %2 + የያዘው %1 %2 + + + + UDiskListener + + + Failed to rename the label + + + + + UserShareManager + + + Kindly Reminder + + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + መሰረዣ + + + + Confirm + ማረጋገጫ + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ar.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ar.ts new file mode 100644 index 0000000..733410c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ar.ts @@ -0,0 +1,4791 @@ + + + AppController + + + New Folder + مجلد جديد + + + + Mounting device error + فشل تنصيب القرض ظاهرياً + + + + The disc image was corrupted, cannot mount now, please erase the disc first + للأسف، صورة القرص تالفة ولا يمكن تشغيلها ظاهرياً الآن، نرجوا مسح القرص أولا + + + + Mount error: unsupported image format + فشل تنصيب القرص ظاهرياً، صيغة صورة القرص غير مدعومة + + + + + The device was not safely removed + لم يتم إزالة الجهاز بأمان + + + + + Click "Safely Remove" and then disconnect it next time + + + + + The device was not ejected + + + + + Disk is busy, cannot eject now + القرص قيد الاستخدام ، لا يمكن فصله اﻵن + + + + Authentication timed out + + + + + BluetoothTransDialog + + + Bluetooth File Transfer + + + + + File Transfer Successful + + + + + File Transfer Failed + + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + + + + + Select a Bluetooth device to receive files + + + + + Cannot find the connected Bluetooth device + + + + + Waiting to be received... + + + + + Go to Bluetooth Settings + + + + + %1/%2 Sent + + + + + Error: the Bluetooth device is disconnected + + + + + Unable to send the file more than 2 GB + + + + + Unable to send 0 KB files + + + + + File doesn't exist + + + + + Next + button + التالي + + + + Cancel + button + إلغاء + + + + Done + button + تم + + + + Retry + button + إعادة المحاولة + + + + OK + button + حسناً + + + Next + التالي + + + Cancel + إلغاء + + + Done + تم + + + Retry + إعادة المحاولة + + + OK + حسناً + + + + File sending request timed out + + + + + The service is busy and unable to process the request + + + + + BurnOptDialog + + + Device error + + + + + Optical device %1 doesn't exist + + + + + Advanced settings + + + + + File system: + + + + + ISO9660/Joliet (For Windows) + + + + + ISO9660/Rock Ridge (For Unix) + + + + + %1 (Compatible with Windows CD/DVD mode) + + + + + ISO9660 Only + + + + + CloseAllDialogIndicator + + + Close all + إغلاق الكل + + + + Total size: %1, %2 files + الحجم الإجمالي: %1, %2 ملفات + + + + ComputerModel + + + + My Directories + مسار مجلداتي + + + + + + + + + + + + Disks + الأقراص + + + + ComputerPropertyDialog + + + Computer + الحاسوب + + + + Basic Info + المعلومات الأساسية + + + + + Computer Name + اسم الحاسوب + + + + + Edition + + + + + + + Version + اﻹصدار + + + + + Type + النوع + + + + + + Processor + المعالج + + + + + + Memory + الذاكرة + + + + + + + Bit + بت + + + + + Available + + + + + Obtaining... + + + + + ConnectToServerDialog + + + Connect to Server + الاتصال بالخادم + + + Cancel + إلغاء + + + Connect + اتصال + + + + Cancel + button + إلغاء + + + + Connect + button + اتصال + + + + My Favorites: + مفضلتي: + + + + + Clear History + مسح السجل الحديث + + + + DFMAddressBar + + + Search or enter address + ابحث أو أدخل عنواناً + + + + DFMAdvanceSearchBar + + + Search: + بحث: + + + + File Type: + نوع الملف: + + + + File Size: + حجم الملف: + + + + Time Modified: + وقت التعديل: + + + + Time Accessed: + + + + + Time Created: + + + + + Reset + إعادة ضبط + + + + All subdirectories + الموقع بتفرعاته + + + + Current directory + الموقع الحالي + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + اليوم + + + + Yesterday + أمس + + + + This week + هذا الأسبوع + + + + Last week + الأسبوع الماضى + + + + This month + هذا الشهر + + + + Last month + الشهر الماضي + + + + This year + هذا العام + + + + Last year + العام الماضي + + + + DFMOpticalMediaWidget + + + + No files to burn + + + + + Unable to burn. Not enough free space on the target disk. + + + + + %1 burning is not supported + + + + + 1. It is not a DVD-R or DVD+R disc; +2. The version of this file system does not support adding files yet. + + + + + DFMSideBarBookmarkItemHandler + + + Gotcha + button + + + + + DFMTagCrumbController + + + Tag information + معلومات شعارية + + + + DFMTagWidget + + + Tag + علامة استدلال + + + + DFMTaskWidget + + Keep both + الاحتفاظ بكليهما + + + Skip + تخطي + + + Replace + استبدال + + + + Do not ask again + لا تسأل ثانيةً + + + + Syncing data + + + + + Please wait + + + + Retry + إعادة المحاولة + + + + + Time modified: %1 + وقت التعديل : %1 + + + + + Contains: %1 + المحتويات : %1 + + + + + Size: %1 + الحجم : %1 + + + + Original folder + المجلد الأصلي + + + + Keep both + button + الاحتفاظ بكليهما + + + + Skip + button + تخطي + + + + Replace + button + استبدال + + + + Retry + button + إعادة المحاولة + + + + Original file + الملف الأصلي + + + + Target folder + المجلد المستهدف + + + + Target file + الملف المستهدف + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + + + + + Click 'Encrypt' and input the user password. + + + + + Encrypting... + + + + + + + + Encrypt + + + + + Failed to create file vault: %1 + + + + + OK + حسناً + + + + The setup is complete + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + + + + + Generate a recovery key in case that you forgot the password + + + + + Key + + + + + QR code + + + + + Scan QR code and save the key to another device + + + + + Next + التالي + + + + Recovery Key: + + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + + + + + Method + + + + + Manual + + + + + Password + كلمة المرور + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + + + + + Repeat password + أعد إدخال كلمة المرور + + + + Input the password again + + + + + Password hint + + + + + Optional + اختياري + + + + Next + التالي + + + + + Passwords do not match + + + + + DFMVaultActiveStartView + + + File Vault + حقيبة الملفات المحمية + + + + Create your secure private space + + + + + Advanced encryption technology + + + + + Convenient and easy to use + مريحة وسهلة الإستخدام + + + + Create + + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + + + + Cancel + إلغاء + + + Unlock + فك القفل + + + + Failed to unlock file vault + + + + + OK + حسناً + + + + Input the 32-digit recovery key + + + + + Cancel + button + إلغاء + + + + Unlock + button + فك القفل + + + + Wrong recovery key + + + + + DFMVaultRemoveByPasswordView + + + Password + كلمة المرور + + + + Password hint: %1 + + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + + + + + DFMVaultRemovePages + + + Delete File Vault + + + + + Once deleted, the files in it will be permanently deleted + + + + Cancel + إلغاء + + + + Use Key + + + + Delete + حذف + + + OK + حسناً + + + + Cancel + button + إلغاء + + + + Use Key + button + + + + + Delete + button + حذف + + + + + OK + button + حسناً + + + + Use Password + + + + + Wrong password + + + + + Wrong recovery key + + + + + Failed to delete file vault + + + + + Deleted successfully + + + + + Failed to delete + + + + + Removing... + + + + + DFMVaultUnlockPages + + + Unlock File Vault + + + + + Verify your password + + + + Cancel + إلغاء + + + Unlock + فك القفل + + + + Password hint: %1 + + + + + Failed to unlock file vault + + + + OK + حسناً + + + + Password + كلمة المرور + + + + Cancel + button + إلغاء + + + + Unlock + button + فك القفل + + + + + Wrong password + + + + + OK + button + حسناً + + + + DFileCopyMoveJob + + + Permission error + خطأ في الإذن + + + + The action is denied + تم رفض الإجراء + + + + Failed to open the file + فشل في فتح الملف + + + + Failed to read the file + فشل في قراءة الملف + + + + Failed to write the file + فشل في كتابة الملف + + + + Failed to create the directory + فشل في إنشاء مجلد + + + + Failed to delete the file + فشل في حذف الملف + + + + Failed to move the file + فشل في نقل الملف + + + + Original file does not exist + الملف الأصلي غير موجود + + + + Failed, file size must be less than 4GB + فشل، يجب أن يكون حجم الملف أقل من 4 غ.ب + + + + Not enough free space on the target disk + لا يوجد مساحة كافية على القرص المستهدف + + + + File integrity was damaged + تضرر الملف + + + + The target device is read only + الجهاز المستهدف قابل للقراءة فقط + + + + Target folder is inside the source folder + المجلد الهدف داخل مجلد المصدر + + + + The action is not supported + + + + + You do not have permission to traverse files in it + + + + + copy + Extra name added to new file name when used for file name. + نسخ + + + + Failed to open the directory, cause: file name too long + + + + + + + Failed to open the file, cause: file name too long + + + + + + Failed to write the file, cause: + + + + + Syncing data + + + + + Please wait + + + + + Failed to create the directory, cause: %1 + فشل في إنشاء مجلد، السبب: %1 + + + + + + + + + Failed to open the file, cause: %1 + فشل في فتح الملف، السبب: %1 + + + + + + + Failed to open the file, cause: Permission denied + + + + + + Failed to read the file, cause: %1 + فشل في قراءة الملف، السبب: %1 + + + + + + + Failed to write the file, cause: %1 + فشل في كتابة الملف، السبب: %1 + + + + + File integrity was damaged, cause: %1 + تضرر الملف، السبب: %1 + + + + Failed to open the file, cause: + + + + + Failed to read the file, cause: + + + + + Failed to delete the file, cause: %1 + فشل في حذف الملف، السبب: %1 + + + + Fail to create symlink, cause: %1 + فشل في إنشاء اختصار، السبب %1 + + + + DFileDialog + + Save + حفظ + + + + + Save + button + حفظ + + + + + Cancel + button + إلغاء + + + + Confirm + button + تأكيد + + + + %1 already exists, do you want to replace it? + %1 موجود بالفعل، هل تريد استبداله؟ + + + + Replace + button + استبدال + + + + Open + button + فتح + + + Cancel + إلغاء + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + + + + Confirm + تأكيد + + + Replace + استبدال + + + Open + فتح + + + + DFileManagerWindow + + + Trash + سلة المهملات + + + + Empty + فارغ/إفراغ + + + + DFileSystemModel + + + + Name + الاسم + + + + + + Time modified + وقت التعديل + + + + Size + الحجم + + + + Type + النوع + + + + Time created + وقت اﻹنشاء + + + + + Last access + آخر دخول + + + + + + + Path + المسار + + + + DFileView + + + Disc mount error + + + + + The disc is in use, please end the running process and remount the disc. + + + + + Mounting failed + + + + + (Reverse) + (عكس) + + + + DFileViewHelper + + + Add tag "%1" + إضافة شعار "%1" + + + + DStatusBar + + + %1 item + %1 عنصر + + + + %1 items + %1 من العناصر + + + + %1 item selected + %1 عنصر محدد + + + + %1 items selected + %1 من العناصر محددة + + + + %1 folder selected (contains %2) + %1 مجلد محدد ( يحتوي على %2 ) + + + + %1 folders selected (contains %2) + %1 من المجلدات محددة ( تحتوي على %2 ) + + + + %1 file selected (%2) + %1 ملف محدد (%2) + + + + %1 files selected (%2) + %1 من المجلدات محددة ( %2 ) + + + + %1 folder selected + %1 مجلد محدد + + + + Filter + تصفية + + + + Save as: + حفظ باسم : + + + + Loading... + يحمل الآن ... + + + + DTaskDialog + + + This action is not supported + الإجراء غير مدعوم + + + + Erasing disc %1, please wait... + جاري حذف القرص %1، الرجاء الانتظار... + + + + Burning disc %1, please wait... + جاري حرق الأسطوانة %1، الرجاء الانتظار... + + + + Writing data... + جاري كتابة البيانات... + + + + Verifying data... + جاري التأكد من البيانات... + + + + Copying %1 + جاي النسخ %1 + + + + + + to %2 + إلى %2 + + + + %1 already exists in target folder + الملف المسمى %1 موجود بالفعل في المجلد الهدف + + + + Original path %1 Target path %2 + المسار الأصلي %1 مسار الهدف %2 + + + + Merge + button + دمج + + + + Replace + button + استبدال + + + + Moving %1 + جاري النقل %1 + + + + Removing file vault, please try later + + + + + Restoring %1 + جاي الإستعادة %1 + + + + Deleting %1 + جاي الحذف %1 + + + + Trashing %1 + جاري إفراغ المحذوفات %1 + + + + Calculating space, please wait + جاي حساب المساحة، يرجى الإنتظار + + + Merge + دمج + + + Replace + استبدال + + + + DUMountManager + + + + Authentication timed out + + + + + + + Disk is busy, cannot unmount now + القرص قيد الاستخدام ، لا يمكن فصله اﻵن + + + + Disk is busy, cannot eject now + القرص قيد الاستخدام ، لا يمكن فصله اﻵن + + + + The device is busy, cannot eject now + + + + + + + The device is busy, cannot remove now + + + + + DeepinStorage + + + + + %1 Volume + %1 مستوى الصوت + + + + Data Disk + Data Partition + قرص البيانات + + + + %1 Drive + %1 قرص + + + + Blank %1 Disc + تفريغ القرص %1 + + + + %1 Encrypted + تم تشفير %1 + + + + DialogManager + + + + + + Operation failed! + فشلت العملية ! + + + + Target folder is inside the source folder! + المجلد الهدف داخل مجلد المصدر ! + + + OK + موافق + + + + Do you want to run %1 or display its content? + هل تريد تشغيل %1 أم عرض محتواه ؟ + + + + It is an executable text file. + ملف نصي قابل للتنفيذ. + + + Cancel + إلغاء + + + Run + تشغيل + + + Run in terminal + تشغيل في الطرفية + + + Display + عرض + + + + It is an executable file. + إنه ملف تنفيذي + + + + This file is not executable, do you want to add the execute permission and run? + هذا الملف غير قابل للتشغيل، هل تريد أن تعطيه الأذن وتشغله؟ + + + + "%1" already exists, please use another name. + "%1" موجود بالفعل، يرجى استخدام اسماً آخر. + + + Confirm + تأكيد + + + + The file name must not contain two dots (..) + + + + + Are you sure you want to erase all data on the disc? + هل أنت متأكد من حذف كافة البيانات على هذه الأسطوانة؟ + + + Erase + مسح + + + + How do you want to use this disc? + كيف تريد استخدام هذه الأسطوانة؟ + + + Burn image + حرق ISO + + + Burn files + حرق ملفات + + + + Disc erase failed + فشل في مسح الأسطوانة + + + + Burn process failed + فشل في عملية الحرق + + + + %1: %2 + %1: %2 + + + + Show details + إظهار التفاصيل + + + + Hide details + إخفاء التفاصيل + + + + Error + خطأ + + + + Permanently delete %1? + حذف %1 بشكل دائم ؟ + + + + Permanently delete %1 items? + حذف بشكل دائم %1 عناصر ؟ + + + Delete + حذف + + + + Empty + إفراغ + + + + Do you want to delete %1? + + + + + Do you want to delete the selected %1 items? + + + + + Sorry, unable to locate your bookmark directory, remove it? + عذراً، غير قادر على تحديد موقع دليل اﻹشارات المرجعية الخاصة بك، هل تريد إزالته؟ + + + Remove + إزالة + + + + Name: + الاسم : + + + Force unmount + إجبار على الفصل + + + + %1 that this shortcut refers to has been changed or moved + إن " %1 " الذي يشير إليه هذا الاختصار قد تغير أو تم نقله . + + + + Do you want to delete this shortcut? + هل تريد حذف هذا الاختصار ؟ + + + + Failed, file size must be less than 4GB. + فشل، يجب أن يكون حجم الملف أقل من 4 غ.ب + + + + Fail to create symlink, cause: + تعذر إنشاء وصلة رمزية ـ بسبب : + + + + The selected files contain system file/directory, and it cannot be deleted + تحتوي الملفات المحددة على ملفات نظام / دليل، ولا يمكن حذفه + + + + Unable to find the original file + + + + + + You do not have permission to operate file/folder! + ليس لديك صلاحيات كافية لتشغيل المجلد \الملف + + + + Failed to restore %1 file, the source file does not exist + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + عذراً ! . ليس لديك إذن لتنفيذ عملية في الملفات/المجلدات التالية %1 + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + 2. إزالة "تشغيل التشغيل السريع" و "وضع السكون" في إعدادات التشغيل + + + + 3. Reboot and enter %1 + 3. أعد التشغيل وأدخل %1 + + + + Reboot + button + إعادة التشغيل + + + + Unable to access %1 + + + + + + Sending files now, please try later + + + + Format + التنسيق + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + + + + Stop + إيقاف + + + + Scanning the device, stop it? + يتم فحص الجهاز ... هل تريد إيقافه ؟ + + + + Share folder can't be named after the current username + لا يمكن تسمية مجلد المشاركة باسم المستخدم الحالي + + + + Do you want to run %1? + هل أنت متأكد من تشغيل %1؟ + + + + Burn image + button + حرق ISO + + + + Burn files + button + حرق ملفات + + + + Are you sure you want to empty %1 item? + هل أنت متأكد من إفراغ %1 عنصر ؟ + + + + Are you sure you want to empty %1 items? + هل أنت متأكد من إفراغ %1 عنصر ؟ + + + + + This action cannot be undone + هذا الإجراء لا يمكن إلغاؤه + + + + + + + + + + + + + + OK + button + حسناً + + + + + + + + + + + + + + + + Cancel + button + إلغاء + + + + + + Run + button + تشغيل + + + + + Run in terminal + button + تشغيل في الطرفية + + + + Display + button + عرض + + + + + + + + + Confirm + button + تأكيد + + + + Erase + button + مسح + + + Burn image, + + + + Burn files, + + + + + Data verification failed + + + + + Show details + button + إظهار التفاصيل + + + + + Delete + button + حذف + + + + Remove + button + إزالة + + + + Disk is busy, cannot unmount now + القرص قيد الاستخدام ، لا يمكن فصله اﻵن + + + + Force unmount + button + إجبار على الفصل + + + + Unable to copy. Not enough free space on the target disk. + غير قادر على النسخ، لا يوجد مساحة كافية على القرص المستهدف + + + + Failed to restore %1 file, the target folder is read-only + فشل إستعادة %1 ملف/ملفات، المجلد المستهدف للقراءة فقط + + + + Failed to restore %1 files, the target folder is read-only + فشل إستعادة %1 ملف/ملفات، المجلد المستهدف للقراءة فقط + + + + Failed to restore %1 files, the source files do not exist + + + + + Mount partition%1 to be read only + القسم المركب %1 ليكون قابل للقراءة فقط + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + الأقسام في ويندوز ستكون غير قابلة للقراءة و الكتابة بشكل صحيح إذا قمت بتحديد الخيار "تشغيل الإقلاع السريع (موصى به)" في إعدادت الإغلاق + + + + Please restore by the following steps to normally access Windows disk + رجاءً قم بالاستعادة عن طريق اتباع الخطوات التالية للوصول الطبيعي لأقراص الويندوز + + + + 1. Reboot to enter Windows + 1. أعد التشغيل للدخول إلى ويندوز + + + + Format + button + التنسيق + + + + Stop + button + إيقاف + + + Reboot + إعادة التشغيل + + + + FileController + + + + + + Unable to find the original file + + + + + + + Kindly Reminder + تذكير + + + + + + Please install File Roller first and then continue + رجاءً قم بتثبيت برنامج إدارة الملفات المضغوطة File Roller أولاً ثم تابع بعد ذلك + + + + + Unable to create files here: %1 + + + + + Confirm + button + تأكيد + + + Confirm + تأكيد + + + + FileDialogStatusBar + + + File Name + اسم الملف + + + + Format + التنسيق + + + Cancel + إلغاء + + + + + + Cancel + button + إلغاء + + + + Save + حفظ + + + + Open + فتح + + + + Save File + حفظ الملف + + + + Open File + فتح ملف + + + + FileIconItem + + + "'/\[]:|<>+=;,?* are not allowed + + + + + FileJob + + + copy + نسخ + + + + + + + Data verification successful. + تم تأكيد البيانات بنجاح. + + + + + + Burn process completed + تمت عملية الحرق + + + + %1 s + %1 ثانية + + + + %1 m %2 s + %1 دقيقة %2 ثانية + + + + %1 h %2 m %3 s + %1 ساعة %2 دقيقة %3 ثانية + + + + %1 d %2 h %3 m %4 s + %1 يوم %2 ساعة %3 دقيقة %4 ثانية + + + + %1 is a duplicate file. + %1 هو ملف مكرر. + + + + Insufficient disc space. + مساحة القرص غير كافية. + + + + Lost connection to drive. + تم فقد الاتصال بالقرص. + + + + The CD/DVD drive is not ready. Try another disc. + قرص CD/DVD ليس مستعدًا. جرب أسطوانة أخرى. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + قرص CD/DVD مشغول. اخرج من البرنامج الذي يستخدم القرص، ثم أدخل القرص مرة أخرى. + + + + Unknown error + خطأ غير معروف + + + + Device disconnected + + + + + GenerateSettingTranslate + + + + + Basic + أساسي + + + + + + Open behavior + سلوك الفتح + + + + + + Always open folder in new window + فتح المجلد في نافذة جديدة دوماً + + + + + + Open file: + فتح الملف: + + + + + + Click + نقرة + + + + + + Double click + نقر مزدوح + + + + + + New window and tab + تبويب ونافذة جديدة + + + + + + Open from default window: + فتح من النافذة الافتراضية + + + + + + + + + Computer + الحاسوب + + + + + + + + + Home + المنزل + + + + + + + + + Desktop + سطح المكتب + + + + + + + + + Videos + الفيديوهات + + + + + + + + + Music + الموسيقى + + + + + + + + + Pictures + الصور + + + + + + + + + Documents + المستندات + + + + + + + + + Downloads + التنزيلات + + + + + + Open in new tab: + فتح في تبويب جديد: + + + + + + Current Directory + الدليل الحالي + + + + + + View + عرض + + + + + + Default size: + الحجم الافتراضي + + + + + + Extra small + صغير جداً + + + + + + Small + صغير + + + + + + Medium + متوسط + + + + + + Large + كبير + + + + + + Extra large + كبير جداً + + + + + + Default view: + العرض الافتراضي: + + + + + + Icon + رموز + + + + + + List + قائمة + + + + + + Hidden files + الملفات المخفية + + + + + + Show hidden files + إظهار الملفات المخفية + + + + + + Hide file extension when rename + إخفاء صيغة الملف عند إعادة التسمية + + + + + + Advanced + متقدم + + + + + + Index + فهرس + + + + + + Auto index internal disk + فهرسة تلقائية للقرص المحلي + + + + + + Index external storage device after connected to computer + فهرسة القرص الخارجي بعد اتصاله للكمبيوتر + + + + + + Full-Text search + + + + + + + Use the file chooser dialog of File Manager + استخدام مربع الحوار للاختيارات لمدير ملفات ديبين + + + + + + Ask for my confirmation when deleting files + + + + + + + Other + غير ذلك + + + + + + Hide system disk + إخفاء فهرسة النظام + + + + + + Show file system on disk icon + + + + + + + Show hidden files in search results + إظهار الملفات المخفية في نتائج البحث + + + + + + Display recent file entry in left panel + إظهار الملفات الحديثة في الشريط الأيسر + + + + + + Preview + معاينة + + + + + Compress file preview + معاينة ملف مضغوط + + + + + + Text preview + معاينة نص + + + + + + Document preview + معاينة مستند + + + + + + Image preview + معاينة صورة + + + + + + Video preview + معاينة الفيديو + + + + + + Mount + وصل + + + + + + Auto mount + وصل تلقائي + + + + + + Open after auto mount + فتح بعد التوصيل التلقائي + + + + + + Dialog + مربع الحوار + + + + Compressed file preview + معاينة الملف المضغوط + + + + GvfsMountManager + + + Can’t verify the identity of %1. + + + + + This happens when you log in to a computer the first time. + + + + + The identity sent by the remote computer is + + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + + + + + + + + + Mounting device error + فشل تنصيب القرض ظاهرياً + + + + + Wrong username or password + + + + + + + + + Confirm + button + تأكيد + + + + + Cannot find the mounted device + + + + + No key available to unlock device + + + + + The disk is mounted by user "%1", you cannot unmount it. + القرص متصل بالمستخدم "%1"، لا يمكنك فصله. + + + Confirm + تأكيد + + + + Cannot unmount the device + لا يمكن فصل الجهاز + + + + Cannot eject the device "%1" + لا يمكن إخراج الجهاز "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + + + + + MergedDesktopController + + + + Pictures + الصور + + + + + Music + الموسيقى + + + + + Applications + التطبيقات + + + + + Videos + الفيديوهات + + + + + Documents + المستندات + + + + + Others + غير ذلك + + + + MimeTypeDisplayManager + + + + Directory + دليل + + + + + + Application + تطبيق + + + + + + Video + فيديو + + + + + + Audio + صوت + + + + + + Image + صورة + + + + + Archive + أرشيف + + + + + + Text + نص + + + + + Executable + ملف تنفيذي + + + + + Backup file + ملف احتياطي + + + + + Unknown + غير معروف + + + + MountAskPasswordDialog + + Cancel + إلغاء + + + Connect + اتصال + + + + Cancel + button + إلغاء + + + + Connect + button + اتصال + + + + Log in as + الدخول كـ + + + + Anonymous + مجهول + + + + Registered user + مستخدم مسجل + + + + Username + اسم المستخدم + + + + Domain + النطاق + + + + Password + كلمة المرور + + + + Remember password + تذكر كلمة المرور + + + + MountSecretDiskAskPasswordDialog + + Cancel + إلغاء + + + Unlock + فك القفل + + + + Cancel + button + إلغاء + + + + Unlock + button + فك القفل + + + + Input password to decrypt the disk + أدخل كلمة المرور لفك تشفير القرص + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + هل أنت متأكد من الحذف الأبدي %1؟ + + + + This file is too big for the trash + الملف كبير جدا بحيث لا يمكن وضعه في سلة المحذوفات + + + + The files are too big for the trash + الملفات كبيرة جدا بحيث لا يمكن وضعها في سلة المحذوفات + + + + Are you sure you want to permanently delete %1 files? + هل أنت متأكد من الحذف الأبدي %1 ملفات؟ + + + + Cancel + button + إلغاء + + + + Delete + button + حذف + + + Cancel + إلغاء + + + Delete + حذف + + + + OpenWithDialog + + + Open with + فتح باستخدام + + + + Add other programs + إضافة برامج آخرى + + + + Set as default + تعيين كافتراضي + + + + Cancel + button + إلغاء + + + + Confirm + button + تأكيد + + + Cancel + إلغاء + + + Confirm + تأكيد + + + + Recommended Applications + تطبيقات موصى بها + + + + Other Applications + تطبيقات أخرى + + + + PathManager + + + Home + المنزل + + + + Desktop + سطح المكتب + + + + Videos + الفيديو + + + + Music + الصوتيات + + + + Pictures + الصور + + + + Documents + المستندات + + + + Downloads + التنزيلات + + + + + Trash + المحذوفات + + + + + + System Disk + قرص النظام + + + + Computers in LAN + حواسيب في الشبكة + + + + My Shares + مشاركاتي + + + + Computer + الحاسوب + + + + Recent + حديث + + + + File Vault + حقيبة الملفات المحمية + + + + PropertyDialog + + + Basic info + المعلومات الأساسية + + + + Open with + فتح باستخدام + + + + Sharing + مشاركة + + + + Permissions + الأذونات + + + + %1 (%2) + %1 (%2) + + + + %1 + + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + إخفاء هذا المجلد + + + + Hide this file + إخفاء هذا الملف + + + + Allow to execute as program + السماح بالتنفيذ كبرنامج + + + + QObject + + + + + Size + الحجم + + + + + + Contains + المحتويات + + + + + + Type + النوع + + + + + + + + Time modified + وقت التعديل + + + + Free space + المساحة الفارغة + + + + Total space + المساحة الإجمالية + + + + + Time locked + + + + + Access denied + تم رفض الوصول + + + + + Executable + ملف تنفيذي + + + + + Write only + للكتابة فقط + + + + + Read only + للقراءة فقط + + + + + Read-write + قراءة وكتابة + + + + Others + غير ذلك + + + + Owner + المالك + + + + Device type + نوع الجهاز + + + + File system + نظام الملف + + + + Group + المجموعة + + + + + Open + فتح + + + + Lock + + + + + Auto lock + + + + + Never + أبداً + + + + 5 minutes + + + + + 10 minutes + + + + + 20 minutes + + + + + Delete File Vault + + + + + Unlock + فك القفل + + + + Unlock by key + + + + + Open + button + فتح + + + + + Size: %1 + الحجم : %1 + + + + Type: %1 + النوع : %1 + + + + Size: 0 + الحجم: 0 + + + + Items: %1 + العناصر: %1 + + + + + + + + + + Open in new window + فتح في نافذة جديدة + + + + + + + + + + Open in new tab + فتح في تبويب جديد + + + + Open with + فتح باستخدام + + + + + Compress + ضغط + + + + Extract + استخراج + + + + Extract here + استخراج هنا + + + + Cut + قص + + + + Copy + نسخ + + + + Paste + لصق + + + + + + + + Rename + إعادة تسمية + + + + + + Remove + إزالة + + + + Create link + إنشاء رابط + + + + Send to desktop + إرسال إلى سطح المكتب + + + + Send to + إرسال إلى + + + + Bluetooth + + + + + Add to bookmark + إضافة إلى اﻹشارات المرجعية + + + + + + + Properties + الخصائص + + + + New folder + مجلد جديد + + + + New window + نافذة جديدة + + + + Select all + تحديد الكل + + + + + Clear recent history + مسح السجل الحديث + + + + + + Empty Trash + إقراغ سلة المحذوفات + + + + Display as + عرض حسب + + + + Sort by + ترتيب حسب + + + + New document + مستند جديد + + + + + Time created + وقت الإنشاء + + + + Log out and unmount + تسجيل خروج وفصل + + + + + + Source path + مسار المصدر + + + + Share folder + مشاركة المجلد + + + + Cancel sharing + إلغاء المشاركة + + + + Connect to Server + الاتصال بالخادم + + + + Set share password + إعداد كلمة مرور المشاركة + + + + Format + تهيئة + + + + Tag information + معلومات شعارية + + + + Open as administrator + + + + + Select default program + تعيين كبرنامج افتراضي + + + + Open file location + فتح مكان الملف + + + + Remove bookmark + إزالة من الإشارات المرجعية + + + + + + Delete + حذف + + + + Office Text + نص مكتبي + + + + Spreadsheets + جدول بيانات + + + + Plain Text + مستند نص عادي + + + + Open in terminal + فتح في الطرفية + + + + Restore + استعادة + + + + Restore all + استعادة الكل + + + + + + + + File Vault + حقيبة الملفات المحمية + + + + Add to disc + + + + + Auto mount + وصل تلقائي + + + + Open after auto mount + فتح بعد التوصيل التلقائي + + + + + Mount + وصل + + + + + Unmount + فصل + + + + It does not support burning %1 discs + + + + + Burn + حرق + + + + Disc name: + اسم الأسطوانة: + + + + + Maximum + أقصى سرعة كتابة + + + + Allow files to be added later + السماح للملفات أن تُضاف لاحقًا + + + + Verify data + تأكيد البيانات + + + + Write speed: + سرعة الكتابة: + + + + + + + Cancel + button + إلغاء + + + + Burn + button + حرق + + + + + Eject + إخراج + + + + Safely Remove + حذف آمن + + + + + Name + الاسم + + + + Settings + إعدادات + + + + Exit + خروج + + + + Icon + رموز + + + + List + قائمة + + + + Extend + تمديد + + + + Set as wallpaper + تعيين كخلفية + + + + + + + Local disk + قرص محلي + + + + + Removable disk + قرص قابل للإزالة + + + + + + Network shared directory + الدليل المشترك للشبكة + + + + + Android mobile device + جهاز أندرويد محمول + + + + + Apple mobile device + جهاز آبل محمول + + + + + Camera + كاميرا + + + + + DVD + دي في دي + + + + + Unknown device + جهاز غير معروف + + + + + + %1 item + %1 عنصر + + + + + + %1 items + %1 من العناصر + + + + Shortcut + اختصار + + + + Create symlink + إنشاء وصلة رمزية + + + + Path + المسار + + + + + + Time deleted + تاريخ الحذف + + + + Loading... + يحمل الآن ... + + + + File has been moved or deleted + تم نقل الملف أو أنه قد حذف + + + + You do not have permission to traverse files in it + + + + + + + You do not have permission to access this folder + ليس لديك صلاحيات للوصول إلى هذا المجلد + + + + + + + + Folder is empty + المجلد فارغ + + + + Searching... + يبحث اﻵن ... + + + + No results + لا توجد نتائج + + + + Source Path + TrashFileInfo + مسار المصدر + + + + Document + مستند + + + + Spreadsheet + جدول بيانات + + + + + Presentation + عرض تقديمي + + + + Text + نص + + + + 1 task in progress + مهمة واحدة قيد المعالجة + + + + %1 tasks in progress + %1 من المهام قيد المعالجة + + + + Mode: + الوضع: + + + + + Replace Text + استبدال النص + + + + + Add Text + إضافة نص + + + + + Custom Text + نص مخصص + + + + Find: + بحث: + + + + Replace: + استبدال: + + + + + Optional + اختياري + + + + Add: + إضافة: + + + + Location: + المكان: + + + + File name: + اسم الملف: + + + + Start at: + + + + + + Rename + button + إعادة تسمية + + + + + + + + + + + Required + مطلوب + + + + + Before file name + قبل اسم الملف + + + + + After file name + بعد اسم الملف + + + + Find + بحث + + + + Replace + استبدال + + + + Add + إضافة + + + + Start at + + + + + + + Location + المكان + + + + File name + اسم الملف + + + + Dimension + البُعد + + + + Duration + الفترة + + + + Tips: Sort by selected file order + نصائح: ترتيب حسب ترتيب الملفات المحددة + + + Cancel + إلغاء + + + + Rename %1 Files + إعادة تسمية %1 من الملفات + + + + Multiple Files + ملفات متعددة + + + + Basic info + المعلومات الأساسية + + + + Total size + الحجم اﻹجمالي + + + + Number of files + عدد الملفات + + + + %1 file(s), %2 folder(s) + %1 من الملفات %2 من المجلدات + + + + + + Time accessed + وقت الدخول + + + + Orange + برتقالي + + + + Red + أحمر + + + + Purple + بنفسجي + + + + Navy-blue + أزرق داكن + + + + Azure + أزرق سماوي + + + + Green + أخضر + + + + Yellow + أصفر + + + + Gray + رمادي + + + + Input tag info, such as work, family. A comma is used between two tags. + أدخل معلومات شعارية، مثل عمل، عائلة. الفاصلة تُستخدم بين شعارين. + + + + Bookmarks + مرجعيات + + + + Erase + مسح + + + + Copy path + نسخ المسار + + + + Edit address + تعديل العنوان + + + It does not support burning UDF discs + + + + + Free Space %1 + المساحة الفارغة %1 + + + + Files are being processed + الملفات قيد المعالجة + + + + Unknown + غير معروف + + + + My Vault + + + + + + + Disks + الأقراص + + + + + Failed to create file info + + + + + Failed to create file handler + + + + + + + Execution error + + + + + + + + "'/\[]:|<>+=;,?* are not allowed + + + + + Failed to open the file, cause: %1 + فشل في فتح الملف، السبب: %1 + + + + Original file does not exist + الملف الأصلي غير موجود + + + + Do you want to delete %1? + + + + + Confirm + button + تأكيد + + + Confirm + تأكيد + + + + ShareInfoFrame + + + Share this folder + مشاركة هذا المجلد + + + + Share name: + اسم المشاركة : + + + + Permission: + اﻷذونات : + + + + Read and write + قراءة وكتابة + + + + Read only + للقراءة فقط + + + + Anonymous: + إخفاء الهوية : + + + + Not allow + غير مسموح + + + + Allow + مسموح + + + + The share name must not be two dots (..) or one dot (.) + + + + + The share name is used by another user. + + + + + OK + button + حسناً + + + + Cancel + button + إلغاء + + + + Replace + button + استبدال + + + OK + حسناً + + + + The share name already exists. Do you want to replace the shared folder? + + + + Cancel + إلغاء + + + Replace + استبدال + + + + Shortcut + + + Item + عنصر + + + + Select to the first item + تحديد إلى أول عنصر + + + + Shift + Home + Shift + Home + + + + Select to the last item + تحديد إلى آخر عنصر + + + + Shift + End + Shift + End + + + + Select leftwards + تحديد من اليسار + + + + Shift + Left + Shift + Left + + + + Select rightwards + تحديد من اليمين + + + + Shift + Right + Shift + Right + + + + Select to upper row + تحديد الصف العلوي + + + + Shift + Up + Shift + Up + + + + Select to lower row + تحديد الصف السفلي + + + + Shift + Down + Shift + Down + + + + Open + فتح + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + إلى الدليل اﻷصل + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + الحذف بشكل دائم + + + + Shift + Delete + Shift + Delete + + + + Delete file + حذف الملف + + + + Delete + حذف + + + + Select all + تحديد الكل + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl +C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + نسخ + + + + Cut + قص + + + + Paste + لصق + + + + Rename + إعادة تسمية + + + + F2 + F2 + + + + New/Search + بحث/جديد + + + + New window + نافذة جديدة + + + + New folder + مجلد جديد + + + + + Search + بحث + + + + New tab + تبويب جديد + + + + View + عرض + + + + Item information + معلومات العنصر + + + + Help + مساعدة + + + + F1 + F1 + + + + Keyboard shortcuts + اختصارات لوحة المفاتيح + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + تبديل إلى حالة العرض + + + + Hide item + إخفاء العنصر + + + + Input in address bar + الإدخال في شريط العناوين + + + + Switch to icon view + التبديل إلى المنظور الأيقوني + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + التبديل إلى منظور القائمة + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + غير ذلك + + + + Close + إغلاق + + + + Alt + F4 + Alt + F4 + + + + Close current tab + إغلاق التبويب الحالي + + + + Back + رجوع + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + التبديل إلى التبويب التالي + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + التبديل إلى التبويب السابق + + + + Next file + الملف التالي + + + + Tab + Tab + + + + Previous file + الملف السابق + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + تبديل التبويب عن طريق رقم محدد ما بين 1 إلى 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + للأمام + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + + + + + TrashPropertyDialog + + + Trash + المحذوفات + + + + item + عنصر + + + + items + من العناصر + + + + Contains %1 %2 + يحتوي على %1 %2 + + + + UDiskListener + + + Failed to rename the label + فشل في إعادة التسمية + + + + UnmountWorker + + + + + The device was not safely unmounted + + + + + The device was not safely removed + لم يتم إزالة الجهاز بأمان + + + + UserShareManager + + + Kindly Reminder + تذكير + + + + Please firstly install samba to continue + رجاءً قم بتثبيت samba أولًا لتكمل + + + + To protect the files, you cannot share this folder. + + + + + The share name must not contain %<>*?|/\+=;:," + + + + + Sharing failed + + + + + The computer name is too long + + + + + You do not have permission to operate file/folder! + ليس لديك صلاحيات كافية لتشغيل المجلد \الملف + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + أدخل كلمة مرور لحماية مجلدات المشاركة + + + + Cancel + button + إلغاء + + + + Confirm + button + تأكيد + + + Cancel + إلغاء + + + Confirm + تأكيد + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ast.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ast.ts new file mode 100644 index 0000000..af62121 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ast.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + Carpeta nueva + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + Zarrar too + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + Ordenador + + + + Basic Info + Información básica + + + + Computer Name + Nome del ordenador + + + + Version + Versión + + + + Type + Triba + + + + Processor + Procesador + + + + Memory + Memoria + + + + Disk + Discu + + + + Bit + Bits + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + Gueta o introduz una direición + + + + DFMAdvanceSearchBar + + + Search: + + + + + File Type: + + + + + File Size: + + + + + Time Modified: + + + + + Reset + + + + + All subdirectories + + + + + Current directory + + + + + 0 ~ 100 KB + + + + + 100 KB ~ 1 MB + + + + + 1 MB ~ 10 MB + + + + + 10 MB ~ 100 MB + + + + + 100 MB ~ 1 GB + + + + + > 1 GB + + + + + Today + + + + + Yesterday + + + + + This week + + + + + Last week + + + + + This month + + + + + Last month + + + + + This year + + + + + Last year + + + + + DFMTagCrumbController + + + Tag information + + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + Fallu de permisos + + + + The action is denied + Ñegóse l'aición + + + + Failed to open the file + Fallu al abrir el ficheru + + + + Failed to read the file + Fallu al lleer el ficheru + + + + Failed to write the file + Fallu al escribir nel ficheru + + + + Failed to create the directory + Fallu al crear el direutoriu + + + + Failed to delete the file + Fallu al desaniciar el ficheru + + + + Failed to move the file + Fallu al mover el ficheru + + + + Original file does not exist + El ficheru orixinal nun esiste + + + + Failed, file size must be less than 4GB + Fallu, el tamañu del ficheru ha ser menos de 4GB + + + + Not enough free space on the target disk + + + + + File integrity was damaged + Dañóse la integridá del ficheru + + + + The target device is read only + El preséu de destín ye de namái llectura + + + + Target folder is inside the source folder + La carpeta de destín ta dientro de la carpeta fonte + + + + copy + Extra name added to new file name when used for file name. + copiar + + + + Failed to create the directory, cause: %1 + Fallu al crear el direutoriu, causa: %1 + + + + + Failed to open the file, cause: %1 + Fallu al abrir el ficheru, causa: %1 + + + + Failed to read the file, cause: %1 + Fallu al lleer el ficheru, causa: %1 + + + + Failed to write the file, cause: %1 + Fallu al escribir nel ficheru, causa: %1 + + + + File integrity was damaged, cause: %1 + Dañóse la integridá del ficheru, causa: %1 + + + + Failed to delete the file, cause: %1 + Fallu al desaniciar el ficheru, causa: %1 + + + + Fail to create symlink, cause: %1 + Fallu al crear l'enllaz simbólicu, causa: %1 + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + %1 yá esiste, ¿quies trocalu? + + + + Cancel + Encaboxar + + + + Replace + Trocar + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + Nome + + + + + + Time modified + Data de modificación + + + + Size + Tamañu + + + + Type + Triba + + + + Time created + Data de creación + + + + + Last access + + + + + Path + Camín + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + (Al aviesu) + + + + DFileViewHelper + + + Add tag "%1" + Amestar etiqueta «%1» + + + + DStatusBar + + + %1 item + %1 elementu + + + + %1 items + %1 elementos + + + + %1 item selected + %1 elementu esbilláu + + + + %1 items selected + %1 elementos esbillaos + + + + %1 folder selected (contains %2) + %1 carpeta esbillada (contién %2) + + + + %1 folders selected (contains %2) + %1 carpetes esbillaes (contienen %2) + + + + %1 file selected (%2) + % ficheru esbilláu (%2) + + + + %1 files selected (%2) + %1 ficheros esbillaos (%2) + + + + %1 folder selected + %1 carpeta esbillada + + + + Filter + Peñera + + + + Save as: + Guardar como: + + + + Loading... + Cargando... + + + + DTaskDialog + + + This action is not supported + Esta aición nun ta sofitada + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + + + + + Data Disk + Data Partition + + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + ¡Falló la operación! + + + + Target folder is inside the source folder! + ¡La carpeta destín ta dientro la carpeta fonte! + + + + + + + + + + + + + OK + Aceutar + + + + Do you want to run %1 or display its content? + ¿Quies executar %1 o amosar el so conteníu? + + + + It is an executable text file. + Ye un ficheru executable. + + + + + + + + + + + + + + Cancel + Encaboxar + + + + + + Run + Executar + + + + + Run in terminal + Executar na terminal + + + + Display + Amosar + + + + It is an executable file. + Ye un ficheru executable. + + + + This file is not executable, do you want to add the execute permission and run? + + + + + "%1" already exists, please use another name. + «%1» yá esiste, por favor usa otru nome. + + + + + + + + Confirm + Confirmar + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + ¿Desaniciar %1 dafechu? + + + + Permanently delete %1 items? + ¿Desaniciar %1 elementos dafechu? + + + + Delete + Desaniciar + + + + Empty + Balero + + + + Sorry, unable to locate your bookmark directory, remove it? + Perdón, nun pue allugase'l direutoriu de marcadores. ¿Desanicialu? + + + + Remove + Desaniciar + + + + Name: + Nome: + + + + Force unmount + Forciar desmontaxe + + + + %1 that this shortcut refers to has been changed or moved + + + + + Do you want to delete this shortcut? + ¿Ques desaniciar esti atayu? + + + + Failed, file size must be less than 4GB. + Fallu, el ficheru ha ser menor de 4GB. + + + + Fail to create symlink, cause: + Fallu al crear l'enllaz simbólicu, causa: + + + + The selected files contain system file/directory, and it cannot be deleted + Los ficheros esbillaos contienen direutorios/ficheros y nun puen desaniciase + + + + + You do not have permission to operate file/folder! + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + + + + + View + Ver + + + + Do you want to run %1? + ¿Quies executar %1? + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + + + + + Please restore by the following steps to normally access Windows disk + + + + + 1. Reboot to enter Windows + + + + 3. Reboot and enter deepin + + + + + Reboot + + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + Nome de ficheru + + + + Format + Formatu + + + + Cancel + Encaboxar + + + + Save + Guardar + + + + Open + Abrir + + + + Save File + Guardar ficheru + + + + Open File + Abrir ficheru + + + + FileJob + + + copy + copiar + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + Básico + + + + + + Open behavior + Comportamientu d'apertura + + + + + + Always open folder in new window + Abrir siempres les carpetes en ventanes nueves + + + + + + Open file: + Abrir ficheru: + + + + + + Click + Clic + + + + + + Double click + Clic doblu + + + + + + New window and tab + Abrir ventana y llingüeta nueves + + + + + + Open from default window: + + + + + + + + + + Computer + Ordenador + + + + + + + + + Home + Aniciu + + + + + + + + + Desktop + Escritoriu + + + + + + + + + Videos + Vídeos + + + + + + + + + Music + Música + + + + + + + + + Pictures + Semeyes + + + + + + + + + Documents + Documentos + + + + + + + + + Downloads + Descargues + + + + + + Open in new tab: + Abrir nuna llingüeta nueva: + + + + + + Current Directory + Direutoriu actual + + + + + + View + Ver + + + + + + Default size: + Tamañu predetermináu: + + + + + + Extra small + Nanu + + + + + + Small + Pequeñu + + + + + + Medium + Mediu + + + + + + Large + Grande + + + + + + Extra large + Escomanáu + + + + + + Default view: + Vista predeterminada: + + + + + + Icon + Iconu + + + + + + List + Llista + + + + + + Hidden files + Ficheros anubríos + + + + + + Show hidden files + Amosar ficheros anubríos + + + + + + Hide file extension when rename + Anubrir la estensión de los ficheros al renomar + + + + + + Advanced + Avanzao + + + + + + Index + Índiz + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + Otru + + + + + + Hide system disk + Anubrir discu del sistema + + + + + + Show hidden files in search results + Amosar ficheros anubríos nos resultaos de gueta + + + + + + Display recent file entry in left panel + + + + + + + Preview + + + + + + Compress file preview + Previsualización del ficheru comprimíu + + + + + + Text preview + Previsualización de testu + + + + + + Document preview + Previsualización del documentu + + + + + + Image preview + Previsualización d'imáxenes + + + + + + Video preview + Previsualización de videu + + + + + + Mount + Montar + + + + + + Auto mount + Auto-montar + + + + + + Open after auto mount + Abrir tres el montaxe automáticu + + + + + + Dialog + Diálogu + + + Use the file chooser dialog of Deepin File Manager + Usa'l diálogu seleutor de ficheros de Deepin File Manager + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + + + + + + + + + Confirm + Confirmar + + + + + Cannot find the mounting device + Nun pue alcontrase'l preséu de montaxe + + + + Cannot unmount the device + Nun pue desmontase'l preséu + + + + Cannot eject the device "%1" + Nun pue espulsase'l preséu «%1» + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + + + + + + + Application + + + + + + + Video + + + + + + + Audio + + + + + + + Image + + + + + + Archive + + + + + + + Text + Testu + + + + + Executable + Executable + + + + + Backup file + + + + + + Unknown + + + + + MountAskPasswordDialog + + + Cancel + Encaboxar + + + + Connect + Coneutar + + + + Log in as + Aniciar sesión como + + + + Anonymous + Anónimu + + + + Registered user + Usuariu rexistráu + + + + Username + Nome d'usuariu + + + + Domain + Dominiu + + + + Password + Contraseña + + + + Remember password + Recordar contraseña + + + + MountSecretDiskAskPasswordDialog + + + Cancel + Encaboxar + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + Saltar + + + Keep both + Caltener dambos + + + Replace + Trocar + + + Do not ask again + Nun entrugar de nueves + + + merge + mecer + + + Copying %1 + Copiando %1 + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + Copia de %2 + + + Moving %1 + Moviendo %1 + + + Move to %2 + Mover a %2 + + + Restoring %1 + Restaurando %1 + + + Restore to %2 + Restaurar a %2 + + + Deleting %1 + Desaniciando %1 + + + Trashing %1 + Unviando a la papelera %1 + + + Calculating space, please wait + Calculando l'espaciu, espera por favor + + + File named %1 already exists in target folder + Yá esiste'l ficheru col nome %1 + + + Original path %1 target path %2 + + + + Retry + + + + Time modified:%1 + Data de modificación:%1 + + + Original folder + Carpeta orixinal + + + Original file + Ficheru orixinal + + + Target folder + Carpeta de destín + + + Target file + Ficheru de destín + + + Contains:%1 + Contién: %1 + + + Size:%1 + Tamañu:%1 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + Encaboxar + + + + Delete + Desaniciar + + + + OpenWithDialog + + + Open with + Abrir con + + + + Add other programs + Amestar otros programas + + + + Set as default + Predeterminar + + + + Cancel + Encaboxar + + + + Confirm + + + + + Recommended Applications + Aplicaciones aconseyaes + + + + Other Applications + Otres aplicaciones + + + + PathManager + + + Home + Aniciu + + + + Desktop + Escritoriu + + + + Videos + Vídeos + + + + Music + Música + + + + Pictures + Semeyes + + + + Documents + Documentos + + + + Downloads + Descergues + + + + + Trash + Papelera + + + + + System Disk + Discu del sistema + + + + Computers in LAN + Ordenadores na LAN + + + + My Shares + Les mios comparticiones + + + + Computer + Ordenador + + + + Recent + + + + + PropertyDialog + + + Basic info + Información básica + + + + Open with + Abrir con + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + Permitir execución como programa + + + + QObject + + + + + Size + Tamañu + + + + + + Contains + Contién + + + + + + Type + Triba + + + + + + + Time modified + Data de modificación + + + + Free space + Espaciu llibre + + + + Total space + Espaciu total + + + + Access denied + + + + + + Executable + Executable + + + + + Write only + Namái escritura + + + + + Read only + Namái llectura + + + + + Read-write + Llectura-escritura + + + + Others + Otros + + + + Owner + Dueñu + + + + Device type + + + + + File system + + + + + Group + Grupu + + + + + + Open + Abrir + + + + + Size: %1 + Tamañu: %1 + + + + Type: %1 + Triba: %1 + + + + Size: 0 + Tamañu: 0 + + + + Items: %1 + Elementos: %1 + + + + + + + + + + + Open in new window + Abrir na ventana nueva + + + + + + + + + + + Open in new tab + Abrir na llingüeta nueva + + + + Open with + Abrir con + + + + Compress + Comprimir + + + + Extract + Estrayer + + + + Extract here + Estrayer equí + + + + Cut + Cortar + + + + Copy + Copiar + + + + Paste + Apegar + + + + + + + + + + Rename + Renomar + + + + + + Remove + Desaniciar + + + + Create link + Crear enllaz + + + + Send to desktop + Unviar a Escritoriu + + + + Send to + Unviar a + + + + Add to bookmark + Amestar a marcadores + + + + + + + Properties + Propiedaes + + + + New folder + Carpeta nueva + + + + New window + Ventana nueva + + + + Select all + Esbillar too + + + + + Clear recent history + Llimpiar historial recién + + + + + + Empty Trash + Balerar papelera + + + + Display as + Amosar como + + + + Sort by + Ordenar per + + + + New document + Documentu nuevu + + + + + Time created + Data de creación + + + + Log out and unmount + Zarrar sesión y desmontar + + + + + + Source path + Camín de fonte + + + + Share folder + Compartir carpeta + + + + Cancel sharing + Encaboxar compartición + + + + Connect to Server + + + + + Set share password + Afitar contraseña de compartición + + + + Format + Formatu + + + + Tag information + + + + + Open in new window as admin + Abrir nuna ventana nueva como alministrador + + + + Select default program + Esbillar programa por defeutu + + + + Open file location + Abrir allugamientu del ficheru + + + + Remove bookmark + + + + + + + Delete + Desaniciar + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + Abrir na terminal + + + + Restore + Restaurar + + + + Restore all + Restaurar too + + + + File Vault + + + + + Auto mount + Auto-montar + + + + Open after auto mount + Abrir tres el montaxe automáticu + + + + + Mount + Montar + + + + + Unmount + Desmontar + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + Espulsar + + + + Safely Remove + Estraición segura + + + + + Name + Nome + + + + Settings + Axustes + + + + Exit + Colar + + + + Icon + Iconu + + + + List + Llista + + + + Extend + + + + + Set as wallpaper + Afitar como fondu de pantalla + + + + + + + Local disk + Discu llocal + + + + + Removable disk + Discu estrayible + + + + + + Network shared directory + Direutoriu compartíu de rede + + + + + Android mobile device + Preséu Android + + + + + Apple mobile device + Preséu d'Apple + + + + + Camera + Cámara + + + + + DVD + + + + + + Unknown device + Preséu desconocíu + + + + + + %1 item + %1 elementu + + + + + + %1 items + %1 elementos + + + + Shortcut + Atayu + + + + Create symlink + Crear enllaz simbólicu + + + + Path + Camín + + + + + + Time deleted + Data de desaniciu + + + + Loading... + Cargando... + + + + File has been moved or deleted + El ficheru movióse o desanicióse + + + + + + You do not have permission to access this folder + Nun tienes permisu p'acceder a esta carpeta + + + + + + + Folder is empty + La carpeta ta balera + + + + Path + SearchFileInfo + Camín + + + + Searching... + Guetando... + + + + No results + Nun hai resultaos + + + + Source Path + TrashFileInfo + Camín fonte + + + + Document + Documentu + + + + Spreadsheet + Fueya de cálculu + + + + + Presentation + Presentación + + + + Text + Testu + + + + 1 task in progress + 1 xera en cursu + + + + %1 tasks in progress + %1 xeres en cursu + + + + Mode: + Mou: + + + + + Replace Text + Trocar testu + + + + + Add Text + Amestar testu + + + + + Custom Text + Testu personalizáu + + + + Find: + Alcontrar: + + + + Replace: + Trocar: + + + + + Optional + Opcional + + + + Add: + Amestar: + + + + Location: + Allugamientu + + + + File name: + Nome de ficheru: + + + + +SN: + + + + + + + + + + + Required + Ríquese + + + + + Before file name + Ficheru siguiente + + + + + After file name + + + + + Find + Alcontrar + + + + Replace + Trocar + + + + Add + Amestar + + + + + + Location + Allugamientu + + + + File name + Nome de ficheru + + + + Dimension + + + + + Duration + + + + + +SN + + + + + Tips: Sort by selected file order + + + + + + + Cancel + Encaboxar + + + + Rename %1 Files + Renomar %1 ficheros + + + + Multiple Files + Ficheros múltiples + + + + Basic info + Información básica + + + + Total size + Tamañu total + + + + Number of files + Númberu de ficheros + + + + %1 file(s), %2 folder(s) + %1 ficheru(os), %2 carpeta(es) + + + + + + Time accessed + + + + + Orange + Naranxa + + + + Red + Bermeyu + + + + Purple + Moráu + + + + Navy-blue + + + + + Azure + + + + + Green + Verde + + + + Yellow + Mariellu + + + + Gray + Buxu + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + Marcadores + + + + Erase + + + + + + Copy path + + + + + + Edit address + + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + Compartir esta carpeta + + + + Share name: + Nome de compartición: + + + + Permission: + Permisos: + + + + Read and write + Llectura y escritura + + + + Read only + Namái llectura + + + + Anonymous: + Anónimu: + + + + Not allow + Nun permitir + + + + Allow + Permitir + + + + Shortcut + + + Item + Elementu + + + + Select to the first item + + + + + Shift + Home + + + + + Select to the last item + + + + + Shift + End + + + + + Select leftwards + + + + + Shift + Left + + + + + Select rightwards + + + + + Shift + Right + + + + + Select to upper row + + + + + Shift + Up + + + + + Select to lower row + + + + + Shift + Down + + + + + Open + Abrir + + + + Ctrl + Down + + + + + To parent directory + Al direutoriu pá + + + + Ctrl + Up + + + + + Permanently delete + Desaniciar dafechu + + + + Shift + Delete + + + + + Delete file + Desaniciar ficheru + + + + Delete + Desaniciar + + + + Select all + Esbillar too + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + Copiar + + + + Cut + Cortar + + + + Paste + Apegar + + + + Rename + Renomar + + + + F2 + F2 + + + + New/Search + Nuevo/Guetar + + + + New window + Ventana nueva + + + + New folder + Carpeta nueva + + + + + Search + Guetar + + + + New tab + Llingüeta nueva + + + + View + Ver + + + + Item information + Información d'elementu + + + + Help + Ayuda + + + + F1 + F1 + + + + Keyboard shortcuts + Atayos de tecláu + + + + Ctrl + Shift + / + + + + + Switch display status + + + + + Hide item + Anubrir elementu + + + + Input in address bar + Introducción na barra de direiciones + + + + Switch to icon view + + + + + Ctrl + 1 + + + + + Switch to list view + + + + + Ctrl + 2 + + + + + Others + Otros + + + + Close + Zarrar + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Zarru de la llingüeta actual + + + + Back + Atrás + + + + Alt + Left + + + + + Alt + Right + + + + + Switch to next tab + + + + + Ctrl + Tab + + + + + Ctrl + Shift + Tab + + + + + Switch to previous tab + + + + + Next file + Ficheru siguiente + + + + Tab + Llingüeta + + + + Previous file + Ficheru previu + + + + Shift + Tab + + + + + Switch tab by specified number between 1 to 8 + + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + + + + + TrashPropertyDialog + + + Trash + Papelera + + + + item + elementu + + + + items + elementos + + + + Contains %1 %2 + Contién %1 %2 + + + + UDiskListener + + + Failed to rename the label + Fallu al renomar la etiqueta + + + + UserShareManager + + + Kindly Reminder + Recordatoriu amistosu + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + Encaboxar + + + + Confirm + Confirmar + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_az.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_az.ts new file mode 100644 index 0000000..21fbb40 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_az.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Yeni qovluq + + + + Mounting device error + Cihaz qoşulma xətası + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Disk surəti pozulub, indi qoşula bilmir, lütfən öncə diski çıxarın + + + + Mount error: unsupported image format + Qoşulma xətası: dəstəklənməyən disk surəti formatı + + + + + The device was not safely removed + Cihaz təhlükəsiz şəkildə çıxarılmadı + + + + + Click "Safely Remove" and then disconnect it next time + Növbəti dəfə "Təhlükəsiz Çıxartmaq" vurun və sonra çıxardın + + + + The device was not ejected + Cihaz çıxarılmayıb + + + + Disk is busy, cannot eject now + Disk məşğuldur, indi çıxarıla bilməz + + + + Authentication timed out + Doğrulama vaxtı bitdi + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Bluetooth fayl mübadiləsi + + + + File Transfer Successful + Fayl mübadiləsi uğurlu oldu + + + + File Transfer Failed + Fayl mübadiləsi alınmadı + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Fayllar "<b style="font-weight: 550;">%1</b>" adlı cihaza göndərilir + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + "<b style="font-weight: 550;">%1</b>" adlı cihaza fayl göndərilməsi alınmadı + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + "<b style="font-weight: 550;">%1</b>"-adlı cihaza uğurla göndərildi + + + + Select a Bluetooth device to receive files + Faylları qəbul edəcək Bluetooth cihazını seçin + + + + Cannot find the connected Bluetooth device + Qoşulmuş Bluetooth cihazı tapılmadı + + + + Waiting to be received... + Qəbul olunması gözlənilir... + + + + Go to Bluetooth Settings + Bluetooth ayarlarına keçin + + + + %1/%2 Sent + %1/%2 göndərin + + + + Error: the Bluetooth device is disconnected + Xəta: Bluetooth cihazı ilə əlaqə kəsildi + + + + Unable to send the file more than 2 GB + 2 QB-dan çox faylın göndərilməsi mümkün deyil + + + + Unable to send 0 KB files + 0 KB faylların göndərilməsi mümkün deyil + + + + File doesn't exist + Fayl mövcud deyil + + + + Next + button + Növbəti + + + + Cancel + button + İmtina + + + + Done + button + Başa çatdı + + + + Retry + button + Təkrar + + + + OK + button + OK + + + + File sending request timed out + Fayl göndərilməsi tələbinin vaxtı bitdi + + + + The service is busy and unable to process the request + Tələbi yerinə yetirmək üçün xidmət məşğuldur və mümkün deyil + + + + BurnOptDialog + + + Device error + Cihaz xətası + + + + Optical device %1 doesn't exist + %1 optik cihazı mövcud deyil + + + + Advanced settings + Əlavə ayarlar + + + + File system: + Fayl sistemi: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Windows üçün) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Unix üçün) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Windows CD/DVD rejimləri ilə uyğun) + + + + ISO9660 Only + Yalnız ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Hamısını bağlamaq + + + + Total size: %1, %2 files + Ümumi ölçü: %1, %2 fayllar + + + + ComputerModel + + + Double click to open it + + + + + My Directories + Mənim qovluğum + + + + Disks + Disklər + + + + File Vault + Fayl seyfi + + + + Quick Access + + + + + ComputerPropertyDialog + + + Computer + Kompyuter + + + + Basic Info + Baza məlumatları + + + + + Computer Name + Kompyuterin adı + + + + + Edition + Nəşr + + + + + + Version + Versiya + + + + + Type + Növ + + + + + + Processor + Prosessor + + + + + + Memory + Yaddaş + + + + + + + Bit + Bit + + + + + Available + Mövcud + + + + Obtaining... + Alınır... + + + + ConnectToServerDialog + + + Connect to Server + Serverə bağlantı + + + + Cancel + button + İmtina + + + + Connect + button + Bağlantı + + + + My Favorites: + Mənim üstünlük verdiklərim: + + + + + Clear History + Tarixçəni təmizləmək + + + + DFMAddressBar + + + Search or enter address + Ünvanı axtarmaq və ya daxil etmək + + + + DFMAdvanceSearchBar + + + Search: + Axtarış: + + + + File Type: + Fayl Növü: + + + + File Size: + Fayl Ölçüsü: + + + + Time Modified: + Dəyişilmə Vaxtı: + + + + Time Accessed: + İstifadə Vaxtı: + + + + Time Created: + Yaradılma Vaxtı: + + + + Reset + Sıfırlamaq + + + + All subdirectories + Bütün alt qovluqlar + + + + Current directory + Cari qovluq + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 QB + + + + > 1 GB + > 1 QB + + + + Today + Bu gün + + + + Yesterday + Sabah + + + + This week + Bu həftə + + + + Last week + Keçən həftə + + + + This month + Bu ay + + + + Last month + Keçən ay + + + + This year + Bu il + + + + Last year + Keçən il + + + + DFMOpticalMediaWidget + + + + No files to burn + Yazmaq üçün fayl yoxdur + + + + Unable to burn. Not enough free space on the target disk. + Yazmaq mümkün olmadı. Hədəf diskində kifayət qədər boş yer yoxdur. + + + + %1 burning is not supported + %1, diskə yazmanı dəstəkləmir + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. Bu %1 diski deyil; +2. Bu fayl sisteminin versiyası hələlik fayl əlavə edilməsini dəstəkləmir. + + + + DFMTagCrumbController + + + Tag information + Etiket məlumatları + + + + DFMTagWidget + + + Tag + Etiket + + + + DFMTaskWidget + + + Do not ask again + Yenidən soruşmamaq + + + + Syncing data + Verilərin eyniləşdirilməsi + + + + Please wait + Lütfən gözləyin + + + + + Time modified: %1 + Dəyişilmə vaxtı: %1 + + + + + Contains: %1 + Tərkibləri: %1 + + + + + Size: %1 + Ölçüsü: %1 + + + + Original folder + Orijinal qovluq + + + + Keep both + button + Hər ikisini saxlamaq + + + + Skip + button + Ötürmək + + + + Replace + button + Əvəzləmək + + + + Retry + button + Təkrar + + + + Original file + Orijinal fayl + + + + Target folder + Hədəf qovluğu + + + + Target file + Hədəf faylı + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Fayl seyfini şifrələmək + + + + Click 'Encrypt' and input the user password. + "Şifrələmək" vurun və şifrəni daxil edin + + + + Encrypting... + Şifrələnir... + + + + + + + Encrypt + Şifrələmək + + + + Failed to create file vault: %1 + Fayl seyfi yaradılması alınmadı: %1 + + + + OK + OK + + + + The setup is complete + Quraşdırma başa çatdı + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Bərpaetmə açarını saxlayın + + + + Keep the key safe to retrieve the vault password later + Seyfin şifrəsini sonradan əldə etmək üçün onu təhlükəsiz yerdə saxlayın + + + + Save to default path + İlkin yolu saxlayın + + + + Save to other locations + Başqa yerdə saxlayın + + + + No permission, please reselect + İcazə yoxdur, lütfən təkrar seçin + + + + Select a path + Yol seçin + + + + Next + Növbəti + + + + The default path is invisible to other users, and the path information will not be shown. + İlkin yol başqa istifadəçilər üçün görünmür və yol haqqında məlumat görünə bilməz. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Bərpaetmə açarı + + + + Generate a recovery key in case that you forgot the password + Unudulacaq şirənin bərpası üçün bir bərpa açarı yaradın + + + + Key + Açar + + + + QR code + QR kodu + + + + Scan QR code and save the key to another device + QR kodu oxudun və açarı başqa cihazda saxlayın + + + + Next + Növbəti + + + + Recovery Key: + Bərpa Açarı: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Seyfin açarını təyin edin + + + + Method + Üsul + + + + Manual + Əl ilə + + + + Password + Şifrə + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 simvollar, A-Z, a-z, 0-9 və simvollardan ibarət + + + + Repeat password + Şifrənin təkrarı + + + + Input the password again + Şifrəni yenidən daxil edin + + + + Password hint + Şifrə ipucu + + + + Optional + İxtiyari + + + + Next + Növbəti + + + + + Passwords do not match + Şifrələr oxşar deyil + + + + DFMVaultActiveStartView + + + File Vault + Fayl seyfi + + + + Create your secure private space + Təhlükəsiz məxfi sahənizi yaradın + + + + Advanced encryption technology + Təkmil şifrələmə texnologiyası + + + + Convenient and easy to use + İstifadə üçün əlverişli və asan + + + + Create + Yaratmaq + + + + DFMVaultFileView + + + Cannot open this path + Bu fayl açıla bilmir + + + + Hint + İpucu + + + + OK + OK + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Açar ilə kilidləmək + + + + Failed to unlock file vault + Fayl seyfini kilidləmək alınmadı + + + + OK + OK + + + + Input the 32-digit recovery key + 32-rəqəmli bərpa açarını daxil edin + + + + Cancel + button + İmtina + + + + Unlock + button + Kilidləmək + + + + Wrong recovery key + Səhv bərpa açarı + + + + DFMVaultRemoveByPasswordView + + + Password + Şifrə + + + + Password hint: %1 + Şifrə ipucu: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + 32-rəqəmli bərpa açarını daxil edin + + + + DFMVaultRemovePages + + + Delete File Vault + Fayl seyfini silmək + + + + Once deleted, the files in it will be permanently deleted + Silidikdən sonra daxilindəki fayllar həmişəlik itiriləcəkdir + + + + Use Key + Açar istifadə edin + + + + Cancel + button + İmtina + + + + Use Key + button + Açar istifadə edin + + + + Delete + button + Silmək + + + + + OK + button + OK + + + + Use Password + Şifrə istifadə etmək + + + + Wrong password + Səhv şifrə + + + + Wrong recovery key + Səhv bərpa açarı + + + + Failed to delete file vault + Fayl seyfinin silinməsi alınmadı + + + + Deleted successfully + Uğurla silindi + + + + Failed to delete + Silmək alınmadı + + + + Removing... + Silinir... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + Açar faylını almaq mümkün deyil + + + + Verification failed + Doğrulanma alınmadı + + + + + Select a path + Yol seçin + + + + + Retrieve Password + Şifrəni əldə edin + + + + By key in the default path + İlkin yoldakı açarla + + + + By key in the specified path + Göstərilmiş yoldakı açar ilə + + + + Verification Successful + Doğrulama uğurlu oldu + + + + Keep it safe + Təhlükəsiz saxlayın + + + + Back + button + Geriyə + + + + Verify Key + button + Doğrulama açarı + + + + Go to Unlock + button + Kilidi açmağa keçin + + + + Close + button + Bağlamaq + + + + Vault password: %1 + Seyfin şifrəsi: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Fayl seyfini kiliddən çıxarmaq + + + + Forgot password? + Şifrəni unutmusunuz? + + + + Password hint: %1 + Şifrə ipucu: %1 + + + + Failed to unlock file vault + Fayl seyfini kilidləmək alınmadı + + + + Cancel + button + İmtina + + + + Password + Şifrə + + + + Unlock + button + Kilidləmək + + + + Please try again %1 minutes later + %1 dəqiqə sonra yenidən cəhd edin + + + + Wrong password, please try again %1 minutes later + Şifrə səhvdir, %1 dəqiqədən sonra yenidən cəhd edin + + + + Wrong password, one chance left + Şifrə səhvdir, bir cəhdiniz qaldı + + + + Wrong password, %1 chances left + Şifrə səhvdir, %1 cəhdiniz qaldı + + + + Wrong password + Səhv şifrə + + + + OK + button + OK + + + + DFileCopyMoveJob + + + Permission error + İcazə xətası + + + + The action is denied + Əməliyyata icazə verilmədi + + + + Failed to open the file + Fayl açıla bilmədi + + + + Failed to read the file + Fayl oxuna bilmədi + + + + Failed to write the file + Fayl yazıla bilmədi + + + + Failed to create the directory + Qovluq yaradıla bilmədi + + + + Failed to delete the file + Fayl silinə bilmədi + + + + Failed to move the file + Faylı köçürmək alınmadı + + + + Original file does not exist + faylın əsli mövcud deyil + + + + Failed, file size must be less than 4GB + Alınmadı, fayl 4QB-dan az olmalıdır + + + + Not enough free space on the target disk + Hədəf diskində kifayət qədər boş yer yoxdur + + + + File integrity was damaged + Faylın bütövlüyü pozulub + + + + The target device is read only + Hədəf cihaz yalnız oxumaq üçündür + + + + Target folder is inside the source folder + Hədəf qovluq mənbə qovluğunun daxilindədir + + + + The action is not supported + Bu əməl dəstəklənmir + + + + You do not have permission to traverse files in it + Onun daxilindəki fayllara keçid etməyə icazəniz yoxdur + + + + Failed to position the file pointer! + Fayl göstəricisini yerləşdirməl alınmadı! + + + + copy + Extra name added to new file name when used for file name. + kopyalamaq + + + + Failed to open the directory, cause: file name too long + Qovluq açıla bilmədi, səbəb: fayl adı çox uzundur + + + + + Failed to open the file, cause: file name too long + Fayl açıla bilmədi, səbəb: fayl adı çox uzundur + + + + + Failed to write the file, cause: + Fayl yazıla bilmədi, səbəb: + + + + Failed to position the file pointer, cause: %1 + Fayl göstəricisini yerləşdirmək alınmadı, səbəb: %1 + + + + Syncing data + Verilərin eyniləşdirilməsi + + + + Please wait + Lütfən gözləyin + + + + Failed to create the directory, cause: %1 + Qovluq yaradıla bilmədi, səbəb: %1 + + + + + + + + Failed to open the file, cause: %1 + Fayl açıla bilmıdi, səbəb: %1 + + + + + + + Failed to open the file, cause: Permission denied + Fayl açıla bilmədi, səbəb: İcazə verilmədi + + + + + Failed to read the file, cause: %1 + Fayl oxuna bilmədi, səbəbi: %1 + + + + + + + Failed to write the file, cause: %1 + Fayl yazıla bilmədi, səbəbi: %1 + + + + + File integrity was damaged, cause: %1 + Faylın bütövlüyü pozulub, səbəbi: %1 + + + + Failed to open the file, cause: + Fayl açıla bilmədi, səbəbi: + + + + Failed to read the file, cause: + Fayl oxuna bilmədi, səbəbi: + + + + Failed to delete the file, cause: %1 + Fayl silinə bilmədi, səbəbi: %1 + + + + Fail to create symlink, cause: %1 + Simvolik keçid yaradıla bilmədi, səbəbi: %1 + + + + DFileDialog + + + + Save + button + Saxlamaq + + + + + Cancel + button + İmtina + + + + Confirm + button + Tədiqləmək + + + + %1 already exists, do you want to replace it? + %1 artıq var, onu əvəzləmək istəyirsiniz? + + + + Replace + button + Əvəzləmək + + + + Open + button + Açmaq + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Adı nöqtə (.) ilə başlayan fayl gizlədiləcəkdir. Gizlətmək istəyirsiniz? + + + + DFileManagerWindow + + + Trash + Səbət + + + + Empty + Boş + + + + DFileSystemModel + + + + Name + Ad + + + + + + Time modified + Dəyişilmə Vaxtı + + + + Size + Ölçüsü + + + + Type + Növ + + + + Time created + Yaradılma Vaxtı + + + + + Last access + Sonuncu giriş + + + + + + + Path + Yol + + + + DFileView + + + Disc mount error + Diskin qoşulmasında xəta + + + + The disc is in use, please end the running process and remount the disc. + Disk istifadə olunur, lütfən işlək prosesləri sonlandırın və diski yenidən qoşun. + + + + Mounting failed + Qoşulma alınmadı + + + + (Reverse) + (Əksinə) + + + + DFileViewHelper + + + Add tag "%1" + "%1" etiketi əlavə edin + + + + DStatusBar + + + %1 item + %1 element + + + + %1 items + %1 element + + + + %1 item selected + %1 element seçildi + + + + %1 items selected + %1 element seçildi + + + + %1 folder selected (contains %2) + %1 qovluq seçildi (tərkibi %2) + + + + %1 folders selected (contains %2) + %1 qovluq seçildi (tərkibi %2) + + + + %1 file selected (%2) + %1 fayl seçildi (%2) + + + + %1 files selected (%2) + %1 fayl seçildi (%2) + + + + %1 folder selected + %1 qovluq seçildi + + + + Filter + Süzgəc + + + + Save as: + Belə saxlayın: + + + + Loading... + Yüklənir... + + + + DTaskDialog + + + Erasing disc %1, please wait... + %1 disk çıxarılır, lütfən gözləyin... + + + + Burning disc %1, please wait... + %1 disk yazılır, lütfən gözləyin... + + + + Writing data... + Verilənlər yazılır... + + + + Verifying data... + Verilənlər yoxlanılır... + + + + Copying %1 + %1 kopyalanır + + + + + + to %2 + %2 üzərinə + + + + %1 already exists in target folder + Hədəf qovluğunda artıq %1 mövcuddur + + + + Original path %1 Target path %2 + Orijinal yol %1 Hədəf yol %2 + + + + Merge + button + Birləşdirmək + + + + Replace + button + Əvəzləmək + + + + Moving %1 + %1 köçürülür + + + + Removing file vault, please try later + fayl seyfi silinir, lütfən gözləyin + + + + Restoring %1 + %1 bərpa olunur + + + + Deleting %1 + %1 silinir + + + + Trashing %1 + %1 təmizlənir + + + + Calculating space, please wait + Sahə hesablanır, lütfən gözləyin + + + + DUMountManager + + + + Authentication timed out + Doğrulama vaxtı bitdi + + + + + + Disk is busy, cannot unmount now + Disk məşğuldur, indi ayrıla bilməz + + + + Disk is busy, cannot eject now + Disk məşğuldur, indi çıxarıla bilməz + + + + The device is busy, cannot eject now + Cihaz məşğuldur, indi çıxarıla bilməz + + + + + + The device is busy, cannot remove now + Cihaz məşğuldur, indi ayrıla bilməz + + + + DeepinStorage + + + + + %1 Volume + %1 disk tutumu + + + + Data Disk + Data Partition + Verilənlər Diski + + + + %1 Drive + %1 sürücü + + + + Blank %1 Disc + Boş %1 disk + + + + %1 Encrypted + %1 şifrələnib + + + + DialogManager + + + + + + Operation failed! + Əməliyyat baş tutmadı! + + + + Target folder is inside the source folder! + Hədəf qovluğu mənbə qovluğu daxilindədir! + + + + Do you want to run %1 or display its content? + %1 başlatmaq, yoxsa tərkiblərini göstərmək istəyirsiniz? + + + + It is an executable text file. + Bu icra faylıdır. + + + + It is an executable file. + Bu icra faylıdır. + + + + This file is not executable, do you want to add the execute permission and run? + Bu icra faylı deyil, ona icraedilmə icazəsi əlavə etmək və başlatmaq istəyirsiniz? + + + + "%1" already exists, please use another name. + "%1" artıq mövcuddur, lütfən başqa ad seçin. + + + + The file name must not contain two dots (..) + Fayl adı iki nöqtədən (..) ibarət olmamalıdır + + + + Device or resource busy + + + + + Are you sure you want to erase all data on the disc? + Disdəki bütün məlumatları silmək istədiyinizə əminsiniz? + + + + How do you want to use this disc? + Bu diski necə istifadə etmək istəyirsiniz? + + + + Disc erase failed + Disk silinə bilmədi + + + + Burn process failed + Yazılma əməliyyatı baş tutmadı + + + + %1: %2 + %1: %2 + + + + Show details + Təfərrüatları göstərmək + + + + Hide details + Təfərrüatları gizlətmək + + + + Error + Xəta + + + + Permanently delete %1? + %1 həmişəlik silinsin? + + + + Permanently delete %1 items? + %1 element həmişəlik silinsin? + + + + Empty + Boş + + + + Do you want to delete %1? + %1 silmək istəyirsiniz + + + + Do you want to delete the selected %1 items? + Seçilmiş %1 elementi silmək istəyirsiniz? + + + + Sorry, unable to locate your bookmark directory, remove it? + Təəsüf ki, əlfəcinlər qovluğu tapılmadı, o silinsin? + + + + Name: + Adı: + + + + %1 that this shortcut refers to has been changed or moved + %1 qısayolu dəyişdirilmiş və ya silinmiş obyektə aiddir + + + + Do you want to delete this shortcut? + Bu qısayolu silmək istəyirsiniz? + + + + Failed, file size must be less than 4GB. + Alınmadı, fayl ölçüsü 4QB-dan az olmalıdır. + + + + Fail to create symlink, cause: + Simvolik keçid yaradıla bilmədi, səbəbi: + + + + The selected files contain system file/directory, and it cannot be deleted + Seçilmiş fayl fayldan/qovluqdan ibarətdir və silinə bilməz + + + + Unable to find the original file + Orijinal faylı tapmaq mümkün olmadı + + + + + You do not have permission to operate file/folder! + Fayı və ya qovluq ilə işləməyə icazəniz yoxdur! + + + + Failed to restore %1 file, the source file does not exist + %1 faylın bərpası alınmadı, mənbə faylı mövcud deyil + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Aşağıdakı %1 fayl/qovluq(lar) ilə işləməyə icazəniz yoxdur! + + + + Unable to access %1 + %1 daxil olmaq mümkün olmadı + + + + + Sending files now, please try later + Fayllar indi göndərilir, lütfən sonra cəhd edin + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Cihaza daxil olmaq üçün öncə onu format etməlisiniz. Onu format etmək istədiyinizə əminsiniz? + + + + Scanning the device, stop it? + Cihazlar aşkarlanır, dayandırılsın? + + + + Share folder can't be named after the current username + Paylaşma qovluğu cari istifadəçi adından sonra adlandırıla bilməz + + + + Do you want to run %1? + %1 başlatmaq istəyirsiniz? + + + + Burn image + button + Disk surəti yazmaq + + + + Burn files + button + Fayllar yazmaq + + + + Are you sure you want to empty %1 item? + %1 elementi təmizləmək istədiyinizə əminsiniz? + + + + Are you sure you want to empty %1 items? + %1 elementi təmizləmək istədiyinizə əminsiniz? + + + + + This action cannot be undone + Bu əməl ləğv edilə bilməz + + + + + + + + + + + + + + OK + button + OK + + + + + + + + + + + + + + + Cancel + button + İmtina + + + + + + Run + button + Başlatmaq + + + + + Run in terminal + button + Terminalda başlatmaq + + + + Display + button + Ekran + + + + + + + + + + + Confirm + button + Tədiqləmək + + + + Erase + button + Silmək + + + + Data verification failed + Verilənlərin doğrulanması alınmadı + + + + Show details + button + Təfərrüatları göstərmək + + + + + Delete + button + Silmək + + + + Remove + button + Silmək + + + + Disk is busy, cannot unmount now + Disk məşğuldur, indi ayrıla bilməz + + + + Force unmount + button + Məvburi ayırmaq + + + + Unable to copy. Not enough free space on the target disk. + Kopyalamaq mümkün olmadı. Hədəf diskində kifayıt qədər yer yoxdur. + + + + Failed to restore %1 file, the target folder is read-only + %1 faylın bərpası baş tutmadı, hədəf qovluq yalnız oxumaq üçündür + + + + Failed to restore %1 files, the target folder is read-only + %1 faylın bərpası baş tutmadı, hədəf qovluq yalnız oxumaq üçündür + + + + Failed to restore %1 files, the source files do not exist + %1 faylın bərpası alınmadı, mənbə faylları mövcud deyil + + + + Format + button + Formatlamaq + + + + Stop + button + Dayandırmaq + + + + FileController + + + + + + Unable to find the original file + Orijinal faylı tapmaq mümkün olmadı + + + + + + Kindly Reminder + Lütfən xatırlat + + + + + + Please install File Roller first and then continue + Lütfən öncə File Roller quraşdırın və sonra davam edin + + + + + Unable to create files here: %1 + Burada fayıllar yaratmaq mümkün olmadı: %1 + + + + Confirm + button + Tədiqləmək + + + + FileDialogStatusBar + + + File Name + Fayl Adı + + + + Format + Formatlamaq + + + + Save + button + Saxlamaq + + + + Open + button + Açmaq + + + + Save File + button + Faylı saxlamaq + + + + Open File + button + Faylı açmaq + + + + + + Cancel + button + İmtina + + + + FileJob + + + copy + kopyalamaq + + + + + + + Data verification successful. + Verilənlər uğurla doğrulandı + + + + + + Burn process completed + Yazma əməliyyatı başa çatdı + + + + %1 s + %1 san + + + + %1 m %2 s + %1 dəq %2 san + + + + %1 h %2 m %3 s + %1 saat %2 dəq %3 san + + + + %1 d %2 h %3 m %4 s + %1 gün %2 saat %3 dəq %4 san + + + + %1 is a duplicate file. + %1 təkrarlanan fayldır. + + + + Insufficient disc space. + Disk sahəsi kifayət deyil. + + + + Lost connection to drive. + Sürücü ilə bağlantı itirildi + + + + The CD/DVD drive is not ready. Try another disc. + CD/DVD sürücüsü hazır deyil. Başqa diski yoxlayın. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + CD/DVD sürücüsü məşquldur,Sürücün istifadə edən tətbiqdən çıxın və diski yenidən daxil edin. + + + + Unknown error + Naməlum xəta + + + + Device disconnected + Cihaz ayrıldı + + + + GenerateSettingTranslate + + + + + Basic + Əsas + + + + + + Open behavior + Açılış əməli + + + + + + Always open folder in new window + Qovluğu həmişə yeni pəncərədə açmaq + + + + + + Open file: + Faylı açmaq: + + + + + + Click + Klik + + + + + + Double click + Cüt klik + + + + + + New window and tab + Yeni pəncərə və vərəq + + + + + + Open from default window: + Standart pəncərədən açmaq: + + + + + + + + + Computer + Kompyuter + + + + + + + + + Home + Ev + + + + + + + + + Desktop + İş Masası + + + + + + + + + Videos + Videolar + + + + + + + + + Music + Musiqilər + + + + + + + + + Pictures + Şəkillər + + + + + + + + + Documents + Sənədlər + + + + + + + + + Downloads + Endirmələr + + + + + + Open in new tab: + Yeni vərəqdə açmaq: + + + + + + Current Directory + Cari qovluq + + + + + + View + Baxış + + + + + + Default size: + Standart ölçü: + + + + + + Extra small + Çox kiçik + + + + + + Small + Kiçik + + + + + + Medium + Orta + + + + + + Large + Geniş + + + + + + Extra large + Çox böyük + + + + + + Default view: + Standart baxış: + + + + + + Icon + Nişan + + + + + + List + Siyahı + + + + + + Hidden files + Gizli fayllar + + + + + + Show hidden files + Gizli faylları göstərmək + + + + + + Hide file extension when rename + Adı dəyişdirilən zaman uzantını göstərmək + + + + + + Advanced + Təkmil + + + + + + Index + İndeksləmə + + + + + + Auto index internal disk + Daxili diskin avtomatik indeklənməsi + + + + + + Index external storage device after connected to computer + Kompyuterə qoşulduqdan sonra xarici yaddaş cihazının avtomatik indekslənməsi + + + + + + Full-Text search + Tam mətnli axtarışı + + + + + + Show item counts and sizes in the path of mounted MTP devices + Qoşulmuş MTP cihazları yolunda elementlərin sayı və ölçüsü göstərilsin + + + + + + Keep showing the mounted Samba shares + Quraşdırılmış Samba paylaşımlarını göstərməyə davam edin + + + + + + Use the file chooser dialog of File Manager + Fayl Menecerin seçim dialoqunu istifadə etmək + + + + + + Ask for my confirmation when deleting files + Fayllar silinən zaman mənim təsdiqləməmi soruşmaq + + + + + + Other + Digər + + + + + + Hide system disk + Sistem diskini gizlətmək + + + + + + Show file system on disk icon + Disk nişanında fayl sistemini göstərmək + + + + + + Show hidden files in search results + Axtarış nəticələrində gizli faylları göstərmək + + + + + + Display recent file entry in left panel + Sol paneldə sonucu açılan faylları gıstərmək + + + + + + Preview + Öncədən baxış + + + + + Compress file preview + Sıxılan fayllara öncədən baxış + + + + + + Text preview + Mətnə öncədən baxış + + + + + + Document preview + Sənədə öncədən baxış + + + + + + Image preview + Şəkilə öncədən baxış + + + + + + Video preview + Videoya öncədən baxış + + + + + + Mount + Qöşmaq + + + + + + Auto mount + Avtomatik qoşulma + + + + + + Open after auto mount + Avtomatik qoşulmadan sonra açmaq + + + + + + Dialog + Dialoq + + + + Compressed file preview + Sıxılmış fayllara öncədən baxış + + + + GvfsMountManager + + + Can’t verify the identity of %1. + %1 kimliyi doğrulana bilmir. + + + + This happens when you log in to a computer the first time. + Bu, siz kompyuterə ilk dəfə daxil olduğunuz zaman baş verir + + + + The identity sent by the remote computer is + Uzaq kompyuter tərəfindən göndərilən kimlik + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Davam etmənin təhlükəsiz olduğundan tamamilə əmin olmaq istəyirsinizsə, sistem administratoru ilə əlaqə saxlayın. + + + + + + + + Mounting device error + Cihazın qoşulması xətası + + + + + Wrong username or password + Səhv istifadəçi adı və şifrəsi + + + + + + + + Confirm + button + Tədiqləmək + + + + + Cannot find the mounted device + Qoşulmuş cihazı tapmaq olmur + + + + No key available to unlock device + Cihazı kiliddən çıxarmaq üçün mövcud açar yoxdur + + + + The disk is mounted by user "%1", you cannot unmount it. + Disk "%1" istifadəçisi tərəfindən qoşulub, siz onu ayıra bilməzsiniz. + + + + Cannot unmount the device + Cihazı ayırmaq mümkün deyil + + + + Cannot eject the device "%1" + "%1" cihazı çıxarıla bilmir + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Yazmaq mümkün olmadı. Hədəf diskində kifayət qədər boş yer yoxdur. + + + + MergedDesktopController + + + + Pictures + Şəkillər + + + + + Music + Musiqilər + + + + + Applications + Tətbiqlər + + + + + Videos + Videolar + + + + + Documents + ənədlər + + + + + Others + Digəriləri + + + + MimeTypeDisplayManager + + + + Directory + Qovluq + + + + + + Application + Tətbiq + + + + + + Video + Video + + + + + + Audio + Səs + + + + + + Image + Şəkil + + + + + Archive + Arxiv + + + + + + Text + Mətn + + + + + Executable + İcra ediləbilən + + + + + Backup file + Ehtiyyat Nüsxə + + + + + Unknown + Naməlum + + + + MountAskPasswordDialog + + + Cancel + button + İmtina + + + + Connect + button + Bağlantı + + + + Log in as + Belə daxil olmaq + + + + Anonymous + Anonim + + + + Registered user + Qeydiyyatdan keçmiş istifadəçi + + + + Username + stifadəçi adı + + + + Domain + Domen + + + + Password + Şifrə + + + + Remember password + Şifrəni xatırlamaq + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + İmtina + + + + Unlock + button + Kilidləmək + + + + Input password to decrypt the disk + Diskin şifrəsini açmaq üçün şifrəni daxil edin + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + %1 həmişəlik silmək istədiyinizə əminsiniz? + + + + This file is too big for the trash + Bu fayl səbət üçün çox böyükdür + + + + The files are too big for the trash + Bu fayllar səbət üçün çox böyükdür + + + + Are you sure you want to permanently delete %1 files? + %1 faylı həmişəlik silmək istədiyinizə əminsiniz? + + + + Cancel + button + İmtina + + + + Delete + button + Silmək + + + + OpenWithDialog + + + Open with + Bununla açmaq + + + + Add other programs + Başqa tətbiq əlavə etmək + + + + Set as default + Standart olaraq təyin etmək + + + + Cancel + button + İmtina + + + + Confirm + button + Tədiqləmək + + + + Recommended Applications + Tövsiyyə olunan Tətbiqlər + + + + Other Applications + Digər Tətbiqlər + + + + PathManager + + + Home + Ev + + + + Desktop + İş Masası + + + + Videos + Videolar + + + + Music + Musiqilər + + + + Pictures + Şəkillər + + + + Documents + ənədlər + + + + Downloads + Endirmələr + + + + + Trash + Səbət + + + + + + System Disk + Sistem diski + + + + Computers in LAN + LAN-dakı kompyuterlər + + + + My Shares + Mənim Paylaşımlarım + + + + Computer + Kompyuter + + + + Recent + Sonuncu + + + + File Vault + Fayl seyfi + + + + PropertyDialog + + + Basic info + Əsas məlumatlar + + + + Open with + Bununla açmaq + + + + Sharing + Paylaşım + + + + Permissions + İcazələr + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Bu qovluğu gizlətmək + + + + Hide this file + Bu faylı gizlətmək + + + + Allow to execute as program + Tətbiq kimi icra etmək + + + + QObject + + + + + + Size + Ölçüsü + + + + + + Contains + Tərkibləri + + + + + + Type + Növ + + + + + + + + Time modified + Dəyişilmə Vaxtı: + + + + Free space + Boş sahə + + + + Total space + Ümumi sahə + + + + + Time locked + Kilidlənmə vaxtı + + + + Access denied + İcazə rədd edildi + + + + + Executable + İcra edilə bilən + + + + + Write only + Yalnız yazmaq + + + + + Read only + Yalnız oxumaq + + + + + Read-write + Yazmaq-oxumaq + + + + Others + Digəriləri + + + + Owner + Sahibi + + + + Unconnected network shared directory + Şəbəkəsiz paylaşım qovluğu + + + + Device type + Cihaz növü + + + + File system + Fayl sistemi + + + + Group + Qrup + + + + + Open + Açmaq + + + + Lock + Kilidləmək + + + + Auto lock + Avtomatik kilidlənmə + + + + Never + Heç vaxt + + + + 5 minutes + 5 dəqiqə + + + + 10 minutes + 10 dəqiqə + + + + 20 minutes + 20 dəqiqə + + + + Delete File Vault + Fayl seyfini silmək + + + + Unlock + Kilidləmək + + + + Unlock by key + Açar ilə kilidləmək + + + + Open + button + Açmaq + + + + + Size: %1 + Ölçüsü: %1 + + + + Type: %1 + Növü: %1 + + + + Size: 0 + Ölçüsü: 0 + + + + Items: %1 + ELementlər: %1 + + + + + + + + + + Open in new window + Yeni pəncərədə açmaq + + + + + + + + + + Open in new tab + Yeni vərəqdə açmaq + + + + Open with + Bununla açmaq + + + + + Compress + Sıxmaq + + + + Extract + Çıxartmaq + + + + Extract here + Buraya çıxartmaq + + + + Cut + Kəsmək + + + + Copy + Kopyalamaq + + + + Paste + Yerləşdirmək + + + + + + + + Rename + Yenidən adlandırmaq + + + + + + + Remove + Silmək + + + + Create link + Keçid yaratmaq + + + + Send to desktop + İş masasına göndərmək + + + + Send to + Buraya göndərmək + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Əlfəcinə əlavə etmək + + + + + + + Properties + Tərcihlər + + + + New folder + Yeni qovluq + + + + New window + Yeni pəncərə + + + + Select all + Hamısını seçmək + + + + + Clear recent history + Əvvəlki tarixçəni silmək + + + + + + Empty Trash + Səbəti boşaltmaq + + + + Display as + Belə göstərmək + + + + Sort by + Çeşidləmə sırası + + + + New document + Yeni sənəd + + + + + Time created + Yaradılma Vaxtı + + + + + + Source path + Mənbə yolu + + + + Share folder + Qovluğu paylaşmaq + + + + Cancel sharing + Paylaşımı ləğv etmək + + + + Connect to Server + Serverə bağlantı + + + + Set share password + Paylaşım şifrəsi təyin etmək + + + + Format + Format + + + + Tag information + Etiket məlumatları + + + + Open as administrator + İnzibatçı kimi açın + + + + Select default program + Standart tətbiqi seçmək + + + + Open file location + Fayl yerini açmaq + + + + Remove bookmark + Əlfəcini silmək + + + + + + Delete + Silmək + + + + Office Text + Ofis mətni + + + + Spreadsheets + Hesablama Cədvəli + + + + Plain Text + Sadə mətn + + + + Open in terminal + Terminalda açmaq + + + + Restore + Bərpa etmək + + + + Restore all + Hamısını bərpa etmək + + + + Clear saved password and unmount + Saxlanılmış şifrələri təmizləyin və ayırın + + + + File Vault + Fayl seyfi + + + + Add to disc + Diskə əlavə etmək + + + + Refresh + + + + + Auto mount + A + + + + Open after auto mount + Avtomatik qoşulmadan sonra açmaq + + + + + Mount + Qöşmaq + + + + + Unmount + Ayırmaq + + + + It does not support burning %1 discs + Bu %1 diskin yazılmasını dəstəkləmir + + + + Burn + Yazmaq + + + + Disc name: + Disk adı: + + + + + Maximum + Ən çox + + + + Allow files to be added later + Faylların sonra əlavə olunmasına icazə vermək + + + + Verify data + Verilənləri doğrulamaq + + + + Write speed: + Yazma sürəti: + + + + + + + Cancel + button + İmtina + + + + Burn + button + Yazmaq + + + + + Eject + Çıxartmaq + + + + Safely Remove + Təhlükəsiz çıxartmaq + + + + + Name + Ad + + + + Settings + Ayarlar + + + + Exit + Çıxmaq + + + + Icon + Nişan + + + + List + Siyahı + + + + Extend + Genişləndirmək + + + + Set as wallpaper + Divar kağızı kimi təyin etmək + + + + + + + Local disk + Yerli disk + + + + + Removable disk + Çıxarılabilən disk + + + + + + Network shared directory + Şəbəkədə paylaşılan qovluq + + + + + Android mobile device + Android mobil cihazı + + + + + Apple mobile device + Apple mobil cihazı + + + + + Camera + Kamera + + + + + DVD + DVD + + + + + Unknown device + Naməlim cihaz + + + + + + %1 item + %1 element + + + + + + %1 items + %1 element + + + + Shortcut + Qısayol + + + + Create symlink + Simvolik keçid yaratmaq + + + + Path + Yol + + + + + + Time deleted + Silinmə vaxtı + + + + Loading... + Yüklənir... + + + + File has been moved or deleted + Fayl silinib və ya köçürülüb + + + + You do not have permission to traverse files in it + Onun daxilindəki fayllara keçid etməyə icazəniz yoxdur + + + + + + You do not have permission to access this folder + Bu qovluğa girməniz üçün icazəniz yoxdur + + + + + + + + Folder is empty + Qovluq boşdur + + + + Searching... + Axtarış... + + + + No results + Nəticə yoxdur + + + + Source Path + TrashFileInfo + Mənbə yolu + + + + Document + Sənəd + + + + Spreadsheet + Hesablama Cədvəli + + + + + Presentation + Təqdimat + + + + Text + Mətn + + + + 1 task in progress + 1 tapşırıq icra olunur + + + + %1 tasks in progress + %1 tapşırıq icra olunur + + + + Mode: + Rejim: + + + + + Replace Text + Mətni əvəzləmək + + + + + Add Text + Mətn əlvə etmək + + + + + Custom Text + İstifadəçi mətni + + + + Find: + Tapmaq: + + + + Replace: + Əvəzləmək: + + + + + Optional + İxtiyari + + + + Add: + Əlavə etmək: + + + + Location: + Yer: + + + + File name: + Fayl adı: + + + + Start at: + Başlatmaq: + + + + + Rename + button + Yenidən adlandırmaq + + + + + + + + + + + Required + Tələb olunan + + + + + Before file name + Fayl adından əvvəl + + + + + After file name + Fayl adından sonra + + + + Find + Tapmaq + + + + Replace + Əvəzləmək + + + + Add + Əlavə etmək + + + + Start at + Başlatmaq + + + + + + Location + Yer + + + + File name + Fayl adı + + + + Dimension + Ölçü + + + + Duration + Müddət + + + + Tips: Sort by selected file order + Məsləhət: Seçilmiş fayl sırasına gırə çeşidləmək + + + + Rename %1 Files + %1 faylın adını dəyişmək + + + + Multiple Files + Çoxsaylı fayllar + + + + Basic info + Əsas məlumatlar + + + + Total size + Ümumi ölçü + + + + Number of files + Faylların sayı + + + + %1 file(s), %2 folder(s) + %1 fayl(lar), %2 qovluq(lar) + + + + + + Time accessed + İstifadə Vaxtı + + + + Orange + Narıncı + + + + Red + Qırmızı + + + + Purple + Cəhrayı + + + + Navy-blue + Tünd göy + + + + Azure + Lacivərd + + + + Green + Yaşıl + + + + Yellow + Sarı + + + + Gray + Boz + + + + Input tag info, such as work, family. A comma is used between two tags. + Yarlıq üçün məlumat daxil edin, məs., iş, ailə. İki yarlığı ayırmaq üçün vergül istifadə edin + + + + Bookmarks + Əlfəcinlər + + + + Erase + Silmək + + + + Copy path + Yolu kopyalamaq + + + + Edit address + Ünvanlara düzəliş + + + + Free Space %1 + %1 boş sahə + + + + Files are being processed + Fayllar işlənir + + + + + Unknown + Naməlum + + + + My Vault + Mənim seyfim + + + + + Failed to create file info + Fayl haqqında məlumat yaradıla bilmədi + + + + Failed to create file handler + Fayl işlədicisi yaradıla bilmədi + + + + Failed to open the file, cause: %1 + Fayl açıla bilmıdi, səbəb: %1 + + + + Original file does not exist + faylın əsli mövcud deyil + + + + Do you want to delete %1? + %1 silmək istəyirsiniz + + + + Confirm + button + Tədiqləmək + + + + + + + + %1 are not allowed + %1 icazə verilmir + + + + + Failed to start Samba services + Samba servisi başladıla bilmədi + + + + RecentController + + + Cancel + button + İmtina + + + + Remove + button + Silmək + + + + Do you want to remove this item? + Bu elementi silmək istıyirsiniz? + + + + Do yout want to remove %1 items? + %1 elementi silmək istəyirsiniz? + + + + It does not delete the original files + Bu, orijinal faylları silmir + + + + ShareInfoFrame + + + Share this folder + Bu qovluğu paylaşmaq + + + + Share name: + Paylaşım adı: + + + + Permission: + İcazə: + + + + Read and write + Yazmaq və oxumaq + + + + Read only + Yalnız oxumaq + + + + Anonymous: + Anonim: + + + + Not allow + İcazə verilmir + + + + Allow + İcazə verilir + + + + The share name must not be two dots (..) or one dot (.) + Bu paylaşım adı iki nöqtədən (..) və ya bir nöqtədən (.) ibarət olmamalıdır + + + + The share name is used by another user. + Paylaşım adı digər istifadəçi tərəfindən istifadə olunur. + + + + OK + button + OK + + + + Cancel + button + İmtina + + + + Replace + button + Əvəzləmək + + + + The share name already exists. Do you want to replace the shared folder? + Paylaşım adı artıq mövcuddur. Paylaşılan qovluğu əvəzləmək istəyirsiniz? + + + + Shortcut + + + Item + Element + + + + Select to the first item + Birinci elementi seçin + + + + Shift + Home + Shift + Home + + + + Select to the last item + Sonuncu elementi seçin + + + + Shift + End + Shift + End + + + + Select leftwards + Sola seçim + + + + Shift + Left + Shift + Sola ox + + + + Select rightwards + Sağa seçim + + + + Shift + Right + Shift + Sağa ox + + + + Select to upper row + Yuxarıdakı sətiri seçin + + + + Shift + Up + Shift + Yuxarı ox + + + + Select to lower row + Aşağıdakı sətiri seçin + + + + Shift + Down + Shift + Aşağı ox + + + + Open + Açmaq + + + + Ctrl + Down + Ctrl + Aşağı ox + + + + To parent directory + Ana qovluğa + + + + Ctrl + Up + Ctrl + Yuxarı ox + + + + Permanently delete + Həmişəlik silmək + + + + Shift + Delete + Shift + Delete + + + + Delete file + Faylı silmək + + + + Delete + Silmək + + + + Select all + Hamısını seçmək + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Kopyalamaq + + + + Cut + əsmək + + + + Paste + Yerləşdirmək + + + + Rename + Yenidən adlandırmaq + + + + F2 + F2 + + + + New/Search + Yeni/Axtarış + + + + New window + Yeni pəncərə + + + + New folder + Yeni qovluq + + + + + Search + Axtarmaq + + + + New tab + Yeni vərəq + + + + View + Baxış + + + + Item information + Element məlumatları + + + + Help + Kömək + + + + F1 + F1 + + + + Keyboard shortcuts + Klaviatura qısayolları + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + EKran vəziyyətini dəyişmək + + + + Hide item + Elementi gizlətmək + + + + Input in address bar + Ünvan çübüğuna daxil etmək + + + + Switch to icon view + Nişanlarla baxış rejiminə keçmək + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Siyahı görünüşü rejiminə keçmək + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Digəriləri + + + + Close + Bağlamaq + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Cari vərəqi bağlamaq + + + + Back + Geriyə + + + + Alt + Left + Alt + Sola ox + + + + Alt + Right + Alt + Sağa ox + + + + Switch to next tab + Sonrakı vərəqə keçmək + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Əvvəlki vərəqə keçmək + + + + Next file + Növbəti fayl + + + + Tab + Tab + + + + Previous file + Əvvəlki fayl + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Vərəqlərə verilmiş 1-dən 8-ə sayları arasında keçid etmək + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + İrəli + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Elementi səbətdə açmaq mümkün deyil, lütfən öncə geri qaytarın + + + + TrashPropertyDialog + + + Trash + Səbət + + + + item + Element + + + + items + Elementlər + + + + Contains %1 %2 + Tərkibi %1 %2 + + + + UDiskListener + + + Failed to rename the label + Yarlığın adı dəyişdirilə bilmədi + + + + UnmountWorker + + + + + The device was not safely unmounted + Cihaz təhlükəsiz ayrılmadı + + + + The device was not safely removed + Cihaz təhlükəsiz şəkildə çıxarılmadı + + + + UserShareManager + + + Kindly Reminder + Lütfən xatırlat + + + + Please firstly install samba to continue + Davam etmək üçün öncə samba quraşdırın + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + Paylaşma adı %<>*?|/\+=;:," işarələrindən ibarət olmamalı və %1 ilə başlamamalıdır + + + + To protect the files, you cannot share this folder. + Faylları qorumaq üçün bu qovluğu paylaşmaq olmaz. + + + + Sharing failed + Paylaşılma uğursuz oldu + + + + The computer name is too long + Kompyuterin adı çox uzundur + + + + You do not have permission to operate file/folder! + Fayı və ya qovluq ilə işləməyə icazəniz yoxdur! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Paylaşılan qovluqları qorumaq üçün şifrə daxil edin + + + + Cancel + button + İmtina + + + + Confirm + button + Tədiqləmək + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_bg.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_bg.ts new file mode 100644 index 0000000..b16e4bc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_bg.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + Нова папка + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + Затвори всичко + + + + Total size: %1, %2 files + Общо: %1, %2 файлове + + + + ComputerModel + + + My Directories + Моите папки + + + + + + Disks + Дискове + + + + ComputerPropertyDialog + + + Computer + Компютър + + + + Basic Info + Основна информация + + + + Computer Name + Име на компютъра + + + + Version + Версия + + + + Type + Тип + + + + Processor + Процесор + + + + Memory + Памет + + + + Disk + Диск + + + + Bit + Бит + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + Търсене или въведете адрес + + + + DFMAdvanceSearchBar + + + Search: + Търсене: + + + + File Type: + Тип на файл: + + + + File Size: + Размер на файл: + + + + Time Modified: + Време на промяна: + + + + Reset + Възстанови + + + + All subdirectories + Всички подпапки + + + + Current directory + Текуща папка + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Днес + + + + Yesterday + Вчера + + + + This week + Тази седмица + + + + Last week + Миналата седмица + + + + This month + Този месец + + + + Last month + Миналия месец + + + + This year + Тази година + + + + Last year + Миналата година + + + + DFMTagCrumbController + + + Tag information + Информационен маркер + + + + DFMTagWidget + + + Tag + Таг + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + Въведете парола на хранилището + + + + Retrieve password + Възстанови парола + + + + DFileCopyMoveJob + + + Permission error + Грешка с правата + + + + The action is denied + Действието е отказано + + + + Failed to open the file + Неуспешно отваряне на файла + + + + Failed to read the file + Неуспешно четене на файла + + + + Failed to write the file + Неуспешен запис на файла + + + + Failed to create the directory + Неуспешно създаване на директория + + + + Failed to delete the file + Неуспешно изтриване на файл + + + + Failed to move the file + Неуспешно преместване на файла + + + + Original file does not exist + Оригиналният файл не съществува + + + + Failed, file size must be less than 4GB + Неуспех, размера на файла трябва да е под 4 ГБ + + + + Not enough free space on the target disk + Няма достатъчно свободно място на избрания диск + + + + File integrity was damaged + Цялостта на файла е повредена + + + + The target device is read only + Избраното устройство е само за четене + + + + Target folder is inside the source folder + Крайната папка е във папката източник + + + + copy + Extra name added to new file name when used for file name. + копиране + + + + Failed to create the directory, cause: %1 + Неуспешно създаване на директория, поради: %1 + + + + + Failed to open the file, cause: %1 + Неуспешно отваряне на файла, поради: %1  + + + + Failed to read the file, cause: %1 + Неуспешно четене на файла, поради: %1  + + + + Failed to write the file, cause: %1 + Неуспешен запис на файла, поради: %1  + + + + File integrity was damaged, cause: %1 + Цялостта на файла е повредена, поради: %1 + + + + Failed to delete the file, cause: %1 + Неуспешно изтриване на файл, поради: %1 + + + + Fail to create symlink, cause: %1 + Неуспешно създаване на symlink, поради: %1 + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + %1 вече съществува, искате ли да го замените? + + + + Cancel + Отказ + + + + Replace + Замени + + + + Open + + + + + DFileManagerWindow + + + Trash + Кошче + + + + Empty + + + + + DFileSystemModel + + + + Name + Име + + + + + + Time modified + Време на промяна + + + + Size + Размер + + + + Type + Тип + + + + Time created + Време на създаване + + + + + Last access + Последно използван + + + + Path + Път + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + (Обърни) + + + + DFileViewHelper + + + Add tag "%1" + Добави маркер "%1" + + + + DStatusBar + + + %1 item + %1 обект + + + + %1 items + %1 обекта + + + + %1 item selected + %1 елемент е избран + + + + %1 items selected + %1 избрани обекта + + + + %1 folder selected (contains %2) + %1 избрана папка (съдържа %2) + + + + %1 folders selected (contains %2) + %1 избрани папки (съдържат %2) + + + + %1 file selected (%2) + %1 избран файл (%2) + + + + %1 files selected (%2) + %1 избрани файла(%2) + + + + %1 folder selected + %1 избрана папка + + + + Filter + Филтър + + + + Save as: + Запазване като: + + + + Loading... + Зареждане... + + + + DTaskDialog + + + This action is not supported + Това действие не се поддържа + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + %1 обем + + + + Data Disk + Data Partition + Диск за данни + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + Операцията е неуспешна! + + + + Target folder is inside the source folder! + Целевата папка се намира в изходната папка! + + + + + + + + + + + + + OK + ОК + + + + Do you want to run %1 or display its content? + Да пусна ли %1 или да покажа съдържанието му? + + + + It is an executable text file. + Това е изпълним текстов файл. + + + + + + + + + + + + + + Cancel + Отказ + + + + + + Run + Стартиране + + + + + Run in terminal + Стартиране в терминал + + + + Display + Екран + + + + It is an executable file. + Това е изпълним файл. + + + + This file is not executable, do you want to add the execute permission and run? + Този файл не е изпълним, искате ли да добавите разрешението за изпълнение и да стартирате? + + + + "%1" already exists, please use another name. + "%1" вече съществува, моля, използвайте друго име. + + + + + + + + Confirm + Потвърждение + + + + Are you sure you want to erase all data on the disc? + Сигурни ли сте, искате да изтриете всички данни на диска? + + + + Erase + Изтриване + + + + How do you want to use this disc? + Как искате да използвате този диск? + + + + Burn image + Записване на образ + + + + Burn files + Записване на файлове + + + + Disc erase failed + Неуспешно изтриване на диска + + + + Burn process failed + Неуспешен процес на запис + + + + %1: %2 + %1: %2 + + + + + Show details + Покази подробности + + + + Hide details + Скриване на подробности + + + + Error + Грешка + + + + Permanently delete %1? + Изтриване завинаги на %1? + + + + Permanently delete %1 items? + Изтриване завинаги на %1 обекта? + + + + Delete + Изтриване + + + + Empty + Изпразване + + + + Sorry, unable to locate your bookmark directory, remove it? + Не може да намерим вашата директория с отметки. Да я премахнем ли ? + + + + Remove + Премахване + + + + Name: + Име: + + + + Force unmount + Принудително демонтиране + + + + %1 that this shortcut refers to has been changed or moved + прекият път за %1 може да е бил променен или преместен + + + + Do you want to delete this shortcut? + Искате ли да изтриете този пряк път ? + + + + Failed, file size must be less than 4GB. + Неуспех, размера на файла трябва да е под 4 ГБ + + + + Fail to create symlink, cause: + Неуспешно създаване на symlink, причина: + + + + The selected files contain system file/directory, and it cannot be deleted + Избраните файлове, съдържат системни файлове/директории и не могат да бъдат изтрити + + + + + You do not have permission to operate file/folder! + Вие нямате права за достъп до този файл/папка! + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Вие нямате право на достъп до този %1 файл/папка(и)! + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + 2. Махнете отметката от „Включване на бързо стартиране“ и „Хибернация“ в настройките за изключване и рестартирайте + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + Споделената папка не може да се преименува сегашният потребител + + + + View + Преглед + + + + Do you want to run %1? + Искате ли да стартирате %1? + + + + Are you sure you want to empty %1 item? + Наистина ли искате да изпразните %1 обект? + + + + Are you sure you want to empty %1 items? + Наистина ли искате да премахнете %1 обекта? + + + + + This action cannot be undone + Това действие не може да бъде възстановено + + + + Disk is busy, cannot unmount now + Файлове от диска се използват не можете да го демонтирате + + + + Unable to copy. Not enough free space on the target disk. + Не може да се копира. Няма достатъчно свободно място на избрания диск. + + + + Failed to restore %1 file, the target folder is read-only + Не може да се възстанови %1 файл, избраната папка е само за четене + + + + Failed to restore %1 files, the target folder is read-only + Не може да се възстановят %1 файлове, избраната папка е само за четене + + + + Mount partition%1 to be read only + Монтиране на дял %1 само за четене + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + Дисковете в Windows няма да използват нормално ако отметнете "Turn on fast startup (recommended)" в настройките за изключване + + + + Please restore by the following steps to normally access Windows disk + Моля възстановете чрез тези стъпки за нормален достъп до Windows диск + + + + 1. Reboot to enter Windows + 1. Рестартиране за влизане в Windows + + + 3. Reboot and enter deepin + 3. Рестартирайте и влезте в Deepin + + + + Reboot + Рестарт + + + + FileController + + + + + Kindly Reminder + Любезно напомняне + + + + + + Please install File Roller first and then continue + Моля инсталирайте File Roller и след това да продължете + + + + FileDialogStatusBar + + + File Name + Име на файл + + + + Format + Формат + + + + Cancel + Отказ + + + + Save + Запазване + + + + Open + Отваряне + + + + Save File + Запис на файл + + + + Open File + Отвори файл + + + + FileJob + + + copy + копиране + + + + + Data verification successful. + Проверка на данните е успешна. + + + + + Data verification failed. + Проверка на данните е неуспешна. + + + + + Burn process completed + Процеса на запис приключи + + + + %1 s + %1 с + + + + %1 m %2 s + %1 м %2 с + + + + %1 h %2 m %3 s + %1 ч %2 м %3 с + + + + %1 d %2 h %3 m %4 s + %1 д %2 ч %3 м %4 с + + + + %1 is a duplicate file. + %1 се повтаря. + + + + Insufficient disc space. + Недостатъчно дисково пространство. + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + Базов + + + + + + Open behavior + Отвори поведение + + + + + + Always open folder in new window + Винаги отваряй папката в нов прозорец + + + + + + Open file: + Отвори файл: + + + + + + Click + Щрак + + + + + + Double click + Двойно щракване + + + + + + New window and tab + Нов прозорец и раздел + + + + + + Open from default window: + Отваряне от подразбиращ прозорец: + + + + + + + + + Computer + Компютър + + + + + + + + + Home + В началото + + + + + + + + + Desktop + Десктоп + + + + + + + + + Videos + Видео + + + + + + + + + Music + Музика + + + + + + + + + Pictures + Картинки + + + + + + + + + Documents + Документи + + + + + + + + + Downloads + Изтегления + + + + + + Open in new tab: + Отвори в нов раздел: + + + + + + Current Directory + Текуща папка + + + + + + View + Преглед + + + + + + Default size: + Стандартен размер: + + + + + + Extra small + много малък + + + + + + Small + малък + + + + + + Medium + Среден + + + + + + Large + Голям + + + + + + Extra large + Много голям + + + + + + Default view: + Стандартен изглед: + + + + + + Icon + Икона + + + + + + List + Списък + + + + + + Hidden files + Скрити файлове + + + + + + Show hidden files + Показване на скритите файлове + + + + + + Hide file extension when rename + Скрий разширение при преименуване + + + + + + Advanced + За напреднали + + + + + + Index + Индекс + + + + + + Auto index internal disk + Автоматичен индекс на вътрешен диск + + + + + + Index external storage device after connected to computer + Индекс на външно устройство след свързване за компютъра + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + Друг + + + + + + Hide system disk + Скриване на системен диск + + + + + + Show hidden files in search results + Покажи скритите файлове при търсене + + + + + + Display recent file entry in left panel + Показване на последните въвеждания на файл в левия панел + + + + + + Preview + Преглед + + + + + Compress file preview + Преглед на компресиран файл + + + + + + Text preview + Преглед на текст + + + + + + Document preview + Преглед на документ + + + + + + Image preview + Преглед на картина + + + + + + Video preview + Преглед на видео + + + + + + Mount + Монтиране + + + + + + Auto mount + Автоматично монтиране + + + + + + Open after auto mount + Отвори след автоматично монтиране + + + + + + Dialog + Диалог + + + Use the file chooser dialog of Deepin File Manager + Използвай прозорец за избор на Deepin файлов мениджър + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + Дискът е монтират от потребителя "%1", не можете да го демонтирате. + + + + + + + + Confirm + Потвърждавам + + + + + Cannot find the mounting device + Не се открива монтирано устройство + + + + Cannot unmount the device + Не се демонтира устройството + + + + Cannot eject the device "%1" + Не може да се отвори устройството "%1" + + + + MergedDesktopController + + + + Pictures + Картинки + + + + + Music + Музика + + + + + Applications + Приложения + + + + + Videos + Видео + + + + + Documents + Документи + + + + + Others + Други + + + + MimeTypeDisplayManager + + + + Directory + Папка + + + + + + Application + Приложение + + + + + + Video + Видео + + + + + + Audio + Аудио + + + + + + Image + Изображение + + + + + Archive + Архив + + + + + + Text + Текст + + + + + Executable + Изпълним + + + + + Backup file + + + + + + Unknown + Непознат + + + + MountAskPasswordDialog + + + Cancel + Отказ + + + + Connect + Свързване + + + + Log in as + Влизане като + + + + Anonymous + Анонимно + + + + Registered user + Регистриран потребител + + + + Username + Потребителско име + + + + Domain + Домейн + + + + Password + Парола + + + + Remember password + Запомни паролата + + + + MountSecretDiskAskPasswordDialog + + + Cancel + Отказ + + + + Unlock + + + + + Input password to decrypt the disk + Моля, въведете парола за декриптиране на диска + + + + MoveCopyTaskWidget + + Skip + Пропускане + + + Keep both + Запази и двете + + + Replace + Замяна + + + Do not ask again + Не ме питай повече + + + merge + обедини + + + Copying %1 + Копиране %1 + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + Копиране в %2 + + + Moving %1 + Преместване %1 + + + Move to %2 + Преместване в %2 + + + Restoring %1 + Възстановяване %1 + + + Restore to %2 + Възстановяване в %2 + + + Deleting %1 + Изтриване %1 + + + Trashing %1 + Преместване в кошчето %1 + + + Calculating space, please wait + Изчисляване на пространството, моля изчакайте + + + File named %1 already exists in target folder + Файл с име %1 вече съществува в посочената папка + + + Original path %1 target path %2 + Път до оригинала %1 път до целта %2 + + + Retry + Отново + + + Time modified:%1 + Време на промяна:%1 + + + Original folder + Оригинална папка + + + Original file + Оригинален файл + + + Target folder + Целева папка + + + Target file + Целеви файл + + + Contains:%1 + Съдържание:%1 + + + Size:%1 + Размер:%1 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Сигурен ли сте, че искате да изтриете напълно %1? + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + Сигурен ли сте, че искате да изтриете напълно %1 файла? + + + + Cancel + Отказ + + + + Delete + Изтриване + + + + OpenWithDialog + + + Open with + Отваряне с + + + + Add other programs + Добави друга програма + + + + Set as default + Задаване както подразбиращ + + + + Cancel + Отказ + + + + Confirm + + + + + Recommended Applications + Препоръчани приложения + + + + Other Applications + Други приложения + + + + PathManager + + + Home + Домашна директория + + + + Desktop + Работен плот + + + + Videos + Видео + + + + Music + Музика + + + + Pictures + Снимки + + + + Documents + Документи + + + + Downloads + Свалени + + + + + Trash + Кошче + + + + + System Disk + Системен диск + + + + Computers in LAN + Компютри в LAN + + + + My Shares + Споделени + + + + Computer + Компютър + + + + Recent + Последни + + + + PropertyDialog + + + Basic info + Основна информация + + + + Open with + Отваряне с + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + %1 (%2) + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + Позволи да се изпълнява, като програма + + + + QObject + + + + + Size + Размер + + + + + + Contains + Съдържание + + + + + + Type + Тип + + + + + + + Time modified + Време на промяна + + + + Free space + Свободно пространство + + + + Total space + Общо пространство + + + + Access denied + Достъп отказан + + + + + Executable + Изпълним + + + + + Write only + Само за писане + + + + + Read only + Само за четене + + + + + Read-write + Четене-запис + + + + Others + Други + + + + Owner + Собственик + + + + Device type + + + + + File system + + + + + Group + Група + + + + + + Open + Отваряне + + + + + Size: %1 + Размер: %1 + + + + Type: %1 + Тип: %1 + + + + Size: 0 + Размер: 0 + + + + Items: %1 + Елементи: %1 + + + + + + + + + + + Open in new window + Отваряне в нов прозорец + + + + + + + + + + + Open in new tab + Отваряне в нов раздел + + + + Open with + Отваряне с + + + + Compress + Компресиране + + + + Extract + Извличане + + + + Extract here + Извличане тук + + + + Cut + Отрязване + + + + Copy + Копиране + + + + Paste + Поставяне + + + + + + + + + + Rename + Преименуване + + + + + + Remove + Преместване + + + + Create link + Създаване на връзка + + + + Send to desktop + Изпращане на десктопа + + + + Send to + Изпрати до + + + + Add to bookmark + Добавяне на отметка + + + + + + + Properties + Свойства + + + + New folder + Нова папка + + + + New window + Нов прозорец + + + + Select all + Избиране на всичко + + + + + Clear recent history + Изчисти последната история + + + + + + Empty Trash + Изпразване на кошчето + + + + Display as + Показване като + + + + Sort by + Сортиране по + + + + New document + Нов документ + + + + + Time created + Време на създаване + + + + Log out and unmount + Изход и демонтиране + + + + + + Source path + Път до източника + + + + Share folder + Споделяне на папка + + + + Cancel sharing + Отказване на споделянето + + + + Connect to Server + + + + + Set share password + Задаване на парола при споделяне + + + + Format + Формат + + + + Tag information + Информационен маркер + + + + Open in new window as admin + Отваряне в нов прозорец, като администратор + + + + Select default program + Задаване на подразбираща програма + + + + Open file location + Отвори местоположението на файла + + + + Remove bookmark + Премахване на отметка + + + + + + Delete + Изтриване + + + + Office Text + Офис текстов + + + + Spreadsheets + Таблица + + + + Plain Text + Обикновен текстов + + + + Open in terminal + Отваряне в терминал + + + + Restore + Възстановяване + + + + Restore all + Възстановяване на всичко + + + + File Vault + + + + + Auto mount + Автоматично монтиране + + + + Open after auto mount + Отвори след автоматично монтиране + + + + + Mount + Монтиране + + + + + Unmount + Демонтиране + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + Изваждане + + + + Safely Remove + Безопасно премахване + + + + + Name + Име + + + + Settings + Настройки + + + + Exit + Изход + + + + Icon + Икона + + + + List + Списък + + + + Extend + Разширяване + + + + Set as wallpaper + Задаване като тапет + + + + + + + Local disk + Локален диск + + + + + Removable disk + Сменяем диск + + + + + + Network shared directory + Споделени папки в мрежата + + + + + Android mobile device + Android мобилни устройства + + + + + Apple mobile device + Apple мобилни устройства + + + + + Camera + Камера + + + + + DVD + DVD + + + + + Unknown device + Непознато устройство + + + + + + %1 item + %1 обект + + + + + + %1 items + %1 обекта + + + + Shortcut + Пряк път + + + + Create symlink + Създаване на символна връзка + + + + Path + Път + + + + + + Time deleted + Време на изтриване + + + + Loading... + Зареждане + + + + File has been moved or deleted + Файлът е преместен или изтрит + + + + + + You do not have permission to access this folder + Вие нямате права за достъп до тази папка + + + + + + + Folder is empty + Папката е празна + + + + Path + SearchFileInfo + Път + + + + Searching... + Търсене... + + + + No results + Няма резултати + + + + Source Path + TrashFileInfo + Път до източника + + + + Document + Донумент + + + + Spreadsheet + Таблица + + + + + Presentation + Презентация + + + + Text + Текст + + + + 1 task in progress + 1 задача в изпълнение + + + + %1 tasks in progress + %1 задачи в изпълнение + + + + Mode: + Режим: + + + + + Replace Text + Замени текст + + + + + Add Text + Добави текст + + + + + Custom Text + Потребителски текст + + + + Find: + Търсене: + + + + Replace: + Замяна: + + + + + Optional + Допълнение + + + + Add: + Добавяне: + + + + Location: + Местоположение: + + + + File name: + Име на файл: + + + + +SN: + +SN: + + + + + + + + + + Required + Необходимо + + + + + Before file name + Преди името на файл + + + + + After file name + След името на файл + + + + Find + Намери + + + + Replace + Замени + + + + Add + Добави + + + + + + Location + Нахождение + + + + File name + Име на файл + + + + Dimension + + + + + Duration + + + + + +SN + +SN + + + + Tips: Sort by selected file order + Насока: Сортирай по избран файлове ред + + + + + + Cancel + Отказ + + + + Rename %1 Files + Преименуване на %1 файла + + + + Multiple Files + Множество файлове + + + + Basic info + Основна информация + + + + Total size + Общо размер + + + + Number of files + Брой на файлове + + + + %1 file(s), %2 folder(s) + %1 файл(ове), %2 папка(и) + + + + + + Time accessed + + + + + Orange + Оранжев + + + + Red + Червен + + + + Purple + Лилав + + + + Navy-blue + Морско синьо + + + + Azure + Небесен + + + + Green + Зелен + + + + Yellow + Жълт + + + + Gray + Сив + + + + Input tag info, such as work, family. A comma is used between two tags. + Въведете информационен маркер, като например работа, семейство. Използва се запетая между два маркера. + + + + Bookmarks + Отметки + + + + Erase + + + + + + Copy path + Копиране на път + + + + + Edit address + Редактиране на адреса + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + Споделяне на тази папка + + + + Share name: + Име за споделянето: + + + + Permission: + Права: + + + + Read and write + Четене и запис + + + + Read only + Само за четене + + + + Anonymous: + Анонимно: + + + + Not allow + Не разрешавай + + + + Allow + Разреши + + + + Shortcut + + + Item + Елемент + + + + Select to the first item + Избиране до първият елемент + + + + Shift + Home + Shift + Home + + + + Select to the last item + Избиране до последният елемент + + + + Shift + End + Shift + End + + + + Select leftwards + Избиране наляво + + + + Shift + Left + Shift + Left + + + + Select rightwards + Избиране надясно + + + + Shift + Right + Shift + Right + + + + Select to upper row + Избиране до горен ред + + + + Shift + Up + Shift + Up + + + + Select to lower row + Избиране до долен ред + + + + Shift + Down + Shift + Down + + + + Open + Отваряне + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + До горната директория + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Изтриване завинаги + + + + Shift + Delete + Shift + Delete + + + + Delete file + Изтриване на файл + + + + Delete + Изтриване + + + + Select all + Избор на всичко + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + Копиране + + + + Cut + Отрязване + + + + Paste + Поставяне + + + + Rename + Преименуване + + + + F2 + F2 + + + + New/Search + Нов/Търсене + + + + New window + Нов прозорец + + + + New folder + Нова папка + + + + + Search + Търсене + + + + New tab + Нов раздел + + + + View + Преглед + + + + Item information + Информация за елемента + + + + Help + Помощ + + + + F1 + F1 + + + + Keyboard shortcuts + Клавишни комбинации + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Превключване режима на показване + + + + Hide item + Скриване на елемент + + + + Input in address bar + Въвеждане в адресната лента + + + + Switch to icon view + Превключване към изглед икони + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Превключване към изглед списък + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Други + + + + Close + Затваряне + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Затвори текущия раздел + + + + Back + Обратно + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Премини на следващия раздел + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Премини на предишния раздел + + + + Next file + Следващ файл + + + + Tab + Tab + + + + Previous file + Предишен файл + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Превключи раздела по зададен номер от 1 до 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Напред + + + + TrashPropertyDialog + + + Trash + Кошче + + + + item + елемент + + + + items + елементи + + + + Contains %1 %2 + Съдържа %1 %2 + + + + UDiskListener + + + Failed to rename the label + Неуспешно преименуване на етикета + + + + UserShareManager + + + Kindly Reminder + Любезно напомняне + + + + Please firstly install samba to continue + Първо инсталирайте samba, за да продължите + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + Отказ + + + + Confirm + Потвърждавам + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_bn.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_bn.ts new file mode 100644 index 0000000..68ba57f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_bn.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + সবকিছু বন্ধ করুন + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + কম্পিউটার + + + + Basic Info + প্রাথমিক তথ্য + + + + Computer Name + কম্পিউটারের নাম + + + + Version + ভার্সন + + + + Type + ধরণ + + + + Processor + প্রসেসর + + + + Memory + মেমরি + + + + Disk + ডিস্ক + + + + Bit + বিট + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + খুঁজুন অথবা ঠিকানা প্রবেশ করান + + + + DFMAdvanceSearchBar + + + Search: + + + + + File Type: + + + + + File Size: + + + + + Time Modified: + + + + + Reset + + + + + All subdirectories + + + + + Current directory + + + + + 0 ~ 100 KB + + + + + 100 KB ~ 1 MB + + + + + 1 MB ~ 10 MB + + + + + 10 MB ~ 100 MB + + + + + 100 MB ~ 1 GB + + + + + > 1 GB + + + + + Today + + + + + Yesterday + + + + + This week + + + + + Last week + + + + + This month + + + + + Last month + + + + + This year + + + + + Last year + + + + + DFMTagCrumbController + + + Tag information + + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + + + + + The action is denied + + + + + Failed to open the file + + + + + Failed to read the file + + + + + Failed to write the file + + + + + Failed to create the directory + + + + + Failed to delete the file + + + + + Failed to move the file + + + + + Original file does not exist + + + + + Failed, file size must be less than 4GB + + + + + Not enough free space on the target disk + + + + + File integrity was damaged + + + + + The target device is read only + + + + + Target folder is inside the source folder + + + + + copy + Extra name added to new file name when used for file name. + + + + + Failed to create the directory, cause: %1 + + + + + + Failed to open the file, cause: %1 + + + + + Failed to read the file, cause: %1 + + + + + Failed to write the file, cause: %1 + + + + + File integrity was damaged, cause: %1 + + + + + Failed to delete the file, cause: %1 + + + + + Fail to create symlink, cause: %1 + + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + + + + + Cancel + বাতিল করুন + + + + Replace + + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + নাম + + + + + + Time modified + সময় পরিবর্তন হয়ে গেছে + + + + Size + আকার + + + + Type + ধরণ + + + + Time created + তৈরি করার সময় + + + + + Last access + + + + + Path + + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + (বিপরীত) + + + + DFileViewHelper + + + Add tag "%1" + + + + + DStatusBar + + + %1 item + %1 আইটেম + + + + %1 items + %1 গুলো আইটেম + + + + %1 item selected + %1 আইটেম নির্বাচন করা হয়েছে + + + + %1 items selected + %1 গুলো আইটেম নির্বাচন করা হয়েছে + + + + %1 folder selected (contains %2) + %1 ফোল্ডার নির্বাচন করা হয়েছে (ধারণ করছে %2) + + + + %1 folders selected (contains %2) + %1 গুলো ফোল্ডার নির্বাচন করা হয়েছে (ধারণ করছে %2) + + + + %1 file selected (%2) + %1 ফাইল নির্বাচন করা হয়েছে (%2) + + + + %1 files selected (%2) + %1 গুলো ফাইল নির্বাচন করা হয়েছে (%2) + + + + %1 folder selected + %1 ফোল্ডার নির্বাচন করা হয়েছে + + + + Filter + ফিল্টার + + + + Save as: + এই নাম সংরক্ষণ করুন + + + + Loading... + লোড হচ্ছে.... + + + + DTaskDialog + + + This action is not supported + + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + + + + + Data Disk + Data Partition + + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + অপারেশন বার্থ হয়েছে + + + + Target folder is inside the source folder! + টার্গেট করা ফোল্ডারটি উৎস ফোল্ডারের ভেতরে অবস্থিত + + + + + + + + + + + + + OK + ঠিক আছে + + + + Do you want to run %1 or display its content? + আপনি কি %1 চালাতে চান না এর কন্টেন্ট দেখাতে চান ? + + + + It is an executable text file. + এটি একটি এক্সেকিউটাবলে টেক্সট ফাইল + + + + + + + + + + + + + + Cancel + বাতিল করুন + + + + + + Run + চালান + + + + + Run in terminal + টার্মিনালে চালান + + + + Display + ডিসপ্লে + + + + It is an executable file. + এটি একটি এক্সেকিউটাবলে ফাইল + + + + This file is not executable, do you want to add the execute permission and run? + + + + + "%1" already exists, please use another name. + "%1" আগে থেকেই আছে, অন্য কোন নাম ব্যবহার করুন। + + + + + + + + Confirm + নিশ্চিত করুন + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + %1 স্থায়ীভাবে মুছে ফেলবেন ? + + + + Permanently delete %1 items? + %1 গুলো আইটেম স্থায়ীভাবে মুছে ফেলবেন ? + + + + Delete + মুছে ফেলুন + + + + Empty + খালি + + + + Sorry, unable to locate your bookmark directory, remove it? + + + + + Remove + + + + + Name: + + + + + Force unmount + + + + + %1 that this shortcut refers to has been changed or moved + + + + + Do you want to delete this shortcut? + + + + + Failed, file size must be less than 4GB. + + + + + Fail to create symlink, cause: + + + + + The selected files contain system file/directory, and it cannot be deleted + + + + + + You do not have permission to operate file/folder! + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + + + + + View + + + + + Do you want to run %1? + + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + + + + + Please restore by the following steps to normally access Windows disk + + + + + 1. Reboot to enter Windows + + + + 3. Reboot and enter deepin + + + + + Reboot + + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + + + + + Format + ফরম্যাট + + + + Cancel + বাতিল করুন + + + + Save + + + + + Open + + + + + Save File + + + + + Open File + + + + + FileJob + + + copy + + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + + + + + %1 m %2 s + + + + + %1 h %2 m %3 s + + + + + %1 d %2 h %3 m %4 s + + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + + + + + + + Open behavior + + + + + + + Always open folder in new window + + + + + + + Open file: + + + + + + + Click + + + + + + + Double click + + + + + + + New window and tab + + + + + + + Open from default window: + + + + + + + + + + Computer + কম্পিউটার + + + + + + + + + Home + + + + + + + + + + Desktop + ডেস্কটপ + + + + + + + + + Videos + + + + + + + + + + Music + + + + + + + + + + Pictures + + + + + + + + + + Documents + + + + + + + + + + Downloads + + + + + + + Open in new tab: + + + + + + + Current Directory + + + + + + + View + + + + + + + Default size: + + + + + + + Extra small + + + + + + + Small + ছোট + + + + + + Medium + মধ্যম + + + + + + Large + বড় + + + + + + Extra large + + + + + + + Default view: + + + + + + + Icon + + + + + + + List + + + + + + + Hidden files + + + + + + + Show hidden files + + + + + + + Hide file extension when rename + + + + + + + Advanced + + + + + + + Index + + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + + + + + + + Hide system disk + + + + + + + Show hidden files in search results + + + + + + + Display recent file entry in left panel + + + + + + + Preview + + + + + + Compress file preview + + + + + + + Text preview + + + + + + + Document preview + + + + + + + Image preview + + + + + + + Video preview + + + + + + + Mount + + + + + + + Auto mount + + + + + + + Open after auto mount + + + + + + + Dialog + + + + Use the file chooser dialog of Deepin File Manager + + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + + + + + + + + + Confirm + নিশ্চিত করুন + + + + + Cannot find the mounting device + + + + + Cannot unmount the device + + + + + Cannot eject the device "%1" + + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + + + + + + + Application + + + + + + + Video + + + + + + + Audio + + + + + + + Image + + + + + + Archive + + + + + + + Text + + + + + + Executable + + + + + + Backup file + + + + + + Unknown + + + + + MountAskPasswordDialog + + + Cancel + বাতিল করুন + + + + Connect + + + + + Log in as + + + + + Anonymous + + + + + Registered user + + + + + Username + + + + + Domain + + + + + Password + + + + + Remember password + + + + + MountSecretDiskAskPasswordDialog + + + Cancel + বাতিল করুন + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + + + + Keep both + + + + Replace + + + + Do not ask again + + + + merge + + + + Copying %1 + + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + + + + Moving %1 + + + + Move to %2 + + + + Restoring %1 + + + + Restore to %2 + + + + Deleting %1 + + + + Trashing %1 + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + Retry + + + + Time modified:%1 + + + + Original folder + + + + Original file + + + + Target folder + + + + Target file + + + + Contains:%1 + + + + Size:%1 + + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + বাতিল করুন + + + + Delete + মুছে ফেলুন + + + + OpenWithDialog + + + Open with + + + + + Add other programs + + + + + Set as default + + + + + Cancel + বাতিল করুন + + + + Confirm + + + + + Recommended Applications + + + + + Other Applications + + + + + PathManager + + + Home + + + + + Desktop + ডেস্কটপ + + + + Videos + + + + + Music + + + + + Pictures + + + + + Documents + + + + + Downloads + + + + + + Trash + ট্র্যাশ + + + + + System Disk + সিস্টেম ডিস্ক + + + + Computers in LAN + + + + + My Shares + + + + + Computer + কম্পিউটার + + + + Recent + + + + + PropertyDialog + + + Basic info + + + + + Open with + + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + + + + + QObject + + + + + Size + আকার + + + + + + Contains + + + + + + + Type + ধরণ + + + + + + + Time modified + সময় পরিবর্তন হয়ে গেছে + + + + Free space + + + + + Total space + + + + + Access denied + + + + + + Executable + + + + + + Write only + + + + + + Read only + + + + + + Read-write + + + + + Others + + + + + Owner + + + + + Device type + + + + + File system + + + + + Group + + + + + + + Open + + + + + + Size: %1 + + + + + Type: %1 + + + + + Size: 0 + + + + + Items: %1 + + + + + + + + + + + + Open in new window + + + + + + + + + + + + Open in new tab + + + + + Open with + + + + + Compress + + + + + Extract + + + + + Extract here + + + + + Cut + + + + + Copy + + + + + Paste + + + + + + + + + + + Rename + + + + + + + Remove + + + + + Create link + + + + + Send to desktop + + + + + Send to + + + + + Add to bookmark + + + + + + + + Properties + বৈশিষ্ট্যসমূহ + + + + New folder + + + + + New window + + + + + Select all + + + + + + Clear recent history + + + + + + + Empty Trash + + + + + Display as + + + + + Sort by + + + + + New document + + + + + + Time created + তৈরি করার সময় + + + + Log out and unmount + + + + + + + Source path + + + + + Share folder + + + + + Cancel sharing + + + + + Connect to Server + + + + + Set share password + + + + + Format + ফরম্যাট + + + + Tag information + + + + + Open in new window as admin + + + + + Select default program + + + + + Open file location + + + + + Remove bookmark + + + + + + + Delete + মুছে ফেলুন + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + + + + + Restore + + + + + Restore all + + + + + File Vault + + + + + Auto mount + + + + + Open after auto mount + + + + + + Mount + + + + + + Unmount + + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + + + + + Safely Remove + + + + + + Name + নাম + + + + Settings + + + + + Exit + + + + + Icon + + + + + List + + + + + Extend + + + + + Set as wallpaper + + + + + + + + Local disk + + + + + + Removable disk + + + + + + + Network shared directory + + + + + + Android mobile device + + + + + + Apple mobile device + + + + + + Camera + + + + + + DVD + + + + + + Unknown device + + + + + + + %1 item + %1 আইটেম + + + + + + %1 items + %1 গুলো আইটেম + + + + Shortcut + + + + + Create symlink + + + + + Path + + + + + + + Time deleted + + + + + Loading... + লোড হচ্ছে.... + + + + File has been moved or deleted + + + + + + + You do not have permission to access this folder + + + + + + + + Folder is empty + + + + + Path + SearchFileInfo + + + + + Searching... + + + + + No results + + + + + Source Path + TrashFileInfo + + + + + Document + + + + + Spreadsheet + + + + + + Presentation + + + + + Text + + + + + 1 task in progress + + + + + %1 tasks in progress + + + + + Mode: + + + + + + Replace Text + + + + + + Add Text + + + + + + Custom Text + + + + + Find: + + + + + Replace: + + + + + + Optional + + + + + Add: + + + + + Location: + + + + + File name: + + + + + +SN: + + + + + + + + + + + Required + + + + + + Before file name + + + + + + After file name + + + + + Find + + + + + Replace + + + + + Add + + + + + + + Location + + + + + File name + + + + + Dimension + + + + + Duration + + + + + +SN + + + + + Tips: Sort by selected file order + + + + + + + Cancel + বাতিল করুন + + + + Rename %1 Files + + + + + Multiple Files + + + + + Basic info + + + + + Total size + + + + + Number of files + + + + + %1 file(s), %2 folder(s) + + + + + + + Time accessed + + + + + Orange + + + + + Red + + + + + Purple + + + + + Navy-blue + + + + + Azure + + + + + Green + + + + + Yellow + + + + + Gray + + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + + + + + Erase + + + + + + Copy path + + + + + + Edit address + + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + + + + + Share name: + + + + + Permission: + + + + + Read and write + + + + + Read only + + + + + Anonymous: + + + + + Not allow + + + + + Allow + + + + + Shortcut + + + Item + + + + + Select to the first item + + + + + Shift + Home + + + + + Select to the last item + + + + + Shift + End + + + + + Select leftwards + + + + + Shift + Left + + + + + Select rightwards + + + + + Shift + Right + + + + + Select to upper row + + + + + Shift + Up + + + + + Select to lower row + + + + + Shift + Down + + + + + Open + + + + + Ctrl + Down + + + + + To parent directory + + + + + Ctrl + Up + + + + + Permanently delete + + + + + Shift + Delete + + + + + Delete file + + + + + Delete + মুছে ফেলুন + + + + Select all + + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + + + + + Cut + + + + + Paste + + + + + Rename + + + + + F2 + + + + + New/Search + + + + + New window + + + + + New folder + + + + + + Search + + + + + New tab + + + + + View + + + + + Item information + + + + + Help + + + + + F1 + + + + + Keyboard shortcuts + + + + + Ctrl + Shift + / + + + + + Switch display status + + + + + Hide item + + + + + Input in address bar + + + + + Switch to icon view + + + + + Ctrl + 1 + + + + + Switch to list view + + + + + Ctrl + 2 + + + + + Others + + + + + Close + + + + + Alt + F4 + + + + + Close current tab + + + + + Back + + + + + Alt + Left + + + + + Alt + Right + + + + + Switch to next tab + + + + + Ctrl + Tab + + + + + Ctrl + Shift + Tab + + + + + Switch to previous tab + + + + + Next file + + + + + Tab + + + + + Previous file + + + + + Shift + Tab + + + + + Switch tab by specified number between 1 to 8 + + + + + Alt + [1-8] + + + + + Forward + + + + + TrashPropertyDialog + + + Trash + ট্র্যাশ + + + + item + + + + + items + + + + + Contains %1 %2 + + + + + UDiskListener + + + Failed to rename the label + + + + + UserShareManager + + + Kindly Reminder + + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + বাতিল করুন + + + + Confirm + নিশ্চিত করুন + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_bo.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_bo.ts new file mode 100644 index 0000000..ce2ebe6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_bo.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + ཡིག་ཁུག་གསར་འཛུགས། + + + + Mounting device error + འཇུག་ཆས་ལ་ནོར་འཁྲུལ་ཤོར་བ། + + + + The disc image was corrupted, cannot mount now, please erase the disc first + སྡུད་སྡེར་འདིའི་ཤེལ་བརྙན་སྐྱོན་ཤོར་བས་འཇུག་ཐབས་བྲལ། བསུབས་རྗེས་བེད་སྤྱོད་བྱེད། + + + + Mount error: unsupported image format + བཅུག་པ་ནོར་འདུག ཤེལ་བརྙན་ཡིག་ཆའི་རྣམ་གཞག་ལ་རྒྱབ་སྐྱོར་མེད་པ། + + + + + The device was not safely removed + སྒྲིག་ཆས་རྒྱུན་གཏན་ངང་སྤོ་འབུད་བྱས་མེད། + + + + + Click "Safely Remove" and then disconnect it next time + “བདེ་འཇགས་སྤོ་འབུད་”མནན་རྗེས། མུ་མཐུད་འབྲེལ་མཐུད་བྱེད་མཚམས་འཇོག་རྒྱུ། + + + + The device was not ejected + སྒྲིག་ཆས་ཕྱིར་བཏོན་མེད། + + + + Disk is busy, cannot eject now + སྡུད་སྡེར་ཡིག་ཆ་གཞན་གྱིས་བཟུང་ཡོད་པས། ཕྱིར་དོན་ཐབས་བྲལ། + + + + Authentication timed out + དཔང་དཔྱད་དུས་བརྒལ། + + + + BluetoothTransDialog + + + Bluetooth File Transfer + སོ་སྔོན་གྱིས་ཡིག་ཆ་བརྒྱུད་གཏོང་། + + + + File Transfer Successful + ཡིག་ཆ་བརྒྱུད་གཏོང་ཐུབ་པ། + + + + File Transfer Failed + ཡིག་ཆ་བརྒྱུད་གཏོང་མི་ཐུབ། + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + ད་ལྟ་“<b style="font-weight: 550;">%1</b>”ལ་ཡིག་ཆ་སྐུར་བཞིན་ཡོད། + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + “<b style="font-weight: 550;">%1</b>”ལ་ཡིག་ཆ་བསྐུར་མ་ཐུབ། + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + “<b style="font-weight: 550;">%1</b>”ལ་ཡིག་ཆ་བསྐུར་ཐུབ་སོང་། + + + + Select a Bluetooth device to receive files + ཡིག་ཆ་འདི་བསྡུ་ལེན་བྱེད་པའི་སོ་སྔོན་སྒྲིག་ཆས་འདེམས་རྒྱུ། + + + + Cannot find the connected Bluetooth device + འབྲེལ་མཐུད་བྱས་ཟིན་པའི་སོ་སྔོན་སྒྲིག་ཆས་རྙེད་མ་བྱུང་། + + + + Waiting to be received... + བསྡུ་ལེན་སྒུག་བཞིན་ཡོད་པས། ཏོག་ཙམ་སྒུག་རོགས། + + + + Go to Bluetooth Settings + སོ་སྔོན་སྒྲིག་འགོད་དུ་འགྲོ་བ། + + + + %1/%2 Sent + %1/%2སྐྱེལ་ཟིན། + + + + Error: the Bluetooth device is disconnected + རྒྱུ་མཚན། སོ་སྔོན་སྒྲིག་ཆས་འབྲེལ་མཐུད་བྱས་མེད། + + + + Unable to send the file more than 2 GB + 2GBལས་བརྒལ་བའི་ཡིག་ཆ་སྐུར་ཐབས་མེད། + + + + Unable to send 0 KB files + 0KBཡིན་པའི་ཡིག་ཆ་སྐུར་ཐབས་མེད། + + + + File doesn't exist + ཡིག་ཆ་མི་འདུག + + + + Next + button + གོམ་སྟབས་རྗེས་མ། + + + + Cancel + button + འདོར་བ། + + + + Done + button + ལེགས་གྲུབ། + + + + Retry + button + ཡང་བསྐྱར་ཚོད་ལྟ་བྱེད་པ། + + + + OK + button + ཆོག + + + + File sending request timed out + ཡིག་ཆ་སྐུར་ཚད་དུས་ལས་བརྒལ་བ། + + + + The service is busy and unable to process the request + སྒྲིག་ཆས་དུས་ལས་བརྒལ་བས། རེ་ཞུ་འདི་ཐག་གཅོད་བྱེད་ཐབས་བྲལ། + + + + BurnOptDialog + + + Device error + སྒྲིག་ཆས་ཀྱི་སྐྱོན། + + + + Optical device %1 doesn't exist + འོད་སྡེར་%1མི་འདུག + + + + Advanced settings + མཐོ་རིམ་སྒྲིག་འགོད། + + + + File system: + ཡིག་ཆའི་རྒྱུད་ཁོངས། + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Windowsལ་སྤྱོད་རུང་བ།) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Unixལ་སྤྱོད་རུང་བ།) + + + + %1 (Compatible with Windows CD/DVD mode) + %1རྣམ་གཞག་(Windowsའཆམ་མཐུན་CD/DVDསོར་བཞག་ཕབ་བརྐོ།) + + + + ISO9660 Only + ISO9660ཁོ་ན། + + + + CloseAllDialogIndicator + + + Close all + ཚང་མ་ཁ་རྒྱོབ། + + + + Total size: %1, %2 files + སྤྱིའི་ཤོང་ཚད་%1དང་། ཡིག་ཆ་སྤྱིའི་ཁ་གྲངས་%2 + + + + ComputerModel + + + Double click to open it + ཐེངས་གཉིས་མནོན་ནས་ཉེར་སྤྱོད་བྱ་རིམ་ཁ་ཕྱེ་བ། + + + + My Directories + ངའི་དཀར་ཆག + + + + Disks + སྡུད་སྡེར། + + + + File Vault + ཡིག་ཆའི་ཉེན་འགོག་ལྕགས་སྒམ། + + + + Quick Access + མགྱོགས་མྱུར་ལྟ་སྤྱོད། + + + + ComputerPropertyDialog + + + Computer + རྩིས་འཁོར། + + + + Basic Info + གཞི་རྩའི་ཆ་འཕྲིན། + + + + + Computer Name + རྩིས་འཁོར་གྱི་མིང་། + + + + + Edition + པར་གཞི། + + + + + + Version + པར་མའི་རྟགས། + + + + + Type + རིགས་གྲས། + + + + + + Processor + སྒྲིག་གཅོད་ཆས། + + + + + + Memory + ནང་གསོག + + + + + + + Bit + གནས། + + + + + Available + སྤྱོད་ཆོག + + + + Obtaining... + ལེན་བཞིན་པ། + + + + ConnectToServerDialog + + + Connect to Server + ཞབས་ཞུ་འཕྲུལ་ཆས་དང་སྦྲེལ་མཐུད་པ། + + + + Cancel + button + འདོར་བ། + + + + Connect + button + སྦྲེལ་མཐུད། + + + + My Favorites: + སྒེར་གྱི་བསྡུ་ཉར་ཞབས་ཞུ་འཕྲུལ་ཆས། + + + + + Clear History + ཉེ་ཆར་བེད་སྤྱོད་བྱས་པའི་ཞབས་ཞུ་འཕྲུལ་ཆས་སུབ་པ། + + + + DFMAddressBar + + + Search or enter address + བཤེར་འཚོལ་ལམ་གནས་ཡུལ་ནང་འཇུག་བྱེད་པ། + + + + DFMAdvanceSearchBar + + + Search: + བཤེར་འཚོལ་གྱི་ཁྱབ་ཁོངས། + + + + File Type: + ཡིག་ཆའི་རིགས། + + + + File Size: + ཡིག་ཆའི་ཆེ་ཆུང་། + + + + Time Modified: + བཟོ་བཅོས་དུས་ཚོད། + + + + Time Accessed: + ལྟ་སྤྱོད་དུས་ཚོད། + + + + Time Created: + བཟོ་བའི་དུས་ཚོད། + + + + Reset + བསྐྱར་སྒྲིག + + + + All subdirectories + ཡན་ལག་ཡིག་ཁུག་ཚང་མ། + + + + Current directory + མིག་སྔའི་ཡིག་ཁུག + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 0 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + དེ་རིང་། + + + + Yesterday + ཁ་སང་། + + + + This week + གཟའ་འཁོར་འདི། + + + + Last week + གཟའ་འཁོར་གོང་མ། + + + + This month + ཟླ་འདི། + + + + Last month + ཟླ་བ་གོང་མ། + + + + This year + ད་ལོ། + + + + Last year + ན་ནིང་། + + + + DFMOpticalMediaWidget + + + + No files to burn + ཕབ་བརྐོ་བྱེད་དགོས་པའི་ཡིག་ཆ་མེད་པ། + + + + Unable to burn. Not enough free space on the target disk. + དམིགས་འབེན་སྡུད་སྡེར་གྱི་ཤོང་ཚད་མི་འདང་བས། ཕབ་བརྐོ་བྱེད་ཐབས་བྲལ། + + + + %1 burning is not supported + མིག་སྔར་སྡུད་སྡེར་བར་རྫས་ཀྱིས་%1ཕབ་བརྐོ་བྱེད་པར་རྒྱབ་སྐྱོར་མེད། + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. འོད་སྡེར་རིགས་སྣ་%1མ་རེད། +2. མིག་སྔའི་འོད་སྡེར་ཡིག་ཆའི་མ་ལག་པར་གཞིས་གསར་སྣོན་བྱེད་པར་རྒྱབ་སྐྱོར་མི་བྱེད། + + + + DFMTagCrumbController + + + Tag information + མཚོན་རྟགས་ཆ་འཕྲིན། + + + + DFMTagWidget + + + Tag + མཚོན་རྟགས། + + + + DFMTaskWidget + + + Do not ask again + འདྲི་རྩད་མི་བྱེད་པ། + + + + Syncing data + གཞི་གྲངས་མཉམ་བགྲོད་བྱེད་བཞིན་པ། + + + + Please wait + སྒུག་རོགས། + + + + + Time modified: %1 + བཟོ་བཅོས་དུས་ཚོད། %1 + + + + + Contains: %1 + ཁ་གྲངས། %1 + + + + + Size: %1 + ཆེ་ཆུང་།%1 + + + + Original folder + ཐོག་མའི་ཡིག་ཁུག + + + + Keep both + button + མཉམ་གནས། + + + + Skip + button + མཆོང་བ། + + + + Replace + button + བརྗེ་བ། + + + + Retry + button + ཡང་བསྐྱར་ཚོད་ལྟ་བྱེད་པ། + + + + Original file + ཐོག་མའི་ཡིག་ཆ། + + + + Target folder + དམིགས་འབེན་ཡིག་ཁུག + + + + Target file + དམིགས་འབེན་ཡིག་ཆ། + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + གསང་སྡོམ་ཉེན་འགོག་སྒམ་ཆུང་། + + + + Click 'Encrypt' and input the user password. + “གསང་སྡོམ་ཉེན་འགོག་སྒམ་ཆུང་”མནན་རྗེས། སྤྱོད་མཁན་གྱི་གསང་ཨང་ནང་འཇུག་བྱས་ནས་སྒྲིག་འགོད་ལེགས་གྲུབ་བྱེད་དགོས། + + + + Encrypting... + གསང་སྡོམ་བྱེད་བཞིན་པ། + + + + + + + Encrypt + གསང་སྡོམ་ཉེན་འགོག་སྒམ་ཆུང་། + + + + Failed to create file vault: %1 + ཉེན་འགོག་སྒམ་ཆུང་བཟོ་མ་ཐུབ་པ། %1 + + + + OK + ཆོག + + + + The setup is complete + གསང་སྡོམ་བྱས་ཟིན། + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + གསང་ལྡེའི་ཡིག་ཆ་ཉར་བ། + + + + Keep the key safe to retrieve the vault password later + གསང་ལྡེའི་ཡིག་ཆས་ཁྱེད་ཀྱིས་སྒྲིག་འགོད་བྱས་པའི་ཉེན་འགོག་སྒམ་ཆུང་གི་གསང་ཨང་འཚོལ་བར་སྤྱད་ཆོག་པས། ཉར་ཚགས་ལེགས་པོ་བྱེད་དགོས། + + + + Save to default path + སོར་བཞག་བརྒྱུད་ལམ་དུ་ཉར་ཚགས་བྱ་རྒྱུ། + + + + Save to other locations + བརྒྱུད་ལམ་གཞན་དག་དུ་ཉར་ཚགས་བྱ་རྒྱུ། + + + + No permission, please reselect + དབང་ཚད་མི་འདང་བས། ཡང་བསྐྱར་འདེམས་རོགས། + + + + Select a path + གསང་ལྡེའི་ཡིག་ཆའི་ཉར་ཚགས་བརྒྱུད་ལམ་འདེམས་རོགས། + + + + Next + གོམ་སྟབས་རྗེས་མ། + + + + The default path is invisible to other users, and the path information will not be shown. + སོར་བཞག་བརྒྱུད་ལམ་ནི་སྤྱོད་མཁན་གཞག་དག་གིས་མི་མཐོང་བའི་བརྒྱུད་ལམ་དམིགས་བསལ་ཞིག་རེད་ལ། ཡི་གེའི་ཐོག་ནས་བརྒྱུད་ལམ་ཆ་འཕྲིན་མངོན་མི་སྲིད། + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + ཡིག་ཆའི་ཉེན་འགོག་སྒམ་ཆུང་གི་གསང་ལྡེ་སོར་ཆུད་པ། + + + + Generate a recovery key in case that you forgot the password + གལ་ཏེ་གསང་ཨང་བརྗེད་ཚེ། གསང་ལྡེ་འདི་སྤྱད་དེ་ལྟ་སྤྱོད་སོར་ཆུད་ཆོག + + + + Key + གསང་ལྡེ། + + + + QR code + རྩ་གཉིས་ཨང་བཤེར། + + + + Scan QR code and save the key to another device + རྩ་གཉིས་ཨང་བཤེར་བཤེར་ནས་སྒྲིག་ཆས་གཞན་དུ་ཉར་ཚགས་བྱེད་པ། + + + + Next + གོམ་སྟབས་རྗེས་མ། + + + + Recovery Key: + ཡིག་ཆའི་ཉེན་འགོག་སྒམ་ཆུང་གི་གསང་ལྡེ་སོར་ཆུད་པ། + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + སྒོ་ལྕགས་འབྱེད་ཐབས་སྒྲིག་འགོད། + + + + Method + རིགས་གྲས། + + + + Manual + ལག་སྒུལ། + + + + Password + གསང་ཨང་། + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ཉུང་མཐར་ཡང་གྲངས་8དགོས་པ་དང་། A-Z, a-z, 0-9དང་མཚོན་རྟགས་ཚུད་དགོས། + + + + Repeat password + བསྐྱར་ཟློས་གསང་ཨང་། + + + + Input the password again + གསང་ཨང་ཡང་བསྐྱར་ནང་འཇུག་བྱེད་པ། + + + + Password hint + གསང་ཨང་དྲན་སྐུལ། + + + + Optional + བདམས་ནས་འབྲི་བ། + + + + Next + གོམ་སྟབས་རྗེས་མ། + + + + + Passwords do not match + ནང་འཇུག་བྱས་པའི་གསང་ཨང་གཅིག་མཚུངས་མིན་པ། + + + + DFMVaultActiveStartView + + + File Vault + ཡིག་ཆའི་ཉེན་འགོག་ལྕགས་སྒམ། + + + + Create your secure private space + སྒེར་ལ་དབང་ལ་བདེ་འཇགས་བར་སྟོང་། + + + + Advanced encryption technology + སྔོན་ཐོན་གྱི་གསང་སྡོམ་ལག་རྩལ་ལས། གསང་དོན་བདེ་འཇགས་ལ་འགན་སྲུང་བྱས་ཡོད། + + + + Convenient and easy to use + བེད་སྤྱོད་བྱེད་བདེ་བ་དང་། བཀོལ་སྤྱོད་སྟབས་བདེ་བ། + + + + Create + ཁ་འབྱེད། + + + + DFMVaultFileView + + + Cannot open this path + མིག་སྔའི་བརྒྱུད་ལམ་ཁ་ཕྱེ་ཐབས་མེད། + + + + Hint + དྲན་སྐུལ། + + + + OK + ཆོག + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + གསང་ལྡེ་འབྱེད་ཐབས་སོར་ཆུད་པ། + + + + Failed to unlock file vault + ཉེན་འགོག་སྒམ་ཆུང་སྒོ་ལྕགས་འབྱེད་མ་ཐུབ། + + + + OK + ཆོག + + + + Input the 32-digit recovery key + གྲངས་གནས་32ནང་འཇུག་བྱས་ཏེ་གསང་ལྡེ་སོར་ཆུད་པ། + + + + Cancel + button + འདོར་བ། + + + + Unlock + button + སྒོ་ལྕགས་འབྱེད་པ། + + + + Wrong recovery key + གསང་ལྡེ་ནོར་བ། + + + + DFMVaultRemoveByPasswordView + + + Password + གསང་ཨང་། + + + + Password hint: %1 + གསང་ཨང་དྲན་སྐུལ། %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + གྲངས་གནས་32ནང་འཇུག་བྱས་ཏེ་གསང་ལྡེ་སོར་ཆུད་པ། + + + + DFMVaultRemovePages + + + Delete File Vault + ཉེན་འགོག་སྒམ་ཆུང་བསུབ་པ། + + + + Once deleted, the files in it will be permanently deleted + ཉེན་འགོག་སྒམ་ཆུང་བསུབས་རྗེས། དེའི་ནང་གི་ནང་དོན་ཚང་མ་ཡོངས་སུ་བསུབས་ངེས་རེད། + + + + Use Key + གསང་ལྡེ་ར་སྤྲོད། + + + + Cancel + button + འདོར་བ། + + + + Use Key + button + གསང་ལྡེ་ར་སྤྲོད། + + + + Delete + button + སུབ་པ། + + + + + OK + button + ཆོག + + + + Use Password + གསང་ཨང་ར་སྤྲོད། + + + + Wrong password + གསང་ཨང་ནོར་བ། + + + + Wrong recovery key + གསང་ལྡེ་ནོར་བ། + + + + Failed to delete file vault + ཉེན་འགོག་སྒམ་ཆུང་བསུབས་མ་ཐུབ། + + + + Deleted successfully + བསུབས་པ། + + + + Failed to delete + བསུབས་མ་ཐུབ། + + + + Removing... + སུབ་བཞིན་པ། + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + གསང་ལྡེའི་ཡིག་ཆ་ཐོབ་ཐབས་མེད། + + + + Verification failed + གསང་ལྡེ་ར་སྤྲོད་བྱེད་མ་ཐུབ། + + + + + Select a path + གསང་ལྡེའི་ཡིག་ཆའི་ཉར་ཚགས་བརྒྱུད་ལམ་འདེམས་རོགས། + + + + + Retrieve Password + གསང་ཨང་འཚོལ་བ། + + + + By key in the default path + སོར་བཞག་བརྒྱུད་ལམ་གྱི་གསང་ལྡེའི་ཡིག་ཆ་བརྒྱུད་ནས་གསང་ཨང་འཚོལ་བ། + + + + By key in the specified path + དམིགས་བཙུགས་བརྒྱུད་ལམ་གྱི་གསང་ལྡེའི་ཡིག་ཆ་བརྒྱུད་ནས་གསང་ཨང་འཚོལ་བ། + + + + Verification Successful + གསང་ལྡེ་ར་སྤྲོད་ལེགས་གྲུབ་བྱུང་བ། + + + + Keep it safe + ཉར་ཚགས་ལེགས་པོ་བྱེད་རོགས། + + + + Back + button + ཕྱིར་བཤོལ། + + + + Verify Key + button + ར་སྤྲོད་གསང་ལྡེ། + + + + Go to Unlock + button + སྒོ་ལྕགས་ཕྱེ་བར་ལོག་པ། + + + + Close + button + སྒོ་བརྒྱབ། + + + + Vault password: %1 + ཉེན་འགོག་སྒམ་ཆུང་གི་གསང་ཨང་ནི་%1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + ཉེན་འགོག་སྒམ་ཆུང་སྒོ་ལྕགས་འབྱེད་པ། + + + + Forgot password? + གསང་ཨང་བརྗེད་འདུག་གམ། + + + + Password hint: %1 + གསང་ཨང་དྲན་སྐུལ། %1 + + + + Failed to unlock file vault + ཉེན་འགོག་སྒམ་ཆུང་སྒོ་ལྕགས་འབྱེད་མ་ཐུབ། + + + + Cancel + button + འདོར་བ། + + + + Password + གསང་ཨང་། + + + + Unlock + button + སྒོ་ལྕགས་འབྱེད་པ། + + + + Please try again %1 minutes later + སྐར་མ་%1རྗེས་ལ་ཚོད་ལྟ་གྱིས་དང་། + + + + Wrong password, please try again %1 minutes later + གསང་ཨང་ནོར་འདུག སྐར་མ་%1རྗེས་ལ་ཚོད་ལྟ་གྱིས་དང་། + + + + Wrong password, one chance left + གསང་ཨང་ནོར་འདུག ཁྱེད་ཀྱིས་ད་དུང་ཚོད་ལྟ་ཐེངས་1བྱས་ཆོག + + + + Wrong password, %1 chances left + གསང་ཨང་ནོར་འདུག ཁྱེད་ཀྱིས་ད་དུང་ཚོད་ལྟ་ཐེངས་%1བྱས་ཆོག + + + + Wrong password + གསང་ཨང་ནོར་བ། + + + + OK + button + ཆོག + + + + DFileCopyMoveJob + + + Permission error + ཡིག་ཆའི་དབང་ཚད་ནོར་བ། + + + + The action is denied + བཀོལ་སྤྱོད་འདིར་ཡིག་ཆའི་རྒྱབ་སྐྱོར་མེད། + + + + Failed to open the file + ཡིག་ཆ་ཁ་ཕྱེ་མ་ཐུབ། + + + + Failed to read the file + ཡིག་ཆའི་ནང་དོན་ཀློག་མ་ཐུབ། + + + + Failed to write the file + ཡིག་ཆའི་ནང་དོན་འབྲི་མ་ཐུབ། + + + + Failed to create the directory + དཀར་ཆག་བཟོ་མ་ཐུབ། + + + + Failed to delete the file + ཡིག་ཆ་བསུབས་མ་ཐུབ། + + + + Failed to move the file + ཡིག་ཆ་སྤོ་མ་ཐུབ། + + + + Original file does not exist + ཁུངས་ཡིག་ཆ་མེད་པ། + + + + Failed, file size must be less than 4GB + བཀོལ་སྤྱོད་བྱེད་མ་ཐུབ། ཡིག་ཆའི་ཆེ་ཆུང་ཚད་4GBལས་བརྒལ་འདུག + + + + Not enough free space on the target disk + དམིགས་འབིན་སྡུད་སྡེར་གྱི་ཤོང་ཚད་མི་འདང་བ། + + + + File integrity was damaged + ཡིག་ཆའི་ཆ་ཚང་རང་བཞིན་ལ་ཞིབ་བཤེར་བྱེད་མ་ཐུབ། + + + + The target device is read only + དམིགས་འབེན་སྒྲིག་ཆས་ནི་ཀློག་ཙམ་རེད་འདུག + + + + Target folder is inside the source folder + དམིགས་འབེན་ཡིག་ཁུག་ནི་ཁུངས་ཡིག་ཁུག་ནང་ཡོད། + + + + The action is not supported + བཀོལ་སྤྱོད་འདིར་རྒྱབ་སྐྱོར་མེད། + + + + You do not have permission to traverse files in it + ཁྱོད་ལ་ཡན་ལག་ཡིག་ཆར་ལྟ་སྤྱོད་བྱེད་དབང་མེད། + + + + Failed to position the file pointer! + ཕྱོགས་སྟོན་གནས་ས་གཏན་འཁེལ་བྱེད་མ་ཐུབ། + + + + copy + Extra name added to new file name when used for file name. + བུ་ཡིག + + + + Failed to open the directory, cause: file name too long + དཀར་ཆག་ཁ་ཕྱེ་མ་ཐུབ། རྒྱུ་མཚན་ནི་ཡིག་ཆའི་མིང་རིང་དྲགས་པ། + + + + + Failed to open the file, cause: file name too long + ཡིག་ཆ་ཁ་ཕྱེ་མ་ཐུབ། རྒྱུ་མཚན་ནི་ཡིག་ཆའི་མིང་རིང་དྲགས་པ། + + + + + Failed to write the file, cause: + ཡིག་ཆའི་ནང་དོན་འབྲི་མ་ཐུབ། རྒྱུ་མཚན་ནི། + + + + Failed to position the file pointer, cause: %1 + ཕྱོགས་སྟོན་གནས་ས་གཏན་འཁེལ་བྱེད་མ་ཐུབ། རྒྱུ་མཚན་ནི་%1 + + + + Syncing data + གཞི་གྲངས་མཉམ་བགྲོད་བྱེད་བཞིན་པ། + + + + Please wait + སྒུག་རོགས། + + + + Failed to create the directory, cause: %1 + དཀར་ཆག་བཟོ་མ་ཐུབ། རྒྱུ་མཚན་ནི་%1 + + + + + + + + Failed to open the file, cause: %1 + ཡིག་ཆ་ཁ་ཕྱེ་མ་ཐུབ། རྒྱུ་མཚན་ནི་%1 + + + + + + + Failed to open the file, cause: Permission denied + ཡིག་ཆ་ཁ་ཕྱེ་མ་ཐུབ། རྒྱུ་མཚན་ནི་དབང་ཚད་མི་འདང་བ། + + + + + Failed to read the file, cause: %1 + ཡིག་ཆའི་ནང་དོན་ཀློག་མ་ཐུབ། རྒྱུ་མཚན་ནི་%1 + + + + + + + Failed to write the file, cause: %1 + ཡིག་ཆའི་ནང་དོན་འབྲི་མ་ཐུབ། རྒྱུ་མཚན་ནི་%1 + + + + + File integrity was damaged, cause: %1 + ཡིག་ཆའི་ཆ་ཚང་རང་བཞིན་ལ་ཞིབ་བཤེར་བྱེད་མ་ཐུབ། རྒྱུ་མཚན་ནི་%1 + + + + Failed to open the file, cause: + ཡིག་ཆ་ཁ་ཕྱེ་མ་ཐུབ། རྒྱུ་མཚན་ནི། + + + + Failed to read the file, cause: + ཡིག་ཆའི་ནང་དོན་ཀློག་མ་ཐུབ། རྒྱུ་མཚན་ནི། + + + + Failed to delete the file, cause: %1 + ཡིག་ཆ་བསུབས་མ་ཐུབ། རྒྱུ་མཚན་ནི་%1 + + + + Fail to create symlink, cause: %1 + སྦྲེལ་མཐུད་བཟོ་མ་ཐུབ། རྒྱུ་མཚན་ནི་%1 + + + + DFileDialog + + + + Save + button + ཉར་ཚགས། + + + + + Cancel + button + འདོར་བ། + + + + Confirm + button + ཆོག + + + + %1 already exists, do you want to replace it? + “%1”ཡོད་པས། ཁྱོད་ཀྱིས་བརྗེ་རྒྱུ་ཡིན་ནམ། + + + + Replace + button + བརྗེ་བ། + + + + Open + button + ཡིག་ཆ་ཁ་འབྱེད་པ། + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + ཡིག་ཆའི་མིང་ (.). བྱས་ཚེ་ཡིག་ཆ་འདི་ཉིད་ཡིབ་སྲིད་པས། མུ་མཐུད་བྱེད་དགོས་མིན་གཏན་འཁེལ་བྱེད་རོགས། + + + + DFileManagerWindow + + + Trash + སྙིགས་སྣོད། + + + + Empty + གཙང་སེལ། + + + + DFileSystemModel + + + + Name + མིང་། + + + + + + Time modified + བཟོ་བཅོས་དུས་ཚོད། + + + + Size + ཆེ་ཆུང་། + + + + Type + རིགས་གྲས། + + + + Time created + བཟོ་བའི་དུས་ཚོད། + + + + + Last access + ཉེ་ཆར་གྱི་ལྟ་སྤྱོད་དུས་ཚོད། + + + + + + + Path + འགྲོ་ལམ། + + + + DFileView + + + Disc mount error + སྡུད་སྡེར་འགེལ་བ་ནོར་འདུག + + + + The disc is in use, please end the running process and remount the disc. + མིག་སྔར་སྡུད་སྡེར་བེད་སྤྱོད་བྱེད་བཞིན་འདུག་པས། སྔོན་ལ་དེ་ཉིད་ཁ་བརྒྱབ་རྗེས་ཡང་བསྐྱར་འགེལ། + + + + Mounting failed + འགེལ་མ་ཐུབ། + + + + (Reverse) + (གོ་རིམ་ལྡོག་པ།) + + + + DFileViewHelper + + + Add tag "%1" + རྟགས་རིས་“%1”སྣོན་པ། + + + + DStatusBar + + + %1 item + ཚན་པ་%1 + + + + %1 items + ཚན་པ་%1 + + + + %1 item selected + ནང་དོན་%1བདམས་པ། + + + + %1 items selected + ནང་དོན་%1བདམས་པ། + + + + %1 folder selected (contains %2) + ཡིག་ཁུག་%1བདམས་པ། (%2ཚུད།) + + + + %1 folders selected (contains %2) + ཡིག་ཁུག་%1བདམས་པ། (%2ཚུད།) + + + + %1 file selected (%2) + ཡིག་ཆ་%1བདམས་པ། (%2) + + + + %1 files selected (%2) + ཡིག་ཆ་%1བདམས་པ། (%2) + + + + %1 folder selected + ཡིག་ཁུག་%1བདམས་པ། + + + + Filter + འཚག་རྒྱག + + + + Save as: + ཉར་ཚགས་བྱེད། + + + + Loading... + སྣོན་འཇུག་བྱེད་བཞིན་པ། + + + + DTaskDialog + + + Erasing disc %1, please wait... + %1སུབ་བཞིན་ཡོད་པས། ཏོག་ཙམ་སྒུག་རོགས། + + + + Burning disc %1, please wait... + %1ཕབ་བརྐོ་བྱེད་བཞིན་ཡོད་པས། ཏོག་ཙམ་སྒུག་རོགས། + + + + Writing data... + གཞི་གྲངས་འབྲི་བཞིན་པ། + + + + Verifying data... + གཞི་གྲངས་དག་བཤེར་བྱེད་བཞིན་པ། + + + + Copying %1 + %1པར་སློག་བྱེད་བཞིན་པ། + + + + + + to %2 + %2སླེབས་པ། + + + + %1 already exists in target folder + དམིགས་འབེན་ཡིག་ཁུག་ནང་མིང་%1བྱས་པའི་ཡིག་ཆ་འདུག + + + + Original path %1 Target path %2 + ཐོག་མའི་འགྲོ་ལམ་%1 དང་། དམིགས་འབེན་འགྲོ་ལམ་%2 + + + + Merge + button + ཟླ་སྒྲིལ། + + + + Replace + button + བརྗེ་བ། + + + + Moving %1 + %1སྤོ་བཞིན་པ། + + + + Removing file vault, please try later + ཉེན་འགོག་སྒམ་ཆུང་སུབ་བཞིན་ཡོད་པས། སྒུག་རོགས། + + + + Restoring %1 + སོར་ཆུད་བཞིན་པ་%1 + + + + Deleting %1 + སུབ་བཞིན་པ་%1 + + + + Trashing %1 + %1སྤོ་བཞིན་པ། + + + + Calculating space, please wait + ཆེ་ཆུང་རྩི་བཞིན་ཡོད་པས། ཏོག་ཙམ་སྒུག་རོགས། + + + + DUMountManager + + + + Authentication timed out + དཔང་དཔྱད་དུས་བརྒལ། + + + + + + Disk is busy, cannot unmount now + སྡུད་སྡེར་ཡིག་ཆ་གཞན་གྱིས་བཟུང་ཡོད་པས། བཤིག་འདོན་བྱེད་ཐབས་བྲལ། + + + + Disk is busy, cannot eject now + སྡུད་སྡེར་ཡིག་ཆ་གཞན་གྱིས་བཟུང་ཡོད་པས། ཕྱིར་དོན་ཐབས་བྲལ། + + + + The device is busy, cannot eject now + འོད་སྡེར་བྲེལ་བཞིན་འདུག་པས། ཕྱིར་བཏོན་ཐབས་བྲལ། + + + + + + The device is busy, cannot remove now + འོད་སྡེར་བྲེལ་བཞིན་འདུག་པས། བདེ་འཇགས་ངང་ཕྱིར་བཏོན་ཐབས་བྲལ། + + + + DeepinStorage + + + + + %1 Volume + བམ་པོ་%1  + + + + Data Disk + Data Partition + གཞི་གྲངས་སྡེར། + + + + %1 Drive + སྐུལ་ཆས་%1  + + + + Blank %1 Disc + འོད་སྡེར་སྟོང་པ་%1  + + + + %1 Encrypted + གསང་སྡོམ་%1  + + + + DialogManager + + + + + + Operation failed! + བཀོལ་སྤྱོད་བྱེད་མ་ཐུབ། + + + + Target folder is inside the source folder! + དམིགས་འབེན་ཡིག་ཁུག་ཁུངས་ཡིག་ཁུག་ནང་འདུག + + + + Do you want to run %1 or display its content? + “%1”འཁོར་སྐྱོད་བྱེད་རྒྱུ་ཡིན་ནམ་ཡང་ན་དེའི་ནང་དོན་མངོན་སྟོན་བྱེད་དགོས། + + + + It is an executable text file. + དེ་ལག་བསྟར་བྱེད་ཆོག་པའི་ཡིག་རྐྱང་ཡིག་ཆ་ཡིན། + + + + It is an executable file. + དེ་ལག་བསྟར་བྱེད་ཆོག་པའི་ཡིག་ཆ་ཞིག་ཡིན། + + + + This file is not executable, do you want to add the execute permission and run? + ཡིག་ཆ་འདིར་ལག་བསྟར་བྱེད་དབང་མེད་པས། དབང་ཚད་སྣོན་ཏེ་འཁོར་སྐྱོད་བྱེད་དགོས་སམ། + + + + "%1" already exists, please use another name. + ཡིག་ཆ་"%1" བཟུང་ཟིན་པས། མིང་གཞན་སྤྱོད་རོགས། + + + + The file name must not contain two dots (..) + ཡིག་ཆའི་མིང་ནང་ཚེག་གཉིས་ཡོད་མི་ཆོག (..) + + + + Device or resource busy + སྒྲིག་ཆས་སམ་ཐོན་ཁུངས་བྲེལ་བཞིན་པ། + + + + Are you sure you want to erase all data on the disc? + ཁྱོད་ཀྱིས་འོད་སྡེར་འདིའི་ནང་དོན་ཚང་མ་བསུབ་རྒྱུ་ཡིན་པ་གཏན་ཁེལ་ལམ། + + + + How do you want to use this disc? + ཁྱོད་ཀྱིས་འོད་སྡེར་འདི་བེད་སྤྱོད་བྱས་ཏེ་ཤེལ་བརྙན་ཕབ་བརྐོ་བྱེད་པ་ཡིན་ཡང་ན་ཡིག་ཆ་ཉར་གསོག་བྱེད་པ་ཡིན། + + + + Disc erase failed + བསུབས་མ་ཐུབ། + + + + Burn process failed + ཕབ་བརྐོ་བྱེད་མ་ཐུབ། + + + + %1: %2 + %1:%2 + + + + Show details + ཞིབ་ཕྲའི་གནས་ཚུལ་མངོན་སྟོན། + + + + Hide details + ཞིབ་ཕྲའི་གནས་ཚུལ་ཡིབ་པ། + + + + Error + ཆ་འཕྲིན་ནོར་བ། + + + + Permanently delete %1? + ཁྱོད་ཀྱིས་%1ཡོངས་སུ་བསུབ་རྒྱུ་ཡིན་པ་གཏན་ཁེལ་ལམ། + + + + Permanently delete %1 items? + ཁྱོད་ཀྱིས་བདམས་ཡོད་པའི་ནང་དོན་%1ཡོངས་སུ་བསུབ་རྒྱུ་ཡིན་པ་གཏན་ཁེལ་ལམ། + + + + Empty + གཙང་སེལ། + + + + Do you want to delete %1? + %1བསུབ་དགོས་སམ། + + + + Do you want to delete the selected %1 items? + བདམས་ཟིན་པའི་ནང་དོན་%1བསུབ་དགོས་སམ། + + + + Sorry, unable to locate your bookmark directory, remove it? + དགོངས་དག་ཞུ། ཁྱོད་ཀྱི་དཀར་ཆག་རྙེད་ཐུབ་མ་སོང་བས། སྤོ་དགོས་སམ། + + + + Name: + མིང་། + + + + %1 that this shortcut refers to has been changed or moved + མྱུར་ལམ་འདིས་སྟོན་པའི་“%1”སྒྱུར་ཟིན་པའམ་སྤོས་འདུག + + + + Do you want to delete this shortcut? + མྱུར་ལམ་འདི་བསུབ་དགོས་སམ། + + + + Failed, file size must be less than 4GB. + བཀོལ་སྤྱོད་བྱེད་མ་ཐུབ། ཡིག་ཆའི་ཆེ་ཆུང་ཚད་4GBལས་བརྒལ་འདུག + + + + Fail to create symlink, cause: + སྦྲེལ་མཐུད་བཟོ་མ་ཐུབ། རྒྱུ་མཚན་ནི། + + + + The selected files contain system file/directory, and it cannot be deleted + བདམས་ཟིན་པའི་ཡིག་ཆའི་ནང་རྒྱུད་ཁོངས་ཀྱི་དཀར་ཆག་ཚུད་ཡོད་པས། སུབ་ཐབས་མི་འདུག + + + + Unable to find the original file + དམིགས་འབེན་ཡིག་ཆའི་འབྲེལ་མཐུད་རྙེད་ཐབས་བྲལ། + + + + + You do not have permission to operate file/folder! + ཁྱོད་ལ་ཡིག་ཆ་/ཡིག་ཁུག་བཀོལ་སྤྱོད་བྱེད་དབང་མེད། + + + + Failed to restore %1 file, the source file does not exist + ཐོག་མའི་ཡིག་ཆ་བསྡད་མེད། ཡིག་ཆ་%1སོར་ཆུད་མ་ཐུབ། + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + དགོངས་དག་ཞུ། ཁྱོད་ལ་གཤམ་གྱི་ཡིག་ཆ་/ཡིག་ཁུག་%1བཀོལ་སྤྱོད་བྱེད་དབང་མེད། + + + + Unable to access %1 + ལྟ་སྤྱོད་%1བྱེད་མ་ཐུབ། + + + + + Sending files now, please try later + མིག་སྔར་སྐུར་བཞིན་པའི་ཡིག་ཆ་ཡོད་པས། ཏོག་ཙམ་ནས་ཡང་བསྐྱར་ཚོད་ལྟ་བྱེད། + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + སྡུད་སྡེར་རྣམ་གཞག་ཅན་དུ་འགྱུར་ཚེ་གཞི་ནས་སྒྲིག་ཆས་འདིར་ལྟ་སྤྱོད་བྱེད་ཐུབ། མུ་མཐུད་བྱེད་དགོས་སམ། + + + + Scanning the device, stop it? + མིག་སྔའི་སྒྲིག་ཆས་བཤར་འབེབས་བཞིན་ཡོད་པས། བཤེར་འབེབས་མཚམས་འཇོག་རྒྱུ་ཡིན་ནམ། + + + + Share folder can't be named after the current username + མཉམ་སྤྱོད་ཡིག་ཁུག་གི་མིང་མིག་སྔའི་སྤྱོད་མཁན་མིང་དང་གཅིག་པ་ཡིན་མི་རུང་། + + + + Do you want to run %1? + ཁྱོད་ཀྱིས་“%1”འཁོར་སྐྱོད་བྱེད་རྒྱུ་ཡིན་ནམ། + + + + Burn image + button + ཤེལ་བརྙན་ཕབ་བརྐོ། + + + + Burn files + button + ཡིག་ཆ་ཉར་གསོག + + + + Are you sure you want to empty %1 item? + ཁྱོད་ཀྱིས་སྙིགས་སྣོད་ནང་གི་ནང་དོན་“%1”གཙང་སེལ་བྱེད་རྒྱུ་གཏན་ཁེལ་ལམ། + + + + Are you sure you want to empty %1 items? + ཁྱོད་ཀྱིས་སྙིགས་སྣོད་ནང་གི་ནང་དོན་“%1”གཙང་སེལ་བྱེད་རྒྱུ་གཏན་ཁེལ་ལམ། + + + + + This action cannot be undone + བཀོལ་སྤྱོད་འདི་བྱས་ཚེ་སོར་ཆུད་མི་ཐུབ། + + + + + + + + + + + + + + OK + button + ཆོག + + + + + + + + + + + + + + + Cancel + button + འདོར་བ། + + + + + + Run + button + འཁོར་སྐྱོད། + + + + + Run in terminal + button + མཐའ་སྣེའི་ནང་འཁོར་སྐྱོད་བྱེད། + + + + Display + button + མངོན་སྟོན། + + + + + + + + + + + Confirm + button + ཆོག + + + + Erase + button + སུབ་པ། + + + + Data verification failed + གཞི་གྲངས་ར་སྤྲོད་བྱེད་མ་ཐུབ། + + + + Show details + button + ཞིབ་ཕྲའི་གནས་ཚུལ་མངོན་སྟོན། + + + + + Delete + button + སུབ་པ། + + + + Remove + button + སྤོ་བ། + + + + Disk is busy, cannot unmount now + སྡུད་སྡེར་ཡིག་ཆ་གཞན་གྱིས་བཟུང་ཡོད་པས། བཤིག་འདོན་བྱེད་ཐབས་བྲལ། + + + + Force unmount + button + བཙན་ཤེད་ཀྱིས་བཤིག་འདོན་བྱེད། + + + + Unable to copy. Not enough free space on the target disk. + དམིགས་འབེན་སྡུད་སྡེར་གྱི་ཤོང་ཚད་མི་འདང་བས། པར་སློག་བྱེད་ཐབས་བྲལ། + + + + Failed to restore %1 file, the target folder is read-only + ཡིག་ཆ་%1སོར་ཆུད་ཐུབ་མ་སོང་། དམིགས་འབེན་ཡིག་ཁུག་འབྲི་མི་རུང་། + + + + Failed to restore %1 files, the target folder is read-only + ཡིག་ཆ་%1སོར་ཆུད་ཐུབ་མ་སོང་། དམིགས་འབེན་ཡིག་ཁུག་འབྲི་མི་རུང་། + + + + Failed to restore %1 files, the source files do not exist + ཐོག་མའི་ཡིག་ཆ་བསྡད་མེད། ཡིག་ཆ་%1སོར་ཆུད་མ་ཐུབ། + + + + Format + button + རྣམ་གཞག་ཏུ་སྒྱུར་བ། + + + + Stop + button + མཚམས་འཇོགས། + + + + FileController + + + + + + Unable to find the original file + དམིགས་འབེན་ཡིག་ཆའི་འབྲེལ་མཐུད་རྙེད་ཐབས་བྲལ། + + + + + + Kindly Reminder + མཛའ་བརྩེའི་དྲན་སྐུལ། + + + + + + Please install File Roller first and then continue + སྔོན་ལ་ཉེར་ཚགས་དོ་དམ་བྱེད་ཆས་སྒྲིག་འཇུག་བྱེད་པ་དང་། དེ་རྗེས་མུ་མཐུད་བྱེད། + + + + + Unable to create files here: %1 + འདིར་ཡིག་ཆ་བཟོ་མ་ཐུབ། %1 + + + + Confirm + button + ཆོག + + + + FileDialogStatusBar + + + File Name + ཡིག་ཆའི་མིང་། + + + + Format + རྣམ་གཞག + + + + Save + button + ཉར་ཚགས། + + + + Open + button + ཡིག་ཆ་ཁ་འབྱེད་པ། + + + + Save File + button + ཡིག་ཆ་ཉར་ཚགས། + + + + Open File + button + ཡིག་ཆ་ཁ་ཕྱེ། + + + + + + Cancel + button + འདོར་བ། + + + + FileJob + + + copy + བུ་ཡིག + + + + + + + Data verification successful. + གཞི་གྲངས་ར་སྤྲོད་ལེགས་གྲུབ་བྱུང་བ། + + + + + + Burn process completed + ཕབ་བརྐོ་ལེགས་གྲུབ་བྱུང་། + + + + %1 s + སྐར་ཆ་%1  + + + + %1 m %2 s + སྐར་མ་%1 དང་སྐར་ཆ་ %2 + + + + %1 h %2 m %3 s + ཆུ་ཚོད་%1 དང་སྐར་མ་ %2 སྐར་ཆ་ %3 + + + + %1 d %2 h %3 m %4 s + ཉིན་གྲངས་%1དང་ཆུ་ཚོད་ %2སྐར་མ་ %3 སྐར་ཆ་%4 + + + + %1 is a duplicate file. + %1བསྐྱར་ཟློས་ཡིག་ཆ། + + + + Insufficient disc space. + འོད་སྡེར་གྱི་ཤོང་ཚད་མི་འདང་བ། + + + + Lost connection to drive. + སྡེར་སྐུལ་དང་སྦྲེལ་ཐག་བཅད་པ། + + + + The CD/DVD drive is not ready. Try another disc. + སྡེར་སྐུར་གྲ་སྒྲིག་ཡག་པོ་བྱས་མེད་པས། ཁྱོད་ཀྱིས་འོད་སྡེར་བརྗེས་རྗེས་ཡང་བསྐྱར་ཚོད་ལྟ་བྱ་ཆོག + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + སྡེར་སྐུར་བཟུང་སྤྱོད་བྱས་འདུག་པས། ཁྱོད་ཀྱིས་ད་ལྟ་སྤྱོད་བཞིན་པའི་སྡེར་སྐུར་གྱི་བྱ་རིམ་སྒོ་བརྒྱབ་རྗེས་ཡང་་བསྐྱར་སྡེར་སྐུར་བཅུག་ཆོག + + + + Unknown error + རྒྱུས་མེད་པའི་ནོར་འཁྲུལ། + + + + Device disconnected + འོད་སྡེར་སྒྲིག་ཆས་འབྲེལ་མཐུད་བྱས་མེད། + + + + GenerateSettingTranslate + + + + + Basic + གཞི་རྩའི་སྒྲིག་འགོད། + + + + + + Open behavior + ཁ་འབྱེད་པའི་བྱ་སྤྱོད། + + + + + + Always open folder in new window + རྟག་ཏུ་སྒེའུ་ཁུང་གསར་པའི་ནང་ཡིག་ཁུག་ཁ་འབྱེད་པ། + + + + + + Open file: + ཡིག་ཆ་ཁ་ཕྱེ། + + + + + + Click + གཅིག་རྡེབ། + + + + + + Double click + ཉིས་རྡེབ། + + + + + + New window and tab + སྒེའུ་ཁུང་གསར་པ་དང་ཤོག་བྱང་གསར་པ། + + + + + + Open from default window: + སོར་བཞག་སྒེའུ་ཁུང་ནས་ཁ་འབྱེད་པ། + + + + + + + + + Computer + རྩིས་འཁོར། + + + + + + + + + Home + དཀར་ཆག་གཙོ་བོ། + + + + + + + + + Desktop + ཅོག་ངོས། + + + + + + + + + Videos + བརྙན་འཕྲིན། + + + + + + + + + Music + རོལ་མོ། + + + + + + + + + Pictures + པར་རིས། + + + + + + + + + Documents + ཡིག་ཆ། + + + + + + + + + Downloads + ཕབ་ལེན། + + + + + + Open in new tab: + ཤོག་བྱང་གསར་པ་ནས་ཁ་ཕྱེ། + + + + + + Current Directory + མིག་སྔའི་དཀར་ཆག + + + + + + View + མཐོང་རིས། + + + + + + Default size: + སོར་བཞག་ཆེ་ཆུང་། + + + + + + Extra small + ཆུང་གྲས། + + + + + + Small + ཆུང་། + + + + + + Medium + འབྲིང་། + + + + + + Large + ཆེ། + + + + + + Extra large + ཆེ་གྲས། + + + + + + Default view: + སོར་བཞག་མཐོང་རིས། + + + + + + Icon + རྟགས་རིས་མཐོང་རིས། + + + + + + List + གསལ་ཐོའི་མཐོང་རིས། + + + + + + Hidden files + ཡིབ་པའི་ཡིག་ཆ། + + + + + + Show hidden files + ཡིབ་པའི་ཡིག་ཆ་མངོན་སྟོན། + + + + + + Hide file extension when rename + ཡང་བསྐྱར་མིང་འདོགས་སྐབས་ཡིག་ཆའི་རྒྱ་སྐྱེད་མིང་ཡིབ་པ། + + + + + + Advanced + མཐོ་རིམ་སྒྲིག་འགོད། + + + + + + Index + གསལ་བྱང་། + + + + + + Auto index internal disk + རང་གསལ་བྱང་གི་ནང་བཅུག་སྡུད་སྡེར། + + + + + + Index external storage device after connected to computer + གློག་ཀླད་དང་སྦྲེལ་རྗེས་ཕྱིའི་ཉར་གསོག་སྒྲིག་ཆས་འདྲེན་པ། + + + + + + Full-Text search + རྩོམ་ཡིག་ཧྲིལ་པོར་བཤེར་འཚོལ་བྱེད། + + + + + + Show item counts and sizes in the path of mounted MTP devices + MTPའཇུག་སྣོན་ཐབས་ཤེས་འོག་ཡིག་ཆའི་སྡོམ་རྩིས་ཞིབ་ཕྲ་གསལ་བ། + + + + + + Keep showing the mounted Samba shares + Sambaམཉམ་སྤྱོད་སྣེ་ཡིས་རྒྱུན་དུ་སྣོན་འཇུག་ཁ་འཆར་གྱི་འདུག + + + + + + Use the file chooser dialog of File Manager + ཡིག་ཆ་དོ་དམ་ཆས་ཀྱི་ཡིག་ཆ་བེད་སྤྱོད་བྱས་ཏེ་གླེང་སྒྲོམ་འདེམས་པ། + + + + + + Ask for my confirmation when deleting files + སྤྱིར་བཏང་གི་བསུབ་རྒྱུའི་དྲན་སྐུལ་ཁ་ཕྱེ་བ། + + + + + + Other + གཞན། + + + + + + Hide system disk + རྒྱུད་ཁོངས་སྡེར་ཡིབ་པ། + + + + + + Show file system on disk icon + སྡུད་སྡེར་གྱི་པར་རིས་ཐོག་ཡིག་ཆའི་རྒྱུད་ཁོངས་ཀྱི་གདོང་འཛར་མངོན་སྟོན། + + + + + + Show hidden files in search results + བཙལ་འབྲས་ནང་ཡིབ་པའི་ཡིག་ཆ་མངོན་སྟོན་བྱེད། + + + + + + Display recent file entry in left panel + ཉེ་ཆར་བེད་སྤྱོད་བྱས་པའི་ཡིག་ཆ་མངོན་སྟོན་བྱེད། + + + + + + Preview + སྔོན་ལྟ། + + + + + Compress file preview + སྡུད་སྒྲིལ་ཁུག་མར་སྔོན་ལྟ། + + + + + + Text preview + ཡིག་ཆ་སྔོན་ལྟ། + + + + + + Document preview + ཡིག་ཆ་སྔོན་ལྟ། + + + + + + Image preview + པར་རིས་སྔོན་ལྟ། + + + + + + Video preview + བརྙན་འཕྲིན་སྔོན་ལྟ། + + + + + + Mount + འཇུག་པ། + + + + + + Auto mount + རང་འཇུག + + + + + + Open after auto mount + རང་འཇུག་བྱས་རྗེས་ཁ་ཕྱེ། + + + + + + Dialog + གླེང་སྒྲོམ། + + + + Compressed file preview + སྡུད་སྒྲིལ་ཡིག་ཆར་སྔོན་ལྟ། + + + + GvfsMountManager + + + Can’t verify the identity of %1. + %1ཡི་ཐོབ་ཐང་ངོས་འཛིན་བྱེད་ཐབས་བྲལ། + + + + This happens when you log in to a computer the first time. + ཁྱོད་རང་ཐེངས་དང་པོར་ཐོ་འཇུག་བྱེད་སྐབས་དྲན་སྐུལ་འདི་མཐོང་སྲིད། + + + + The identity sent by the remote computer is + རྒྱང་སྟོན་གློག་ཀླད་ཀྱིས་བསྐུར་བའི་ཐོབ་ཐང་གི་ཆ་འཕྲིན་ནི། + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + མུ་མཐུད་བཀོལ་སྤྱོད་བྱས་ཚེ་བདེ་འཇགས་ཡིན་མིན་གཏན་འཁེལ་བྱེད་དགོས་ན། རྒྱུད་ཁོངས་ཀྱི་དོ་དམ་པར་འབྲེལ་བ་བྱོས། + + + + + + + + Mounting device error + འཇུག་ཆས་ལ་ནོར་འཁྲུལ་ཤོར་བ། + + + + + Wrong username or password + སྤྱོད་མཁན་མིང་ངམ་གསང་ཨང་ནོར་བ། + + + + + + + + Confirm + button + ཆོག + + + + + Cannot find the mounted device + བབ་མཚུངས་ཀྱི་འགེལ་ཆས་རྙེད་མ་བྱུང་། + + + + No key available to unlock device + སྒྲིག་ཆས་སྒོ་འབྱེད་པའི་གསང་ལྡེ་མེད། + + + + The disk is mounted by user "%1", you cannot unmount it. + སྡུད་སྡེར་ནི་སྤྱོད་མཁན་“%1”གྱིས་བཅུག་པས། ཁྱོད་ལ་བཤིག་འདོན་བྱེད་དབང་མེད། + + + + Cannot unmount the device + སྒྲིག་ཆས་བཤིག་འདོན་བྱེད་ཐབས་བྲལ། + + + + Cannot eject the device "%1" + སྒྲིག་ཆས་"%1"ཕྱིར་འདོན་ཐབས་བྲལ། + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + དམིགས་འབེན་སྡུད་སྡེར་གྱི་ཤོང་ཚད་མི་འདང་བས། ཕབ་བརྐོ་བྱེད་ཐབས་བྲལ། + + + + MergedDesktopController + + + + Pictures + པར་རིས། + + + + + Music + རོལ་མོ། + + + + + Applications + ཉེར་སྤྱོད། + + + + + Videos + བརྙན་འཕྲིན། + + + + + Documents + ཡིག་ཆ། + + + + + Others + གཞན། + + + + MimeTypeDisplayManager + + + + Directory + དཀར་ཆག + + + + + + Application + ཉེར་སྤྱོད་བྱ་རིམ། + + + + + + Video + བརྙན་འཕྲིན། + + + + + + Audio + སྒྲ་ཟློས། + + + + + + Image + པར་རིས། + + + + + Archive + སྡུད་སྒྲིལ་ཡིག་ཆ། + + + + + + Text + ཡིག་ཆ། + + + + + Executable + ལག་བསྟར་བྱེད་ཆོག་པའི་བྱ་རིམ། + + + + + Backup file + གྲབས་ཉར་ཡིག་ཆ། + + + + + Unknown + མི་ཤེས་པ། + + + + MountAskPasswordDialog + + + Cancel + button + འདོར་བ། + + + + Connect + button + སྦྲེལ་མཐུད། + + + + Log in as + ཐོབ་ཐང་དང་སྦྲེལ་བ། + + + + Anonymous + སྐུང་མིང་། + + + + Registered user + སྤྱོད་མཁན་ཐོ་འགོད། + + + + Username + སྤྱོད་མཁན་མིང་། + + + + Domain + ཁོངས། + + + + Password + གསང་ཨང་། + + + + Remember password + གསང་ཨང་ངེས་པ། + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + འདོར་བ། + + + + Unlock + button + སྒོ་ལྕགས་འབྱེད་པ། + + + + Input password to decrypt the disk + གསང་ཨང་གིས་སྡུད་སྡེར་འདི་སྒོ་འབྱེད་པ། + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + ཁྱོད་ཀྱིས་%1ཡོངས་སུ་བསུབ་རྒྱུ་ཡིན་པ་གཏན་ཁེལ་ལམ། + + + + This file is too big for the trash + ཡིག་ཆ་འདི་ཆེ་དྲག་པས་སྙིགས་སྣོད་ནང་བཞག་ཐབས་བྲལ། + + + + The files are too big for the trash + ཡིག་ཆ་ཆེ་དྲག་པས་སྙིགས་སྣོད་ནང་བཞག་ཐབས་བྲལ། + + + + Are you sure you want to permanently delete %1 files? + ཁྱོད་ཀྱིས་ཡིག་ཆ་%1འདི་ཡོངས་སུ་བསུབ་རྒྱུ་ཡིན་པ་གཏན་ཁེལ་ལམ། + + + + Cancel + button + འདོར་བ། + + + + Delete + button + སུབ་པ། + + + + OpenWithDialog + + + Open with + ཁ་འབྱེད་སྟངས། + + + + Add other programs + བྱ་རིམ་གཞན་སྣོན་པ། + + + + Set as default + སོར་བཞག་ལ་འཇོག་པ། + + + + Cancel + button + འདོར་བ། + + + + Confirm + button + ཆོག + + + + Recommended Applications + ཉེར་སྤྱོད་འོས་སྦྱོར། + + + + Other Applications + ཉེར་སྤྱོད་གཞན། + + + + PathManager + + + Home + དཀར་ཆག་གཙོ་བོ། + + + + Desktop + ཅོག་ངོས། + + + + Videos + བརྙན་འཕྲིན། + + + + Music + རོལ་མོ། + + + + Pictures + པར་རིས། + + + + Documents + ཡིག་ཆ། + + + + Downloads + ཕབ་ལེན། + + + + + Trash + སྙིགས་སྣོད། + + + + + + System Disk + རྒྱུད་ཁོངས་སྡེར། + + + + Computers in LAN + དྲ་རྒྱའི་ཁྱིམ་མཚེས། + + + + My Shares + ངའི་མཉམ་སྤྱོད། + + + + Computer + རྩིས་འཁོར། + + + + Recent + ཉེར་ཆར་བེད་སྤྱོད་བྱས་པ། + + + + File Vault + ཡིག་ཆའི་ཉེན་འགོག་ལྕགས་སྒམ། + + + + PropertyDialog + + + Basic info + གཞི་རྩའི་ཆ་འཕྲིན། + + + + Open with + ཁ་འབྱེད་སྟངས། + + + + Sharing + མཉམ་སྤྱོད་དོ་དམ། + + + + Permissions + དབང་ཚད་དོ་དམ། + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + ཡིག་ཁུག་འདི་ཡིབ་པ། + + + + Hide this file + ཡིག་ཆ་འདི་ཡིབ་པ། + + + + Allow to execute as program + བྱ་རིམ་གྱིས་ལག་བསྟར་བྱེད་ཆོག + + + + QObject + + + + + + Size + ཆེ་ཆུང་། + + + + + + Contains + ཡིག་ཆའི་ཁ་གྲངས། + + + + + + Type + རིགས་གྲས། + + + + + + + + Time modified + བཟོ་བཅོས་དུས་ཚོད། + + + + Free space + སྤྱོད་རུང་བར་སྟོང་། + + + + Total space + སྤྱིའི་ཤོང་ཚད། + + + + + Time locked + སྒོ་ལྕགས་བརྒྱབ་པའི་དུས་ཚོད། + + + + Access denied + ཀློག་མི་རུང་བ་དང་འབྲི་མི་རུང་བ། + + + + + Executable + ལག་བསྟར་བྱེད་ཆོག་པའི་བྱ་རིམ། + + + + + Write only + འབྲི་རུང་ཡང་ཀློག་མི་རུང་བ། + + + + + Read only + ཀློག་ཙམ། + + + + + Read-write + འབྲི་ཀློག + + + + Others + གཞན། + + + + Owner + དབང་མཁན། + + + + Unconnected network shared directory + དྲ་བ་འབྲེལ་མེད་པའི་མཉམ་སྤྱོད་དཀར་ཆག + + + + Device type + སྒྲིག་ཆས་ཀྱི་རིགས། + + + + File system + ཡིག་ཆའི་རྒྱུད་ཁོངས། + + + + Group + ཚོགས་ཆུང་། + + + + + Open + ཁ་འབྱེད་པ། + + + + Lock + ལམ་སེང་སྒོ་ལྕགས་བརྒྱབ། + + + + Auto lock + སྒོ་ལྕགས་རང་བཞིན་གྱིས་རྒྱག་པ། + + + + Never + གཏན་ནས་མིན། + + + + 5 minutes + སྐར་མ་5 + + + + 10 minutes + སྐར་མ་10 + + + + 20 minutes + སྐར་མ་20 + + + + Delete File Vault + ཉེན་འགོག་སྒམ་ཆུང་བསུབ་པ། + + + + Unlock + སྒོ་ལྕགས་འབྱེད་པ། + + + + Unlock by key + གསང་ལྡེས་སྒོ་ཕྱེ་བ། + + + + Open + button + ཡིག་ཆ་ཁ་འབྱེད་པ། + + + + + Size: %1 + ཆེ་ཆུང་།%1 + + + + Type: %1 + རིགས་གྲས། %1 + + + + Size: 0 + ཆེ་ཆུང་།0 + + + + Items: %1 + ཡིག་ཆའི་ཁ་གྲངས།%1 + + + + + + + + + + Open in new window + སྒེའུ་ཁུང་གསར་པ་ནས་ཁ་ཕྱེ། + + + + + + + + + + Open in new tab + ཤོག་བྱང་གསར་པ་ནས་ཁ་ཕྱེ། + + + + Open with + ཁ་འབྱེད་སྟངས། + + + + + Compress + སྡུད་སྒྲིལ། + + + + Extract + བསྡུས་འགྲོལ། + + + + Extract here + མིག་སྔའི་ཡིག་ཁུག་ནང་བསྡུས་སྒྲོལ་བྱེད། + + + + Cut + དྲས་གཏུབ། + + + + Copy + པར་སློག + + + + Paste + སྦྱར་བ། + + + + + + + + Rename + མིང་ཡང་བསྐྱར་འདོགས་པ། + + + + + + + Remove + སྤོ་བ། + + + + Create link + སྦྲེལ་མཐུད་པ། + + + + Send to desktop + ཅོག་ངོས་སུ་སྐྱེལ་བ། + + + + Send to + སྐྱེལ་བ། + + + + Bluetooth + སོ་སྔོན། + + + + Add to bookmark + དཔེ་འཛར་སྣོན་པ། + + + + + + + Properties + ངོ་བོ། + + + + New folder + ཡིག་ཁུག་གསར་འཛུགས། + + + + New window + སྒེའུ་ཁུང་གསར་འཛུགས། + + + + Select all + ཆ་ཚང་འདེམས། + + + + + Clear recent history + ཉེ་ཆར་གྱི་ལྟ་སྤྱོད་མེད་པར་བཟོ་བ། + + + + + + Empty Trash + སྙིགས་སྣོད་གཙང་སེལ། + + + + Display as + མངོན་སྟོན་བྱེད་སྟངས། + + + + Sort by + སྟར་སྒྲིག་སྟངས། + + + + New document + ཡིག་ཆ་གསར་བཟོ། + + + + + Time created + བཟོ་བའི་དུས་ཚོད། + + + + + + Source path + ཐོག་མའི་འགྲོ་ལམ། + + + + Share folder + མཉམ་སྤྱོད་ཡིག་ཁུག + + + + Cancel sharing + མཉམ་སྤྱོད་མི་བྱེད་པ། + + + + Connect to Server + ཞབས་ཞུ་འཕྲུལ་ཆས་དང་སྦྲེལ་མཐུད་པ། + + + + Set share password + མཉམ་སྤྱོད་གསང་ཨང་བཟོ་བ། + + + + Format + རྣམ་གཞག་ཏུ་སྒྱུར། + + + + Tag information + མཚོན་རྟགས་ཆ་འཕྲིན། + + + + Open as administrator + དོ་དམ་པའི་ཐོབ་ཐང་གིས་ཁ་ཕྱེ་བ། + + + + Select default program + སོར་བཞག་བྱ་རིམ་འདེམས་པ། + + + + Open file location + ཡིག་ཆ་གནས་ས་ཁ་འབྱེད་པ། + + + + Remove bookmark + དཔེ་འཛར་སྤོ་བ། + + + + + + Delete + སུབ་པ། + + + + Office Text + གཞུང་ལས་ཡིག་ཆ + + + + Spreadsheets + གློག་རྡུལ་རེའུ་མིག + + + + Plain Text + ཡིག་རྐྱང་ཡིག་ཆ། + + + + Open in terminal + མཐའ་སྣེ་ནས་ཁ་འབྱེད་པ། + + + + Restore + སོར་ཆུད། + + + + Restore all + ཆ་ཚང་སོར་ཆུད། + + + + Clear saved password and unmount + གསང་ཨང་ངེས་རྒྱུ་དོར་བ་མ་ཟད་བཤིག་རྒྱུ། + + + + File Vault + ཡིག་ཆའི་ཉེན་འགོག་ལྕགས་སྒམ། + + + + Add to disc + འོད་སྡེར་དུ་ཕབ་བརྐོ་བྱེད་པ། + + + + Refresh + གསར་སྒྱུར། + + + + Auto mount + རང་འཇུག + + + + Open after auto mount + རང་འཇུག་བྱས་རྗེས་ཁ་ཕྱེ། + + + + + Mount + འཇུག་པ། + + + + + Unmount + བཤིག་འདོན། + + + + It does not support burning %1 discs + %1རྣམ་གཞག་གིས་གནས་སྐབས་ཕབ་བརྐོ་བྱེད་པར་རྒྱབ་སྐྱོར་མེད། + + + + Burn + ཕབ་བརྐོ། + + + + Disc name: + འོད་སྡེར་གྱི་མིང་། + + + + + Maximum + མྱུར་ཚད་མགྱོགས་ཤོས། + + + + Allow files to be added later + གཞི་གྲངས་བསྐྱར་སྣོན་བྱེད་ཆོག་པ། + + + + Verify data + གཞི་གྲངས་དག་བཤེར། + + + + Write speed: + མྱུར་ཚད་འབྲི་བ། + + + + + + + Cancel + button + འདོར་བ། + + + + Burn + button + ཕབ་བརྐོ། + + + + + Eject + ཕྱིར་འདོན། + + + + Safely Remove + བདེ་འཇགས་ངང་སྤོ་བ། + + + + + Name + མིང་། + + + + Settings + སྒྲིག་འགོད། + + + + Exit + ཕྱིར་འཐོན། + + + + Icon + རྟགས་རིས་མཐོང་རིས། + + + + List + གསལ་ཐོའི་མཐོང་རིས། + + + + Extend + མཐོང་རིས་རྒྱ་སྐྱེད། + + + + Set as wallpaper + རྒྱབ་ཤོག་སྒྲིག་འགོད། + + + + + + + Local disk + རང་སའི་སྡུད་སྡེར། + + + + + Removable disk + སྤོ་རུང་བའི་སྡུད་སྡེར། + + + + + + Network shared directory + དྲ་རྒྱ་མཉམ་སྤྱོད་དཀར་ཆག + + + + + Android mobile device + ཨན་ཊོ་སྤོ་རུང་སྒྲིག་ཆས། + + + + + Apple mobile device + ཀུ་ཤུའི་སྤོ་རུང་སྒྲིག་ཆས། + + + + + Camera + པར་ཆས། + + + + + DVD + སྡེར་སྐུར་སྒྲིག་ཆས། + + + + + Unknown device + རྒྱུས་མེད་པའི་སྒྲིག་ཆས། + + + + + + %1 item + ཚན་པ་%1 + + + + + + %1 items + ཚན་པ་%1 + + + + Shortcut + མྱུར་ལམ། + + + + Create symlink + སྦྲེལ་མཐུད་པ། + + + + Path + འགྲོ་ལམ། + + + + + + Time deleted + བསུབས་པའི་དུས་ཚོད། + + + + Loading... + སྣོན་འཇུག་བྱེད་བཞིན་པ། + + + + File has been moved or deleted + ཡིག་ཆ་སྤོས་ཟིན་པའམ་བསུབས་ཟིན། + + + + You do not have permission to traverse files in it + ཁྱོད་ལ་ཡན་ལག་ཡིག་ཆར་ལྟ་སྤྱོད་བྱེད་དབང་མེད། + + + + + + You do not have permission to access this folder + ཁྱོད་ལ་ཡིག་ཁུག་འདི་ཀློག་དབང་མེད། + + + + + + + + Folder is empty + ཡིག་ཁུག་སྟོང་པ་རེད་འདུག + + + + Searching... + བཤེར་འཚོལ་བྱེད་བཞིན་པ། + + + + No results + བཙལ་འབྲས་མེད། + + + + Source Path + TrashFileInfo + ཐོག་མའི་འགྲོ་ལམ། + + + + Document + Wordཡིག་ཆ་གསར་བཟོ། + + + + Spreadsheet + Excelཡིག་ཆ་གསར་བཟོ། + + + + + Presentation + ཡིག་ཆ་སྟོན་འགྲེམས། + + + + Text + ཡིག་ཆ་གསར་བཟོ། + + + + 1 task in progress + ལས་འགན་1སྤེལ་བཞིན་པ། + + + + %1 tasks in progress + ལས་འགན་%1སྤེལ་བཞིན་པ། + + + + Mode: + ཐབས་ལམ། + + + + + Replace Text + ཡིག་ཆ་བརྗེ་བ། + + + + + Add Text + ཡིག་ཆ་སྣོན་པ། + + + + + Custom Text + རང་སྒྲུབ་ཡིག་ཆ། + + + + Find: + འཚོལ། + + + + Replace: + བརྗེ་བ། + + + + + Optional + བདམས་ནས་འབྲི་བ། + + + + Add: + ཁ་སྣོན། + + + + Location: + གནས་ས། + + + + File name: + ཡིག་ཆའི་མིང་། + + + + Start at: + +རིམ་སྟར། + + + + + Rename + button + མིང་ཡང་བསྐྱར་འདོགས་པ། + + + + + + + + + + + Required + ངེས་པར་དུ་འབྲི་དགོས་པ། + + + + + Before file name + མིང་གི་སྔོན་དུ། + + + + + After file name + མིང་གི་མཇུག་ཏུ། + + + + Find + འཚོལ། + + + + Replace + བརྗེ་བ། + + + + Add + ཁ་སྣོན། + + + + Start at + +རིམ་སྟར། + + + + + + Location + གནས་ས། + + + + File name + ཡིག་ཆའི་མིང་། + + + + Dimension + རིང་ཐུང་། + + + + Duration + དུས་ཚོད་རིང་ཐུང་། + + + + Tips: Sort by selected file order + དྲན་སྐུལ། བདམས་ཡོད་པའི་ཡིག་ཆའི་གོ་རིམ་ལྟར་རིམ་པ་སྒྲིག་པ། + + + + Rename %1 Files + ཡིག་ཆ་%1མིང་བསྐྱར་དུ་འདོགས་པ། + + + + Multiple Files + ཡིག་ཆ་མང་པོ། + + + + Basic info + གཞི་རྩའི་ཆ་འཕྲིན། + + + + Total size + སྤྱིའི་ཆེ་ཆུང་། + + + + Number of files + ཡིག་ཆའི་ཁ་གྲངས། + + + + %1 file(s), %2 folder(s) + ཡིག་ཆ་%1དང་། ཡིག་ཁུག་%2 + + + + + + Time accessed + ལྟ་སྤྱོད་དུས་ཚོད། + + + + Orange + ལི་མདོག + + + + Red + དམར་པོ། + + + + Purple + རྒྱ་སྨུག + + + + Navy-blue + རྒྱ་མཚོའི་མདོག + + + + Azure + སྔོན་པོ། + + + + Green + ལྗང་ཁུ། + + + + Yellow + སེར་པོ། + + + + Gray + ཐལ་མདོག + + + + Input tag info, such as work, family. A comma is used between two tags. + མཚོན་རྟགས་ཆ་འཕྲིན་འབྲི་དགོས། དཔེར་ན་“ལས་ཀ་”དང་“ནང་མི་”སོགས། མཚོན་རྟགས་སོ་སོའི་དབར་ཤད་ཀྱིས་དབྱེ་བ་འབྱེད་དགོས། + + + + Bookmarks + དཔེ་འཛར། + + + + Erase + སུབ་པ། + + + + Copy path + པར་སློག་འགྲོ་ལམ། + + + + Edit address + རྩོམ་སྒྲིག་བྱེད་ས། + + + + Free Space %1 + སྤྱོད་རུང་བར་སྟོང་།%1 + + + + Files are being processed + ཡིག་ཆ་ཐག་གཅོད་བཞིན་པ། + + + + + Unknown + མི་ཤེས་པ། + + + + My Vault + ངའི་ཉེན་འགོག་སྒམ་ཆུང་། + + + + + Failed to create file info + ཡིག་ཆའི་ཆ་འཕྲིན་བཟོ་མ་ཐུབ། + + + + Failed to create file handler + ཡིག་ཆ་ཐག་གཅོད་བྱེད་པའི་བྱ་རིམ་བཟོ་མ་ཐུབ། + + + + Failed to open the file, cause: %1 + ཡིག་ཆ་ཁ་ཕྱེ་མ་ཐུབ། རྒྱུ་མཚན་ནི་%1 + + + + Original file does not exist + ཁུངས་ཡིག་ཆ་མེད་པ། + + + + Do you want to delete %1? + %1བསུབ་དགོས་སམ། + + + + Confirm + button + ཆོག + + + + + + + + %1 are not allowed + %1ཡོད་མི་རུང་། + + + + + Failed to start Samba services + Sambaཞབས་ཞུ་སྐུལ་སློང་བྱེད་མི་ཐུབ། + + + + RecentController + + + Cancel + button + འདོར་བ། + + + + Remove + button + སྤོ་བ། + + + + Do you want to remove this item? + ཁྱེད་ཀྱིས་བདམས་ཟིན་པའི་ནང་དོན་འདི་བསུབ་རྒྱུ་གཏན་ཁེལ་ལམ། + + + + Do yout want to remove %1 items? + ཁྱེད་ཀྱིས་བདམས་ཟིན་པའི་ནང་དོན་%1བསུབ་རྒྱུ་གཏན་ཁེལ་ལམ། + + + + It does not delete the original files + བཀོལ་སྤྱོད་འདིས་ཁུངས་ཡིག་ཆ་བསུབ་མི་སྲིད། + + + + ShareInfoFrame + + + Share this folder + ཡིག་ཁུག་འདི་མཉམ་སྤྱོད་བྱེད་པ། + + + + Share name: + མཉམ་སྤྱོད་མིང་། + + + + Permission: + དབང་ཚད། + + + + Read and write + འབྲི་ཀློག་རུང་བ། + + + + Read only + ཀློག་ཙམ། + + + + Anonymous: + མིང་མི་འགོད་པའི་ལྟ་སྤྱོད་བྱེད་པ། + + + + Not allow + མི་ཆོག + + + + Allow + ཆོག་པ། + + + + The share name must not be two dots (..) or one dot (.) + དང་བཀག་འགོག་ནི་མཉམ་སྤྱོད་མིང་ལ་བྱས་ཏེ་སྤྱོད་པ། + + + + The share name is used by another user. + མཉམ་སྤྱོད་མིང་འདི་སྤྱོད་མཁན་གཞན་གྱིས་བེད་སྤྱོད་བྱས་འདུག + + + + OK + button + ཆོག + + + + Cancel + button + འདོར་བ། + + + + Replace + button + བརྗེ་བ། + + + + The share name already exists. Do you want to replace the shared folder? + མཉམ་སྤྱོད་མིང་འདི་འདུག་པས། དང་ཐོག་གི་མཉམ་སྤྱོད་ཡིག་ཁུལ་ལ་བརྗེ་དགོས་དགོས་སམ། + + + + Shortcut + + + Item + ཡིག་ཆ། + + + + Select to the first item + ཡིག་ཆ་དང་པོའི་ནང་ + + + + Shift + Home + Shift + Home + + + + Select to the last item + ཡིག་ཆ་ཆེས་མཐའ་མའི་ནང་། + + + + Shift + End + Shift + End + + + + Select leftwards + མདུན་ཕྱོགས་འདེམས་པ། + + + + Shift + Left + Shift + Left + + + + Select rightwards + རྒྱབ་ཕྱོགས་འདེམས་པ། + + + + Shift + Right + Shift + Right + + + + Select to upper row + ཡིག་ཕྲེང་གོང་མ་འདེམས་པ། + + + + Shift + Up + Shift + Up + + + + Select to lower row + ཡིག་ཕྲེང་འོག་མ་འདེམས་པ། + + + + Shift + Down + Shift + Down + + + + Open + ཡིག་ཆ་ཁ་འབྱེད་པ། + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + མདུན་དུ་ལོག་པ། + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + ཡོངས་སུ་སུབ་པ། + + + + Shift + Delete + Shift + Delete + + + + Delete file + ཡིག་ཆ་སུབ་པ། + + + + Delete + སུབ་པ། + + + + Select all + ཡིག་ཆ་ཆ་ཚང་འདེམས། + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + ཡིག་ཆ་མཁོ་ཕབ། + + + + Cut + ཡིག་ཆ་དྲས་གཏུབ། + + + + Paste + ཡིག་ཆ་སྦྱར་བ། + + + + Rename + མིང་ཡང་བསྐྱར་འདོགས་པ། + + + + F2 + F2 + + + + New/Search + གསར་འཛུགས།/བཤེར་འཚོལ། + + + + New window + སྒེའུ་ཁུང་གསར་འཛུགས། + + + + New folder + ཡིག་ཁུག་གསར་འཛུགས། + + + + + Search + བཤེར་འཚོལ། + + + + New tab + ཤོག་བྱང་གསར་བཟོ། + + + + View + ལྟ་བཤེར། + + + + Item information + ཡིག་ཆའི་ཆ་འཕྲིན། + + + + Help + རོགས་ལམ་ལག་དེབ། + + + + F1 + F1 + + + + Keyboard shortcuts + མྱུར་མཐེབ་ཚང་མ། + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + མངོན་སྟོན་རྣམ་པ་བརྗེ་བ། + + + + Hide item + ཡིབ་པའི་ཡིག་ཆ། + + + + Input in address bar + གནས་ས་ནང་འཇུག + + + + Switch to icon view + རྟགས་རིས་མཐོང་རིས་ལ་བརྗེ་བ། + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + རེའུ་མིག་མཐོང་རིས་ལ་བརྗེ་བ། + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + གཞན། + + + + Close + སྒོ་བརྒྱབ། + + + + Alt + F4 + Alt + F4 + + + + Close current tab + མིག་སྔའི་ཤོག་བྱང་ཁ་རྒྱོབ། + + + + Back + ཕྱིར་བཤོལ། + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + ཤོག་བྱང་རྗེས་མར་བརྗེ་བ། + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + ཤོག་བྱང་གོང་མར་བརྗེ་བ། + + + + Next file + ཡིག་ཆ་རྗེས་མ། + + + + Tab + Tab + + + + Previous file + ཡིག་ཆ་གོང་མ། + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + 1-8བར་དམིགས་འཛུགས་བྱས་པའི་རིམ་པར་བརྗེ་བ། + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + མདུན་སྐྱོད། + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + སྙིགས་སྣོད་ནང་གི་རྣམ་གྲངས་དག་ཁ་ཕྱེ་མེད་པས། སྔོན་ལ་སོར་ཆུད་དགོས། + + + + TrashPropertyDialog + + + Trash + སྙིགས་སྣོད། + + + + item + ལས་གཞི། + + + + items + ལས་གཞི། + + + + Contains %1 %2 + %1བྱས་པ་%2ཚུད་པ། + + + + UDiskListener + + + Failed to rename the label + ཤོག་བྱང་ལ་མིང་བསྐྱར་དུ་བཏགས་མ་ཐུབ། + + + + UnmountWorker + + + + + The device was not safely unmounted + སྒྲིག་ཆས་རྒྱུན་ལྡན་ལྟར་བཀལ་མེད། + + + + The device was not safely removed + སྒྲིག་ཆས་རྒྱུན་གཏན་ངང་སྤོ་འབུད་བྱས་མེད། + + + + UserShareManager + + + Kindly Reminder + མཛའ་བརྩེའི་དྲན་སྐུལ། + + + + Please firstly install samba to continue + ཁྱོད་ཀྱིས་སྔོན་ལ་sambaསྒྲིག་འཇུག་བྱེད་དགོས་པ་དང་། དེ་རྗེས་མཉམ་སྤྱོད་དང་འབྲེལ་བའི་བཀོལ་སྤྱོད་བྱེད་དགོས། + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + མཉམ་སྤྱོད་མིང་ནང་%<>*?|/\+=;:,"ཡོད་མི་རུང་ལ། %1ཡིས་འགོ་ཚུགས་མི་རུང་། + + + + To protect the files, you cannot share this folder. + ཡིག་ཆའི་བདེ་འཇགས་ཆེད་ཡིག་ཁུག་འདི་མཉམ་སྤྱོད་བྱེད་ཐབས་བྲལ། + + + + Sharing failed + མཉམ་སྤྱོད་བྱེད་མ་ཐུབ། + + + + The computer name is too long + རྩིས་འཁོར་མིང་རིང་དྲགས་པ། + + + + You do not have permission to operate file/folder! + ཁྱོད་ལ་ཡིག་ཆ་/ཡིག་ཁུག་བཀོལ་སྤྱོད་བྱེད་དབང་མེད། + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + མཉམ་སྤྱོད་གསང་ཨང་ནང་འཇུག་བྱེད་རོགས། + + + + Cancel + button + འདོར་བ། + + + + Confirm + button + ཆོག + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ca.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ca.ts new file mode 100644 index 0000000..58e3408 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ca.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Carpeta nova + + + + Mounting device error + Error de muntatge del dispositiu + + + + The disc image was corrupted, cannot mount now, please erase the disc first + La imatge del disc estava malmesa i no es pot muntar ara; si us plau, esborreu primer el disc. + + + + Mount error: unsupported image format + Error de muntatge: format d'imatge no admès. + + + + + The device was not safely removed + El dispositiu no s'ha extret amb seguretat. + + + + + Click "Safely Remove" and then disconnect it next time + A la propera, cliqueu a "Extreu-lo amb seguretat" i després desconnecteu-lo. + + + + The device was not ejected + El dispositiu no s'ha extret. + + + + Disk is busy, cannot eject now + El disc està ocupat. No es pot extreure ara. + + + + Authentication timed out + S'ha esgotat el temps d'espera de l'autenticació. + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Transferència de fitxers per Bluetooth + + + + File Transfer Successful + Transferència de fitxers correcta + + + + File Transfer Failed + Ha fallat la transferència de fitxers. + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + S'envien fitxers a <b style="font-weight: 550;">%1</b> + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Ha fallat enviar fitxers a <b style="font-weight: 550;">%1</b> + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Enviament a <b style="font-weight: 550;">%1</b> correcte + + + + Select a Bluetooth device to receive files + Seleccioneu un dispositiu de Bluetooth per rebre fitxers. + + + + Cannot find the connected Bluetooth device + No es pot trobar el dispositiu de Bluetooth connectat. + + + + Waiting to be received... + S'espera la recepció... + + + + Go to Bluetooth Settings + Ves a la configuració del Bluetooth + + + + %1/%2 Sent + Enviat: %1/%2 + + + + Error: the Bluetooth device is disconnected + Error: el dispositiu de Bluetooth està desconnectat. + + + + Unable to send the file more than 2 GB + No es pot enviar un fitxer de més de 2 GB. + + + + Unable to send 0 KB files + No es poden enviar fitxers de 0 KB. + + + + File doesn't exist + El fitxer no existeix. + + + + Next + button + Següent + + + + Cancel + button + Cancel·la + + + + Done + button + Fet + + + + Retry + button + Torna-ho a provar + + + + OK + button + D'acord + + + + File sending request timed out + S'ha esgotat el temps d'espera per enviar el fitxer. + + + + The service is busy and unable to process the request + El servei està ocupat i no pot processar la petició. + + + + BurnOptDialog + + + Device error + Error del dispositiu + + + + Optical device %1 doesn't exist + El dispositiu òptic %1 no existeix. + + + + Advanced settings + Configuració avançada + + + + File system: + Sistema de fitxers: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Per a Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Per a Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (compatible amb el mode de CD / DVD de Windows) + + + + ISO9660 Only + Només ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Tanca-ho tot + + + + Total size: %1, %2 files + Mida total: %1, %2 fitxers + + + + ComputerModel + + + Double click to open it + Clic doble per obrir-ho + + + + My Directories + Directoris de l'usuari + + + + Disks + Discs + + + + File Vault + Cambra cuirassada de fitxers + + + + Quick Access + Accés ràpid + + + + ComputerPropertyDialog + + + Computer + Ordinador + + + + Basic Info + Informació bàsica + + + + + Computer Name + Nom de l'ordinador + + + + + Edition + Edició + + + + + + Version + Versió + + + + + Type + Tipus + + + + + + Processor + Processador + + + + + + Memory + Memòria + + + + + + + Bit + Bit + + + + + Available + Disponible + + + + Obtaining... + S'obté... + + + + ConnectToServerDialog + + + Connect to Server + Connecta amb el servidor + + + + Cancel + button + Cancel·la + + + + Connect + button + Connecta + + + + My Favorites: + Preferits: + + + + + Clear History + Neteja l'historial + + + + DFMAddressBar + + + Search or enter address + Cerqueu o introduïu l'adreça + + + + DFMAdvanceSearchBar + + + Search: + Cerca: + + + + File Type: + Tipus de fitxer: + + + + File Size: + Mida del fitxer: + + + + Time Modified: + Hora de modificació: + + + + Time Accessed: + Hora d'accés: + + + + Time Created: + Hora de creació: + + + + Reset + Restableix + + + + All subdirectories + Tots els subdirectoris + + + + Current directory + Directori actual + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Avui + + + + Yesterday + Ahir + + + + This week + Aquesta setmana + + + + Last week + La setmana passada + + + + This month + Aquest mes + + + + Last month + El mes passat + + + + This year + Aquest any + + + + Last year + L'any passat + + + + DFMOpticalMediaWidget + + + + No files to burn + No hi ha fitxers per gravar. + + + + Unable to burn. Not enough free space on the target disk. + No es pot fer la gravació. No hi ha prou espai lliure al disc de destinació. + + + + %1 burning is not supported + No s'admet la gravació de %1. + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. No és un disc %1. +2. La versió d'aquest sistema de fitxers encara no admet afegir-hi fitxers. + + + + DFMTagCrumbController + + + Tag information + Informació de l'etiqueta + + + + DFMTagWidget + + + Tag + Etiqueta + + + + DFMTaskWidget + + + Do not ask again + No ho tornis a preguntar. + + + + Syncing data + Se sincronitzen dades + + + + Please wait + Espereu, si us plau... + + + + + Time modified: %1 + Hora de modificació: %1 + + + + + Contains: %1 + Contingut: %1 + + + + + Size: %1 + Mida: %1 + + + + Original folder + Carpeta original + + + + Keep both + button + Mantén-los ambdós + + + + Skip + button + Omet + + + + Replace + button + Reemplaça + + + + Retry + button + Torna-ho a provar + + + + Original file + Fitxer original + + + + Target folder + Carpeta de destinació + + + + Target file + Fitxer de destinació + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Encripta la cambra cuirassada de fitxers + + + + Click 'Encrypt' and input the user password. + Cliqueu a Encripta i escriviu la contrasenya de l'usuari. + + + + Encrypting... + S'encripta... + + + + + + + Encrypt + Encripta + + + + Failed to create file vault: %1 + Ha fallat crear la cambra cuirassada: %1 + + + + OK + D'acord + + + + The setup is complete + La configuració és completa. + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Desa la clau de recuperació + + + + Keep the key safe to retrieve the vault password later + Deseu la clau de manera segura per recuperar la contrasenya de la cambra cuirassada més tard. + + + + Save to default path + Desa-ho al camí predeterminat + + + + Save to other locations + Desa-ho en altres ubicacions + + + + No permission, please reselect + Sense permís, torneu-ho a seleccionar. + + + + Select a path + Seleccioneu un camí. + + + + Next + Següent + + + + The default path is invisible to other users, and the path information will not be shown. + El camí predeterminat és invisible per a altres usuaris i la informació del camí no es mostrarà. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Clau de recuperació + + + + Generate a recovery key in case that you forgot the password + Genereu una clau de recuperació per si oblideu la contrasenya. + + + + Key + Clau + + + + QR code + Codi QR + + + + Scan QR code and save the key to another device + Escanegeu el codi QR i deseu la clau en un altre dispositiu. + + + + Next + Següent + + + + Recovery Key: + Clau de recuperació: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Establiu la contrasenya de la cambra cuirassada. + + + + Method + Mètode + + + + Manual + Manual + + + + Password + Contrasenya + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 caràcters, conté A-Z, a-z, 0-9 i símbols + + + + Repeat password + Repetiu la contrasenya + + + + Input the password again + Torneu a escriure la contrasenya. + + + + Password hint + Suggeriment de la contrasenya + + + + Optional + Opcional + + + + Next + Següent + + + + + Passwords do not match + Les contrasenyes no coincideixen. + + + + DFMVaultActiveStartView + + + File Vault + Cambra cuirassada de fitxers + + + + Create your secure private space + Creeu un espai segur privat + + + + Advanced encryption technology + Tecnologia d'encriptació avançada + + + + Convenient and easy to use + Convenient i fàcil d’usar + + + + Create + Crea + + + + DFMVaultFileView + + + Cannot open this path + No es pot obrir aquest camí. + + + + Hint + Pista + + + + OK + D'acord + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Desbloca la clau + + + + Failed to unlock file vault + Ha fallat desblocar la cambra cuirassada. + + + + OK + D'acord + + + + Input the 32-digit recovery key + Introduïu la clau de recuperació de 32 dígits. + + + + Cancel + button + Cancel·la + + + + Unlock + button + Desbloqueja + + + + Wrong recovery key + Clau de recuperació incorrecta + + + + DFMVaultRemoveByPasswordView + + + Password + Contrasenya + + + + Password hint: %1 + Suggeriment de la contrasenya: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Introduïu la clau de recuperació de 32 dígits. + + + + DFMVaultRemovePages + + + Delete File Vault + Elimina la cambra cuirassada + + + + Once deleted, the files in it will be permanently deleted + Un cop eliminada, els fitxers que hi havia s'hauran esborrat permanentment. + + + + Use Key + Usa la clau + + + + Cancel + button + Cancel·la + + + + Use Key + button + Usa la clau + + + + Delete + button + Elimina + + + + + OK + button + D'acord + + + + Use Password + Usa la contrasenya + + + + Wrong password + Contrasenya incorrecta + + + + Wrong recovery key + Clau de recuperació incorrecta + + + + Failed to delete file vault + Ha fallat eliminar la cambra cuirassada. + + + + Deleted successfully + S'ha eliminat correctament. + + + + Failed to delete + Ha fallat l'eliminació. + + + + Removing... + S'elimina... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + No es pot obtenir el fitxer de claus. + + + + Verification failed + Ha fallat la verificació. + + + + + Select a path + Seleccioneu un camí. + + + + + Retrieve Password + Recupera la contrasenya + + + + By key in the default path + Per clau al camí predeterminat + + + + By key in the specified path + Per clau al camí especificat + + + + Verification Successful + Verificació correcta + + + + Keep it safe + Deseu-ho de manera segura + + + + Back + button + Enrere + + + + Verify Key + button + Verifica la clau + + + + Go to Unlock + button + Ves al desbloqueig + + + + Close + button + Tanca + + + + Vault password: %1 + Contrasenya de la cambra cuirassada: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Desbloca la cambra cuirassada + + + + Forgot password? + Heu oblidat la contrasenya? + + + + Password hint: %1 + Suggeriment de la contrasenya: %1 + + + + Failed to unlock file vault + Ha fallat desblocar la cambra cuirassada. + + + + Cancel + button + Cancel·la + + + + Password + Contrasenya + + + + Unlock + button + Desbloqueja + + + + Please try again %1 minutes later + Si us plau, torneu-ho a provar d'aquí a %1 minuts. + + + + Wrong password, please try again %1 minutes later + Contrasenya incorrecta. Si us plau, torneu-ho a provar d'aquí a %1 minuts. + + + + Wrong password, one chance left + Contrasenya incorrecta. Us queda un intent. + + + + Wrong password, %1 chances left + Contrasenya incorrecta. Us queden %1 intents. + + + + Wrong password + Contrasenya incorrecta + + + + OK + button + D'acord + + + + DFileCopyMoveJob + + + Permission error + Error de permís + + + + The action is denied + S'ha denegat l'acció + + + + Failed to open the file + Ha fallat obrir el fitxer. + + + + Failed to read the file + Ha fallat llegir el fitxer. + + + + Failed to write the file + Ha fallat escriure al fitxer. + + + + Failed to create the directory + Ha fallat crear el directori. + + + + Failed to delete the file + Ha fallat eliminar el fitxer. + + + + Failed to move the file + Ha fallat moure el fitxer. + + + + Original file does not exist + El fitxer original no existeix. + + + + Failed, file size must be less than 4GB + Ha fallat: la mida del fitxer ha de ser inferior a 4 GB. + + + + Not enough free space on the target disk + No hi ha prou espai al disc de destinació. + + + + File integrity was damaged + La integritat del fitxer s'ha danyat. + + + + The target device is read only + El dispositiu de destinació és de només lectura. + + + + Target folder is inside the source folder + La carpeta de destinació és dins de la carpeta d'origen. + + + + The action is not supported + L'acció no s'admet. + + + + You do not have permission to traverse files in it + No teniu permís per passar-hi fitxers. + + + + Failed to position the file pointer! + Ha fallat situar el punter del fitxer! + + + + copy + Extra name added to new file name when used for file name. + copia + + + + Failed to open the directory, cause: file name too long + Ha fallat obrir el directori. Causa: nom del fitxer massa llarg. + + + + + Failed to open the file, cause: file name too long + Ha fallat obrir el fitxer. Causa: nom del fitxer massa llarg. + + + + + Failed to write the file, cause: + Ha fallat escriure el fitxer. Causa: + + + + Failed to position the file pointer, cause: %1 + Ha fallat situar el punter del fitxer. Causa: %1 + + + + Syncing data + Se sincronitzen dades + + + + Please wait + Espereu, si us plau... + + + + Failed to create the directory, cause: %1 + Ha fallat crear el directori, causa: %1 + + + + + + + + Failed to open the file, cause: %1 + Ha fallat obrir el fitxer, causa: %1 + + + + + + + Failed to open the file, cause: Permission denied + Ha fallat obrir el fitxer. Causa: permís denegat. + + + + + Failed to read the file, cause: %1 + Ha fallat llegir el fitxer, causa: %1 + + + + + + + Failed to write the file, cause: %1 + Ha fallat escriure al fitxer, causa: %1 + + + + + File integrity was damaged, cause: %1 + La integritat del fitxer s'ha danyat. Causa: %1 + + + + Failed to open the file, cause: + Ha fallat obrir el fitxer. Causa: + + + + Failed to read the file, cause: + Ha fallat llegir el fitxer. Causa: + + + + Failed to delete the file, cause: %1 + Ha fallat eliminar el fitxer, causa: %1 + + + + Fail to create symlink, cause: %1 + No es pot crear l'enllaç simbòlic. Causa: %1 + + + + DFileDialog + + + + Save + button + Desa + + + + + Cancel + button + Cancel·la + + + + Confirm + button + Confirmeu-ho + + + + %1 already exists, do you want to replace it? + %1 ja existeix, voleu reemplaçar-la? + + + + Replace + button + Reemplaça + + + + Open + button + Obre + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Aquest fitxer serà ocult si el nom comença amb un punt. Voleu amagar-lo? + + + + DFileManagerWindow + + + Trash + Paperera + + + + Empty + Buit + + + + DFileSystemModel + + + + Name + Nom + + + + + + Time modified + Hora de modificació + + + + Size + Mida + + + + Type + Tipus + + + + Time created + Hora de creació + + + + + Last access + Últim accés + + + + + + + Path + Camí + + + + DFileView + + + Disc mount error + Error de muntatge de dis + + + + The disc is in use, please end the running process and remount the disc. + El disc està en ús. Acabeu el procés en execució i torneu a muntar-lo. + + + + Mounting failed + Ha fallat el muntatge. + + + + (Reverse) + (Inversió) + + + + DFileViewHelper + + + Add tag "%1" + Afegeix l'etiqueta «%1» + + + + DStatusBar + + + %1 item + %1 element + + + + %1 items + %1 elements + + + + %1 item selected + %1 element seleccionat + + + + %1 items selected + %1 elements seleccionats + + + + %1 folder selected (contains %2) + %1 carpeta seleccionada (conté %2) + + + + %1 folders selected (contains %2) + %1 carpetes seleccionades (contenen %2) + + + + %1 file selected (%2) + %1 fitxer seleccionat (%2) + + + + %1 files selected (%2) + %1 fitxers seleccionats (%2) + + + + %1 folder selected + %1 carpeta seleccionada + + + + Filter + Filtra + + + + Save as: + Desa com a... + + + + Loading... + Carregant... + + + + DTaskDialog + + + Erasing disc %1, please wait... + S'esborra el disc %1. Espereu, si us plau... + + + + Burning disc %1, please wait... + Es grava el disc %1. Espereu, si us plau... + + + + Writing data... + S'escriuen les dades... + + + + Verifying data... + Es verifiquen les dades... + + + + Copying %1 + Es copia %1 + + + + + + to %2 + a %2 + + + + %1 already exists in target folder + %1 ja existeix a la carpeta de destinació. + + + + Original path %1 Target path %2 + Camí original: %1. Camí de destinació: %2 + + + + Merge + button + Fusiona + + + + Replace + button + Reemplaça + + + + Moving %1 + Es mou %1 + + + + Removing file vault, please try later + S'elimina la cambra cuirassada. Proveu-ho més tard. + + + + Restoring %1 + Es restaura %1 + + + + Deleting %1 + S'elimina %1 + + + + Trashing %1 + S'envia a la paperera %1 + + + + Calculating space, please wait + Es calcula l'espai. Espereu, si us plau... + + + + DUMountManager + + + + Authentication timed out + S'ha esgotat el temps d'espera de l'autenticació. + + + + + + Disk is busy, cannot unmount now + El disc està ocupat. No es pot desmuntar ara. + + + + Disk is busy, cannot eject now + El disc està ocupat. No es pot extreure ara. + + + + The device is busy, cannot eject now + El dispositiu està ocupat. No es pot extreure ara. + + + + + + The device is busy, cannot remove now + El dispositiu està ocupat. No es pot suprimir ara. + + + + DeepinStorage + + + + + %1 Volume + Volum: %1 + + + + Data Disk + Data Partition + Disc de dades + + + + %1 Drive + Dispositiu: %1 + + + + Blank %1 Disc + Disc en blanc %1 + + + + %1 Encrypted + Encriptat: %1 + + + + DialogManager + + + + + + Operation failed! + Ha fallat l'operació! + + + + Target folder is inside the source folder! + La carpeta de destinació és dins de la carpeta d'origen! + + + + Do you want to run %1 or display its content? + Voleu executar %1 o veure'n el contingut? + + + + It is an executable text file. + És un fitxer de text executable. + + + + It is an executable file. + És un fitxer executable. + + + + This file is not executable, do you want to add the execute permission and run? + Aquest fitxer no és executable. Voleu afegir-hi el permís d'execució i executar-lo? + + + + "%1" already exists, please use another name. + "%1" ja existeix; si us plau, trieu un altre nom. + + + + The file name must not contain two dots (..) + El nom del fitxer no ha de contenir dos punts (..). + + + + Device or resource busy + Dispositiu o recurs ocupat + + + + Are you sure you want to erase all data on the disc? + Segur que voleu esborrar totes les dades del disc? + + + + How do you want to use this disc? + Com voleu usar aquest disc? + + + + Disc erase failed + Ha fallat esborrar el disc. + + + + Burn process failed + Ha fallat gravar el disc. + + + + %1: %2 + %1. %2 + + + + Show details + Mostra'n els detalls + + + + Hide details + Amaga'n els detalls + + + + Error + Error + + + + Permanently delete %1? + Voleu eliminar permanentment %1? + + + + Permanently delete %1 items? + Voleu eliminar permanentment %1 elements? + + + + Empty + Buida + + + + Do you want to delete %1? + Voleu eliminar %1? + + + + Do you want to delete the selected %1 items? + Voleu eliminar els %1 elements seleccionats? + + + + Sorry, unable to locate your bookmark directory, remove it? + Disculpeu, no es pot trobar el directori d'adreces d'interès. L'elimino? + + + + Name: + Nom: + + + + %1 that this shortcut refers to has been changed or moved + %1: la referència d'aquesta drecera ha canviat o s'ha desplaçat. + + + + Do you want to delete this shortcut? + Voleu eliminar aquesta drecera? + + + + Failed, file size must be less than 4GB. + Ha fallat. La mida del fitxer ha de ser inferior a 4 GB. + + + + Fail to create symlink, cause: + Ha fallat crear l'enllaç simbòlic. Causa: + + + + The selected files contain system file/directory, and it cannot be deleted + Els fitxers seleccionats contenen fitxers / directoris del sistema i no es poden eliminar. + + + + Unable to find the original file + No es pot trobar el fitxer original. + + + + + You do not have permission to operate file/folder! + No teniu permís per fer operacions amb el fitxer o carpeta! + + + + Failed to restore %1 file, the source file does not exist + Ha fallat restaurar %1 fitxer. El fitxer d'origen no existeix. + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Disculpeu, no teniu permís per fer operacions amb els %1 fitxers o carpetes següents! + + + + Unable to access %1 + No es pot accedir a %1. + + + + + Sending files now, please try later + Ara s'envien fitxers. Proveu-ho més tard. + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Per accedir al dispositiu, primer heu de formatar el disc. Segur que el voleu formatar ara? + + + + Scanning the device, stop it? + S'escaneja el dispositiu. Voleu interrompre-ho? + + + + Share folder can't be named after the current username + La carpeta de compartició no pot tenir el nom de l'usuari actual. + + + + Do you want to run %1? + Voleu executar %1? + + + + Burn image + button + Grava la imatge + + + + Burn files + button + Grava els fitxers + + + + Are you sure you want to empty %1 item? + Segur que voleu eliminar %1 element? + + + + Are you sure you want to empty %1 items? + Segur que voleu eliminar %1 elements? + + + + + This action cannot be undone + Aquesta acció no es pot desfer + + + + + + + + + + + + + + OK + button + D'acord + + + + + + + + + + + + + + + Cancel + button + Cancel·la + + + + + + Run + button + Executa + + + + + Run in terminal + button + Executa al terminal + + + + Display + button + Mostra + + + + + + + + + + + Confirm + button + Confirmeu-ho + + + + Erase + button + Esborra + + + + Data verification failed + Ha fallat la verificació de les dades. + + + + Show details + button + Mostra'n els detalls + + + + + Delete + button + Elimina + + + + Remove + button + Elimina + + + + Disk is busy, cannot unmount now + El disc està ocupat, no es pot desmuntar ara + + + + Force unmount + button + Força'n el desmuntatge + + + + Unable to copy. Not enough free space on the target disk. + No es pot fer la còpia. No hi ha prou espai al disc de destinació. + + + + Failed to restore %1 file, the target folder is read-only + No s'ha pogut restaurar %1 fitxer, la carpeta de destinació és de només lectura. + + + + Failed to restore %1 files, the target folder is read-only + No s'han pogut restaurar %1 fitxers, la carpeta de destinació és de només lectura. + + + + Failed to restore %1 files, the source files do not exist + Ha fallat restaurar %1 fitxers. Els fitxers d'origen no existeixen. + + + + Format + button + Formatació + + + + Stop + button + Interromp + + + + FileController + + + + + + Unable to find the original file + No es pot trobar el fitxer original. + + + + + + Kindly Reminder + Recordatori amable + + + + + + Please install File Roller first and then continue + Si us plau, instal·leu primer el File Roller i després continueu. + + + + + Unable to create files here: %1 + No es poden crear els fitxers aquí: %1 + + + + Confirm + button + Confirmeu-ho + + + + FileDialogStatusBar + + + File Name + Nom del fitxer + + + + Format + Formatació + + + + Save + button + Desa + + + + Open + button + Obre + + + + Save File + button + Desa el fitxer + + + + Open File + button + Obre un fitxer + + + + + + Cancel + button + Cancel·la + + + + FileJob + + + copy + copia + + + + + + + Data verification successful. + Verificació de dades correcta. + + + + + + Burn process completed + S'ha completat el procés de gravació. + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 és un fitxer duplicat. + + + + Insufficient disc space. + No hi ha prou espai de disc. + + + + Lost connection to drive. + S'ha perdut la connexió amb la unitat. + + + + The CD/DVD drive is not ready. Try another disc. + La unitat de CD / DVD no està a punt. Proveu-ho amb un altre disc. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + La unitat de CD / DVD està ocupada. Sortiu del programa usant la unitat i torneu-la a inserir. + + + + Unknown error + Error desconegut + + + + Device disconnected + Dispositiu desconnectat + + + + GenerateSettingTranslate + + + + + Basic + Bàsic + + + + + + Open behavior + Comportament d'obertura + + + + + + Always open folder in new window + Obre sempre la carpeta en una finestra nova + + + + + + Open file: + Obre el fitxer: + + + + + + Click + Clic + + + + + + Double click + Clic doble + + + + + + New window and tab + Finestra i pestanya noves + + + + + + Open from default window: + Obre des de la finestra per defecte: + + + + + + + + + Computer + Ordinador + + + + + + + + + Home + Carpeta de l'usuari + + + + + + + + + Desktop + Escriptori + + + + + + + + + Videos + Vídeos + + + + + + + + + Music + Música + + + + + + + + + Pictures + Imatges + + + + + + + + + Documents + Documents + + + + + + + + + Downloads + Baixades + + + + + + Open in new tab: + Obre en una pestanya nova: + + + + + + Current Directory + Directori actual + + + + + + View + Visualització + + + + + + Default size: + Mida per defecte: + + + + + + Extra small + Molt petita + + + + + + Small + Petita + + + + + + Medium + Mitjana + + + + + + Large + Grossa + + + + + + Extra large + Molt grossa + + + + + + Default view: + Visualització per defecte: + + + + + + Icon + Icona + + + + + + List + Llista + + + + + + Hidden files + Fitxers ocults + + + + + + Show hidden files + Mostra els fitxers ocults. + + + + + + Hide file extension when rename + Amaga l'extensió del fitxer en canviar-ne el nom. + + + + + + Advanced + Avançat + + + + + + Index + Índex + + + + + + Auto index internal disk + Indexa automàticament el disc intern. + + + + + + Index external storage device after connected to computer + Indexa el dispositiu d'emmagatzematge extern després de connectar-lo a l'ordinador. + + + + + + Full-Text search + Cerca de text complet + + + + + + Show item counts and sizes in the path of mounted MTP devices + Mostra el recompte i les mides d’elements al camí dels dispositius MTP muntats. + + + + + + Keep showing the mounted Samba shares + Continua mostrant els recursos compartits de Samba muntats. + + + + + + Use the file chooser dialog of File Manager + Usa el diàleg de tria de fitxers del Gestor de fitxers + + + + + + Ask for my confirmation when deleting files + Demana'm la confirmació quan s'eliminin fitxers. + + + + + + Other + Altres + + + + + + Hide system disk + Amaga el disc del sistema. + + + + + + Show file system on disk icon + Mostra el sistema de fitxers a la icona del disc. + + + + + + Show hidden files in search results + Mostra els fitxers ocults als resultats de la cerca. + + + + + + Display recent file entry in left panel + Mostra l'entrada de fitxers recents al plafó de l'esquerra. + + + + + + Preview + Visalització prèvia + + + + + Compress file preview + Comprimeix la visualització prèvia del fitxer. + + + + + + Text preview + Visualització prèvia del text + + + + + + Document preview + Visualització prèvia del document + + + + + + Image preview + Visualització prèvia de la imatge + + + + + + Video preview + Visualització prèvia del vídeo + + + + + + Mount + Munta + + + + + + Auto mount + Muntatge automàtic + + + + + + Open after auto mount + Obre després de muntar-ho automàticament. + + + + + + Dialog + Diàleg + + + + Compressed file preview + Previsualització del fitxer comprimit + + + + GvfsMountManager + + + Can’t verify the identity of %1. + No es pot verificar la identitat de %1. + + + + This happens when you log in to a computer the first time. + Això passa quan obriu la sessió per primer cop. + + + + The identity sent by the remote computer is + La identitat enviada per l'ordinador remot és + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Si voleu estar absolutament segur que és segur continuar, poseu-vos en contacte amb l'administrador del sistema. + + + + + + + + Mounting device error + Error de muntatge del dispositiu + + + + + Wrong username or password + Nom d'usuari o contrasenya incorrectes + + + + + + + + Confirm + button + Confirmeu-ho + + + + + Cannot find the mounted device + No es pot trobar el dispositiu muntat. + + + + No key available to unlock device + No hi ha cap clau disponible per desbloquejar el dispositiu. + + + + The disk is mounted by user "%1", you cannot unmount it. + El disc està muntat per l'usuari %1, no podeu desmuntar-lo. + + + + Cannot unmount the device + No es pot desmuntar el dispositiu. + + + + Cannot eject the device "%1" + No es pot extreure el dispositiu «%1». + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + No es pot fer la gravació. No hi ha prou espai lliure al disc de destinació. + + + + MergedDesktopController + + + + Pictures + Imatges + + + + + Music + Música + + + + + Applications + Aplicacions + + + + + Videos + Vídeos + + + + + Documents + Documents + + + + + Others + Altres + + + + MimeTypeDisplayManager + + + + Directory + Directori + + + + + + Application + Aplicació + + + + + + Video + Vídeo + + + + + + Audio + Àudio + + + + + + Image + Imatge + + + + + Archive + Arxiu + + + + + + Text + Text + + + + + Executable + Executable + + + + + Backup file + Fitxer de còpia de seguretat + + + + + Unknown + Desconegut + + + + MountAskPasswordDialog + + + Cancel + button + Cancel·la + + + + Connect + button + Connecta + + + + Log in as + Entreu-hi com a + + + + Anonymous + Anònim + + + + Registered user + Usuari registrat + + + + Username + Nom d'usuari + + + + Domain + Domini + + + + Password + Contrasenya: + + + + Remember password + Recorda la contrasenya + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Cancel·la + + + + Unlock + button + Desbloqueja + + + + Input password to decrypt the disk + Introduïu la contrasenya per desxifrar el disc + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Segur que voleu eliminar %1 permanentment? + + + + This file is too big for the trash + Aquest fitxer és massa gros per a la paperera. + + + + The files are too big for the trash + Els fitxers són massa grossos per a la paperera. + + + + Are you sure you want to permanently delete %1 files? + Segur que voleu eliminar %1 fitxers permanentment? + + + + Cancel + button + Cancel·la + + + + Delete + button + Elimina + + + + OpenWithDialog + + + Open with + Obre amb... + + + + Add other programs + Afegiu-hi altres programes + + + + Set as default + Estableix com a predeterminat + + + + Cancel + button + Cancel·la + + + + Confirm + button + Confirmeu-ho + + + + Recommended Applications + Aplicacions recomanades + + + + Other Applications + Altres aplicacions + + + + PathManager + + + Home + Carpeta de l'usuari + + + + Desktop + Escriptori + + + + Videos + Vídeos + + + + Music + Música + + + + Pictures + Imatges + + + + Documents + Documents + + + + Downloads + Baixades + + + + + Trash + Paperera + + + + + + System Disk + Disc del sistema + + + + Computers in LAN + Ordinadors a la xarxa d'àrea local + + + + My Shares + Comparticions + + + + Computer + Ordinador + + + + Recent + Recent + + + + File Vault + Cambra cuirassada de fitxers + + + + PropertyDialog + + + Basic info + Informació bàsica + + + + Open with + Obre amb... + + + + Sharing + Compartició + + + + Permissions + Permisos + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Amaga aquesta carpeta + + + + Hide this file + Amaga aquest fitxer + + + + Allow to execute as program + Permet executar-lo com a programa. + + + + QObject + + + + + + Size + Mida + + + + + + Contains + Contingut + + + + + + Type + Tipus + + + + + + + + Time modified + Hora de modificació + + + + Free space + Espai lliure + + + + Total space + Espai total + + + + + Time locked + Temps de bloqueig + + + + Access denied + Accés denegat + + + + + Executable + Executable + + + + + Write only + Només d'escriptura + + + + + Read only + Només de lectura + + + + + Read-write + De lectura i escriptura + + + + Others + Altres + + + + Owner + Propietari + + + + Unconnected network shared directory + Directori compartit de xarxa sense connexió + + + + Device type + Tipus de dispositiu + + + + File system + Sistema de fitxers + + + + Group + Grup + + + + + Open + Obre + + + + Lock + Bloca + + + + Auto lock + Bloqueig automàtic + + + + Never + Mai + + + + 5 minutes + 5 minuts + + + + 10 minutes + 10 minuts + + + + 20 minutes + 20 minuts + + + + Delete File Vault + Elimina la cambra cuirassada + + + + Unlock + Desbloqueja + + + + Unlock by key + Desbloca amb la clau + + + + Open + button + Obre + + + + + Size: %1 + Mida: %1 + + + + Type: %1 + Tipus: %1 + + + + Size: 0 + Mida: 0 + + + + Items: %1 + Elements: %1 + + + + + + + + + + Open in new window + Obre en una finestra nova + + + + + + + + + + Open in new tab + Obre en una pestanya nova + + + + Open with + Obre amb... + + + + + Compress + Comprimeix + + + + Extract + Extreu + + + + Extract here + Extreu aquí + + + + Cut + Retalla + + + + Copy + Copia + + + + Paste + Enganxa + + + + + + + + Rename + Canvia'n el nom + + + + + + + Remove + Elimina + + + + Create link + Crea'n un enllaç + + + + Send to desktop + Envia a l'escriptori + + + + Send to + Envia a... + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Afegeix a les adreces d'interès + + + + + + + Properties + Propietats + + + + New folder + Carpeta nova + + + + New window + Finestra nova + + + + Select all + Selecciona-ho tot + + + + + Clear recent history + Neteja l'historial recent + + + + + + Empty Trash + Buida la paperera + + + + Display as + Mostra com a... + + + + Sort by + Classifica per... + + + + New document + Document nou + + + + + Time created + Hora de creació + + + + + + Source path + Camí font + + + + Share folder + Comparteix la carpeta + + + + Cancel sharing + Cancel·la la compartició + + + + Connect to Server + Connecta amb el servidor + + + + Set share password + Estableix la contrasenya de compartició + + + + Format + Formatació + + + + Tag information + Informació de l'etiqueta + + + + Open as administrator + Obre com a administrador + + + + Select default program + Seleccioneu el programa predeterminat + + + + Open file location + Obre la ubicació del fitxer + + + + Remove bookmark + Elimina el marcador + + + + + + Delete + Elimina + + + + Office Text + Document de text + + + + Spreadsheets + Full de càlcul + + + + Plain Text + Text simple + + + + Open in terminal + Obre al terminal + + + + Restore + Restaura + + + + Restore all + Restaura-ho tot + + + + Clear saved password and unmount + Esborra la contrasenya desada i desmunta-ho + + + + File Vault + Cambra cuirassada de fitxers + + + + Add to disc + Afegeix al disc + + + + Refresh + Refresca-ho + + + + Auto mount + Muntatge automàtic + + + + Open after auto mount + Obre després de muntar-ho automàticament + + + + + Mount + Munta + + + + + Unmount + Desmunta + + + + It does not support burning %1 discs + No s'admet gravar discs %1. + + + + Burn + Grava + + + + Disc name: + Nom del disc: + + + + + Maximum + Màxim + + + + Allow files to be added later + Permet afegir-hi fitxers després. + + + + Verify data + Verifica'n les dades. + + + + Write speed: + Velocitat d'escriptura: + + + + + + + Cancel + button + Cancel·la + + + + Burn + button + Grava + + + + + Eject + Expulsa + + + + Safely Remove + Extreu-ho amb seguretat + + + + + Name + Nom + + + + Settings + Configuració + + + + Exit + Surt + + + + Icon + Icona + + + + List + Llista + + + + Extend + Amplia + + + + Set as wallpaper + Estableix com a fons d'escriptori + + + + + + + Local disk + Disc local + + + + + Removable disk + Disc extraïble + + + + + + Network shared directory + Directori compartit per xarxa + + + + + Android mobile device + Dispositiu mòbil d'Android + + + + + Apple mobile device + Dispositiu mòbil d'Apple + + + + + Camera + Càmera + + + + + DVD + DVD + + + + + Unknown device + Dispositiu desconegut + + + + + + %1 item + %1 element + + + + + + %1 items + %1 elements + + + + Shortcut + Drecera + + + + Create symlink + Crea un enllaç simbòlic + + + + Path + Camí + + + + + + Time deleted + Hora d'eliminació + + + + Loading... + Carregant... + + + + File has been moved or deleted + El fitxer s'ha desplaçat o eliminat + + + + You do not have permission to traverse files in it + No teniu permís per passar-hi fitxers. + + + + + + You do not have permission to access this folder + No teniu permís per accedir a aquesta carpeta. + + + + + + + + Folder is empty + La carpeta és buida + + + + Searching... + Cercant... + + + + No results + No ha ha resultats. + + + + Source Path + TrashFileInfo + Camí font + + + + Document + Document + + + + Spreadsheet + Full de càlcul + + + + + Presentation + Presentació + + + + Text + Text + + + + 1 task in progress + 1 tasca en execució + + + + %1 tasks in progress + %1 tasques en execució + + + + Mode: + Mode: + + + + + Replace Text + Reemplaça el text + + + + + Add Text + Afegeix text + + + + + Custom Text + Text personalitzat + + + + Find: + Troba: + + + + Replace: + Reemplaça: + + + + + Optional + Opcional + + + + Add: + Afegeix: + + + + Location: + Ubicació: + + + + File name: + Nom del fitxer: + + + + Start at: + Inici: + + + + + Rename + button + Canvia'n el nom + + + + + + + + + + + Required + Necessari + + + + + Before file name + Abans del nom + + + + + After file name + Després del nom + + + + Find + Troba + + + + Replace + Reemplaça + + + + Add + Afegeix + + + + Start at + Inici a + + + + + + Location + Ubicació + + + + File name + Nom del fitxer + + + + Dimension + Dimensió + + + + Duration + Durada + + + + Tips: Sort by selected file order + Consell: classificació per ordre de fitxer seleccionat + + + + Rename %1 Files + Canvia el nom de %1 fitxers + + + + Multiple Files + Fitxers múltiples + + + + Basic info + Informació bàsica + + + + Total size + Mida total + + + + Number of files + Nombre de fitxers + + + + %1 file(s), %2 folder(s) + %1 fitxer/s, %2 carpeta/es + + + + + + Time accessed + Hora d'accés + + + + Orange + Taronja + + + + Red + Vermell + + + + Purple + Porpra + + + + Navy-blue + Blau marí + + + + Azure + Atzur + + + + Green + Verd + + + + Yellow + Groc + + + + Gray + Gris + + + + Input tag info, such as work, family. A comma is used between two tags. + Escriviu la informació de l'etiqueta, com ara la feina, la família... S'usa una coma entre dues etiquetes. + + + + Bookmarks + Preferits + + + + Erase + Esborra + + + + Copy path + Copia'n el camí + + + + Edit address + Edita l'adreça + + + + Free Space %1 + Espai lliure: %1 + + + + Files are being processed + Es processen fitxers + + + + + Unknown + Desconegut + + + + My Vault + La meva cambra cuirassada + + + + + Failed to create file info + Ha fallat crear la informació del fitxer. + + + + Failed to create file handler + Ha fallat crear el gestor de fitxers. + + + + Failed to open the file, cause: %1 + Ha fallat obrir el fitxer, causa: %1 + + + + Original file does not exist + El fitxer original no existeix. + + + + Do you want to delete %1? + Voleu eliminar %1? + + + + Confirm + button + Confirmeu-ho + + + + + + + + %1 are not allowed + No es permeten %1 + + + + + Failed to start Samba services + No s'han pogut iniciar els serveis de Samba. + + + + RecentController + + + Cancel + button + Cancel·la + + + + Remove + button + Elimina + + + + Do you want to remove this item? + Voleu eliminar aquest element? + + + + Do yout want to remove %1 items? + Voleu eliminar %1 elements? + + + + It does not delete the original files + No s'eliminen els fitxers originals. + + + + ShareInfoFrame + + + Share this folder + Comparteix aquesta carpeta + + + + Share name: + Nom de compartició: + + + + Permission: + Permís: + + + + Read and write + De lectura i d'escriptura + + + + Read only + Només de lectura + + + + Anonymous: + Anònim + + + + Not allow + No ho permetis + + + + Allow + Permet-ho + + + + The share name must not be two dots (..) or one dot (.) + El nom de la compartició no ha de tenir dos punts (..) ni un punt (.). + + + + The share name is used by another user. + El nom de compartició l'usa un altre usuari. + + + + OK + button + D'acord + + + + Cancel + button + Cancel·la + + + + Replace + button + Reemplaça + + + + The share name already exists. Do you want to replace the shared folder? + El nom de compartició ja existeix. Voleu reemplaçar la carpeta compartida? + + + + Shortcut + + + Item + Element + + + + Select to the first item + Selecciona fins al primer element + + + + Shift + Home + Maj. + Inici + + + + Select to the last item + Selecciona fins al darrer element + + + + Shift + End + Maj. + Fi + + + + Select leftwards + Selecciona cap a l'esquerra + + + + Shift + Left + Maj. + Esquerra + + + + Select rightwards + Selecciona cap a la dreta + + + + Shift + Right + Maj. + Dreta + + + + Select to upper row + Selecciona cap a la línia superior + + + + Shift + Up + Maj. + Amunt + + + + Select to lower row + Selecciona cap a la línia inferior + + + + Shift + Down + Maj. + Avall + + + + Open + Obre + + + + Ctrl + Down + Ctrl + Avall + + + + To parent directory + Cap al directori pare + + + + Ctrl + Up + Ctrl + Amunt + + + + Permanently delete + Elimina permanentment + + + + Shift + Delete + Maj. + Elimina + + + + Delete file + Elimina el fitxer + + + + Delete + Elimina + + + + Select all + Selecciona-ho tot + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Maj. + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Copia + + + + Cut + Retalla + + + + Paste + Enganxa + + + + Rename + Canvia'n el nom + + + + F2 + F2 + + + + New/Search + Cerca nova + + + + New window + Finestra nova + + + + New folder + Carpeta nova + + + + + Search + Cerca + + + + New tab + Pestanya nova + + + + View + Visualització + + + + Item information + Informació de l'element + + + + Help + Ajuda + + + + F1 + F1 + + + + Keyboard shortcuts + Dreceres del teclat + + + + Ctrl + Shift + / + Ctrl + Maj. + / + + + + Switch display status + Canvia l'estat de la visualització + + + + Hide item + Amaga l'element + + + + Input in address bar + Entrada a la barra d'adreces + + + + Switch to icon view + Canvia a la visualització d'icona + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Canvia a la visualització de llista + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Altres + + + + Close + Tanca + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Tanca la pestanya actual + + + + Back + Enrere + + + + Alt + Left + Alt + Esquerra + + + + Alt + Right + Alt + Dreta + + + + Switch to next tab + Canvia a la pestanya següent + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Maj. + Tab + + + + Switch to previous tab + Canvia a la pestanya anterior + + + + Next file + Fitxer següent + + + + Tab + Tab + + + + Previous file + Fitxer anterior + + + + Shift + Tab + Maj. + Tab + + + + Switch tab by specified number between 1 to 8 + Canvia de pestanya especificant un número d'entre l'1 al 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Endavant + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + No es poden obrir els elements de la paperera. Si us plau, restaureu-los primer. + + + + TrashPropertyDialog + + + Trash + Paperera + + + + item + element + + + + items + elements + + + + Contains %1 %2 + Conté %1 %2 + + + + UDiskListener + + + Failed to rename the label + Ha fallat canviar el nom de l'etiqueta. + + + + UnmountWorker + + + + + The device was not safely unmounted + El dispositiu no s'ha desmuntat amb seguretat. + + + + The device was not safely removed + El dispositiu no s'ha extret amb seguretat. + + + + UserShareManager + + + Kindly Reminder + Recordatori amable + + + + Please firstly install samba to continue + Primer, instal·leu samba per continuar. + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + El nom de compartició no ha de contenir %<>*?|/\+=;:," i no hauria de començar amb %1. + + + + To protect the files, you cannot share this folder. + Per protegir els fitxers, no podeu compartir aquesta carpeta. + + + + Sharing failed + Ha fallat la compartició. + + + + The computer name is too long + El nom de l'ordinador és massa llarg. + + + + You do not have permission to operate file/folder! + No teniu permís per fer operacions amb el fitxer o carpeta! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Escriviu una contrasenya per protegir les carpetes compartides. + + + + Cancel + button + Cancel·la + + + + Confirm + button + Confirmeu-ho + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_cs.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_cs.ts new file mode 100644 index 0000000..4fc5de9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_cs.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Nová složka + + + + Mounting device error + Chyba při připojování zařízení + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Obraz disku byl poškozen. Nyní ho nelze připojit. Nejprve disk vymažte + + + + Mount error: unsupported image format + Chyba připojování: Nepodporovaný formát obrazu + + + + + The device was not safely removed + Zařízení nebylo bezpečně odebráno + + + + + Click "Safely Remove" and then disconnect it next time + Příště klepněte na „Bezpečně odebrat“, a až pak odpojte + + + + The device was not ejected + Zařízení nebylo vysunuto + + + + Disk is busy, cannot eject now + Disk je zaneprázdněn, nyní ho proto nelze vysunout + + + + Authentication timed out + Překročen časový limit pro ověření se + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Přenos souborů přes Bluetooth + + + + File Transfer Successful + Přenos souboru úspěšný + + + + File Transfer Failed + Přenos souboru se nezdařil + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Odesílání souborů do „<b style="font-weight: 550;">%1</b>“ + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Nepodařilo se odeslat soubory do „<b style="font-weight: 550;">%1</b>“ + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Odeslání do „<b style="font-weight: 550;">%1</b>“ úspěšné + + + + Select a Bluetooth device to receive files + Vyberte Bluetooth zařízení, ze kterého obdržet soubory + + + + Cannot find the connected Bluetooth device + Nedaří se najít připojené Bluetooth zařízení + + + + Waiting to be received... + Čeká se na přijetí… + + + + Go to Bluetooth Settings + Přejít do nastavení Bluetooth + + + + %1/%2 Sent + Odesláno %1/%2 + + + + Error: the Bluetooth device is disconnected + Chyba: Bluetooth zařízení je odpojeno + + + + Unable to send the file more than 2 GB + Není možné odesílat soubory větší než 2 GB + + + + Unable to send 0 KB files + Není možné odesílat prázdné (0 KB) soubory + + + + File doesn't exist + Soubor neexistuje + + + + Next + button + Další + + + + Cancel + button + Zrušit + + + + Done + button + Hotovo + + + + Retry + button + Zkusit znovu + + + + OK + button + OK + + + + File sending request timed out + Překročen časový limit požadavku na odeslání souboru + + + + The service is busy and unable to process the request + Služba je zaneprázdněná a nemůže požadavek zpracovat + + + + BurnOptDialog + + + Device error + Chyba zařízení + + + + Optical device %1 doesn't exist + Optické zařízení %1 neexistuje + + + + Advanced settings + Pokročilá nastavení + + + + File system: + Souborový systém: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (pro systém Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (pro unixové systémy) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (kompatibilní s režimem CD/DVD Windows) + + + + ISO9660 Only + Pouze ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Zavřít vše + + + + Total size: %1, %2 files + Celková velikost: %1, %2 souborů + + + + ComputerModel + + + Double click to open it + + + + + My Directories + Moje složky + + + + Disks + Disky + + + + File Vault + Trezor pro soubory + + + + Quick Access + + + + + ComputerPropertyDialog + + + Computer + Počítač + + + + Basic Info + Základní informace + + + + + Computer Name + Název počítače + + + + + Edition + Vydání + + + + + + Version + Verze + + + + + Type + Typ + + + + + + Processor + Procesor + + + + + + Memory + Paměť + + + + + + + Bit + Bit + + + + + Available + K dispozici + + + + Obtaining... + Získává se + + + + ConnectToServerDialog + + + Connect to Server + Připojit se k serveru + + + + Cancel + button + Zrušit + + + + Connect + button + Připojit + + + + My Favorites: + Moje oblíbené: + + + + + Clear History + Smazat historii + + + + DFMAddressBar + + + Search or enter address + Vyhledávání nebo zadání adresy + + + + DFMAdvanceSearchBar + + + Search: + Hledat: + + + + File Type: + Typ souboru: + + + + File Size: + Velikost souboru: + + + + Time Modified: + Změněno: + + + + Time Accessed: + Okamžik přístupu: + + + + Time Created: + Okamžik vytvoření: + + + + Reset + Vynulovat + + + + All subdirectories + Všechny podsložky + + + + Current directory + Stávající složka + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Dnes + + + + Yesterday + Včera + + + + This week + Tento týden + + + + Last week + Poslední týden + + + + This month + Tento měsíc + + + + Last month + Poslední měsíc + + + + This year + Tento rok + + + + Last year + Poslední rok + + + + DFMOpticalMediaWidget + + + + No files to burn + Žádné soubory pro vypálení + + + + Unable to burn. Not enough free space on the target disk. + Není možné zapsat. Nedostatek volného prostoru na cílovém disku. + + + + %1 burning is not supported + %1 vypalování není podporováno + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. Není disk %1; +2. Verze tohoto souborového systému zatím nepodporuje přidávání souborů. + + + + DFMTagCrumbController + + + Tag information + Informace o značce + + + + DFMTagWidget + + + Tag + Štítek + + + + DFMTaskWidget + + + Do not ask again + Znovu se neptat + + + + Syncing data + Synchronizují se data + + + + Please wait + Počkejte, prosím + + + + + Time modified: %1 + Změněno: %1 + + + + + Contains: %1 + Obsahuje: %1 + + + + + Size: %1 + Velikost: %1 + + + + Original folder + Původní složka + + + + Keep both + button + Ponechat oba + + + + Skip + button + Přeskočit + + + + Replace + button + Nahradit + + + + Retry + button + Zkusit znovu + + + + Original file + Původní soubor + + + + Target folder + Cílová složka + + + + Target file + Cílový soubor + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Zašifrovat trezor na soubory + + + + Click 'Encrypt' and input the user password. + Klepněte na „Zašifrovat“ a zadejte heslo uživatele + + + + Encrypting... + Šifruje se… + + + + + + + Encrypt + Šifrovat + + + + Failed to create file vault: %1 + Nepodařilo se vytvořit trezor na soubory: %1 + + + + OK + OK + + + + The setup is complete + Nastavení je dokončeno + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + + + + + Keep the key safe to retrieve the vault password later + + + + + Save to default path + + + + + Save to other locations + + + + + No permission, please reselect + + + + + Select a path + + + + + Next + Další + + + + The default path is invisible to other users, and the path information will not be shown. + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Obnovovací klíč + + + + Generate a recovery key in case that you forgot the password + Vytvořte si obnovovací klíč pro případ, že byste zapomněli heslo + + + + Key + Klíč + + + + QR code + QR kód + + + + Scan QR code and save the key to another device + Naskenujte QR kód a klíč uložte na jiném zařízení + + + + Next + Další + + + + Recovery Key: + Obnovovací klíč: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Nastavit heslo k trezoru + + + + Method + Metoda + + + + Manual + Ruční + + + + Password + Heslo + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + alespoň 8 znaků, obsahující A-Z, a-z, 0-9 a symboly + + + + Repeat password + Zopakovat heslo + + + + Input the password again + Zopakujte zadání hesla + + + + Password hint + Nápověda pro heslo + + + + Optional + Volitelné + + + + Next + Další + + + + + Passwords do not match + Zadání hesla se neshodují + + + + DFMVaultActiveStartView + + + File Vault + Trezor pro soubory + + + + Create your secure private space + Vytvořte si svůj soukromý zabezpečený prostor + + + + Advanced encryption technology + Pokročilá šifrovací technologie + + + + Convenient and easy to use + Pohodlné a snadno se používající + + + + Create + Vytvořit + + + + DFMVaultFileView + + + Cannot open this path + + + + + Hint + + + + + OK + OK + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Odemknout klíčem + + + + Failed to unlock file vault + Nepodařilo se odemknout trezor + + + + OK + OK + + + + Input the 32-digit recovery key + Zadejte obnovovací klíč (32 číslic) + + + + Cancel + button + Zrušit + + + + Unlock + button + Odemknout + + + + Wrong recovery key + Nesprávný obnovovací klíč + + + + DFMVaultRemoveByPasswordView + + + Password + Heslo + + + + Password hint: %1 + Nápověda pro heslo: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Zadejte obnovovací klíč (32 číslic) + + + + DFMVaultRemovePages + + + Delete File Vault + Smazat trezor na soubory + + + + Once deleted, the files in it will be permanently deleted + Po jeho smazání budou soubory v něm natrvalo smazány + + + + Use Key + Použít klíč + + + + Cancel + button + Zrušit + + + + Use Key + button + Použít klíč + + + + Delete + button + Smazat + + + + + OK + button + OK + + + + Use Password + Použít heslo + + + + Wrong password + Nesprávné heslo + + + + Wrong recovery key + Nesprávný obnovovací klíč + + + + Failed to delete file vault + Nepodařilo se smazat trezor na soubory + + + + Deleted successfully + Úspěšně smazáno + + + + Failed to delete + Nepodařilo se smazat + + + + Removing... + Odebírání… + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + + + + + Verification failed + + + + + + Select a path + + + + + + Retrieve Password + + + + + By key in the default path + + + + + By key in the specified path + + + + + Verification Successful + + + + + Keep it safe + + + + + Back + button + Zpět + + + + Verify Key + button + + + + + Go to Unlock + button + + + + + Close + button + Zavřít + + + + Vault password: %1 + + + + + DFMVaultUnlockPages + + + Unlock File Vault + Odemknout trezor na soubory + + + + Forgot password? + + + + + Password hint: %1 + Nápověda pro heslo: %1 + + + + Failed to unlock file vault + Nepodařilo se odemknout trezor + + + + Cancel + button + Zrušit + + + + Password + Heslo + + + + Unlock + button + Odemknout + + + + Please try again %1 minutes later + + + + + Wrong password, please try again %1 minutes later + + + + + Wrong password, one chance left + + + + + Wrong password, %1 chances left + + + + + Wrong password + Nesprávné heslo + + + + OK + button + OK + + + + DFileCopyMoveJob + + + Permission error + Chyba v oprávnění + + + + The action is denied + Tato akce je zakázána + + + + Failed to open the file + Soubor se nepodařilo otevřít + + + + Failed to read the file + Soubor se nepodařilo přečíst + + + + Failed to write the file + Do souboru se nepodařilo zapsat + + + + Failed to create the directory + Složku se nepodařilo vytvořit + + + + Failed to delete the file + Soubor se nepodařilo smazat + + + + Failed to move the file + Soubor se nepodařilo přesunout + + + + Original file does not exist + Původní soubor neexistuje + + + + Failed, file size must be less than 4GB + Nezdařilo se. Je třeba, aby velikost souboru byla menší než 4 GB. + + + + Not enough free space on the target disk + Nedostatek volného místa na cílovém disku + + + + File integrity was damaged + Soubor je poškozený + + + + The target device is read only + Cílové zařízení je pouze pro čtení + + + + Target folder is inside the source folder + Cílová složka je uvnitř zdrojové složky (nelze samo do sebe) + + + + The action is not supported + Akce není podporována + + + + You do not have permission to traverse files in it + Nemáte oprávnění pro procházení souborů v ní + + + + Failed to position the file pointer! + + + + + copy + Extra name added to new file name when used for file name. + kopírovat + + + + Failed to open the directory, cause: file name too long + Nepodařilo se otevřít složku. Příčina: název souboru je příliš dlouhý + + + + + Failed to open the file, cause: file name too long + Nepodařilo se otevřít soubor. Příčina: název souboru je příliš dlouhý + + + + + Failed to write the file, cause: + Soubor se nepodařilo zapsat, protože: + + + + Failed to position the file pointer, cause: %1 + + + + + Syncing data + Synchronizují se data + + + + Please wait + Počkejte, prosím + + + + Failed to create the directory, cause: %1 + Složku se nepodařilo vytvořit – příčina: %1 + + + + + + + + Failed to open the file, cause: %1 + Soubor se nepodařilo otevřít – příčina: + + + + + + + Failed to open the file, cause: Permission denied + Soubor se nepodařilo otevřít – příčina: přístup odepřen + + + + + Failed to read the file, cause: %1 + Ze souboru se nepodařilo číst – příčina: + + + + + + + Failed to write the file, cause: %1 + Do souboru se nepodařilo zapsat – příčina: %1 + + + + + File integrity was damaged, cause: %1 + Soubor je poškozený – důvod: %1 + + + + Failed to open the file, cause: + Soubor se nepodařilo otevřít, protože: + + + + Failed to read the file, cause: + Ze souboru se nepodařilo číst, protože: + + + + Failed to delete the file, cause: %1 + Soubor se nepodařilo smazat – příčina: + + + + Fail to create symlink, cause: %1 + Symbolický odkaz se nepodařilo vytvořit – příčina: %1 + + + + DFileDialog + + + + Save + button + Uložit + + + + + Cancel + button + Zrušit + + + + Confirm + button + Potvrdit + + + + %1 already exists, do you want to replace it? + %1 už existuje. Chcete ji nahradit? + + + + Replace + button + Nahradit + + + + Open + button + Otevřít + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Pokud název souboru bude začínat na tečku (.), bude skrytý. Opravdu to chcete? + + + + DFileManagerWindow + + + Trash + Koš + + + + Empty + Prázdný + + + + DFileSystemModel + + + + Name + Název + + + + + + Time modified + Změněno + + + + Size + Velikost + + + + Type + Typ + + + + Time created + Vytvořeno + + + + + Last access + Poslední přístup + + + + + + + Path + Popis umístění + + + + DFileView + + + Disc mount error + Chyba při připojování disku + + + + The disc is in use, please end the running process and remount the disc. + Disk se používá. Ukončete, prosím, běžící proces a disk znovu připojte. + + + + Mounting failed + Připojování (mount) se nezdařilo + + + + (Reverse) + (obrácený) + + + + DFileViewHelper + + + Add tag "%1" + Přidat štítek „%1“ + + + + DStatusBar + + + %1 item + %1 položka + + + + %1 items + %1 položek + + + + %1 item selected + Vybrána %1 položka + + + + %1 items selected + Vybráno %1 položek + + + + %1 folder selected (contains %2) + Vybrána %1 složka (obsahuje %2) + + + + %1 folders selected (contains %2) + Vybráno %1 složek (obsahuje %2) + + + + %1 file selected (%2) + Vybrán %1 soubor (%2) + + + + %1 files selected (%2) + Vybráno %1 souborů (%2) + + + + %1 folder selected + Vybrána %1 složka + + + + Filter + Filtrovat + + + + Save as: + Uložit jako: + + + + Loading... + Načítání… + + + + DTaskDialog + + + Erasing disc %1, please wait... + Maže se disk %1 – čekejte prosím… + + + + Burning disc %1, please wait... + Vypalování disku %1 – čekejte prosím… + + + + Writing data... + Zápis dat… + + + + Verifying data... + Ověřování dat… + + + + Copying %1 + Kopíruje se %1 + + + + + + to %2 + do %2 + + + + %1 already exists in target folder + %1 už v cílové složce existuje + + + + Original path %1 Target path %2 + Původní umístění %1, cílové %2 + + + + Merge + button + Sloučit + + + + Replace + button + Nahradit + + + + Moving %1 + Přesunuje se %1 + + + + Removing file vault, please try later + Odebírání trezoru pro soubory - zkuste to znovu později + + + + Restoring %1 + Obnovuje se %1 + + + + Deleting %1 + Maže se %1 + + + + Trashing %1 + Přesouvání %1 do koše + + + + Calculating space, please wait + Počítá se místo – čekejte prosím + + + + DUMountManager + + + + Authentication timed out + Překročen časový limit pro ověření se + + + + + + Disk is busy, cannot unmount now + Disk je zaneprázdněn, nyní ho proto nelze odpojit + + + + Disk is busy, cannot eject now + Disk je zaneprázdněn, nyní ho proto nelze vysunout + + + + The device is busy, cannot eject now + Zařízení je něčím využíváno, proto ho nyní není možné vysunout + + + + + + The device is busy, cannot remove now + Zařízení je něčím využíváno, proto ho není možné nyní odebrat + + + + DeepinStorage + + + + + %1 Volume + %1 svazek + + + + Data Disk + Data Partition + Datový disk + + + + %1 Drive + %1 mechanika + + + + Blank %1 Disc + Prázdný %1 disk + + + + %1 Encrypted + %1 zašifrováno + + + + DialogManager + + + + + + Operation failed! + Operace se nezdařila! + + + + Target folder is inside the source folder! + Cílová složka je uvnitř zdrojové složky (nelze samo do sebe)! + + + + Do you want to run %1 or display its content? + Chcete %1 spustit nebo zobrazit jeho obsah? + + + + It is an executable text file. + Je spustitelným textovým souborem. + + + + It is an executable file. + Je spustitelným textovým souborem. + + + + This file is not executable, do you want to add the execute permission and run? + Tento soubor není spustitelný. Chcete přidat oprávnění pro spouštění a spustit ho? + + + + "%1" already exists, please use another name. + „%1“ už existuje. Použijte jiný název. + + + + The file name must not contain two dots (..) + Je třeba, aby název souboru neobsahoval dvě po sobě jdoucí tečky (..) + + + + Device or resource busy + + + + + Are you sure you want to erase all data on the disc? + Opravdu chcete smazat všechna data na disku? + + + + How do you want to use this disc? + Jak chcete tento disk použít? + + + + Disc erase failed + Disk se nepodařilo smazat + + + + Burn process failed + Vypalování se nezdařilo + + + + %1: %2 + %1: %2 + + + + Show details + Zobrazit podrobnosti + + + + Hide details + Skrýt podrobnosti + + + + Error + Chyba + + + + Permanently delete %1? + Nadobro smazat %1? + + + + Permanently delete %1 items? + Nadobro smazat %1 položek? + + + + Empty + Prázdný + + + + Do you want to delete %1? + Opravdu chcete %1 smazat? + + + + Do you want to delete the selected %1 items? + Opravdu chcete označených %1 položek smazat? + + + + Sorry, unable to locate your bookmark directory, remove it? + Je nám líto, ale nepodařilo najít složku s vašimi záložkami. Odstranit? + + + + Name: + Název: + + + + %1 that this shortcut refers to has been changed or moved + %1 odkazující na tuto zkratku byl změněn nebo přesunut + + + + Do you want to delete this shortcut? + Chcete smazat tuto klávesovou zkratku? + + + + Failed, file size must be less than 4GB. + Nezdařilo se. Je třeba, aby velikost souboru byla menší než 4 GB. + + + + Fail to create symlink, cause: + Symbolický odkaz se nepodařilo vytvořit – příčina: + + + + The selected files contain system file/directory, and it cannot be deleted + Vybrané soubory obsahují systémový soubor/složku, a nelze je proto smazat + + + + Unable to find the original file + Nelze najít původní soubor + + + + + You do not have permission to operate file/folder! + Nemáte oprávnění pro přistupování k této složce/souboru! + + + + Failed to restore %1 file, the source file does not exist + Nepodařilo se obnovit %1 soubor, zdrojový soubor neexistuje + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Je nám líto, ale nemáte oprávnění pro přístup k následujícímu %1 souboru/složce(kám)! + + + + Unable to access %1 + Nedaří se přistupovat k %1 + + + + + Sending files now, please try later + Soubory jsou nyní odesílány, zkuste to prosím později + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Aby bylo možné k zařízení přistupovat, je třeba ho nejprve naformátovat. Chcete to provést nyní? + + + + Scanning the device, stop it? + Prohledává se zařízení. Zastavit? + + + + Share folder can't be named after the current username + Sdílenou složku nelze nazvat stejně jako uživatelské jméno, kterým jste právě přihlášení + + + + Do you want to run %1? + Chcete %1 spustit? + + + + Burn image + button + Vypálit obraz + + + + Burn files + button + Vypálit soubory + + + + Are you sure you want to empty %1 item? + Chcete smazat %1 položku? + + + + Are you sure you want to empty %1 items? + Chcete smazat %1 položek? + + + + + This action cannot be undone + Tuto akci není možné vzít zpět + + + + + + + + + + + + + + OK + button + OK + + + + + + + + + + + + + + + Cancel + button + Zrušit + + + + + + Run + button + Spustit + + + + + Run in terminal + button + Spustit v terminálu + + + + Display + button + Zobrazení + + + + + + + + + + + Confirm + button + Potvrdit + + + + Erase + button + Vymazat + + + + Data verification failed + Ověření dat se nezdařilo + + + + Show details + button + Zobrazit podrobnosti + + + + + Delete + button + Smazat + + + + Remove + button + Odstranit + + + + Disk is busy, cannot unmount now + Disk je zaneprázdněn, nyní ho proto nelze odpojit + + + + Force unmount + button + Vynutit odpojení + + + + Unable to copy. Not enough free space on the target disk. + Nelze zkopírovat. Nedostatek volného místa na cílovém disku. + + + + Failed to restore %1 file, the target folder is read-only + Nepodařilo se obnovit %1 soubor, cílová složka je jen pro čtení + + + + Failed to restore %1 files, the target folder is read-only + Nepodařilo se obnovit %1 souborů, cílová složka je jen pro čtení + + + + Failed to restore %1 files, the source files do not exist + Nepodařilo se obnovit %1 souborů, zdrojové soubory neexistují + + + + Format + button + Formát + + + + Stop + button + Zastavit + + + + FileController + + + + + + Unable to find the original file + Nelze najít původní soubor + + + + + + Kindly Reminder + Laskavá připomínka + + + + + + Please install File Roller first and then continue + Nejprve je třeba nainstalovat nástroj Správce archivů + + + + + Unable to create files here: %1 + Soubory zde není možné vytvářet: %1 + + + + Confirm + button + Potvrdit + + + + FileDialogStatusBar + + + File Name + Název souboru + + + + Format + Formát + + + + Save + button + Uložit + + + + Open + button + Otevřít + + + + Save File + button + Uložit soubor + + + + Open File + button + Otevřít soubor + + + + + + Cancel + button + Zrušit + + + + FileJob + + + copy + Kopírovat + + + + + + + Data verification successful. + Data úspěšně ověřena. + + + + + + Burn process completed + Vypalování dokončeno + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 je kopie souboru. + + + + Insufficient disc space. + Nedostatek místa na disku. + + + + Lost connection to drive. + Spojení s mechanikou ztraceno. + + + + The CD/DVD drive is not ready. Try another disc. + Mechanika CD/DVD není připravena. Zkuste jiný disk. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + Mechanika optických disků je zaneprázdněna. Ukončete program používající mechaniku a disk vložte znovu. + + + + Unknown error + Neznámá chyba + + + + Device disconnected + Zařízení odpojeno + + + + GenerateSettingTranslate + + + + + Basic + Základní + + + + + + Open behavior + Chování pro otevírání + + + + + + Always open folder in new window + Složku vždy otevřít v novém okně + + + + + + Open file: + Otevřít soubor: + + + + + + Click + Klepnutí + + + + + + Double click + Dvojklepnutí + + + + + + New window and tab + Nové okno a karta + + + + + + Open from default window: + V okně otevírat jako výchozí: + + + + + + + + + Computer + Počítač + + + + + + + + + Home + Domů + + + + + + + + + Desktop + Plocha + + + + + + + + + Videos + Videa + + + + + + + + + Music + Hudba + + + + + + + + + Pictures + Obrázky + + + + + + + + + Documents + Dokumenty + + + + + + + + + Downloads + Stažené + + + + + + Open in new tab: + V nové kartě otevřít: + + + + + + Current Directory + Stávající složka + + + + + + View + Pohled + + + + + + Default size: + Výchozí velikost: + + + + + + Extra small + Velice malá + + + + + + Small + Malá + + + + + + Medium + Střední + + + + + + Large + Velká + + + + + + Extra large + Opravdu velká + + + + + + Default view: + Výchozí pohled: + + + + + + Icon + Ikony + + + + + + List + Seznam + + + + + + Hidden files + Skryté soubory + + + + + + Show hidden files + Zobrazit skryté soubory + + + + + + Hide file extension when rename + Při přejmenovávání vynechat příponu souboru + + + + + + Advanced + Pokročilé + + + + + + Index + Rejstřík + + + + + + Auto index internal disk + Automaticky vytvářet rejstřík obsahu vestavěného disku + + + + + + Index external storage device after connected to computer + Po jeho připojení k počítači, vytvořit rejstřík obsahu externího úložiště + + + + + + Full-Text search + Plnotextové vyhledávání + + + + + + Show item counts and sizes in the path of mounted MTP devices + Zobrazit počty položek a velikosti v popisu umístění připojených MTP zařízení + + + + + + Keep showing the mounted Samba shares + + + + + + + Use the file chooser dialog of File Manager + Použít dialog pro výběr souboru správce souborů + + + + + + Ask for my confirmation when deleting files + Při mazání souborů vyžadovat potvrzení + + + + + + Other + Ostatní + + + + + + Hide system disk + Skrýt systémový disk + + + + + + Show file system on disk icon + Zobrazovat typ souborového systému na ikoně disku + + + + + + Show hidden files in search results + Zobrazovat ve výsledcích hledání skryté soubory + + + + + + Display recent file entry in left panel + Zobrazit nedávný soubor v levém panelu + + + + + + Preview + Náhled + + + + + Compress file preview + Náhled zkomprimovaného souboru + + + + + + Text preview + Náhled textu + + + + + + Document preview + Náhled na dokument + + + + + + Image preview + Náhled na obrázek + + + + + + Video preview + Náhled videa + + + + + + Mount + Připojit + + + + + + Auto mount + Připojit automaticky + + + + + + Open after auto mount + Po automatickém připojení otevřít + + + + + + Dialog + Dialog + + + + Compressed file preview + Náhled komprimovaného souboru + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Nedaří se ověřit totožnost %1. + + + + This happens when you log in to a computer the first time. + Toto se stává, když se k počítači přihlašujete poprvé. + + + + The identity sent by the remote computer is + Totožnost poslaná vzdáleným počítačem je + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Pokud si chcete být zcela jistí, zda je bezpečné pokračovat, obraťte se na správce systému. + + + + + + + + Mounting device error + Chyba při připojování zařízení + + + + + Wrong username or password + Nesprávné uživatelské jméno nebo heslo + + + + + + + + Confirm + button + Potvrdit + + + + + Cannot find the mounted device + Nedaří se nalézt připojené zařízení + + + + No key available to unlock device + Není k dispozici žádný klíč pro odemknutí zařízení + + + + The disk is mounted by user "%1", you cannot unmount it. + Disk je připojený (mount) uživatelem „%1“ – vy ho odpojit nemůžete. + + + + Cannot unmount the device + Zařízení se nedaří odpojit + + + + Cannot eject the device "%1" + Zařízení „%1“ není možné vysunout + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Není možné zapsat. Nedostatek volného prostoru na cílovém disku. + + + + MergedDesktopController + + + + Pictures + Obrázky + + + + + Music + Hudba + + + + + Applications + Aplikace + + + + + Videos + Videa + + + + + Documents + Dokumenty + + + + + Others + Ostatní + + + + MimeTypeDisplayManager + + + + Directory + Složka + + + + + + Application + Aplikace + + + + + + Video + Obraz + + + + + + Audio + Zvuk + + + + + + Image + Obrázek + + + + + Archive + Archiv + + + + + + Text + Text + + + + + Executable + Spustitelný + + + + + Backup file + Záložní soubor + + + + + Unknown + Neznámý + + + + MountAskPasswordDialog + + + Cancel + button + Zrušit + + + + Connect + button + Připojit + + + + Log in as + Přihlásit se jako + + + + Anonymous + Anonymní + + + + Registered user + Zaregistrovaný uživatel + + + + Username + Uživatelské jméno + + + + Domain + Doména + + + + Password + Heslo + + + + Remember password + Zapamatovat si heslo + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Zrušit + + + + Unlock + button + Odemknout + + + + Input password to decrypt the disk + Zadejte heslo pro rozšifrování disku + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Opravdu chcete %1 nadobro smazat? + + + + This file is too big for the trash + Tento soubor je příliš velký pro přesunutí do koše + + + + The files are too big for the trash + Soubory jsou příliš velké pro přesunutí do koše + + + + Are you sure you want to permanently delete %1 files? + Opravdu chcete trvale smazat %1 souborů? + + + + Cancel + button + Zrušit + + + + Delete + button + Smazat + + + + OpenWithDialog + + + Open with + Otevřít s + + + + Add other programs + Přidat ostatní programy + + + + Set as default + Nastavit jako výchozí + + + + Cancel + button + Zrušit + + + + Confirm + button + Potvrdit + + + + Recommended Applications + Doporučené aplikace + + + + Other Applications + Ostatní aplikace + + + + PathManager + + + Home + Domovská složka + + + + Desktop + Plocha + + + + Videos + Videa + + + + Music + Hudba + + + + Pictures + Obrázky + + + + Documents + Dokumenty + + + + Downloads + Stažené + + + + + Trash + Koš + + + + + + System Disk + Systémový disk + + + + Computers in LAN + Počítače v místní síti (LAN) + + + + My Shares + Má sdílení + + + + Computer + Počítač + + + + Recent + Nedávné + + + + File Vault + Trezor pro soubory + + + + PropertyDialog + + + Basic info + Základní informace + + + + Open with + Otevřít s + + + + Sharing + Sdílení + + + + Permissions + Oprávnění + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Skrýt tuto složku + + + + Hide this file + Skrýt tento soubor + + + + Allow to execute as program + Umožnit spouštět jako program + + + + QObject + + + + + + Size + Velikost + + + + + + Contains + Obsahuje + + + + + + Type + Typ + + + + + + + + Time modified + Změněno + + + + Free space + Volné místo + + + + Total space + Celkový prostor + + + + + Time locked + Čas uzamčen + + + + Access denied + Přístup odepřen + + + + + Executable + Spustitelný + + + + + Write only + Pouze zápis + + + + + Read only + Pouze pro čtení + + + + + Read-write + Čtení a zápis + + + + Others + Ostatní + + + + Owner + Vlastník + + + + Unconnected network shared directory + + + + + Device type + Typ zařízení + + + + File system + Souborový systém + + + + Group + Skupina + + + + + Open + Otevřít + + + + Lock + Zamknout + + + + Auto lock + Automatické zamykání + + + + Never + Nespouštět + + + + 5 minutes + 5 minut + + + + 10 minutes + 10 minut + + + + 20 minutes + 20 minut + + + + Delete File Vault + Smazat trezor na soubory + + + + Unlock + Odemknout + + + + Unlock by key + Odemknout klíčem + + + + Open + button + Otevřít + + + + + Size: %1 + Velikost: %1 + + + + Type: %1 + Typ: %1 + + + + Size: 0 + Velikost: 0 + + + + Items: %1 + Položek: %1 + + + + + + + + + + Open in new window + Otevřít v novém okně + + + + + + + + + + Open in new tab + Otevřít v nové kartě + + + + Open with + Otevřít s + + + + + Compress + Komprimovat + + + + Extract + Rozbalit + + + + Extract here + Rozbalit zde + + + + Cut + Vyjmout + + + + Copy + Kopírovat + + + + Paste + Vložit + + + + + + + + Rename + Přejmenovat + + + + + + + Remove + Odstranit + + + + Create link + Vytvořit odkaz + + + + Send to desktop + Odeslat na pracovní plochu + + + + Send to + Odeslat na + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Přidat do záložek + + + + + + + Properties + Vlastnosti + + + + New folder + Nová složka + + + + New window + Nové okno + + + + Select all + Vybrat vše + + + + + Clear recent history + Smazat nedávnou historii + + + + + + Empty Trash + Vyprázdnit koš + + + + Display as + Zobrazit jako + + + + Sort by + Seřadit podle + + + + New document + Nový dokument + + + + + Time created + Čas vytvoření + + + + + + Source path + Zdrojový popis umístění + + + + Share folder + Sdílet složku + + + + Cancel sharing + Zrušit sdílení + + + + Connect to Server + Připojit se k serveru + + + + Set share password + Nastavit heslo pro sdílení + + + + Format + Formát + + + + Tag information + Informace o značce + + + + Open as administrator + Otevřít jako správce + + + + Select default program + Vybrat výchozí program + + + + Open file location + Otevřít umístění souboru + + + + Remove bookmark + Odstranit záložku + + + + + + Delete + Smazat + + + + Office Text + Textový dokument + + + + Spreadsheets + Tabulky + + + + Plain Text + Neformátovaný text + + + + Open in terminal + Otevřít v terminálu + + + + Restore + Obnovit + + + + Restore all + Obnovit vše + + + + Clear saved password and unmount + + + + + File Vault + Trezor na soubory + + + + Add to disc + Přidat na disk + + + + Refresh + + + + + Auto mount + Připojit automaticky + + + + Open after auto mount + Po automatickém připojení otevřít + + + + + Mount + Připojit + + + + + Unmount + Odpojit + + + + It does not support burning %1 discs + Nepodporuje vypalování disků %1 + + + + Burn + Vypálit + + + + Disc name: + Název disku: + + + + + Maximum + Maximum + + + + Allow files to be added later + Umožnit přidávat později další soubory (neuzavírat disk) + + + + Verify data + Ověřit data + + + + Write speed: + Rychlost zápisu: + + + + + + + Cancel + button + Zrušit + + + + Burn + button + Vypálit + + + + + Eject + Vysunout + + + + Safely Remove + Bezpečně odstranit + + + + + Name + Název + + + + Settings + Nastavení + + + + Exit + Ukončit + + + + Icon + Ikony + + + + List + Seznam + + + + Extend + Rozšířit + + + + Set as wallpaper + Nastavit jako pozadí + + + + + + + Local disk + Pevný disk + + + + + Removable disk + Vyměnitelný disk + + + + + + Network shared directory + Síťová sdílená složka + + + + + Android mobile device + Android mobilní zařízení + + + + + Apple mobile device + Apple mobilní zařízení + + + + + Camera + Kamera + + + + + DVD + DVD + + + + + Unknown device + Neznámé zařízení + + + + + + %1 item + %1 položka + + + + + + %1 items + %1 položek + + + + Shortcut + -odkaz_na + + + + Create symlink + Vytvořit symbolický odkaz + + + + Path + Popis umístění + + + + + + Time deleted + Smazáno + + + + Loading... + Načítání… + + + + File has been moved or deleted + Soubor byl přesunut nebo smazán + + + + You do not have permission to traverse files in it + Nemáte oprávnění pro procházení souborů v ní + + + + + + You do not have permission to access this folder + Nemáte oprávnění pro přistupování k této složce + + + + + + + + Folder is empty + Složka je prázdná + + + + Searching... + Hledání… + + + + No results + Nic nenalezeno + + + + Source Path + TrashFileInfo + Zdrojový popis umístění + + + + Document + Dokument + + + + Spreadsheet + Tabulka + + + + + Presentation + Prezentace + + + + Text + Text + + + + 1 task in progress + 1 probíhající úloha + + + + %1 tasks in progress + %1 probíhajících úloh + + + + Mode: + Režim: + + + + + Replace Text + Nahradit text + + + + + Add Text + Přidat text + + + + + Custom Text + Vlastní text + + + + Find: + Najít: + + + + Replace: + Nahradit: + + + + + Optional + Volitelné + + + + Add: + Přidat: + + + + Location: + Umístění: + + + + File name: + Název souboru: + + + + Start at: + Začínat na: + + + + + Rename + button + Přejmenovat + + + + + + + + + + + Required + Požadováno + + + + + Before file name + Před názvem souboru + + + + + After file name + Za názvem souboru + + + + Find + Najít + + + + Replace + Nahradit + + + + Add + Přidat + + + + Start at + Začínat na + + + + + + Location + Umístění + + + + File name + Název souboru + + + + Dimension + Rozměr + + + + Duration + Doba trvání + + + + Tips: Sort by selected file order + Tipy: Seřazujte podle pořadí vybraných souborů + + + + Rename %1 Files + Přejmenovat %1 souborů + + + + Multiple Files + Více souborů + + + + Basic info + Základní informace + + + + Total size + Celková velikost + + + + Number of files + Počet souborů + + + + %1 file(s), %2 folder(s) + %1 soubor(ů), %2 složka(y) + + + + + + Time accessed + Čas přístupu + + + + Orange + Oranžová + + + + Red + Červená + + + + Purple + Purpurová + + + + Navy-blue + Námořní modrá + + + + Azure + Azurová + + + + Green + Zelená + + + + Yellow + Žlutá + + + + Gray + Šedá + + + + Input tag info, such as work, family. A comma is used between two tags. + Zadejte údaje štítku – jako třeba práce, rodina, atp. Jednotlivé štítky oddělujte čárkou. + + + + Bookmarks + Záložky + + + + Erase + Vymazat + + + + Copy path + Zkopírovat cestu + + + + Edit address + Upravit adresu + + + + Free Space %1 + Volné místo %1 + + + + Files are being processed + Soubory jsou zpracovávány + + + + + Unknown + Neznámý + + + + My Vault + Můj trezor + + + + + Failed to create file info + Nepodařilo se vytvořit informace o souboru + + + + Failed to create file handler + Nepodařilo se vytvořit ovladač souboru + + + + Failed to open the file, cause: %1 + Soubor se nepodařilo otevřít – příčina: + + + + Original file does not exist + Původní soubor neexistuje + + + + Do you want to delete %1? + Opravdu chcete %1 smazat? + + + + Confirm + button + Potvrdit + + + + + + + + %1 are not allowed + %1 nejsou dovolené + + + + + Failed to start Samba services + + + + + RecentController + + + Cancel + button + Storno + + + + Remove + button + Odstranit + + + + Do you want to remove this item? + + + + + Do yout want to remove %1 items? + + + + + It does not delete the original files + + + + + ShareInfoFrame + + + Share this folder + Sdílet tuto složku + + + + Share name: + Název sdílení: + + + + Permission: + Oprávnění: + + + + Read and write + Číst a zapisovat + + + + Read only + Pouze pro čtení + + + + Anonymous: + Anonymní: + + + + Not allow + Neumožnit + + + + Allow + Povolit + + + + The share name must not be two dots (..) or one dot (.) + Je třeba, aby název sdílení nebyl dvě tečky (..) nebo jedna tečka (.) + + + + The share name is used by another user. + Název pro sdílení je používán jiným uživatelem. + + + + OK + button + OK + + + + Cancel + button + Zrušit + + + + Replace + button + Nahradit + + + + The share name already exists. Do you want to replace the shared folder? + Název pro sdílení už existuje. Přejete si sdílenou složku nahradit? + + + + Shortcut + + + Item + Položka + + + + Select to the first item + Vybrat po první položku + + + + Shift + Home + Shift + Home + + + + Select to the last item + Vybrat po poslední položku + + + + Shift + End + Shift + End + + + + Select leftwards + Vybrat směrem doleva + + + + Shift + Left + Shift + Left + + + + Select rightwards + Vybrat směrem doprava + + + + Shift + Right + Shift + Right + + + + Select to upper row + Vybrat po vyšší řádek + + + + Shift + Up + Shift + Up + + + + Select to lower row + Vybrat po nižší řádek + + + + Shift + Down + Shift + Down + + + + Open + Otevřít + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + Do nadřazené složky + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Nadobro smazat + + + + Shift + Delete + Shift + Delete + + + + Delete file + Smazat soubor + + + + Delete + Delete + + + + Select all + Vybrat vše + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Kopírovat + + + + Cut + Vyjmout + + + + Paste + Vložit + + + + Rename + Přejmenovat + + + + F2 + F2 + + + + New/Search + Nový/Hledat + + + + New window + Nové okno + + + + New folder + Nová složka + + + + + Search + Hledat + + + + New tab + Nová karta + + + + View + Pohled + + + + Item information + Informace o položce + + + + Help + Nápověda + + + + F1 + F1 + + + + Keyboard shortcuts + Klávesové zkratky + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Přepnout stav zobrazení + + + + Hide item + Skrýt položku + + + + Input in address bar + Zadat v adresním řádku + + + + Switch to icon view + Přepnout na pohled s ikonami + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Přepnout na podrobný pohled + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Ostatní + + + + Close + Zavřít + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Zavřít stávající kartu + + + + Back + Zpět + + + + Alt + Left + Alt + šipka vlevo + + + + Alt + Right + Alt + šipka vpravo + + + + Switch to next tab + Přepnout na další kartu + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Přepnout na předchozí kartu + + + + Next file + Následující soubor + + + + Tab + Karta + + + + Previous file + Předchozí soubor + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Přepnout kartu pomocí zadaného čísla z rozmezí 1 až 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Vpřed + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Nedaří se otevřít položky v koši, prosím nejprve ho obnovte + + + + TrashPropertyDialog + + + Trash + Koš + + + + item + položku + + + + items + položek + + + + Contains %1 %2 + Obsahuje %1 %2 + + + + UDiskListener + + + Failed to rename the label + Štítek se nepodařilo přejmenovat + + + + UnmountWorker + + + + + The device was not safely unmounted + Zařízení nebylo odebráno bezpečně + + + + The device was not safely removed + Zařízení nebylo bezpečně odebráno + + + + UserShareManager + + + Kindly Reminder + Laskavá připomínka + + + + Please firstly install samba to continue + Nejprve je třeba nainstalovat nástroj samba + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + + + + + To protect the files, you cannot share this folder. + Pro ochranu souborů, tuto složku není možné sdílet. + + + + Sharing failed + Nepodařilo se sdílet + + + + The computer name is too long + Název počítače je příliš dlouhý + + + + You do not have permission to operate file/folder! + Nemáte oprávnění pro přistupování k této složce/souboru! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Zadejte heslo, kterým chránit přístup do sdílených složek + + + + Cancel + button + Zrušit + + + + Confirm + button + Potvrdit + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_da.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_da.ts new file mode 100644 index 0000000..214df65 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_da.ts @@ -0,0 +1,4791 @@ + + + AppController + + + New Folder + Ny mappe + + + + Mounting device error + Fejl ved montering af enhed + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Diskaftrykket var ødelagt, kan ikke montere nu, slet venligst disken først + + + + Mount error: unsupported image format + Fejl ved montering: uunderstøttet aftryksformat + + + + + The device was not safely removed + + + + + + Click "Safely Remove" and then disconnect it next time + + + + + The device was not ejected + + + + + Disk is busy, cannot eject now + Disken er i brug. Kan ikke skubbe ud nu + + + + Authentication timed out + + + + + BluetoothTransDialog + + + Bluetooth File Transfer + + + + + File Transfer Successful + + + + + File Transfer Failed + + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + + + + + Select a Bluetooth device to receive files + + + + + Cannot find the connected Bluetooth device + + + + + Waiting to be received... + + + + + Go to Bluetooth Settings + + + + + %1/%2 Sent + + + + + Error: the Bluetooth device is disconnected + + + + + Unable to send the file more than 2 GB + + + + + Unable to send 0 KB files + + + + + File doesn't exist + + + + + Next + button + Næste + + + + Cancel + button + Annuller + + + + Done + button + Færdig + + + + Retry + button + Prøv igen + + + + OK + button + OK + + + Next + Næste + + + Cancel + Annuller + + + Done + Færdig + + + Retry + Prøv igen + + + OK + OK + + + + File sending request timed out + + + + + The service is busy and unable to process the request + + + + + BurnOptDialog + + + Device error + + + + + Optical device %1 doesn't exist + + + + + Advanced settings + Avancerede indstillinger + + + + File system: + + + + + ISO9660/Joliet (For Windows) + + + + + ISO9660/Rock Ridge (For Unix) + + + + + %1 (Compatible with Windows CD/DVD mode) + + + + + ISO9660 Only + + + + + CloseAllDialogIndicator + + + Close all + Luk alle + + + + Total size: %1, %2 files + Samlet størrelse: %1, %2 filer + + + + ComputerModel + + + + My Directories + Mine mapper + + + + + + + + + + + + Disks + Diske + + + + ComputerPropertyDialog + + + Computer + Computer + + + + Basic Info + Grundlæggende info + + + + + Computer Name + Computernavn + + + + + Edition + + + + + + + Version + Version + + + + + Type + Type + + + + + + Processor + Processor + + + + + + Memory + Hukommelse + + + + + + + Bit + Bit + + + + + Available + + + + + Obtaining... + + + + + ConnectToServerDialog + + + Connect to Server + Opret forbindelse til server + + + Cancel + Annuller + + + Connect + Opret forbindelse + + + + Cancel + button + Annuller + + + + Connect + button + Opret forbindelse + + + + My Favorites: + Mine favoritter: + + + + + Clear History + Ryd historik + + + + DFMAddressBar + + + Search or enter address + Søg eller indtast adresse + + + + DFMAdvanceSearchBar + + + Search: + Søg: + + + + File Type: + Filtype: + + + + File Size: + Filstørrelse: + + + + Time Modified: + Ændringstidspunkt: + + + + Time Accessed: + + + + + Time Created: + + + + + Reset + Nulstil + + + + All subdirectories + Alle undermapper + + + + Current directory + Nuværende mappe + + + + 0 ~ 100 KB + 0-100 KB + + + + 100 KB ~ 1 MB + 100 KB-1 MB + + + + 1 MB ~ 10 MB + 1 MB-10 MB + + + + 10 MB ~ 100 MB + 10 MB-100 MB + + + + 100 MB ~ 1 GB + 100 MB-1 GB + + + + > 1 GB + > 1 GB + + + + Today + I dag + + + + Yesterday + I går + + + + This week + Denne uge + + + + Last week + Sidste uge + + + + This month + Denne måned + + + + Last month + Sidste måned + + + + This year + I år + + + + Last year + Sidste år + + + + DFMOpticalMediaWidget + + + + No files to burn + + + + + Unable to burn. Not enough free space on the target disk. + + + + + %1 burning is not supported + + + + + 1. It is not a DVD-R or DVD+R disc; +2. The version of this file system does not support adding files yet. + + + + + DFMSideBarBookmarkItemHandler + + + Gotcha + button + + + + + DFMTagCrumbController + + + Tag information + Mærkatinformation + + + + DFMTagWidget + + + Tag + Mærkat + + + + DFMTaskWidget + + Keep both + Behold begge + + + Skip + Spring over + + + Replace + Erstat + + + + Do not ask again + Spørg ikke igen + + + + Syncing data + + + + + Please wait + + + + Retry + Prøv igen + + + + + Time modified: %1 + Ændringstidspunkt: %1 + + + + + Contains: %1 + Indeholder: %1 + + + + + Size: %1 + Størrelse: %1 + + + + Original folder + Original mappe + + + + Keep both + button + Behold begge + + + + Skip + button + Spring over + + + + Replace + button + Erstat + + + + Retry + button + Prøv igen + + + + Original file + Original fil + + + + Target folder + Målmappe + + + + Target file + Målfil + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + + + + + Click 'Encrypt' and input the user password. + + + + + Encrypting... + + + + + + + + Encrypt + + + + + Failed to create file vault: %1 + + + + + OK + OK + + + + The setup is complete + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + + + + + Generate a recovery key in case that you forgot the password + + + + + Key + + + + + QR code + + + + + Scan QR code and save the key to another device + + + + + Next + Næste + + + + Recovery Key: + + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + + + + + Method + + + + + Manual + + + + + Password + Adgangskode + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + + + + + Repeat password + Gentag adgangskode + + + + Input the password again + + + + + Password hint + + + + + Optional + Valgfri + + + + Next + Næste + + + + + Passwords do not match + + + + + DFMVaultActiveStartView + + + File Vault + Filboks + + + + Create your secure private space + + + + + Advanced encryption technology + + + + + Convenient and easy to use + Praktisk og let at bruge + + + + Create + + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + + + + Cancel + Annuller + + + Unlock + Lås op + + + + Failed to unlock file vault + + + + + OK + OK + + + + Input the 32-digit recovery key + + + + + Cancel + button + Annuller + + + + Unlock + button + Lås op + + + + Wrong recovery key + + + + + DFMVaultRemoveByPasswordView + + + Password + Adgangskode + + + + Password hint: %1 + + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + + + + + DFMVaultRemovePages + + + Delete File Vault + + + + + Once deleted, the files in it will be permanently deleted + + + + Cancel + Annuller + + + + Use Key + + + + Delete + Slet + + + OK + OK + + + + Cancel + button + Annuller + + + + Use Key + button + + + + + Delete + button + Slet + + + + + OK + button + OK + + + + Use Password + + + + + Wrong password + + + + + Wrong recovery key + + + + + Failed to delete file vault + + + + + Deleted successfully + + + + + Failed to delete + + + + + Removing... + + + + + DFMVaultUnlockPages + + + Unlock File Vault + + + + + Verify your password + + + + Cancel + Annuller + + + Unlock + Lås op + + + + Password hint: %1 + + + + + Failed to unlock file vault + + + + OK + OK + + + + Password + Adgangskode + + + + Cancel + button + Annuller + + + + Unlock + button + Lås op + + + + + Wrong password + + + + + OK + button + OK + + + + DFileCopyMoveJob + + + Permission error + Fejl ved tilladelse + + + + The action is denied + Handlingen blev nægtet + + + + Failed to open the file + Kunne ikke åbne filen + + + + Failed to read the file + Kunne ikke læse filen + + + + Failed to write the file + Kunne ikke skrive filen + + + + Failed to create the directory + Kunne ikke oprette mappen + + + + Failed to delete the file + Kunne ikke slette filen + + + + Failed to move the file + Kunne ikke flytte filen + + + + Original file does not exist + Den originale fil findes ikke + + + + Failed, file size must be less than 4GB + Mislykkedes, filstørrelse skal være mindre end 4GB + + + + Not enough free space on the target disk + Ikke nok ledig plads på måldisken + + + + File integrity was damaged + Filintegritet blev beskadiget + + + + The target device is read only + Målenheden er skrivebeskyttet + + + + Target folder is inside the source folder + Målmappe er ikke inden i kildemappen + + + + The action is not supported + + + + + You do not have permission to traverse files in it + + + + + copy + Extra name added to new file name when used for file name. + kopiér + + + + Failed to open the directory, cause: file name too long + + + + + + + Failed to open the file, cause: file name too long + + + + + + Failed to write the file, cause: + + + + + Syncing data + + + + + Please wait + + + + + Failed to create the directory, cause: %1 + Kunne ikke oprette mappen, årsag: %1 + + + + + + + + + Failed to open the file, cause: %1 + Kunne ikke åbne filen, årsag: %1 + + + + + + + Failed to open the file, cause: Permission denied + + + + + + Failed to read the file, cause: %1 + Kunne ikke læse filen, årsag: %1 + + + + + + + Failed to write the file, cause: %1 + Kunne ikke skrive filen, årsag: %1 + + + + + File integrity was damaged, cause: %1 + Filintegritet blev beskadiget, årsag: %1 + + + + Failed to open the file, cause: + + + + + Failed to read the file, cause: + + + + + Failed to delete the file, cause: %1 + Kunne ikke slette filen, årsag: %1 + + + + Fail to create symlink, cause: %1 + Kunne ikke oprette symlink, årsag: %1 + + + + DFileDialog + + Save + Gem + + + + + Save + button + Gem + + + + + Cancel + button + Annuller + + + + Confirm + button + Bekræft + + + + %1 already exists, do you want to replace it? + %1 findes allerede. Vil du erstatte den? + + + + Replace + button + Erstat + + + + Open + button + Åbn + + + Cancel + Annuller + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + + + + Confirm + Bekræft + + + Replace + Erstat + + + Open + Åbn + + + + DFileManagerWindow + + + Trash + Papirkurv + + + + Empty + Tøm + + + + DFileSystemModel + + + + Name + Navn + + + + + + Time modified + Ændringstidspunkt + + + + Size + Størrelse + + + + Type + Type + + + + Time created + Oprettelsestidspunkt + + + + + Last access + Sidste adgang + + + + + + + Path + Sti + + + + DFileView + + + Disc mount error + + + + + The disc is in use, please end the running process and remount the disc. + + + + + Mounting failed + + + + + (Reverse) + (omvendt) + + + + DFileViewHelper + + + Add tag "%1" + Tilføj mærkatet "%1" + + + + DStatusBar + + + %1 item + %1 element + + + + %1 items + %1 elementer + + + + %1 item selected + %1 element valgt + + + + %1 items selected + %1 elementer valgt + + + + %1 folder selected (contains %2) + %1 mappe valgt (indeholder %2) + + + + %1 folders selected (contains %2) + %1 mapper valgt (indeholder %2) + + + + %1 file selected (%2) + %1 fil valgt (%2) + + + + %1 files selected (%2) + %1 filer valgt (%2) + + + + %1 folder selected + %1 mappe valgt + + + + Filter + Filter + + + + Save as: + Gem som: + + + + Loading... + Indlæser... + + + + DTaskDialog + + + This action is not supported + Handlingen understøttes ikke + + + + Erasing disc %1, please wait... + Rydder disken %1, vent venligst ... + + + + Burning disc %1, please wait... + Brænder disken %1, vent venligst ... + + + + Writing data... + Skriver data ... + + + + Verifying data... + Bekræfter data ... + + + + Copying %1 + Kopierer %1 + + + + + + to %2 + til %2 + + + + %1 already exists in target folder + %1 findes allerede i målmappe + + + + Original path %1 Target path %2 + Original sti %1, målsti %2 + + + + Merge + button + Sammenføj + + + + Replace + button + Erstat + + + + Moving %1 + Flytter %1 + + + + Removing file vault, please try later + + + + + Restoring %1 + Gendanner %1 + + + + Deleting %1 + Sletter %1 + + + + Trashing %1 + Smider %1 i papirkurven + + + + Calculating space, please wait + Beregner plads - vent venligst + + + Merge + Sammenføj + + + Replace + Erstat + + + + DUMountManager + + + + Authentication timed out + + + + + + + Disk is busy, cannot unmount now + Disken er i brug. Kan ikke afmontere nu + + + + Disk is busy, cannot eject now + Disken er i brug. Kan ikke skubbe ud nu + + + + The device is busy, cannot eject now + + + + + + + The device is busy, cannot remove now + + + + + DeepinStorage + + + + + %1 Volume + %1-diskområde + + + + Data Disk + Data Partition + Datadisk + + + + %1 Drive + %1-drev + + + + Blank %1 Disc + Slet %1-disk + + + + %1 Encrypted + %1-krypteret + + + + DialogManager + + + + + + Operation failed! + Handling fejlede! + + + + Target folder is inside the source folder! + Målmappe er inde i kildemappe! + + + OK + OK + + + + Do you want to run %1 or display its content? + Vil du køre %1 eller vise dens indhold? + + + + It is an executable text file. + Det er en eksekverbar tekstfil. + + + Cancel + Annuller + + + Run + Kør + + + Run in terminal + Kør i terminal + + + Display + Visning + + + + It is an executable file. + Det er en eksekverbar fil. + + + + This file is not executable, do you want to add the execute permission and run? + Filen er ikke eksekverbar, vil du tilføje eksekverbar-tilladelsen og køre? + + + + "%1" already exists, please use another name. + "%1" findes allerede. Vælg venligst et andet navn. + + + Confirm + Bekræft + + + + The file name must not contain two dots (..) + + + + + Are you sure you want to erase all data on the disc? + Er du sikker på, at du vil rydde al data på disken? + + + Erase + Ryd + + + + How do you want to use this disc? + Hvordan vil du bruge disken? + + + Burn image + Brænd aftryk + + + Burn files + Brænd filer + + + + Disc erase failed + Rydning af disk mislykkedes + + + + Burn process failed + Brændingsprocess mislykkedes + + + + %1: %2 + %1: %2 + + + + Show details + Vis detaljer + + + + Hide details + Skjul detaljer + + + + Error + Fejl + + + + Permanently delete %1? + Slet %1 permanent? + + + + Permanently delete %1 items? + Slet %1 elementer permanent? + + + Delete + Slet + + + + Empty + Tøm + + + + Do you want to delete %1? + + + + + Do you want to delete the selected %1 items? + + + + + Sorry, unable to locate your bookmark directory, remove it? + Beklager, kan ikke finde din bogmærkemappe. fjern den? + + + Remove + Fjern + + + + Name: + Navn: + + + Force unmount + Gennemtving afmontering + + + + %1 that this shortcut refers to has been changed or moved + %1 som denne genvej referer til er blevet ændret eller flyttet + + + + Do you want to delete this shortcut? + Vil du slette denne genvej? + + + + Failed, file size must be less than 4GB. + Mislykkedes, filstørrelsen skal være mindre end 4 GB. + + + + Fail to create symlink, cause: + Kunne ikke oprette symlink - årsag: + + + + The selected files contain system file/directory, and it cannot be deleted + De valgte filer indeholder systemfil/-mappe og kan ikke slettes + + + + Unable to find the original file + + + + + + You do not have permission to operate file/folder! + Du har ikke tilladelse til at håndtere fil/mappe! + + + + Failed to restore %1 file, the source file does not exist + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Beklager, du har ikke tilladelse til at håndtere følgende %1 fil(er)/mappe(r)! + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + 2. Fravælg "Aktivér hurtig start" og "Dvale" i nedlukningsindstillinger og genstart + + + + 3. Reboot and enter %1 + 3. Genstart og kom ind i %1 + + + + Reboot + button + Genstart + + + + Unable to access %1 + + + + + + Sending files now, please try later + + + + Format + Format + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + + + + Stop + + + + + Scanning the device, stop it? + + + + + Share folder can't be named after the current username + Share-mappe kan ikke omdøbes til det nuværende brugernavn + + + + Do you want to run %1? + Vil du køre %1? + + + + Burn image + button + Brænd aftryk + + + + Burn files + button + Brænd filer + + + + Are you sure you want to empty %1 item? + Er du sikker på, at du vil tømme %1 element? + + + + Are you sure you want to empty %1 items? + Er du sikker på, at du vil tømme %1 elementer? + + + + + This action cannot be undone + Handlingen kan ikke fortrydes + + + + + + + + + + + + + + OK + button + OK + + + + + + + + + + + + + + + + Cancel + button + Annuller + + + + + + Run + button + Kør + + + + + Run in terminal + button + Kør i terminal + + + + Display + button + Visning + + + + + + + + + Confirm + button + Bekræft + + + + Erase + button + Ryd + + + Burn image, + + + + Burn files, + + + + + Data verification failed + + + + + Show details + button + Vis detaljer + + + + + Delete + button + Slet + + + + Remove + button + Fjern + + + + Disk is busy, cannot unmount now + Diskfil er i brug. Kan ikke afmontere nu + + + + Force unmount + button + Gennemtving afmontering + + + + Unable to copy. Not enough free space on the target disk. + Kan ikke kopiere. Ikke nok ledig plads på måldisken. + + + + Failed to restore %1 file, the target folder is read-only + Kunne ikke gendanne %1 fil, målmappen er skrivebeskyttet + + + + Failed to restore %1 files, the target folder is read-only + Kunne ikke gendanne %1 filer, målmappen er skrivebeskyttet + + + + Failed to restore %1 files, the source files do not exist + + + + + Mount partition%1 to be read only + Monter partition %1 til at være skrivebeskyttet + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + Diske i Windows vil ikke kunne læse og skrive normalt hvis "Aktivér hurtig start (anbefales)" er valgt til i nedlukningsindstillinger + + + + Please restore by the following steps to normally access Windows disk + Gendan venligst med følgende trin for at få normal adgang til Windows-disken + + + + 1. Reboot to enter Windows + 1. Genstart for at komme ind i Windows + + + + Format + button + Format + + + + Stop + button + + + + Reboot + Genstart + + + + FileController + + + + + + Unable to find the original file + + + + + + + Kindly Reminder + Venlig påmindelse + + + + + + Please install File Roller first and then continue + Installer venligst først File Roller og forsæt herefter + + + + + Unable to create files here: %1 + + + + + Confirm + button + Bekræft + + + Confirm + Bekræft + + + + FileDialogStatusBar + + + File Name + Filnavn + + + + Format + Format + + + Cancel + Annuller + + + + + + Cancel + button + Annuller + + + + Save + Gem + + + + Open + Åbn + + + + Save File + Gem fil + + + + Open File + Åbn fil + + + + FileIconItem + + + "'/\[]:|<>+=;,?* are not allowed + + + + + FileJob + + + copy + kopiér + + + + + + + Data verification successful. + Bekræftelse af data lykkedes. + + + + + + Burn process completed + Brændingsprocess gennemført + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 t %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 t %3 m %4 s + + + + %1 is a duplicate file. + %1 er en duplikeret fil. + + + + Insufficient disc space. + Utilstrækkelig diskplads. + + + + Lost connection to drive. + Mistede forbindelsen til drevet. + + + + The CD/DVD drive is not ready. Try another disc. + CD/DVD-drevet er ikke klart. Prøv en anden disk. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + CD-/DVD-drevet er optaget. Afslut programmet som bruger drevet og indsæt drevet igen. + + + + Unknown error + Ukendt fejl + + + + Device disconnected + + + + + GenerateSettingTranslate + + + + + Basic + Grundlæggende + + + + + + Open behavior + Opførsel ved åbning + + + + + + Always open folder in new window + Åbn altid mappe i nyt vindue + + + + + + Open file: + Åbn fil: + + + + + + Click + Klik + + + + + + Double click + Dobbeltklik + + + + + + New window and tab + Nyt vindue og faneblad + + + + + + Open from default window: + Åbn fra standardvindue: + + + + + + + + + Computer + Computer + + + + + + + + + Home + Hjem + + + + + + + + + Desktop + Skrivebord + + + + + + + + + Videos + Videoer + + + + + + + + + Music + Musik + + + + + + + + + Pictures + Billeder + + + + + + + + + Documents + Dokumenter + + + + + + + + + Downloads + Downloads + + + + + + Open in new tab: + Åbn i nyt faneblad: + + + + + + Current Directory + Nuværende mappe + + + + + + View + Visning + + + + + + Default size: + Standardstørrelse: + + + + + + Extra small + Ekstra små + + + + + + Small + Små + + + + + + Medium + Medium + + + + + + Large + Store + + + + + + Extra large + Ekstra store + + + + + + Default view: + Standardvisning: + + + + + + Icon + Ikon + + + + + + List + Liste + + + + + + Hidden files + Skjulte filer + + + + + + Show hidden files + Vis skjulte filer + + + + + + Hide file extension when rename + Skjul filendelse ved omdøbning + + + + + + Advanced + Avanceret + + + + + + Index + Indeks + + + + + + Auto index internal disk + Automatisk indeksering af intern disk + + + + + + Index external storage device after connected to computer + Indekser ekstern lagerenhed efter tilslutning til computer + + + + + + Full-Text search + + + + + + + Use the file chooser dialog of File Manager + Brug filvælgerdialogen i filhåndtering + + + + + + Ask for my confirmation when deleting files + + + + + + + Other + Andre + + + + + + Hide system disk + Skjul systemdisk + + + + + + Show file system on disk icon + + + + + + + Show hidden files in search results + Vis skjulte filer i søgeresultater + + + + + + Display recent file entry in left panel + Vis seneste filpost i venstre panel + + + + + + Preview + Forhåndsvisning + + + + + Compress file preview + Forhåndsvisning af komprimeret fil + + + + + + Text preview + Forhåndsvisning af tekst + + + + + + Document preview + Forhåndsvisning af dokument + + + + + + Image preview + Forhåndsvisning af billede + + + + + + Video preview + Forhåndsvisning af video + + + + + + Mount + Montér + + + + + + Auto mount + Montér automatisk + + + + + + Open after auto mount + Åbn efter automatisk montering + + + + + + Dialog + Dialog + + + + Compressed file preview + Forhåndsvisning af komprimeret fil + + + + GvfsMountManager + + + Can’t verify the identity of %1. + + + + + This happens when you log in to a computer the first time. + + + + + The identity sent by the remote computer is + + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + + + + + + + + + Mounting device error + Fejl ved montering af enhed + + + + + Wrong username or password + + + + + + + + + Confirm + button + Bekræft + + + + + Cannot find the mounted device + + + + + No key available to unlock device + + + + + The disk is mounted by user "%1", you cannot unmount it. + Disken er monteret af brugeren "%1", du kan ikke afmontere den. + + + Confirm + Bekræft + + + + Cannot unmount the device + Kan ikke afmontere enheden + + + + Cannot eject the device "%1" + Kan ikke skubbe enheden "%1" ud + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + + + + + MergedDesktopController + + + + Pictures + Billeder + + + + + Music + Musik + + + + + Applications + Programmer + + + + + Videos + Videoer + + + + + Documents + Dokumenter + + + + + Others + Andre + + + + MimeTypeDisplayManager + + + + Directory + Mappe + + + + + + Application + Program + + + + + + Video + Video + + + + + + Audio + Lyd + + + + + + Image + Billede + + + + + Archive + Arkiv + + + + + + Text + Tekst + + + + + Executable + Eksekverbar + + + + + Backup file + Sikkerhedskopifil + + + + + Unknown + Ukendt + + + + MountAskPasswordDialog + + Cancel + Annuller + + + Connect + Opret forbindelse + + + + Cancel + button + Annuller + + + + Connect + button + Opret forbindelse + + + + Log in as + Log ind som + + + + Anonymous + Anonym + + + + Registered user + Tilmeldt bruger + + + + Username + Brugernavn + + + + Domain + Domæne + + + + Password + Adgangskode + + + + Remember password + Husk adgangskode + + + + MountSecretDiskAskPasswordDialog + + Cancel + Anulere + + + Unlock + Lås op + + + + Cancel + button + Annuller + + + + Unlock + button + Lås op + + + + Input password to decrypt the disk + Indtast adgangskode for at dekryptere disken + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Er du sikker på, at du vil slette %1 permanent? + + + + This file is too big for the trash + Filen er for stor til papirkurven + + + + The files are too big for the trash + Filerne er for store til papirkurven + + + + Are you sure you want to permanently delete %1 files? + Er du sikker på, at du vil slette %1 filer permanent? + + + + Cancel + button + Annuller + + + + Delete + button + Slet + + + Cancel + Annuller + + + Delete + Slet + + + + OpenWithDialog + + + Open with + Åbn med + + + + Add other programs + Tilføj andre programmer + + + + Set as default + Sæt som standard + + + + Cancel + button + Annuller + + + + Confirm + button + Bekræft + + + Cancel + Annuller + + + Confirm + Bekræft + + + + Recommended Applications + Anbefalede programmer + + + + Other Applications + Andre programmer + + + + PathManager + + + Home + Hjem + + + + Desktop + Skrivebord + + + + Videos + Videoer + + + + Music + Musik + + + + Pictures + Billeder + + + + Documents + Dokumenter + + + + Downloads + Downloads + + + + + Trash + Papirkurv + + + + + + System Disk + Systemdisk + + + + Computers in LAN + Computere på LAN + + + + My Shares + Mine shares + + + + Computer + Computer + + + + Recent + Seneste + + + + File Vault + Filboks + + + + PropertyDialog + + + Basic info + Grundlæggende info + + + + Open with + Åbn med + + + + Sharing + Deling + + + + Permissions + Tilladelser + + + + %1 (%2) + %1 (%2) + + + + %1 + + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Skjul mappen + + + + Hide this file + Skjul filen + + + + Allow to execute as program + Tillad eksekvering som program + + + + QObject + + + + + Size + Størrelse + + + + + + Contains + Indeholder + + + + + + Type + Type + + + + + + + + Time modified + Ændringstidspunkt + + + + Free space + Ledig plads + + + + Total space + Samlet plads + + + + + Time locked + + + + + Access denied + Adgang nægtet + + + + + Executable + Eksekverbar + + + + + Write only + Kun skrive + + + + + Read only + Kun læse + + + + + Read-write + Læse-skrive + + + + Others + Andre + + + + Owner + Ejer + + + + Device type + Enhedstype + + + + File system + Filsystem + + + + Group + Gruppe + + + + + Open + Åbn + + + + Lock + + + + + Auto lock + + + + + Never + Aldrig + + + + 5 minutes + + + + + 10 minutes + + + + + 20 minutes + + + + + Delete File Vault + + + + + Unlock + Lås op + + + + Unlock by key + + + + + Open + button + Åbn + + + + + Size: %1 + Størrelse: %1 + + + + Type: %1 + Type: %1 + + + + Size: 0 + Størrelse: 0 + + + + Items: %1 + Elementer: %1 + + + + + + + + + + Open in new window + Åbn i nyt vindue + + + + + + + + + + Open in new tab + Åbn i nyt faneblad + + + + Open with + Åbn med + + + + + Compress + Komprimér + + + + Extract + Udpak + + + + Extract here + Udpak her + + + + Cut + Klip + + + + Copy + Kopiér + + + + Paste + Indsæt + + + + + + + + Rename + Omdøb + + + + + + Remove + Fjern + + + + Create link + Opret link + + + + Send to desktop + Send til skrivebord + + + + Send to + Send til + + + + Bluetooth + + + + + Add to bookmark + Tilføj til bogmærke + + + + + + + Properties + Egenskaber + + + + New folder + Ny mappe + + + + New window + Nyt vindue + + + + Select all + Vælg alle + + + + + Clear recent history + Ryd seneste historik + + + + + + Empty Trash + Tøm papirkurv + + + + Display as + Vis som + + + + Sort by + Sortér efter + + + + New document + Nyt dokument + + + + + Time created + Oprettelsestidspunkt + + + + Log out and unmount + Log ud og afmontér + + + + + + Source path + Kildesti + + + + Share folder + Share-mappe + + + + Cancel sharing + Annuller deling + + + + Connect to Server + Opret forbindelse til server + + + + Set share password + Sæt share-adgangskode + + + + Format + Format + + + + Tag information + Mærkatinformation + + + + Open as administrator + + + + + Select default program + Vælg standardprogram + + + + Open file location + Åbn fil placering + + + + Remove bookmark + Fjern bogmærke + + + + + + Delete + Slet + + + + Office Text + Office-tekstdokument + + + + Spreadsheets + Regneark + + + + Plain Text + Tekstdokument + + + + Open in terminal + Åbn i terminal + + + + Restore + Gendan + + + + Restore all + Gendan alle + + + + + + + + File Vault + Filboks + + + + Add to disc + + + + + Auto mount + Montér automatisk + + + + Open after auto mount + Åbn efter automatisk montering + + + + + Mount + Montér + + + + + Unmount + Afmontér + + + + It does not support burning %1 discs + + + + + Burn + Bræn + + + + Disc name: + Disknavn: + + + + + Maximum + Maksimum + + + + Allow files to be added later + Tillad at filer kan tilføjes senere + + + + Verify data + Bekræft data + + + + Write speed: + Skrivehastighed: + + + + + + + Cancel + button + Annuller + + + + Burn + button + Bræn + + + + + Eject + Skub ud + + + + Safely Remove + Sikker fjernelse + + + + + Name + Navn + + + + Settings + Indstillinger + + + + Exit + Afslut + + + + Icon + Ikon + + + + List + Liste + + + + Extend + Udvid + + + + Set as wallpaper + Sæt som tapet + + + + + + + Local disk + Lokal disk + + + + + Removable disk + Flytbar disk + + + + + + Network shared directory + Netværksdelingsmappe + + + + + Android mobile device + Android-mobilenhed + + + + + Apple mobile device + Apple-mobilenhed + + + + + Camera + Kamera + + + + + DVD + DVD + + + + + Unknown device + Ukendt enhed + + + + + + %1 item + %1 element + + + + + + %1 items + %1 elementer + + + + Shortcut + Genvej + + + + Create symlink + Opret symlink + + + + Path + Sti + + + + + + Time deleted + Sletningstidspunkt + + + + Loading... + Indlæser... + + + + File has been moved or deleted + Filen er blevet flyttet eller slettet + + + + You do not have permission to traverse files in it + + + + + + + You do not have permission to access this folder + Du kan ikke de nødvendige tilladelser til at tilgå denne mappe + + + + + + + + Folder is empty + Mappen er tom + + + + Searching... + Søger... + + + + No results + Ingen resultater + + + + Source Path + TrashFileInfo + Kildesti + + + + Document + Dokument + + + + Spreadsheet + Regneark + + + + + Presentation + Præsentation + + + + Text + Tekst + + + + 1 task in progress + 1 igangværende opgave + + + + %1 tasks in progress + %1 igangværende opgaver + + + + Mode: + Tilstand: + + + + + Replace Text + Udskift tekst + + + + + Add Text + Tilføj tekst + + + + + Custom Text + Brugerdefineret tekst + + + + Find: + Find: + + + + Replace: + Erstat: + + + + + Optional + Valgfri + + + + Add: + Tilføj: + + + + Location: + Placering: + + + + File name: + Filnavn: + + + + Start at: + + + + + + Rename + button + Omdøb + + + + + + + + + + + Required + Påkrævet + + + + + Before file name + Før filnavn + + + + + After file name + Efter filnavn + + + + Find + Find + + + + Replace + Erstat + + + + Add + Tilføj + + + + Start at + + + + + + + Location + Placering + + + + File name + Filnavn + + + + Dimension + Dimension + + + + Duration + Varighed + + + + Tips: Sort by selected file order + Tips: Sorter efter valgte filorden + + + Cancel + Anullere + + + + Rename %1 Files + Omdøb %1 filer + + + + Multiple Files + Flere filer + + + + Basic info + Grundlæggende info + + + + Total size + Samlet størrelse + + + + Number of files + Antal filer + + + + %1 file(s), %2 folder(s) + %1 fil(er), %2 mappe(r) + + + + + + Time accessed + Adgangstidspunkt + + + + Orange + Orange + + + + Red + Rød + + + + Purple + Lilla + + + + Navy-blue + Marineblå + + + + Azure + Azur + + + + Green + Grøn + + + + Yellow + Gul + + + + Gray + Grå + + + + Input tag info, such as work, family. A comma is used between two tags. + Input mærkatinfo, såsom arbejde, familje. Der bruges et komma mellem to mærkater. + + + + Bookmarks + Bogmærker + + + + Erase + Ryd + + + + Copy path + Kopiér sti + + + + Edit address + Rediger adresse + + + It does not support burning UDF discs + + + + + Free Space %1 + Ledig plads %1 + + + + Files are being processed + Filerne er ved at blive behandlet + + + + Unknown + Ukendt + + + + My Vault + + + + + + + Disks + Diske + + + + + Failed to create file info + + + + + Failed to create file handler + + + + + + + Execution error + + + + + + + + "'/\[]:|<>+=;,?* are not allowed + + + + + Failed to open the file, cause: %1 + Kunne ikke åbne filen, årsag: %1 + + + + Original file does not exist + Den originale fil findes ikke + + + + Do you want to delete %1? + + + + + Confirm + button + Bekræft + + + Confirm + Bekræft + + + + ShareInfoFrame + + + Share this folder + Del denne mappe + + + + Share name: + Share-navn: + + + + Permission: + Tilladelse: + + + + Read and write + Læs og skriv + + + + Read only + Skrivebeskyttet + + + + Anonymous: + Anonym: + + + + Not allow + Tillad ikke + + + + Allow + Tillad + + + + The share name must not be two dots (..) or one dot (.) + + + + + The share name is used by another user. + + + + + OK + button + OK + + + + Cancel + button + Annuller + + + + Replace + button + Erstat + + + OK + OK + + + + The share name already exists. Do you want to replace the shared folder? + + + + Cancel + Annuller + + + Replace + Erstat + + + + Shortcut + + + Item + Element + + + + Select to the first item + Vælg til det første element + + + + Shift + Home + Skift + Home + + + + Select to the last item + Vælg til det sidste element + + + + Shift + End + Skift + End + + + + Select leftwards + Vælg til venstre + + + + Shift + Left + Skift + Venstre + + + + Select rightwards + Vælg til højre + + + + Shift + Right + Skift + Højre + + + + Select to upper row + Vælg til øvre række + + + + Shift + Up + Skift + Op + + + + Select to lower row + Vælg til nedre række + + + + Shift + Down + Skift + Ned + + + + Open + Åbn + + + + Ctrl + Down + Ctrl + Ned + + + + To parent directory + Til forældremappe + + + + Ctrl + Up + Ctrl + Op + + + + Permanently delete + Slet permanent + + + + Shift + Delete + Skift + Delete + + + + Delete file + Slet fil + + + + Delete + Slet + + + + Select all + Vælg alle + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Skift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Kopiér + + + + Cut + Klip + + + + Paste + Indsæt + + + + Rename + Omdøb + + + + F2 + F2 + + + + New/Search + Ny/søg + + + + New window + Nyt vindue + + + + New folder + Ny mappe + + + + + Search + Søg + + + + New tab + Nyt faneblad + + + + View + Vis + + + + Item information + Elementinformation + + + + Help + Hjælp + + + + F1 + F1 + + + + Keyboard shortcuts + Tastaturgenveje + + + + Ctrl + Shift + / + Ctrl + Skift + / + + + + Switch display status + Skift visningsstatus + + + + Hide item + Skjul element + + + + Input in address bar + Input i adressebjælke + + + + Switch to icon view + Skift til ikonvisning + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Skift til listevisning + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Andre + + + + Close + Luk + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Luk nuværende faneblad + + + + Back + Tilbage + + + + Alt + Left + Alt + Venstre + + + + Alt + Right + Alt + Højre + + + + Switch to next tab + Skift til næste faneblad + + + + Ctrl + Tab + Ctrl + Tabulator + + + + Ctrl + Shift + Tab + Ctrl + Skift + Tabulator + + + + Switch to previous tab + Skift til forrige faneblad + + + + Next file + Næste fil + + + + Tab + Faneblad + + + + Previous file + Forrige fil + + + + Shift + Tab + Skift + Tabulator + + + + Switch tab by specified number between 1 to 8 + Skifte faneblad med angivet nummer mellem 1 og 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Fremad + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + + + + + TrashPropertyDialog + + + Trash + Papirkurv + + + + item + element + + + + items + elementer + + + + Contains %1 %2 + Indeholder %1 %2 + + + + UDiskListener + + + Failed to rename the label + Kunne ikke omdøbe etiketten + + + + UnmountWorker + + + + + The device was not safely unmounted + + + + + The device was not safely removed + + + + + UserShareManager + + + Kindly Reminder + Venlig påmindelse + + + + Please firstly install samba to continue + Installer venligst først samba for at fortsætte + + + + To protect the files, you cannot share this folder. + + + + + The share name must not contain %<>*?|/\+=;:," + + + + + Sharing failed + + + + + The computer name is too long + + + + + You do not have permission to operate file/folder! + Du har ikke tilladelse til at håndtere fil/mappe! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Indtast en adgangskode for at beskytte delte mapper + + + + Cancel + button + Annuller + + + + Confirm + button + Bekræft + + + Cancel + Annuller + + + Confirm + Bekræft + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_de.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_de.ts new file mode 100644 index 0000000..a5be310 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_de.ts @@ -0,0 +1,4715 @@ + + + AppController + + + New Folder + Neuer Ordner + + + + Mounting device error + Fehler beim Einhängen des Geräts + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Das Disc-Abbild ist beschädigt. Es kann jetzt nicht geladen werden. Löschen Sie zuerst die Disc + + + + Mount error: unsupported image format + Einhängefehler: Nicht unterstütztes Abbildformat + + + + + The device was not safely removed + Das Gerät wurde nicht sicher entfernt + + + + + Click "Safely Remove" and then disconnect it next time + Klicke auf „Sicher entfernen“ und trenne die Verbindung dann beim nächsten Mal + + + + The device was not ejected + Das Gerät wurde nicht ausgeworfen + + + + Disk is busy, cannot eject now + Datenträger wird verwendet, er kann jetzt nicht ausgeworfen werden + + + + Authentication timed out + Zeitüberschreitung bei der Authentifizierung + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Bluetooth-Dateiübertragung + + + + File Transfer Successful + Dateiübertragung erfolgreich + + + + File Transfer Failed + Dateiübertragung fehlgeschlagen + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Dateien werden an „<b style="font-weight: 550;">%1</b>“ gesendet + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Fehler beim Senden von Dateien an „<b style="font-weight: 550;">%1</b>“ + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + An „<b style="font-weight: 550;">%1</b>“ erfolgreich gesendet + + + + Select a Bluetooth device to receive files + Wählen Sie ein Bluetooth-Gerät zum Empfangen von Dateien aus + + + + Cannot find the connected Bluetooth device + Kann das angeschlossene Bluetooth-Gerät nicht finden + + + + Waiting to be received... + Warten auf den Empfang ... + + + + Go to Bluetooth Settings + Zu den Bluetooth-Einstellungen gehen + + + + %1/%2 Sent + %1/%2 gesendet + + + + Error: the Bluetooth device is disconnected + Fehler: das Bluetooth-Gerät ist getrennt + + + + Unable to send the file more than 2 GB + Datei kann nicht gesendet werden, wenn sie größer als 2 GB ist + + + + Unable to send 0 KB files + 0 KB-Dateien können nicht gesendet werden + + + + File doesn't exist + Datei existiert nicht + + + + Next + button + Weiter + + + + Cancel + button + Abbrechen + + + + Done + button + Fertig + + + + Retry + button + Wiederholen + + + + OK + button + OK + + + + File sending request timed out + Zeitüberschreitung beim Senden der Datei + + + + The service is busy and unable to process the request + Der Dienst ist ausgelastet und kann die Anfrage nicht bearbeiten + + + + BurnOptDialog + + + Device error + Gerätefehler + + + + Optical device %1 doesn't exist + Optisches Gerät %1 existiert nicht + + + + Advanced settings + Erweiterte Einstellungen + + + + File system: + Dateisystem: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Für Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (für Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Kompatibel mit Windows-CD/DVD-Modus) + + + + ISO9660 Only + Nur ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Alle schließen + + + + Total size: %1, %2 files + Gesamtgröße: %1, %2 Dateien + + + + ComputerModel + + + Double click to open it + + + + + My Directories + Meine Verzeichnisse + + + + Disks + Laufwerke + + + + File Vault + Dateitresor + + + + Quick Access + + + + + ComputerPropertyDialog + + + Computer + Computer + + + + Basic Info + Grundlegende Informationen + + + + + Computer Name + Computername + + + + + Edition + Edition + + + + + + Version + Version + + + + + Type + Typ + + + + + + Processor + Prozessor + + + + + + Memory + Arbeitsspeicher + + + + + + + Bit + Bit + + + + + Available + Verfügbar + + + + Obtaining... + Wird abgerufen ... + + + + ConnectToServerDialog + + + Connect to Server + Mit Server verbinden + + + + Cancel + button + Abbrechen + + + + Connect + button + Verbinden + + + + My Favorites: + Meine Favoriten: + + + + + Clear History + Verlauf löschen + + + + DFMAddressBar + + + Search or enter address + Suchen oder Adresse eingeben + + + + DFMAdvanceSearchBar + + + Search: + Suchen: + + + + File Type: + Dateityp: + + + + File Size: + Dateigröße: + + + + Time Modified: + Änderungszeit: + + + + Time Accessed: + Zugriffszeit: + + + + Time Created: + Erstellungszeit: + + + + Reset + Zurücksetzen + + + + All subdirectories + Alle Unterverzeichnisse + + + + Current directory + Aktuelles Verzeichnis + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Heute + + + + Yesterday + Gestern + + + + This week + Diese Woche + + + + Last week + Letzte Woche + + + + This month + Diesen Monat + + + + Last month + Letzten Monat + + + + This year + Dieses Jahr + + + + Last year + Letztes Jahr + + + + DFMOpticalMediaWidget + + + + No files to burn + Keine zu brennenden Dateien + + + + Unable to burn. Not enough free space on the target disk. + Das Brennen ist nicht möglich. Nicht genügend freier Speicherplatz auf dem Zieldatenträger. + + + + %1 burning is not supported + + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + + + + + DFMTagCrumbController + + + Tag information + Schlagwort-Informationen + + + + DFMTagWidget + + + Tag + Schlagwort + + + + DFMTaskWidget + + + Do not ask again + Nicht erneut nachfragen + + + + Syncing data + Daten werden synchronisiert + + + + Please wait + Bitte warten + + + + + Time modified: %1 + Änderungszeit: %1 + + + + + Contains: %1 + Enthält: %1 + + + + + Size: %1 + Größe: %1 + + + + Original folder + Ursprungsordner + + + + Keep both + button + Beide behalten + + + + Skip + button + Überspringen + + + + Replace + button + Ersetzen + + + + Retry + button + Wiederholen + + + + Original file + Ursprungsdatei + + + + Target folder + Zielordner + + + + Target file + Zieldatei + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Dateitresor verschlüsseln + + + + Click 'Encrypt' and input the user password. + Klicke auf 'Verschlüsseln' und gib das Benutzerpasswort ein. + + + + Encrypting... + Wird verschlüsselt ... + + + + + + + Encrypt + Verschlüsseln + + + + Failed to create file vault: %1 + Fehler beim Erstellen des Dateitresors: %1 + + + + OK + OK + + + + The setup is complete + Die Einrichtung ist abgeschlossen + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Wiederherstellungsschlüssel speichern + + + + Keep the key safe to retrieve the vault password later + Bewahren Sie den Schlüssel sicher auf, um das Passwort für den Tresor später abrufen zu können + + + + Save to default path + Im Standardpfad speichern + + + + Save to other locations + An anderen Orten speichern + + + + No permission, please reselect + Keine Berechtigung, bitte erneut auswählen + + + + Select a path + Wählen Sie einen Pfad aus + + + + Next + Weiter + + + + The default path is invisible to other users, and the path information will not be shown. + Der Standardpfad ist für andere Benutzer unsichtbar, und die Pfadinformationen werden nicht angezeigt. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Wiederherstellungsschlüssel + + + + Generate a recovery key in case that you forgot the password + Einen Wiederherstellungsschlüssel generieren, für den Fall, dass Sie das Passwort vergessen haben + + + + Key + Schlüssel + + + + QR code + QR-Code + + + + Scan QR code and save the key to another device + QR-Code scannen und den Schlüssel auf einem anderen Gerät speichern + + + + Next + Weiter + + + + Recovery Key: + Wiederherstellungsschlüssel: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Tresor-Passwort festlegen + + + + Method + Methode + + + + Manual + Manuell + + + + Password + Passwort + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 Zeichen, enthält A-Z, a-z, 0-9 und Symbole + + + + Repeat password + Passwort wiederholen + + + + Input the password again + Geben Sie das Passwort erneut ein + + + + Password hint + Passworthinweis + + + + Optional + Optional + + + + Next + Weiter + + + + + Passwords do not match + Passwörter stimmen nicht überein + + + + DFMVaultActiveStartView + + + File Vault + Dateitresor + + + + Create your secure private space + Schaffen Sie Ihren sicheren privaten Raum + + + + Advanced encryption technology + Fortschrittliche Verschlüsselungstechnologie + + + + Convenient and easy to use + Komfortabel und einfach zu bedienen + + + + Create + Erstellen + + + + DFMVaultFileView + + + Cannot open this path + Dieser Pfad kann nicht geöffnet werden + + + + Hint + Hinweis + + + + OK + OK + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Mit Schlüssel entsperren + + + + Failed to unlock file vault + Fehler beim Entsperren des Dateitresors + + + + OK + OK + + + + Input the 32-digit recovery key + Geben Sie den 32-stelligen Wiederherstellungsschlüssel ein + + + + Cancel + button + Abbrechen + + + + Unlock + button + Entsperren + + + + Wrong recovery key + Falscher Wiederherstellungsschlüssel + + + + DFMVaultRemoveByPasswordView + + + Password + Passwort + + + + Password hint: %1 + Passworthinweis: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Geben Sie den 32-stelligen Wiederherstellungsschlüssel ein + + + + DFMVaultRemovePages + + + Delete File Vault + Dateitresor löschen + + + + Once deleted, the files in it will be permanently deleted + Einmal gelöscht, werden die darin enthaltenen Dateien endgültig gelöscht + + + + Use Key + Schlüssel verwenden + + + + Cancel + button + Abbrechen + + + + Use Key + button + Schlüssel verwenden + + + + Delete + button + Löschen + + + + + OK + button + OK + + + + Use Password + Passwort verwenden + + + + Wrong password + Falsches Passwort + + + + Wrong recovery key + Falscher Wiederherstellungsschlüssel + + + + Failed to delete file vault + Fehler beim Löschen des Dateitresors + + + + Deleted successfully + Erfolgreich gelöscht + + + + Failed to delete + Fehler beim Löschen + + + + Removing... + Wird entfernt ... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + Die Schlüsseldatei kann nicht abgerufen werden + + + + Verification failed + Verifizierung fehlgeschlagen + + + + + Select a path + Wählen Sie einen Pfad aus + + + + + Retrieve Password + Passwort abrufen + + + + By key in the default path + Mit dem Schlüssel im Standardpfad + + + + By key in the specified path + Mit dem Schlüssel im angegebenen Pfad + + + + Verification Successful + Verifizierung erfolgreich + + + + Keep it safe + + + + + Back + button + Zurück + + + + Verify Key + button + Schlüssel verifizieren + + + + Go to Unlock + button + + + + + Close + button + Schließen + + + + Vault password: %1 + Tresor-Passwort: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Dateitresor entsperren + + + + Forgot password? + Passwort vergessen? + + + + Password hint: %1 + Passworthinweis: %1 + + + + Failed to unlock file vault + Fehler beim Entsperren des Dateitresors + + + + Cancel + button + Abbrechen + + + + Password + Passwort + + + + Unlock + button + Entsperren + + + + Please try again %1 minutes later + Bitte versuchen Sie es %1 Minuten später erneut + + + + Wrong password, please try again %1 minutes later + Falsches Passwort, bitte versuchen Sie es %1 Minuten später erneut + + + + Wrong password, one chance left + Falsches Passwort, noch eine Chance übrig + + + + Wrong password, %1 chances left + Falsches Passwort, noch %1 Chancen übrig + + + + Wrong password + Falsches Passwort + + + + OK + button + OK + + + + DFileCopyMoveJob + + + Permission error + Berechtigungsfehler + + + + The action is denied + Diese Aktion wurde verweigert + + + + Failed to open the file + Fehler beim Öffnen der Datei + + + + Failed to read the file + Fehler beim Lesen der Datei + + + + Failed to write the file + Fehler beim Schreiben der Datei + + + + Failed to create the directory + Fehler beim Erstellen des Verzeichnisses + + + + Failed to delete the file + Fehler beim Löschen der Datei + + + + Failed to move the file + Fehler beim Verschieben der Datei + + + + Original file does not exist + Originale Datei existiert nicht + + + + Failed, file size must be less than 4GB + Fehlgeschlagen, Dateigröße muss kleiner als 4 GB sein + + + + Not enough free space on the target disk + Nicht genügend freier Speicherplatz auf dem Ziellaufwerk + + + + File integrity was damaged + Datei-Integrität wurde beschädigt + + + + The target device is read only + Das Zielgerät ist schreibgeschützt + + + + Target folder is inside the source folder + Zielordner befindet sich innerhalb des Ursprungsordners + + + + The action is not supported + Die Aktion wird nicht unterstützt + + + + You do not have permission to traverse files in it + + + + + Failed to position the file pointer! + + + + + copy + Extra name added to new file name when used for file name. + Kopie + + + + Failed to open the directory, cause: file name too long + Fehler beim Öffnen des Verzeichnisses, Grund: Dateiname zu lang + + + + + Failed to open the file, cause: file name too long + Fehler beim Öffnen der Datei, Grund: Dateiname zu lang + + + + + Failed to write the file, cause: + Fehler beim Öffnen der Datei, Grund: + + + + Failed to position the file pointer, cause: %1 + + + + + Syncing data + Daten werden synchronisiert + + + + Please wait + Bitte warten + + + + Failed to create the directory, cause: %1 + Fehler beim Erstellen des Verzeichnisses, Grund: %1 + + + + + + + + Failed to open the file, cause: %1 + Fehler beim Öffnen der Datei, Grund: %1 + + + + + + + Failed to open the file, cause: Permission denied + Fehler beim Öffnen der Datei, Grund: Berechtigung verweigert + + + + + Failed to read the file, cause: %1 + Fehler beim Lesen der Datei, Grund: %1 + + + + + + + Failed to write the file, cause: %1 + Fehler beim Schreiben der Datei, Grund: %1 + + + + + File integrity was damaged, cause: %1 + Datei-Integrität wurde beschädigt, Grund: %1 + + + + Failed to open the file, cause: + Fehler beim Öffnen der Datei, Grund: + + + + Failed to read the file, cause: + Fehler beim Lesen der Datei, Grund: + + + + Failed to delete the file, cause: %1 + Fehler beim Löschen der Datei, Grund: %1 + + + + Fail to create symlink, cause: %1 + Fehler beim Erstellen des Symlinks, Grund: %1 + + + + DFileDialog + + + + Save + button + Speichern + + + + + Cancel + button + Abbrechen + + + + Confirm + button + Bestätigen + + + + %1 already exists, do you want to replace it? + %1 existiert bereits, möchten Sie es ersetzen? + + + + Replace + button + Ersetzen + + + + Open + button + Öffnen + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Diese Datei wird ausgeblendet, wenn der Dateiname mit einem Punkt (.) beginnt. Möchten Sie diese Datei ausblenden? + + + + DFileManagerWindow + + + Trash + Papierkorb + + + + Empty + Leeren + + + + DFileSystemModel + + + + Name + Name + + + + + + Time modified + Änderungszeit + + + + Size + Größe + + + + Type + Typ + + + + Time created + Erstellungszeit + + + + + Last access + Letzter Zugriff + + + + + + + Path + Pfad + + + + DFileView + + + Disc mount error + + + + + The disc is in use, please end the running process and remount the disc. + + + + + Mounting failed + Einhängen fehlgeschlagen + + + + (Reverse) + (Umgekehrt) + + + + DFileViewHelper + + + Add tag "%1" + Schlagwort "%1" hinzufügen + + + + DStatusBar + + + %1 item + %1 Element + + + + %1 items + %1 Elemente + + + + %1 item selected + %1 Element ausgewählt + + + + %1 items selected + %1 Elemente ausgewählt + + + + %1 folder selected (contains %2) + %1 Ordner ausgewählt (enthält %2) + + + + %1 folders selected (contains %2) + %1 Ordner ausgewählt (enthält %2) + + + + %1 file selected (%2) + %1 Datei ausgewählt (%2) + + + + %1 files selected (%2) + %1 Dateien ausgewählt (%2) + + + + %1 folder selected + %1 Ordner ausgewählt + + + + Filter + Filter + + + + Save as: + Speichern als: + + + + Loading... + Wird geladen ... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Disc %1 wird gelöscht, bitte warten ... + + + + Burning disc %1, please wait... + Disc %1 wird gebrannt, bitte warten ... + + + + Writing data... + Daten werden geschrieben ... + + + + Verifying data... + Daten werden verifiziert ... + + + + Copying %1 + %1 wird kopiert + + + + + + to %2 + nach %2 + + + + %1 already exists in target folder + %1 existiert bereits im Zielordner + + + + Original path %1 Target path %2 + Ursprungspfad %1 Zielpfad %2 + + + + Merge + button + Zusammenführen + + + + Replace + button + Ersetzen + + + + Moving %1 + %1 wird verschoben + + + + Removing file vault, please try later + Dateitresor wird entfernt, bitte versuchen Sie es später + + + + Restoring %1 + %1 wird wiederhergestellt + + + + Deleting %1 + %1 wird gelöscht + + + + Trashing %1 + %1 wird in den Papierkorb verschoben + + + + Calculating space, please wait + Speicherplatz wird berechnet, bitte warten + + + + DUMountManager + + + + Authentication timed out + Zeitüberschreitung bei der Authentifizierung + + + + + + Disk is busy, cannot unmount now + Laufwerk wird verwendet, es kann jetzt nicht ausgehängt werden + + + + Disk is busy, cannot eject now + Datenträger wird verwendet, er kann jetzt nicht ausgeworfen werden + + + + The device is busy, cannot eject now + Das Gerät ist beschäftigt, kann jetzt nicht ausgeworfen werden + + + + + + The device is busy, cannot remove now + Das Gerät ist beschäftigt, kann jetzt nicht entfernt werden + + + + DeepinStorage + + + + + %1 Volume + %1 Laufwerk + + + + Data Disk + Data Partition + Datenlaufwerk + + + + %1 Drive + %1 Laufwerk + + + + Blank %1 Disc + Leere %1 Disc + + + + %1 Encrypted + %1 verschlüsselt + + + + DialogManager + + + + + + Operation failed! + Operation fehlgeschlagen! + + + + Target folder is inside the source folder! + Zielordner befindet sich im Quellordner! + + + + Do you want to run %1 or display its content? + Möchten Sie %1 ausführen oder den Inhalt anzeigen? + + + + It is an executable text file. + Es ist eine ausführbare Textdatei. + + + + It is an executable file. + Es ist eine ausführbare Datei. + + + + This file is not executable, do you want to add the execute permission and run? + Diese Datei ist nicht ausführbar, möchten Sie die entsprechenden Berechtigungen hinzufügen und die Datei dann ausführen? + + + + "%1" already exists, please use another name. + "%1" existiert bereits, bitte verwenden Sie einen anderen Namen. + + + + The file name must not contain two dots (..) + Der Dateiname darf keine zwei Punkte (..) enthalten + + + + Device or resource busy + + + + + Are you sure you want to erase all data on the disc? + Sind Sie sicher, dass Sie alle Daten auf der Disc löschen möchten? + + + + How do you want to use this disc? + Wie möchten Sie diese Disc verwenden? + + + + Disc erase failed + Fehler beim Löschen der Disc + + + + Burn process failed + Brennvorgang fehlgeschlagen + + + + %1: %2 + %1: %2 + + + + Show details + Details anzeigen + + + + Hide details + Details ausblenden + + + + Error + Fehler + + + + Permanently delete %1? + %1 endgültig löschen? + + + + Permanently delete %1 items? + %1 Elemente endgültig löschen? + + + + Empty + Leeren + + + + Do you want to delete %1? + Möchten Sie %1 löschen? + + + + Do you want to delete the selected %1 items? + Möchten Sie die ausgewählten %1 Elemente löschen? + + + + Sorry, unable to locate your bookmark directory, remove it? + Entschuldigung, Ihr Lesezeichenverzeichnis kann nicht gefunden werden, entfernen? + + + + Name: + Name: + + + + %1 that this shortcut refers to has been changed or moved + %1 worauf sich diese Verknüpfung bezieht wurde verschoben oder entfernt. + + + + Do you want to delete this shortcut? + Möchten Sie diese Verknüpfung löschen? + + + + Failed, file size must be less than 4GB. + Fehlgeschlagen, die Dateigröße muss weniger als 4 GB betragen. + + + + Fail to create symlink, cause: + Fehler beim Erstellen der symbolischen Verknüpfung, Grund: + + + + The selected files contain system file/directory, and it cannot be deleted + Die ausgewählten Dateien enthalten Systemdateien/Ordner und können nicht gelöscht werden + + + + Unable to find the original file + Die Originaldatei kann nicht gefunden werden + + + + + You do not have permission to operate file/folder! + Sie besitzen nicht die erforderlichen Rechte um den Ordner oder die Datei zu bearbeiten! + + + + Failed to restore %1 file, the source file does not exist + Datei %1 konnte nicht wiederhergestellt werden, die Quelldatei existiert nicht + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Sie haben keine Berechtigung um die Operation auf die folgenden %1 Datei(en)/Ordner anzuwenden! + + + + Unable to access %1 + Zugriff auf %1 nicht möglich + + + + + Sending files now, please try later + Dateien werden jetzt gesendet, bitte versuchen Sie es später + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Um auf das Gerät zugreifen zu können, müssen Sie das Laufwerk zuerst formatieren. Sind Sie sicher, dass Sie es jetzt formatieren wollen? + + + + Scanning the device, stop it? + + + + + Share folder can't be named after the current username + Ein geteilter Ordner kann nicht nach dem aktuellen Benutzernamen benamt werden. + + + + Do you want to run %1? + Möchten Sie %1 ausführen? + + + + Burn image + button + Abbild brennen + + + + Burn files + button + Dateien brennen + + + + Are you sure you want to empty %1 item? + Sind Sie sicher, dass Sie %1 Element löschen möchten? + + + + Are you sure you want to empty %1 items? + Sind Sie sicher, dass Sie %1 Elemente löschen möchten? + + + + + This action cannot be undone + Diese Aktion kann nicht rückgängig gemacht werden + + + + + + + + + + + + + + OK + button + OK + + + + + + + + + + + + + + + Cancel + button + Abbrechen + + + + + + Run + button + Ausführen + + + + + Run in terminal + button + Im Terminal ausführen + + + + Display + button + Anzeige + + + + + + + + + + + Confirm + button + Bestätigen + + + + Erase + button + Löschen + + + + Data verification failed + Datenverifizierung fehlgeschlagen + + + + Show details + button + Details anzeigen + + + + + Delete + button + Löschen + + + + Remove + button + Entfernen + + + + Disk is busy, cannot unmount now + Laufwerk wird verwendet, es kann jetzt nicht ausgehängt werden + + + + Force unmount + button + Aushängen erzwingen + + + + Unable to copy. Not enough free space on the target disk. + Kopieren nicht möglich. Nicht genügend freier Speicherplatz auf dem Ziellaufwerk. + + + + Failed to restore %1 file, the target folder is read-only + %1 Datei konnte nicht wiederhergestellt werden. Der Zielordner ist schreibgeschützt + + + + Failed to restore %1 files, the target folder is read-only + %1 Dateien konnten nicht wiederhergestellt werden. Der Zielordner ist schreibgeschützt + + + + Failed to restore %1 files, the source files do not exist + Dateien %1 konnten nicht wiederhergestellt werden, die Quelldateien existieren nicht + + + + Format + button + Formatieren + + + + Stop + button + Stopp + + + + FileController + + + + + + Unable to find the original file + Die Originaldatei kann nicht gefunden werden + + + + + + Kindly Reminder + Freundliche Erinnerung + + + + + + Please install File Roller first and then continue + Bitte installieren Sie zuerst File Roller und fahren Sie dann fort + + + + + Unable to create files here: %1 + Dateien können hier nicht erstellt werden: %1 + + + + Confirm + button + Bestätigen + + + + FileDialogStatusBar + + + File Name + Dateiname + + + + Format + Formatieren + + + + Save + button + Speichern + + + + Open + button + Öffnen + + + + Save File + button + Datei speichern + + + + Open File + button + Datei öffnen + + + + + + Cancel + button + Abbrechen + + + + FileJob + + + copy + Kopie + + + + + + + Data verification successful. + Datenverifizierung erfolgreich. + + + + + + Burn process completed + Brennvorgang abgeschlossen + + + + %1 s + %1 Sek. + + + + %1 m %2 s + %1 Min. %2 Sek. + + + + %1 h %2 m %3 s + %1 Std. %2 Min. %3 Sek. + + + + %1 d %2 h %3 m %4 s + %1 Tag %2 Std. %3 Min. %4 Sek. + + + + %1 is a duplicate file. + %1 ist eine doppelte Datei. + + + + Insufficient disc space. + Zu wenig Festplattenspeicher. + + + + Lost connection to drive. + Verbindung zum Laufwerk verloren. + + + + The CD/DVD drive is not ready. Try another disc. + Das CD/DVD-Laufwerk ist nicht bereit. Versuchen Sie eine andere CD. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + Das CD/DVD-Laufwerk ist beschäftigt. Beenden Sie das Programm und schließen Sie das Laufwerk erneut an. + + + + Unknown error + Unbekannter Fehler + + + + Device disconnected + Gerät getrennt + + + + GenerateSettingTranslate + + + + + Basic + Basis + + + + + + Open behavior + Öffnungsverhalten + + + + + + Always open folder in new window + Ordner immer in neuem Fenster öffnen + + + + + + Open file: + Datei öffnen: + + + + + + Click + Klick + + + + + + Double click + Doppelklick + + + + + + New window and tab + Neues Fenster und Tab + + + + + + Open from default window: + Vom Standardfenster aus öffnen: + + + + + + + + + Computer + Computer + + + + + + + + + Home + Home + + + + + + + + + Desktop + Schreibtisch + + + + + + + + + Videos + Videos + + + + + + + + + Music + Musik + + + + + + + + + Pictures + Bilder + + + + + + + + + Documents + Dokumente + + + + + + + + + Downloads + Downloads + + + + + + Open in new tab: + Im neuen Tab öffnen: + + + + + + Current Directory + Aktuelles Verzeichnis + + + + + + View + Ansicht + + + + + + Default size: + Standardgröße: + + + + + + Extra small + Extra klein + + + + + + Small + Klein + + + + + + Medium + Mittel + + + + + + Large + Groß + + + + + + Extra large + Extra groß + + + + + + Default view: + Standardansicht: + + + + + + Icon + Symbol + + + + + + List + Liste + + + + + + Hidden files + Versteckte Dateien + + + + + + Show hidden files + Versteckte Dateien anzeigen + + + + + + Hide file extension when rename + Dateierweiterungen beim Umbenennen verstecken + + + + + + Advanced + Erweitert + + + + + + Index + Index + + + + + + Auto index internal disk + Interne Festplatte automatisch indexieren + + + + + + Index external storage device after connected to computer + Externen Speicher beim Anschließen indexieren + + + + + + Full-Text search + Volltextsuche + + + + + + Show item counts and sizes in the path of mounted MTP devices + Anzahl und Größe der Elemente im Pfad der eingehängten MTP-Geräte anzeigen + + + + + + Keep showing the mounted Samba shares + Eingehängte Samba-Freigaben weiterhin anzeigen + + + + + + Use the file chooser dialog of File Manager + Verwenden Sie den Dateiauswahldialog vom Dateimanager + + + + + + Ask for my confirmation when deleting files + Beim Löschen von Dateien nach meiner Bestätigung fragen + + + + + + Other + Anderes + + + + + + Hide system disk + Systemlaufwerk verstecken + + + + + + Show file system on disk icon + Dateisystem auf Laufwerkssymbol anzeigen + + + + + + Show hidden files in search results + Versteckte Dateien in Suchergebnissen anzeigen + + + + + + Display recent file entry in left panel + Letzte Dateieinträge im linken Bereich anzeigen + + + + + + Preview + Vorschau + + + + + Compress file preview + Dateivorschau komprimieren + + + + + + Text preview + Textvorschau + + + + + + Document preview + Dokumentvorschau + + + + + + Image preview + Bildvorschau + + + + + + Video preview + Videovorschau + + + + + + Mount + Einhängen + + + + + + Auto mount + Automatisches Einhängen + + + + + + Open after auto mount + Nach automatischem Einhängen öffnen + + + + + + Dialog + Dialog + + + + Compressed file preview + Vorschau der komprimierten Datei + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Kann die Identität von %1 nicht verifizieren. + + + + This happens when you log in to a computer the first time. + Dies geschieht, wenn Sie sich das erste Mal an einem Computer anmelden. + + + + The identity sent by the remote computer is + Die vom Remote-Computer gesendete Identität ist + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Wenn Sie absolut sicher sein wollen, dass es sicher ist, fortzufahren, wenden Sie sich an den Systemadministrator. + + + + + + + + Mounting device error + Fehler beim Einhängen des Geräts + + + + + Wrong username or password + Falscher Benutzername oder falsches Passwort + + + + + + + + Confirm + button + Bestätigen + + + + + Cannot find the mounted device + Kann das eingehängte Gerät nicht finden + + + + No key available to unlock device + Kein Schlüssel zum Entsperren des Geräts verfügbar + + + + The disk is mounted by user "%1", you cannot unmount it. + Das Laufwerk ist vom Benutzer „%1“ eingehängt, Sie können es nicht aushängen. + + + + Cannot unmount the device + Das Gerät kann nicht ausgehängt werden + + + + Cannot eject the device "%1" + Das Gerät „%1“ kann nicht ausgeworfen werden + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Das Brennen ist nicht möglich. Nicht genügend freier Speicherplatz auf dem Zieldatenträger. + + + + MergedDesktopController + + + + Pictures + Bilder + + + + + Music + Musik + + + + + Applications + Anwendungen + + + + + Videos + Videos + + + + + Documents + Dokumente + + + + + Others + Andere + + + + MimeTypeDisplayManager + + + + Directory + Verzeichnis + + + + + + Application + Anwendung + + + + + + Video + Video + + + + + + Audio + Audio + + + + + + Image + Bild + + + + + Archive + Archiv + + + + + + Text + Text + + + + + Executable + Ausführbare Datei + + + + + Backup file + Sicherungsdatei + + + + + Unknown + Unbekannt + + + + MountAskPasswordDialog + + + Cancel + button + Abbrechen + + + + Connect + button + Verbinden + + + + Log in as + Anmelden als + + + + Anonymous + Anonym + + + + Registered user + Registrierter Benutzer + + + + Username + Benutzername + + + + Domain + Domäne + + + + Password + Passwort + + + + Remember password + Passwort merken + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Abbrechen + + + + Unlock + button + Entsperren + + + + Input password to decrypt the disk + Passwort eingeben, um das Laufwerk zu entschlüsseln + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Sind Sie sicher, dass Sie %1 endgültig löschen möchten? + + + + This file is too big for the trash + Diese Datei ist zu groß für den Papierkorb + + + + The files are too big for the trash + Die Dateien sind zu groß für den Papierkorb + + + + Are you sure you want to permanently delete %1 files? + Sind Sie sicher, dass Sie %1 Dateien endgültig löschen möchten? + + + + Cancel + button + Abbrechen + + + + Delete + button + Löschen + + + + OpenWithDialog + + + Open with + Öffnen mit + + + + Add other programs + Andere Programme hinzufügen + + + + Set as default + Als Standard festlegen + + + + Cancel + button + Abbrechen + + + + Confirm + button + Bestätigen + + + + Recommended Applications + Empfohlene Anwendungen + + + + Other Applications + Andere Anwendungen + + + + PathManager + + + Home + Home + + + + Desktop + Arbeitsplatz + + + + Videos + Videos + + + + Music + Musik + + + + Pictures + Bilder + + + + Documents + Dokumente + + + + Downloads + Downloads + + + + + Trash + Papierkorb + + + + + + System Disk + Systemlaufwerk + + + + Computers in LAN + Computer im LAN + + + + My Shares + Meine Freigaben + + + + Computer + Computer + + + + Recent + Zuletzt + + + + File Vault + Dateitresor + + + + PropertyDialog + + + Basic info + Grundinformationen + + + + Open with + Öffnen mit + + + + Sharing + Teilen + + + + Permissions + Berechtigungen + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Diesen Ordner verstecken + + + + Hide this file + Diese Datei verstecken + + + + Allow to execute as program + Ausführung als Programm erlauben + + + + QObject + + + + + + Size + Größe + + + + + + Contains + Enthält + + + + + + Type + Typ + + + + + + + + Time modified + Änderungszeit + + + + Free space + Freier Speicher + + + + Total space + Gesamter Speicher + + + + + Time locked + + + + + Access denied + Zugriff verweigert + + + + + Executable + Ausführbar + + + + + Write only + Nur schreiben + + + + + Read only + Nur Lesen + + + + + Read-write + Lesen/Schreiben + + + + Others + Anderes + + + + Owner + Besitzer + + + + Unconnected network shared directory + Nicht verbundenes gemeinsames Netzwerkverzeichnis + + + + Device type + Gerätetyp + + + + File system + Dateisystem + + + + Group + Gruppe + + + + + Open + Öffnen + + + + Lock + Sperren + + + + Auto lock + Automatisch sperren + + + + Never + Nie + + + + 5 minutes + 5 Minuten + + + + 10 minutes + 10 Minuten + + + + 20 minutes + 20 Minuten + + + + Delete File Vault + Dateitresor löschen + + + + Unlock + Entsperren + + + + Unlock by key + Mit Schlüssel entsperren + + + + Open + button + Öffnen + + + + + Size: %1 + Größe: %1 + + + + Type: %1 + Typ: %1 + + + + Size: 0 + Größe: 0 + + + + Items: %1 + Elemente: %1 + + + + + + + + + + Open in new window + In neuem Fenster öffnen + + + + + + + + + + Open in new tab + In neuem Tab öffnen + + + + Open with + Öffnen mit + + + + + Compress + Komprimieren + + + + Extract + Entpacken + + + + Extract here + Hier entpacken + + + + Cut + Ausschneiden + + + + Copy + Kopieren + + + + Paste + Einfügen + + + + + + + + Rename + Umbenennen + + + + + + + Remove + Entfernen + + + + Create link + Verknüpfung erstellen + + + + Send to desktop + An Desktop senden + + + + Send to + Senden an + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Als Lesezeichen hinzufügen + + + + + + + Properties + Eigenschaften + + + + New folder + Neuer Ordner + + + + New window + Neues Fenster + + + + Select all + Alles auswählen + + + + + Clear recent history + Kürzlichen Verlauf löschen + + + + + + Empty Trash + Papierkorb leeren + + + + Display as + Anzeigen als + + + + Sort by + Sortieren nach + + + + New document + Neues Dokument + + + + + Time created + Erstellungszeit + + + + + + Source path + Quellpfad + + + + Share folder + Ordner freigeben + + + + Cancel sharing + Freigabe abbrechen + + + + Connect to Server + Mit Server verbinden + + + + Set share password + Freigabepasswort festlegen + + + + Format + Format + + + + Tag information + Schlagwort-Informationen + + + + Open as administrator + Als Administrator öffnen + + + + Select default program + Standardprogramm auswählen + + + + Open file location + Dateiort öffnen + + + + Remove bookmark + Lesezeichen entfernen + + + + + + Delete + Löschen + + + + Office Text + Office Text + + + + Spreadsheets + Tabellen + + + + Plain Text + Einfacher Text + + + + Open in terminal + Im Terminal öffnen + + + + Restore + Wiederherstellen + + + + Restore all + Alle wiederherstellen + + + + Clear saved password and unmount + Gespeichertes Passwort löschen und aushängen + + + + File Vault + Dateitresor + + + + Add to disc + Zur Disc hinzufügen + + + + Refresh + + + + + Auto mount + Automatisch einhängen + + + + Open after auto mount + Nach automatischem Einbinden öffnen + + + + + Mount + Einhängen + + + + + Unmount + Aushängen + + + + It does not support burning %1 discs + Das Brennen von %1-Datenträgern wird nicht unterstützt + + + + Burn + Brennen + + + + Disc name: + Name der Disc: + + + + + Maximum + Maxmimum + + + + Allow files to be added later + Nachträgliches Hinzufügen von Daten erlauben + + + + Verify data + Daten verifizieren + + + + Write speed: + Schreibgeschwindigkeit: + + + + + + + Cancel + button + Abbrechen + + + + Burn + button + Brennen + + + + + Eject + Auswerfen + + + + Safely Remove + Sicheres Entfernen + + + + + Name + Name + + + + Settings + Einstellungen + + + + Exit + Beenden + + + + Icon + Symbol + + + + List + Liste + + + + Extend + Ausklappen + + + + Set as wallpaper + Als Hintergrundbild verwenden + + + + + + + Local disk + Lokale Festplatte + + + + + Removable disk + Wechseldatenträger + + + + + + Network shared directory + Freigegebenes Netzwerkverzeichnis + + + + + Android mobile device + Android-Mobilgerät + + + + + Apple mobile device + Apple-Mobilgerät + + + + + Camera + Kamera + + + + + DVD + DVD + + + + + Unknown device + Unbekanntes Gerät + + + + + + %1 item + %1 Element + + + + + + %1 items + %1 Elemente + + + + Shortcut + Verknüpfung + + + + Create symlink + Symbolische Verknüpfung erstellen + + + + Path + Pfad + + + + + + Time deleted + Löschzeit + + + + Loading... + Wird geladen ... + + + + File has been moved or deleted + Datei wurde verschoben oder gelöscht + + + + You do not have permission to traverse files in it + + + + + + + You do not have permission to access this folder + Sie haben keine Berechtigung, um auf diesen Ordner zuzugreifen + + + + + + + + Folder is empty + Ordner ist leer + + + + Searching... + Wird gesucht ... + + + + No results + Keine Ergebnisse + + + + Source Path + TrashFileInfo + Quellpfad + + + + Document + Dokument + + + + Spreadsheet + Tabelle + + + + + Presentation + Präsentation + + + + Text + Text + + + + 1 task in progress + 1 Aufgabe in Bearbeitung + + + + %1 tasks in progress + %1 Aufgaben in Bearbeitung + + + + Mode: + Modus: + + + + + Replace Text + Text ersetzen + + + + + Add Text + Text hinzufügen + + + + + Custom Text + Benutzerdefinierter Text + + + + Find: + Suchen: + + + + Replace: + Ersetzen: + + + + + Optional + Optional + + + + Add: + Hinzufügen: + + + + Location: + Speicherort: + + + + File name: + Dateiname: + + + + Start at: + Start bei: + + + + + Rename + button + Umbenennen + + + + + + + + + + + Required + Erforderlich + + + + + Before file name + Vor dem Dateinamen + + + + + After file name + Hinter dem Dateinamen + + + + Find + Suchen + + + + Replace + Ersetzen + + + + Add + Hinzufügen + + + + Start at + Start bei + + + + + + Location + Speicherort + + + + File name + Dateiname + + + + Dimension + Abmessungen + + + + Duration + Dauer + + + + Tips: Sort by selected file order + Tipps: Nach ausgewählter Dateireihenfolge sortieren + + + + Rename %1 Files + %1 Dateien umbenennen + + + + Multiple Files + Datei-Mehrfachauswahl + + + + Basic info + Basisinformation + + + + Total size + Gesamtgröße + + + + Number of files + Anzahl der Dateien + + + + %1 file(s), %2 folder(s) + %1 Datei(en), %2 Ordner + + + + + + Time accessed + Zugriffszeit + + + + Orange + Orange + + + + Red + Rot + + + + Purple + Lila + + + + Navy-blue + Dunkelblau + + + + Azure + Blau + + + + Green + Grün + + + + Yellow + Gelb + + + + Gray + Grau + + + + Input tag info, such as work, family. A comma is used between two tags. + Schlagwort-Informationen eingeben, wie etwa 'Arbeit', 'Familie'. Ein Komma wird zwischen zwei Schlagwörtern benutzt. + + + + Bookmarks + Lesezeichen + + + + Erase + Löschen + + + + Copy path + Pfad kopieren + + + + Edit address + Adresse bearbeiten + + + + Free Space %1 + Freier Speicher %1 + + + + Files are being processed + Dateien werden verarbeitet + + + + + Unknown + Unbekannt + + + + My Vault + Mein Tresor + + + + + Failed to create file info + Fehler beim Erstellen der Dateiinfo + + + + Failed to create file handler + + + + + Failed to open the file, cause: %1 + Fehler beim Öffnen der Datei, Grund: %1 + + + + Original file does not exist + Ursprungsdatei existiert nicht + + + + Do you want to delete %1? + Möchten Sie %1 löschen? + + + + Confirm + button + Bestätigen + + + + + + + + %1 are not allowed + %1 sind nicht erlaubt + + + + + Failed to start Samba services + Start der Samba-Dienste ist fehlgeschlagen + + + + RecentController + + + Cancel + button + Abbrechen + + + + Remove + button + Entfernen + + + + Do you want to remove this item? + Möchten Sie dieses Element entfernen? + + + + Do yout want to remove %1 items? + Möchten Sie %1 Elemente entfernen? + + + + It does not delete the original files + Die Originaldateien werden dabei nicht gelöscht. + + + + ShareInfoFrame + + + Share this folder + Diesen Ordner freigeben + + + + Share name: + Freigabename: + + + + Permission: + Berechtigung: + + + + Read and write + Lesen und schreiben + + + + Read only + Nur lesen + + + + Anonymous: + Anonym: + + + + Not allow + Nicht erlauben + + + + Allow + Erlauben + + + + The share name must not be two dots (..) or one dot (.) + Der Freigabename darf nicht aus zwei Punkten (..) oder einem Punkt (.) bestehen + + + + The share name is used by another user. + Der Freigabename wird von einem anderen Benutzer verwendet. + + + + OK + button + OK + + + + Cancel + button + Abbrechen + + + + Replace + button + Ersetzen + + + + The share name already exists. Do you want to replace the shared folder? + Der Freigabename existiert bereits. Möchten Sie den freigegebenen Ordner ersetzen? + + + + Shortcut + + + Item + Element + + + + Select to the first item + Bis zum ersten Element auswählen + + + + Shift + Home + Umschalt + Pos1 + + + + Select to the last item + Bis zum letzten Element auswählen + + + + Shift + End + Umschalt + Ende + + + + Select leftwards + Auswahl nach links + + + + Shift + Left + Umschalt + Pfeil nach links + + + + Select rightwards + Auswahl nach rechts + + + + Shift + Right + Umschalt + Pfeil nach rechts + + + + Select to upper row + Bis obere Reihe auswählen + + + + Shift + Up + Umschalt + Pfeil nach oben + + + + Select to lower row + Bis untere Reihe auswählen + + + + Shift + Down + Umschalt + Pfeil nach unten + + + + Open + Öffnen + + + + Ctrl + Down + Strg + Pfeil nach unten + + + + To parent directory + Zum übergeordneten Verzeichnis + + + + Ctrl + Up + Strg + Pfeil nach oben + + + + Permanently delete + Endgültig löschen + + + + Shift + Delete + Umschalt + Entfernen + + + + Delete file + Datei löschen + + + + Delete + Löschen + + + + Select all + Alles auswählen + + + + Ctrl + A + Strg + A + + + + Ctrl + C + Strg + C + + + + Ctrl + X + Strg + X + + + + Ctrl + V + Strg + V + + + + Ctrl + N + Strg + N + + + + Ctrl + Shift + N + Strg + Umschalt + N + + + + Ctrl + F + Strg + F + + + + Ctrl + T + Strg + T + + + + Ctrl + I + Strg + I + + + + Ctrl + H + Strg + H + + + + Ctrl + L + Strg + L + + + + Ctrl + W + Strg + W + + + + Copy + Kopieren + + + + Cut + Ausschneiden + + + + Paste + Einfügen + + + + Rename + Umbenennen + + + + F2 + F2 + + + + New/Search + Neu/Suchen + + + + New window + Neues Fenster + + + + New folder + Neuer Ordner + + + + + Search + Suchen + + + + New tab + Neuer Tab + + + + View + Ansicht + + + + Item information + Elementinformationen + + + + Help + Hilfe + + + + F1 + F1 + + + + Keyboard shortcuts + Tastaturkürzel + + + + Ctrl + Shift + / + Strg + Umschalt + / + + + + Switch display status + Anzeigestatus umschalten + + + + Hide item + Element ausblenden + + + + Input in address bar + In Adresszeile eingeben + + + + Switch to icon view + Zur Symbolansicht wechseln + + + + Ctrl + 1 + Strg + 1 + + + + Switch to list view + Zur Listenansicht wechseln + + + + Ctrl + 2 + Strg + 2 + + + + Others + Andere + + + + Close + Schließen + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Aktuellen Tab schließen + + + + Back + Zurück + + + + Alt + Left + Alt + Pfeil nach links + + + + Alt + Right + Alt + Pfeil nach rechts + + + + Switch to next tab + Zu nächstem Tab wechseln + + + + Ctrl + Tab + Strg + Tab + + + + Ctrl + Shift + Tab + Strg + Shift + Tab + + + + Switch to previous tab + Zu vorherigem Tab wechseln + + + + Next file + Nächste Datei + + + + Tab + Tab + + + + Previous file + Vorherige Datei + + + + Shift + Tab + Umschalt + Tab + + + + Switch tab by specified number between 1 to 8 + Tab unter Verwendung der Tasten 1 bis 8 wechseln + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Weiterleiten + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Elemente im Papierkorb können nicht geöffnet werden, bitte stellen Sie die Elemente zuerst wieder her + + + + TrashPropertyDialog + + + Trash + Papierkorb + + + + item + Element + + + + items + Elemente + + + + Contains %1 %2 + Enthält %1 %2 + + + + UDiskListener + + + Failed to rename the label + Fehler beim Umbenennen der Bezeichnung + + + + UnmountWorker + + + + + The device was not safely unmounted + Das Gerät wurde nicht sicher ausgehängt + + + + The device was not safely removed + Das Gerät wurde nicht sicher entfernt + + + + UserShareManager + + + Kindly Reminder + Freundliche Erinnerung + + + + Please firstly install samba to continue + Bitte installieren Sie zunächst Samba, um fortzufahren + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + + + + + To protect the files, you cannot share this folder. + Um die Dateien zu schützen, können Sie diesen Ordner nicht freigeben. + + + + Sharing failed + Teilen fehlgeschlagen + + + + The computer name is too long + Der Computername ist zu lang + + + + You do not have permission to operate file/folder! + Sie besitzen nicht die erforderlichen Rechte um den Ordner oder die Datei zu bearbeiten! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Geben Sie ein Kennwort ein, um freigegebene Ordner zu schützen + + + + Cancel + button + Abbrechen + + + + Confirm + button + Bestätigen + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_el.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_el.ts new file mode 100644 index 0000000..e1a0631 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_el.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + Νέος Φάκελος + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + Κλείσιμο όλων + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + Υπολογιστής + + + + Basic Info + Βασικές Πληροφορίες + + + + Computer Name + Όνομα Υπολογιστή + + + + Version + Έκδοση + + + + Type + Τύπος + + + + Processor + Επεξεργαστής + + + + Memory + Μνήμη + + + + Disk + Δίσκος + + + + Bit + Bit + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + Αναζήτηση ή εισαγωγή διεύθυνσης + + + + DFMAdvanceSearchBar + + + Search: + Εύρεση: + + + + File Type: + Τύπος Αρχείου: + + + + File Size: + Μέγεθος Αρχείου: + + + + Time Modified: + Ώρα Μορφοποίησης: + + + + Reset + Επαναφορά + + + + All subdirectories + Όλοι οι υποφάκελλοι + + + + Current directory + Τρέχων Φάκελος + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Σήμερα + + + + Yesterday + Χτες + + + + This week + Αυτήν τη εβδομάδα + + + + Last week + Τελευταία εβδομάδα + + + + This month + Αυτόν το μήνα + + + + Last month + Τελευταίο μήνα + + + + This year + Αυτό τον χρόνο + + + + Last year + Τελευταίος χρόνος + + + + DFMTagCrumbController + + + Tag information + Ετικέτα κατηγοριοποίησης + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + Σφάλμα εξουσιοδότησης + + + + The action is denied + Η ενέργεια απορρίφθηκε + + + + Failed to open the file + Αποτυχία ανοίγματος του αρχείου + + + + Failed to read the file + Αποτυχία ανάγνωσης του αρχείου + + + + Failed to write the file + Αποτυχία εγγραφής στο αρχείο + + + + Failed to create the directory + Αποτυχία δημιουργίας φακέλου + + + + Failed to delete the file + Αποτυχία διαγραφής αρχείου + + + + Failed to move the file + Αποτυχία μεταφοράς αρχείου + + + + Original file does not exist + Το αρχείο δεν υπάρχει + + + + Failed, file size must be less than 4GB + Αποτυχία, το αρχείο πρεπει να ειναι μικροτερο απο 4GB + + + + Not enough free space on the target disk + + + + + File integrity was damaged + Η ακεραιότητα του αρχείου καταστράφηκε + + + + The target device is read only + Στην συγκεκριμένη συσκευή έχετε μόνο δικαιώματα ανάγνωσης + + + + Target folder is inside the source folder + Ο φάκελος προορισμού είναι μέσα στον αρχικό φάκελο + + + + copy + Extra name added to new file name when used for file name. + αντιγραφή + + + + Failed to create the directory, cause: %1 + Αποτυχία δημιουργίας φακέλου, λόγω: %1 + + + + + Failed to open the file, cause: %1 + Αποτυχία ανοίγματος του αρχείου, λόγω: %1 + + + + Failed to read the file, cause: %1 + Αποτυχία διαβάσματος του αρχείου, λόγω: %1 + + + + Failed to write the file, cause: %1 + Αποτυχία εγγραφής του αρχείου, λόγω: %1 + + + + File integrity was damaged, cause: %1 + Η ακεραιότητα του αρχείου καταστράφηκε, λόγω: %1 + + + + Failed to delete the file, cause: %1 + Αποτυχία διαγραφής του αρχείου, λόγω: %1 + + + + Fail to create symlink, cause: %1 + Αποτυχία δημιουργίας συμβολικού συνδέσμου, λόγω: %1 + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + Το %1 υπάρχει ήδη, θέλετε να αντικατασταθεί; + + + + Cancel + Άκυρο + + + + Replace + Αντικατάσταση + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + Όνομα + + + + + + Time modified + Ώρα τροποποίησης + + + + Size + Μέγεθος + + + + Type + Τύπος + + + + Time created + Ώρα δημιουργίας + + + + + Last access + Τελευταία πρόσβαση + + + + Path + Μονοπάτι + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + (Αντίστροφα) + + + + DFileViewHelper + + + Add tag "%1" + Προσθήκη ετικέτας "%1" + + + + DStatusBar + + + %1 item + %1 αντικείμενο + + + + %1 items + %1 αντικείμενα + + + + %1 item selected + %1 επιλεγμένο αντικείμενο + + + + %1 items selected + %1 επιλεγμένα αντικείμενα + + + + %1 folder selected (contains %2) + %1 επιλεγμένος φάκελος (περιέχει %2) + + + + %1 folders selected (contains %2) + %1 επιλεγμένοι φάκελοι (περιέχουν %2) + + + + %1 file selected (%2) + %1 επιλεγμένο αρχείο (%2) + + + + %1 files selected (%2) + %1 επιλεγμένα αρχεία (%2) + + + + %1 folder selected + %1 επιλεγμένος φάκελος + + + + Filter + Φίλτρο + + + + Save as: + Αποθήκευση ως: + + + + Loading... + Φόρτωση... + + + + DTaskDialog + + + This action is not supported + Αυτή η ενέργεια δεν υποστηρίζεται + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + %1 Ένταση + + + + Data Disk + Data Partition + Δίσκος Δεδομένων + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + Η λειτουργία απέτυχε! + + + + Target folder is inside the source folder! + Ο φάκελος προορισμού είναι μέσα στον αρχικό φάκελο + + + + + + + + + + + + + OK + OK + + + + Do you want to run %1 or display its content? + Θέλετε να εκτελέσετε το %1 ή να εμφανιστούν τα περιεχόμενά του; + + + + It is an executable text file. + Είναι ένα εκτελέσιμο αρχείο κειμένου, + + + + + + + + + + + + + + Cancel + Άκυρο + + + + + + Run + Εκτέλεση + + + + + Run in terminal + Εκτέλεση στο terminal + + + + Display + Εμφάνιση + + + + It is an executable file. + Είναι ένα εκτελέσιμο αρχείο. + + + + This file is not executable, do you want to add the execute permission and run? + Αυτό το αρχείο δεν είναι εκτελέσιμο, θέλετε να προσθέσετε άδεια εκτέλεσης και να το τρέξετε; + + + + "%1" already exists, please use another name. + Το "%1" υπάρχει ήδη, παρακαλούμε χρησιμοποιήστε άλλο όνομα. + + + + + + + + Confirm + Επαλήθευση + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + Οριστική διαγραφή του %1; + + + + Permanently delete %1 items? + Οριστική διαγραφή %1 αντικειμένων; + + + + Delete + Διαγραφή + + + + Empty + Άδειασμα + + + + Sorry, unable to locate your bookmark directory, remove it? + Λυπούμαστε, δεν μπορεί να εντοπιστεί ο φάκελος σελιδοδεικτών σας, να αφαιρεθεί; + + + + Remove + Αφαίρεση + + + + Name: + Όνομα: + + + + Force unmount + Δυναμική αποσύνδεση + + + + %1 that this shortcut refers to has been changed or moved + %1 το ότι αυτή η συντόμευση αναφέρεται στο ότι έχει αλλάξει ή μετακινηθεί + + + + Do you want to delete this shortcut? + Θέλετε να διαγραφεί αυτή η συντόμευση; + + + + Failed, file size must be less than 4GB. + Αποτυχία, το αρχείο πρεπει να ειναι μικροτερο απο 4GB + + + + Fail to create symlink, cause: + Αποτυχία δημιουργίας συμβολικού συνδέσμου, λόγω: + + + + The selected files contain system file/directory, and it cannot be deleted + Τα επιλεγμένα αρχεία, περιέχουν, αρχείο/φάκελο συστήματος και δεν μπορεί να διαγραφεί + + + + + You do not have permission to operate file/folder! + Δεν έχετε την άδεια να χειριστείτε αρχείο/φάκελο + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Συγγνώμη, δεν έχετε την άδεια να χειριστείτε το ακόλουθο %1 αρχείο/φάκελο(ους)! + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + 2. Αποεπιλέξετε το "Ενεργοποίηση γρήγορης εκκίνησης" και "Αδράνεια" στις ρυθμίσεις απενεργοποίησης και επανεκκίνησης + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + Ο κοινόχρηστος φάκελλος δεν μπορεί να ονομάζεται με το τρέχον όνομα χρήστη + + + + View + Εμφάνιση + + + + Do you want to run %1? + Θέλετε να εκτελέσετε το %1; + + + + Are you sure you want to empty %1 item? + Είστε βέβαιος, ότι θέλετε να αδειάσετε %1 αντικείμενο; + + + + Are you sure you want to empty %1 items? + Είστε βέβαιος, ότι θέλετε να αδειάσετε %1 αντικείμενα; + + + + + This action cannot be undone + Αυτή η ενέργεια δεν μπορεί να αναιρεθεί + + + + Disk is busy, cannot unmount now + Ο δίσκος είναι απασχολημένος, δεν μπορεί να αποσυνδεθεί τώρα + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + Σύνδεση διαμερίσματος %1 ως μόνο για ανάγνωση + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + Οι δίσκοι σε παράθυρα θα είναι ανίκανα να, διαβάσου και να γράψουν ομαλά εάν επιλεγεί "Ενεργοποίηση γρήγορης εκκίνησης (προτείνεται)" στις ρυθμίσεις απενεργοποίησης + + + + Please restore by the following steps to normally access Windows disk + Παρακαλώ επαναφέρετε με τα ακόλουθα βήματα για ομαλή πρόσβαση των δίσκων παραθύρων + + + + 1. Reboot to enter Windows + 1. Επανεκκίνηση για να μπείτε στα Windows + + + 3. Reboot and enter deepin + 3. Επανεκκίνηση και είσοδος πάλι στο Deepin + + + + Reboot + Επανεκκίνηση + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + Όνομα Αρχείου + + + + Format + Διαμόρφωση + + + + Cancel + Άκυρο + + + + Save + Αποθήκευση + + + + Open + Άνοιγμα + + + + Save File + Αποθήκευση Αρχείου + + + + Open File + Άνοιγμα Αρχείου + + + + FileJob + + + copy + αντιγραφή + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + %1 δ + + + + %1 m %2 s + %1 λ %2 δ + + + + %1 h %2 m %3 s + %1 ω %2 λ %3 δ + + + + %1 d %2 h %3 m %4 s + %1 η %2 ω %3 λ %4 δ + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + Βασικό + + + + + + Open behavior + Συμπεριφορά ανοίγματος + + + + + + Always open folder in new window + Άνοιγμα φακέλλων σε νέο παράθυρο πάντα + + + + + + Open file: + Άνοιγμα αρχείου: + + + + + + Click + Κλικ + + + + + + Double click + Διπλό κλικ + + + + + + New window and tab + Νέο παράθυρο και καρτέλα + + + + + + Open from default window: + Άνοιγμα από το προεπιλεγμένο παράθυρο: + + + + + + + + + Computer + Υπολογιστής + + + + + + + + + Home + Αρχική + + + + + + + + + Desktop + Επιφάνεια Εργασίας + + + + + + + + + Videos + Βίντεο + + + + + + + + + Music + Μουσική + + + + + + + + + Pictures + Εικόνες + + + + + + + + + Documents + Έγγραφα + + + + + + + + + Downloads + Λήψεις + + + + + + Open in new tab: + Άνοιγμα σε νέα καρτέλα: + + + + + + Current Directory + Τρέχων Φάκελος + + + + + + View + Προβολή + + + + + + Default size: + Προεπιλεγμένο μέγεθος: + + + + + + Extra small + Πολύ μικρό + + + + + + Small + Μικρό + + + + + + Medium + Μεσσαίο + + + + + + Large + Μεγάλο + + + + + + Extra large + Πολύ μεγάλο + + + + + + Default view: + Προεπιλεγμένη προβολή: + + + + + + Icon + Εικονίδιο + + + + + + List + Λίστα + + + + + + Hidden files + Κρυφά αρχεία + + + + + + Show hidden files + Εμφάνιση κρυφών αρχείων + + + + + + Hide file extension when rename + Απόκρυψη επέκτασης αρχείου κατά την μετονομασία + + + + + + Advanced + Προηγμένο + + + + + + Index + Δείκτης + + + + + + Auto index internal disk + Αυτόματη ένταξη εσωτερικών δίσκων + + + + + + Index external storage device after connected to computer + Ένταξη εξωτερικής συσκευής χώρου αποθήκευσης μετά την σύνδεση με τον υπολογιστή + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + Άλλο + + + + + + Hide system disk + Απόκρυψη δίσκου συστήματος + + + + + + Show hidden files in search results + Εμφάνιση κρυφών αρχείων στα αποτελέσματα αναζήτησης + + + + + + Display recent file entry in left panel + Προβολή πρόσφατα καταχωρημένων αρχείων στον αριστερό πίνακα + + + + + + Preview + Προεπισκόπιση + + + + + Compress file preview + Προεπισκόπιση συμπιεσμένου αρχείου + + + + + + Text preview + Προεπισκόπιση κειμένου + + + + + + Document preview + Προεπισκόπιση εγγράφου + + + + + + Image preview + Προεπισκόπιση εικόνας + + + + + + Video preview + Προεπισκόπιση βίντεο + + + + + + Mount + Σύνδεση + + + + + + Auto mount + Αυτόματη σύνδεση + + + + + + Open after auto mount + Άνοιγμα μετά την αυτόματη σύνδεση + + + + + + Dialog + Καταγραφή + + + Use the file chooser dialog of Deepin File Manager + Χρησιμοποιήστε το παράθυρο επιλογής αρχείων του Deepin File Manager + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + Ο δίσκος είναι συνδεδεμένος από τον χρήστη "%1", εσείς δεν μπορείτε να τον αποσυνδέσετε + + + + + + + + Confirm + Επαλήθευση + + + + + Cannot find the mounting device + Αδυναμία εύρεσης της συνδεόμενης συσκευής + + + + Cannot unmount the device + Αδυναμία αποσύνδεσης της συσκευής + + + + Cannot eject the device "%1" + Αδυναμία εξαγωγής της συσκευής "%1" + + + + MergedDesktopController + + + + Pictures + Εικόνες + + + + + Music + Μουσική + + + + + Applications + Εφαρμογές + + + + + Videos + Βίντεο + + + + + Documents + Έγγραφα + + + + + Others + Άλλα + + + + MimeTypeDisplayManager + + + + Directory + Φάκελλος + + + + + + Application + Εφαρμογές + + + + + + Video + Βίντεο + + + + + + Audio + Ήχοι + + + + + + Image + Εικόνες + + + + + Archive + Αρχείο + + + + + + Text + Κείμενο + + + + + Executable + Εκτελέσιμο + + + + + Backup file + Αρχείο εφεδρικού αντιγράφου ασφαλείας + + + + + Unknown + Άγνωστο + + + + MountAskPasswordDialog + + + Cancel + Άκυρο + + + + Connect + Σύνδεση + + + + Log in as + Είσοδος ως + + + + Anonymous + Ανώνυμος + + + + Registered user + Εγγεγραμμένος χρήστης + + + + Username + Όνομα χρήστη + + + + Domain + Τομέας + + + + Password + Κωδικός + + + + Remember password + Απομνημόνευση κωδικού πρόσβασης + + + + MountSecretDiskAskPasswordDialog + + + Cancel + Άκυρο + + + + Unlock + + + + + Input password to decrypt the disk + Εισαγωγή κωδικού ασφαλείας για αποκρυπτογράφηση δίσκου + + + + MoveCopyTaskWidget + + Skip + Παράλειψη + + + Keep both + Διατήρηση και των δύο + + + Replace + Αντικατάσταση + + + Do not ask again + Να μην ερωτηθείτε ξανά + + + merge + συγχώνευση + + + Copying %1 + Αντιγραφή %1 + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + Αντιγραφή στο %2 + + + Moving %1 + Μεταφορά %1 + + + Move to %2 + Μεταφορά στο %2 + + + Restoring %1 + Ανάκτηση %1 + + + Restore to %2 + Ανάκτηση στο %2 + + + Deleting %1 + Διαγραφή %1 + + + Trashing %1 + Πέταμα στα σκουπίδια %1 + + + Calculating space, please wait + Υπολογισμός χώρου, παρακαλούμε περιμένετε + + + File named %1 already exists in target folder + Το αρχείο με όνομα %1 υπάρχει ήδη στο φάκελο προορισμού + + + Original path %1 target path %2 + Πρωτότυπος φάκελος %1 φάκελος προορισμού %2 + + + Retry + Επανάληψη + + + Time modified:%1 + Χρόνος τροποποίησης:%1 + + + Original folder + Αρχικός φάκελλος + + + Original file + Αρχικό αρχείο + + + Target folder + Φάκελλος προορισμού + + + Target file + Αρχείο προορισμού + + + Contains:%1 + Περιέχει:%1 + + + Size:%1 + Μέγεθος:%1 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Είστε βέβαιος ότι θέλετε να διαγράψετε μόνιμα %1; + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + Είστε βέβαιος ότι θέλετε να διαγράψετε μόνιμα %1 αρχεία; + + + + Cancel + Άκυρο + + + + Delete + Διαγραφή + + + + OpenWithDialog + + + Open with + Άνοιγμα με + + + + Add other programs + Προσθήκη άλλων προγραμμάτων + + + + Set as default + Ορισμός ως προεπιλογή + + + + Cancel + Άκυρο + + + + Confirm + + + + + Recommended Applications + Απαραίτητες Εφαρμογές + + + + Other Applications + Άλλες Εφαρμογές + + + + PathManager + + + Home + Αρχική + + + + Desktop + Επιφάνεια Εργασίας + + + + Videos + Βίντεο + + + + Music + Μουσική + + + + Pictures + Εικόνες + + + + Documents + Έγγραφα + + + + Downloads + Λήψεις + + + + + Trash + Κάδος + + + + + System Disk + Δίσκος Συστήματος + + + + Computers in LAN + Υπολογιστές στο LAN + + + + My Shares + Οι κοινοποιήσεις μου + + + + Computer + Υπολογιστής + + + + Recent + Πρόσφατα + + + + PropertyDialog + + + Basic info + Βασικές πληροφορίες + + + + Open with + Άνοιγμα με + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + Αποδοχή εκτέλεσης ως πρόγραμμα + + + + QObject + + + + + Size + Μέγεθος + + + + + + Contains + Περιέχει + + + + + + Type + Τύπος + + + + + + + Time modified + Χρόνος τροποποίησης + + + + Free space + Ελεύθερος χώρος + + + + Total space + Συνολικός χώρος + + + + Access denied + Απαγορεύεται η πρόσβαση + + + + + Executable + Εκτελέσιμο + + + + + Write only + Μόνο για εγγραφή + + + + + Read only + Μόνο για ανάγνωση + + + + + Read-write + Ανάγνωση-εγγραφή + + + + Others + Άλλα + + + + Owner + Ιδιοκτήτης + + + + Device type + + + + + File system + + + + + Group + Ομάδα + + + + + + Open + Άνοιγμα + + + + + Size: %1 + Μέγεθος: %1 + + + + Type: %1 + Τύπος: %1 + + + + Size: 0 + Μέγεθος: 0 + + + + Items: %1 + Αντικείμενα: %1 + + + + + + + + + + + Open in new window + Άνοιγμα σε νέο παράθυρο + + + + + + + + + + + Open in new tab + Άνοιγμα σε νέα καρτέλα + + + + Open with + Άνοιγμα με + + + + Compress + Συμπίεση + + + + Extract + Αποσυμπίεση + + + + Extract here + Αποσυμπίεση εδώ + + + + Cut + Αποκοπή + + + + Copy + Αντιγραφή + + + + Paste + Επικόλληση + + + + + + + + + + Rename + Μετονομασία + + + + + + Remove + Αφαίρεση + + + + Create link + Δημιουργία συνδέσμου + + + + Send to desktop + Αποστολή στην επιφάνεια εργασίας + + + + Send to + Αποστολή σε + + + + Add to bookmark + Προσθήκη στο σελιδοδείκτη + + + + + + + Properties + Ιδιότητες + + + + New folder + Νέος φάκελος + + + + New window + Νέο παράθυρο + + + + Select all + Επιλογή όλων + + + + + Clear recent history + Εκκαθάριση πρόσφατου ιστορικού + + + + + + Empty Trash + Άδειασμα κάδου + + + + Display as + Εμφάνιση ως + + + + Sort by + Ταξινόμηση κατά + + + + New document + Νέο έγγραφο + + + + + Time created + Χρόνος δημιουργίας + + + + Log out and unmount + Αποσύνδεση και εκβολή + + + + + + Source path + Μονοπάτι πηγής + + + + Share folder + Κοινοποιήση φακέλου + + + + Cancel sharing + Ακύρωση κοινοποίησης + + + + Connect to Server + + + + + Set share password + Θέστε κωδικό πρόσβασης κοινοποιήσης + + + + Format + Μορφή + + + + Tag information + Ετικέτα κατηγοριοποίησης + + + + Open in new window as admin + Άνοιγμα νέου παραθύρου ως διαχειριστής + + + + Select default program + Επιλέξτε προεπιλεγμένο πρόγραμμα + + + + Open file location + Άνοιγμα τοποθεσίας αρχείου + + + + Remove bookmark + Αφαίρεση σελιδοδείκτη + + + + + + Delete + Διαγραφή + + + + Office Text + Κείμενο office + + + + Spreadsheets + Υπολογιστικά φύλλα + + + + Plain Text + Απλό κείμενο + + + + Open in terminal + Άνοιγμα στο terminal + + + + Restore + Ανάκτηση + + + + Restore all + Ανάκτηση όλων + + + + File Vault + + + + + Auto mount + Αυτόματη σύνδεση + + + + Open after auto mount + Άνοιγμα μετά την αυτόματη σύνδεση + + + + + Mount + Σύνδεση + + + + + Unmount + Αποσύνδεση + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + Εξαγωγή + + + + Safely Remove + Ασφαλής Αφαίρεση + + + + + Name + Όνομα + + + + Settings + Ρυθμίσεις + + + + Exit + Έξοδος + + + + Icon + Εικονίδιο + + + + List + Λίστα + + + + Extend + Επέκταση + + + + Set as wallpaper + Ορισμός ως ταπετσαρία + + + + + + + Local disk + Τοπικός δίσκος + + + + + Removable disk + Αφαιρούμενος δίσκος + + + + + + Network shared directory + Φάκελλος δικτυακά κοινοποιημένος + + + + + Android mobile device + Φορητή συσκευή Android + + + + + Apple mobile device + Φορητή συσκευή Apple + + + + + Camera + Κάμερα + + + + + DVD + DVD + + + + + Unknown device + Άγνωστη συσκευή + + + + + + %1 item + %1 αντικείμενο + + + + + + %1 items + %1 αντικείμενα + + + + Shortcut + Συντόμευση + + + + Create symlink + Δημιουργία συμβολικού συνδέσμου + + + + Path + Μονοπάτι + + + + + + Time deleted + Ο χρόνος διαγράφηκε + + + + Loading... + Φόρτωση... + + + + File has been moved or deleted + Το αρχείο έχει μετακινηθεί ή διεγράφη + + + + + + You do not have permission to access this folder + Δεν έχετε άδεια πρόσβασης σε αυτό το φάκελλο + + + + + + + Folder is empty + Ο φάκελλος είναι άδειος + + + + Path + SearchFileInfo + Μονοπάτι + + + + Searching... + Αναζήτηση + + + + No results + Κανένα αποτέλεσμα + + + + Source Path + TrashFileInfo + Μονοπάτι πηγής + + + + Document + Έγγραφο + + + + Spreadsheet + Υπολογιστικά φύλλα + + + + + Presentation + Παρουσίαση + + + + Text + Κείμενο + + + + 1 task in progress + 1 εργασίας σε εξέλιξη + + + + %1 tasks in progress + %1 εργασίες σε εξέλιξη + + + + Mode: + Λειτουργία: + + + + + Replace Text + Αντικατάσταση κειμένου + + + + + Add Text + Προσθήκη Κειμένου + + + + + Custom Text + Προσαρμοσμένο κείμενο + + + + Find: + Εύρεση: + + + + Replace: + Αντικατάσταση: + + + + + Optional + Προαιρετικό + + + + Add: + Προσθήκη: + + + + Location: + Τοποθεσία: + + + + File name: + Όνομα αρχείου: + + + + +SN: + +SN: + + + + + + + + + + Required + Απαραίτητο + + + + + Before file name + Πριν από το όνομα αρχείου + + + + + After file name + Μετά το όνομα αρχείου + + + + Find + Εύρεση + + + + Replace + Αντικατάσταση + + + + Add + Προσθήκη + + + + + + Location + Τοποθεσία + + + + File name + Όνομα αρχείου + + + + Dimension + + + + + Duration + + + + + +SN + +SN + + + + Tips: Sort by selected file order + Συμβουλές: Ταξινόμηση κατά επιλεγμένη σειρά αρχείων + + + + + + Cancel + Άκυρο + + + + Rename %1 Files + Μετονομασία %1 Αρχεία + + + + Multiple Files + Πολλαπλά Αρχεία + + + + Basic info + Βασικές πληροφορίες + + + + Total size + Συνολικό μέγεθος + + + + Number of files + Αριθμός αρχείων + + + + %1 file(s), %2 folder(s) + %1 αρχείο(α), %2 αρχείο(α) + + + + + + Time accessed + + + + + Orange + Πορτοκαλί + + + + Red + Κόκκινο + + + + Purple + Μωβ + + + + Navy-blue + Navy-blue + + + + Azure + Azure + + + + Green + Πράσινο + + + + Yellow + Κίτρινο + + + + Gray + Γκρι + + + + Input tag info, such as work, family. A comma is used between two tags. + Εισαγωγή πληροφοριών ετικέτας, όπως δουλειά, οικογένεια. Ένα κόμμα χρησιμοποιείται ανάμεσα σε δύο ετικέτες. + + + + Bookmarks + Σελιδοδείκτες + + + + Erase + + + + + + Copy path + Αντιγραφή μονοπατιού + + + + + Edit address + Επεξεργασία διεύθυνσης + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + Κοινοποιήση αυτού φακέλου + + + + Share name: + Κοινοποίηση ονόματος: + + + + Permission: + Άδεια: + + + + Read and write + Ανάγνωση και εγγραφή + + + + Read only + Μόνο για ανάγνωση + + + + Anonymous: + Ανώνυμο: + + + + Not allow + Μη αποδεκτό + + + + Allow + Αποδοχή + + + + Shortcut + + + Item + Αντικείμενο + + + + Select to the first item + Επιλογή ως το πρώτο αντικείμενο + + + + Shift + Home + Shift + Home + + + + Select to the last item + Επιλογή ως το τελευταίο αντικείμενο + + + + Shift + End + Shift + End + + + + Select leftwards + Επιλογή προς αριστερά + + + + Shift + Left + Shift + Left + + + + Select rightwards + Επιλογή προς δεξιά + + + + Shift + Right + Shift + Right + + + + Select to upper row + Επιλογή ανώτερη σειράς + + + + Shift + Up + Shift + Up + + + + Select to lower row + Επιλογή χαμηλότερης σειράς + + + + Shift + Down + Shift + Down + + + + Open + Άνοιγμα + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + Στο γονικό φάκελο + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Οριστική διαγραφή + + + + Shift + Delete + Shift + Delete + + + + Delete file + Διαγραφή αρχείου + + + + Delete + Διαγραφή + + + + Select all + Επιλογή όλων + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + Αντιγραφή + + + + Cut + Αποκοπή + + + + Paste + Επικόλληση + + + + Rename + Μετονομασία + + + + F2 + F2 + + + + New/Search + Νέο/Αναζήτηση + + + + New window + Νέο παράθυρο + + + + New folder + Νέος φάκελος + + + + + Search + Εύρεση + + + + New tab + Νέα καρτέλα + + + + View + Προβολή + + + + Item information + Πληροφορίες αντικειμένου + + + + Help + Βοήθεια + + + + F1 + F1 + + + + Keyboard shortcuts + Συντομεύσεις πληκτρολογίου + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Εναλλαγή κατάστασης προβολής + + + + Hide item + Απόκρυψη αντικειμένου + + + + Input in address bar + Εισαγωγή στην μπάρα διευθύνσεων + + + + Switch to icon view + Εναλλαγή σε προβολή εικονιδίων + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Εναλλαγή σε προβολή λίστας + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Άλλα + + + + Close + Κλείσιμο + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Κλείσιμο τρέχουσας καρτέλας + + + + Back + Πίσω + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Αλλαγή στην επόμενη καρτέλα + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Αλλαγή στην προηγούμενη καρτέλα + + + + Next file + Επόμενο αρχείο + + + + Tab + Tab + + + + Previous file + Προηγούμενο αρχείο + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Αλλάξτε την καρτέλα με τον καθορισμένο αριθμό μεταξύ 1 και 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Εμπρός + + + + TrashPropertyDialog + + + Trash + Κάδος + + + + item + αντικείμενο + + + + items + αντικείμενα + + + + Contains %1 %2 + Περιέχει:%1 %2 + + + + UDiskListener + + + Failed to rename the label + Αποτυχία μετονομασίας της ετικέτας + + + + UserShareManager + + + Kindly Reminder + Ευγενική Υπενθύμιση + + + + Please firstly install samba to continue + Αρχικά, εγκαταστήστε το samba για να συνεχίσετε + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + Άκυρο + + + + Confirm + Επαλήθευση + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_eo.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_eo.ts new file mode 100644 index 0000000..1293295 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_eo.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + Fermui ĉiuj + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + + + + + Basic Info + + + + + Computer Name + + + + + Version + + + + + Type + + + + + Processor + + + + + Memory + + + + + Disk + Disko + + + + Bit + + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + + + + + DFMAdvanceSearchBar + + + Search: + + + + + File Type: + + + + + File Size: + + + + + Time Modified: + + + + + Reset + + + + + All subdirectories + + + + + Current directory + + + + + 0 ~ 100 KB + + + + + 100 KB ~ 1 MB + + + + + 1 MB ~ 10 MB + + + + + 10 MB ~ 100 MB + + + + + 100 MB ~ 1 GB + + + + + > 1 GB + + + + + Today + + + + + Yesterday + + + + + This week + + + + + Last week + + + + + This month + + + + + Last month + + + + + This year + + + + + Last year + + + + + DFMTagCrumbController + + + Tag information + + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + + + + + The action is denied + + + + + Failed to open the file + + + + + Failed to read the file + + + + + Failed to write the file + + + + + Failed to create the directory + + + + + Failed to delete the file + + + + + Failed to move the file + + + + + Original file does not exist + + + + + Failed, file size must be less than 4GB + + + + + Not enough free space on the target disk + + + + + File integrity was damaged + + + + + The target device is read only + + + + + Target folder is inside the source folder + + + + + copy + Extra name added to new file name when used for file name. + + + + + Failed to create the directory, cause: %1 + + + + + + Failed to open the file, cause: %1 + + + + + Failed to read the file, cause: %1 + + + + + Failed to write the file, cause: %1 + + + + + File integrity was damaged, cause: %1 + + + + + Failed to delete the file, cause: %1 + + + + + Fail to create symlink, cause: %1 + + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + + + + + Cancel + Nuligi + + + + Replace + + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + Nomo + + + + + + Time modified + + + + + Size + + + + + Type + + + + + Time created + + + + + + Last access + + + + + Path + + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + + + + + DFileViewHelper + + + Add tag "%1" + + + + + DStatusBar + + + %1 item + + + + + %1 items + + + + + %1 item selected + + + + + %1 items selected + + + + + %1 folder selected (contains %2) + + + + + %1 folders selected (contains %2) + + + + + %1 file selected (%2) + + + + + %1 files selected (%2) + + + + + %1 folder selected + + + + + Filter + + + + + Save as: + + + + + Loading... + + + + + DTaskDialog + + + This action is not supported + + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + + + + + Data Disk + Data Partition + + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + + + + + Target folder is inside the source folder! + + + + + + + + + + + + + + OK + + + + + Do you want to run %1 or display its content? + + + + + It is an executable text file. + + + + + + + + + + + + + + + Cancel + Nuligi + + + + + + Run + + + + + + Run in terminal + + + + + Display + + + + + It is an executable file. + + + + + This file is not executable, do you want to add the execute permission and run? + + + + + "%1" already exists, please use another name. + + + + + + + + + Confirm + + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + + + + + Permanently delete %1 items? + + + + + Delete + Forigi + + + + Empty + Malpleni + + + + Sorry, unable to locate your bookmark directory, remove it? + + + + + Remove + + + + + Name: + + + + + Force unmount + + + + + %1 that this shortcut refers to has been changed or moved + + + + + Do you want to delete this shortcut? + + + + + Failed, file size must be less than 4GB. + + + + + Fail to create symlink, cause: + + + + + The selected files contain system file/directory, and it cannot be deleted + + + + + + You do not have permission to operate file/folder! + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + + + + + View + + + + + Do you want to run %1? + + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + + + + + Please restore by the following steps to normally access Windows disk + + + + + 1. Reboot to enter Windows + + + + 3. Reboot and enter deepin + + + + + Reboot + + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + + + + + Format + + + + + Cancel + Nuligi + + + + Save + + + + + Open + + + + + Save File + + + + + Open File + + + + + FileJob + + + copy + + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + + + + + %1 m %2 s + + + + + %1 h %2 m %3 s + + + + + %1 d %2 h %3 m %4 s + + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + + + + + + + Open behavior + + + + + + + Always open folder in new window + + + + + + + Open file: + + + + + + + Click + + + + + + + Double click + + + + + + + New window and tab + + + + + + + Open from default window: + + + + + + + + + + Computer + + + + + + + + + + Home + Domo + + + + + + + + + Desktop + + + + + + + + + + Videos + + + + + + + + + + Music + + + + + + + + + + Pictures + + + + + + + + + + Documents + + + + + + + + + + Downloads + + + + + + + Open in new tab: + + + + + + + Current Directory + + + + + + + View + + + + + + + Default size: + + + + + + + Extra small + + + + + + + Small + + + + + + + Medium + + + + + + + Large + + + + + + + Extra large + + + + + + + Default view: + + + + + + + Icon + + + + + + + List + + + + + + + Hidden files + + + + + + + Show hidden files + + + + + + + Hide file extension when rename + + + + + + + Advanced + + + + + + + Index + + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + + + + + + + Hide system disk + + + + + + + Show hidden files in search results + + + + + + + Display recent file entry in left panel + + + + + + + Preview + + + + + + Compress file preview + + + + + + + Text preview + + + + + + + Document preview + + + + + + + Image preview + + + + + + + Video preview + + + + + + + Mount + + + + + + + Auto mount + + + + + + + Open after auto mount + + + + + + + Dialog + + + + Use the file chooser dialog of Deepin File Manager + + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + + + + + + + + + Confirm + + + + + + Cannot find the mounting device + + + + + Cannot unmount the device + + + + + Cannot eject the device "%1" + + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + + + + + + + Application + + + + + + + Video + + + + + + + Audio + + + + + + + Image + + + + + + Archive + + + + + + + Text + + + + + + Executable + + + + + + Backup file + + + + + + Unknown + + + + + MountAskPasswordDialog + + + Cancel + Nuligi + + + + Connect + + + + + Log in as + + + + + Anonymous + + + + + Registered user + + + + + Username + + + + + Domain + + + + + Password + + + + + Remember password + + + + + MountSecretDiskAskPasswordDialog + + + Cancel + Nuligi + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + + + + Keep both + + + + Replace + + + + Do not ask again + + + + merge + + + + Copying %1 + + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + + + + Moving %1 + + + + Move to %2 + + + + Restoring %1 + + + + Restore to %2 + + + + Deleting %1 + + + + Trashing %1 + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + Retry + + + + Time modified:%1 + + + + Original folder + + + + Original file + + + + Target folder + + + + Target file + + + + Contains:%1 + + + + Size:%1 + + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + Nuligi + + + + Delete + Forigi + + + + OpenWithDialog + + + Open with + + + + + Add other programs + + + + + Set as default + + + + + Cancel + Nuligi + + + + Confirm + + + + + Recommended Applications + + + + + Other Applications + + + + + PathManager + + + Home + Domo + + + + Desktop + + + + + Videos + + + + + Music + + + + + Pictures + + + + + Documents + + + + + Downloads + + + + + + Trash + Korbeto + + + + + System Disk + + + + + Computers in LAN + + + + + My Shares + + + + + Computer + + + + + Recent + + + + + PropertyDialog + + + Basic info + + + + + Open with + + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + + + + + QObject + + + + + Size + + + + + + + Contains + + + + + + + Type + + + + + + + + Time modified + + + + + Free space + + + + + Total space + + + + + Access denied + + + + + + Executable + + + + + + Write only + + + + + + Read only + + + + + + Read-write + + + + + Others + + + + + Owner + + + + + Device type + + + + + File system + + + + + Group + + + + + + + Open + + + + + + Size: %1 + + + + + Type: %1 + + + + + Size: 0 + + + + + Items: %1 + + + + + + + + + + + + Open in new window + + + + + + + + + + + + Open in new tab + + + + + Open with + + + + + Compress + + + + + Extract + + + + + Extract here + + + + + Cut + + + + + Copy + + + + + Paste + + + + + + + + + + + Rename + + + + + + + Remove + + + + + Create link + + + + + Send to desktop + + + + + Send to + + + + + Add to bookmark + + + + + + + + Properties + + + + + New folder + + + + + New window + + + + + Select all + + + + + + Clear recent history + + + + + + + Empty Trash + + + + + Display as + + + + + Sort by + + + + + New document + + + + + + Time created + + + + + Log out and unmount + + + + + + + Source path + + + + + Share folder + + + + + Cancel sharing + + + + + Connect to Server + + + + + Set share password + + + + + Format + + + + + Tag information + + + + + Open in new window as admin + + + + + Select default program + + + + + Open file location + + + + + Remove bookmark + + + + + + + Delete + Forigi + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + + + + + Restore + + + + + Restore all + + + + + File Vault + + + + + Auto mount + + + + + Open after auto mount + + + + + + Mount + + + + + + Unmount + + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + + + + + Safely Remove + + + + + + Name + Nomo + + + + Settings + + + + + Exit + + + + + Icon + + + + + List + + + + + Extend + + + + + Set as wallpaper + + + + + + + + Local disk + + + + + + Removable disk + + + + + + + Network shared directory + + + + + + Android mobile device + + + + + + Apple mobile device + + + + + + Camera + + + + + + DVD + + + + + + Unknown device + + + + + + + %1 item + + + + + + + %1 items + + + + + Shortcut + + + + + Create symlink + + + + + Path + + + + + + + Time deleted + + + + + Loading... + + + + + File has been moved or deleted + + + + + + + You do not have permission to access this folder + + + + + + + + Folder is empty + + + + + Path + SearchFileInfo + + + + + Searching... + + + + + No results + + + + + Source Path + TrashFileInfo + + + + + Document + + + + + Spreadsheet + + + + + + Presentation + + + + + Text + + + + + 1 task in progress + + + + + %1 tasks in progress + + + + + Mode: + + + + + + Replace Text + + + + + + Add Text + + + + + + Custom Text + + + + + Find: + + + + + Replace: + + + + + + Optional + + + + + Add: + + + + + Location: + + + + + File name: + + + + + +SN: + + + + + + + + + + + Required + + + + + + Before file name + + + + + + After file name + + + + + Find + + + + + Replace + + + + + Add + + + + + + + Location + + + + + File name + + + + + Dimension + + + + + Duration + + + + + +SN + + + + + Tips: Sort by selected file order + + + + + + + Cancel + Nuligi + + + + Rename %1 Files + + + + + Multiple Files + + + + + Basic info + + + + + Total size + + + + + Number of files + + + + + %1 file(s), %2 folder(s) + + + + + + + Time accessed + + + + + Orange + + + + + Red + + + + + Purple + + + + + Navy-blue + + + + + Azure + + + + + Green + + + + + Yellow + + + + + Gray + + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + + + + + Erase + + + + + + Copy path + + + + + + Edit address + + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + + + + + Share name: + + + + + Permission: + + + + + Read and write + + + + + Read only + + + + + Anonymous: + + + + + Not allow + + + + + Allow + + + + + Shortcut + + + Item + + + + + Select to the first item + + + + + Shift + Home + + + + + Select to the last item + + + + + Shift + End + + + + + Select leftwards + + + + + Shift + Left + + + + + Select rightwards + + + + + Shift + Right + + + + + Select to upper row + + + + + Shift + Up + + + + + Select to lower row + + + + + Shift + Down + + + + + Open + + + + + Ctrl + Down + + + + + To parent directory + + + + + Ctrl + Up + + + + + Permanently delete + + + + + Shift + Delete + + + + + Delete file + + + + + Delete + Forigi + + + + Select all + + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + + + + + Cut + + + + + Paste + + + + + Rename + + + + + F2 + + + + + New/Search + + + + + New window + + + + + New folder + + + + + + Search + + + + + New tab + + + + + View + + + + + Item information + + + + + Help + + + + + F1 + + + + + Keyboard shortcuts + + + + + Ctrl + Shift + / + + + + + Switch display status + + + + + Hide item + + + + + Input in address bar + + + + + Switch to icon view + + + + + Ctrl + 1 + + + + + Switch to list view + + + + + Ctrl + 2 + + + + + Others + + + + + Close + + + + + Alt + F4 + + + + + Close current tab + + + + + Back + + + + + Alt + Left + + + + + Alt + Right + + + + + Switch to next tab + + + + + Ctrl + Tab + + + + + Ctrl + Shift + Tab + + + + + Switch to previous tab + + + + + Next file + + + + + Tab + + + + + Previous file + + + + + Shift + Tab + + + + + Switch tab by specified number between 1 to 8 + + + + + Alt + [1-8] + + + + + Forward + + + + + TrashPropertyDialog + + + Trash + Korbeto + + + + item + + + + + items + + + + + Contains %1 %2 + + + + + UDiskListener + + + Failed to rename the label + + + + + UserShareManager + + + Kindly Reminder + + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + Nuligi + + + + Confirm + + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_es.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_es.ts new file mode 100644 index 0000000..77d1bab --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_es.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Nueva carpeta + + + + Mounting device error + Error al montar el dispositivo + + + + The disc image was corrupted, cannot mount now, please erase the disc first + La imagen del disco estaba dañada, no se puede montar ahora, por favor, borre el disco primero. + + + + Mount error: unsupported image format + Error de montaje: formato de imagen incompatible + + + + + The device was not safely removed + El dispositivo no fue retirado de forma segura + + + + + Click "Safely Remove" and then disconnect it next time + Clic en «Extraer del equipo» y luego desconéctelo + + + + The device was not ejected + El dispositivo no fue expulsado + + + + Disk is busy, cannot eject now + El disco está en uso, no se puede expulsar ahora + + + + Authentication timed out + El tiempo para autenticarse agotado + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Transferencia de archivos por Bluetooth + + + + File Transfer Successful + Transferencia de archivos exitosa + + + + File Transfer Failed + La transferencia de archivos falló + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Enviando archivos a «<b style="font-weight: 550;">%1</b>» + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + El envío de archivos a «<b style="font-weight: 550;">%1</b>» falló + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Enviado a «<b style="font-weight: 550;">%1</b>» con éxito + + + + Select a Bluetooth device to receive files + Seleccione un dispositivo Bluetooth para recibir archivos + + + + Cannot find the connected Bluetooth device + No se encontró ningún dispositivo Bluetooth conectado + + + + Waiting to be received... + Esperando recepción de datos... + + + + Go to Bluetooth Settings + Ir a ajustes de Bluetooth + + + + %1/%2 Sent + %1/%2 enviados + + + + Error: the Bluetooth device is disconnected + Error: el dispositivo Bluetooth está desconectado + + + + Unable to send the file more than 2 GB + No se puede enviar archivos de más de 2 GB + + + + Unable to send 0 KB files + No se pueden enviar archivos de 0 KB + + + + File doesn't exist + El archivo no existe + + + + Next + button + Siguiente + + + + Cancel + button + Cancelar + + + + Done + button + Finalizar + + + + Retry + button + Reintentar + + + + OK + button + Aceptar + + + + File sending request timed out + Se agotó el tiempo de espera de la solicitud de envío de archivos + + + + The service is busy and unable to process the request + El servicio está ocupado y no puede procesar la solicitud. + + + + BurnOptDialog + + + Device error + Error del dispositivo + + + + Optical device %1 doesn't exist + El dispositivo óptico % 1 no existe + + + + Advanced settings + Ajustes avanzados + + + + File system: + Sistema de archivos + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Para Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Para Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Compatible con el modo CD/DVD de Windows) + + + + ISO9660 Only + Solo ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Cerrar todo + + + + Total size: %1, %2 files + Tamaño total: %1, %2 archivos + + + + ComputerModel + + + Double click to open it + Haga doble clic para abrirlo + + + + My Directories + Mis carpetas + + + + Disks + Discos + + + + File Vault + Bóveda de archivos + + + + Quick Access + Acceso rápido + + + + ComputerPropertyDialog + + + Computer + Equipo + + + + Basic Info + Información básica + + + + + Computer Name + Nombre del equipo + + + + + Edition + Edición + + + + + + Version + Versión + + + + + Type + Tipo + + + + + + Processor + Procesador + + + + + + Memory + Memoria + + + + + + + Bit + bits + + + + + Available + Disponible + + + + Obtaining... + Obtener... + + + + ConnectToServerDialog + + + Connect to Server + Conectarse al servidor + + + + Cancel + button + Cancelar + + + + Connect + button + Conectar + + + + My Favorites: + Mis favoritos: + + + + + Clear History + Borrar historial + + + + DFMAddressBar + + + Search or enter address + Buscar o introducir dirección + + + + DFMAdvanceSearchBar + + + Search: + Buscar + + + + File Type: + Tipo de archivo: + + + + File Size: + Tamaño del archivo: + + + + Time Modified: + Fecha de modificación: + + + + Time Accessed: + Fecha de acceso: + + + + Time Created: + Fecha de creación: + + + + Reset + Reiniciar + + + + All subdirectories + Subcarpetas + + + + Current directory + Carpeta actual + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Hoy + + + + Yesterday + Ayer + + + + This week + Esta semana + + + + Last week + La semana pasada + + + + This month + Este mes + + + + Last month + El mes pasado + + + + This year + Este año + + + + Last year + El año pasado + + + + DFMOpticalMediaWidget + + + + No files to burn + No hay archivos para grabar + + + + Unable to burn. Not enough free space on the target disk. + No se puede grabar. No hay suficiente espacio libre en el disco de destino. + + + + %1 burning is not supported + %1 No se admite la grabación + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. No es el disco %1; +2. La versión de este sistema de archivos aún no admite la adición de archivos. + + + + DFMTagCrumbController + + + Tag information + Etiqueta informativa + + + + DFMTagWidget + + + Tag + Etiqueta + + + + DFMTaskWidget + + + Do not ask again + No volver a preguntar + + + + Syncing data + Sincronizando datos + + + + Please wait + Espere por favor + + + + + Time modified: %1 + Fecha de modificación: %1 + + + + + Contains: %1 + Contiene: %1 + + + + + Size: %1 + Tamaño: %1 + + + + Original folder + Carpeta original + + + + Keep both + button + Mantener ambos + + + + Skip + button + Omitir + + + + Replace + button + Reemplazar + + + + Retry + button + Reintentar + + + + Original file + Archivo original + + + + Target folder + Carpeta de destino + + + + Target file + Archivo de destino + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Cifrar la bóveda de archivos + + + + Click 'Encrypt' and input the user password. + Haz clic en "Cifrar" e introduce la contraseña de usuario. + + + + Encrypting... + Cifrando... + + + + + + + Encrypt + Cifrar + + + + Failed to create file vault: %1 + Error al crear la bóveda de archivos: %1 + + + + OK + Aceptar + + + + The setup is complete + La configuración está completa + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Guardar clave de recuperación + + + + Keep the key safe to retrieve the vault password later + Guarde la clave para recuperar la contraseña de la bóveda + + + + Save to default path + Guardar en la ruta por defecto + + + + Save to other locations + Guardar en otra ubicación + + + + No permission, please reselect + No hay permiso, por favor, vuelva a seleccionar + + + + Select a path + Seleccione una ruta + + + + Next + Siguiente + + + + The default path is invisible to other users, and the path information will not be shown. + La ruta predeterminada y la información de ésta, no son visibles para otros usuarios. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Clave de recuperación + + + + Generate a recovery key in case that you forgot the password + Genere una clave de recuperación en caso de que olvide la contraseña + + + + Key + Clave + + + + QR code + Código QR + + + + Scan QR code and save the key to another device + Escanee el código QR y guarde la clave en otro dispositivo + + + + Next + Siguiente + + + + Recovery Key: + Clave de recuperación: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Establecer la contraseña de la bóveda + + + + Method + Método + + + + Manual + Manual + + + + Password + Contraseña + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + 8 o más caracteres, contener A-Z, a-z, 0-9, y símbolos + + + + Repeat password + Repetir contraseña + + + + Input the password again + Introduzca de nuevo la contraseña + + + + Password hint + Indicio de contraseña + + + + Optional + Opcional + + + + Next + Siguiente + + + + + Passwords do not match + Las contraseñas no coinciden + + + + DFMVaultActiveStartView + + + File Vault + Bóveda de archivos + + + + Create your secure private space + Crear su espacio privado y seguro + + + + Advanced encryption technology + Tecnología de cifrado avanzado + + + + Convenient and easy to use + Cómodo y fácil de usar + + + + Create + Crear + + + + DFMVaultFileView + + + Cannot open this path + No se puede abrir esta carpeta + + + + Hint + Sugerencia + + + + OK + Aceptar + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Desbloquear con clave + + + + Failed to unlock file vault + Error al desbloquear la bóveda de archivos + + + + OK + Aceptar + + + + Input the 32-digit recovery key + Introduzca la clave de recuperación de 32 dígitos + + + + Cancel + button + Cancelar + + + + Unlock + button + Desbloquear + + + + Wrong recovery key + Clave de recuperación equivocada + + + + DFMVaultRemoveByPasswordView + + + Password + Contraseña + + + + Password hint: %1 + Indicio de contraseña: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Introduzca la clave de recuperación de 32 dígitos + + + + DFMVaultRemovePages + + + Delete File Vault + Borrar bóveda de archivos + + + + Once deleted, the files in it will be permanently deleted + Una vez borrados, estos archivos no pueden ser recuperados + + + + Use Key + Usar clave + + + + Cancel + button + Cancelar + + + + Use Key + button + Usar clave + + + + Delete + button + Borrar + + + + + OK + button + Aceptar + + + + Use Password + Usar contraseña + + + + Wrong password + Contraseña incorrecta + + + + Wrong recovery key + Clave de recuperación incorrecta + + + + Failed to delete file vault + Error al borrar la bóveda de archivos + + + + Deleted successfully + Borrado correctamente + + + + Failed to delete + Error al borrar + + + + Removing... + Quitando... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + No se puede obtener el archivo de claves + + + + Verification failed + La verificación falló + + + + + Select a path + Seleccione una ruta + + + + + Retrieve Password + Recuperar la contraseña + + + + By key in the default path + Por clave en la ruta por defecto + + + + By key in the specified path + Por clave en la ruta especificada + + + + Verification Successful + Verificación exitosa + + + + Keep it safe + Guardelo bien + + + + Back + button + Volver + + + + Verify Key + button + Verificar clave + + + + Go to Unlock + button + Ir a desbloquear + + + + Close + button + Cerrar + + + + Vault password: %1 + Contraseña de bóveda: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Desbloquear la bóveda de archivos + + + + Forgot password? + ¿Olvidó la contraseña? + + + + Password hint: %1 + Indicio de contraseña: %1 + + + + Failed to unlock file vault + Error al desbloquear la bóveda de archivos + + + + Cancel + button + Cancelar + + + + Password + Contraseña + + + + Unlock + button + Desbloquear + + + + Please try again %1 minutes later + Inténtelo de nuevo en %1 minutos + + + + Wrong password, please try again %1 minutes later + Contraseña incorrecta, inténtelo de nuevo en %1 minutos + + + + Wrong password, one chance left + Contraseña incorrecta, último intento + + + + Wrong password, %1 chances left + Contraseña incorrecta, quedan %1 intentos + + + + Wrong password + Contraseña incorrecta + + + + OK + button + Aceptar + + + + DFileCopyMoveJob + + + Permission error + Error de permisos + + + + The action is denied + Acción no autorizada + + + + Failed to open the file + Error al abrir el archivo + + + + Failed to read the file + Error al leer el archivo + + + + Failed to write the file + Error al escribir el archivo + + + + Failed to create the directory + Error al crear la carpeta + + + + Failed to delete the file + Error al borrar el archivo + + + + Failed to move the file + Error al mover el archivo + + + + Original file does not exist + El archivo original no existe + + + + Failed, file size must be less than 4GB + Error, el tamaño del archivo no debe superar los 4GB. + + + + Not enough free space on the target disk + No hay suficiente espacio libre en el disco de destino + + + + File integrity was damaged + La integridad del archivo esta dañada + + + + The target device is read only + El dispositivo de destino es de solo lectura + + + + Target folder is inside the source folder + La carpeta de destino está dentro de la carpeta de seguridad + + + + The action is not supported + Esta acción no está permitida + + + + You do not have permission to traverse files in it + No tiene permiso para recorrer los archivos en él + + + + Failed to position the file pointer! + ¡Fallo al posicionar el puntero del archivo! + + + + copy + Extra name added to new file name when used for file name. + copiar + + + + Failed to open the directory, cause: file name too long + Error al abrir la carpeta, el nombre del archivo es muy largo + + + + + Failed to open the file, cause: file name too long + Errrt al abrir el archivo, el nombre del archivo es muy largo + + + + + Failed to write the file, cause: + Error al escribir el archivo, motivo: %1 + + + + Failed to position the file pointer, cause: %1 + Fallo al posicionar el puntero del archivo, causa: %1 + + + + Syncing data + Sincronizando datos + + + + Please wait + Espere por favor + + + + Failed to create the directory, cause: %1 + Error al crear la carpeta, causa: %1 + + + + + + + + Failed to open the file, cause: %1 + Error al abrir el archivo, causa: %1 + + + + + + + Failed to open the file, cause: Permission denied + Error al abrir el archivo, acceso denegado + + + + + Failed to read the file, cause: %1 + Error al leer el archivo, causa: %1 + + + + + + + Failed to write the file, cause: %1 + Error al escribir el archivo, motivo: %1 + + + + + File integrity was damaged, cause: %1 + La integridad del archivo esta dañada, causa: %1 + + + + Failed to open the file, cause: + Falló al abrir el archivo, motivo: + + + + Failed to read the file, cause: + Falló al cargar el archivo, motivo: + + + + Failed to delete the file, cause: %1 + Error al borrar el archivo, causa: %1 + + + + Fail to create symlink, cause: %1 + Error al crear enlace simbólico, causa: %1 + + + + DFileDialog + + + + Save + button + Guardar + + + + + Cancel + button + Cancelar + + + + Confirm + button + Confirmar + + + + %1 already exists, do you want to replace it? + %1 ya existe, ¿quiere reemplazar? + + + + Replace + button + Reemplazar + + + + Open + button + Abrir + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Este archivo será ocultado si el nombre del archivo comienza con un punto (.). ¿Quiere ocultarlo? + + + + DFileManagerWindow + + + Trash + Papelera + + + + Empty + Vaciar + + + + DFileSystemModel + + + + Name + Nombre + + + + + + Time modified + Fecha de modificación + + + + Size + Tamaño + + + + Type + Tipo + + + + Time created + Fecha de creación + + + + + Last access + Ultimo acceso + + + + + + + Path + Ruta + + + + DFileView + + + Disc mount error + Error al montar el disco + + + + The disc is in use, please end the running process and remount the disc. + El disco está en uso, finalice el proceso en ejecución y vuelva a montar el disco. + + + + Mounting failed + Error al montar + + + + (Reverse) + (Invertido) + + + + DFileViewHelper + + + Add tag "%1" + Añadir etiqueta «%1» + + + + DStatusBar + + + %1 item + %1 elemento + + + + %1 items + %1 elementos + + + + %1 item selected + %1 elemento seleccionado + + + + %1 items selected + %1 elementos seleccionados + + + + %1 folder selected (contains %2) + %1 carpeta seleccionada (contiene %2) + + + + %1 folders selected (contains %2) + %1 carpetas seleccionadas (contienen %2) + + + + %1 file selected (%2) + %1 archivo seleccionado (%2) + + + + %1 files selected (%2) + %1 archivos seleccionados (%2) + + + + %1 folder selected + %1 carpeta seleccionada + + + + Filter + Filtrar + + + + Save as: + Guardar como: + + + + Loading... + Cargando... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Borrando el disco %1, por favor espere... + + + + Burning disc %1, please wait... + Quemando disco %1, por favor espere... + + + + Writing data... + Escribiendo datos... + + + + Verifying data... + Verificando datos... + + + + Copying %1 + Copiando %1 + + + + + + to %2 + a %2 + + + + %1 already exists in target folder + %1 ya existe en la carpeta de destino + + + + Original path %1 Target path %2 + Ruta de origen %1 Ruta de destino %2 + + + + Merge + button + Mezclar + + + + Replace + button + Reemplazar + + + + Moving %1 + Moviendo %1 + + + + Removing file vault, please try later + Borrando bóveda de archivos, por favor inténtelo más tarde + + + + Restoring %1 + Restaurando %1 + + + + Deleting %1 + Borrando %1 + + + + Trashing %1 + Moviendo a papelera %1 + + + + Calculating space, please wait + Calculando espacio, espere por favor + + + + DUMountManager + + + + Authentication timed out + El tiempo para autenticarse agotado + + + + + + Disk is busy, cannot unmount now + El disco está en uso, no se puede desmontar ahora + + + + Disk is busy, cannot eject now + El disco está en uso, no se puede expulsar ahora + + + + The device is busy, cannot eject now + El disco está ocupado, no se puede expulsar ahora + + + + + + The device is busy, cannot remove now + El dispositivo está ocupado, no se puede quitar ahora + + + + DeepinStorage + + + + + %1 Volume + Volumen %1 + + + + Data Disk + Data Partition + Disco de datos + + + + %1 Drive + %1 unidad + + + + Blank %1 Disc + Disco %1 en blanco + + + + %1 Encrypted + %1 Cifrar + + + + DialogManager + + + + + + Operation failed! + ¡La operación falló! + + + + Target folder is inside the source folder! + ¡La carpeta de destino está dentro de la carpeta de origen! + + + + Do you want to run %1 or display its content? + ¿Desea ejecutar %1 o mostrar su contenido? + + + + It is an executable text file. + Es un archivo de texto ejecutable. + + + + It is an executable file. + Es un archivo ejecutable. + + + + This file is not executable, do you want to add the execute permission and run? + Este archivo no es ejecutable, ¿desea añadir el permiso de ejecución y ejecutar? + + + + "%1" already exists, please use another name. + «%1» ya existe, por favor use otro nombre. + + + + The file name must not contain two dots (..) + El nombre de archivo no puede contener dos puntos (..) + + + + Device or resource busy + Dispositivo o recurso ocupado + + + + Are you sure you want to erase all data on the disc? + ¿Está seguro de que desea borrar todos los datos del disco? + + + + How do you want to use this disc? + ¿Cómo quiere usar este disco? + + + + Disc erase failed + Falló el borrado del disco + + + + Burn process failed + El proceso de grabación falló + + + + %1: %2 + %1: %2 + + + + Show details + Mostrar detalles + + + + Hide details + Ocultar detalles + + + + Error + Error + + + + Permanently delete %1? + ¿Borrar permanentemente %1? + + + + Permanently delete %1 items? + ¿Borrar permanentemente %1 elementos? + + + + Empty + Vaciar + + + + Do you want to delete %1? + ¿Desea borrar %1? + + + + Do you want to delete the selected %1 items? + ¿Desea borrar los %1 elementos seleccionados? + + + + Sorry, unable to locate your bookmark directory, remove it? + No se pudo encontrar la carpeta, ¿desea quitar el marcador? + + + + Name: + Nombre: + + + + %1 that this shortcut refers to has been changed or moved + Este enlace hace referencia a «%1» pero no se pudo encontrar + + + + Do you want to delete this shortcut? + ¿Quiere borrar este enlace? + + + + Failed, file size must be less than 4GB. + Error, el tamaño del archivo no debe superar los 4GB. + + + + Fail to create symlink, cause: + Fallo al crear enlace simbólico, causa: + + + + The selected files contain system file/directory, and it cannot be deleted + Los archivos seleccionados contienen archivos/carpetas del sistema, y no pueden ser borrados + + + + Unable to find the original file + No se puede encontrar el archivo original + + + + + You do not have permission to operate file/folder! + ¡No tienes permiso para operar el archivo/carpeta! + + + + Failed to restore %1 file, the source file does not exist + La restauración de %1 archivo falló, el archivo de origen no existen + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + ¡Lo sentimos, no tienes permiso para continuar operando %1 archivo/carpeta(s)! + + + + Unable to access %1 + No se pude acceder a %1 + + + + + Sending files now, please try later + Enviando archivos, por favor inténtelo más tarde + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Para acceder al dispositivo, primero debe formatear el disco. ¿Está seguro de que quiere formatearlo ahora? + + + + Scanning the device, stop it? + Disco bajo escaneo, ¿desea detenerlo? + + + + Share folder can't be named after the current username + La carpeta compartida no puede nombrarse después del nombre de usuario actual + + + + Do you want to run %1? + ¿Desea ejecutar %1? + + + + Burn image + button + Grabar una imagen + + + + Burn files + button + Grabar archivos + + + + Are you sure you want to empty %1 item? + ¿Seguro desea vaciar %1 elemento de la papelera? + + + + Are you sure you want to empty %1 items? + ¿Seguro desea vaciar %1 elementos de la papelera? + + + + + This action cannot be undone + Esta acción no se puede deshacer + + + + + + + + + + + + + + OK + button + Aceptar + + + + + + + + + + + + + + + Cancel + button + Cancelar + + + + + + Run + button + Ejecutar + + + + + Run in terminal + button + Ejecutar en terminal + + + + Display + button + Mostrar + + + + + + + + + + + Confirm + button + Confirmar + + + + Erase + button + Borrar + + + + Data verification failed + La verificación de datos falló + + + + Show details + button + Mostrar detalles + + + + + Delete + button + Borrar + + + + Remove + button + Quitar + + + + Disk is busy, cannot unmount now + El disco está en uso, no puede desmontarlo ahora + + + + Force unmount + button + Forzar desmontaje + + + + Unable to copy. Not enough free space on the target disk. + No se puede copiar. No hay suficiente espacio libre en el disco de destino. + + + + Failed to restore %1 file, the target folder is read-only + No se pudo restaurar el archivo %1, la carpeta de destino es de solo lectura. + + + + Failed to restore %1 files, the target folder is read-only + Fallo al restaurar %1 archivos, la carpeta de destino es de solo lectura + + + + Failed to restore %1 files, the source files do not exist + La restauración de %1 archivos falló, los archivos de origen no existen + + + + Format + button + Formatear + + + + Stop + button + Detener + + + + FileController + + + + + + Unable to find the original file + No se puede encontrar el archivo original + + + + + + Kindly Reminder + Recordatorio amistoso + + + + + + Please install File Roller first and then continue + Por favor, instale primero el File Roller y luego continúe + + + + + Unable to create files here: %1 + No se puede crear el archivo aquí: %1 + + + + Confirm + button + Confirmar + + + + FileDialogStatusBar + + + File Name + Nombre de archivo + + + + Format + Formato + + + + Save + button + Guardar + + + + Open + button + Abrir + + + + Save File + button + Guardar archivo + + + + Open File + button + Abrir archivo + + + + + + Cancel + button + Cancelar + + + + FileJob + + + copy + copia + + + + + + + Data verification successful. + Verificación de datos exitosa. + + + + + + Burn process completed + Proceso de grabación completado + + + + %1 s + %1 segundos + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 es un archivo duplicado. + + + + Insufficient disc space. + Espacio en disco insuficiente. + + + + Lost connection to drive. + Se perdió la conexión con la unidad. + + + + The CD/DVD drive is not ready. Try another disc. + La unidad de CD / DVD no está lista. Probar con otro disco. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + La unidad de CD / DVD está en uso. Cierre el programa que esta usando la unidad e inténtelo de nuevo. + + + + Unknown error + Error desconocido + + + + Device disconnected + Dispositivo desconectado + + + + GenerateSettingTranslate + + + + + Basic + Básico + + + + + + Open behavior + Orden de apertura + + + + + + Always open folder in new window + Abrir siempre la carpeta en una nueva ventana + + + + + + Open file: + Abrir archivo: + + + + + + Click + Clic + + + + + + Double click + Doble clic + + + + + + New window and tab + Nueva vent. y pestaña + + + + + + Open from default window: + Abrir en la ventana predeterminada: + + + + + + + + + Computer + Equipo + + + + + + + + + Home + Carpeta personal + + + + + + + + + Desktop + Escritorio + + + + + + + + + Videos + Vídeos + + + + + + + + + Music + Música + + + + + + + + + Pictures + Imágenes + + + + + + + + + Documents + Documentos + + + + + + + + + Downloads + Descargas + + + + + + Open in new tab: + Abrir en una nueva pestaña: + + + + + + Current Directory + Carpeta actual + + + + + + View + Vista + + + + + + Default size: + Tamaño por defecto: + + + + + + Extra small + Muy pequeño + + + + + + Small + Pequeño + + + + + + Medium + Mediano + + + + + + Large + Grande + + + + + + Extra large + Muy grande + + + + + + Default view: + Vista predeterminada: + + + + + + Icon + Icono + + + + + + List + Lista + + + + + + Hidden files + Archivos ocultos + + + + + + Show hidden files + Mostrar archivos ocultos + + + + + + Hide file extension when rename + Ocultar extensión de archivo al renombrar + + + + + + Advanced + Avanzado + + + + + + Index + Indexación + + + + + + Auto index internal disk + Autoindexar disco interno + + + + + + Index external storage device after connected to computer + Indexar unidades externas después de conectar al equipo + + + + + + Full-Text search + Buscar texto completo + + + + + + Show item counts and sizes in the path of mounted MTP devices + Mostrar los recuentos y tamaños de los elementos en la ruta de los dispositivos MTP montados + + + + + + Keep showing the mounted Samba shares + Seguir mostrando recursos compartidos Samba montados + + + + + + Use the file chooser dialog of File Manager + Usar el diálogo del selector de archivos del administrador de archivos + + + + + + Ask for my confirmation when deleting files + Solicitar mi confirmación al borrar archivos + + + + + + Other + Otros + + + + + + Hide system disk + Ocultar el disco del sistema + + + + + + Show file system on disk icon + Mostrar etiquetas del tipo de partición + + + + + + Show hidden files in search results + Mostrar archivos ocultos en los resultados de búsqueda + + + + + + Display recent file entry in left panel + Mostrar la entrada de archivos recientes en el panel izquierdo + + + + + + Preview + Previsualización + + + + + Compress file preview + Previsualización del archivo comprimido + + + + + + Text preview + Previsualización del texto + + + + + + Document preview + Previsualización del documento + + + + + + Image preview + Previsualización de la imagen + + + + + + Video preview + Previsualización del vídeo + + + + + + Mount + Montado + + + + + + Auto mount + Montar unidades automáticamente + + + + + + Open after auto mount + Abrir después de montar automáticamente + + + + + + Dialog + Diálogo + + + + Compressed file preview + Previsualización de archivos comprimidos + + + + GvfsMountManager + + + Can’t verify the identity of %1. + No se puede verificar la identidad de %1. + + + + This happens when you log in to a computer the first time. + Esto sucede cuando inicia sesión en un equipo por primera vez. + + + + The identity sent by the remote computer is + La identidad enviada por el equipo remoto es + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Si quiere verificar que es seguro continuar, comuníquese con el administrador del sistema. + + + + + + + + Mounting device error + Error en el dispositivo de montaje + + + + + Wrong username or password + Error de usuario o contraseña + + + + + + + + Confirm + button + Confirmar + + + + + Cannot find the mounted device + No puedo encontrar el dispositivo montado + + + + No key available to unlock device + No hay llave disponible para desbloquear el dispositivo + + + + The disk is mounted by user "%1", you cannot unmount it. + El disco fue montado por el usuario «%1», no puedes desmontarlo. + + + + Cannot unmount the device + No se puede desmontar el dispositivo + + + + Cannot eject the device "%1" + No se puede expulsar el dispositivo «%1» + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + No se puede grabar. No hay suficiente espacio libre en el disco de destino. + + + + MergedDesktopController + + + + Pictures + Imágenes + + + + + Music + Música + + + + + Applications + Aplicaciones + + + + + Videos + Vídeos + + + + + Documents + Documentos + + + + + Others + Otros + + + + MimeTypeDisplayManager + + + + Directory + Carpeta + + + + + + Application + Aplicación + + + + + + Video + Vídeo + + + + + + Audio + Audio + + + + + + Image + Imagen + + + + + Archive + Archivo + + + + + + Text + Texto + + + + + Executable + Ejecutable + + + + + Backup file + Archivo de respaldo + + + + + Unknown + Desconocido + + + + MountAskPasswordDialog + + + Cancel + button + Cancelar + + + + Connect + button + Conectar + + + + Log in as + Iniciar sesión como + + + + Anonymous + Anónimo + + + + Registered user + Usuario registrado + + + + Username + Nombre de usuario + + + + Domain + Dominio + + + + Password + Contraseña + + + + Remember password + Recordar contraseña + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Cancelar + + + + Unlock + button + Desbloquear + + + + Input password to decrypt the disk + Introduzca la contraseña para descifrar el disco + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Está seguro de que quiere borrar definitivamente %1? + + + + This file is too big for the trash + Este archivo es demasiado grande para la papelera + + + + The files are too big for the trash + Los archivos son demasiado grandes para la papelera + + + + Are you sure you want to permanently delete %1 files? + Está seguro de que quiere borrar definitivamente %1 archivos? + + + + Cancel + button + Cancelar + + + + Delete + button + Borrar + + + + OpenWithDialog + + + Open with + Abrir con + + + + Add other programs + Añadir otros programas + + + + Set as default + Establecer por defecto + + + + Cancel + button + Cancelar + + + + Confirm + button + Confirmar + + + + Recommended Applications + Aplicaciones recomendadas + + + + Other Applications + Otras aplicaciones + + + + PathManager + + + Home + Carpeta personal + + + + Desktop + Escritorio + + + + Videos + Vídeos + + + + Music + Música + + + + Pictures + Imágenes + + + + Documents + Documentos + + + + Downloads + Descargas + + + + + Trash + Papelera + + + + + + System Disk + Disco del sistema + + + + Computers in LAN + Equipos en LAN + + + + My Shares + Uso compartido + + + + Computer + Equipo + + + + Recent + Reciente + + + + File Vault + Bóveda de archivos + + + + PropertyDialog + + + Basic info + Información básica + + + + Open with + Abrir con + + + + Sharing + Compartir + + + + Permissions + Permisos + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Ocultar + + + + Hide this file + Ocultar + + + + Allow to execute as program + Ejecutar como programa + + + + QObject + + + + + + Size + Tamaño + + + + + + Contains + Contiene + + + + + + Type + Tipo + + + + + + + + Time modified + Fecha de modificación + + + + Free space + Espacio libre + + + + Total space + Espacio total + + + + + Time locked + Fecha de bloqueo + + + + Access denied + Acceso denegado + + + + + Executable + Ejecutable + + + + + Write only + Escribir solamente + + + + + Read only + Solo lectura + + + + + Read-write + Escribir-Leer + + + + Others + Otros + + + + Owner + Propietario + + + + Unconnected network shared directory + Directorio compartido de red no conectado + + + + Device type + Tipo de dispositivo + + + + File system + Sistema de archivos + + + + Group + Grupo + + + + + Open + Abrir + + + + Lock + Bloquear + + + + Auto lock + Bloquear automáticamente + + + + Never + Nunca + + + + 5 minutes + 5 minutos + + + + 10 minutes + 10 minutos + + + + 20 minutes + 20 minutos + + + + Delete File Vault + Borrar bóveda de archivos + + + + Unlock + Desbloquear + + + + Unlock by key + Desbloquear con clave + + + + Open + button + Abrir + + + + + Size: %1 + Tamaño: %1 + + + + Type: %1 + Tipo: %1 + + + + Size: 0 + Tamaño: 0 + + + + Items: %1 + Elementos: %1 + + + + + + + + + + Open in new window + Abrir en una ventana nueva + + + + + + + + + + Open in new tab + Abrir en una nueva pestaña + + + + Open with + Abrir con + + + + + Compress + Comprimir + + + + Extract + Extraer + + + + Extract here + Extraer aquí + + + + Cut + Cortar + + + + Copy + Copiar + + + + Paste + Pegar + + + + + + + + Rename + Renombrar + + + + + + + Remove + Quitar + + + + Create link + Crear enlace + + + + Send to desktop + Enviar al escritorio + + + + Send to + Enviar a + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Añadir a marcadores + + + + + + + Properties + Propiedades + + + + New folder + Nueva carpeta + + + + New window + Nueva ventana + + + + Select all + Seleccionar todo + + + + + Clear recent history + Borrar historial reciente + + + + + + Empty Trash + Vaciar papelera + + + + Display as + Mostrar como + + + + Sort by + Ordenar por + + + + New document + Nuevo documento + + + + + Time created + Fecha de creación + + + + + + Source path + Ruta de origen + + + + Share folder + Compartir carpeta + + + + Cancel sharing + Dejar de compartir + + + + Connect to Server + Conectarse al servidor + + + + Set share password + Establecer contraseña para compartir + + + + Format + Formatear + + + + Tag information + Etiqueta informativa + + + + Open as administrator + Abrir como administrador + + + + Select default program + Seleccionar programa por defecto + + + + Open file location + Abrir ubicación del archivo + + + + Remove bookmark + Quitar de marcadores + + + + + + Delete + Borrar + + + + Office Text + Documento de texto de Office + + + + Spreadsheets + Documento de hoja de cálculo + + + + Plain Text + Documento de texto plano + + + + Open in terminal + Abrir en la terminal + + + + Restore + Restaurar + + + + Restore all + Restaurar todo + + + + Clear saved password and unmount + Borrar la contraseña guardada y desmontar + + + + File Vault + Bóveda de archivos + + + + Add to disc + Añadir al disco + + + + Refresh + Actualizar + + + + Auto mount + Montar automáticamente + + + + Open after auto mount + Abrir después de montar automáticamente + + + + + Mount + Montar + + + + + Unmount + Desmontar + + + + It does not support burning %1 discs + No se admite la grabación de % 1 discos + + + + Burn + Grabar + + + + Disc name: + Nombre del disco: + + + + + Maximum + Máximo + + + + Allow files to be added later + Permitir agregar archivos en el futuro + + + + Verify data + Verificar datos + + + + Write speed: + Velocidad de escritura: + + + + + + + Cancel + button + Cancelar + + + + Burn + button + Grabar + + + + + Eject + Expulsar + + + + Safely Remove + Extraer del equipo + + + + + Name + Nombre + + + + Settings + Ajustes + + + + Exit + Salida + + + + Icon + Icono + + + + List + Lista + + + + Extend + Ampliar + + + + Set as wallpaper + Establecer como fondo de pantalla + + + + + + + Local disk + Disco local + + + + + Removable disk + Disco extraíble + + + + + + Network shared directory + Carpeta compartida de red + + + + + Android mobile device + Dispositivo móvil Android + + + + + Apple mobile device + Dispositivo móvil Apple + + + + + Camera + Cámara + + + + + DVD + DVD + + + + + Unknown device + Dispositivo desconocido + + + + + + %1 item + %1 elemento + + + + + + %1 items + %1 elementos + + + + Shortcut + Enlace + + + + Create symlink + Crear enlace simbólico + + + + Path + Ruta + + + + + + Time deleted + Fecha de borrado + + + + Loading... + Cargando... + + + + File has been moved or deleted + El archivo ha sido movido o borrado + + + + You do not have permission to traverse files in it + No tiene permiso para recorrer los archivos en él + + + + + + You do not have permission to access this folder + No tienes permiso para acceder a esta carpeta + + + + + + + + Folder is empty + La carpeta está vacía + + + + Searching... + Buscando... + + + + No results + Sin resultados + + + + Source Path + TrashFileInfo + Ruta de origen + + + + Document + Documento + + + + Spreadsheet + Hoja de cálculo + + + + + Presentation + Presentación + + + + Text + Texto + + + + 1 task in progress + 1 tarea en progreso + + + + %1 tasks in progress + %1 tareas en progreso + + + + Mode: + Modo: + + + + + Replace Text + Reemplazar texto + + + + + Add Text + Añadir texto + + + + + Custom Text + Personalizar texto + + + + Find: + Buscar: + + + + Replace: + Reemplazar: + + + + + Optional + Opcional + + + + Add: + Añadir: + + + + Location: + Ubicación: + + + + File name: + Nombre del archivo: + + + + Start at: + Empieza con: + + + + + Rename + button + Renombrar + + + + + + + + + + + Required + Necesario + + + + + Before file name + Antes del nombre del archivo + + + + + After file name + Después del nombre del archivo + + + + Find + Buscar + + + + Replace + Reemplazar + + + + Add + Añadir + + + + Start at + Empieza con + + + + + + Location + Ubicación + + + + File name + Nombre del archivo + + + + Dimension + Dimensiones + + + + Duration + Duración + + + + Tips: Sort by selected file order + Consejo: Ordene igual que los archivos seleccionados + + + + Rename %1 Files + Renombrar %1 archivos + + + + Multiple Files + Múltiples archivos + + + + Basic info + Información básica + + + + Total size + Tamaño total + + + + Number of files + Número de archivos + + + + %1 file(s), %2 folder(s) + %1 archivo(s), %2 carpeta(s) + + + + + + Time accessed + Fecha de acceso + + + + Orange + Naranja + + + + Red + Rojo + + + + Purple + Púrpura + + + + Navy-blue + Azul + + + + Azure + Cian + + + + Green + Verde + + + + Yellow + Amarillo + + + + Gray + Gris + + + + Input tag info, such as work, family. A comma is used between two tags. + Añade información a la etiqueta, como «familia» o «trabajo». Una coma es usada para separar etiquetas. + + + + Bookmarks + Marcadores + + + + Erase + Borrar + + + + Copy path + Copiar ruta + + + + Edit address + Editar dirección + + + + Free Space %1 + Espacio libre% 1 + + + + Files are being processed + Los archivos están siendo procesados + + + + + Unknown + Desconocido + + + + My Vault + Mi bóveda + + + + + Failed to create file info + Error al crear un archivo de datos + + + + Failed to create file handler + Error al crear un archivo contenedor + + + + Failed to open the file, cause: %1 + Error al abrir el archivo, causa: %1 + + + + Original file does not exist + El archivo original no existe + + + + Do you want to delete %1? + ¿Desea borrar %1? + + + + Confirm + button + Confirmar + + + + + + + + %1 are not allowed + %1 no están permitidos + + + + + Failed to start Samba services + El inicio del servicio de Samba falló + + + + RecentController + + + Cancel + button + Cancelar + + + + Remove + button + Quitar + + + + Do you want to remove this item? + ¿Desea eliminar este elemento? + + + + Do yout want to remove %1 items? + ¿Desea eliminar %1 elementos? + + + + It does not delete the original files + No borrar archivos originales + + + + ShareInfoFrame + + + Share this folder + Compartir + + + + Share name: + Nombre: + + + + Permission: + Permiso: + + + + Read and write + Lectura y escritura + + + + Read only + Solo lectura + + + + Anonymous: + Anónimo: + + + + Not allow + No permitido + + + + Allow + Permitido + + + + The share name must not be two dots (..) or one dot (.) + El nombre del recurso compartido no puede contener un punto (.) o dos puntos (..) + + + + The share name is used by another user. + Otro usuario ya usa ese nombre de recurso compartido. + + + + OK + button + Aceptar + + + + Cancel + button + Cancelar + + + + Replace + button + Reemplazar + + + + The share name already exists. Do you want to replace the shared folder? + El nombre del recurso compartido ya existe. ¿Quiere reemplazar la carpeta compartida? + + + + Shortcut + + + Item + Elemento + + + + Select to the first item + Seleccionar el primer elemento + + + + Shift + Home + Mayús + Inicio + + + + Select to the last item + Seleccionar el último elemento + + + + Shift + End + Mayús + Fin + + + + Select leftwards + Seleccionar hacia la izquierda + + + + Shift + Left + Mayús + Izquierda + + + + Select rightwards + Seleccionar hacia la derecha + + + + Shift + Right + Mayús + Derecha + + + + Select to upper row + Seleccionar fila superior + + + + Shift + Up + Mayús + Arriba + + + + Select to lower row + Seleccionar fila inferior + + + + Shift + Down + Mayús + Abajo + + + + Open + Abrir + + + + Ctrl + Down + Ctrl + Abajo + + + + To parent directory + Regresar al nivel superior + + + + Ctrl + Up + Ctrl + Arriba + + + + Permanently delete + Borrar permanentemente + + + + Shift + Delete + Mayús + Suprimir + + + + Delete file + Borrar archivo + + + + Delete + Borrar + + + + Select all + Seleccionar todo + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Mayús + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Copiar + + + + Cut + Cortar + + + + Paste + Pegar + + + + Rename + Renombrar + + + + F2 + F2 + + + + New/Search + Nueva búsqueda + + + + New window + Nueva ventana + + + + New folder + Nueva carpeta + + + + + Search + Buscar + + + + New tab + Nueva pestaña + + + + View + Ver + + + + Item information + Información del elemento + + + + Help + Ayuda + + + + F1 + F1 + + + + Keyboard shortcuts + Atajos de teclado + + + + Ctrl + Shift + / + Ctrl + Mayús + / + + + + Switch display status + Cambiar estado de pantalla + + + + Hide item + Elemento oculto + + + + Input in address bar + Introduzca en la barra de direcciones + + + + Switch to icon view + Cambiar la vista de iconos + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Cambiar la vista de lista + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Otros + + + + Close + Cerrar + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Cerrar pestaña actual + + + + Back + Volver + + + + Alt + Left + Alt + Izquierda + + + + Alt + Right + Alt + Derecha + + + + Switch to next tab + Cambiar a siguiente pestaña + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Mayús + Tab + + + + Switch to previous tab + Cambiar a pestaña anterior + + + + Next file + Próximo archivo + + + + Tab + Pestaña + + + + Previous file + Archivo previo + + + + Shift + Tab + Mayús + Tab + + + + Switch tab by specified number between 1 to 8 + Cambiar la pestaña por el número especificado entre 1 y 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Adelante + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + No se pueden abrir elementos en la papelera, primero restáurelos + + + + TrashPropertyDialog + + + Trash + Papelera + + + + item + elemento + + + + items + elementos + + + + Contains %1 %2 + Contiene %1 %2 + + + + UDiskListener + + + Failed to rename the label + Error al cambiar el nombre de la etiqueta + + + + UnmountWorker + + + + + The device was not safely unmounted + El dispositivo no fue desmontado de forma segura + + + + The device was not safely removed + El dispositivo no fue retirado de forma segura + + + + UserShareManager + + + Kindly Reminder + Recordatorio amistoso + + + + Please firstly install samba to continue + Por favor, primero instale samba para continuar + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + El nombre de la acción no debe contener %<>*?|/\+=;:" y no debe empezar por %1 + + + + To protect the files, you cannot share this folder. + Para proteger los archivos, no puede compartir esta carpeta. + + + + Sharing failed + No se pudo compartir + + + + The computer name is too long + El nombre de la computadora es demasiado largo + + + + You do not have permission to operate file/folder! + ¡No tienes permiso para operar el archivo/carpeta! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Introduzca una contraseña para proteger las carpetas compartidas + + + + Cancel + button + Cancelar + + + + Confirm + button + Confirmar + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_fa.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_fa.ts new file mode 100644 index 0000000..3c252c7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_fa.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + پوشه جدید + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + خطای سوار کردن : قالب تصویر پشتیبانی نمی شود + + + + Disk is busy, cannot unmount now + دیسک مشغول است ، اکنون نمی توانید آن را جدا کنید + + + + + Disk is busy, cannot eject now + دیسک مشغول است و قادر به بیرون آوردن نیست + + + Mount Error + خطای سوار کردن + + + Unsupported image format + قالب تصویر پشتیبانی نمی شود + + + + CloseAllDialogIndicator + + + Close all + بستن همه + + + + Total size: %1, %2 files + اندازه کل: %1 ، %2 فایل + + + + ComputerModel + + + My Directories + دایرکتوری های من + + + + + + Disks + دیسک ها + + + + ComputerPropertyDialog + + + Computer + رایانه + + + + Basic Info + اطلاعات پایه + + + + Computer Name + نام رایانه + + + + Version + نسخه + + + + Type + نوع + + + + Processor + پردازنده + + + + Memory + حافظه + + + + Disk + دیسک + + + + Bit + بیت + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + آدرس را جستجو یا وارد کنید + + + + DFMAdvanceSearchBar + + + Search: + جستجو: + + + + File Type: + نوع فایل: + + + + File Size: + حجم فایل: + + + + Time Modified: + زمان تغییر یافتن: + + + + Reset + باز نشاندن + + + + All subdirectories + کلیه زیرشاخه ها + + + + Current directory + دایرکتوری کنونی + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + امروز + + + + Yesterday + دیروز + + + + This week + این هفته + + + + Last week + هفته گذشته + + + + This month + این ماه + + + + Last month + ماه گذشته + + + + This year + امسال + + + + Last year + سال گذشته + + + + DFMTagCrumbController + + + Tag information + اطلاعات برچسب + + + + DFMTagWidget + + + Tag + برچسب + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + رمز عبور رمز را وارد کنید + + + + Retrieve password + بازیابی رمز عبور + + + + DFileCopyMoveJob + + + Permission error + خطای مجوز + + + + The action is denied + این عمل رد شده است + + + + Failed to open the file + فایل باز نشد + + + + Failed to read the file + فایل خوانده نشد + + + + Failed to write the file + فایل نوشته نشد + + + + Failed to create the directory + ایجاد پوشه انجام نشد + + + + Failed to delete the file + فایل حذف نشد + + + + Failed to move the file + انتقال فایل انجام نشد + + + + Original file does not exist + فایل اصلی وجود ندارد + + + + Failed, file size must be less than 4GB + انجام نشد ، اندازه فایل باید کمتر از 4 گیگ باشد + + + + Not enough free space on the target disk + فضای خالی کافی روی دیسک هدف نیست + + + + File integrity was damaged + یکپارچگی فایل خراب شده است + + + + The target device is read only + دستگاه هدف فقط خواندنی است + + + + Target folder is inside the source folder + پوشه هدف درون پوشه منبع قرار دارد + + + + copy + Extra name added to new file name when used for file name. + کپی + + + + Failed to create the directory, cause: %1 + ایجاد فهرست انجام نشد ، به علت: %1 + + + + + Failed to open the file, cause: %1 + فایل باز نشد ، به علت: %1 + + + + Failed to read the file, cause: %1 + فایل خوانده نشد ، به علت: %1 + + + + Failed to write the file, cause: %1 + فایل نوشته نشد ، به علت: %1 + + + + File integrity was damaged, cause: %1 + یکپارچگی فایل خراب شده است  ، به علت: %1 + + + + Failed to delete the file, cause: %1 + فایل حذف نشد ، به علت: %1 + + + + Fail to create symlink, cause: %1 + عدم ایجاد Symlink ، به علت: %1 + + + + DFileDialog + + + + Save + ذخیره + + + + %1 already exists, do you want to replace it? + %1 وجود دارد ، آیا می خواهید آن را جایگزین کنید؟ + + + + Cancel + لغو + + + + Replace + جایگزین + + + + Open + باز کردن + + + + DFileManagerWindow + + + Trash + زباله دان + + + + Empty + خالی + + + + DFileSystemModel + + + + Name + اسم + + + + + + Time modified + زمان تغییر یافتن + + + + Size + حجم + + + + Type + تایپ + + + + Time created + زمان ایجاد شدن + + + + + Last access + آخرین دسترسی + + + + Path + مسیر + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + (معکوس) + + + + DFileViewHelper + + + Add tag "%1" + افزودن برچسب "%1" + + + + DStatusBar + + + %1 item + %1 مورد + + + + %1 items + %1 مورد + + + + %1 item selected + %1 مورد انتخاب شده + + + + %1 items selected + %1 مورد انتخاب شده + + + + %1 folder selected (contains %2) + %1 پوشه انتخاب شد (حاوی %2 ) + + + + %1 folders selected (contains %2) + %1 پوشه انتخاب شد (حاوی %2 ) + + + + %1 file selected (%2) + %1فایل انتخاب شد (حاوی %2 ) + + + + %1 files selected (%2) + %1فایل انتخاب شد (حاوی %2 ) + + + + %1 folder selected + %1 پوشه انتخاب شد + + + + Filter + فیلتر + + + + Save as: + ذخیره به عنوان: + + + + Loading... + در حال بارگذاری... + + + + DTaskDialog + + + This action is not supported + این اقدام پشتیبانی نمی شود + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + %1 حجم + + + + Data Disk + Data Partition + دیسک داده + + + + %1 Drive + %1 درایو + + + + Blank %1 Disc + خالی %1 دیسک + + + + %1 Encrypted + %1 رمزگذاری شده + + + + DialogManager + + + + + Operation failed! + عملیاتی انجام نشد! + + + + Target folder is inside the source folder! + پوشه هدف درون پوشه منبع قرار دارد! + + + + + + + + + + + + + OK + باشه + + + + Do you want to run %1 or display its content? + آیا می خواهید %1 را اجرا کنید یا محتوای آن را نمایش دهید؟ + + + + It is an executable text file. + این یک فایل متنی قابل اجرا است. + + + + + + + + + + + + + + Cancel + لغو + + + + + + Run + اجرا + + + + + Run in terminal + اجرا در ترمینال + + + + Display + نمایش + + + + It is an executable file. + این یک فایل قابل اجرا است. + + + + This file is not executable, do you want to add the execute permission and run? + این فایل قابل اجرا نیست ، آیا می خواهید مجوز اجرای را اضافه کنید و آن را اجرا کنید؟ + + + + "%1" already exists, please use another name. + "%1" در حال حاضر وجود دارد ، لطفاً از نام دیگری استفاده کنید. + + + + + + + + Confirm + تایید + + + + Are you sure you want to erase all data on the disc? + آیا مطمئن هستید که می خواهید تمام داده های موجود در دیسک را پاک کنید؟ + + + + Erase + پاک کردن + + + + How do you want to use this disc? + چگونه می خواهید از این دیسک استفاده کنید؟ + + + + Burn image + رایت کردن ایمیج + + + + Burn files + رایت کردن فایل + + + + Disc erase failed + پاک کردن دیسک انجام نشد + + + + Burn process failed + روند رایت کردن انجام نشد + + + + %1: %2 + %1: %2 + + + + + Show details + نمایش جزئیات + + + + Hide details + مخفی کردن جزئیات + + + + Error + خطا + + + + Permanently delete %1? + به صورت دائمی %1 را حذف می کنید؟ + + + + Permanently delete %1 items? + به صورت دائمی %1 را حذف می کنید؟ + + + + Delete + حذف + + + + Empty + خالی + + + + Sorry, unable to locate your bookmark directory, remove it? + متأسفیم ، قادر به یافتن دایرکتوری نشانه شما نیستیم ، آن را حذف می کنید؟ + + + + Remove + برچیدن + + + + Name: + نام: + + + + Force unmount + جدا کردن به اجبار + + + + %1 that this shortcut refers to has been changed or moved + %1 که این میانبر به آن اشاره دارد تغییر یافته یا جابجا شده است + + + + Do you want to delete this shortcut? + آیا می خواهید این میانبر را حذف کنید؟ + + + + Failed, file size must be less than 4GB. + انجام نشد ، اندازه فایل باید کمتر از 4 گیگ باشد + + + + Fail to create symlink, cause: + عدم ایجاد Symlink ، به علت: + + + + The selected files contain system file/directory, and it cannot be deleted + فایل های انتخاب شده حاوی فایل / فهرست سیستم هستند و نمی توان آن را حذف کرد + + + + + You do not have permission to operate file/folder! + شما اجازه کار با فایل/ پوشه را ندارید! + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + متأسفیم ، شما اجازه استفاده از فایل/ پوشه (های) %1 را ندارید! + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + 2. در تنظیمات خاموش کردن ، گزینه "روشن کردن با راه اندازی سریع" و "هایبرنت" را بردارید و راه اندازی مجدد کنید + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + پوشه اشتراک گذاری را نمی توان بعد از کاربر جاری نام برد + + + + View + نما + + + + Do you want to run %1? + آیا می خواهید %1 را اجرا کنید ؟ + + + + Are you sure you want to empty %1 item? + آیا مطمئن هستید که می خواهید %1 مورد را خالی کنید؟ + + + + Are you sure you want to empty %1 items? + Are you sure you want to empty %1 items? + + + + + This action cannot be undone + این عملکرد قابل برگشت نیست + + + + Disk is busy, cannot unmount now + دیسک مشغول است ، اکنون نمی توانید آن را جدا کنید + + + + Unable to copy. Not enough free space on the target disk. + امکان کپی وجود ندارد. فضای خالی کافی روی دیسک هدف نیست. + + + + Failed to restore %1 file, the target folder is read-only + بازیابی %1 فایل انجام نشد ، پوشه هدف فقط خواندنی است + + + + Failed to restore %1 files, the target folder is read-only + بازیابی %1 فایل انجام نشد ، پوشه هدف فقط خواندنی است + + + + Mount partition%1 to be read only + سوار کردن پارتیشن %1 فقط خوانده شود + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + اگر "روشن کردن راه اندازی سریع (توصیه شده)" در تنظیمات خاموش شود ، دیسک ها در ویندوز قادر به خواندن و نوشتن عادی نخواهند بود + + + + Please restore by the following steps to normally access Windows disk + لطفاً برای دستیابی عادی به دیسک ویندوز ، مراحل زیر را بازیابی کنید + + + + 1. Reboot to enter Windows + 1. راه اندازی مجدد برای ورود به ویندوز + + + 3. Reboot and enter deepin + 3. راه اندازی مجدد و ورود به دیپین + + + + Reboot + راه اندازی مجدد + + + + FileController + + + + + Kindly Reminder + یادآور مهربان + + + + + + Please install File Roller first and then continue + لطفاً ابتدا File Roller را نصب کنید و سپس ادامه دهید + + + + FileDialogStatusBar + + + File Name + اسم فایل + + + + Format + فرمت + + + + Cancel + لغو + + + + Save + ذخیره + + + + Open + باز کردن + + + + Save File + ذخیره فایل + + + + Open File + باز کردن فایل + + + + FileJob + + + copy + کپی + + + + + Data verification successful. + تأیید اطلاعات با موفقیت انجام شد + + + + + Data verification failed. + تأیید اطلاعات انجام نشد. + + + + + Burn process completed + روند رایت کامل شد + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 یک فایل تکراری است . + + + + Insufficient disc space. + فضای دیسک کافی نیست. + + + + Lost connection to drive. + اتصال به درایو از بین رفته است. + + + + The CD/DVD drive is not ready. Try another disc. + درایو CD / DVD آماده نیست. دیسک دیگری را امتحان کنید. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + درایو CD / DVD مشغول است. از برنامه ایی که در حال استفاده از درایو است خارج شده و درایو را دو باره قرار دهید. + + + + Unknown error + خطای ناشناخته + + + + GenerateSettingTranslate + + + + + Basic + اولیه + + + + + + Open behavior + بازکردن رفتار + + + + + + Always open folder in new window + همیشه پوشه را در پنجره جدید باز کن + + + + + + Open file: + باز کردن فایل: + + + + + + Click + کلیک + + + + + + Double click + دو بار کلیک + + + + + + New window and tab + پنجره و زبانه جدید + + + + + + Open from default window: + باز کردن از پنجره پیش فرض: + + + + + + + + + Computer + رایانه + + + + + + + + + Home + خانه + + + + + + + + + Desktop + دسکتاپ + + + + + + + + + Videos + ویدئو + + + + + + + + + Music + موسیقی + + + + + + + + + Pictures + تصاویر + + + + + + + + + Documents + اسناد + + + + + + + + + Downloads + دانلودها + + + + + + Open in new tab: + باز کردن در زبانه جدید: + + + + + + Current Directory + دایرکتوری کنونی + + + + + + View + نما + + + + + + Default size: + اندازه پیش فرض: + + + + + + Extra small + بسیار کوچک + + + + + + Small + کوچک + + + + + + Medium + متوسط + + + + + + Large + بزرگ + + + + + + Extra large + خیلی بزرگ + + + + + + Default view: + نمای پیش فرض: + + + + + + Icon + آیکون + + + + + + List + لیست + + + + + + Hidden files + فایل های پنهان + + + + + + Show hidden files + نمایش فایلهای مخفی + + + + + + Hide file extension when rename + هنگام تغییر نام پسوند فایل را مخفی کن + + + + + + Advanced + پیشرفته + + + + + + Index + شاخص + + + + + + Auto index internal disk + شاخص خودکار دیسک داخلی + + + + + + Index external storage device after connected to computer + دستگاه ذخیره خارجی را پس از اتصال به رایانه فهرست کن + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + سایر + + + + + + Hide system disk + پنهان کردن دیسک سیستم + + + + + + Show hidden files in search results + نمایش فایل های مخفی در نتایج جستجو + + + + + + Display recent file entry in left panel + نمایش فایل اخیر در پانل سمت چپ + + + + + + Preview + پیش نمایش + + + + + Compress file preview + فشرده سازی پیش نمایش فایل + + + + + + Text preview + پیش نمایش متن + + + + + + Document preview + پیش نمایش سند + + + + + + Image preview + پیش نمایش تصویر + + + + + + Video preview + پیش نمایش ویدئو + + + + + + Mount + سوارکردن + + + + + + Auto mount + سوار کردن خودکار + + + + + + Open after auto mount + باز کردن بعد از سوار کردن خودکار + + + + + + Dialog + دیالوگ + + + Use the file chooser dialog of Deepin File Manager + از کادر دیالوگ انتخاب فایل مدیر فایل دیپین استفاده کنید + + + + Compressed file preview + پیش نمایش فایل فشرده شده + + + + GvfsMountManager + + + Mounting device error + خطای سوار کردن دستگاه + + + + The disk is mounted by user "%1", you cannot unmount it. + دیسک توسط کاربر "%1"سوار شده است ,شما قادر به جدا کردن نمی باشید. + + + + + + + + Confirm + تایید + + + + + Cannot find the mounting device + دستگاه سوار شده را نمی توان یافت + + + + Cannot unmount the device + دستگاه را نمی توان از آن جدا کرد + + + + Cannot eject the device "%1" + دستگاه "%1" را نمی توان خارج کرد + + + + MergedDesktopController + + + + Pictures + تصاویر + + + + + Music + موسیقی + + + + + Applications + برنامه ها + + + + + Videos + ویدئو ها + + + + + Documents + اسناد + + + + + Others + سایرین + + + + MimeTypeDisplayManager + + + + Directory + دایرکتوری + + + + + + Application + برنامه + + + + + + Video + ویدئو + + + + + + Audio + صوت + + + + + + Image + تصویر + + + + + Archive + بایگانی + + + + + + Text + متن + + + + + Executable + قابل اجرا + + + + + Backup file + فایل پشتیبان + + + + + Unknown + ناشناخته + + + + MountAskPasswordDialog + + + Cancel + لغو + + + + Connect + اتصال + + + + Log in as + ورود به عنوان + + + + Anonymous + ناشناس + + + + Registered user + کاربر ثبت شده + + + + Username + نام کاربری + + + + Domain + دامنه + + + + Password + کلمه عبور + + + + Remember password + رمز ورود را به خاطر بسپار + + + + MountSecretDiskAskPasswordDialog + + + Cancel + لغو + + + + Unlock + باز کردن + + + + Input password to decrypt the disk + برای رمزگشایی دیسک ، رمز ورود را وارد کنید + + + + MoveCopyTaskWidget + + Skip + پرش + + + Keep both + هر دو را نگه دار + + + Replace + جایگزین + + + Do not ask again + دوباره نپرس + + + merge + ادغام + + + Copying %1 + در حال کپی کردن %1 + + + Erasing disc %1, please wait... + در حال پاک کردن دیسک %1 ، لطفا صبر کنید ... + + + Burning disc %1, please wait... + در حال نوشتن روی دیسک %1 ، لطفا صبر کنید ... + + + Writing data... + در حال نوشتن داده ها ... + + + Verifying data... + در حال تأیید داده ها ... + + + Copy to %2 + کپی به %2 + + + Moving %1 + در حال انتقال %1 + + + Move to %2 + انتقال به %2 + + + Restoring %1 + در حال بازیابی %1 + + + Restore to %2 + بازیابی به %2 + + + Deleting %1 + در حال حذف %1 + + + Trashing %1 + در حال حذف %1 + + + Calculating space, please wait + در حال محاسبه فضا ، لطفا صبر کنید + + + File named %1 already exists in target folder + فایل با نام %1 در حال حاضر در پوشه هدف وجود دارد + + + Original path %1 target path %2 + مسیر اصلی%1 مسیر هدف %2 + + + Retry + دوباره امتحان کنید + + + Time modified:%1 + زمان تغییر یافتن:%1 + + + Original folder + پوشه اصلی + + + Original file + فایل اصلی + + + Target folder + پوشه هدف + + + Target file + فایل هدف + + + Contains:%1 + شامل:%1 + + + Size:%1 + حجم:%1 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + آیا مطمئن هستید که می خواهید به صورت دائمی %1 را حذف می کنید؟ + + + + This file is too big for the trash + این فایل برای سطل زباله بسیار بزرگ است + + + + The files are too big for the trash + این فایل ها برای سطل زباله بسیار بزرگ است + + + + Are you sure you want to permanently delete %1 files? + آیا مطمئن هستید که می خواهید به صورت دائمی فایلهای %1 را حذف می کنید؟ + + + + Cancel + لغو + + + + Delete + حذف + + + + OpenWithDialog + + + Open with + باز کردن با + + + + Add other programs + اضافه کردن برنامه های دیگر + + + + Set as default + تنظیم به عنوان پیشفرض + + + + Cancel + لغو + + + + Confirm + تایید + + + + Recommended Applications + برنامه های پیشنهادی + + + + Other Applications + برنامه های دیگر + + + + PathManager + + + Home + خانه + + + + Desktop + دسکتاپ + + + + Videos + ویدئو ها + + + + Music + موسیقی + + + + Pictures + تصاویر + + + + Documents + اسناد + + + + Downloads + دانلودها + + + + + Trash + زباله دان + + + + + System Disk + دیسک سیستم + + + + Computers in LAN + رایانه های در LAN + + + + My Shares + اشتراک گذاری ها من + + + + Computer + رایانه + + + + Recent + اخیر + + + + PropertyDialog + + + Basic info + اطلاعات پایه + + + + Open with + باز کردن با + + + + Sharing + اشتراک گذاری + + + + Permissions + مجوزها + + + + %1 (%2) + %1 (%2) + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + اجازه اجرا به صورت برنامه + + + + QObject + + + + + Size + حجم + + + + + + Contains + شامل + + + + + + Type + نوع + + + + + + + Time modified + زمان تغییر یافتن + + + + Free space + فضای خالی + + + + Total space + فضای کل + + + + Access denied + دسترسی رد شد + + + + + Executable + قابل اجرا + + + + + Write only + فقط نوشتنی + + + + + Read only + فقط خواندنی + + + + + Read-write + خواندن-نوشتن + + + + Others + سایرین + + + + Owner + صاحب + + + + Device type + نوع دستگاه + + + + File system + فایل سیستم + + + + Group + گروه + + + + + + Open + باز کردن + + + + + Size: %1 + حجم:%1 + + + + Type: %1 + نوع: %1 + + + + Size: 0 + حجم: 0 + + + + Items: %1 + موارد:%1 + + + + + + + + + + + Open in new window + باز کردن درپنجره جدید + + + + + + + + + + + Open in new tab + باز کردن در زبانه جدید + + + + Open with + باز کردن با + + + + Compress + فشرده سازی + + + + Extract + استخراج + + + + Extract here + استخراج در اینجا + + + + Cut + برش + + + + Copy + کپی + + + + Paste + چسباندن + + + + + + + + + + Rename + تغییرنام + + + + + + Remove + برچیدن + + + + Create link + ایجاد لینک + + + + Send to desktop + ارسال به دسکتاپ + + + + Send to + ارسال به + + + + Add to bookmark + اضافه کردن به نشانک + + + + + + + Properties + خصوصیات + + + + New folder + پوشه جدید + + + + New window + پنجره جدید + + + + Select all + انتخاب همه + + + + + Clear recent history + پاک کردن تاریخ اخیر + + + + + + Empty Trash + خالی کردن زباله دان + + + + Display as + نمایش به عنوان + + + + Sort by + مرتب سازی بر اساس + + + + New document + سند جدید + + + + + Time created + زمان ایجاد شدن + + + + Log out and unmount + از سیستم خارج شو و جدا شو + + + + + + Source path + مسیر منبع + + + + Share folder + پوشه اشتراکی + + + + Cancel sharing + لغو اشتراک گذاری + + + + Connect to Server + + + + + Set share password + تنظیم رمزعبور اشتراک + + + + Format + فرمت + + + + Tag information + اطلاعات برچسب + + + + Open in new window as admin + به عنوان مدیر در پنجره جدید باز کنید + + + + Select default program + تنظیم به عنوان پیشفرض + + + + Open file location + باز کردن مکان فایل + + + + Remove bookmark + حذف نشانک + + + + + + Delete + حذف + + + + Office Text + متن دفتر + + + + Spreadsheets + صفحات گسترده + + + + Plain Text + متن ساده + + + + Open in terminal + باز کردن در ترمینال + + + + Restore + بازیابی + + + + Restore all + بازگرداندن همه + + + + File Vault + والت فایل + + + + Auto mount + سوار کردن خودکار + + + + Open after auto mount + باز کردن بعد از سوار کردن خودکار + + + + + Mount + سوارکردن + + + + + Unmount + جدا کردن همه + + + + + + Burn + نوشتن + + + + Disc name: + نام دیسک: + + + + + Maximum + بیشترین + + + + Allow files to be added later + اجازه دهید فایل ها بعدا اضافه شوند + + + + Verify data + تأیید داده + + + + Write speed: + سرعت نوشتن: + + + + + Eject + بیرون انداختن + + + + Safely Remove + با خیال راحت برچینید + + + + + Name + اسم + + + + Settings + تنظیمات + + + + Exit + خروج + + + + Icon + آیکون + + + + List + لیست + + + + Extend + گسترش + + + + Set as wallpaper + تنظیم به عنوان تصویر پس زمینه + + + + + + + Local disk + دیسک محلی + + + + + Removable disk + دیسک قابل جابجایی + + + + + + Network shared directory + دایرکتوری مشترک شبکه + + + + + Android mobile device + دستگاه تلفن همراه اندروید + + + + + Apple mobile device + دستگاه موبایل اپل + + + + + Camera + دوربین + + + + + DVD + DVD + + + + + Unknown device + دستگاه ناشناخته + + + + + + %1 item + %1 مورد + + + + + + %1 items + %1 مورد + + + + Shortcut + میانبر + + + + Create symlink + ایجاد symlink + + + + Path + مسیر + + + + + + Time deleted + زمان حذف شد + + + + Loading... + در حال بارگذاری... + + + + File has been moved or deleted + فایل منتقل شده یا حذف شده است + + + + + + You do not have permission to access this folder + شما اجازه دسترسی به این پوشه را ندارید + + + + + + + Folder is empty + پوشه خالی است + + + + Path + SearchFileInfo + مسیر + + + + Searching... + در حال جستجو... + + + + No results + بدون نتیجه + + + + Source Path + TrashFileInfo + مسیر منبع + + + + Document + سند + + + + Spreadsheet + صفحه گسترده + + + + + Presentation + ارائه + + + + Text + متن + + + + 1 task in progress + 1 کار در حال انجام است + + + + %1 tasks in progress + %1 کار در حال انجام است + + + + Mode: + حالت: + + + + + Replace Text + جایگزینی متن + + + + + Add Text + افزودن متن + + + + + Custom Text + متن سفارشی + + + + Find: + یافتن: + + + + Replace: + جایگزین: + + + + + Optional + اختیاری + + + + Add: + اضافه کردن: + + + + Location: + مکان: + + + + File name: + اسم فایل: + + + + +SN: + +SN: + + + + + + + + + + Required + ضروری + + + + + Before file name + قبل از نام فایل + + + + + After file name + بعد از نام فایل + + + + Find + یافتن + + + + Replace + جایگزین + + + + Add + اضافه کردن + + + + + + Location + مکان + + + + File name + اسم فایل + + + + Dimension + ابعاد + + + + Duration + مدت + + + + +SN + +SN + + + + Tips: Sort by selected file order + نکات: مرتب سازی بر اساس فایل انتخاب شده + + + + + + Cancel + لغو + + + + Rename %1 Files + تغییر نام %1 فایل + + + + Multiple Files + چندین فایل + + + + Basic info + اطلاعات پایه + + + + Total size + اندازه کل + + + + Number of files + تعداد فایل ها + + + + %1 file(s), %2 folder(s) + %1 فایل ، %2 پوشه + + + + + + Time accessed + زمان دسترسی + + + + Orange + نارنجی + + + + Red + قرمز + + + + Purple + بنفش + + + + Navy-blue + آبی-دریا + + + + Azure + لاجوردی + + + + Green + سبز + + + + Yellow + زرد + + + + Gray + خاکستری + + + + Input tag info, such as work, family. A comma is used between two tags. + اطلاعات برچسب ورودی مانند کار ، خانواده . کاما بین دو تگ استفاده می شود. + + + + Bookmarks + نشانک ها + + + + Erase + پاک کردن + + + + + Copy path + مسیر کپی + + + + + Edit address + ویرایش آدرس + + + + Free Space %1 + فضای خالی %1 + + + + Files are being processed + فایل ها در حال پردازش هستند + + + + %1/%2 + %1/%2 + + + + ShareInfoFrame + + + Share this folder + این پوشه را به اشتراک بگذار + + + + Share name: + نام اشتراک گذاری: + + + + Permission: + مجوز: + + + + Read and write + خواندن و نوشتن + + + + Read only + فقط خواندنی + + + + Anonymous: + ناشناس: + + + + Not allow + مجاز نیست + + + + Allow + مجاز + + + + Shortcut + + + Item + مورد + + + + Select to the first item + اولین مورد را انتخاب کنید + + + + Shift + Home + Shift + Home + + + + Select to the last item + آخرین مورد را انتخاب کنید + + + + Shift + End + Shift + End + + + + Select leftwards + سمت چپ را انتخاب کنید + + + + Shift + Left + Shift + Left + + + + Select rightwards + سمت راست را انتخاب کنید + + + + Shift + Right + Shift + Right + + + + Select to upper row + انتخاب ردیف بالایی + + + + Shift + Up + Shift + Up + + + + Select to lower row + انتخاب ردیف پایینی + + + + Shift + Down + Shift + Down + + + + Open + باز کردن + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + به دایرکتوری والدین + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + حذف دائمی + + + + Shift + Delete + Shift + Delete + + + + Delete file + حذف فایل + + + + Delete + حذف + + + + Select all + انتخاب همه + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + کپی + + + + Cut + برش + + + + Paste + چسباندن + + + + Rename + تغییرنام + + + + F2 + F2 + + + + New/Search + جدید/جستجو + + + + New window + پنجره جدید + + + + New folder + پوشه جدید + + + + + Search + جستجو + + + + New tab + زبانه جدید + + + + View + نما + + + + Item information + اطلاعات مورد + + + + Help + راهنما + + + + F1 + F1 + + + + Keyboard shortcuts + میانبرهای صفحه کلید + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + تغییر وضعیت نمایش + + + + Hide item + مخفی کردن مورد + + + + Input in address bar + ورودی در نوار آدرس + + + + Switch to icon view + تغییر به نمای آیکون + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + تغییر به نمای لیست + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + سایرین + + + + Close + بستن + + + + Alt + F4 + Alt + F4 + + + + Close current tab + بستن زبانه جاری + + + + Back + بازگشت + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + رفتن به زبانه بعدی + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + رفتن به زبانه قبلی + + + + Next file + فایل بعدی + + + + Tab + زبانه + + + + Previous file + فایل قبلی + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + زبانه را با شماره مشخص شده بین 1 تا 8 تغییر دهید + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + جلو + + + + TrashPropertyDialog + + + Trash + زباله دان + + + + item + مورد + + + + items + موارد + + + + Contains %1 %2 + شامل %1 %2 + + + + UDiskListener + + + Failed to rename the label + تغییر نام برچسب انجام نشد + + + + UserShareManager + + + Kindly Reminder + یادآور مهربان + + + + Please firstly install samba to continue + لطفاً ابتدا برای ادامه ، سامبا را نصب کنید + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + برای محافظت از پوشه های مشترک ، یک رمز عبور وارد کنید + + + + Cancel + لغو + + + + Confirm + تایید + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + آیا می خواهید در صورت فراموش کردن رمز ورود ، یک فایل کلید صادر کنید؟ + + + Export key + صدور کلید + + + + Do you want to generate a key in case that you forgot the password? + آیا می خواهید در صورت فراموش کردن رمز ورود ، کلید ایجاد کنید؟ + + + + Generate key + تولید کلید + + + + Skip + پرش + + + + VaultGeneratedKeyPage + + + Find your recovery key below + کلید بازیابی خود را در زیر بیابید + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + با چاپ ، نوشتن یا ذخیره آن در یک درایو فلش USB ، از کلید ریکاوری خوب مراقبت کنید + + + + Your recovery key is as important as your password. Do not save the key file on this computer + کلید بازیابی شما به اندازه رمز عبور مهم است. فایل اصلی کلید را در این رایانه ذخیره نکنید + + + + Save your vault recovery key + کلید بازیابی والت را ذخیره کنید + + + + + File Vault Recovery Key + کلید بازیابی فایل والت + + + + File Vault Recovery Key (*.txt) + کلید بازیابی فایل والت (*.txt) + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + برای تأیید صحت این کلید بازیابی ، شناسه کلید زیر را با شناسه کلیدی نمایش داده شده در رایانه خود مقایسه کنید. + + + + Key ID: %1 + شناسه کلید: %1 + + + + If they are identical, then use the following key to retrieve your vault password. + اگر آنها یکسان هستند ، پس از آن ،از کلید زیر برای بازیابی رمز عبور والت استفاده کنید. + + + + Recovery Key: %1 + کلید بازیابی: %1 + + + + If they do not match, then this is not the right key, please try another recovery key. + اگر آنها مطابقت ندارند ، این کلید مناسب نیست ، لطفا یک کلید بازیابی دیگر را امتحان کنید. + + + + Save + ذخیره + + + + Done + انجام شد + + + + VaultHeaderView + + + File Vault + والت فایل + + + + Lock vault + قفل والت + + + + Generate key + تولید کلید + + + Generate key file + تولید فایل کلید + + + + VaultPasswordPage + + + Here is your vault password + این رمز عبور والت شماست + + + + OK + باشه + + + + VaultSetupSetPasswordPage + + + Next + بعدی + + + + Set a password for the vault + رمز عبور را برای والت تنظیم کنید + + + + Password + کلمه عبور + + + + Repeat password + تکرار رمز عبور + + + + VaultSetupWelcomePage + + + Create a new vault + ساخت والت جدید + + + + Import a vault + وارد کردن والت + + + + File Vault + فایل والت + + + + Welcome to File Vault + به فایل والت خوش آمدید + + + + Create secure private space here + فضای خصوصی امن را در اینجا ایجاد کنید + + + + Advanced encryption technology, safe and secure + فناوری رمزگذاری پیشرفته ، ایمن و مطمئن + + + + Convenient and easy to use + مناسب و آسان برای استفاده + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + متن زیر را با شناسه کلیدی موجود در فایل بازیابی کلید خود مقایسه کنید + + + + If they are identical, input the recovery key below to retrieve your vault password + اگر آنها یکسان هستند ، کلید بازیابی زیر را وارد کنید تا رمز عبور والت خود را بازیابی کنید + + + + Retrieve password + بازیابی رمز عبور + + + + VaultVerifyUserPage + + + Enter the vault password + رمز عبور رمز را وارد کنید + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_fi.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_fi.ts new file mode 100644 index 0000000..e3e4b0d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_fi.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Uusi kansio + + + + Mounting device error + Asennuslaitteen virhe + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Levyn kuva on vioittunut ja sitä ei voi liittää, tyhjennä levy ensin + + + + Mount error: unsupported image format + Asennus virhe: formaattia ei tueta + + + + + The device was not safely removed + Laitetta ei poistettu turvallisesti + + + + + Click "Safely Remove" and then disconnect it next time + Napsauta ensin "Poista turvallisesti" ja irrota se sitten + + + + The device was not ejected + Laitetta ei ole poistettu + + + + Disk is busy, cannot eject now + Levy varattu, ei voi poistaa nyt + + + + Authentication timed out + Todennus aikakatkaistiin + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Bluetooth-tiedostonsiirto + + + + File Transfer Successful + Tiedostonsiirto onnistui + + + + File Transfer Failed + Tiedostonsiirto epäonnistui + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Lähettää tiedostoja "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Tiedostojen lähettäminen "<b style="font-weight: 550;">%1</b>" epäonnistui + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Lähetys onnistui "<b style="font-weight: 550;">%1</b>" + + + + Select a Bluetooth device to receive files + Valitse Bluetooth-laite tiedostojen vastaanottamistasi + + + + Cannot find the connected Bluetooth device + Bluetooth-laitetta ei löydy + + + + Waiting to be received... + Odotetaan vastaanotettavaa... + + + + Go to Bluetooth Settings + Siirry Bluetooth-asetuksiin + + + + %1/%2 Sent + %1/%2 lähetetty + + + + Error: the Bluetooth device is disconnected + Virhe: Bluetooth-laite on katkaistu + + + + Unable to send the file more than 2 GB + Yli 2 Gt tiedostoa ei voi lähettää + + + + Unable to send 0 KB files + 0 kt tiedostoja ei voi lähettää + + + + File doesn't exist + Tiedostoa ei ole olemassa + + + + Next + button + Seuraava + + + + Cancel + button + Peruuta + + + + Done + button + Tehty + + + + Retry + button + Uudelleen + + + + OK + button + OK + + + + File sending request timed out + Tiedostojen lähetyspyyntö aikakatkaistiin + + + + The service is busy and unable to process the request + Palvelu on varattu, eikä pyyntöä voi käsittellä + + + + BurnOptDialog + + + Device error + Laitteen virhe + + + + Optical device %1 doesn't exist + Optista laitetta %1 ei ole + + + + Advanced settings + Lisäasetukset + + + + File system: + Tiedostojärjestelmä: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Windowsille) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (yhteensopiva Windowsin CD-/DVD-tilan kanssa) + + + + ISO9660 Only + ISO9660 ainoastaan + + + + CloseAllDialogIndicator + + + Close all + Sulje kaikki + + + + Total size: %1, %2 files + Yhteensä: %1, %2 tiedostoa + + + + ComputerModel + + + Double click to open it + Avaa napsauttamalla kahdesti + + + + My Directories + Omat hakemistot + + + + Disks + Levyt + + + + File Vault + Tiedostoholvi + + + + Quick Access + Nopea pääsy + + + + ComputerPropertyDialog + + + Computer + Tietokone + + + + Basic Info + Perustiedot + + + + + Computer Name + Tietokoneen nimi + + + + + Edition + Versio + + + + + + Version + Versio + + + + + Type + Tyyppi + + + + + + Processor + Suoritin + + + + + + Memory + Muisti + + + + + + + Bit + Bitti + + + + + Available + Saatavilla + + + + Obtaining... + Saaminen... + + + + ConnectToServerDialog + + + Connect to Server + Yhdistä palvelimeen + + + + Cancel + button + Peruuta + + + + Connect + button + Yhdistä + + + + My Favorites: + Suosikkini: + + + + + Clear History + Tyhjennä historia + + + + DFMAddressBar + + + Search or enter address + Etsi tai anna osoite + + + + DFMAdvanceSearchBar + + + Search: + Etsi: + + + + File Type: + Tiedoston tyyppi: + + + + File Size: + Tiedoston koko: + + + + Time Modified: + Muokattu: + + + + Time Accessed: + Käytetty: + + + + Time Created: + Luotu: + + + + Reset + Nollaa + + + + All subdirectories + Kaikki alihakemistot + + + + Current directory + Nykyinen hakemisto + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 Mt + + + + 1 MB ~ 10 MB + 1 Mt ~ 10 Mt + + + + 10 MB ~ 100 MB + 10 Mt ~ 100 Mt + + + + 100 MB ~ 1 GB + 100 Mt ~ 1 Gt + + + + > 1 GB + > 1 Gt + + + + Today + Tänään + + + + Yesterday + Eilen + + + + This week + Tämä viikko + + + + Last week + Viime viikko + + + + This month + Tässä kuussa + + + + Last month + Viime kuussa + + + + This year + Tämä vuosi + + + + Last year + Viime vuosi + + + + DFMOpticalMediaWidget + + + + No files to burn + Ei tallennettavia tiedostoja + + + + Unable to burn. Not enough free space on the target disk. + Polttaminen ei onnistu. Kohdelevyllä ei ole riittävästi vapaata tilaa. + + + + %1 burning is not supported + %1 polttamista ei tueta + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. Tämä ei ole %1 levy; +2. Tämän tiedostojärjestelmän versio ei tue vielä tiedostojen lisäämistä. + + + + DFMTagCrumbController + + + Tag information + Lisää tunniste + + + + DFMTagWidget + + + Tag + Tunniste + + + + DFMTaskWidget + + + Do not ask again + Älä kysy uudestaan + + + + Syncing data + Tietojen synkronointi + + + + Please wait + Odota + + + + + Time modified: %1 + Muokattu: %1 + + + + + Contains: %1 + Sisältää: %1 + + + + + Size: %1 + Koko: %1 + + + + Original folder + Alkuperäinen kansio + + + + Keep both + button + Pidä molemmat + + + + Skip + button + Ohita + + + + Replace + button + Korvaa + + + + Retry + button + Uudelleen + + + + Original file + Alkuperäinen tiedosto + + + + Target folder + Kohde kansio + + + + Target file + Kohde tiedosto + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Salaa tiedostovarasto + + + + Click 'Encrypt' and input the user password. + Napsauta 'Salaa' ja anna käyttäjän salasana. + + + + Encrypting... + Salataan... + + + + + + + Encrypt + Salaa + + + + Failed to create file vault: %1 + Varaston luominen epäonnistui: %1 + + + + OK + OK + + + + The setup is complete + Asennus on valmis + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Tallenna palautusavain + + + + Keep the key safe to retrieve the vault password later + Pidä avain turvassa, jotta voit hakea holvin salasanan myöhemmin + + + + Save to default path + Tallenna oletuspolkuun + + + + Save to other locations + Tallenna toiseen sijaintiin + + + + No permission, please reselect + Ei oikeuksia, valitse uudelleen + + + + Select a path + Valitse polku + + + + Next + Seuraava + + + + The default path is invisible to other users, and the path information will not be shown. + Oletuspolku on näkymätön muille käyttäjille, eikä polkutietoa näytetä. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Palautusavain + + + + Generate a recovery key in case that you forgot the password + Luo palautusavain siltä varalta, että unohdit salasanan + + + + Key + Avain + + + + QR code + QR-koodi + + + + Scan QR code and save the key to another device + Skannaa QR-koodi ja tallenna avain toiseen laitteeseen + + + + Next + Seuraava + + + + Recovery Key: + Palautusavain: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Aseta tietovaraston salasana + + + + Method + Menetelmä + + + + Manual + Manuaalinen + + + + Password + Salasana + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 merkkiä, sisältäen A-Z-, a-z-, 0-9 ja erikoismerkit + + + + Repeat password + Toista salasana + + + + Input the password again + Anna salasana uudelleen + + + + Password hint + Salasanavihje + + + + Optional + Valinnainen + + + + Next + Seuraava + + + + + Passwords do not match + Salasanat eivät täsmää + + + + DFMVaultActiveStartView + + + File Vault + Tiedostoholvi + + + + Create your secure private space + Luo suojattu yksityinen tila + + + + Advanced encryption technology + Edistynyt salaustekniikka + + + + Convenient and easy to use + Kätevä ja helppokäyttöinen + + + + Create + Luo + + + + DFMVaultFileView + + + Cannot open this path + Tätä polkua ei voi avata + + + + Hint + Vihje + + + + OK + OK + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Avaa avaimella + + + + Failed to unlock file vault + Varaston lukituksen poistaminen epäonnistui + + + + OK + OK + + + + Input the 32-digit recovery key + Anna 32-numeroinen palautusavain + + + + Cancel + button + Peruuta + + + + Unlock + button + Avaa + + + + Wrong recovery key + Väärä palautusavain + + + + DFMVaultRemoveByPasswordView + + + Password + Salasana + + + + Password hint: %1 + Salasanavihje: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Anna 32-numeroinen palautusavain + + + + DFMVaultRemovePages + + + Delete File Vault + Poista tietovarasto + + + + Once deleted, the files in it will be permanently deleted + Tiedostot poistetaan pysyvästi + + + + Use Key + Käytä avainta + + + + Cancel + button + Peruuta + + + + Use Key + button + Käytä avainta + + + + Delete + button + Poista + + + + + OK + button + OK + + + + Use Password + Käytä salasanaa + + + + Wrong password + Väärä salasana + + + + Wrong recovery key + Väärä palautusavain + + + + Failed to delete file vault + Varaston poistaminen epäonnistui + + + + Deleted successfully + Poistettu onnistuneesti + + + + Failed to delete + Poistaminen epäonnistui + + + + Removing... + Poistetaan... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + Avaintiedostoa ei voi hakea + + + + Verification failed + Tarkistaminen epäonnistui + + + + + Select a path + Valitse polku + + + + + Retrieve Password + Hae salasana + + + + By key in the default path + Oletuspolun avaimella + + + + By key in the specified path + Avaimella määritetyssä polussa + + + + Verification Successful + Tarkistaminen onnistui + + + + Keep it safe + Pidä se turvassa + + + + Back + button + Takaisin + + + + Verify Key + button + Vahvista avain + + + + Go to Unlock + button + Lukituksen avaamiseen + + + + Close + button + Sulje + + + + Vault password: %1 + Holvin salasana: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Avaa tiedostovaraston lukitus + + + + Forgot password? + Unohtuiko salasana? + + + + Password hint: %1 + Salasanavihje: %1 + + + + Failed to unlock file vault + Varaston lukituksen poistaminen epäonnistui + + + + Cancel + button + Peruuta + + + + Password + Salasana + + + + Unlock + button + Avaa + + + + Please try again %1 minutes later + Yritä uudelleen %1 minuuttia myöhemmin + + + + Wrong password, please try again %1 minutes later + Väärä salasana, yritä uudelleen %1 minuuttia myöhemmin + + + + Wrong password, one chance left + Väärä salasana, yksi mahdollisuus jäljellä + + + + Wrong password, %1 chances left + Väärä salasana, %1 mahdollisuutta jäljellä + + + + Wrong password + Väärä salasana + + + + OK + button + OK + + + + DFileCopyMoveJob + + + Permission error + Käyttöoikeusvirhe + + + + The action is denied + Toimenpide on evätty + + + + Failed to open the file + Tiedoston avaaminen epäonnistui + + + + Failed to read the file + Tiedoston lukeminen epäonnistui + + + + Failed to write the file + Tiedoston kirjoittaminen epäonnistui + + + + Failed to create the directory + Kansion luominen epäonnistui + + + + Failed to delete the file + Tiedoston poistaminen epäonnistui + + + + Failed to move the file + Tiedoston siirtäminen epäonnistui + + + + Original file does not exist + Alkuperäistä tiedostoa ei ole + + + + Failed, file size must be less than 4GB + Epäonnistui, tiedoston koko on oltava alle 4Gt + + + + Not enough free space on the target disk + Kohdelevyllä ei ole tarpeeksi vapaata tilaa + + + + File integrity was damaged + Tiedoston eheys oli vaurioitunut + + + + The target device is read only + Kohde on vain luku-muodossa + + + + Target folder is inside the source folder + Kohdekansio on lähdekansion sisällä + + + + The action is not supported + Tätä toimintoa ei tueta + + + + You do not have permission to traverse files in it + Sinulla ei ole käyttöoikeutta tiedostoihin + + + + Failed to position the file pointer! + Tiedosto-osoittinta ei sijoitettu! + + + + copy + Extra name added to new file name when used for file name. + kopioi + + + + Failed to open the directory, cause: file name too long + Kansion avaaminen epäonnistui, syy: nimi on liian pitkä + + + + + Failed to open the file, cause: file name too long + Tiedoston avaaminen epäonnistui, syy: nimi on liian pitkä + + + + + Failed to write the file, cause: + Tiedoston kirjoittaminen epäonnistui, syy: + + + + Failed to position the file pointer, cause: %1 + Tiedosto-osoittinta ei sijoitettu, syy: %1 + + + + Syncing data + Tietojen synkronointi + + + + Please wait + Odota + + + + Failed to create the directory, cause: %1 + Kansion luominen epäonnistui, syy: %1 + + + + + + + + Failed to open the file, cause: %1 + Tiedoston avaaminen epäonnistui, syy: %1 + + + + + + + Failed to open the file, cause: Permission denied + Tiedoston avaaminen epäonnistui, syy: Käyttö estetty + + + + + Failed to read the file, cause: %1 + Tiedoston lukeminen epäonnistui, syy: %1 + + + + + + + Failed to write the file, cause: %1 + Tiedoston kirjoittaminen epäonnistui, syy: %1 + + + + + File integrity was damaged, cause: %1 + Tiedoston eheys oli vaurioitunut, syy: %1 + + + + Failed to open the file, cause: + Tiedoston avaaminen epäonnistui, syy: + + + + Failed to read the file, cause: + Tiedoston lukeminen epäonnistui, syy: + + + + Failed to delete the file, cause: %1 + Tiedoston poistaminen epäonnistui, syy: %1 + + + + Fail to create symlink, cause: %1 + Symlinkin luominen epäonnistui, syy: %1 + + + + DFileDialog + + + + Save + button + Tallenna + + + + + Cancel + button + Peruuta + + + + Confirm + button + Vahvista + + + + %1 already exists, do you want to replace it? + %1 on jo olemassa, haluatko korvata sen? + + + + Replace + button + Korvaa + + + + Open + button + Avaa + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Tämä tiedosto piilotetaan, jos tiedoston nimi alkaa pisteellä (.). Haluatko piilottaa sen? + + + + DFileManagerWindow + + + Trash + Roskakori + + + + Empty + Tyhjennä + + + + DFileSystemModel + + + + Name + Nimi + + + + + + Time modified + Muokattu + + + + Size + Koko + + + + Type + Tyyppi + + + + Time created + Luotu + + + + + Last access + Viimeisin käyttö + + + + + + + Path + Polku + + + + DFileView + + + Disc mount error + Levyn kiinnitysvirhe + + + + The disc is in use, please end the running process and remount the disc. + Levy on käytössä, lopeta käynnissä oleva prosessi ja liitä levy uudelleen. + + + + Mounting failed + Liittäminen epäonnistui + + + + (Reverse) + (Käänteinen) + + + + DFileViewHelper + + + Add tag "%1" + Lisää tunniste "%1" + + + + DStatusBar + + + %1 item + %1 kohde + + + + %1 items + %1 kohdetta + + + + %1 item selected + %1 kohde valittuna + + + + %1 items selected + %1 kohdetta valittuna + + + + %1 folder selected (contains %2) + %1 kansio valittu (sisältää %2) + + + + %1 folders selected (contains %2) + %1 kansiota valittu (sisältää %2) + + + + %1 file selected (%2) + %1 tiedosto valittu (%2) + + + + %1 files selected (%2) + %1 tiedostoa valittu (%2) + + + + %1 folder selected + %1 kansio valittuna + + + + Filter + Suodatin + + + + Save as: + Tallenna nimellä: + + + + Loading... + Lataa... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Tyhjentää levyä %1, odota hetki... + + + + Burning disc %1, please wait... + Kirjoittaa levyä %1, odota hetki... + + + + Writing data... + Kirjoitetaan tietoja... + + + + Verifying data... + Tarkistetaan tietoja... + + + + Copying %1 + Kopioi %1 + + + + + + to %2 + / %2 + + + + %1 already exists in target folder + %1 on jo kohdekansiossa + + + + Original path %1 Target path %2 + Alkuperäinen %1, kode %2 + + + + Merge + button + Liitä + + + + Replace + button + Korvaa + + + + Moving %1 + Siirtää %1 + + + + Removing file vault, please try later + Varaston poisto, kokeile myöhemmin uudelleen + + + + Restoring %1 + Palautus %1 + + + + Deleting %1 + Poistaa %1 + + + + Trashing %1 + Tuhoaa %1 + + + + Calculating space, please wait + Lasketaan tilaa, odota hetki + + + + DUMountManager + + + + Authentication timed out + Todennus aikakatkaistiin + + + + + + Disk is busy, cannot unmount now + Levy on varattu, ei voi irrottaa + + + + Disk is busy, cannot eject now + Levy varattu, ei voi poistaa nyt + + + + The device is busy, cannot eject now + Laite on varattu, eikä sitä voi avata + + + + + + The device is busy, cannot remove now + Laite on varattu, eikä sitä voi poistaa + + + + DeepinStorage + + + + + %1 Volume + %1 Levy + + + + Data Disk + Data Partition + Kiintolevy + + + + %1 Drive + %1 asema + + + + Blank %1 Disc + Tyhjä %1 levy + + + + %1 Encrypted + %1 salattu + + + + DialogManager + + + + + + Operation failed! + Toimenpide epäonnistui! + + + + Target folder is inside the source folder! + Kohdekansio on lähdekansion sisällä! + + + + Do you want to run %1 or display its content? + Haluatko suorittaa %1 :n tai näyttää sen sisällön? + + + + It is an executable text file. + On suoritettava tekstitiedosto. + + + + It is an executable file. + On suoritettava tiedosto. + + + + This file is not executable, do you want to add the execute permission and run? + Tätä tiedostoa ei voi suorittaa, haluatko lisätä suoritusluvan ja suorittaa? + + + + "%1" already exists, please use another name. + "%1" on jo olemassa, käytä toista nimeä. + + + + The file name must not contain two dots (..) + Tiedoston nimi ei saa sisältää kahta pistettä (..) + + + + Device or resource busy + Laite tai resurssi varattu + + + + Are you sure you want to erase all data on the disc? + Haluatko varmasti poistaa kaikki levyllä olevat tiedot? + + + + How do you want to use this disc? + Miten haluat käyttää tätä levyä? + + + + Disc erase failed + Levyn tyhjentäminen epäonnistui + + + + Burn process failed + Polttoprosessi epäonnistui + + + + %1: %2 + %1: %2 + + + + Show details + Näytä tiedot + + + + Hide details + Piilota tiedot + + + + Error + Virhe + + + + Permanently delete %1? + Poista %1 pysyvästi? + + + + Permanently delete %1 items? + Poista kohteet %1 pysyvästi? + + + + Empty + Tyhjennä + + + + Do you want to delete %1? + Haluatko poistaa kohteen %1? + + + + Do you want to delete the selected %1 items? + Haluatko poistaa valitut %1 kohdetta? + + + + Sorry, unable to locate your bookmark directory, remove it? + Valitettavasti kirjamerkkihakemistoasi ei löydy, poistetaanko se? + + + + Name: + Nimi: + + + + %1 that this shortcut refers to has been changed or moved + %1 pikakuvakkeen kohde on muutettu tai siirretty + + + + Do you want to delete this shortcut? + Haluatko poistaa tämän pikakuvakkeen? + + + + Failed, file size must be less than 4GB. + Epäonnistui, tiedoston koon on oltava alle 4 Gt. + + + + Fail to create symlink, cause: + Symlinkin luominen epäonnistui, syy: + + + + The selected files contain system file/directory, and it cannot be deleted + Valitut tiedostot sisältävät järjestelmätiedoston / hakemiston, ei voi poistaa + + + + Unable to find the original file + Alkuperäistä tiedostoa ei löydy + + + + + You do not have permission to operate file/folder! + Sinulla ei ole lupaa käyttää tiedostoa / kansiota! + + + + Failed to restore %1 file, the source file does not exist + Tiedoston %1 palauttaminen epäonnistui, lähdetiedostoa ei ole + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Valitettavasti sinulla ei ole lupaa käyttää seuraavia %1 tiedostoja/kansioita! + + + + Unable to access %1 + Ei oikeuksia %1 + + + + + Sending files now, please try later + Lähetetään tiedostoja nyt, kokeile myöhemmin uudelleen + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Laitteen käyttämiseksi sinun on ensin alustettava levy. Haluatko varmasti alustaa sen nyt? + + + + Scanning the device, stop it? + Skannaa laitetta, pysäytä se? + + + + Share folder can't be named after the current username + Jaettua kansiota ei voi nimetä nykyisen käyttäjätunnuksen mukaan + + + + Do you want to run %1? + Haluatko suorittaa %1? + + + + Burn image + button + Kirjoita levykuva + + + + Burn files + button + Kirjoita tiedostot + + + + Are you sure you want to empty %1 item? + Haluatko varmasti tyhjentää %1 kohteen? + + + + Are you sure you want to empty %1 items? + Haluatko varmasti tyhjentää %1 kohdetta? + + + + + This action cannot be undone + Tätä toimintoa ei voi peruuttaa + + + + + + + + + + + + + + OK + button + OK + + + + + + + + + + + + + + + Cancel + button + Peruuta + + + + + + Run + button + Suorita + + + + + Run in terminal + button + Suorita päätteessä + + + + Display + button + Näyttö + + + + + + + + + + + Confirm + button + Vahvista + + + + Erase + button + Tyhjennä + + + + Data verification failed + Tietojen tarkistaminen epäonnistui + + + + Show details + button + Näytä tiedot + + + + + Delete + button + Poista + + + + Remove + button + Poista + + + + Disk is busy, cannot unmount now + Levy varattu, ei voi irrottaa nyt + + + + Force unmount + button + Pakota irrotus + + + + Unable to copy. Not enough free space on the target disk. + Kopioiminen ei onnistu. Kohdelevyllä ei ole tarpeeksi vapaata tilaa. + + + + Failed to restore %1 file, the target folder is read-only + Tiedoston %1 palauttaminen epäonnistui, kohdekansio on vain luku -tilassa + + + + Failed to restore %1 files, the target folder is read-only + Tiedostojen %1 palauttaminen epäonnistui, kohdekansio on vain luku -tilassa + + + + Failed to restore %1 files, the source files do not exist + Tiedostojen %1 palauttaminen epäonnistui, lähdetiedostoja ei ole + + + + Format + button + Alusta + + + + Stop + button + Seis + + + + FileController + + + + + + Unable to find the original file + Alkuperäistä tiedostoa ei löydy + + + + + + Kindly Reminder + Ystävällinen muistutus + + + + + + Please install File Roller first and then continue + Asenna ensin File Roller ja jatka sitten + + + + + Unable to create files here: %1 + Tiedostoja ei voi luoda tähän: %1 + + + + Confirm + button + Vahvista + + + + FileDialogStatusBar + + + File Name + Tiedoston nimi + + + + Format + Alusta + + + + Save + button + Tallenna + + + + Open + button + Avaa + + + + Save File + button + Tallenna tiedosto + + + + Open File + button + Avaa tiedosto + + + + + + Cancel + button + Peruuta + + + + FileJob + + + copy + kopioi + + + + + + + Data verification successful. + Tietojen tarkistaminen onnistui. + + + + + + Burn process completed + Polttoprosessi valmis + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 t %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 vrk %2 t %3 m %4 s + + + + %1 is a duplicate file. + %1 on tiedoston kaksoiskappale. + + + + Insufficient disc space. + Levytila ei riitä. + + + + Lost connection to drive. + Asemaan kadonnut yhteys. + + + + The CD/DVD drive is not ready. Try another disc. + CD/DVD-asema ei ole valmis. Kokeile toista levyä. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + CD/DVD-asema on varattu. Poistu ohjelmasta aseman avulla ja kytke asema uudelleen. + + + + Unknown error + Tuntematon virhe + + + + Device disconnected + Laite irrotettu + + + + GenerateSettingTranslate + + + + + Basic + Perustiedot + + + + + + Open behavior + Avaamiskäytäntö + + + + + + Always open folder in new window + Avaa kansio aina uudessa ikkunassa + + + + + + Open file: + Avaa tiedosto: + + + + + + Click + Klikkaus + + + + + + Double click + Tuplaklikkaus + + + + + + New window and tab + Ikkuna ja välilehti + + + + + + Open from default window: + Avaa oletuksena ikkunassa: + + + + + + + + + Computer + Tietokone + + + + + + + + + Home + Koti + + + + + + + + + Desktop + Työpöytä + + + + + + + + + Videos + Videot + + + + + + + + + Music + Musiikki + + + + + + + + + Pictures + Kuvat + + + + + + + + + Documents + Asiakirjat + + + + + + + + + Downloads + Lataukset + + + + + + Open in new tab: + Avaa uudessa välilehdessä: + + + + + + Current Directory + Nykyinen kansio + + + + + + View + Näytä + + + + + + Default size: + Oletuskoko: + + + + + + Extra small + Pienin + + + + + + Small + Pieni + + + + + + Medium + Keskikoko + + + + + + Large + Suuri + + + + + + Extra large + Suurin + + + + + + Default view: + Oletusnäkymä: + + + + + + Icon + Kuvake + + + + + + List + Lista + + + + + + Hidden files + Piilotiedostot + + + + + + Show hidden files + Näytä piilotiedostot + + + + + + Hide file extension when rename + Piilota tiedostopääte nimettäessä uudelleen + + + + + + Advanced + Lisäasetukset + + + + + + Index + Indeksi + + + + + + Auto index internal disk + Indeksoi automaattisesti sisäinen levy + + + + + + Index external storage device after connected to computer + Indeksoi ulkoinen tallennuslaite kytkettäessä tietokoneeseen + + + + + + Full-Text search + Täysi tekstihaku + + + + + + Show item counts and sizes in the path of mounted MTP devices + Näytä nimikkeiden määrät ja koot MTP-laitteiden polussa + + + + + + Keep showing the mounted Samba shares + Näytä käyttöönotetut Samba-jaetut kansiot + + + + + + Use the file chooser dialog of File Manager + Käytä tiedostonhallinnan valintaikkunaa + + + + + + Ask for my confirmation when deleting files + Pyydä vahvistukseni tiedostoja poistettaessa + + + + + + Other + Muut + + + + + + Hide system disk + Piilota järjestelmän levy + + + + + + Show file system on disk icon + Näytä kuvake järjestelmän asemasta + + + + + + Show hidden files in search results + Näytä piilotetut tiedostot hakutuloksissa + + + + + + Display recent file entry in left panel + Näytä historia vasemmassa paneelissa + + + + + + Preview + Esikatselu + + + + + Compress file preview + Pakkaa tiedoston esikatselu + + + + + + Text preview + Tekstin esikatselu + + + + + + Document preview + Asiakirjan esikatselu + + + + + + Image preview + Kuvan esikatselu + + + + + + Video preview + Videon esikatselu + + + + + + Mount + Liitä + + + + + + Auto mount + Liitä automaattisesti + + + + + + Open after auto mount + Avaa automaattisen liittämisen jälkeen + + + + + + Dialog + Valintaikkuna + + + + Compressed file preview + Pakatun tiedoston esikatselu + + + + GvfsMountManager + + + Can’t verify the identity of %1. + %1 henkilöllisyyttä ei voida vahvistaa. + + + + This happens when you log in to a computer the first time. + Näin tapahtuu, kun kirjaudut tietokoneeseen ensimmäisen kerran. + + + + The identity sent by the remote computer is + Etätietokoneen lähettämät tunnistetiedot ovat + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Jos haluat olla täysin varma, että on turvallista jatkaa, ota yhteyttä järjestelmänvalvojaan. + + + + + + + + Mounting device error + Asennuslaitteen virhe + + + + + Wrong username or password + Väärä käyttäjätunnus tai salasana + + + + + + + + Confirm + button + Vahvista + + + + + Cannot find the mounted device + Liitettyä laitetta ei löydy + + + + No key available to unlock device + Laitetta ei voida avata avaimella jota ei ole + + + + The disk is mounted by user "%1", you cannot unmount it. + Levyä käyttää käyttäjä "%1", et voi irrottaa sitä. + + + + Cannot unmount the device + Laitteen irrottaminen ei onnistu + + + + Cannot eject the device "%1" + Laitetta ei voi poistaa "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Polttaminen ei onnistu. Kohdelevyllä ei ole riittävästi vapaata tilaa. + + + + MergedDesktopController + + + + Pictures + Kuvat + + + + + Music + Musiikki + + + + + Applications + Sovellukset + + + + + Videos + Videot + + + + + Documents + Asiakirjat + + + + + Others + Muut + + + + MimeTypeDisplayManager + + + + Directory + Hakemisto + + + + + + Application + Sovellus + + + + + + Video + Video + + + + + + Audio + Ääni + + + + + + Image + Kuva + + + + + Archive + Arkisto + + + + + + Text + Teksti + + + + + Executable + Suoritettava + + + + + Backup file + Varmuuskopio + + + + + Unknown + Tuntematon + + + + MountAskPasswordDialog + + + Cancel + button + Peruuta + + + + Connect + button + Yhdistä + + + + Log in as + Kirjaudu sisään + + + + Anonymous + Anonyymi + + + + Registered user + Rekisteröitynyt käyttäjä + + + + Username + Käyttäjätunnus + + + + Domain + Verkkotunnus + + + + Password + Salasana + + + + Remember password + Muista salasana + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Peruuta + + + + Unlock + button + Avaa + + + + Input password to decrypt the disk + Syötä salasana levyn salaamiseksi + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Haluatko varmasti poistaa pysyvästi %1? + + + + This file is too big for the trash + Tämä tiedosto on liian suuri roskakoriin + + + + The files are too big for the trash + Tiedostot ovat liian suuria roskakoriin + + + + Are you sure you want to permanently delete %1 files? + Haluatko varmasti poistaa tiedostot %1 pysyvästi? + + + + Cancel + button + Peruuta + + + + Delete + button + Poista + + + + OpenWithDialog + + + Open with + Avaa sovelluksella + + + + Add other programs + Lisää muita ohjelmia + + + + Set as default + Määrää oletus + + + + Cancel + button + Peruuta + + + + Confirm + button + Vahvista + + + + Recommended Applications + Suositellut sovellukset + + + + Other Applications + Muut sovellukset + + + + PathManager + + + Home + Koti + + + + Desktop + Työpöytä + + + + Videos + Videot + + + + Music + Musiikki + + + + Pictures + Kuvat + + + + Documents + Asiakirjat + + + + Downloads + Lataukset + + + + + Trash + Roskakori + + + + + + System Disk + Järjestelmä + + + + Computers in LAN + Lähiverkossa + + + + My Shares + Jaetut kansiot + + + + Computer + Tietokone + + + + Recent + Historia + + + + File Vault + Tiedostoholvi + + + + PropertyDialog + + + Basic info + Perustiedot + + + + Open with + Avaa sovelluksella + + + + Sharing + Jakaminen + + + + Permissions + Käyttöoikeudet + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Piilota tämä kansio + + + + Hide this file + Piilota tämä tiedosto + + + + Allow to execute as program + Salli suorittaa ohjelmana + + + + QObject + + + + + + Size + Koko + + + + + + Contains + Sisältää + + + + + + Type + Tyyppi + + + + + + + + Time modified + Muokattu + + + + Free space + Vapaa tila + + + + Total space + Kokonaistila + + + + + Time locked + Lukittu aika + + + + Access denied + Pääsy evätty + + + + + Executable + Suoritettava + + + + + Write only + Vain kirjoitus + + + + + Read only + Vain luku + + + + + Read-write + Luku-kirjoitus + + + + Others + Muut + + + + Owner + Omistaja + + + + Unconnected network shared directory + Yhdistämättömän verkon jaettu kansio + + + + Device type + Laitetyyppi + + + + File system + Tiedostojärjestelmä + + + + Group + Ryhmä + + + + + Open + Avaa + + + + Lock + Lukko + + + + Auto lock + Automaattinen lukitus + + + + Never + Ei koskaan + + + + 5 minutes + 5 minuuttia + + + + 10 minutes + 10 minuuttia + + + + 20 minutes + 20 minuuttia + + + + Delete File Vault + Poista tietovarasto + + + + Unlock + Avaa + + + + Unlock by key + Avaa avaimella + + + + Open + button + Avaa + + + + + Size: %1 + Koko: %1 + + + + Type: %1 + Tyyppi: %1 + + + + Size: 0 + Koko: 0 + + + + Items: %1 + Kohdetta: %1 + + + + + + + + + + Open in new window + Avaa uudessa ikkunassa + + + + + + + + + + Open in new tab + Avaa uudessa välilehdessä + + + + Open with + Avaa sovelluksella + + + + + Compress + Pakkaa + + + + Extract + Pura + + + + Extract here + Pura tähän + + + + Cut + Leikkaa + + + + Copy + Kopioi + + + + Paste + Liitä + + + + + + + + Rename + Nimeä uudelleen + + + + + + + Remove + Poista + + + + Create link + Luo linkki + + + + Send to desktop + Lähetä työpöydälle + + + + Send to + Lähetä + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Lisää kirjamerkkeihin + + + + + + + Properties + Ominaisuudet + + + + New folder + Uusi kansio + + + + New window + Uusi ikkuna + + + + Select all + Valitse kaikki + + + + + Clear recent history + Tyhjennä historia + + + + + + Empty Trash + Tyhjennä roskakori + + + + Display as + Näytä + + + + Sort by + Järjestä + + + + New document + Uusi asiakirja + + + + + Time created + Luotu + + + + + + Source path + Lähteen polku + + + + Share folder + Jaettu kansio + + + + Cancel sharing + Peruuta jakaminen + + + + Connect to Server + Yhdistä palvelimeen + + + + Set share password + Aseta jakamisen salasana + + + + Format + Alusta + + + + Tag information + Lisää tunniste + + + + Open as administrator + Avaa pääkäyttäjänä + + + + Select default program + Valitse oletusohjelma + + + + Open file location + Avaa tiedoston sijainti + + + + Remove bookmark + Poista kirjamerkki + + + + + + Delete + Poista + + + + Office Text + Asiakirja + + + + Spreadsheets + Taulukko + + + + Plain Text + Tekstitiedosto + + + + Open in terminal + Avaa päätteessä + + + + Restore + Palauta + + + + Restore all + Palauta kaikki + + + + Clear saved password and unmount + Tyhjennä tallennettu salasana ja poista + + + + File Vault + Tiedostoholvi + + + + Add to disc + Lisää levylle + + + + Refresh + Virkistä + + + + Auto mount + Liitä automaattisesti + + + + Open after auto mount + Avaa automaattisen liittämisen jälkeen + + + + + Mount + Liitä + + + + + Unmount + Irrota + + + + It does not support burning %1 discs + Levyjen %1 polttamista ei tueta + + + + Burn + Kirjoita CD-DVD + + + + Disc name: + Levyn nimi: + + + + + Maximum + Enimmäisnopeus + + + + Allow files to be added later + Salli tiedostojen lisääminen myöhemmin + + + + Verify data + Tarkista sisältö + + + + Write speed: + Kirjoitusnopeus: + + + + + + + Cancel + button + Peruuta + + + + Burn + button + Kirjoita CD-DVD + + + + + Eject + Poista + + + + Safely Remove + Poista turvallisesti + + + + + Name + Nimi + + + + Settings + Asetukset + + + + Exit + Poistu + + + + Icon + Kuvake + + + + List + Lista + + + + Extend + Laajenna + + + + Set as wallpaper + Aseta taustakuvaksi + + + + + + + Local disk + Paikallinen levy + + + + + Removable disk + Irroitettava levy + + + + + + Network shared directory + Lähiverkon jaettu hakemisto + + + + + Android mobile device + Android mobiililaite + + + + + Apple mobile device + Apple mobiililaite + + + + + Camera + Kamera + + + + + DVD + DVD + + + + + Unknown device + Tuntematon laite + + + + + + %1 item + %1 kohde + + + + + + %1 items + %1 kohdetta + + + + Shortcut + Pikakuvake + + + + Create symlink + Luo symlinkki + + + + Path + Polku + + + + + + Time deleted + Aika poistettu + + + + Loading... + Lataa... + + + + File has been moved or deleted + Tiedosto on siirretty tai poistettu + + + + You do not have permission to traverse files in it + Sinulla ei ole käyttöoikeutta tiedostoihin + + + + + + You do not have permission to access this folder + Sinulla ei ole oikeutta käyttää tätä kansiota + + + + + + + + Folder is empty + Kansio on tyhjä + + + + Searching... + Etsitään... + + + + No results + Ei tuloksia + + + + Source Path + TrashFileInfo + Lähteen polku + + + + Document + Asiakirja + + + + Spreadsheet + Taulukko + + + + + Presentation + Esitys + + + + Text + Teksti + + + + 1 task in progress + 1 käynnissä oleva tehtävä + + + + %1 tasks in progress + %1 käynnissä olevaa tehtävää + + + + Mode: + Moodi: + + + + + Replace Text + Korvaa teksti + + + + + Add Text + Lisää teksti + + + + + Custom Text + Mukautettu teksti + + + + Find: + Etsi: + + + + Replace: + Korvaa: + + + + + Optional + Valinnainen + + + + Add: + Lisää: + + + + Location: + Sijainti: + + + + File name: + Tiedoston nimi: + + + + Start at: + Alkaa: + + + + + Rename + button + Nimeä uudelleen + + + + + + + + + + + Required + Vaaditaan + + + + + Before file name + Ennen tiedoston nimeä + + + + + After file name + Tiedoston nimen jälkeen + + + + Find + Etsi + + + + Replace + Korvaa + + + + Add + Lisää + + + + Start at + Alkaa + + + + + + Location + Sijainti + + + + File name + Tiedoston nimi + + + + Dimension + Mitat + + + + Duration + Kesto + + + + Tips: Sort by selected file order + Vihje: Lajittele valitun tiedoston mukaan + + + + Rename %1 Files + Nimeä uudelleen %1 tiedostoa + + + + Multiple Files + Useita tiedostoja + + + + Basic info + Perustiedot + + + + Total size + Yhteensä + + + + Number of files + Tiedostojen määrä + + + + %1 file(s), %2 folder(s) + %1 tiedostoa, %2 kansiota + + + + + + Time accessed + Käytetty + + + + Orange + Oranssi + + + + Red + Punainen + + + + Purple + Violetti + + + + Navy-blue + Sininen + + + + Azure + Taivaansininen + + + + Green + Vihreä + + + + Yellow + Keltainen + + + + Gray + Harmaa + + + + Input tag info, such as work, family. A comma is used between two tags. + Tunnistetiedot, kuten työ, perhe, eritellään pilkuilla. + + + + Bookmarks + Kirjamerkit + + + + Erase + Tyhjennä + + + + Copy path + Kopioi kohde + + + + Edit address + Muokkaa osoitetta + + + + Free Space %1 + Vapaa tila %1 + + + + Files are being processed + Tiedostoja käsitellään + + + + + Unknown + Tuntematon + + + + My Vault + Minun tietovarasto + + + + + Failed to create file info + Tiedoston tietojen luonti epäonnistui + + + + Failed to create file handler + Tiedoston käsittelijän luonti epäonnistui + + + + Failed to open the file, cause: %1 + Tiedoston avaaminen epäonnistui, syy: %1 + + + + Original file does not exist + Alkuperäistä tiedostoa ei ole + + + + Do you want to delete %1? + Haluatko poistaa kohteen %1? + + + + Confirm + button + Vahvista + + + + + + + + %1 are not allowed + %1 eivät ole sallittuja + + + + + Failed to start Samba services + Samba-palveluiden käynnistäminen epäonnistui + + + + RecentController + + + Cancel + button + Peruuta + + + + Remove + button + Poista + + + + Do you want to remove this item? + Haluatko poistaa tämän kohteen? + + + + Do yout want to remove %1 items? + Haluatko poistaa %1 kohdetta? + + + + It does not delete the original files + Se ei poista alkuperäisiä tiedostoja + + + + ShareInfoFrame + + + Share this folder + Jaa tämä kansio + + + + Share name: + Jaettu nimi: + + + + Permission: + Lupa: + + + + Read and write + Lue ja kirjoita + + + + Read only + Vain luku + + + + Anonymous: + Anonyymi: + + + + Not allow + Ei sallittu + + + + Allow + Salli + + + + The share name must not be two dots (..) or one dot (.) + Jaetussa nimessä ei saa olla kahta pistettä (..) tai yhtä (.) + + + + The share name is used by another user. + Toinen käyttäjä käyttää jakonimeä. + + + + OK + button + OK + + + + Cancel + button + Peruuta + + + + Replace + button + Korvaa + + + + The share name already exists. Do you want to replace the shared folder? + Jaettu nimi on jo olemassa. Haluatko korvata jaetun kansion? + + + + Shortcut + + + Item + Kohde + + + + Select to the first item + Valitse ensimmäinen kohde + + + + Shift + Home + Shift + Home + + + + Select to the last item + Valitse viimeinen kohde + + + + Shift + End + Shift + End + + + + Select leftwards + Valitse vasemmalle + + + + Shift + Left + Shift + Left + + + + Select rightwards + Valitse oikealle + + + + Shift + Right + Shift + Right + + + + Select to upper row + Valitse yläreunaan + + + + Shift + Up + Shift + Up + + + + Select to lower row + Valitse alareunaan + + + + Shift + Down + Shift + Down + + + + Open + Avaa + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + Aikaisempaan hakemistoon + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Poista pysyvästi? + + + + Shift + Delete + Shift + Delete + + + + Delete file + Poista tiedosto + + + + Delete + Poista + + + + Select all + Valitse kaikki + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Kopioi + + + + Cut + Leikkaa + + + + Paste + Liitä + + + + Rename + Nimeä uudelleen + + + + F2 + F2 + + + + New/Search + Uusi/haku + + + + New window + Uusi ikkuna + + + + New folder + Uusi kansio + + + + + Search + Haku + + + + New tab + Uusi välilehti + + + + View + Näytä + + + + Item information + Kohteen tiedot + + + + Help + Apua + + + + F1 + F1 + + + + Keyboard shortcuts + Pikanäppäimet + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Vaihda näytön tila + + + + Hide item + Piilota kohde + + + + Input in address bar + Kirjoita osoiteriville + + + + Switch to icon view + Vaihda kuvakenäkymään + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Vaihda luettelonäkymään + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Muut + + + + Close + Sulje + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Sulje nykyinen välilehti + + + + Back + Takaisin + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Siirry seuraavaan välilehteen + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Vaihda edelliseen välilehteen + + + + Next file + Seuraava tiedosto + + + + Tab + Välilehti + + + + Previous file + Edellinen tiedosto + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Vaihda välilehteä määrätyllä numerolla 1 ja 8 väliltä + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Eteenpäin + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Roskakorin kohteita ei voi avata, palauta se ensin + + + + TrashPropertyDialog + + + Trash + Roskakori + + + + item + kohde + + + + items + kohdetta + + + + Contains %1 %2 + Sisältää %1 %2 + + + + UDiskListener + + + Failed to rename the label + Uudelleen nimeäminen epäonnistui + + + + UnmountWorker + + + + + The device was not safely unmounted + Laitetta ei poistettu turvallisesti + + + + The device was not safely removed + Laitetta ei poistettu turvallisesti + + + + UserShareManager + + + Kindly Reminder + Ystävällinen muistutus + + + + Please firstly install samba to continue + Asenna samba jatkaaksesi + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + Jaetun tiedoston nimessä ei saa olla %<>*?|/\+=;:," ,eikä saa alkaa %1 + + + + To protect the files, you cannot share this folder. + Tiedostojen suojaamiseksi et voi jakaa tätä kansiota. + + + + Sharing failed + Jakaminen epäonnistui + + + + The computer name is too long + Tietokoneen nimi on liian pitkä + + + + You do not have permission to operate file/folder! + Sinulla ei ole lupaa käyttää tiedostoa / kansiota! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Kirjoita salasana jaettujen kansioiden suojaamiseksi + + + + Cancel + button + Peruuta + + + + Confirm + button + Vahvista + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_fr.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_fr.ts new file mode 100644 index 0000000..fc9ea51 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_fr.ts @@ -0,0 +1,4715 @@ + + + AppController + + + New Folder + Nouveau dossier + + + + Mounting device error + Erreur de montage du périphérique + + + + The disc image was corrupted, cannot mount now, please erase the disc first + L'image du disque était corrompue, impossible à monter maintenant, veuillez d'abord effacer le disque + + + + Mount error: unsupported image format + Erreur de montage : format d'image non pris en charge + + + + + The device was not safely removed + Le périphérique n'a pas été retiré en toute sécurité + + + + + Click "Safely Remove" and then disconnect it next time + Cliquez sur "Supprimer en toute sécurité" et ensuite déconnectez-le + + + + The device was not ejected + Le périphérique n'a pas été éjecté + + + + Disk is busy, cannot eject now + Le disque est occupé, impossible de l'éjecter maintenant + + + + Authentication timed out + L'authentification a expiré + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Transfert de fichiers Bluetooth + + + + File Transfer Successful + Transfert de fichiers réussi + + + + File Transfer Failed + Le transfert de fichiers a échoué + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Envoi de fichiers à "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Échec de l'envoi des fichiers à "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Envoyé à "<b style="font-weight: 550;">%1</b>" avec succès + + + + Select a Bluetooth device to receive files + Sélectionnez un appareil Bluetooth pour recevoir des fichiers + + + + Cannot find the connected Bluetooth device + Impossible de trouver le périphérique Bluetooth connecté + + + + Waiting to be received... + En attente de réception... + + + + Go to Bluetooth Settings + Accéder aux paramètres Bluetooth + + + + %1/%2 Sent + %1/%2 envoyés + + + + Error: the Bluetooth device is disconnected + Erreur : l'appareil Bluetooth est déconnecté + + + + Unable to send the file more than 2 GB + Impossible d'envoyer un fichier de plus de 2 Go + + + + Unable to send 0 KB files + Impossible d'envoyer des fichiers de 0 Ko + + + + File doesn't exist + Le fichier n'existe pas + + + + Next + button + Suivant + + + + Cancel + button + Annuler + + + + Done + button + Terminé + + + + Retry + button + Réessayer + + + + OK + button + OK + + + + File sending request timed out + La demande d'envoi de fichier a expiré + + + + The service is busy and unable to process the request + Le service est occupé et ne peut pas traiter la demande + + + + BurnOptDialog + + + Device error + Erreur de périphérique + + + + Optical device %1 doesn't exist + Le périphérique optique %1 n'existe pas + + + + Advanced settings + Réglages avancés + + + + File system: + Système de fichiers : + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (pour Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (pour Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Compatible avec le mode Windows CD/DVD) + + + + ISO9660 Only + ISO9660 uniquement + + + + CloseAllDialogIndicator + + + Close all + Fermer tout + + + + Total size: %1, %2 files + Taille totale : %1, %2 fichiers + + + + ComputerModel + + + Double click to open it + + + + + My Directories + Dossiers + + + + Disks + Disques + + + + File Vault + Coffre-fort + + + + Quick Access + + + + + ComputerPropertyDialog + + + Computer + Ordinateur + + + + Basic Info + Informations de base + + + + + Computer Name + Nom de l'ordinateur + + + + + Edition + Édition + + + + + + Version + Version + + + + + Type + Type + + + + + + Processor + Processeur + + + + + + Memory + Mémoire + + + + + + + Bit + Bit + + + + + Available + Disponible + + + + Obtaining... + + + + + ConnectToServerDialog + + + Connect to Server + Se connecter au serveur + + + + Cancel + button + Annuler + + + + Connect + button + Se connecter + + + + My Favorites: + Mes favoris : + + + + + Clear History + Effacer l'historique + + + + DFMAddressBar + + + Search or enter address + Rechercher ou saisir une adresse + + + + DFMAdvanceSearchBar + + + Search: + Rechercher : + + + + File Type: + Type de fichier : + + + + File Size: + Taille du fichier : + + + + Time Modified: + Heure de modification : + + + + Time Accessed: + Temps d'accès : + + + + Time Created: + Heure de création : + + + + Reset + Réinitialiser + + + + All subdirectories + Tous les sous-répertoires + + + + Current directory + Répertoire actuel + + + + 0 ~ 100 KB + 0 ~ 100 Ko + + + + 100 KB ~ 1 MB + 100 Ko ~ 1 Mo + + + + 1 MB ~ 10 MB + 1 Mo ~ 10 Mo + + + + 10 MB ~ 100 MB + 10 Mo ~ 100 Mo + + + + 100 MB ~ 1 GB + 100 Mo ~ 1 Go + + + + > 1 GB + > 1 Go + + + + Today + Aujourd'hui + + + + Yesterday + Hier + + + + This week + Cette semaine + + + + Last week + La semaine dernière + + + + This month + Ce mois-ci + + + + Last month + Le mois dernier + + + + This year + Cette année + + + + Last year + L'année dernière + + + + DFMOpticalMediaWidget + + + + No files to burn + Aucun fichier à graver + + + + Unable to burn. Not enough free space on the target disk. + Impossible de graver. Espace libre insuffisant sur le disque cible. + + + + %1 burning is not supported + Gravure de %1 non supporté + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + + + + + DFMTagCrumbController + + + Tag information + Informations des balises + + + + DFMTagWidget + + + Tag + Tag + + + + DFMTaskWidget + + + Do not ask again + Ne plus demander + + + + Syncing data + Synchronisation des données + + + + Please wait + Veuillez attendre, s'il vous plaît + + + + + Time modified: %1 + Heure de modification : %1 + + + + + Contains: %1 + Contient : %1 + + + + + Size: %1 + Taille : %1 + + + + Original folder + Dossier d'origine + + + + Keep both + button + Conserver les deux + + + + Skip + button + Ignorer + + + + Replace + button + Remplacer + + + + Retry + button + Réessayer + + + + Original file + Fichier d'origine + + + + Target folder + Dossier cible + + + + Target file + Fichier cible + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Crypter le coffre-fort des fichiers + + + + Click 'Encrypt' and input the user password. + Cliquez sur "Crypter" et saisissez le mot de passe de l'utilisateur. + + + + Encrypting... + Cryptage... + + + + + + + Encrypt + Crypter + + + + Failed to create file vault: %1 + Échec de la création du coffre-fort de fichiers : %1 + + + + OK + OK + + + + The setup is complete + La configuration est terminée + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + + + + + Keep the key safe to retrieve the vault password later + + + + + Save to default path + + + + + Save to other locations + + + + + No permission, please reselect + + + + + Select a path + + + + + Next + Suivant + + + + The default path is invisible to other users, and the path information will not be shown. + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Clé de récupération + + + + Generate a recovery key in case that you forgot the password + Générer une clé de récupération au cas où vous auriez oublié le mot de passe + + + + Key + Clé + + + + QR code + QR Code + + + + Scan QR code and save the key to another device + Scanner le code QR et enregistrer la clé sur un autre périphérique + + + + Next + Suivant + + + + Recovery Key: + Clé de récupération : + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Définir le mot de passe du coffre-fort + + + + Method + Méthode + + + + Manual + Manuel + + + + Password + Mot de passe + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 caractères, contient A-Z, a-z, 0-9 et symboles + + + + Repeat password + Répéter le mot de passe + + + + Input the password again + Saisir à nouveau le mot de passe + + + + Password hint + Indice de mot de passe + + + + Optional + Facultatif + + + + Next + Suivant + + + + + Passwords do not match + Les mots de passe ne correspondent pas + + + + DFMVaultActiveStartView + + + File Vault + Coffre-fort + + + + Create your secure private space + Créer votre espace privé sécurisé + + + + Advanced encryption technology + Technologie de cryptage avancée + + + + Convenient and easy to use + Pratique et facile à utiliser + + + + Create + Créer + + + + DFMVaultFileView + + + Cannot open this path + + + + + Hint + + + + + OK + OK + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Déverrouiller par clé + + + + Failed to unlock file vault + Échec du déverrouillage du coffre-fort de fichiers + + + + OK + OK + + + + Input the 32-digit recovery key + Saisir la clé de récupération à 32 chiffres + + + + Cancel + button + Annuler + + + + Unlock + button + Déverrouiller + + + + Wrong recovery key + Clé de récupération incorrecte + + + + DFMVaultRemoveByPasswordView + + + Password + Mot de passe + + + + Password hint: %1 + Indice de mot de passe : %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Saisir la clé de récupération à 32 chiffres + + + + DFMVaultRemovePages + + + Delete File Vault + Supprimer le coffre-fort + + + + Once deleted, the files in it will be permanently deleted + Une fois supprimés, les fichiers qu'il contient seront définitivement effacés + + + + Use Key + Utiliser la clé + + + + Cancel + button + Annuler + + + + Use Key + button + Utiliser la clé + + + + Delete + button + Supprimer + + + + + OK + button + OK + + + + Use Password + Utiliser le mot de passe + + + + Wrong password + Mauvais mot de passe + + + + Wrong recovery key + Clé de récupération incorrecte + + + + Failed to delete file vault + Échec de la suppression du coffre-fort de fichiers + + + + Deleted successfully + Supprimé avec succès + + + + Failed to delete + Échec de la suppression + + + + Removing... + Suppression... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + + + + + Verification failed + + + + + + Select a path + + + + + + Retrieve Password + + + + + By key in the default path + + + + + By key in the specified path + + + + + Verification Successful + + + + + Keep it safe + + + + + Back + button + Retour + + + + Verify Key + button + + + + + Go to Unlock + button + + + + + Close + button + Fermer + + + + Vault password: %1 + + + + + DFMVaultUnlockPages + + + Unlock File Vault + Déverrouiller le coffre-fort + + + + Forgot password? + + + + + Password hint: %1 + Indice de mot de passe : %1 + + + + Failed to unlock file vault + Échec du déverrouillage du coffre-fort de fichiers + + + + Cancel + button + Annuler + + + + Password + Mot de passe + + + + Unlock + button + Déverrouiller + + + + Please try again %1 minutes later + + + + + Wrong password, please try again %1 minutes later + + + + + Wrong password, one chance left + + + + + Wrong password, %1 chances left + + + + + Wrong password + Mauvais mot de passe + + + + OK + button + OK + + + + DFileCopyMoveJob + + + Permission error + Erreur d'autorisation + + + + The action is denied + L'action est refusée + + + + Failed to open the file + Impossible d'ouvrir le fichier + + + + Failed to read the file + Impossible de lire le fichier + + + + Failed to write the file + Impossible d'écrire le fichier + + + + Failed to create the directory + Impossible de créer le répertoire + + + + Failed to delete the file + Impossible de supprimer le fichier + + + + Failed to move the file + Impossible de déplacer le fichier + + + + Original file does not exist + Le fichier d'origine n'existe pas + + + + Failed, file size must be less than 4GB + Échec, la taille du fichier doit être inférieure à 4 Go + + + + Not enough free space on the target disk + Pas assez d'espace libre sur le disque cible + + + + File integrity was damaged + L'intégrité du fichier a été endommagée + + + + The target device is read only + Le périphérique cible est en lecture seule + + + + Target folder is inside the source folder + Le dossier cible se trouve dans le dossier source + + + + The action is not supported + L'action n'est pas prise en charge + + + + You do not have permission to traverse files in it + Vous n'êtes pas autorisé à parcourir les fichiers qu'il contient + + + + Failed to position the file pointer! + + + + + copy + Extra name added to new file name when used for file name. + copier + + + + Failed to open the directory, cause: file name too long + Impossible d'ouvrir le répertoire, cause : nom de fichier trop long + + + + + Failed to open the file, cause: file name too long + Impossible d'ouvrir le fichier, cause : nom de fichier trop long + + + + + Failed to write the file, cause: + Échec de l'écriture du fichier, cause : + + + + Failed to position the file pointer, cause: %1 + + + + + Syncing data + Synchronisation des données + + + + Please wait + Veuillez attendre, s'il vous plaît + + + + Failed to create the directory, cause: %1 + Impossible de créer le répertoire, cause : %1 + + + + + + + + Failed to open the file, cause: %1 + Impossible d'ouvrir le fichier, cause : %1 + + + + + + + Failed to open the file, cause: Permission denied + Échec de l'ouverture du fichier, cause : Autorisation refusée + + + + + Failed to read the file, cause: %1 + Impossible de lire le fichier, cause : %1 + + + + + + + Failed to write the file, cause: %1 + Impossible d'écrire le fichier, cause : %1 + + + + + File integrity was damaged, cause: %1 + L'intégrité du fichier a été endommagée, cause : %1 + + + + Failed to open the file, cause: + Échec de l'ouverture du fichier, cause : + + + + Failed to read the file, cause: + Échec de la lecture du fichier, cause : + + + + Failed to delete the file, cause: %1 + Impossible de supprimer le fichier, cause : %1 + + + + Fail to create symlink, cause: %1 + Impossible de créer un lien symbolique, cause : %1 + + + + DFileDialog + + + + Save + button + Enregistrer + + + + + Cancel + button + Annuler + + + + Confirm + button + Confirmer + + + + %1 already exists, do you want to replace it? + %1 existe déjà, voulez-vous le remplacer ? + + + + Replace + button + Remplacer + + + + Open + button + Ouvrir + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Ce fichier sera masqué si le nom du fichier commence par un point (.). Voulez-vous le masquer ? + + + + DFileManagerWindow + + + Trash + Corbeille + + + + Empty + Vide + + + + DFileSystemModel + + + + Name + Nom + + + + + + Time modified + Heure de modification + + + + Size + Taille + + + + Type + Type + + + + Time created + Heure de création + + + + + Last access + Dernier accès + + + + + + + Path + Chemin + + + + DFileView + + + Disc mount error + Erreur de montage du disque + + + + The disc is in use, please end the running process and remount the disc. + Le disque est en cours d'utilisation, veuillez terminer le processus en cours et remonter le disque. + + + + Mounting failed + Le montage a échoué + + + + (Reverse) + (Inverse) + + + + DFileViewHelper + + + Add tag "%1" + Ajouter une balise "%1" + + + + DStatusBar + + + %1 item + %1 élément + + + + %1 items + %1 éléments + + + + %1 item selected + %1 élément sélectionné + + + + %1 items selected + %1 éléments sélectionnés + + + + %1 folder selected (contains %2) + %1 dossier sélectionné (contient %2) + + + + %1 folders selected (contains %2) + %1 dossiers sélectionnés (contient %2) + + + + %1 file selected (%2) + %1 fichier sélectionné (%2) + + + + %1 files selected (%2) + %1 fichiers sélectionnés (%2) + + + + %1 folder selected + %1 dossier sélectionné + + + + Filter + Filtre + + + + Save as: + Enregistrer sous : + + + + Loading... + Chargement... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Suppression du disque %1, veuillez patienter... + + + + Burning disc %1, please wait... + Gravure du disque %1, veuillez patienter... + + + + Writing data... + Écriture de données... + + + + Verifying data... + Vérification des données... + + + + Copying %1 + Copie de %1 + + + + + + to %2 + vers %2 + + + + %1 already exists in target folder + %1 existe déjà dans le dossier cible + + + + Original path %1 Target path %2 + Chemin d'origine %1 Chemin cible %2 + + + + Merge + button + Fusionner + + + + Replace + button + Remplacer + + + + Moving %1 + Déplacement de %1 + + + + Removing file vault, please try later + Suppression du coffre-fort des fichiers, veuillez essayer plus tard + + + + Restoring %1 + Restauration de %1 + + + + Deleting %1 + Suppression de %1 + + + + Trashing %1 + Corbeille %1 + + + + Calculating space, please wait + Calcul de l'espace, veuillez patienter + + + + DUMountManager + + + + Authentication timed out + L'authentification a expiré + + + + + + Disk is busy, cannot unmount now + Le disque est occupé, et ne peut donc pas être démonté maintenant + + + + Disk is busy, cannot eject now + Le disque est occupé, impossible de l'éjecter maintenant + + + + The device is busy, cannot eject now + L'appareil est occupé et ne peut pas être éjecté maintenant + + + + + + The device is busy, cannot remove now + L'appareil est occupé et ne peut pas être retiré maintenant + + + + DeepinStorage + + + + + %1 Volume + %1 Volume + + + + Data Disk + Data Partition + Disque de données + + + + %1 Drive + %1 Drive + + + + Blank %1 Disc + Disque %1 vierge + + + + %1 Encrypted + %1 Chiffré + + + + DialogManager + + + + + + Operation failed! + L'opération a échoué ! + + + + Target folder is inside the source folder! + Le dossier cible se trouve dans le dossier source ! + + + + Do you want to run %1 or display its content? + Voulez-vous exécuter %1 ou afficher son contenu ? + + + + It is an executable text file. + Il s'agit d'un fichier texte exécutable. + + + + It is an executable file. + Il s'agit d'un fichier exécutable. + + + + This file is not executable, do you want to add the execute permission and run? + Ce fichier n'est pas exécutable, voulez-vous ajouter l'autorisation d'exécution et exécuter ? + + + + "%1" already exists, please use another name. + "%1" existe déjà, veuillez utiliser un autre nom. + + + + The file name must not contain two dots (..) + Le nom du fichier ne doit pas contenir deux points (..) + + + + Device or resource busy + + + + + Are you sure you want to erase all data on the disc? + Voulez-vous vraiment effacer toutes les données du disque ? + + + + How do you want to use this disc? + Comment voulez-vous utiliser ce disque ? + + + + Disc erase failed + L'effacement du disque a échoué + + + + Burn process failed + Échec du processus de gravure + + + + %1: %2 + %1 : %2 + + + + Show details + Afficher les détails + + + + Hide details + Masquer les détails + + + + Error + Erreur + + + + Permanently delete %1? + Supprimer définitivement %1 ? + + + + Permanently delete %1 items? + Supprimer définitivement %1 éléments ? + + + + Empty + Vide + + + + Do you want to delete %1? + Voulez-vous supprimer %1 ? + + + + Do you want to delete the selected %1 items? + Voulez-vous supprimer les %1 éléments sélectionnés ? + + + + Sorry, unable to locate your bookmark directory, remove it? + Désolé, impossible de localiser votre répertoire de signets, le supprimer? + + + + Name: + Nom : + + + + %1 that this shortcut refers to has been changed or moved + %1 auquel ce raccourci fait référence a été modifié ou déplacé + + + + Do you want to delete this shortcut? + Voulez-vous supprimer ce raccourci ? + + + + Failed, file size must be less than 4GB. + Échec, la taille du fichier doit être inférieure à 4 Go. + + + + Fail to create symlink, cause: + Impossible de créer un lien symbolique, car : + + + + The selected files contain system file/directory, and it cannot be deleted + Les fichiers sélectionnés contiennent un fichier/répertoire système et ne peuvent pas être supprimés + + + + Unable to find the original file + Impossible de trouver le fichier d'origine + + + + + You do not have permission to operate file/folder! + Vous n'êtes pas autorisé à opérer un fichier/dossier ! + + + + Failed to restore %1 file, the source file does not exist + Échec de la restauration du fichier %1, le fichier source n'existe pas + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Désolé, vous n'êtes pas autorisé à opérer sur les %1 fichier/dossier(s) suivants ! + + + + Unable to access %1 + Impossible d'accéder à %1 + + + + + Sending files now, please try later + Envoi de fichiers en cours, veuillez réessayer plus tard + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Pour accéder au périphérique, vous devez d'abord formater le disque. Voulez-vous vraiment le formater maintenant ? + + + + Scanning the device, stop it? + Scanner l'appareil, l'arrêter ? + + + + Share folder can't be named after the current username + Le dossier de partage ne peut pas être nommé d'après le nom d'utilisateur actuel + + + + Do you want to run %1? + Voulez-vous exécuter %1 ? + + + + Burn image + button + Graver l'image + + + + Burn files + button + Graver les fichiers + + + + Are you sure you want to empty %1 item? + Voulez-vous vraiment vider %1 élément ? + + + + Are you sure you want to empty %1 items? + Voulez-vous vraiment vider %1 éléments ? + + + + + This action cannot be undone + Cette action ne peut pas être annulée + + + + + + + + + + + + + + OK + button + OK + + + + + + + + + + + + + + + Cancel + button + Annuler + + + + + + Run + button + Exécuter + + + + + Run in terminal + button + Exécuter dans le terminal + + + + Display + button + Afficher + + + + + + + + + + + Confirm + button + Confirmer + + + + Erase + button + Effacer + + + + Data verification failed + La vérification des données a échoué + + + + Show details + button + Afficher les détails + + + + + Delete + button + Supprimer + + + + Remove + button + Supprimer + + + + Disk is busy, cannot unmount now + Le disque est occupé, et ne peut donc pas être démonté maintenant + + + + Force unmount + button + Forcer le démontage + + + + Unable to copy. Not enough free space on the target disk. + Impossible de copier. Espace libre insuffisant sur le disque cible. + + + + Failed to restore %1 file, the target folder is read-only + Impossible de restaurer le fichier %1, le dossier cible est en lecture seule + + + + Failed to restore %1 files, the target folder is read-only + Impossible de restaurer les fichiers %1, le dossier cible est en lecture seule + + + + Failed to restore %1 files, the source files do not exist + Échec de la restauration des fichiers %1, les fichiers source n'existent pas + + + + Format + button + Formater + + + + Stop + button + Arrêter + + + + FileController + + + + + + Unable to find the original file + Impossible de trouver le fichier d'origine + + + + + + Kindly Reminder + Veuillez rappeler + + + + + + Please install File Roller first and then continue + Veuillez d'abord installer File Roller pour continuer + + + + + Unable to create files here: %1 + Impossible de créer des fichiers ici : %1 + + + + Confirm + button + Confirmer + + + + FileDialogStatusBar + + + File Name + Nom de fichier + + + + Format + Format + + + + Save + button + Enregistrer + + + + Open + button + Ouvrir + + + + Save File + button + Enregistrer le fichier + + + + Open File + button + Ouvrir un fichier + + + + + + Cancel + button + Annuler + + + + FileJob + + + copy + copier + + + + + + + Data verification successful. + La vérification des données a réussi. + + + + + + Burn process completed + Processus de gravure terminé + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 j %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 est un fichier en double. + + + + Insufficient disc space. + Espace disque insuffisant. + + + + Lost connection to drive. + Perte de connexion du lecteur. + + + + The CD/DVD drive is not ready. Try another disc. + Le lecteur de CD / DVD n'est pas prêt. Essayer un autre disque. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + Le lecteur de CD/DVD est occupé. Quitter le programme à l'aide du lecteur et réinsérer le lecteur. + + + + Unknown error + Erreur inconnue + + + + Device disconnected + Périphérique déconnecté + + + + GenerateSettingTranslate + + + + + Basic + Basique + + + + + + Open behavior + Comportement d'ouverture + + + + + + Always open folder in new window + Toujours ouvrir le dossier dans une nouvelle fenêtre + + + + + + Open file: + Ouvrir le fichier : + + + + + + Click + Cliquer + + + + + + Double click + Double-cliquer + + + + + + New window and tab + Nouvelle fenêtre et nouvel onglet + + + + + + Open from default window: + Ouvrir à partir de la fenêtre par défaut : + + + + + + + + + Computer + Ordinateur + + + + + + + + + Home + Accueil + + + + + + + + + Desktop + Bureau + + + + + + + + + Videos + Vidéos + + + + + + + + + Music + Musique + + + + + + + + + Pictures + Images + + + + + + + + + Documents + Documents + + + + + + + + + Downloads + Téléchargements + + + + + + Open in new tab: + Ouvrir dans un nouvel onglet : + + + + + + Current Directory + Répertoire actuel + + + + + + View + Afficher + + + + + + Default size: + Taille par défaut : + + + + + + Extra small + Extra petit + + + + + + Small + Petit + + + + + + Medium + Moyen + + + + + + Large + Large + + + + + + Extra large + Extra large + + + + + + Default view: + Vue par défaut : + + + + + + Icon + Icône + + + + + + List + Liste + + + + + + Hidden files + Fichiers cachés + + + + + + Show hidden files + Afficher les fichiers cachés + + + + + + Hide file extension when rename + Masquer l'extension du fichier lors du renommage + + + + + + Advanced + Avancés + + + + + + Index + Index + + + + + + Auto index internal disk + Disque interne à indexation automatique + + + + + + Index external storage device after connected to computer + Indexer le périphérique de stockage externe après connexion à l'ordinateur + + + + + + Full-Text search + Recherche en texte intégral + + + + + + Show item counts and sizes in the path of mounted MTP devices + + + + + + + Keep showing the mounted Samba shares + + + + + + + Use the file chooser dialog of File Manager + Utiliser la boîte de dialogue de sélection de fichiers du gestionnaire de fichiers + + + + + + Ask for my confirmation when deleting files + Demander ma confirmation lors de la suppression de fichiers + + + + + + Other + Autre + + + + + + Hide system disk + Masquer le disque système + + + + + + Show file system on disk icon + Afficher le système de fichiers sur l'icône du disque + + + + + + Show hidden files in search results + Afficher les fichiers cachés dans les résultats de recherche + + + + + + Display recent file entry in left panel + Afficher l'entrée de fichier récente dans le panneau de gauche + + + + + + Preview + Aperçu + + + + + Compress file preview + Compression de l'aperçu du fichier + + + + + + Text preview + Aperçu du texte + + + + + + Document preview + Aperçu du document + + + + + + Image preview + Aperçu d'image + + + + + + Video preview + Aperçu vidéo + + + + + + Mount + Monter + + + + + + Auto mount + Montage automatique + + + + + + Open after auto mount + Ouvrir après le montage automatique + + + + + + Dialog + Boîte de dialogue + + + + Compressed file preview + Aperçu du fichier compressé + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Impossible de vérifier l'identité de %1. + + + + This happens when you log in to a computer the first time. + Cela se produit lorsque vous vous connectez à un ordinateur pour la première fois. + + + + The identity sent by the remote computer is + L'identité envoyée par l'ordinateur distant est + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Si vous voulez être absolument sûr de pouvoir continuer en toute sécurité, contactez l'administrateur système. + + + + + + + + Mounting device error + Erreur de montage de l'appareil + + + + + Wrong username or password + Nom d'utilisateur ou mot de passe incorrect + + + + + + + + Confirm + button + Confirmer + + + + + Cannot find the mounted device + Impossible de trouver le périphérique monté + + + + No key available to unlock device + Aucune clé disponible pour déverrouiller l'appareil + + + + The disk is mounted by user "%1", you cannot unmount it. + Le disque est monté par l'utilisateur "% 1", vous ne pouvez pas le démonter. + + + + Cannot unmount the device + Impossible de démonter l'appareil + + + + Cannot eject the device "%1" + Impossible d'éjecter le périphérique "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Impossible de graver. Espace libre insuffisant sur le disque cible. + + + + MergedDesktopController + + + + Pictures + Images + + + + + Music + Musique + + + + + Applications + Applications + + + + + Videos + Vidéos + + + + + Documents + Documents + + + + + Others + Autres + + + + MimeTypeDisplayManager + + + + Directory + Répertoire + + + + + + Application + Application + + + + + + Video + Vidéo + + + + + + Audio + Audio + + + + + + Image + Image + + + + + Archive + Archive + + + + + + Text + Texte + + + + + Executable + Exécutable + + + + + Backup file + Fichier de sauvegarde + + + + + Unknown + Inconnu + + + + MountAskPasswordDialog + + + Cancel + button + Annuler + + + + Connect + button + Se connecter + + + + Log in as + Connectez-vous en tant que + + + + Anonymous + Anonyme + + + + Registered user + Utilisateur enregistré + + + + Username + Nom d'utilisateur + + + + Domain + Domaine + + + + Password + Mot de passe + + + + Remember password + Mémoriser le mot de passe + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Annuler + + + + Unlock + button + Déverrouiller + + + + Input password to decrypt the disk + Saisir le mot de passe pour décrypter le disque + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Voulez-vous vraiment supprimer définitivement %1 ? + + + + This file is too big for the trash + Ce fichier est trop volumineux pour la corbeille + + + + The files are too big for the trash + Les fichiers sont trop gros pour la corbeille + + + + Are you sure you want to permanently delete %1 files? + Voulez-vous vraiment supprimer définitivement %1 fichiers ? + + + + Cancel + button + Annuler + + + + Delete + button + Supprimer + + + + OpenWithDialog + + + Open with + Ouvrir avec + + + + Add other programs + Ajouter d'autres programmes + + + + Set as default + Définir par défaut + + + + Cancel + button + Annuler + + + + Confirm + button + Confirmer + + + + Recommended Applications + Applications recommandées + + + + Other Applications + Autres applications + + + + PathManager + + + Home + Accueil + + + + Desktop + Bureau + + + + Videos + Vidéos + + + + Music + Musique + + + + Pictures + Images + + + + Documents + Documents + + + + Downloads + Téléchargements + + + + + Trash + Corbeille + + + + + + System Disk + Disque système + + + + Computers in LAN + Ordinateurs dans le réseau local + + + + My Shares + Mes partages + + + + Computer + Ordinateur + + + + Recent + Récent + + + + File Vault + Coffre-fort + + + + PropertyDialog + + + Basic info + Informations de base + + + + Open with + Ouvrir avec + + + + Sharing + Partage + + + + Permissions + Autorisations + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Masquer ce dossier + + + + Hide this file + Masquer ce fichier + + + + Allow to execute as program + Autoriser l'exécution en tant que programme + + + + QObject + + + + + + Size + Taille + + + + + + Contains + Contient + + + + + + Type + Type + + + + + + + + Time modified + Heure de modification + + + + Free space + Espace libre + + + + Total space + Espace total + + + + + Time locked + Temps verrouillé + + + + Access denied + Accès refusé + + + + + Executable + Exécutable + + + + + Write only + Écriture uniquement + + + + + Read only + Lecture seule + + + + + Read-write + Lecture-écriture + + + + Others + Autres + + + + Owner + Propriétaire + + + + Unconnected network shared directory + + + + + Device type + Type d'appareil + + + + File system + Système de fichiers + + + + Group + Groupe + + + + + Open + Ouvrir + + + + Lock + Verrouiller + + + + Auto lock + Verrouillage automatique + + + + Never + Jamais + + + + 5 minutes + 5 minutes + + + + 10 minutes + 10 minutes + + + + 20 minutes + 20 minutes + + + + Delete File Vault + Supprimer le coffre-fort + + + + Unlock + Déverrouiller + + + + Unlock by key + Déverrouiller par clé + + + + Open + button + Ouvrir + + + + + Size: %1 + Taille : %1 + + + + Type: %1 + Type : %1 + + + + Size: 0 + Taille : 0 + + + + Items: %1 + Éléments : %1 + + + + + + + + + + Open in new window + Ouvrir dans une nouvelle fenêtre + + + + + + + + + + Open in new tab + Ouvrir dans un nouvel onglet + + + + Open with + Ouvrir avec + + + + + Compress + Compresser + + + + Extract + Extraire + + + + Extract here + Extraire ici + + + + Cut + Couper + + + + Copy + Copier + + + + Paste + Coller + + + + + + + + Rename + Renommer + + + + + + + Remove + Supprimer + + + + Create link + Créer un lien + + + + Send to desktop + Envoyer sur le bureau + + + + Send to + Envoyer à + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Ajouter au signet + + + + + + + Properties + Propriétés + + + + New folder + Nouveau dossier + + + + New window + Nouvelle fenêtre + + + + Select all + Tout sélectionner + + + + + Clear recent history + Effacer l'historique récent + + + + + + Empty Trash + Vider la corbeille + + + + Display as + Afficher en tant que + + + + Sort by + Trier par + + + + New document + Nouveau document + + + + + Time created + Heure de création + + + + + + Source path + Source + + + + Share folder + Partager le dossier + + + + Cancel sharing + Annuler le partage + + + + Connect to Server + Se connecter au serveur + + + + Set share password + Définir le mot de passe du partage + + + + Format + Format + + + + Tag information + Informations sur les balises + + + + Open as administrator + Ouvrir en tant qu'administrateur + + + + Select default program + Sélectionner le programme par défaut + + + + Open file location + Ouvrir l'emplacement du fichier + + + + Remove bookmark + Supprimer le signet + + + + + + Delete + Supprimer + + + + Office Text + Texte Office + + + + Spreadsheets + Feuilles de calcul + + + + Plain Text + Texte brut + + + + Open in terminal + Ouvrir dans le terminal + + + + Restore + Restaurer + + + + Restore all + Tout restaurer + + + + Clear saved password and unmount + + + + + File Vault + Coffre-fort + + + + Add to disc + Ajouter au disque + + + + Refresh + + + + + Auto mount + Montage automatique + + + + Open after auto mount + Ouvrir après le montage automatique + + + + + Mount + Monter + + + + + Unmount + Démonter + + + + It does not support burning %1 discs + Il ne supporte pas la gravure de %1 disques + + + + Burn + Graver + + + + Disc name: + Nom du disque : + + + + + Maximum + Maximum + + + + Allow files to be added later + Autoriser l'ajout de fichiers ultérieurement + + + + Verify data + Vérifier les données + + + + Write speed: + Vitesse d'écriture : + + + + + + + Cancel + button + Annuler + + + + Burn + button + Graver + + + + + Eject + Éjecter + + + + Safely Remove + Supprimer en toute sécurité + + + + + Name + Nom + + + + Settings + Paramètres + + + + Exit + Quitter + + + + Icon + Icône + + + + List + Liste + + + + Extend + Étendre + + + + Set as wallpaper + Définir comme fond d'écran + + + + + + + Local disk + Disque local + + + + + Removable disk + Disque amovible + + + + + + Network shared directory + Répertoire partagé du réseau + + + + + Android mobile device + Appareil mobile Android + + + + + Apple mobile device + Appareil mobile Apple + + + + + Camera + Appareil photo + + + + + DVD + DVD + + + + + Unknown device + Appareil inconnu + + + + + + %1 item + %1 élément + + + + + + %1 items + %1 éléments + + + + Shortcut + Raccourci + + + + Create symlink + Créer un lien symbolique + + + + Path + Chemin + + + + + + Time deleted + Heure de suppression + + + + Loading... + Chargement... + + + + File has been moved or deleted + Le fichier a été déplacé ou supprimé + + + + You do not have permission to traverse files in it + Vous n'êtes pas autorisé à parcourir les fichiers qu'il contient + + + + + + You do not have permission to access this folder + Vous n'êtes pas autorisé à accéder à ce dossier + + + + + + + + Folder is empty + Le dossier est vide + + + + Searching... + Recherche en cours... + + + + No results + Aucun résultat + + + + Source Path + TrashFileInfo + Chemin source + + + + Document + Document + + + + Spreadsheet + Feuille de calcul + + + + + Presentation + Présentation + + + + Text + Texte + + + + 1 task in progress + 1 tâche en cours + + + + %1 tasks in progress + %1 tâches en cours + + + + Mode: + Mode : + + + + + Replace Text + Remplacer le texte + + + + + Add Text + Ajouter du texte + + + + + Custom Text + Texte personnalisé + + + + Find: + Rechercher : + + + + Replace: + Remplacer : + + + + + Optional + Facultatif + + + + Add: + Ajouter : + + + + Location: + Emplacement : + + + + File name: + Nom du fichier : + + + + Start at: + Commencer à : + + + + + Rename + button + Renommer + + + + + + + + + + + Required + Obligatoire + + + + + Before file name + Avant le nom du fichier + + + + + After file name + Après le nom du fichier + + + + Find + Rechercher + + + + Replace + Remplacer + + + + Add + Ajouter + + + + Start at + Commencer à + + + + + + Location + Emplacement + + + + File name + Nom de fichier + + + + Dimension + Dimension + + + + Duration + Durée + + + + Tips: Sort by selected file order + Conseils : trier par ordre de fichier sélectionné + + + + Rename %1 Files + Renommer %1 fichiers + + + + Multiple Files + Fichiers multiples + + + + Basic info + Informations de base + + + + Total size + Taille totale + + + + Number of files + Nombre de fichiers + + + + %1 file(s), %2 folder(s) + %1 fichier(s), %2 dossier(s) + + + + + + Time accessed + Temps d'accès + + + + Orange + Orange + + + + Red + Rouge + + + + Purple + Violet + + + + Navy-blue + Bleu marine + + + + Azure + Azure + + + + Green + Vert + + + + Yellow + Jaune + + + + Gray + Gris + + + + Input tag info, such as work, family. A comma is used between two tags. + Entrer les informations du tag. Une virgule est utilisée entre deux tags. + + + + Bookmarks + Signets + + + + Erase + Effacer + + + + Copy path + Copier le chemin + + + + Edit address + Modifier l'adresse + + + + Free Space %1 + Espace libre %1 + + + + Files are being processed + Les fichiers sont en cours de traitement + + + + + Unknown + Inconnu + + + + My Vault + Mon coffre-fort + + + + + Failed to create file info + Échec de la création des informations du fichier + + + + Failed to create file handler + Échec de la création du gestionnaire de fichiers + + + + Failed to open the file, cause: %1 + Impossible d'ouvrir le fichier, cause : %1 + + + + Original file does not exist + Le fichier d'origine n'existe pas + + + + Do you want to delete %1? + Voulez-vous supprimer %1 ? + + + + Confirm + button + Confirmer + + + + + + + + %1 are not allowed + + + + + + Failed to start Samba services + + + + + RecentController + + + Cancel + button + Annuler + + + + Remove + button + Supprimer + + + + Do you want to remove this item? + + + + + Do yout want to remove %1 items? + + + + + It does not delete the original files + + + + + ShareInfoFrame + + + Share this folder + Partager ce dossier + + + + Share name: + Nom du partage : + + + + Permission: + Autorisation : + + + + Read and write + Lecture et écriture + + + + Read only + Lecture seule + + + + Anonymous: + Anonyme : + + + + Not allow + Ne pas autoriser + + + + Allow + Autoriser + + + + The share name must not be two dots (..) or one dot (.) + Le nom de partage ne doit pas être composé de deux points (..) ou d'un point (.) + + + + The share name is used by another user. + Le nom de partage est utilisé par un autre utilisateur. + + + + OK + button + OK + + + + Cancel + button + Annuler + + + + Replace + button + Remplacer + + + + The share name already exists. Do you want to replace the shared folder? + Le nom de partage existe déjà. Voulez-vous remplacer le dossier partagé ? + + + + Shortcut + + + Item + Article + + + + Select to the first item + Sélectionner le premier élément + + + + Shift + Home + Maj + Accueil + + + + Select to the last item + Sélectionner jusqu'au dernier élément + + + + Shift + End + Maj + Fin + + + + Select leftwards + Sélectionner vers la gauche + + + + Shift + Left + Maj + Gauche + + + + Select rightwards + Sélectionner vers la droite + + + + Shift + Right + Maj + Droite + + + + Select to upper row + Sélectionner sur la ligne supérieure + + + + Shift + Up + Maj + Haut + + + + Select to lower row + Sélectionner pour abaisser la ligne + + + + Shift + Down + Maj + Bas + + + + Open + Ouvrir + + + + Ctrl + Down + Ctrl + Bas + + + + To parent directory + Vers le répertoire parent + + + + Ctrl + Up + Ctrl + Haut + + + + Permanently delete + Supprimer définitivement + + + + Shift + Delete + Maj + Suppr + + + + Delete file + Supprimer le fichier + + + + Delete + Supprimer + + + + Select all + Tout sélectionner + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Maj + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Copier + + + + Cut + Couper + + + + Paste + Coller + + + + Rename + Renommer + + + + F2 + F2 + + + + New/Search + Nouveau/Rechercher + + + + New window + Nouvelle fenêtre + + + + New folder + Nouveau dossier + + + + + Search + Rechercher + + + + New tab + Nouvel onglet + + + + View + Afficher + + + + Item information + Informations sur l'élément + + + + Help + Aide + + + + F1 + F1 + + + + Keyboard shortcuts + Raccourcis clavier + + + + Ctrl + Shift + / + Ctrl + Maj + / + + + + Switch display status + Changer l'état d'affichage + + + + Hide item + Masquer l'élément + + + + Input in address bar + Entrée dans la barre d'adresse + + + + Switch to icon view + Passer à l'affichage des icônes + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Passer en vue liste + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Autres + + + + Close + Fermer + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Fermer l'onglet actuel + + + + Back + Retour + + + + Alt + Left + Alt + Gauche + + + + Alt + Right + Alt + Droite + + + + Switch to next tab + Passer à l'onglet suivant + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Maj + Tab + + + + Switch to previous tab + Passer à l'onglet précédent + + + + Next file + Fichier suivant + + + + Tab + Onglet + + + + Previous file + Fichier précédent + + + + Shift + Tab + Maj + Tab + + + + Switch tab by specified number between 1 to 8 + Basculer l'onglet par numéro spécifié entre 1 et 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Transférer + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Impossible d'ouvrir des éléments de la corbeille, veuillez d'abord les restaurer + + + + TrashPropertyDialog + + + Trash + Corbeille + + + + item + élément + + + + items + éléments + + + + Contains %1 %2 + Contient %1 %2 + + + + UDiskListener + + + Failed to rename the label + Impossible de renommer l'étiquette + + + + UnmountWorker + + + + + The device was not safely unmounted + Le périphérique n'a pas été démonté en toute sécurité + + + + The device was not safely removed + Le périphérique n'a pas été retiré en toute sécurité + + + + UserShareManager + + + Kindly Reminder + Veuillez rappeler + + + + Please firstly install samba to continue + Veuillez d'abord installer samba pour continuer + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + + + + + To protect the files, you cannot share this folder. + Pour protéger les fichiers, vous ne pouvez pas partager ce dossier. + + + + Sharing failed + Le partage a échoué + + + + The computer name is too long + Le nom de l'ordinateur est trop long + + + + You do not have permission to operate file/folder! + Vous n'êtes pas autorisé à opérer sur un fichier/dossier ! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Entrer un mot de passe pour protéger les dossiers partagés + + + + Cancel + button + Annuler + + + + Confirm + button + Confirmer + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_gl_ES.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_gl_ES.ts new file mode 100644 index 0000000..237f22d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_gl_ES.ts @@ -0,0 +1,4547 @@ + + + AppController + + + New Folder + Novo cartafol + + + + Mounting device error + Erro do dispositivo de montaxe + + + + The disc image was corrupted, cannot mount now, please erase the disc first + A imaxe do disco estaba corrompida, non se pode montar agora. Borre o disco primeiro + + + + Mount error: unsupported image format + Erro de montaxe: formato de imaxe non soportado + + + + + The device was not safely removed + + + + + + Click "Safely Remove" and then disconnect it next time + + + + + The device was not ejected + + + + + Disk is busy, cannot eject now + O disco está ocupado, non se pode expulsar agora + + + + Authentication timed out + + + + + BluetoothTransDialog + + + Bluetooth File Transfer + + + + + File Transfer Successful + + + + + File Transfer Failed + + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + + + + + Select a Bluetooth device to receive files + + + + + Cannot find the connected Bluetooth device + + + + + Waiting to be received... + + + + + Go to Bluetooth Settings + + + + + %1/%2 Sent + + + + + Error: the Bluetooth device is disconnected + + + + + Unable to send the file more than 2 GB + + + + + Unable to send 0 KB files + + + + + File doesn't exist + + + + + Next + button + Seguinte + + + + Cancel + button + Cancelar + + + + Done + button + Feito + + + + Retry + button + Volver a intentar + + + + OK + button + Aceptar + + + + File sending request timed out + + + + + The service is busy and unable to process the request + + + + + BurnOptDialog + + + Device error + + + + + Optical device %1 doesn't exist + + + + + Advanced settings + Axustes avanzados + + + + File system: + + + + + ISO9660/Joliet (For Windows) + + + + + ISO9660/Rock Ridge (For Unix) + + + + + %1 (Compatible with Windows CD/DVD mode) + + + + + ISO9660 Only + + + + + CloseAllDialogIndicator + + + Close all + Pechar todo + + + + Total size: %1, %2 files + Tamaño total:% 1,% 2 ficheiros + + + + ComputerModel + + + + My Directories + Os meus directorios + + + + + + + + + + + + Disks + Discos + + + + ComputerPropertyDialog + + + Computer + Computador + + + + Basic Info + Info. básica + + + + + Computer Name + Nome do computador + + + + + Edition + + + + + + + Version + Versión + + + + + Type + Tipo + + + + + + Processor + Procesador + + + + + + Memory + Memoria + + + + + + + Bit + Bit + + + + + Available + Dispoñible + + + + Obtaining... + + + + + ConnectToServerDialog + + + Connect to Server + Conectar ao servidor + + + + Cancel + button + Cancelar + + + + Connect + button + Conectar + + + + My Favorites: + Os meus favoritos: + + + + + Clear History + Borrar o historial + + + + DFMAddressBar + + + Search or enter address + Buscar ou inserir enderezo + + + + DFMAdvanceSearchBar + + + Search: + Buscar: + + + + File Type: + Tipo de ficheiro: + + + + File Size: + Tamaño do ficheiro: + + + + Time Modified: + Tempo modificado: + + + + Time Accessed: + + + + + Time Created: + + + + + Reset + Restablecer + + + + All subdirectories + Todos os subdirectorios + + + + Current directory + Directorio actual + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Hoxe + + + + Yesterday + Onte + + + + This week + Esta semana + + + + Last week + Última semana + + + + This month + Este mes + + + + Last month + Último mes + + + + This year + Este ano + + + + Last year + Último ano + + + + DFMOpticalMediaWidget + + + + No files to burn + + + + + Unable to burn. Not enough free space on the target disk. + Non se pode gravar. Non hai espazo libre no disco de destino. + + + + %1 burning is not supported + + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + + + + + DFMTagCrumbController + + + Tag information + Información da etiqueta + + + + DFMTagWidget + + + Tag + Etiqueta + + + + DFMTaskWidget + + + Do not ask again + Non preguntar de novo + + + + Syncing data + + + + + Please wait + + + + + + Time modified: %1 + Tempo modificado: %1 + + + + + Contains: %1 + Contén: %1 + + + + + Size: %1 + Tamaño: %1 + + + + Original folder + Cartafol orixinal + + + + Keep both + button + Manter ambos + + + + Skip + button + Saltar + + + + Replace + button + Substituír + + + + Retry + button + Volver a intentar + + + + Original file + Ficheiro orixinal + + + + Target folder + Cartafol de destino + + + + Target file + Ficheiro de destino + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + + + + + Click 'Encrypt' and input the user password. + + + + + Encrypting... + + + + + + + + Encrypt + + + + + Failed to create file vault: %1 + + + + + OK + Aceptar + + + + The setup is complete + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + + + + + Generate a recovery key in case that you forgot the password + + + + + Key + + + + + QR code + + + + + Scan QR code and save the key to another device + + + + + Next + Seguinte + + + + Recovery Key: + + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + + + + + Method + + + + + Manual + + + + + Password + Contrasinal + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + + + + + Repeat password + Repetir contrasinal + + + + Input the password again + + + + + Password hint + + + + + Optional + Opcional + + + + Next + Seguinte + + + + + Passwords do not match + + + + + DFMVaultActiveStartView + + + File Vault + Bóveda de ficheiros + + + + Create your secure private space + + + + + Advanced encryption technology + + + + + Convenient and easy to use + Conveniente and fácil de usar + + + + Create + + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + + + + + Failed to unlock file vault + + + + + OK + Aceptar + + + + Input the 32-digit recovery key + + + + + Cancel + button + Cancelar + + + + Unlock + button + Desbloquear + + + + Wrong recovery key + + + + + DFMVaultRemoveByPasswordView + + + Password + Contrasinal + + + + Password hint: %1 + + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + + + + + DFMVaultRemovePages + + + Delete File Vault + + + + + Once deleted, the files in it will be permanently deleted + + + + + Use Key + + + + + Cancel + button + Cancelar + + + + Use Key + button + + + + + Delete + button + Eliminar + + + + + OK + button + Aceptar + + + + Use Password + + + + + Wrong password + + + + + Wrong recovery key + + + + + Failed to delete file vault + + + + + Deleted successfully + + + + + Failed to delete + + + + + Removing... + + + + + DFMVaultUnlockPages + + + Unlock File Vault + + + + + Verify your password + + + + + Password hint: %1 + + + + + Failed to unlock file vault + + + + + Password + Contrasinal + + + + Cancel + button + Cancelar + + + + Unlock + button + Desbloquear + + + + + Wrong password + + + + + OK + button + Aceptar + + + + DFileCopyMoveJob + + + Permission error + Erro do permiso + + + + The action is denied + A acción foi invalidada + + + + Failed to open the file + Produciuse un erro ao abrir o arquivo + + + + Failed to read the file + Produciuse un erro ao abrir o arquivo + + + + Failed to write the file + Produciuse un erro ao escribir o arquivo + + + + Failed to create the directory + Produciuse un erro ao crear o cartafol + + + + Failed to delete the file + Produciuse un erro ao eliminar o arquivo + + + + Failed to move the file + Produciuse un erro ao mover o arquivo + + + + Original file does not exist + O arquivo orixinal non existe + + + + Failed, file size must be less than 4GB + Fallo, o tamaño do ficheiro ten que ser menor de 4GB + + + + Not enough free space on the target disk + Non hai espazo libre no disco de destino + + + + File integrity was damaged + A integridade do arquivo foi danada + + + + The target device is read only + O arquivo só se pode leer + + + + Target folder is inside the source folder + O cartafol de destino está dentro do cartafol de orixe + + + + The action is not supported + + + + + You do not have permission to traverse files in it + + + + + copy + Extra name added to new file name when used for file name. + copiar + + + + Failed to open the directory, cause: file name too long + + + + + + + Failed to open the file, cause: file name too long + + + + + + Failed to write the file, cause: + + + + + Syncing data + + + + + Please wait + + + + + Failed to create the directory, cause: %1 + Produciuse un erro ao crear o cartafol debido a: %1 + + + + + + + + + Failed to open the file, cause: %1 + Produciuse un erro ao abrir o arquivo debido a: %1 + + + + + + + Failed to open the file, cause: Permission denied + + + + + + Failed to read the file, cause: %1 + Produciuse un erro ao leer o arquivo debido a: %1 + + + + + + + Failed to write the file, cause: %1 + Produciuse un erro ao escribir o arquivo debido a: %1 + + + + + File integrity was damaged, cause: %1 + A integridade do arquivo foi danada debido a: %1 + + + + Failed to open the file, cause: + + + + + Failed to read the file, cause: + + + + + Failed to delete the file, cause: %1 + Produciuse un erro ao eliminar o arquivo debido a: %1 + + + + Fail to create symlink, cause: %1 + Fallo ao crear a ligazón simbólica, causa:% 1 + + + + DFileDialog + + + + Save + button + Gardar + + + + + Cancel + button + Cancelar + + + + Confirm + button + Confirmar + + + + %1 already exists, do you want to replace it? + %1 xa existe, queres substituílo? + + + + Replace + button + Substituír + + + + Open + button + Abrir + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + + + + + DFileManagerWindow + + + Trash + Papeleira + + + + Empty + Vacía + + + + DFileSystemModel + + + + Name + Nome + + + + + + Time modified + Hora de modificación + + + + Size + Tamaño + + + + Type + Tipo + + + + Time created + Hora de creación + + + + + Last access + Último acceso + + + + + + + Path + Ruta + + + + DFileView + + + Disc mount error + + + + + The disc is in use, please end the running process and remount the disc. + + + + + Mounting failed + + + + + (Reverse) + (inverso) + + + + DFileViewHelper + + + Add tag "%1" + Engadir etiqueta "%1" + + + + DStatusBar + + + %1 item + %1 elemento + + + + %1 items + %1 elementos + + + + %1 item selected + %1 elemento seleccionado + + + + %1 items selected + %1 elementos seleccionados + + + + %1 folder selected (contains %2) + %1 cartafol seleccionado (contén %2) + + + + %1 folders selected (contains %2) + %1 cartafoles seleccionados (conteñen %2) + + + + %1 file selected (%2) + %1 ficheiro seleccionadoo (%2) + + + + %1 files selected (%2) + %1 ficheiros seleccionados (%2) + + + + %1 folder selected + %1 cartafol seleccionado + + + + Filter + Filtrar + + + + Save as: + Gardar como: + + + + Loading... + Cargando... + + + + DTaskDialog + + + This action is not supported + Esta acción non é compatible + + + + Erasing disc %1, please wait... + Eliminando o disco% 1, agarde... + + + + Burning disc %1, please wait... + Gravando o disco% 1, agarde ... + + + + Writing data... + Escritura de datos ... + + + + Verifying data... + Verificando os datos... + + + + Copying %1 + Copiando %1 + + + + + + to %2 + a %2 + + + + %1 already exists in target folder + %1 xa existe un cartafol de destino + + + + Original path %1 Target path %2 + Ruta orixinal %1 Ruta de destino %2 + + + + Merge + button + Fusionar + + + + Replace + button + Substituír + + + + Moving %1 + Movendo %1 + + + + Removing file vault, please try later + + + + + Restoring %1 + Restaurando %1 + + + + Deleting %1 + Eliminando %1 + + + + Trashing %1 + Lixo %1 + + + + Calculating space, please wait + Calcular o espazo, agarde + + + + DUMountManager + + + + Authentication timed out + + + + + + + Disk is busy, cannot unmount now + O disco está ocupado e non se pode desmontar agora + + + + Disk is busy, cannot eject now + O disco está ocupado, non se pode expulsar agora + + + + The device is busy, cannot eject now + + + + + + + The device is busy, cannot remove now + + + + + DeepinStorage + + + + + %1 Volume + %1 Volume + + + + Data Disk + Data Partition + Disco de datos + + + + %1 Drive + %1 Drive + + + + Blank %1 Disc + %1 Disco en branco + + + + %1 Encrypted + %1 encriptado + + + + DialogManager + + + + + + Operation failed! + Faiou a operación! + + + + Target folder is inside the source folder! + O cartafol destino está no cartafol orixe! + + + + Do you want to run %1 or display its content? + Queres executar %1 ou amosar o seu contido? + + + + It is an executable text file. + É un ficheiro de texto executable. + + + + It is an executable file. + É un ficheiro executable. + + + + This file is not executable, do you want to add the execute permission and run? + Este ficheiro non é executable, quere engadir o permiso de execución e executalo? + + + + "%1" already exists, please use another name. + "%1" xa existe, por favor emprega outro nome. + + + + The file name must not contain two dots (..) + + + + + Are you sure you want to erase all data on the disc? + Está seguro de que quere borrar todos os datos do disco? + + + + How do you want to use this disc? + Como quere usar este disco? + + + + Disc erase failed + Erro ao borrar o disco + + + + Burn process failed + Erro ao gravar o proceso + + + + %1: %2 + %1: %2 + + + + Show details + Ensinar detalles + + + + Hide details + Agochar detalles + + + + Error + Erro + + + + Permanently delete %1? + Eliminar permanentemente %1? + + + + Permanently delete %1 items? + Eliminar permanentemente %1 elementos? + + + + Empty + Baleiro + + + + Do you want to delete %1? + + + + + Do you want to delete the selected %1 items? + + + + + Sorry, unable to locate your bookmark directory, remove it? + Sentímolo, non foi posíbel atopar o teu cartafol de marcadores, eliminalo? + + + + Name: + Nome: + + + + %1 that this shortcut refers to has been changed or moved + %1 que este atallo cambiouse ou foi movido + + + + Do you want to delete this shortcut? + Queres eliminar este atallo? + + + + Failed, file size must be less than 4GB. + Fallo, o tamaño do ficheiro ten que ser menor de 4GB. + + + + Fail to create symlink, cause: + Non se puido crear a ligazón simbólica, causa: + + + + The selected files contain system file/directory, and it cannot be deleted + Os ficheiros seleccionados conteñen ficheiros/cartafoles do sistema, e non poden ser eliminados + + + + Unable to find the original file + + + + + + You do not have permission to operate file/folder! + Non tes permiso para operar neste ficheiro/cartafol. + + + + Failed to restore %1 file, the source file does not exist + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Sentímolo, non tes permiso para operar nos seguintes ficheiros / cartafol(es)% 1 seguintes! + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + 2. Desmarque "Activar o inicio rápido" e "Hibernar" na configuración de apagado e reiniciar + + + + 3. Reboot and enter %1 + 3. Reinicie e ingrese% 1 + + + + Reboot + button + Reinicia + + + + Unable to access %1 + + + + + + Sending files now, please try later + + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + + + + + Scanning the device, stop it? + + + + + Share folder can't be named after the current username + O cartafol Compartir non pode ser nomeado co nome de usuario actual + + + + Do you want to run %1? + Tes a certeza de querer executar %1? + + + + Burn image + button + Imaxe gravada + + + + Burn files + button + Ficheiros gravados + + + + Are you sure you want to empty %1 item? + Está seguro de que quere vaciar %1 elemento? + + + + Are you sure you want to empty %1 items? + Está seguro de que quere vaciar %1 elementos? + + + + + This action cannot be undone + Esta acción non se pode desfacer + + + + + + + + + + + + + + OK + button + Aceptar + + + + + + + + + + + + + + + + Cancel + button + Cancelar + + + + + + Run + button + Executar + + + + + Run in terminal + button + Executar no terminal + + + + Display + button + Amosar + + + + + + + + + + Confirm + button + Confirmar + + + + Erase + button + Borrar + + + + Data verification failed + + + + + Show details + button + Ensinar detalles + + + + + Delete + button + Eliminar + + + + Remove + button + Eliminar + + + + Disk is busy, cannot unmount now + O disco está ocupado e non se pode desmontar agora + + + + Force unmount + button + Forzar o desmontado + + + + Unable to copy. Not enough free space on the target disk. + Non se pode copiar. Non hai espazo libre no disco de destino. + + + + Failed to restore %1 file, the target folder is read-only + Erro ao restaurar o ficheiro% 1, o cartafol de destino é de só lectura + + + + Failed to restore %1 files, the target folder is read-only + Erro ao restaurar os ficheiros% 1, o cartafol de destino é de só lectura + + + + Failed to restore %1 files, the source files do not exist + + + + + Mount partition%1 to be read only + Montar a partición% 1 para ser lida só + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + Os discos de Windows non poderán ler e escribir normalmente se está marcado "Activar o inicio rápido (recomendado)" na configuración de Apagado + + + + Please restore by the following steps to normally access Windows disk + Restaura os seguintes pasos para acceder normalmente ao disco de Windows + + + + 1. Reboot to enter Windows + 1. Reinicia para entrar en Windows + + + + Format + button + Formato + + + + Stop + button + + + + + FileController + + + + + + Unable to find the original file + + + + + + + Kindly Reminder + Recordatorio amistoso + + + + + + Please install File Roller first and then continue + Instale primeiro rolo de ficheiros e despois continúe + + + + + Unable to create files here: %1 + + + + + Confirm + button + Confirmar + + + + FileDialogStatusBar + + + File Name + Nome do ficheiro + + + + Format + Formato + + + + Save + button + Gardar + + + + Open + button + Abrir + + + + Save File + button + Gardar ficheiro + + + + Open File + button + Abrir ficheiro + + + + + + Cancel + button + Cancelar + + + + FileIconItem + + + "'/\[]:|<>+=;,?* are not allowed + + + + + FileJob + + + copy + copiar + + + + + + + Data verification successful. + A comprobación dos datos tivo éxito. + + + + + + Burn process completed + Completouse o proceso de gravación + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 é un ficheiro duplicado. + + + + Insufficient disc space. + Espazo do disco insuficiente. + + + + Lost connection to drive. + Perdeu a conexión para dirixir. + + + + The CD/DVD drive is not ready. Try another disc. + A unidade de CD / DVD non está lista. Proba con outro disco. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + A unidade de CD / DVD está ocupada. Saia do programa usando a unidade e volva a introducir a unidade. + + + + Unknown error + Erro descoñecido + + + + Device disconnected + + + + + GenerateSettingTranslate + + + + + Basic + Básico + + + + + + Open behavior + Comportamento aberto + + + + + + Always open folder in new window + Abrir sempre o cartafol nunha xanela nova + + + + + + Open file: + Abrir ficheiro: + + + + + + Click + Clic + + + + + + Double click + Duplo clic + + + + + + New window and tab + Nova xanela e lapela + + + + + + Open from default window: + Abrir dende a xanela predefinida: + + + + + + + + + Computer + Computador + + + + + + + + + Home + Inicio + + + + + + + + + Desktop + Escritorio + + + + + + + + + Videos + Vídeos + + + + + + + + + Music + Música + + + + + + + + + Pictures + Imaxes + + + + + + + + + Documents + Documentos + + + + + + + + + Downloads + Descargas + + + + + + Open in new tab: + Abrir nunha lapela nova: + + + + + + Current Directory + Cartafol actual + + + + + + View + Ver + + + + + + Default size: + Tamaño predefinido: + + + + + + Extra small + Moi pequeno + + + + + + Small + Pequeno + + + + + + Medium + Normal + + + + + + Large + Grande + + + + + + Extra large + Moi grande + + + + + + Default view: + Vista predefinida: + + + + + + Icon + Icona + + + + + + List + Listaxe + + + + + + Hidden files + Ficheiros ocultos + + + + + + Show hidden files + Amosar ficheiros ocultos + + + + + + Hide file extension when rename + Agochar a extensión do ficheiro cando se renomeen + + + + + + Advanced + Avanzado + + + + + + Index + Índice + + + + + + Auto index internal disk + Disco interno índice automático + + + + + + Index external storage device after connected to computer + Disco interno índice automático + + + + + + Full-Text search + + + + + + + Show item counts and sizes in the path of mounted MTP devices + + + + + + + Use the file chooser dialog of File Manager + Use o diálogo de selección de ficheiros do Xestor de ficheiros + + + + + + Ask for my confirmation when deleting files + + + + + + + Other + Outros + + + + + + Hide system disk + Ocultar o disco do sistema + + + + + + Show file system on disk icon + + + + + + + Show hidden files in search results + Amosar ficheiros ocultos nos resultados da busca + + + + + + Display recent file entry in left panel + Amosa a entrada de ficheiro recente no panel esquerdo + + + + + + Preview + Vista previa + + + + + Compress file preview + Vista previa do ficheiro comprimido + + + + + + Text preview + Vista previa do texto + + + + + + Document preview + Vista previa do documento + + + + + + Image preview + Vista previa da imaxe + + + + + + Video preview + Vista previa do vídeo + + + + + + Mount + Montar + + + + + + Auto mount + Montar automaticamente + + + + + + Open after auto mount + Abrir despois de montar automaticamente + + + + + + Dialog + Diálogo + + + + Compressed file preview + Vista previa do ficheiro comprimido + + + + GvfsMountManager + + + Can’t verify the identity of %1. + + + + + This happens when you log in to a computer the first time. + + + + + The identity sent by the remote computer is + + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + + + + + + + + + Mounting device error + Erro do dispositivo de montaxe + + + + + Wrong username or password + + + + + + + + + Confirm + button + Confirmar + + + + + Cannot find the mounted device + + + + + No key available to unlock device + Non hai clave dispoñible para desbloquear o dispositivo + + + + The disk is mounted by user "%1", you cannot unmount it. + O disco está montado polo usuario "% 1", non podes desmontalo. + + + + Cannot unmount the device + Non se pode desmontar o dispositivo + + + + Cannot eject the device "%1" + Non se pode expulsar o dispositivo "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Non se pode gravar. Non hai espazo libre no disco de destino. + + + + MergedDesktopController + + + + Pictures + Imaxes + + + + + Music + Música + + + + + Applications + Aplicativos + + + + + Videos + Vídeos + + + + + Documents + Documentos + + + + + Others + Outros + + + + MimeTypeDisplayManager + + + + Directory + Directorio + + + + + + Application + Aplicativo + + + + + + Video + Vídeo + + + + + + Audio + Audio + + + + + + Image + Imaxe + + + + + Archive + Arquivo + + + + + + Text + Texto + + + + + Executable + Executable + + + + + Backup file + Ficheiro de copia de seguranza + + + + + Unknown + Descoñecido + + + + MountAskPasswordDialog + + + Cancel + button + Cancelar + + + + Connect + button + Conectar + + + + Log in as + Iniciar sesión como + + + + Anonymous + Anónimo + + + + Registered user + Usuario rexistrado + + + + Username + Nome de usuario + + + + Domain + Dominio + + + + Password + Contrasinal + + + + Remember password + Lembrar contrasinal + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Cancelar + + + + Unlock + button + Desbloquear + + + + Input password to decrypt the disk + Contraseña de entrada para descifrar o disco + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Está seguro de que quere eliminar definitivamente% 1? + + + + This file is too big for the trash + Este ficheiro é demasiado grande para a papeleira + + + + The files are too big for the trash + Estes ficheiros son demasiado grandes para a papeleira + + + + Are you sure you want to permanently delete %1 files? + Está seguro de que quere eliminar definitivamente% 1? + + + + Cancel + button + Cancelar + + + + Delete + button + Eliminar + + + + OpenWithDialog + + + Open with + Abrir con + + + + Add other programs + Engadir outros programas + + + + Set as default + Definir como predefinido + + + + Cancel + button + Cancelar + + + + Confirm + button + Confirmar + + + + Recommended Applications + Aplicacións recomendadas + + + + Other Applications + Outras aplicacións + + + + PathManager + + + Home + Inicio + + + + Desktop + Escritorio + + + + Videos + Vídeos + + + + Music + Música + + + + Pictures + Imaxes + + + + Documents + Documentos + + + + Downloads + Descargas + + + + + Trash + Lixo + + + + + + System Disk + Disco do sistema + + + + Computers in LAN + Computadores na rede local + + + + My Shares + As miñas comparticións + + + + Computer + Computador + + + + Recent + Recente + + + + File Vault + Bóveda de ficheiros + + + + PropertyDialog + + + Basic info + Info. básica + + + + Open with + Abrir con + + + + Sharing + Compartindo + + + + Permissions + Permisos + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Agochar este cartafol + + + + Hide this file + Agochar este ficheiro + + + + Allow to execute as program + Permitir a execución como programa + + + + QObject + + + + + + Size + Tamaño + + + + + + Contains + Contén + + + + + + Type + Tipo + + + + + + + + Time modified + Data de modificación + + + + Free space + Espazo libre + + + + Total space + Espazo total + + + + + Time locked + + + + + Access denied + Acceso denegado + + + + + Executable + Executable + + + + + Write only + Só escribir + + + + + Read only + Só ler + + + + + Read-write + Ler-escribir + + + + Others + Outros + + + + Owner + Propietario + + + + Device type + Tipo de dispositivo + + + + File system + Sistema de ficheiros + + + + Group + Grupo + + + + + Open + Abrir + + + + Lock + + + + + Auto lock + + + + + Never + Nunca + + + + 5 minutes + + + + + 10 minutes + + + + + 20 minutes + + + + + Delete File Vault + + + + + Unlock + Desbloquear + + + + Unlock by key + + + + + Open + button + Abrir + + + + + Size: %1 + Tamaño: %1 + + + + Type: %1 + Tipo: %1 + + + + Size: 0 + Tamaño: 0 + + + + Items: %1 + Elemento: %1 + + + + + + + + + + Open in new window + Abrir nunha xanela nova + + + + + + + + + + Open in new tab + Abrir nunha lapela nova + + + + Open with + Abrir con + + + + + Compress + Comprimir + + + + Extract + Descomprimir + + + + Extract here + Descomprimir aquí + + + + Cut + Cortar + + + + Copy + Copiar + + + + Paste + Pegar + + + + + + + + Rename + Renomear + + + + + + Remove + Eliminar + + + + Create link + Crear ligazón + + + + Send to desktop + Enviar ao escritorio + + + + Send to + Enviar a + + + + Bluetooth + + + + + Add to bookmark + Engadir aos marcadores + + + + + + + Properties + Propiedades + + + + New folder + Novo cartafol + + + + New window + Nova xanela + + + + Select all + Seleccionar todo + + + + + Clear recent history + Limpar o historial recente + + + + + + Empty Trash + Baleirar o lixo + + + + Display as + Amosar como + + + + Sort by + Ordenar por + + + + New document + Novo documento + + + + + Time created + Data de creación + + + + Log out and unmount + Saír e desmontar + + + + + + Source path + Ruta orixe + + + + Share folder + Cartafol compartido + + + + Cancel sharing + Cancelar compartición + + + + Connect to Server + Conectar ao servidor + + + + Set share password + Fixar o contrasinal para compartir + + + + Format + Formatar + + + + Tag information + Información da etiqueta + + + + Open as administrator + + + + + Select default program + Seleccionar programa predefinido + + + + Open file location + Abrir localización do ficheiro + + + + Remove bookmark + Quitar dos marcadores + + + + + + Delete + Eliminar + + + + Office Text + Texto de oficina + + + + Spreadsheets + Folla de cálculo + + + + Plain Text + Texto simple + + + + Open in terminal + Abrir no termial + + + + Restore + Restaurar + + + + Restore all + Restaurar todo + + + + + + + + File Vault + Bóveda de ficheiros + + + + Add to disc + Engadir ao disco + + + + Auto mount + Montar automaticamente + + + + Open after auto mount + Abrir despois de montar automaticamente + + + + + Mount + Montar + + + + + Unmount + Desmontar + + + + It does not support burning %1 discs + + + + + Burn + Gravar + + + + Disc name: + Nome do disco: + + + + + Maximum + Máximo + + + + Allow files to be added later + Permitir aos ficheiros ser engadidos mais tarde + + + + Verify data + Datos verificados + + + + Write speed: + Velocidade de escritura: + + + + + + + Cancel + button + Cancelar + + + + Burn + button + Gravar + + + + + Eject + Expulsar + + + + Safely Remove + Eliminar de forma segura + + + + + Name + Nome + + + + Settings + Axustes + + + + Exit + Saír + + + + Icon + Icona + + + + List + Listaxe + + + + Extend + Estender + + + + Set as wallpaper + Definir coma fondo de pantalla + + + + + + + Local disk + Disco local + + + + + Removable disk + Disco extraíbel + + + + + + Network shared directory + Cartafol compartido + + + + + Android mobile device + Móbil Android + + + + + Apple mobile device + Dispositivo móbil de Apple + + + + + Camera + Cámara + + + + + DVD + DVD + + + + + Unknown device + Dispositivo descoñecido + + + + + + %1 item + %1 elemento + + + + + + %1 items + %1 elementos + + + + Shortcut + Atallo + + + + Create symlink + Crear ligazón simbólica + + + + Path + Ruta + + + + + + Time deleted + Data de eliminación + + + + Loading... + Cargando... + + + + File has been moved or deleted + O ficheiro foi movido ou eliminado + + + + You do not have permission to traverse files in it + + + + + + + You do not have permission to access this folder + Non tes permiso para acceder a este cartafol + + + + + + + + Folder is empty + Cartafol baleiro + + + + Searching... + Buscando... + + + + No results + Sen resultados + + + + Source Path + TrashFileInfo + Ruta orixe + + + + Document + Documento + + + + Spreadsheet + Folla de cálculo + + + + + Presentation + Presentación + + + + Text + Texto + + + + 1 task in progress + 1 tarefa en progreso + + + + %1 tasks in progress + %1 tarefas en progreso + + + + Mode: + Modo: + + + + + Replace Text + Substituír Texto + + + + + Add Text + Engadir Texto + + + + + Custom Text + Texto personalizado + + + + Find: + Buscar: + + + + Replace: + Substituír: + + + + + Optional + Opcional + + + + Add: + Engadir: + + + + Location: + Localización: + + + + File name: + Nome do ficheiro: + + + + Start at: + + + + + + Rename + button + Renomear + + + + + + + + + + + Required + Requirido + + + + + Before file name + Antes do nome do ficheiro + + + + + After file name + Despois do nome do ficheiro + + + + Find + Buscar + + + + Replace + Substituír + + + + Add + Engadir + + + + Start at + + + + + + + Location + Localización + + + + File name + Nome do ficheiro + + + + Dimension + Dimensión + + + + Duration + Duración + + + + Tips: Sort by selected file order + Consellos: ordenar por orde de ficheiros seleccionada + + + + Rename %1 Files + Renomear %1 ficheiros + + + + Multiple Files + Ficheiros múltiples + + + + Basic info + Info. básica + + + + Total size + Tamaño total + + + + Number of files + Número de ficheiros + + + + %1 file(s), %2 folder(s) + % 1 ficheiro (s),% 2 cartafol (s) + + + + + + Time accessed + Tempo accedido + + + + Orange + Laranxa + + + + Red + Vermello + + + + Purple + Morado + + + + Navy-blue + Azul marino + + + + Azure + Azul + + + + Green + Verde + + + + Yellow + Amarelo + + + + Gray + Gris + + + + Input tag info, such as work, family. A comma is used between two tags. + Información sobre etiquetas de entrada, como traballo, familia. Utilízase unha coma entre dúas etiquetas. + + + + Bookmarks + Marcadores + + + + Erase + Borrar + + + + Copy path + Copiar ruta + + + + Edit address + Editar enderezo + + + + Free Space %1 + Espazo libre %1 + + + + Files are being processed + Os ficheiros están a ser procesados + + + + Unknown + Descoñecido + + + + My Vault + + + + + + + Disks + Discos + + + + + Failed to create file info + + + + + Failed to create file handler + + + + + + + Execution error + + + + + + + + "'/\[]:|<>+=;,?* are not allowed + + + + + Failed to open the file, cause: %1 + Produciuse un erro ao abrir o arquivo debido a: %1 + + + + Original file does not exist + O arquivo orixinal non existe + + + + Do you want to delete %1? + + + + + Confirm + button + Confirmar + + + + ShareInfoFrame + + + Share this folder + Compartir este cartafol + + + + Share name: + Compartir nome: + + + + Permission: + Permiso: + + + + Read and write + Ler e escribir + + + + Read only + Só ler + + + + Anonymous: + Anónimo: + + + + Not allow + Non permitido + + + + Allow + Permitido + + + + The share name must not be two dots (..) or one dot (.) + + + + + The share name is used by another user. + + + + + OK + button + Aceptar + + + + Cancel + button + Cancelar + + + + Replace + button + Substituír + + + + The share name already exists. Do you want to replace the shared folder? + + + + + Shortcut + + + Item + Elemento + + + + Select to the first item + Seleccionar ata o primeiro elemento + + + + Shift + Home + Shift + Inicio + + + + Select to the last item + Seleccionar ata o último elemento + + + + Shift + End + Shift + Fin + + + + Select leftwards + Seleccionar á esquerda + + + + Shift + Left + Shift + Esquerda + + + + Select rightwards + Seeccionar á dereita + + + + Shift + Right + Shift + Dereita + + + + Select to upper row + Seleccionar ata a primeira fila + + + + Shift + Up + Shift + Arriba + + + + Select to lower row + Seleccionar ata a última fila + + + + Shift + Down + Shift + Abaixo + + + + Open + Abrir + + + + Ctrl + Down + Ctrl + Abaixo + + + + To parent directory + Ao cartafol superior + + + + Ctrl + Up + Ctrl + Arriba + + + + Permanently delete + Eliminar permanentemente + + + + Shift + Delete + Shift + Delete + + + + Delete file + Eliminar ficheiro + + + + Delete + Eliminar + + + + Select all + Seleccionar todo + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Copiar + + + + Cut + Cortar + + + + Paste + Pegar + + + + Rename + Renomear + + + + F2 + F2 + + + + New/Search + Novo/Buscar + + + + New window + Nova xanela + + + + New folder + Novo cartafol + + + + + Search + Buscar + + + + New tab + Nova lapela + + + + View + Ver + + + + Item information + Información do elemento + + + + Help + Axuda + + + + F1 + F1 + + + + Keyboard shortcuts + Atallos de teclado + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Estado de visualización + + + + Hide item + Ocultar elementos + + + + Input in address bar + Entrada na barra de dirección + + + + Switch to icon view + Cambia a vista de iconas + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Cambiar a vista de lista + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Outros + + + + Close + Pechar + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Pechar a lapela actual + + + + Back + Atrás + + + + Alt + Left + Alt + Esquerda + + + + Alt + Right + Alt + Dereita + + + + Switch to next tab + Cambiar á nova lapela + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Cambiar á lapela previa + + + + Next file + Seguinte ficheiro + + + + Tab + Tab + + + + Previous file + Ficheiro anterior + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Ir á lapela especificado cun número entre 1 e 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Avanzar + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + + + + + TrashPropertyDialog + + + Trash + Lixo + + + + item + Elemento + + + + items + Elementos + + + + Contains %1 %2 + Contén %1 %2 + + + + UDiskListener + + + Failed to rename the label + Produciuse un erro ao cambiar o nome da etiqueta + + + + UnmountWorker + + + + + The device was not safely unmounted + + + + + The device was not safely removed + + + + + UserShareManager + + + Kindly Reminder + Recordatorio + + + + Please firstly install samba to continue + En primeiro lugar, instalar samba para continuar + + + + To protect the files, you cannot share this folder. + Para protexer os ficheiros, non pode compartir este cartafol. + + + + The share name must not contain %<>*?|/\+=;:," + + + + + Sharing failed + + + + + The computer name is too long + + + + + You do not have permission to operate file/folder! + Non tes permiso para operar neste ficheiro/cartafol. + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Insira un contrasinal para protexer os cartafoles compartidos + + + + Cancel + button + Cancelar + + + + Confirm + button + Confirmar + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_hi_IN.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_hi_IN.ts new file mode 100644 index 0000000..9ff459a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_hi_IN.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + + + + + Basic Info + + + + + Computer Name + + + + + Version + संस्करण + + + + Type + प्रकार + + + + Processor + प्रोसेसर + + + + Memory + मेमोरी + + + + Disk + डिस्क + + + + Bit + बिट + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + + + + + DFMAdvanceSearchBar + + + Search: + + + + + File Type: + + + + + File Size: + + + + + Time Modified: + + + + + Reset + + + + + All subdirectories + + + + + Current directory + + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + + + + + Yesterday + + + + + This week + + + + + Last week + + + + + This month + + + + + Last month + + + + + This year + + + + + Last year + + + + + DFMTagCrumbController + + + Tag information + + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + + + + + The action is denied + + + + + Failed to open the file + + + + + Failed to read the file + + + + + Failed to write the file + + + + + Failed to create the directory + + + + + Failed to delete the file + + + + + Failed to move the file + + + + + Original file does not exist + + + + + Failed, file size must be less than 4GB + + + + + Not enough free space on the target disk + + + + + File integrity was damaged + + + + + The target device is read only + + + + + Target folder is inside the source folder + + + + + copy + Extra name added to new file name when used for file name. + + + + + Failed to create the directory, cause: %1 + + + + + + Failed to open the file, cause: %1 + + + + + Failed to read the file, cause: %1 + + + + + Failed to write the file, cause: %1 + + + + + File integrity was damaged, cause: %1 + + + + + Failed to delete the file, cause: %1 + + + + + Fail to create symlink, cause: %1 + + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + + + + + Cancel + + + + + Replace + + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + + + + + + + Time modified + + + + + Size + + + + + Type + + + + + Time created + + + + + + Last access + + + + + Path + + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + + + + + DFileViewHelper + + + Add tag "%1" + + + + + DStatusBar + + + %1 item + + + + + %1 items + + + + + %1 item selected + + + + + %1 items selected + + + + + %1 folder selected (contains %2) + + + + + %1 folders selected (contains %2) + + + + + %1 file selected (%2) + + + + + %1 files selected (%2) + + + + + %1 folder selected + + + + + Filter + + + + + Save as: + + + + + Loading... + + + + + DTaskDialog + + + This action is not supported + + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + + + + + Data Disk + Data Partition + + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + + + + + Target folder is inside the source folder! + + + + + + + + + + + + + + OK + + + + + Do you want to run %1 or display its content? + + + + + It is an executable text file. + + + + + + + + + + + + + + + Cancel + रद्द करें + + + + + + Run + + + + + + Run in terminal + + + + + Display + डिस्प्ले + + + + It is an executable file. + + + + + This file is not executable, do you want to add the execute permission and run? + + + + + "%1" already exists, please use another name. + + + + + + + + + Confirm + पुष्टि करें + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + %1: %2 + + + + + Show details + + + + + Hide details + + + + + Error + त्रुटि + + + + Permanently delete %1? + + + + + Permanently delete %1 items? + + + + + Delete + + + + + Empty + + + + + Sorry, unable to locate your bookmark directory, remove it? + + + + + Remove + + + + + Name: + + + + + Force unmount + + + + + %1 that this shortcut refers to has been changed or moved + + + + + Do you want to delete this shortcut? + + + + + Failed, file size must be less than 4GB. + + + + + Fail to create symlink, cause: + + + + + The selected files contain system file/directory, and it cannot be deleted + + + + + + You do not have permission to operate file/folder! + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + + + + + View + + + + + Do you want to run %1? + + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + + + + + Please restore by the following steps to normally access Windows disk + + + + + 1. Reboot to enter Windows + + + + 3. Reboot and enter deepin + + + + + Reboot + + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + + + + + Format + + + + + Cancel + + + + + Save + + + + + Open + + + + + Save File + + + + + Open File + + + + + FileJob + + + copy + + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + + + + + %1 m %2 s + + + + + %1 h %2 m %3 s + + + + + %1 d %2 h %3 m %4 s + + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + + + + + + + Open behavior + + + + + + + Always open folder in new window + + + + + + + Open file: + + + + + + + Click + + + + + + + Double click + + + + + + + New window and tab + + + + + + + Open from default window: + + + + + + + + + + Computer + + + + + + + + + + Home + + + + + + + + + + Desktop + + + + + + + + + + Videos + + + + + + + + + + Music + + + + + + + + + + Pictures + + + + + + + + + + Documents + + + + + + + + + + Downloads + + + + + + + Open in new tab: + + + + + + + Current Directory + + + + + + + View + + + + + + + Default size: + + + + + + + Extra small + + + + + + + Small + + + + + + + Medium + + + + + + + Large + + + + + + + Extra large + + + + + + + Default view: + + + + + + + Icon + + + + + + + List + + + + + + + Hidden files + + + + + + + Show hidden files + + + + + + + Hide file extension when rename + + + + + + + Advanced + + + + + + + Index + + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + + + + + + + Hide system disk + + + + + + + Show hidden files in search results + + + + + + + Display recent file entry in left panel + + + + + + + Preview + + + + + + Compress file preview + + + + + + + Text preview + + + + + + + Document preview + + + + + + + Image preview + + + + + + + Video preview + + + + + + + Mount + + + + + + + Auto mount + + + + + + + Open after auto mount + + + + + + + Dialog + + + + Use the file chooser dialog of Deepin File Manager + + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + + + + + + + + + Confirm + + + + + + Cannot find the mounting device + + + + + Cannot unmount the device + + + + + Cannot eject the device "%1" + + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + + + + + + + Application + + + + + + + Video + + + + + + + Audio + + + + + + + Image + + + + + + Archive + + + + + + + Text + + + + + + Executable + + + + + + Backup file + + + + + + Unknown + + + + + MountAskPasswordDialog + + + Cancel + + + + + Connect + + + + + Log in as + + + + + Anonymous + + + + + Registered user + + + + + Username + + + + + Domain + + + + + Password + + + + + Remember password + + + + + MountSecretDiskAskPasswordDialog + + + Cancel + + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + + + + Keep both + + + + Replace + + + + Do not ask again + + + + merge + + + + Copying %1 + + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + + + + Moving %1 + + + + Move to %2 + + + + Restoring %1 + + + + Restore to %2 + + + + Deleting %1 + + + + Trashing %1 + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + Retry + + + + Time modified:%1 + + + + Original folder + + + + Original file + + + + Target folder + + + + Target file + + + + Contains:%1 + + + + Size:%1 + + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + + + + + Delete + + + + + OpenWithDialog + + + Open with + + + + + Add other programs + + + + + Set as default + + + + + Cancel + + + + + Confirm + + + + + Recommended Applications + + + + + Other Applications + + + + + PathManager + + + Home + + + + + Desktop + + + + + Videos + + + + + Music + + + + + Pictures + + + + + Documents + + + + + Downloads + + + + + + Trash + + + + + + System Disk + + + + + Computers in LAN + + + + + My Shares + + + + + Computer + + + + + Recent + + + + + PropertyDialog + + + Basic info + + + + + Open with + + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + + + + + QObject + + + + + Size + + + + + + + Contains + + + + + + + Type + + + + + + + + Time modified + + + + + Free space + + + + + Total space + + + + + Access denied + + + + + + Executable + + + + + + Write only + + + + + + Read only + + + + + + Read-write + + + + + Others + + + + + Owner + + + + + Device type + + + + + File system + + + + + Group + + + + + + + Open + + + + + + Size: %1 + + + + + Type: %1 + + + + + Size: 0 + + + + + Items: %1 + + + + + + + + + + + + Open in new window + + + + + + + + + + + + Open in new tab + + + + + Open with + + + + + Compress + + + + + Extract + + + + + Extract here + + + + + Cut + + + + + Copy + + + + + Paste + + + + + + + + + + + Rename + + + + + + + Remove + + + + + Create link + + + + + Send to desktop + + + + + Send to + + + + + Add to bookmark + + + + + + + + Properties + + + + + New folder + + + + + New window + + + + + Select all + + + + + + Clear recent history + + + + + + + Empty Trash + + + + + Display as + + + + + Sort by + + + + + New document + + + + + + Time created + + + + + Log out and unmount + + + + + + + Source path + + + + + Share folder + + + + + Cancel sharing + + + + + Connect to Server + + + + + Set share password + + + + + Format + + + + + Tag information + + + + + Open in new window as admin + + + + + Select default program + + + + + Open file location + + + + + Remove bookmark + + + + + + + Delete + + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + + + + + Restore + + + + + Restore all + + + + + File Vault + + + + + Auto mount + + + + + Open after auto mount + + + + + + Mount + + + + + + Unmount + + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + + + + + Safely Remove + + + + + + Name + + + + + Settings + + + + + Exit + + + + + Icon + + + + + List + + + + + Extend + + + + + Set as wallpaper + + + + + + + + Local disk + + + + + + Removable disk + + + + + + + Network shared directory + + + + + + Android mobile device + + + + + + Apple mobile device + + + + + + Camera + + + + + + DVD + + + + + + Unknown device + + + + + + + %1 item + + + + + + + %1 items + + + + + Shortcut + + + + + Create symlink + + + + + Path + + + + + + + Time deleted + + + + + Loading... + + + + + File has been moved or deleted + + + + + + + You do not have permission to access this folder + + + + + + + + Folder is empty + + + + + Path + SearchFileInfo + + + + + Searching... + + + + + No results + + + + + Source Path + TrashFileInfo + + + + + Document + + + + + Spreadsheet + + + + + + Presentation + + + + + Text + + + + + 1 task in progress + + + + + %1 tasks in progress + + + + + Mode: + + + + + + Replace Text + + + + + + Add Text + + + + + + Custom Text + + + + + Find: + + + + + Replace: + + + + + + Optional + + + + + Add: + + + + + Location: + + + + + File name: + + + + + +SN: + + + + + + + + + + + Required + + + + + + Before file name + + + + + + After file name + + + + + Find + + + + + Replace + + + + + Add + + + + + + + Location + + + + + File name + + + + + Dimension + + + + + Duration + + + + + +SN + + + + + Tips: Sort by selected file order + + + + + + + Cancel + + + + + Rename %1 Files + + + + + Multiple Files + + + + + Basic info + + + + + Total size + + + + + Number of files + + + + + %1 file(s), %2 folder(s) + + + + + + + Time accessed + + + + + Orange + + + + + Red + + + + + Purple + + + + + Navy-blue + + + + + Azure + + + + + Green + + + + + Yellow + + + + + Gray + + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + + + + + Erase + + + + + + Copy path + + + + + + Edit address + + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + + + + + Share name: + + + + + Permission: + + + + + Read and write + + + + + Read only + + + + + Anonymous: + + + + + Not allow + + + + + Allow + + + + + Shortcut + + + Item + + + + + Select to the first item + + + + + Shift + Home + + + + + Select to the last item + + + + + Shift + End + + + + + Select leftwards + + + + + Shift + Left + + + + + Select rightwards + + + + + Shift + Right + + + + + Select to upper row + + + + + Shift + Up + + + + + Select to lower row + + + + + Shift + Down + + + + + Open + + + + + Ctrl + Down + + + + + To parent directory + + + + + Ctrl + Up + + + + + Permanently delete + + + + + Shift + Delete + + + + + Delete file + + + + + Delete + + + + + Select all + + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + + + + + Cut + + + + + Paste + + + + + Rename + + + + + F2 + + + + + New/Search + + + + + New window + + + + + New folder + + + + + + Search + + + + + New tab + + + + + View + + + + + Item information + + + + + Help + + + + + F1 + + + + + Keyboard shortcuts + + + + + Ctrl + Shift + / + + + + + Switch display status + + + + + Hide item + + + + + Input in address bar + + + + + Switch to icon view + + + + + Ctrl + 1 + + + + + Switch to list view + + + + + Ctrl + 2 + + + + + Others + + + + + Close + + + + + Alt + F4 + + + + + Close current tab + + + + + Back + + + + + Alt + Left + + + + + Alt + Right + + + + + Switch to next tab + + + + + Ctrl + Tab + + + + + Ctrl + Shift + Tab + + + + + Switch to previous tab + + + + + Next file + + + + + Tab + + + + + Previous file + + + + + Shift + Tab + + + + + Switch tab by specified number between 1 to 8 + + + + + Alt + [1-8] + + + + + Forward + + + + + TrashPropertyDialog + + + Trash + + + + + item + + + + + items + + + + + Contains %1 %2 + + + + + UDiskListener + + + Failed to rename the label + + + + + UserShareManager + + + Kindly Reminder + + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + + + + + Confirm + + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_hr.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_hr.ts new file mode 100644 index 0000000..de72120 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_hr.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + Nova mapa + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + Zatvori sve + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + Računalo + + + + Basic Info + Osnovne informacije + + + + Computer Name + Ime računala + + + + Version + Inačica + + + + Type + Tip + + + + Processor + Procesor + + + + Memory + Memorija + + + + Disk + Disk + + + + Bit + Bit + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + Pretraži ili unesi adresu + + + + DFMAdvanceSearchBar + + + Search: + Traži: + + + + File Type: + Vrsta datoteke: + + + + File Size: + Veličina datoteke: + + + + Time Modified: + Vrijeme izmjene: + + + + Reset + + + + + All subdirectories + Svi poddirektoriji + + + + Current directory + Trenutni direktorij + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Danas + + + + Yesterday + Jučer + + + + This week + Ovaj tjedan + + + + Last week + Prošli tjedan + + + + This month + Ovaj mjesec + + + + Last month + Prošli mjesec + + + + This year + Ove godine + + + + Last year + Prošle godine + + + + DFMTagCrumbController + + + Tag information + + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + Greška dozvole + + + + The action is denied + Radnja je odbijena + + + + Failed to open the file + Neuspjelo otvaranje datoteke + + + + Failed to read the file + Neuspjelo čitanje datoteke + + + + Failed to write the file + Neuspjelo pisanje datoteke + + + + Failed to create the directory + Neuspjelo stvaranje direktorija + + + + Failed to delete the file + Neuspjelo brisanje datoteke + + + + Failed to move the file + Neuspjelo premještanje datoteke + + + + Original file does not exist + Izvorna datoteka ne postoji + + + + Failed, file size must be less than 4GB + Neuspjeh, datoteka mora biti manja od 4GB + + + + Not enough free space on the target disk + + + + + File integrity was damaged + + + + + The target device is read only + + + + + Target folder is inside the source folder + + + + + copy + Extra name added to new file name when used for file name. + kopiraj + + + + Failed to create the directory, cause: %1 + + + + + + Failed to open the file, cause: %1 + + + + + Failed to read the file, cause: %1 + + + + + Failed to write the file, cause: %1 + + + + + File integrity was damaged, cause: %1 + + + + + Failed to delete the file, cause: %1 + + + + + Fail to create symlink, cause: %1 + + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + + + + + Cancel + Otkaži + + + + Replace + Zamijeni + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + Ime + + + + + + Time modified + Vrijeme promjene + + + + Size + Veličina + + + + Type + Tip + + + + Time created + Vrijeme stvaranja + + + + + Last access + Zadnji pristup + + + + Path + Putanja + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + + + + + DFileViewHelper + + + Add tag "%1" + + + + + DStatusBar + + + %1 item + %1 stavka + + + + %1 items + %1 stavki + + + + %1 item selected + %1 stavka odabrana + + + + %1 items selected + %1 stavki odabrano + + + + %1 folder selected (contains %2) + %1 mapa odabrana (sadrži %2) + + + + %1 folders selected (contains %2) + %1 mapa odabrano (sadrže %2) + + + + %1 file selected (%2) + %1 datoteka odabrana (%2) + + + + %1 files selected (%2) + %1 datoteka odabrana (%2) + + + + %1 folder selected + %1 mapa odabrana + + + + Filter + Filter + + + + Save as: + Spremi kao: + + + + Loading... + Učitavam... + + + + DTaskDialog + + + This action is not supported + Ova radnja nije podržana + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + + + + + Data Disk + Data Partition + Podatkovni disk + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + Operacija nije uspjela! + + + + Target folder is inside the source folder! + Ciljana mapa je unutar izvorne mape! + + + + + + + + + + + + + OK + U redu + + + + Do you want to run %1 or display its content? + Želiš li pokrenuti %1 ili prikazati sadržaj? + + + + It is an executable text file. + To je izvršna tekstualna datoteka. + + + + + + + + + + + + + + Cancel + Otkaži + + + + + + Run + Pokreni + + + + + Run in terminal + Pokreni u terminalu + + + + Display + Prikaži + + + + It is an executable file. + To je izvršna tekstualna datoteka. + + + + This file is not executable, do you want to add the execute permission and run? + + + + + "%1" already exists, please use another name. + "%1" već postoji, molim koristi drugo ime. + + + + + + + + Confirm + Potvrdi + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + Trajno obriši %1? + + + + Permanently delete %1 items? + Trajno obriši %1 stavki? + + + + Delete + Obriši + + + + Empty + Isprazni + + + + Sorry, unable to locate your bookmark directory, remove it? + Isprika, ne mogu locirati tvoj označeni direktorij, ukloni ga? + + + + Remove + Ukloni + + + + Name: + Ime: + + + + Force unmount + Prisili odmontiranje + + + + %1 that this shortcut refers to has been changed or moved + %1 na što se ovaj prečac odnosi je promjenjeno ili premješteno + + + + Do you want to delete this shortcut? + Želite li izbrisati ovaj prečac? + + + + Failed, file size must be less than 4GB. + Neuspjelo, datoteka mora biti manja od 4GB. + + + + Fail to create symlink, cause: + Neuspjeh u stvaranju simboličke poveznice,uzrok: + + + + The selected files contain system file/directory, and it cannot be deleted + Odabrane datoteke sadrže mapu/direktorij sustava, i ne može biti izbrisan + + + + + You do not have permission to operate file/folder! + Nemate dozvolu da radite sa datotekom/mapom! + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + + + + + View + Pogled + + + + Do you want to run %1? + + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + Montiraj particiju%1 samo za čitanje + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + + + + + Please restore by the following steps to normally access Windows disk + Molim obnovite slijedeće korake za normalan pristup Windows disku + + + + 1. Reboot to enter Windows + 1. Ponovno podigni sustav za ulaz u Windowse + + + 3. Reboot and enter deepin + 3. Ponovno podigni sustav i uđi u deepin + + + + Reboot + Ponovno podigni sustav + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + Ime datoteke + + + + Format + Format + + + + Cancel + Otkaži + + + + Save + Spremi + + + + Open + Otvori + + + + Save File + Spremi datoteku + + + + Open File + Otvori datoteku + + + + FileJob + + + copy + kopiraj + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 s %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 s %3 m %4 s + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + Osnovno + + + + + + Open behavior + Ponašanje otvaranja + + + + + + Always open folder in new window + Uvijek otvori mapu u novom prozoru + + + + + + Open file: + Otvori datoteku: + + + + + + Click + Klik + + + + + + Double click + Dvostruki klik + + + + + + New window and tab + Novi prozor i nova kartica + + + + + + Open from default window: + Otvori iz zadanog prozora: + + + + + + + + + Computer + Računalo + + + + + + + + + Home + Dom + + + + + + + + + Desktop + Radna površina + + + + + + + + + Videos + Video zapisi + + + + + + + + + Music + Glazba + + + + + + + + + Pictures + Slike + + + + + + + + + Documents + Dokumenti + + + + + + + + + Downloads + Preuzimanja + + + + + + Open in new tab: + Otvori u novoj kartici: + + + + + + Current Directory + Trenutni direktorij + + + + + + View + Pogled + + + + + + Default size: + Zadana veličina: + + + + + + Extra small + Izuzetno malo + + + + + + Small + Malo + + + + + + Medium + Srednje + + + + + + Large + Veliko + + + + + + Extra large + Izuzetno veliko + + + + + + Default view: + + + + + + + Icon + Ikona + + + + + + List + Popis + + + + + + Hidden files + Skrivene datoteke + + + + + + Show hidden files + Pokaži skrivene datoteke + + + + + + Hide file extension when rename + + + + + + + Advanced + Napredno + + + + + + Index + + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + Ostalo + + + + + + Hide system disk + + + + + + + Show hidden files in search results + Pokaži skrivene datoteke u rezultatima pretrage + + + + + + Display recent file entry in left panel + + + + + + + Preview + Pregled + + + + + Compress file preview + + + + + + + Text preview + Pregled teksta + + + + + + Document preview + Pregled dokumenta + + + + + + Image preview + Pregled slike + + + + + + Video preview + Pregled video zapisa + + + + + + Mount + Spoji + + + + + + Auto mount + Samomontiranje + + + + + + Open after auto mount + + + + + + + Dialog + Dijalog + + + Use the file chooser dialog of Deepin File Manager + + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + + + + + + + + + Confirm + Potvrdi + + + + + Cannot find the mounting device + + + + + Cannot unmount the device + + + + + Cannot eject the device "%1" + + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + Direktorij + + + + + + Application + + + + + + + Video + Video + + + + + + Audio + Audio + + + + + + Image + Slika + + + + + Archive + Arhiva + + + + + + Text + Tekst + + + + + Executable + Izvršna + + + + + Backup file + + + + + + Unknown + Nepoznato + + + + MountAskPasswordDialog + + + Cancel + Otkaži + + + + Connect + Spoji se + + + + Log in as + Prijavi se kao + + + + Anonymous + Anonimac + + + + Registered user + Registrirani korisnik + + + + Username + Korisničko ime + + + + Domain + Domena + + + + Password + Lozinka + + + + Remember password + Zapamti lozinku + + + + MountSecretDiskAskPasswordDialog + + + Cancel + Otkaži + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + Preskoči + + + Keep both + Zadrži obje + + + Replace + Zamijeni + + + Do not ask again + Ne pitaj ponovno + + + merge + + + + Copying %1 + Kopiram %1 + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + Kopiraj u %2 + + + Moving %1 + Premještam %1 + + + Move to %2 + Premjesti u %2 + + + Restoring %1 + Obnavljam %1 + + + Restore to %2 + Obnovi u %2 + + + Deleting %1 + Brišem %1 + + + Trashing %1 + Bacam u smeće %1 + + + Calculating space, please wait + Izračunavam prostor, molim pričekajte + + + File named %1 already exists in target folder + Datoteka imenom %1 već postoji u ciljanoj mapi + + + Original path %1 target path %2 + Izvorna putanja %1 ciljana putanja %2 + + + Retry + Pokušajte ponovno + + + Time modified:%1 + Vrijeme izmjene:%1 + + + Original folder + Izvorna mapa + + + Original file + Izvorna datoteka + + + Target folder + + + + Target file + + + + Contains:%1 + Sadrži:%1 + + + Size:%1 + Veličina:%1 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + Otkaži + + + + Delete + Obriši + + + + OpenWithDialog + + + Open with + Otvori sa + + + + Add other programs + Dodaj druge programe + + + + Set as default + Postavi kao zadano + + + + Cancel + Otkaži + + + + Confirm + + + + + Recommended Applications + Preporučeni programi + + + + Other Applications + Ostali programi + + + + PathManager + + + Home + Dom + + + + Desktop + Radna površina + + + + Videos + Video zapisi + + + + Music + Glazba + + + + Pictures + Slike + + + + Documents + Dokumenti + + + + Downloads + Preuzimanja + + + + + Trash + Smeće + + + + + System Disk + Disk sustava + + + + Computers in LAN + Računala u LAN-u + + + + My Shares + Moja djeljenja + + + + Computer + Računalo + + + + Recent + + + + + PropertyDialog + + + Basic info + Osnovne informacije + + + + Open with + Otvori sa + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + Dopusti da se pokrene kao program + + + + QObject + + + + + Size + Veličina + + + + + + Contains + Sadrži + + + + + + Type + Tip + + + + + + + Time modified + Vrijeme promjene + + + + Free space + Slobodan prostor + + + + Total space + Ukupan prostor + + + + Access denied + + + + + + Executable + Izvršna + + + + + Write only + + + + + + Read only + Samo čitaj + + + + + Read-write + + + + + Others + Ostali + + + + Owner + Vlasnik + + + + Device type + + + + + File system + + + + + Group + Grupa + + + + + + Open + Otvori + + + + + Size: %1 + Veličina: %1 + + + + Type: %1 + Vrsta: %1 + + + + Size: 0 + Veličina: 0 + + + + Items: %1 + Stavke: %1 + + + + + + + + + + + Open in new window + Otvori u novom prozoru + + + + + + + + + + + Open in new tab + Otvori u novoj kartici + + + + Open with + Otvori sa + + + + Compress + Komprimiranje + + + + Extract + Dekomprimiranje + + + + Extract here + Dekomprimiraj ovdje + + + + Cut + Pomakni + + + + Copy + Kopiraj + + + + Paste + Prekopiraj + + + + + + + + + + Rename + Preimenuj + + + + + + Remove + Ukloni + + + + Create link + Stvori vezu + + + + Send to desktop + Pošalji na radnu površinu + + + + Send to + Pošalji za + + + + Add to bookmark + Dodaj u favorite + + + + + + + Properties + Svojstva + + + + New folder + Novi direktorij + + + + New window + Novi prozor + + + + Select all + Odaberi sve + + + + + Clear recent history + Očisti nedavnu povijest + + + + + + Empty Trash + Isprazni smeće + + + + Display as + Prikaži kao + + + + Sort by + Sortiraj po + + + + New document + Novi dokument + + + + + Time created + Vrijeme stvaranja + + + + Log out and unmount + Odjavi i odspoji se + + + + + + Source path + Izvorna putanja + + + + Share folder + Dijeli mapu + + + + Cancel sharing + Otkaži djeljenje + + + + Connect to Server + + + + + Set share password + Postavi lozinku djeljenja + + + + Format + Format + + + + Tag information + + + + + Open in new window as admin + Otvori u novom prozoru kao administrator + + + + Select default program + Odaberi zadani program + + + + Open file location + Otvori lokaciju datoteke + + + + Remove bookmark + + + + + + + Delete + Obriši + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + Otvori u terminalu + + + + Restore + Vrati + + + + Restore all + Vrati sve + + + + File Vault + + + + + Auto mount + Samomontiranje + + + + Open after auto mount + + + + + + Mount + Spoji + + + + + Unmount + Odspoji + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + Izbaci + + + + Safely Remove + Sigurno ukloni + + + + + Name + Ime + + + + Settings + Postavke + + + + Exit + Izlaz + + + + Icon + Ikona + + + + List + Popis + + + + Extend + Proširi + + + + Set as wallpaper + Postavi za pozadinu + + + + + + + Local disk + Lokalni disk + + + + + Removable disk + Uklonjivi disk + + + + + + Network shared directory + Mrežni dijeljeni direktorij + + + + + Android mobile device + Android mobilni uređaj + + + + + Apple mobile device + Apple mobilni uređaj + + + + + Camera + Kamera + + + + + DVD + + + + + + Unknown device + Nepoznati uređaj + + + + + + %1 item + %1 stavka + + + + + + %1 items + %1 stavki + + + + Shortcut + Prečac + + + + Create symlink + Stvori simboličku vezu + + + + Path + Putanja + + + + + + Time deleted + Vrijeme brisanja + + + + Loading... + Učitavam... + + + + File has been moved or deleted + Datoteka je premještena ili obrisana + + + + + + You do not have permission to access this folder + Nemate dozvole za pristup ovoj mapi + + + + + + + Folder is empty + Mapa je prazna + + + + Path + SearchFileInfo + Putanja + + + + Searching... + Pretražujem... + + + + No results + Nema rezultata + + + + Source Path + TrashFileInfo + Izvorna putanja + + + + Document + Dokument + + + + Spreadsheet + + + + + + Presentation + Prezentacija + + + + Text + Tekst + + + + 1 task in progress + 1 zadatak u tijeku + + + + %1 tasks in progress + %1 zadataka u tijeku + + + + Mode: + Način rada: + + + + + Replace Text + Zamijeni tekst + + + + + Add Text + Dodaj tekst + + + + + Custom Text + Prilagođeni tekst + + + + Find: + Nađi: + + + + Replace: + Zamijeni: + + + + + Optional + + + + + Add: + Dodaj: + + + + Location: + Lokacija + + + + File name: + Ime datoteke: + + + + +SN: + +SN: + + + + + + + + + + Required + + + + + + Before file name + Prije imena datoteke + + + + + After file name + Nakon imena datoteke + + + + Find + Nađi + + + + Replace + Zamijeni + + + + Add + Dodaj + + + + + + Location + Lokacija + + + + File name + Ime datoteke + + + + Dimension + + + + + Duration + + + + + +SN + +SN + + + + Tips: Sort by selected file order + Savjeti: Sortiraj po odabranom redu datoteku + + + + + + Cancel + Otkaži + + + + Rename %1 Files + Preimenuj %1 datoteka + + + + Multiple Files + Višestruke datoteke + + + + Basic info + Osnovne informacije + + + + Total size + Ukupna veličina + + + + Number of files + Broj datoteka + + + + %1 file(s), %2 folder(s) + + + + + + + Time accessed + + + + + Orange + + + + + Red + + + + + Purple + + + + + Navy-blue + + + + + Azure + + + + + Green + + + + + Yellow + + + + + Gray + + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + Zabilješke + + + + Erase + + + + + + Copy path + + + + + + Edit address + Uredi adresu + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + Dijeli ovu mapu + + + + Share name: + Ime djeljenja: + + + + Permission: + Dozvola: + + + + Read and write + Čitaj i piši + + + + Read only + Samo čitaj + + + + Anonymous: + Anonimac: + + + + Not allow + Ne dopusti + + + + Allow + Dopusti + + + + Shortcut + + + Item + Stavka + + + + Select to the first item + Odaberi prvu stavku + + + + Shift + Home + Shift + Home + + + + Select to the last item + Odaberi zadnju stavku + + + + Shift + End + Shift + End + + + + Select leftwards + Odaberi ulijevo + + + + Shift + Left + Shift + Left + + + + Select rightwards + Odaberi udesno + + + + Shift + Right + Shift + Right + + + + Select to upper row + Odaberi gornji redak + + + + Shift + Up + Shift + Up + + + + Select to lower row + Odaberi donji redak + + + + Shift + Down + Shift + Down + + + + Open + Otvori + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Trajno obriši + + + + Shift + Delete + Shift + Delete + + + + Delete file + Izbriši datoteku + + + + Delete + Obriši + + + + Select all + Odaberi sve + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + Kopiraj + + + + Cut + Izreži + + + + Paste + Zalijepi + + + + Rename + Preimenuj + + + + F2 + F2 + + + + New/Search + Novi/traži + + + + New window + Novi prozor + + + + New folder + Nova mapa + + + + + Search + Traži + + + + New tab + Nova kartica + + + + View + Pogled + + + + Item information + Informacija o stavci + + + + Help + Pomoć + + + + F1 + F1 + + + + Keyboard shortcuts + Kratice tipkovnice + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Promjeni status prikaza + + + + Hide item + Sakrij stavku + + + + Input in address bar + Unesi u adresnu traku + + + + Switch to icon view + + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Ostali + + + + Close + Zatvori + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Zatvori trenutnu karticu + + + + Back + Natrag + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Prebaci na slijedeću karticu + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Prebaci na prethodnu karticu + + + + Next file + Slijedeća datoteka + + + + Tab + Kartica + + + + Previous file + Prethodna datoteka + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Prebacuj između kartica pomoću određenih brojeva između 1 do 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Naprijed + + + + TrashPropertyDialog + + + Trash + Smeće + + + + item + Stavka + + + + items + stavke + + + + Contains %1 %2 + Sadrži %1 %2 + + + + UDiskListener + + + Failed to rename the label + + + + + UserShareManager + + + Kindly Reminder + + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + Otkaži + + + + Confirm + Potvrdi + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_hu.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_hu.ts new file mode 100644 index 0000000..5aac637 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_hu.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Új mappa + + + + Mounting device error + Eszköz csatlakoztatása sikertelen + + + + The disc image was corrupted, cannot mount now, please erase the disc first + A lemezkép sérült, most nem csatlakoztatható, kérjük először törölje a lemezt + + + + Mount error: unsupported image format + Csatlakoztatás meghiúsult: nem támogatott képformátum + + + + + The device was not safely removed + Az eszközt nem sikerült biztonságosan eltávolítani + + + + + Click "Safely Remove" and then disconnect it next time + Kattintson a "Biztonságos eltávolítás" gombra, majd csatlakoztassa le később + + + + The device was not ejected + Az eszközt nem sikerült lecsatolni + + + + Disk is busy, cannot eject now + A lemez használatban van, jelenleg nem választható le + + + + Authentication timed out + A hitelesítés lejárt + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Bluetooth fájlátvitel + + + + File Transfer Successful + A fájlátvitel sikeres + + + + File Transfer Failed + A fájlátvitel sikertelen + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Fájlok küldése a "<b style="font-weight: 550;">%1</b>-re" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Fájlok küldése a "<b style="font-weight: 550;">%1</b>-re" sikertelen + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Sikeresen elküldve a "<b style="font-weight: 550;">%1</b>-re" + + + + Select a Bluetooth device to receive files + Válasszon egy Bluetooth-eszközt a fájlok fogadásához + + + + Cannot find the connected Bluetooth device + Nem található a csatlakoztatott Bluetooth-eszköz + + + + Waiting to be received... + Várakozás a fogadásra ... + + + + Go to Bluetooth Settings + Ugrás a Bluetooth beállításokra + + + + %1/%2 Sent + %1/%2 elküldve + + + + Error: the Bluetooth device is disconnected + Hiba: A Bluetooth-eszköz lecsatlakoztatva + + + + Unable to send the file more than 2 GB + Nem lehet 2 GB-nál nagyobb méretű fájlt küldeni + + + + Unable to send 0 KB files + 0 KB-os fájl nem küldhető + + + + File doesn't exist + Az fájl nem létezik + + + + Next + button + Következő + + + + Cancel + button + Mégsem + + + + Done + button + Kész + + + + Retry + button + Újra + + + + OK + button + OK + + + + File sending request timed out + A fájlküldési kérelem időtúllépése + + + + The service is busy and unable to process the request + A szolgáltatás foglalt, így nem tudja feldolgozni a kérést + + + + BurnOptDialog + + + Device error + Eszköz hiba + + + + Optical device %1 doesn't exist + A %1 optikai eszköz nem létezik + + + + Advanced settings + Haladó beállítások + + + + File system: + Fájlrendszer: + + + + ISO9660/Joliet (For Windows) + ISO9660 / Joliet (Windows esetén) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660 / RockRidge (Unix esetén) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Kompatibilis a Windows CD/DVD móddal) + + + + ISO9660 Only + Csak ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Összes bezárása + + + + Total size: %1, %2 files + Teljes méret: %1, %2 fájl + + + + ComputerModel + + + Double click to open it + Kattintson duplán a megnyitásához + + + + My Directories + Saját könyvtáram + + + + Disks + Lemezek + + + + File Vault + Fájl tároló + + + + Quick Access + Gyors hozzáférés + + + + ComputerPropertyDialog + + + Computer + Számítógép + + + + Basic Info + Alapvető információk + + + + + Computer Name + Számítógép név + + + + + Edition + Kiadás + + + + + + Version + Verzió: + + + + + Type + Típus + + + + + + Processor + Processzor + + + + + + Memory + Memória + + + + + + + Bit + Bit + + + + + Available + Elérhető + + + + Obtaining... + A beszerzés folyamatban... + + + + ConnectToServerDialog + + + Connect to Server + Csatlakozás kiszolgálóhoz + + + + Cancel + button + Mégsem + + + + Connect + button + Csatlakozás + + + + My Favorites: + Kedvenceim: + + + + + Clear History + Előzmények törlése + + + + DFMAddressBar + + + Search or enter address + Cím megadása vagy keresése + + + + DFMAdvanceSearchBar + + + Search: + Keresés: + + + + File Type: + Fájltípus: + + + + File Size: + Fájlméret: + + + + Time Modified: + Módosítás időpontja: + + + + Time Accessed: + Hozzáférési idő: + + + + Time Created: + Létrehozás ideje: + + + + Reset + Visszaállítás + + + + All subdirectories + Minden alkönyvtár + + + + Current directory + Jelenlegi mappa + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Ma + + + + Yesterday + Tegnap + + + + This week + Ezen a héten + + + + Last week + Múlthéten + + + + This month + Ebben a hónapban + + + + Last month + Múlt hónapban + + + + This year + Ebben az évben + + + + Last year + Múlt évben + + + + DFMOpticalMediaWidget + + + + No files to burn + Nincsenek írható fájlok + + + + Unable to burn. Not enough free space on the target disk. + Nem sikerült megírni. Nincs elég szabad hely a céllemezen. + + + + %1 burning is not supported + A %1 írása nem támogatott + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. Ez nem a %1 lemez; +2. A fájlrendszer verziója még nem támogatja a fájlok hozzáadását. + + + + DFMTagCrumbController + + + Tag information + Címke információ + + + + DFMTagWidget + + + Tag + Címke + + + + DFMTaskWidget + + + Do not ask again + Ne kérdezze újra + + + + Syncing data + Adatok szinkronizálása + + + + Please wait + Kérjük várjon + + + + + Time modified: %1 + Módosítási idő: %1 + + + + + Contains: %1 + Tartalmazza: %1 + + + + + Size: %1 + Méret: %1 + + + + Original folder + Eredeti mappa + + + + Keep both + button + Mindkettő megtartása + + + + Skip + button + Kihagyás + + + + Replace + button + Csere + + + + Retry + button + Újra + + + + Original file + Eredeti fájl + + + + Target folder + Cél mappa + + + + Target file + Cél fájl + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Fájl tároló titkosítása + + + + Click 'Encrypt' and input the user password. + Kattintson a "Titkosítás" gombra, és írja be a felhasználói jelszót. + + + + Encrypting... + Titkosítás... + + + + + + + Encrypt + Titkosítás + + + + Failed to create file vault: %1 + Nem sikerült létrehozni a % 1 fájltárolót + + + + OK + OK + + + + The setup is complete + A beállítás befejeződött + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Helyreállítási kulcs mentése + + + + Keep the key safe to retrieve the vault password later + Tartsa biztonságban a kulcsot, hogy később lekérhesse a trezor jelszót + + + + Save to default path + Mentés az alapértelmezett elérési útvonalra + + + + Save to other locations + Mentés más helyre + + + + No permission, please reselect + Nincs engedélye, kérjük válasszon újra + + + + Select a path + Válasszon egy útvonalat + + + + Next + Következő + + + + The default path is invisible to other users, and the path information will not be shown. + Az alapértelmezett elérési útvonal más felhasználók számára nem látható, és az elérési útvonal információi nem jelennek meg. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Helyreállítási kulcs + + + + Generate a recovery key in case that you forgot the password + Generáljon helyreállítási kulcsot arra az esetre, ha elfelejtette a jelszót + + + + Key + Kulcs + + + + QR code + QR kód + + + + Scan QR code and save the key to another device + Olvassa be a QR-kódot, és mentse a kulcsot egy másik eszközre + + + + Next + Következő + + + + Recovery Key: + Helyreállítási kulcs: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Tároló jelszó beállítása + + + + Method + Módszer + + + + Manual + Manuális + + + + Password + Jelszó + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 karakter, tartalmazhatja A-Z, a-z, 0-9 és szimbólumokat + + + + Repeat password + Jelszó ismétlése + + + + Input the password again + Adja meg a jelszót újra + + + + Password hint + Jelszó emlékeztető + + + + Optional + Opcionális + + + + Next + Következő + + + + + Passwords do not match + A jelszavak nem egyeznek + + + + DFMVaultActiveStartView + + + File Vault + Fájl tároló + + + + Create your secure private space + Hozzon létre biztonságos privát teret + + + + Advanced encryption technology + Fejlett titkosítási technológia + + + + Convenient and easy to use + Kényelmes és könnyen használható + + + + Create + Létrehozás + + + + DFMVaultFileView + + + Cannot open this path + Ez az útvonal nem nyitható meg + + + + Hint + Célzás + + + + OK + OK + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Feloldás kulccsal + + + + Failed to unlock file vault + Nem sikerült feloldani a fájltárolót + + + + OK + OK + + + + Input the 32-digit recovery key + Írja be a 32 jegyű helyreállítási kulcsot + + + + Cancel + button + Mégsem + + + + Unlock + button + Feloldás + + + + Wrong recovery key + Helytelen helyreállítási kulcs + + + + DFMVaultRemoveByPasswordView + + + Password + Jelszó + + + + Password hint: %1 + Jelszó emlékeztető: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Írja be a 32 jegyű helyreállítási kulcsot + + + + DFMVaultRemovePages + + + Delete File Vault + Fájl tároló törlése + + + + Once deleted, the files in it will be permanently deleted + A törlés után a benne lévő fájlok véglegesen törlődnek + + + + Use Key + Kulcs használata + + + + Cancel + button + Mégsem + + + + Use Key + button + Kulcs használata + + + + Delete + button + Törlés + + + + + OK + button + OK + + + + Use Password + Jelszó használata + + + + Wrong password + Helytelen jelszó + + + + Wrong recovery key + Helytelen helyreállítási kulcs + + + + Failed to delete file vault + A fájl tároló törlése sikertelen + + + + Deleted successfully + Sikeresen törölve + + + + Failed to delete + A törlés sikertelen + + + + Removing... + Eltávolítás... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + Nem sikerült beszerezni a kulcsfájlt + + + + Verification failed + Az ellenőrzés sikertelen + + + + + Select a path + Válasszon egy útvonalat + + + + + Retrieve Password + Jelszó lekérése + + + + By key in the default path + Az alapértelmezett elérési útvonal kulcsával + + + + By key in the specified path + Kulcs segítségével a megadott útvonalon + + + + Verification Successful + Az ellenőrzés sikeres + + + + Keep it safe + Tartsa biztonságban + + + + Back + button + Vissza + + + + Verify Key + button + Kulcs ellenőrzése + + + + Go to Unlock + button + Ugrás a feloldáshoz + + + + Close + button + Bezárás + + + + Vault password: %1 + Trezor jelszó: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Fájltároló feloldása + + + + Forgot password? + Elfelejtette a jelszavát? + + + + Password hint: %1 + Jelszó emlékeztető: %1 + + + + Failed to unlock file vault + Nem sikerült feloldani a fájltárolót + + + + Cancel + button + Mégsem + + + + Password + Jelszó + + + + Unlock + button + Feloldás + + + + Please try again %1 minutes later + Kérjük próbálja újra %1 perc múlva + + + + Wrong password, please try again %1 minutes later + Helytelen jelszó, kérjük próbálja újra %1 perc múlva + + + + Wrong password, one chance left + Helytelen jelszó, egy próbálkozása maradt + + + + Wrong password, %1 chances left + Helytelen jelszó, %1 próbálkozása maradt + + + + Wrong password + Helytelen jelszó + + + + OK + button + OK + + + + DFileCopyMoveJob + + + Permission error + Jogosultsági hiba + + + + The action is denied + A művelet megtagadva + + + + Failed to open the file + A fájl megnyitása sikertelen + + + + Failed to read the file + A fájl beolvasása sikertelen + + + + Failed to write the file + A fájl írása sikertelen + + + + Failed to create the directory + A mappa létrehozása sikertelen + + + + Failed to delete the file + A fájl törlése sikertelen + + + + Failed to move the file + A fájl áthelyezése sikertelen + + + + Original file does not exist + Az eredeti fájl nem létezik + + + + Failed, file size must be less than 4GB + Hiba, a fájlméretnek 4GB-nál kisebbnek kell lennie + + + + Not enough free space on the target disk + Nincs elég szabad hely a céllemezen + + + + File integrity was damaged + A fájlintegritás sérült + + + + The target device is read only + A céleszköz csak olvasható + + + + Target folder is inside the source folder + A cél mappa a forrás mappában található + + + + The action is not supported + A művelet nem támogatott + + + + You do not have permission to traverse files in it + Nincs jogosultsága a belső fájlok bejárására + + + + Failed to position the file pointer! + Nem sikerült elhelyezni a fájl mutatót + + + + copy + Extra name added to new file name when used for file name. + másolat + + + + Failed to open the directory, cause: file name too long + Nem sikerült megnyitni a mappát, oka: a fájlnév túl hosszú + + + + + Failed to open the file, cause: file name too long + Nem sikerült megnyitni a fájlt, oka: a fájlnév túl hosszú + + + + + Failed to write the file, cause: + Nem sikerült megírni a fájlt, oka: + + + + Failed to position the file pointer, cause: %1 + Nem sikerült elhelyezni a fájl mutatót, oka: %1 + + + + Syncing data + Adatok szinkronizálása + + + + Please wait + Kérjük várjon + + + + Failed to create the directory, cause: %1 + A mappa létrehozása meghiúsult, oka: %1 + + + + + + + + Failed to open the file, cause: %1 + A fájl megnyitása sikertelen, oka: %1 + + + + + + + Failed to open the file, cause: Permission denied + Nem sikerült megnyitni a fájlt, oka: Engedély megtagadva + + + + + Failed to read the file, cause: %1 + A fájl olvasása sikertelen, oka: %1 + + + + + + + Failed to write the file, cause: %1 + A fájl írása sikertelen, oka: %1 + + + + + File integrity was damaged, cause: %1 + A fájl integritása sérült, oka: %1 + + + + Failed to open the file, cause: + Nem sikerült megnyitni a fájlt, oka: + + + + Failed to read the file, cause: + Nem sikerült olvasni a fájlt, oka: + + + + Failed to delete the file, cause: %1 + A fájl törlése sikertelen, oka: %1 + + + + Fail to create symlink, cause: %1 + A symlink létrehozása sikertelen, oka: %1 + + + + DFileDialog + + + + Save + button + Mentés + + + + + Cancel + button + Mégsem + + + + Confirm + button + Megerősítés + + + + %1 already exists, do you want to replace it? + A %1 már létezik, felül kívánja írni? + + + + Replace + button + Csere + + + + Open + button + Megnyitás + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Ez a fájl el lesz rejtve, ha a fájl neve ponttal (.) Kezdődik. El akarja rejteni? + + + + DFileManagerWindow + + + Trash + Kuka + + + + Empty + Üres + + + + DFileSystemModel + + + + Name + Név + + + + + + Time modified + Módosítási idő + + + + Size + Méret + + + + Type + Típus + + + + Time created + Létrehozási idő + + + + + Last access + Utolsó hozzáférés + + + + + + + Path + Útvonal + + + + DFileView + + + Disc mount error + Lemez csatolási hiba + + + + The disc is in use, please end the running process and remount the disc. + A lemez használatban van, kérjük fejezze be a futó folyamatokat, és csatolja fel újra a lemezt. + + + + Mounting failed + A csatolás sikertelen + + + + (Reverse) + (Fordított) + + + + DFileViewHelper + + + Add tag "%1" + "%1" cimke hozzáadása + + + + DStatusBar + + + %1 item + %1 elem + + + + %1 items + %1 elem + + + + %1 item selected + %1 elem kiválasztva + + + + %1 items selected + %1 elem kiválasztva + + + + %1 folder selected (contains %2) + %1 mappa kiválasztva (összes: %2) + + + + %1 folders selected (contains %2) + %1 mappák kiválasztva (összes: %2) + + + + %1 file selected (%2) + %1 fájl kiválasztva (%2) + + + + %1 files selected (%2) + %1 fájlok kiválasztva (%2) + + + + %1 folder selected + %1 mappa kiválasztva + + + + Filter + Szűrő + + + + Save as: + Mentés másként: + + + + Loading... + Betöltés... + + + + DTaskDialog + + + Erasing disc %1, please wait... + %1 lemez törlése, kérjük várjon ... + + + + Burning disc %1, please wait... + %1 lemez írása, kérjük várjon ... + + + + Writing data... + Adatok írása ... + + + + Verifying data... + Adatok ellenőrzése... + + + + Copying %1 + %1 másolása + + + + + + to %2 + %2 -re + + + + %1 already exists in target folder + A %1 már létezik a cél mappában + + + + Original path %1 Target path %2 + Eredeti útvonal %1 Célútvonal %2 + + + + Merge + button + Egyesítés + + + + Replace + button + Csere + + + + Moving %1 + %1 mozgatása + + + + Removing file vault, please try later + A fájltároló eltávolítása, kérjük próbálkozzon később + + + + Restoring %1 + %1 visszaállítása + + + + Deleting %1 + %1 törlése + + + + Trashing %1 + %1 kukába helyezése + + + + Calculating space, please wait + Hely kiszámítása, kérjük várjon + + + + DUMountManager + + + + Authentication timed out + A hitelesítés lejárt + + + + + + Disk is busy, cannot unmount now + A lemez használatban van, jelenleg nem választható le + + + + Disk is busy, cannot eject now + A lemez használatban van, jelenleg nem választható le + + + + The device is busy, cannot eject now + Az eszköz használatban van, jelenleg nem választható le + + + + + + The device is busy, cannot remove now + Az eszköz használatban van, jelenleg nem távolítható el + + + + DeepinStorage + + + + + %1 Volume + %1 Kötet + + + + Data Disk + Data Partition + Adatlemez + + + + %1 Drive + %1 meghajtó + + + + Blank %1 Disc + Üres %1 lemez + + + + %1 Encrypted + %1 titkosítva + + + + DialogManager + + + + + + Operation failed! + Hibás művelet! + + + + Target folder is inside the source folder! + A cél mappa a forrás mappán belül található + + + + Do you want to run %1 or display its content? + Futtatja a %1 -et, vagy megjeleníti annak tartalmát? + + + + It is an executable text file. + Ez egy futtatható szöveges fájl. + + + + It is an executable file. + Ez egy futtatható fájl. + + + + This file is not executable, do you want to add the execute permission and run? + Ez a fájl nem futtatható, hozzá akarja adni a végrehajtási engedélyt és utána futtni? + + + + "%1" already exists, please use another name. + A "%1" már használatban van, kérjük válasszon egy másik nevet. + + + + The file name must not contain two dots (..) + A fájlnév nem tartalmazhat két pontot (..) + + + + Device or resource busy + Az eszköz vagy az erőforrás foglalt + + + + Are you sure you want to erase all data on the disc? + Biztosan törölni kíván minden adatot a lemezről? + + + + How do you want to use this disc? + Milyen módon kívánja használni ezt a lemezt? + + + + Disc erase failed + A lemez törlése sikertelen + + + + Burn process failed + Az írás sikertelen + + + + %1: %2 + %1: %2 + + + + Show details + Részletek megjelenítése + + + + Hide details + Részletek elrejtése + + + + Error + Hiba + + + + Permanently delete %1? + Véglegesen törli a %1-et? + + + + Permanently delete %1 items? + Véglegesen törli a %1 elemet? + + + + Empty + Üres + + + + Do you want to delete %1? + Biztosan törölni szeretné a %1 fájlt? + + + + Do you want to delete the selected %1 items? + Biztosan törölni szeretné a kijelölt %1 elemet? + + + + Sorry, unable to locate your bookmark directory, remove it? + Sajnáljuk, a könyvjelző mappa nem található, eltávolítsuk? + + + + Name: + Név: + + + + %1 that this shortcut refers to has been changed or moved + A %1 -re mutató parancsikon meg lett változtatva vagy át lett helyezve + + + + Do you want to delete this shortcut? + Biztosan törölni szeretné ezt a parancsikont? + + + + Failed, file size must be less than 4GB. + Sikertelen, a fájl mérete nem lehet nagyobb mint 4GB. + + + + Fail to create symlink, cause: + Nem sikerült a symlink létrehozása, oka: + + + + The selected files contain system file/directory, and it cannot be deleted + A kiválasztott fájlok rendszerfájlokat/mappákat tartalmaznak és nem lehet őket törölni + + + + Unable to find the original file + Nem található az eredeti fájl + + + + + You do not have permission to operate file/folder! + Nincs engedélye a fájl / mappa kezelésére! + + + + Failed to restore %1 file, the source file does not exist + Nem sikerült visszaállítani a %1 fájlt, a forrásfájl nem létezik + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Sajnáljuk, nincs engedélye a következő %1 fájl / mappa kezelésére! + + + + Unable to access %1 + Nem sikerült elérni a %1 fájlt + + + + + Sending files now, please try later + Fájlok küldése folyamatban, kérjük próbálja meg később + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Az eszköz eléréséhez először meg kell formáznia a lemezt. Biztosan formázni szeretné most? + + + + Scanning the device, stop it? + Az eszköz ellenőrzése, biztos benne hogy leállítja? + + + + Share folder can't be named after the current username + A megosztási mappa nem nevezhető el az aktuális felhasználónév alapján + + + + Do you want to run %1? + Futtatni szeretné a %1? + + + + Burn image + button + Kép írása + + + + Burn files + button + Fájlok írása + + + + Are you sure you want to empty %1 item? + Biztosan ki akarja üríteni a %1 elemet? + + + + Are you sure you want to empty %1 items? + Biztosan ki akarja üríteni a %1 elemet? + + + + + This action cannot be undone + Ez a művelet nem vonható vissza + + + + + + + + + + + + + + OK + button + OK + + + + + + + + + + + + + + + Cancel + button + Mégsem + + + + + + Run + button + Futtatás + + + + + Run in terminal + button + Futtatás terminálban + + + + Display + button + Megjelenítés + + + + + + + + + + + Confirm + button + Megerősítés + + + + Erase + button + Törlés + + + + Data verification failed + Az adatok ellenőrzése nem sikerült + + + + Show details + button + Részletek megjelenítése + + + + + Delete + button + Törlés + + + + Remove + button + Eltávolítás + + + + Disk is busy, cannot unmount now + Lemez használatban van, jelenleg nem választható le + + + + Force unmount + button + Kényszerített lecsatolás + + + + Unable to copy. Not enough free space on the target disk. + Nem sikerült másolni. Nincs elég szabad hely a céllemezen. + + + + Failed to restore %1 file, the target folder is read-only + Nem sikerült visszaállítani a %1 fájlt, a célmappa csak olvasható + + + + Failed to restore %1 files, the target folder is read-only + Nem sikerült visszaállítani a %1 fájlokat, a célmappa csak olvasható + + + + Failed to restore %1 files, the source files do not exist + Nem sikerült visszaállítani a %1 fájlt, a forrásfájlok nem léteznek + + + + Format + button + Formázás + + + + Stop + button + Leállítás + + + + FileController + + + + + + Unable to find the original file + Nem található az eredeti fájl + + + + + + Kindly Reminder + Baráti emlékeztető + + + + + + Please install File Roller first and then continue + Kérjük először telepítse a Fájl Rollert, majd folytassa + + + + + Unable to create files here: %1 + Nem lehet itt fájlokat létrehozni: %1 + + + + Confirm + button + Megerősítés + + + + FileDialogStatusBar + + + File Name + Fájl név + + + + Format + Formátum + + + + Save + button + Mentés + + + + Open + button + Megnyitás + + + + Save File + button + Fájl mentése + + + + Open File + button + Fájl megnyitása + + + + + + Cancel + button + Mégsem + + + + FileJob + + + copy + másolat + + + + + + + Data verification successful. + Adatellenőrzés sikeres. + + + + + + Burn process completed + Az írás befejeződött + + + + %1 s + %1 mp + + + + %1 m %2 s + %1 p %2 mp + + + + %1 h %2 m %3 s + %1 ó %2 p %3 mp + + + + %1 d %2 h %3 m %4 s + %1 n %2 ó %3 p %4 mp + + + + %1 is a duplicate file. + %1 egy duplikátum fájl. + + + + Insufficient disc space. + Nem elegendő lemezterület. + + + + Lost connection to drive. + Megszűnt a kapcsolat a meghajtóval. + + + + The CD/DVD drive is not ready. Try another disc. + CD/DVD meghajtó nem áll készen. Próbáljon meg egy másik lemezt. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + CD/DVD meghajtó használatban van. Lépjen ki a meghajtót használó programból és próbálja újra. + + + + Unknown error + Ismeretlen hiba + + + + Device disconnected + Az eszköz leválasztva + + + + GenerateSettingTranslate + + + + + Basic + Alapvető + + + + + + Open behavior + Működés megnyitása + + + + + + Always open folder in new window + Mindig új ablakban nyissa meg + + + + + + Open file: + Fájl megnyitása: + + + + + + Click + Kattintás + + + + + + Double click + Dupla kattintás + + + + + + New window and tab + Új ablak és fül + + + + + + Open from default window: + Megnyitás alapértelmezett ablakban: + + + + + + + + + Computer + Számítógép + + + + + + + + + Home + Saját mappa + + + + + + + + + Desktop + Asztal + + + + + + + + + Videos + Videók + + + + + + + + + Music + Zene + + + + + + + + + Pictures + Képek + + + + + + + + + Documents + Dokumentumok + + + + + + + + + Downloads + Letöltések + + + + + + Open in new tab: + Megnyitás új fülön: + + + + + + Current Directory + Jelenlegi mappa + + + + + + View + Nézet + + + + + + Default size: + Alapértelmezett méret: + + + + + + Extra small + Nagyon kicsi + + + + + + Small + Kicsi + + + + + + Medium + Közepes + + + + + + Large + Nagy + + + + + + Extra large + Nagyon nagy + + + + + + Default view: + Alapértelmezett nézet: + + + + + + Icon + Ikon + + + + + + List + Lista + + + + + + Hidden files + Rejtett fájlok + + + + + + Show hidden files + Rejtett fájlok megjelenítése + + + + + + Hide file extension when rename + Fájlkiterjesztés elrejtése átnevezéskor + + + + + + Advanced + Haladó + + + + + + Index + Indexelés + + + + + + Auto index internal disk + Belső lemez automatikus indexelése + + + + + + Index external storage device after connected to computer + Külső tároló eszközök indexelése a számítógéphez való csatlakoztatás után + + + + + + Full-Text search + Teljes szöveg keresése + + + + + + Show item counts and sizes in the path of mounted MTP devices + Elemszámok és méretek megjelenítése a csatlakoztatott MTP -eszközök útvonalában + + + + + + Keep showing the mounted Samba shares + Mutassa folyamatosan a Samba megosztásokat + + + + + + Use the file chooser dialog of File Manager + Használja a Fájlkezelő fájlválasztó párbeszédpanelét + + + + + + Ask for my confirmation when deleting files + Kérjen megerősítést a fájlok törlésekor + + + + + + Other + Egyéb + + + + + + Hide system disk + Rendszerlemez elrejtése + + + + + + Show file system on disk icon + Fájlrendszer megjelenítése a lemezen ikonokon + + + + + + Show hidden files in search results + Rejtett fájlok megjelenítése a keresési eredmények között + + + + + + Display recent file entry in left panel + A legutóbbi fájlok megjelenítése a bal oldali panelen + + + + + + Preview + Előnézet + + + + + Compress file preview + Tömörített fájl előnézete + + + + + + Text preview + Szöveg előnézete + + + + + + Document preview + Dokumentum előnézete + + + + + + Image preview + Kép előnézete + + + + + + Video preview + Videó előnézete + + + + + + Mount + Csatolás + + + + + + Auto mount + Automatikus csatolás + + + + + + Open after auto mount + Megnyitás automatikus csatolás után + + + + + + Dialog + Párbeszéd + + + + Compressed file preview + Tömörített fájl előnézete + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Nem sikerült ellenőrizni a %1 azonosságát. + + + + This happens when you log in to a computer the first time. + Ez akkor történik, amikor először jelentkezik be a számítógépre. + + + + The identity sent by the remote computer is + A távoli számítógép által küldött azonosság + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Ha teljesen biztos akar lenni abban, hogy biztonságos a folytatás, vegye fel a kapcsolatot a rendszergazdával. + + + + + + + + Mounting device error + Csatoló eszköz hiba + + + + + Wrong username or password + Helytelen felhasználónév vagy jelszó + + + + + + + + Confirm + button + Megerősítés + + + + + Cannot find the mounted device + Nem található a csatlakoztatott eszköz + + + + No key available to unlock device + Nincs elérhető kulcs az eszköz feloldásához + + + + The disk is mounted by user "%1", you cannot unmount it. + A lemez "%1" felhasználó által felcsatolva, a leválasztása nem lehetséges. + + + + Cannot unmount the device + Eszköz nem leválasztható + + + + Cannot eject the device "%1" + "%1" eszköz nem kiadható + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Nem sikerült megírni. Nincs elég szabad hely a céllemezen. + + + + MergedDesktopController + + + + Pictures + Képek + + + + + Music + Zene + + + + + Applications + Alkalmazások + + + + + Videos + Videók + + + + + Documents + Dokumentumok + + + + + Others + Egyebek + + + + MimeTypeDisplayManager + + + + Directory + Mappa + + + + + + Application + Alkalmazás + + + + + + Video + Videó + + + + + + Audio + Audió + + + + + + Image + Kép + + + + + Archive + Tömörített + + + + + + Text + Szöveg + + + + + Executable + Futtatható + + + + + Backup file + Biztonsági mentési fájl + + + + + Unknown + Ismeretlen + + + + MountAskPasswordDialog + + + Cancel + button + Mégsem + + + + Connect + button + Csatlakozás + + + + Log in as + Bejelentkezés mint + + + + Anonymous + Névtelen + + + + Registered user + Regisztrált felhasználó + + + + Username + Felhasználónév + + + + Domain + Tartomány + + + + Password + Jelszó + + + + Remember password + Jelszó megjegyzése + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Mégsem + + + + Unlock + button + Feloldás + + + + Input password to decrypt the disk + Adja meg a jelszavát a lemez titkosításának feloldásához + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Biztos benne, hogy véglegesen törli %1? + + + + This file is too big for the trash + Fájl túl nagy a kukába helyezéshez + + + + The files are too big for the trash + Fájlok túl nagyok a kukába helyezéshez + + + + Are you sure you want to permanently delete %1 files? + Biztos benne, hogy véglegesen törli %1 fájlokat? + + + + Cancel + button + Mégsem + + + + Delete + button + Törlés + + + + OpenWithDialog + + + Open with + Megnyitás ezzel + + + + Add other programs + Más program hozzáadása + + + + Set as default + Beállítás alapértelmezettként + + + + Cancel + button + Mégsem + + + + Confirm + button + Megerősítés + + + + Recommended Applications + Ajánlott Alkalmazások + + + + Other Applications + Más alkalmazások + + + + PathManager + + + Home + Saját mappa + + + + Desktop + Asztal + + + + Videos + Videók + + + + Music + Zene + + + + Pictures + Képek + + + + Documents + Dokumentumok + + + + Downloads + Letöltések + + + + + Trash + Kuka + + + + + + System Disk + Rendszerlemez + + + + Computers in LAN + Számítógépek a vezetékes hálózatban + + + + My Shares + Megosztásaim + + + + Computer + Számítógép + + + + Recent + Legutóbbi + + + + File Vault + Fájl tároló + + + + PropertyDialog + + + Basic info + Alapvető információk + + + + Open with + Megnyitás ezzel + + + + Sharing + Megosztás + + + + Permissions + Engedélyek + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Mappa elrejtése + + + + Hide this file + Fájl elrejtése + + + + Allow to execute as program + Programként való futtatás engedélyezése + + + + QObject + + + + + + Size + Méret + + + + + + Contains + Tartalmak + + + + + + Type + Típus + + + + + + + + Time modified + Módosítási idő + + + + Free space + Szabad tárhely + + + + Total space + Teljes tárhely + + + + + Time locked + Az idő zárolva + + + + Access denied + Hozzáférés megtagadva + + + + + Executable + Futtatható + + + + + Write only + Csak írható + + + + + Read only + Csak olvasható + + + + + Read-write + Írható/olvasható + + + + Others + Egyebek + + + + Owner + Tulajdonos + + + + Unconnected network shared directory + Nem csatlakoztatott hálózati megosztott könyvtár + + + + Device type + Eszköztípus + + + + File system + Fájlrendszer + + + + Group + Csoport + + + + + Open + Megnyitás + + + + Lock + Zárolás + + + + Auto lock + Automatikus zárolás + + + + Never + Soha + + + + 5 minutes + 5 perc + + + + 10 minutes + 10 perc + + + + 20 minutes + 20 perc + + + + Delete File Vault + Fájl tároló törlése + + + + Unlock + Feloldás + + + + Unlock by key + Feloldás kulccsal + + + + Open + button + Megnyitás + + + + + Size: %1 + Méret: %1 + + + + Type: %1 + Típus: %1 + + + + Size: 0 + Méret: 0 + + + + Items: %1 + Elem: %1 + + + + + + + + + + Open in new window + Megnyitás új ablakban + + + + + + + + + + Open in new tab + Megnyitás új fülön + + + + Open with + Megnyitás ezzel + + + + + Compress + Tömörítés + + + + Extract + Kibontás + + + + Extract here + Kibontás ide + + + + Cut + Kivágás + + + + Copy + Másolás + + + + Paste + Beillesztés + + + + + + + + Rename + Átnevezés + + + + + + + Remove + Eltávolítás + + + + Create link + Hivatkozás létrehozása + + + + Send to desktop + Küldés az asztalra + + + + Send to + Küldés a + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Hozzáadás a könyvjelzőkhöz + + + + + + + Properties + Tulajdonságok + + + + New folder + Új mappa + + + + New window + Új ablak + + + + Select all + Összes kijelölése + + + + + Clear recent history + Előzmények törlése + + + + + + Empty Trash + Kuka ürítése + + + + Display as + Megtekintés mint + + + + Sort by + Rendezés + + + + New document + Új dokumentum + + + + + Time created + Létrehozási idő + + + + + + Source path + Forrás útvonal + + + + Share folder + Mappa megosztása + + + + Cancel sharing + Megosztás törlése + + + + Connect to Server + Csatlakozás kiszolgálóhoz + + + + Set share password + Megosztási jelszó beállítása + + + + Format + Formázás + + + + Tag information + Címke információ + + + + Open as administrator + Megnyitás Rendszergazdaként + + + + Select default program + Alapértelmezett program választása + + + + Open file location + Fájl helyének megnyitása + + + + Remove bookmark + Könyvjelző eltávolítása + + + + + + Delete + Törlés + + + + Office Text + Szöveges Dokumentum + + + + Spreadsheets + Táblázat + + + + Plain Text + Egyszerű szöveges dokumentum + + + + Open in terminal + Megnyitás terminálban + + + + Restore + Visszaállítás + + + + Restore all + Összes visszaállítása + + + + Clear saved password and unmount + A mentett jelszó törlése és leválasztása + + + + File Vault + Fájl tároló + + + + Add to disc + Lemezre írás + + + + Refresh + Frissítés + + + + Auto mount + Automatikus csatolás + + + + Open after auto mount + Megnyitás automatikus csatolás után + + + + + Mount + Csatolás + + + + + Unmount + Leválasztás + + + + It does not support burning %1 discs + Nem támogatja a %1 lemezek írását + + + + Burn + Írás + + + + Disc name: + Lemeznév: + + + + + Maximum + Maximum + + + + Allow files to be added later + Fájlok későbbi hozzáadásának engedélyezése + + + + Verify data + Adat ellenőrzése + + + + Write speed: + Írási sebesség: + + + + + + + Cancel + button + Mégsem + + + + Burn + button + Írás + + + + + Eject + Kiadás + + + + Safely Remove + Biztonságos eltávolítás + + + + + Name + Név + + + + Settings + Beállítások + + + + Exit + Kilépés + + + + Icon + Ikon + + + + List + Lista + + + + Extend + Kiterjesztés + + + + Set as wallpaper + Beállítás háttérképként + + + + + + + Local disk + Helyi lemez + + + + + Removable disk + Eltávolítható lemez + + + + + + Network shared directory + Hálózaton megosztott mappa + + + + + Android mobile device + Android mobil eszköz + + + + + Apple mobile device + Apple® mobil eszköz + + + + + Camera + Kamera + + + + + DVD + DVD + + + + + Unknown device + Ismeretlen eszköz + + + + + + %1 item + %1 elem + + + + + + %1 items + %1 elem + + + + Shortcut + Parancsikon + + + + Create symlink + Symlink létrehozása + + + + Path + Útvonal + + + + + + Time deleted + Törlési idő + + + + Loading... + Betöltés... + + + + File has been moved or deleted + A fájl törölve lett vagy át lett helyezve + + + + You do not have permission to traverse files in it + Nincs jogosultsága a belső fájlok bejárására + + + + + + You do not have permission to access this folder + Nincs jogosultsága a mappához való hozzáféréséhez + + + + + + + + Folder is empty + A mappa üres + + + + Searching... + Keresés... + + + + No results + Nincs keresési eredmény + + + + Source Path + TrashFileInfo + Forrásútvonal + + + + Document + Dokumentum + + + + Spreadsheet + Táblázat + + + + + Presentation + Prezentáció + + + + Text + Szöveg + + + + 1 task in progress + 1 feladat folyamatban + + + + %1 tasks in progress + %1 feladat folyamatban + + + + Mode: + Mód: + + + + + Replace Text + Szöveg cseréje + + + + + Add Text + Szöveg hozzáadása + + + + + Custom Text + Egyéni szöveg + + + + Find: + Találat: + + + + Replace: + Csere: + + + + + Optional + Opcionális + + + + Add: + Hozzáadás: + + + + Location: + Hely: + + + + File name: + Fájlnév: + + + + Start at: + Kezdődik: + + + + + Rename + button + Átnevezés + + + + + + + + + + + Required + Kötelező + + + + + Before file name + Fájlnév előtt + + + + + After file name + Fájlnév után + + + + Find + Találat + + + + Replace + Csere + + + + Add + Hozzáadás + + + + Start at + Kezdődik + + + + + + Location + Hely + + + + File name + Fájlnév + + + + Dimension + Méret + + + + Duration + Időtartam + + + + Tips: Sort by selected file order + Tipp: Rendezés a kiválasztott fájl szerint + + + + Rename %1 Files + %1 fájl átnevezése + + + + Multiple Files + Több Fájl + + + + Basic info + Alapvető információk + + + + Total size + Teljes méret + + + + Number of files + Fájlok száma + + + + %1 file(s), %2 folder(s) + %1 fájl, %2 mappa + + + + + + Time accessed + Hozzáférés ideje + + + + Orange + Narancs + + + + Red + Piros + + + + Purple + Lila + + + + Navy-blue + Sötétkék + + + + Azure + Égszínkék + + + + Green + Zöld + + + + Yellow + Sárga + + + + Gray + Szürke + + + + Input tag info, such as work, family. A comma is used between two tags. + Adja meg a címke adatait, például a munkahely, a család. Vesszőt használjon két címke között. + + + + Bookmarks + Könyvjelzők + + + + Erase + Törlés + + + + Copy path + Elérési út másolása + + + + Edit address + Cím szerkesztése + + + + Free Space %1 + Szabad terület %1 + + + + Files are being processed + A fájlok feldolgozás alatt vannak + + + + + Unknown + Ismeretlen + + + + My Vault + Saját tároló + + + + + Failed to create file info + Nem sikerült létrehozni a fájl adatait + + + + Failed to create file handler + Nem sikerült létrehozni a fájl kezelőjét + + + + Failed to open the file, cause: %1 + A fájl megnyitása sikertelen, oka: %1 + + + + Original file does not exist + Az eredeti fájl nem létezik + + + + Do you want to delete %1? + Biztosan törölni szeretné a %1 fájlt? + + + + Confirm + button + Megerősítés + + + + + + + + %1 are not allowed + A %1 nem engedélyezett + + + + + Failed to start Samba services + A Samba szolgáltatás elindítása sikertelen + + + + RecentController + + + Cancel + button + Mégsem + + + + Remove + button + Eltávolítás + + + + Do you want to remove this item? + Biztosan el szeretné távolítani ezt az elemet? + + + + Do yout want to remove %1 items? + Biztosan el szeretne távolítani %1 elemet? + + + + It does not delete the original files + Nem törli az eredeti fájlokat + + + + ShareInfoFrame + + + Share this folder + Mappa megosztása + + + + Share name: + Név megosztása: + + + + Permission: + Engedély: + + + + Read and write + Írás és olvasás + + + + Read only + Csak olvasható + + + + Anonymous: + Névtelen: + + + + Not allow + Nem engedélyezett + + + + Allow + Engedélyezés + + + + The share name must not be two dots (..) or one dot (.) + A megosztás neve nem lehet két pont (..) vagy egy pont (.) + + + + The share name is used by another user. + A megosztás nevét egy másik felhasználó használja. + + + + OK + button + OK + + + + Cancel + button + Mégsem + + + + Replace + button + Csere + + + + The share name already exists. Do you want to replace the shared folder? + A megosztás neve már létezik. Cserélni szeretné a megosztott mappát? + + + + Shortcut + + + Item + Elem + + + + Select to the first item + Válasszuk ki az első elemhez + + + + Shift + Home + Shift + Home + + + + Select to the last item + Válasszuk ki az utolsó elemhez + + + + Shift + End + Shift + End + + + + Select leftwards + Kiválasztás balról + + + + Shift + Left + Shift + Left + + + + Select rightwards + Kiválasztás jobbról + + + + Shift + Right + Shift + Right + + + + Select to upper row + Kiválasztás a felső sorban + + + + Shift + Up + Shift + Up + + + + Select to lower row + Kiválasztás az alsó sorból + + + + Shift + Down + Shift + Down + + + + Open + Megnyitás + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + Szülőmappa + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Végleges törlés + + + + Shift + Delete + Shift + Delete + + + + Delete file + Fájl törlése + + + + Delete + Törlés + + + + Select all + Összes kijelölése + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Másolás + + + + Cut + Kivágás + + + + Paste + Beillesztés + + + + Rename + Átnevezés + + + + F2 + F2 + + + + New/Search + Új/Keresés + + + + New window + Új ablak + + + + New folder + Új mappa + + + + + Search + Keresés + + + + New tab + Új lap + + + + View + Nézet + + + + Item information + Elem információ + + + + Help + Segítség + + + + F1 + F1 + + + + Keyboard shortcuts + Gyorsbillentyűk + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Kijelzőállapot megváltoztatása + + + + Hide item + Elem elrejtése + + + + Input in address bar + Bevitel a címsorba + + + + Switch to icon view + Váltás ikonnézetre + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Váltás listanézetre + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Egyebek + + + + Close + Bezárás + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Jelenlegi lap bezárása + + + + Back + Vissza + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Váltás a következő lapra + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Váltás az előző lapra + + + + Next file + Következő fájl + + + + Tab + Lap + + + + Previous file + Előző fájl + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Váltás a lapok között, megadott számmal, 1 és 8 között + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Előre + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Nem sikerült megnyitni a kukában lévő elemeket, először állítsa vissza + + + + TrashPropertyDialog + + + Trash + Kuka + + + + item + elem + + + + items + elem + + + + Contains %1 %2 + Tartalmazza %1 %2 + + + + UDiskListener + + + Failed to rename the label + A címke átnevezése sikertelen + + + + UnmountWorker + + + + + The device was not safely unmounted + Az eszközt nem sikerült biztonságosan leválasztani + + + + The device was not safely removed + Az eszközt nem sikerült biztonságosan eltávolítani + + + + UserShareManager + + + Kindly Reminder + Baráti emlékeztető + + + + Please firstly install samba to continue + A folytatáshoz először telepítsd a samba-t + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + A megosztás neve nem tartalmazhatja a következőket, %<>*?|/\+=;:,", és nem kezdődhet %1-el + + + + To protect the files, you cannot share this folder. + A fájlok védelme érdekében nem oszthatja meg ezt a mappát. + + + + Sharing failed + A megosztás sikertelen + + + + The computer name is too long + A számítógép neve túl hosszú + + + + You do not have permission to operate file/folder! + Nincs engedélye a fájl / mappa kezelésére! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Adjon meg egy jelszót a megosztott mappák védelméhez + + + + Cancel + button + Mégsem + + + + Confirm + button + Megerősítés + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_id.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_id.ts new file mode 100644 index 0000000..907cf25 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_id.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + Folder baru + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + Tutup semua + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + Komputer + + + + Basic Info + Info Dasar + + + + Computer Name + Nama Komputer + + + + Version + Versi + + + + Type + Jenis + + + + Processor + Prosesor + + + + Memory + Memori + + + + Disk + Diska + + + + Bit + Bit + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + Cari atau masukkan alamat + + + + DFMAdvanceSearchBar + + + Search: + Cari: + + + + File Type: + Tipe Berkas: + + + + File Size: + Ukuran Berkas: + + + + Time Modified: + Waktu Modifikasi: + + + + Reset + Setel Ulang + + + + All subdirectories + Semua subdirektori + + + + Current directory + Direktori saat ini + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Sekarang + + + + Yesterday + Kemarin + + + + This week + Minggu ini + + + + Last week + Minggu kemarin + + + + This month + Bulan ini + + + + Last month + Bulan lalu + + + + This year + Tahun ini + + + + Last year + Tahun lalu + + + + DFMTagCrumbController + + + Tag information + Maklumat tanda + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + Kesalahan izin + + + + The action is denied + Aksi ditolak + + + + Failed to open the file + Gagal untuk membuka berkas + + + + Failed to read the file + Gagal membaca berkas + + + + Failed to write the file + Gagal menulis berkas + + + + Failed to create the directory + Gagal membuat direktori + + + + Failed to delete the file + Gagal menghapus berkas + + + + Failed to move the file + Gagal memindah berkas + + + + Original file does not exist + Berkas asli tidak ada + + + + Failed, file size must be less than 4GB + Gagal, ukuran berkas harus lebih kecil dari 4GB + + + + Not enough free space on the target disk + + + + + File integrity was damaged + Integritas berkas rusak + + + + The target device is read only + Perangkat target hanya bisa dibaca + + + + Target folder is inside the source folder + Folder tujuan berada di dalam folder sumber + + + + copy + Extra name added to new file name when used for file name. + salin + + + + Failed to create the directory, cause: %1 + Gagal untuk membuat direktori, karena %1 + + + + + Failed to open the file, cause: %1 + Gagal membuka direktori, karena %1 + + + + Failed to read the file, cause: %1 + Gagal membaca berkas, karena %1 + + + + Failed to write the file, cause: %1 + Gagal menulis berkas, karena %1 + + + + File integrity was damaged, cause: %1 + Integritas berkas rusak, karena %1 + + + + Failed to delete the file, cause: %1 + Gagal menghapus berkas, karena %1 + + + + Fail to create symlink, cause: %1 + Gagal membuat tautan simbolik, karena %1 + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + %1 telah ada, apakah Anda akan menimpanya? + + + + Cancel + Batal + + + + Replace + Ganti + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + Nama + + + + + + Time modified + Tanggal dimodifikasi + + + + Size + Ukuran + + + + Type + Tipe + + + + Time created + Tanggal dibuat + + + + + Last access + Akses terakhir + + + + Path + Jejak + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + (Dibalik) + + + + DFileViewHelper + + + Add tag "%1" + Tambah tagar "%1% + + + + DStatusBar + + + %1 item + %1 item + + + + %1 items + %1 item + + + + %1 item selected + %1 item dipilih + + + + %1 items selected + %1 item dipilih + + + + %1 folder selected (contains %2) + %1 folder dipilih (mengandung %2) + + + + %1 folders selected (contains %2) + %1 folder dipilih (mengandung %2) + + + + %1 file selected (%2) + %1 berkas dipilih (%2) + + + + %1 files selected (%2) + %1 berkas dipilih (%2) + + + + %1 folder selected + %1 folder dipilih + + + + Filter + Saring + + + + Save as: + Simpan sebagai: + + + + Loading... + Memuat... + + + + DTaskDialog + + + This action is not supported + Aksi ini tidak didukung + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + Volume %1 + + + + Data Disk + Data Partition + Diska Data + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + Operasi gagal! + + + + Target folder is inside the source folder! + Folder target berada di dalam folder sumber! + + + + + + + + + + + + + OK + OK + + + + Do you want to run %1 or display its content? + Apakah Anda ingin menjalankan %1 atau menampilkan kontennya? + + + + It is an executable text file. + Ini merupakan berkas teks bisa dieksekusi. + + + + + + + + + + + + + + Cancel + Batal + + + + + + Run + Jalankan + + + + + Run in terminal + Jalankan di terminal + + + + Display + Tampilkan + + + + It is an executable file. + Ini merupakan berkas yang bisa dieksekusi. + + + + This file is not executable, do you want to add the execute permission and run? + Berkas ini bukan eksekusi, apakah anda ingin tambah ijin eksekusi dan jalan? + + + + "%1" already exists, please use another name. + "%1" sudah ada, silakan gunakan nama lain. + + + + + + + + Confirm + Konfirmasi. + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + Menghapus permanen %1 item? + + + + Permanently delete %1 items? + Menghapus permanen %1 item? + + + + Delete + Hapus + + + + Empty + Kosong + + + + Sorry, unable to locate your bookmark directory, remove it? + Maaf, tidak bisa menemukan direktori marka buku Anda, hapus? + + + + Remove + Hapus + + + + Name: + Nama: + + + + Force unmount + Paksa lepaskan + + + + %1 that this shortcut refers to has been changed or moved + %1 bahwa pintasan ini mengacu telah berubah atau dipindahkan + + + + Do you want to delete this shortcut? + Apakah Anda yakin untuk menghapus jalan pintas ini? + + + + Failed, file size must be less than 4GB. + Gagal, ukuran berkas harus kurang dari 4GB. + + + + Fail to create symlink, cause: + Gagal membuat symlink, karena: + + + + The selected files contain system file/directory, and it cannot be deleted + Berkas yang terpilih merupakan berkas/direktori sistem, tidak dapat menyalin + + + + + You do not have permission to operate file/folder! + Kamu tidak memiliki ijin untuk mengolah berkas/folder! + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Maaf, kamu tidak memiliki ijin untuk mengolah %1 berkas/folder ini! + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + 2. Hapus centang "Aktifkan startup cepat" dan "Hibernasi" dalam pengaturan mematikan dan muat ulang + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + Folder berbagi tidak bisa diberi nama sebagaimana nama pengguna saat ini + + + + View + Lihat + + + + Do you want to run %1? + Apakah Anda ingin menjalankan %1? + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + Partisi kaitan %1 diatur menjadi hanya baca + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + Diska-diska pada Windows tidak bisa dibaca dan ditulis secara normal jika pilihan "Hidupkan fast startup (direkomendasikan)" pada pengaturan Matikan diaktifkan + + + + Please restore by the following steps to normally access Windows disk + Mohon kembalikan dengan melakukan langkah-langkah berikut untuk mengakses secara normal diska Windows + + + + 1. Reboot to enter Windows + 1. Boot ulang untuk masuk ke Windows + + + 3. Reboot and enter deepin + 3. Boot ulang dan masuk ke deepin + + + + Reboot + Boot ulang + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + Nama Berkas + + + + Format + Format + + + + Cancel + Batal + + + + Save + Simpan + + + + Open + Buka + + + + Save File + Simpan Berkas + + + + Open File + Buka Berkas + + + + FileJob + + + copy + salin + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + %1 d + + + + %1 m %2 s + %1 m %2 d + + + + %1 h %2 m %3 s + %1 j %2 m %3 d + + + + %1 d %2 h %3 m %4 s + %1 h %2 j %3 m %4 d + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + Dasar + + + + + + Open behavior + Buka perilaku + + + + + + Always open folder in new window + Selalu buka folder pada jendela baru + + + + + + Open file: + Buka berkas: + + + + + + Click + Klik + + + + + + Double click + Klik ganda + + + + + + New window and tab + Jendela dan tab baru + + + + + + Open from default window: + Buka dari jendela bawaan: + + + + + + + + + Computer + Komputer + + + + + + + + + Home + Rumah + + + + + + + + + Desktop + Desktop + + + + + + + + + Videos + Video + + + + + + + + + Music + Musik + + + + + + + + + Pictures + Gambar + + + + + + + + + Documents + Dokumen + + + + + + + + + Downloads + Unduhan + + + + + + Open in new tab: + Buka pada tab baru: + + + + + + Current Directory + Direktori saat ini + + + + + + View + Lihat + + + + + + Default size: + Ukuran bawaan: + + + + + + Extra small + Sangat kecil + + + + + + Small + Kecil + + + + + + Medium + Pertengahan + + + + + + Large + Besar + + + + + + Extra large + Sangat besar + + + + + + Default view: + Tampilan bawaan: + + + + + + Icon + Ikon + + + + + + List + Daftar + + + + + + Hidden files + Berkas tersembunyi + + + + + + Show hidden files + Tampilkan berkas tersembunyi + + + + + + Hide file extension when rename + Sembunyikan ekstensi berkas saat mengganti nama + + + + + + Advanced + Canggih + + + + + + Index + Susun + + + + + + Auto index internal disk + Susun otomatis diska internal + + + + + + Index external storage device after connected to computer + Susun perangkat penyimpanan eksternal setelah tersambung ke komputer + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + Lainnya + + + + + + Hide system disk + Sembunyikan diska sistem + + + + + + Show hidden files in search results + Tampilkan berkas tersembunyi pada hasil pencarian + + + + + + Display recent file entry in left panel + Tampilkan berkas terakhir di panel sebelah kiri + + + + + + Preview + Pratayang + + + + + Compress file preview + Pratayang berkas terkompres + + + + + + Text preview + Pratayang teks + + + + + + Document preview + Pratayang dokumen + + + + + + Image preview + Pratayang gambar + + + + + + Video preview + Pratayang video + + + + + + Mount + Kaitkan + + + + + + Auto mount + Kaitkan otomatis + + + + + + Open after auto mount + Buka setelah pengaitan otomatis + + + + + + Dialog + Dialog + + + Use the file chooser dialog of Deepin File Manager + Gunakan dialog pemilih berkas Manajer Berkas Deepin + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + Diska ini dikaitkan oleh pengguna "%1", Anda tidak bisa melepas kaitannya. + + + + + + + + Confirm + Pastikan + + + + + Cannot find the mounting device + Tidak bisa menemukan perangkat terkait + + + + Cannot unmount the device + Tidak bisa melepas kaitan perangkat + + + + Cannot eject the device "%1" + Tidak bisa mengeluarkan perangkat "%1" + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + Direktori + + + + + + Application + Aplikasi + + + + + + Video + Video + + + + + + Audio + Audio + + + + + + Image + Gambar + + + + + Archive + Arsip + + + + + + Text + teks + + + + + Executable + Dapat dijalankan + + + + + Backup file + + + + + + Unknown + Tidak diketahui + + + + MountAskPasswordDialog + + + Cancel + Batal + + + + Connect + Sambung + + + + Log in as + Masuk sebagai + + + + Anonymous + Anonim + + + + Registered user + Pengguna terdaftar + + + + Username + Nama pengguna + + + + Domain + Domain + + + + Password + Sandi lewat + + + + Remember password + Ingatkan sandi lewat + + + + MountSecretDiskAskPasswordDialog + + + Cancel + Batal + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + Lewati + + + Keep both + Simpan keduanya + + + Replace + Timpa + + + Do not ask again + Jangan tanya lagi + + + merge + gabung + + + Copying %1 + Menyalin %1 + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + Salin ke %2 + + + Moving %1 + Memindahkan %1 + + + Move to %2 + Pindah ke %2 + + + Restoring %1 + Mengembalikan %1 + + + Restore to %2 + Kembalikan ke %2 + + + Deleting %1 + Menghapus %1 + + + Trashing %1 + Membuang ke tong sampah %1 + + + Calculating space, please wait + Menghitung ruang, mohon menunggu + + + File named %1 already exists in target folder + Berkas dengan nama %1 sudah ada dalam folder target + + + Original path %1 target path %2 + Jalur asli %1 kalur tujuan %2 + + + Retry + Coba lagi + + + Time modified:%1 + Tanggal dimodifikasi:%1 + + + Original folder + Folder asli + + + Original file + Berkas asli + + + Target folder + Folder tujuan + + + Target file + Berkas tujuan + + + Contains:%1 + Mengandung:%1 + + + Size:%1 + Ukuran:%1 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + Batal + + + + Delete + Hapus + + + + OpenWithDialog + + + Open with + Buka dengan + + + + Add other programs + Tambah program lain + + + + Set as default + Setel sebagai bawaan + + + + Cancel + Batal + + + + Confirm + + + + + Recommended Applications + Aplikasi-aplikasi yang Direkomendasikan + + + + Other Applications + Aplikasi lainnya + + + + PathManager + + + Home + Rumah + + + + Desktop + Desktop + + + + Videos + Video + + + + Music + Musik + + + + Pictures + Gambar + + + + Documents + Dokumen + + + + Downloads + Unduhan + + + + + Trash + Tong sampah + + + + + System Disk + Diska Sistem + + + + Computers in LAN + Komputer dalam LAN + + + + My Shares + Berbagiku + + + + Computer + Komputer + + + + Recent + Baru ini + + + + PropertyDialog + + + Basic info + Info dasar + + + + Open with + Buka dengan + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + Izinkan eksekusi sebagai program + + + + QObject + + + + + Size + Ukuran + + + + + + Contains + Mengandung + + + + + + Type + Tipe + + + + + + + Time modified + Waktu dimodifikasi + + + + Free space + Ruang kosong + + + + Total space + Total ruang + + + + Access denied + Akses ditolak + + + + + Executable + Dapat dijalankan + + + + + Write only + Hanya tulis + + + + + Read only + Hanya baca + + + + + Read-write + Baca-tulis + + + + Others + Lainnya + + + + Owner + Pemilik + + + + Device type + + + + + File system + + + + + Group + Grup + + + + + + Open + Buka + + + + + Size: %1 + Ukuran: %1 + + + + Type: %1 + Jenis: %1 + + + + Size: 0 + Ukuran: 0 + + + + Items: %1 + Butir: %1 + + + + + + + + + + + Open in new window + Bukan di jendela baru + + + + + + + + + + + Open in new tab + Buka di tab baru + + + + Open with + Buka dengan + + + + Compress + Kompres + + + + Extract + Ekstrak + + + + Extract here + Ekstrak di sini + + + + Cut + Potong + + + + Copy + Salin + + + + Paste + Tempel + + + + + + + + + + Rename + Ganti nama + + + + + + Remove + Hapus + + + + Create link + Buat tautan + + + + Send to desktop + Kirim ke desktop + + + + Send to + Kirim ke + + + + Add to bookmark + Tambah ke marka buku + + + + + + + Properties + Properti + + + + New folder + Folder baru + + + + New window + Jendela baru + + + + Select all + Pilih semua + + + + + Clear recent history + Bersihkan riwayat saat ini + + + + + + Empty Trash + Kosongkan Tong sampah + + + + Display as + Tampilkan sebagai + + + + Sort by + Urutkan berdasar + + + + New document + Dokumen baru + + + + + Time created + Tanggal dibuat + + + + Log out and unmount + Keluar dan lepaskan + + + + + + Source path + Jalur sumber + + + + Share folder + Bagikan folder + + + + Cancel sharing + Batalkan berbagi + + + + Connect to Server + + + + + Set share password + Setel sandi lewat berbagi + + + + Format + Format + + + + Tag information + Maklumat tanda + + + + Open in new window as admin + Buka di jendela baru sebagai admin + + + + Select default program + Pilih program bawaan + + + + Open file location + Buka lokasi berkas + + + + Remove bookmark + Hapus penanda + + + + + + Delete + Hapus + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + Buka di terminal + + + + Restore + Kembalikan + + + + Restore all + Kembalikan semua + + + + File Vault + + + + + Auto mount + Pasang otomatis + + + + Open after auto mount + Buka setelah pengaitan otomatis + + + + + Mount + Pasang + + + + + Unmount + Lepaskan + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + Keluarkan + + + + Safely Remove + Keluarkan dengan aman + + + + + Name + Nama + + + + Settings + engaturan + + + + Exit + Keluar + + + + Icon + Ikon + + + + List + Daftar + + + + Extend + Beberkan + + + + Set as wallpaper + Setel sebagai wallpaper + + + + + + + Local disk + Diska Lokal + + + + + Removable disk + Diska yang bisa dilepas + + + + + + Network shared directory + Direktori berbagi jaringan + + + + + Android mobile device + Perangkat mobil Android + + + + + Apple mobile device + Perangkat mobil Apple + + + + + Camera + Kamera + + + + + DVD + + + + + + Unknown device + Perangkat tidak diketahui + + + + + + %1 item + %1 item + + + + + + %1 items + %1 item + + + + Shortcut + Pintasan + + + + Create symlink + Buat symlink + + + + Path + Jejak + + + + + + Time deleted + Waktu dihapus + + + + Loading... + Memuat... + + + + File has been moved or deleted + Berkas telah dipindahkan atau dihapus + + + + + + You do not have permission to access this folder + Anda tidak punya hak akses untuk mengakses folder ini + + + + + + + Folder is empty + Folder kosong + + + + Path + SearchFileInfo + Jejak + + + + Searching... + Mencari... + + + + No results + Tidak ada hasil + + + + Source Path + TrashFileInfo + Jejak Sumber + + + + Document + Dokumen + + + + Spreadsheet + Lembar kerja + + + + + Presentation + Presentasi + + + + Text + teks + + + + 1 task in progress + 1 tugas sedang berlangsung + + + + %1 tasks in progress + %1 tugas-tugas sedang berlangsung + + + + Mode: + Modus: + + + + + Replace Text + Ganti teks + + + + + Add Text + Tambah teks + + + + + Custom Text + Teks Gubahan + + + + Find: + Temukan: + + + + Replace: + Ganti: + + + + + Optional + Pilihan + + + + Add: + Tambah: + + + + Location: + Lokasi: + + + + File name: + Nama berkas: + + + + +SN: + +SN: + + + + + + + + + + Required + Disyaratkan: + + + + + Before file name + Sebelum nama berkas + + + + + After file name + Setelah nama berkas + + + + Find + Cari + + + + Replace + Ganti + + + + Add + Tambahkan + + + + + + Location + Lokasi + + + + File name + Nama berkas + + + + Dimension + + + + + Duration + + + + + +SN + +SN + + + + Tips: Sort by selected file order + Kiat: Urutkan berdasarkan urutan berkas terpilih + + + + + + Cancel + Batal + + + + Rename %1 Files + Ganti nama %1 Berkas + + + + Multiple Files + Banyak Berkas-berkas + + + + Basic info + Maklumat dasar + + + + Total size + Ukuran total + + + + Number of files + Jumlah berkas + + + + %1 file(s), %2 folder(s) + %1 berkas, %2 folder + + + + + + Time accessed + + + + + Orange + Jingga + + + + Red + Merah + + + + Purple + Ungu + + + + Navy-blue + Biru angkatan laut + + + + Azure + Biru langit + + + + Green + Hijau + + + + Yellow + Kuning + + + + Gray + Abu-abu + + + + Input tag info, such as work, family. A comma is used between two tags. + Masukan informasi penanda, seperti pekerjaan, keluarga. Tanda koma dipakai di antara dua penanda + + + + Bookmarks + Penanda + + + + Erase + + + + + + Copy path + Salin jalur + + + + + Edit address + Sunting alamat + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + Bagikan folder ini + + + + Share name: + Nama berbagi: + + + + Permission: + Izin: + + + + Read and write + Baca dan tulis + + + + Read only + Baca saja + + + + Anonymous: + Anonim: + + + + Not allow + Tidak diiizinkan + + + + Allow + Diizinkan + + + + Shortcut + + + Item + Item + + + + Select to the first item + Pilih ke item pertama + + + + Shift + Home + Shift + Home + + + + Select to the last item + Pilih ke item terakhir + + + + Shift + End + Shift + End + + + + Select leftwards + Pilih ke kiri + + + + Shift + Left + Shift + Left + + + + Select rightwards + Pilih ke kanan + + + + Shift + Right + Shift + Right + + + + Select to upper row + Pilih ke baris atas + + + + Shift + Up + Shift + Up + + + + Select to lower row + Pilih ke baris bawah + + + + Shift + Down + Shift + Down + + + + Open + Buka + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + Ke direktori induk + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Hapus permanen + + + + Shift + Delete + Shift + Delete + + + + Delete file + Hapus berkas + + + + Delete + Hapus + + + + Select all + Pilih semua + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + Salin + + + + Cut + Potong + + + + Paste + Tempel + + + + Rename + Ganti nama + + + + F2 + F2 + + + + New/Search + Baru/Cari + + + + New window + Jendela Baru + + + + New folder + Folder baru + + + + + Search + Cari + + + + New tab + Tab baru + + + + View + Lihat + + + + Item information + Informasi item + + + + Help + Bantuan + + + + F1 + F1 + + + + Keyboard shortcuts + Pintasan papan tombol + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Beralih status tampilan + + + + Hide item + Sembunyikan item + + + + Input in address bar + Masukkan dalam bar alamat + + + + Switch to icon view + Beralih ke tampilan ikon + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Ganti ke tampilan senarai + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Lainnya + + + + Close + Tutup + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Tutup tab saat ini + + + + Back + Kembali + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Alih ke tab selanjutnya + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Alih ke tab sebelumnya + + + + Next file + Berkas sleanjutnya + + + + Tab + Tab + + + + Previous file + Berkas sbeelumnya + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Beralih tab dengan nomor tertentu di antara 1 sampai dengan 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Teruskan + + + + TrashPropertyDialog + + + Trash + Tong sampah + + + + item + item + + + + items + item + + + + Contains %1 %2 + Mengandung %1 %2 + + + + UDiskListener + + + Failed to rename the label + Gagal mengganti nama label + + + + UserShareManager + + + Kindly Reminder + Pengingat Baik + + + + Please firstly install samba to continue + Mohon pasang terlebih dahulu samba untuk melanjutkan + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + Batal + + + + Confirm + Konfirmasi + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_it.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_it.ts new file mode 100644 index 0000000..daedc0d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_it.ts @@ -0,0 +1,4717 @@ + + + AppController + + + New Folder + Nuova cartella + + + + Mounting device error + Errori montaggio dispositivo + + + + The disc image was corrupted, cannot mount now, please erase the disc first + L'immagine è corrotta, impossibile montare, prima cancella il disco + + + + Mount error: unsupported image format + Mount fallito: formato immagine non supportato + + + + + The device was not safely removed + Il dispositivo non è stato rimosso in sicurezza + + + + + Click "Safely Remove" and then disconnect it next time + Clicca su "Rimozione sicura" e rimuovilo solo successivamente + + + + The device was not ejected + Il dispositivo non è stato rimosso + + + + Disk is busy, cannot eject now + Disco occupato, impossibile espellerlo ora + + + + Authentication timed out + Autenticazione scaduta + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Trasferimento file via Bluetooth + + + + File Transfer Successful + Trasferimento file riuscito + + + + File Transfer Failed + Trasferimento file fallito + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Invio file a "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Invio fallito a "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Invio a "<b style="font-weight: 550;">%1</b>" completato + + + + Select a Bluetooth device to receive files + Seleziona un dispositivo Bluetooth in cui ricevere i file + + + + Cannot find the connected Bluetooth device + Impossibile trovare il dispositivo Bluetooth collegato + + + + Waiting to be received... + In attesa di ricezione... + + + + Go to Bluetooth Settings + Vai alle impostazioni Bluetooth + + + + %1/%2 Sent + %1/%2 Invio completato + + + + Error: the Bluetooth device is disconnected + Errore: il dispositivo Bluetooth si è disconnesso + + + + Unable to send the file more than 2 GB + Impossibile inviare file più grandi di 2 GB + + + + Unable to send 0 KB files + Impossibile inviare file da 0 KB + + + + File doesn't exist + Il file non esiste + + + + Next + button + Prosegui + + + + Cancel + button + Annulla + + + + Done + button + Fatto + + + + Retry + button + Riprova + + + + OK + button + OK + + + + File sending request timed out + Timeout della richiesta invio file + + + + The service is busy and unable to process the request + Il servizio è occupato ed è impossibile eseguire la richiesta + + + + BurnOptDialog + + + Device error + Errore dispositivo + + + + Optical device %1 doesn't exist + Il dispositivo ottico %1 non esiste + + + + Advanced settings + Impostazioni avanzate + + + + File system: + File system: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Per Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Per Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Compatibile con la modalità Windows CD/DVD) + + + + ISO9660 Only + Solo ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Chiudi tutto + + + + Total size: %1, %2 files + Dimensione totale %1, %2 file + + + + ComputerModel + + + Double click to open it + + + + + My Directories + Preferiti + + + + Disks + Dischi + + + + File Vault + File di recupero Vault + + + + Quick Access + + + + + ComputerPropertyDialog + + + Computer + Computer + + + + Basic Info + Info base + + + + + Computer Name + Nome Computer + + + + + Edition + Edizione + + + + + + Version + Versione + + + + + Type + Modello + + + + + + Processor + Processore + + + + + + Memory + Memoria + + + + + + + Bit + Bit + + + + + Available + Disponibile + + + + Obtaining... + Ottenimento in corso... + + + + ConnectToServerDialog + + + Connect to Server + Connetti al Server + + + + Cancel + button + Annulla + + + + Connect + button + Connetti + + + + My Favorites: + Favoriti: + + + + + Clear History + Cancella cronologia + + + + DFMAddressBar + + + Search or enter address + Cerca o inserisci un indirizzo + + + + DFMAdvanceSearchBar + + + Search: + Cerca: + + + + File Type: + Tipo file: + + + + File Size: + Dimensione file: + + + + Time Modified: + Ultima modifica: + + + + Time Accessed: + Ultimo accesso: + + + + Time Created: + Data creazione: + + + + Reset + Reset + + + + All subdirectories + Tutte le sottocartelle + + + + Current directory + Cartella corrente + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Oggi + + + + Yesterday + Ieri + + + + This week + Questa settimana + + + + Last week + La settimana scorsa + + + + This month + Questo mese + + + + Last month + Il mese scorso + + + + This year + Quest'anno + + + + Last year + L'anno scorso + + + + DFMOpticalMediaWidget + + + + No files to burn + Nessun file da scrivere + + + + Unable to burn. Not enough free space on the target disk. + Scrittura non possibile. Spazio disponibile sul disco di destinazione non sufficiente. + + + + %1 burning is not supported + %1 scrittura non supportata + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. Non è il disco %1 ; +2. La versione di questo file system non supporta ancora l'aggiunta di file. + + + + DFMTagCrumbController + + + Tag information + Info Tag + + + + DFMTagWidget + + + Tag + Tag + + + + DFMTaskWidget + + + Do not ask again + Non chiederlo nuovamente + + + + Syncing data + Sincronizzazione dati + + + + Please wait + Attendere prego + + + + + Time modified: %1 + Ultima modifica: %1 + + + + + Contains: %1 + Contiene: %1 + + + + + Size: %1 + Dimensione: %1 + + + + Original folder + Cartella di origine + + + + Keep both + button + Mantieni entrambi + + + + Skip + button + Salta + + + + Replace + button + Sostituisci + + + + Retry + button + Riprova + + + + Original file + File originario + + + + Target folder + Cartella di destinazione + + + + Target file + File di destinazione + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Encrypt File Vault + + + + Click 'Encrypt' and input the user password. + Clicca 'Crittografa' ed inserisci la password. + + + + Encrypting... + Crittografia in corso... + + + + + + + Encrypt + Crittografa + + + + Failed to create file vault: %1 + Creazione file vault fallita: %1 + + + + OK + OK + + + + The setup is complete + La configurazione è terminata + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Salva chiave di recupero + + + + Keep the key safe to retrieve the vault password later + Conserva la chiave al sicuro per recuperare la password del vault in un secondo momento + + + + Save to default path + Salva nel percorso predefinito + + + + Save to other locations + Salva in altri percorsi + + + + No permission, please reselect + Autorizzazione negata + + + + Select a path + Seleziona un percorso + + + + Next + Prosegui + + + + The default path is invisible to other users, and the path information will not be shown. + Il percorso predefinito è invisibile agli altri utenti e le informazioni sul percorso non verranno visualizzate. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Chiave di recupero + + + + Generate a recovery key in case that you forgot the password + Genera una chiave di recupero nel caso perdessi la password + + + + Key + Chiave + + + + QR code + QR code + + + + Scan QR code and save the key to another device + Scansiona il codice QR e salva la chiave su un altro dispositivo + + + + Next + Prosegui + + + + Recovery Key: + Chiave di recupero: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Imposta la password Vault + + + + Method + Metodo + + + + Manual + Manuale + + + + Password + Password + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 caratteri, che contenga A-Z, a-z, 0-9 e simboli + + + + Repeat password + Ripeti Password + + + + Input the password again + Inserisci nuovamente la password + + + + Password hint + Suggerimento password + + + + Optional + Facoltativo + + + + Next + Prosegui + + + + + Passwords do not match + La password non corrisponde + + + + DFMVaultActiveStartView + + + File Vault + File di recupero Vault + + + + Create your secure private space + Crea il tuo spazio privato sicuro + + + + Advanced encryption technology + Tecnologia di cifratura avanzata + + + + Convenient and easy to use + Facile da usare. +Localizzazione italiana a cura di Massimo A. Carofano. + + + + Create + Crea + + + + DFMVaultFileView + + + Cannot open this path + Impossibile aprire questo percorso + + + + Hint + Suggerisci + + + + OK + OK + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Sblocca mediante chiave + + + + Failed to unlock file vault + Sblocco file vault vallito + + + + OK + OK + + + + Input the 32-digit recovery key + Inserisci la chiave di 32 caratteri + + + + Cancel + button + Annulla + + + + Unlock + button + Sblocca + + + + Wrong recovery key + Password di recupero errata + + + + DFMVaultRemoveByPasswordView + + + Password + Password + + + + Password hint: %1 + Suggerimento password: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Inserisci la chiave di 32 caratteri + + + + DFMVaultRemovePages + + + Delete File Vault + Elimina File Vault + + + + Once deleted, the files in it will be permanently deleted + Una volta rimosso, i file contenuti saranno eliminati + + + + Use Key + Usa la chiave + + + + Cancel + button + Annulla + + + + Use Key + button + Usa la chiave + + + + Delete + button + Elimina + + + + + OK + button + OK + + + + Use Password + Usa la password + + + + Wrong password + Password errata + + + + Wrong recovery key + Password di recupero errata + + + + Failed to delete file vault + Rimozione file vault fallita + + + + Deleted successfully + Rimozione riuscita + + + + Failed to delete + Eliminazione file fallita + + + + Removing... + Rimozione... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + Impossibile ottenere il file chiave + + + + Verification failed + Verifica fallita + + + + + Select a path + Seleziona un percorso + + + + + Retrieve Password + Recupera la password + + + + By key in the default path + Dalla chiave nel percorso predefinito + + + + By key in the specified path + Dalla chiave in un percorso specifico + + + + Verification Successful + Verifica completata + + + + Keep it safe + Tienila al sicuro + + + + Back + button + Indietro + + + + Verify Key + button + Verifica chiave + + + + Go to Unlock + button + Vai allo sblocco + + + + Close + button + Chiudi + + + + Vault password: %1 + Password Vault: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Sblocca File Vault + + + + Forgot password? + Password dimenticata? + + + + Password hint: %1 + Suggerimento password: %1 + + + + Failed to unlock file vault + Sblocco file vault vallito + + + + Cancel + button + Annulla + + + + Password + Password + + + + Unlock + button + Sblocca + + + + Please try again %1 minutes later + Riprova tra %1 minuti + + + + Wrong password, please try again %1 minutes later + Password errata, riprova tra %1 minuti + + + + Wrong password, one chance left + Password errata, ultimo tentativo disponibile + + + + Wrong password, %1 chances left + Password errata, %1 tentativi disponibili + + + + Wrong password + Password errata + + + + OK + button + OK + + + + DFileCopyMoveJob + + + Permission error + Errore dei permessi + + + + The action is denied + Azione negata + + + + Failed to open the file + Apertura file fallita + + + + Failed to read the file + Lettura file fallita + + + + Failed to write the file + Scrittura file fallita + + + + Failed to create the directory + Creazione cartella fallita + + + + Failed to delete the file + Eliminazione file fallita + + + + Failed to move the file + Spostamento file fallito + + + + Original file does not exist + Il file originario non esiste + + + + Failed, file size must be less than 4GB + Ops, la dimensione del file deve essere inferiore ai 4 Gb + + + + Not enough free space on the target disk + Spazio disponibile su disco insufficiente + + + + File integrity was damaged + L'integrità del file è danneggiata + + + + The target device is read only + Il dispositivo di destinazione è in sola lettura + + + + Target folder is inside the source folder + La cartella di destinazione si trova all'interno della cartella di origine + + + + The action is not supported + Azione non supportata + + + + You do not have permission to traverse files in it + Non hai i permessi per modificare i file contenuti + + + + Failed to position the file pointer! + + + + + copy + Extra name added to new file name when used for file name. + copia + + + + Failed to open the directory, cause: file name too long + Impossibile aprire il percorso, causa: il nome file è troppo lungo + + + + + Failed to open the file, cause: file name too long + Impossibile aprire il file, causa: il nome file è troppo lungo + + + + + Failed to write the file, cause: + Scrittura fallita, causa: + + + + Failed to position the file pointer, cause: %1 + + + + + Syncing data + Sincronizzazione dati + + + + Please wait + Attendere prego + + + + Failed to create the directory, cause: %1 + Creazione della cartella fallita, causa: %1 + + + + + + + + Failed to open the file, cause: %1 + Apertura file fallita, causa: %1 + + + + + + + Failed to open the file, cause: Permission denied + Apertura non riuscita, causa: permesso negato + + + + + Failed to read the file, cause: %1 + Lettura file fallita, causa: %1 + + + + + + + Failed to write the file, cause: %1 + Scrittura file fallita, causa: %1 + + + + + File integrity was damaged, cause: %1 + Integrità del file danneggiata, causa: %1 + + + + Failed to open the file, cause: + Apertura fallita, causa: + + + + Failed to read the file, cause: + Lettura fallita, causa: + + + + Failed to delete the file, cause: %1 + Eliminazione file fallita, causa: %1 + + + + Fail to create symlink, cause: %1 + Creazione symlink fallita, causa: %1 + + + + DFileDialog + + + + Save + button + Salva + + + + + Cancel + button + Annulla + + + + Confirm + button + Conferma + + + + %1 already exists, do you want to replace it? + %1 esiste già, desideri sostituirlo? + + + + Replace + button + Sostituisci + + + + Open + button + Apri + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Il file sarà nascosto se il suo nome inizierà per punto (.). Desideri confermarlo? + + + + DFileManagerWindow + + + Trash + Cestino + + + + Empty + Vuoto + + + + DFileSystemModel + + + + Name + Nome + + + + + + Time modified + Ultima modifica + + + + Size + Dimensione + + + + Type + Tipo + + + + Time created + Data creazione + + + + + Last access + Ultimo accesso + + + + + + + Path + Percorso + + + + DFileView + + + Disc mount error + Errore montaggio Disco + + + + The disc is in use, please end the running process and remount the disc. + Il Disco è in uso, termina il processo corrente e monta nuovamente il Disco. + + + + Mounting failed + Montaggio fallito + + + + (Reverse) + (Inverti) + + + + DFileViewHelper + + + Add tag "%1" + Aggiungi il tag "%1" + + + + DStatusBar + + + %1 item + %1 oggetto + + + + %1 items + %1 oggetti + + + + %1 item selected + %1 oggetto selezionato + + + + %1 items selected + %1 oggetti selezionati + + + + %1 folder selected (contains %2) + Selezionata %1 cartella (contiene %2 file) + + + + %1 folders selected (contains %2) + Selezionate %1 cartelle (contengono %2 file) + + + + %1 file selected (%2) + %1 file selezionato (%2) + + + + %1 files selected (%2) + %1 files selezionati (%2) + + + + %1 folder selected + %1 cartella/e selezionata/e + + + + Filter + Filtri + + + + Save as: + Salva come: + + + + Loading... + Caricamento... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Cancellazione disco %1, attendi... + + + + Burning disc %1, please wait... + Scrittura disco %1, attendi... + + + + Writing data... + Scrittura dati... + + + + Verifying data... + Verifica dati... + + + + Copying %1 + Copia in corso di %1 + + + + + + to %2 + in %2 + + + + %1 already exists in target folder + %1 esiste già nella cartella di destinazione + + + + Original path %1 Target path %2 + Cartella di origine %1, cartella di destinazione %2 + + + + Merge + button + Unisci + + + + Replace + button + Sostituisci + + + + Moving %1 + Spostamento di %1 + + + + Removing file vault, please try later + Rimozione file vault, riprova più tardi + + + + Restoring %1 + Ripristino di %1 + + + + Deleting %1 + Eliminazione di %1 + + + + Trashing %1 + Eliminazione di %1 + + + + Calculating space, please wait + Calcolo spazio, attendere prego + + + + DUMountManager + + + + Authentication timed out + Autenticazione scaduta + + + + + + Disk is busy, cannot unmount now + Disco occupato, impossibile smontare + + + + Disk is busy, cannot eject now + Disco occupato, impossibile espellerlo ora + + + + The device is busy, cannot eject now + Disco occupato, impossibile espellerlo ora + + + + + + The device is busy, cannot remove now + Disco occupato, impossibile espellerlo ora + + + + DeepinStorage + + + + + %1 Volume + Volume %1 + + + + Data Disk + Data Partition + Disco dati + + + + %1 Drive + Dispositivo %1 + + + + Blank %1 Disc + Cancella disco %1 + + + + %1 Encrypted + %1 Crittografato + + + + DialogManager + + + + + + Operation failed! + Operazione fallita! + + + + Target folder is inside the source folder! + La cartella di destinazione è all'interno di quella originaria! + + + + Do you want to run %1 or display its content? + Vuoi eseguire %1 o visualizzarne il contenuto? + + + + It is an executable text file. + E' un file eseguibile di testo. + + + + It is an executable file. + È un file eseguibile. + + + + This file is not executable, do you want to add the execute permission and run? + Il file non è eseguibile, desideri impostare i relativi permessi ed eseguire? + + + + "%1" already exists, please use another name. + "%1" esiste già, usa un altro nome. + + + + The file name must not contain two dots (..) + Il nome del file non deve contenere due punti consecutivi (..) + + + + Device or resource busy + + + + + Are you sure you want to erase all data on the disc? + Sicuro di voler eliminare tutti i dati presenti sul disco? + + + + How do you want to use this disc? + Come vuoi utilizzare questo disco? + + + + Disc erase failed + Cancellazione disco fallita + + + + Burn process failed + Processo di scrittura fallito + + + + %1: %2 + %1: %2 + + + + Show details + Mostra dettagli + + + + Hide details + Nascondi dettagli + + + + Error + Errore + + + + Permanently delete %1? + Elimina definitivamente %1? + + + + Permanently delete %1 items? + Elimina definitivamente %1? + + + + Empty + Svuota + + + + Do you want to delete %1? + Desideri cancellare %1? + + + + Do you want to delete the selected %1 items? + Desideri eliminare i %1 elementi selezionati? + + + + Sorry, unable to locate your bookmark directory, remove it? + Scusa, impossibile localizzare il segnalibro, rimuoverlo? + + + + Name: + Nome: + + + + %1 that this shortcut refers to has been changed or moved + %1 questa scorciatoia è stata modificata o spostata + + + + Do you want to delete this shortcut? + Desideri eliminare questa scorciatoia? + + + + Failed, file size must be less than 4GB. + Ops, il file deve esser più piccolo di 4GB. + + + + Fail to create symlink, cause: + Creazione symlink fallita, causa: + + + + The selected files contain system file/directory, and it cannot be deleted + La selezione contiene files e cartelle di sistema, quindi non possono esser eliminati. + + + + Unable to find the original file + Impossibile trovare il file di origine + + + + + You do not have permission to operate file/folder! + Non hai i permessi per modificare il file/cartella! + + + + Failed to restore %1 file, the source file does not exist + Ripristino di %1 file fallito, il file originario non esiste + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Ops, non hai l'autorizzazione per modificare %1 file/cartella(e)! + + + + Unable to access %1 + Accesso non riuscito a %1 + + + + + Sending files now, please try later + Invio file in corso, riprova più tardi + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Per accedere al dispositivo dovresti prima formattare il disco. Sicuro di volerlo formattare? + + + + Scanning the device, stop it? + Scansione del dispositivo in corso, interromperla? + + + + Share folder can't be named after the current username + La condivisione della cartella non potrà esser rinominata dopo + + + + Do you want to run %1? + Desideri eseguire %1? + + + + Burn image + button + Scrivi immagine + + + + Burn files + button + Scrivi file + + + + Are you sure you want to empty %1 item? + Sicuro di voler eliminare %1 oggetto? + + + + Are you sure you want to empty %1 items? + Sicuro di eliminare %1 oggetti? + + + + + This action cannot be undone + Questa azione non può esser annullata + + + + + + + + + + + + + + OK + button + OK + + + + + + + + + + + + + + + Cancel + button + Annulla + + + + + + Run + button + Esegui + + + + + Run in terminal + button + Esegui nel Terminale + + + + Display + button + Visualizza + + + + + + + + + + + Confirm + button + Conferma + + + + Erase + button + Elimina + + + + Data verification failed + Verifica data fallita + + + + Show details + button + Mostra dettagli + + + + + Delete + button + Elimina + + + + Remove + button + Rimuovi + + + + Disk is busy, cannot unmount now + Disco in uso, impossibile smontarlo + + + + Force unmount + button + Smonta forzosamente + + + + Unable to copy. Not enough free space on the target disk. + Copia impossibile. Spazio libero non sufficiente nel disco di destinazione. + + + + Failed to restore %1 file, the target folder is read-only + Ripristino di %1 file fallito, la destinazione è di tipo sola lettura + + + + Failed to restore %1 files, the target folder is read-only + Ripristino di %1 file fallito, la destinazione è di tipo sola lettura + + + + Failed to restore %1 files, the source files do not exist + Ripristino di %1 file fallito, i file alla fonte non esistono + + + + Format + button + Formatta + + + + Stop + button + Stop + + + + FileController + + + + + + Unable to find the original file + Impossibile trovare il file di origine + + + + + + Kindly Reminder + Promemoria + + + + + + Please install File Roller first and then continue + Installa File Roller prima di continuare + + + + + Unable to create files here: %1 + Impossibile creare qui il file: %1 + + + + Confirm + button + Conferma + + + + FileDialogStatusBar + + + File Name + Nome file + + + + Format + Formatta + + + + Save + button + Salva + + + + Open + button + Apri + + + + Save File + button + Salva file + + + + Open File + button + Apri file + + + + + + Cancel + button + Annulla + + + + FileJob + + + copy + copia + + + + + + + Data verification successful. + Verifica dati completata. + + + + + + Burn process completed + Processo di scrittura completato + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 è un file duplicato. + + + + Insufficient disc space. + Spazio insufficiente su disco + + + + Lost connection to drive. + Connessione al disco persa. + + + + The CD/DVD drive is not ready. Try another disc. + Il CD/DVD non è pronto. Prova con un altro disco. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + Il CD/DVD è occupato. Esci dal programma che sta utilizzando il lettore, inserendo nuovamente il disco. + + + + Unknown error + Errore sconosciuto + + + + Device disconnected + Dispositivo disconnesso + + + + GenerateSettingTranslate + + + + + Basic + Base + + + + + + Open behavior + Comportamento in apertura + + + + + + Always open folder in new window + Apri sempre una cartella in nuova finestra + + + + + + Open file: + Apri file: + + + + + + Click + Click + + + + + + Double click + Doppio click + + + + + + New window and tab + Nuove finestre e schede + + + + + + Open from default window: + Apri dalla finestra principale: + + + + + + + + + Computer + Computer + + + + + + + + + Home + Home + + + + + + + + + Desktop + Desktop + + + + + + + + + Videos + Video + + + + + + + + + Music + Musica + + + + + + + + + Pictures + Immagini + + + + + + + + + Documents + Documenti + + + + + + + + + Downloads + Download + + + + + + Open in new tab: + Apri in nuova scheda: + + + + + + Current Directory + Cartella corrente + + + + + + View + Visualizza + + + + + + Default size: + Dimensione di default: + + + + + + Extra small + Molto piccola + + + + + + Small + Piccola + + + + + + Medium + Media + + + + + + Large + Grande + + + + + + Extra large + Molto grande + + + + + + Default view: + Vista di default: + + + + + + Icon + Icona + + + + + + List + Lista + + + + + + Hidden files + File nascosti + + + + + + Show hidden files + Mostra file nascosti + + + + + + Hide file extension when rename + Nascondi l'estensione mentre rinomini + + + + + + Advanced + Avanzate + + + + + + Index + Indice + + + + + + Auto index internal disk + Indicizza il disco primario + + + + + + Index external storage device after connected to computer + Indicizza i dispositivi esterni dopo la loro connessione al computer + + + + + + Full-Text search + Ricerca in tutto il testo + + + + + + Show item counts and sizes in the path of mounted MTP devices + Mostra il numero e le dimensioni degli elementi nel percorso dei dispositivi MTP montati + + + + + + Keep showing the mounted Samba shares + Continua a mostrare le condivisioni Samba montate + + + + + + Use the file chooser dialog of File Manager + Usa il form di dialog del File Manager + + + + + + Ask for my confirmation when deleting files + Chiedi la conferma in caso di eliminazione + + + + + + Other + Altro + + + + + + Hide system disk + Nascondi disco di Sistema + + + + + + Show file system on disk icon + Mostra il file system nell'icona del Disco + + + + + + Show hidden files in search results + Mostra i file nascosti nei risultati di ricerca + + + + + + Display recent file entry in left panel + Visualizza i file recenti nel pannello sinistro + + + + + + Preview + Anteprima + + + + + Compress file preview + Anteprima file compressi + + + + + + Text preview + Anteprima file di testo + + + + + + Document preview + Anteprima dei documenti + + + + + + Image preview + Anteprima immagini + + + + + + Video preview + Anteprima video + + + + + + Mount + Monta + + + + + + Auto mount + Monta automaticamente + + + + + + Open after auto mount + Apri dopo l'auto-mount + + + + + + Dialog + Dialog + + + + Compressed file preview + Anteprima file compresso + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Impossibile verificare l'identità di %1. + + + + This happens when you log in to a computer the first time. + Questo accade quando effettui l'accesso ad un computer per la prima volta. + + + + The identity sent by the remote computer is + L'identità inviata dal computer remoto è + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Se desideri essere sicuro, contatta l'admin di sistema. + + + + + + + + Mounting device error + Errori montaggio dispositivo + + + + + Wrong username or password + Nome utente o password errati + + + + + + + + Confirm + button + Conferma + + + + + Cannot find the mounted device + Impossibile trovare il dispositivo montato + + + + No key available to unlock device + Nessuna chiave di decrittazione disponibile per sbloccare il dispositivo + + + + The disk is mounted by user "%1", you cannot unmount it. + Il disco è stato montato dall'utente "%1", non puoi smontarlo. + + + + Cannot unmount the device + Impossibile smontare il dispositivo + + + + Cannot eject the device "%1" + Impossibile espellere "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Scrittura non possibile. Spazio disponibile sul disco di destinazione non sufficiente. + + + + MergedDesktopController + + + + Pictures + Immagini + + + + + Music + Musica + + + + + Applications + Applicazioni + + + + + Videos + Video + + + + + Documents + Documenti + + + + + Others + Altro + + + + MimeTypeDisplayManager + + + + Directory + Cartella + + + + + + Application + Applicazioni + + + + + + Video + Video + + + + + + Audio + Audio + + + + + + Image + Immagini + + + + + Archive + Archivio + + + + + + Text + Testo + + + + + Executable + Eseguibile + + + + + Backup file + Backup del file + + + + + Unknown + Sconosciuto + + + + MountAskPasswordDialog + + + Cancel + button + Annulla + + + + Connect + button + Connetti + + + + Log in as + Login come + + + + Anonymous + Anonimo + + + + Registered user + Utente registrato + + + + Username + Username + + + + Domain + Dominio + + + + Password + Password + + + + Remember password + Ricorda password + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Annulla + + + + Unlock + button + Sblocca + + + + Input password to decrypt the disk + Inserisci la password per decifrare il Disco + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Sicuro di eliminare definitivamente %1 oggetto? + + + + This file is too big for the trash + File troppo grande per spostarlo nel cestino + + + + The files are too big for the trash + File troppo grande per spostarlo nel cestino + + + + Are you sure you want to permanently delete %1 files? + Sicuro di eliminare definitivamente %1 oggetti? + + + + Cancel + button + Annulla + + + + Delete + button + Elimina + + + + OpenWithDialog + + + Open with + Apri con + + + + Add other programs + Aggiungi altri programmi + + + + Set as default + Imposta come predefinito + + + + Cancel + button + Annulla + + + + Confirm + button + Conferma + + + + Recommended Applications + Applicazioni raccomandate + + + + Other Applications + Altre applicazioni + + + + PathManager + + + Home + Home + + + + Desktop + Desktop + + + + Videos + Video + + + + Music + Musica + + + + Pictures + Immagini + + + + Documents + Documenti + + + + Downloads + Download + + + + + Trash + Cestino + + + + + + System Disk + Disco di sistema + + + + Computers in LAN + Computer in LAN + + + + My Shares + Condivisi + + + + Computer + Computer + + + + Recent + File Recenti + + + + File Vault + File di recupero Vault + + + + PropertyDialog + + + Basic info + Info base + + + + Open with + Apri con + + + + Sharing + Condividi + + + + Permissions + Permessi + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Nascondi questa cartella + + + + Hide this file + Nascondi questo file + + + + Allow to execute as program + Permetti di eseguire il programma + + + + QObject + + + + + + Size + Dimensione + + + + + + Contains + Contiene + + + + + + Type + Tipo + + + + + + + + Time modified + Ultima modifica + + + + Free space + Spazio libero + + + + Total space + Spazio totale + + + + + Time locked + Data blocco + + + + Access denied + Accesso negato + + + + + Executable + Eseguibile + + + + + Write only + Sola scrittura + + + + + Read only + Sola lettura + + + + + Read-write + Lettura e scrittura + + + + Others + Altro + + + + Owner + Proprietario + + + + Unconnected network shared directory + Directory condivisa di rete non connessa + + + + Device type + Tipo dispositivo + + + + File system + File system + + + + Group + Gruppo + + + + + Open + Apri + + + + Lock + Blocca + + + + Auto lock + Blocca automaticamente + + + + Never + Mai + + + + 5 minutes + 5 minuti + + + + 10 minutes + 10 minuti + + + + 20 minutes + 20 minuti + + + + Delete File Vault + Elimina File Vault + + + + Unlock + Sblocca + + + + Unlock by key + Sblocca con chiave + + + + Open + button + Apri + + + + + Size: %1 + Dimensione: %1 + + + + Type: %1 + Tipologia: %1 + + + + Size: 0 + Dimensione: 0 + + + + Items: %1 + Elementi: %1 + + + + + + + + + + Open in new window + Apri in una nuova finestra + + + + + + + + + + Open in new tab + Apri in una nuova scheda + + + + Open with + Apri con + + + + + Compress + Comprimi + + + + Extract + Estrai + + + + Extract here + Estrai qui + + + + Cut + Taglia + + + + Copy + Copia + + + + Paste + Incolla + + + + + + + + Rename + Rinomina + + + + + + + Remove + Rimuovi + + + + Create link + Crea collegamento + + + + Send to desktop + Invia al desktop + + + + Send to + Invia a + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Aggiungi ai segnalibri + + + + + + + Properties + Proprietà + + + + New folder + Nuova cartella + + + + New window + Nuova finestra + + + + Select all + Seleziona tutto + + + + + Clear recent history + Pulisci cronologia + + + + + + Empty Trash + Svuota cestino + + + + Display as + Visualizza come + + + + Sort by + Ordina per + + + + New document + Nuovo documento + + + + + Time created + Data creazione + + + + + + Source path + Percorso + + + + Share folder + Condividi cartella + + + + Cancel sharing + Annulla condivisione + + + + Connect to Server + Connetti al Server + + + + Set share password + Imposta la password di condivisione + + + + Format + Formatta + + + + Tag information + Informazioni Tag + + + + Open as administrator + Apri come Admin + + + + Select default program + Seleziona un programma predefinito + + + + Open file location + Apri la cartella del file + + + + Remove bookmark + Rimuovi riferimento + + + + + + Delete + Elimina + + + + Office Text + Documento Office + + + + Spreadsheets + Foglio di calcolo + + + + Plain Text + Documento di testo + + + + Open in terminal + Apri nel Terminale + + + + Restore + Ripristina + + + + Restore all + Ripristina tutto + + + + Clear saved password and unmount + Cancella le password salvate e smonta + + + + File Vault + File Vault + + + + Add to disc + Aggiungi al disco + + + + Refresh + + + + + Auto mount + Monta automaticamente + + + + Open after auto mount + Apri dopo l'auto-mount + + + + + Mount + Monta + + + + + Unmount + Smonta + + + + It does not support burning %1 discs + Non supporta la scrittura di %1 dischi + + + + Burn + Scrivi + + + + Disc name: + Nome disco: + + + + + Maximum + Massimo + + + + Allow files to be added later + Permetti l'aggiunta di file successivamente + + + + Verify data + Verifica dati + + + + Write speed: + Velocità di scrittura: + + + + + + + Cancel + button + Annulla + + + + Burn + button + Scrivi + + + + + Eject + Espelli + + + + Safely Remove + Rimuovi in sicurezza + + + + + Name + Nome + + + + Settings + Impostazioni + + + + Exit + Esci + + + + Icon + Icona + + + + List + Lista + + + + Extend + Estendi + + + + Set as wallpaper + Imposta come sfondo + + + + + + + Local disk + Disco locale + + + + + Removable disk + Disco rimovibile + + + + + + Network shared directory + Directory condivisa di rete + + + + + Android mobile device + Dispositivo Mobile Android + + + + + Apple mobile device + Dispositivo Mobile Apple + + + + + Camera + Camera + + + + + DVD + DVD + + + + + Unknown device + Dispositivo sconosciuto + + + + + + %1 item + %1 oggetto + + + + + + %1 items + %1 oggetti + + + + Shortcut + Scorciatoia + + + + Create symlink + Crea symlink + + + + Path + Percorso + + + + + + Time deleted + Data eliminazione + + + + Loading... + Caricamento... + + + + File has been moved or deleted + Il file è stato spostato o eliminato + + + + You do not have permission to traverse files in it + Non hai i permessi per modificare i file contenuti + + + + + + You do not have permission to access this folder + Non hai i permessi per accedere a questa cartella + + + + + + + + Folder is empty + Cartella vuota + + + + Searching... + Ricerca... + + + + No results + Nessun risultato + + + + Source Path + TrashFileInfo + Percorso fonte + + + + Document + Documento + + + + Spreadsheet + Foglio di calcolo + + + + + Presentation + Presentazione + + + + Text + Testo + + + + 1 task in progress + 1 operazione in corso + + + + %1 tasks in progress + 1% operazioni in corso + + + + Mode: + Modalità: + + + + + Replace Text + Sostituisci testo + + + + + Add Text + Aggiungi testo + + + + + Custom Text + Testo personalizzato + + + + Find: + Trova: + + + + Replace: + Sostituisci: + + + + + Optional + Facoltativo + + + + Add: + Aggiungi: + + + + Location: + Percorso: + + + + File name: + Nome file: + + + + Start at: + Inizia da: + + + + + Rename + button + Rinomina + + + + + + + + + + + Required + Richiesto + + + + + Before file name + Prima del nome del file + + + + + After file name + Dopo il nome del file + + + + Find + Trova + + + + Replace + Sostituisci + + + + Add + Aggiungi + + + + Start at + Inizia da + + + + + + Location + Percorso + + + + File name + Nome file + + + + Dimension + Dimensioni + + + + Duration + Durata + + + + Tips: Sort by selected file order + Suggerimento: ordina selezionando la modalità che preferisci + + + + Rename %1 Files + Rinomina %1 file + + + + Multiple Files + File multipli + + + + Basic info + Info di base + + + + Total size + Spazio totale + + + + Number of files + Oggetti totali + + + + %1 file(s), %2 folder(s) + %1 file(s), %2 cartella(e) + + + + + + Time accessed + Ultimo accesso + + + + Orange + Arancione + + + + Red + Rosso + + + + Purple + Viola + + + + Navy-blue + Blu Navy + + + + Azure + Azzurro + + + + Green + Verde + + + + Yellow + Giallo + + + + Gray + Grigio + + + + Input tag info, such as work, family. A comma is used between two tags. + Inserisci le info del Tag, come lavoro, famiglia..Occore la virgola per separare i tag. + + + + Bookmarks + Preferiti + + + + Erase + Elimina + + + + Copy path + Copia percorso + + + + Edit address + Modifica percorso + + + + Free Space %1 + Spazio libero %1 + + + + Files are being processed + File in gestione + + + + + Unknown + Sconosciuto + + + + My Vault + Il mio Vault + + + + + Failed to create file info + Creazione info file fallita + + + + Failed to create file handler + Creazione del gestore file fallita + + + + Failed to open the file, cause: %1 + Apertura file fallita, causa: %1 + + + + Original file does not exist + Il file originario non esiste + + + + Do you want to delete %1? + Desideri cancellare %1? + + + + Confirm + button + Conferma + + + + + + + + %1 are not allowed + %1 non ammessi + + + + + Failed to start Samba services + Impossibile avviare i servizi Samba + + + + RecentController + + + Cancel + button + Annulla + + + + Remove + button + Rimuovi + + + + Do you want to remove this item? + Desideri eliminare questo elemento? + + + + Do yout want to remove %1 items? + Vuoi rimuovere %1 elementi? + + + + It does not delete the original files + Non cancellare i file originali + + + + ShareInfoFrame + + + Share this folder + Condividi questa cartella + + + + Share name: + Nome condivisione: + + + + Permission: + Permessi: + + + + Read and write + Lettura e scrittura + + + + Read only + Sola lettura + + + + Anonymous: + Anonimato: + + + + Not allow + Non ammesso + + + + Allow + Ammesso + + + + The share name must not be two dots (..) or one dot (.) + Il nome file non deve contenere due punti (..) o un punto (.) + + + + The share name is used by another user. + Il nome condiviso è utilizzato da un altro utente. + + + + OK + button + OK + + + + Cancel + button + Annulla + + + + Replace + button + Sostituisci + + + + The share name already exists. Do you want to replace the shared folder? + Il nome condiviso esiste già. Desideri sostituire la cartella condivisa? + + + + Shortcut + + + Item + Oggetto + + + + Select to the first item + Seleziona dal primo oggetto + + + + Shift + Home + Shift + Home + + + + Select to the last item + Seleziona dall'ultimo oggetto + + + + Shift + End + Shift + Fine + + + + Select leftwards + Seleziona verso sinistra + + + + Shift + Left + Shift + Sinistra + + + + Select rightwards + Seleziona verso destra + + + + Shift + Right + Shift + Destra + + + + Select to upper row + Seleziona verso la riga superiore + + + + Shift + Up + Shift + Su + + + + Select to lower row + Seleziona verso la riga inferiore + + + + Shift + Down + Shift + Giù + + + + Open + Apri + + + + Ctrl + Down + Ctrl + Giù + + + + To parent directory + Alla cartella superiore + + + + Ctrl + Up + Ctrl + Sopra + + + + Permanently delete + Elimina definitivamente + + + + Shift + Delete + Shift + Canc + + + + Delete file + Elimina file + + + + Delete + Canc + + + + Select all + Seleziona tutto + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Copia + + + + Cut + Taglia + + + + Paste + Incolla + + + + Rename + Rinomina + + + + F2 + F2 + + + + New/Search + Nuovo/Cerca + + + + New window + Nuova finestra + + + + New folder + Nuova cartella + + + + + Search + Cerca + + + + New tab + Nuova scheda + + + + View + Visualizza + + + + Item information + Informazioni oggetto + + + + Help + Aiuto + + + + F1 + F1 + + + + Keyboard shortcuts + Scorciatoie tastiera + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Cambia visualizzazione + + + + Hide item + Nascondi oggetto + + + + Input in address bar + Inserisci nella barra degli indirizzi + + + + Switch to icon view + Visualizza come icone + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Visualizza come lista + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Altri + + + + Close + Chiudi + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Chiudi scheda attuale + + + + Back + Indietro + + + + Alt + Left + Alt + Sinistra + + + + Alt + Right + Alt + Destra + + + + Switch to next tab + Passa alla scheda successiva + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Torna alla scheda precedente + + + + Next file + Prossimo file + + + + Tab + Scheda + + + + Previous file + File precedente + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Cambia scheda specificando un numero tra 1 e 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Avanti + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Impossibile aprire i file nel cestino, ripristinali prima di procedere + + + + TrashPropertyDialog + + + Trash + Cestino + + + + item + Oggetto + + + + items + Oggetti + + + + Contains %1 %2 + Contiene %1 %2 + + + + UDiskListener + + + Failed to rename the label + Ridenominazione della label fallita + + + + UnmountWorker + + + + + The device was not safely unmounted + Il dispositivo non è stato rimosso in sicurezza + + + + The device was not safely removed + Il dispositivo non è stato rimosso in sicurezza + + + + UserShareManager + + + Kindly Reminder + Promemoria + + + + Please firstly install samba to continue + Installa Samba prima di continuare + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + + + + + To protect the files, you cannot share this folder. + Per proteggere i file non puoi condividere questa cartella. + + + + Sharing failed + Condivisione fallita + + + + The computer name is too long + Il nome computer è troppo lungo + + + + You do not have permission to operate file/folder! + Non hai i permessi per modificare il file/cartella! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Inserisci una password per proteggere le cartelle + + + + Cancel + button + Annulla + + + + Confirm + button + Conferma + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ja.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ja.ts new file mode 100644 index 0000000..54631f4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ja.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + 新しいフォルダー + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + すべて閉じる + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + コンピューター + + + + Basic Info + 基本情報 + + + + Computer Name + コンピューター名 + + + + Version + バージョン + + + + Type + 種類 + + + + Processor + プロセッサー + + + + Memory + メモリー + + + + Disk + デイスク + + + + Bit + ビット + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + 検索またはアドレスを入力 + + + + DFMAdvanceSearchBar + + + Search: + 検索: + + + + File Type: + ファイルの種類: + + + + File Size: + ファイルサイズ: + + + + Time Modified: + 変更日時: + + + + Reset + リセット + + + + All subdirectories + すべてのサブディレクトリ + + + + Current directory + 現在のディレクトリ + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + 今日 + + + + Yesterday + 昨日 + + + + This week + 今週 + + + + Last week + 先週 + + + + This month + 今月 + + + + Last month + 先月 + + + + This year + 今年 + + + + Last year + 昨年 + + + + DFMTagCrumbController + + + Tag information + タグ情報 + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + パーミッションエラー + + + + The action is denied + アクションが拒否されました + + + + Failed to open the file + ファイルを開けません + + + + Failed to read the file + ファイルを読み込めません + + + + Failed to write the file + ファイルに書き込めません + + + + Failed to create the directory + ディレクトリを作成できません + + + + Failed to delete the file + ファイルを削除できません + + + + Failed to move the file + ファイルを移動できません + + + + Original file does not exist + オリジナルのファイルが存在しません + + + + Failed, file size must be less than 4GB + 失敗、ファイルサイズは4GB未満にしてください + + + + Not enough free space on the target disk + + + + + File integrity was damaged + + + + + The target device is read only + ターゲットデバイスは読み込み専用です + + + + Target folder is inside the source folder + ターゲットフォルダが元フォルダの内側です + + + + copy + Extra name added to new file name when used for file name. + コピー + + + + Failed to create the directory, cause: %1 + ディレクトリが作成できません: %1 + + + + + Failed to open the file, cause: %1 + ファイルが開けません: %1 + + + + Failed to read the file, cause: %1 + ファイルが読み込めません: %1 + + + + Failed to write the file, cause: %1 + ファイルに書き込めません: %1 + + + + File integrity was damaged, cause: %1 + + + + + Failed to delete the file, cause: %1 + ファイルを削除できません: %1 + + + + Fail to create symlink, cause: %1 + シンボリックリンクを作成できません: %1 + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + %1はすでに存在します。置き換えますか? + + + + Cancel + キャンセル + + + + Replace + 置き換え + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + 名前 + + + + + + Time modified + 更新日時 + + + + Size + サイズ + + + + Type + 種類 + + + + Time created + 作成日時 + + + + + Last access + 最後のアクセス + + + + Path + パス + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + + + + + DFileViewHelper + + + Add tag "%1" + + + + + DStatusBar + + + %1 item + %1 項目 + + + + %1 items + %1 項目 + + + + %1 item selected + %1 項目を選択中 + + + + %1 items selected + %1 項目を選択中 + + + + %1 folder selected (contains %2) + %1フォルダーを選択中 (%2を含む) + + + + %1 folders selected (contains %2) + %1フォルダーを選択中 (%2を含む) + + + + %1 file selected (%2) + %1ファイルを選択中 (%2) + + + + %1 files selected (%2) + %1ファイルを選択中 (%2) + + + + %1 folder selected + %1 フォルダを選択中 + + + + Filter + フィルター + + + + Save as: + + + + + Loading... + 読み込み中… + + + + DTaskDialog + + + This action is not supported + このアクションはサポートされていません + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + %1 ボリューム + + + + Data Disk + Data Partition + データディスク + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + 操作失敗。 + + + + Target folder is inside the source folder! + + + + + + + + + + + + + + OK + OK + + + + Do you want to run %1 or display its content? + %1 を実行またはコンテンツ表示してよろしいですか? + + + + It is an executable text file. + これは実行可能なテキストファイルです。 + + + + + + + + + + + + + + Cancel + キャンセル + + + + + + Run + 実行 + + + + + Run in terminal + ターミナルで実行 + + + + Display + 表示 + + + + It is an executable file. + これは実行可能なファイルです。 + + + + This file is not executable, do you want to add the execute permission and run? + このファイルは実行できません。実行パーミッションを追加して実行しますか? + + + + "%1" already exists, please use another name. + "%1" はすでに使われてます。他の名前を入力してください。 + + + + + + + + Confirm + 確認 + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + 詳細を表示 + + + + Hide details + 詳細を隠す + + + + Error + エラー + + + + Permanently delete %1? + 本当に %1 を削除してよろしいですか? + + + + Permanently delete %1 items? + 本当に %1 項目を削除してよろしいですか? + + + + Delete + 削除 + + + + Empty + 完全に削除 + + + + Sorry, unable to locate your bookmark directory, remove it? + 申し訳ありませんが、ブックマークのディレクトリを見つけることができません。削除してもよろしいですか? + + + + Remove + 削除 + + + + Name: + 名前: + + + + Force unmount + 強制的にアンマウント + + + + %1 that this shortcut refers to has been changed or moved + + + + + Do you want to delete this shortcut? + このショートカットを削除しますか? + + + + Failed, file size must be less than 4GB. + ファイルサイズは4GB 未満にする必要があります。 + + + + Fail to create symlink, cause: + シンボリックリンクを作成できません: + + + + The selected files contain system file/directory, and it cannot be deleted + 選択中のファイルはシステムファイル・ディレクトリを含んでいるため削除できません。 + + + + + You do not have permission to operate file/folder! + ファイル・フォルダーを操作する権限がありません。 + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + + + + + View + 表示 + + + + Do you want to run %1? + %1を実行しますか? + + + + Are you sure you want to empty %1 item? + %1 項目を完全に削除してもよろしいですか? + + + + Are you sure you want to empty %1 items? + %1 項目を完全に削除してもよろしいですか? + + + + + This action cannot be undone + この操作は取り消せません + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + パーティション%1 を読取専用でマウント + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + Windowsでシャットダウン設定の「高速スタートアップを有効にする (推奨)」にチェックが入っている場合ディスクは通常どおり読み書きすることができません + + + + Please restore by the following steps to normally access Windows disk + + + + + 1. Reboot to enter Windows + 1. 再起動してWindowsに入る + + + 3. Reboot and enter deepin + 3. 再起動してdeepinに入る + + + + Reboot + 再起動する + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + ファイル名 + + + + Format + フォーマット + + + + Cancel + キャンセル + + + + Save + 保存 + + + + Open + 開く + + + + Save File + ファイルを保存 + + + + Open File + ファイルを開く + + + + FileJob + + + copy + コピー + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + %1 秒 + + + + %1 m %2 s + %1 分 %2 秒 + + + + %1 h %2 m %3 s + %1 時 %2 分 %3 秒 + + + + %1 d %2 h %3 m %4 s + %1 日 %2 時 %3 分 %4 秒 + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + 基本 + + + + + + Open behavior + + + + + + + Always open folder in new window + + + + + + + Open file: + ファイルを開く: + + + + + + Click + クリック + + + + + + Double click + ダブルクリック + + + + + + New window and tab + 新しいウインドウとタブ + + + + + + Open from default window: + + + + + + + + + + Computer + コンピューター + + + + + + + + + Home + ホーム + + + + + + + + + Desktop + デスクトップ + + + + + + + + + Videos + ビデオ + + + + + + + + + Music + ミュージック + + + + + + + + + Pictures + ピクチャー + + + + + + + + + Documents + ドキュメント + + + + + + + + + Downloads + ダウンロード + + + + + + Open in new tab: + 新しいタブで開く: + + + + + + Current Directory + 現在のディレクトリ + + + + + + View + ビュー + + + + + + Default size: + デフォルトサイズ: + + + + + + Extra small + 最小: + + + + + + Small + + + + + + + Medium + + + + + + + Large + + + + + + + Extra large + 最大 + + + + + + Default view: + デフォルトの表示: + + + + + + Icon + アイコン + + + + + + List + リスト + + + + + + Hidden files + 隠しファイル + + + + + + Show hidden files + 隠しファイルを表示 + + + + + + Hide file extension when rename + リネーム時に拡張子を隠す + + + + + + Advanced + 高度な設定 + + + + + + Index + インデックス + + + + + + Auto index internal disk + 内部ディスクを自動的にインデックスする + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + その他 + + + + + + Hide system disk + システムディスクを隠す + + + + + + Show hidden files in search results + 検索結果で隠しファイルを表示する + + + + + + Display recent file entry in left panel + 左パネルに最近使ったファイルを表示する + + + + + + Preview + プレビュー + + + + + Compress file preview + 圧縮ファイルをプレビュー + + + + + + Text preview + テキストをプレビュー + + + + + + Document preview + ドキュメントをプレビュー + + + + + + Image preview + 画像をプレビュー + + + + + + Video preview + 動画をプレビュー + + + + + + Mount + マウント + + + + + + Auto mount + 自動マウント + + + + + + Open after auto mount + 自動マウント後に開く + + + + + + Dialog + ダイアログ + + + Use the file chooser dialog of Deepin File Manager + Deepin File Managerのファイル選択ダイアログを使用する + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + このディスクはユーザー "%1" によってマウントされたためアンマウントできません。 + + + + + + + + Confirm + 確認 + + + + + Cannot find the mounting device + マウント中デバイスがみつかりません + + + + Cannot unmount the device + デバイスをアンマウントできません + + + + Cannot eject the device "%1" + デバイス「%1」を取り出せません + + + + MergedDesktopController + + + + Pictures + ピクチャー + + + + + Music + ミュージック + + + + + Applications + アプリケーション + + + + + Videos + ビデオ + + + + + Documents + ドキュメント + + + + + Others + その他 + + + + MimeTypeDisplayManager + + + + Directory + ディレクトリ + + + + + + Application + アプリケーション + + + + + + Video + ビデオ + + + + + + Audio + オーディオ + + + + + + Image + 画像 + + + + + Archive + アーカイブ + + + + + + Text + テキスト + + + + + Executable + 実行可能 + + + + + Backup file + バックアップファイル + + + + + Unknown + 不明 + + + + MountAskPasswordDialog + + + Cancel + キャンセル + + + + Connect + 接続 + + + + Log in as + ログイン者 + + + + Anonymous + 匿名 + + + + Registered user + 登録ユーザー + + + + Username + ユーザー名 + + + + Domain + ドメイン + + + + Password + パスワード + + + + Remember password + パスワード 再度 + + + + MountSecretDiskAskPasswordDialog + + + Cancel + キャンセル + + + + Unlock + + + + + Input password to decrypt the disk + ファイルを復号化するためのパスワードを入力 + + + + MoveCopyTaskWidget + + Skip + スキップ + + + Keep both + どちらも保持 + + + Replace + 置き換え + + + Do not ask again + 再度確認しない + + + merge + マージ + + + Copying %1 + %1をコピー中 + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + データを書き込み中… + + + Verifying data... + データを検証中… + + + Copy to %2 + %2にコピー + + + Moving %1 + %1を移動中 + + + Move to %2 + %2に移動 + + + Restoring %1 + %1を復元中 + + + Restore to %2 + %2に復元 + + + Deleting %1 + %1を削除中 + + + Trashing %1 + + + + Calculating space, please wait + 容量を計算中、しばらくお待ちください + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + Retry + 再試行 + + + Time modified:%1 + 更新日時: %1 + + + Original folder + + + + Original file + + + + Target folder + + + + Target file + + + + Contains:%1 + + + + Size:%1 + サイズ:%1 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + キャンセル + + + + Delete + 削除 + + + + OpenWithDialog + + + Open with + 他のアプリケーションで開く + + + + Add other programs + 他のプログラムを追加 + + + + Set as default + + + + + Cancel + キャンセル + + + + Confirm + + + + + Recommended Applications + + + + + Other Applications + 他のアプリケーション + + + + PathManager + + + Home + ホーム + + + + Desktop + デスクトップ + + + + Videos + ビデオ + + + + Music + ミュージック + + + + Pictures + ピクチャー + + + + Documents + ドキュメント + + + + Downloads + ダウンロード + + + + + Trash + ゴミ箱 + + + + + System Disk + システムディスク + + + + Computers in LAN + LAN 内コンピューター + + + + My Shares + + + + + Computer + コンピューター + + + + Recent + 最近使ったファイル + + + + PropertyDialog + + + Basic info + 基本情報 + + + + Open with + 他のアプリケーションで開く + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + プログラムとして実行可能 + + + + QObject + + + + + Size + サイズ + + + + + + Contains + ファイル数 + + + + + + Type + 種類 + + + + + + + Time modified + 更新時間 + + + + Free space + 空き容量 + + + + Total space + すべての容量 + + + + Access denied + アクセス拒否 + + + + + Executable + 実行可能 + + + + + Write only + 書き込みのみ + + + + + Read only + 読み込みのみ + + + + + Read-write + 読み書き + + + + Others + その他 + + + + Owner + 所有者 + + + + Device type + + + + + File system + + + + + Group + グループ + + + + + + Open + 開く + + + + + Size: %1 + サイズ: %1 + + + + Type: %1 + 種類: %1 + + + + Size: 0 + サイズ: 0 + + + + Items: %1 + + + + + + + + + + + + Open in new window + 新しいウインドウで開く + + + + + + + + + + + Open in new tab + 新しいタブで開く + + + + Open with + 他のアプリケーションで開く + + + + Compress + 圧縮 + + + + Extract + 解凍 + + + + Extract here + ここへ解凍 + + + + Cut + カット + + + + Copy + コピー + + + + Paste + ペースト + + + + + + + + + + Rename + 名前を変更 + + + + + + Remove + 削除 + + + + Create link + リンクの作成 + + + + Send to desktop + デスクトップへ送る + + + + Send to + 送る + + + + Add to bookmark + ブックマークへ追加 + + + + + + + Properties + プロパテイ + + + + New folder + 新しいフォルダー + + + + New window + 新しいウインドウ + + + + Select all + すべて選択 + + + + + Clear recent history + 最近の履歴を削除 + + + + + + Empty Trash + ゴミ箱を空にする + + + + Display as + 表示方法 + + + + Sort by + 並び方 + + + + New document + 新しいドキュメント + + + + + Time created + 作成時間 + + + + Log out and unmount + ログアウトしてアンマウント + + + + + + Source path + ソースのパス + + + + Share folder + 共有フォルダ + + + + Cancel sharing + 共有をやめる + + + + Connect to Server + + + + + Set share password + 共有パスワードを設定 + + + + Format + フォーマット + + + + Tag information + タグ情報 + + + + Open in new window as admin + 新しいウインドウを管理者として開く + + + + Select default program + 既定のプログラムを選択 + + + + Open file location + + + + + Remove bookmark + + + + + + + Delete + 削除 + + + + Office Text + + + + + Spreadsheets + スプレッドシート + + + + Plain Text + プレーンテキスト + + + + Open in terminal + ターミナルで開く + + + + Restore + 元に戻す + + + + Restore all + すべて元に戻す + + + + File Vault + + + + + Auto mount + 自動マウント + + + + Open after auto mount + マウント後に開く + + + + + Mount + マウント + + + + + Unmount + アンマウント + + + + + + Burn + + + + + Disc name: + ディスク名: + + + + + Maximum + 最大 + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + 書き込み速度: + + + + + Eject + 取り出す + + + + Safely Remove + 安全に取り出す + + + + + Name + 名前 + + + + Settings + 設定 + + + + Exit + 終了 + + + + Icon + アイコン + + + + List + リスト + + + + Extend + 延長 + + + + Set as wallpaper + 壁紙に設定 + + + + + + + Local disk + ローカルディスク + + + + + Removable disk + リムーバブルディスク + + + + + + Network shared directory + ネットワーク共有ディレクトリ + + + + + Android mobile device + Android モバイルデバイス + + + + + Apple mobile device + Apple モバイルデバイス + + + + + Camera + カメラ + + + + + DVD + DVD + + + + + Unknown device + 不明なデバイス + + + + + + %1 item + %1 項目 + + + + + + %1 items + %1 項目 + + + + Shortcut + ショートカット + + + + Create symlink + シンボリックリンクの作成 + + + + Path + パス + + + + + + Time deleted + 削除日時 + + + + Loading... + 読み込み中... + + + + File has been moved or deleted + ファイルは移動または削除されました + + + + + + You do not have permission to access this folder + このフォルダーにアクセスする権限がありません + + + + + + + Folder is empty + フォルダは空です + + + + Path + SearchFileInfo + パス + + + + Searching... + 検索中... + + + + No results + + + + + Source Path + TrashFileInfo + + + + + Document + ドキュメント + + + + Spreadsheet + スプレッドシート + + + + + Presentation + プレゼンテーション + + + + Text + テキスト + + + + 1 task in progress + 1 タスク動作中 + + + + %1 tasks in progress + %1 タスク動作中 + + + + Mode: + モード: + + + + + Replace Text + + + + + + Add Text + + + + + + Custom Text + + + + + Find: + + + + + Replace: + + + + + + Optional + + + + + Add: + 追加: + + + + Location: + 場所: + + + + File name: + ファイル名: + + + + +SN: + + + + + + + + + + + Required + 必須 + + + + + Before file name + + + + + + After file name + + + + + Find + + + + + Replace + 置き換え + + + + Add + 追加 + + + + + + Location + 場所 + + + + File name + ファイル名 + + + + Dimension + + + + + Duration + + + + + +SN + + + + + Tips: Sort by selected file order + + + + + + + Cancel + キャンセル + + + + Rename %1 Files + + + + + Multiple Files + 複数のファイル + + + + Basic info + 基本情報 + + + + Total size + 合計サイズ + + + + Number of files + ファイル数 + + + + %1 file(s), %2 folder(s) + + + + + + + Time accessed + + + + + Orange + オレンジ + + + + Red + + + + + Purple + + + + + Navy-blue + + + + + Azure + + + + + Green + + + + + Yellow + 黄色 + + + + Gray + グレー + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + ブックマーク + + + + Erase + + + + + + Copy path + + + + + + Edit address + + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + このフォルダを共有 + + + + Share name: + 共有名: + + + + Permission: + パーミッション: + + + + Read and write + 読み書き + + + + Read only + 読み込み専用 + + + + Anonymous: + 匿名: + + + + Not allow + 許可しない + + + + Allow + 許可 + + + + Shortcut + + + Item + 項目 + + + + Select to the first item + 最初の項目を選択 + + + + Shift + Home + Shift + Home + + + + Select to the last item + + + + + Shift + End + Shift + End + + + + Select leftwards + + + + + Shift + Left + Shift + Left + + + + Select rightwards + + + + + Shift + Right + Shift + Right + + + + Select to upper row + + + + + Shift + Up + Shift + Up + + + + Select to lower row + + + + + Shift + Down + Shift + Down + + + + Open + 開く + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + 親ディレクトリへ + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + 完全に削除 + + + + Shift + Delete + Shift + Delete + + + + Delete file + ファイルを削除 + + + + Delete + Delete + + + + Select all + すべて選択 + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + コピー + + + + Cut + カット + + + + Paste + ペースト + + + + Rename + 名前を変更 + + + + F2 + F2 + + + + New/Search + + + + + New window + 新しいウインドウ + + + + New folder + 新しいフォルダー + + + + + Search + 検索 + + + + New tab + 新しいタブ + + + + View + ビュー + + + + Item information + 項目の情報 + + + + Help + ヘルプ + + + + F1 + F1 + + + + Keyboard shortcuts + キーボードショートカット + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + 表示状態の切替 + + + + Hide item + 項目を隠す + + + + Input in address bar + アドレスバーに入力 + + + + Switch to icon view + アイコンビューに切替 + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + リストビューに切替 + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + その他 + + + + Close + 閉じる + + + + Alt + F4 + Alt + F4 + + + + Close current tab + 現在のタブを閉じる + + + + Back + 戻る + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + 次のタブへ切り替え + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + 前のタブへ切り替え + + + + Next file + 次のファイルへ + + + + Tab + Tab + + + + Previous file + 前のファイルへ + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + 1〜8番目の特定のタブに切り替える + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + 進む + + + + TrashPropertyDialog + + + Trash + ゴミ箱 + + + + item + + + + + items + + + + + Contains %1 %2 + + + + + UDiskListener + + + Failed to rename the label + + + + + UserShareManager + + + Kindly Reminder + + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + キャンセル + + + + Confirm + 確認 + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ko.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ko.ts new file mode 100644 index 0000000..3a17fd4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ko.ts @@ -0,0 +1,4547 @@ + + + AppController + + + New Folder + 새 폴더 + + + + Mounting device error + 마운트중인 장치 오류 + + + + The disc image was corrupted, cannot mount now, please erase the disc first + 디스크 이미지가 손상되어 지금 마운트할 수 없습니다, 먼저 디스크를 지우십시오. + + + + Mount error: unsupported image format + 마운트 오류: 지원되지 않는 이미지 형식 + + + + + The device was not safely removed + + + + + + Click "Safely Remove" and then disconnect it next time + + + + + The device was not ejected + + + + + Disk is busy, cannot eject now + 디스크가 사용 중이므로, 지금 꺼낼 수 없습니다 + + + + Authentication timed out + + + + + BluetoothTransDialog + + + Bluetooth File Transfer + + + + + File Transfer Successful + + + + + File Transfer Failed + + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + + + + + Select a Bluetooth device to receive files + + + + + Cannot find the connected Bluetooth device + + + + + Waiting to be received... + + + + + Go to Bluetooth Settings + + + + + %1/%2 Sent + + + + + Error: the Bluetooth device is disconnected + + + + + Unable to send the file more than 2 GB + + + + + Unable to send 0 KB files + + + + + File doesn't exist + + + + + Next + button + 다음 + + + + Cancel + button + 취소 + + + + Done + button + 완료 + + + + Retry + button + 재시도 + + + + OK + button + 승인 + + + + File sending request timed out + + + + + The service is busy and unable to process the request + + + + + BurnOptDialog + + + Device error + + + + + Optical device %1 doesn't exist + + + + + Advanced settings + + + + + File system: + + + + + ISO9660/Joliet (For Windows) + + + + + ISO9660/Rock Ridge (For Unix) + + + + + %1 (Compatible with Windows CD/DVD mode) + + + + + ISO9660 Only + + + + + CloseAllDialogIndicator + + + Close all + 모두 닫기 + + + + Total size: %1, %2 files + 전체 크기: %1, %2 파일 + + + + ComputerModel + + + + My Directories + 내 디렉토리 + + + + + + + + + + + + Disks + 디스크 + + + + ComputerPropertyDialog + + + Computer + 컴퓨터 + + + + Basic Info + 기본 정보 + + + + + Computer Name + 컴퓨터 이름 + + + + + Edition + + + + + + + Version + 버전 + + + + + Type + 종류 + + + + + + Processor + 프로세서 + + + + + + Memory + 메모리 + + + + + + + Bit + 비트 + + + + + Available + 사용 가능 + + + + Obtaining... + + + + + ConnectToServerDialog + + + Connect to Server + 서버에 연결 + + + + Cancel + button + 취소 + + + + Connect + button + 연결 + + + + My Favorites: + 내 즐겨 찾기: + + + + + Clear History + 기록 지우기 + + + + DFMAddressBar + + + Search or enter address + 검색 또는 주소 입력 + + + + DFMAdvanceSearchBar + + + Search: + 검색: + + + + File Type: + 파일 형식: + + + + File Size: + 파일 크기: + + + + Time Modified: + 수정된 시간: + + + + Time Accessed: + + + + + Time Created: + + + + + Reset + 재설정 + + + + All subdirectories + 모든 하위 디렉토리 + + + + Current directory + 현재 디렉토리 + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + 오늘 + + + + Yesterday + 어제 + + + + This week + 이번 주 + + + + Last week + 지난 주 + + + + This month + 이번 달 + + + + Last month + 지난 달 + + + + This year + 올해 + + + + Last year + 작년 + + + + DFMOpticalMediaWidget + + + + No files to burn + + + + + Unable to burn. Not enough free space on the target disk. + 굽기를 할 수 없습니다. 대상 디스크에 여유 공간이 부족합니다. + + + + %1 burning is not supported + + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + + + + + DFMTagCrumbController + + + Tag information + 태그 정보 + + + + DFMTagWidget + + + Tag + 태그 + + + + DFMTaskWidget + + + Do not ask again + 다시 묻지 않기 + + + + Syncing data + + + + + Please wait + + + + + + Time modified: %1 + 수정된 시간: %1 + + + + + Contains: %1 + 내용: %1 + + + + + Size: %1 + 크기: %1 + + + + Original folder + 원본 폴더 + + + + Keep both + button + 둘 다 유지 + + + + Skip + button + 건너뛰기 + + + + Replace + button + 바꾸기 + + + + Retry + button + 재시도 + + + + Original file + 원본 파일 + + + + Target folder + 대상 폴더 + + + + Target file + 대상 파일 + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + + + + + Click 'Encrypt' and input the user password. + + + + + Encrypting... + + + + + + + + Encrypt + + + + + Failed to create file vault: %1 + + + + + OK + 승인 + + + + The setup is complete + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + + + + + Generate a recovery key in case that you forgot the password + + + + + Key + + + + + QR code + + + + + Scan QR code and save the key to another device + + + + + Next + 다음 + + + + Recovery Key: + + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + + + + + Method + + + + + Manual + + + + + Password + 비밀번호 + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + + + + + Repeat password + 비밀번호 반복 + + + + Input the password again + + + + + Password hint + + + + + Optional + 선택가능 + + + + Next + 다음 + + + + + Passwords do not match + + + + + DFMVaultActiveStartView + + + File Vault + 파일 보관소 + + + + Create your secure private space + + + + + Advanced encryption technology + + + + + Convenient and easy to use + 편리하고 사용하기 쉬움 + + + + Create + + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + + + + + Failed to unlock file vault + + + + + OK + 승인 + + + + Input the 32-digit recovery key + + + + + Cancel + button + 취소 + + + + Unlock + button + 잠금해제 + + + + Wrong recovery key + + + + + DFMVaultRemoveByPasswordView + + + Password + 비밀번호 + + + + Password hint: %1 + + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + + + + + DFMVaultRemovePages + + + Delete File Vault + + + + + Once deleted, the files in it will be permanently deleted + + + + + Use Key + + + + + Cancel + button + 취소 + + + + Use Key + button + + + + + Delete + button + 삭제 + + + + + OK + button + 승인 + + + + Use Password + + + + + Wrong password + + + + + Wrong recovery key + + + + + Failed to delete file vault + + + + + Deleted successfully + + + + + Failed to delete + + + + + Removing... + + + + + DFMVaultUnlockPages + + + Unlock File Vault + + + + + Verify your password + + + + + Password hint: %1 + + + + + Failed to unlock file vault + + + + + Password + 비밀번호 + + + + Cancel + button + 취소 + + + + Unlock + button + 잠금해제 + + + + + Wrong password + + + + + OK + button + 승인 + + + + DFileCopyMoveJob + + + Permission error + 권한 오류 + + + + The action is denied + 작업이 거부되었습니다 + + + + Failed to open the file + 파일을 열지 못했습니다 + + + + Failed to read the file + 파일을 읽지 못했습니다 + + + + Failed to write the file + 파일을 쓰지 못했습니다 + + + + Failed to create the directory + 디렉토리를 만들지 못했습니다 + + + + Failed to delete the file + 파일을 삭제하지 못했습니다 + + + + Failed to move the file + 파일을 이동하지 못했습니다 + + + + Original file does not exist + 원본 파일이 없습니다 + + + + Failed, file size must be less than 4GB + 실패, 파일 크기는 4GB보다 작아야 합니다 + + + + Not enough free space on the target disk + 대상 디스크의 사용 가능한 공간이 부족합니다 + + + + File integrity was damaged + 손상된 파일입니다 + + + + The target device is read only + 대상 장치는 읽기 전용입니다 + + + + Target folder is inside the source folder + 대상 폴더가 원본 폴더 안에 있습니다 + + + + The action is not supported + + + + + You do not have permission to traverse files in it + + + + + copy + Extra name added to new file name when used for file name. + 복사 + + + + Failed to open the directory, cause: file name too long + + + + + + + Failed to open the file, cause: file name too long + + + + + + Failed to write the file, cause: + + + + + Syncing data + + + + + Please wait + + + + + Failed to create the directory, cause: %1 + 디렉토리 생성 실패, 원인: %1 + + + + + + + + + Failed to open the file, cause: %1 + 파일 열기 실패, 원인: %1 + + + + + + + Failed to open the file, cause: Permission denied + + + + + + Failed to read the file, cause: %1 + 파일 읽기 실패, 원인: %1 + + + + + + + Failed to write the file, cause: %1 + 파일 쓰기 실패, 원인: %1 + + + + + File integrity was damaged, cause: %1 + 손상된 파일, 원인: %1 + + + + Failed to open the file, cause: + + + + + Failed to read the file, cause: + + + + + Failed to delete the file, cause: %1 + 파일 삭제 실패, 원인: %1 + + + + Fail to create symlink, cause: %1 + 심볼릭링크 생성 실패, 원인: %1 + + + + DFileDialog + + + + Save + button + 저장 + + + + + Cancel + button + 취소 + + + + Confirm + button + 확정 + + + + %1 already exists, do you want to replace it? + %1이(가) 이미 있습니다. 바꾸시겠습니까? + + + + Replace + button + 바꾸기 + + + + Open + button + 열기 + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + + + + + DFileManagerWindow + + + Trash + 휴지통 + + + + Empty + 비우기 + + + + DFileSystemModel + + + + Name + 이름 + + + + + + Time modified + 수정된 시간 + + + + Size + 크기 + + + + Type + 형식 + + + + Time created + 생성된 시간 + + + + + Last access + 마지막 액세스 + + + + + + + Path + 경로 + + + + DFileView + + + Disc mount error + + + + + The disc is in use, please end the running process and remount the disc. + + + + + Mounting failed + + + + + (Reverse) + (역순) + + + + DFileViewHelper + + + Add tag "%1" + "%1" 태그 추가 + + + + DStatusBar + + + %1 item + %1 항목 + + + + %1 items + %1개의 항목 + + + + %1 item selected + %1 항목 선택됨 + + + + %1 items selected + %1개의 항목 선택됨 + + + + %1 folder selected (contains %2) + %1 폴더 선택됨 (%2 포함) + + + + %1 folders selected (contains %2) + %1개의 폴더 선택됨 (%2 포함) + + + + %1 file selected (%2) + %1 파일 선택됨 (%2) + + + + %1 files selected (%2) + %1개의 파일 선택됨 (%2) + + + + %1 folder selected + %1 폴더 선택됨 + + + + Filter + 필터 + + + + Save as: + 다른 이름으로 저장: + + + + Loading... + 불러오는 중... + + + + DTaskDialog + + + This action is not supported + 해당 작업은 지원되지 않습니다 + + + + Erasing disc %1, please wait... + %1 디스크 지우는 중, 잠시 기다리십시오... + + + + Burning disc %1, please wait... + %1 디스크 굽는 중, 잠시 기다리십시오... + + + + Writing data... + 데이터를 쓰는 중... + + + + Verifying data... + 데이터 확인중... + + + + Copying %1 + %1 복사중 + + + + + + to %2 + %2로 + + + + %1 already exists in target folder + %1 파일이 대상 폴더에 이미 존재합니다 + + + + Original path %1 Target path %2 + 원본 경로 %1 대상 경로 %2 + + + + Merge + button + 합치기 + + + + Replace + button + 바꾸기 + + + + Moving %1 + %1 이동중 + + + + Removing file vault, please try later + + + + + Restoring %1 + %1 복구중 + + + + Deleting %1 + %1 삭제중 + + + + Trashing %1 + %1 버리는 중 + + + + Calculating space, please wait + 공간을 계산하는 중, 잠시 기다리십시오 + + + + DUMountManager + + + + Authentication timed out + + + + + + + Disk is busy, cannot unmount now + 디스크가 사용 중이므로, 지금 마운트 해제할 수 없습니다 + + + + Disk is busy, cannot eject now + 디스크가 사용 중이므로, 지금 꺼낼 수 없습니다 + + + + The device is busy, cannot eject now + + + + + + + The device is busy, cannot remove now + + + + + DeepinStorage + + + + + %1 Volume + %1 볼륨 + + + + Data Disk + Data Partition + 데이터 디스크 + + + + %1 Drive + %1 드라이브 + + + + Blank %1 Disc + 빈 %1 디스크 + + + + %1 Encrypted + %1 암호화 + + + + DialogManager + + + + + + Operation failed! + 작업이 실패했습니다! + + + + Target folder is inside the source folder! + 대상 폴더가 원본 폴더 안에 있습니다! + + + + Do you want to run %1 or display its content? + %1을(를) 실행하거나 내용을 표시 하시겠습니까? + + + + It is an executable text file. + 실행 가능한 텍스트 파일입니다. + + + + It is an executable file. + 실행 파일입니다. + + + + This file is not executable, do you want to add the execute permission and run? + 이 파일은 실행 파일이 아닙니다. 실행 권한을 추가하고 실행 하시겠습니까? + + + + "%1" already exists, please use another name. + "%1"이(가) 이미 존재합니다. 다른 이름을 사용하십시오. + + + + The file name must not contain two dots (..) + + + + + Are you sure you want to erase all data on the disc? + 디스크의 모든 데이터를 지우시겠습니까? + + + + How do you want to use this disc? + 이 디스크를 어떻게 사용하시겠습니까? + + + + Disc erase failed + 디스크 지우기 실패 + + + + Burn process failed + 굽기 프로세스 실패 + + + + %1: %2 + %1: %2 + + + + Show details + 세부정보 표시 + + + + Hide details + 세부정보 숨기기 + + + + Error + 오류 + + + + Permanently delete %1? + %1을(를) 완전히 삭제하시겠습니까? + + + + Permanently delete %1 items? + %1개의 항목을 완전히 삭제하시겠습니까? + + + + Empty + 비우기 + + + + Do you want to delete %1? + + + + + Do you want to delete the selected %1 items? + + + + + Sorry, unable to locate your bookmark directory, remove it? + 북마크 디렉토리를 찾을 수 없습니다. 제거 하시겠습니까? + + + + Name: + 이름: + + + + %1 that this shortcut refers to has been changed or moved + %1 바로가기가 가리키는 파일이 변경 또는 이동되었습니다. + + + + Do you want to delete this shortcut? + 이 바로가기를 삭제하시겠습니까? + + + + Failed, file size must be less than 4GB. + 실패, 파일 크기는 4GB보다 작아야 합니다 + + + + Fail to create symlink, cause: + 심볼릭링크 생성 실패, 원인: + + + + The selected files contain system file/directory, and it cannot be deleted + 선택한 파일에 시스템 파일/디렉토리가 포함되어 있으며, 삭제할 수 없습니다 + + + + Unable to find the original file + + + + + + You do not have permission to operate file/folder! + 파일/폴더를 운용할 수 있는 권한이 없습니다! + + + + Failed to restore %1 file, the source file does not exist + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + 죄송합니다. 다음 %1 파일/폴더를 운용할 수 있는 권한이 없습니다! + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + 2. 종료 설정에서 "빠른 시작 켜기"및 "최대 절전"을 선택 취소하고 재부팅하십시오. + + + + 3. Reboot and enter %1 + 3. 재부팅하고 %1 입력 + + + + Reboot + button + 재시동 + + + + Unable to access %1 + + + + + + Sending files now, please try later + + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + + + + + Scanning the device, stop it? + + + + + Share folder can't be named after the current username + 현재 사용자 이름으로 공유 폴더의 이름을 지정할 수 없습니다 + + + + Do you want to run %1? + %1을(를) 실행하시겠습니까? + + + + Burn image + button + 이미지 굽기 + + + + Burn files + button + 파일 굽기 + + + + Are you sure you want to empty %1 item? + %1 항목을 비우시겠습니까? + + + + Are you sure you want to empty %1 items? + %1개의 항목을 비우시겠습니까? + + + + + This action cannot be undone + 이 작업은 취소할 수 없습니다 + + + + + + + + + + + + + + OK + button + 승인 + + + + + + + + + + + + + + + + Cancel + button + 취소 + + + + + + Run + button + 실행 + + + + + Run in terminal + button + 터미널에서 실행 + + + + Display + button + 표시 + + + + + + + + + + Confirm + button + 확정 + + + + Erase + button + 지우기 + + + + Data verification failed + + + + + Show details + button + 세부정보 표시 + + + + + Delete + button + 삭제 + + + + Remove + button + 제거 + + + + Disk is busy, cannot unmount now + 디스크가 사용 중이므로, 지금 마운트 해제할 수 없습니다 + + + + Force unmount + button + 강제로 마운트 해제 + + + + Unable to copy. Not enough free space on the target disk. + 복사할 수 없습니다. 대상 디스크에 여유 공간이 부족합니다. + + + + Failed to restore %1 file, the target folder is read-only + %1 파일 복원 실패, 대상 폴더가 읽기 전용입니다 + + + + Failed to restore %1 files, the target folder is read-only + %1개의 파일 복원 실패, 대상 폴더가 읽기 전용입니다 + + + + Failed to restore %1 files, the source files do not exist + + + + + Mount partition%1 to be read only + %1 파티션을 읽기 전용으로 마운트 + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + 종료 설정의 "빠른 시작 켜기(권장)"를 선택하면 Windows의 디스크를 정상적으로 읽고 쓸 수 없습니다. + + + + Please restore by the following steps to normally access Windows disk + 일반적으로 Windows 디스크에 액세스하려면 다음 단계로 복원하십시오 + + + + 1. Reboot to enter Windows + 1. Windows로 재시동 + + + + Format + button + 포맷 + + + + Stop + button + + + + + FileController + + + + + + Unable to find the original file + + + + + + + Kindly Reminder + 친절한 미리 알림 + + + + + + Please install File Roller first and then continue + 먼저 파일 롤러를 설치한 다음 계속하십시오 + + + + + Unable to create files here: %1 + + + + + Confirm + button + 확정 + + + + FileDialogStatusBar + + + File Name + 파일 이름 + + + + Format + 포맷 + + + + Save + button + 저장 + + + + Open + button + 열기 + + + + Save File + button + 파일 저장 + + + + Open File + button + 파일 열기 + + + + + + Cancel + button + 취소 + + + + FileIconItem + + + "'/\[]:|<>+=;,?* are not allowed + + + + + FileJob + + + copy + 복사 + + + + + + + Data verification successful. + 데이터 확인 성공. + + + + + + Burn process completed + 굽기 프로세스 완료 + + + + %1 s + %1 초 + + + + %1 m %2 s + %1 분 %2 초 + + + + %1 h %2 m %3 s + %1 시간 %2 분 %3 초 + + + + %1 d %2 h %3 m %4 s + %1 일 %2 시간 %3 분 %4 초 + + + + %1 is a duplicate file. + %1은(는) 중복 파일입니다. + + + + Insufficient disc space. + 디스크 공간이 부족합니다. + + + + Lost connection to drive. + 드라이브 연결이 끊어졌습니다. + + + + The CD/DVD drive is not ready. Try another disc. + CD/DVD 드라이브가 준비되지 않았습니다. 다른 디스크를 사용해 보십시오. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + CD/DVD 드라이브가 사용 중입니다. 드라이브를 사용하여 프로그램을 종료하고 드라이브를 다시 삽입하십시오. + + + + Unknown error + 알 수 없는 오류 + + + + Device disconnected + + + + + GenerateSettingTranslate + + + + + Basic + 기본 + + + + + + Open behavior + 열기 방식 + + + + + + Always open folder in new window + 항상 새 창에서 폴더 열기 + + + + + + Open file: + 파일 열기: + + + + + + Click + 클릭 + + + + + + Double click + 두 번 클릭 + + + + + + New window and tab + 새 창 및 탭 + + + + + + Open from default window: + 기본 창에서 열기: + + + + + + + + + Computer + 컴퓨터 + + + + + + + + + Home + + + + + + + + + + Desktop + 바탕화면 + + + + + + + + + Videos + 동영상 + + + + + + + + + Music + 음악 + + + + + + + + + Pictures + 사진 + + + + + + + + + Documents + 문서 + + + + + + + + + Downloads + 다운로드 + + + + + + Open in new tab: + 새 탭에서 열기: + + + + + + Current Directory + 현재 디렉토리 + + + + + + View + 보기 + + + + + + Default size: + 기본 크기: + + + + + + Extra small + 초소형 + + + + + + Small + 소형 + + + + + + Medium + 중형 + + + + + + Large + 대형 + + + + + + Extra large + 초대형 + + + + + + Default view: + 기본 보기: + + + + + + Icon + 아이콘 + + + + + + List + 목록 + + + + + + Hidden files + 숨겨진 파일 + + + + + + Show hidden files + 숨겨진 파일 표시 + + + + + + Hide file extension when rename + 이름 변경시 파일 확장자 숨기기 + + + + + + Advanced + 고급 + + + + + + Index + 색인 + + + + + + Auto index internal disk + 내부 디스크 자동 색인 + + + + + + Index external storage device after connected to computer + 컴퓨터에 연결 후 외부 저장소 색인 + + + + + + Full-Text search + + + + + + + Show item counts and sizes in the path of mounted MTP devices + + + + + + + Use the file chooser dialog of File Manager + 파일 관리자의 파일 선택기 대화 상자 사용 + + + + + + Ask for my confirmation when deleting files + + + + + + + Other + 다른 사용자 + + + + + + Hide system disk + 시스템 디스크 숨기기 + + + + + + Show file system on disk icon + + + + + + + Show hidden files in search results + 검색 결과에 숨겨진 파일 표시 + + + + + + Display recent file entry in left panel + 왼쪽 패널에 최근 파일 항목 표시 + + + + + + Preview + 미리보기 + + + + + Compress file preview + 압축 파일 미리 보기 + + + + + + Text preview + 텍스트 미리보기 + + + + + + Document preview + 문서 미리보기 + + + + + + Image preview + 이미지 미리보기 + + + + + + Video preview + 동영상 미리보기 + + + + + + Mount + 마운트 + + + + + + Auto mount + 자동 마운트 + + + + + + Open after auto mount + 자동 마운트 후 열기 + + + + + + Dialog + 대화상자 + + + + Compressed file preview + 압축된 파일 미리보기 + + + + GvfsMountManager + + + Can’t verify the identity of %1. + + + + + This happens when you log in to a computer the first time. + + + + + The identity sent by the remote computer is + + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + + + + + + + + + Mounting device error + 마운트중인 장치 오류 + + + + + Wrong username or password + + + + + + + + + Confirm + button + 확정 + + + + + Cannot find the mounted device + + + + + No key available to unlock device + 기기 잠금을 해제 할 수있는 키가 없습니다 + + + + The disk is mounted by user "%1", you cannot unmount it. + %1 사용자가 디스크를 마운트했으며, 마운트를 해제할 수 없습니다. + + + + Cannot unmount the device + 장치를 마운트 해제할 수 없습니다 + + + + Cannot eject the device "%1" + "%1" 장치를 제거할 수 없습니다 + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + 굽기를 할 수 없습니다. 대상 디스크에 여유 공간이 부족합니다. + + + + MergedDesktopController + + + + Pictures + 사진 + + + + + Music + 음악 + + + + + Applications + 응용프로그램 + + + + + Videos + 동영상 + + + + + Documents + 문서 + + + + + Others + 기타 + + + + MimeTypeDisplayManager + + + + Directory + 디렉토리 + + + + + + Application + 응용프로그램 + + + + + + Video + 동영상 + + + + + + Audio + 오디오 + + + + + + Image + 이미지 + + + + + Archive + 압축파일 + + + + + + Text + 텍스트 + + + + + Executable + 실행가능 + + + + + Backup file + 백업 파일 + + + + + Unknown + 알 수 없음 + + + + MountAskPasswordDialog + + + Cancel + button + 취소 + + + + Connect + button + 연결 + + + + Log in as + 로그인 : + + + + Anonymous + 익명 + + + + Registered user + 등록된 사용자 + + + + Username + 사용자 이름 + + + + Domain + 도메인 + + + + Password + 비밀번호 + + + + Remember password + 비밀번호 기억 + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + 취소 + + + + Unlock + button + 잠금해제 + + + + Input password to decrypt the disk + 디스크를 해독하기 위한 비밀번호 입력 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + %1을(를) 완전히 삭제하시겠습니까? + + + + This file is too big for the trash + 이 파일은 휴지통에 비해 너무 큽니다 + + + + The files are too big for the trash + 파일이 휴지통에 비해 너무 큽니다 + + + + Are you sure you want to permanently delete %1 files? + %1 파일을 완전히 삭제하시겠습니까? + + + + Cancel + button + 취소 + + + + Delete + button + 삭제 + + + + OpenWithDialog + + + Open with + 다음으로 열기 + + + + Add other programs + 다른 프로그램 추가 + + + + Set as default + 기본값으로 설정 + + + + Cancel + button + 취소 + + + + Confirm + button + 확정 + + + + Recommended Applications + 추천 응용프로그램 + + + + Other Applications + 다른 프로그램 + + + + PathManager + + + Home + + + + + Desktop + 바탕화면 + + + + Videos + 동영상 + + + + Music + 음악 + + + + Pictures + 사진 + + + + Documents + 문서 + + + + Downloads + 다운로드 + + + + + Trash + 휴지통 + + + + + + System Disk + 시스템 디스크 + + + + Computers in LAN + 내부 네트워크 + + + + My Shares + 내 공유 + + + + Computer + 컴퓨터 + + + + Recent + 최근 사용한 파일 + + + + File Vault + 파일 보관소 + + + + PropertyDialog + + + Basic info + 기본 정보 + + + + Open with + 다음으로 열기 + + + + Sharing + 공유중 + + + + Permissions + 권한 + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + 이 폴더 숨기기 + + + + Hide this file + 이 파일 숨기기 + + + + Allow to execute as program + 프로그램으로 실행하도록 허용 + + + + QObject + + + + + + Size + 크기 + + + + + + Contains + 포함 + + + + + + Type + 형식 + + + + + + + + Time modified + 수정된 시간 + + + + Free space + 여유 공간 + + + + Total space + 총 공간 + + + + + Time locked + + + + + Access denied + 접근 거부 + + + + + Executable + 실행가능 + + + + + Write only + 쓰기 전용 + + + + + Read only + 읽기 전용 + + + + + Read-write + 읽기-쓰기 + + + + Others + 다른 사용자 + + + + Owner + 소유자 + + + + Device type + 장치 유형 + + + + File system + 파일 시스템 + + + + Group + 그룹 + + + + + Open + 열기 + + + + Lock + + + + + Auto lock + + + + + Never + 없음 + + + + 5 minutes + + + + + 10 minutes + + + + + 20 minutes + + + + + Delete File Vault + + + + + Unlock + 잠금해제 + + + + Unlock by key + + + + + Open + button + 열기 + + + + + Size: %1 + 크기: %1 + + + + Type: %1 + 형식: %1 + + + + Size: 0 + 크기: 0 + + + + Items: %1 + 항목: %1 + + + + + + + + + + Open in new window + 새 창에서 열기 + + + + + + + + + + Open in new tab + 새 탭에서 열기 + + + + Open with + 다음으로 열기 + + + + + Compress + 압축하기 + + + + Extract + 압축풀기 + + + + Extract here + 여기에 압축풀기 + + + + Cut + 잘라내기 + + + + Copy + 복사 + + + + Paste + 붙여넣기 + + + + + + + + Rename + 이름 변경 + + + + + + Remove + 제거 + + + + Create link + 링크 생성 + + + + Send to desktop + 바탕화면으로 전송 + + + + Send to + 전송 + + + + Bluetooth + + + + + Add to bookmark + 즐겨찾기에 추가 + + + + + + + Properties + 속성 + + + + New folder + 새 폴더 + + + + New window + 새 창 + + + + Select all + 모두 선택 + + + + + Clear recent history + 최근 기록 지우기 + + + + + + Empty Trash + 휴지통 비우기 + + + + Display as + 다음으로 표시 + + + + Sort by + 정렬 기준: + + + + New document + 새 문서 + + + + + Time created + 생성된 시간 + + + + Log out and unmount + 로그아웃 및 마운트 해제 + + + + + + Source path + 원본 경로 + + + + Share folder + 공유 폴더 + + + + Cancel sharing + 공유 취소 + + + + Connect to Server + 서버에 연결 + + + + Set share password + 공유 비밀번호 설정 + + + + Format + 포맷 + + + + Tag information + 태그 정보 + + + + Open as administrator + + + + + Select default program + 기본 프로그램 선택 + + + + Open file location + 파일 위치 열기 + + + + Remove bookmark + 즐겨찾기 제거 + + + + + + Delete + 삭제 + + + + Office Text + Office 텍스트 + + + + Spreadsheets + 스프레드시트 + + + + Plain Text + 일반 텍스트 + + + + Open in terminal + 터미널에서 열기 + + + + Restore + 복원 + + + + Restore all + 전부 복원 + + + + + + + + File Vault + 파일 보관소 + + + + Add to disc + 디스크에 추가 + + + + Auto mount + 자동 마운트 + + + + Open after auto mount + 자동 마운트 후 열기 + + + + + Mount + 마운트 + + + + + Unmount + 마운트 해제 + + + + It does not support burning %1 discs + + + + + Burn + 굽기 + + + + Disc name: + 디스크 이름: + + + + + Maximum + 최대 + + + + Allow files to be added later + 파일을 나중에 추가할 수 있도록 허용 + + + + Verify data + 데이터 확인 + + + + Write speed: + 쓰기 속도: + + + + + + + Cancel + button + 취소 + + + + Burn + button + 굽기 + + + + + Eject + 꺼내기 + + + + Safely Remove + 안전하게 제거 + + + + + Name + 이름 + + + + Settings + 설정 + + + + Exit + 종료 + + + + Icon + 아이콘 + + + + List + 목록 + + + + Extend + 확장 + + + + Set as wallpaper + 배경화면으로 설정 + + + + + + + Local disk + 로컬 디스크 + + + + + Removable disk + 제거 가능한 디스크 + + + + + + Network shared directory + 네트워크 공유 디렉토리 + + + + + Android mobile device + 안드로이드 모바일 장치 + + + + + Apple mobile device + 애플 모바일 장치 + + + + + Camera + 카메라 + + + + + DVD + DVD + + + + + Unknown device + 알 수 없는 장치 + + + + + + %1 item + %1 항목 + + + + + + %1 items + %1개의 항목 + + + + Shortcut + 바로가기 + + + + Create symlink + 심볼릭링크 생성 + + + + Path + 경로 + + + + + + Time deleted + 삭제된 시간 + + + + Loading... + 불러오는 중... + + + + File has been moved or deleted + 파일이 이동되었거나 삭제됨 + + + + You do not have permission to traverse files in it + + + + + + + You do not have permission to access this folder + 이 폴더에 접근할 권한이 없습니다 + + + + + + + + Folder is empty + 폴더가 비어있습니다 + + + + Searching... + 검색중... + + + + No results + 결과 없음 + + + + Source Path + TrashFileInfo + 원본 경로 + + + + Document + 문서 + + + + Spreadsheet + 스프레드시트 + + + + + Presentation + 프레젠테이션 + + + + Text + 텍스트 + + + + 1 task in progress + 1개의 작업이 진행중 + + + + %1 tasks in progress + %1개의 작업이 진행중 + + + + Mode: + 모드: + + + + + Replace Text + 텍스트 바꾸기 + + + + + Add Text + 텍스트 추가 + + + + + Custom Text + 사용자 지정 텍스트 + + + + Find: + 찾기: + + + + Replace: + 바꾸기: + + + + + Optional + 선택가능 + + + + Add: + 추가: + + + + Location: + 위치: + + + + File name: + 파일 이름: + + + + Start at: + + + + + + Rename + button + 이름 변경 + + + + + + + + + + + Required + 필수 항목 + + + + + Before file name + 파일 이름 앞에 + + + + + After file name + 파일 이름 뒤에 + + + + Find + 찾기 + + + + Replace + 바꾸기 + + + + Add + 추가 + + + + Start at + + + + + + + Location + 위치 + + + + File name + 파일 이름 + + + + Dimension + 크기 + + + + Duration + 기간 + + + + Tips: Sort by selected file order + 팁: 선택한 파일 순서로 정렬 + + + + Rename %1 Files + %1개의 파일 이름 변경 + + + + Multiple Files + 다수의 파일 + + + + Basic info + 기본 정보 + + + + Total size + 총 크기 + + + + Number of files + 파일의 갯수 + + + + %1 file(s), %2 folder(s) + 파일(%1개), 폴더(%2개) + + + + + + Time accessed + 액세스한 시간 + + + + Orange + 주황색 + + + + Red + 빨강색 + + + + Purple + 보라색 + + + + Navy-blue + 감청색 + + + + Azure + 하늘색 + + + + Green + 초록색 + + + + Yellow + 노란색 + + + + Gray + 회색 + + + + Input tag info, such as work, family. A comma is used between two tags. + 직장, 가족과 같은 입력 태그 정보입니다. 쉼표는 두 태그 사이에 사용됩니다. + + + + Bookmarks + 즐겨찾기 + + + + Erase + 지우기 + + + + Copy path + 복사 경로 + + + + Edit address + 주소 수정 + + + + Free Space %1 + 여유 공간 %1 + + + + Files are being processed + 파일 처리 중 + + + + Unknown + 알 수 없음 + + + + My Vault + + + + + + + Disks + 디스크 + + + + + Failed to create file info + + + + + Failed to create file handler + + + + + + + Execution error + + + + + + + + "'/\[]:|<>+=;,?* are not allowed + + + + + Failed to open the file, cause: %1 + 파일 열기 실패, 원인: %1 + + + + Original file does not exist + 원본 파일이 없습니다 + + + + Do you want to delete %1? + + + + + Confirm + button + 확정 + + + + ShareInfoFrame + + + Share this folder + 이 폴더 공유 + + + + Share name: + 공유 이름: + + + + Permission: + 권한: + + + + Read and write + 읽기 및 쓰기 + + + + Read only + 읽기 전용 + + + + Anonymous: + 익명: + + + + Not allow + 허용되지 않음 + + + + Allow + 허용 + + + + The share name must not be two dots (..) or one dot (.) + + + + + The share name is used by another user. + + + + + OK + button + 승인 + + + + Cancel + button + 취소 + + + + Replace + button + 바꾸기 + + + + The share name already exists. Do you want to replace the shared folder? + + + + + Shortcut + + + Item + 항목 + + + + Select to the first item + 첫번째 항목을 선택 + + + + Shift + Home + Shift + Home + + + + Select to the last item + 마지막 항목을 선택 + + + + Shift + End + Shift + End + + + + Select leftwards + 왼쪽으로 선택 + + + + Shift + Left + Shift + Left + + + + Select rightwards + 오른쪽으로 선택 + + + + Shift + Right + Shift + Right + + + + Select to upper row + 위쪽 행으로 선택 + + + + Shift + Up + Shift + Up + + + + Select to lower row + 아래쪽 행으로 선택 + + + + Shift + Down + Shift + Down + + + + Open + 열기 + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + 상위 디렉터리로 + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + 완전히 삭제 + + + + Shift + Delete + Shift + Delete + + + + Delete file + 파일 삭제 + + + + Delete + 삭제 + + + + Select all + 모두 선택 + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + 복사 + + + + Cut + 잘라내기 + + + + Paste + 붙여넣기 + + + + Rename + 이름 변경 + + + + F2 + F2 + + + + New/Search + 새로 만들기/검색 + + + + New window + 새 창 + + + + New folder + 새 폴더 + + + + + Search + 검색 + + + + New tab + 새 탭 + + + + View + 보기 + + + + Item information + 항목 정보 + + + + Help + 도움말 + + + + F1 + F1 + + + + Keyboard shortcuts + 키보드 단축키 + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + 표시 상태 전환 + + + + Hide item + 항목 숨기기 + + + + Input in address bar + 주소창에 입력 + + + + Switch to icon view + 아이콘 보기로 전환 + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + 목록 보기로 전환 + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + 기타 + + + + Close + 닫기 + + + + Alt + F4 + Alt + F4 + + + + Close current tab + 현재 탭 닫기 + + + + Back + 뒤로 + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + 다음 탭으로 전환 + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + 이전 탭으로 전환 + + + + Next file + 다음 파일 + + + + Tab + + + + + Previous file + 이전 파일 + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + 1에서 8 사이의 지정된 번호로 탭 전환 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + 정방향 + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + + + + + TrashPropertyDialog + + + Trash + 휴지통 + + + + item + 항목 + + + + items + 항목 + + + + Contains %1 %2 + %1 %2 포함 + + + + UDiskListener + + + Failed to rename the label + 레이블 이름 변경 실패 + + + + UnmountWorker + + + + + The device was not safely unmounted + + + + + The device was not safely removed + + + + + UserShareManager + + + Kindly Reminder + 친절한 미리 알림 + + + + Please firstly install samba to continue + 계속하려면 먼저 삼바를 설치하십시오 + + + + To protect the files, you cannot share this folder. + 파일을 보호하기 위해 이 폴더를 공유할 수 없습니다. + + + + The share name must not contain %<>*?|/\+=;:," + + + + + Sharing failed + + + + + The computer name is too long + + + + + You do not have permission to operate file/folder! + 파일/폴더를 운용할 수 있는 권한이 없습니다! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + 공유 폴더를 보호할 비밀번호 입력 + + + + Cancel + button + 취소 + + + + Confirm + button + 확정 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_lt.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_lt.ts new file mode 100644 index 0000000..e0502a2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_lt.ts @@ -0,0 +1,4690 @@ + + + AppController + + + New Folder + Naujas aplankas + + + + Mounting device error + Įrenginio prijungimo klaida + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + Prijungimo klaida: nepalaikomas atvaizdžio formatas + + + + + The device was not safely removed + + + + + + Click "Safely Remove" and then disconnect it next time + + + + + The device was not ejected + + + + + Disk is busy, cannot eject now + Diskas yra užimtas, dabar negalima išstumti + + + + Authentication timed out + + + + + BluetoothTransDialog + + + Bluetooth File Transfer + + + + + File Transfer Successful + + + + + File Transfer Failed + + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + + + + + Select a Bluetooth device to receive files + + + + + Cannot find the connected Bluetooth device + + + + + Waiting to be received... + + + + + Go to Bluetooth Settings + + + + + %1/%2 Sent + + + + + Error: the Bluetooth device is disconnected + Klaida: Bluetooth įrenginys yra atsijungęs + + + + Unable to send the file more than 2 GB + + + + + Unable to send 0 KB files + + + + + File doesn't exist + Failo nėra + + + + Next + button + Kitas + + + + Cancel + button + Atsisakyti + + + + Done + button + Atlikta + + + + Retry + button + Bandyti dar kartą + + + + OK + button + Gerai + + + Next + Kitas + + + Cancel + Atsisakyti + + + Done + Atlikta + + + Retry + Bandyti dar kartą + + + OK + Gerai + + + + File sending request timed out + + + + + The service is busy and unable to process the request + + + + + BurnOptDialog + + + Device error + Įrenginio klaida + + + + Optical device %1 doesn't exist + Optinio įrenginio %1 nėra + + + + Advanced settings + Išplėstiniai nustatymai + + + + File system: + Failų sistema: + + + + ISO9660/Joliet (For Windows) + + + + + ISO9660/Rock Ridge (For Unix) + + + + + ISO9660 Only + Tik ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Užverti visus + + + + Total size: %1, %2 files + Bendras dydis: %1, %2 failų + + + + ComputerModel + + + + My Directories + Mano katalogai + + + + + + + + + + + + Disks + Diskai + + + + ComputerPropertyDialog + + + Computer + Kompiuteris + + + + Basic Info + Pagrindinė informacija + + + + Computer Name + Kompiuterio vardas + + + + Edition + + + + + + Version + Versija + + + + Type + Tipas + + + + Processor + Procesorius + + + + + Memory + Atmintis + + + + Bit + Bitų + + + + Available + + + + + ConnectToServerDialog + + + Connect to Server + Prisijungti prie serverio + + + Cancel + Atsisakyti + + + Connect + Prisijungti + + + + Cancel + button + Atsisakyti + + + + Connect + button + Prisijungti + + + + My Favorites: + Mano mėgstami: + + + + + Clear History + Išvalyti istoriją + + + + DFMAddressBar + + + Search or enter address + Ieškokite arba įrašykite adresą + + + + DFMAdvanceSearchBar + + + Search: + Ieškoti: + + + + File Type: + Failo tipas: + + + + File Size: + Failo dydis: + + + + Time Modified: + Modifikavimo laikas: + + + + Time Accessed: + + + + + Time Created: + + + + + Reset + Atstatyti + + + + All subdirectories + Visuose pakatalogiuose + + + + Current directory + Dabartiniame kataloge + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Šiandien + + + + Yesterday + Vakar + + + + This week + Šią savaitę + + + + Last week + Praeitą savaitę + + + + This month + Šį mėnesį + + + + Last month + Praeitą mėnesį + + + + This year + Šiais metais + + + + Last year + Praeitais metais + + + + DFMOpticalMediaWidget + + + + No files to burn + + + + + Unable to burn. Not enough free space on the target disk. + + + + + DFMSideBarBookmarkItemHandler + + + Gotcha + button + + + + + DFMTagCrumbController + + + Tag information + Žymės informacija + + + + DFMTagWidget + + + Tag + Žymė + + + + DFMTaskWidget + + + Keep both + Palikti abu + + + + Skip + Praleisti + + + + Replace + Pakeisti + + + + Do not ask again + Daugiau nebeklausti + + + + Syncing data + + + + + Please wait + Palaukite + + + + Retry + Bandyti dar kartą + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + + Original folder + Pradinis aplankas + + + + Original file + Pradinis failas + + + + Target folder + Paskirties aplankas + + + + Target file + Paskirties failas + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + + + + + Click 'Encrypt' and input the user password. + + + + + Encrypting... + Šifruojama... + + + + + + Encrypt + + + + + Failed to create file vault: %1 + + + + + OK + Gerai + + + + The setup is complete + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + + + + + Generate a recovery key in case that you forgot the password + + + + + Key + + + + + QR code + QR kodas + + + + Scan QR code and save the key to another device + + + + + Next + Kitas + + + + Recovery Key: + Atkūrimo raktas: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + + + + + Method + + + + + Manual + + + + + Password + Slaptažodis + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + + + + + Repeat password + Pakartokite slaptažodį + + + + Input the password again + + + + + Password hint + + + + + Optional + Nebūtina + + + + Next + Kitas + + + + + Passwords do not match + Slaptažodžiai nesutampa + + + + DFMVaultActiveStartView + + + File Vault + Failų slėptuvė + + + + Create your secure private space + + + + + Advanced encryption technology + + + + + Convenient and easy to use + Patogi ir lengva naudoti + + + + Create + + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + + + + Cancel + Atsisakyti + + + Unlock + Atrakinti + + + + Failed to unlock file vault + + + + + OK + Gerai + + + + Input the 32-digit recovery key + + + + + Cancel + button + Atsisakyti + + + + Unlock + button + Atrakinti + + + + Wrong recovery key + + + + + DFMVaultRemoveByPasswordView + + + Password + Slaptažodis + + + + Password hint: %1 + + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + + + + + DFMVaultRemovePages + + + Delete File Vault + + + + + Once deleted, the files in it will be permanently deleted + + + + Cancel + Atsisakyti + + + + Use Key + Naudoti raktą + + + Delete + Ištrinti + + + OK + Gerai + + + + Cancel + button + Atsisakyti + + + + Use Key + button + Naudoti raktą + + + + Delete + button + Ištrinti + + + + + OK + button + Gerai + + + + Use Password + Naudoti slaptažodį + + + + Wrong password + Neteisingas slaptažodis + + + + Wrong recovery key + + + + + Failed to delete file vault + + + + + Deleted successfully + + + + + Failed to delete + Nepavyko ištrinti failo + + + + Removing... + Šalinama... + + + + DFMVaultUnlockPages + + + Unlock File Vault + + + + + Verify your password + + + + Cancel + Atsisakyti + + + Unlock + Atrakinti + + + + Password hint: %1 + + + + + Failed to unlock file vault + + + + OK + Gerai + + + + Password + Slaptažodis + + + + Cancel + button + Atsisakyti + + + + Unlock + button + Atrakinti + + + + + Wrong password + Neteisingas slaptažodis + + + + OK + button + Gerai + + + + DFileCopyMoveJob + + + Permission error + Leidimų klaida + + + + The action is denied + Veiksmas atmestas + + + + Failed to open the file + Nepavyko atverti failo + + + + Failed to read the file + Nepavyko perskaityti failą + + + + Failed to write the file + Nepavyko įrašyti failo + + + + Failed to create the directory + Nepavyko sukurti katalogą + + + + Failed to delete the file + Nepavyko ištrinti failo + + + + Failed to move the file + Nepavyko perkelti failo + + + + Original file does not exist + Pradinio failo nėra + + + + Failed, file size must be less than 4GB + Nepavyko, failo dydis privalo būti mažesnis nei 4GB + + + + Not enough free space on the target disk + Paskirties diske nepakanka laisvos vietos + + + + File integrity was damaged + Failo vientisumas buvo pažeistas + + + + The target device is read only + Paskirties įrenginys yra skirtas tik skaitymui + + + + Target folder is inside the source folder + Paskirties aplankas yra šaltinio aplanko viduje + + + + The action is not supported + + + + + You do not have permission to traverse files in it + + + + + copy + Extra name added to new file name when used for file name. + kopija + + + + Failed to open the directory, cause: file name too long + + + + + + + Failed to open the file, cause: file name too long + + + + + + Failed to write the file, cause: + + + + + Syncing data + + + + + Please wait + Palaukite + + + + Failed to create the directory, cause: %1 + Nepavyko sukurti katalogą, priežastis: %1 + + + + + + + + + Failed to open the file, cause: %1 + Nepavyko atverti failą, priežastis: %1 + + + + + + + Failed to open the file, cause: Permission denied + + + + + + Failed to read the file, cause: %1 + Nepavyko perskaityti failą, priežastis: %1 + + + + + + + Failed to write the file, cause: %1 + Nepavyko rašyti failą, priežastis: %1 + + + + + File integrity was damaged, cause: %1 + Failo vientisumas buvo pažeistas, priežastis: %1 + + + + Failed to open the file, cause: + + + + + Failed to read the file, cause: + + + + + Failed to delete the file, cause: %1 + Nepavyko ištrinti failą, priežastis: %1 + + + + Fail to create symlink, cause: %1 + Nepavyko sukurti simbolinę nuorodą, priežastis: %1 + + + + DFileDialog + + + + Save + Įrašyti + + + + + Cancel + button + Atsisakyti + + + + Confirm + button + Patvirtinti + + + + %1 already exists, do you want to replace it? + %1 jau yra, ar norite jį pakeisti? + + + + Replace + button + Pakeisti + + + Cancel + Atsisakyti + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + + + + Confirm + Patvirtinti + + + Replace + Pakeisti + + + + Open + Atverti + + + + DFileManagerWindow + + + Trash + Šiukšlinė + + + + Empty + Išvalyti + + + + DFileSystemModel + + + + Name + Pavadinimas + + + + + + Time modified + Modifikavimo laikas + + + + Size + Dydis + + + + Type + Tipas + + + + Time created + Sukūrimo laikas + + + + + Last access + Paskiausia prieiga + + + + + + + Path + Kelias + + + + DFileView + + + Disc mount error + + + + + The disc is in use, please end the running process and remount the disc. + + + + + Mounting failed + + + + + (Reverse) + (Atvirkščiai) + + + + DFileViewHelper + + + Add tag "%1" + Pridėti žymę "%1" + + + + DStatusBar + + + %1 item + %1 elementas + + + + %1 items + %1 elementai + + + + %1 item selected + Pažymėtas %1 elementas + + + + %1 items selected + Pažymėti %1 elementai + + + + %1 folder selected (contains %2) + Pažymėtas %1 aplankas (kuriame yra %2) + + + + %1 folders selected (contains %2) + Pažymėta %1 aplankų (kuriuose yra %2) + + + + %1 file selected (%2) + Pažymėtas %1 failas (%2) + + + + %1 files selected (%2) + Pažymėta %1 failų (%2) + + + + %1 folder selected + Pažymėtas %1 aplankas + + + + Filter + Filtras + + + + Save as: + Įrašyti kaip: + + + + Loading... + Įkeliama... + + + + DTaskDialog + + + This action is not supported + Šis veiksmas yra nepalaikomas + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + Rašomi duomenys... + + + + Verifying data... + + + + + Copying %1 + Kopijuojama %1 + + + + + + to %2 + į %2 + + + + %1 already exists in target folder + %1 paskirties aplanke jau yra + + + + Original path %1 Target path %2 + + + + + Moving %1 + + + + + Removing file vault, please try later + + + + + Restoring %1 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + Apskaičiuojama vieta, palaukite + + + + Merge + Sulieti + + + + Replace + Pakeisti + + + + DUMountManager + + + + Authentication timed out + + + + + + Disk is busy, cannot unmount now + Diskas yra užimtas, dabar negalima atjungti + + + + Disk is busy, cannot eject now + Diskas yra užimtas, dabar negalima išstumti + + + + The device is busy, cannot eject now + + + + + + + The device is busy, cannot remove now + + + + + DeepinStorage + + + + + %1 Volume + %1 tomas + + + + Data Disk + Data Partition + Duomenų diskas + + + + %1 Drive + %1 diskas + + + + Blank %1 Disc + Tuščias %1 diskas + + + + %1 Encrypted + Šifruotas %1 + + + + DialogManager + + + + + + Operation failed! + Operacija nepavyko! + + + + Target folder is inside the source folder! + Paskirties aplankas yra šaltinio aplanko viduje! + + + OK + Gerai + + + + Do you want to run %1 or display its content? + Jūs norite vykdyti %1 ar rodyti jo turinį? + + + + It is an executable text file. + Tai yra vykdomasis tekstinis failas. + + + Cancel + Atsisakyti + + + Run + Vykdyti + + + Run in terminal + Vykdyti terminale + + + Display + Rodyti + + + + It is an executable file. + Tai yra vykdomasis failas. + + + + This file is not executable, do you want to add the execute permission and run? + Šis failas nėra vykdomasis, ar norite pridėti vykdymo leidimą ir paleisti šį failą? + + + + "%1" already exists, please use another name. + "%1" jau yra, prašome naudoti kitą pavadinimą. + + + Confirm + Patvirtinti + + + + The file name must not contain two dots (..) + + + + + Are you sure you want to erase all data on the disc? + Ar tikrai norite ištrinti visus diske esančius duomenis? + + + Erase + Ištrinti + + + + How do you want to use this disc? + Kaip norite naudoti diską? + + + Burn image + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + %1: %2 + + + + Show details + Rodyti išsamesnę informaciją + + + + Hide details + Slėpti išsamesnę informaciją + + + + Error + Klaida + + + + Permanently delete %1? + Ištrinti %1 visiems laikams? + + + + Permanently delete %1 items? + Ištrinti %1 elementus visiems laikams? + + + Delete + Ištrinti + + + + Empty + Išvalyti + + + + Do you want to delete %1? + Ar norite ištrinti %1? + + + + Do you want to delete the selected %1 items? + + + + + Sorry, unable to locate your bookmark directory, remove it? + Atleiskite, nepavyko nustatyti jūsų žymelės katalogo vietą, pašalinti žymelę? + + + Remove + Šalinti + + + + Name: + Pavadinimas: + + + Force unmount + Priverstinai atjungti + + + + %1 that this shortcut refers to has been changed or moved + %1, į kurį nurodo šis šaukinys, buvo pakeistas arba perkeltas + + + + Do you want to delete this shortcut? + Ar norite ištrinti šį šaukinį? + + + + Failed, file size must be less than 4GB. + Nepavyko, failo dydis privalo būti mažesnis nei 4GB. + + + + Fail to create symlink, cause: + Nepavyko sukurti simbolinės nuorodos, kadangi: + + + + The selected files contain system file/directory, and it cannot be deleted + Pažymėtuose failuose yra sisteminiai failai/katalogai ir jie negali būti ištrinti + + + + Unable to find the original file + + + + + + You do not have permission to operate file/folder! + Jūs neturite leidimo dirbti su failu/aplanku! + + + + Failed to restore %1 file, the source file does not exist + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Atleiskite, jūs neturite leidimo dirbti su šiuo %1 failu(-ais)/aplanku(-ais)! + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + 2. Išjungimo nustatymuose nuimkite žymėjimą nuo "Įjungti sparčiąją paleistį" (angl. Turn on fast startup) ir "Užmigdyti" (angl. Hibernate) ir paleiskite kompiuterį iš naujo + + + + 3. Reboot and enter %1 + + + + + Reboot + button + Paleisti iš naujo + + + + Unable to access %1 + + + + + + Sending files now, please try later + + + + Format + Formatuoti + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + + + + Stop + + + + + Scanning the device, stop it? + + + + + Share folder can't be named after the current username + Bendrinamas aplankas negali būti pavadintas esamo naudotojo vardu + + + + Do you want to run %1? + Ar norite vykdyti %1? + + + + Are you sure you want to empty %1 item? + Ar tikrai norite išvalyti %1 elementą? + + + + Are you sure you want to empty %1 items? + Ar tikrai norite išvalyti %1 elementus(-ų)? + + + + + This action cannot be undone + Šio veiksmo negalima bus atšaukti + + + + + + + + + + + + + + OK + button + Gerai + + + + + + + + + + + + + + + + Cancel + button + Atsisakyti + + + + + + Run + button + Vykdyti + + + + + Run in terminal + button + Vykdyti terminale + + + + Display + button + Rodyti + + + + + + + + + Confirm + button + Patvirtinti + + + + Erase + button + Ištrinti + + + + Burn image, + + + + + Burn files, + + + + + Data verification failed + + + + + Show details + button + Rodyti išsamesnę informaciją + + + + + Delete + button + Ištrinti + + + + Remove + button + Šalinti + + + + Disk is busy, cannot unmount now + Diskas yra užimtas, dabar negalima atjungti + + + + Force unmount + button + Priverstinai atjungti + + + + Unable to copy. Not enough free space on the target disk. + Nepavyko nukopijuoti. Paskirties diske nepakanka laisvos vietos. + + + + Failed to restore %1 file, the target folder is read-only + Nepavyko atkurti %1 failo, paskirties aplankas yra tik skaitymui + + + + Failed to restore %1 files, the target folder is read-only + Nepavyko atkurti %1 failų, paskirties aplankas yra tik skaitymui + + + + Failed to restore %1 files, the source files do not exist + + + + + Mount partition%1 to be read only + Prijungti skaidinį %1 kaip skirtą tik skaitymui + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + Jeigu išjungimo nustatymuose yra pažymėta "Įjungti sparčiąją paleistį (rekomenduojama)" (angl. Turn on fast startup (recommended)), tuomet Diskai Windows sistemoje negalės normaliai skaityti ir rašyti į diską + + + + Please restore by the following steps to normally access Windows disk + Norėdami atkurti normalią prieigą prie Windows disko, sekite šiais žingsniais + + + + 1. Reboot to enter Windows + 1. Paleiskite kompiuterį iš naujo, kad įeitumėte į Windows + + + + Format + button + Formatuoti + + + + Stop + button + + + + Reboot + Paleisti iš naujo + + + + FileController + + + + + + Unable to find the original file + + + + + + + Kindly Reminder + Draugiškas priminimas + + + + + + Please install File Roller first and then continue + Iš pradžių, įsidiekite Failų presą, o tuomet tęskite + + + + + Unable to create files here: %1 + + + + + Confirm + button + Patvirtinti + + + Confirm + Patvirtinti + + + + FileDialogStatusBar + + + File Name + Failo pavadinimas + + + + Format + Formatuoti + + + Cancel + Atsisakyti + + + + + + Cancel + button + Atsisakyti + + + + Save + Įrašyti + + + + Open + Atverti + + + + Save File + Įrašyti failą + + + + Open File + Atverti failą + + + + FileIconItem + + + "'/\[]:|<>+=;,?* are not allowed + + + + + FileJob + + + copy + kopija + + + + + + + Data verification successful. + Duomenys sėkmingai patikrinti. + + + + + Burn process completed + + + + + %1 s + %1 sek. + + + + %1 m %2 s + %1 min. %2 sek. + + + + %1 h %2 m %3 s + %1 val. %2 min. %3 sek. + + + + %1 d %2 h %3 m %4 s + %1 d. %2 val. %3 min. %4 sek. + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + Trūksta vietos diske. + + + + Lost connection to drive. + Prarastas ryšys su disku. + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + Nežinoma klaida + + + + Device disconnected + + + + + GenerateSettingTranslate + + + + + Basic + Pagrindiniai + + + + + + Open behavior + Atvėrimo elgsena + + + + + + Always open folder in new window + Visada atverti aplanką naujame lange + + + + + + Open file: + Atverti failą: + + + + + + Click + Spustelėjimu + + + + + + Double click + Dvikarčiu spustelėjimu + + + + + + New window and tab + Naujas langas ir kortelė + + + + + + Open from default window: + Atverti numatytajame lange: + + + + + + + + + Computer + Kompiuteris + + + + + + + + + Home + Namai + + + + + + + + + Desktop + Darbalaukis + + + + + + + + + Videos + Vaizdo įrašai + + + + + + + + + Music + Muzika + + + + + + + + + Pictures + Paveikslai + + + + + + + + + Documents + Dokumentai + + + + + + + + + Downloads + Atsiuntimai + + + + + + Open in new tab: + Atverti naujoje kortelėje: + + + + + + Current Directory + Esamas katalogas + + + + + + View + Rodinys + + + + + + Default size: + Numatytasis dydis: + + + + + + Extra small + Ypač mažas + + + + + + Small + Mažas + + + + + + Medium + Vidutinis + + + + + + Large + Didelis + + + + + + Extra large + Ypač didelis + + + + + + Default view: + Numatytasis rodinys: + + + + + + Icon + Piktogramos + + + + + + List + Sąrašas + + + + + + Hidden files + Paslėpti failai + + + + + + Show hidden files + Rodyti paslėptus failus + + + + + + Hide file extension when rename + Pervadinant, slėpti failo prievardį + + + + + + Advanced + Išplėstiniai + + + + + + Index + Indeksas + + + + + + Auto index internal disk + Automatiškai indeksuoti vidinį diską + + + + + + Index external storage device after connected to computer + Prijungus prie kompiuterio išorinius kaupiklio įrenginius, juos indeksuoti + + + + + + Full-Text search + + + + + + + Use the file chooser dialog of File Manager + Naudoti failų tvarkytuvės failų parinkiklio dialogą + + + + + + Ask for my confirmation when deleting files + + + + + + + Other + Kita + + + + + + Hide system disk + Slėpti sistemos diską + + + + + + Show file system on disk icon + + + + + + + Show hidden files in search results + Rodyti paslėptus failus paieškos rezultatuose + + + + + + Display recent file entry in left panel + Rodyti paskiausiai naudotų failų įrašą kairiajame skydelyje + + + + + + Preview + Peržiūra + + + + + Compress file preview + Suglaudinto failo peržiūra + + + + + + Text preview + Tekstų peržiūra + + + + + + Document preview + Dokumentų peržiūra + + + + + + Image preview + Paveikslų peržiūra + + + + + + Video preview + Vaizdo įrašų peržiūra + + + + + + Mount + Prijungti + + + + + + Auto mount + Automatiškai prijungti + + + + + + Open after auto mount + Automatiškai prijungus, atverti + + + + + + Dialog + Dialogas + + + + Compressed file preview + Suglaudinto failo peržiūra + + + + GvfsMountManager + + + Can’t verify the identity of %1. + + + + + This happens when you log in to a computer the first time. + + + + + The identity sent by the remote computer is + + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + + + + + + + + + Mounting device error + Įrenginio prijungimo klaida + + + + + Wrong username or password + + + + + + + + + Confirm + button + Patvirtinti + + + + + Cannot find the mounted device + + + + + No key available to unlock device + + + + + The disk is mounted by user "%1", you cannot unmount it. + Diską prijungė naudotojas "%1", jūs negalite jo atjungti. + + + Confirm + Patvirtinti + + + + Cannot unmount the device + Nepavyksta atjungti įrenginio + + + + Cannot eject the device "%1" + Nepavyksta išimti įrenginio "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + + + + + MergedDesktopController + + + + Pictures + Paveikslai + + + + + Music + Muzika + + + + + Applications + Programos + + + + + Videos + Vaizdo įrašai + + + + + Documents + Dokumentai + + + + + Others + Kita + + + + MimeTypeDisplayManager + + + + Directory + Katalogas + + + + + + Application + Programa + + + + + + Video + Vaizdo įrašas + + + + + + Audio + Garso įrašas + + + + + + Image + Paveikslas + + + + + Archive + Archyvas + + + + + + Text + Tekstas + + + + + Executable + Vykdomasis + + + + + Backup file + Atsarginės kopijos failas + + + + + Unknown + Nežinoma + + + + MountAskPasswordDialog + + Cancel + Atsisakyti + + + Connect + Prisijungti + + + + Cancel + button + Atsisakyti + + + + Connect + button + Prisijungti + + + + Log in as + Prisijungti kaip + + + + Anonymous + Anonimiškai + + + + Registered user + Registruotas naudotojas + + + + Username + Naudotojo vardas + + + + Domain + Sritis + + + + Password + Slaptažodis + + + + Remember password + Prisiminti slaptažodį + + + + MountSecretDiskAskPasswordDialog + + Cancel + Atsisakyti + + + Unlock + Atrakinti + + + + Cancel + button + Atsisakyti + + + + Unlock + button + Atrakinti + + + + Input password to decrypt the disk + Norėdami iššifruoti diską, įveskite slaptažodį + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Ar tikrai norite negrįžtamai ištrinti %1? + + + + This file is too big for the trash + Šis failas yra šiukšlinei per didelis + + + + The files are too big for the trash + Šie failai yra šiukšlinei per dideli + + + + Are you sure you want to permanently delete %1 files? + Ar tikrai norite negrįžtamai ištrinti %1 failus(-ų)? + + + + Cancel + button + Atsisakyti + + + + Delete + button + Ištrinti + + + Cancel + Atsisakyti + + + Delete + Ištrinti + + + + OpenWithDialog + + + Open with + Atverti naudojant + + + + Add other programs + Pridėti kitas programas + + + + Set as default + Nustatyti kaip numatytąją + + + + Cancel + button + Atsisakyti + + + + Confirm + button + Patvirtinti + + + Cancel + Atsisakyti + + + Confirm + Patvirtinti + + + + Recommended Applications + Rekomenduojamos programos + + + + Other Applications + Kitos programos + + + + PathManager + + + Home + Namai + + + + Desktop + Darbalaukis + + + + Videos + Vaizdo įrašai + + + + Music + Muzika + + + + Pictures + Paveikslai + + + + Documents + Dokumentai + + + + Downloads + Atsiuntimai + + + + + Trash + Šiukšlinė + + + + + + System Disk + Sistemos diskas + + + + Computers in LAN + Kompiuteriai vietiniame (LAN) tinkle + + + + My Shares + Mano viešiniai + + + + Computer + Kompiuteris + + + + Recent + Paskiausiai naudoti + + + + File Vault + Failų slėptuvė + + + + PropertyDialog + + + Basic info + Pagrindinė informacija + + + + Open with + Atverti naudojant + + + + Sharing + Bendrinimas + + + + Permissions + Leidimai + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Slėpti šį aplanką + + + + Hide this file + Slėpti šį failą + + + + Allow to execute as program + Leisti vykdyti kaip programą + + + + QObject + + + + + Size + Dydis + + + + + + Contains + Turi + + + + + + Type + Tipas + + + + + + + + Time modified + Modifikavimo laikas + + + + Free space + Laisva vieta + + + + Total space + Bendra vieta + + + + + Time locked + + + + + Access denied + Prieiga atmesta + + + + + Executable + Vykdomasis + + + + + Write only + Tik rašyti + + + + + Read only + Tik skaityti + + + + + Read-write + Skaityti, rašyti + + + + Others + Kita + + + + Owner + Savininkas + + + + Device type + Įrenginio tipas + + + + File system + Failų sistema + + + + Group + Grupė + + + + + + Open + Atverti + + + + Lock + + + + + Auto lock + + + + + Never + Niekada + + + + 5 minutes + + + + + 10 minutes + + + + + 20 minutes + + + + + Delete File Vault + + + + + Unlock + Atrakinti + + + + Unlock by key + + + + + + Size: %1 + Dydis: %1 + + + + Type: %1 + Tipas: %1 + + + + Size: 0 + Dydis: 0 + + + + Items: %1 + Elementai: %1 + + + + + + + + + + Open in new window + Atverti naujame lange + + + + + + + + + + Open in new tab + Atverti naujoje kortelėje + + + + Open with + Atverti naudojant + + + + + Compress + Glaudinti + + + + Extract + Išskleisti + + + + Extract here + Išskleisti čia + + + + Cut + Iškirpti + + + + Copy + Kopijuoti + + + + Paste + Įdėti + + + + + + + + Rename + Pervadinti + + + + + + Remove + Šalinti + + + + Create link + Sukurti nuorodą + + + + Send to desktop + Siųsti į darbalaukį + + + + Send to + Siųsti į + + + + Bluetooth + + + + + Add to bookmark + Pridėti į žymeles + + + + + + + Properties + Savybės + + + + New folder + Naujas aplankas + + + + New window + Naujas langas + + + + Select all + Žymėti visus + + + + + Clear recent history + Išvalyti paskiausią istoriją + + + + + + Empty Trash + Išvalyti šiukšlinę + + + + Display as + Rodyti kaip + + + + Sort by + Rikiuoti pagal + + + + New document + Naujas dokumentas + + + + + Time created + Sukūrimo laikas + + + + Log out and unmount + Atsijungti ir atjungti + + + + + + Source path + Šaltinio kelias + + + + Share folder + Bendrinti aplanką + + + + Cancel sharing + Nustoti bendrinti + + + + Connect to Server + Prisijungti prie serverio + + + + Set share password + Nustatyti bendrinimo slaptažodį + + + + Format + Formatuoti + + + + Tag information + Žymės informacija + + + + Open as administrator + + + + + Select default program + Pasirinkti numatytąją programą + + + + Open file location + Atverti failo vietą + + + + Remove bookmark + Šalinti žymelę + + + + + + Delete + Ištrinti + + + + Office Text + Raštinės tekstas + + + + Spreadsheets + Skaičiuoklės + + + + Plain Text + Grynasis tekstas + + + + Open in terminal + Atverti terminale + + + + Restore + Atkurti + + + + Restore all + Atkurti visus + + + + + + + + File Vault + Failų slėptuvė + + + + Add to disc + Pridėti į diską + + + + Auto mount + Automatiškai prijungti + + + + Open after auto mount + Automatiškai prijungus, atverti + + + + + Mount + Prijungti + + + + + Unmount + Atjungti + + + + Burn + + + + + Disc name: + Disko pavadinimas: + + + + + Maximum + Didžiausias + + + + Allow files to be added later + Leisti pridėti failus vėliau + + + + Verify data + Patikrinti duomenis + + + + Write speed: + Rašymo greitis: + + + + + + Cancel + button + Atsisakyti + + + + Burn + button + + + + + + Eject + Išstumti + + + + Safely Remove + Saugiai pašalinti + + + + + Name + Pavadinimas + + + + Settings + Nustatymai + + + + Exit + Išeiti + + + + Icon + Piktogramos + + + + List + Sąrašas + + + + Extend + Išplėsti + + + + Set as wallpaper + Nustatyti kaip darbalaukio foną + + + + + + + Local disk + Vietinis diskas + + + + + Removable disk + Keičiamasis diskas + + + + + + Network shared directory + Bendrinamas tinklo katalogas + + + + + Android mobile device + Android mobilusis įrenginys + + + + + Apple mobile device + Apple mobilusis įrenginys + + + + + Camera + Fotoaparatas + + + + + DVD + DVD + + + + + Unknown device + Nežinomas įrenginys + + + + + + %1 item + %1 elementas + + + + + + %1 items + %1 elementai + + + + Shortcut + Šaukinys + + + + Create symlink + Sukurti simbolinę nuorodą + + + + Path + Kelias + + + + + + Time deleted + Ištrynimo laikas + + + + Loading... + Įkeliama... + + + + File has been moved or deleted + Failas buvo perkeltas arba ištrintas + + + + You do not have permission to traverse files in it + + + + + + + You do not have permission to access this folder + Jūs neturite leidimų gauti prieigą prie šio aplanko + + + + + + + + Folder is empty + Aplankas tuščias + + + + Searching... + Ieškoma... + + + + No results + Rezultatų nėra + + + + Source Path + TrashFileInfo + Šaltinio kelias + + + + Document + Dokumentas + + + + Spreadsheet + Skaičiuoklė + + + + + Presentation + Pateiktis + + + + Text + Tekstas + + + + 1 task in progress + 1 užduotis eigoje + + + + %1 tasks in progress + %1 užduotys eigoje + + + + Mode: + Veiksena: + + + + + Replace Text + Pakeisti tekstą + + + + + Add Text + Pridėti tekstą + + + + + Custom Text + Tinkintas tekstas + + + + Find: + Rasti: + + + + Replace: + Pakeisti: + + + + + Optional + Nebūtina + + + + Add: + Pridėti: + + + + Location: + Vieta: + + + + File name: + Failo pavadinimas: + + + + Start at: + + + + + + Rename + button + Pervadinti + + + + + + + + + + + Required + Būtina + + + + + Before file name + Prieš failo pavadinimą + + + + + After file name + Po failo pavadinimo + + + + Find + Rasti + + + + Replace + Pakeisti + + + + Add + Pridėti + + + + Start at + + + + + + + Location + Vieta + + + + File name + Failo pavadinimas + + + + Dimension + + + + + Duration + Trukmė + + + + Tips: Sort by selected file order + Patarimai: Rikiuoti pagal pasirinktą failų tvarką + + + Cancel + Atsisakyti + + + + Rename %1 Files + Pervadinti %1 failų(-us) + + + + Multiple Files + Keli failai + + + + Basic info + Pagrindinė informacija + + + + Total size + Bendras dydis + + + + Number of files + Failų skaičius + + + + %1 file(s), %2 folder(s) + %1 failų(-ai), %2 aplankų(-ai) + + + + + + Time accessed + Prieigos laikas + + + + Orange + Oranžinė + + + + Red + Raudona + + + + Purple + Purpurinė + + + + Navy-blue + Tamsiai mėlyna + + + + Azure + Žydra + + + + Green + Žalia + + + + Yellow + Geltona + + + + Gray + Pilka + + + + Input tag info, such as work, family. A comma is used between two tags. + Įveskite žymės informaciją, tokią kaip darbas, šeima. Kablelis yra naudojamas atskirti dvi žymes. + + + + Bookmarks + Žymelės + + + + Erase + + + + + Copy path + Kopijuoti kelią + + + + Edit address + Taisyti adresą + + + + It does not support burning UDF discs + + + + + Free Space %1 + Laisva vieta %1 + + + + Files are being processed + Failai yra apdorojami + + + + Unknown + Nežinoma + + + + My Vault + + + + + + + Disks + Diskai + + + + + Failed to create file info + + + + + Failed to create file handler + + + + + + + Execution error + + + + + + + + "'/\[]:|<>+=;,?* are not allowed + + + + + Failed to open the file, cause: %1 + Nepavyko atverti failą, priežastis: %1 + + + + Original file does not exist + Pradinio failo nėra + + + + Do you want to delete %1? + Ar norite ištrinti %1? + + + + Confirm + Patvirtinti + + + + ShareInfoFrame + + + Share this folder + Bendrinti šį aplanką + + + + Share name: + Viešinio pavadinimas: + + + + Permission: + Leidimai: + + + + Read and write + Skaityti ir rašyti + + + + Read only + Tik skaityti + + + + Anonymous: + Anonimas: + + + + Not allow + Neleisti + + + + Allow + Leisti + + + + The share name must not be two dots (..) or one dot (.) + + + + + The share name is used by another user. + + + + + OK + button + Gerai + + + + Cancel + button + Atsisakyti + + + + Replace + button + Pakeisti + + + OK + Gerai + + + + The share name already exists. Do you want to replace the shared folder? + + + + Cancel + Atsisakyti + + + Replace + Pakeisti + + + + Shortcut + + + Item + Elementas + + + + Select to the first item + Pažymėti iki pirmo elemento + + + + Shift + Home + Lyg2 + Prad + + + + Select to the last item + Pažymėti iki paskutinio elemento + + + + Shift + End + Lyg2 + Pab + + + + Select leftwards + Pažymėti kairėn + + + + Shift + Left + Lyg2 + Kairėn + + + + Select rightwards + Pažymėti dešinėn + + + + Shift + Right + Lyg2 + Dešinėn + + + + Select to upper row + Pažymėti iki viršutinės eilutės + + + + Shift + Up + Lyg2 + Aukštyn + + + + Select to lower row + Pažymėti iki apatinės eilutės + + + + Shift + Down + Lyg2 + Žemyn + + + + Open + Atverti + + + + Ctrl + Down + Vald + Žemyn + + + + To parent directory + Į tėvinį katalogą + + + + Ctrl + Up + Vald + Aukštyn + + + + Permanently delete + Ištrinti visiems laikams + + + + Shift + Delete + Lyg2 + Šal + + + + Delete file + Ištrinti failą + + + + Delete + Ištrinti + + + + Select all + Žymėti viską + + + + Ctrl + A + Vald + A + + + + Ctrl + C + Vald + C + + + + Ctrl + X + Vald + X + + + + Ctrl + V + Vald + V + + + + Ctrl + N + Vald + N + + + + Ctrl + Shift + N + Vald + Lyg2 + N + + + + Ctrl + F + Vald + F + + + + Ctrl + T + Vald + T + + + + Ctrl + I + Vald + I + + + + Ctrl + H + Vald + H + + + + Ctrl + L + Vald + L + + + + Ctrl + W + Vald + W + + + + Copy + Kopijuoti + + + + Cut + Iškirpti + + + + Paste + Įdėti + + + + Rename + Pervadinti + + + + F2 + F2 + + + + New/Search + Nauja/ Paieška + + + + New window + Naujas langas + + + + New folder + Naujas aplankas + + + + + Search + Paieška + + + + New tab + Nauja kortelė + + + + View + Rodyti + + + + Item information + Elemento informacija + + + + Help + Žinynas + + + + F1 + F1 + + + + Keyboard shortcuts + Klaviatūros trumpiniai + + + + Ctrl + Shift + / + Vald + Lyg2 + / + + + + Switch display status + Perjungti rodymo būseną + + + + Hide item + Slėpti elementą + + + + Input in address bar + Įvesti į adreso juostą + + + + Switch to icon view + Perjungti į piktogramų rodinį + + + + Ctrl + 1 + Vald + 1 + + + + Switch to list view + Perjungti į sąrašo rodinį + + + + Ctrl + 2 + Vald + 2 + + + + Others + Kiti + + + + Close + Užverti + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Užverti esamą kortelę + + + + Back + Atgal + + + + Alt + Left + Alt + Kairėn + + + + Alt + Right + Alt + Dešinėn + + + + Switch to next tab + Perjungti į kitą kortelę + + + + Ctrl + Tab + Vald + Tab + + + + Ctrl + Shift + Tab + Vald + Lyg2 + Tab + + + + Switch to previous tab + Perjungti į ankstesnę kortelę + + + + Next file + Kitas failas + + + + Tab + Tab + + + + Previous file + Ankstesnis failas + + + + Shift + Tab + Lyg2 + Tab + + + + Switch tab by specified number between 1 to 8 + Perjungti kortelę pagal nurodytą skaičių tarp 1 ir 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Pirmyn + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + + + + + TrashPropertyDialog + + + Trash + Šiukšlinė + + + + item + elementas + + + + items + elementų + + + + Contains %1 %2 + Turi %1 %2 + + + + UDiskListener + + + Failed to rename the label + Nepavyko pervadinti etiketę + + + + UnmountWorker + + + + The device was not safely unmounted + + + + + The device was not safely removed + + + + + UserShareManager + + + Kindly Reminder + Draugiškas priminimas + + + + Please firstly install samba to continue + Norėdami tęsti, iš pradžių įdiekite samba + + + + To protect the files, you cannot share this folder. + + + + + The share name must not contain %<>*?|/\+=;:," + + + + + Sharing failed + + + + + The computer name is too long + + + + + You do not have permission to operate file/folder! + Jūs neturite leidimo dirbti su failu/aplanku! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Norėdami apsaugoti bendrinamus aplankus, įveskite slaptažodį + + + + Cancel + button + Atsisakyti + + + + Confirm + button + Patvirtinti + + + Cancel + Atsisakyti + + + Confirm + Patvirtinti + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ml.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ml.ts new file mode 100644 index 0000000..4107fc4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ml.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + എല്ലാം അടയ്ക്കുക + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + + + + + Basic Info + + + + + Computer Name + + + + + Version + + + + + Type + തരം + + + + Processor + + + + + Memory + + + + + Disk + ഡിസ്ക് + + + + Bit + + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + തിരയുക അല്ലെങ്കിൽ വിലാസം നൽകുക + + + + DFMAdvanceSearchBar + + + Search: + + + + + File Type: + + + + + File Size: + + + + + Time Modified: + + + + + Reset + + + + + All subdirectories + + + + + Current directory + + + + + 0 ~ 100 KB + + + + + 100 KB ~ 1 MB + + + + + 1 MB ~ 10 MB + + + + + 10 MB ~ 100 MB + + + + + 100 MB ~ 1 GB + + + + + > 1 GB + + + + + Today + + + + + Yesterday + + + + + This week + + + + + Last week + + + + + This month + + + + + Last month + + + + + This year + + + + + Last year + + + + + DFMTagCrumbController + + + Tag information + + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + + + + + The action is denied + + + + + Failed to open the file + + + + + Failed to read the file + + + + + Failed to write the file + + + + + Failed to create the directory + + + + + Failed to delete the file + + + + + Failed to move the file + + + + + Original file does not exist + + + + + Failed, file size must be less than 4GB + + + + + Not enough free space on the target disk + + + + + File integrity was damaged + + + + + The target device is read only + + + + + Target folder is inside the source folder + + + + + copy + Extra name added to new file name when used for file name. + + + + + Failed to create the directory, cause: %1 + + + + + + Failed to open the file, cause: %1 + + + + + Failed to read the file, cause: %1 + + + + + Failed to write the file, cause: %1 + + + + + File integrity was damaged, cause: %1 + + + + + Failed to delete the file, cause: %1 + + + + + Fail to create symlink, cause: %1 + + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + + + + + Cancel + റദ്ദാക്കുക + + + + Replace + മാറ്റിവയ്ക്കുക + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + പേര് + + + + + + Time modified + പുതുക്കിയ സമയം + + + + Size + വലിപ്പം + + + + Type + തരം + + + + Time created + നിർമ്മിച്ച സമയം + + + + + Last access + + + + + Path + + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + + + + + DFileViewHelper + + + Add tag "%1" + + + + + DStatusBar + + + %1 item + %1 വസ്തു + + + + %1 items + %1 വസ്തുക്കൾ + + + + %1 item selected + + + + + %1 items selected + %1 വസ്തുക്കൾ തിരഞ്ഞെടുത്തു + + + + %1 folder selected (contains %2) + + + + + %1 folders selected (contains %2) + + + + + %1 file selected (%2) + + + + + %1 files selected (%2) + + + + + %1 folder selected + + + + + Filter + + + + + Save as: + + + + + Loading... + ലഭ്യമാക്കുന്നു... + + + + DTaskDialog + + + This action is not supported + + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + + + + + Data Disk + Data Partition + + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + + + + + Target folder is inside the source folder! + + + + + + + + + + + + + + OK + + + + + Do you want to run %1 or display its content? + %1 പ്രവർത്തിപ്പിക്കണോ അതോ അതിന്റെ ഉള്ളടക്കം പ്രദർശിപ്പിക്കണോ? + + + + It is an executable text file. + അത് പ്രവർത്തിപ്പിക്കാൻ സാധിക്കുന്ന ഒരു ടെക്സ്റ്റ് ഫയൽ ആണു് + + + + + + + + + + + + + + Cancel + റദ്ദാക്കുക + + + + + + Run + പ്രവർത്തിപ്പിക്കുക + + + + + Run in terminal + ടെർമിനലിൽ പ്രവർത്തിപ്പിക്കുക + + + + Display + പ്രദർശിപ്പിക്കുക + + + + It is an executable file. + + + + + This file is not executable, do you want to add the execute permission and run? + + + + + "%1" already exists, please use another name. + "%1" മുമ്പേതന്നെ ഉപയോഗത്തിലുണ്ട്, ദയവായി മറ്റൊരു പേരു് തിരഞ്ഞെടുക്കുക + + + + + + + + Confirm + ഉറപ്പാക്കുക + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + %1 സ്ഥിരമായി നീക്കം ചെയ്യണോ? + + + + Permanently delete %1 items? + %1 വസ്തുക്കൾ സ്ഥിരമായി നീക്കം ചെയ്യണോ? + + + + Delete + നീക്കം ചെയ്യുക + + + + Empty + കാലിയാക്കുക + + + + Sorry, unable to locate your bookmark directory, remove it? + + + + + Remove + നീക്കം ചെയ്യുക + + + + Name: + + + + + Force unmount + + + + + %1 that this shortcut refers to has been changed or moved + + + + + Do you want to delete this shortcut? + + + + + Failed, file size must be less than 4GB. + + + + + Fail to create symlink, cause: + + + + + The selected files contain system file/directory, and it cannot be deleted + + + + + + You do not have permission to operate file/folder! + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + + + + + View + + + + + Do you want to run %1? + + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + + + + + Please restore by the following steps to normally access Windows disk + + + + + 1. Reboot to enter Windows + + + + 3. Reboot and enter deepin + + + + + Reboot + + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + + + + + Format + + + + + Cancel + റദ്ദാക്കുക + + + + Save + + + + + Open + തുറക്കുക + + + + Save File + + + + + Open File + + + + + FileJob + + + copy + + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + %1 സെ + + + + %1 m %2 s + %1 മി %2 സെ + + + + %1 h %2 m %3 s + %1 മ %2 മി %3 സെ + + + + %1 d %2 h %3 m %4 s + %1 ദി %2 മ %3 മി %4 സെ + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + + + + + + + Open behavior + + + + + + + Always open folder in new window + + + + + + + Open file: + + + + + + + Click + + + + + + + Double click + + + + + + + New window and tab + + + + + + + Open from default window: + + + + + + + + + + Computer + + + + + + + + + + Home + + + + + + + + + + Desktop + ഡെസ്ക്ടോപ്പ് + + + + + + + + + Videos + ചലച്ചിത്രങ്ങൾ + + + + + + + + + Music + സംഗീതം + + + + + + + + + Pictures + ചിത്രങ്ങൾ + + + + + + + + + Documents + രേഖകൾ + + + + + + + + + Downloads + ഡൗൺലോഡുകൾ + + + + + + Open in new tab: + + + + + + + Current Directory + + + + + + + View + + + + + + + Default size: + + + + + + + Extra small + + + + + + + Small + + + + + + + Medium + + + + + + + Large + + + + + + + Extra large + + + + + + + Default view: + + + + + + + Icon + + + + + + + List + + + + + + + Hidden files + + + + + + + Show hidden files + + + + + + + Hide file extension when rename + + + + + + + Advanced + + + + + + + Index + + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + മറ്റുള്ളവ + + + + + + Hide system disk + + + + + + + Show hidden files in search results + + + + + + + Display recent file entry in left panel + + + + + + + Preview + + + + + + Compress file preview + + + + + + + Text preview + + + + + + + Document preview + + + + + + + Image preview + + + + + + + Video preview + + + + + + + Mount + മൗണ്ട് ചെയ്യുക + + + + + + Auto mount + + + + + + + Open after auto mount + + + + + + + Dialog + + + + Use the file chooser dialog of Deepin File Manager + + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + + + + + + + + + Confirm + ഉറപ്പാക്കുക + + + + + Cannot find the mounting device + + + + + Cannot unmount the device + + + + + Cannot eject the device "%1" + + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + + + + + + + Application + + + + + + + Video + + + + + + + Audio + + + + + + + Image + + + + + + Archive + + + + + + + Text + ടെക്സ്റ്റ് + + + + + Executable + + + + + + Backup file + + + + + + Unknown + + + + + MountAskPasswordDialog + + + Cancel + റദ്ദാക്കുക + + + + Connect + ബന്ധിപ്പിക്കുക + + + + Log in as + മറ്റൊരാളായി പ്രവേശിക്കുക + + + + Anonymous + + + + + Registered user + രജിസ്റ്റർ ചെയ്ത ഉപയോക്താവ് + + + + Username + ഉപയോക്തൃനാമം + + + + Domain + ഡൊമൈൻ + + + + Password + രഹസ്യവാക്ക് + + + + Remember password + രഹസ്യവാക്ക് ഓർമ്മിക്കുക + + + + MountSecretDiskAskPasswordDialog + + + Cancel + റദ്ദാക്കുക + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + ഒഴിവാക്കുക + + + Keep both + രണ്ടും നിലനിർത്തുക + + + Replace + മാറ്റിവയ്ക്കുക + + + Do not ask again + ഇനി ചോദിക്കരുത് + + + merge + + + + Copying %1 + + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + + + + Moving %1 + + + + Move to %2 + + + + Restoring %1 + + + + Restore to %2 + + + + Deleting %1 + + + + Trashing %1 + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + Retry + + + + Time modified:%1 + + + + Original folder + + + + Original file + + + + Target folder + + + + Target file + + + + Contains:%1 + + + + Size:%1 + + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + റദ്ദാക്കുക + + + + Delete + നീക്കം ചെയ്യുക + + + + OpenWithDialog + + + Open with + മറ്റൊന്നുപയോഗിച്ച് തുറക്കുക + + + + Add other programs + + + + + Set as default + + + + + Cancel + റദ്ദാക്കുക + + + + Confirm + + + + + Recommended Applications + + + + + Other Applications + + + + + PathManager + + + Home + + + + + Desktop + ഡെസ്ക്ടോപ്പ് + + + + Videos + ചലച്ചിത്രങ്ങൾ + + + + Music + സംഗീതം + + + + Pictures + ചിത്രങ്ങൾ + + + + Documents + രേഖകൾ + + + + Downloads + ഡൗൺലോഡുകൾ + + + + + Trash + ചവറ്റുകൊട്ട + + + + + System Disk + + + + + Computers in LAN + ലാനിൽ ഉള്ള കമ്പ്യൂട്ടറുകൾ + + + + My Shares + + + + + Computer + + + + + Recent + + + + + PropertyDialog + + + Basic info + അടിസ്ഥാന വിവരം + + + + Open with + മറ്റൊന്നുപയോഗിച്ച് തുറക്കുക + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + പ്രയോഗമായി പ്രവർത്തിപ്പിക്കാൻ അനുവദിക്കുക + + + + QObject + + + + + Size + വലിപ്പം + + + + + + Contains + ഉൾക്കൊള്ളുന്നത് + + + + + + Type + തരം + + + + + + + Time modified + പുതുക്കിയ സമയം + + + + Free space + + + + + Total space + മൊത്തം സ്ഥലം + + + + Access denied + + + + + + Executable + + + + + + Write only + + + + + + Read only + + + + + + Read-write + + + + + Others + മറ്റുള്ളവ + + + + Owner + ഉടമസ്ഥൻ + + + + Device type + + + + + File system + + + + + Group + കൂട്ടം + + + + + + Open + തുറക്കുക + + + + + Size: %1 + + + + + Type: %1 + + + + + Size: 0 + + + + + Items: %1 + + + + + + + + + + + + Open in new window + + + + + + + + + + + + Open in new tab + + + + + Open with + മറ്റൊന്നുപയോഗിച്ച് തുറക്കുക + + + + Compress + + + + + Extract + + + + + Extract here + + + + + Cut + മുറിക്കുക + + + + Copy + പകർത്തുക + + + + Paste + ഒട്ടിയ്ക്കുക + + + + + + + + + + Rename + പേര് മാറ്റുക + + + + + + Remove + നീക്കം ചെയ്യുക + + + + Create link + കണ്ണി ഉണ്ടാക്കുക + + + + Send to desktop + ഡെസ്ക്ടോപ്പിലേക്ക് അയയ്ക്കുക + + + + Send to + + + + + Add to bookmark + അടയാളക്കുറിപ്പുകളിലേക്ക് ചേർക്കുക + + + + + + + Properties + സവിശേഷതകൾ + + + + New folder + പുതിയ ഫോൾഡർ + + + + New window + + + + + Select all + എല്ലാം തിരഞ്ഞെടുക്കുക + + + + + Clear recent history + + + + + + + Empty Trash + ചവറ്റുകൊട്ട കാലിയാക്കുക + + + + Display as + + + + + Sort by + + + + + New document + + + + + + Time created + നിർമ്മിച്ച സമയം + + + + Log out and unmount + + + + + + + Source path + + + + + Share folder + + + + + Cancel sharing + + + + + Connect to Server + + + + + Set share password + + + + + Format + + + + + Tag information + + + + + Open in new window as admin + + + + + Select default program + + + + + Open file location + + + + + Remove bookmark + + + + + + + Delete + നീക്കം ചെയ്യുക + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + ടെർമിനലിൽ തുറക്കുക + + + + Restore + പുനഃസ്ഥാപിക്കുക + + + + Restore all + എല്ലാം പുനഃസ്ഥാപിക്കുക + + + + File Vault + + + + + Auto mount + + + + + Open after auto mount + + + + + + Mount + മൗണ്ട് ചെയ്യുക + + + + + Unmount + + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + + + + + Safely Remove + + + + + + Name + പേര് + + + + Settings + ക്രമീകരണങ്ങൾ + + + + Exit + + + + + Icon + + + + + List + + + + + Extend + + + + + Set as wallpaper + + + + + + + + Local disk + + + + + + Removable disk + + + + + + + Network shared directory + + + + + + Android mobile device + ആൻഡ്രോയിഡ് മൊബൈൽ ഉപകരണം + + + + + Apple mobile device + ആപ്പിൾ മൊബൈൽ ഉപകരണം + + + + + Camera + കാമറ + + + + + DVD + + + + + + Unknown device + അപരിചിതമായ ഉപകരണം + + + + + + %1 item + %1 വസ്തു + + + + + + %1 items + %1 വസ്തുക്കൾ + + + + Shortcut + + + + + Create symlink + + + + + Path + + + + + + + Time deleted + നീക്കം ചെയ്ത സമയം + + + + Loading... + ലഭ്യമാക്കുന്നു... + + + + File has been moved or deleted + ഫയൽ സ്ഥാനം മാറ്റുകയോ നീക്കം ചെയ്യുകയോ ചെയ്തു + + + + + + You do not have permission to access this folder + + + + + + + + Folder is empty + ഫോൾഡർ കാലിയാണ് + + + + Path + SearchFileInfo + + + + + Searching... + തിരയുന്നു... + + + + No results + + + + + Source Path + TrashFileInfo + + + + + Document + + + + + Spreadsheet + + + + + + Presentation + + + + + Text + ടെക്സ്റ്റ് + + + + 1 task in progress + %1 പ്രവൃത്തി നിലവിൽ നടന്നുകൊണ്ടിരിക്കുന്നുണ്ട് + + + + %1 tasks in progress + %1 പ്രവൃത്തികൾ നിലവിൽ നടന്നുകൊണ്ടിരിക്കുന്നുണ്ട് + + + + Mode: + + + + + + Replace Text + + + + + + Add Text + + + + + + Custom Text + + + + + Find: + + + + + Replace: + + + + + + Optional + + + + + Add: + + + + + Location: + + + + + File name: + + + + + +SN: + + + + + + + + + + + Required + + + + + + Before file name + + + + + + After file name + + + + + Find + + + + + Replace + മാറ്റിവയ്ക്കുക + + + + Add + + + + + + + Location + + + + + File name + + + + + Dimension + + + + + Duration + + + + + +SN + + + + + Tips: Sort by selected file order + + + + + + + Cancel + റദ്ദാക്കുക + + + + Rename %1 Files + + + + + Multiple Files + + + + + Basic info + അടിസ്ഥാന വിവരം + + + + Total size + + + + + Number of files + + + + + %1 file(s), %2 folder(s) + + + + + + + Time accessed + + + + + Orange + + + + + Red + + + + + Purple + + + + + Navy-blue + + + + + Azure + + + + + Green + + + + + Yellow + + + + + Gray + + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + + + + + Erase + + + + + + Copy path + + + + + + Edit address + + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + + + + + Share name: + + + + + Permission: + + + + + Read and write + + + + + Read only + + + + + Anonymous: + + + + + Not allow + + + + + Allow + + + + + Shortcut + + + Item + + + + + Select to the first item + + + + + Shift + Home + + + + + Select to the last item + + + + + Shift + End + + + + + Select leftwards + + + + + Shift + Left + + + + + Select rightwards + + + + + Shift + Right + + + + + Select to upper row + + + + + Shift + Up + + + + + Select to lower row + + + + + Shift + Down + + + + + Open + തുറക്കുക + + + + Ctrl + Down + + + + + To parent directory + + + + + Ctrl + Up + + + + + Permanently delete + സ്ഥിരമായി നീക്കം ചെയ്യുക + + + + Shift + Delete + + + + + Delete file + + + + + Delete + നീക്കം ചെയ്യുക + + + + Select all + എല്ലാം തിരഞ്ഞെടുക്കുക + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + പകർത്തുക + + + + Cut + മുറിക്കുക + + + + Paste + ഒട്ടിയ്ക്കുക + + + + Rename + പേര് മാറ്റുക + + + + F2 + + + + + New/Search + + + + + New window + + + + + New folder + പുതിയ ഫോൾഡർ + + + + + Search + + + + + New tab + + + + + View + + + + + Item information + + + + + Help + സഹായം + + + + F1 + + + + + Keyboard shortcuts + + + + + Ctrl + Shift + / + + + + + Switch display status + + + + + Hide item + + + + + Input in address bar + + + + + Switch to icon view + + + + + Ctrl + 1 + + + + + Switch to list view + + + + + Ctrl + 2 + + + + + Others + മറ്റുള്ളവ + + + + Close + + + + + Alt + F4 + + + + + Close current tab + + + + + Back + + + + + Alt + Left + + + + + Alt + Right + + + + + Switch to next tab + + + + + Ctrl + Tab + + + + + Ctrl + Shift + Tab + + + + + Switch to previous tab + + + + + Next file + + + + + Tab + + + + + Previous file + + + + + Shift + Tab + + + + + Switch tab by specified number between 1 to 8 + + + + + Alt + [1-8] + + + + + Forward + + + + + TrashPropertyDialog + + + Trash + ചവറ്റുകൊട്ട + + + + item + + + + + items + + + + + Contains %1 %2 + + + + + UDiskListener + + + Failed to rename the label + + + + + UserShareManager + + + Kindly Reminder + + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + റദ്ദാക്കുക + + + + Confirm + ഉറപ്പാക്കുക + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_mn.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_mn.ts new file mode 100644 index 0000000..b9ca6d1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_mn.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + Шинэ хавтас + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + Бүгдийг хаах + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + Компьютер + + + + Basic Info + Ерөнхий мэдээлэл + + + + Computer Name + Компьютерийн нэр + + + + Version + Хувилбар + + + + Type + Төрөл + + + + Processor + Процессор + + + + Memory + Санах ой + + + + Disk + Диск + + + + Bit + Бит + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + Хайх эсвэл хаяг оруулах + + + + DFMAdvanceSearchBar + + + Search: + Хайх: + + + + File Type: + Файлын төрөл: + + + + File Size: + Файлын хэмжээ: + + + + Time Modified: + Өөрчлөгдсөн цаг: + + + + Reset + Дахин тохируулах + + + + All subdirectories + Бүх дэд хавтаснууд + + + + Current directory + Одоогийн байршил + + + + 0 ~ 100 KB + 0 ~ 100 КБ + + + + 100 KB ~ 1 MB + 100 КБ ~ 1 МБ + + + + 1 MB ~ 10 MB + 1 МБ ~ 10 МБ + + + + 10 MB ~ 100 MB + 10 МБ ~ 100 МБ + + + + 100 MB ~ 1 GB + 100 МБ ~ 1 ГБ + + + + > 1 GB + + + + + Today + + + + + Yesterday + + + + + This week + + + + + Last week + + + + + This month + + + + + Last month + + + + + This year + + + + + Last year + + + + + DFMTagCrumbController + + + Tag information + + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + + + + + The action is denied + + + + + Failed to open the file + + + + + Failed to read the file + + + + + Failed to write the file + + + + + Failed to create the directory + + + + + Failed to delete the file + + + + + Failed to move the file + + + + + Original file does not exist + + + + + Failed, file size must be less than 4GB + + + + + Not enough free space on the target disk + + + + + File integrity was damaged + + + + + The target device is read only + + + + + Target folder is inside the source folder + + + + + copy + Extra name added to new file name when used for file name. + + + + + Failed to create the directory, cause: %1 + + + + + + Failed to open the file, cause: %1 + + + + + Failed to read the file, cause: %1 + + + + + Failed to write the file, cause: %1 + + + + + File integrity was damaged, cause: %1 + + + + + Failed to delete the file, cause: %1 + + + + + Fail to create symlink, cause: %1 + + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + + + + + Cancel + + + + + Replace + + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + + + + + + + Time modified + + + + + Size + + + + + Type + + + + + Time created + + + + + + Last access + + + + + Path + + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + + + + + DFileViewHelper + + + Add tag "%1" + + + + + DStatusBar + + + %1 item + + + + + %1 items + + + + + %1 item selected + + + + + %1 items selected + + + + + %1 folder selected (contains %2) + + + + + %1 folders selected (contains %2) + + + + + %1 file selected (%2) + + + + + %1 files selected (%2) + + + + + %1 folder selected + + + + + Filter + + + + + Save as: + + + + + Loading... + + + + + DTaskDialog + + + This action is not supported + + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + + + + + Data Disk + Data Partition + + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + + + + + Target folder is inside the source folder! + + + + + + + + + + + + + + OK + + + + + Do you want to run %1 or display its content? + + + + + It is an executable text file. + + + + + + + + + + + + + + + Cancel + + + + + + + Run + + + + + + Run in terminal + + + + + Display + + + + + It is an executable file. + + + + + This file is not executable, do you want to add the execute permission and run? + + + + + "%1" already exists, please use another name. + + + + + + + + + Confirm + + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + + + + + Permanently delete %1 items? + + + + + Delete + + + + + Empty + + + + + Sorry, unable to locate your bookmark directory, remove it? + + + + + Remove + + + + + Name: + + + + + Force unmount + + + + + %1 that this shortcut refers to has been changed or moved + + + + + Do you want to delete this shortcut? + + + + + Failed, file size must be less than 4GB. + + + + + Fail to create symlink, cause: + + + + + The selected files contain system file/directory, and it cannot be deleted + + + + + + You do not have permission to operate file/folder! + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + + + + + View + + + + + Do you want to run %1? + + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + + + + + Please restore by the following steps to normally access Windows disk + + + + + 1. Reboot to enter Windows + + + + 3. Reboot and enter deepin + + + + + Reboot + + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + + + + + Format + + + + + Cancel + + + + + Save + + + + + Open + + + + + Save File + + + + + Open File + + + + + FileJob + + + copy + + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + + + + + %1 m %2 s + + + + + %1 h %2 m %3 s + + + + + %1 d %2 h %3 m %4 s + + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + + + + + + + Open behavior + + + + + + + Always open folder in new window + + + + + + + Open file: + + + + + + + Click + + + + + + + Double click + + + + + + + New window and tab + + + + + + + Open from default window: + + + + + + + + + + Computer + + + + + + + + + + Home + + + + + + + + + + Desktop + + + + + + + + + + Videos + + + + + + + + + + Music + + + + + + + + + + Pictures + + + + + + + + + + Documents + + + + + + + + + + Downloads + + + + + + + Open in new tab: + + + + + + + Current Directory + + + + + + + View + + + + + + + Default size: + + + + + + + Extra small + + + + + + + Small + + + + + + + Medium + + + + + + + Large + + + + + + + Extra large + + + + + + + Default view: + + + + + + + Icon + + + + + + + List + + + + + + + Hidden files + + + + + + + Show hidden files + + + + + + + Hide file extension when rename + + + + + + + Advanced + + + + + + + Index + + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + + + + + + + Hide system disk + + + + + + + Show hidden files in search results + + + + + + + Display recent file entry in left panel + + + + + + + Preview + + + + + + Compress file preview + + + + + + + Text preview + + + + + + + Document preview + + + + + + + Image preview + + + + + + + Video preview + + + + + + + Mount + + + + + + + Auto mount + + + + + + + Open after auto mount + + + + + + + Dialog + + + + Use the file chooser dialog of Deepin File Manager + + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + + + + + + + + + Confirm + + + + + + Cannot find the mounting device + + + + + Cannot unmount the device + + + + + Cannot eject the device "%1" + + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + + + + + + + Application + + + + + + + Video + + + + + + + Audio + + + + + + + Image + + + + + + Archive + + + + + + + Text + + + + + + Executable + + + + + + Backup file + + + + + + Unknown + + + + + MountAskPasswordDialog + + + Cancel + + + + + Connect + + + + + Log in as + + + + + Anonymous + + + + + Registered user + + + + + Username + + + + + Domain + + + + + Password + + + + + Remember password + + + + + MountSecretDiskAskPasswordDialog + + + Cancel + + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + + + + Keep both + + + + Replace + + + + Do not ask again + + + + merge + + + + Copying %1 + + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + + + + Moving %1 + + + + Move to %2 + + + + Restoring %1 + + + + Restore to %2 + + + + Deleting %1 + + + + Trashing %1 + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + Retry + + + + Time modified:%1 + + + + Original folder + + + + Original file + + + + Target folder + + + + Target file + + + + Contains:%1 + + + + Size:%1 + + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + + + + + Delete + + + + + OpenWithDialog + + + Open with + + + + + Add other programs + + + + + Set as default + + + + + Cancel + + + + + Confirm + + + + + Recommended Applications + + + + + Other Applications + + + + + PathManager + + + Home + + + + + Desktop + + + + + Videos + + + + + Music + + + + + Pictures + + + + + Documents + + + + + Downloads + + + + + + Trash + + + + + + System Disk + + + + + Computers in LAN + + + + + My Shares + + + + + Computer + + + + + Recent + + + + + PropertyDialog + + + Basic info + + + + + Open with + + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + + + + + QObject + + + + + Size + + + + + + + Contains + + + + + + + Type + + + + + + + + Time modified + + + + + Free space + + + + + Total space + + + + + Access denied + + + + + + Executable + + + + + + Write only + + + + + + Read only + + + + + + Read-write + + + + + Others + + + + + Owner + + + + + Device type + + + + + File system + + + + + Group + + + + + + + Open + + + + + + Size: %1 + + + + + Type: %1 + + + + + Size: 0 + + + + + Items: %1 + + + + + + + + + + + + Open in new window + + + + + + + + + + + + Open in new tab + + + + + Open with + + + + + Compress + + + + + Extract + + + + + Extract here + + + + + Cut + + + + + Copy + + + + + Paste + + + + + + + + + + + Rename + + + + + + + Remove + + + + + Create link + + + + + Send to desktop + + + + + Send to + + + + + Add to bookmark + + + + + + + + Properties + + + + + New folder + + + + + New window + + + + + Select all + + + + + + Clear recent history + + + + + + + Empty Trash + + + + + Display as + + + + + Sort by + + + + + New document + + + + + + Time created + + + + + Log out and unmount + + + + + + + Source path + + + + + Share folder + + + + + Cancel sharing + + + + + Connect to Server + + + + + Set share password + + + + + Format + + + + + Tag information + + + + + Open in new window as admin + + + + + Select default program + + + + + Open file location + + + + + Remove bookmark + + + + + + + Delete + + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + + + + + Restore + + + + + Restore all + + + + + File Vault + + + + + Auto mount + + + + + Open after auto mount + + + + + + Mount + + + + + + Unmount + + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + + + + + Safely Remove + + + + + + Name + + + + + Settings + + + + + Exit + + + + + Icon + + + + + List + + + + + Extend + + + + + Set as wallpaper + + + + + + + + Local disk + + + + + + Removable disk + + + + + + + Network shared directory + + + + + + Android mobile device + + + + + + Apple mobile device + + + + + + Camera + + + + + + DVD + + + + + + Unknown device + + + + + + + %1 item + + + + + + + %1 items + + + + + Shortcut + + + + + Create symlink + + + + + Path + + + + + + + Time deleted + + + + + Loading... + + + + + File has been moved or deleted + + + + + + + You do not have permission to access this folder + + + + + + + + Folder is empty + + + + + Path + SearchFileInfo + + + + + Searching... + + + + + No results + + + + + Source Path + TrashFileInfo + + + + + Document + + + + + Spreadsheet + + + + + + Presentation + + + + + Text + + + + + 1 task in progress + + + + + %1 tasks in progress + + + + + Mode: + + + + + + Replace Text + + + + + + Add Text + + + + + + Custom Text + + + + + Find: + + + + + Replace: + + + + + + Optional + + + + + Add: + + + + + Location: + + + + + File name: + + + + + +SN: + + + + + + + + + + + Required + + + + + + Before file name + + + + + + After file name + + + + + Find + + + + + Replace + + + + + Add + + + + + + + Location + + + + + File name + + + + + Dimension + + + + + Duration + + + + + +SN + + + + + Tips: Sort by selected file order + + + + + + + Cancel + + + + + Rename %1 Files + + + + + Multiple Files + + + + + Basic info + + + + + Total size + + + + + Number of files + + + + + %1 file(s), %2 folder(s) + + + + + + + Time accessed + + + + + Orange + + + + + Red + + + + + Purple + + + + + Navy-blue + + + + + Azure + + + + + Green + + + + + Yellow + + + + + Gray + + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + + + + + Erase + + + + + + Copy path + + + + + + Edit address + + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + + + + + Share name: + + + + + Permission: + + + + + Read and write + + + + + Read only + + + + + Anonymous: + + + + + Not allow + + + + + Allow + + + + + Shortcut + + + Item + + + + + Select to the first item + + + + + Shift + Home + + + + + Select to the last item + + + + + Shift + End + + + + + Select leftwards + + + + + Shift + Left + + + + + Select rightwards + + + + + Shift + Right + + + + + Select to upper row + + + + + Shift + Up + + + + + Select to lower row + + + + + Shift + Down + + + + + Open + + + + + Ctrl + Down + + + + + To parent directory + + + + + Ctrl + Up + + + + + Permanently delete + + + + + Shift + Delete + + + + + Delete file + + + + + Delete + + + + + Select all + + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + + + + + Cut + + + + + Paste + + + + + Rename + + + + + F2 + + + + + New/Search + + + + + New window + + + + + New folder + + + + + + Search + + + + + New tab + + + + + View + + + + + Item information + + + + + Help + + + + + F1 + + + + + Keyboard shortcuts + + + + + Ctrl + Shift + / + + + + + Switch display status + + + + + Hide item + + + + + Input in address bar + + + + + Switch to icon view + + + + + Ctrl + 1 + + + + + Switch to list view + + + + + Ctrl + 2 + + + + + Others + + + + + Close + + + + + Alt + F4 + + + + + Close current tab + + + + + Back + + + + + Alt + Left + + + + + Alt + Right + + + + + Switch to next tab + + + + + Ctrl + Tab + + + + + Ctrl + Shift + Tab + + + + + Switch to previous tab + + + + + Next file + + + + + Tab + + + + + Previous file + + + + + Shift + Tab + + + + + Switch tab by specified number between 1 to 8 + + + + + Alt + [1-8] + + + + + Forward + + + + + TrashPropertyDialog + + + Trash + + + + + item + + + + + items + + + + + Contains %1 %2 + + + + + UDiskListener + + + Failed to rename the label + + + + + UserShareManager + + + Kindly Reminder + + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + + + + + Confirm + + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ms.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ms.ts new file mode 100644 index 0000000..80288f4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ms.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Folder Baharu + + + + Mounting device error + Ralat melekap peranti + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Imej cakera telah rosak, tidak dapat dilekapkan, sila padam cakera dahulu + + + + Mount error: unsupported image format + Ralat lekap: format imej tidak disokong + + + + + The device was not safely removed + Peranti masih tidak selamat ditanggalkan + + + + + Click "Safely Remove" and then disconnect it next time + Klik "Tanggal secara Selamat" dan kemudian putuskannya di lain masa + + + + The device was not ejected + Peranti tidak dilenting + + + + Disk is busy, cannot eject now + Cakera sibuk, tidak dapat ditanggalkan sekarang + + + + Authentication timed out + Pengesahihan telah tamat masa + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Pemindahan Fail Bluetooth + + + + File Transfer Successful + Pemindahan Fail Berjaya + + + + File Transfer Failed + Pemindahan Fail Gagal + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Menghantar fail kepada "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Gagal menghantar fail kepada "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Berjaya menghantar fail kepada "<b style="font-weight: 550;">%1</b>" + + + + Select a Bluetooth device to receive files + Pilih peranti Bluetooth untuk menerima fail + + + + Cannot find the connected Bluetooth device + Tidak menemui peranti Bluetooth tersambung + + + + Waiting to be received... + Menunggu penerimaan... + + + + Go to Bluetooth Settings + Pergi ke Tetapan Bluetooth + + + + %1/%2 Sent + %1/%2 Dihantar + + + + Error: the Bluetooth device is disconnected + Ralat: peranti Bluetooth terputus + + + + Unable to send the file more than 2 GB + Tidak dapat menghantar fail melebihi 2 GB + + + + Unable to send 0 KB files + Tidak dapat menghantar fail bersaiz 0 KB + + + + File doesn't exist + Fail tidak wujud + + + + Next + button + Berikutnya + + + + Cancel + button + Batal + + + + Done + button + Selesai + + + + Retry + button + Cuba lagi + + + + OK + button + OK + + + + File sending request timed out + Permohonan hantar fail telah tamat masa + + + + The service is busy and unable to process the request + Perkhidmatan sibuk dan tidak boleh memproses permintaan + + + + BurnOptDialog + + + Device error + Ralat peranti + + + + Optical device %1 doesn't exist + Peranti optik %1 tidak wujud + + + + Advanced settings + Tetapan lanjutan + + + + File system: + Sistem fail: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Untuk Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Untuk Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Serasi dengan mod CD/DVD Windows CD/DVD) + + + + ISO9660 Only + ISO9660 Sahaja + + + + CloseAllDialogIndicator + + + Close all + Tutup semua + + + + Total size: %1, %2 files + Jumlah saiz: %1, %2 fail + + + + ComputerModel + + + Double click to open it + + + + + My Directories + Direktori Saya + + + + Disks + Cakera-Cakera + + + + File Vault + Kekubah Fail + + + + Quick Access + + + + + ComputerPropertyDialog + + + Computer + Komputer + + + + Basic Info + Maklumat Asas + + + + + Computer Name + Nama Komputer + + + + + Edition + Edisi + + + + + + Version + Versi + + + + + Type + Jenis + + + + + + Processor + Pemproses + + + + + + Memory + Ingatan + + + + + + + Bit + Bit + + + + + Available + Tersedia + + + + Obtaining... + Mendapatkan... + + + + ConnectToServerDialog + + + Connect to Server + Sambung dengan Pelayan + + + + Cancel + button + Batal + + + + Connect + button + Sambung + + + + My Favorites: + Kegemaran Saya: + + + + + Clear History + Kosongkan Sejarah + + + + DFMAddressBar + + + Search or enter address + Gelintar atau masukkan alamat + + + + DFMAdvanceSearchBar + + + Search: + Gelintar: + + + + File Type: + Jenis Fail: + + + + File Size: + Saiz Fail: + + + + Time Modified: + Masa Diubahsuai: + + + + Time Accessed: + Masa Dicapai: + + + + Time Created: + Masa Dicipta: + + + + Reset + Tetap Semula + + + + All subdirectories + Semua subdirektori + + + + Current directory + Direktori semasa + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Hari Ini + + + + Yesterday + Semalam + + + + This week + Minggu ini + + + + Last week + Minggu lepas + + + + This month + Bulan ini + + + + Last month + Bulan lepas + + + + This year + Tahun ini + + + + Last year + Tahun lepas + + + + DFMOpticalMediaWidget + + + + No files to burn + Tiada fail dirakam + + + + Unable to burn. Not enough free space on the target disk. + Tidak dapat merakam. Ruang bebas dalam cakera sasaran tidak mencukupi. + + + + %1 burning is not supported + Rakaman %1 tidak disokong + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. Ia bukan cakera %1; +2. Versi sistem fail ini tidak menyokong penambahan fail. + + + + DFMTagCrumbController + + + Tag information + Maklumat tag + + + + DFMTagWidget + + + Tag + Tag + + + + DFMTaskWidget + + + Do not ask again + Jangan tanya lagi + + + + Syncing data + Menyegerak data + + + + Please wait + Tunggu sebentar + + + + + Time modified: %1 + Masa diubah suai: %1 + + + + + Contains: %1 + Mengandungi: %1 + + + + + Size: %1 + Saiz: %1 + + + + Original folder + Folder asal + + + + Keep both + button + Kekal kedua-duanya + + + + Skip + button + Langkau + + + + Replace + button + Ganti + + + + Retry + button + Cuba lagi + + + + Original file + Fail asal + + + + Target folder + Folder sasaran + + + + Target file + Fail sasaran + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Sulit Bilik Kebal Fail + + + + Click 'Encrypt' and input the user password. + Klik 'Sulit' dan masukkan kata laluan pengguna. + + + + Encrypting... + Menyulitkan... + + + + + + + Encrypt + Sulit + + + + Failed to create file vault: %1 + Gagal mencipta bilik kebal fail: %1 + + + + OK + OK + + + + The setup is complete + Persediaan selesai + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + + + + + Keep the key safe to retrieve the vault password later + + + + + Save to default path + + + + + Save to other locations + + + + + No permission, please reselect + + + + + Select a path + + + + + Next + Berikutnya + + + + The default path is invisible to other users, and the path information will not be shown. + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Kunci Pemulihan + + + + Generate a recovery key in case that you forgot the password + Jana satu kunci pemulihan sekiranya anda terlupa kata laluan + + + + Key + Kunci + + + + QR code + Kod QR + + + + Scan QR code and save the key to another device + Imbas kod QR dan simpan kunci ke peranti lain + + + + Next + Berikutnya + + + + Recovery Key: + Kunci Pemulihan: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Tetapkan Kata Laluan Bilik Kebal + + + + Method + Kaedah + + + + Manual + Manual + + + + Password + Kata laluan + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 aksara, terdiri daripada A-Z, a-z, 0-9, dan simbol + + + + Repeat password + Ulang kata laluan + + + + Input the password again + Masukkan kata laluan sekali lagi + + + + Password hint + Pembayang kata laluan + + + + Optional + Pilihan + + + + Next + Berikutnya + + + + + Passwords do not match + Kata laluan tidak sepadan + + + + DFMVaultActiveStartView + + + File Vault + Kekubah Fail + + + + Create your secure private space + Cipta ruang peribadi selamat anda + + + + Advanced encryption technology + Teknologi penyulitan termaju + + + + Convenient and easy to use + Mudah dan senang digunakan + + + + Create + Cipta + + + + DFMVaultFileView + + + Cannot open this path + + + + + Hint + + + + + OK + OK + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Buka dengan Kunci + + + + Failed to unlock file vault + Gagal membuka bilik kebal fail + + + + OK + OK + + + + Input the 32-digit recovery key + Masukkan kunci pemulihan 32-digit + + + + Cancel + button + Batal + + + + Unlock + button + Buka + + + + Wrong recovery key + Kunci pemulihan salah + + + + DFMVaultRemoveByPasswordView + + + Password + Kata laluan + + + + Password hint: %1 + Pembayang kata laluan: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Masukkan kunci pemulihan 32-digit + + + + DFMVaultRemovePages + + + Delete File Vault + Padam Bilik Kebal Fail + + + + Once deleted, the files in it will be permanently deleted + Setelah dipadamkan, fail di dalamnya akan kekal terpadam + + + + Use Key + Guna Kunci + + + + Cancel + button + Batal + + + + Use Key + button + Guna Kunci + + + + Delete + button + Padam + + + + + OK + button + OK + + + + Use Password + Guna Kata Laluan + + + + Wrong password + Kata laluan salah + + + + Wrong recovery key + Kunci pemulihan salah + + + + Failed to delete file vault + Gagal memadam bilik kebal fail + + + + Deleted successfully + Pemadaman berjaya + + + + Failed to delete + Gagal dipadamkan + + + + Removing... + Membuang... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + + + + + Verification failed + + + + + + Select a path + + + + + + Retrieve Password + + + + + By key in the default path + + + + + By key in the specified path + + + + + Verification Successful + + + + + Keep it safe + + + + + Back + button + Undur + + + + Verify Key + button + + + + + Go to Unlock + button + + + + + Close + button + Tutup + + + + Vault password: %1 + + + + + DFMVaultUnlockPages + + + Unlock File Vault + Buka Bilik Kebal Fail + + + + Forgot password? + + + + + Password hint: %1 + Pembayang kata laluan: %1 + + + + Failed to unlock file vault + Gagal membuka bilik kebal fail + + + + Cancel + button + Batal + + + + Password + Kata laluan + + + + Unlock + button + Buka + + + + Please try again %1 minutes later + + + + + Wrong password, please try again %1 minutes later + + + + + Wrong password, one chance left + + + + + Wrong password, %1 chances left + + + + + Wrong password + Kata laluan salah + + + + OK + button + OK + + + + DFileCopyMoveJob + + + Permission error + Ralat keizinan + + + + The action is denied + Tindakan dinafikan + + + + Failed to open the file + Gagal membuka fail + + + + Failed to read the file + Gagal membaca fail + + + + Failed to write the file + Gagal menulis fail + + + + Failed to create the directory + Gagal mencipta direktori + + + + Failed to delete the file + Gagal memadam fail + + + + Failed to move the file + Gagal mengalih fail + + + + Original file does not exist + Fail asal tidak wijud + + + + Failed, file size must be less than 4GB + Gagal, saiz fail mesti kurang dari 4GB + + + + Not enough free space on the target disk + Ruang bebas dalam cakera sasaran tidak mencukupi + + + + File integrity was damaged + Integriti fail telah rosak + + + + The target device is read only + Peranti sasaran hanya baca sahaja + + + + Target folder is inside the source folder + Folder sasaran di dalam folder sumber + + + + The action is not supported + Tindakan ini tidak disokong + + + + You do not have permission to traverse files in it + Anda tiada keizinan untuk rentas fail di dalamnya + + + + Failed to position the file pointer! + + + + + copy + Extra name added to new file name when used for file name. + salin + + + + Failed to open the directory, cause: file name too long + Gagal membuka direktori, sebab: nama fail terlalu panjang + + + + + Failed to open the file, cause: file name too long + Gagal membuka fail, sebab: nama fail terlalu panjang + + + + + Failed to write the file, cause: + Gagal menulis fail, sebab: + + + + Failed to position the file pointer, cause: %1 + + + + + Syncing data + Menyegerak data + + + + Please wait + Tunggu sebentar + + + + Failed to create the directory, cause: %1 + Gagal mencipta direktori, sebab: %1 + + + + + + + + Failed to open the file, cause: %1 + Gagal membuka fail, sebab: %1 + + + + + + + Failed to open the file, cause: Permission denied + Gagal membuka fail, sebab: Keizinan dinafikan + + + + + Failed to read the file, cause: %1 + Gagal membaca fail, sebab: %1 + + + + + + + Failed to write the file, cause: %1 + Gagal menulis fail, sebab: %1 + + + + + File integrity was damaged, cause: %1 + Integriti fail telah rosak, sebab: %1 + + + + Failed to open the file, cause: + Gagal membuka fail, sebab: + + + + Failed to read the file, cause: + Gagal membaca fail, sebab: + + + + Failed to delete the file, cause: %1 + Gagal memadam fail, sebab: %1 + + + + Fail to create symlink, cause: %1 + Gagal mencipta pautan simbolik, sebab: %1 + + + + DFileDialog + + + + Save + button + Simpan + + + + + Cancel + button + Batal + + + + Confirm + button + Sahkan + + + + %1 already exists, do you want to replace it? + %1 sudah wujud, anda mahu gantikannya? + + + + Replace + button + Ganti + + + + Open + button + Buka + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Fail ini akan disembunyikan jika nama fail bermula dengan titik (.). Anda pasti mahu sembunyikannya? + + + + DFileManagerWindow + + + Trash + Tong Sampah + + + + Empty + Kosong + + + + DFileSystemModel + + + + Name + Nama + + + + + + Time modified + Masa diubahsuai + + + + Size + Saiz + + + + Type + Jenis + + + + Time created + Masa dicipta + + + + + Last access + Capaian Terakhir + + + + + + + Path + Laluan + + + + DFileView + + + Disc mount error + Ralat lekap cakera + + + + The disc is in use, please end the running process and remount the disc. + Cakera sedang digunakan, sila tamatkan proses yang berjalan dan lekap semula cakera. + + + + Mounting failed + Gagal dilekapkan + + + + (Reverse) + (Songsang) + + + + DFileViewHelper + + + Add tag "%1" + Tambah tag "%1" + + + + DStatusBar + + + %1 item + %1 item + + + + %1 items + %1 item + + + + %1 item selected + %1 item terpilih + + + + %1 items selected + %1 item terpilih + + + + %1 folder selected (contains %2) + %1 folder terpilih (mengandungi %2) + + + + %1 folders selected (contains %2) + %1 folder terpilih (mengandungi %2) + + + + %1 file selected (%2) + %1 fail terpilih (%2) + + + + %1 files selected (%2) + %1 fail terpilih (%2) + + + + %1 folder selected + %1 folder terpilih + + + + Filter + Tapis + + + + Save as: + Simpan sebagai: + + + + Loading... + Memuatkan... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Memadam cakera %1, tunggu sebentar... + + + + Burning disc %1, please wait... + Merakam cakera %1, tunggu sebentar... + + + + Writing data... + Menulis data... + + + + Verifying data... + Mengesahkan data... + + + + Copying %1 + Menyalin %1 + + + + + + to %2 + ke %2 + + + + %1 already exists in target folder + %1 sudah wujud dalam folder sasaran + + + + Original path %1 Target path %2 + Laluan asal %1 Laluan sasaran %2 + + + + Merge + button + Gabung + + + + Replace + button + Ganti + + + + Moving %1 + Mengalih %1 + + + + Removing file vault, please try later + Membuang bilik kebal fail, cuba lagi kemudian + + + + Restoring %1 + Memulihkan %1 + + + + Deleting %1 + Memadam %1 + + + + Trashing %1 + Tong Sampahkan %1 + + + + Calculating space, please wait + Mengira ruang, tunggu sebentar + + + + DUMountManager + + + + Authentication timed out + Pengesahihan telah tamat masa + + + + + + Disk is busy, cannot unmount now + Cakera sibuk, tidak dapat ditanggalkan sekarang + + + + Disk is busy, cannot eject now + Cakera sibuk, tidak dapat ditanggalkan sekarang + + + + The device is busy, cannot eject now + Peranti masih sibuk, tidak dapat lentingkan sekarang + + + + + + The device is busy, cannot remove now + Peranti masih sibuk, tidak dapat tanggalkan sekarang + + + + DeepinStorage + + + + + %1 Volume + Volum %1 + + + + Data Disk + Data Partition + Cakera Data + + + + %1 Drive + Pemacu %1 + + + + Blank %1 Disc + Cakera %1 Kosong + + + + %1 Encrypted + %1 Disulitkan + + + + DialogManager + + + + + + Operation failed! + Operasi gagal! + + + + Target folder is inside the source folder! + Folder sasaran di dalam folder sumber! + + + + Do you want to run %1 or display its content? + Anda mahu jalankan %1 atau papar kandungannya? + + + + It is an executable text file. + Ia adalah fail teks bolehlaku. + + + + It is an executable file. + Ia adalah fail bolehlaku. + + + + This file is not executable, do you want to add the execute permission and run? + Fail ini tidak bolehlaku, anda mahu tambah keizinan laku dan jalankan? + + + + "%1" already exists, please use another name. + "%1" sudah wujud, sila gunakan nama lain. + + + + The file name must not contain two dots (..) + Nama fail tidak boleh mengandungi dua titik (..) + + + + Device or resource busy + + + + + Are you sure you want to erase all data on the disc? + Anda pasti mahu memadam semua data di dalam cakera? + + + + How do you want to use this disc? + Bagaimanakah anda mahu gunakan cakera ini? + + + + Disc erase failed + Pemadaman cakera gagal + + + + Burn process failed + Proses rakaman gagal + + + + %1: %2 + %1: %2 + + + + Show details + Tunjuk perincian + + + + Hide details + Sembunyi perincian + + + + Error + Ralat + + + + Permanently delete %1? + Padam %1 secara kekal? + + + + Permanently delete %1 items? + Padam %1 item secara kekal? + + + + Empty + Kosong + + + + Do you want to delete %1? + Anda pasti mahu memadam %1? + + + + Do you want to delete the selected %1 items? + Anda pasti mahu memadam %1 item terpilih? + + + + Sorry, unable to locate your bookmark directory, remove it? + Maaf, tidak dapat cari direktori tanda buka anda, buang ia? + + + + Name: + Nama: + + + + %1 that this shortcut refers to has been changed or moved + %1 yang mana pintasan rujuk telah berubah atau dialihkan + + + + Do you want to delete this shortcut? + Anda mahu padam pintasan ini? + + + + Failed, file size must be less than 4GB. + Gagal, saiz fail mesti kurang dari 4GB. + + + + Fail to create symlink, cause: + Gagal mencipta pautan simbolik, puncanya: + + + + The selected files contain system file/directory, and it cannot be deleted + Fail terpilih mengandungi fail/direktori sistem, dan ia tidak boleh dipadamkan + + + + Unable to find the original file + Tidak menemui fail asal + + + + + You do not have permission to operate file/folder! + Anda tidak mempunyai keizinan untuk mengendali fail/folder! + + + + Failed to restore %1 file, the source file does not exist + Gagal memulihkan fail %1, fail sumber tidak wujud + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Maaf, anda tidak mempunyai keizinan untuk mengendali fail/folder(s) %1 berikut! + + + + Unable to access %1 + Tidak dapat mencapai %1 + + + + + Sending files now, please try later + Menghantar fail sekarang, cuba lagi kemudian + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Untuk mencapai peranti, anda mesti format cakera dahulu. Anda pasti mahu memformatnya sekarang? + + + + Scanning the device, stop it? + Mengimbas peranti, hentikannya? + + + + Share folder can't be named after the current username + Folder dikongsi tidak boleh dinamakan selepas nama pengguna semasa + + + + Do you want to run %1? + Anda mahu jalankan %1? + + + + Burn image + button + Rakam imej + + + + Burn files + button + Rakam fail + + + + Are you sure you want to empty %1 item? + Anda pasti mahu kosongkan %1 item? + + + + Are you sure you want to empty %1 items? + Anda pasti mahu kosongkan %1 item? + + + + + This action cannot be undone + Tindakan ini tidak boleh dipulihkan + + + + + + + + + + + + + + OK + button + OK + + + + + + + + + + + + + + + Cancel + button + Batal + + + + + + Run + button + Jalan + + + + + Run in terminal + button + Jalankan dalam terminal + + + + Display + button + Papar + + + + + + + + + + + Confirm + button + Sahkan + + + + Erase + button + Padam + + + + Data verification failed + Pengesahan data gagal + + + + Show details + button + Tunjuk perincian + + + + + Delete + button + Padam + + + + Remove + button + Buang + + + + Disk is busy, cannot unmount now + Cakera sibuk, tidak dapat ditanggalkan sekarang + + + + Force unmount + button + Paksa tanggal + + + + Unable to copy. Not enough free space on the target disk. + Tidak boleh menyalin. Ruang bebas dalam cakera sasaran tidak mencukupi. + + + + Failed to restore %1 file, the target folder is read-only + Gagal memulihkan %1 fail, folder sasaran adalah baca-sahaja + + + + Failed to restore %1 files, the target folder is read-only + Gagal memulihkan %1 fail, folder sasaran adalah baca-sahaja + + + + Failed to restore %1 files, the source files do not exist + Gagal memulihkan %1 fail, fail sumber tidak wujud + + + + Format + button + Format + + + + Stop + button + Henti + + + + FileController + + + + + + Unable to find the original file + Tidak menemui fail asal + + + + + + Kindly Reminder + Peringatan Mesra + + + + + + Please install File Roller first and then continue + Sila pasang File Roller terlebih dahulu sebelum diteruskan + + + + + Unable to create files here: %1 + Tidak dapat mencipta fail di sini: %1 + + + + Confirm + button + Sahkan + + + + FileDialogStatusBar + + + File Name + Nama Fail + + + + Format + Format + + + + Save + button + Simpan + + + + Open + button + Buka + + + + Save File + button + Simpan Fail + + + + Open File + button + Buka Fail + + + + + + Cancel + button + Batal + + + + FileJob + + + copy + salin + + + + + + + Data verification successful. + Pengesahan data berjaya. + + + + + + Burn process completed + Proses rakaman selesai + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 j %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 h %2 j %3 m %4 s + + + + %1 is a duplicate file. + %1 merupakan fail pendua. + + + + Insufficient disc space. + Ruang cakera tidak mencukupi. + + + + Lost connection to drive. + Sambungan ke pemacu telah terputus. + + + + The CD/DVD drive is not ready. Try another disc. + Pemacu CD/DVD tidak sedia. Cuba cakera yang lain. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + Pemacu CD/DVD masih sibuk. Keluar program menggunakan pemacu, dan sisip pemacu sekali lagi. + + + + Unknown error + Ralat tidak diketahui + + + + Device disconnected + Peranti terputus + + + + GenerateSettingTranslate + + + + + Basic + Asas + + + + + + Open behavior + Kelakuan buka + + + + + + Always open folder in new window + Sentiasa buka folder dalam tetingkap baharu + + + + + + Open file: + Buka fail: + + + + + + Click + Klik + + + + + + Double click + Dwi-klik + + + + + + New window and tab + Tetingkap dan tab baharu + + + + + + Open from default window: + Buka dari tetingkap lalai: + + + + + + + + + Computer + Komputer + + + + + + + + + Home + Rumah + + + + + + + + + Desktop + Desktop + + + + + + + + + Videos + Video + + + + + + + + + Music + Muzik + + + + + + + + + Pictures + Gambar + + + + + + + + + Documents + Dokumen + + + + + + + + + Downloads + Muat Turun + + + + + + Open in new tab: + Buka dalam tab baharu: + + + + + + Current Directory + Direktori Semasa + + + + + + View + Lihat + + + + + + Default size: + Saiz lalai: + + + + + + Extra small + Sangat kecil + + + + + + Small + Kecil + + + + + + Medium + Sederhana + + + + + + Large + Besar + + + + + + Extra large + Sangat besar + + + + + + Default view: + Lihat lalai: + + + + + + Icon + Ikon + + + + + + List + Senarai + + + + + + Hidden files + Fail tersembunyi + + + + + + Show hidden files + Tunjuk fail tersembunyi + + + + + + Hide file extension when rename + Sembunyi sambungan fail ketika menamakan semula + + + + + + Advanced + Lanjutan + + + + + + Index + Indeks + + + + + + Auto index internal disk + Auto indeks cakera dalaman + + + + + + Index external storage device after connected to computer + Indekskan peranti storan luar selepas bersambung dengan komputer + + + + + + Full-Text search + Gelintar Teks-Penuh + + + + + + Show item counts and sizes in the path of mounted MTP devices + Tunjuk kiraan dan saiz item dalam laluan peranti MTP terlekap + + + + + + Keep showing the mounted Samba shares + + + + + + + Use the file chooser dialog of File Manager + Guna dialog pemilih fail bagi Pengurus Fail + + + + + + Ask for my confirmation when deleting files + Tanya pengesahan saya ketika memadam fail + + + + + + Other + Lain-lain + + + + + + Hide system disk + Sembunyi cakera sistem + + + + + + Show file system on disk icon + Tunjuk sistem fail dalam ikon cakera + + + + + + Show hidden files in search results + Tunjuk fail tersembunyi dalam keputusan gelintar + + + + + + Display recent file entry in left panel + Papar masukan fail baru-baru ini pada panel kiri + + + + + + Preview + Pratonton + + + + + Compress file preview + Mampat pratonton fail + + + + + + Text preview + Pratonton teks + + + + + + Document preview + Pratonton dokumen + + + + + + Image preview + Pratonton imej + + + + + + Video preview + Pratonton video + + + + + + Mount + Lekap + + + + + + Auto mount + Auto lekap + + + + + + Open after auto mount + Buka selepas auto lekap + + + + + + Dialog + Dialog + + + + Compressed file preview + Pratonton fail termampat + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Tidak dapat mengesahkan identiti %1 + + + + This happens when you log in to a computer the first time. + Ia berlaku ketika anda mendaftar masuk komputer kali pertama. + + + + The identity sent by the remote computer is + Identiti dihantar yang dihantar komputer jauh ialah + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Jika anda tidak pasti selamat diteruskan, hubungi pentadbir sistem. + + + + + + + + Mounting device error + Ralat melekap peranti + + + + + Wrong username or password + Nama pengguna atau kata laluan salah + + + + + + + + Confirm + button + Sahkan + + + + + Cannot find the mounted device + Tidak dapat cari peranti dilekap + + + + No key available to unlock device + Tiada kunci tersedia untuk membuka peranti + + + + The disk is mounted by user "%1", you cannot unmount it. + Cakera dilekap oleh pengguna "%1", anda tidak dapat menyahlekapkannya. + + + + Cannot unmount the device + Tidak dapat menanggalkan peranti + + + + Cannot eject the device "%1" + Tidak dapat lenting peranti "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Tidak dapat merakam. Ruang bebas dalam cakera sasaran tidak mencukupi. + + + + MergedDesktopController + + + + Pictures + Gambar + + + + + Music + Muzik + + + + + Applications + Aplikasi + + + + + Videos + Video + + + + + Documents + Dokumen + + + + + Others + Lain-lain + + + + MimeTypeDisplayManager + + + + Directory + Direktori + + + + + + Application + Aplikasi + + + + + + Video + Video + + + + + + Audio + Audio + + + + + + Image + Imej + + + + + Archive + Arkib + + + + + + Text + Teks + + + + + Executable + Bolehlaku + + + + + Backup file + Fail sandar + + + + + Unknown + Tidak diketahui + + + + MountAskPasswordDialog + + + Cancel + button + Batal + + + + Connect + button + Sambung + + + + Log in as + Daftar masuk sebagai + + + + Anonymous + Awanama + + + + Registered user + Pengguna berdaftar + + + + Username + Nama pengguna + + + + Domain + Domain + + + + Password + Kata laluan + + + + Remember password + Ingat kata laluan + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Batal + + + + Unlock + button + Buka + + + + Input password to decrypt the disk + Masukkan kata laluan untuk menyahsulit cakera + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Anda pasti mahu padam %1 secara kekal? + + + + This file is too big for the trash + Fail ini terlalu besar untuk dimuatkan ke dalam tong sampah + + + + The files are too big for the trash + Fail terlalu besar untuk dimuatkan ke dalam tong sampah + + + + Are you sure you want to permanently delete %1 files? + Anda pasti mahu padam %1 secara kekal? + + + + Cancel + button + Batal + + + + Delete + button + Padam + + + + OpenWithDialog + + + Open with + Buka dengan + + + + Add other programs + Tambah program lain + + + + Set as default + Tetapkan sebagai lalai + + + + Cancel + button + Batal + + + + Confirm + button + Sahkan + + + + Recommended Applications + Aplikasi Disaran + + + + Other Applications + Aplikasi Lain + + + + PathManager + + + Home + Rumah + + + + Desktop + Desktop + + + + Videos + Video + + + + Music + Muzik + + + + Pictures + Gambar + + + + Documents + Dokumen + + + + Downloads + Muat turun + + + + + Trash + Tong Sampah + + + + + + System Disk + Cakera Sistem + + + + Computers in LAN + Komputer dalam LAN + + + + My Shares + Perkongsian Saya + + + + Computer + Komputer + + + + Recent + Baru-Baru Ini + + + + File Vault + Kekubah Fail + + + + PropertyDialog + + + Basic info + Maklumat asas + + + + Open with + Buka dengan + + + + Sharing + Perkongsian + + + + Permissions + Keizinan + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Sembunyi folder ini + + + + Hide this file + Sembunyi fail ini + + + + Allow to execute as program + Benarkan dilakukan sebagai program + + + + QObject + + + + + + Size + Saiz + + + + + + Contains + Mengandungi + + + + + + Type + Jenis + + + + + + + + Time modified + Masa diubahsuai + + + + Free space + Ruang bebas + + + + Total space + Jumlah ruang + + + + + Time locked + Masa dikunci + + + + Access denied + Capaian dinafikan + + + + + Executable + Bolehlaku + + + + + Write only + Tulis sahaja + + + + + Read only + Baca sahaja + + + + + Read-write + Baca-tulis + + + + Others + Lain-lain + + + + Owner + Pemilik + + + + Unconnected network shared directory + + + + + Device type + Jenis peranti + + + + File system + Sistem fail + + + + Group + Kumpulan + + + + + Open + Buka + + + + Lock + Kunci + + + + Auto lock + Auto kunci + + + + Never + Tidak Sesekali + + + + 5 minutes + 5 minit + + + + 10 minutes + 10 minit + + + + 20 minutes + 20 minit + + + + Delete File Vault + Padam Bilik Kebal Fail + + + + Unlock + Buka + + + + Unlock by key + Buka dengan Kunci + + + + Open + button + Buka + + + + + Size: %1 + Saiz: %1 + + + + Type: %1 + Jenis: %1 + + + + Size: 0 + Saiz: 0 + + + + Items: %1 + Item: %1 + + + + + + + + + + Open in new window + Buka dalam tetingkap baharu + + + + + + + + + + Open in new tab + Buka dalam tab baharu + + + + Open with + Buka dengan + + + + + Compress + Mampat + + + + Extract + Esktrak + + + + Extract here + Ekstrak di sini + + + + Cut + Potong + + + + Copy + Salin + + + + Paste + Tampal + + + + + + + + Rename + Nama semula + + + + + + + Remove + Buang + + + + Create link + Cipta pautan + + + + Send to desktop + Hantar ke desktop + + + + Send to + Hantar ke + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Tambah ke tanda buku + + + + + + + Properties + Sifat + + + + New folder + Folder baharu + + + + New window + Tetingkap baharu + + + + Select all + Pilih semua + + + + + Clear recent history + Kosongkan sejarah baru-baru ini + + + + + + Empty Trash + Kosongkan Tong Sampah + + + + Display as + Papar sebagai + + + + Sort by + Isih mengikut + + + + New document + Dokumen baharu + + + + + Time created + Masa dicipta + + + + + + Source path + Laluan sumber + + + + Share folder + Kongsi folder + + + + Cancel sharing + Batal perkongsian + + + + Connect to Server + Sambung dengan Pelayan + + + + Set share password + Tetapkan kata laluan kongsi + + + + Format + Format + + + + Tag information + Maklumat tag + + + + Open as administrator + Buka sebagai pentadbir + + + + Select default program + Pilih program lalai + + + + Open file location + Buka lokasi fail + + + + Remove bookmark + Buang tanda buku + + + + + + Delete + Padam + + + + Office Text + Teks Pejabat + + + + Spreadsheets + Hamparan Elektronik + + + + Plain Text + Teks Biasa + + + + Open in terminal + Buka dalam terminal + + + + Restore + Pulih + + + + Restore all + Pulih semua + + + + Clear saved password and unmount + + + + + File Vault + Kekubah Fail + + + + Add to disc + Tambah ke cakera + + + + Refresh + + + + + Auto mount + Auto lekap + + + + Open after auto mount + Buka selepas auto lekap + + + + + Mount + Lekap + + + + + Unmount + Tanggal + + + + It does not support burning %1 discs + Ia tidak menyokong rakaman cakera %1 + + + + Burn + Rakam + + + + Disc name: + Nama cakera: + + + + + Maximum + Maksimum + + + + Allow files to be added later + Benarkan fail-fail ditambah kemudian + + + + Verify data + Sahkan data + + + + Write speed: + Kelajuan tulis: + + + + + + + Cancel + button + Batal + + + + Burn + button + Rakam + + + + + Eject + Lenting + + + + Safely Remove + Tanggal secara Selamat + + + + + Name + Nama + + + + Settings + Tetapan + + + + Exit + Keluar + + + + Icon + Ikon + + + + List + Senarai + + + + Extend + Lanjut + + + + Set as wallpaper + Tetapkan sebagai kertas dinding + + + + + + + Local disk + Cakera setempat + + + + + Removable disk + Cakera mudah alih + + + + + + Network shared directory + Direktori terkongsi rangkaian + + + + + Android mobile device + Peranti mudah alih Android + + + + + Apple mobile device + Peranti mudah alih Apple + + + + + Camera + Kamera + + + + + DVD + DVD + + + + + Unknown device + Peranti tidak diketahui + + + + + + %1 item + %1 item + + + + + + %1 items + %1 item + + + + Shortcut + Pintasan + + + + Create symlink + Cipta pautan simbolik + + + + Path + Laluan + + + + + + Time deleted + Masa dipadam + + + + Loading... + Memuatkan... + + + + File has been moved or deleted + Fail telah dialih atau dipadamkan + + + + You do not have permission to traverse files in it + Anda tiada keizinan untuk rentas fail di dalamnya + + + + + + You do not have permission to access this folder + Anda tidak mempunyai keizinan untuk mencapai folder ini + + + + + + + + Folder is empty + Folder kosong + + + + Searching... + Menggelintar... + + + + No results + Tiada keputusan + + + + Source Path + TrashFileInfo + Laluan Sumber + + + + Document + Dokumen + + + + Spreadsheet + Hamparan Elektronik + + + + + Presentation + Persembahan + + + + Text + Teks + + + + 1 task in progress + 1 tugas sedang diproses + + + + %1 tasks in progress + %1 tugas sedang diproses + + + + Mode: + Mod: + + + + + Replace Text + Ganti Teks + + + + + Add Text + Tambah Teks + + + + + Custom Text + Teks Suai + + + + Find: + Cari: + + + + Replace: + Ganti: + + + + + Optional + Pilihan + + + + Add: + Tambah: + + + + Location: + Lokasi: + + + + File name: + Nama fail: + + + + Start at: + Mula pada: + + + + + Rename + button + Nama Semula + + + + + + + + + + + Required + Diperlukan + + + + + Before file name + Sebelum nama fail + + + + + After file name + Selepas nama fail + + + + Find + Cari + + + + Replace + Ganti + + + + Add + Tambah + + + + Start at + Mula pada + + + + + + Location + Lokasi + + + + File name + Nama fail + + + + Dimension + Dimensi + + + + Duration + Jangka masa + + + + Tips: Sort by selected file order + Petua: Isih mengikut tertib fail terpilih + + + + Rename %1 Files + Nama Semula %1 Fail + + + + Multiple Files + Fail Berbilang + + + + Basic info + Maklumat asas + + + + Total size + Jumlah saiz + + + + Number of files + Bilangan fail + + + + %1 file(s), %2 folder(s) + %1 fail(s), %2 folder(s) + + + + + + Time accessed + Masa dicapai + + + + Orange + Jingga + + + + Red + Merah + + + + Purple + Ungu + + + + Navy-blue + Biru-laut + + + + Azure + Lazuardi + + + + Green + Hijau + + + + Yellow + Kuning + + + + Gray + Kelabu + + + + Input tag info, such as work, family. A comma is used between two tags. + Input maklumat tag, seperti kerja, keluarga. Satu tanda koma digunakan untuk memisahkan antara dua tag. + + + + Bookmarks + Tanda buku + + + + Erase + Padam + + + + Copy path + Salin laluan + + + + Edit address + Sunting alamat + + + + Free Space %1 + Ruang Bebas %1 + + + + Files are being processed + Fail-fail yang telah diproses + + + + + Unknown + Tidak diketahui + + + + My Vault + Bilik Kebal Saya + + + + + Failed to create file info + Gagal mencipta maklumat fail + + + + Failed to create file handler + Gagal mencipta pengendali fail + + + + Failed to open the file, cause: %1 + Gagal membuka fail, sebab: %1 + + + + Original file does not exist + Fail asal tidak wijud + + + + Do you want to delete %1? + Anda pasti mahu memadam %1? + + + + Confirm + button + Sahkan + + + + + + + + %1 are not allowed + + + + + + Failed to start Samba services + + + + + RecentController + + + Cancel + button + Batal + + + + Remove + button + Buang + + + + Do you want to remove this item? + + + + + Do yout want to remove %1 items? + + + + + It does not delete the original files + + + + + ShareInfoFrame + + + Share this folder + Kongsi folder ini + + + + Share name: + Nama kongsi: + + + + Permission: + Keizinan: + + + + Read and write + Baca dan tulis + + + + Read only + Baca sahaja + + + + Anonymous: + Awanama: + + + + Not allow + Tidak dibenarkan + + + + Allow + Benarkan + + + + The share name must not be two dots (..) or one dot (.) + Nama kongsi tidak boleh ada dua titik (..) atau satu titik (.) + + + + The share name is used by another user. + Nama kongsi telah digunakan oleh pengguna lain. + + + + OK + button + OK + + + + Cancel + button + Batal + + + + Replace + button + Ganti + + + + The share name already exists. Do you want to replace the shared folder? + Nama kongsi sudah wujud. Anda pasti mahu ganti folder terkongsi? + + + + Shortcut + + + Item + Item + + + + Select to the first item + Pilih ke item pertama + + + + Shift + Home + Shift + Home + + + + Select to the last item + Pilih ke item terakhir + + + + Shift + End + Shift + End + + + + Select leftwards + Pilih ke kiri + + + + Shift + Left + Shift + Kiri + + + + Select rightwards + Pilih ke kanan + + + + Shift + Right + Shift + Kanan + + + + Select to upper row + Pilih ke baris atas + + + + Shift + Up + Shift + Atas + + + + Select to lower row + Pilih ke baris bawah + + + + Shift + Down + Shift + Bawah + + + + Open + Buka + + + + Ctrl + Down + Ctrl + Bawah + + + + To parent directory + Ke direktori induk + + + + Ctrl + Up + Ctrl + Atas + + + + Permanently delete + Padam secara kekal + + + + Shift + Delete + Shift + Delete + + + + Delete file + Padam fail + + + + Delete + Padam + + + + Select all + Pilih semua + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Salin + + + + Cut + Potong + + + + Paste + Tampal + + + + Rename + Nama Semula + + + + F2 + F2 + + + + New/Search + Baharu/Gelintar + + + + New window + Tetingkap baharu + + + + New folder + Folder baharu + + + + + Search + Gelintar + + + + New tab + Tab baharu + + + + View + Lihat + + + + Item information + Maklumat item + + + + Help + Bantuan + + + + F1 + F1 + + + + Keyboard shortcuts + Pintasan papan kekunci + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Tukar status paparan + + + + Hide item + Sembunyi item + + + + Input in address bar + Input dalam palang alamat + + + + Switch to icon view + Tukar ke paparan ikon + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Tukar ke paparan senarai + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Lain-lain + + + + Close + Tutup + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Tutup tab semasa + + + + Back + Undur + + + + Alt + Left + Alt + Kiri + + + + Alt + Right + Alt + Kanan + + + + Switch to next tab + Beralih ke tab berikutnya + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Beralih ke tab terdahulu + + + + Next file + Fail berikutnya + + + + Tab + Tab + + + + Previous file + Fail terdahulu + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Tukar tab dengan menyatakan nombor diantara 1 hingga 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Maju + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Tidak dapat membuka item dalam tong sampah, sila pulih ia dahulu + + + + TrashPropertyDialog + + + Trash + Tong Sampah + + + + item + item + + + + items + item + + + + Contains %1 %2 + Mengandungi %1 %2 + + + + UDiskListener + + + Failed to rename the label + Gagal menamakan semula label + + + + UnmountWorker + + + + + The device was not safely unmounted + Peranti masih tidak selamat dinyahlekapkan + + + + The device was not safely removed + Peranti masih tidak selamat ditanggalkan + + + + UserShareManager + + + Kindly Reminder + Peringatan Mesra + + + + Please firstly install samba to continue + Pastikan memasang samba terlebih dahulu sebelum diteruskan + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + + + + + To protect the files, you cannot share this folder. + Untuk melindungi fail, anda tidak boleh berkongsi folder ini. + + + + Sharing failed + Gagal dikongsi + + + + The computer name is too long + Nama komputer terlalu panjang + + + + You do not have permission to operate file/folder! + Anda tidak mempunyai keizinan untuk mengendali fail/folder! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Masukkan satu kata laluan untuk melindungi folder-folder terkongsi + + + + Cancel + button + Batal + + + + Confirm + button + Sahkan + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_nb.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_nb.ts new file mode 100644 index 0000000..b328061 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_nb.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + Ny mappe + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + Lukk alle + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + Datamaskin + + + + Basic Info + Grunnleggende informasjon + + + + Computer Name + Datamaskin Navn + + + + Version + Versjon + + + + Type + Type + + + + Processor + Prosessor + + + + Memory + Minne + + + + Disk + Disk + + + + Bit + Bit + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + Søk eller oppgi addresse + + + + DFMAdvanceSearchBar + + + Search: + Søk: + + + + File Type: + Filtype: + + + + File Size: + Filstørrelse: + + + + Time Modified: + Sist endret: + + + + Reset + Nullstill + + + + All subdirectories + Alle undermapper + + + + Current directory + Nåværende mappe + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + I dag + + + + Yesterday + I går + + + + This week + Denne uken + + + + Last week + Forrige uke + + + + This month + Denne måneden + + + + Last month + Forrige måned + + + + This year + I år + + + + Last year + I fjor + + + + DFMTagCrumbController + + + Tag information + Tag informasjon + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + Tillatelsesfeil + + + + The action is denied + Handlingen er nektet + + + + Failed to open the file + Klarte ikke å åpne filen + + + + Failed to read the file + Klarte ikke å lese filen + + + + Failed to write the file + Klarte ikke å skrive filen + + + + Failed to create the directory + Klarte ikke å opprette mappen + + + + Failed to delete the file + Klarte ikke å slette filen + + + + Failed to move the file + Klarte ikke å flytte filen + + + + Original file does not exist + Den opprinnelige filen eksisterer ikke + + + + Failed, file size must be less than 4GB + Feil, filstørrelse må være under 4GB + + + + Not enough free space on the target disk + + + + + File integrity was damaged + Filintegriteten ble skadet + + + + The target device is read only + Målenheten er "bare les" + + + + Target folder is inside the source folder + Målmappen er inni kildemappen + + + + copy + Extra name added to new file name when used for file name. + kopier + + + + Failed to create the directory, cause: %1 + Klarte ikke å opprette mappen, årsak: %1 + + + + + Failed to open the file, cause: %1 + Klarte ikke å opprette filen, årsak: %1 + + + + Failed to read the file, cause: %1 + Klarte ikke å lese filen, årsak:%1 + + + + Failed to write the file, cause: %1 + Klarte ikke å skrive til filen, årsak: %1 + + + + File integrity was damaged, cause: %1 + Filintegritet ble skadet, årsak: %1 + + + + Failed to delete the file, cause: %1 + Klarte ikke å slette filen, årsak: %1 + + + + Fail to create symlink, cause: %1 + Klarte ikke å opprette symbolsk lenke, årsak: %1 + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + %1 eksisterer allerede, vil du erstatte den? + + + + Cancel + Avbryt + + + + Replace + Erstatt + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + Navn + + + + + + Time modified + Tid modifisert + + + + Size + Størrelse + + + + Type + Type + + + + Time created + Tid opprettes + + + + + Last access + Siste tilgang + + + + Path + Sti + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + (Reverser) + + + + DFileViewHelper + + + Add tag "%1" + Legg til tag "%1" + + + + DStatusBar + + + %1 item + %1 ting + + + + %1 items + %1 ting + + + + %1 item selected + %1 ting valgt + + + + %1 items selected + %1 ting valgt + + + + %1 folder selected (contains %2) + %1 mappe valgt (inneholder %2) + + + + %1 folders selected (contains %2) + %1 mapper valgt (inneholder %2) + + + + %1 file selected (%2) + %1 fil valgt (%2) + + + + %1 files selected (%2) + %1 filer valgt (%2) + + + + %1 folder selected + %1 mappe valgt + + + + Filter + Filter + + + + Save as: + Lagre som: + + + + Loading... + Laster.. + + + + DTaskDialog + + + This action is not supported + Denne handlingen er ikke støttet + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + %1 Volum + + + + Data Disk + Data Partition + Data Disk + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + Operasjonen feilet! + + + + Target folder is inside the source folder! + Målmappen er inni kildemappen! + + + + + + + + + + + + + OK + OK + + + + Do you want to run %1 or display its content? + Vil du kjøre %1 eller vise dens innhold? + + + + It is an executable text file. + Det er en kjørbart tekstfil + + + + + + + + + + + + + + Cancel + Avbryt + + + + + + Run + Kjør + + + + + Run in terminal + Kjør i terminalen + + + + Display + Vis + + + + It is an executable file. + Det er en kjørbar fil. + + + + This file is not executable, do you want to add the execute permission and run? + Denne filen er ikke kjørbar. Vil du legge til kjøringstillatelse og kjøre den? + + + + "%1" already exists, please use another name. + "%1" eksisterer allerede, Vennligst bruk et annet navn + + + + + + + + Confirm + Bekrefte + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + Slette permanent %1? + + + + Permanently delete %1 items? + Permanent slette %1 ting? + + + + Delete + Slett + + + + Empty + Tøm + + + + Sorry, unable to locate your bookmark directory, remove it? + Beklager, ikke i stand til å lokalisere bokmerkemappen. Fjerne den? + + + + Remove + Fjerne + + + + Name: + Navn: + + + + Force unmount + Tving avmontering + + + + %1 that this shortcut refers to has been changed or moved + %1 som denne snarveien refererer til har blitt endret eller flyttet + + + + Do you want to delete this shortcut? + Vil du slette denne snarveien? + + + + Failed, file size must be less than 4GB. + Feilet, filstørrelse må være mindre enn 4GB + + + + Fail to create symlink, cause: + Klarte ikke å opprette symlink, årsak: + + + + The selected files contain system file/directory, and it cannot be deleted + Den valgte filen inneholder en systemfil eller mappe og kan ikke slettes + + + + + You do not have permission to operate file/folder! + Du har ikke tillatelse til å operere fil/mappe + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Beklager, du har ikke tillatelse til å operere følgende %1 filer/mappe(r)! + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + 2. Huk vekk "Skru på rask oppstart" og "Dvale" i avslutningsinnstillingene og start på nytt + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + Delt mappe kan ikke ha samme navn som nåværende brukernavn + + + + View + Vis + + + + Do you want to run %1? + Vil du kjøre %1? + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + Monter partition%1 som "bare les" + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + + + + + Please restore by the following steps to normally access Windows disk + + + + + 1. Reboot to enter Windows + + + + 3. Reboot and enter deepin + + + + + Reboot + Omstart + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + Filnavn + + + + Format + Format + + + + Cancel + Avbryt + + + + Save + Lagre + + + + Open + Åpne + + + + Save File + Lagre fil + + + + Open File + Åpne fil + + + + FileJob + + + copy + kopier + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + %1 + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 t %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 t %3 m %4 s + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + + + + + + + Open behavior + + + + + + + Always open folder in new window + Alltid åpne mappe i nytt vindu + + + + + + Open file: + Åpne fil: + + + + + + Click + Klikk + + + + + + Double click + Dobbeltklikk + + + + + + New window and tab + Nytt vindu og arkfane + + + + + + Open from default window: + + + + + + + + + + Computer + Datamaskin + + + + + + + + + Home + Hjem + + + + + + + + + Desktop + Skrivebord + + + + + + + + + Videos + Video + + + + + + + + + Music + Musikk + + + + + + + + + Pictures + Kilder + + + + + + + + + Documents + Dokumenter + + + + + + + + + Downloads + Nedlastninger + + + + + + Open in new tab: + Åpne i ny fane: + + + + + + Current Directory + Nåværende mappe + + + + + + View + Vis + + + + + + Default size: + + + + + + + Extra small + Ekstra liten + + + + + + Small + Liten + + + + + + Medium + Middels + + + + + + Large + Stor + + + + + + Extra large + Ekstra stor + + + + + + Default view: + + + + + + + Icon + Ikon + + + + + + List + Liste + + + + + + Hidden files + Skjulte filer + + + + + + Show hidden files + Vis skjulte filer + + + + + + Hide file extension when rename + + + + + + + Advanced + Avansert + + + + + + Index + Indeks + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + Andre + + + + + + Hide system disk + Skjul systemdisk + + + + + + Show hidden files in search results + Vis skjulte filer i søkeresultat + + + + + + Display recent file entry in left panel + Vis nylige filer i venstre panel + + + + + + Preview + Forhåndsvis + + + + + Compress file preview + + + + + + + Text preview + Forhåndsvis tekst + + + + + + Document preview + Forhåndsvis dokument + + + + + + Image preview + Forhåndsvis bilde + + + + + + Video preview + Forhåndsvis video + + + + + + Mount + Monter + + + + + + Auto mount + Automonter + + + + + + Open after auto mount + Åpne etter automonter + + + + + + Dialog + Dialog + + + Use the file chooser dialog of Deepin File Manager + + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + + + + + + + + + Confirm + Bekrefte + + + + + Cannot find the mounting device + + + + + Cannot unmount the device + + + + + Cannot eject the device "%1" + + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + + + + + + + Application + + + + + + + Video + Video + + + + + + Audio + Lyd + + + + + + Image + Bilde + + + + + Archive + Arkiv + + + + + + Text + Tekst + + + + + Executable + Kjørbar + + + + + Backup file + + + + + + Unknown + Ukjent + + + + MountAskPasswordDialog + + + Cancel + Avbryt + + + + Connect + Koble til + + + + Log in as + Logg inn som + + + + Anonymous + Anonym + + + + Registered user + Registrert bruker + + + + Username + Brukernavn + + + + Domain + Domene + + + + Password + Passord + + + + Remember password + Husk passordet + + + + MountSecretDiskAskPasswordDialog + + + Cancel + Avbryt + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + Hopp over + + + Keep both + Behold begge to + + + Replace + Erstatt + + + Do not ask again + Ikke spør igjen + + + merge + slå sammen + + + Copying %1 + Kopierer %1 + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + Kopier til %2 + + + Moving %1 + Flytter %1 + + + Move to %2 + Flytt til %2 + + + Restoring %1 + Gjenoppretter %1 + + + Restore to %2 + Gjenopprett til %2 + + + Deleting %1 + Sletter %1 + + + Trashing %1 + Kaster i søpla %1 + + + Calculating space, please wait + Kalkulerer plass, vennligst vent + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + Retry + Prøv igjen + + + Time modified:%1 + + + + Original folder + + + + Original file + + + + Target folder + + + + Target file + + + + Contains:%1 + + + + Size:%1 + + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + Avbryt + + + + Delete + Slett + + + + OpenWithDialog + + + Open with + Åpne med + + + + Add other programs + Legg til andre programmer + + + + Set as default + Sett som forhåndsvalg + + + + Cancel + Avbryt + + + + Confirm + + + + + Recommended Applications + Anbefalte Applikasjoner + + + + Other Applications + Andre Applikasjoner + + + + PathManager + + + Home + Hjem + + + + Desktop + Skrivebord + + + + Videos + Video + + + + Music + Musikk + + + + Pictures + Bilder + + + + Documents + Dokumenter + + + + Downloads + Nedlastninger + + + + + Trash + Søppel + + + + + System Disk + + + + + Computers in LAN + Datamaskiner i LAN + + + + My Shares + Mine Delinger + + + + Computer + Datamaskin + + + + Recent + Nylig + + + + PropertyDialog + + + Basic info + Grunnleggende info + + + + Open with + Åpne med + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + Tillat å kjøre som et program + + + + QObject + + + + + Size + Størrelse + + + + + + Contains + Inneholder + + + + + + Type + Type + + + + + + + Time modified + Tid modifisert + + + + Free space + Ledig plass + + + + Total space + Total plass + + + + Access denied + Tilgang nektet + + + + + Executable + Kjørbar + + + + + Write only + Bare skriv + + + + + Read only + Bare les + + + + + Read-write + Les og skriv + + + + Others + Andre + + + + Owner + Eier + + + + Device type + + + + + File system + + + + + Group + Gruppe + + + + + + Open + Åpne + + + + + Size: %1 + Størrelse: %1 + + + + Type: %1 + Type: %1 + + + + Size: 0 + Størrelse: 0 + + + + Items: %1 + + + + + + + + + + + + Open in new window + Åpne i et nytt vindu + + + + + + + + + + + Open in new tab + Åpne i ny fane + + + + Open with + Åpne med + + + + Compress + Komprimert + + + + Extract + Pakk ut + + + + Extract here + Pakk ut her + + + + Cut + Klipp ut + + + + Copy + Kopier + + + + Paste + Lim inn + + + + + + + + + + Rename + Endre navn + + + + + + Remove + Fjerne + + + + Create link + Opprett lenke + + + + Send to desktop + Send til skrivebordet + + + + Send to + Send til + + + + Add to bookmark + Legg til bokmerker + + + + + + + Properties + Innstillinger + + + + New folder + Ny mappe + + + + New window + Nytt vindu + + + + Select all + Velg alle + + + + + Clear recent history + Slett nylig historie + + + + + + Empty Trash + Tøm søppel + + + + Display as + Vis som + + + + Sort by + Sorter etter + + + + New document + Nytt dokument + + + + + Time created + Tid opprettet + + + + Log out and unmount + Logg ut og løs ut + + + + + + Source path + Kildesti + + + + Share folder + Del mappe + + + + Cancel sharing + Avbryt deling + + + + Connect to Server + + + + + Set share password + Sett delingspassord + + + + Format + Format + + + + Tag information + Tag informasjon + + + + Open in new window as admin + Åpne i nytt vindu som admin + + + + Select default program + Velg forhåndsvalgt program + + + + Open file location + + + + + Remove bookmark + Fjern bokmerke + + + + + + Delete + Slett + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + Åpne i terminalen + + + + Restore + Gjenopprett + + + + Restore all + Gjenopprett alle + + + + File Vault + + + + + Auto mount + Automonter + + + + Open after auto mount + Åpne etter automonter + + + + + Mount + Monter + + + + + Unmount + Løs ut + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + Løs ut + + + + Safely Remove + Trygg Fjerning + + + + + Name + Navn + + + + Settings + Instillinger + + + + Exit + Avslutt + + + + Icon + Ikon + + + + List + Liste + + + + Extend + Utvide + + + + Set as wallpaper + Sett som bakgrunn + + + + + + + Local disk + Lokal disk + + + + + Removable disk + Fjernbar disk + + + + + + Network shared directory + Delt nettverksmappe + + + + + Android mobile device + Android mobil enhet + + + + + Apple mobile device + Apple mobil enet + + + + + Camera + Kamera + + + + + DVD + + + + + + Unknown device + Ukjent enhet + + + + + + %1 item + %1 ting + + + + + + %1 items + %1 ting + + + + Shortcut + Snarvei + + + + Create symlink + Opprett symbolsk lenke + + + + Path + Sti + + + + + + Time deleted + Tid slettet + + + + Loading... + Laster... + + + + File has been moved or deleted + Filen har blitt flyttet eller slettet + + + + + + You do not have permission to access this folder + Du har ikke tilgang til denne mappen + + + + + + + Folder is empty + Mappen er tom + + + + Path + SearchFileInfo + Sti + + + + Searching... + Søker... + + + + No results + Ingen resultater + + + + Source Path + TrashFileInfo + + + + + Document + Dokument + + + + Spreadsheet + Regneark + + + + + Presentation + Presentasjon + + + + Text + Tekst + + + + 1 task in progress + 1 oppgave pågående + + + + %1 tasks in progress + %1 oppgaver pågående + + + + Mode: + Modus: + + + + + Replace Text + Erstatt tekst + + + + + Add Text + Legg til tekst + + + + + Custom Text + + + + + Find: + Finn: + + + + Replace: + Erstatt: + + + + + Optional + Valgfri + + + + Add: + Legg til: + + + + Location: + Sted: + + + + File name: + Filnavn: + + + + +SN: + + + + + + + + + + + Required + Nødvendig + + + + + Before file name + Før filnavn + + + + + After file name + Etter filnavn + + + + Find + Finn + + + + Replace + Erstatt + + + + Add + Legg til + + + + + + Location + Sted + + + + File name + Filnavn + + + + Dimension + + + + + Duration + + + + + +SN + + + + + Tips: Sort by selected file order + + + + + + + Cancel + Avbryt + + + + Rename %1 Files + Gi %1 filer nytt navn + + + + Multiple Files + Flere filer + + + + Basic info + Grunnleggende info + + + + Total size + Total størrelse + + + + Number of files + Antall filer + + + + %1 file(s), %2 folder(s) + %1 fil(er), %2 mapper + + + + + + Time accessed + + + + + Orange + Oransje + + + + Red + Rød + + + + Purple + Lilla + + + + Navy-blue + Blå + + + + Azure + Azurblå + + + + Green + Grønn + + + + Yellow + Gul + + + + Gray + Grå + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + Bokmerker + + + + Erase + + + + + + Copy path + Kopier bane + + + + + Edit address + Rediger adresse + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + Del denne mappen + + + + Share name: + Del navn: + + + + Permission: + Tillatelser: + + + + Read and write + Les og skriv + + + + Read only + Bare les + + + + Anonymous: + Anonym: + + + + Not allow + Ikke tillat + + + + Allow + Tillat + + + + Shortcut + + + Item + + + + + Select to the first item + + + + + Shift + Home + + + + + Select to the last item + + + + + Shift + End + + + + + Select leftwards + + + + + Shift + Left + + + + + Select rightwards + + + + + Shift + Right + + + + + Select to upper row + + + + + Shift + Up + + + + + Select to lower row + + + + + Shift + Down + + + + + Open + Åpne + + + + Ctrl + Down + + + + + To parent directory + + + + + Ctrl + Up + + + + + Permanently delete + Slett permanent + + + + Shift + Delete + + + + + Delete file + Slett fil + + + + Delete + Slett + + + + Select all + Velg alle + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + Kopier + + + + Cut + Klipp ut + + + + Paste + Lim inn + + + + Rename + Endre navn + + + + F2 + + + + + New/Search + Ny/Søk + + + + New window + Nytt vindu + + + + New folder + Ny mappe + + + + + Search + Søk + + + + New tab + Ny fane + + + + View + Vis + + + + Item information + + + + + Help + Hjelp + + + + F1 + + + + + Keyboard shortcuts + Tastatursnarveier + + + + Ctrl + Shift + / + + + + + Switch display status + + + + + Hide item + + + + + Input in address bar + + + + + Switch to icon view + + + + + Ctrl + 1 + + + + + Switch to list view + Bytt til listevisning + + + + Ctrl + 2 + + + + + Others + Andre + + + + Close + Lukk + + + + Alt + F4 + + + + + Close current tab + Lukk nåværende fane + + + + Back + Tilbake + + + + Alt + Left + + + + + Alt + Right + + + + + Switch to next tab + Bytt til neste fane + + + + Ctrl + Tab + + + + + Ctrl + Shift + Tab + + + + + Switch to previous tab + Bytt til forrige fane + + + + Next file + Neste fil + + + + Tab + + + + + Previous file + Forrige fil + + + + Shift + Tab + + + + + Switch tab by specified number between 1 to 8 + + + + + Alt + [1-8] + + + + + Forward + Fremover + + + + TrashPropertyDialog + + + Trash + Søppel + + + + item + + + + + items + + + + + Contains %1 %2 + + + + + UDiskListener + + + Failed to rename the label + + + + + UserShareManager + + + Kindly Reminder + Vennlig Påminnelse + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + Avbryt + + + + Confirm + Bekrefte + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ne.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ne.ts new file mode 100644 index 0000000..e8a4eb0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ne.ts @@ -0,0 +1,4791 @@ + + + AppController + + + New Folder + नयाँ फोल्डर + + + + Mounting device error + माउन्टिंग उपकरण त्रुटि + + + + The disc image was corrupted, cannot mount now, please erase the disc first + डिस्क छवि बिग्रेको थियो, अहिले चढ्न सक्दैन, कृपया पहिले डिस्कलाई मेटाउनुहोस् + + + + Mount error: unsupported image format + माउन्ट त्रुटि: असमर्थित छवि ढाँचा + + + + + The device was not safely removed + + + + + + Click "Safely Remove" and then disconnect it next time + + + + + The device was not ejected + + + + + Disk is busy, cannot eject now + डिस्क व्यस्त छ, अब निकाल्न सक्दैन + + + + Authentication timed out + + + + + BluetoothTransDialog + + + Bluetooth File Transfer + + + + + File Transfer Successful + + + + + File Transfer Failed + + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + + + + + Select a Bluetooth device to receive files + + + + + Cannot find the connected Bluetooth device + + + + + Waiting to be received... + + + + + Go to Bluetooth Settings + + + + + %1/%2 Sent + + + + + Error: the Bluetooth device is disconnected + + + + + Unable to send the file more than 2 GB + + + + + Unable to send 0 KB files + + + + + File doesn't exist + + + + + Next + button + अर्को + + + + Cancel + button + रद्द गर्नुहोस् + + + + Done + button + भयो + + + + Retry + button + पुनःप्रयास गर्नुहोस् + + + + OK + button + ठिक छ + + + Next + अर्को + + + Cancel + रद्द गर्नुहोस् + + + Done + भयो + + + Retry + पुनःप्रयास गर्नुहोस् + + + OK + ठिक छ + + + + File sending request timed out + + + + + The service is busy and unable to process the request + + + + + BurnOptDialog + + + Device error + + + + + Optical device %1 doesn't exist + + + + + Advanced settings + + + + + File system: + + + + + ISO9660/Joliet (For Windows) + + + + + ISO9660/Rock Ridge (For Unix) + + + + + %1 (Compatible with Windows CD/DVD mode) + + + + + ISO9660 Only + + + + + CloseAllDialogIndicator + + + Close all + सबै बन्द गर्नुहोस् + + + + Total size: %1, %2 files + कुल आकार:% 1,% 2 फाईलहरू + + + + ComputerModel + + + + My Directories + मेरो निर्देशिका + + + + + + + + + + + + Disks + डिस्कहरू + + + + ComputerPropertyDialog + + + Computer + कम्प्युटर + + + + Basic Info + आधारभूत जानकारी + + + + + Computer Name + कम्प्युटरको नाम + + + + + Edition + + + + + + + Version + संस्करण + + + + + Type + प्रकार + + + + + + Processor + प्रोसेसर + + + + + + Memory + मेमोरी + + + + + + + Bit + बिट + + + + + Available + + + + + Obtaining... + + + + + ConnectToServerDialog + + + Connect to Server + सर्भरमा जडान गर्नुहोस् + + + Cancel + रद्द गर्नुहोस् + + + Connect + जडान गर्नुहोस् + + + + Cancel + button + रद्द गर्नुहोस् + + + + Connect + button + जडान गर्नुहोस् + + + + My Favorites: + मेरो प्यारो: + + + + + Clear History + ईतिहास खाली गर्नुहोस् + + + + DFMAddressBar + + + Search or enter address + खोज्नुहोस् वा ठेगाना प्रविष्ट गर्नुहोस् + + + + DFMAdvanceSearchBar + + + Search: + खोजी गर्नुहोस् + + + + File Type: + फाईलको प्रकार: + + + + File Size: + फाईलको आकार: + + + + Time Modified: + समय परिमार्जित: + + + + Time Accessed: + + + + + Time Created: + + + + + Reset + रिसेट गर्नुहोस् + + + + All subdirectories + सबै उपनिर्देशिकाहरू + + + + Current directory + वर्तमान निर्देशिका + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + आज + + + + Yesterday + हिजो + + + + This week + यो हप्ता + + + + Last week + गएको हप्ता + + + + This month + यो महिना + + + + Last month + अघिल्लो महिना + + + + This year + यो वर्ष + + + + Last year + पछिल्लो वर्ष + + + + DFMOpticalMediaWidget + + + + No files to burn + + + + + Unable to burn. Not enough free space on the target disk. + + + + + %1 burning is not supported + + + + + 1. It is not a DVD-R or DVD+R disc; +2. The version of this file system does not support adding files yet. + + + + + DFMSideBarBookmarkItemHandler + + + Gotcha + button + + + + + DFMTagCrumbController + + + Tag information + ट्याग जानकारी + + + + DFMTagWidget + + + Tag + ट्याग + + + + DFMTaskWidget + + Keep both + दुबै राख्नुहोस् + + + Skip + छोड्नुहोस् + + + Replace + बदल्नुहोस् + + + + Do not ask again + फेरि नसोध्नुहोस् + + + + Syncing data + + + + + Please wait + + + + Retry + पुनःप्रयास गर्नुहोस् + + + + + Time modified: %1 + समय परिमार्जित:% 1 + + + + + Contains: %1 + समावेश:% 1 + + + + + Size: %1 + आकार:% 1 + + + + Original folder + मूल फोल्डर + + + + Keep both + button + दुबै राख्नुहोस् + + + + Skip + button + छोड्नुहोस् + + + + Replace + button + बदल्नुहोस् + + + + Retry + button + पुनःप्रयास गर्नुहोस् + + + + Original file + मूल फाइल + + + + Target folder + लक्ष्य फोल्डर + + + + Target file + लक्ष्य फाईल + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + + + + + Click 'Encrypt' and input the user password. + + + + + Encrypting... + + + + + + + + Encrypt + + + + + Failed to create file vault: %1 + + + + + OK + ठिक छ + + + + The setup is complete + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + + + + + Generate a recovery key in case that you forgot the password + + + + + Key + + + + + QR code + + + + + Scan QR code and save the key to another device + + + + + Next + अर्को + + + + Recovery Key: + + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + + + + + Method + + + + + Manual + + + + + Password + पासवर्ड + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + + + + + Repeat password + पासवर्ड फेरि दोहोर्याउँनुहोस् + + + + Input the password again + + + + + Password hint + + + + + Optional + वैकल्पिक + + + + Next + अर्को + + + + + Passwords do not match + + + + + DFMVaultActiveStartView + + + File Vault + फाईल भल्ट + + + + Create your secure private space + + + + + Advanced encryption technology + + + + + Convenient and easy to use + सुविधाजनक र प्रयोग गर्न सजिलो + + + + Create + + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + + + + Cancel + रद्द गर्नुहोस् + + + Unlock + अनलक गर्नुहोस् + + + + Failed to unlock file vault + + + + + OK + ठिक छ + + + + Input the 32-digit recovery key + + + + + Cancel + button + रद्द गर्नुहोस् + + + + Unlock + button + अनलक गर्नुहोस् + + + + Wrong recovery key + + + + + DFMVaultRemoveByPasswordView + + + Password + पासवर्ड + + + + Password hint: %1 + + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + + + + + DFMVaultRemovePages + + + Delete File Vault + + + + + Once deleted, the files in it will be permanently deleted + + + + Cancel + रद्द गर्नुहोस् + + + + Use Key + + + + Delete + हटाउनुहोस् + + + OK + ठिक छ + + + + Cancel + button + रद्द गर्नुहोस् + + + + Use Key + button + + + + + Delete + button + हटाउनुहोस् + + + + + OK + button + ठिक छ + + + + Use Password + + + + + Wrong password + + + + + Wrong recovery key + + + + + Failed to delete file vault + + + + + Deleted successfully + + + + + Failed to delete + + + + + Removing... + + + + + DFMVaultUnlockPages + + + Unlock File Vault + + + + + Verify your password + + + + Cancel + रद्द गर्नुहोस् + + + Unlock + अनलक गर्नुहोस् + + + + Password hint: %1 + + + + + Failed to unlock file vault + + + + OK + ठिक छ + + + + Password + पासवर्ड + + + + Cancel + button + रद्द गर्नुहोस् + + + + Unlock + button + अनलक गर्नुहोस् + + + + + Wrong password + + + + + OK + button + ठिक छ + + + + DFileCopyMoveJob + + + Permission error + अनुमति त्रुटि + + + + The action is denied + कार्य अस्वीकृत गरिएको छ + + + + Failed to open the file + फाईल खोल्न असफल भयो + + + + Failed to read the file + फाईल पढ्न असफल भयो + + + + Failed to write the file + फाईल लेख्न असफल भयो + + + + Failed to create the directory + निर्देशिका बनाउन असफल + + + + Failed to delete the file + फाईल हटाउन असफल भयो + + + + Failed to move the file + फाईल सार्न असफल भयो + + + + Original file does not exist + मूल फाईल अवस्थित छैन + + + + Failed, file size must be less than 4GB + असफल भयो, फाईल आकार 4GB जीबी भन्दा कम हुनुपर्दछ + + + + Not enough free space on the target disk + लक्ष्य डिस्कमा पर्याप्त खाली ठाउँ छैन + + + + File integrity was damaged + फाईल अखण्डता बिग्रियो + + + + The target device is read only + लक्षित उपकरण मात्र पढ्न सकिन्छ + + + + Target folder is inside the source folder + लक्ष्य फोल्डर स्रोत फोल्डर भित्र छ + + + + The action is not supported + + + + + You do not have permission to traverse files in it + + + + + copy + Extra name added to new file name when used for file name. + कपी + + + + Failed to open the directory, cause: file name too long + + + + + + + Failed to open the file, cause: file name too long + + + + + + Failed to write the file, cause: + + + + + Syncing data + + + + + Please wait + + + + + Failed to create the directory, cause: %1 + डाइरेक्टरी सिर्जना गर्न असफल भयो, कारण:% 1 + + + + + + + + + Failed to open the file, cause: %1 + फाइल खोल्न असफल भयो, कारण:% 1 + + + + + + + Failed to open the file, cause: Permission denied + + + + + + Failed to read the file, cause: %1 + फाइल पढ्न असफल भयो, कारण:% 1 + + + + + + + Failed to write the file, cause: %1 + फाइल लेख्न असफल भयो, कारण:% 1 + + + + + File integrity was damaged, cause: %1 + फाईल अखण्डता बिग्रियो, कारण:% 1 + + + + Failed to open the file, cause: + + + + + Failed to read the file, cause: + + + + + Failed to delete the file, cause: %1 + फाइल हटाउन असफल भयो, कारण:% 1 + + + + Fail to create symlink, cause: %1 + स्य्मलिंक सिर्जना गर्न असफल भयो, कारण:% 1 + + + + DFileDialog + + Save + बचत गर्नुहोस् + + + + + Save + button + बचत गर्नुहोस् + + + + + Cancel + button + रद्द गर्नुहोस् + + + + Confirm + button + पुष्टि गर्नुहोस् + + + + %1 already exists, do you want to replace it? + % 1 पहिले नै अवस्थित छ, के तपाइँ यसलाई बदल्न चाहानुहुन्छ? + + + + Replace + button + बदल्नुहोस् + + + + Open + button + खोल्नुहोस् + + + Cancel + रद्द गर्नुहोस् + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + + + + Confirm + पुष्टि गर्नुहोस् + + + Replace + बदल्नुहोस् + + + Open + खोल्नुहोस् + + + + DFileManagerWindow + + + Trash + रद्दी टोकरी + + + + Empty + खाली + + + + DFileSystemModel + + + + Name + नाम + + + + + + Time modified + समय परिमार्जित + + + + Size + आकार + + + + Type + प्रकार + + + + Time created + समय सिर्जना गरियो + + + + + Last access + अन्तिम पहुँच + + + + + + + Path + पथ + + + + DFileView + + + Disc mount error + + + + + The disc is in use, please end the running process and remount the disc. + + + + + Mounting failed + + + + + (Reverse) + (उल्टो) + + + + DFileViewHelper + + + Add tag "%1" + ट्याग "% 1" थप्नुहोस् + + + + DStatusBar + + + %1 item + % 1 वस्तु + + + + %1 items + % 1 वस्तुहरू + + + + %1 item selected + % 1 वस्तु चयन गरियो + + + + %1 items selected + % 1 वस्तुहरू चयन गरियो + + + + %1 folder selected (contains %2) + % 1 फोल्डर चयन गरियो (% 2 समावेश गर्दछ) + + + + %1 folders selected (contains %2) + % 1 फोल्डरहरू चयन गरियो (% 2 समावेश गर्दछ) + + + + %1 file selected (%2) + % 1 फाइल चयन गरियो (% 2) + + + + %1 files selected (%2) + % 1 फाइलहरू चयन गरियो (% 2) + + + + %1 folder selected + % 1 फोल्डर चयन गरियो + + + + Filter + फिल्टर + + + + Save as: + बचत गर्नुहोस् जब: + + + + Loading... + लोड हुँदैछ ... + + + + DTaskDialog + + + This action is not supported + यो कार्य समर्थित छैन + + + + Erasing disc %1, please wait... + डिस्क% 1 मेटाईदै, कृपया प्रतीक्षा गर्नुहोस् ... + + + + Burning disc %1, please wait... + % 1 डिस्क बर्न गर्दै, कृपया प्रतीक्षा गर्नुहोस् ... + + + + Writing data... + डाटा लेख्दै ... + + + + Verifying data... + डाटा प्रमाणित गर्दै ... + + + + Copying %1 + % 1 प्रतिलिपि गर्दै + + + + + + to %2 + % 2 मा + + + + %1 already exists in target folder + % 1 पहिले नै लक्ष्य फोल्डरमा अवस्थित छ + + + + Original path %1 Target path %2 + मूल मार्ग% 1 लक्ष्य मार्ग% 2 + + + + Merge + button + मर्ज गर्नुहोस् + + + + Replace + button + बदल्नुहोस् + + + + Moving %1 + % 1 सार्दै + + + + Removing file vault, please try later + + + + + Restoring %1 + % 1 पुनर्स्थापना गर्दै + + + + Deleting %1 + % 1 हटाउँदै + + + + Trashing %1 + % 1 रद्दी टोकरीमा + + + + Calculating space, please wait + ठाउँ गणना गर्दै, कृपया प्रतीक्षा गर्नुहोस् + + + Merge + मर्ज गर्नुहोस् + + + Replace + बदल्नुहोस् + + + + DUMountManager + + + + Authentication timed out + + + + + + + Disk is busy, cannot unmount now + डिस्क व्यस्त छ, अब अनमाउन्ट गर्न सक्दैन + + + + Disk is busy, cannot eject now + डिस्क व्यस्त छ, अब निकाल्न सक्दैन + + + + The device is busy, cannot eject now + + + + + + + The device is busy, cannot remove now + + + + + DeepinStorage + + + + + %1 Volume + % 1 खण्ड + + + + Data Disk + Data Partition + डाटा डिस्क + + + + %1 Drive + % 1 ड्राइभ + + + + Blank %1 Disc + खाली% 1 डिस्क + + + + %1 Encrypted + % 1 ईन्क्रिप्टेड + + + + DialogManager + + + + + + Operation failed! + सञ्चालन असफल! + + + + Target folder is inside the source folder! + लक्ष्य फोल्डर स्रोत फोल्डर भित्र छ! + + + OK + ठिक छ + + + + Do you want to run %1 or display its content? + के तपाइँ% 1 चलाउन चाहानुहुन्छ वा यसको सामग्री प्रदर्शन गर्न चाहानुहुन्छ? + + + + It is an executable text file. + यो एक कार्यान्वयन योग्य पाठ फाइल हो। + + + Cancel + रद्द गर्नुहोस् + + + Run + चलाउनुहोस् + + + Run in terminal + टर्मिनलमा चलाउनुहोस् + + + Display + प्रदर्शन + + + + It is an executable file. + यो एक कार्यान्वयन योग्य फाईल हो। + + + + This file is not executable, do you want to add the execute permission and run? + यो फाईल कार्यान्वयन योग्य छैन, के तपाईं कार्यान्वयन अनुमति थप्न र चलाउन चाहानुहुन्छ? + + + + "%1" already exists, please use another name. + "% 1" पहिले नै अवस्थित छ, कृपया अर्को नाम प्रयोग गर्नुहोस्। + + + Confirm + पुष्टि गर्नुहोस् + + + + The file name must not contain two dots (..) + + + + + Are you sure you want to erase all data on the disc? + के तपाईं निश्चित रूपमा डिस्कमा सबै डाटा मेटाउन चाहानुहुन्छ? + + + Erase + मेटाउनु + + + + How do you want to use this disc? + तपाईं यो डिस्क कसरी प्रयोग गर्न चाहनुहुन्छ? + + + Burn image + छवि बर्न गर्नुहोस् + + + Burn files + फाईलहरू बर्न गर्नुहोस् + + + + Disc erase failed + डिस्क मेट्न असफल भयो + + + + Burn process failed + बर्न प्रक्रिया असफल भयो + + + + %1: %2 + %1: %2 + + + + Show details + विवरण देखाऊ + + + + Hide details + विवरण लुकाउनुहोस् + + + + Error + त्रुटि + + + + Permanently delete %1? + % 1 लाई स्थायी रूपमा हटाउने हो? + + + + Permanently delete %1 items? + स्थायी रूपमा% 1 आईटमहरू हटाउने हो? + + + Delete + हटाउनु होस् + + + + Empty + खाली + + + + Do you want to delete %1? + + + + + Do you want to delete the selected %1 items? + + + + + Sorry, unable to locate your bookmark directory, remove it? + माफ गर्नुहोस्, तपाईंको बुकमार्क डाइरेक्टरी पत्ता लगाउन असमर्थ हुनुहुन्छ, यसलाई हटाउनुहुन्छ? + + + Remove + हटाउनुहोस् + + + + Name: + नाम: + + + Force unmount + बल अनमाउन्ट गर्नुहोस् + + + + %1 that this shortcut refers to has been changed or moved + % 1 जुन यो सर्टकटले जनाउँछ परिवर्तन गरिएको छ वा सारियो + + + + Do you want to delete this shortcut? + के तपाइँ यो सर्टकट मेटाउन चाहानुहुन्छ? + + + + Failed, file size must be less than 4GB. + असफल भयो, फाईल आकार 4GB जीबी भन्दा कम हुनुपर्दछ। + + + + Fail to create symlink, cause: + सिमलिंक सिर्जना गर्न असफल, कारण: + + + + The selected files contain system file/directory, and it cannot be deleted + चयनित फाईलहरूले प्रणाली फाइल / निर्देशिका समावेश गर्दछ, र यसलाई मेटाउन सकिदैन + + + + Unable to find the original file + + + + + + You do not have permission to operate file/folder! + तपाईंसँग फाईल / फोल्डर अपरेट गर्न अनुमति छैन! + + + + Failed to restore %1 file, the source file does not exist + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + माफ गर्नुहोस्, तपाईंसँग निम्न% 1 फाइल / फोल्डर (हरू) सञ्चालन गर्न अनुमति छैन! + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + 2. शटडाउन सेटिंग्स र रिबुटमा "छिटो सुरु गर्नुहोस्" र "हाइबरनेट" अनचेक गर्नुहोस् + + + + 3. Reboot and enter %1 + 3. रिबुट गर्नुहोस् र % 1 प्रविष्ट गर्नुहोस् + + + + Reboot + button + रिबुट + + + + Unable to access %1 + + + + + + Sending files now, please try later + + + + Format + फरम्याट गर्नुहोस + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + + + + Stop + + + + + Scanning the device, stop it? + + + + + Share folder can't be named after the current username + सेयर फोल्डर वर्तमान प्रयोगकर्ता नाम पछि नामकरण गर्न सकिदैन + + + + Do you want to run %1? + के तपाइँ % 1 चलाउन चाहानुहुन्छ? + + + + Burn image + button + छवि बर्न गर्नुहोस् + + + + Burn files + button + फाईलहरू बर्न गर्नुहोस् + + + + Are you sure you want to empty %1 item? + के तपाईं % 1 आईटम खाली गर्न निश्चित हुनुहुन्छ? + + + + Are you sure you want to empty %1 items? + के तपाईं% 1 आईटमहरू खाली गर्न निश्चित हुनुहुन्छ? + + + + + This action cannot be undone + यो कार्य पूर्ववत गर्न सकिदैन + + + + + + + + + + + + + + OK + button + ठिक छ + + + + + + + + + + + + + + + + Cancel + button + रद्द गर्नुहोस् + + + + + + Run + button + चलाउनुहोस् + + + + + Run in terminal + button + टर्मिनलमा चलाउनुहोस् + + + + Display + button + प्रदर्शन + + + + + + + + + Confirm + button + पुष्टि गर्नुहोस् + + + + Erase + button + मेटाउनु + + + Burn image, + + + + Burn files, + + + + + Data verification failed + + + + + Show details + button + विवरण देखाऊ + + + + + Delete + button + हटाउनुहोस् + + + + Remove + button + हटाउनुहोस् + + + + Disk is busy, cannot unmount now + डिस्क व्यस्त छ, अब अनमाउन्ट गर्न सक्दैन + + + + Force unmount + button + बल अनमाउन्ट गर्नुहोस् + + + + Unable to copy. Not enough free space on the target disk. + प्रतिलिपि गर्न असमर्थ। लक्ष्य डिस्कमा पर्याप्त खाली ठाउँ छैन। + + + + Failed to restore %1 file, the target folder is read-only + % 1 फाईल पुनर्स्थापित गर्न असफल भयो, लक्ष्य फोल्डर पढ्ने मात्र हो + + + + Failed to restore %1 files, the target folder is read-only + % 1 फाईलहरू पुन: भण्डारण गर्न असफल भयो, लक्ष्य फोल्डर पढ्नको लागि मात्र हो + + + + Failed to restore %1 files, the source files do not exist + + + + + Mount partition%1 to be read only + माउन्ट विभाजन% 1 मात्र पढ्नको लागि + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + विन्डोजमा डिस्कहरू सामान्य रूपमा पढ्न र लेख्न असक्षम हुन्छन् यदि शटडाउन सेटिंग्समा "द्रुत सुरुआत (सिफारिस गरिएको)" जाँच गरियो भने। + + + + Please restore by the following steps to normally access Windows disk + कृपया तलका चरणहरू द्वारा सामान्य रूपमा विन्डोज डिस्क पहुँच गर्न पुनःस्थापना गर्नुहोस् + + + + 1. Reboot to enter Windows + 1. विन्डोज प्रविष्ट गर्न पुनःबुट गर्नुहोस् + + + + Format + button + फरम्याट गर्नुहोस + + + + Stop + button + + + + Reboot + रिबुट + + + + FileController + + + + + + Unable to find the original file + + + + + + + Kindly Reminder + कृपया अनुस्मारक + + + + + + Please install File Roller first and then continue + कृपया पहिले फाइल रोलर स्थापना गर्नुहोस् र त्यसपछि जारी राख्नुहोस् + + + + + Unable to create files here: %1 + + + + + Confirm + button + पुष्टि गर्नुहोस् + + + Confirm + पुष्टि गर्नुहोस् + + + + FileDialogStatusBar + + + File Name + फाईल नाम + + + + Format + फरम्याट + + + Cancel + रद्द गर्नुहोस् + + + + + + Cancel + button + रद्द गर्नुहोस् + + + + Save + बचत गर्नुहोस् + + + + Open + खोल्नुहोस् + + + + Save File + फाइल बचत गर्नुहोस् + + + + Open File + फाईल खोल्नुहोस् + + + + FileIconItem + + + "'/\[]:|<>+=;,?* are not allowed + + + + + FileJob + + + copy + प्रतिलिपी + + + + + + + Data verification successful. + डाटा प्रमाणीकरण सफल। + + + + + + Burn process completed + बर्न प्रक्रिया पूरा भयो + + + + %1 s + %1 सेकेन्ड + + + + %1 m %2 s + % 1 मिनेट% 2 सेकेन्ड + + + + %1 h %2 m %3 s + % 1 घण्टा% 2 मिनेट% 3 सेकेन्ड + + + + %1 d %2 h %3 m %4 s + % 1 दिन% 2 घण्टा%3 मिनेट% 4 सेकेन्ड + + + + %1 is a duplicate file. + % 1 डुप्लिकेट फाईल हो। + + + + Insufficient disc space. + अपर्याप्त डिस्क ठाउँ। + + + + Lost connection to drive. + ड्राइभमा जडान हरायो। + + + + The CD/DVD drive is not ready. Try another disc. + CD / DVD ड्राइव तयार छैन। अर्को डिस्क प्रयोग गर्नुहोस्। + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + CD / DVD ड्राइभ व्यस्त छ। ड्राइभको प्रयोग गरेर कार्यक्रमबाट बाहिर निस्कनुहोस् र फेरि ड्राइभ घुसाउनुहोस्। + + + + Unknown error + अज्ञात त्रुटि + + + + Device disconnected + + + + + GenerateSettingTranslate + + + + + Basic + आधारभूत + + + + + + Open behavior + खुल्ला व्यवहार + + + + + + Always open folder in new window + सँधै नयाँ विन्डोमा फोल्डर खोल्नुहोस् + + + + + + Open file: + फाईल खोल्नुहोस्: + + + + + + Click + क्लिक गर्नुहोस् + + + + + + Double click + दुई पटक क्लिक गर्नुहोस् + + + + + + New window and tab + नयाँ विन्डो र ट्याब + + + + + + Open from default window: + पूर्वनिर्धारित विन्डोबाट खोल्नुहोस्: + + + + + + + + + Computer + कम्प्युटर + + + + + + + + + Home + होम + + + + + + + + + Desktop + डेस्कटप + + + + + + + + + Videos + भिडियोस + + + + + + + + + Music + म्युजिक + + + + + + + + + Pictures + पिक्चारहरु + + + + + + + + + Documents + डोकुमेन्त्स + + + + + + + + + Downloads + डाउनलोडहरू + + + + + + Open in new tab: + नयाँ ट्याबमा खोल्नुहोस्: + + + + + + Current Directory + हालको निर्देशिका + + + + + + View + हेर्नुहोस् + + + + + + Default size: + पूर्वनिर्धारित आकार: + + + + + + Extra small + थप सानो + + + + + + Small + सानो + + + + + + Medium + मध्यम + + + + + + Large + ठूलो + + + + + + Extra large + धेरै ठूलाे + + + + + + Default view: + पूर्वनिर्धारित दृश्य: + + + + + + Icon + आइकन + + + + + + List + सूची + + + + + + Hidden files + लुकेका फाइलहरू + + + + + + Show hidden files + लुकेका फाइलहरू देखाउनुहोस् + + + + + + Hide file extension when rename + पुन: नामाकरण गर्दा फाइल विस्तार लुकाउनुहोस् + + + + + + Advanced + उन्नत + + + + + + Index + अनुक्रमणिका + + + + + + Auto index internal disk + स्वत: अनुक्रमणिका आन्तरिक डिस्क + + + + + + Index external storage device after connected to computer + कम्प्युटरमा जडित पछि बाह्य भण्डारण उपकरणको सूचकांक + + + + + + Full-Text search + + + + + + + Use the file chooser dialog of File Manager + फाइल प्रबन्धकको फाइल छनौटकर्ता संवाद प्रयोग गर्नुहोस् + + + + + + Ask for my confirmation when deleting files + + + + + + + Other + अन्य + + + + + + Hide system disk + अन्य स्थान लुकाउनुहोस् + + + + + + Show file system on disk icon + + + + + + + Show hidden files in search results + खोज परिणामहरूमा लुकेका फाइलहरू देखाउनुहोस् + + + + + + Display recent file entry in left panel + बायाँ प्यानलमा भर्खरको फाइल प्रविष्टि प्रदर्शन गर्नुहोस् + + + + + + Preview + पूर्वावलोकन + + + + + Compress file preview + फाइल पूर्वावलोकन संकुचन गर्नुहोस् + + + + + + Text preview + पाठ पूर्वावलोकन + + + + + + Document preview + डोकुमेन्त पूर्वावलोकन + + + + + + Image preview + छवि पूर्वावलोकन + + + + + + Video preview + भिडियो पूर्वावलोकन + + + + + + Mount + माउन्ट + + + + + + Auto mount + स्वत: माउन्ट + + + + + + Open after auto mount + स्वत: माउन्ट पछि खोल्नुहोस् + + + + + + Dialog + संवाद + + + + Compressed file preview + संकुचित फाइल पूर्वावलोकन + + + + GvfsMountManager + + + Can’t verify the identity of %1. + + + + + This happens when you log in to a computer the first time. + + + + + The identity sent by the remote computer is + + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + + + + + + + + + Mounting device error + माउन्टिंग उपकरण त्रुटि + + + + + Wrong username or password + + + + + + + + + Confirm + button + पुष्टि गर्नुहोस् + + + + + Cannot find the mounted device + + + + + No key available to unlock device + + + + + The disk is mounted by user "%1", you cannot unmount it. + डिस्क "% 1" प्रयोगकर्ता द्वारा माउन्ट गरिएको छ, तपाईं यसलाई अनमाउन्ट गर्न सक्नुहुन्न। + + + Confirm + पुष्टि गर्नुहोस् + + + + Cannot unmount the device + उपकरण अनमाउन्ट गर्न सक्दैन + + + + Cannot eject the device "%1" + "% 1" उपकरण निकाल्न सक्दैन + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + + + + + MergedDesktopController + + + + Pictures + पिकचरहरु + + + + + Music + म्युजिक + + + + + Applications + अनुप्रयोगहरू + + + + + Videos + भिडियोहरू + + + + + Documents + डोकुमेन्त्स + + + + + Others + अन्य + + + + MimeTypeDisplayManager + + + + Directory + निर्देशिका + + + + + + Application + अनुप्रयोग + + + + + + Video + भिडियो + + + + + + Audio + अडियो + + + + + + Image + इमेज + + + + + Archive + अर्चिवे + + + + + + Text + टेक्स्ट + + + + + Executable + कार्यान्वयन योग्य + + + + + Backup file + ब्याकअप फाइल + + + + + Unknown + अज्ञात + + + + MountAskPasswordDialog + + Cancel + रद्द गर्नुहोस् + + + Connect + जडान गर्नुहोस् + + + + Cancel + button + रद्द गर्नुहोस् + + + + Connect + button + जडान गर्नुहोस् + + + + Log in as + यस रूपमा लग इन गर्नुहोस् + + + + Anonymous + बेनामी + + + + Registered user + पंजीकृत प्रयोगकर्ता + + + + Username + प्रयोगकर्ता नाम + + + + Domain + डोमेन + + + + Password + पासवर्ड + + + + Remember password + पासवर्ड याद गर्नुहोस् + + + + MountSecretDiskAskPasswordDialog + + Cancel + रद्द गर्नुहोस् + + + Unlock + अनलक गर्नुहोस् + + + + Cancel + button + रद्द गर्नुहोस् + + + + Unlock + button + अनलक गर्नुहोस् + + + + Input password to decrypt the disk + डिस्क डिक्रिप्ट गर्न इनपुट पासवर्ड + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + के तपाईं स्थायी रूपमा % 1 हटाउन निश्चित हुनुहुन्छ? + + + + This file is too big for the trash + यो फाईल रद्दीटोकरीको लागि धेरै ठूलो छ + + + + The files are too big for the trash + फाईलहरू रद्दी टोकरीको लागि धेरै ठुलो छ + + + + Are you sure you want to permanently delete %1 files? + के तपाईं स्थायी रूपमा% 1 फाइलहरू हटाउन निश्चित हुनुहुन्छ? + + + + Cancel + button + रद्द गर्नुहोस् + + + + Delete + button + हटाउनुहोस् + + + Cancel + रद्द गर्नुहोस् + + + Delete + हटाउनुहोस् + + + + OpenWithDialog + + + Open with + खोल्नुहोस् संग + + + + Add other programs + अन्य प्रोग्रामहरू थप्नुहोस् + + + + Set as default + पूर्वनिर्धारितको रूपमा सेट गर्नुहोस् + + + + Cancel + button + रद्द गर्नुहोस् + + + + Confirm + button + पुष्टि गर्नुहोस् + + + Cancel + रद्द गर्नुहोस् + + + Confirm + पुष्टि गर्नुहोस् + + + + Recommended Applications + सिफारिस गरिएका अनुप्रयोगहरू + + + + Other Applications + अन्य अनुप्रयोगहरू + + + + PathManager + + + Home + होम + + + + Desktop + डेस्कटप + + + + Videos + भिडियोस + + + + Music + म्युजिक + + + + Pictures + पिक्चारहरु + + + + Documents + डोकुमेन्त्स + + + + Downloads + डाउनलोडहरू + + + + + Trash + रद्दी टोकरी + + + + + + System Disk + प्रणाली डिस्क + + + + Computers in LAN + ल्यानमा कम्प्युटरहरू + + + + My Shares + मेरो सेयरहरू + + + + Computer + कम्प्युटर + + + + Recent + रिसेन्ट + + + + File Vault + फाईल भल्ट + + + + PropertyDialog + + + Basic info + आधारभूत जानकारी + + + + Open with + खोल्नुहोस् संग + + + + Sharing + शरिंग + + + + Permissions + अनुमतिहरू + + + + %1 (%2) + %1 (%2) + + + + %1 + + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + यस फोल्डरलाई लुकाउनुहोस् + + + + Hide this file + यो फाईल लुकाउनुहोस् + + + + Allow to execute as program + प्रोग्रामको रूपमा कार्यान्वयन गर्न अनुमति दिनुहोस् + + + + QObject + + + + + Size + आकार + + + + + + Contains + समावेश + + + + + + Type + प्रकार + + + + + + + + Time modified + समय परिमार्जित + + + + Free space + खाली ठाउँ + + + + Total space + कुल ठाउँ + + + + + Time locked + + + + + Access denied + प्रवेश अस्वीकृत + + + + + Executable + कार्यान्वयन योग्य + + + + + Write only + मात्र लेख्नुहोस् + + + + + Read only + पढ्न मात्र मिल्ने + + + + + Read-write + पढ्न-लेख्ननुहोस् + + + + Others + अन्य + + + + Owner + मालिक + + + + Device type + उपकरण प्रकार + + + + File system + फाइल प्रणाली + + + + Group + समूह + + + + + Open + खोल्नुहोस् + + + + Lock + + + + + Auto lock + + + + + Never + + + + + 5 minutes + + + + + 10 minutes + + + + + 20 minutes + + + + + Delete File Vault + + + + + Unlock + अनलक गर्नुहोस् + + + + Unlock by key + + + + + Open + button + खोल्नुहोस् + + + + + Size: %1 + आकार:% 1 + + + + Type: %1 + प्रकार: %1 + + + + Size: 0 + आकार: 0 + + + + Items: %1 + आईटमहरू:% 1 + + + + + + + + + + Open in new window + नयाँ विन्डोमा खोल्नुहोस् + + + + + + + + + + Open in new tab + नयाँ ट्याबमा खोल्नुहोस्: + + + + Open with + खोल्नुहोस् संग + + + + + Compress + कम्प्रेस गर्नुहोस् + + + + Extract + निकाल्नुहोस् + + + + Extract here + यहाँ निकाल्नुहोस् + + + + Cut + काट्नुहोस् + + + + Copy + प्रतिलिपी + + + + Paste + टाँस्नुहोस् + + + + + + + + Rename + नाम बदल्नुहोस् + + + + + + Remove + हटाउनुहोस् + + + + Create link + लिंक सिर्जना गर्नुहोस् + + + + Send to desktop + डेस्कटपमा पठाउनुहोस् + + + + Send to + लाई पठाउनुहोस् + + + + Bluetooth + + + + + Add to bookmark + बुकमार्कमा थप्नुहोस् + + + + + + + Properties + गुणहरू + + + + New folder + नयाँ फोल्डर + + + + New window + नयाँ विन्डो + + + + Select all + सबै छान्नु + + + + + Clear recent history + हालको ईतिहास खाली गर्नुहोस् + + + + + + Empty Trash + रद्दी टोकरी खाली गर्नुहोस् + + + + Display as + को रूपमा प्रदर्शन गर्नुहोस् + + + + Sort by + द्वारा क्रमबद्ध गर्नुहोस् + + + + New document + नयाँ डोकुम्नेन्त + + + + + Time created + समय सिर्जना गरियो + + + + Log out and unmount + लग आउट र अनमाउन्ट गर्नुहोस् + + + + + + Source path + स्रोत मार्ग + + + + Share folder + फोल्डर साझेदारी गर्नुहोस् + + + + Cancel sharing + साझेदारी रद्द गर्नुहोस् + + + + Connect to Server + सर्भरमा जडान गर्नुहोस् + + + + Set share password + शेयर पासवर्ड सेट गर्नुहोस् + + + + Format + फरम्याट गर्नुहोस + + + + Tag information + ट्याग जानकारी + + + + Open as administrator + + + + + Select default program + पूर्वनिर्धारित कार्यक्रम चयन गर्नुहोस् + + + + Open file location + फाईल स्थान खोल्नुहोस् + + + + Remove bookmark + बुकमार्क हटाउनुहोस् + + + + + + Delete + हटाउनुहोस् + + + + Office Text + अफिस टेक्स्ट + + + + Spreadsheets + स्प्रिडशिटहरू + + + + Plain Text + प्लैन टेक्स्ट + + + + Open in terminal + टर्मिनलमा खोल्नुहोस् + + + + Restore + पुनर्स्थापना गर्नुहोस् + + + + Restore all + सबै पुनर्स्थापना गर्नुहोस् + + + + + + + + File Vault + फाईल भल्ट + + + + Add to disc + + + + + Auto mount + स्वत: माउन्ट + + + + Open after auto mount + स्वत: माउन्ट पछि खोल्नुहोस् + + + + + Mount + माउन्ट + + + + + Unmount + अनमाउन्ट + + + + It does not support burning %1 discs + + + + + Burn + बर्न + + + + Disc name: + डिस्क नाम: + + + + + Maximum + अधिकतम + + + + Allow files to be added later + फाइलहरूलाई पछि थप्न अनुमति दिनुहोस् + + + + Verify data + डाटा प्रमाणित गर्नुहोस् + + + + Write speed: + गति लेख्नुहोस्: + + + + + + + Cancel + button + रद्द गर्नुहोस् + + + + Burn + button + बर्न + + + + + Eject + निकाल्नुहोस् + + + + Safely Remove + सुरक्षित रूपले हटाउनुहोस् + + + + + Name + नाम + + + + Settings + सेटिंग्स + + + + Exit + बाहिर निस्कनुहोस् + + + + Icon + आइकन + + + + List + सूची + + + + Extend + विस्तार गर्नुहोस् + + + + Set as wallpaper + वालपेपरको रूपमा सेट गर्नुहोस् + + + + + + + Local disk + स्थानीय डिस्क + + + + + Removable disk + हटाउन योग्य डिस्क + + + + + + Network shared directory + नेटवर्क साझा निर्देशिका + + + + + Android mobile device + एन्ड्रोइड मोबाइल उपकरण + + + + + Apple mobile device + एप्पल मोबाइल उपकरण + + + + + Camera + क्यामेरा + + + + + DVD + DVD + + + + + Unknown device + अज्ञात उपकरण + + + + + + %1 item + % 1 वस्तु + + + + + + %1 items + % 1 वस्तुहरू + + + + Shortcut + सर्टकट + + + + Create symlink + स्य्म्लिंक सिर्जना गर्नुहोस् + + + + Path + पथ + + + + + + Time deleted + समय हटाइयो + + + + Loading... + लोड हुँदैछ ... + + + + File has been moved or deleted + फाईल सारियो वा हटाईयो + + + + You do not have permission to traverse files in it + + + + + + + You do not have permission to access this folder + तपाईंसँग यो फोल्डर पहुँच गर्न अनुमति छैन + + + + + + + + Folder is empty + फोल्डर खाली छ + + + + Searching... + खोजी गर्दै ... + + + + No results + कुनै परिणाम छैन + + + + Source Path + TrashFileInfo + स्रोत मार्ग + + + + Document + डोकुमेन्त + + + + Spreadsheet + स्प्रिडशिटहरू + + + + + Presentation + प्रेसेंतेशन + + + + Text + टेक्स्ट + + + + 1 task in progress + 1 कार्य प्रगतिमा छ + + + + %1 tasks in progress + % 1 कार्यहरू प्रगतिमा छ + + + + Mode: + मोड: + + + + + Replace Text + टेक्स्ट बदल्नुहोस् + + + + + Add Text + टेक्स्ट थप्नुहोस् + + + + + Custom Text + कस्टम टेक्स्ट  + + + + Find: + खोज्नुहोस्: + + + + Replace: + बदल्नुहोस्: + + + + + Optional + वैकल्पिक + + + + Add: + थप्नुहोस्: + + + + Location: + स्थान: + + + + File name: + फाईल नाम: + + + + Start at: + + + + + + Rename + button + नाम बदल्नुहोस् + + + + + + + + + + + Required + आवाश्यक + + + + + Before file name + फाइल नाम अघि + + + + + After file name + फाइल नाम पछि + + + + Find + खोज्नुहोस् + + + + Replace + बदल्नुहोस् + + + + Add + थप्नुहोस्: + + + + Start at + + + + + + + Location + स्थान + + + + File name + फाईल नाम + + + + Dimension + आयाम + + + + Duration + अवधि + + + + Tips: Sort by selected file order + सुझावहरू: चयनित फाइल अर्डर द्वारा क्रमबद्ध गर्नुहोस् + + + Cancel + रद्द गर्नुहोस् + + + + Rename %1 Files + % 1 फाईलहरूको नाम बदल्नुहोस् + + + + Multiple Files + बहु फाइलहरू + + + + Basic info + आधारभूत जानकारी + + + + Total size + कुल आकार + + + + Number of files + फाईलहरूको संख्या + + + + %1 file(s), %2 folder(s) + % 1 फाइल (हरू),% 2 फोल्डर (हरू) + + + + + + Time accessed + समय पहुँच गरियो + + + + Orange + सुन्तला रंग + + + + Red + रातो + + + + Purple + बैजनी + + + + Navy-blue + नेभी-निलो + + + + Azure + Azure + + + + Green + हरियो + + + + Yellow + पहेंलो + + + + Gray + खैरो + + + + Input tag info, such as work, family. A comma is used between two tags. + इनपुट ट्याग जानकारी, जस्तै काम, परिवार। एक अल्पविराम दुई ट्याग बीचको प्रयोग गरीन्छ। + + + + Bookmarks + बुकमार्कहरू + + + + Erase + मेटाउनु + + + + Copy path + मार्ग प्रतिलिपि गर्नुहोस् + + + + Edit address + ठेगाना सम्पादन गर्नुहोस् + + + It does not support burning UDF discs + + + + + Free Space %1 + खाली ठाउँ% 1 + + + + Files are being processed + फाईलहरू प्रक्रियामा छन् + + + + Unknown + अज्ञात + + + + My Vault + + + + + + + Disks + डिस्कहरू + + + + + Failed to create file info + + + + + Failed to create file handler + + + + + + + Execution error + + + + + + + + "'/\[]:|<>+=;,?* are not allowed + + + + + Failed to open the file, cause: %1 + फाइल खोल्न असफल भयो, कारण:% 1 + + + + Original file does not exist + मूल फाईल अवस्थित छैन + + + + Do you want to delete %1? + + + + + Confirm + button + पुष्टि गर्नुहोस् + + + Confirm + पुष्टि गर्नुहोस् + + + + ShareInfoFrame + + + Share this folder + यो फोल्डर साझेदारी गर्नुहोस् + + + + Share name: + नाम साझेदारी गर्नुहोस्: + + + + Permission: + अनुमति: + + + + Read and write + पढ र लेख + + + + Read only + पढ्न मात्र मिल्ने + + + + Anonymous: + बेनामी: + + + + Not allow + अनुमति छैन + + + + Allow + अनुमति दिनुहोस् + + + + The share name must not be two dots (..) or one dot (.) + + + + + The share name is used by another user. + + + + + OK + button + ठिक छ + + + + Cancel + button + रद्द गर्नुहोस् + + + + Replace + button + बदल्नुहोस् + + + OK + ठिक छ + + + + The share name already exists. Do you want to replace the shared folder? + + + + Cancel + रद्द गर्नुहोस् + + + Replace + बदल्नुहोस् + + + + Shortcut + + + Item + आईटम + + + + Select to the first item + पहिलो आईटममा चयन गर्नुहोस् + + + + Shift + Home + Shift + Home + + + + Select to the last item + अन्तिम आईटममा चयन गर्नुहोस् + + + + Shift + End + Shift + End + + + + Select leftwards + बाँया तिर चयन गर्नुहोस् + + + + Shift + Left + Shift + Left + + + + Select rightwards + दायाँ चयन गर्नुहोस् + + + + Shift + Right + Shift + Right + + + + Select to upper row + माथिल्लो पक्तिमा चयन गर्नुहोस् + + + + Shift + Up + Shift + Up + + + + Select to lower row + तल्लो पक्तिमा चयन गर्नुहोस् + + + + Shift + Down + Shift + Down + + + + Open + खोल्नुहोस् + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + अभिभावक डाइरेक्टरीमा + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + स्थायी रूपमा हटाउनुहोस् + + + + Shift + Delete + Shift + Delete + + + + Delete file + फाइल हटाउनुहोस् + + + + Delete + हटाउनुहोस् + + + + Select all + सबै छान्नु + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + प्रतिलिपी + + + + Cut + काट्नुहोस् + + + + Paste + टाँस्नुहोस् + + + + Rename + नाम बदल्नुहोस् + + + + F2 + F2 + + + + New/Search + नयाँ / खोज + + + + New window + नयाँ विन्डो + + + + New folder + नयाँ फोल्डर + + + + + Search + खोजी गर्नुहोस् + + + + New tab + नयाँ ट्याब + + + + View + हेर्नुहोस् + + + + Item information + वस्तु जानकारी + + + + Help + मद्दत + + + + F1 + F1 + + + + Keyboard shortcuts + कीबोर्ड शर्टकटहरू + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + स्विच प्रदर्शन स्थिति + + + + Hide item + वस्तु लुकाउनुहोस् + + + + Input in address bar + ठेगाना बारमा इनपुट गर्नुहोस् + + + + Switch to icon view + आइकन दृश्यमा स्विच गर्नुहोस् + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + सूची दृश्यमा स्विच गर्नुहोस् + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + अन्य + + + + Close + बन्द + + + + Alt + F4 + Alt + F4 + + + + Close current tab + हालको ट्याब बन्द गर्नुहोस् + + + + Back + पछाडि + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + अर्को ट्याबमा स्विच गर्नुहोस् + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + अघिल्लो ट्याबमा स्विच गर्नुहोस् + + + + Next file + अर्को फाईल + + + + Tab + Tab + + + + Previous file + अघिल्लो फाइल + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + 1 देखि 8 बीचमा निर्दिष्ट संख्याबाट ट्याब स्विच गर्नुहोस् + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + अगाडि + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + + + + + TrashPropertyDialog + + + Trash + रद्दी टोकरी + + + + item + आईटम + + + + items + वस्तुहरू + + + + Contains %1 %2 + % 1% 2 समावेश गर्दछ + + + + UDiskListener + + + Failed to rename the label + लेबलको नाम बदल्न असफल भयो + + + + UnmountWorker + + + + + The device was not safely unmounted + + + + + The device was not safely removed + + + + + UserShareManager + + + Kindly Reminder + कृपया अनुस्मारक + + + + Please firstly install samba to continue + कृपया सुरूमा साम्बा स्थापना गर्नुहोस् + + + + To protect the files, you cannot share this folder. + + + + + The share name must not contain %<>*?|/\+=;:," + + + + + Sharing failed + + + + + The computer name is too long + + + + + You do not have permission to operate file/folder! + तपाईंसँग फाईल / फोल्डर अपरेट गर्न अनुमति छैन! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + साझेदारी फोल्डरहरू सुरक्षित गर्न पासवर्ड प्रविष्ट गर्नुहोस् + + + + Cancel + button + रद्द गर्नुहोस् + + + + Confirm + button + पुष्टि गर्नुहोस् + + + Cancel + रद्द गर्नुहोस् + + + Confirm + पुष्टि गर्नुहोस् + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_nl.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_nl.ts new file mode 100644 index 0000000..40f5124 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_nl.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Nieuwe map + + + + Mounting device error + Het apparaat kan niet worden aangekoppeld + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Aankoppelen mislukt: het schijfkopiebestand is beschadigd. Wis de schijf. + + + + Mount error: unsupported image format + Aankoppelfout: niet-ondersteund schijfkopiebestand + + + + + The device was not safely removed + Het apparaat is niet veilig verwijderd + + + + + Click "Safely Remove" and then disconnect it next time + Klik voortaan op ‘Veilig verwijderen’ voordat je het apparaat loskoppelt + + + + The device was not ejected + De schijf is niet uitgeworpen + + + + Disk is busy, cannot eject now + Schijf is in gebruik; je kunt nu niet uitwerpen + + + + Authentication timed out + De authenticatie is verlopen + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Bluetooth-bestandsoverdracht + + + + File Transfer Successful + Bestandsoverdracht voltooid + + + + File Transfer Failed + Bestandsoverdracht mislukt + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Bezig met versturen van bestanden naar "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Kan geen bestanden versturen naar "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + De bestanden zijn verstuurd naar "<b style="font-weight: 550;">%1</b>" + + + + Select a Bluetooth device to receive files + Kies het bluetoothapparaat waarvan je bestanden wilt ontvangen + + + + Cannot find the connected Bluetooth device + Het verbonden bluetoothapparaat is niet aangetroffen + + + + Waiting to be received... + Bezig met ophalen… + + + + Go to Bluetooth Settings + Ga naar de bluetoothinstellingen + + + + %1/%2 Sent + %1/%2 verstuurd + + + + Error: the Bluetooth device is disconnected + Foutmelding: de verbinding met het bluetoothapparaat is verbroken + + + + Unable to send the file more than 2 GB + De maximale bestandsgrootte is 2 GB + + + + Unable to send 0 KB files + Bestanden van 0 KB kunnen niet worden verstuurd + + + + File doesn't exist + Het bestand bestaat niet + + + + Next + button + Volgende + + + + Cancel + button + Annuleren + + + + Done + button + Klaar + + + + Retry + button + Opnieuw + + + + OK + button + Oké + + + + File sending request timed out + Het bestandsdelingverzoek is verlopen + + + + The service is busy and unable to process the request + Het verzoek kan niet worden verwerkt omdat de dienst bezet is + + + + BurnOptDialog + + + Device error + Apparaatfout + + + + Optical device %1 doesn't exist + Het optische apparaat, %1, bestaat niet + + + + Advanced settings + Geavanceerde instellingen + + + + File system: + Bestandssysteem: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (compatibel met Windows cd-/dvd-modus) + + + + ISO9660 Only + Alleen ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Alles sluiten + + + + Total size: %1, %2 files + Totale grootte: %1 - %2 bestanden + + + + ComputerModel + + + Double click to open it + Dubbelklik om te openen + + + + My Directories + Mijn mappen + + + + Disks + Schijven + + + + File Vault + Bestandskluis + + + + Quick Access + Snelle toegang + + + + ComputerPropertyDialog + + + Computer + Computer + + + + Basic Info + Basisinformatie + + + + + Computer Name + Computernaam + + + + + Edition + Versie + + + + + + Version + Versie + + + + + Type + Type + + + + + + Processor + Processor + + + + + + Memory + Geheugen + + + + + + + Bit + Bit + + + + + Available + Beschikbaar + + + + Obtaining... + Bezig met ophalen… + + + + ConnectToServerDialog + + + Connect to Server + Verbinden met server + + + + Cancel + button + Annuleren + + + + Connect + button + Verbinden + + + + My Favorites: + Mijn favorieten: + + + + + Clear History + Geschiedenis wissen + + + + DFMAddressBar + + + Search or enter address + Voer een zoekopdracht of locatie in + + + + DFMAdvanceSearchBar + + + Search: + Doorzoeken: + + + + File Type: + Bestandssoort: + + + + File Size: + Bestandsgrootte: + + + + Time Modified: + Aangepast om: + + + + Time Accessed: + Benaderd op: + + + + Time Created: + Aangemaakt op: + + + + Reset + Standaardwaarden + + + + All subdirectories + Onderliggende mappen + + + + Current directory + Huidige map + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Vandaag + + + + Yesterday + Gisteren + + + + This week + Deze week + + + + Last week + Vorige week + + + + This month + Deze maand + + + + Last month + Vorige maand + + + + This year + Dit jaar + + + + Last year + Vorig jaar + + + + DFMOpticalMediaWidget + + + + No files to burn + Geen te branden bestanden + + + + Unable to burn. Not enough free space on the target disk. + Kan niet branden: onvoldoende vrije ruimte op de doelschijf. + + + + %1 burning is not supported + Het branden van %1 wordt niet ondersteund + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. Het is geen %1-schijf; +2. Deze versie van het bestandssysteem heeft geen ondersteuning voor het toevoegen van bestanden. + + + + DFMTagCrumbController + + + Tag information + Labelnaam + + + + DFMTagWidget + + + Tag + Label + + + + DFMTaskWidget + + + Do not ask again + Niet meer vragen + + + + Syncing data + Bezig met synchroniseren… + + + + Please wait + Even geduld… + + + + + Time modified: %1 + Aangepast om: %1 + + + + + Contains: %1 + Bevat: %1 + + + + + Size: %1 + Grootte: %1 + + + + Original folder + Oorspronkelijke map + + + + Keep both + button + Beide behouden + + + + Skip + button + Overslaan + + + + Replace + button + Vervangen + + + + Retry + button + Opnieuw + + + + Original file + Oorspronkelijk bestand + + + + Target folder + Doelmap + + + + Target file + Doelbestand + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Bestandskluis versleutelen + + + + Click 'Encrypt' and input the user password. + Klik op ‘Versleutelen’ en voer je wachtwoord in. + + + + Encrypting... + Bezig met versleutelen… + + + + + + + Encrypt + Versleutelen + + + + Failed to create file vault: %1 + De bestandskluis kan niet worden aangemaakt: %1 + + + + OK + Oké + + + + The setup is complete + Instellen voltooid + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Herstelsleutel opslaan + + + + Keep the key safe to retrieve the vault password later + Bewaar de sleutel zorgvuldig zodat je de kluis evt. kunt herstellen + + + + Save to default path + Opslaan op standaardlocatie + + + + Save to other locations + Opslaan op andere locatie + + + + No permission, please reselect + Niet bevoegd - maak een andere keuze + + + + Select a path + Kies een locatie + + + + Next + Volgende + + + + The default path is invisible to other users, and the path information will not be shown. + De standaardlocatie is onzichtbaar voor andere gebruikers. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Herstelsleutel + + + + Generate a recovery key in case that you forgot the password + Genereer een herstelsleutel voor als je het wachtwoord bent vergeten + + + + Key + Sleutel + + + + QR code + QR-code + + + + Scan QR code and save the key to another device + Scan de qr-code om de sleutel op te slaan op een ander apparaat + + + + Next + Volgende + + + + Recovery Key: + Herstelsleutel: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Kluiswachtwoord instellen + + + + Method + Methode + + + + Manual + Handmatig + + + + Password + Wachtwoord + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + Minimaal 8 tekens: A-Z, a-z, 0-9 of speciale tekens + + + + Repeat password + Wachtwoord herhalen + + + + Input the password again + Wachtwoord opnieuw invoeren + + + + Password hint + Wachtwoordhint + + + + Optional + Optioneel + + + + Next + Volgende + + + + + Passwords do not match + De wachtwoorden komen niet overeen + + + + DFMVaultActiveStartView + + + File Vault + Bestandskluis + + + + Create your secure private space + Maak een beveiligde privéruimte + + + + Advanced encryption technology + Geavanceerde versleutelingstechnieken + + + + Convenient and easy to use + Eenvoudig te gebruiken + + + + Create + Maken + + + + DFMVaultFileView + + + Cannot open this path + Deze locatie kan niet worden geopend + + + + Hint + Hint + + + + OK + Oké + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Ontgrendelen met sleutel + + + + Failed to unlock file vault + De bestandskluis kan niet worden ontgrendeld + + + + OK + Oké + + + + Input the 32-digit recovery key + Voer de herstelsleutel in + + + + Cancel + button + Annuleren + + + + Unlock + button + Ontgrendelen + + + + Wrong recovery key + Onjuiste herstelsleutel + + + + DFMVaultRemoveByPasswordView + + + Password + Wachtwoord + + + + Password hint: %1 + Wachtwoordhint: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Voer de herstelsleutel in + + + + DFMVaultRemovePages + + + Delete File Vault + Standaard bestandskluis + + + + Once deleted, the files in it will be permanently deleted + Door het vernietigen worden alle kluisbestanden permanent verwijderd. + + + + Use Key + Sleutel gebruiken + + + + Cancel + button + Annuleren + + + + Use Key + button + Sleutel gebruiken + + + + Delete + button + Verwijderen + + + + + OK + button + Oké + + + + Use Password + Wachtwoord gebruiken + + + + Wrong password + Onjuist wachtwoord + + + + Wrong recovery key + Onjuiste herstelsleutel + + + + Failed to delete file vault + De bestandskluis kan niet worden vernietigd + + + + Deleted successfully + De kluis is vernietigd + + + + Failed to delete + De kluis kan niet worden vernietigd + + + + Removing... + Bezig met verwijderen… + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + Het sleutelbestand kan niet worden opgehaald + + + + Verification failed + De verificatie is mislukt + + + + + Select a path + Kies een locatie + + + + + Retrieve Password + Wachtwoord opvragen + + + + By key in the default path + Op sleutel op standaardlocatie + + + + By key in the specified path + Op sleutel op andere locatie + + + + Verification Successful + De sleutel is geverifieerd. + + + + Keep it safe + Veilig bewaren + + + + Back + button + Terug + + + + Verify Key + button + Sleutel verifiëren + + + + Go to Unlock + button + Ontgrendelen + + + + Close + button + Sluiten + + + + Vault password: %1 + Kluiswachtwoord: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Bestandskluis ontgrendelen + + + + Forgot password? + Wachtwoord vergeten? + + + + Password hint: %1 + Wachtwoordhint: %1 + + + + Failed to unlock file vault + De bestandskluis kan niet worden ontgrendeld + + + + Cancel + button + Annuleren + + + + Password + Wachtwoord + + + + Unlock + button + Ontgrendelen + + + + Please try again %1 minutes later + Probeer het over %1 minuten opnieuw + + + + Wrong password, please try again %1 minutes later + Onjuist wachtwoord - probeer het over %1 minuten opnieuw + + + + Wrong password, one chance left + Onjuist wachtwoord - nog 1 poging te gaan + + + + Wrong password, %1 chances left + Onjuist wachtwoord - nog %1 pogingen te gaan + + + + Wrong password + Onjuist wachtwoord + + + + OK + button + Oké + + + + DFileCopyMoveJob + + + Permission error + Bevoegdheidsfout + + + + The action is denied + De actie is niet toegestaan + + + + Failed to open the file + Openen van bestand mislukt + + + + Failed to read the file + Lezen van bestand mislukt + + + + Failed to write the file + Schrijven naar bestand mislukt + + + + Failed to create the directory + Kan map niet aanmaken + + + + Failed to delete the file + Verwijderen van bestand mislukt + + + + Failed to move the file + Verplaatsen van bestand mislukt + + + + Original file does not exist + Origineel bestand bestaat niet + + + + Failed, file size must be less than 4GB + Mislukt; de bestandsgrootte moet kleiner dan 4 GB zijn + + + + Not enough free space on the target disk + Onvoldoende vrije ruimte op de doelschijf + + + + File integrity was damaged + De bestandsintegriteit is beschadigd + + + + The target device is read only + Het doelapparaat is alleen-lezen + + + + Target folder is inside the source folder + De doelmap staat in de hoofdmap! + + + + The action is not supported + Deze actie wordt niet ondersteund + + + + You do not have permission to traverse files in it + Je bent niet bevoegd om deze map te gebruiken + + + + Failed to position the file pointer! + De bestandsverwijzing kan niet worden gepositioneerd! + + + + copy + Extra name added to new file name when used for file name. + kopiëren + + + + Failed to open the directory, cause: file name too long + De map kan niet worden geopend: de bestandsnaam is te lang. + + + + + Failed to open the file, cause: file name too long + Het bestand kan niet worden geopend: de bestandsnaam is te lang + + + + + Failed to write the file, cause: + Schrijven naar bestand mislukt. Oorzaak: %1 + + + + Failed to position the file pointer, cause: %1 + De bestandsverwijzing kan niet worden gepositioneerd! Oorzaak: %1 + + + + Syncing data + Bezig met synchroniseren… + + + + Please wait + Even geduld… + + + + Failed to create the directory, cause: %1 + De map kan niet worden aangemaakt. Oorzaak: %1 + + + + + + + + Failed to open the file, cause: %1 + Openen van bestand mislukt. Oorzaak: %1 + + + + + + + Failed to open the file, cause: Permission denied + Openen van bestand mislukt. Oorzaak: toegang geweigerd. + + + + + Failed to read the file, cause: %1 + Lezen van bestand mislukt. Oorzaak: %1 + + + + + + + Failed to write the file, cause: %1 + Schrijven naar bestand mislukt. Oorzaak: %1 + + + + + File integrity was damaged, cause: %1 + Bestandsintegriteit is beschadigd. Oorzaak: %1 + + + + Failed to open the file, cause: + Openen van bestand mislukt. Oorzaak: %1 + + + + Failed to read the file, cause: + Lezen van bestand mislukt. Oorzaak: %1 + + + + Failed to delete the file, cause: %1 + Verwijderen van bestand mislukt. Oorzaak: %1 + + + + Fail to create symlink, cause: %1 + Er kan geen snelkoppeling worden gemaakt. Oorzaak: %1 + + + + DFileDialog + + + + Save + button + Opslaan + + + + + Cancel + button + Annuleren + + + + Confirm + button + Oké + + + + %1 already exists, do you want to replace it? + %1 bestaat al. Wil je het vervangen? + + + + Replace + button + Vervangen + + + + Open + button + Openen + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Het bestand wordt verborgen als de bestandsnaam begint met ‘.’. Wil je het verbergen? + + + + DFileManagerWindow + + + Trash + Prullenbak + + + + Empty + Legen + + + + DFileSystemModel + + + + Name + Naam + + + + + + Time modified + Gewijzigd + + + + Size + Grootte + + + + Type + Type + + + + Time created + Aangemaakt op + + + + + Last access + Laatst benaderd + + + + + + + Path + Pad + + + + DFileView + + + Disc mount error + Schijfaankoppelfout + + + + The disc is in use, please end the running process and remount the disc. + De schijf is in gebruik. Beëindig het lopende proces en koppel de schijf opnieuw aan. + + + + Mounting failed + Aankoppelen mislukt + + + + (Reverse) + (Omkeren) + + + + DFileViewHelper + + + Add tag "%1" + ‘%1’-label toekennen + + + + DStatusBar + + + %1 item + %1 item + + + + %1 items + %1 items + + + + %1 item selected + %1 item geselecteerd + + + + %1 items selected + %1 items geselecteerd + + + + %1 folder selected (contains %2) + %1 map geselecteerd (bevat %2) + + + + %1 folders selected (contains %2) + %1 mappen geselecteerd (bevat %2) + + + + %1 file selected (%2) + %1 bestand geselecteerd (%2) + + + + %1 files selected (%2) + %1 bestanden geselecteerd (%2) + + + + %1 folder selected + %1 map geselecteerd + + + + Filter + Filter + + + + Save as: + Opslaan als: + + + + Loading... + Bezig met laden… + + + + DTaskDialog + + + Erasing disc %1, please wait... + Bezig met wissen van %1… + + + + Burning disc %1, please wait... + Bezig met branden van %1… + + + + Writing data... + Bezig met wegschrijven… + + + + Verifying data... + Bezig met verifiëren… + + + + Copying %1 + Bezig met kopiëren van %1 + + + + + + to %2 + naar %2 + + + + %1 already exists in target folder + ‘%1’ staat al in de doelmap + + + + Original path %1 Target path %2 + Oorspronkelijk pad %1 - Doelpad %2 + + + + Merge + button + Samenvoegen + + + + Replace + button + Vervangen + + + + Moving %1 + Bezig met verplaatsen van %1 + + + + Removing file vault, please try later + De bestandskluis wordt vernietigd - probeer het later opnieuw + + + + Restoring %1 + Bezig met herstellen van %1 + + + + Deleting %1 + Bezig met verwijderen van %1 + + + + Trashing %1 + Bezig met verplaatsen van %1 naar de prullenbak + + + + Calculating space, please wait + Bezig met vaststellen van ruimte… + + + + DUMountManager + + + + Authentication timed out + De authenticatie is verlopen + + + + + + Disk is busy, cannot unmount now + Schijf is in gebruik; je kunt nu niet afkoppelen + + + + Disk is busy, cannot eject now + Schijf is in gebruik; je kunt nu niet uitwerpen + + + + The device is busy, cannot eject now + Schijf is in gebruik; je kunt nu niet uitwerpen + + + + + + The device is busy, cannot remove now + Schijf is in gebruik; je kunt nu niet afkoppelen + + + + DeepinStorage + + + + + %1 Volume + Volume %1 + + + + Data Disk + Data Partition + Gegevensschijf + + + + %1 Drive + %1-schijf + + + + Blank %1 Disc + Lege %1-schijf + + + + %1 Encrypted + %1 versleuteld + + + + DialogManager + + + + + + Operation failed! + Operatie mislukt! + + + + Target folder is inside the source folder! + De doelmap staat in de hoofdmap! + + + + Do you want to run %1 or display its content? + Wil je %1 uitvoeren of de inhoud ervan tonen? + + + + It is an executable text file. + Dit is een uitvoerbaar tekstbestand. + + + + It is an executable file. + Dit is een uitvoerbaar bestand. + + + + This file is not executable, do you want to add the execute permission and run? + Dit bestand is niet uitvoerbaar. Wil je het markeren als uitvoerbaar en uitvoeren? + + + + "%1" already exists, please use another name. + "%1" bestaat al. Kies een andere naam. + + + + The file name must not contain two dots (..) + De bestandsnaam mag geen twee punten (..) bevatten + + + + Device or resource busy + Het apparaat of de bron is in gebruik + + + + Are you sure you want to erase all data on the disc? + Weet je zeker dat je alle gegevens op deze schijf definitief wilt verwijderen? + + + + How do you want to use this disc? + Hoe wil je deze schijf gebruiken? + + + + Disc erase failed + Wissen mislukt + + + + Burn process failed + Branden mislukt + + + + %1: %2 + %1: %2 + + + + Show details + Details tonen + + + + Hide details + Details verbergen + + + + Error + Foutmelding + + + + Permanently delete %1? + %1 permanent verwijderen? + + + + Permanently delete %1 items? + %1 items permanent verwijderen? + + + + Empty + Leeg + + + + Do you want to delete %1? + Weet je zeker dat je %1 wilt verwijderen? + + + + Do you want to delete the selected %1 items? + Weet je zeker dat je de %1 geselecteerde items wilt verwijderen? + + + + Sorry, unable to locate your bookmark directory, remove it? + Je bladwijzermap is niet aangetroffen. Wil je deze verwijderen? + + + + Name: + Naam: + + + + %1 that this shortcut refers to has been changed or moved + %1, dat naar deze snelkoppeling verwijst, is gewijzigd of verplaatst + + + + Do you want to delete this shortcut? + Wil je deze snelkoppeling verwijderen? + + + + Failed, file size must be less than 4GB. + Mislukt. De bestandsgrootte moet kleiner dan 4 GB zijn. + + + + Fail to create symlink, cause: + Er kan geen snelkoppeling worden gemaakt. Oorzaak: %1 + + + + The selected files contain system file/directory, and it cannot be deleted + De geselecteerde items bevatten systeembestanden of -mappen, en kunnen niet worden verwijderd + + + + Unable to find the original file + Het oorspronkelijke bestand is niet aangetroffen + + + + + You do not have permission to operate file/folder! + Je bent niet bevoegd om deze map/dit bestand te gebruiken! + + + + Failed to restore %1 file, the source file does not exist + Kan %1 bestand niet terugzetten: het bronbestand bestaat niet + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Je bent niet bevoegd om het/de volgende %1 bestand(en)/map(pen) te gebruiken! + + + + Unable to access %1 + Geen toegang tot %1 + + + + + Sending files now, please try later + De bestanden worden verstuurd - probeer het later opnieuw + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Het apparaat kan pas worden gebruikt als het geformatteerd is. Weet je zeker dat je het nu wilt formatteren? + + + + Scanning the device, stop it? + Wil je het doorzoeken van het apparaat afbreken? + + + + Share folder can't be named after the current username + Gedeelde mappen mogen niet dezelfde naam dragen als de huidige gebruikersnaam + + + + Do you want to run %1? + Weet je zeker dat je %1 wilt uitvoeren? + + + + Burn image + button + Schijfbestand branden + + + + Burn files + button + Bestanden branden + + + + Are you sure you want to empty %1 item? + Weet je zeker dat je %1 item wilt verwijderen? + + + + Are you sure you want to empty %1 items? + Weet je zeker dat je %1 items wilt verwijderen? + + + + + This action cannot be undone + Deze actie kan niet ongedaan worden gemaakt + + + + + + + + + + + + + + OK + button + Oké + + + + + + + + + + + + + + + Cancel + button + Annuleren + + + + + + Run + button + Uitvoeren + + + + + Run in terminal + button + Uitvoeren in terminalvenster + + + + Display + button + Tonen + + + + + + + + + + + Confirm + button + Oké + + + + Erase + button + Wissen + + + + Data verification failed + De gegevens kunnen niet worden geverifieerd + + + + Show details + button + Details tonen + + + + + Delete + button + Verwijderen + + + + Remove + button + Verwijderen + + + + Disk is busy, cannot unmount now + Schijf is in gebruik; je kunt nu niet afkoppelen + + + + Force unmount + button + Afkoppelen forceren + + + + Unable to copy. Not enough free space on the target disk. + Kopiëren mislukt: onvoldoende vrije ruimte op de doelschijf. + + + + Failed to restore %1 file, the target folder is read-only + Kan %1 bestand niet terugzetten: de doelmap is alleen-lezen + + + + Failed to restore %1 files, the target folder is read-only + Kan %1 bestanden niet terugzetten: de doelmap is alleen-lezen + + + + Failed to restore %1 files, the source files do not exist + Kan %1 bestanden niet terugzetten: de bronbestanden bestaan niet + + + + Format + button + Formaat + + + + Stop + button + Afbreken + + + + FileController + + + + + + Unable to find the original file + Het oorspronkelijke bestand is niet aangetroffen + + + + + + Kindly Reminder + Vriendelijke herinnering + + + + + + Please install File Roller first and then continue + Installeer file-roller om door te gaan + + + + + Unable to create files here: %1 + Er kunnen hier geen bestanden worden aangemaakt: %1 + + + + Confirm + button + Oké + + + + FileDialogStatusBar + + + File Name + Bestandsnaam + + + + Format + Formaat + + + + Save + button + Opslaan + + + + Open + button + Openen + + + + Save File + button + Bestand opslaan + + + + Open File + button + Bestand openen + + + + + + Cancel + button + Annuleren + + + + FileJob + + + copy + Kopiëren + + + + + + + Data verification successful. + Gegevens zijn geverifieerd. + + + + + + Burn process completed + Branden voltooid + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 u %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 u %3 m %4 s + + + + %1 is a duplicate file. + %1 is een duplicaat. + + + + Insufficient disc space. + Onvoldoende schijfruimte. + + + + Lost connection to drive. + Verbinding met schijf verbroken. + + + + The CD/DVD drive is not ready. Try another disc. + De CD/DVD is niet gereed. Probeer een andere. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + De CD-/DVD-schijf is bezig. Sluit het programma af waarin deze wordt gebruikt en voer de schijf opnieuw in. + + + + Unknown error + Onbekende fout + + + + Device disconnected + Verbinding met apparaat verbroken + + + + GenerateSettingTranslate + + + + + Basic + Algemeen + + + + + + Open behavior + Openen + + + + + + Always open folder in new window + Mappen altijd openen in nieuw venster + + + + + + Open file: + Bestand openen: + + + + + + Click + Eenmaal klikken + + + + + + Double click + Dubbelklikken + + + + + + New window and tab + Nieuw venster en tabblad + + + + + + Open from default window: + Openen in standaardvenster: + + + + + + + + + Computer + Computer + + + + + + + + + Home + Persoonlijke map + + + + + + + + + Desktop + Bureaublad + + + + + + + + + Videos + Video's + + + + + + + + + Music + Muziek + + + + + + + + + Pictures + Afbeeldingen + + + + + + + + + Documents + Documenten + + + + + + + + + Downloads + Downloads + + + + + + Open in new tab: + Openen op nieuw tabblad: + + + + + + Current Directory + Huidige map + + + + + + View + Weergave + + + + + + Default size: + Standaardgrootte: + + + + + + Extra small + Extra klein + + + + + + Small + Klein + + + + + + Medium + Normaal + + + + + + Large + Groot + + + + + + Extra large + Extra groot + + + + + + Default view: + Standaardweergave: + + + + + + Icon + Pictogram + + + + + + List + Lijst + + + + + + Hidden files + Verborgen bestanden + + + + + + Show hidden files + Verborgen bestanden tonen + + + + + + Hide file extension when rename + Bestandextensie verbergen tijdens naamswijzigingen + + + + + + Advanced + Geavanceerd + + + + + + Index + Indexeren + + + + + + Auto index internal disk + Interne schijf automatisch indexeren + + + + + + Index external storage device after connected to computer + Externe schijf indexeren na aankoppelen + + + + + + Full-Text search + Volledige tekst doorzoeken + + + + + + Show item counts and sizes in the path of mounted MTP devices + Aantal items en groottes tonen op locaties van aangekoppelde mtp-apparaten + + + + + + Keep showing the mounted Samba shares + Aangekoppelde Samba-mappen blijven tonen + + + + + + Use the file chooser dialog of File Manager + Deepin-bestandskiezer gebruiken + + + + + + Ask for my confirmation when deleting files + Om bevestiging vragen bij verwijderen van bestanden + + + + + + Other + Overig + + + + + + Hide system disk + Systeemschijf verbergen + + + + + + Show file system on disk icon + Bestandssyteemlabel tonen op schijfpictogrammen + + + + + + Show hidden files in search results + Verborgen bestanden tonen in zoekresultaten + + + + + + Display recent file entry in left panel + Verwijzing naar recente bestanden tonen in linkerpaneel + + + + + + Preview + Voorbeeld + + + + + Compress file preview + Compressie toepassen op bestandsvoorbeeld + + + + + + Text preview + Tekstvoorbeeld + + + + + + Document preview + Documentvoorbeeld + + + + + + Image preview + Afbeeldingsvoorvertoning + + + + + + Video preview + Videovoorbeeld + + + + + + Mount + Aankoppelen + + + + + + Auto mount + Automatisch aankoppelen + + + + + + Open after auto mount + Openen na automatisch aankoppelen + + + + + + Dialog + Dialoogvenster + + + + Compressed file preview + Ingepakte bestanden voorvertonen + + + + GvfsMountManager + + + Can’t verify the identity of %1. + De identiteit van %1 kan niet worden bevestigd. + + + + This happens when you log in to a computer the first time. + Dit gebeurt als je voor de eerste keer inlogt op een computer. + + + + The identity sent by the remote computer is + De door de andere computer verstuurde identiteit is + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Als je wilt bevestigen dat het veilig is om door te gaan, neem dan contact op met de systeembeheerder. + + + + + + + + Mounting device error + Het apparaat kan niet worden aangekoppeld + + + + + Wrong username or password + Onjuiste gebruikersnaam of wachtwoord + + + + + + + + Confirm + button + Oké + + + + + Cannot find the mounted device + Het aangekoppelde apparaat is niet aangetroffen + + + + No key available to unlock device + Geen sleutel beschikbaar om het apparaat te ontgrendelen + + + + The disk is mounted by user "%1", you cannot unmount it. + De schijf is aangekoppeld door gebruiker "%1". Je kunt deze daarom niet afkoppelen. + + + + Cannot unmount the device + Kan apparaat niet afkoppelen + + + + Cannot eject the device "%1" + Kan apparaat "%1" niet uitwerpen + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Kan niet branden: onvoldoende vrije ruimte op de doelschijf. + + + + MergedDesktopController + + + + Pictures + Afbeeldingen + + + + + Music + Muziek + + + + + Applications + Applicaties + + + + + Videos + Video's + + + + + Documents + Documenten + + + + + Others + Overige + + + + MimeTypeDisplayManager + + + + Directory + Map + + + + + + Application + App + + + + + + Video + Video + + + + + + Audio + Audio + + + + + + Image + Afbeelding + + + + + Archive + Archief + + + + + + Text + Tekst + + + + + Executable + Uitvoerbaar + + + + + Backup file + Backup-bestand + + + + + Unknown + Onbekend + + + + MountAskPasswordDialog + + + Cancel + button + Annuleren + + + + Connect + button + Verbinden + + + + Log in as + Inloggen als + + + + Anonymous + Anoniem + + + + Registered user + Geregistreerde gebruiker + + + + Username + Gebruikersnaam + + + + Domain + Domein + + + + Password + Wachtwoord + + + + Remember password + Wachtwoord onthouden + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Annuleren + + + + Unlock + button + Ontgrendelen + + + + Input password to decrypt the disk + Voer je wachtwoord in om de schijf te ontgrendelen + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Weet je zeker dat je %1 definitief wilt verwijderen? + + + + This file is too big for the trash + Dit bestand is te groot voor de prullenbak + + + + The files are too big for the trash + Deze bestanden zijn te groot voor de prullenbak + + + + Are you sure you want to permanently delete %1 files? + Weet je zeker dat je %1 bestanden definitief wilt verwijderen? + + + + Cancel + button + Annuleren + + + + Delete + button + Verwijderen + + + + OpenWithDialog + + + Open with + Openen met + + + + Add other programs + Andere applicaties toevoegen + + + + Set as default + Instellen als standaard + + + + Cancel + button + Annuleren + + + + Confirm + button + Oké + + + + Recommended Applications + Aanbevolen applicaties + + + + Other Applications + Andere applicaties + + + + PathManager + + + Home + Persoonlijke map + + + + Desktop + Bureaublad + + + + Videos + Video's + + + + Music + Muziek + + + + Pictures + Afbeeldingen + + + + Documents + Documenten + + + + Downloads + Downloads + + + + + Trash + Prullenbak + + + + + + System Disk + Systeemschijf + + + + Computers in LAN + Computers op LAN-netwerk + + + + My Shares + Mijn gedeelde items + + + + Computer + Computer + + + + Recent + Recent + + + + File Vault + Bestandskluis + + + + PropertyDialog + + + Basic info + Basisinformatie + + + + Open with + Openen met + + + + Sharing + Delen + + + + Permissions + Machtigingen + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Deze map verbergen + + + + Hide this file + Dit bestand verbergen + + + + Allow to execute as program + Machtigen om uit te voeren als programma + + + + QObject + + + + + + Size + Grootte + + + + + + Contains + Bevat + + + + + + Type + Type + + + + + + + + Time modified + Gewijzigd + + + + Free space + Vrije ruimte + + + + Total space + Totale ruimte + + + + + Time locked + Tijd vergrendeld + + + + Access denied + Toegang geweigerd + + + + + Executable + Uitvoerbaar + + + + + Write only + Alleen-schrijven + + + + + Read only + Alleen-lezen + + + + + Read-write + Lezen-schrijven + + + + Others + Overig + + + + Owner + Eigenaar + + + + Unconnected network shared directory + Niet verbonden met een gedeelde netwerkmap + + + + Device type + Soort apparaat + + + + File system + Bestandssysteem + + + + Group + Groep + + + + + Open + Openen + + + + Lock + Vergrendelen + + + + Auto lock + Automatisch vergrendelen + + + + Never + Nooit + + + + 5 minutes + 5 minuten + + + + 10 minutes + 10 minuten + + + + 20 minutes + 20 minuten + + + + Delete File Vault + Standaard bestandskluis + + + + Unlock + Ontgrendelen + + + + Unlock by key + Ontgrendelen met sleutel + + + + Open + button + Openen + + + + + Size: %1 + Grootte: %1 + + + + Type: %1 + Type: %1 + + + + Size: 0 + Grootte: 0 + + + + Items: %1 + Items: %1 + + + + + + + + + + Open in new window + Openen in nieuw venster + + + + + + + + + + Open in new tab + Openen op nieuw tabblad + + + + Open with + Openen met + + + + + Compress + Comprimeren + + + + Extract + Uitpakken + + + + Extract here + Hier uitpakken + + + + Cut + Knippen + + + + Copy + Kopiëren + + + + Paste + Plakken + + + + + + + + Rename + Naam wijzigen + + + + + + + Remove + Verwijderen + + + + Create link + Snelkoppeling maken + + + + Send to desktop + Op bureaublad plaatsen + + + + Send to + Versturen naar + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Toevoegen aan bladwijzers + + + + + + + Properties + Eigenschappen + + + + New folder + Nieuwe map + + + + New window + Nieuw venster + + + + Select all + Alles selecteren + + + + + Clear recent history + Recente geschiedenis wissen + + + + + + Empty Trash + Prullenbak legen + + + + Display as + Tonen als + + + + Sort by + Sorteren op + + + + New document + Nieuw document + + + + + Time created + Aangemaakt op + + + + + + Source path + Bronpad + + + + Share folder + Map delen + + + + Cancel sharing + Delen afbreken + + + + Connect to Server + Verbinden met server + + + + Set share password + Gedeeld wachtwoord instellen + + + + Format + Formaat + + + + Tag information + Labelnaam + + + + Open as administrator + Openen met beheerdersbevoegdheid + + + + Select default program + Standaardprogramma kiezen + + + + Open file location + Bestandslocatie openen + + + + Remove bookmark + Bladwijzer verwijderen + + + + + + Delete + Verwijderen + + + + Office Text + Tekstdocument + + + + Spreadsheets + Rekenblad + + + + Plain Text + Platte tekst + + + + Open in terminal + Openen in terminalvenster + + + + Restore + Herstellen + + + + Restore all + Alles herstellen + + + + Clear saved password and unmount + Opgeslagen wachtwoord wissen en ontkoppelen + + + + File Vault + Bestandskluis + + + + Add to disc + Toevoegen aan schijf + + + + Refresh + Herladen + + + + Auto mount + Automatisch aankoppelen + + + + Open after auto mount + Openen na automatisch aankoppelen + + + + + Mount + Aankoppelen + + + + + Unmount + Afkoppelen + + + + It does not support burning %1 discs + Het branden van %1-schijven wordt niet ondersteund + + + + Burn + Branden + + + + Disc name: + Schijfnaam: + + + + + Maximum + Maximaal + + + + Allow files to be added later + Ik wil later nog bestanden toevoegen + + + + Verify data + Gegevens verifiëren + + + + Write speed: + Schrijfsnelheid: + + + + + + + Cancel + button + Annuleren + + + + Burn + button + Branden + + + + + Eject + Uitwerpen + + + + Safely Remove + Veilig verwijderen + + + + + Name + Naam + + + + Settings + Instellingen + + + + Exit + Afsluiten + + + + Icon + Pictogram + + + + List + Lijst + + + + Extend + Uitklappen + + + + Set as wallpaper + Instellen als achtergrond + + + + + + + Local disk + Lokale schijf + + + + + Removable disk + Verwijderbare schijf + + + + + + Network shared directory + Gedeelde netwerkmap + + + + + Android mobile device + Mobiel Android-apparaat + + + + + Apple mobile device + Mobiel Apple-apparaat + + + + + Camera + Camera + + + + + DVD + DVD + + + + + Unknown device + Onbekend apparaat + + + + + + %1 item + %1 item + + + + + + %1 items + %1 items + + + + Shortcut + Snelkoppeling + + + + Create symlink + Snelkoppeling maken + + + + Path + Pad + + + + + + Time deleted + Verwijderd om + + + + Loading... + Bezig met laden… + + + + File has been moved or deleted + Bestand is verplaatst of verwijderd + + + + You do not have permission to traverse files in it + Je bent niet bevoegd om deze map te gebruiken + + + + + + You do not have permission to access this folder + Je bent niet bevoegd om deze map te openen + + + + + + + + Folder is empty + Map is leeg + + + + Searching... + Bezig met zoeken… + + + + No results + Geen resultaten + + + + Source Path + TrashFileInfo + Bronpad + + + + Document + Document + + + + Spreadsheet + Rekenblad + + + + + Presentation + Presentatie + + + + Text + Tekst + + + + 1 task in progress + Er wordt 1 taak uitgevoerd + + + + %1 tasks in progress + Er worden 1% taken uitgevoerd + + + + Mode: + Modus: + + + + + Replace Text + Tekst vervangen + + + + + Add Text + Tekst toevoegen + + + + + Custom Text + Aangepaste tekst + + + + Find: + Zoeken: + + + + Replace: + Vervangen: + + + + + Optional + Optioneel + + + + Add: + Toevoegen: + + + + Location: + Locatie: + + + + File name: + Bestandsnaam: + + + + Start at: + Beginnen bij: + + + + + Rename + button + Naam wijzigen + + + + + + + + + + + Required + Vereist + + + + + Before file name + Vóór de bestandsnaam + + + + + After file name + Achter de bestandsnaam + + + + Find + Zoeken + + + + Replace + Vervangen + + + + Add + Toevoegen + + + + Start at + Beginnen bij + + + + + + Location + Locatie + + + + File name + Bestandsnaam + + + + Dimension + Afmetingen + + + + Duration + Duur + + + + Tips: Sort by selected file order + Tip: sorteren op geselecteerde bestandsvolgorde + + + + Rename %1 Files + %1 bestandsnamen wijzigen + + + + Multiple Files + Meerdere bestanden + + + + Basic info + Basisinformatie + + + + Total size + Totale grootte + + + + Number of files + Aantal bestanden + + + + %1 file(s), %2 folder(s) + %1 bestand(en), %2 map(pen) + + + + + + Time accessed + Benaderd op + + + + Orange + Oranje + + + + Red + Rood + + + + Purple + Paars + + + + Navy-blue + Marineblauw + + + + Azure + Groenblauw + + + + Green + Groen + + + + Yellow + Geel + + + + Gray + Grijs + + + + Input tag info, such as work, family. A comma is used between two tags. + Voer een labelnaam in, bijv. werk of familie. Labels zijn kommagescheiden. + + + + Bookmarks + Bladwijzers + + + + Erase + Wissen + + + + Copy path + Pad kopiëren + + + + Edit address + Locatie invoeren + + + + Free Space %1 + Vrije ruimte %1 + + + + Files are being processed + De bestanden worden verwerkt + + + + + Unknown + Onbekend + + + + My Vault + Mijn kluis + + + + + Failed to create file info + Kan geen bestandsinformatie samenstellen + + + + Failed to create file handler + Kan geen bestandshandeling aanmaken + + + + Failed to open the file, cause: %1 + Openen van bestand mislukt. Oorzaak: %1 + + + + Original file does not exist + Origineel bestand bestaat niet + + + + Do you want to delete %1? + Weet je zeker dat je %1 wilt verwijderen? + + + + Confirm + button + Oké + + + + + + + + %1 are not allowed + %1 is niet toegestaan + + + + + Failed to start Samba services + De Samba-diensten kunnen niet worden gestart + + + + RecentController + + + Cancel + button + Annuleren + + + + Remove + button + Verwijderen + + + + Do you want to remove this item? + Wil je dit item verwijderen? + + + + Do yout want to remove %1 items? + Wil je %1 items verwijderen? + + + + It does not delete the original files + De oorspronkelijke bestanden worden niet verwijderd + + + + ShareInfoFrame + + + Share this folder + Deze map delen + + + + Share name: + Deelnaam: + + + + Permission: + Machtiging: + + + + Read and write + Lezen en schrijven + + + + Read only + Alleen-lezen + + + + Anonymous: + Anoniem: + + + + Not allow + Niet machtigen + + + + Allow + Machtigen + + + + The share name must not be two dots (..) or one dot (.) + Het gedeelde bestand mag geen .. of . bevatten. + + + + The share name is used by another user. + Het gedeelde item is in gebruik door een andere gebruiker. + + + + OK + button + Oké + + + + Cancel + button + Annuleren + + + + Replace + button + Vervangen + + + + The share name already exists. Do you want to replace the shared folder? + Het gedeelde item bestaat al. Wil je het vervangen? + + + + Shortcut + + + Item + Item + + + + Select to the first item + Selecteren tot eerste item + + + + Shift + Home + Shift + Home + + + + Select to the last item + Selecteren tot laatste item + + + + Shift + End + Shift + End + + + + Select leftwards + Naar links selecteren + + + + Shift + Left + Shift + Pijltje links + + + + Select rightwards + Naar rechts selecteren + + + + Shift + Right + Shift + Pijltje rechts + + + + Select to upper row + Naar boven selecteren + + + + Shift + Up + Shift + Pijltje omhoog + + + + Select to lower row + Naar onder selecteren + + + + Shift + Down + Shift + Pijltje omlaag + + + + Open + Openen + + + + Ctrl + Down + Ctrl + Pijltje omlaag + + + + To parent directory + Naar bovenliggende map + + + + Ctrl + Up + Ctrl + Pijltje omhoog + + + + Permanently delete + Permanent verwijderen + + + + Shift + Delete + Shift + Delete + + + + Delete file + Bestand verwijderen + + + + Delete + Verwijderen + + + + Select all + Alles selecteren + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Kopiëren + + + + Cut + Knippen + + + + Paste + Plakken + + + + Rename + Naam wijzigen + + + + F2 + F2 + + + + New/Search + Nieuw/Zoeken + + + + New window + Nieuw venster + + + + New folder + Nieuwe map + + + + + Search + Zoeken + + + + New tab + Nieuw tabblad + + + + View + Tonen + + + + Item information + Iteminformatie + + + + Help + Hulp + + + + F1 + F1 + + + + Keyboard shortcuts + Sneltoetsen + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Weergavestatus omschakelen + + + + Hide item + Item verbergen + + + + Input in address bar + Invoeren in adresbalk + + + + Switch to icon view + Overschakelen naar pictogramweergave + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Overschakelen naar lijstweergave + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Overig + + + + Close + Sluiten + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Huidig tabblad sluiten + + + + Back + Terug + + + + Alt + Left + Alt + Pijltje links + + + + Alt + Right + Alt + Pijltje rechts + + + + Switch to next tab + Overschakelen naar volgend tabblad + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Overschakelen naar vorig tabblad + + + + Next file + Volgend bestand + + + + Tab + Tab + + + + Previous file + Vorig bestand + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Schakelen tussen tabbladen met cijfertoetsen 1-8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Vooruit + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Items kunnen niet worden geopend vanuit de prullenbak - zet ze eerst terug. + + + + TrashPropertyDialog + + + Trash + Prullenbak + + + + item + item + + + + items + items + + + + Contains %1 %2 + Bevat %1 %2 + + + + UDiskListener + + + Failed to rename the label + De labelnaam kan niet worden gewijzigd + + + + UnmountWorker + + + + + The device was not safely unmounted + Het apparaat is niet veilig verwijderd + + + + The device was not safely removed + Het apparaat is niet veilig verwijderd + + + + UserShareManager + + + Kindly Reminder + Vriendelijke herinnering + + + + Please firstly install samba to continue + Installeer samba om door te gaan + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + De itemnaam mag niet beginnen met %1 en geen van de volgende tekens bevatten: %<>*?|/\+=;:," + + + + To protect the files, you cannot share this folder. + Om de bestanden te beschermen, kunt u deze map niet delen. + + + + Sharing failed + Delen mislukt + + + + The computer name is too long + De computernaam is te lang + + + + You do not have permission to operate file/folder! + Je bent niet bevoegd om deze map/dit bestand te gebruiken! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Voer een wachtwoord in om gedeelde mappen te beveiligen + + + + Cancel + button + Annuleren + + + + Confirm + button + Oké + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_pa.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_pa.ts new file mode 100644 index 0000000..b476393 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_pa.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + ਕੰਪਿਊਟਰ + + + + Basic Info + ਮੁੱਢਲੀ ਜਾਣਕਾਰੀ + + + + Computer Name + + + + + Version + + + + + Type + ਕਿਸਮ + + + + Processor + ਪਰੋਸੈਸਰ + + + + Memory + + + + + Disk + ਡਿਸਕ + + + + Bit + ਬਿੱਟ + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + + + + + DFMAdvanceSearchBar + + + Search: + + + + + File Type: + + + + + File Size: + + + + + Time Modified: + + + + + Reset + + + + + All subdirectories + + + + + Current directory + + + + + 0 ~ 100 KB + + + + + 100 KB ~ 1 MB + + + + + 1 MB ~ 10 MB + + + + + 10 MB ~ 100 MB + + + + + 100 MB ~ 1 GB + + + + + > 1 GB + + + + + Today + + + + + Yesterday + + + + + This week + + + + + Last week + + + + + This month + + + + + Last month + + + + + This year + + + + + Last year + + + + + DFMTagCrumbController + + + Tag information + + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + + + + + The action is denied + + + + + Failed to open the file + + + + + Failed to read the file + + + + + Failed to write the file + + + + + Failed to create the directory + + + + + Failed to delete the file + + + + + Failed to move the file + + + + + Original file does not exist + + + + + Failed, file size must be less than 4GB + + + + + Not enough free space on the target disk + + + + + File integrity was damaged + + + + + The target device is read only + + + + + Target folder is inside the source folder + + + + + copy + Extra name added to new file name when used for file name. + + + + + Failed to create the directory, cause: %1 + + + + + + Failed to open the file, cause: %1 + + + + + Failed to read the file, cause: %1 + + + + + Failed to write the file, cause: %1 + + + + + File integrity was damaged, cause: %1 + + + + + Failed to delete the file, cause: %1 + + + + + Fail to create symlink, cause: %1 + + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + + + + + Cancel + + + + + Replace + + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + ਨਾਂ + + + + + + Time modified + ਸੋਧ ਕਰਨ ਦਾ ਵੇਲਾ + + + + Size + ਆਕਾਰ + + + + Type + + + + + Time created + ਬਣਾਉਣ ਵੇਲਾ + + + + + Last access + + + + + Path + + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + + + + + DFileViewHelper + + + Add tag "%1" + + + + + DStatusBar + + + %1 item + %1 ਚੀਜ਼ + + + + %1 items + %1 ਚੀਜ਼ਾਂ + + + + %1 item selected + %1 ਚੀਜ਼ ਚੁਣੀ + + + + %1 items selected + %1 ਚੀਜ਼ਾਂ ਚੁਣੀਆਂ + + + + %1 folder selected (contains %2) + %1 ਫੋਲਡਰ ਚੁਣਿਆ (%2 ਰੱਖਦਾ ਹੈ) + + + + %1 folders selected (contains %2) + %1 ਫੋਲਡਰ ਚੁਣਿਆ (%2 ਰੱਖਦਾ ਹੈ) + + + + %1 file selected (%2) + %1 ਫਾਇਲ ਚੁਣੀ (%2) + + + + %1 files selected (%2) + %1 ਫਾਇਲਾਂ ਚੁਣੀਆਂ (%2) + + + + %1 folder selected + + + + + Filter + ਫਿਲਟਰ + + + + Save as: + ਇੰਞ ਸੰਭਾਲੋ: + + + + Loading... + ...ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ + + + + DTaskDialog + + + This action is not supported + + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + + + + + Data Disk + Data Partition + + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + ਕਾਰਵਾਈ ਅਸਫ਼ਲ ਹੈ! + + + + Target folder is inside the source folder! + + + + + + + + + + + + + + OK + ਠੀਕ ਹੈ + + + + Do you want to run %1 or display its content? + + + + + It is an executable text file. + + + + + + + + + + + + + + + Cancel + ਰੱਦ ਕਰੋ + + + + + + Run + ਚਲਾਓ + + + + + Run in terminal + ਟਰਮੀਨਲ 'ਚ ਚਲਾਓ + + + + Display + ਵੇਖਾਓ + + + + It is an executable file. + + + + + This file is not executable, do you want to add the execute permission and run? + + + + + "%1" already exists, please use another name. + + + + + + + + + Confirm + ਤਸਦੀਕ ਕਰੋ + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + %1 ਨੂੰ ਪੱਕੇ ਤੌਰ ਉੱਤੇ ਹਟਾਉਣਾ ਹੈ? + + + + Permanently delete %1 items? + %1 ਚੀਜ਼ਾਂ ਨੂੰ ਪੱਕੇ ਤੌਰ ਉੱਤੇ ਹਟਾਉਣਾ ਹੈ? + + + + Delete + ਹਟਾਓ + + + + Empty + + + + + Sorry, unable to locate your bookmark directory, remove it? + + + + + Remove + ਹਟਾਓ + + + + Name: + ਨਾਂ: + + + + Force unmount + ਧੱਕੇ ਨਾਲ ਅਣ-ਮਾਊਂਟ ਕਰੋ + + + + %1 that this shortcut refers to has been changed or moved + + + + + Do you want to delete this shortcut? + + + + + Failed, file size must be less than 4GB. + + + + + Fail to create symlink, cause: + + + + + The selected files contain system file/directory, and it cannot be deleted + ਚੁਣੀਆਂ ਫਾਇਲਾਂ ਸਿਸਟਮ ਫਾਇਲਾਂ/ਡਾਇਰੈਕਟਰੀ ਰੱਖਦੀਆਂ ਹਨ, ਤੇ ਹਟਾਈਆਂ ਨਹੀਂ ਜਾ ਸਕਦੀਆਂ + + + + + You do not have permission to operate file/folder! + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + + + + + View + + + + + Do you want to run %1? + + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + + + + + Please restore by the following steps to normally access Windows disk + + + + + 1. Reboot to enter Windows + + + + 3. Reboot and enter deepin + + + + + Reboot + + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + + + + + Format + + + + + Cancel + + + + + Save + + + + + Open + + + + + Save File + + + + + Open File + + + + + FileJob + + + copy + ਕਾਪੀ ਕਰੋ + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + %1 ਸ + + + + %1 m %2 s + %1 ਮਿੰ %2 ਸ + + + + %1 h %2 m %3 s + %1 ਘੰ %2 ਮਿੰ %3 ਸ + + + + %1 d %2 h %3 m %4 s + %1 ਦਿ %2 ਘੰ %3 ਮਿੰ %4 ਸ + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + + + + + + + Open behavior + + + + + + + Always open folder in new window + + + + + + + Open file: + + + + + + + Click + + + + + + + Double click + + + + + + + New window and tab + + + + + + + Open from default window: + + + + + + + + + + Computer + + + + + + + + + + Home + + + + + + + + + + Desktop + + + + + + + + + + Videos + + + + + + + + + + Music + + + + + + + + + + Pictures + + + + + + + + + + Documents + + + + + + + + + + Downloads + + + + + + + Open in new tab: + + + + + + + Current Directory + + + + + + + View + + + + + + + Default size: + + + + + + + Extra small + + + + + + + Small + + + + + + + Medium + + + + + + + Large + + + + + + + Extra large + + + + + + + Default view: + + + + + + + Icon + + + + + + + List + + + + + + + Hidden files + + + + + + + Show hidden files + + + + + + + Hide file extension when rename + + + + + + + Advanced + + + + + + + Index + + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + + + + + + + Hide system disk + + + + + + + Show hidden files in search results + + + + + + + Display recent file entry in left panel + + + + + + + Preview + + + + + + Compress file preview + + + + + + + Text preview + + + + + + + Document preview + + + + + + + Image preview + + + + + + + Video preview + + + + + + + Mount + + + + + + + Auto mount + + + + + + + Open after auto mount + + + + + + + Dialog + + + + Use the file chooser dialog of Deepin File Manager + + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + + + + + + + + + Confirm + + + + + + Cannot find the mounting device + + + + + Cannot unmount the device + + + + + Cannot eject the device "%1" + + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + + + + + + + Application + + + + + + + Video + + + + + + + Audio + + + + + + + Image + + + + + + Archive + + + + + + + Text + + + + + + Executable + + + + + + Backup file + + + + + + Unknown + + + + + MountAskPasswordDialog + + + Cancel + + + + + Connect + ਕਨੈਕਟ ਕਰੋ + + + + Log in as + ਇਸ ਵਜੋਂ ਲਾਗਇਨ ਕਰੋ + + + + Anonymous + ਅਣਪਛਾਤਾ + + + + Registered user + ਰਜਿਸਟਰ ਕੀਤਾ ਵਰਤੋਂਕਾਰ + + + + Username + ਵਰਤੋਂਕਾਰ-ਨਾਂ + + + + Domain + + + + + Password + ਪਾਸਵਰਡ + + + + Remember password + ਪਾਸਵਰਡ ਯਾਦ ਰੱਖੋ + + + + MountSecretDiskAskPasswordDialog + + + Cancel + + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + ਛੱਡੋ + + + Keep both + ਦੋਵੇ ਰੱਖੋ + + + Replace + ਤਬਦੀਲ ਕਰੋ + + + Do not ask again + ਮੁੜ ਨਾ ਪੁੱਛੋ + + + merge + + + + Copying %1 + + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + %2 ਉੱਤੇ ਕਾਪੀ ਕਰੋ + + + Moving %1 + + + + Move to %2 + %2 ਉੱਤੇ ਭੇਜੋ + + + Restoring %1 + % ਬਹਾਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ + + + Restore to %2 + %2 ਲਈ ਬਹਾਲ ਕਰੋ + + + Deleting %1 + %1 ਨੂੰ ਹਟਾਇਆ ਜਾ ਰਿਹਾ ਹੈ + + + Trashing %1 + + + + Calculating space, please wait + ਥਾਂ ਦੀ ਗਿਣਤੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ, ਉਡੀਕੋ ਜੀ + + + File named %1 already exists in target folder + %1 ਫਾਇਲ ਨਾਂ ਪਹਿਲਾਂ ਹੀ ਨਿਯਤ ਫੋਲਡਰ ਵਿੱਚ ਮੌਜੂਦ ਹੈ + + + Original path %1 target path %2 + + + + Retry + + + + Time modified:%1 + + + + Original folder + + + + Original file + + + + Target folder + + + + Target file + + + + Contains:%1 + + + + Size:%1 + + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + + + + + Delete + ਹਟਾਓ + + + + OpenWithDialog + + + Open with + ਇਸ ਨਾਲ ਖੋਲ੍ਹੋ + + + + Add other programs + + + + + Set as default + + + + + Cancel + ਰੱਦ ਕਰੋ + + + + Confirm + + + + + Recommended Applications + + + + + Other Applications + + + + + PathManager + + + Home + ਘਰ + + + + Desktop + ਡੈਸਕਟਾਪ + + + + Videos + + + + + Music + ਸੰਗੀਤ + + + + Pictures + ਤਸਵੀਰਾਂ + + + + Documents + ਡੌਕੂਮੈਂਟ + + + + Downloads + ਡਾਊਨਲੋਡ + + + + + Trash + + + + + + System Disk + ਸਿਸਟਮ ਡਿਸਕ + + + + Computers in LAN + LAN ਵਿੱਚ ਕੰਪਿਊਟਰ + + + + My Shares + + + + + Computer + ਕੰਪਿਊਟਰ + + + + Recent + + + + + PropertyDialog + + + Basic info + ਮੁੱਢਲੀ ਜਾਣਕਾਰੀ + + + + Open with + ਇਸ ਨਾਲ ਖੋਲ੍ਹੋ + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + ਪਰੋਗਰਾਮ ਵਜੋਂ ਚਲਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ + + + + QObject + + + + + Size + ਆਕਾਰ + + + + + + Contains + + + + + + + Type + ਕਿਸਮ + + + + + + + Time modified + ਸੋਧਣ ਦਾ ਵੇਲਾ + + + + Free space + ਖਾਲੀ ਥਾਂ + + + + Total space + + + + + Access denied + + + + + + Executable + + + + + + Write only + + + + + + Read only + + + + + + Read-write + + + + + Others + + + + + Owner + ਮਾਲਕ + + + + Device type + + + + + File system + + + + + Group + ਗਰੁੱਪ + + + + + + Open + ਖੋਲ੍ਹੋ + + + + + Size: %1 + + + + + Type: %1 + + + + + Size: 0 + + + + + Items: %1 + + + + + + + + + + + + Open in new window + + + + + + + + + + + + Open in new tab + ਨਵੀਂ ਟੈਬ ਵਿੱਚ ਖੋਲ੍ਹੋ + + + + Open with + + + + + Compress + ਨਪੀੜੋ + + + + Extract + ਖਿਲਾਰੋ + + + + Extract here + + + + + Cut + ਕੱਟੋ + + + + Copy + ਕਾਪੀ ਕਰੋ + + + + Paste + ਚੇਪੋ + + + + + + + + + + Rename + ਨਾਂ ਬਦਲੋ + + + + + + Remove + + + + + Create link + + + + + Send to desktop + ਡੈਸਕਟਾਪ ਉੱਤੇ ਭੇਜੋ + + + + Send to + + + + + Add to bookmark + ਬੁੱਕਮਾਰਕ 'ਚ ਜੋੜੋ + + + + + + + Properties + + + + + New folder + ਨਵਾਂ ਫੋਲਡਰ + + + + New window + + + + + Select all + ਸਾਰੇ ਚੁਣੋ + + + + + Clear recent history + ਤਾਜ਼ਾ ਅਤੀਤ ਸਾਫ਼ ਕਰੋ + + + + + + Empty Trash + ਰੱਦੀ ਖਾਲੀ ਕਰੋ + + + + Display as + ਇੰਞ ਵੇਖਾਓ + + + + Sort by + ਲੜੀਬੱਧ + + + + New document + + + + + + Time created + ਬਣਾਉਣ ਦਾ ਵੇਲਾ + + + + Log out and unmount + ਲਾਗ ਆਉਟ ਤੇ ਅਣ-ਮਾਊਂਟ ਕਰੋ + + + + + + Source path + + + + + Share folder + ਸਾਂਝਾ ਫੋਲਡਰ + + + + Cancel sharing + ਸਾਂਝਾ ਕਰਨਾ ਰੱਦ ਕਰੋ + + + + Connect to Server + + + + + Set share password + + + + + Format + ਫਾਰਮੈਟ ਕਰੋ + + + + Tag information + + + + + Open in new window as admin + ਨਵੀਂ ਵਿੰਡੋ ਵਿੱਚ ਪਰਸ਼ਾਸ਼ਕ ਵਜੋਂ ਖੋਲ੍ਹੋ + + + + Select default program + + + + + Open file location + + + + + Remove bookmark + + + + + + + Delete + + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + ਟਰਮੀਨਲ 'ਚ ਖੋਲ੍ਹੋ + + + + Restore + ਬਹਾਲ ਕਰੋ + + + + Restore all + + + + + File Vault + + + + + Auto mount + + + + + Open after auto mount + + + + + + Mount + ਮਾਊਂਟ ਕਰੋ + + + + + Unmount + + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + + + + + Safely Remove + + + + + + Name + ਨਾਂ + + + + Settings + ਸੈਟਿੰਗਾਂ + + + + Exit + ਬਾਹਰ + + + + Icon + ਚਿੰਨ੍ਹ + + + + List + ਸੂਚੀ + + + + Extend + + + + + Set as wallpaper + + + + + + + + Local disk + + + + + + Removable disk + ਹਟਾਉਣਯੋਗ ਡਿਸਕ + + + + + + Network shared directory + ਨੈੱਟਵਰਕ ਸਾਂਝੀ ਕੀਤੀ ਡਾਇਰੈਕਟਰੀ + + + + + Android mobile device + ਐਂਡਰਾਇਡ ਮੋਬਾਈਲ ਡਿਵਾਈਸ + + + + + Apple mobile device + + + + + + Camera + ਕੈਮਰਾ + + + + + DVD + + + + + + Unknown device + ਅਣਪਛਾਤਾ ਡਿਵਾਈਸ + + + + + + %1 item + %1 ਚੀਜ਼ + + + + + + %1 items + + + + + Shortcut + + + + + Create symlink + ਸਿਮ-ਲਿੰਕ ਬਣਾਓ + + + + Path + ਮਾਰਗ + + + + + + Time deleted + ਹਟਾਉਣ ਦਾ ਵੇਲਾ + + + + Loading... + ...ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ + + + + File has been moved or deleted + ਫਾਇਲ ਨੂੰ ਹਿਲਾਇਆ ਜਾਂ ਹਟਾਇਆ ਗਿਆ ਹੈ + + + + + + You do not have permission to access this folder + ਤੁਹਾਡੇ ਕੋਲ ਇਸ ਫੋਲਡਰ ਲਈ ਪਹੁੰਚ ਨਹੀਂ ਹੈ + + + + + + + Folder is empty + ਫੋਲਡਰ ਖਾਲੀ ਹੈ + + + + Path + SearchFileInfo + ਮਾਰਗ + + + + Searching... + + + + + No results + + + + + Source Path + TrashFileInfo + ਸਰੋਤ ਮਾਰਗ + + + + Document + + + + + Spreadsheet + + + + + + Presentation + + + + + Text + + + + + 1 task in progress + + + + + %1 tasks in progress + + + + + Mode: + + + + + + Replace Text + + + + + + Add Text + + + + + + Custom Text + + + + + Find: + + + + + Replace: + + + + + + Optional + + + + + Add: + + + + + Location: + + + + + File name: + + + + + +SN: + + + + + + + + + + + Required + + + + + + Before file name + + + + + + After file name + + + + + Find + + + + + Replace + + + + + Add + + + + + + + Location + + + + + File name + + + + + Dimension + + + + + Duration + + + + + +SN + + + + + Tips: Sort by selected file order + + + + + + + Cancel + + + + + Rename %1 Files + + + + + Multiple Files + + + + + Basic info + + + + + Total size + + + + + Number of files + + + + + %1 file(s), %2 folder(s) + + + + + + + Time accessed + + + + + Orange + + + + + Red + + + + + Purple + + + + + Navy-blue + + + + + Azure + + + + + Green + + + + + Yellow + + + + + Gray + + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + + + + + Erase + + + + + + Copy path + + + + + + Edit address + + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + ਇਹ ਫੋਲਡਰ ਸਾਂਝਾ ਕਰੋ + + + + Share name: + ਸਾਂਝ ਦਾ ਨਾਂ: + + + + Permission: + ਇਜਾਜ਼ਤ: + + + + Read and write + ਪੜ੍ਹਨ ਅਤੇ ਲਿਖਣ + + + + Read only + ਸਿਰਫ਼ ਪੜ੍ਹਨ ਲਈ + + + + Anonymous: + ਅਣਪਛਾਤਾ: + + + + Not allow + ਆਗਿਆ ਨਹੀਂ + + + + Allow + ਆਗਿਆ + + + + Shortcut + + + Item + ਚੀਜ਼ + + + + Select to the first item + ਪਹਿਲਾਂ ਚੀਜ਼ ਚੁਣੋ + + + + Shift + Home + + + + + Select to the last item + ਆਖਰੀ ਚੀਜ਼ ਲਈ ਚੁਣੋ + + + + Shift + End + Shift + End + + + + Select leftwards + ਖੱਬੇ ਵੱਲ ਚੁਣੋ + + + + Shift + Left + + + + + Select rightwards + ਸੱਜੇ ਵੱਲ ਚੁਣੋ + + + + Shift + Right + Shift + Right + + + + Select to upper row + + + + + Shift + Up + Shift + Up + + + + Select to lower row + ਹੇਠਲੀ ਕਤਾਰ ਲਈ ਚੁਣੋ + + + + Shift + Down + + + + + Open + ਖੋਲ੍ਹੋ + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + ਮੁੱਢਲੀ ਡਾਇਰੈਕਟਰੀ ਉੱਤੇ + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + ਪੱਕੇ ਤੌਰ 'ਤੇ ਹਟਾਓ + + + + Shift + Delete + + + + + Delete file + + + + + Delete + ਹਟਾਓ + + + + Select all + + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + ਕਾਪੀ ਕਰੋ + + + + Cut + + + + + Paste + ਚੇਪੋ + + + + Rename + + + + + F2 + F2 + + + + New/Search + ਨਵਾਂ/ਖੋਜੋ + + + + New window + + + + + New folder + ਨਵਾਂ ਫੋਲਡਰ + + + + + Search + + + + + New tab + ਨਵੀਂ ਟੈਬ + + + + View + ਵੇਖੋ + + + + Item information + ਚੀਜ਼ ਦੀ ਜਾਣਕਾਰੀ + + + + Help + ਮਦਦ + + + + F1 + F1 + + + + Keyboard shortcuts + ਕੀਬੋਰਡ ਸ਼ਾਰਟਕੱਟ + + + + Ctrl + Shift + / + + + + + Switch display status + ਡਿਸਪਲੇਅ ਹਾਲਤ ਲਈ ਬਦਲੋ + + + + Hide item + ਚੀਜ਼ ਲੁਕੋਵੋ + + + + Input in address bar + ਸਿਰਨਾਵਾਂ ਪੱਟੀ ਵਿੱਚ ਦਰਜ ਕਰੋ + + + + Switch to icon view + + + + + Ctrl + 1 + + + + + Switch to list view + + + + + Ctrl + 2 + + + + + Others + ਹੋਰ + + + + Close + ਬੰਦ ਕਰੋ + + + + Alt + F4 + Alt + F4 + + + + Close current tab + ਮੌਜੂਦਾ ਟੈਬ ਬੰਦ ਕਰੋ + + + + Back + ਪਿੱਛੇ + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + ਅਗਲੀ ਟੈਬ ਉੱਤੇ ਜਾਓ + + + + Ctrl + Tab + + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + ਪਿਛਲੀ ਟੈਬ ਉੇੱਤੇ ਜਾਓ + + + + Next file + ਅਗਲੀ ਫਾਇਲ + + + + Tab + ਟੈਬ + + + + Previous file + ਪਿਛਲੀ ਫਾਇਲ + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + + + + + Alt + [1-8] + + + + + Forward + + + + + TrashPropertyDialog + + + Trash + + + + + item + + + + + items + ਚੀਜ਼ਾਂ + + + + Contains %1 %2 + %1 %2 ਰੱਖਦਾ ਹੈ + + + + UDiskListener + + + Failed to rename the label + + + + + UserShareManager + + + Kindly Reminder + + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + ਰੱਦ ਕਰੋ + + + + Confirm + ਤਸਦੀਕ ਕਰੋ + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_pl.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_pl.ts new file mode 100644 index 0000000..d18e807 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_pl.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Nowy katalog + + + + Mounting device error + Błąd montowania urządzenia + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Obraz dysku jest uszkodzony, nie można go teraz zamontować, najpierw usuń dysk + + + + Mount error: unsupported image format + Błąd montowania: nieobsługiwany format obrazu + + + + + The device was not safely removed + Urządzenie nie zostało bezpiecznie usunięte + + + + + Click "Safely Remove" and then disconnect it next time + Kliknij „Bezpieczne usuwanie”, a następnie odłącz go następnym razem + + + + The device was not ejected + Urządzenie nie zostało wysunięte + + + + Disk is busy, cannot eject now + Dysk jest zajęty, nie można go teraz wysunąć + + + + Authentication timed out + Upłynął limit czasu uwierzytelniania + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Transfer plików Bluetooth + + + + File Transfer Successful + Przesyłanie pliku powiodło się + + + + File Transfer Failed + Przesyłanie pliku nie powiodło się + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Wysyłanie plików do "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Błąd wysyłania plików do "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Wysłanie do "<b style="font-weight: 550;">%1</b>" zakończone pomyślnie + + + + Select a Bluetooth device to receive files + Wybierz urządzenie Bluetooth, aby odbierać pliki + + + + Cannot find the connected Bluetooth device + Nie można znaleźć podłączonego urządzenia Bluetooth + + + + Waiting to be received... + Czekam na otrzymanie... + + + + Go to Bluetooth Settings + Przejdź do ustawień Bluetooth + + + + %1/%2 Sent + %1/%2 Wysłane + + + + Error: the Bluetooth device is disconnected + Błąd: urządzenie Bluetooth jest odłączone + + + + Unable to send the file more than 2 GB + Nie można wysłać pliku większego niż 2 GB + + + + Unable to send 0 KB files + Nie można wysłać plików 0 KB + + + + File doesn't exist + Plik nie istnieje + + + + Next + button + Dalej + + + + Cancel + button + Anuluj + + + + Done + button + Gotowe + + + + Retry + button + Ponów + + + + OK + button + OK + + + + File sending request timed out + Żądanie wysłania pliku zajmuje zbyt dużo czasu + + + + The service is busy and unable to process the request + Usługa jest zajęta i niezdolna do przetworzenia żądania + + + + BurnOptDialog + + + Device error + Błąd urządzenia + + + + Optical device %1 doesn't exist + Urządzenie optyczne %1 nie istnieje + + + + Advanced settings + Ustawienia zaawansowane + + + + File system: + System plików: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Dla Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Dla Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Kompatybilny z trybem CD-DVD w Windows) + + + + ISO9660 Only + Wyłącznie ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Zamknij wszystkie + + + + Total size: %1, %2 files + Całkowity rozmiar: %1, %2 plików + + + + ComputerModel + + + Double click to open it + Podwójne kliknięcie, aby otworzyć + + + + My Directories + Moje katalogi + + + + Disks + Dyski + + + + File Vault + Skarbiec Plików + + + + Quick Access + Szybki Dostęp + + + + ComputerPropertyDialog + + + Computer + Komputer + + + + Basic Info + Podstawowe informacje + + + + + Computer Name + Nazwa komputera + + + + + Edition + Wydanie + + + + + + Version + Wersja + + + + + Type + Rodzaj + + + + + + Processor + Procesor + + + + + + Memory + Pamięć + + + + + + + Bit + Bitów + + + + + Available + Dostępny + + + + Obtaining... + Pobieranie... + + + + ConnectToServerDialog + + + Connect to Server + Połącz z serwerem + + + + Cancel + button + Anuluj + + + + Connect + button + Połącz + + + + My Favorites: + Moje ulubione: + + + + + Clear History + Wyczyść historię + + + + DFMAddressBar + + + Search or enter address + Szukaj lub wpisz adres + + + + DFMAdvanceSearchBar + + + Search: + Szukaj: + + + + File Type: + Typ pliku: + + + + File Size: + Rozmiar pliku: + + + + Time Modified: + Data modyfikacji: + + + + Time Accessed: + Ostatni dostęp: + + + + Time Created: + Data utworzenia: + + + + Reset + Resetuj + + + + All subdirectories + Wszystkie podkatalogi + + + + Current directory + Bieżący katalog + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Dzisiaj + + + + Yesterday + Wczoraj + + + + This week + W tym tygodniu + + + + Last week + W poprzednim tygodniu + + + + This month + W tym miesiącu + + + + Last month + W poprzednim miesiącu + + + + This year + W tym roku + + + + Last year + W poprzednim roku + + + + DFMOpticalMediaWidget + + + + No files to burn + Brak plików do wypalenia + + + + Unable to burn. Not enough free space on the target disk. + Nie można wypalić. Za mało wolnego miejsca na dysku docelowym. + + + + %1 burning is not supported + %1 wypalanie jest nie jest wspierane + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. To nie jest %1 dysk; +2. Wersja tego pliku systemowego nie wspiera jeszcze dodawania plików + + + + DFMTagCrumbController + + + Tag information + Utwórz znacznik + + + + DFMTagWidget + + + Tag + Znacznik + + + + DFMTaskWidget + + + Do not ask again + Nie pytaj ponownie + + + + Syncing data + Data synchronizacji + + + + Please wait + Proszę czekać + + + + + Time modified: %1 + Data modyfikacji: %1 + + + + + Contains: %1 + Zawiera: %1 + + + + + Size: %1 + Rozmiar: %1 + + + + Original folder + Oryginalny folder + + + + Keep both + button + Zatrzymaj oba + + + + Skip + button + Pomiń + + + + Replace + button + Zastąp + + + + Retry + button + Ponów + + + + Original file + Oryginalny plik + + + + Target folder + Folder docelowy + + + + Target file + Plik docelowy + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Zaszyfruj Skarbiec Plików + + + + Click 'Encrypt' and input the user password. + Kliknij "Szyfruj" oraz wprowadź hasło użytkownika + + + + Encrypting... + Szyfrowanie... + + + + + + + Encrypt + Szyfruj + + + + Failed to create file vault: %1 + Nie udało się utworzyć skarbca plików: %1 + + + + OK + OK + + + + The setup is complete + Instalacja zakończona + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Zapisz klucz odzyskiwania + + + + Keep the key safe to retrieve the vault password later + Zachowaj klucz w razie konieczności, gdy będzie trzeba odzyskać hasło do skarbca + + + + Save to default path + Zapisz do domyślnej ścieżki + + + + Save to other locations + Zapisz do innych lokacji + + + + No permission, please reselect + Brak permisji, proszę wybrać ponownie + + + + Select a path + Wybierz ścieżkę + + + + Next + Dalej + + + + The default path is invisible to other users, and the path information will not be shown. + Domyślna ścieżka jest niewidoczna dla innych użytkowników, dlatego informacja o ścieżce nie będzie widoczna. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Klucz odzyskiwania + + + + Generate a recovery key in case that you forgot the password + Wygeneruj klucz odzyskiwania w razie gdybyś zapomniał/a hasła + + + + Key + Klucz + + + + QR code + Kod QR + + + + Scan QR code and save the key to another device + Skanuj kod QR i zapisz klucz na innym urządzeniu + + + + Next + Dalej + + + + Recovery Key: + Klucz odzyskiwania: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Ustaw Hasło Skarbca + + + + Method + Metoda + + + + Manual + Ręczny + + + + Password + Hasło + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 znaków, zawiera A-Z, a-z, 0-9, i symbole + + + + Repeat password + Powtórz hasło + + + + Input the password again + Wprowadź hasło ponownie + + + + Password hint + Wskazówka do hasła + + + + Optional + Opcjonalne + + + + Next + Dalej + + + + + Passwords do not match + Hasła nie pasują do siebie + + + + DFMVaultActiveStartView + + + File Vault + Skarbiec Plików + + + + Create your secure private space + Utwórz tutaj bezpieczną przestrzeń prywatną + + + + Advanced encryption technology + Zaawansowana technologia szyfrowania + + + + Convenient and easy to use + Wygodny i łatwy w użyciu + + + + Create + Utwórz + + + + DFMVaultFileView + + + Cannot open this path + Nie można otworzyć tej ścieżki + + + + Hint + Wskazówka + + + + OK + OK + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Odblokuj przy użyciu Klucza + + + + Failed to unlock file vault + Nie udało się odblokować skarbca plików + + + + OK + OK + + + + Input the 32-digit recovery key + Wprowadź 32 cyfrowy klucz odzyskiwania + + + + Cancel + button + Anuluj + + + + Unlock + button + Odblokuj + + + + Wrong recovery key + nieprawidłowy klucz odzyskiwania + + + + DFMVaultRemoveByPasswordView + + + Password + Hasło + + + + Password hint: %1 + Wskazówka do hasła: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Wprowadź 32 cyfrowy klucz odzyskiwania + + + + DFMVaultRemovePages + + + Delete File Vault + Usuń Skarbiec plików + + + + Once deleted, the files in it will be permanently deleted + Usunięty, pliki w nim zostaną również usunięte + + + + Use Key + Użyj klucza + + + + Cancel + button + Anuluj + + + + Use Key + button + Użyj klucza + + + + Delete + button + Usuń + + + + + OK + button + OK + + + + Use Password + Użyj hasła + + + + Wrong password + Nieprawidłowe hasło + + + + Wrong recovery key + nieprawidłowy klucz odzyskiwania + + + + Failed to delete file vault + Nie udało się usunąć skarbca plików + + + + Deleted successfully + Usunięto pomyślnie + + + + Failed to delete + Błąd usuwania + + + + Removing... + Przesuwanie... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + Nie udało się uzyskać pliku klucza + + + + Verification failed + Weryfikacja nie powiodła się + + + + + Select a path + Wybierz ścieżkę + + + + + Retrieve Password + Odzyskaj Hasło + + + + By key in the default path + Przy kluczu, w domyślnej ścieżce + + + + By key in the specified path + Przy kluczu, w określonej ścieżce + + + + Verification Successful + Weryfikacja zakończona sukcesem + + + + Keep it safe + Zachowaj go w bezpiecznym miejscu + + + + Back + button + Cofnij + + + + Verify Key + button + Zweryfikuj klucz + + + + Go to Unlock + button + Przejdź do odblokowywania + + + + Close + button + Zamknij + + + + Vault password: %1 + Hasło skarbca: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Odblokuj Skarbiec + + + + Forgot password? + Zapomniałeś hasła? + + + + Password hint: %1 + Wskazówka do hasła: %1 + + + + Failed to unlock file vault + Nie udało się odblokować skarbca plików + + + + Cancel + button + Anuluj + + + + Password + Hasło + + + + Unlock + button + Odblokuj + + + + Please try again %1 minutes later + Proszę powtórzyć ponownie za %1 minut + + + + Wrong password, please try again %1 minutes later + Nieprawidłowe hasło, proszę powtórzyć ponownie za %1 minut + + + + Wrong password, one chance left + Nieprawidłowe hasło, pozostała tylko jedna szansa + + + + Wrong password, %1 chances left + Nieprawidłowe hasło, pozostały %1 próby + + + + Wrong password + Nieprawidłowe hasło + + + + OK + button + OK + + + + DFileCopyMoveJob + + + Permission error + Błąd uprawnień + + + + The action is denied + To działanie jest zabronione + + + + Failed to open the file + Błąd otwarcia pliku + + + + Failed to read the file + Błąd odczytu pliku + + + + Failed to write the file + Błąd zapisu pliku + + + + Failed to create the directory + Błąd utworzenia katalogu + + + + Failed to delete the file + Błąd usunięcia pliku + + + + Failed to move the file + Błąd przenoszenia pliku + + + + Original file does not exist + Pierwotny plik nie istnieje + + + + Failed, file size must be less than 4GB + Błąd. Rozmiar pliku musi być mniejszy od 4GB + + + + Not enough free space on the target disk + Za mało wolnego miejsca na dysku docelowym + + + + File integrity was damaged + Integralność pliku została naruszona + + + + The target device is read only + Urządzenie docelowe jest w trybie tylko do odczytu + + + + Target folder is inside the source folder + Katalog docelowy znajduje się wewnątrz katalogu źródłowego + + + + The action is not supported + To działanie nie jest obsługiwane + + + + You do not have permission to traverse files in it + Nie masz uprawnień do krzyżowania plików + + + + Failed to position the file pointer! + Nie udało się ustawić wskaźnika pliku! + + + + copy + Extra name added to new file name when used for file name. + kopia + + + + Failed to open the directory, cause: file name too long + Błąd otwierania ścieżki, przyczyna: nazwa pliku zbyt długa + + + + + Failed to open the file, cause: file name too long + Błąd otwierania pliku, przyczyna: nazwa pliku zbyt długa + + + + + Failed to write the file, cause: + Błąd zapisu pliku, powód: + + + + Failed to position the file pointer, cause: %1 + Nie udało się ustawić wskaźnika pliku, przyczyna: %1 + + + + Syncing data + Data synchronizacji + + + + Please wait + Proszę czekać + + + + Failed to create the directory, cause: %1 + Błąd utworzenia katalogu, powód: %1 + + + + + + + + Failed to open the file, cause: %1 + Błąd otwarcia pliku, powód: %1 + + + + + + + Failed to open the file, cause: Permission denied + Błąd otwarcia pliku, powód: Odmowa dostępu + + + + + Failed to read the file, cause: %1 + Błąd odczytu pliku, powód: %1 + + + + + + + Failed to write the file, cause: %1 + Błąd zapisu pliku, powód: %1 + + + + + File integrity was damaged, cause: %1 + Integralność pliku została naruszona, powód: %1 + + + + Failed to open the file, cause: + Błąd otwarcia pliku, powód: + + + + Failed to read the file, cause: + Błąd odczytu pliku, powód: + + + + Failed to delete the file, cause: %1 + Błąd usunięcia pliku, powód: %1 + + + + Fail to create symlink, cause: %1 + Błąd utworzenia dowiązania symbolicznego, powód: %1 + + + + DFileDialog + + + + Save + button + Zapisz + + + + + Cancel + button + Anuluj + + + + Confirm + button + Potwierdź + + + + %1 already exists, do you want to replace it? + %1 już istnieje, czy chcesz go zastąpić? + + + + Replace + button + Zastąp + + + + Open + button + Otwórz + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Ten plik zostanie ukryty, jeśli jego nazwa zaczyna się od (.). Chcesz go ukryć? + + + + DFileManagerWindow + + + Trash + Śmieci + + + + Empty + Opróżnij + + + + DFileSystemModel + + + + Name + Nazwa + + + + + + Time modified + Data modyfikacji + + + + Size + Rozmiar + + + + Type + Rodzaj + + + + Time created + Data utworzenia + + + + + Last access + Ostatni dostęp + + + + + + + Path + Ścieżka + + + + DFileView + + + Disc mount error + Błąd montowania dysku + + + + The disc is in use, please end the running process and remount the disc. + Dysk jest w użyciu, zakończ trwający proces i zamontuj dysk od nowa + + + + Mounting failed + Błąd montowania + + + + (Reverse) + (Odwróć) + + + + DFileViewHelper + + + Add tag "%1" + Dodaj znacznik "%1" + + + + DStatusBar + + + %1 item + %1 przedmiot + + + + %1 items + %1 przedmiotów + + + + %1 item selected + Zaznaczono %1 przedmiot + + + + %1 items selected + Zaznaczono %1 przedmiotów + + + + %1 folder selected (contains %2) + Zaznaczono %1 katalog (zawierający %2) + + + + %1 folders selected (contains %2) + Zaznaczono %1 katalogów (zawierające %2) + + + + %1 file selected (%2) + Zaznaczono %1 plik (%2) + + + + %1 files selected (%2) + Zaznaczono %1 plików (%2) + + + + %1 folder selected + Zaznaczono %1 katalog + + + + Filter + Filtr + + + + Save as: + Zapisz jako: + + + + Loading... + Wczytywanie... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Kasowanie dysku %1, prosimy czekać... + + + + Burning disc %1, please wait... + Nagrywanie dysku %1, prosimy czekać... + + + + Writing data... + Zapisywanie danych... + + + + Verifying data... + Weryfikuję dane... + + + + Copying %1 + Kopiowanie %1 + + + + + + to %2 + do %2 + + + + %1 already exists in target folder + %1 już istnieje w folderze docelowym + + + + Original path %1 Target path %2 + Oryginalna ścieżka %1 Docelowa ścieżka %2 + + + + Merge + button + Scal + + + + Replace + button + Zastąp + + + + Moving %1 + Przenoszenie %1 + + + + Removing file vault, please try later + Usuwanie skarbca plików, spróbuj ponownie później + + + + Restoring %1 + Przywracanie %1 + + + + Deleting %1 + Usuwanie %1 + + + + Trashing %1 + Kasowanie %1 + + + + Calculating space, please wait + Obliczanie miejsca, prosimy czekać + + + + DUMountManager + + + + Authentication timed out + Upłynął limit czasu uwierzytelniania + + + + + + Disk is busy, cannot unmount now + Dysk jest zajęty, nie można teraz odmontować + + + + Disk is busy, cannot eject now + Dysk jest zajęty, nie można go teraz wysunąć + + + + The device is busy, cannot eject now + Urządzenie jest zajęte, nie można go teraz wysunąć + + + + + + The device is busy, cannot remove now + Urządzenie jest zajęte, nie można go teraz wyjąć + + + + DeepinStorage + + + + + %1 Volume + Wolumin %1 + + + + Data Disk + Data Partition + Dysk z danymi + + + + %1 Drive + Napęd %1 + + + + Blank %1 Disc + Pusty dysk %1 + + + + %1 Encrypted + %1 zaszyfrowany + + + + DialogManager + + + + + + Operation failed! + Błąd działania! + + + + Target folder is inside the source folder! + Katalog docelowy znajduje się wewnątrz katalogu źródłowego! + + + + Do you want to run %1 or display its content? + Czy chcesz uruchomić %1 albo wyświetlić jego zawartość? + + + + It is an executable text file. + Jest to wykonywalny plik tekstowy. + + + + It is an executable file. + Jest to plik wykonywalny. + + + + This file is not executable, do you want to add the execute permission and run? + Ten plik jest niewykonywalny, czy chcesz mu dodać uprawnienia do wykonywania i uruchomić? + + + + "%1" already exists, please use another name. + "%1" już istnieje, prosimy użyć innej nazwy. + + + + The file name must not contain two dots (..) + Nazwa pliku nie może zawierać dwóch kropek (..) + + + + Device or resource busy + Urządzenie lub zasoby zajęte + + + + Are you sure you want to erase all data on the disc? + Czy na pewno chcesz usunąć wszystkie dane z dysku? + + + + How do you want to use this disc? + Jak chcesz korzystać z tego dysku? + + + + Disc erase failed + Kasowanie płyty nie powiodło się + + + + Burn process failed + Proces nagrywania nie powiódł się + + + + %1: %2 + %1: %2 + + + + Show details + Pokaż szczegóły + + + + Hide details + Ukryj szczegóły + + + + Error + Błąd + + + + Permanently delete %1? + Permanentnie usunąć %1? + + + + Permanently delete %1 items? + Permanentnie usunąć %1 przedmioty? + + + + Empty + Opróżnij + + + + Do you want to delete %1? + Czy chcesz usunąć %1? + + + + Do you want to delete the selected %1 items? + Czy chcesz usunąć zaznaczone przedmioty %1? + + + + Sorry, unable to locate your bookmark directory, remove it? + Przepraszamy, nie jest możliwa lokalizacja Twojego katalogu zakładek, usunąć to? + + + + Name: + Nazwa: + + + + %1 that this shortcut refers to has been changed or moved + %1, do którego odnosi się skrót, został zmieniony lub przeniesiony + + + + Do you want to delete this shortcut? + Czy chcesz usunąć ten skrót? + + + + Failed, file size must be less than 4GB. + Błąd. Rozmiar pliku musi być mniejszy od 4GB. + + + + Fail to create symlink, cause: + Błąd tworzenia dowiązania symbolicznego; powód: + + + + The selected files contain system file/directory, and it cannot be deleted + Wybrane pliki zawierają pliki/katalogi systemowe i nie mogą zostać usunięte + + + + Unable to find the original file + Brak możliwości znalezienia pierwotnego pliku + + + + + You do not have permission to operate file/folder! + Nie masz uprawnień do dokonywania działań na tym pliku/katalogu! + + + + Failed to restore %1 file, the source file does not exist + Nie udało się przywrócić pliku %1, folder docelowy nie istnieje + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Niestety, nie masz uprawnień do obsługi następującego %1 pliku(ów) / katalogu(ów)! + + + + Unable to access %1 + Brak możliwości dostępu do %1 + + + + + Sending files now, please try later + Teraz trwa wysyłanie plików, spróbuj później + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Aby uzyskać dostęp do urządzenia, musisz najpierw sformatować dysk. Czy chcesz zrobić to teraz? + + + + Scanning the device, stop it? + Skanowanie urządzenia, zatrzymać? + + + + Share folder can't be named after the current username + Katalog współdzielony nie może mieć aktualnej nazwy użytkownika + + + + Do you want to run %1? + Czy chcesz uruchomić %1? + + + + Burn image + button + Nagraj obraz + + + + Burn files + button + Nagraj pliki + + + + Are you sure you want to empty %1 item? + Czy na pewno chcesz trwale usunąć %1 przedmiot? + + + + Are you sure you want to empty %1 items? + Czy na pewno chcesz trwale usunąć %1 przedmiotów? + + + + + This action cannot be undone + Tej akcji nie można cofnąć + + + + + + + + + + + + + + OK + button + OK + + + + + + + + + + + + + + + Cancel + button + Anuluj + + + + + + Run + button + Uruchom + + + + + Run in terminal + button + Uruchom w terminalu + + + + Display + button + Wyświetl + + + + + + + + + + + Confirm + button + Potwierdź + + + + Erase + button + Wymaż + + + + Data verification failed + Weryfikacja danych nie powiodła się. + + + + Show details + button + Pokaż szczegóły + + + + + Delete + button + Usuń + + + + Remove + button + Usuń + + + + Disk is busy, cannot unmount now + Dysk jest zajęty, teraz nie można odmontować + + + + Force unmount + button + Wymuś odmontowanie + + + + Unable to copy. Not enough free space on the target disk. + Nie można skopiować. Za mało wolnego miejsca na dysku docelowym. + + + + Failed to restore %1 file, the target folder is read-only + Nie udało się przywrócić pliku %1, folder docelowy jest tylko do odczytu + + + + Failed to restore %1 files, the target folder is read-only + Nie udało się przywrócić plików %1, folder docelowy jest tylko do odczytu + + + + Failed to restore %1 files, the source files do not exist + Nie udało się przywrócić pliku %1, folder docelowy nie istnieje + + + + Format + button + Format + + + + Stop + button + Stop + + + + FileController + + + + + + Unable to find the original file + Brak możliwości znalezienia pierwotnego pliku + + + + + + Kindly Reminder + Miłe przypomnienie + + + + + + Please install File Roller first and then continue + Najpierw zainstaluj File Roller, a następnie kontynuuj + + + + + Unable to create files here: %1 + Brak możliwości utworzenia tutaj plików: %1 + + + + Confirm + button + Potwierdź + + + + FileDialogStatusBar + + + File Name + Nazwa pliku + + + + Format + Format + + + + Save + button + Zapisz + + + + Open + button + Otwórz + + + + Save File + button + Zapisz plik + + + + Open File + button + Otwórz plik + + + + + + Cancel + button + Anuluj + + + + FileJob + + + copy + kopia + + + + + + + Data verification successful. + Weryfikacja danych powiodła się. + + + + + + Burn process completed + Proces nagrywania zakończony + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 g %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 g %3 m %4 s + + + + %1 is a duplicate file. + %1 jest duplikatem pliku. + + + + Insufficient disc space. + Za mało miejsca na dysku. + + + + Lost connection to drive. + Utracono połączenie z dyskiem. + + + + The CD/DVD drive is not ready. Try another disc. + Napęd CD/DVD nie jest gotowy. Wypróbuj inną płytę. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + Napęd CD/DVD jest zajęty. Wyjdź z programu za pomocą napędu i włóż go ponownie. + + + + Unknown error + Nieznany błąd + + + + Device disconnected + Urządzenie odłączone + + + + GenerateSettingTranslate + + + + + Basic + Podstawowe + + + + + + Open behavior + Zachowanie otwierania + + + + + + Always open folder in new window + Zawsze otwieraj katalogi w nowym oknie + + + + + + Open file: + Otwórz plik: + + + + + + Click + Kliknięcie + + + + + + Double click + Podwójne kliknięcie + + + + + + New window and tab + Nowe okno i karta + + + + + + Open from default window: + Otwórz w domyślnym oknie: + + + + + + + + + Computer + Komputer + + + + + + + + + Home + Katalog domowy + + + + + + + + + Desktop + Pulpit + + + + + + + + + Videos + Filmy + + + + + + + + + Music + Muzyka + + + + + + + + + Pictures + Zdjęcia + + + + + + + + + Documents + Dokumenty + + + + + + + + + Downloads + Pobrane + + + + + + Open in new tab: + Otwórz w nowej karcie: + + + + + + Current Directory + Bieżący katalog + + + + + + View + Podgląd + + + + + + Default size: + Domyślny rozmiar: + + + + + + Extra small + Bardzo mały + + + + + + Small + Mały + + + + + + Medium + Średni + + + + + + Large + Duży + + + + + + Extra large + Bardzo duży + + + + + + Default view: + Domyślny widok: + + + + + + Icon + Ikony + + + + + + List + Lista + + + + + + Hidden files + Ukryte pliki + + + + + + Show hidden files + Wyświetl ukryte pliki + + + + + + Hide file extension when rename + Ukryj rozszerzenia plików podczas zmiany ich nazwy + + + + + + Advanced + Zaawansowane + + + + + + Index + Indeksowanie + + + + + + Auto index internal disk + Automatycznie indeksuj dysk wewnętrzny + + + + + + Index external storage device after connected to computer + Indeksuj zewnętrzne urządzenie przechowywania po podłączeniu do komputera + + + + + + Full-Text search + Wyszukiwanie Full-Text + + + + + + Show item counts and sizes in the path of mounted MTP devices + Pokaż liczbę i rozmiar plików w ścieżce zamontowanych urządzeń MTP + + + + + + Keep showing the mounted Samba shares + Pokazuj zamontowane katalogi współdzielone Samba + + + + + + Use the file chooser dialog of File Manager + Użyj okna wyboru plików w Menedżerze plików + + + + + + Ask for my confirmation when deleting files + Zapytaj mnie o potwierdzenie podczas usuwania plików + + + + + + Other + Inne + + + + + + Hide system disk + Ukryj dysk systemowy + + + + + + Show file system on disk icon + Pokaż system plików na ikonie dysku + + + + + + Show hidden files in search results + Wyświetl w wynikach wyszukiwania ukryte pliki + + + + + + Display recent file entry in left panel + Wyświetl wpisy ostatnich plików w panelu po lewej stronie + + + + + + Preview + Podgląd + + + + + Compress file preview + Podgląd plików skompresowanych + + + + + + Text preview + Podgląd tekstów + + + + + + Document preview + Podgląd dokumentów + + + + + + Image preview + Podgląd obrazów + + + + + + Video preview + Podgląd filmów + + + + + + Mount + Zamontuj + + + + + + Auto mount + Automatyczne montowanie + + + + + + Open after auto mount + Otwórz po automatycznym zamontowaniu + + + + + + Dialog + Okno dialogowe + + + + Compressed file preview + Podgląd plików skompresowanych + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Nie można zweryfikować %1 + + + + This happens when you log in to a computer the first time. + Dzieje się to kiedy zalogujesz się do komputera po raz pierwszy. + + + + The identity sent by the remote computer is + Identyfikator wysłany przed komputer zdalny to + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Jeśli chcesz być absolutnie pewny czy można bezpiecznie kontynuować, skontaktuj się z administratorem systemu. + + + + + + + + Mounting device error + Błąd urządzenia montowania + + + + + Wrong username or password + Nieprawidłowa nazwa lub hasło użytkownika + + + + + + + + Confirm + button + Potwierdź + + + + + Cannot find the mounted device + Nie można odnaleźć podpiętego urządzenia + + + + No key available to unlock device + Brak klucza do odblokowania urządzenia + + + + The disk is mounted by user "%1", you cannot unmount it. + Dysk został zamontowany przez użytkownika "%1", nie możesz go wymontować. + + + + Cannot unmount the device + Nie można odmontować urządzenia + + + + Cannot eject the device "%1" + Nie można wysunąć urządzenia "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Nie można wypalić. Za mało wolnego miejsca na dysku docelowym. + + + + MergedDesktopController + + + + Pictures + Zdjęcia + + + + + Music + Muzyka + + + + + Applications + Aplikacje + + + + + Videos + Wideo + + + + + Documents + Dokumenty + + + + + Others + Inne + + + + MimeTypeDisplayManager + + + + Directory + Katalog + + + + + + Application + Aplikacja + + + + + + Video + Wideo + + + + + + Audio + Audio + + + + + + Image + Obraz + + + + + Archive + Archiwum + + + + + + Text + Tekst + + + + + Executable + Wykonywalny + + + + + Backup file + Plik kopii zapasowej + + + + + Unknown + Nieznany + + + + MountAskPasswordDialog + + + Cancel + button + Anuluj + + + + Connect + button + Połącz + + + + Log in as + Zaloguj jako + + + + Anonymous + Anonimowo + + + + Registered user + Zarejestrowany użytkownik + + + + Username + Nazwa użytkownika + + + + Domain + Domena + + + + Password + Hasło + + + + Remember password + Zapamiętaj hasło + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Anuluj + + + + Unlock + button + Odblokuj + + + + Input password to decrypt the disk + Wprowadź hasło, aby odszyfrować dysk + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Czy na pewno chcesz trwale usunąć %1? + + + + This file is too big for the trash + Ten plik jest za duży, aby wyrzucić do kosza + + + + The files are too big for the trash + Pliki są za duże, aby wyrzucić do kosza + + + + Are you sure you want to permanently delete %1 files? + Czy na pewno chcesz trwale usunąć pliki %1? + + + + Cancel + button + Anuluj + + + + Delete + button + Usuń + + + + OpenWithDialog + + + Open with + Otwórz za pomocą + + + + Add other programs + Dodaj inne programy + + + + Set as default + Ustaw jako domyślne + + + + Cancel + button + Anuluj + + + + Confirm + button + Potwierdź + + + + Recommended Applications + Programy polecane + + + + Other Applications + Inne programy + + + + PathManager + + + Home + Katalog domowy + + + + Desktop + Pulpit + + + + Videos + Filmy + + + + Music + Muzyka + + + + Pictures + Zdjęcia + + + + Documents + Dokumenty + + + + Downloads + Pobrane + + + + + Trash + Kosz + + + + + + System Disk + Dysk systemowy + + + + Computers in LAN + Komputery w sieci LAN + + + + My Shares + Moje współdzielenia + + + + Computer + Komputer + + + + Recent + Ostatnie + + + + File Vault + Skarbiec Plików + + + + PropertyDialog + + + Basic info + Podstawowe informacje + + + + Open with + Otwórz za pomocą + + + + Sharing + Udostępnij + + + + Permissions + Uprawnienia + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Ukryj folder + + + + Hide this file + Ukryj plik + + + + Allow to execute as program + Zezwól na wykonywanie jako program + + + + QObject + + + + + + Size + Rozmiar + + + + + + Contains + Zawiera + + + + + + Type + Rodzaj + + + + + + + + Time modified + Data modyfikacji + + + + Free space + Wolna przestrzeń + + + + Total space + Całkowita przestrzeń + + + + + Time locked + Data zablokowania + + + + Access denied + Odmowa dostępu + + + + + Executable + Wykonywalny + + + + + Write only + Tylko zapis + + + + + Read only + Tylko do odczytu + + + + + Read-write + Odczyt-zapis + + + + Others + Inne + + + + Owner + Właściciel + + + + Unconnected network shared directory + Niepodłączony współdzielony folder sieciowy + + + + Device type + Rodzaj urządzenia + + + + File system + System plików + + + + Group + Grupa + + + + + Open + Otwórz + + + + Lock + Zablokuj + + + + Auto lock + Automatyczne blokowanie + + + + Never + Nigdy + + + + 5 minutes + 5 minut + + + + 10 minutes + 10 minut + + + + 20 minutes + 20 minut + + + + Delete File Vault + Usuń Skarbiec Plików + + + + Unlock + Odblokuj + + + + Unlock by key + Odblokuj przy użyciu Klucza + + + + Open + button + Otwórz + + + + + Size: %1 + Rozmiar: %1 + + + + Type: %1 + Rodzaj: %1 + + + + Size: 0 + Rozmiar: 0 + + + + Items: %1 + Przedmioty: %1 + + + + + + + + + + Open in new window + Otwórz w nowym oknie + + + + + + + + + + Open in new tab + Otwórz w nowej karcie + + + + Open with + Otwórz za pomocą + + + + + Compress + Skompresuj + + + + Extract + Rozpakuj + + + + Extract here + Rozpakuj tutaj + + + + Cut + Wytnij + + + + Copy + Kopiuj + + + + Paste + Wklej + + + + + + + + Rename + Zmień nazwę + + + + + + + Remove + Usuń + + + + Create link + Utwórz dowiązanie + + + + Send to desktop + Wyślij na pulpit + + + + Send to + Wyślij do + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Dodaj do zakładek + + + + + + + Properties + Właściwości + + + + New folder + Nowy katalog + + + + New window + Nowe okno + + + + Select all + Zaznacz wszystko + + + + + Clear recent history + Wyczyść ostatnią historię + + + + + + Empty Trash + Opróżnij kosz + + + + Display as + Wyświetl jako + + + + Sort by + Sortuj według + + + + New document + Nowy dokument + + + + + Time created + Data utworzenia + + + + + + Source path + Ścieżka źródłowa + + + + Share folder + Współdziel katalog + + + + Cancel sharing + Anuluj współdzielenie + + + + Connect to Server + Połącz się z serwerem + + + + Set share password + Ustaw hasło współdzielenia + + + + Format + Format + + + + Tag information + Utwórz znacznik + + + + Open as administrator + Otwórz jako administrator + + + + Select default program + Wybierz program domyślny + + + + Open file location + Otwórz położenie pliku + + + + Remove bookmark + Usuń zakładkę + + + + + + Delete + Usuń + + + + Office Text + Tekst biurowy + + + + Spreadsheets + Arkusz kalkulacyjny + + + + Plain Text + Zwykły tekst + + + + Open in terminal + Otwórz w terminalu + + + + Restore + Przywróć + + + + Restore all + Przywróć wszystkie + + + + Clear saved password and unmount + Wyczyść zapisane hasło i odmontuj + + + + File Vault + Skarbiec Plików + + + + Add to disc + Dodaj do dysku + + + + Refresh + Odśwież + + + + Auto mount + Automatyczne montowanie + + + + Open after auto mount + Otwórz po automatycznym zamontowaniu + + + + + Mount + Zamontuj + + + + + Unmount + Odmontuj + + + + It does not support burning %1 discs + Nie wspiera wypalania dysków %1 + + + + Burn + Wypal + + + + Disc name: + Nazwa płyty: + + + + + Maximum + Maksymalny + + + + Allow files to be added later + Zezwól na dodanie plików później + + + + Verify data + Sprawdź dane + + + + Write speed: + Szybkość zapisu: + + + + + + + Cancel + button + Anuluj + + + + Burn + button + Wypal + + + + + Eject + Wysuń + + + + Safely Remove + Bezpieczne usunięcie + + + + + Name + Nazwa + + + + Settings + Ustawienia + + + + Exit + Wyjdź + + + + Icon + Ikony + + + + List + Lista + + + + Extend + Rozwiń + + + + Set as wallpaper + Ustaw jako tapetę + + + + + + + Local disk + Dysk lokalny + + + + + Removable disk + Dysk wymienny + + + + + + Network shared directory + Współdzielony katalog sieciowy + + + + + Android mobile device + Przenośne urządzenie Android + + + + + Apple mobile device + Przenośne urządzenie Apple + + + + + Camera + Kamera + + + + + DVD + DVD + + + + + Unknown device + Nieznane urządzenie + + + + + + %1 item + %1 przedmiot + + + + + + %1 items + %1 przedmiotów + + + + Shortcut + Skrót + + + + Create symlink + Utwórz dowiązanie symboliczne + + + + Path + Ścieżka + + + + + + Time deleted + Data usunięcia + + + + Loading... + Wczytywanie... + + + + File has been moved or deleted + Plik został przeniesiony lub usunięty + + + + You do not have permission to traverse files in it + Nie masz uprawnień do krzyżowania plików + + + + + + You do not have permission to access this folder + Nie masz uprawnień do dostępu do tego katalogu + + + + + + + + Folder is empty + Katalog jest pusty + + + + Searching... + Wyszukiwanie... + + + + No results + Brak wyników + + + + Source Path + TrashFileInfo + Ścieżka źródłowa + + + + Document + Dokument + + + + Spreadsheet + Arkusz kalkulacyjny + + + + + Presentation + Prezentacja + + + + Text + Tekst + + + + 1 task in progress + 1 zadanie w trakcie wykonywania + + + + %1 tasks in progress + %1 zadań w trakcie wykonywania + + + + Mode: + Tryb: + + + + + Replace Text + Zastąp tekst + + + + + Add Text + Dodaj tekst + + + + + Custom Text + Własny tekst + + + + Find: + Znajdź: + + + + Replace: + Zastąp: + + + + + Optional + Opcjonalne + + + + Add: + Dodaj: + + + + Location: + Położenie: + + + + File name: + Nazwa pliku: + + + + Start at: + Zacznij o: + + + + + Rename + button + Zmień nazwę + + + + + + + + + + + Required + Wymagane + + + + + Before file name + Przed nazwą pliku + + + + + After file name + Po nazwie pliku + + + + Find + Znajdź + + + + Replace + Zastąp + + + + Add + Dodaj + + + + Start at + Zacznij o + + + + + + Location + Położenie + + + + File name + Nazwa pliku + + + + Dimension + Wymiar + + + + Duration + Czas trwania + + + + Tips: Sort by selected file order + Podpowiedź: Sortuj według określonego porządku plików + + + + Rename %1 Files + Zmień nazwę %1 plików + + + + Multiple Files + Wiele plików + + + + Basic info + Podstawowe informacje + + + + Total size + Całkowity rozmiar + + + + Number of files + Liczba plików + + + + %1 file(s), %2 folder(s) + %1 plik(ów), %2 katalog(ów) + + + + + + Time accessed + Ostatni dostęp + + + + Orange + Pomarańczowy + + + + Red + Czerwony + + + + Purple + Purpurowy + + + + Navy-blue + Granatowy + + + + Azure + Błękitny + + + + Green + Zielony + + + + Yellow + Żółty + + + + Gray + Szary + + + + Input tag info, such as work, family. A comma is used between two tags. + Wpisz informacje o znaczniku, takie jak praca, rodzina. Między nazwami znaczników użyj przecinka. + + + + Bookmarks + Zakładki + + + + Erase + Wymaż + + + + Copy path + Skopiuj ścieżkę + + + + Edit address + Edytuj adres + + + + Free Space %1 + Wolne miejsce %1 + + + + Files are being processed + Pliki są przetwarzane + + + + + Unknown + Nieznany + + + + My Vault + Mój Skarbiec + + + + + Failed to create file info + Błąd tworzenia informacji o pliku + + + + Failed to create file handler + Błąd tworzenia handlera plików + + + + Failed to open the file, cause: %1 + Błąd otwarcia pliku, powód: %1 + + + + Original file does not exist + Pierwotny plik nie istnieje + + + + Do you want to delete %1? + Czy chcesz usunąć %1? + + + + Confirm + button + Potwierdź + + + + + + + + %1 are not allowed + %1 są niedozwolone + + + + + Failed to start Samba services + Nie udało się wystartować usług Samba + + + + RecentController + + + Cancel + button + Anuluj + + + + Remove + button + Usuń + + + + Do you want to remove this item? + Czy chcesz usunąć ten przedmiot? + + + + Do yout want to remove %1 items? + Czy chcesz usunąć %1 przedmiotów? + + + + It does not delete the original files + Ta akcja nie usuwa oryginalnych plików + + + + ShareInfoFrame + + + Share this folder + Współdziel folder + + + + Share name: + Nazwa: + + + + Permission: + Uprawnienia: + + + + Read and write + Odczyt i zapis + + + + Read only + Tylko do odczytu + + + + Anonymous: + Anonimowo: + + + + Not allow + Nie pozwalaj + + + + Allow + Pozwól + + + + The share name must not be two dots (..) or one dot (.) + Nazwa współdzielenia nie może zawierać wyłącznie dwóch kropek (..) lub jednej kropki (.) + + + + The share name is used by another user. + Nazwa współdzielenia jest używana przez innego użytkownika + + + + OK + button + OK + + + + Cancel + button + Anuluj + + + + Replace + button + Zastąp + + + + The share name already exists. Do you want to replace the shared folder? + Nazwa współdzielenia już istnieje. Czy chcesz zastąpić folder współdzielenia? + + + + Shortcut + + + Item + Przedmiot + + + + Select to the first item + Zaznacz pierwszy przedmiot + + + + Shift + Home + Shift + Home + + + + Select to the last item + Wybierz ostatni przedmiot + + + + Shift + End + Shift + End + + + + Select leftwards + Zaznacz po lewej + + + + Shift + Left + Shift + Strzałka w lewo + + + + Select rightwards + Zaznacz po prawej + + + + Shift + Right + Shift + Strzałka w prawo + + + + Select to upper row + Zaznacz górny wiersz + + + + Shift + Up + Shift + Strzałka w górę + + + + Select to lower row + Zaznacz dolny wiersz + + + + Shift + Down + Shift + Strzałka w dół + + + + Open + Otwórz + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + Do katalogu nadrzędnego + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Permanentnie usuń + + + + Shift + Delete + Shift + Delete + + + + Delete file + Usuń plik + + + + Delete + Delete + + + + Select all + Zaznacz wszystko + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Kopiuj + + + + Cut + Wytnij + + + + Paste + Wklej + + + + Rename + Zmień nazwę + + + + F2 + F2 + + + + New/Search + Nowe/Szukaj + + + + New window + Nowe okno + + + + New folder + Nowy katalog + + + + + Search + Szukaj + + + + New tab + Nowa karta + + + + View + Podgląd + + + + Item information + Informacje o przedmiocie + + + + Help + Pomoc + + + + F1 + F1 + + + + Keyboard shortcuts + Skróty klawiszowe + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Przełącz stan wyświetlania + + + + Hide item + Ukryj przedmiot + + + + Input in address bar + Wprowadź w pasku adresu + + + + Switch to icon view + Przełącz na widok ikon + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Przełącz na widok listy + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Inne + + + + Close + Zamknij + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Zamknij bieżącą kartę + + + + Back + Cofnij + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Przełącz na następną kartę + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Przełącz na poprzednią kartę + + + + Next file + Następny plik + + + + Tab + Tab + + + + Previous file + Poprzedni plik + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Przełącz kartę poprzez określoną cyfrę pomiędzy 1 a 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Dalej + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Brak możliwości otwarcia przedmiotów w koszu, najpierw je przywróć + + + + TrashPropertyDialog + + + Trash + Kosz + + + + item + przedmiot + + + + items + przedmiotów + + + + Contains %1 %2 + Zawiera %1 %2 + + + + UDiskListener + + + Failed to rename the label + Błąd zmiany nazwy etykiety + + + + UnmountWorker + + + + + The device was not safely unmounted + Urządzenie nie zostało bezpiecznie usunięte + + + + The device was not safely removed + Urządzenie nie zostało bezpiecznie usunięte + + + + UserShareManager + + + Kindly Reminder + Uprzejme przypomnienie + + + + Please firstly install samba to continue + Prosimy najpierw zainstalować pakiet samba, aby kontynuować + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + Nazwa współdzielenia nie może zawierać %<>*?|/\+=;:," i nie powinna się zaczynać od %1 + + + + To protect the files, you cannot share this folder. + Aby chronić pliki, nie możesz udostępniać tego folderu. + + + + Sharing failed + Błąd dzielenia + + + + The computer name is too long + Nazwa komputera jest zbyt długa + + + + You do not have permission to operate file/folder! + Nie masz uprawnień do dokonywania działań na tym pliku/katalogu! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Wprowadź hasło, aby chronić udostępnione foldery + + + + Cancel + button + Anuluj + + + + Confirm + button + Potwierdź + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_pt.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_pt.ts new file mode 100644 index 0000000..86cca34 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_pt.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Nova pasta + + + + Mounting device error + Erro do dispositivo de montagem + + + + The disc image was corrupted, cannot mount now, please erase the disc first + A imagem do disco foi corrompida, não pode ser montada agora, apague o disco primeiro + + + + Mount error: unsupported image format + Erro de montagem: formato de imagem não suportado + + + + + The device was not safely removed + O dispositivo não foi removido em segurança + + + + + Click "Safely Remove" and then disconnect it next time + Clique em "Remover em segurança" e retire-o da próxima vez + + + + The device was not ejected + O dispositivo não foi ejetado + + + + Disk is busy, cannot eject now + O disco está ocupado, não pode ser ejectado agora + + + + Authentication timed out + Autenticação expirou + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Transferência de ficheiros por Bluetooth + + + + File Transfer Successful + Transferência de ficheiros bem sucedida + + + + File Transfer Failed + Transferência de ficheiros falhada + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + A enviar ficheiros para "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Falha no envio de ficheiros para "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Enviado para "<b style="font-weight: 550;">%1</b>" com sucesso + + + + Select a Bluetooth device to receive files + Selecionar um dispositivo Bluetooth para receber ficheiros + + + + Cannot find the connected Bluetooth device + Não é possível encontrar o dispositivo Bluetooth ligado + + + + Waiting to be received... + À espera de ser recebido... + + + + Go to Bluetooth Settings + Ir para Definições Bluetooth + + + + %1/%2 Sent + %1/%2 Enviado + + + + Error: the Bluetooth device is disconnected + Erro: o dispositivo Bluetooth está desligado + + + + Unable to send the file more than 2 GB + Incapaz de enviar o ficheiro com mais de 2 GB + + + + Unable to send 0 KB files + Incapaz de enviar ficheiros 0 KB + + + + File doesn't exist + O ficheiro não existe + + + + Next + button + Seguinte + + + + Cancel + button + Cancelar + + + + Done + button + Concluído + + + + Retry + button + Repetir + + + + OK + button + Aceitar + + + + File sending request timed out + O pedido de envio de ficheiro expirou + + + + The service is busy and unable to process the request + O serviço está ocupado e não pode processar o pedido + + + + BurnOptDialog + + + Device error + Erro de dispositivo + + + + Optical device %1 doesn't exist + O dispositivo óptico %1 não existe + + + + Advanced settings + Definições avançadas + + + + File system: + Sistema de ficheiros: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Para Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Para Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Compatível com o modo Windows CD/DVD) + + + + ISO9660 Only + ISO9660 Apenas + + + + CloseAllDialogIndicator + + + Close all + Fechar todos + + + + Total size: %1, %2 files + Tamanho total: %1, %2 ficheiros + + + + ComputerModel + + + Double click to open it + + + + + My Directories + Meus Diretórios + + + + Disks + Discos + + + + File Vault + Cofre de ficheiros + + + + Quick Access + + + + + ComputerPropertyDialog + + + Computer + Computador + + + + Basic Info + Informação Básica + + + + + Computer Name + Nome do Computador + + + + + Edition + Edição + + + + + + Version + Versão + + + + + Type + Tipo + + + + + + Processor + Processador + + + + + + Memory + Memória + + + + + + + Bit + Bit + + + + + Available + Disponível + + + + Obtaining... + A obter... + + + + ConnectToServerDialog + + + Connect to Server + Ligar-se ao Servidor + + + + Cancel + button + Cancelar + + + + Connect + button + Ligar + + + + My Favorites: + Meus Favoritos: + + + + + Clear History + Eliminar Histórico + + + + DFMAddressBar + + + Search or enter address + Procurar ou inserir endereço + + + + DFMAdvanceSearchBar + + + Search: + Pesquisa: + + + + File Type: + Tipo de ficheiro: + + + + File Size: + Tamanho do ficheiro: + + + + Time Modified: + Data de Modificação: + + + + Time Accessed: + Duração do acesso: + + + + Time Created: + Data de criação: + + + + Reset + Restabelecer + + + + All subdirectories + Todos os subdiretórios + + + + Current directory + Diretório atual + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Hoje + + + + Yesterday + Ontem + + + + This week + Esta semana + + + + Last week + Na semana passada + + + + This month + Este mês + + + + Last month + No mês passado + + + + This year + Este ano + + + + Last year + No ano passado + + + + DFMOpticalMediaWidget + + + + No files to burn + Sem ficheiros para gravar + + + + Unable to burn. Not enough free space on the target disk. + Incapaz de gravar. Não existe espaço livre suficiente no disco de destino. + + + + %1 burning is not supported + A gravação %1 não é suportada + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. Não é %1 disco; +2. A versão deste sistema de ficheiros ainda não suporta adicionar ficheiros. + + + + DFMTagCrumbController + + + Tag information + Informação de etiqueta + + + + DFMTagWidget + + + Tag + Etiqueta + + + + DFMTaskWidget + + + Do not ask again + Não perguntar novamente + + + + Syncing data + Sincronização de dados + + + + Please wait + Aguarde + + + + + Time modified: %1 + Data de modificação: %1 + + + + + Contains: %1 + Conteúdo: %1 + + + + + Size: %1 + Tamanho: %1 + + + + Original folder + Pasta original + + + + Keep both + button + Manter ambos + + + + Skip + button + Ignorar + + + + Replace + button + Substituir + + + + Retry + button + Repetir + + + + Original file + Ficheiro original + + + + Target folder + Pasta de destino + + + + Target file + Ficheiro de destino + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Encriptar cofre de ficheiros + + + + Click 'Encrypt' and input the user password. + Clique em 'Encriptar' e introduza a palavra-passe do utilizador. + + + + Encrypting... + A encriptar... + + + + + + + Encrypt + Encriptar + + + + Failed to create file vault: %1 + Falha na criação do cofre de ficheiros: %1 + + + + OK + Aceitar + + + + The setup is complete + A configuração está concluída + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Guardar chave de recuperação + + + + Keep the key safe to retrieve the vault password later + Mantenha a chave segura para recuperar a palavra-passe do cofre mais tarde + + + + Save to default path + Guardar na localização padrão + + + + Save to other locations + Guardar para outros locais + + + + No permission, please reselect + Sem permissão, volte a selecionar + + + + Select a path + Selecionar uma localização + + + + Next + Seguinte + + + + The default path is invisible to other users, and the path information will not be shown. + A localização padrão é invisível para outros utilizadores e a informação da localização não será mostrada. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Chave de recuperação + + + + Generate a recovery key in case that you forgot the password + Gerar uma chave de recuperação no caso de se ter esquecido da palavra-passe + + + + Key + Chave + + + + QR code + Código QR + + + + Scan QR code and save the key to another device + Analisar o código QR e guardar a chave para outro dispositivo + + + + Next + Seguinte + + + + Recovery Key: + Chave de recuperação: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Definir palavra-passe do cofre + + + + Method + Método + + + + Manual + Manual + + + + Password + Palavra-passe + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 caracteres, contém A-Z, a-z, 0-9, e símbolos + + + + Repeat password + Repetir palavra-passe + + + + Input the password again + Introduzir novamente a palavra-passe + + + + Password hint + Sugestão de palavra-passe + + + + Optional + Opcional + + + + Next + Seguinte + + + + + Passwords do not match + As palavras-passe não coincidem + + + + DFMVaultActiveStartView + + + File Vault + Cofre de ficheiros + + + + Create your secure private space + Crie o seu espaço privado seguro + + + + Advanced encryption technology + Tecnologia de encriptação avançada + + + + Convenient and easy to use + Conveniente e fácil de usar + + + + Create + Criar + + + + DFMVaultFileView + + + Cannot open this path + Impossível abrir este local + + + + Hint + Dica + + + + OK + Aceitar + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Desbloquear por chave + + + + Failed to unlock file vault + Falha ao desbloquear o cofre de ficheiros + + + + OK + Aceitar + + + + Input the 32-digit recovery key + Introduza a chave de recuperação com 32 dígitos + + + + Cancel + button + Cancelar + + + + Unlock + button + Desbloquear + + + + Wrong recovery key + Chave de recuperação incorreta + + + + DFMVaultRemoveByPasswordView + + + Password + Palavra-passe + + + + Password hint: %1 + Sugestão de palavra-passe: 1% + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Introduza a chave de recuperação com 32 dígitos + + + + DFMVaultRemovePages + + + Delete File Vault + Eliminar cofre de ficheiros + + + + Once deleted, the files in it will be permanently deleted + Uma vez eliminados, os ficheiros que lá se encontram serão permanentemente eliminados + + + + Use Key + Utilizar chave + + + + Cancel + button + Cancelar + + + + Use Key + button + Utilizar chave + + + + Delete + button + Eliminar + + + + + OK + button + Aceitar + + + + Use Password + Utilizar palavra-passe + + + + Wrong password + Palavra-passe incorreta + + + + Wrong recovery key + Chave de recuperação incorreta + + + + Failed to delete file vault + Falha ao eliminar o cofre de ficheiros + + + + Deleted successfully + Eliminado com sucesso + + + + Failed to delete + Falha ao eliminar + + + + Removing... + A remover... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + Não foi possível obter o ficheiro chave + + + + Verification failed + Falha na verificação + + + + + Select a path + Selecionar uma localização + + + + + Retrieve Password + Recuperar palavra-passe + + + + By key in the default path + Por chave na localização padrão + + + + By key in the specified path + Por chave na localização especificada + + + + Verification Successful + Verificação bem sucedida. + + + + Keep it safe + Mantenha-a segura + + + + Back + button + Retroceder + + + + Verify Key + button + Verificar chave + + + + Go to Unlock + button + Ir para Desbloquear + + + + Close + button + Fechar + + + + Vault password: %1 + Palavra-passe do cofre: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Desbloquear cofre de ficheiros + + + + Forgot password? + Esqueceu-se da palavra-passe? + + + + Password hint: %1 + Sugestão de palavra-passe: 1% + + + + Failed to unlock file vault + Falha ao desbloquear o cofre de ficheiros + + + + Cancel + button + Cancelar + + + + Password + Palavra-passe + + + + Unlock + button + Desbloquear + + + + Please try again %1 minutes later + Tente novamente %1 minutos mais tarde + + + + Wrong password, please try again %1 minutes later + Palavra-passe incorreta. Tente novamente %1 minutos mais tarde + + + + Wrong password, one chance left + Palavra-passe incorreta, uma tentativa restante + + + + Wrong password, %1 chances left + Palavra-passe incorreta, %1 tentativas restantes + + + + Wrong password + Palavra-passe incorreta + + + + OK + button + Aceitar + + + + DFileCopyMoveJob + + + Permission error + Erro de autorização + + + + The action is denied + Esta ação não é permitida + + + + Failed to open the file + Erro ao abrir o ficheiro + + + + Failed to read the file + Erro ao ler o ficheiro + + + + Failed to write the file + Erro ao escrever o ficheiro + + + + Failed to create the directory + Erro ao criar a diretório + + + + Failed to delete the file + Falha ao eliminar o ficheiro + + + + Failed to move the file + Erro ao mover o ficheiro + + + + Original file does not exist + O ficheiro original não existe + + + + Failed, file size must be less than 4GB + Erro, o tamanho tem de ser inferior a 4GB + + + + Not enough free space on the target disk + Não há espaço livre suficiente no disco de destino. + + + + File integrity was damaged + Integridade do ficheiro danificada + + + + The target device is read only + O dispositivo de destino é apenas de leitura + + + + Target folder is inside the source folder + A pasta de destino é dentro da pasta de origem + + + + The action is not supported + A ação não é suportada + + + + You do not have permission to traverse files in it + Não tem autorização para percorrer ficheiros dentro dele + + + + Failed to position the file pointer! + + + + + copy + Extra name added to new file name when used for file name. + copiar + + + + Failed to open the directory, cause: file name too long + Falha ao abrir o diretório, causa: nome do ficheiro demasiado comprido + + + + + Failed to open the file, cause: file name too long + Falha ao abrir o ficheiro, causa: nome do ficheiro demasiado comprido + + + + + Failed to write the file, cause: + Erro ao gravar o ficheiro, causa: + + + + Failed to position the file pointer, cause: %1 + + + + + Syncing data + Sincronização de dados + + + + Please wait + Aguarde + + + + Failed to create the directory, cause: %1 + Falha ao criar diretório. Motivo: %1 + + + + + + + + Failed to open the file, cause: %1 + Erro ao abrir o ficheiro, causa: %1 + + + + + + + Failed to open the file, cause: Permission denied + Erro ao abrir o ficheiro, causa: Autorização negada + + + + + Failed to read the file, cause: %1 + Erro ao ler o ficheiro, causa: %1 + + + + + + + Failed to write the file, cause: %1 + Erro ao escrever o ficheiro, causa: %1 + + + + + File integrity was damaged, cause: %1 + Integridade do ficheiro danificada, causa: %1 + + + + Failed to open the file, cause: + Falha ao abrir o ficheiro, causa: + + + + Failed to read the file, cause: + Falha ao ler o ficheiro, causa: + + + + Failed to delete the file, cause: %1 + Erro ao eliminar o ficheiro, causa: %1 + + + + Fail to create symlink, cause: %1 + Falha ao criar atalho, causa: %1 + + + + DFileDialog + + + + Save + button + Guardar + + + + + Cancel + button + Cancelar + + + + Confirm + button + Confirmar + + + + %1 already exists, do you want to replace it? + %1 já existe, deseja substitui-lo? + + + + Replace + button + Substituir + + + + Open + button + Abrir + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Este ficheiro será ocultado se o nome do ficheiro começar com um (.). Deseja ocultá-lo? + + + + DFileManagerWindow + + + Trash + Lixo + + + + Empty + Esvaziar + + + + DFileSystemModel + + + + Name + Nome + + + + + + Time modified + Data de Modificação + + + + Size + Tamanho + + + + Type + Tipo + + + + Time created + Data de criação + + + + + Last access + O último acesso + + + + + + + Path + Caminho + + + + DFileView + + + Disc mount error + Erro ao montar disco + + + + The disc is in use, please end the running process and remount the disc. + O disco está a ser utilizado. Termine o processo em execução e volte a montar o disco. + + + + Mounting failed + Falha ao montar + + + + (Reverse) + (Reverter) + + + + DFileViewHelper + + + Add tag "%1" + Adicionar etiqueta "%1" + + + + DStatusBar + + + %1 item + %1 item + + + + %1 items + %1 itens + + + + %1 item selected + %1 item selecionado + + + + %1 items selected + %1 itens selecionados + + + + %1 folder selected (contains %2) + %1 pasta selecionada (contém %2) + + + + %1 folders selected (contains %2) + %1 pastas selecionadas (contém %2) + + + + %1 file selected (%2) + %1 ficheiro selecionado (%2) + + + + %1 files selected (%2) + %1 ficheiros selecionados (%2) + + + + %1 folder selected + %1 pasta selecionada + + + + Filter + Filtro + + + + Save as: + Guardar como: + + + + Loading... + A carregar... + + + + DTaskDialog + + + Erasing disc %1, please wait... + A apagar o disco %1, aguarde... + + + + Burning disc %1, please wait... + A gravar o disco %1, aguarde... + + + + Writing data... + A escrever dados... + + + + Verifying data... + A verificar dados... + + + + Copying %1 + A copiar %1 + + + + + + to %2 + para %2 + + + + %1 already exists in target folder + %1 já existe na pasta de destino + + + + Original path %1 Target path %2 + Caminho de origem %1 Caminho de destino %2 + + + + Merge + button + Agrupar + + + + Replace + button + Substituir + + + + Moving %1 + A mover %1 + + + + Removing file vault, please try later + A remover o cofre de ficheiros, tente mais tarde + + + + Restoring %1 + A restaurar %1 + + + + Deleting %1 + A eliminar %1 + + + + Trashing %1 + A enviar %1 para o lixo + + + + Calculating space, please wait + A calcular o espaço, aguarde + + + + DUMountManager + + + + Authentication timed out + Autenticação expirou + + + + + + Disk is busy, cannot unmount now + O disco está ocupado, não pode ser desmontado agora + + + + Disk is busy, cannot eject now + O disco está ocupado, não pode ser ejectado agora + + + + The device is busy, cannot eject now + O dispositivo está ocupado, não é possível ejectar agora + + + + + + The device is busy, cannot remove now + O dispositivo está ocupado, não é possível remover agora + + + + DeepinStorage + + + + + %1 Volume + Volume %1 + + + + Data Disk + Data Partition + Dados do disco + + + + %1 Drive + Unidade %1 + + + + Blank %1 Disc + Disco %1 Vazio + + + + %1 Encrypted + %1 Encriptado + + + + DialogManager + + + + + + Operation failed! + Falha na operação! + + + + Target folder is inside the source folder! + A pasta de destino está dentro da pasta de origem! + + + + Do you want to run %1 or display its content? + Deseja executar %1 ou mostrar o seu conteúdo? + + + + It is an executable text file. + É um ficheiro de texto executável. + + + + It is an executable file. + É um um ficheiro executável. + + + + This file is not executable, do you want to add the execute permission and run? + Este ficheiro não é executável, deseja adicionar a autorização de execução e executá-lo? + + + + "%1" already exists, please use another name. + "%1" já existe, use outro nome. + + + + The file name must not contain two dots (..) + O nome do ficheiro não deve conter dois pontos (..) + + + + Device or resource busy + + + + + Are you sure you want to erase all data on the disc? + Tem a certeza que deseja apagar todos os dados no disco? + + + + How do you want to use this disc? + Como deseja usar este disco? + + + + Disc erase failed + Erro ao apagar o disco + + + + Burn process failed + Processo de gravação falhou + + + + %1: %2 + %1: %2 + + + + Show details + Mostrar detalhes + + + + Hide details + Ocultar detalhes + + + + Error + Erro + + + + Permanently delete %1? + Eliminar permanentemente %1? + + + + Permanently delete %1 items? + Eliminar permanentemente %1 itens? + + + + Empty + Esvaziar + + + + Do you want to delete %1? + Deseja eliminar %1? + + + + Do you want to delete the selected %1 items? + Deseja eliminar os %1 itens selecionados? + + + + Sorry, unable to locate your bookmark directory, remove it? + Não foi possível encontrar o seu diretório de favoritos. Deseja removê-lo? + + + + Name: + Nome: + + + + %1 that this shortcut refers to has been changed or moved + %1 a que este atalho se refere foi modificado ou movido + + + + Do you want to delete this shortcut? + Tem a certeza que quer eliminar este atalho? + + + + Failed, file size must be less than 4GB. + Erro, o tamanho do ficheiro tem de ser menor de 4GB. + + + + Fail to create symlink, cause: + Erro ao criar hiperligação simbólica, causa: + + + + The selected files contain system file/directory, and it cannot be deleted + Os ficheiros selecionados contêm ficheiros/diretórios de sistema, por isso não podem ser eliminados + + + + Unable to find the original file + Não foi possível localizar o ficheiro original + + + + + You do not have permission to operate file/folder! + Não tem autorização para alterar o ficheiro/pasta! + + + + Failed to restore %1 file, the source file does not exist + Falha ao restaurar o ficheiro %1, o ficheiro de origem não existe + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Desculpe, não tem autorização para operar o seguinte %1 ficheiro/pasta(s)! + + + + Unable to access %1 + Incapaz de aceder a %1 + + + + + Sending files now, please try later + A enviar ficheiros, tente mais tarde + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Para aceder ao dispositivo, é necessário formatar primeiro o disco. Tem a certeza que o deseja formatar agora? + + + + Scanning the device, stop it? + A analisar o dispositivo, interromper? + + + + Share folder can't be named after the current username + A pasta de partilha não pode ser nomeada depois do nome de utilizador atual + + + + Do you want to run %1? + Deseja executar %1? + + + + Burn image + button + Gravar imagem + + + + Burn files + button + Gravar ficheiros + + + + Are you sure you want to empty %1 item? + Tem a certeza que deseja eliminar %1 item? + + + + Are you sure you want to empty %1 items? + Tem a certeza que deseja eliminar %1 itens? + + + + + This action cannot be undone + Esta ação não pode ser anulada + + + + + + + + + + + + + + OK + button + Aceitar + + + + + + + + + + + + + + + Cancel + button + Cancelar + + + + + + Run + button + Executar + + + + + Run in terminal + button + Executar no Terminal + + + + Display + button + Visualizar + + + + + + + + + + + Confirm + button + Confirmar + + + + Erase + button + Apagar + + + + Data verification failed + Falha na verificação de dados + + + + Show details + button + Mostrar detalhes + + + + + Delete + button + Eliminar + + + + Remove + button + Remover + + + + Disk is busy, cannot unmount now + O disco está ocupado, não é possível desmontar agora + + + + Force unmount + button + Forçar desmontagem + + + + Unable to copy. Not enough free space on the target disk. + Incapaz de copiar. Não há espaço livre suficiente no disco de destino. + + + + Failed to restore %1 file, the target folder is read-only + Erro ao restaurar o ficheiro %1, a pasta de destino é apenas de leitura + + + + Failed to restore %1 files, the target folder is read-only + Erro ao restaurar ficheiros %1, a pasta de destino é apenas de leitura + + + + Failed to restore %1 files, the source files do not exist + Falha ao restaurar %1 ficheiros, os ficheiros de origem não existem + + + + Format + button + Formatar + + + + Stop + button + Parar + + + + FileController + + + + + + Unable to find the original file + Não foi possível localizar o ficheiro original + + + + + + Kindly Reminder + Aviso + + + + + + Please install File Roller first and then continue + Instalar o File Roller primeiro e depois continuar + + + + + Unable to create files here: %1 + Incapaz de criar ficheiros aqui: %1 + + + + Confirm + button + Confirmar + + + + FileDialogStatusBar + + + File Name + Nome do ficheiro + + + + Format + Formato + + + + Save + button + Guardar + + + + Open + button + Abrir + + + + Save File + button + Guardar Ficheiro + + + + Open File + button + Abrir ficheiro + + + + + + Cancel + button + Cancelar + + + + FileJob + + + copy + copiar + + + + + + + Data verification successful. + Verificação de dados bem sucedida. + + + + + + Burn process completed + Processo de gravação concluído + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 é um ficheiro duplicado. + + + + Insufficient disc space. + Espaço em disco insuficiente. + + + + Lost connection to drive. + Ligação à unidade perdida. + + + + The CD/DVD drive is not ready. Try another disc. + A unidade de CD/DVD não está pronta. Tente outro disco. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + A unidade de CD/DVD está ocupada. Saia do programa usando a unidade e insira a unidade novamente. + + + + Unknown error + Erro desconhecido + + + + Device disconnected + Unidade desligada + + + + GenerateSettingTranslate + + + + + Basic + Básico + + + + + + Open behavior + Comportamento de abertura + + + + + + Always open folder in new window + Abrir sempre pastas numa nova janela + + + + + + Open file: + Abrir ficheiro: + + + + + + Click + Clique + + + + + + Double click + Duplo clique + + + + + + New window and tab + Nova janela e separador + + + + + + Open from default window: + Abrir a janela por predefinição em: + + + + + + + + + Computer + Computador + + + + + + + + + Home + Pasta Pessoal + + + + + + + + + Desktop + Ambiente de trabalho + + + + + + + + + Videos + Vídeos + + + + + + + + + Music + Música + + + + + + + + + Pictures + Imagens + + + + + + + + + Documents + Documentos + + + + + + + + + Downloads + Transferências + + + + + + Open in new tab: + Abrir num novo separador: + + + + + + Current Directory + Diretório atual + + + + + + View + Ver + + + + + + Default size: + Tamanho predefinido: + + + + + + Extra small + Extra pequeno + + + + + + Small + Pequeno + + + + + + Medium + Médio + + + + + + Large + Grande + + + + + + Extra large + Extra grande + + + + + + Default view: + Vista predefinida: + + + + + + Icon + Ícone + + + + + + List + Lista + + + + + + Hidden files + Ficheiros ocultos + + + + + + Show hidden files + Mostrar ficheiros ocultos + + + + + + Hide file extension when rename + Ocultar extensão do ficheiro ao renomear + + + + + + Advanced + Avançado + + + + + + Index + Indexar + + + + + + Auto index internal disk + Indexação automática do disco interno + + + + + + Index external storage device after connected to computer + Indexar armazenamento externo depois de ligado ao computador + + + + + + Full-Text search + Pesquisa de texto completo + + + + + + Show item counts and sizes in the path of mounted MTP devices + Mostrar contagem de itens e tamanho no endereço de montagem dos dispositivos MTP + + + + + + Keep showing the mounted Samba shares + Continuar a mostrar as partilhas do Samba montadas + + + + + + Use the file chooser dialog of File Manager + Usar a caixa de diálogo de seleção de ficheiros do Gestor de Ficheiros + + + + + + Ask for my confirmation when deleting files + Pedir a minha confirmação ao eliminar ficheiros + + + + + + Other + Outro + + + + + + Hide system disk + Ocultar disco de sistema + + + + + + Show file system on disk icon + Mostrar sistema de ficheiros no ícone do disco + + + + + + Show hidden files in search results + Mostrar ficheiros ocultos nos resultados de pesquisa + + + + + + Display recent file entry in left panel + Mostrar ficheiros recentes no painel esquerdo + + + + + + Preview + Pré-visualizar + + + + + Compress file preview + Pré-visualizar ficheiros comprimidos + + + + + + Text preview + Pré-visualizar textos + + + + + + Document preview + Pré-visualizar documentos + + + + + + Image preview + Pré-visualizar imagens + + + + + + Video preview + Pré-visualizar vídeos + + + + + + Mount + Montar + + + + + + Auto mount + Montar automaticamente + + + + + + Open after auto mount + Abrir depois de montar automaticamente + + + + + + Dialog + Caixa de diálogo + + + + Compressed file preview + Pré-visualização de ficheiro comprimido + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Não é possível verificar a identidade de %1. + + + + This happens when you log in to a computer the first time. + Isto acontece quando se inicia sessão num computador pela primeira vez. + + + + The identity sent by the remote computer is + A identidade enviada pelo computador remoto é + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Se quiser ter a certeza absoluta de que é seguro continuar, contacte o administrador do sistema. + + + + + + + + Mounting device error + Erro ao montar dispositivo + + + + + Wrong username or password + Nome de utilizador ou palavra-passe incorretos + + + + + + + + Confirm + button + Confirmar + + + + + Cannot find the mounted device + Não é possível localizar o dispositivo montado + + + + No key available to unlock device + Nenhuma chave disponível para desbloquear o dispositivo + + + + The disk is mounted by user "%1", you cannot unmount it. + O disco foi montado pelo utilizador "%1", não o pode desmontar. + + + + Cannot unmount the device + Não é possível desmontar o dispositivo + + + + Cannot eject the device "%1" + Não é possível ejectar o dispositivo "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Incapaz de gravar. Não existe espaço livre suficiente no disco de destino. + + + + MergedDesktopController + + + + Pictures + Imagens + + + + + Music + Música + + + + + Applications + Aplicações + + + + + Videos + Vídeos + + + + + Documents + Documentos + + + + + Others + Outros + + + + MimeTypeDisplayManager + + + + Directory + Diretório + + + + + + Application + Aplicação + + + + + + Video + Vídeo + + + + + + Audio + Áudio + + + + + + Image + Imagem + + + + + Archive + Arquivo + + + + + + Text + Texto + + + + + Executable + Executável + + + + + Backup file + Cópia de segurança + + + + + Unknown + Desconhecido + + + + MountAskPasswordDialog + + + Cancel + button + Cancelar + + + + Connect + button + Ligar + + + + Log in as + Entrar como + + + + Anonymous + Anónimo + + + + Registered user + Utilizador registado + + + + Username + Utilizador + + + + Domain + Domínio + + + + Password + Palavra-passe + + + + Remember password + Lembrar palavra-passe + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Cancelar + + + + Unlock + button + Desbloquear + + + + Input password to decrypt the disk + Inserir a palavra-passe para desencriptar o disco + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Tem a certeza que deseja eliminar definitivamente %1? + + + + This file is too big for the trash + Este ficheiro é demasiado grande para mover para o lixo + + + + The files are too big for the trash + Os ficheiros são demasiado grandes para mover para o lixo + + + + Are you sure you want to permanently delete %1 files? + Tem a certeza que deseja eliminar definitivamente %1 ficheiros? + + + + Cancel + button + Cancelar + + + + Delete + button + Eliminar + + + + OpenWithDialog + + + Open with + Abrir com + + + + Add other programs + Adicionar outros programas + + + + Set as default + Estabelecer como predefinido + + + + Cancel + button + Cancelar + + + + Confirm + button + Confirmar + + + + Recommended Applications + Aplicações Recomendadas + + + + Other Applications + Outras Aplicações + + + + PathManager + + + Home + Pasta Pessoal + + + + Desktop + Ambiente de trabalho + + + + Videos + Vídeos + + + + Music + Música + + + + Pictures + Imagens + + + + Documents + Documentos + + + + Downloads + Transferências + + + + + Trash + Lixo + + + + + + System Disk + Disco do sistema + + + + Computers in LAN + Computadores em rede de área local + + + + My Shares + Minhas Partilhas + + + + Computer + Computador + + + + Recent + Recente + + + + File Vault + Cofre de ficheiros + + + + PropertyDialog + + + Basic info + Informação básica + + + + Open with + Abrir com + + + + Sharing + Partilha + + + + Permissions + Autorizações + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Ocultar esta pasta + + + + Hide this file + Ocultar este ficheiro + + + + Allow to execute as program + Permitir execução como programa + + + + QObject + + + + + + Size + Tamanho + + + + + + Contains + Conteúdo + + + + + + Type + Tipo + + + + + + + + Time modified + Data de modificação + + + + Free space + Espaço livre + + + + Total space + Espaço total + + + + + Time locked + Tempo bloqueado + + + + Access denied + Acesso negado + + + + + Executable + Executável + + + + + Write only + Apenas escrever + + + + + Read only + Apenas ler + + + + + Read-write + Ler-Escrever + + + + Others + Outros + + + + Owner + Proprietário + + + + Unconnected network shared directory + Diretório partilhado não ligado em rede + + + + Device type + Tipo de dispositivo + + + + File system + Sistema de ficheiros + + + + Group + Grupo + + + + + Open + Abrir + + + + Lock + Bloquear + + + + Auto lock + Bloqueio automático + + + + Never + Nunca + + + + 5 minutes + 5 minutos + + + + 10 minutes + 10 minutos + + + + 20 minutes + 20 minutos + + + + Delete File Vault + Eliminar cofre de ficheiros + + + + Unlock + Desbloquear + + + + Unlock by key + Desbloquear com chave + + + + Open + button + Abrir + + + + + Size: %1 + Tamanho: %1 + + + + Type: %1 + Tipo: %1 + + + + Size: 0 + Tamanho: 0 + + + + Items: %1 + Itens: %1 + + + + + + + + + + Open in new window + Abrir numa nova janela + + + + + + + + + + Open in new tab + Abrir num novo separador + + + + Open with + Abrir com + + + + + Compress + Comprimir + + + + Extract + Extrair + + + + Extract here + Extrair aqui + + + + Cut + Cortar + + + + Copy + Copiar + + + + Paste + Colar + + + + + + + + Rename + Renomear + + + + + + + Remove + Remover + + + + Create link + Criar ligação + + + + Send to desktop + Enviar para o ambiente de trabalho + + + + Send to + Enviar para + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Adicionar aos favoritos + + + + + + + Properties + Propriedades + + + + New folder + Nova pasta + + + + New window + Nova janela + + + + Select all + Selecionar todos + + + + + Clear recent history + Eliminar histórico recente + + + + + + Empty Trash + Esvaziar o lixo + + + + Display as + Mostrar como + + + + Sort by + Ordenar por + + + + New document + Novo documento + + + + + Time created + Data de criação + + + + + + Source path + Caminho de origem + + + + Share folder + Partilhar pasta + + + + Cancel sharing + Cancelar partilha + + + + Connect to Server + Ligar-se ao Servidor + + + + Set share password + Definir palavra-passe da partilha + + + + Format + Formatar + + + + Tag information + Informação de etiqueta + + + + Open as administrator + Abrir como administrador + + + + Select default program + Selecionar programa predefinido + + + + Open file location + Abrir localização do ficheiro + + + + Remove bookmark + Remover favorito + + + + + + Delete + Eliminar + + + + Office Text + Texto do Office + + + + Spreadsheets + Folha de Cálculo + + + + Plain Text + Texto Simples + + + + Open in terminal + Abrir no terminal + + + + Restore + Restaurar + + + + Restore all + Restaurar tudo + + + + Clear saved password and unmount + Limpar palavra-passe guardada e desmontar + + + + File Vault + Cofre de ficheiros + + + + Add to disc + Adicionar ao disco + + + + Refresh + + + + + Auto mount + Montar automaticamente + + + + Open after auto mount + Abrir depois de montar automaticamente + + + + + Mount + Montar + + + + + Unmount + Desmontar + + + + It does not support burning %1 discs + Não suporta a gravação de discos %1 + + + + Burn + Gravar + + + + Disc name: + Nome do disco: + + + + + Maximum + Máximo + + + + Allow files to be added later + Permite que os ficheiros sejam adicionados depois + + + + Verify data + Verificar dados + + + + Write speed: + Velocidade de gravação: + + + + + + + Cancel + button + Cancelar + + + + Burn + button + Gravar + + + + + Eject + Ejetar + + + + Safely Remove + Remover em segurança + + + + + Name + Nome + + + + Settings + Definições + + + + Exit + Sair + + + + Icon + Ícone + + + + List + Lista + + + + Extend + Expandir + + + + Set as wallpaper + Definir como papel de parede + + + + + + + Local disk + Disco local + + + + + Removable disk + Disco removível + + + + + + Network shared directory + Pasta de rede partilhada + + + + + Android mobile device + Dispositivo móvel Android + + + + + Apple mobile device + Dispositivo móvel Apple + + + + + Camera + Câmara + + + + + DVD + DVD + + + + + Unknown device + Dispositivo desconhecido + + + + + + %1 item + %1 item + + + + + + %1 items + %1 itens + + + + Shortcut + Atalho + + + + Create symlink + Criar hiperligação simbólica + + + + Path + Caminho + + + + + + Time deleted + Data de eliminação + + + + Loading... + A Carregar... + + + + File has been moved or deleted + O ficheiro foi movido ou eliminado + + + + You do not have permission to traverse files in it + Não tem autorização para percorrer ficheiros dentro dele + + + + + + You do not have permission to access this folder + Não tem autorização para aceder a esta pasta + + + + + + + + Folder is empty + Esta pasta está vazia + + + + Searching... + A Procurar... + + + + No results + Sem resultados + + + + Source Path + TrashFileInfo + Caminho de origem + + + + Document + Documento + + + + Spreadsheet + Folha de Cálculo + + + + + Presentation + Apresentação + + + + Text + Texto + + + + 1 task in progress + 1 tarefa em andamento + + + + %1 tasks in progress + %1 tarefas em andamento + + + + Mode: + Modo: + + + + + Replace Text + Substituir Texto + + + + + Add Text + Adicionar Texto + + + + + Custom Text + Texto Personalizado + + + + Find: + Encontrar: + + + + Replace: + Substituir: + + + + + Optional + Opcional + + + + Add: + Adicionar: + + + + Location: + Localização: + + + + File name: + Nome do ficheiro: + + + + Start at: + Começar a: + + + + + Rename + button + Renomear + + + + + + + + + + + Required + Obrigatório + + + + + Before file name + Antes do nome do ficheiro + + + + + After file name + Depois do nome do ficheiro + + + + Find + Encontrar + + + + Replace + Substituir + + + + Add + Adicionar + + + + Start at + Começar a + + + + + + Location + Localização + + + + File name + Nome de ficheiro + + + + Dimension + Dimensão + + + + Duration + Duração + + + + Tips: Sort by selected file order + Dicas: ordenar por ordem de ficheiro selecionado + + + + Rename %1 Files + Renomear %1 ficheiros + + + + Multiple Files + Múltiplos Ficheiros + + + + Basic info + Informação básica + + + + Total size + Tamanho total + + + + Number of files + Número de ficheiros + + + + %1 file(s), %2 folder(s) + %1 ficheiro(s), %2 pasta(s) + + + + + + Time accessed + Duração do acesso + + + + Orange + Laranja + + + + Red + Vermelho + + + + Purple + Roxo + + + + Navy-blue + Azul-marinho + + + + Azure + Azul + + + + Green + Verde + + + + Yellow + Amarelo + + + + Gray + Cinzento + + + + Input tag info, such as work, family. A comma is used between two tags. + Insira a informação da etiqueta, como trabalho, família. Uma vírgula é usada entre duas etiquetas. + + + + Bookmarks + Favoritos + + + + Erase + Apagar + + + + Copy path + Copiar caminho + + + + Edit address + Editar endereço + + + + Free Space %1 + Espaço Livre %1 + + + + Files are being processed + Os ficheiros estão a ser processados + + + + + Unknown + Desconhecido + + + + My Vault + O meu cofre + + + + + Failed to create file info + Falha ao criar informações de ficheiros + + + + Failed to create file handler + Falha ao criar manuseamento de ficheiros + + + + Failed to open the file, cause: %1 + Erro ao abrir o ficheiro, causa: %1 + + + + Original file does not exist + O ficheiro original não existe + + + + Do you want to delete %1? + Deseja eliminar %1? + + + + Confirm + button + Confirmar + + + + + + + + %1 are not allowed + %1 não são permitidos + + + + + Failed to start Samba services + Falha ao iniciar os serviços Samba + + + + RecentController + + + Cancel + button + Cancelar + + + + Remove + button + Remover + + + + Do you want to remove this item? + Deseja remover este item? + + + + Do yout want to remove %1 items? + Deseja remover %1 itens? + + + + It does not delete the original files + Não elimina os ficheiros originais + + + + ShareInfoFrame + + + Share this folder + Partilhar esta pasta + + + + Share name: + Nome da partilha: + + + + Permission: + Autorização: + + + + Read and write + Ler e escrever + + + + Read only + Só de leitura + + + + Anonymous: + Anónimo: + + + + Not allow + Não permitir + + + + Allow + Permitir + + + + The share name must not be two dots (..) or one dot (.) + O nome da partilha não deve ter dois pontos (..) ou um ponto (.) + + + + The share name is used by another user. + O nome da partilha é usado por outro utilizador. + + + + OK + button + Aceitar + + + + Cancel + button + Cancelar + + + + Replace + button + Substituir + + + + The share name already exists. Do you want to replace the shared folder? + O nome da partilha já existe. Deseja substituir a pasta partilhada? + + + + Shortcut + + + Item + Item + + + + Select to the first item + Selecionar para o primeiro item + + + + Shift + Home + Shift + Home + + + + Select to the last item + Selecionar até o último item + + + + Shift + End + Shift + End + + + + Select leftwards + Selecionar à esquerda + + + + Shift + Left + Shift + Left + + + + Select rightwards + Selecionar à direita + + + + Shift + Right + Shift + Right + + + + Select to upper row + Selecionar linha superior + + + + Shift + Up + Shift + Seta para cima + + + + Select to lower row + Selecionar a linha inferior + + + + Shift + Down + Shift + Seta para baixo + + + + Open + Abrir + + + + Ctrl + Down + Ctrl + Seta para baixo + + + + To parent directory + Ir para a pasta acima + + + + Ctrl + Up + Ctrl + Seta para cima + + + + Permanently delete + Eliminar permanentemente + + + + Shift + Delete + Shift + Delete + + + + Delete file + Eliminar ficheiro + + + + Delete + Eliminar + + + + Select all + Selecionar todos + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Copiar + + + + Cut + Cortar + + + + Paste + Colar + + + + Rename + Renomear + + + + F2 + F2 + + + + New/Search + Novo/Pesquisa + + + + New window + Nova janela + + + + New folder + Nova pasta + + + + + Search + Pesquisa + + + + New tab + Novo separador + + + + View + Ver + + + + Item information + Informação do item + + + + Help + Ajuda + + + + F1 + F1 + + + + Keyboard shortcuts + Teclas de atalho + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Alterar estado de visualização + + + + Hide item + Ocultar item + + + + Input in address bar + Escrever na barra de endereços + + + + Switch to icon view + Alterar para vista de ícone + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Alterar para vista de lista + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Outros + + + + Close + Fechar + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Fechar separador atual + + + + Back + Retroceder + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Alterar para separador seguinte + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Alterar para separador anterior + + + + Next file + Ficheiro seguinte + + + + Tab + Tab + + + + Previous file + Ficheiro anterior + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Alternar o tab especificando um número entre 1 a 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Avançar + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Incapaz de abrir os itens no lixo, restaure-os primeiro + + + + TrashPropertyDialog + + + Trash + Lixo + + + + item + item + + + + items + itens + + + + Contains %1 %2 + Contém %1 %2 + + + + UDiskListener + + + Failed to rename the label + Erro ao renomear a etiqueta + + + + UnmountWorker + + + + + The device was not safely unmounted + O dispositivo não foi desmontado em segurança + + + + The device was not safely removed + O dispositivo não foi removido em segurança + + + + UserShareManager + + + Kindly Reminder + Advertência + + + + Please firstly install samba to continue + Instale primeiro o samba para continuar + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + O nome da partilha não deve conter %<>*?|/\+=;:," e não pode iniciar com %1 + + + + To protect the files, you cannot share this folder. + Para proteger os ficheiros, não pode partilhar esta pasta. + + + + Sharing failed + Falha ao partilhar + + + + The computer name is too long + O nome do computador é demasiado extenso + + + + You do not have permission to operate file/folder! + Não tem autorização para alterar o ficheiro/pasta! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Introduza uma palavra-passe para proteger pastas partilhadas + + + + Cancel + button + Cancelar + + + + Confirm + button + Confirmar + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_pt_BR.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_pt_BR.ts new file mode 100644 index 0000000..13cc76d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_pt_BR.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Nova Pasta + + + + Mounting device error + Erro ao montar o dispositivo + + + + The disc image was corrupted, cannot mount now, please erase the disc first + A imagem do disco está corrompida, e não pode ser montada; apague o disco + + + + Mount error: unsupported image format + Erro de montagem: formato de imagem não suportado + + + + + The device was not safely removed + O dispositivo não foi removido com segurança + + + + + Click "Safely Remove" and then disconnect it next time + Clique em "Remover com segurança" e então desconecte-o na próxima vez + + + + The device was not ejected + O dispositivo não foi ejetado + + + + Disk is busy, cannot eject now + O disco está ocupado; é impossível ejetá-lo agora + + + + Authentication timed out + A autenticação expirou + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Transferir arquivos por Bluetooth + + + + File Transfer Successful + A transferência dos arquivos foi bem-sucedida + + + + File Transfer Failed + A transferência dos arquivos falhou + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Enviando os arquivos para "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Falha ao enviar os arquivos para "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Enviado para "<b style="font-weight: 550;">%1</b>" + + + + Select a Bluetooth device to receive files + Selecione um dispositivo Bluetooth para receber os arquivos + + + + Cannot find the connected Bluetooth device + Impossível encontrar o dispositivo Bluetooth conectado + + + + Waiting to be received... + Aguardando ser recebido... + + + + Go to Bluetooth Settings + Ir para Configurações de Bluetooth + + + + %1/%2 Sent + Enviado %1/%2 + + + + Error: the Bluetooth device is disconnected + Erro: o dispositivo Bluetooth está desconectado + + + + Unable to send the file more than 2 GB + Impossível enviar os arquivos com mais de 2 GB + + + + Unable to send 0 KB files + Impossível enviar arquivos de 0 kB + + + + File doesn't exist + O arquivo não existe + + + + Next + button + Próximo + + + + Cancel + button + Cancelar + + + + Done + button + Concluído + + + + Retry + button + Tentar novamente + + + + OK + button + Ok + + + + File sending request timed out + A solicitação de envio do arquivo expirou + + + + The service is busy and unable to process the request + O serviço está ocupado e não pode processar a solicitação + + + + BurnOptDialog + + + Device error + Erro de dispositivo + + + + Optical device %1 doesn't exist + O dispositivo óptico %1 não existe + + + + Advanced settings + Configurações avançadas + + + + File system: + Sistema de arquivos: + + + + ISO9660/Joliet (For Windows) + ISO 9660 / Joliet (Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO 9660 / Rock Ridge (Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Compatível com modo Windows de CD / DVD) + + + + ISO9660 Only + Somente ISO 9660 + + + + CloseAllDialogIndicator + + + Close all + Fechar tudo + + + + Total size: %1, %2 files + Tamanho total: %1, %2 arquivos + + + + ComputerModel + + + Double click to open it + + + + + My Directories + Meus Diretórios + + + + Disks + Dispositivos + + + + File Vault + Cofre de Arquivo + + + + Quick Access + + + + + ComputerPropertyDialog + + + Computer + Computador + + + + Basic Info + Informação Básica + + + + + Computer Name + Nome do Computador + + + + + Edition + Versão + + + + + + Version + Versão + + + + + Type + Tipo + + + + + + Processor + Processador + + + + + + Memory + Memória + + + + + + + Bit + Bit + + + + + Available + Disponível + + + + Obtaining... + Obtendo... + + + + ConnectToServerDialog + + + Connect to Server + Conectar ao servidor + + + + Cancel + button + Cancelar + + + + Connect + button + Conectar + + + + My Favorites: + Favoritos: + + + + + Clear History + Limpar histórico + + + + DFMAddressBar + + + Search or enter address + Pesquise ou insira o endereço + + + + DFMAdvanceSearchBar + + + Search: + Pesquisar: + + + + File Type: + Tipo de Arquivo: + + + + File Size: + Tamanho do Arquivo: + + + + Time Modified: + Última modificação: + + + + Time Accessed: + Último acesso: + + + + Time Created: + Data da Criação: + + + + Reset + Redefinir + + + + All subdirectories + Todas as subpastas + + + + Current directory + Diretório + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Hoje + + + + Yesterday + Ontem + + + + This week + Esta semana + + + + Last week + Semana passada + + + + This month + Este mês + + + + Last month + Mês passado + + + + This year + Este Ano + + + + Last year + Ano passado + + + + DFMOpticalMediaWidget + + + + No files to burn + Nenhum arquivo para gravar + + + + Unable to burn. Not enough free space on the target disk. + Impossível gravar. Não há espaço disponível no disco de destino. + + + + %1 burning is not supported + A gravação de %1 não é permitida + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. Não é um disco %1; +2. A versão deste sistema de arquivos ainda não permite a adição de arquivos. + + + + DFMTagCrumbController + + + Tag information + Informação da etiqueta + + + + DFMTagWidget + + + Tag + Etiqueta + + + + DFMTaskWidget + + + Do not ask again + Não perguntar novamente + + + + Syncing data + Sincronizando os dados + + + + Please wait + Aguarde + + + + + Time modified: %1 + Última modificação: %1 + + + + + Contains: %1 + Contém: %1 + + + + + Size: %1 + Tamanho: %1 + + + + Original folder + Pasta de origem + + + + Keep both + button + Manter Ambos + + + + Skip + button + Ignorar + + + + Replace + button + Substituir + + + + Retry + button + Tentar novamente + + + + Original file + Arquivo original + + + + Target folder + Pasta de destino + + + + Target file + Arquivo de destino + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Criptografar o Cofre de Arquivo + + + + Click 'Encrypt' and input the user password. + Clique em 'Criptografar' e insira a senha do usuário. + + + + Encrypting... + Criptografando... + + + + + + + Encrypt + Criptografar + + + + Failed to create file vault: %1 + Falha ao criar o cofre de arquivos: %1 + + + + OK + Ok + + + + The setup is complete + A configuração está completa + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Salvar a Chave de Recuperação + + + + Keep the key safe to retrieve the vault password later + Mantenha a chave segura para recuperar a senha do cofre mais tarde + + + + Save to default path + Salvar no local padrão + + + + Save to other locations + Salvar em outros locais + + + + No permission, please reselect + Sem permissões, por favor selecione novamente + + + + Select a path + Selecione um local + + + + Next + Próximo + + + + The default path is invisible to other users, and the path information will not be shown. + O local padrão é invisível para outros usuários e a informação do local não será exibida + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Chave de Recuperação + + + + Generate a recovery key in case that you forgot the password + Gerar uma chave de recuperação caso a senha seja esquecida + + + + Key + Chave + + + + QR code + QR Code + + + + Scan QR code and save the key to another device + Leia o código QR e salve a chave em outro dispositivo + + + + Next + Próximo + + + + Recovery Key: + Chave de Recuperação: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Definir a Senha do Cofre + + + + Method + Método + + + + Manual + Manual + + + + Password + Senha + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 caracteres; contém A-Z, a-z, 0-9 e símbolos + + + + Repeat password + Repetir senha + + + + Input the password again + Insira a senha novamente + + + + Password hint + Dica de senha + + + + Optional + Opcional + + + + Next + Próximo + + + + + Passwords do not match + As senhas não coincidem + + + + DFMVaultActiveStartView + + + File Vault + Cofre de Arquivo + + + + Create your secure private space + Criar um espaço privado e seguro + + + + Advanced encryption technology + Tecnologia avançada de criptografia + + + + Convenient and easy to use + Conveniente e fácil de usar + + + + Create + Criar + + + + DFMVaultFileView + + + Cannot open this path + Impossível abrir este local + + + + Hint + Dica + + + + OK + Ok + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Desbloquear por Chave + + + + Failed to unlock file vault + Falha ao desbloquear o cofre de arquivo + + + + OK + Ok + + + + Input the 32-digit recovery key + Insira a chave de recuperação de 32 dígitos + + + + Cancel + button + Cancelar + + + + Unlock + button + Desbloquear + + + + Wrong recovery key + Chave de recuperação incorreta + + + + DFMVaultRemoveByPasswordView + + + Password + Senha + + + + Password hint: %1 + Dica de senha: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Insira a chave de recuperação de 32 dígitos + + + + DFMVaultRemovePages + + + Delete File Vault + Excluir o Cofre de Arquivos + + + + Once deleted, the files in it will be permanently deleted + Uma vez excluídos, os arquivos serão excluídos permanentemente + + + + Use Key + Usar Chave + + + + Cancel + button + Cancelar + + + + Use Key + button + Usar Chave + + + + Delete + button + Excluir + + + + + OK + button + Ok + + + + Use Password + Usar Senha + + + + Wrong password + Senha incorreta + + + + Wrong recovery key + Chave de recuperação incorreta + + + + Failed to delete file vault + Falha ao excluir o cofre de arquivos + + + + Deleted successfully + Excluído + + + + Failed to delete + Falha ao excluir + + + + Removing... + Removendo... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + Não foi possível obter o arquivo de chave + + + + Verification failed + Falha na verificação + + + + + Select a path + Selecione um local + + + + + Retrieve Password + Recuperar Senha + + + + By key in the default path + Pela chave no local padrão + + + + By key in the specified path + Pela chave no local especificado + + + + Verification Successful + Verificado com sucesso + + + + Keep it safe + Mantenha seguro + + + + Back + button + Voltar + + + + Verify Key + button + Verificar chave + + + + Go to Unlock + button + Ir para Desbloquear + + + + Close + button + Fechar + + + + Vault password: %1 + Senha do Cofre: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Desbloquear o Cofre de Arquivo + + + + Forgot password? + Esqueceu a senha? + + + + Password hint: %1 + Dica de senha: %1 + + + + Failed to unlock file vault + Falha ao desbloquear o cofre de arquivo + + + + Cancel + button + Cancelar + + + + Password + Senha + + + + Unlock + button + Desbloquear + + + + Please try again %1 minutes later + Por favor, tente novamente em %1 minutos + + + + Wrong password, please try again %1 minutes later + Senha incorreta, por favor, tente novamente em %1 minutos + + + + Wrong password, one chance left + Senha incorreta, uma tentativa restante + + + + Wrong password, %1 chances left + Senha incorreta, %1 tentativas restantes + + + + Wrong password + Senha incorreta + + + + OK + button + Ok + + + + DFileCopyMoveJob + + + Permission error + Erro de permissão + + + + The action is denied + Esta ação não é permitida + + + + Failed to open the file + Falha ao abrir o arquivo + + + + Failed to read the file + Falha ao ler o arquivo + + + + Failed to write the file + Falha ao escrever o arquivo + + + + Failed to create the directory + Falha ao criar o diretório + + + + Failed to delete the file + Falha ao excluir o arquivo + + + + Failed to move the file + Falha ao mover o arquivo + + + + Original file does not exist + O arquivo original não existe + + + + Failed, file size must be less than 4GB + Falha! O tamanho do arquivo deve ser inferior a 4GB + + + + Not enough free space on the target disk + Não há espaço disponível no disco de destino + + + + File integrity was damaged + A integridade do arquivo foi comprometida + + + + The target device is read only + O dispositivo de destino é somente leitura + + + + Target folder is inside the source folder + A pasta de destino está dentro da pasta de origem + + + + The action is not supported + A ação não é suportada + + + + You do not have permission to traverse files in it + Você não tem permissão para mover os arquivos + + + + Failed to position the file pointer! + Falha em posicionar o ponteiro do arquivo! + + + + copy + Extra name added to new file name when used for file name. + copiar + + + + Failed to open the directory, cause: file name too long + Falha ao abrir o diretório; motivo: o nome do arquivo é muito longo + + + + + Failed to open the file, cause: file name too long + Falha ao abrir o arquivo; motivo: o nome do arquivo é muito longo + + + + + Failed to write the file, cause: + Falha ao gravar o arquivo; motivo: + + + + Failed to position the file pointer, cause: %1 + Falha em posicionar o ponteiro do arquivo, motivo: %1 + + + + Syncing data + Sincronizando os dados + + + + Please wait + Aguarde + + + + Failed to create the directory, cause: %1 + Falha ao criar o diretório; motivo: %1 + + + + + + + + Failed to open the file, cause: %1 + Falha ao abrir o arquivo; motivo: %1 + + + + + + + Failed to open the file, cause: Permission denied + Falha ao abrir o arquivo; motivo: permissão negada + + + + + Failed to read the file, cause: %1 + Falha ao ler o arquivo; motivo: %1 + + + + + + + Failed to write the file, cause: %1 + Falha ao gravar o arquivo; motivo: %1 + + + + + File integrity was damaged, cause: %1 + A integridade do arquivo foi comprometida; motivo: %1 + + + + Failed to open the file, cause: + Falha ao abrir o arquivo; motivo: + + + + Failed to read the file, cause: + Falha ao ler o arquivo; motivo: + + + + Failed to delete the file, cause: %1 + Falha ao excluir o arquivo; motivo: %1 + + + + Fail to create symlink, cause: %1 + Falha ao criar o link simbólico; motivo: %1 + + + + DFileDialog + + + + Save + button + Salvar + + + + + Cancel + button + Cancelar + + + + Confirm + button + Confirmar + + + + %1 already exists, do you want to replace it? + %1 já existe, substituí-lo? + + + + Replace + button + Substituir + + + + Open + button + Abrir + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Este arquivo será ocultado se o nome do arquivo iniciar com um ponto (.). Ocultá-lo? + + + + DFileManagerWindow + + + Trash + Lixeira + + + + Empty + Esvaziar + + + + DFileSystemModel + + + + Name + Nome + + + + + + Time modified + Última modificação + + + + Size + Tamanho + + + + Type + Tipo + + + + Time created + Data da criação + + + + + Last access + Último acesso + + + + + + + Path + Caminho + + + + DFileView + + + Disc mount error + Erro de montagem do disco + + + + The disc is in use, please end the running process and remount the disc. + O disco está em uso; encerre o processo em execução e monte novamente o disco. + + + + Mounting failed + A montagem falhou + + + + (Reverse) + (Reverso) + + + + DFileViewHelper + + + Add tag "%1" + Adicionar Etiqueta "%1" + + + + DStatusBar + + + %1 item + %1 item + + + + %1 items + %1 itens + + + + %1 item selected + %1 item selecionado + + + + %1 items selected + %1 itens selecionados + + + + %1 folder selected (contains %2) + %1 pasta selecionada (contém %2) + + + + %1 folders selected (contains %2) + %1 pastas selecionadas (contém %2) + + + + %1 file selected (%2) + %1 arquivo selecionado (%2) + + + + %1 files selected (%2) + %1 arquivos selecionados (%2) + + + + %1 folder selected + %1 pasta selecionada + + + + Filter + Filtro + + + + Save as: + Salvar como: + + + + Loading... + Carregando... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Apagando disco %1, aguarde... + + + + Burning disc %1, please wait... + Gravando disco %1, aguarde... + + + + Writing data... + Gravando dados... + + + + Verifying data... + Verificando dados... + + + + Copying %1 + Copiando %1 + + + + + + to %2 + para %2 + + + + %1 already exists in target folder + %1 já existe na pasta de destino + + + + Original path %1 Target path %2 + Caminho original %1 Caminho de destino %2 + + + + Merge + button + Mesclar + + + + Replace + button + Substituir + + + + Moving %1 + Movendo %1 + + + + Removing file vault, please try later + Removendo o cofre de arquivos; tente novamente mais tarde + + + + Restoring %1 + Restaurando %1 + + + + Deleting %1 + Excluindo %1 + + + + Trashing %1 + Destruindo %1 + + + + Calculating space, please wait + Calculando espaço, aguarde... + + + + DUMountManager + + + + Authentication timed out + A autenticação expirou + + + + + + Disk is busy, cannot unmount now + O disco está ocupado; impossível desmontá-lo + + + + Disk is busy, cannot eject now + O disco está ocupado; impossível ejetá-lo + + + + The device is busy, cannot eject now + O dispositivo está ocupado; impossível ejetá-lo + + + + + + The device is busy, cannot remove now + O dispositivo está ocupado; impossível removê-lo + + + + DeepinStorage + + + + + %1 Volume + Volume de %1 + + + + Data Disk + Data Partition + Disco de Dados + + + + %1 Drive + %1 Disco + + + + Blank %1 Disc + %1 Disco Vazio + + + + %1 Encrypted + %1 Criptografado + + + + DialogManager + + + + + + Operation failed! + Operação falhou! + + + + Target folder is inside the source folder! + A pasta de destino está dentro da pasta de origem! + + + + Do you want to run %1 or display its content? + Executar %1 ou exibir o conteúdo? + + + + It is an executable text file. + O arquivo de texto é executável. + + + + It is an executable file. + O arquivo é executável. + + + + This file is not executable, do you want to add the execute permission and run? + Este arquivo não é executável. Adicionar a permissão de execução e executá-lo? + + + + "%1" already exists, please use another name. + "%1" já existe; use outro nome. + + + + The file name must not contain two dots (..) + O nome do arquivo não deve conter dois pontos (..) + + + + Device or resource busy + + + + + Are you sure you want to erase all data on the disc? + Apagar todos os dados no disco? + + + + How do you want to use this disc? + Como usar este disco? + + + + Disc erase failed + Falha ao apagar o disco + + + + Burn process failed + Falha no processo de gravação + + + + %1: %2 + %1: %2 + + + + Show details + Exibir Detalhes + + + + Hide details + Ocultar detalhes + + + + Error + Erro + + + + Permanently delete %1? + Excluir permanentemente %1? + + + + Permanently delete %1 items? + Excluir permanentemente %1 itens? + + + + Empty + Esvaziar + + + + Do you want to delete %1? + Excluir %1? + + + + Do you want to delete the selected %1 items? + Excluir os %1 itens selecionados? + + + + Sorry, unable to locate your bookmark directory, remove it? + Impossível localizar o diretório dos favoritos. Removê-lo? + + + + Name: + Nome: + + + + %1 that this shortcut refers to has been changed or moved + %1 a que este atalho se refere foi alterado ou movido + + + + Do you want to delete this shortcut? + Excluir este atalho? + + + + Failed, file size must be less than 4GB. + Falha! O tamanho do arquivo deve ser inferior a 4GB. + + + + Fail to create symlink, cause: + Falha ao criar o link simbólico; motivo: + + + + The selected files contain system file/directory, and it cannot be deleted + Os arquivos selecionados contém um arquivo/diretório do sistema, e não podem ser excluídos + + + + Unable to find the original file + Impossível encontrar o arquivo original + + + + + You do not have permission to operate file/folder! + O usuário não tem permissão para operar o/a arquivo/pasta! + + + + Failed to restore %1 file, the source file does not exist + Falha ao restaurar %1 arquivo; o arquivo de origem não existe + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + O usuário não tem permissão para operar os seguintes arquivo(s)/pasta(s) %1! + + + + Unable to access %1 + Impossível acessar %1 + + + + + Sending files now, please try later + Enviando agora os arquivos; tente novamente mais tarde + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Para acessar o dispositivo, é necessário formatar o disco. Formatá-lo agora? + + + + Scanning the device, stop it? + Verificando o dispositivo, parar? + + + + Share folder can't be named after the current username + A pasta compartilhada não pode ser nomeada após o nome de usuário atual + + + + Do you want to run %1? + Executar %1? + + + + Burn image + button + Gravar imagem + + + + Burn files + button + Gravar arquivos + + + + Are you sure you want to empty %1 item? + Excluir permanentemente %1 item? + + + + Are you sure you want to empty %1 items? + Excluir permanentemente %1 itens? + + + + + This action cannot be undone + Está ação não poderá ser revertida + + + + + + + + + + + + + + OK + button + Ok + + + + + + + + + + + + + + + Cancel + button + Cancelar + + + + + + Run + button + Executar + + + + + Run in terminal + button + Executar no Terminal + + + + Display + button + Exibir + + + + + + + + + + + Confirm + button + Confirmar + + + + Erase + button + Apagar + + + + Data verification failed + A verificação de dados falhou + + + + Show details + button + Exibir Detalhes + + + + + Delete + button + Excluir + + + + Remove + button + Remover + + + + Disk is busy, cannot unmount now + O disco está ocupado; é impossível desmontá-lo agora + + + + Force unmount + button + Forçar desmontagem + + + + Unable to copy. Not enough free space on the target disk. + Impossível copiar. Não há espaço disponível no disco de destino. + + + + Failed to restore %1 file, the target folder is read-only + Falha ao restaurar %1 arquivo, a pasta de destino é somente leitura + + + + Failed to restore %1 files, the target folder is read-only + Falha ao restaurar %1 arquivos, a pasta de destino é somente leitura + + + + Failed to restore %1 files, the source files do not exist + Falha ao restaurar %1 arquivos; o arquivos de origem não existem + + + + Format + button + Formato + + + + Stop + button + Parar + + + + FileController + + + + + + Unable to find the original file + Impossível encontrar o arquivo original + + + + + + Kindly Reminder + Lembrete Gentil + + + + + + Please install File Roller first and then continue + Instale o File Roller para continuar + + + + + Unable to create files here: %1 + Impossível criar os arquivos aqui: %1 + + + + Confirm + button + Confirmar + + + + FileDialogStatusBar + + + File Name + Nome do Arquivo + + + + Format + Formato + + + + Save + button + Salvar + + + + Open + button + Abrir + + + + Save File + button + Salvar Arquivo + + + + Open File + button + Abrir Arquivo + + + + + + Cancel + button + Cancelar + + + + FileJob + + + copy + copiar + + + + + + + Data verification successful. + Verificação de Dados Bem-sucedida. + + + + + + Burn process completed + Gravação completa + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 é um arquivo duplicado. + + + + Insufficient disc space. + Espaço insuficiente em disco. + + + + Lost connection to drive. + Conexão perdida com o dispositivo. + + + + The CD/DVD drive is not ready. Try another disc. + O dispositivo de CD/DVD não está pronto. Tente outro disco. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + O dispositivo de CD/DVD está ocupado. Feche o programa que o está utilizando e insira o disco novamente. + + + + Unknown error + Erro desconhecido + + + + Device disconnected + Dispositivo desconectado + + + + GenerateSettingTranslate + + + + + Basic + Básico + + + + + + Open behavior + Comportamento ao abrir + + + + + + Always open folder in new window + Sempre abrir a pasta em nova janela + + + + + + Open file: + Arquivo: + + + + + + Click + Clique Único + + + + + + Double click + Clique Duplo + + + + + + New window and tab + Nova janela e aba + + + + + + Open from default window: + Janela padrão: + + + + + + + + + Computer + Computador + + + + + + + + + Home + Pasta Pessoal + + + + + + + + + Desktop + Área de Trabalho + + + + + + + + + Videos + Vídeos + + + + + + + + + Music + Músicas + + + + + + + + + Pictures + Imagens + + + + + + + + + Documents + Documentos + + + + + + + + + Downloads + Downloads + + + + + + Open in new tab: + Aba padrão: + + + + + + Current Directory + Diretório + + + + + + View + Visualização + + + + + + Default size: + Tamanho padrão: + + + + + + Extra small + Muito pequeno + + + + + + Small + Pequeno + + + + + + Medium + Médio + + + + + + Large + Grande + + + + + + Extra large + Muito grande + + + + + + Default view: + Visualização padrão: + + + + + + Icon + Ícone + + + + + + List + Lista + + + + + + Hidden files + Exibição + + + + + + Show hidden files + Exibir os arquivos ocultos + + + + + + Hide file extension when rename + Ocultar a extensão do arquivo ao renomear + + + + + + Advanced + Avançado + + + + + + Index + Índice + + + + + + Auto index internal disk + Indexar automaticamente o disco interno + + + + + + Index external storage device after connected to computer + Indexar os dispositivos de armazenamento externo após conectarem-se ao computador + + + + + + Full-Text search + Pesquisar no conteúdo dos arquivos + + + + + + Show item counts and sizes in the path of mounted MTP devices + Mostrar a quantidade e tamanho de itens no endereço de dispositivos MTP montados + + + + + + Keep showing the mounted Samba shares + Continuar exibindo os compartilhamentos Samba montados + + + + + + Use the file chooser dialog of File Manager + Usar a caixa de diálogo do Gerenciador de Arquivos + + + + + + Ask for my confirmation when deleting files + Pedir confirmação antes de excluir os arquivos + + + + + + Other + Outros + + + + + + Hide system disk + Ocultar o disco do sistema + + + + + + Show file system on disk icon + Exibir o sistema de arquivos no ícone do disco + + + + + + Show hidden files in search results + Exibir os arquivos ocultos nos resultados de pesquisa + + + + + + Display recent file entry in left panel + Exibir a opção Recentes no painel de navegação à esquerda + + + + + + Preview + Pré-visualização + + + + + Compress file preview + Pré-visualizar arquivo comprimido + + + + + + Text preview + Pré-visualizar texto + + + + + + Document preview + Pré-visualizar documento + + + + + + Image preview + Pré-visualizar imagem + + + + + + Video preview + Pré-visualizar vídeo + + + + + + Mount + Montagem + + + + + + Auto mount + Montar automaticamente + + + + + + Open after auto mount + Abrir após montar automáticamente + + + + + + Dialog + Integração ao sistema + + + + Compressed file preview + Pré-visualizar arquivo comprimido + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Impossível verificar a identidade de %1. + + + + This happens when you log in to a computer the first time. + Isto ocorre quando o login é feito pela primeira vez em um computador + + + + The identity sent by the remote computer is + A identidade enviada pelo computador remoto é + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Para continuar com segurança, contate o administrador do sistema. + + + + + + + + Mounting device error + Erro ao montar o dispositivo + + + + + Wrong username or password + O nome de usuário ou a senha estão incorretos + + + + + + + + Confirm + button + Confirmar + + + + + Cannot find the mounted device + Impossível encontrar o dispositivo montado + + + + No key available to unlock device + Nenhuma chave disponível para desbloquear o dispositivo + + + + The disk is mounted by user "%1", you cannot unmount it. + O disco foi montado pelo usuário "%1", você não pode desmontá-lo. + + + + Cannot unmount the device + Impossível desmontar o dispositivo + + + + Cannot eject the device "%1" + Não foi possível ejetar o dispositivo "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Impossível gravar. Não há espaço disponível no disco de destino. + + + + MergedDesktopController + + + + Pictures + Imagens + + + + + Music + Músicas + + + + + Applications + Aplicativos + + + + + Videos + Vídeos + + + + + Documents + Documentos + + + + + Others + Outros + + + + MimeTypeDisplayManager + + + + Directory + Diretório + + + + + + Application + Aplicativo + + + + + + Video + Vídeo + + + + + + Audio + Áudio + + + + + + Image + Imagem + + + + + Archive + Arquivo + + + + + + Text + Texto + + + + + Executable + Executável + + + + + Backup file + Arquivo de backup + + + + + Unknown + Desconhecido + + + + MountAskPasswordDialog + + + Cancel + button + Cancelar + + + + Connect + button + Conectar + + + + Log in as + Entrar como + + + + Anonymous + Anônimo + + + + Registered user + Usuário Registrado + + + + Username + Nome de Usuário + + + + Domain + Domínio + + + + Password + Senha + + + + Remember password + Lembrar senha + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Cancelar + + + + Unlock + button + Desbloquear + + + + Input password to decrypt the disk + Insira a senha para descriptografar o disco + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Excluir permanentemente %1? + + + + This file is too big for the trash + Este arquivo é muito grande para a lixeira + + + + The files are too big for the trash + Estes arquivos são muito grandes para a lixeira + + + + Are you sure you want to permanently delete %1 files? + Excluir permanentemente %1 arquivos? + + + + Cancel + button + Cancelar + + + + Delete + button + Excluir + + + + OpenWithDialog + + + Open with + Abrir com + + + + Add other programs + Adicionar mais aplicativos + + + + Set as default + Definir como padrão + + + + Cancel + button + Cancelar + + + + Confirm + button + Confirmar + + + + Recommended Applications + Aplicativos Recomendados + + + + Other Applications + Outras Aplicativos + + + + PathManager + + + Home + Pasta Pessoal + + + + Desktop + Área de Trabalho + + + + Videos + Vídeos + + + + Music + Músicas + + + + Pictures + Imagens + + + + Documents + Documentos + + + + Downloads + Downloads + + + + + Trash + Lixeira + + + + + + System Disk + Disco do Sistema + + + + Computers in LAN + Rede + + + + My Shares + Compartilhamentos + + + + Computer + Computador + + + + Recent + Recentes + + + + File Vault + Cofre de Arquivo + + + + PropertyDialog + + + Basic info + Informação básica + + + + Open with + Abrir com + + + + Sharing + Compartilhar + + + + Permissions + Permissões + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Ocultar esta pasta + + + + Hide this file + Ocultar este arquivo + + + + Allow to execute as program + Executar como programa + + + + QObject + + + + + + Size + Tamanho + + + + + + Contains + Contém + + + + + + Type + Tipo + + + + + + + + Time modified + Última modificação + + + + Free space + Espaço livre + + + + Total space + Espaço total + + + + + Time locked + Tempo bloqueado + + + + Access denied + Acesso negado + + + + + Executable + Executável + + + + + Write only + Somente escrita + + + + + Read only + Somente Leitura + + + + + Read-write + Leitura e Escrita + + + + Others + Outros + + + + Owner + Proprietário + + + + Unconnected network shared directory + Diretório compartilhado em rede desconectado + + + + Device type + Tipo de dispositivo + + + + File system + Sistema de arquivos + + + + Group + Grupo + + + + + Open + Abrir + + + + Lock + Bloquear + + + + Auto lock + Bloquear automaticamente + + + + Never + Nunca + + + + 5 minutes + 5 minutos + + + + 10 minutes + 10 minutos + + + + 20 minutes + 20 minutos + + + + Delete File Vault + Excluir o Cofre de Arquivos + + + + Unlock + Desbloquear + + + + Unlock by key + Desbloquear por chave + + + + Open + button + Abrir + + + + + Size: %1 + Tamanho: %1 + + + + Type: %1 + Tipo: %1 + + + + Size: 0 + Tamanho: 0 + + + + Items: %1 + Itens: %1 + + + + + + + + + + Open in new window + Abrir em nova janela + + + + + + + + + + Open in new tab + Abrir em nova aba + + + + Open with + Abrir com + + + + + Compress + Comprimir + + + + Extract + Extrair + + + + Extract here + Extrair aqui + + + + Cut + Recortar + + + + Copy + Copiar + + + + Paste + Colar + + + + + + + + Rename + Renomear + + + + + + + Remove + Remover + + + + Create link + Criar atalho + + + + Send to desktop + Enviar para a área de trabalho + + + + Send to + Enviar para + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Adicionar aos Favoritos + + + + + + + Properties + Propriedades + + + + New folder + Nova pasta + + + + New window + Nova janela + + + + Select all + Selecionar tudo + + + + + Clear recent history + Limpar o histórico recente + + + + + + Empty Trash + Esvaziar Lixeira + + + + Display as + Exibir como + + + + Sort by + Ordenar por + + + + New document + Novo documento + + + + + Time created + Data da criação + + + + + + Source path + Caminho de origem + + + + Share folder + Compartilhar pasta + + + + Cancel sharing + Cancelar compartilhamento + + + + Connect to Server + Conectar ao servidor + + + + Set share password + Definir a senha de compartilhamento + + + + Format + Formatar + + + + Tag information + Informação da etiqueta + + + + Open as administrator + Abrir como administrador + + + + Select default program + Selecionar o aplicativo padrão + + + + Open file location + Abrir local do arquivo + + + + Remove bookmark + Remover favorito + + + + + + Delete + Excluir + + + + Office Text + Texto + + + + Spreadsheets + Planilha + + + + Plain Text + Texto Simples + + + + Open in terminal + Abrir no terminal + + + + Restore + Restaurar + + + + Restore all + Restaurar tudo + + + + Clear saved password and unmount + Apagar senhas salvas e desmontar + + + + File Vault + Cofre de Arquivo + + + + Add to disc + Adicionar ao disco + + + + Refresh + + + + + Auto mount + Montar automaticamente + + + + Open after auto mount + Abrir após montar automaticamente + + + + + Mount + Montar + + + + + Unmount + Desmontar + + + + It does not support burning %1 discs + Não permite a gravação de %1 discos + + + + Burn + Gravar + + + + Disc name: + Nome do disco: + + + + + Maximum + Máximo + + + + Allow files to be added later + Permitir que arquivos sejam adicionados mais tarde + + + + Verify data + Verificar dados + + + + Write speed: + Velocidade de gravação: + + + + + + + Cancel + button + Cancelar + + + + Burn + button + Gravar + + + + + Eject + Ejetar + + + + Safely Remove + Remover com Segurança + + + + + Name + Nome + + + + Settings + Configurações + + + + Exit + Sair + + + + Icon + Ícone + + + + List + Lista + + + + Extend + Estender + + + + Set as wallpaper + Definir como papel de parede + + + + + + + Local disk + Disco local + + + + + Removable disk + Disco removível + + + + + + Network shared directory + Diretório de rede compartilhado + + + + + Android mobile device + Dispositivo Móvel Android + + + + + Apple mobile device + Dispositivo Móvel Apple + + + + + Camera + Câmera + + + + + DVD + DVD + + + + + Unknown device + Dispositivo desconhecido + + + + + + %1 item + %1 item + + + + + + %1 items + %1 itens + + + + Shortcut + Atalho + + + + Create symlink + Criação de atalho + + + + Path + Caminho + + + + + + Time deleted + Excluido + + + + Loading... + Carregando... + + + + File has been moved or deleted + O arquivo foi movido ou excluído + + + + You do not have permission to traverse files in it + Você não tem permissão para mover os arquivos + + + + + + You do not have permission to access this folder + O usuário não tem permissão para acessar esta pasta + + + + + + + + Folder is empty + A pasta está vazia + + + + Searching... + Pesquisando... + + + + No results + Nenhum resultado + + + + Source Path + TrashFileInfo + Caminho de origem + + + + Document + Documentos + + + + Spreadsheet + Planilha + + + + + Presentation + Apresentação + + + + Text + Texto + + + + 1 task in progress + 1 tarefa em andamento + + + + %1 tasks in progress + %1 tarefas em andamento + + + + Mode: + Modo: + + + + + Replace Text + Substituir texto + + + + + Add Text + Adicionar Texto + + + + + Custom Text + Personalizar texto + + + + Find: + Encontrar: + + + + Replace: + Substituir: + + + + + Optional + Opcional + + + + Add: + Adicionar: + + + + Location: + Local: + + + + File name: + Nome do arquivo: + + + + Start at: + Prefixo: + + + + + Rename + button + Renomear + + + + + + + + + + + Required + Requeridos + + + + + Before file name + Antes do nome do arquivo + + + + + After file name + Após o nome do arquivo + + + + Find + Encontrar + + + + Replace + Substituir + + + + Add + Adicionar + + + + Start at + Iniciar em + + + + + + Location + Local + + + + File name + Nome do arquivo + + + + Dimension + Dimensão + + + + Duration + Duração + + + + Tips: Sort by selected file order + Dicas: Classificar por ordem de arquivo selecionado + + + + Rename %1 Files + Renomear %1 arquivos + + + + Multiple Files + Arquivos múltiplos + + + + Basic info + Informação básica + + + + Total size + Tamanho total + + + + Number of files + Número de arquivos + + + + %1 file(s), %2 folder(s) + %1 arquivo(s), %2 pasta(s) + + + + + + Time accessed + Último acesso + + + + Orange + Laranja + + + + Red + Vermelha + + + + Purple + Roxa + + + + Navy-blue + Azul marinho + + + + Azure + Azul + + + + Green + Verde + + + + Yellow + Amarela + + + + Gray + Cinza + + + + Input tag info, such as work, family. A comma is used between two tags. + Insira as informações de etiqueta; como trabalho, família e etc.. Uma vírgula é usada entre duas etiquetas. + + + + Bookmarks + Favoritos + + + + Erase + Apagar + + + + Copy path + Copiar caminho + + + + Edit address + Editar endereço + + + + Free Space %1 + Espaço livre %1 + + + + Files are being processed + Arquivos estão sendo processados + + + + + Unknown + Desconhecido + + + + My Vault + Meu Cofre + + + + + Failed to create file info + Falhou ao criar as informações do arquivo + + + + Failed to create file handler + Falha ao criar um manipulador de arquivo + + + + Failed to open the file, cause: %1 + Falha ao abrir o arquivo; motivo: %1 + + + + Original file does not exist + O arquivo original não existe + + + + Do you want to delete %1? + Excluir %1? + + + + Confirm + button + Confirmar + + + + + + + + %1 are not allowed + %1 não são permitidos + + + + + Failed to start Samba services + Falha ao iniciar os serviços Samba + + + + RecentController + + + Cancel + button + Cancelar + + + + Remove + button + Remover + + + + Do you want to remove this item? + Deseja remover este item? + + + + Do yout want to remove %1 items? + Deseja remover %1 itens? + + + + It does not delete the original files + Isto não apaga os arquivos originais + + + + ShareInfoFrame + + + Share this folder + Compartilhar esta pasta + + + + Share name: + Nome do compartilhamento: + + + + Permission: + Permissão: + + + + Read and write + Leitura e Escrita + + + + Read only + Somente Leitura + + + + Anonymous: + Anônimo: + + + + Not allow + Não permitido + + + + Allow + Permitir + + + + The share name must not be two dots (..) or one dot (.) + O nome do compartilhamento não deve ser dois pontos (..) ou um ponto (.) + + + + The share name is used by another user. + O nome do compartilhamento é utilizado por outro usuário. + + + + OK + button + Ok + + + + Cancel + button + Cancelar + + + + Replace + button + Substituir + + + + The share name already exists. Do you want to replace the shared folder? + O nome do compartilhamento já existe. Substituir a pasta compartilhada? + + + + Shortcut + + + Item + Item + + + + Select to the first item + Selecionar o primeiro item + + + + Shift + Home + Shift + Home + + + + Select to the last item + Selecionar até o último item + + + + Shift + End + Shift + End + + + + Select leftwards + Selecionar para a esquerda + + + + Shift + Left + Shift + Left + + + + Select rightwards + Selecionar para a direita + + + + Shift + Right + Shift + Right + + + + Select to upper row + Selecionar para a linha superior + + + + Shift + Up + Shift + Up + + + + Select to lower row + Selecionar para a linha inferior + + + + Shift + Down + Shift + Down + + + + Open + Abrir + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + Para o diretório superior + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Excluir permanentemente + + + + Shift + Delete + Shift + Delete + + + + Delete file + Excluir arquivo + + + + Delete + Excluir + + + + Select all + Selecionar tudo + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Copiar + + + + Cut + Recortar + + + + Paste + Colar + + + + Rename + Renomear + + + + F2 + F2 + + + + New/Search + Nova Pesquisa + + + + New window + Nova janela + + + + New folder + Nova pasta + + + + + Search + Pesquisar + + + + New tab + Nova aba + + + + View + Visualizar + + + + Item information + Informação do item + + + + Help + Ajuda + + + + F1 + F1 + + + + Keyboard shortcuts + Atalhos de teclado + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Mudar a exibição de status + + + + Hide item + Ocultar item + + + + Input in address bar + Insira na barra de endereços + + + + Switch to icon view + Alternar para visualização em ícone + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Alternar para visualização em lista + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Outros + + + + Close + Fechar + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Fechar aba atual + + + + Back + Voltar + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Alterar para a próxima aba + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Alternar para a aba anterior + + + + Next file + Próximo arquivo + + + + Tab + Tab + + + + Previous file + Arquivo anterior + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Alternar a aba pelo número especificado entre 1 e 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Avançar + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Impossível abrir os itens da lixeira; restaure-os + + + + TrashPropertyDialog + + + Trash + Lixeira + + + + item + Item + + + + items + Itens + + + + Contains %1 %2 + Contém %1 %2 + + + + UDiskListener + + + Failed to rename the label + Falha ao renomear o rótulo + + + + UnmountWorker + + + + + The device was not safely unmounted + O dispositivo não foi desmontado com segurança + + + + The device was not safely removed + O dispositivo não foi removido com segurança + + + + UserShareManager + + + Kindly Reminder + Lembrete gentil + + + + Please firstly install samba to continue + Instale o samba para continuar + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + O nome do compartilhamento não pode conter %<>*?|/\+=;:," e não pode iniciar com %1 + + + + To protect the files, you cannot share this folder. + O compartilhamento desta pasta não é permitido, visando proteger os arquivos. + + + + Sharing failed + O compartilhamento falhou + + + + The computer name is too long + O nome do computador é muito longo + + + + You do not have permission to operate file/folder! + O usuário não tem permissão para operar o/a arquivo/pasta! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Insira uma senha para proteger as pastas compartilhadas + + + + Cancel + button + Cancelar + + + + Confirm + button + Confirmar + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ro.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ro.ts new file mode 100644 index 0000000..5aa72c7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ro.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + Dosar Nou + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + Eroare montare: format imagine nesuportat + + + + Disk is busy, cannot unmount now + Disc ocupat, nu se poate demonta acum + + + + + Disk is busy, cannot eject now + Disc ocupat, nu se poate elimina acum + + + Mount Error + Eroare Montare + + + Unsupported image format + Format imagine nesuportat + + + + CloseAllDialogIndicator + + + Close all + Închide tot + + + + Total size: %1, %2 files + Dimensiunea totală:% 1,% 2 fișiere + + + + ComputerModel + + + My Directories + Directoare mele + + + + + + Disks + Discuri + + + + ComputerPropertyDialog + + + Computer + Computer + + + + Basic Info + Informaţii de bază + + + + Computer Name + Nume Computer + + + + Version + Versiune + + + + Type + Tip + + + + Processor + Procesor + + + + Memory + Memorie + + + + Disk + Disc + + + + Bit + Bit + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + Căutați sau introduceți adresa + + + + DFMAdvanceSearchBar + + + Search: + Căutați: + + + + File Type: + Tip Fişier: + + + + File Size: + Dimensiune Fişier: + + + + Time Modified: + Timp modificare: + + + + Reset + Resetează + + + + All subdirectories + Toate subdirectoarele + + + + Current directory + Director curent + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Azi + + + + Yesterday + Ieri + + + + This week + Săptămâna aceasta + + + + Last week + Săptămâna trecută + + + + This month + Luna aceasta + + + + Last month + Luna trecută + + + + This year + Acest an + + + + Last year + Anul trecut + + + + DFMTagCrumbController + + + Tag information + Informaţii etichetă + + + + DFMTagWidget + + + Tag + Etichetă + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + Introduceţi parolă seif + + + + Retrieve password + Recuperează parolă + + + + DFileCopyMoveJob + + + Permission error + Eroare permisiuni + + + + The action is denied + Acțiunea este interzisă + + + + Failed to open the file + + + + + Failed to read the file + + + + + Failed to write the file + + + + + Failed to create the directory + + + + + Failed to delete the file + + + + + Failed to move the file + + + + + Original file does not exist + + + + + Failed, file size must be less than 4GB + + + + + Not enough free space on the target disk + + + + + File integrity was damaged + + + + + The target device is read only + + + + + Target folder is inside the source folder + + + + + copy + Extra name added to new file name when used for file name. + + + + + Failed to create the directory, cause: %1 + + + + + + Failed to open the file, cause: %1 + + + + + Failed to read the file, cause: %1 + + + + + Failed to write the file, cause: %1 + + + + + File integrity was damaged, cause: %1 + + + + + Failed to delete the file, cause: %1 + + + + + Fail to create symlink, cause: %1 + + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + + + + + Cancel + + + + + Replace + + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + + + + + + + Time modified + + + + + Size + + + + + Type + + + + + Time created + + + + + + Last access + + + + + Path + + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + + + + + DFileViewHelper + + + Add tag "%1" + + + + + DStatusBar + + + %1 item + + + + + %1 items + + + + + %1 item selected + + + + + %1 items selected + + + + + %1 folder selected (contains %2) + + + + + %1 folders selected (contains %2) + + + + + %1 file selected (%2) + + + + + %1 files selected (%2) + + + + + %1 folder selected + + + + + Filter + + + + + Save as: + + + + + Loading... + + + + + DTaskDialog + + + This action is not supported + + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + + + + + Data Disk + Data Partition + + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + + + + + Target folder is inside the source folder! + + + + + + + + + + + + + + OK + + + + + Do you want to run %1 or display its content? + + + + + It is an executable text file. + + + + + + + + + + + + + + + Cancel + + + + + + + Run + + + + + + Run in terminal + + + + + Display + + + + + It is an executable file. + + + + + This file is not executable, do you want to add the execute permission and run? + + + + + "%1" already exists, please use another name. + + + + + + + + + Confirm + + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + + + + + Permanently delete %1 items? + + + + + Delete + + + + + Empty + + + + + Sorry, unable to locate your bookmark directory, remove it? + + + + + Remove + + + + + Name: + + + + + Force unmount + + + + + %1 that this shortcut refers to has been changed or moved + + + + + Do you want to delete this shortcut? + + + + + Failed, file size must be less than 4GB. + + + + + Fail to create symlink, cause: + + + + + The selected files contain system file/directory, and it cannot be deleted + + + + + + You do not have permission to operate file/folder! + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + + + + + View + + + + + Do you want to run %1? + + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + + + + + Please restore by the following steps to normally access Windows disk + + + + + 1. Reboot to enter Windows + + + + 3. Reboot and enter deepin + + + + + Reboot + + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + + + + + Format + + + + + Cancel + + + + + Save + + + + + Open + + + + + Save File + + + + + Open File + + + + + FileJob + + + copy + + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + + + + + %1 m %2 s + + + + + %1 h %2 m %3 s + + + + + %1 d %2 h %3 m %4 s + + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + + + + + + + Open behavior + + + + + + + Always open folder in new window + + + + + + + Open file: + + + + + + + Click + + + + + + + Double click + + + + + + + New window and tab + + + + + + + Open from default window: + + + + + + + + + + Computer + + + + + + + + + + Home + + + + + + + + + + Desktop + + + + + + + + + + Videos + + + + + + + + + + Music + + + + + + + + + + Pictures + + + + + + + + + + Documents + + + + + + + + + + Downloads + + + + + + + Open in new tab: + + + + + + + Current Directory + + + + + + + View + + + + + + + Default size: + + + + + + + Extra small + + + + + + + Small + + + + + + + Medium + + + + + + + Large + + + + + + + Extra large + + + + + + + Default view: + + + + + + + Icon + + + + + + + List + + + + + + + Hidden files + + + + + + + Show hidden files + + + + + + + Hide file extension when rename + + + + + + + Advanced + + + + + + + Index + + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + + + + + + + Hide system disk + + + + + + + Show hidden files in search results + + + + + + + Display recent file entry in left panel + + + + + + + Preview + + + + + + Compress file preview + + + + + + + Text preview + + + + + + + Document preview + + + + + + + Image preview + + + + + + + Video preview + + + + + + + Mount + + + + + + + Auto mount + + + + + + + Open after auto mount + + + + + + + Dialog + + + + Use the file chooser dialog of Deepin File Manager + + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + + + + + + + + + Confirm + + + + + + Cannot find the mounting device + + + + + Cannot unmount the device + + + + + Cannot eject the device "%1" + + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + + + + + + + Application + + + + + + + Video + + + + + + + Audio + + + + + + + Image + + + + + + Archive + + + + + + + Text + + + + + + Executable + + + + + + Backup file + + + + + + Unknown + + + + + MountAskPasswordDialog + + + Cancel + + + + + Connect + + + + + Log in as + + + + + Anonymous + + + + + Registered user + + + + + Username + + + + + Domain + + + + + Password + + + + + Remember password + + + + + MountSecretDiskAskPasswordDialog + + + Cancel + + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + + + + Keep both + + + + Replace + + + + Do not ask again + + + + merge + + + + Copying %1 + + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + + + + Moving %1 + + + + Move to %2 + + + + Restoring %1 + + + + Restore to %2 + + + + Deleting %1 + + + + Trashing %1 + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + Retry + + + + Time modified:%1 + + + + Original folder + + + + Original file + + + + Target folder + + + + Target file + + + + Contains:%1 + + + + Size:%1 + + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + + + + + Delete + + + + + OpenWithDialog + + + Open with + + + + + Add other programs + + + + + Set as default + + + + + Cancel + + + + + Confirm + + + + + Recommended Applications + + + + + Other Applications + + + + + PathManager + + + Home + + + + + Desktop + + + + + Videos + + + + + Music + + + + + Pictures + + + + + Documents + + + + + Downloads + + + + + + Trash + + + + + + System Disk + + + + + Computers in LAN + + + + + My Shares + + + + + Computer + + + + + Recent + + + + + PropertyDialog + + + Basic info + + + + + Open with + + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + + + + + QObject + + + + + Size + + + + + + + Contains + + + + + + + Type + + + + + + + + Time modified + + + + + Free space + + + + + Total space + + + + + Access denied + + + + + + Executable + + + + + + Write only + + + + + + Read only + + + + + + Read-write + + + + + Others + + + + + Owner + + + + + Device type + + + + + File system + + + + + Group + + + + + + + Open + + + + + + Size: %1 + + + + + Type: %1 + + + + + Size: 0 + + + + + Items: %1 + + + + + + + + + + + + Open in new window + + + + + + + + + + + + Open in new tab + + + + + Open with + + + + + Compress + + + + + Extract + + + + + Extract here + + + + + Cut + + + + + Copy + + + + + Paste + + + + + + + + + + + Rename + + + + + + + Remove + + + + + Create link + + + + + Send to desktop + + + + + Send to + + + + + Add to bookmark + + + + + + + + Properties + + + + + New folder + + + + + New window + + + + + Select all + + + + + + Clear recent history + + + + + + + Empty Trash + + + + + Display as + + + + + Sort by + + + + + New document + + + + + + Time created + + + + + Log out and unmount + + + + + + + Source path + + + + + Share folder + + + + + Cancel sharing + + + + + Connect to Server + + + + + Set share password + + + + + Format + + + + + Tag information + + + + + Open in new window as admin + + + + + Select default program + + + + + Open file location + + + + + Remove bookmark + + + + + + + Delete + + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + + + + + Restore + + + + + Restore all + + + + + File Vault + + + + + Auto mount + + + + + Open after auto mount + + + + + + Mount + + + + + + Unmount + + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + + + + + Safely Remove + + + + + + Name + + + + + Settings + + + + + Exit + + + + + Icon + + + + + List + + + + + Extend + + + + + Set as wallpaper + + + + + + + + Local disk + + + + + + Removable disk + + + + + + + Network shared directory + + + + + + Android mobile device + + + + + + Apple mobile device + + + + + + Camera + + + + + + DVD + + + + + + Unknown device + + + + + + + %1 item + + + + + + + %1 items + + + + + Shortcut + + + + + Create symlink + + + + + Path + + + + + + + Time deleted + + + + + Loading... + + + + + File has been moved or deleted + + + + + + + You do not have permission to access this folder + + + + + + + + Folder is empty + + + + + Path + SearchFileInfo + + + + + Searching... + + + + + No results + + + + + Source Path + TrashFileInfo + + + + + Document + + + + + Spreadsheet + + + + + + Presentation + + + + + Text + + + + + 1 task in progress + + + + + %1 tasks in progress + + + + + Mode: + + + + + + Replace Text + + + + + + Add Text + + + + + + Custom Text + + + + + Find: + + + + + Replace: + + + + + + Optional + + + + + Add: + + + + + Location: + + + + + File name: + + + + + +SN: + + + + + + + + + + + Required + + + + + + Before file name + + + + + + After file name + + + + + Find + + + + + Replace + + + + + Add + + + + + + + Location + + + + + File name + + + + + Dimension + + + + + Duration + + + + + +SN + + + + + Tips: Sort by selected file order + + + + + + + Cancel + + + + + Rename %1 Files + + + + + Multiple Files + + + + + Basic info + + + + + Total size + + + + + Number of files + + + + + %1 file(s), %2 folder(s) + + + + + + + Time accessed + + + + + Orange + + + + + Red + + + + + Purple + + + + + Navy-blue + + + + + Azure + + + + + Green + + + + + Yellow + + + + + Gray + + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + + + + + Erase + + + + + + Copy path + + + + + + Edit address + + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + + + + + Share name: + + + + + Permission: + + + + + Read and write + + + + + Read only + + + + + Anonymous: + + + + + Not allow + + + + + Allow + + + + + Shortcut + + + Item + + + + + Select to the first item + + + + + Shift + Home + + + + + Select to the last item + + + + + Shift + End + + + + + Select leftwards + + + + + Shift + Left + + + + + Select rightwards + + + + + Shift + Right + + + + + Select to upper row + + + + + Shift + Up + + + + + Select to lower row + + + + + Shift + Down + + + + + Open + + + + + Ctrl + Down + + + + + To parent directory + + + + + Ctrl + Up + + + + + Permanently delete + + + + + Shift + Delete + + + + + Delete file + + + + + Delete + + + + + Select all + + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + + + + + Cut + + + + + Paste + + + + + Rename + + + + + F2 + + + + + New/Search + + + + + New window + + + + + New folder + + + + + + Search + + + + + New tab + + + + + View + + + + + Item information + + + + + Help + + + + + F1 + + + + + Keyboard shortcuts + + + + + Ctrl + Shift + / + + + + + Switch display status + + + + + Hide item + + + + + Input in address bar + + + + + Switch to icon view + + + + + Ctrl + 1 + + + + + Switch to list view + + + + + Ctrl + 2 + + + + + Others + + + + + Close + + + + + Alt + F4 + + + + + Close current tab + + + + + Back + + + + + Alt + Left + + + + + Alt + Right + + + + + Switch to next tab + + + + + Ctrl + Tab + + + + + Ctrl + Shift + Tab + + + + + Switch to previous tab + + + + + Next file + + + + + Tab + + + + + Previous file + + + + + Shift + Tab + + + + + Switch tab by specified number between 1 to 8 + + + + + Alt + [1-8] + + + + + Forward + + + + + TrashPropertyDialog + + + Trash + + + + + item + + + + + items + + + + + Contains %1 %2 + + + + + UDiskListener + + + Failed to rename the label + + + + + UserShareManager + + + Kindly Reminder + + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + + + + + Confirm + + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ru.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ru.ts new file mode 100644 index 0000000..72405bb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ru.ts @@ -0,0 +1,4715 @@ + + + AppController + + + New Folder + Новая Папка + + + + Mounting device error + Ошибка подключения устройства + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Образ диска был поврежден и не может быть смонтирован, пожалуйста, сначала удалите диск + + + + Mount error: unsupported image format + Ошибка монтирования: не поддерживаемый формат образа + + + + + The device was not safely removed + Устройство не было безопасно извлечено + + + + + Click "Safely Remove" and then disconnect it next time + В следующий раз сначала нажмите "Безопасное извлечение", а затем отключите устройство + + + + The device was not ejected + Устройство не было извлечено + + + + Disk is busy, cannot eject now + Диск занят и не может быть извлечён сейчас + + + + Authentication timed out + Истекло время аутентификации + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Передача файлов по Bluetooth + + + + File Transfer Successful + Передача файла прошла успешно + + + + File Transfer Failed + Ошибка передачи файла + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Отправка файлов на "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Не удалось отправить файлы на "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Отправка файлов на "<b style="font-weight: 550;">%1</b>" прошла успешно + + + + Select a Bluetooth device to receive files + Выберите устройство Bluetooth для приема файлов + + + + Cannot find the connected Bluetooth device + Не удается найти подключенное устройство Bluetooth + + + + Waiting to be received... + Ожидание получения... + + + + Go to Bluetooth Settings + Перейти в настройки Bluetooth + + + + %1/%2 Sent + Отправлено %1/%2 + + + + Error: the Bluetooth device is disconnected + Ошибка: устройство Bluetooth отключено + + + + Unable to send the file more than 2 GB + Невозможно отправить файл размером превышающий 2 ГБ + + + + Unable to send 0 KB files + Невозможно отправить файлы размером 0 КБ + + + + File doesn't exist + Файл не существует + + + + Next + button + Следующий + + + + Cancel + button + Отмена + + + + Done + button + Готово + + + + Retry + button + Повторить + + + + OK + button + + + + + File sending request timed out + Время ожидания запроса на отправку файла истекло + + + + The service is busy and unable to process the request + Сервис занят и не может обработать запрос + + + + BurnOptDialog + + + Device error + Ошибка устройства + + + + Optical device %1 doesn't exist + Оптическое устройство %1 не существует + + + + Advanced settings + Расширенные настройки + + + + File system: + Файловая система: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (для Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (для Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Совместимый с режимом Windows CD/DVD) + + + + ISO9660 Only + Только ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Закрыть все + + + + Total size: %1, %2 files + Общий размер %1, %2 файлов + + + + ComputerModel + + + Double click to open it + + + + + My Directories + Мои Каталоги + + + + Disks + Диски + + + + File Vault + Файловое хранилище + + + + Quick Access + + + + + ComputerPropertyDialog + + + Computer + Компьютер + + + + Basic Info + Основная Информация + + + + + Computer Name + Имя Компьютера + + + + + Edition + Издание + + + + + + Version + Версия + + + + + Type + Тип + + + + + + Processor + Процессор + + + + + + Memory + Память + + + + + + + Bit + Бит + + + + + Available + Доступный + + + + Obtaining... + + + + + ConnectToServerDialog + + + Connect to Server + Соединиться с Сервером + + + + Cancel + button + Отмена + + + + Connect + button + Соединить + + + + My Favorites: + Мое Избранное: + + + + + Clear History + Очистить Историю + + + + DFMAddressBar + + + Search or enter address + Поиск или ввод адреса + + + + DFMAdvanceSearchBar + + + Search: + Поиск: + + + + File Type: + Тип Файла: + + + + File Size: + Размер Файла: + + + + Time Modified: + Время Изменения: + + + + Time Accessed: + Время доступа: + + + + Time Created: + Время создания: + + + + Reset + Сбросить + + + + All subdirectories + Все подкаталоги + + + + Current directory + Текущий каталог + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Сегодня + + + + Yesterday + Вчера + + + + This week + На этой неделе + + + + Last week + На прошлой неделе + + + + This month + В этом месяце + + + + Last month + В прошлом месяце + + + + This year + В этом году + + + + Last year + В прошлом году + + + + DFMOpticalMediaWidget + + + + No files to burn + Нет файлов для записи + + + + Unable to burn. Not enough free space on the target disk. + Ошибка записи. Недостаточно свободного места на целевом диске. + + + + %1 burning is not supported + Прожиг %1 не поддерживается + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + + + + + DFMTagCrumbController + + + Tag information + Информация о метках + + + + DFMTagWidget + + + Tag + Ярлык + + + + DFMTaskWidget + + + Do not ask again + Не спрашивать больше + + + + Syncing data + Синхронизация данных + + + + Please wait + Пожалуйста подождите + + + + + Time modified: %1 + Время изменения: %1 + + + + + Contains: %1 + Содержит: %1 + + + + + Size: %1 + Размер: %1 + + + + Original folder + Исходная папка + + + + Keep both + button + Оставить оба + + + + Skip + button + Пропустить + + + + Replace + button + Заменить + + + + Retry + button + Повторить + + + + Original file + Исходный файл + + + + Target folder + Папка назначения + + + + Target file + Файл назначения + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Зашифровать Хранилище Файлов + + + + Click 'Encrypt' and input the user password. + Нажмите 'Зашифровать' и введите пароль пользователя. + + + + Encrypting... + Шифрование... + + + + + + + Encrypt + Зашифровать + + + + Failed to create file vault: %1 + Не удалось создать хранилище файлов: %1 + + + + OK + + + + + The setup is complete + Настройка завершена + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + + + + + Keep the key safe to retrieve the vault password later + + + + + Save to default path + + + + + Save to other locations + + + + + No permission, please reselect + + + + + Select a path + + + + + Next + Следующий + + + + The default path is invisible to other users, and the path information will not be shown. + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Ключ восстановления + + + + Generate a recovery key in case that you forgot the password + Сгенерируйте ключ восстановления на случай, если вы забыли пароль + + + + Key + Ключ + + + + QR code + QR-код + + + + Scan QR code and save the key to another device + Отсканируйте QR-код и сохраните ключ на другом устройстве + + + + Next + Следующий + + + + Recovery Key: + Ключ восстановления: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Установить пароль хранилища + + + + Method + Метод + + + + Manual + Ручной + + + + Password + Пароль + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 символов, содержит A-Z, a-z, 0-9 и символы + + + + Repeat password + Повторите пароль + + + + Input the password again + Введите пароль еще раз + + + + Password hint + Подсказка пароля + + + + Optional + Необязательный + + + + Next + Следующий + + + + + Passwords do not match + Пароли не совпадают + + + + DFMVaultActiveStartView + + + File Vault + Файловое хранилище + + + + Create your secure private space + Создайте свое безопасное личное пространство + + + + Advanced encryption technology + Передовая технология шифрования + + + + Convenient and easy to use + Удобный и простой в использовании + + + + Create + Создать + + + + DFMVaultFileView + + + Cannot open this path + + + + + Hint + + + + + OK + + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Разблокировать ключом + + + + Failed to unlock file vault + Не удалось разблокировать хранилище файлов + + + + OK + + + + + Input the 32-digit recovery key + Введите 32-значный ключ восстановления + + + + Cancel + button + Отмена + + + + Unlock + button + Разблокировать + + + + Wrong recovery key + Неверный ключ восстановления + + + + DFMVaultRemoveByPasswordView + + + Password + Пароль + + + + Password hint: %1 + Подсказка пароля: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Введите 32-значный ключ восстановления + + + + DFMVaultRemovePages + + + Delete File Vault + Удалить хранилище файлов + + + + Once deleted, the files in it will be permanently deleted + После удаления файлы в нем будут удалены безвозвратно + + + + Use Key + Использовать ключ + + + + Cancel + button + Отмена + + + + Use Key + button + Использовать ключ + + + + Delete + button + Удалить + + + + + OK + button + + + + + Use Password + Использовать пароль + + + + Wrong password + Неверный пароль + + + + Wrong recovery key + Неверный ключ восстановления + + + + Failed to delete file vault + Не удалось удалить хранилище файлов + + + + Deleted successfully + Успешно удалено + + + + Failed to delete + Не удалось удалить + + + + Removing... + Удаление... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + + + + + Verification failed + + + + + + Select a path + + + + + + Retrieve Password + + + + + By key in the default path + + + + + By key in the specified path + + + + + Verification Successful + + + + + Keep it safe + + + + + Back + button + Назад + + + + Verify Key + button + + + + + Go to Unlock + button + + + + + Close + button + Закрыть + + + + Vault password: %1 + + + + + DFMVaultUnlockPages + + + Unlock File Vault + Разблокировать хранилище файлов + + + + Forgot password? + + + + + Password hint: %1 + Подсказка пароля: %1 + + + + Failed to unlock file vault + Не удалось разблокировать хранилище файлов + + + + Cancel + button + Отмена + + + + Password + Пароль + + + + Unlock + button + Разблокировать + + + + Please try again %1 minutes later + + + + + Wrong password, please try again %1 minutes later + + + + + Wrong password, one chance left + + + + + Wrong password, %1 chances left + + + + + Wrong password + Неверный пароль + + + + OK + button + + + + + DFileCopyMoveJob + + + Permission error + Ошибка доступа + + + + The action is denied + Действие отклонено + + + + Failed to open the file + Не удалось открыть файл + + + + Failed to read the file + Не удалось прочитать файл + + + + Failed to write the file + Не удалось прочитать файл + + + + Failed to create the directory + Не удалось создать каталог + + + + Failed to delete the file + Не удалось удалить файл + + + + Failed to move the file + Не удалось переместить файл + + + + Original file does not exist + Исходный файл не существует + + + + Failed, file size must be less than 4GB + Не удалось, размер файла должен быть меньше 4Гб + + + + Not enough free space on the target disk + Недостаточно свободного места на целевом диске + + + + File integrity was damaged + Целостность файла повреждена + + + + The target device is read only + Устройство назначения доступно только для чтения + + + + Target folder is inside the source folder + Целевая папка находится внутри исходной папки + + + + The action is not supported + Действие не поддерживается + + + + You do not have permission to traverse files in it + У вас нет прав для просмотра файлов + + + + Failed to position the file pointer! + + + + + copy + Extra name added to new file name when used for file name. + копировать + + + + Failed to open the directory, cause: file name too long + Не удалось открыть каталог: слишком длинное имя файла + + + + + Failed to open the file, cause: file name too long + Не удалось открыть файл: слишком длинное имя файла + + + + + Failed to write the file, cause: + Не удалось записать файл: + + + + Failed to position the file pointer, cause: %1 + + + + + Syncing data + Синхронизация данных + + + + Please wait + Пожалуйста подождите + + + + Failed to create the directory, cause: %1 + Не удалось создать каталог потому, что: %1 + + + + + + + + Failed to open the file, cause: %1 + Не удалось открыть файл потому, что: %1 + + + + + + + Failed to open the file, cause: Permission denied + Не удалось открыть файл: отказано в доступе + + + + + Failed to read the file, cause: %1 + Не удалось прочитать файл потому, что: %1 + + + + + + + Failed to write the file, cause: %1 + Не удалось записать файл потому, что: %1 + + + + + File integrity was damaged, cause: %1 + Целостность файла была нарушена потому, что: %1 + + + + Failed to open the file, cause: + Не удалось открыть файл, по причине: + + + + Failed to read the file, cause: + Не удалось прочитать файл, по причине: + + + + Failed to delete the file, cause: %1 + Не удалось удалить файл потому, что: %1 + + + + Fail to create symlink, cause: %1 + Не удалось создать символическую ссылку потому, что: %1 + + + + DFileDialog + + + + Save + button + Сохранить + + + + + Cancel + button + Отмена + + + + Confirm + button + Подтвердить + + + + %1 already exists, do you want to replace it? + %1 существует, хотите заменить? + + + + Replace + button + Заменить + + + + Open + button + Открыть + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Этот файл будет скрыт, если имя файла начинается с точки (.). Вы хотите продолжить? + + + + DFileManagerWindow + + + Trash + Корзина + + + + Empty + Очистить + + + + DFileSystemModel + + + + Name + Имя + + + + + + Time modified + Время изменения + + + + Size + Размер + + + + Type + Тип + + + + Time created + Время создания + + + + + Last access + Последний доступ + + + + + + + Path + Путь + + + + DFileView + + + Disc mount error + Ошибка монтирования диска + + + + The disc is in use, please end the running process and remount the disc. + Диск уже используется, пожалуйста завершите процесс и повторите монтирование диска заново. + + + + Mounting failed + Не удалось подключить + + + + (Reverse) + (Реверс) + + + + DFileViewHelper + + + Add tag "%1" + Добавить метку "%1" + + + + DStatusBar + + + %1 item + %1 элемент + + + + %1 items + %1 элементов + + + + %1 item selected + %1 элемент выбран + + + + %1 items selected + %1 элементов выбрано + + + + %1 folder selected (contains %2) + %1 папка выбрана (содержит %2) + + + + %1 folders selected (contains %2) + %1 папки выбраны (содержат %2) + + + + %1 file selected (%2) + %1 файлов выбрано (%2) + + + + %1 files selected (%2) + %1 выбрано файлов (%2) + + + + %1 folder selected + %1 выбрана папка + + + + Filter + Фильтр + + + + Save as: + Сохранить как: + + + + Loading... + Загрузка.... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Стирание диска %1, пожалуйста, подождите... + + + + Burning disc %1, please wait... + Прожиг диска %1, пожалуйста, подождите... + + + + Writing data... + Запись данных... + + + + Verifying data... + Проверка данных... + + + + Copying %1 + Копирование %1 + + + + + + to %2 + в %2 + + + + %1 already exists in target folder + %1 уже существует в целевой папке + + + + Original path %1 Target path %2 + Исходный путь %1 путь назначения %2 + + + + Merge + button + Объединить + + + + Replace + button + Заменить + + + + Moving %1 + Перемещение %1 + + + + Removing file vault, please try later + Удаление хранилища файлов, попробуйте позже + + + + Restoring %1 + Восстановление %1 + + + + Deleting %1 + Удаление %1 + + + + Trashing %1 + Удаление %1 + + + + Calculating space, please wait + Подсчет места, пожалуйста подождите + + + + DUMountManager + + + + Authentication timed out + Истекло время аутентификации + + + + + + Disk is busy, cannot unmount now + Диск занят, не могу отмонтировать сейчас + + + + Disk is busy, cannot eject now + Диск занят и не может быть извлечён сейчас + + + + The device is busy, cannot eject now + Устройство занято и не может быть извлечено сейчас + + + + + + The device is busy, cannot remove now + Устройство занято, сейчас извлечь нельзя + + + + DeepinStorage + + + + + %1 Volume + %1 Объём + + + + Data Disk + Data Partition + Диск Данных + + + + %1 Drive + %1 Привод + + + + Blank %1 Disc + Чистый %1 Диск + + + + %1 Encrypted + %1 Зашифровано + + + + DialogManager + + + + + + Operation failed! + Не удалось выполнить операцию! + + + + Target folder is inside the source folder! + Целевая папка находится внутри исходной папки! + + + + Do you want to run %1 or display its content? + Вы хотите запустить %1 или отобразить его содержание? + + + + It is an executable text file. + это исполняемый текстовый файл. + + + + It is an executable file. + Это исполняемый файл. + + + + This file is not executable, do you want to add the execute permission and run? + Этот файл не является исполняемым, вы хотите добавить разрешение на выполнение и запустить? + + + + "%1" already exists, please use another name. + %1 существует, пожалуйста выберите другое имя. + + + + The file name must not contain two dots (..) + Имя файла не должно содержать двух точек (..) + + + + Device or resource busy + + + + + Are you sure you want to erase all data on the disc? + Вы уверены, что хотите стереть все данные на диске? + + + + How do you want to use this disc? + Как вы хотите использовать этот диск? + + + + Disc erase failed + Очистить диск не удалось + + + + Burn process failed + Процесс записи не удался + + + + %1: %2 + %1: %2 + + + + Show details + Показать детали + + + + Hide details + Скрыть детали + + + + Error + Ошибка + + + + Permanently delete %1? + Удалить без возможности восстановления %1? + + + + Permanently delete %1 items? + Удалить без возможности восстановления %1 элементов? + + + + Empty + Очистить + + + + Do you want to delete %1? + Вы хотите удалить %1? + + + + Do you want to delete the selected %1 items? + Вы хотите удалить выбранные %1 элемента(ов)? + + + + Sorry, unable to locate your bookmark directory, remove it? + К сожалению, не удалось найти каталог закладок, удалить его? + + + + Name: + Имя: + + + + %1 that this shortcut refers to has been changed or moved + %1, этот ярлык относится к измененному или перемещенному объекту + + + + Do you want to delete this shortcut? + Вы хотите удалить этот ярлык? + + + + Failed, file size must be less than 4GB. + Не удалось, размер файла должен быть меньше 4 Гб. + + + + Fail to create symlink, cause: + Ошибка создания ссылки, решение: + + + + The selected files contain system file/directory, and it cannot be deleted + Выбранные файлы содержат системный файл/каталог и не могут быть удалены + + + + Unable to find the original file + Не удалось найти исходный файл + + + + + You do not have permission to operate file/folder! + У вас нет разрешения на использование файла/папки! + + + + Failed to restore %1 file, the source file does not exist + Не удалось восстановить %1 файл, исходный файл не существует + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Извините, но у вас нет разрешения на использование следующих %1 файла(ов)! + + + + Unable to access %1 + Невозможно получить доступ к %1 + + + + + Sending files now, please try later + Отправка файлов, пожалуйста попробуйте позже + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Чтобы получить доступ к устройству, вы должны сначала отформатировать диск. Вы уверены, что хотите отформатировать его сейчас? + + + + Scanning the device, stop it? + Сканирование устройства, остановить его? + + + + Share folder can't be named after the current username + Папка общего доступа не может быть названа после текущего имени пользователя + + + + Do you want to run %1? + Вы хотите выполнить %1? + + + + Burn image + button + Записать образ + + + + Burn files + button + Записать файлы + + + + Are you sure you want to empty %1 item? + Вы уверены в очистке %1 объекта? + + + + Are you sure you want to empty %1 items? + Вы уверены в очистке %1 объектов? + + + + + This action cannot be undone + Это действие не может быть отменено + + + + + + + + + + + + + + OK + button + + + + + + + + + + + + + + + + Cancel + button + Отмена + + + + + + Run + button + Выполнить + + + + + Run in terminal + button + Выполнить в терминале + + + + Display + button + Дисплей + + + + + + + + + + + Confirm + button + Подтвердить + + + + Erase + button + Очистить + + + + Data verification failed + Ошибка проверки данных + + + + Show details + button + Показать детали + + + + + Delete + button + Удалить + + + + Remove + button + Удалить + + + + Disk is busy, cannot unmount now + Диск занят, не могу отмонтировать сейчас + + + + Force unmount + button + Отмонтировать принудительно + + + + Unable to copy. Not enough free space on the target disk. + Невозможно скопировать. Недостаточно свободного места на целевом диске + + + + Failed to restore %1 file, the target folder is read-only + Не удалось восстановить %1 файл, целевая папка доступна только для чтения + + + + Failed to restore %1 files, the target folder is read-only + Не удалось восстановить %1 файлы, целевая папка доступна только для чтения + + + + Failed to restore %1 files, the source files do not exist + Не удалось восстановить %1 файла(ов), исходные файлы не существуют + + + + Format + button + Форматировать + + + + Stop + button + Стоп + + + + FileController + + + + + + Unable to find the original file + Не удалось найти исходный файл + + + + + + Kindly Reminder + Пожалуйста Запомните + + + + + + Please install File Roller first and then continue + Пожалуйста, сначала установите File Roller, а затем продолжайте + + + + + Unable to create files here: %1 + Невозможно создать файлы здесь: %1 + + + + Confirm + button + Подтвердить + + + + FileDialogStatusBar + + + File Name + Имя Файла + + + + Format + Форматировать + + + + Save + button + Сохранить + + + + Open + button + Открыть + + + + Save File + button + Сохранить Файл + + + + Open File + button + Открыть Файл + + + + + + Cancel + button + Отмена + + + + FileJob + + + copy + копия + + + + + + + Data verification successful. + Проверка данных прошла успешно. + + + + + + Burn process completed + Процесс записи завершен + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 является дубликатом файла. + + + + Insufficient disc space. + Недостаточно места на диске. + + + + Lost connection to drive. + Потеряна связь с приводом. + + + + The CD/DVD drive is not ready. Try another disc. + Привод CD/DVD не готов. Попробуйте другой диск. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + Дисковод CD/DVD занят. Выйдите из программы, используя привод, и снова вставьте диск. + + + + Unknown error + Неизвестная ошибка + + + + Device disconnected + Устройство отключено + + + + GenerateSettingTranslate + + + + + Basic + Основной + + + + + + Open behavior + Поведение при открытии + + + + + + Always open folder in new window + Всегда открывать папку в новом окне + + + + + + Open file: + Открыть файл: + + + + + + Click + Щелчок + + + + + + Double click + Двойной щелчок + + + + + + New window and tab + Новое окно и закладка + + + + + + Open from default window: + Открыть в текущем окне: + + + + + + + + + Computer + Компьютер + + + + + + + + + Home + Главная + + + + + + + + + Desktop + Рабочий Стол + + + + + + + + + Videos + Видео + + + + + + + + + Music + Мызука + + + + + + + + + Pictures + Изображения + + + + + + + + + Documents + Документы + + + + + + + + + Downloads + Загрузки + + + + + + Open in new tab: + Открыть в новой вкладке: + + + + + + Current Directory + Текущий Каталог + + + + + + View + Просмотр + + + + + + Default size: + Размер по-умолчанию: + + + + + + Extra small + Крохотный + + + + + + Small + Маленький + + + + + + Medium + Средний + + + + + + Large + Большой + + + + + + Extra large + Очень большой + + + + + + Default view: + Вид по-умолчанию: + + + + + + Icon + Значок + + + + + + List + Список + + + + + + Hidden files + Скрытые файлы + + + + + + Show hidden files + Показывать скрытые файлы + + + + + + Hide file extension when rename + Скрыть расширение файла при переименовании + + + + + + Advanced + Расширенные + + + + + + Index + Указатель + + + + + + Auto index internal disk + Автоматически индексировать внутренний диск + + + + + + Index external storage device after connected to computer + Индексировать внешнее запоминающее устройство после подключения к компьютеру + + + + + + Full-Text search + Полнотекстовый поиск + + + + + + Show item counts and sizes in the path of mounted MTP devices + + + + + + + Keep showing the mounted Samba shares + + + + + + + Use the file chooser dialog of File Manager + Использовать диалог выбора файлов в Диспетчере Файлов + + + + + + Ask for my confirmation when deleting files + Запрашивать подтверждение при удалении файлов + + + + + + Other + Другое + + + + + + Hide system disk + Скрыть системный диск + + + + + + Show file system on disk icon + Показать файловую систему на значке диска + + + + + + Show hidden files in search results + Показывать скрытые файлы в результатах поиска + + + + + + Display recent file entry in left panel + Отобразить недавние обращения к файлам в левой панели + + + + + + Preview + Предварительный просмотр + + + + + Compress file preview + Предварительный просмотр сжатых файлов + + + + + + Text preview + Предварительный просмотр текста + + + + + + Document preview + Предварительный просмотр документа + + + + + + Image preview + Предварительный просмотр изображения + + + + + + Video preview + Предварительный просмотр видео + + + + + + Mount + Подключить + + + + + + Auto mount + Авто-подключение + + + + + + Open after auto mount + Открывать после авто-подключения + + + + + + Dialog + Диалог + + + + Compressed file preview + Предварительный просмотр сжатого файла + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Не удается подтвердить подлинность %1. + + + + This happens when you log in to a computer the first time. + Это происходит при первом вашем входе в систему. + + + + The identity sent by the remote computer is + Идентификация, отправленная удаленным компьютером + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Если вы хотите быть абсолютно уверены в безопасности действия и его продолжения, обратитесь к системному администратору. + + + + + + + + Mounting device error + Ошибка подключения устройства + + + + + Wrong username or password + Неверное имя пользователя или пароль + + + + + + + + Confirm + button + Подтвердить + + + + + Cannot find the mounted device + Не удается найти подключенное устройство + + + + No key available to unlock device + Ключа для разблокировки устройства не существует + + + + The disk is mounted by user "%1", you cannot unmount it. + Диск смонтирован пользователем "%1", вы не сможете его размонтировать. + + + + Cannot unmount the device + Не могу отключить устройство + + + + Cannot eject the device "%1" + Не могу извлечь устройство "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Ошибка записи. Недостаточно свободного места на целевом диске. + + + + MergedDesktopController + + + + Pictures + Изображения + + + + + Music + Мызука + + + + + Applications + Приложения + + + + + Videos + Видео + + + + + Documents + Документы + + + + + Others + Прочее + + + + MimeTypeDisplayManager + + + + Directory + Каталог + + + + + + Application + Приложение + + + + + + Video + Видео + + + + + + Audio + Аудио + + + + + + Image + Изображение + + + + + Archive + Архив + + + + + + Text + Текст + + + + + Executable + Исполняемый + + + + + Backup file + Резервное копирование файла + + + + + Unknown + Неизвестно + + + + MountAskPasswordDialog + + + Cancel + button + Отмена + + + + Connect + button + Соединить + + + + Log in as + Войти как + + + + Anonymous + Анонимный + + + + Registered user + Зарегистрированный пользователь + + + + Username + Имя пользователя + + + + Domain + Домен + + + + Password + Пароль + + + + Remember password + Запомнить пароль + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Отмена + + + + Unlock + button + Разблокировать + + + + Input password to decrypt the disk + Пожалуйста введите пароль для расшифровки диска + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Вы уверены, что хотите окончательно удалить %1? + + + + This file is too big for the trash + Этот файл слишком велик для корзины + + + + The files are too big for the trash + Этот файл слишком велик для корзины + + + + Are you sure you want to permanently delete %1 files? + Вы уверены, что хотите окончательно удалить %1 файлов? + + + + Cancel + button + Отмена + + + + Delete + button + Удалить + + + + OpenWithDialog + + + Open with + Открыть с помощью + + + + Add other programs + Добавить другие программы + + + + Set as default + Установить по умолчанию + + + + Cancel + button + Отмена + + + + Confirm + button + Подтвердить + + + + Recommended Applications + Рекомендованные Приложения + + + + Other Applications + Другие Приложения + + + + PathManager + + + Home + Главная + + + + Desktop + Рабочий стол + + + + Videos + Видео + + + + Music + Музыка + + + + Pictures + Изображения + + + + Documents + Документы + + + + Downloads + Загрузки + + + + + Trash + Корзина + + + + + + System Disk + Системный Диск + + + + Computers in LAN + Компьютеры в сети + + + + My Shares + Общедоступные + + + + Computer + Компьютер + + + + Recent + Недавние + + + + File Vault + Файловое хранилище + + + + PropertyDialog + + + Basic info + Основная информация + + + + Open with + Открыть с помощью + + + + Sharing + Обмен + + + + Permissions + Права доступа + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Скрыть эту папку + + + + Hide this file + Скрыть этот файл + + + + Allow to execute as program + Разрешить выполнение в качестве программы + + + + QObject + + + + + + Size + Размер + + + + + + Contains + Содержит + + + + + + Type + Тип + + + + + + + + Time modified + Время изменения + + + + Free space + Свободное место + + + + Total space + Всего + + + + + Time locked + Время заблокировано + + + + Access denied + Доступ закрыт + + + + + Executable + Исполняемый + + + + + Write only + Только запись + + + + + Read only + Только чтение + + + + + Read-write + Чтение-запись + + + + Others + Другие + + + + Owner + Владелец + + + + Unconnected network shared directory + + + + + Device type + Тип устройства + + + + File system + Файловая система + + + + Group + Группа + + + + + Open + Открыть + + + + Lock + Заблокировать + + + + Auto lock + Автоматическая блокировка + + + + Never + Никогда + + + + 5 minutes + 5 минут + + + + 10 minutes + 10 минут + + + + 20 minutes + 20 минут + + + + Delete File Vault + Удалить хранилище файлов + + + + Unlock + Разблокировать + + + + Unlock by key + Разблокировка ключом + + + + Open + button + Открыть + + + + + Size: %1 + Размер: %1 + + + + Type: %1 + Тип: %1 + + + + Size: 0 + Размер: 0 + + + + Items: %1 + Элементов: %1 + + + + + + + + + + Open in new window + Открыть в новом окне + + + + + + + + + + Open in new tab + Открыть в новой вкладке + + + + Open with + Открыть с помощью + + + + + Compress + Сжать + + + + Extract + Извлечь + + + + Extract here + Извлечь сюда + + + + Cut + Вырезать + + + + Copy + Копировать + + + + Paste + Вставить + + + + + + + + Rename + Переименовать + + + + + + + Remove + Удалить + + + + Create link + Создать ссылку + + + + Send to desktop + Отправить на рабочий стол + + + + Send to + Отправить в + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Добавить в закладки + + + + + + + Properties + Свойства + + + + New folder + Новая папка + + + + New window + Новое окно + + + + Select all + Выбрать все + + + + + Clear recent history + Очистить недавнюю историю + + + + + + Empty Trash + Очистить корзину + + + + Display as + Отобразить как + + + + Sort by + Сортировать по + + + + New document + Новый документ + + + + + Time created + Время создания + + + + + + Source path + Путь к источнику + + + + Share folder + Общедоступная папка + + + + Cancel sharing + Отменить общий доступ + + + + Connect to Server + Соединиться с Сервером + + + + Set share password + Установить пароль общего доступа + + + + Format + Форматировать + + + + Tag information + Информация о метках + + + + Open as administrator + Открыть в качестве администратора + + + + Select default program + Выбрать программу по умолчанию + + + + Open file location + Открыть местоположение файла + + + + Remove bookmark + Удалить закладку + + + + + + Delete + Удалить + + + + Office Text + Офисный + + + + Spreadsheets + Таблица + + + + Plain Text + Обычный + + + + Open in terminal + Открыть в терминале + + + + Restore + Восстановить + + + + Restore all + Восстановить все + + + + Clear saved password and unmount + + + + + File Vault + Файловое Хранилище + + + + Add to disc + Добавить на диск + + + + Refresh + + + + + Auto mount + Авто-подключение + + + + Open after auto mount + Открыть после авто-монтирования + + + + + Mount + Подключить + + + + + Unmount + Отключить + + + + It does not support burning %1 discs + Не поддерживается прожиг дисков %1  + + + + Burn + Запись + + + + Disc name: + Имя привода: + + + + + Maximum + Максимальная + + + + Allow files to be added later + Разрешить добавление файлов позже + + + + Verify data + Проверить данные + + + + Write speed: + Скорость записи: + + + + + + + Cancel + button + Отмена + + + + Burn + button + Запись + + + + + Eject + Извлечь + + + + Safely Remove + Безопасное Извлечение + + + + + Name + Имя + + + + Settings + Настройки + + + + Exit + Выход + + + + Icon + Значок + + + + List + Список + + + + Extend + Расширить + + + + Set as wallpaper + Сделать фоном рабочего стола + + + + + + + Local disk + Локальный диск + + + + + Removable disk + Съемный диск + + + + + + Network shared directory + Общий сетевой каталог + + + + + Android mobile device + Мобильное устройство Android + + + + + Apple mobile device + Мобильное устройство Apple + + + + + Camera + Камера + + + + + DVD + DVD + + + + + Unknown device + Неизвестное устройство + + + + + + %1 item + %1 элемент + + + + + + %1 items + %1 элементов + + + + Shortcut + Ярлык + + + + Create symlink + Создать символическую ссылку + + + + Path + Путь + + + + + + Time deleted + Время удаления + + + + Loading... + Загрузка... + + + + File has been moved or deleted + Файл был перемещен или удален + + + + You do not have permission to traverse files in it + У вас нет прав для просмотра файлов + + + + + + You do not have permission to access this folder + У вас нет разрешения на доступ к этой папке + + + + + + + + Folder is empty + Папка пуста + + + + Searching... + Поиск... + + + + No results + Нет результатов + + + + Source Path + TrashFileInfo + Исходный Путь + + + + Document + Документ + + + + Spreadsheet + Таблица + + + + + Presentation + Презентация + + + + Text + Текст + + + + 1 task in progress + 1 задача выполняется + + + + %1 tasks in progress + %1 задачи выполняются + + + + Mode: + Режим: + + + + + Replace Text + Заменить Текст + + + + + Add Text + Добавить Текст + + + + + Custom Text + Пользовательский Текст + + + + Find: + Найти: + + + + Replace: + Заменить: + + + + + Optional + Необязательный + + + + Add: + Добавить: + + + + Location: + Местоположение: + + + + File name: + Имя файла: + + + + Start at: + Начать с: + + + + + Rename + button + Переименовать + + + + + + + + + + + Required + Требуется + + + + + Before file name + До имени файла + + + + + After file name + После имени файла + + + + Find + Найти + + + + Replace + Переместить + + + + Add + Добавить + + + + Start at + Начать с + + + + + + Location + Местонахождение + + + + File name + Имя файла + + + + Dimension + Размерность + + + + Duration + Продолжительность + + + + Tips: Sort by selected file order + Совет: Сортировать по выбранному файлу ордера + + + + Rename %1 Files + Переименовать %1 Файлов + + + + Multiple Files + Несколько файлов + + + + Basic info + Основная информация + + + + Total size + Общий размер + + + + Number of files + Количество файлов + + + + %1 file(s), %2 folder(s) + %1 файл(ов), %2 папка(ок) + + + + + + Time accessed + Время доступа к + + + + Orange + Оранжевый + + + + Red + Красный + + + + Purple + Пурпурный + + + + Navy-blue + Темно-синий + + + + Azure + Лазурь + + + + Green + Зеленый + + + + Yellow + Желтый + + + + Gray + Серый + + + + Input tag info, such as work, family. A comma is used between two tags. + Введите информацию для метки, например, работа, семья. Для разделения двух меток используется запятая. + + + + Bookmarks + Закладки + + + + Erase + Очистить + + + + Copy path + Копировать путь + + + + Edit address + Редактировать адресс + + + + Free Space %1 + Свободное пространство %1 + + + + Files are being processed + Файлы обрабатываются + + + + + Unknown + Неизвестно + + + + My Vault + Моё хранилище + + + + + Failed to create file info + Не удалось создать информацию о файле + + + + Failed to create file handler + Не удалось создать обработчик файлов + + + + Failed to open the file, cause: %1 + Не удалось открыть файл потому, что: %1 + + + + Original file does not exist + Исходный файл не существует + + + + Do you want to delete %1? + Вы хотите удалить %1? + + + + Confirm + button + Подтвердить + + + + + + + + %1 are not allowed + + + + + + Failed to start Samba services + + + + + RecentController + + + Cancel + button + Отмена + + + + Remove + button + Удалить + + + + Do you want to remove this item? + + + + + Do yout want to remove %1 items? + + + + + It does not delete the original files + + + + + ShareInfoFrame + + + Share this folder + Открыть общий доступ + + + + Share name: + Имя в сети: + + + + Permission: + Права доступа: + + + + Read and write + Чтение и запись + + + + Read only + Только чтение + + + + Anonymous: + Анонимно: + + + + Not allow + Не разрешено + + + + Allow + Разрешено + + + + The share name must not be two dots (..) or one dot (.) + Имя общего ресурса не должно состоять из двух точек (..) или одной точки (.) + + + + The share name is used by another user. + Имя общего ресурса используется другим пользователем. + + + + OK + button + + + + + Cancel + button + Отмена + + + + Replace + button + Заменить + + + + The share name already exists. Do you want to replace the shared folder? + Имя общего ресурса уже существует. Хотите заменить папку общего доступа? + + + + Shortcut + + + Item + элемент + + + + Select to the first item + Выбрать первый элемент + + + + Shift + Home + Shift + Home + + + + Select to the last item + Выберите последний элемент + + + + Shift + End + Shift + End + + + + Select leftwards + Выбрать слева + + + + Shift + Left + Shift + Left + + + + Select rightwards + Выбрать справа + + + + Shift + Right + Shift + Right + + + + Select to upper row + Выбрать верхний ряд + + + + Shift + Up + Shift + Up + + + + Select to lower row + Выберать нижний ряд + + + + Shift + Down + Shift + Down + + + + Open + Открыть + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + В родительский каталог + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Удалить навсегда + + + + Shift + Delete + Shift + Delete + + + + Delete file + Удалить файл + + + + Delete + Удалить + + + + Select all + Выбрать все + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Копировать + + + + Cut + Вырезать + + + + Paste + Вставить + + + + Rename + Переименовать + + + + F2 + F2 + + + + New/Search + Новый/Поиск + + + + New window + Новое окно + + + + New folder + Новая папка + + + + + Search + Поиск + + + + New tab + Новая вкладка + + + + View + Просмотр + + + + Item information + Информация об элементе + + + + Help + Помощь + + + + F1 + F1 + + + + Keyboard shortcuts + Горячие клавиши + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Переключить индикацию состояния + + + + Hide item + Скрыть элемент + + + + Input in address bar + ввод в адресной строке + + + + Switch to icon view + Переключить на просмотр в виде значков + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Переключить на просмотр в виде списка + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Прочее + + + + Close + Закрыть + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Закрыть текущую вкладку + + + + Back + Назад + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Переключиться на следующую вкладку + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Переключиться на предыдущую вкладку + + + + Next file + Следующий файл + + + + Tab + Вкладка + + + + Previous file + Предыдущий файл + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Переключить вкладку по указанному номеру от 1 до 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Вперед + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Не удаётся открыть элементы в корзине, сначала восстановите их. + + + + TrashPropertyDialog + + + Trash + Корзина + + + + item + элемент + + + + items + элементы + + + + Contains %1 %2 + Содержит %1 %2 + + + + UDiskListener + + + Failed to rename the label + Не удалось переименовать метку + + + + UnmountWorker + + + + + The device was not safely unmounted + Устройство не было безопасно извлечено + + + + The device was not safely removed + Устройство не было безопасно извлечено + + + + UserShareManager + + + Kindly Reminder + Пожалуйста Запомните + + + + Please firstly install samba to continue + Пожалуйста, сначала установите samba для продолжения + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + + + + + To protect the files, you cannot share this folder. + Для защиты файлов эту папку нельзя совместно использовать. + + + + Sharing failed + Ошибка предоставления общего доступа + + + + The computer name is too long + Слишком длинное имя компьютера + + + + You do not have permission to operate file/folder! + У вас нет разрешения на использование файла/папки! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Введите пароль для защиты общих папок + + + + Cancel + button + Отмена + + + + Confirm + button + Подтвердить + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sk.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sk.ts new file mode 100644 index 0000000..2244134 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sk.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + Nový priečinok + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + Zatvoriť všetko + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + Počítač + + + + Basic Info + Základné informácie + + + + Computer Name + Názov počítača + + + + Version + Verzia + + + + Type + Typ + + + + Processor + Procesor + + + + Memory + Pamäť + + + + Disk + Disk + + + + Bit + Trocha + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + Vyhľadávanie alebo zadanie adresy + + + + DFMAdvanceSearchBar + + + Search: + Vyhľadať: + + + + File Type: + + + + + File Size: + + + + + Time Modified: + Čas úpravy: + + + + Reset + + + + + All subdirectories + + + + + Current directory + Aktuálny priečinok + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + + + + + Yesterday + + + + + This week + + + + + Last week + + + + + This month + + + + + Last month + + + + + This year + + + + + Last year + + + + + DFMTagCrumbController + + + Tag information + Informácie štítku + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + Chyba oprávnení + + + + The action is denied + Akcia bola zamietnutá + + + + Failed to open the file + Nepodarilo sa otvoriť súbor + + + + Failed to read the file + Nepodarilo sa prečítať súbor + + + + Failed to write the file + Nepodarilo sa zapísať súbor + + + + Failed to create the directory + Nepodarilo sa vytvoriť priečinok + + + + Failed to delete the file + Nepodarilo sa odstrániť súbor + + + + Failed to move the file + Nepodarilo sa presunúť súbor + + + + Original file does not exist + Pôvodný súbor neexistuje + + + + Failed, file size must be less than 4GB + Zlyhanie, veľkosť súboru musí byť menšia ako 4 GB + + + + Not enough free space on the target disk + + + + + File integrity was damaged + Integrita súboru bola poškodená + + + + The target device is read only + Cieľové zariadenie je iba na čítanie + + + + Target folder is inside the source folder + Cieľový priečinok je vnútri zdrojovej zložky + + + + copy + Extra name added to new file name when used for file name. + kopírovať + + + + Failed to create the directory, cause: %1 + Nepodarilo sa vytvoriť adresár, pretože: %1 + + + + + Failed to open the file, cause: %1 + Nepodarilo sa otvoriť súbor, pretože: %1 + + + + Failed to read the file, cause: %1 + Nepodarilo sa prečítať súbor, pretože: %1 + + + + Failed to write the file, cause: %1 + Nepodarilo sa zapísať súbor, pretože: %1 + + + + File integrity was damaged, cause: %1 + Integrita súboru bola poškodená, pretože: %1 + + + + Failed to delete the file, cause: %1 + Nepodarilo sa odstrániť súbor, pretože: %1 + + + + Fail to create symlink, cause: %1 + Nepodarilo sa vytvoriť symbolický odkaz, pretože: %1 + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + %1 už existuje, chcete ho nahradiť? + + + + Cancel + Zrušiť + + + + Replace + Nahradiť + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + Meno + + + + + + Time modified + Čas úpravy + + + + Size + Veľkosť + + + + Type + Typ + + + + Time created + Čas vytvorenia + + + + + Last access + Posledný prístup + + + + Path + Cesta + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + (Reverzné) + + + + DFileViewHelper + + + Add tag "%1" + Pridať štítok "%1" + + + + DStatusBar + + + %1 item + %1 položka + + + + %1 items + %1 položky + + + + %1 item selected + %1 položka vybraná + + + + %1 items selected + %1 vybraných položiek + + + + %1 folder selected (contains %2) + %1 priečinok vybraný (obsahuje %2) + + + + %1 folders selected (contains %2) + %1 priečinky vybrané (obsahuje %2) + + + + %1 file selected (%2) + %1 súbor vybraný (%2) + + + + %1 files selected (%2) + %1 súbory vybrané (%2) + + + + %1 folder selected + %1 priečinok vybraný + + + + Filter + Filter + + + + Save as: + Uložiť ako: + + + + Loading... + Načítavanie... + + + + DTaskDialog + + + This action is not supported + Táto akcia nie je podporovaná + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + + + + + Data Disk + Data Partition + Data Disk + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + Operácia zlyhala! + + + + Target folder is inside the source folder! + Cieľový priečinok je vnútri zdrojovej zložky! + + + + + + + + + + + + + OK + OK + + + + Do you want to run %1 or display its content? + Chcete spustiť %1 alebo zobraziť jej obsah? + + + + It is an executable text file. + Je to spustiteľný textový súbor. + + + + + + + + + + + + + + Cancel + Zrušiť + + + + + + Run + Spustiť + + + + + Run in terminal + Spustiť v termináli + + + + Display + Zobrazenie + + + + It is an executable file. + Je to spustiteľný textový súbor. + + + + This file is not executable, do you want to add the execute permission and run? + + + + + "%1" already exists, please use another name. + "%1" už existuje, použite iné meno. + + + + + + + + Confirm + Potvrdiť + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + Natrvalo zmazať %1? + + + + Permanently delete %1 items? + Natrvalo zmazať %1 položky? + + + + Delete + Vymazať + + + + Empty + Prázdny + + + + Sorry, unable to locate your bookmark directory, remove it? + Bohužiaľ sa nepodarilo nájsť váš adresár záložiek, odstrániť? + + + + Remove + Odstrániť + + + + Name: + Názov: + + + + Force unmount + Násilné odpojenie + + + + %1 that this shortcut refers to has been changed or moved + %1, ktorý odkazujena tento odkaz bol zmenený alebo presunutý + + + + Do you want to delete this shortcut? + Chcete vymazať tento odkaz? + + + + Failed, file size must be less than 4GB. + Zlyhanie, veľkosť súboru musí byť menšia ako 4 GB. + + + + Fail to create symlink, cause: + Nepodarilo sa vytvoriť symlink, pretože: + + + + The selected files contain system file/directory, and it cannot be deleted + Vybrané súbory obsahujú systémový súbor/priečinok, a nemôžu byť zmazané + + + + + You do not have permission to operate file/folder! + Nemáte oprávnenie na spravovanie súboru/priečinka! + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Ľutujeme, nemáte povolenie na správu nasledujúceho %1 súboru/priečinka(kov)! + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + Zdieľaný priečinok nemôže byť pomenovaný podľa aktuálneho mena používateľa + + + + View + Zobrazenie + + + + Do you want to run %1? + Chcete spustiť %1? + + + + Are you sure you want to empty %1 item? + Naozaj chcete vymazať %1 položku? + + + + Are you sure you want to empty %1 items? + Naozaj chcete vymazať %1 položky? + + + + + This action cannot be undone + Túto akciu nie je možné obnoviť + + + + Disk is busy, cannot unmount now + Disk sa používa, zariadenie nie je možné odpojiť + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + Pripojiť oddiel %1 iba na čítanie + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + Disky v systéme Windows nebudú schopné čítať a zapisovať, ak v nastaveniach vypínania zvolíte možnosť "Zapnúť rýchle spustenie (odporúčané)" + + + + Please restore by the following steps to normally access Windows disk + Prosím obnovte pomocou nasledujúcich krokov normálny prístup k disku Windows + + + + 1. Reboot to enter Windows + 1. Reštartujte, ak chcete vstúpiť do systému Windows + + + 3. Reboot and enter deepin + 3. Reštartujte a vstúpte do deepinu + + + + Reboot + Reštart + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + Názov súboru + + + + Format + Formát + + + + Cancel + Zrušiť + + + + Save + Uložiť + + + + Open + Otvoriť + + + + Save File + Uložiť súbor + + + + Open File + Otvoriť súbor + + + + FileJob + + + copy + kopírovať + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + Základné + + + + + + Open behavior + Otvorené správanie + + + + + + Always open folder in new window + Vždy otvárať priečinok v novom okne + + + + + + Open file: + Otvoriť súbor: + + + + + + Click + Klik + + + + + + Double click + Dvojklik + + + + + + New window and tab + Nové okno a karta + + + + + + Open from default window: + Otvoriť z predvoleného okna: + + + + + + + + + Computer + Počítač + + + + + + + + + Home + Domov + + + + + + + + + Desktop + Pracovná plocha + + + + + + + + + Videos + Videá + + + + + + + + + Music + Hudba + + + + + + + + + Pictures + Obrázky + + + + + + + + + Documents + Dokumenty + + + + + + + + + Downloads + Stiahnuté + + + + + + Open in new tab: + Otvoriť na novej karte: + + + + + + Current Directory + Aktuálny priečinok + + + + + + View + Zobrazenie + + + + + + Default size: + Predvolená veľkosť: + + + + + + Extra small + Extra malé + + + + + + Small + Malé + + + + + + Medium + Stredné + + + + + + Large + Veľké + + + + + + Extra large + Extra veľké + + + + + + Default view: + Predvolené zobrazenie: + + + + + + Icon + Ikona + + + + + + List + Zoznam + + + + + + Hidden files + Skryté súbory + + + + + + Show hidden files + Zobraziť skryté súbory + + + + + + Hide file extension when rename + Skryť príponu súboru pri premenovaní + + + + + + Advanced + Pokročilé + + + + + + Index + Indexovanie + + + + + + Auto index internal disk + Automatický index vnútorného disku + + + + + + Index external storage device after connected to computer + Indexovať externé pamäťové zariadenie po pripojení k počítaču + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + Iný + + + + + + Hide system disk + Skryť systémový disk + + + + + + Show hidden files in search results + Zobraziť skryté súbory vo výsledkoch vyhľadávania + + + + + + Display recent file entry in left panel + Zobraziť poslednú položku súboru v ľavom paneli + + + + + + Preview + Náhľad + + + + + Compress file preview + Náhľad skomprimovaného súboru + + + + + + Text preview + Náhľad textu + + + + + + Document preview + Náhľad dokumentu + + + + + + Image preview + Náhľad obrázku + + + + + + Video preview + Náhľad videa + + + + + + Mount + Pripojiť + + + + + + Auto mount + Automaticky pripojiť + + + + + + Open after auto mount + Otvoriť po automatickom pripojení + + + + + + Dialog + Dialóg + + + Use the file chooser dialog of Deepin File Manager + Použite dialóg pre výber súborov v programe Deepin Manažér súborov + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + Disk je pripojený používateľom "%1", nemôžete ho odpojiť. + + + + + + + + Confirm + Potvrdiť + + + + + Cannot find the mounting device + Nemožno nájsť pripojené zariadenie + + + + Cannot unmount the device + Zariadenie sa nedá odpojiť + + + + Cannot eject the device "%1" + Nemožno vysunúť zariadenie "%1" + + + + MergedDesktopController + + + + Pictures + Obrázky + + + + + Music + Hudba + + + + + Applications + Aplikácie + + + + + Videos + Videá + + + + + Documents + Dokumenty + + + + + Others + Iné + + + + MimeTypeDisplayManager + + + + Directory + Adresár + + + + + + Application + Aplikácia + + + + + + Video + Video + + + + + + Audio + Zvuk + + + + + + Image + Obrázok + + + + + Archive + Archív + + + + + + Text + Text + + + + + Executable + Spustiteľný + + + + + Backup file + + + + + + Unknown + Neznámy + + + + MountAskPasswordDialog + + + Cancel + Zrušiť + + + + Connect + Pripojiť + + + + Log in as + Prihlásiť sa ako + + + + Anonymous + Anonymný + + + + Registered user + Registrovaný užívateľ + + + + Username + Užívateľské meno + + + + Domain + Doména + + + + Password + Heslo + + + + Remember password + Zapamätať heslo + + + + MountSecretDiskAskPasswordDialog + + + Cancel + Zrušiť + + + + Unlock + + + + + Input password to decrypt the disk + Zadajte heslo na dešifrovanie disku + + + + MoveCopyTaskWidget + + Skip + Preskočiť + + + Keep both + Ponechať obe + + + Replace + Nahradiť + + + Do not ask again + Nepýtaj sa znova + + + merge + zlúčiť + + + Copying %1 + Kopírujem %1 + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + Skopírovať do %2 + + + Moving %1 + Presúvam %1 + + + Move to %2 + Presunúť do %2 + + + Restoring %1 + Obnovujem %1 + + + Restore to %2 + Obnoviť na %2 + + + Deleting %1 + Odstraňujem %1 + + + Trashing %1 + Šrotujem %1 + + + Calculating space, please wait + Prepočítavam miesto, čakajte prosím + + + File named %1 already exists in target folder + Súbor s názvom %1 už v cieľovom priečinku existuje + + + Original path %1 target path %2 + Pôvodná cesta %1 cieľová cesta %2 + + + Retry + Skúsiť znova + + + Time modified:%1 + Čas úpravy:%1 + + + Original folder + Pôvodný priečinok + + + Original file + Pôvodný súbor + + + Target folder + Cieľový priečinok + + + Target file + Cieľový súbor + + + Contains:%1 + Obsahuje:%1 + + + Size:%1 + Veľkosť:%1 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Naozaj chcete úplne vymazať %1? + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + Naozaj chcete úplne vymazať %1 súbory? + + + + Cancel + Zrušiť + + + + Delete + Vymazať + + + + OpenWithDialog + + + Open with + Otvoriť s + + + + Add other programs + Pridať ďalšie programy + + + + Set as default + Nastaviť ako predvolené + + + + Cancel + Zrušiť + + + + Confirm + + + + + Recommended Applications + Odporúčané aplikácie + + + + Other Applications + Ďalšie aplikácie + + + + PathManager + + + Home + Domov + + + + Desktop + Pracovná plocha + + + + Videos + Videá + + + + Music + Hudba + + + + Pictures + Obrázky + + + + Documents + Dokumenty + + + + Downloads + Stiahnuté + + + + + Trash + Kôš + + + + + System Disk + Systémový disk + + + + Computers in LAN + Počítače v LAN + + + + My Shares + Moje zdieľania + + + + Computer + Počítač + + + + Recent + Posledné + + + + PropertyDialog + + + Basic info + Základné informácie + + + + Open with + Otvoriť s + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + Umožňiť spustiť ako program + + + + QObject + + + + + Size + Veľkosť + + + + + + Contains + Obsahuje + + + + + + Type + Typ + + + + + + + Time modified + Čas úpravy + + + + Free space + Voľný priestor + + + + Total space + Celkový priestor + + + + Access denied + Prístup zamietnutý + + + + + Executable + Spustiteľný + + + + + Write only + Iba na zápis + + + + + Read only + Iba na čítanie + + + + + Read-write + Čítanie-zápis + + + + Others + Iné + + + + Owner + Vlastník + + + + Device type + + + + + File system + + + + + Group + Skupina + + + + + + Open + Otvoriť + + + + + Size: %1 + Veľkosť: %1 + + + + Type: %1 + Typ: %1 + + + + Size: 0 + Veľkosť: 0 + + + + Items: %1 + Položky: %1 + + + + + + + + + + + Open in new window + Otvoriť v novom okne + + + + + + + + + + + Open in new tab + Otvoriť v novej karte + + + + Open with + Otvoriť s + + + + Compress + Kompresia + + + + Extract + Extrahovať + + + + Extract here + Extrahovať sem + + + + Cut + Vystrihnúť + + + + Copy + Kopírovať + + + + Paste + Prilepiť + + + + + + + + + + Rename + Premenovať + + + + + + Remove + Odstrániť + + + + Create link + Vytvoriť odkaz + + + + Send to desktop + Odoslať na pracovnú plochu + + + + Send to + Odoslať na + + + + Add to bookmark + Pridať do záložiek + + + + + + + Properties + Vlastnosti + + + + New folder + Nový priečinok + + + + New window + Nové okno + + + + Select all + Vybrať všetko + + + + + Clear recent history + Vyčistiť nedávnu históriu + + + + + + Empty Trash + Prázdny kôš + + + + Display as + Zobraziť ako + + + + Sort by + Zoradiť podľa + + + + New document + Nový dokument + + + + + Time created + Čas vytvorenia + + + + Log out and unmount + Odhlásiť sa a odpojiť + + + + + + Source path + Zdrojová cesta + + + + Share folder + Zdieľaný priečinok + + + + Cancel sharing + Zrušiť zdieľanie + + + + Connect to Server + + + + + Set share password + Nastaviť kód zdieľania + + + + Format + Formátovanie + + + + Tag information + Informácie štítku + + + + Open in new window as admin + Otvoriť v novom okne ako administrátor + + + + Select default program + Výber predvoleného programu + + + + Open file location + Otvoriť umiestnenie súboru + + + + Remove bookmark + Odstrániť záložku + + + + + + Delete + Vymazať + + + + Office Text + Kancelársky textový + + + + Spreadsheets + Tabuľkový + + + + Plain Text + Jednoduchý textový + + + + Open in terminal + Otvoriť v termináli + + + + Restore + Obnoviť + + + + Restore all + Obnoviť všetko + + + + File Vault + + + + + Auto mount + Automaticky pripojiť + + + + Open after auto mount + Otvoriť po automatickom pripojení + + + + + Mount + Pripojiť + + + + + Unmount + Odpojiť + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + Vysunúť + + + + Safely Remove + Bezpečne odstrániť + + + + + Name + Meno + + + + Settings + Nastavenia + + + + Exit + Ukončiť + + + + Icon + Ikona + + + + List + Zoznam + + + + Extend + Rozšíriť + + + + Set as wallpaper + Nastaviť ako pozadie + + + + + + + Local disk + Lokálny disk + + + + + Removable disk + Odpojiteľný disk + + + + + + Network shared directory + Sieťový zdieľaný adresár + + + + + Android mobile device + Android mobilné zariadenie + + + + + Apple mobile device + Apple mobilné zariadenie + + + + + Camera + Kamera + + + + + DVD + DVD + + + + + Unknown device + Neznáme zariadenie + + + + + + %1 item + %1 položky + + + + + + %1 items + %1 vybraných položiek + + + + Shortcut + Odkaz + + + + Create symlink + Vytvoriť symlink + + + + Path + Cesta + + + + + + Time deleted + Čas vymazania + + + + Loading... + Nahrávanie... + + + + File has been moved or deleted + Súbor bol presunutý alebo vymazaný + + + + + + You do not have permission to access this folder + Nemáte povolenie na prístup do tohto priečinka + + + + + + + Folder is empty + Priečinok je prázdny + + + + Path + SearchFileInfo + Cesta + + + + Searching... + Vyhľadávanie... + + + + No results + Žiadne výsledky + + + + Source Path + TrashFileInfo + Zdrojová cesta + + + + Document + Dokument + + + + Spreadsheet + Tabuľka + + + + + Presentation + Prezentácia + + + + Text + Text + + + + 1 task in progress + 1 úloha prebieha + + + + %1 tasks in progress + %1 úlohy prebiehajú + + + + Mode: + Režim: + + + + + Replace Text + Nahradiť text + + + + + Add Text + Pridať text + + + + + Custom Text + Vlastný text + + + + Find: + Nájsť: + + + + Replace: + Nahradiť: + + + + + Optional + Voliteľný + + + + Add: + Pridať: + + + + Location: + Umiestnenie: + + + + File name: + Názov súboru: + + + + +SN: + +SN: + + + + + + + + + + Required + Požadované + + + + + Before file name + Pred názvom súboru + + + + + After file name + Za názvom súboru + + + + Find + Nájsť + + + + Replace + Nahradiť + + + + Add + Pridať + + + + + + Location + Umiestnenie + + + + File name + Názov súboru + + + + Dimension + + + + + Duration + + + + + +SN + +SN + + + + Tips: Sort by selected file order + Tipy: Zoradiť podľa vybraného poradia súborov + + + + + + Cancel + Zrušiť + + + + Rename %1 Files + Premenovať %1 súborov + + + + Multiple Files + Viaceré súbory + + + + Basic info + Základné informácie + + + + Total size + Celková veľkosť + + + + Number of files + Počet súborov + + + + %1 file(s), %2 folder(s) + %1 súbor(y), %2 priečinok(y) + + + + + + Time accessed + + + + + Orange + Oranžová + + + + Red + Červená + + + + Purple + Fialová + + + + Navy-blue + Námornícka modrá + + + + Azure + Azurová + + + + Green + Zelená + + + + Yellow + Žltá + + + + Gray + Sivá + + + + Input tag info, such as work, family. A comma is used between two tags. + Vstupné informácie o štítkoch, napríklad práca, rodina. Medzi dve štítky sa používa čiarka. + + + + Bookmarks + Záložky + + + + Erase + + + + + + Copy path + + + + + + Edit address + + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + Zdieľať tento priečinok + + + + Share name: + Názov zdieľania: + + + + Permission: + Oprávnenie: + + + + Read and write + Čítanie a zápis + + + + Read only + Iba na čítanie + + + + Anonymous: + Anonymný: + + + + Not allow + Nepovoliť + + + + Allow + Povoliť + + + + Shortcut + + + Item + Položka + + + + Select to the first item + Označiť na prvú položku + + + + Shift + Home + Shift + Home + + + + Select to the last item + Označiť na poslednú položku + + + + Shift + End + Shift + End + + + + Select leftwards + Označiť doľava + + + + Shift + Left + Shift + šípka Vľavo + + + + Select rightwards + Označiť doprava + + + + Shift + Right + Shift + šípka Vpravo + + + + Select to upper row + Označiť z horného riadka + + + + Shift + Up + Shift + šípka Hore + + + + Select to lower row + Označiť zo spodného riadka + + + + Shift + Down + Shift + šípka Dole + + + + Open + Otvoriť + + + + Ctrl + Down + Ctrl + šípka Dole + + + + To parent directory + Do rodičovského priečinka + + + + Ctrl + Up + Ctrl + šípka Hore + + + + Permanently delete + Trvalé zmazanie + + + + Shift + Delete + Shift + Delete + + + + Delete file + Vymazať súbor + + + + Delete + Vymazať + + + + Select all + Vybrať všetko + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + Kopírovať + + + + Cut + Vystrihnúť + + + + Paste + Prilepiť + + + + Rename + Premenovať + + + + F2 + F2 + + + + New/Search + Nový/Hľadať + + + + New window + Nové okno + + + + New folder + Nový priečinok + + + + + Search + Vyhľadať + + + + New tab + Nová karta + + + + View + Zobraziť + + + + Item information + Informácie o položke + + + + Help + Pomoc + + + + F1 + F1 + + + + Keyboard shortcuts + Klávesové skratky + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Prepnúť stav zobrazenia + + + + Hide item + Skryť položku + + + + Input in address bar + Vložiť do adresného riadka + + + + Switch to icon view + Prepnúť na zobrazenie ikony + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Prepnúť na zobrazenie zoznamu + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Iné + + + + Close + Zatvoriť + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Zatvoriť aktuálnu kartu + + + + Back + Späť + + + + Alt + Left + Alt + šípka Vľavo + + + + Alt + Right + Alt + šípka Vpravo + + + + Switch to next tab + Prepnúť na ďalšiu kartu + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Prepnúť na predchádzajúcu kartu + + + + Next file + Ďalší súbor + + + + Tab + Tabulátor + + + + Previous file + Predchádzajúci súbor + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Prepnite na kartu podľa zadaného čísla medzi 1 až 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Dopredu + + + + TrashPropertyDialog + + + Trash + Kôš + + + + item + Položka + + + + items + Položky + + + + Contains %1 %2 + Obsahuje %1 %2 + + + + UDiskListener + + + Failed to rename the label + Značku sa nepodarilo premenovať + + + + UserShareManager + + + Kindly Reminder + Láskavé pripomenutie + + + + Please firstly install samba to continue + Najskôr nainštalujte sambu a potom pokračujte + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + Zrušiť + + + + Confirm + Potvrdiť + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sl.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sl.ts new file mode 100644 index 0000000..0cf28e2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sl.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Nova mapa + + + + Mounting device error + Napaka ob priklopu naprave + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Posenetek diska je okvarjen. Ne morem ga priklopiti. Najprej izbrišite disk + + + + Mount error: unsupported image format + Napaka pri priklapljanju: ni podprta oblika posnetka + + + + + The device was not safely removed + Naprava ni bila varno odstranjena + + + + + Click "Safely Remove" and then disconnect it next time + Klikni "Varno odstrani" in nato odstranite + + + + The device was not ejected + Naprava ni bila varno odstranjena + + + + Disk is busy, cannot eject now + Disk deluje in ga trenutno ni mogoče varno odstraniti + + + + Authentication timed out + Čas za overitev je potekel + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Blutetooth prenos podatkov + + + + File Transfer Successful + Prenos datoteke je uspel + + + + File Transfer Failed + Prenos datoteke ni uspel + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Pošiljanje datotek do "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Pošiljanje datotek do "<b style="font-weight: 550;">%1</b>" ni uspelo + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Pošiljanje do "<b style="font-weight: 550;">%1</b>" je uspelo + + + + Select a Bluetooth device to receive files + Izberite Blutetooth napravo za sprejemanje datotek + + + + Cannot find the connected Bluetooth device + Ne morem najti priključene bluetooth naprave + + + + Waiting to be received... + Čakam na prejem... + + + + Go to Bluetooth Settings + Pojdi na bluetooth nastavitve + + + + %1/%2 Sent + %1/%2 poslano + + + + Error: the Bluetooth device is disconnected + Napaka: bluetooth naprava je odklopljena + + + + Unable to send the file more than 2 GB + Ni mogoče poslati datotek večjih od 2GB + + + + Unable to send 0 KB files + Ni mogoče poslati 0kB velikih datotek + + + + File doesn't exist + Datoteka ne obstaja + + + + Next + button + Naprej + + + + Cancel + button + Prekini + + + + Done + button + Končano + + + + Retry + button + Znova + + + + OK + button + V redu + + + + File sending request timed out + Zahteva za pošiljanje datoteke je časovno potekla + + + + The service is busy and unable to process the request + Storitev je zasedena in ne more obdelati zahtevanega procesa + + + + BurnOptDialog + + + Device error + Napaka naprave + + + + Optical device %1 doesn't exist + Optični pogon %1 ne obstaja + + + + Advanced settings + Napredne nastavitve + + + + File system: + Datotečni sistem: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (za Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (za Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Združljivo z Windows CD/DVD načinom) + + + + ISO9660 Only + zgolj ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Zapri vse + + + + Total size: %1, %2 files + Skupna velikost: %1, %2 datotek + + + + ComputerModel + + + Double click to open it + + + + + My Directories + Moje mape + + + + Disks + Diski + + + + File Vault + Trezor datotek + + + + Quick Access + + + + + ComputerPropertyDialog + + + Computer + Računalnik + + + + Basic Info + Osnovne informacije + + + + + Computer Name + Ime računalnika + + + + + Edition + Izdaja + + + + + + Version + Različica + + + + + Type + Vrsta + + + + + + Processor + Procesor + + + + + + Memory + Pomnilnik + + + + + + + Bit + Bit + + + + + Available + Na voljo + + + + Obtaining... + Pridobivam... + + + + ConnectToServerDialog + + + Connect to Server + Poveži s strežnikom + + + + Cancel + button + Prekini + + + + Connect + button + Poveži + + + + My Favorites: + Moji priljubljeni: + + + + + Clear History + Počisti zgodovino + + + + DFMAddressBar + + + Search or enter address + Poišči ali vnesi naslov + + + + DFMAdvanceSearchBar + + + Search: + Iskanje: + + + + File Type: + Vrsta datoteke: + + + + File Size: + Velikost datoteke: + + + + Time Modified: + Čas spremembe: + + + + Time Accessed: + Čas dostopa: + + + + Time Created: + Čas stvaritve: + + + + Reset + Ponastavi + + + + All subdirectories + Vse podmape + + + + Current directory + Trenutna mapa + + + + 0 ~ 100 KB + 0 ~ 100 kB + + + + 100 KB ~ 1 MB + 100 kB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Danes + + + + Yesterday + Včeraj + + + + This week + Ta teden + + + + Last week + Prejšnji teden + + + + This month + Ta mesec + + + + Last month + Prejšnji mesec + + + + This year + To leto + + + + Last year + Prejšnje leto + + + + DFMOpticalMediaWidget + + + + No files to burn + Ni datotek za zapisovanje + + + + Unable to burn. Not enough free space on the target disk. + Ne morem zapisati. Na ciljnem disku ni dovolj prostora. + + + + %1 burning is not supported + %1 zapisovanje ni podprto + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. Ni %1 disk; +2. Datotečni sistem te različice še ne podpira dodajanja datotek. + + + + DFMTagCrumbController + + + Tag information + Podatki oznak + + + + DFMTagWidget + + + Tag + Oznaka + + + + DFMTaskWidget + + + Do not ask again + Ne sprašuje več + + + + Syncing data + Sinhronizacija podatkov + + + + Please wait + Počakajte + + + + + Time modified: %1 + Čas spremembe: %1 + + + + + Contains: %1 + Vsebuje: %1 + + + + + Size: %1 + Velikost: %1 + + + + Original folder + Izvorna mapa + + + + Keep both + button + Ohrani oboje + + + + Skip + button + Preskoči + + + + Replace + button + Zamenjaj + + + + Retry + button + Znova + + + + Original file + Izvirnik datoteke + + + + Target folder + Ciljna mapa + + + + Target file + Ciljna datoteka + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Šifiraj trezor datotek + + + + Click 'Encrypt' and input the user password. + Kliknite 'Šifriraj' in vnesite uporabniško geslo. + + + + Encrypting... + Šifriranje + + + + + + + Encrypt + Šifriraj + + + + Failed to create file vault: %1 + Trezorja datotek ni bilo mogoče ustvariti: %1 + + + + OK + V redu + + + + The setup is complete + Namesitiev je končana + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + + + + + Keep the key safe to retrieve the vault password later + + + + + Save to default path + + + + + Save to other locations + + + + + No permission, please reselect + + + + + Select a path + + + + + Next + Naprej + + + + The default path is invisible to other users, and the path information will not be shown. + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Obnovitveni ključ + + + + Generate a recovery key in case that you forgot the password + Ustvari obnovitveni ključ za primer pozabljenega gesla + + + + Key + Ključ + + + + QR code + QR koda + + + + Scan QR code and save the key to another device + Skeniraj QR kodo in shrani ključ na drugo napravo + + + + Next + Naprej + + + + Recovery Key: + Obnovitveni ključ: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Določi geslo trezorja + + + + Method + Metoda + + + + Manual + Ročno + + + + Password + Geslo + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 znakov, vsebuje A-Z, a-z, 0-9, in simbole + + + + Repeat password + Ponovite geslo + + + + Input the password again + Znova vnesite geslo + + + + Password hint + Namig za geslo + + + + Optional + Neobvezno + + + + Next + Naslednja + + + + + Passwords do not match + Gesli se ne ujemata + + + + DFMVaultActiveStartView + + + File Vault + Trezor datotek + + + + Create your secure private space + Ustvarite svoj varni zasebni prostor + + + + Advanced encryption technology + Napredna tehnologija šifriranja + + + + Convenient and easy to use + Priročno in enostavno za rabo + + + + Create + Ustvari + + + + DFMVaultFileView + + + Cannot open this path + + + + + Hint + + + + + OK + V redu + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Odkleni s ključem + + + + Failed to unlock file vault + Odklepanje trezorja datotek ni bilo uspešno + + + + OK + V redu + + + + Input the 32-digit recovery key + Vnesite 32-mestni obnovitveni ključ + + + + Cancel + button + Prekini + + + + Unlock + button + Odkleni + + + + Wrong recovery key + Napačen obnovitveni ključ + + + + DFMVaultRemoveByPasswordView + + + Password + Geslo + + + + Password hint: %1 + Namig za geslo: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Vnesite 32-mestni obnovitveni ključ + + + + DFMVaultRemovePages + + + Delete File Vault + Izbriši trezor datotek + + + + Once deleted, the files in it will be permanently deleted + Ko je zbrisan, so podatki v njemu za vedno izgubljeni + + + + Use Key + Uporabi ključ + + + + Cancel + button + Prekini + + + + Use Key + button + Uporabi ključ + + + + Delete + button + Izbriši + + + + + OK + button + V redu + + + + Use Password + Uporabi geslo + + + + Wrong password + Napačno geslo + + + + Wrong recovery key + Napačen obnovitveni ključ + + + + Failed to delete file vault + Trezorja datotek ni bilo mogoče izbrisati + + + + Deleted successfully + Upešeno izbrisano + + + + Failed to delete + Brisanje ni uspelo + + + + Removing... + Odstranjevanje... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + + + + + Verification failed + + + + + + Select a path + + + + + + Retrieve Password + + + + + By key in the default path + + + + + By key in the specified path + + + + + Verification Successful + + + + + Keep it safe + + + + + Back + button + Nazaj + + + + Verify Key + button + + + + + Go to Unlock + button + + + + + Close + button + Zapri + + + + Vault password: %1 + + + + + DFMVaultUnlockPages + + + Unlock File Vault + Odkleni trezor datotek + + + + Forgot password? + + + + + Password hint: %1 + Namig za geslo: %1 + + + + Failed to unlock file vault + Odklepanje trezorja datotek ni bilo uspešno + + + + Cancel + button + Prekini + + + + Password + Geslo + + + + Unlock + button + Odkleni + + + + Please try again %1 minutes later + + + + + Wrong password, please try again %1 minutes later + + + + + Wrong password, one chance left + + + + + Wrong password, %1 chances left + + + + + Wrong password + Napačno geslo + + + + OK + button + V redu + + + + DFileCopyMoveJob + + + Permission error + Napaka zaradi dovoljenj + + + + The action is denied + Dejanje ni odobreno + + + + Failed to open the file + Datoteke ni bilo mogoče odpreti + + + + Failed to read the file + Datoteke ni bilo mogoče prebrati + + + + Failed to write the file + Datotrke ni bilo mogoče zapisati + + + + Failed to create the directory + Datoteke ni bilo mogoče ustvariti + + + + Failed to delete the file + Datoteke ni bilo mogoče izbrisati + + + + Failed to move the file + Datoteke ni bilo mogoče premakniti + + + + Original file does not exist + Izvirnik datoteke ne obstaja + + + + Failed, file size must be less than 4GB + Napaka - velikost mora biti manjša od 4GB + + + + Not enough free space on the target disk + Na ciljnjem disku ni dovolj prostora + + + + File integrity was damaged + Integriteta datoteke je bila poškodovana + + + + The target device is read only + Ciljna naprava je zgolj bralna + + + + Target folder is inside the source folder + Ciljna mapa se nahaja v izvorni mapi + + + + The action is not supported + Dejanje ni podprto + + + + You do not have permission to traverse files in it + Nimate dovoljenja za prehod preko datotek v njej + + + + Failed to position the file pointer! + + + + + copy + Extra name added to new file name when used for file name. + kopiraj + + + + Failed to open the directory, cause: file name too long + Mape ni bilo mogoče odpreti: predolgo ime + + + + + Failed to open the file, cause: file name too long + Datoteke ni bilo mogoče odpreti: predolgo ime + + + + + Failed to write the file, cause: + Napaka pri zapisovanju datoteke. Razlog: + + + + Failed to position the file pointer, cause: %1 + + + + + Syncing data + Sinhronizacija podatkov + + + + Please wait + Počakajte + + + + Failed to create the directory, cause: %1 + Mape ni bilo mogoče ustvariti, razlog: %1 + + + + + + + + Failed to open the file, cause: %1 + Datoteke ni bilo mogoče odpreti, razlog: %1 + + + + + + + Failed to open the file, cause: Permission denied + Datoteke ni bilo mogoče odpreti: ni dovoljenja + + + + + Failed to read the file, cause: %1 + Datoteke ni bilo mogoče prebrati: %1 + + + + + + + Failed to write the file, cause: %1 + Datoteke ni bilo mogoče zapisati: %1 + + + + + File integrity was damaged, cause: %1 + Integriteta datoteke je bila poškodovana: %1 + + + + Failed to open the file, cause: + Datoteke ni bilo mogoče odpreti, razlog: %1 + + + + Failed to read the file, cause: + Datoteke ni bilo mogoče prebrati: %1 + + + + Failed to delete the file, cause: %1 + Datoteke ni bilo mogoče izbrisati: %1 + + + + Fail to create symlink, cause: %1 + Simbolične povezave ni bilo mogoče ustvariti: %1 + + + + DFileDialog + + + + Save + button + Shrani + + + + + Cancel + button + Prekini + + + + Confirm + button + Potrdi + + + + %1 already exists, do you want to replace it? + %1 že obstaja, hočete zamenjati? + + + + Replace + button + Zamenjaj + + + + Open + button + Odpri + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Datoteka bo skrita, če se začne s piko (.). Bi jo radi skrili? + + + + DFileManagerWindow + + + Trash + Koš + + + + Empty + Prazen + + + + DFileSystemModel + + + + Name + Naziv + + + + + + Time modified + Čas spremembe + + + + Size + Velikost + + + + Type + Vrsta + + + + Time created + Čas nastanka + + + + + Last access + Zadnji dostop + + + + + + + Path + Pot + + + + DFileView + + + Disc mount error + Napaka pri priklapljanju diska + + + + The disc is in use, please end the running process and remount the disc. + Disk je v rabi. Končajte proces, ki se izvaja in ponovno priklopite disk. + + + + Mounting failed + Priklop ni uspel + + + + (Reverse) + (Obratno) + + + + DFileViewHelper + + + Add tag "%1" + Dodaj oznako "%1" + + + + DStatusBar + + + %1 item + %1 element + + + + %1 items + %1 elementov + + + + %1 item selected + %1 izbran element + + + + %1 items selected + %1 izbranih elementov + + + + %1 folder selected (contains %2) + %1 izbrana mapa (vsebuje %2) + + + + %1 folders selected (contains %2) + %1 izbranih map (vsebuje %2) + + + + %1 file selected (%2) + %1 izbrana datoteka (%2) + + + + %1 files selected (%2) + %1 izbranih datotek (%2) + + + + %1 folder selected + %1 izbrana mapa + + + + Filter + Filter + + + + Save as: + Shrani kot: + + + + Loading... + Nalagam... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Brisanje diska %1, počakajte... + + + + Burning disc %1, please wait... + Zapisovanje diska %1, počakajte... + + + + Writing data... + Zapisovanje podatkov... + + + + Verifying data... + Preverjanje podatkov... + + + + Copying %1 + Kopiranje %1 + + + + + + to %2 + v %2 + + + + %1 already exists in target folder + %1 že obstaja v ciljni mapi + + + + Original path %1 Target path %2 + Izvorna pot %1, ciljna pot %2 + + + + Merge + button + Združi + + + + Replace + button + Zamenjaj + + + + Moving %1 + Premik %1 + + + + Removing file vault, please try later + Odstranjevanje trezorja datotek, poskusite kasneje + + + + Restoring %1 + Obnavljanje %1 + + + + Deleting %1 + Brisanje %1 + + + + Trashing %1 + V koš %1 + + + + Calculating space, please wait + Izračun prostora, počakajte + + + + DUMountManager + + + + Authentication timed out + Čas za overitev je potekel + + + + + + Disk is busy, cannot unmount now + Disk je v rabi. Trenutno ga ni mogoče odklopiti + + + + Disk is busy, cannot eject now + Disk deluje in ga trenutno ni mogoče varno odstraniti + + + + The device is busy, cannot eject now + Naprava je v rabi in je trenutno ni mogoče izvreči + + + + + + The device is busy, cannot remove now + Naprava je v rabi n je trenutno ni mogoče odstraniti + + + + DeepinStorage + + + + + %1 Volume + %1 Glasnost + + + + Data Disk + Data Partition + Podatkovni disk + + + + %1 Drive + %1 pogon + + + + Blank %1 Disc + Prazen %1 disk + + + + %1 Encrypted + %1 šifriran + + + + DialogManager + + + + + + Operation failed! + Operacija ni uspela! + + + + Target folder is inside the source folder! + Ciljna mapa je znotraj izvorne mape! + + + + Do you want to run %1 or display its content? + Želite zagnati %1 ali prikazati pripadajočo vsebino? + + + + It is an executable text file. + To je izvršljiva besedilna datoteka. + + + + It is an executable file. + To je izvršljiva datoteka. + + + + This file is not executable, do you want to add the execute permission and run? + Ta datoteka ni izvršljiva. Bi radi dodali dovoljenje za izvedbo in jo zagnali? + + + + "%1" already exists, please use another name. + "%1" že obstaja. Uporabite drug naziv. + + + + The file name must not contain two dots (..) + Ime datoteke mora vsebovati dve piki (..) + + + + Device or resource busy + + + + + Are you sure you want to erase all data on the disc? + Ali ste prepričani, da želite izbrisati vse podatke na disku? + + + + How do you want to use this disc? + Kako želite uporabljati ta disk? + + + + Disc erase failed + Brisanje diska ni uspelo + + + + Burn process failed + Zapisovanje ni uspelo + + + + %1: %2 + %1: %2 + + + + Show details + Prikaži podrobnosti + + + + Hide details + Skrij podrobnosti + + + + Error + Napaka + + + + Permanently delete %1? + Trajno izbrišem %1? + + + + Permanently delete %1 items? + Trajno izbrišem %1 elementov? + + + + Empty + Izprazni + + + + Do you want to delete %1? + Želite izbrisati %1? + + + + Do you want to delete the selected %1 items? + Ali žeite izbrisati izbranih %1 predmetov? + + + + Sorry, unable to locate your bookmark directory, remove it? + Žal ni bilo mogoče najti mape z zaznamki. Jo odstranim? + + + + Name: + Ime: + + + + %1 that this shortcut refers to has been changed or moved + %1, kamor kaže ta bližnjica, je bil spremenjen ali premaknjen + + + + Do you want to delete this shortcut? + Želite izbrisati to bližnjico? + + + + Failed, file size must be less than 4GB. + Ni uspelo. Velikost datoteke mora biti manjša od 4GB. + + + + Fail to create symlink, cause: + Simbolna povezava ni bila ustvarjena: + + + + The selected files contain system file/directory, and it cannot be deleted + Izbrane datoteke vsebujejo sistemske datoteke/mape, zato jih ni mogoče izbrisati + + + + Unable to find the original file + Ne morem najti izvirnih datotek + + + + + You do not have permission to operate file/folder! + Nimate dovoljenja, da bi upravljali z datoteko/mapo! + + + + Failed to restore %1 file, the source file does not exist + Obnova %1 ni uspela. Izvorna datoteka ne obstaja + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Žal nimate dovoljenja za upravljanje z navedenimi %1 datotekami/mapami! + + + + Unable to access %1 + Dostop do %1 ni mogoč + + + + + Sending files now, please try later + Trenutno pošiljam datoteke. Poskusite kasneje + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Za dostop do naprave morate najprej formatirati disk. Jo želite zdaj formatirati? + + + + Scanning the device, stop it? + Preverjanje naprave. Zaustavim? + + + + Share folder can't be named after the current username + Deljene mape ne morete imenovati po trenutnem uporabniku + + + + Do you want to run %1? + Hočete zagnati %1? + + + + Burn image + button + Zapiši posnetek + + + + Burn files + button + Zapiši datoteke + + + + Are you sure you want to empty %1 item? + Ali ste prepričani, da želite počistiti %1 predmet? + + + + Are you sure you want to empty %1 items? + Ali ste prepričani, da želite počistiti %1 predmetov? + + + + + This action cannot be undone + Tega dejanja ni mogoče razveljaviti + + + + + + + + + + + + + + OK + button + V redu + + + + + + + + + + + + + + + Cancel + button + Prekini + + + + + + Run + button + Zaženi + + + + + Run in terminal + button + Zaženi v terminalu + + + + Display + button + Prikaži + + + + + + + + + + + Confirm + button + Potrdi + + + + Erase + button + Izbriši + + + + Data verification failed + Preverjanje podatkov ni uspelo + + + + Show details + button + Prikaži podrobnosti + + + + + Delete + button + Izbriši + + + + Remove + button + Odstrani + + + + Disk is busy, cannot unmount now + Disk je v rabi. Trenutno ga ni mogoče odklopiti + + + + Force unmount + button + Prisiljen odklop + + + + Unable to copy. Not enough free space on the target disk. + Kopiranje ni mogoče. Na ciljnem disku ni dovolj prostora. + + + + Failed to restore %1 file, the target folder is read-only + Neuspešno obnavljanje %1 datoteke. Ciljna mapa je zgolj bralna + + + + Failed to restore %1 files, the target folder is read-only + Neuspešno obnavljanje %1 datotek. Ciljna mapa je zgolj bralna + + + + Failed to restore %1 files, the source files do not exist + Neuspešno obnavljanje %1 datoteke. Izvirniki datotek ne obstajajo + + + + Format + button + Format + + + + Stop + button + Zaustavi + + + + FileController + + + + + + Unable to find the original file + Ne morem najti izvirnih datotek + + + + + + Kindly Reminder + Prijazen opomnik + + + + + + Please install File Roller first and then continue + Pred nadaljevanjem namestite File Roller + + + + + Unable to create files here: %1 + Na tem mestu ni mogoče ustvariti datotek: %1 + + + + Confirm + button + Potrdi + + + + FileDialogStatusBar + + + File Name + Ime datoteke + + + + Format + Format + + + + Save + button + Shrani + + + + Open + button + Odpri + + + + Save File + button + Shrani + + + + Open File + button + Odpri + + + + + + Cancel + button + Prekini + + + + FileJob + + + copy + kopiraj + + + + + + + Data verification successful. + Preverjanje podatkov je uspelo. + + + + + + Burn process completed + Zapisovanje se je zaključilo + + + + %1 s + %1 s + + + + %1 m %2 s + %1 min %2 s + + + + %1 h %2 m %3 s + %1 u %2 min %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 u %3 min %4 s + + + + %1 is a duplicate file. + %1 je podvojena datoteka + + + + Insufficient disc space. + Na disku ni dovolj prostora, + + + + Lost connection to drive. + Izgubljena povezava s pogonom. + + + + The CD/DVD drive is not ready. Try another disc. + CD/DVD pogon ni pripravljen. Poskusite z drugim diskom. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + CD/DVD pogon je v rabi. Zaprite program, ki ga uporablja in ponovno vstavite disk v pogon. + + + + Unknown error + Neznana napaka + + + + Device disconnected + Naprava je odklopljena + + + + GenerateSettingTranslate + + + + + Basic + Osnovno + + + + + + Open behavior + Način odklopa + + + + + + Always open folder in new window + Vedno odpri mapo v novem oknu + + + + + + Open file: + Odpri datoteko: + + + + + + Click + Klik + + + + + + Double click + Dvojni klik + + + + + + New window and tab + Novo okno in zavihek + + + + + + Open from default window: + Odpri iz privzetega okna: + + + + + + + + + Computer + Računalnik + + + + + + + + + Home + Domov + + + + + + + + + Desktop + Namizje + + + + + + + + + Videos + Videoposnetki + + + + + + + + + Music + Glasba + + + + + + + + + Pictures + Slike + + + + + + + + + Documents + Dokumenti + + + + + + + + + Downloads + Prenosi + + + + + + Open in new tab: + Odpri v novem zavihku: + + + + + + Current Directory + Trenutna mapa + + + + + + View + Pogled + + + + + + Default size: + Privzeta velikost: + + + + + + Extra small + Zelo majhno + + + + + + Small + Majhna + + + + + + Medium + Srednje + + + + + + Large + Velika + + + + + + Extra large + Zelo veliko + + + + + + Default view: + Privzeti pogled: + + + + + + Icon + Ikona + + + + + + List + Seznam + + + + + + Hidden files + Skrite datoteke + + + + + + Show hidden files + Pokaži skrite datoteke + + + + + + Hide file extension when rename + Ob preimenovanju skrij končnico datoteke + + + + + + Advanced + Napredno + + + + + + Index + Indeks + + + + + + Auto index internal disk + Samodejno indeksiraj notranji disk + + + + + + Index external storage device after connected to computer + Po priključitvi na računalnik indeksiraj zunanji nosilec podatkov + + + + + + Full-Text search + Iskanje po celotnem besedilu + + + + + + Show item counts and sizes in the path of mounted MTP devices + Prikaži števec predmetov in velikost v poteh priklopljenih MTP naprav + + + + + + Keep showing the mounted Samba shares + + + + + + + Use the file chooser dialog of File Manager + Uporabi izbirnik datotek iz upravitelja datotek + + + + + + Ask for my confirmation when deleting files + Vprašaj za dovoljenje pri brisanju datotek + + + + + + Other + Drugo + + + + + + Hide system disk + Skrij sistemski disk + + + + + + Show file system on disk icon + Na ikoni diska prikaži datotečni sistem + + + + + + Show hidden files in search results + V razultatih iskanja pokaži skrite datoteke + + + + + + Display recent file entry in left panel + Prikaži nedavne vnose datotek v levem panoju + + + + + + Preview + Predogled + + + + + Compress file preview + Stisni predogled datoteke + + + + + + Text preview + Predogled besedila + + + + + + Document preview + Predogled dokumenta + + + + + + Image preview + Predogled slike + + + + + + Video preview + Predogled posnetka + + + + + + Mount + Priklopi + + + + + + Auto mount + Samodejno priklopi + + + + + + Open after auto mount + Odpri po samodejni priklopitvi + + + + + + Dialog + Dialog + + + + Compressed file preview + Predogled stisnjene datoteke + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Ne morem preveriti istovetnosti za %1 + + + + This happens when you log in to a computer the first time. + To se zgodi ob prvi prijavi v računalnik. + + + + The identity sent by the remote computer is + Identiteta, ki jo je poslal oddaljeni računalnik, je + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Če želite biti povsem prepričani, da je nadaljevanje varno, kontaktirajte skrbnika sistema + + + + + + + + Mounting device error + Napaka ob priklopu naprave + + + + + Wrong username or password + Napačno uporabniško ime ali geslo + + + + + + + + Confirm + button + Potrdi + + + + + Cannot find the mounted device + Priklopljene naprave ni mogoče najti + + + + No key available to unlock device + Ni ključa za odklepanje naprave + + + + The disk is mounted by user "%1", you cannot unmount it. + Disk je priklopil uporabnik "%1", ne morete ga odklopiti. + + + + Cannot unmount the device + Naprave ni mogoče odklopiti + + + + Cannot eject the device "%1" + Naprave "%1" ni mogoče izvreči + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Ne morem zapisati. Na ciljnem disku ni dovolj prostora. + + + + MergedDesktopController + + + + Pictures + Slike + + + + + Music + Glasba + + + + + Applications + Aplikacije + + + + + Videos + Video + + + + + Documents + Dokumenti + + + + + Others + Drugo + + + + MimeTypeDisplayManager + + + + Directory + Mapa + + + + + + Application + Aplikacija + + + + + + Video + Video + + + + + + Audio + Zvok + + + + + + Image + Slika + + + + + Archive + Arhiv + + + + + + Text + Besedilo + + + + + Executable + Zagonska + + + + + Backup file + Varnostna kopija + + + + + Unknown + Neznano + + + + MountAskPasswordDialog + + + Cancel + button + Prekini + + + + Connect + button + Poveži + + + + Log in as + Prijavite se kot + + + + Anonymous + Anonimnež + + + + Registered user + Registriran uporabnik + + + + Username + Uporabniško ime + + + + Domain + Domena + + + + Password + Geslo + + + + Remember password + Zapomni si geslo + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Prekini + + + + Unlock + button + Odkleni + + + + Input password to decrypt the disk + Vnesite geslo za dešifriranje diska + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Ali ste prepričani, da želite trajno izbrisati %1? + + + + This file is too big for the trash + Datoteka je prevelika za koš + + + + The files are too big for the trash + Datoteke so prevelike za koš + + + + Are you sure you want to permanently delete %1 files? + Ali ste prepričani, da želite trajno izbrisati %1 datotek? + + + + Cancel + button + Prekini + + + + Delete + button + Izbriši + + + + OpenWithDialog + + + Open with + Odpri z/s + + + + Add other programs + Dodaj druge programe + + + + Set as default + Nastavi kot privzeto + + + + Cancel + button + Prekini + + + + Confirm + button + Potrdi + + + + Recommended Applications + Priporočene aplikacije + + + + Other Applications + Druge aplikacije + + + + PathManager + + + Home + Dom + + + + Desktop + Namizje + + + + Videos + Videoposnetki + + + + Music + Glasba + + + + Pictures + Slike + + + + Documents + Dokumenti + + + + Downloads + Prenosi + + + + + Trash + Koš + + + + + + System Disk + Sistemski disk + + + + Computers in LAN + Računalniki v LAN omrežju + + + + My Shares + Predmeti v skupni rabi + + + + Computer + Računalnik + + + + Recent + Nedavno + + + + File Vault + Trezor datotek + + + + PropertyDialog + + + Basic info + Osnovne informacije + + + + Open with + Odpri z/s + + + + Sharing + V skupni rabi + + + + Permissions + Dovoljenja + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Skrij to mapo + + + + Hide this file + Skrij to datoteko + + + + Allow to execute as program + Dovoli, da se izvrši kot program + + + + QObject + + + + + + Size + Velikost + + + + + + Contains + Vsebuje + + + + + + Type + Vrsta + + + + + + + + Time modified + Čas spremembe + + + + Free space + Nezaseden prostor + + + + Total space + Celoten prostor + + + + + Time locked + Zaklenjen čas + + + + Access denied + Zavrnjen dostop + + + + + Executable + Zagonska + + + + + Write only + Samo pisanje + + + + + Read only + Samo branje + + + + + Read-write + Branje in pisanje + + + + Others + Drugo + + + + Owner + Lastnik + + + + Unconnected network shared directory + + + + + Device type + Vrsta naprave + + + + File system + Datotečni sistem + + + + Group + Skupina + + + + + Open + Odpri + + + + Lock + Zaklenjeno + + + + Auto lock + Samodejni zaklep + + + + Never + Nikoli + + + + 5 minutes + 5 minut + + + + 10 minutes + 10 minut + + + + 20 minutes + 20 minut + + + + Delete File Vault + Izbriši trezor datotek + + + + Unlock + Odkleni + + + + Unlock by key + Odkleni s ključem + + + + Open + button + Odpri + + + + + Size: %1 + Velikost: %1 + + + + Type: %1 + Vrsta: %1 + + + + Size: 0 + Velikost: 0 + + + + Items: %1 + Predmeti: %1 + + + + + + + + + + Open in new window + Odpri v novem oknu + + + + + + + + + + Open in new tab + Odpri v novem zavihku + + + + Open with + Odpri z/s + + + + + Compress + Stisni + + + + Extract + Razširi + + + + Extract here + Razširi sem + + + + Cut + Izreži + + + + Copy + Kopiraj + + + + Paste + Prilepi + + + + + + + + Rename + Preimenuj + + + + + + + Remove + Odstrani + + + + Create link + Ustvari povezavo + + + + Send to desktop + Pošlji na namizje + + + + Send to + Pošlji v/na + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Dodaj med zaznamke + + + + + + + Properties + Lastnosti + + + + New folder + Nova mapa + + + + New window + Novo okno + + + + Select all + Izberi vse + + + + + Clear recent history + Počisti nedavno zgodovino + + + + + + Empty Trash + Izprazni koš + + + + Display as + Prikaži kot + + + + Sort by + Razvrsti po + + + + New document + Nov dokument + + + + + Time created + Čas nastanka + + + + + + Source path + Izhodišče + + + + Share folder + Deli mapo + + + + Cancel sharing + Prekliči deljenje + + + + Connect to Server + Poveži s strežnikom + + + + Set share password + Nastavi geslo za skupno rabo + + + + Format + Format + + + + Tag information + Podatki oznak + + + + Open as administrator + Odpri kot administrator + + + + Select default program + Izberi privzeti program + + + + Open file location + Odpri mapo datoteke + + + + Remove bookmark + Odstrani zaznamek + + + + + + Delete + Izbriši + + + + Office Text + Urejeno besedilo + + + + Spreadsheets + Preglednica + + + + Plain Text + Navadno besedilo + + + + Open in terminal + Odpri v terminalu + + + + Restore + Obnovi + + + + Restore all + Obnovi vse + + + + Clear saved password and unmount + Počisti shrano geslo in odklopi + + + + File Vault + Trezor datotek + + + + Add to disc + Dodaj na disk + + + + Refresh + + + + + Auto mount + Samodejno priklopi + + + + Open after auto mount + Odpri po samodejni priklopitvi + + + + + Mount + Priklopi + + + + + Unmount + Odklopi + + + + It does not support burning %1 discs + Ne podpira zapisovanja %1 + + + + Burn + Zapiši + + + + Disc name: + Ime diska: + + + + + Maximum + Največ + + + + Allow files to be added later + Dovoli kasnejše dodajanje datotek + + + + Verify data + Preveri podatke + + + + Write speed: + Hitrost zapisovanja: + + + + + + + Cancel + button + Prekini + + + + Burn + button + Zapiši + + + + + Eject + Izvrzi + + + + Safely Remove + Varno odstrani + + + + + Name + Ime + + + + Settings + Nastavitve + + + + Exit + Izhod + + + + Icon + Ikona + + + + List + Seznam + + + + Extend + Razširi + + + + Set as wallpaper + Nastavi za ozadje + + + + + + + Local disk + Lokalni disk + + + + + Removable disk + Zunanji disk + + + + + + Network shared directory + Omrežna mapa v skupni rabi + + + + + Android mobile device + Mobilna naprava Android + + + + + Apple mobile device + Mobilna naprava Apple + + + + + Camera + Kamera + + + + + DVD + DVD + + + + + Unknown device + Neznana naprava + + + + + + %1 item + %1 element + + + + + + %1 items + %1 elementov + + + + Shortcut + Bližnjica + + + + Create symlink + Ustvari simbolno povezavo + + + + Path + Pot do elementa + + + + + + Time deleted + Čas brisanja + + + + Loading... + Nalagam... + + + + File has been moved or deleted + Datoteka je bila premaknjena ali izbrisana + + + + You do not have permission to traverse files in it + Nimate dovoljenja za prehod preko datotek v njej + + + + + + You do not have permission to access this folder + Nimate dovoljenja za dostopanje do te mape + + + + + + + + Folder is empty + Mapa je prazna + + + + Searching... + Iščem... + + + + No results + Ni rezultatov + + + + Source Path + TrashFileInfo + Izvorna pot + + + + Document + Dokument + + + + Spreadsheet + Preglednica + + + + + Presentation + Predstavitev + + + + Text + Besedilo + + + + 1 task in progress + 1 opravilo v obdelavi + + + + %1 tasks in progress + %1 opravil v obdelavi + + + + Mode: + Način: + + + + + Replace Text + Zamenjaj besedilo + + + + + Add Text + Dodaj besedilo + + + + + Custom Text + Besedilo po meri + + + + Find: + Išči: + + + + Replace: + Zamenjaj: + + + + + Optional + Po želji + + + + Add: + Dodaj: + + + + Location: + Lokacija: + + + + File name: + Ime datoteke: + + + + Start at: + Začni na: + + + + + Rename + button + Preimenuj + + + + + + + + + + + Required + Potrebno + + + + + Before file name + Pred imenom datoteke + + + + + After file name + Po imenu datoteke + + + + Find + Najdi + + + + Replace + Zamenjaj + + + + Add + Dodaj + + + + Start at + Začni na + + + + + + Location + Lokacija + + + + File name + Ime datoteke + + + + Dimension + Velikost + + + + Duration + Trajanje + + + + Tips: Sort by selected file order + Namig: Sortirajte po izbranem zaporedju datotek + + + + Rename %1 Files + Preimenuj %1 datotek + + + + Multiple Files + Več datotek + + + + Basic info + Osnovne informacije + + + + Total size + Celotna velikost + + + + Number of files + Število datotek + + + + %1 file(s), %2 folder(s) + %1 datotek, %2 map + + + + + + Time accessed + Čas dostopa + + + + Orange + Oranžna + + + + Red + Rdeča + + + + Purple + Vijolična + + + + Navy-blue + Mornarsko modra + + + + Azure + Nebesno modra + + + + Green + Zelena + + + + Yellow + Rumena + + + + Gray + Siva + + + + Input tag info, such as work, family. A comma is used between two tags. + Vnesite oznako, recimo delo ali družina. Dve oznaki ločuje vejica. + + + + Bookmarks + Zaznamki + + + + Erase + Izbriši + + + + Copy path + Pot kopiranja + + + + Edit address + Urejanje dostopa + + + + Free Space %1 + Nezaseden prostor %1 + + + + Files are being processed + Datoteke se obdelujejo + + + + + Unknown + Neznano + + + + My Vault + Moj trezor + + + + + Failed to create file info + Podatkov o datoteki ni bilo mogoče ustvariti + + + + Failed to create file handler + Ni bilo mogoče ustvariti ročice za datoteko + + + + Failed to open the file, cause: %1 + Datoteke ni bilo mogoče odpreti, razlog: %1 + + + + Original file does not exist + Izvirnik datoteke ne obstaja + + + + Do you want to delete %1? + Želite izbrisati %1? + + + + Confirm + button + Potrdi + + + + + + + + %1 are not allowed + + + + + + Failed to start Samba services + + + + + RecentController + + + Cancel + button + Prekini + + + + Remove + button + Odstrani + + + + Do you want to remove this item? + + + + + Do yout want to remove %1 items? + + + + + It does not delete the original files + + + + + ShareInfoFrame + + + Share this folder + Deli to mapo + + + + Share name: + Delitveno ime: + + + + Permission: + Dovoljenje: + + + + Read and write + Za branje in pisanje + + + + Read only + Samo za branje + + + + Anonymous: + Anonimen: + + + + Not allow + Ne dovoli + + + + Allow + Dovoli + + + + The share name must not be two dots (..) or one dot (.) + Ime skupne rabe ne sme imeti dveh (..) ali ene pike (.). + + + + The share name is used by another user. + Ime skupne rabe uporablja drug uporabnik. + + + + OK + button + V redu + + + + Cancel + button + Prekini + + + + Replace + button + Zamenjaj + + + + The share name already exists. Do you want to replace the shared folder? + To ime za skupno rabo že obstaja. Ali želite zamenjati mapo v skupni rabi? + + + + Shortcut + + + Item + Element + + + + Select to the first item + Izberi do prvega elementa + + + + Shift + Home + Shift + Home + + + + Select to the last item + Izberi do zadnjega elementa + + + + Shift + End + Shift + End + + + + Select leftwards + Izberi na levo + + + + Shift + Left + Shift + Left + + + + Select rightwards + Izberi na desno + + + + Shift + Right + Shift + Right + + + + Select to upper row + Izberi do zgornje vrste + + + + Shift + Up + Shift + Up + + + + Select to lower row + Izberi do spodnje vrste + + + + Shift + Down + Shift + Down + + + + Open + Odpri + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + Do starševske mape + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Trajno izbriši + + + + Shift + Delete + Shift + Delete + + + + Delete file + Izbriši datoteko + + + + Delete + Izbriši + + + + Select all + Izberi vse + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Kopiraj + + + + Cut + Izreži + + + + Paste + Prilepi + + + + Rename + Preimenuj + + + + F2 + F2 + + + + New/Search + Novo/Išči + + + + New window + Novo okno + + + + New folder + Nova mapa + + + + + Search + Išči + + + + New tab + Nov zavihek + + + + View + Pogled + + + + Item information + Informacije o elementu + + + + Help + Pomoč + + + + F1 + F1 + + + + Keyboard shortcuts + Bližnjice na tipkovnici + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Preklopi status prikaza + + + + Hide item + Skrij element + + + + Input in address bar + Vnos spletnega naslova + + + + Switch to icon view + Preklopi na prikaz ikon + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Preklopi na prikaz seznama + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Drugo + + + + Close + Zapri + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Zapri trenuten zavihek + + + + Back + Nazaj + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Preklopi na naslednji zavihek + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Preklopi na prejšnji zavihek + + + + Next file + Naslednja datoteka + + + + Tab + Tab + + + + Previous file + Prejšnja datoteka + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Preklopite na zavihek z določeno številko med 1 in 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Naprej + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Ne morem odpreti predmetov v košu. Najprej jih obnovite + + + + TrashPropertyDialog + + + Trash + Koš + + + + item + Element + + + + items + Elementi + + + + Contains %1 %2 + Vsebuje %1 %2 + + + + UDiskListener + + + Failed to rename the label + Neuspešno preimenovanje oznake + + + + UnmountWorker + + + + + The device was not safely unmounted + Naprava ni bila varno odklopljena + + + + The device was not safely removed + Naprava ni bila varno odstranjena + + + + UserShareManager + + + Kindly Reminder + Prijazen opomin + + + + Please firstly install samba to continue + Za nadaljevanje najprej namestite Sambo + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + + + + + To protect the files, you cannot share this folder. + Zaradi zaščite datotek ne morete deliti te mape. + + + + Sharing failed + Deljenje za skupno rabo ni uspelo + + + + The computer name is too long + Ime računalnika je predolgo + + + + You do not have permission to operate file/folder! + Nimate dovoljenja, da bi upravljali z datoteko/mapo! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Za zaščito map v skupni rabi vnesite geslo + + + + Cancel + button + Prekini + + + + Confirm + button + Potrdi + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sq.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sq.ts new file mode 100644 index 0000000..153d052 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sq.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Dosje e Re + + + + Mounting device error + Gabim montimi pajisjeje + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Pamja e diskut qe dëmtuar, s’mund të montohet, ju lutemi, së pari fshijeni diskun + + + + Mount error: unsupported image format + Gabim montimi: format pamjeje i pambuluar + + + + + The device was not safely removed + Pajisja s’u hoq në mënyrë të parrezik + + + + + Click "Safely Remove" and then disconnect it next time + Herës tjetër klikoni mbi “Hiqe Në Mënyrë të Parrezik” dhe mandej shkëputeni + + + + The device was not ejected + Pajisja s’u hoq + + + + Disk is busy, cannot eject now + Disku është i zënë, s’mund të nxirret + + + + Authentication timed out + Mirëfilltësimit i mbaroi koha + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Shpërngulje Bluetooth Kartelash + + + + File Transfer Successful + Shpërngulje e Suksesshme Kartelash + + + + File Transfer Failed + Shpërngulja e Kartelave Dështoi + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Po dërgohen kartela te "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + S’u arrit të dërgohen kartela te "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + U dërgua me sukses te "<b style="font-weight: 550;">%1</b>" + + + + Select a Bluetooth device to receive files + Që të merrni kartela, përzgjidhni një pajisje Bluetooth + + + + Cannot find the connected Bluetooth device + S’gjendet dot pajisja Bluetooth e lidhur + + + + Waiting to be received... + Po pritet të merren… + + + + Go to Bluetooth Settings + Kalo te Rregullime Bluetooth-i + + + + %1/%2 Sent + %1/%2 u Dërgua + + + + Error: the Bluetooth device is disconnected + Gabim: pajisja Bluetooth është shkëputur + + + + Unable to send the file more than 2 GB + S’arrihet të dërgohet kartela më e madhe se 2 GB + + + + Unable to send 0 KB files + S’arrihet të dërgohen kartela 0 KB + + + + File doesn't exist + Kartela s’ekziston + + + + Next + button + Pasuesi + + + + Cancel + button + Anuloje + + + + Done + button + U bë + + + + Retry + button + Riprovo + + + + OK + button + OK + + + + File sending request timed out + Kërkesës për dërgim kartele i mbaroi koha + + + + The service is busy and unable to process the request + Shërbimi është i zënë dhe s’arrin të përpunojë kërkesën + + + + BurnOptDialog + + + Device error + Gabim pajisjeje + + + + Optical device %1 doesn't exist + Pajisja optike %1 s’ekziston + + + + Advanced settings + Rregullime të mëtejshme + + + + File system: + Sistem kartelash: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Për Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Për Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (E përputhshme me mënyrën CD/DVD Windows) + + + + ISO9660 Only + Vetëm ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Mbylli krejt + + + + Total size: %1, %2 files + Madhësi gjithsej: %1, %2 kartela + + + + ComputerModel + + + Double click to open it + Dyklikojeni që ta hapet + + + + My Directories + Drejtoritë e Mia + + + + Disks + Disqe + + + + File Vault + Kasafortë Kartelash + + + + Quick Access + Përdorim i Shpejtë + + + + ComputerPropertyDialog + + + Computer + Kompjuter + + + + Basic Info + Të dhëna Elementare + + + + + Computer Name + Emër Kompjuteri + + + + + Edition + Edicion + + + + + + Version + Version + + + + + Type + Lloj + + + + + + Processor + Procesor + + + + + + Memory + Kujtesë + + + + + + + Bit + Bit + + + + + Available + Të passhme + + + + Obtaining... + Po merret… + + + + ConnectToServerDialog + + + Connect to Server + Lidhu te Shërbyesi + + + + Cancel + button + Anuloje + + + + Connect + button + Lidhu + + + + My Favorites: + Të parapëlqyerat e Mia: + + + + + Clear History + Spastro Historikun + + + + DFMAddressBar + + + Search or enter address + Kërkoni ose jepni adresë + + + + DFMAdvanceSearchBar + + + Search: + Kërko: + + + + File Type: + Lloj Kartele: + + + + File Size: + Madhësi Kartele: + + + + Time Modified: + Kohë Kur u Ndryshua: + + + + Time Accessed: + Kohë Kur u Hap: + + + + Time Created: + Kohë Kur u Krijua: + + + + Reset + Ktheje te parazgjedhjet + + + + All subdirectories + Krejt nëndrejtoritë + + + + Current directory + Drejtoria e tanishme + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Sot + + + + Yesterday + Dje + + + + This week + Këtë javë + + + + Last week + Javën e fundit + + + + This month + Këtë muaj + + + + Last month + Muajin e fundit + + + + This year + Këtë vit + + + + Last year + Vitin e shkuar + + + + DFMOpticalMediaWidget + + + + No files to burn + S’ka kartela për shkrim + + + + Unable to burn. Not enough free space on the target disk. + S’arrihet të shkruhet. S’ka hapësirë të mjaftueshme te disku i synuar. + + + + %1 burning is not supported + Nuk mbulohet shkrimi %1 + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. S’është disk %1; +2. Versioni i këtij sistemi kartelash s’mbulon ende shtim kartelash. + + + + DFMTagCrumbController + + + Tag information + Të dhëna etikete + + + + DFMTagWidget + + + Tag + Etiketë + + + + DFMTaskWidget + + + Do not ask again + Mos pyet sërish + + + + Syncing data + Njëkohësim të dhënash + + + + Please wait + Ju lutemi, prisni + + + + + Time modified: %1 + Kohë kur u ndryshua: %1 + + + + + Contains: %1 + Përmban: %1 + + + + + Size: %1 + Madhësi: %1 + + + + Original folder + Dosja origjinale + + + + Keep both + button + Mbaji të dyja + + + + Skip + button + Anashkaloje + + + + Replace + button + Zëvendësoje + + + + Retry + button + Riprovo + + + + Original file + Kartela origjinale + + + + Target folder + Dosja e synuar + + + + Target file + Kartela e synuar + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Fshehtëzo Kasafortë Kartelash + + + + Click 'Encrypt' and input the user password. + Klikoni mbi “Fshehtëzoje” dhe jepni fjalëkalimin e përdoruesit. + + + + Encrypting... + Po fshehtëzohet… + + + + + + + Encrypt + Fshehtëzoje + + + + Failed to create file vault: %1 + S’u arrit të krijohet kasafortë kartelash: %1 + + + + OK + OK + + + + The setup is complete + Ujdisja është e plotë + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Ruani Kyç Rimarrjesh + + + + Keep the key safe to retrieve the vault password later + Mbajeni të parrezik kyçin, që të rimerrni më vonë fjalëkalim kasaforte + + + + Save to default path + Ruaje te shtegu parazgjedhje + + + + Save to other locations + Ruajeni në vendndodhje të tjera + + + + No permission, please reselect + S’kihen leje, ju lutemi, ripërzgjidhni + + + + Select a path + Përzgjidhni një shteg + + + + Next + Pasuesi + + + + The default path is invisible to other users, and the path information will not be shown. + Shtegu parazgjedhje është i padukshëm për përdorues të tjerë dhe hollësitë e shtegut nuk do të shfaqen. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Kyç Rimarrjesh + + + + Generate a recovery key in case that you forgot the password + Prodhohet një kyç rimarrjesh, për rastin kur harroni fjalëkalimin + + + + Key + Kyç + + + + QR code + Kod QR + + + + Scan QR code and save the key to another device + Skanoni kodin QR dhe ruajeni kyçin në një pajisje tjetër + + + + Next + Pasuesi + + + + Recovery Key: + Kyç Rimarrjesh: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Caktoni Fjalëkalim Kasaforte + + + + Method + Metodë + + + + Manual + Dorazi + + + + Password + Fjalëkalim + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 shenja, përmban A-Z, a-z, 0-9, dhe simbole + + + + Repeat password + Përsëritni fjalëkalimin + + + + Input the password again + Jepeni sërish fjalëkalimin + + + + Password hint + Ndihmëz fjalëkalimi + + + + Optional + Opsionale + + + + Next + Pasuesi + + + + + Passwords do not match + Fjalëkalimet s’përputhen + + + + DFMVaultActiveStartView + + + File Vault + Kasafortë Kartelash + + + + Create your secure private space + Krijoni hapësirën tuaj private të siguruar + + + + Advanced encryption technology + Teknologji e përparuar fshehtëzimesh + + + + Convenient and easy to use + I leverdishëm dhe i lehtë për ta përdorur + + + + Create + Krijoje + + + + DFMVaultFileView + + + Cannot open this path + S’hapet dot ky shteg + + + + Hint + Ndihmës + + + + OK + OK + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Shkyçeni përmes Kyçi + + + + Failed to unlock file vault + S’u arrit të shkyçet kasafortë kartelash + + + + OK + OK + + + + Input the 32-digit recovery key + Jepni kyçin 32-shifror të rimarrjeve + + + + Cancel + button + Anuloje + + + + Unlock + button + Shkyçe + + + + Wrong recovery key + Kyç rimarrjesh i gabuar + + + + DFMVaultRemoveByPasswordView + + + Password + Fjalëkalim + + + + Password hint: %1 + Ndihmëz fjalëkalimi: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Jepni kyçin 32-shifror të rimarrjeve + + + + DFMVaultRemovePages + + + Delete File Vault + Fshi Kasafortë Kartelash + + + + Once deleted, the files in it will be permanently deleted + Pasi të jetë fshirë, kartelat në të do të fshihen përgjithnjë + + + + Use Key + Përdor Kyç + + + + Cancel + button + Anuloje + + + + Use Key + button + Përdor Kyç + + + + Delete + button + Fshije + + + + + OK + button + OK + + + + Use Password + Përdor Fjalëkalim + + + + Wrong password + Fjalëkalim i gabuar + + + + Wrong recovery key + Kyç rimarrjesh i gabuar + + + + Failed to delete file vault + S’u arrit të fshihet kasafortë kartelash + + + + Deleted successfully + U fshi me sukses + + + + Failed to delete + S’u arrit të fshihet + + + + Removing... + Po hiqet… + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + S’arrihet të merret kartela e kyçit + + + + Verification failed + Verifikimi dështoi + + + + + Select a path + Përzgjidhni një shteg + + + + + Retrieve Password + Rimerrni Fjalëkalimin + + + + By key in the default path + Përmes kyçi te shtegu parazgjedhje + + + + By key in the specified path + Përmes kyçi te shtegu i përcaktuar + + + + Verification Successful + Verifikim i Suksesshëm + + + + Keep it safe + Mbajeni të parrezik + + + + Back + button + Mbrapsht + + + + Verify Key + button + Verifikoni Kyç + + + + Go to Unlock + button + Kalo te Shkyçja + + + + Close + button + Mbylle + + + + Vault password: %1 + Fjalëkalim kasaforte: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Shkyç Kasafortë Kartelash + + + + Forgot password? + Harruat fjalëkalimin? + + + + Password hint: %1 + Ndihmëz fjalëkalimi: %1 + + + + Failed to unlock file vault + S’u arrit të shkyçet kasafortë kartelash + + + + Cancel + button + Anuloje + + + + Password + Fjalëkalim + + + + Unlock + button + Shkyçe + + + + Please try again %1 minutes later + Ju lutemi, riprovoni pas %1 minutash + + + + Wrong password, please try again %1 minutes later + Fjalëkalim i gabuar, ju lutemi, riprovoni pas %1 minutash + + + + Wrong password, one chance left + Fjalëkalim i gabuar, edhe një provë + + + + Wrong password, %1 chances left + Fjalëkalim i gabuar, edhe %1 prova + + + + Wrong password + Fjalëkalim i gabuar + + + + OK + button + OK + + + + DFileCopyMoveJob + + + Permission error + Gabim lejesh + + + + The action is denied + Veprimi s’u lejua + + + + Failed to open the file + S’u arrit të hapej kartela + + + + Failed to read the file + S’u arrit të lexohej kartela + + + + Failed to write the file + S’u arrit të shkruhej kartela + + + + Failed to create the directory + S’u arrit të krijohej drejtoria + + + + Failed to delete the file + S’u arrit të fshihej kartela + + + + Failed to move the file + S’u arrit të lëvizej kartela + + + + Original file does not exist + Kartela origjinale s’ekziston + + + + Failed, file size must be less than 4GB + Dështoi, madhësia e kartelave duhet të jetë më pak se 4GB + + + + Not enough free space on the target disk + S’ka hapësirë të mjaftueshme te disku i synuar + + + + File integrity was damaged + Integriteti i kartelës qe cenuar + + + + The target device is read only + Pajisja e synuar është vetëm-për-lexim + + + + Target folder is inside the source folder + Dosja e synuar gjendet brenda dosjes burim + + + + The action is not supported + Veprimi nuk mbulohet + + + + You do not have permission to traverse files in it + S’keni leje për të kaluar kartela në të + + + + Failed to position the file pointer! + S’u arrit të vendosej treguesi i kartelës! + + + + copy + Extra name added to new file name when used for file name. + kopjoje + + + + Failed to open the directory, cause: file name too long + S’u arrit të hapej drejtoria, shkak: emër shumë i gjatë kartele + + + + + Failed to open the file, cause: file name too long + S’u arrit të hapej kartela, shkak: emër shumë i gjatë kartele + + + + + Failed to write the file, cause: + S’u arrit të shkruhej kartela, shkaku: + + + + Failed to position the file pointer, cause: %1 + S’u arrit të vendosej treguesi i kartelës, shkaku: %1 + + + + Syncing data + Njëkohësim të dhënash + + + + Please wait + Ju lutemi, prisni + + + + Failed to create the directory, cause: %1 + S’u arrit të krijohej drejtoria, shkaku: %1 + + + + + + + + Failed to open the file, cause: %1 + S’u arrit të hapej kartela, shkaku: %1 + + + + + + + Failed to open the file, cause: Permission denied + S’u arrit të hapej kartela, shkak: Leje e mohuar + + + + + Failed to read the file, cause: %1 + S’u arrit të lexohej kartela, shkaku: %1 + + + + + + + Failed to write the file, cause: %1 + S’u arrit të shkruhej kartela, shkaku: %1 + + + + + File integrity was damaged, cause: %1 + Integriteti i kartelës qe cenuar, shkaku: %1 + + + + Failed to open the file, cause: + S’u arrit të hapej kartela, shkaku: + + + + Failed to read the file, cause: + S’u arrit të lexohej kartela, shkaku: + + + + Failed to delete the file, cause: %1 + S’u arrit të fshihej kartela, shkaku: %1 + + + + Fail to create symlink, cause: %1 + S’u arrit të krijohej simlidhje, shkaku: %1 + + + + DFileDialog + + + + Save + button + Ruaje + + + + + Cancel + button + Anuloje + + + + Confirm + button + Ripohojeni + + + + %1 already exists, do you want to replace it? + %1 ekziston tashmë, doni të mbishkruhet? + + + + Replace + button + Zëvendësoje + + + + Open + button + Hape + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Kjo kartelë do të kalohet e fshehur, nëse emri i kartelës fillon me një pikë (.). Doni të bëhet fshehja? + + + + DFileManagerWindow + + + Trash + Hedhurina + + + + Empty + E zbrazët + + + + DFileSystemModel + + + + Name + Emër + + + + + + Time modified + Kohë kur u ndryshua + + + + Size + Madhësi + + + + Type + Lloj + + + + Time created + Kohë kur u krijua + + + + + Last access + Hyrja e fundit + + + + + + + Path + Shteg + + + + DFileView + + + Disc mount error + Gabim montimi disku + + + + The disc is in use, please end the running process and remount the disc. + Disku është në përdorim, ju lutemi, përfundoni procesin në xhirim dhe rimontoni diskun. + + + + Mounting failed + Montimi dështoi + + + + (Reverse) + (Së prapthi) + + + + DFileViewHelper + + + Add tag "%1" + Shto etiketë "%1" + + + + DStatusBar + + + %1 item + %1 objekt + + + + %1 items + %1 objekte + + + + %1 item selected + %1 objekt i përzgjedhur + + + + %1 items selected + %1 objekte të përzgjedhur + + + + %1 folder selected (contains %2) + %1 dosje e përzgjedhur (përmban %2) + + + + %1 folders selected (contains %2) + %1 dosje të përzgjedhura (përmban %2) + + + + %1 file selected (%2) + %1 kartelë e përzgjedhur (%2) + + + + %1 files selected (%2) + %1 kartela të përzgjedhura (%2) + + + + %1 folder selected + %1 dosje e përzgjedhur + + + + Filter + Filtër + + + + Save as: + Ruaje si: + + + + Loading... + Po ngarkohet… + + + + DTaskDialog + + + Erasing disc %1, please wait... + Po fshihet disku %1, ju lutemi, pritni… + + + + Burning disc %1, please wait... + Po shkruhet disku %1, ju lutemi, pritni… + + + + Writing data... + Po shkruhen të dhëna… + + + + Verifying data... + Po verifikohen të dhëna… + + + + Copying %1 + Po kopjohet %1 + + + + + + to %2 + te %2 + + + + %1 already exists in target folder + %1 ekziston tashmë te dosja e synuar + + + + Original path %1 Target path %2 + Shtegu origjinal %1 Shtegu i synuar %2 + + + + Merge + button + Përzieji + + + + Replace + button + Zëvendësoje + + + + Moving %1 + Po lëvizet %1 + + + + Removing file vault, please try later + Po hiqet kasafortë kartelash, ju lutemi, provoni më vonë + + + + Restoring %1 + Po rikthehet %1 + + + + Deleting %1 + Po fshihet %1 + + + + Trashing %1 + Po shpihet në hedhurina %1 + + + + Calculating space, please wait + Po llogaritet hapësirë, ju lutemi, pritni + + + + DUMountManager + + + + Authentication timed out + Mirëfilltësimit i mbaroi koha + + + + + + Disk is busy, cannot unmount now + Disku është i zënë, s’mund të montohet + + + + Disk is busy, cannot eject now + Disku është i zënë, s’mund të nxirret + + + + The device is busy, cannot eject now + Pajisja është e zënë, s’mund të nxirret tani + + + + + + The device is busy, cannot remove now + Pajisja është e zënë, s’mund të hiqet tani + + + + DeepinStorage + + + + + %1 Volume + Vëllim %1 + + + + Data Disk + Data Partition + Disk të Dhënash + + + + %1 Drive + Pajisje %1 + + + + Blank %1 Disc + Zbardh Diskun %1 + + + + %1 Encrypted + %1 i Fshehtëzuar + + + + DialogManager + + + + + + Operation failed! + Veprimi dështoi! + + + + Target folder is inside the source folder! + Dosja e synuar gjendet brenda dosjes burim! + + + + Do you want to run %1 or display its content? + Doni që %1 të xhirohet apo të shfaqet lënda e saj? + + + + It is an executable text file. + Është kartelë tekst e ekzekutueshme. + + + + It is an executable file. + Është kartelë e ekzekutueshme. + + + + This file is not executable, do you want to add the execute permission and run? + Kartela s’është e ekzekutueshme, doni të shtohet leja e ekzekutimit dhe të xhirohet? + + + + "%1" already exists, please use another name. + "%1" ekziston tashmë, ju lutemi, përdorni një emër tjetër. + + + + The file name must not contain two dots (..) + Emri i kartelës s’duhet të përmbajë dy pika (..) + + + + Device or resource busy + Pajisje ose burim i zënë + + + + Are you sure you want to erase all data on the disc? + Jeni i sigurt se doni të fshihen krejt të dhënat te disku? + + + + How do you want to use this disc? + Si doni ta përdorni këtë disk? + + + + Disc erase failed + Fshirja e diskut dështoi + + + + Burn process failed + Procesi i shkrimit dështoi + + + + %1: %2 + %1: %2 + + + + Show details + Shfaq hollësi + + + + Hide details + Fshihi hollësitë + + + + Error + Gabim + + + + Permanently delete %1? + Të fshihet përgjithmonë %1? + + + + Permanently delete %1 items? + Të fshihen përgjithmonë %1 objekte? + + + + Empty + E zbrazët + + + + Do you want to delete %1? + Doni të fshihet %1? + + + + Do you want to delete the selected %1 items? + Doni të fshihen %1 objektet e përzgjedhur? + + + + Sorry, unable to locate your bookmark directory, remove it? + Na ndjeni, s’arrihet të gjendet drejtoria juaj e faqerojtësve, të hiqet? + + + + Name: + Emër: + + + + %1 that this shortcut refers to has been changed or moved + %1 së cilës i referohet kjo shkurtore, është ndryshuar ose lëvizur + + + + Do you want to delete this shortcut? + Doni të fshihet kjo shkurtore? + + + + Failed, file size must be less than 4GB. + U dështua, madhësia e kartelës duhet të jetë më pak 4GB. + + + + Fail to create symlink, cause: + S’u arrit të krijohej simlidhje, shkaku: + + + + The selected files contain system file/directory, and it cannot be deleted + Kartelat e përzgjedhura përmbajnë kartelë/drejtori sistemit dhe s’mund të fshihen + + + + Unable to find the original file + S’arrihet të gjendet kartela origjinale + + + + + You do not have permission to operate file/folder! + S’keni leje të bëni veprime në kartelë/dosje! + + + + Failed to restore %1 file, the source file does not exist + S’u arrit të rikthehet %1 kartelë, kartela burim s’ekziston + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Na ndjeni, s’keni leje të veproni me %1 kartelën/dosjen(et) vijuese! + + + + Unable to access %1 + S’arrihet të hyhet në %1 + + + + + Sending files now, please try later + Tani po dërgohen kartela, ju lutemi, provoni më vonë + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Që të përdorni pajisjen, së pari duhet ta formatoni diskun. Jeni i sigurt se doni të formatohet tani? + + + + Scanning the device, stop it? + Po skanohet pajisja, të ndalet? + + + + Share folder can't be named after the current username + Dosja e ndarjes s’mund të emërtohet sipas emrin të tanishëm të përdoruesit + + + + Do you want to run %1? + Doni të xhirohet %1? + + + + Burn image + button + Shkruani pamje + + + + Burn files + button + Shkruani kartela + + + + Are you sure you want to empty %1 item? + Jeni i sigurt se doni të zbrazet %1 objekt? + + + + Are you sure you want to empty %1 items? + Jeni i sigurt se doni të zbrazen %1 objekte? + + + + + This action cannot be undone + Ky veprim s’mund të zhbëhet + + + + + + + + + + + + + + OK + button + OK + + + + + + + + + + + + + + + Cancel + button + Anuloje + + + + + + Run + button + Xhiroje + + + + + Run in terminal + button + Xhiroje në terminal + + + + Display + button + Shfaqe + + + + + + + + + + + Confirm + button + Ripohojeni + + + + Erase + button + Fshije + + + + Data verification failed + Verifikimi i të dhënave dështoi + + + + Show details + button + Shfaq hollësi + + + + + Delete + button + Fshije + + + + Remove + button + Hiqe + + + + Disk is busy, cannot unmount now + Disku është i zënë, s’mund të montohet + + + + Force unmount + button + Detyro çmontimin + + + + Unable to copy. Not enough free space on the target disk. + S’arrihet të kopjohet. S’ka hapësirë të mjaftueshme te disku i synuar. + + + + Failed to restore %1 file, the target folder is read-only + S’u arrit të rikthehet %1 kartelë, dosja e synuar është vetëm-lexim + + + + Failed to restore %1 files, the target folder is read-only + S’u arrit të rikthehen %1 kartela, dosja e synuar është vetëm-lexim + + + + Failed to restore %1 files, the source files do not exist + S’u arrit të rikthehet %1 kartela, kartelat burim s’ekzistojnë + + + + Format + button + Formatoje + + + + Stop + button + Ndale + + + + FileController + + + + + + Unable to find the original file + S’arrihet të gjendet kartela origjinale + + + + + + Kindly Reminder + Kujtues i Sjellshëm + + + + + + Please install File Roller first and then continue + Ju lutemi, së pari, instaloni File Roller dhe mandej vazhdoni + + + + + Unable to create files here: %1 + S’arrihet të krijohen kartela këtu: %1 + + + + Confirm + button + Ripohojeni + + + + FileDialogStatusBar + + + File Name + Emër Kartele + + + + Format + Formatoje + + + + Save + button + Ruaje + + + + Open + button + Hape + + + + Save File + button + Ruaje Kartelën + + + + Open File + button + Hapni Kartelë + + + + + + Cancel + button + Anuloje + + + + FileJob + + + copy + kopjim + + + + + + + Data verification successful. + Verifikim i suksesshëm të dhënash. + + + + + + Burn process completed + Procesi i shkrimit u plotësua + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 është kartelë e përsëdytur. + + + + Insufficient disc space. + Hapësirë disku e pamjaftueshme. + + + + Lost connection to drive. + Humbi lidhja me pajisjen. + + + + The CD/DVD drive is not ready. Try another disc. + Pajisja CD/DVD s’është gati. Provoni disk tjetër. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + Pajisja CD/DVD është e zënë. Dilni nga programi duke përdorur pajisjen, dhe rifuteni pajisjen. + + + + Unknown error + Gabim i panjohur + + + + Device disconnected + Pajisja u shkëput + + + + GenerateSettingTranslate + + + + + Basic + Elementare + + + + + + Open behavior + Sjellje hapjesh + + + + + + Always open folder in new window + Dosjen hape përherë në një dritare të re + + + + + + Open file: + Hap kartelë: + + + + + + Click + Klikim + + + + + + Double click + Dyklikojeni + + + + + + New window and tab + Dritare dhe skedë e re + + + + + + Open from default window: + Hape prej dritares parazgjedhje: + + + + + + + + + Computer + Kompjuter + + + + + + + + + Home + Shtëpi + + + + + + + + + Desktop + Desktop + + + + + + + + + Videos + Video + + + + + + + + + Music + Muzikë + + + + + + + + + Pictures + Foto + + + + + + + + + Documents + Dokumente + + + + + + + + + Downloads + Shkarkime + + + + + + Open in new tab: + Hape në skedë të re: + + + + + + Current Directory + Drejtoria e Tanishme + + + + + + View + Shihni + + + + + + Default size: + Madhësi parazgjedhje: + + + + + + Extra small + Ekstra e vogël + + + + + + Small + E vogël + + + + + + Medium + E mesme + + + + + + Large + E madhe + + + + + + Extra large + Ekstra e madhe + + + + + + Default view: + Pamje parazgjedhje: + + + + + + Icon + Ikonë + + + + + + List + Listë + + + + + + Hidden files + Kartela të fshehura + + + + + + Show hidden files + Shfaq kartela të fshehura + + + + + + Hide file extension when rename + Fshih zgjatim kartele, kur riemërtohet + + + + + + Advanced + Të mëtejshme + + + + + + Index + Tregues + + + + + + Auto index internal disk + Vetëindekso disqe të brendshëm + + + + + + Index external storage device after connected to computer + Indekso pajisje të jashtme depozitimi pas lidhjes me kompjuterin + + + + + + Full-Text search + Kërkim në Krejt Tekstin + + + + + + Show item counts and sizes in the path of mounted MTP devices + Shfaq numër dhe madhësi objektesh te shtegu i pajisjeve MTP të montuara + + + + + + Keep showing the mounted Samba shares + Vazhdo të shfaqësh ndarje Samba të montuara + + + + + + Use the file chooser dialog of File Manager + Përdorni dialogun e zgjedhjes së kartelave të Përgjegjësit të Kartelave + + + + + + Ask for my confirmation when deleting files + Kërko ripohim prej meje, kur fshihen kartela + + + + + + Other + Tjetër + + + + + + Hide system disk + Fshih disk sistemi + + + + + + Show file system on disk icon + Shfaq sistem kartelash në ikonë disku + + + + + + Show hidden files in search results + Shfaq kartela të fshehura në përfundime kërkimi + + + + + + Display recent file entry in left panel + Shfaq te paneli majtas zë kartele së fundi + + + + + + Preview + Paraparje + + + + + Compress file preview + Ngjesh paraparje kartele + + + + + + Text preview + Paraparje teksti + + + + + + Document preview + Paraparje dokumenti + + + + + + Image preview + Paraparje figure + + + + + + Video preview + Paraparje e videos + + + + + + Mount + Montoje + + + + + + Auto mount + Vetëmontim + + + + + + Open after auto mount + Hape pas vetëmontimi + + + + + + Dialog + Dialog + + + + Compressed file preview + U ngjesh paraparje kartele + + + + GvfsMountManager + + + Can’t verify the identity of %1. + S’verifikohet dot identiteti i %1. + + + + This happens when you log in to a computer the first time. + Kjo ndodh kur bëni hyrjen për herë të parë në një kompjuter. + + + + The identity sent by the remote computer is + Identiteti i dërguar nga kompjuteri i largët është + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Nëse doni të jeni absolutisht i sigurt se, të vazhdohet, është pa rrezik, lidhuni me përgjegjësin e sistemit. + + + + + + + + Mounting device error + Gabim montimi pajisjeje + + + + + Wrong username or password + Emër përdoruesi ose fjalëkalim i gabuar + + + + + + + + Confirm + button + Ripohojeni + + + + + Cannot find the mounted device + S’gjendet pajisje e montuar + + + + No key available to unlock device + S’ka kyç të gatshëm për shkyçje të pajisjes + + + + The disk is mounted by user "%1", you cannot unmount it. + Disku është montuar nga përdoruesi "%1", s’mund të çmontoni. + + + + Cannot unmount the device + Nuk çmontohet dot pajisja + + + + Cannot eject the device "%1" + S’nxirret dot pajisja "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + S’arrihet të shkruhet. S’ka hapësirë të mjaftueshme te disku i synuar. + + + + MergedDesktopController + + + + Pictures + Foto + + + + + Music + Muzikë + + + + + Applications + Aplikacione + + + + + Videos + Video + + + + + Documents + Dokumente + + + + + Others + Të tjera + + + + MimeTypeDisplayManager + + + + Directory + Drejtori + + + + + + Application + Aplikacion + + + + + + Video + Video + + + + + + Audio + Audio + + + + + + Image + Figurë + + + + + Archive + Arkiv + + + + + + Text + Tekst + + + + + Executable + E ekzekutueshme + + + + + Backup file + Kartelë kopjeruajtje + + + + + Unknown + I panjohur + + + + MountAskPasswordDialog + + + Cancel + button + Anuloje + + + + Connect + button + Lidhu + + + + Log in as + Hyni si + + + + Anonymous + I paemër + + + + Registered user + Përdorues i regjistruar + + + + Username + Emër përdoruesi + + + + Domain + Përkatësi + + + + Password + Fjalëkalim + + + + Remember password + Mbaje mend fjalëkalimin + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Anuloje + + + + Unlock + button + Shkyçe + + + + Input password to decrypt the disk + Që të shfshehtëzohet disku, jepni fjalëkalimin + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Jeni i sigurt se doni të fshihet përgjithmonë %1? + + + + This file is too big for the trash + Kjo kartelë është shumë e madhe për hedhurinat + + + + The files are too big for the trash + Tejtëdhëna shumë të mëdha + + + + Are you sure you want to permanently delete %1 files? + Jeni i sigurt se doni të fshihen përgjithmonë %1 kartela? + + + + Cancel + button + Anuloje + + + + Delete + button + Fshije + + + + OpenWithDialog + + + Open with + Hape me + + + + Add other programs + Shtoni programe të tjerë + + + + Set as default + Caktojeni si parazgjedhje + + + + Cancel + button + Anuloje + + + + Confirm + button + Ripohojeni + + + + Recommended Applications + Aplikacione të Rekomanduara + + + + Other Applications + Aplikacione të Tjera + + + + PathManager + + + Home + Shtëpia + + + + Desktop + Desktop + + + + Videos + Video + + + + Music + Muzikë + + + + Pictures + Foto + + + + Documents + Dokumente + + + + Downloads + Shkarkime + + + + + Trash + Hedhurina + + + + + + System Disk + Disk Sistemi + + + + Computers in LAN + Kompjuter në LAN + + + + My Shares + Ndarjet e Mia + + + + Computer + Kompjuter + + + + Recent + Së fundi + + + + File Vault + Kasafortë Kartelash + + + + PropertyDialog + + + Basic info + Të dhëna elementare + + + + Open with + Hape me + + + + Sharing + Ndarje me të tjerët + + + + Permissions + Leje + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Fshihe këtë dosje + + + + Hide this file + Fshihe këtë kartelë + + + + Allow to execute as program + Lejo të ekzekutohet si program + + + + QObject + + + + + + Size + Madhësi + + + + + + Contains + Përmban + + + + + + Type + Lloj + + + + + + + + Time modified + Kohë kur u ndryshua + + + + Free space + Hapësirë e lirë + + + + Total space + Hapësirë gjithsej + + + + + Time locked + Kyçur me kohë + + + + Access denied + Hyrja u mohua + + + + + Executable + E ekzekutueshme + + + + + Write only + Vetëm shkrim + + + + + Read only + Vetëm lexim + + + + + Read-write + Lexim-shkrim + + + + Others + Të tjera + + + + Owner + Pronar + + + + Unconnected network shared directory + Drejtori e ndarë përmes rrjeti jo e lidhur + + + + Device type + Lloj pajisjeje + + + + File system + Sistem kartelash + + + + Group + Grup + + + + + Open + Hape + + + + Lock + Kyçe + + + + Auto lock + Vetëkyçu + + + + Never + Kurrë + + + + 5 minutes + 5 minuta + + + + 10 minutes + 10 minuta + + + + 20 minutes + 20 minuta + + + + Delete File Vault + Fshi Kasafortë Kartelash + + + + Unlock + Shkyçe + + + + Unlock by key + Shkyçe përmes kyçi + + + + Open + button + Hape + + + + + Size: %1 + Madhësi: %1 + + + + Type: %1 + Lloj: %1 + + + + Size: 0 + Madhësi: 0 + + + + Items: %1 + Objekte: %1 + + + + + + + + + + Open in new window + Hape në dritare të re + + + + + + + + + + Open in new tab + Hape në skedë të re + + + + Open with + Hape me + + + + + Compress + Ngjeshe + + + + Extract + Përfto + + + + Extract here + Përftoje këtu + + + + Cut + Prije + + + + Copy + Kopjoje + + + + Paste + Ngjite + + + + + + + + Rename + Riemërtoni + + + + + + + Remove + Hiqe + + + + Create link + Krijo lidhje + + + + Send to desktop + Dërgoje në desktop + + + + Send to + Dërgoje te + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Shtoni faqerojtës + + + + + + + Properties + Veti + + + + New folder + Dosje e re + + + + New window + Dritare e re + + + + Select all + Përzgjidhi krejt + + + + + Clear recent history + Spastro historik së fundi + + + + + + Empty Trash + Zbraz Hedhurinat + + + + Display as + Shfaqe si + + + + Sort by + Renditi sipas + + + + New document + Dokument i ri + + + + + Time created + Kohë kur u krijua + + + + + + Source path + Shteg burimi + + + + Share folder + Dosje ndarjesh + + + + Cancel sharing + Anuloje ndarjen me të tjerët + + + + Connect to Server + Lidhu te Shërbyesi + + + + Set share password + Caktoni fjalëkalim ndarjeje + + + + Format + Format + + + + Tag information + Të dhëna etikete + + + + Open as administrator + Hapeni si përgjegjës + + + + Select default program + Përzgjidhni program parazgjedhje + + + + Open file location + Hap vendndodhje kartele + + + + Remove bookmark + Hiqe faqerojtësin + + + + + + Delete + Fshije + + + + Office Text + Tekst Zyrash + + + + Spreadsheets + Fletëllogaritje + + + + Plain Text + Tekst i Thjeshtë + + + + Open in terminal + Hape në terminal + + + + Restore + Riktheje + + + + Restore all + Riktheji krejt + + + + Clear saved password and unmount + Spastro fjalëkalimin e ruajtur dhe çmontoje + + + + File Vault + Kasafortë Kartelash + + + + Add to disc + Shtoje në disk + + + + Refresh + Rifreskoje + + + + Auto mount + Vetëmontoje + + + + Open after auto mount + Hape pas vetëmontimi + + + + + Mount + Montoje + + + + + Unmount + Çmontoje + + + + It does not support burning %1 discs + Nuk mbulohet shkrim disqesh %1 + + + + Burn + Shkruaje + + + + Disc name: + Emër disku: + + + + + Maximum + Maksimum + + + + Allow files to be added later + Lejo shtim kartelash më vonë + + + + Verify data + Verifikoni Shkarkime](verify-downloads): Verifikoni pacenueshmëri të dhënash të shkarkimeve + + + + Write speed: + Shpejtësi shkrimi: + + + + + + + Cancel + button + Anuloje + + + + Burn + button + Shkruaje + + + + + Eject + Nxirre + + + + Safely Remove + Hiqeni Pa Rrezik + + + + + Name + Emër + + + + Settings + Rregullime + + + + Exit + Dalje + + + + Icon + Ikonë + + + + List + Listë + + + + Extend + Zgjeroje + + + + Set as wallpaper + Vëre si sfond + + + + + + + Local disk + Disk vendor + + + + + Removable disk + Disk i heqshëm + + + + + + Network shared directory + Drejtori e përbashkët në rrjet + + + + + Android mobile device + Pajisje celulare Android + + + + + Apple mobile device + Pajisje celulare Apple + + + + + Camera + Kamerë + + + + + DVD + DVD + + + + + Unknown device + Pajisje e panjohur + + + + + + %1 item + %1 objekt + + + + + + %1 items + %1 objekte + + + + Shortcut + Shkurtore + + + + Create symlink + Krijo simlidhje + + + + Path + Shteg + + + + + + Time deleted + Kohë fshirjeje + + + + Loading... + Po ngarkohet… + + + + File has been moved or deleted + Kartela është lëvizur ose fshirë + + + + You do not have permission to traverse files in it + S’keni leje për të kaluar kartela në të + + + + + + You do not have permission to access this folder + S’keni leje të hyni te kjo dosje + + + + + + + + Folder is empty + Dosja është e zbrazët + + + + Searching... + Po kërkohet… + + + + No results + S’ka përfundime + + + + Source Path + TrashFileInfo + Shteg Burimi + + + + Document + Dokument + + + + Spreadsheet + Fletëllogaritje + + + + + Presentation + Paraqitje + + + + Text + Tekst + + + + 1 task in progress + 1 punë në përmbushje e sipër + + + + %1 tasks in progress + %1 punë në përmbushje e sipër + + + + Mode: + Mënyrë: + + + + + Replace Text + Zëvendësoni Tekst + + + + + Add Text + Shtoni Tekst + + + + + Custom Text + Tekst Vetjak + + + + Find: + Gjej: + + + + Replace: + Zëvendëso: + + + + + Optional + Opsionale + + + + Add: + Shtoni: + + + + Location: + Vendndodhje: + + + + File name: + Emër kartele: + + + + Start at: + Fillo në: + + + + + Rename + button + Riemërtoni + + + + + + + + + + + Required + E domosdoshme + + + + + Before file name + Para emri kartele + + + + + After file name + Pas emri kartele + + + + Find + Gjej + + + + Replace + Zëvendësoje + + + + Add + Shto + + + + Start at + Fillo në + + + + + + Location + Vendndodhje + + + + File name + Emër kartele + + + + Dimension + Përmasë + + + + Duration + Kohëzgjatje + + + + Tips: Sort by selected file order + Ndihmëza: Renditi sipas rendit të përzgjedhur kartelash + + + + Rename %1 Files + Riemërtoni %1 Kartela + + + + Multiple Files + Disa Kartela Njëherësh + + + + Basic info + Të dhëna elementare + + + + Total size + Madhësi gjithsej + + + + Number of files + Numër kartelash + + + + %1 file(s), %2 folder(s) + %1 kartelë(a), %2 dosje(e) + + + + + + Time accessed + Hapur më + + + + Orange + Portokalli + + + + Red + E kuqe + + + + Purple + E purpurt + + + + Navy-blue + Blu e errët + + + + Azure + E kaltër + + + + Green + E gjelbër + + + + Yellow + E verdhë + + + + Gray + Gri + + + + Input tag info, such as work, family. A comma is used between two tags. + Futni info etikete, bie fjala, pune, familje. Ndajini etiketat me presje. + + + + Bookmarks + Faqerojtës + + + + Erase + Fshije + + + + Copy path + Kopjo shtegun + + + + Edit address + Përpunoni adresë + + + + Free Space %1 + Hapësirë e Lirë %1 + + + + Files are being processed + Kartelat po përpunohen + + + + + Unknown + E panjohur + + + + My Vault + Kasaforta Ime + + + + + Failed to create file info + S’u arrit të krijohet informacion rreth kartelës + + + + Failed to create file handler + S’u arrit të krijohej trajtues kartele + + + + Failed to open the file, cause: %1 + S’u arrit të hapej kartela, shkaku: %1 + + + + Original file does not exist + Kartela origjinale s’ekziston + + + + Do you want to delete %1? + Doni të fshihet %1? + + + + Confirm + button + Ripohojeni + + + + + + + + %1 are not allowed + Nuk lejohen %1 + + + + + Failed to start Samba services + S’u arrit të niseshin shërbime Samba + + + + RecentController + + + Cancel + button + Anuloje + + + + Remove + button + Hiqe + + + + Do you want to remove this item? + Doni të hiqet ky objekt? + + + + Do yout want to remove %1 items? + Doni të hiqen %1 objekte? + + + + It does not delete the original files + Kjo nuk sjell fshirjen e kartelave origjinale + + + + ShareInfoFrame + + + Share this folder + Ndajeni këtë dosje me të tjerë + + + + Share name: + Emër pjese: + + + + Permission: + Leje: + + + + Read and write + Lexim dhe shkrim + + + + Read only + Vetëm për lexim + + + + Anonymous: + I paemër: + + + + Not allow + Mos e lejo + + + + Allow + Lejoje + + + + The share name must not be two dots (..) or one dot (.) + Emri i ndarjes s’duhet të jetë dy pika (..) ose një pikë (.) + + + + The share name is used by another user. + Emri i ndarjes është i përdorur nga tjetër përdorues + + + + OK + button + OK + + + + Cancel + button + Anuloje + + + + Replace + button + Zëvendësoje + + + + The share name already exists. Do you want to replace the shared folder? + Emri i ndarjes ekziston tashmë. Doni të zëvendësohet dosja e ndarë? + + + + Shortcut + + + Item + Objekt + + + + Select to the first item + Përzgjidh deri te elementi i parë + + + + Shift + Home + Shift + Home + + + + Select to the last item + Përzgjidh deri te elementi i fundit + + + + Shift + End + Shift + End + + + + Select leftwards + Përzgjidh majtas + + + + Shift + Left + Shift + Left + + + + Select rightwards + Përzgjidh djathtas + + + + Shift + Right + Shift + Right + + + + Select to upper row + Përzgjidh deri rreshti i sipërm + + + + Shift + Up + Shift + Up + + + + Select to lower row + Përzgjidh deri te rreshti i poshtëm + + + + Shift + Down + Shift + Down + + + + Open + Hap + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + Te drejtoria mëmë + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Fshije përgjithmonë + + + + Shift + Delete + Shift + Delete + + + + Delete file + Fshije kartelën + + + + Delete + Fshije + + + + Select all + Përzgjidhi krejt + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Kopjoje + + + + Cut + Prije + + + + Paste + Ngjite + + + + Rename + Riemërtoni + + + + F2 + F2 + + + + New/Search + E re/Kërkim + + + + New window + Dritare e re + + + + New folder + Dosje e re + + + + + Search + Kërkoje + + + + New tab + Skedë e re + + + + View + Shihni + + + + Item information + Të dhëna objekti + + + + Help + Ndihmë + + + + F1 + F1 + + + + Keyboard shortcuts + Shkurtore tastiere + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Këmbe gjendje ekrani + + + + Hide item + Fshihe objektin + + + + Input in address bar + Dhënie te shtyllë adrese + + + + Switch to icon view + Kalo te pamja ikona + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Kalo te pamja listë + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Të tjerë + + + + Close + Mbylle + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Mbyll skedën e tanishme + + + + Back + Mbrapsht + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Kalo te skeda pasuese + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Kalo te skeda e mëparshme + + + + Next file + Kartela pasuese + + + + Tab + Tab + + + + Previous file + Kartela e mëparshme + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Kaloni nga një skedë në tjetër, përmes numri të dhënë nga 1 deri në 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Përpara + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + S’arrihet të hapen objekte te hedhurinat, ju lutemi, së pari rikthejini + + + + TrashPropertyDialog + + + Trash + Hedhurina + + + + item + objekt + + + + items + objekte + + + + Contains %1 %2 + Përmban %1 %2 + + + + UDiskListener + + + Failed to rename the label + S’u arrit të riemërtohej etiketa + + + + UnmountWorker + + + + + The device was not safely unmounted + Pajisja s’u çmontua në mënyrë të parrezik + + + + The device was not safely removed + Pajisja s’u hoq në mënyrë të parrezik + + + + UserShareManager + + + Kindly Reminder + Kujtues i Sjellshëm + + + + Please firstly install samba to continue + Ju lutemi, që të vazhdohet, së pari instaloni Samba-n + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + Emri i pjesë s’duhet të përmbajë %<>*?|/\+=;:," dhe s’duhet të fillojë me %1 + + + + To protect the files, you cannot share this folder. + Që të mbrohen kartelat, s’mund ta ndani këtë dosje me të tjerë. + + + + Sharing failed + Ndarja me të tjerë dështoi + + + + The computer name is too long + Emri i kompjuterit është shumë i gjatë + + + + You do not have permission to operate file/folder! + S’keni leje të bëni veprime në kartelë/dosje! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Jepni një fjalëkalim që të mbrohen dosje të ndara + + + + Cancel + button + Anuloje + + + + Confirm + button + Ripohojeni + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sr.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sr.ts new file mode 100644 index 0000000..171c0c7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sr.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Нова фасцикла + + + + Mounting device error + Грешка монтирања уређаја + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Одраз диска је оштећен, тренутно се не може монтирати. Прво обришите диск. + + + + Mount error: unsupported image format + Грешка монтирања: неподржан формат одраза + + + + + The device was not safely removed + Уређај није безбедно уклоњен + + + + + Click "Safely Remove" and then disconnect it next time + Следећи пут, кликните на "Безбедно уклони", затим уклоните уређај + + + + The device was not ejected + Уређај није избачен + + + + Disk is busy, cannot eject now + Диск је у употреби, тренутно се не може избацити + + + + Authentication timed out + Време за идентификацију је истекло + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Блутут пренос датотека + + + + File Transfer Successful + Успешан пренос датотека + + + + File Transfer Failed + Неуспешан пренос датотека + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Слање датотека за "<b style="font-weight: 550;">%1</b>" + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Неуспешно слање датотека за "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Успешно послато за "<b style="font-weight: 550;">%1</b>" + + + + Select a Bluetooth device to receive files + Изабери блутут уређај да преузмеш датотеке + + + + Cannot find the connected Bluetooth device + Не могу да пронађем повезани блутут уређај + + + + Waiting to be received... + Чека се пријем... + + + + Go to Bluetooth Settings + Иди у блутут подешавања + + + + %1/%2 Sent + %1/%2 послато + + + + Error: the Bluetooth device is disconnected + Грешка: Блутут уређај није повезан + + + + Unable to send the file more than 2 GB + Није могуће послати датотеке веће од 2 GB + + + + Unable to send 0 KB files + Није могуће послати датотеке од 0 KB + + + + File doesn't exist + Датотека не постоји + + + + Next + button + Следеће + + + + Cancel + button + Откажи + + + + Done + button + Готово + + + + Retry + button + Понови + + + + OK + button + У реду + + + + File sending request timed out + Захтев за слање датотека је истекао + + + + The service is busy and unable to process the request + Услуга је заузета и не може да обради захтев + + + + BurnOptDialog + + + Device error + Грешка уређаја + + + + Optical device %1 doesn't exist + Отички уређај %1 не постоји + + + + Advanced settings + Напредна подешавања + + + + File system: + Систем датотека: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (За Виндоуз) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (За Јуникс) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Усаглашено са Windows ЦД/ДВД режимом) + + + + ISO9660 Only + ISO9660 Искључиво + + + + CloseAllDialogIndicator + + + Close all + Затвори све + + + + Total size: %1, %2 files + Укупна величина: %1, %2 датотека/е + + + + ComputerModel + + + Double click to open it + + + + + My Directories + Моји директоријуми + + + + Disks + Дискови + + + + File Vault + Трезор датотека + + + + Quick Access + + + + + ComputerPropertyDialog + + + Computer + Рачунар + + + + Basic Info + Основни подаци + + + + + Computer Name + Име рачунара + + + + + Edition + Издање + + + + + + Version + Верзија + + + + + Type + Врста + + + + + + Processor + Процесор + + + + + + Memory + Меморија + + + + + + + Bit + Бит + + + + + Available + Слободно + + + + Obtaining... + Прибављање... + + + + ConnectToServerDialog + + + Connect to Server + Повежи се са сервером + + + + Cancel + button + Откажи + + + + Connect + button + Повежи + + + + My Favorites: + Моји омиљени: + + + + + Clear History + Очисти историју + + + + DFMAddressBar + + + Search or enter address + Претражи или унеси адресу + + + + DFMAdvanceSearchBar + + + Search: + Претражи: + + + + File Type: + Врста датотеке: + + + + File Size: + Величина датотеке: + + + + Time Modified: + Измењено: + + + + Time Accessed: + Приступљено: + + + + Time Created: + Настало: + + + + Reset + Поништи + + + + All subdirectories + Сви под-директоријуми + + + + Current directory + Тренутни директоријум + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Данас + + + + Yesterday + Јуче + + + + This week + Ове недеље + + + + Last week + Прошле недеље + + + + This month + Овог месеца + + + + Last month + Прошлог месеца + + + + This year + Ове године + + + + Last year + Прошле године + + + + DFMOpticalMediaWidget + + + + No files to burn + Нема датотека за нарезивање + + + + Unable to burn. Not enough free space on the target disk. + Немогуће нарезати. Недовољно простора на одредишном диску. + + + + %1 burning is not supported + %1 нарезивање није подржано + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. Није %1 диск; +2. Верзија тренутног система датотека још увек не подржава додавање датотека. + + + + DFMTagCrumbController + + + Tag information + Означи + + + + DFMTagWidget + + + Tag + Ознака + + + + DFMTaskWidget + + + Do not ask again + Не питај ме поново + + + + Syncing data + Синхронизовање података + + + + Please wait + Молимо сачекајте + + + + + Time modified: %1 + Измењено:%1 + + + + + Contains: %1 + Садржи: %1 + + + + + Size: %1 + Величина: %1 + + + + Original folder + Првобитна фасцикла + + + + Keep both + button + Задржи оба + + + + Skip + button + Прескочи + + + + Replace + button + Замени + + + + Retry + button + Понови + + + + Original file + Првобитна датотека + + + + Target folder + Одредишна фасцикла + + + + Target file + Одредишна датотека + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Шифруј трезор датотека + + + + Click 'Encrypt' and input the user password. + Кликните на 'Шифруј' и унесите корисничку лозинку. + + + + Encrypting... + Шифровање... + + + + + + + Encrypt + Шифруј + + + + Failed to create file vault: %1 + Неуспешно прављење трезора: %1 + + + + OK + У реду + + + + The setup is complete + Подешавање је завршено + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + + + + + Keep the key safe to retrieve the vault password later + + + + + Save to default path + + + + + Save to other locations + + + + + No permission, please reselect + + + + + Select a path + + + + + Next + Следеће + + + + The default path is invisible to other users, and the path information will not be shown. + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Кључ за опоравак + + + + Generate a recovery key in case that you forgot the password + Кључ за опоравак у случају да заборавите лозинку + + + + Key + Кључ + + + + QR code + QR код + + + + Scan QR code and save the key to another device + Очитајте QR код и сачувајте кључ на дугом уређају + + + + Next + Следеће + + + + Recovery Key: + Кључ за опоравак: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Постави лозинку трзора + + + + Method + Начин + + + + Manual + Ручно + + + + Password + Лозинка + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 карактера, садржај A-Z, a-z, 0-9, и симболи + + + + Repeat password + Понови лозинку + + + + Input the password again + Поново унесите лозинку + + + + Password hint + Подсетник лозинке + + + + Optional + Опционо + + + + Next + Следеће + + + + + Passwords do not match + Лозинке се не подударају + + + + DFMVaultActiveStartView + + + File Vault + Трезор датотека + + + + Create your secure private space + Направите Ваш приватни безбедан простор + + + + Advanced encryption technology + Напредна шифарска технологија + + + + Convenient and easy to use + Згодно и лако за употребу + + + + Create + Направи + + + + DFMVaultFileView + + + Cannot open this path + + + + + Hint + Подсетник + + + + OK + У реду + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Откључај кључем + + + + Failed to unlock file vault + Неуспешно откључавање трезора + + + + OK + У реду + + + + Input the 32-digit recovery key + Унесите 32-цифрени кључ за опоравак + + + + Cancel + button + Откажи + + + + Unlock + button + Откључај + + + + Wrong recovery key + Погрешан кључ за опоравак + + + + DFMVaultRemoveByPasswordView + + + Password + Лозинка + + + + Password hint: %1 + Подсетник лозинке: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Унесите 32-цифрени кључ за опоравак + + + + DFMVaultRemovePages + + + Delete File Vault + Обриши трезор + + + + Once deleted, the files in it will be permanently deleted + Након уклањања, биће трајно обрисане све припадајуће датотеке + + + + Use Key + Употреби кључ + + + + Cancel + button + Откажи + + + + Use Key + button + Употреби кључ + + + + Delete + button + Обриши + + + + + OK + button + У реду + + + + Use Password + Употреби лозинку + + + + Wrong password + Погрешна лозинка + + + + Wrong recovery key + Погрешан кључ за опоравак + + + + Failed to delete file vault + Неуспешно брисање трезора + + + + Deleted successfully + Успешно обрисано + + + + Failed to delete + Неуспешно брисање + + + + Removing... + Уклањање... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + + + + + Verification failed + + + + + + Select a path + + + + + + Retrieve Password + + + + + By key in the default path + + + + + By key in the specified path + + + + + Verification Successful + + + + + Keep it safe + + + + + Back + button + Назад + + + + Verify Key + button + + + + + Go to Unlock + button + + + + + Close + button + Затвори + + + + Vault password: %1 + + + + + DFMVaultUnlockPages + + + Unlock File Vault + Откључај трезор + + + + Forgot password? + + + + + Password hint: %1 + Подсетник лозинке: %1 + + + + Failed to unlock file vault + Неуспешно откључавање трезора + + + + Cancel + button + Откажи + + + + Password + Лозинка + + + + Unlock + button + Откључај + + + + Please try again %1 minutes later + + + + + Wrong password, please try again %1 minutes later + + + + + Wrong password, one chance left + + + + + Wrong password, %1 chances left + + + + + Wrong password + Погрешна лозинка + + + + OK + button + У реду + + + + DFileCopyMoveJob + + + Permission error + Грешка дозволе + + + + The action is denied + Радња је одбијена + + + + Failed to open the file + Неуспешно отварање датотеке + + + + Failed to read the file + Неуспешно читање датотеке + + + + Failed to write the file + Неуспешно уписивање датотеке + + + + Failed to create the directory + Неуспешно прављење директиријума + + + + Failed to delete the file + Неуспешно брисање датотеке + + + + Failed to move the file + Неуспешно премештање датотеке + + + + Original file does not exist + Првобитна датотека не постоји + + + + Failed, file size must be less than 4GB + Неуспех, величина датотека мора бити мања од 4GB + + + + Not enough free space on the target disk + Недовољно простора на одредишном диску + + + + File integrity was damaged + Интегритет датотеке оштећен + + + + The target device is read only + Одредишни уређај је само за читање + + + + Target folder is inside the source folder + Одредишна фасцикла је унутар изворне фасцикле + + + + The action is not supported + Ова радња није подржана + + + + You do not have permission to traverse files in it + Немате дозволу да пролазите датотеке које садржи + + + + Failed to position the file pointer! + + + + + copy + Extra name added to new file name when used for file name. + Копија + + + + Failed to open the directory, cause: file name too long + Неуспешно отварање дир, узрок: Предугачко име датотеке + + + + + Failed to open the file, cause: file name too long + Неуспешно отварање датотеке, узрок: Предугачко име датотеке + + + + + Failed to write the file, cause: + Неуспешно уписивање датотеке, узрок: + + + + Failed to position the file pointer, cause: %1 + + + + + Syncing data + Синхронизовање података + + + + Please wait + Молимо сачекајте + + + + Failed to create the directory, cause: %1 + Неуспешно прављење директиријума, узрок: %1 + + + + + + + + Failed to open the file, cause: %1 + Неуспешно отварање датотеке, узрок: %1 + + + + + + + Failed to open the file, cause: Permission denied + Неуспешно отварање датотеке, узрок: Забрањен приступ + + + + + Failed to read the file, cause: %1 + Неуспешно читање датотеке, узрок: %1 + + + + + + + Failed to write the file, cause: %1 + Неуспешно уписивање датотеке, узрок: %1 + + + + + File integrity was damaged, cause: %1 + Интегритет датотеке оштећен, узрок: %1 + + + + Failed to open the file, cause: + Неуспешно отварање датотеке, узрок: + + + + Failed to read the file, cause: + Неуспешно читање датотеке, узрок: + + + + Failed to delete the file, cause: %1 + Неуспешно брисање датотеке, узрок: %1 + + + + Fail to create symlink, cause: %1 + Неуспешно прављење симболичке везе, узрок: %1 + + + + DFileDialog + + + + Save + button + Сачувај + + + + + Cancel + button + Откажи + + + + Confirm + button + Потврди + + + + %1 already exists, do you want to replace it? + %1 већ постоји, желите ли да замените? + + + + Replace + button + Замени + + + + Open + button + Отвори + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Ова датотека ће бити сакривена ако име почиње са тачком (.). Заиста желите да је сакријете? + + + + DFileManagerWindow + + + Trash + Смеће + + + + Empty + Испразни + + + + DFileSystemModel + + + + Name + Име + + + + + + Time modified + Измењено + + + + Size + Величина + + + + Type + Врста + + + + Time created + Настало + + + + + Last access + Последњи приступ + + + + + + + Path + Путања + + + + DFileView + + + Disc mount error + Грешка при монтирању диска + + + + The disc is in use, please end the running process and remount the disc. + Диск се користи, окончајте покренуте процесе и поново монтирајте диск. + + + + Mounting failed + Неуспешно монтирање + + + + (Reverse) + (Поништи) + + + + DFileViewHelper + + + Add tag "%1" + Додај ознаку "%1" + + + + DStatusBar + + + %1 item + %1 ставка/и + + + + %1 items + %1 ставки/е + + + + %1 item selected + %1 ставка изабрана + + + + %1 items selected + %1 ставки/е изабрано + + + + %1 folder selected (contains %2) + %1 фасцикла изабрана (садржи %2 ставки) + + + + %1 folders selected (contains %2) + %1 фасцикли/е изабрано (садржај %2 ставки/е) + + + + %1 file selected (%2) + %1 датотека изабрана (%2) + + + + %1 files selected (%2) + %1 датотеке/а изабрано (%2) + + + + %1 folder selected + %1 фасцикла изабрана + + + + Filter + Филтер + + + + Save as: + Сачувај као: + + + + Loading... + Учитавање... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Брисање диска %1, молимо сачекајте... + + + + Burning disc %1, please wait... + Нарезивање диска %1, молимо сачекајте... + + + + Writing data... + Уписивање података... + + + + Verifying data... + Провера података... + + + + Copying %1 + Копирање %1 + + + + + + to %2 + у %2 + + + + %1 already exists in target folder + %1 већ постоји у фасцикли + + + + Original path %1 Target path %2 + Првобитна путања %1 Oдредишна путања %2 + + + + Merge + button + Спој + + + + Replace + button + Замени + + + + Moving %1 + Премештање %1 + + + + Removing file vault, please try later + Уклањање трезора датотека, покушајте касније + + + + Restoring %1 + Враћање %1 + + + + Deleting %1 + Брисање %1 + + + + Trashing %1 + Слање у смеће %1 + + + + Calculating space, please wait + Израчунавање простора. молимо сачекајте + + + + DUMountManager + + + + Authentication timed out + Време за идентификацију је истекло + + + + + + Disk is busy, cannot unmount now + Диск је у употреби, тренутно се не може демонтирати + + + + Disk is busy, cannot eject now + Диск је у употреби, тренутно се не може избацити + + + + The device is busy, cannot eject now + Уређај је заузет, не може се избацити + + + + + + The device is busy, cannot remove now + Уређај је заузет, не може се уклонити + + + + DeepinStorage + + + + + %1 Volume + %1 Логички диск + + + + Data Disk + Data Partition + Складиште + + + + %1 Drive + %1 Уређај + + + + Blank %1 Disc + Празан %1 диск + + + + %1 Encrypted + %1 Шифровано + + + + DialogManager + + + + + + Operation failed! + Операција неуспешна! + + + + Target folder is inside the source folder! + Одредишна фасцикла је унутар изворне фасцикле! + + + + Do you want to run %1 or display its content? + Да ли желите да покренете %1 или да прикажете садржај? + + + + It is an executable text file. + Ово је извршна текстуална датотека. + + + + It is an executable file. + Ово је извршна датотека. + + + + This file is not executable, do you want to add the execute permission and run? + Ова датотека није извршна. Желите ли да додате дозволу за извршење и покренете? + + + + "%1" already exists, please use another name. + "%1" већ постоји, молимо користите друго име. + + + + The file name must not contain two dots (..) + Име датотеке не сме садржати две тачке (..) + + + + Device or resource busy + + + + + Are you sure you want to erase all data on the disc? + Заиста желите да обришете све податке са диска? + + + + How do you want to use this disc? + Како желите да користите диск? + + + + Disc erase failed + Неуспешно брисање диска + + + + Burn process failed + Неуспешан процес нарезивања + + + + %1: %2 + %1: %2 + + + + Show details + Прикажи детаље + + + + Hide details + Сакриј детаље + + + + Error + Грешка + + + + Permanently delete %1? + Трајно обриши %1? + + + + Permanently delete %1 items? + Трајно обриши %1 ставки/е? + + + + Empty + Испразни + + + + Do you want to delete %1? + Желите ли да обришете %1? + + + + Do you want to delete the selected %1 items? + Желите ли да обришете изабране/их %1 ставке/и? + + + + Sorry, unable to locate your bookmark directory, remove it? + Жао нам је, не можемо да пронађемо путању забележеног директоријума, уколнити забелешку? + + + + Name: + Име: + + + + %1 that this shortcut refers to has been changed or moved + %1 на шта ова пречица показује је промењено или померено + + + + Do you want to delete this shortcut? + Да ли желите да обришете ову пречицу? + + + + Failed, file size must be less than 4GB. + Неуспех, величина датотека мора бити мања од 4GB + + + + Fail to create symlink, cause: + Неуспешно прављење симболичке везе, узрок: + + + + The selected files contain system file/directory, and it cannot be deleted + Изабране датотеке садрже системску датотеку или директоријум и зато се не могу обрисати + + + + Unable to find the original file + Не могу да пронађем изворну датотеку + + + + + You do not have permission to operate file/folder! + Немате дозволу за рад са датотеком/фасциклом! + + + + Failed to restore %1 file, the source file does not exist + Неуспешно враћање %1 датотеке, изворна датотека не постоји + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Нажалост немате дозволу за рад са следећим %1 датотекама/фасциклама! + + + + Unable to access %1 + Не могу да приступим %1 + + + + + Sending files now, please try later + У току је слање датотека, покушајте касније + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Да приступите уређају, морате га прво форматирати. Заиста желите да га форматирате сад? + + + + Scanning the device, stop it? + Проверавање уређаја, зауставити? + + + + Share folder can't be named after the current username + Дељена фасикла не може имати исти назив као тренуто корисничко име + + + + Do you want to run %1? + Желите да покренете %1? + + + + Burn image + button + Нарежи одраз + + + + Burn files + button + Нарежи датотеке + + + + Are you sure you want to empty %1 item? + Заиста желите да испразните %1 ставку? + + + + Are you sure you want to empty %1 items? + Заиста желите да испразните %1 ставки/е? + + + + + This action cannot be undone + Ова радња је неповратна + + + + + + + + + + + + + + OK + button + У реду + + + + + + + + + + + + + + + Cancel + button + Откажи + + + + + + Run + button + Покрени + + + + + Run in terminal + button + Покре. у терминалу + + + + Display + button + Прикажи + + + + + + + + + + + Confirm + button + Потврди + + + + Erase + button + Обриши + + + + Data verification failed + Неуспешна верификација подтака + + + + Show details + button + Прикажи детаље + + + + + Delete + button + Обриши + + + + Remove + button + Уклони + + + + Disk is busy, cannot unmount now + Диск је у употреби, тренутно се не може демонтирати + + + + Force unmount + button + Принудно демонтирај + + + + Unable to copy. Not enough free space on the target disk. + Немогуће копирати. Недовољно простора на одредишном диску. + + + + Failed to restore %1 file, the target folder is read-only + Неуспешно враћање %1 датотеке, одредишна фасцикла је само за читање + + + + Failed to restore %1 files, the target folder is read-only + Неуспешно враћање %1 датотеке/а, одредишна фасцикла је само за читање + + + + Failed to restore %1 files, the source files do not exist + Неуспешно враћање %1 датотеке/а, изворна датотека не постоји + + + + Format + button + Форматирање + + + + Stop + button + Заустави + + + + FileController + + + + + + Unable to find the original file + Не могу да пронађем изворну датотеку + + + + + + Kindly Reminder + Љубазно подсећамо + + + + + + Please install File Roller first and then continue + Прво инсталирајте Управљач Архивом па наставите + + + + + Unable to create files here: %1 + Не могу направити датотеке овде: %1 + + + + Confirm + button + Потврди + + + + FileDialogStatusBar + + + File Name + Име датотеке + + + + Format + Формат + + + + Save + button + Сачувај + + + + Open + button + Отвори + + + + Save File + button + Сачувај датотеку + + + + Open File + button + Отвори датотеку + + + + + + Cancel + button + Откажи + + + + FileJob + + + copy + Копирање + + + + + + + Data verification successful. + Успешна провера података. + + + + + + Burn process completed + Процес нарезивања завршен + + + + %1 s + %1 сек + + + + %1 m %2 s + %1 мин %2 сек + + + + %1 h %2 m %3 s + %1 час %2 мин %3 сек + + + + %1 d %2 h %3 m %4 s + %1 дан %2 час %3 мин %4 сек + + + + %1 is a duplicate file. + %1 је дупликат. + + + + Insufficient disc space. + Недовољно простора на диску. + + + + Lost connection to drive. + Прекинута веза са уређајем. + + + + The CD/DVD drive is not ready. Try another disc. + ЦД/ДВД уређај није спреман. Покушајте са другим диском. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + ЦД/ДВД уређеј је заузет. Изађите из програма за уређај и прикључите уређај поново. + + + + Unknown error + Непозната грешка + + + + Device disconnected + Веза са уређејем је прекинута + + + + GenerateSettingTranslate + + + + + Basic + Основно + + + + + + Open behavior + Начин отварања + + + + + + Always open folder in new window + Увек отварај фасцикле у новом прозору + + + + + + Open file: + Отварање датотека: + + + + + + Click + Клик + + + + + + Double click + Двоклик + + + + + + New window and tab + Нови прозор и картица + + + + + + Open from default window: + Прозор при покретању: + + + + + + + + + Computer + Рачунар + + + + + + + + + Home + Лично + + + + + + + + + Desktop + Радна површина + + + + + + + + + Videos + Видео + + + + + + + + + Music + Музика + + + + + + + + + Pictures + Слике + + + + + + + + + Documents + Документи + + + + + + + + + Downloads + Преузимања + + + + + + Open in new tab: + Отвори у новој картици: + + + + + + Current Directory + Тренутни директоријум + + + + + + View + Приказ + + + + + + Default size: + Основна величина: + + + + + + Extra small + Сићушно + + + + + + Small + Мало + + + + + + Medium + Средње + + + + + + Large + Велико + + + + + + Extra large + Огромно + + + + + + Default view: + Основни приказ: + + + + + + Icon + Иконице + + + + + + List + Списак + + + + + + Hidden files + Скривене датотеке + + + + + + Show hidden files + Прикажи скривене датотеке + + + + + + Hide file extension when rename + Сакриј проширење датотеке при преименовању + + + + + + Advanced + Напредно + + + + + + Index + Индекс + + + + + + Auto index internal disk + Аутоматски индексирај унутрашњи диск + + + + + + Index external storage device after connected to computer + Индексирај спољашње уређаје након повезивања + + + + + + Full-Text search + Претрага целокупног текста + + + + + + Show item counts and sizes in the path of mounted MTP devices + Прикажи број ставки и величину на путањи монтираних МТП уређаја + + + + + + Keep showing the mounted Samba shares + + + + + + + Use the file chooser dialog of File Manager + Користи дијалог за одабир датотека Управника Података + + + + + + Ask for my confirmation when deleting files + Питај за потврду када се бришу подаци + + + + + + Other + Остало + + + + + + Hide system disk + Сакриј системски диск + + + + + + Show file system on disk icon + Прикажи систем датотека на диску + + + + + + Show hidden files in search results + Прикажи скривене датотеке у резултатима претраге + + + + + + Display recent file entry in left panel + Прикажи недавне датотеке у левом панелу + + + + + + Preview + Преглед + + + + + Compress file preview + Преглед запакованих датотека + + + + + + Text preview + Преглед текста + + + + + + Document preview + Преглед докумената + + + + + + Image preview + Преглед слика + + + + + + Video preview + Преглед видеа + + + + + + Mount + Монтирање + + + + + + Auto mount + Самомонтирај + + + + + + Open after auto mount + Отвори након самомонтирања + + + + + + Dialog + Дијалог + + + + Compressed file preview + Преглед запакованих датотека + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Немогуће потврдити идентитет %1. + + + + This happens when you log in to a computer the first time. + Ово се дешава када се први пут пријавите на рачунар. + + + + The identity sent by the remote computer is + Идентитет послат од удаљеног рачунара је + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Ако желите да будете сигурни да је безбедно наставити, контактирајте администратора. + + + + + + + + Mounting device error + Грешка монтирања уређаја + + + + + Wrong username or password + Погрешно корисничко име или лозинка + + + + + + + + Confirm + button + Потврди + + + + + Cannot find the mounted device + Не могу да пронађем монтирани уређај + + + + No key available to unlock device + Нема кључа за откључавање уређаја + + + + The disk is mounted by user "%1", you cannot unmount it. + Диск је монтирао корисник "%1", не можете га демонтирати. + + + + Cannot unmount the device + Не могу да демонтирам уређај + + + + Cannot eject the device "%1" + Не могу да избацим уређај "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Немогуће нарезати. Недовољно простора на одредишном диску. + + + + MergedDesktopController + + + + Pictures + Слике + + + + + Music + Музика + + + + + Applications + Програми + + + + + Videos + Видео + + + + + Documents + Документи + + + + + Others + Остало + + + + MimeTypeDisplayManager + + + + Directory + Директоријум + + + + + + Application + Програм + + + + + + Video + Видео + + + + + + Audio + Звук + + + + + + Image + Слика + + + + + Archive + Архива + + + + + + Text + Текст + + + + + Executable + Извршна + + + + + Backup file + Резерва + + + + + Unknown + Непознато + + + + MountAskPasswordDialog + + + Cancel + button + Откажи + + + + Connect + button + Повежи + + + + Log in as + Пријави се као + + + + Anonymous + Анониман + + + + Registered user + Регистрован + + + + Username + Корисничко име + + + + Domain + Домен + + + + Password + Лозинка + + + + Remember password + Запамти лозинку + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Откажи + + + + Unlock + button + Откључај + + + + Input password to decrypt the disk + Унесите лозинку за дешифровање диска + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Заиста желите да трајно обришете %1? + + + + This file is too big for the trash + Ова датотека је превелика за смеће + + + + The files are too big for the trash + Датотеке су превелике за смеће + + + + Are you sure you want to permanently delete %1 files? + Заиста желите да трајно обришете %1 датотеке? + + + + Cancel + button + Откажи + + + + Delete + button + Обриши + + + + OpenWithDialog + + + Open with + Отвори са + + + + Add other programs + Додај још програма + + + + Set as default + Постави као основни + + + + Cancel + button + Откажи + + + + Confirm + button + Потврди + + + + Recommended Applications + Препоручени програми + + + + Other Applications + Други програми + + + + PathManager + + + Home + Лично + + + + Desktop + Радна површина + + + + Videos + Видео + + + + Music + Музика + + + + Pictures + Слике + + + + Documents + Документи + + + + Downloads + Преузимања + + + + + Trash + Смеће + + + + + + System Disk + Системски диск + + + + Computers in LAN + Рачунари у ЛАН-у + + + + My Shares + Моја дељења + + + + Computer + Рачунар + + + + Recent + Недавно + + + + File Vault + Трезор датотека + + + + PropertyDialog + + + Basic info + Основни подаци + + + + Open with + Отвори са + + + + Sharing + Дељење + + + + Permissions + Дозволе + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Сакриј фасциклу + + + + Hide this file + Сакриј датотеку + + + + Allow to execute as program + Дозволи покретање као програм + + + + QObject + + + + + + Size + Величина + + + + + + Contains + Садржи + + + + + + Type + Врста + + + + + + + + Time modified + Измењено + + + + Free space + Слободно + + + + Total space + Укупан простор + + + + + Time locked + Закључано + + + + Access denied + Забрањен приступ + + + + + Executable + Извршна + + + + + Write only + Само уписивање + + + + + Read only + Само читање + + + + + Read-write + Читање-уписивање + + + + Others + Остали + + + + Owner + Власник + + + + Unconnected network shared directory + + + + + Device type + Врста уређаја + + + + File system + Систем датотека + + + + Group + Група + + + + + Open + Отвори + + + + Lock + Зкључај + + + + Auto lock + Самозакључавање + + + + Never + Никад + + + + 5 minutes + 5 минута + + + + 10 minutes + 10 минута + + + + 20 minutes + 20 минута + + + + Delete File Vault + Обриши трезор + + + + Unlock + Откључај + + + + Unlock by key + Откључај кључем + + + + Open + button + Отвори + + + + + Size: %1 + Величина: %1 + + + + Type: %1 + Врста: %1 + + + + Size: 0 + Величина: 0 + + + + Items: %1 + Ставки: %1 + + + + + + + + + + Open in new window + Отвори у новом прозору + + + + + + + + + + Open in new tab + Отвори у новој картици + + + + Open with + Отвори са + + + + + Compress + Запакуј + + + + Extract + Распакуј + + + + Extract here + Распакуј овде + + + + Cut + Исеци + + + + Copy + Копирај + + + + Paste + Убаци + + + + + + + + Rename + Преименуј + + + + + + + Remove + Уклони + + + + Create link + Направи везу + + + + Send to desktop + Пошаљи на радну површину + + + + Send to + Пошаљи у + + + + Bluetooth + Блутут + + + + Add to bookmark + Додај у забелешке + + + + + + + Properties + Својства + + + + New folder + Нова фасцикла + + + + New window + Нови прозор + + + + Select all + Изабери све + + + + + Clear recent history + Очисти недавну историју + + + + + + Empty Trash + Испразни смеће + + + + Display as + Прикажи као + + + + Sort by + Поређај по + + + + New document + Нови документ + + + + + Time created + Настало + + + + + + Source path + Путања + + + + Share folder + Дели фасциклу + + + + Cancel sharing + Откажи дељење + + + + Connect to Server + Повежи се са сервером + + + + Set share password + Постави лозинку дељењa + + + + Format + Форматирај + + + + Tag information + Означи + + + + Open as administrator + Отвори као адмнистратор + + + + Select default program + Изабери подразумевани програм + + + + Open file location + Отвори локацију датотеке + + + + Remove bookmark + Уклони забелешку + + + + + + Delete + Обриши + + + + Office Text + Канцеларијски текст + + + + Spreadsheets + Табела + + + + Plain Text + Обичан текст + + + + Open in terminal + Отвори у терминалу + + + + Restore + Врати + + + + Restore all + Врати све + + + + Clear saved password and unmount + + + + + File Vault + Трезор датотека + + + + Add to disc + Додај на диск + + + + Refresh + + + + + Auto mount + Самомонтирај + + + + Open after auto mount + Отвори након самомонтирања + + + + + Mount + Монтирај + + + + + Unmount + Демонтирај + + + + It does not support burning %1 discs + Није подржано нарезивање %1 дискова + + + + Burn + Нарежи + + + + Disc name: + Име диска: + + + + + Maximum + Максимум + + + + Allow files to be added later + Дозволи да се накнадно додају датотеке + + + + Verify data + Провери податке + + + + Write speed: + Брзина уписивања: + + + + + + + Cancel + button + Откажи + + + + Burn + button + Нарежи + + + + + Eject + Избаци + + + + Safely Remove + Безбедно уклони + + + + + Name + Име + + + + Settings + Подешавања + + + + Exit + Изађи + + + + Icon + Иконице + + + + List + Списак + + + + Extend + Прошири + + + + Set as wallpaper + Постави као позадину + + + + + + + Local disk + Локални диск + + + + + Removable disk + Уклоњиви диск + + + + + + Network shared directory + Мрежно дељени директоријум + + + + + Android mobile device + Андроид мобилни уређај + + + + + Apple mobile device + Apple мобилни уређај + + + + + Camera + Камера + + + + + DVD + ДВД + + + + + Unknown device + Непознат уређај + + + + + + %1 item + %1 ставка/и + + + + + + %1 items + %1 ставки/е + + + + Shortcut + Пречица + + + + Create symlink + Направи симболичку везу + + + + Path + Путања + + + + + + Time deleted + Обрисано + + + + Loading... + Учитавање... + + + + File has been moved or deleted + Датотека је премештена или обрисана + + + + You do not have permission to traverse files in it + Немате дозволу да пролазите датотеке које садржи + + + + + + You do not have permission to access this folder + Немате дозволу да приступите овој фасцикли + + + + + + + + Folder is empty + Фасцикла је празна + + + + Searching... + Претрага... + + + + No results + Нема резултата + + + + Source Path + TrashFileInfo + Путања + + + + Document + Документ + + + + Spreadsheet + Табела + + + + + Presentation + Презентација + + + + Text + Текст + + + + 1 task in progress + 1 задатак у току + + + + %1 tasks in progress + %1 задатака у току + + + + Mode: + Режим: + + + + + Replace Text + Замени текст + + + + + Add Text + Додај текст + + + + + Custom Text + Прилагођен текст + + + + Find: + Пронађи: + + + + Replace: + Замени: + + + + + Optional + Опционо + + + + Add: + Додај: + + + + Location: + Локација: + + + + File name: + Име датотеке: + + + + Start at: + Почни од: + + + + + Rename + button + Преименуј + + + + + + + + + + + Required + Обавезно + + + + + Before file name + Пре имена датотеке + + + + + After file name + После имена датотеке + + + + Find + Пронађи + + + + Replace + Замени + + + + Add + Додај + + + + Start at + Почни од + + + + + + Location + Локација + + + + File name + Име датотеке + + + + Dimension + Димензије + + + + Duration + Трајање + + + + Tips: Sort by selected file order + Савет: Поређај по изабраном редоследу датотека + + + + Rename %1 Files + Преименуј %1 датотеке/а + + + + Multiple Files + Више датотека + + + + Basic info + Основни подаци + + + + Total size + Укупна величина + + + + Number of files + Број датотека + + + + %1 file(s), %2 folder(s) + %1 датотеке(а), %2 фасцикле(и) + + + + + + Time accessed + Приступљено + + + + Orange + Наранџаста + + + + Red + Црвена + + + + Purple + Љубичаста + + + + Navy-blue + Плава + + + + Azure + Азурна + + + + Green + Зелена + + + + Yellow + Жута + + + + Gray + Сива + + + + Input tag info, such as work, family. A comma is used between two tags. + Унеси податке ознаке, нпр. посао, породица. Зарез одваја две ознаке. + + + + Bookmarks + Забелешке + + + + Erase + Обриши + + + + Copy path + Копирај путању + + + + Edit address + Уреди адресу + + + + Free Space %1 + Слободан простор %1 + + + + Files are being processed + Датотеке се обрађују + + + + + Unknown + Непознато + + + + My Vault + Мој трезор + + + + + Failed to create file info + Стварање података о датотеци није успело + + + + Failed to create file handler + Стварање обрађивача датотека није успело + + + + Failed to open the file, cause: %1 + Неуспешно отварање датотеке, узрок: %1 + + + + Original file does not exist + Првобитна датотека не постоји + + + + Do you want to delete %1? + Желите ли да обришете %1? + + + + Confirm + button + Потврди + + + + + + + + %1 are not allowed + + + + + + Failed to start Samba services + + + + + RecentController + + + Cancel + button + Откажи + + + + Remove + button + Уклони + + + + Do you want to remove this item? + + + + + Do yout want to remove %1 items? + + + + + It does not delete the original files + + + + + ShareInfoFrame + + + Share this folder + Дели ову фасциклу + + + + Share name: + Име дељења: + + + + Permission: + Дозвола: + + + + Read and write + Читање и уписивање + + + + Read only + Само читање + + + + Anonymous: + Анониман: + + + + Not allow + Не дозволи + + + + Allow + Дозволи + + + + The share name must not be two dots (..) or one dot (.) + Име дељења не семе бити две тачке (..) или једна тачка (.) + + + + The share name is used by another user. + Име дељења употребљава други корисник. + + + + OK + button + У реду + + + + Cancel + button + Откажи + + + + Replace + button + Замени + + + + The share name already exists. Do you want to replace the shared folder? + Име дељења већ постоји. Желите ли да замените дељену фасциклу? + + + + Shortcut + + + Item + Ставка + + + + Select to the first item + Обележи до прве ставке + + + + Shift + Home + Shift + Home + + + + Select to the last item + Обележи до последње ставке + + + + Shift + End + Shift + End + + + + Select leftwards + Обележи улево + + + + Shift + Left + Shift + Лево + + + + Select rightwards + Обележи удесно + + + + Shift + Right + Shift + Десно + + + + Select to upper row + Обележи ред нагоре + + + + Shift + Up + Shift + Горе + + + + Select to lower row + Обележи ред надоле + + + + Shift + Down + Shift + Доле + + + + Open + Отвори + + + + Ctrl + Down + Ctrl + Доле + + + + To parent directory + У родитељски директоријум + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Трајно обриши + + + + Shift + Delete + Shift + Delete + + + + Delete file + Обриши датотеку + + + + Delete + Обриши + + + + Select all + Изабери све + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Копирај + + + + Cut + Исеци + + + + Paste + Убаци + + + + Rename + Преименуј + + + + F2 + F2 + + + + New/Search + Нови/Претражи + + + + New window + Нови прозор + + + + New folder + Нова фасцикла + + + + + Search + Претражи + + + + New tab + Нова картица + + + + View + Приказ + + + + Item information + Информације о ставци + + + + Help + Помоћ + + + + F1 + F1 + + + + Keyboard shortcuts + Пречице на тастатури + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Промени статус приказа + + + + Hide item + Сакриј ставку + + + + Input in address bar + Унеси у адресну траку + + + + Switch to icon view + Пређи на приказ иконица + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Пређи на приказ списка + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Остали + + + + Close + Затвори + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Затвори тренутну картицу + + + + Back + Назад + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Пређи на следећу картицу + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Пређи на претходну картицу + + + + Next file + Следећа датотека + + + + Tab + Tab + + + + Previous file + Претходна датотека + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Мењај картице одабиром бројева од 1 до 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Напред + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Неуспешно отварање ставки у смећу, прво их вратите + + + + TrashPropertyDialog + + + Trash + Смеће + + + + item + ставку/и + + + + items + ставки/е + + + + Contains %1 %2 + Садржи %1 %2 + + + + UDiskListener + + + Failed to rename the label + Неуспешно преименовање ознаке + + + + UnmountWorker + + + + + The device was not safely unmounted + Уређај није безбедно демонтиран + + + + The device was not safely removed + Уређај није безбедно уклоњен + + + + UserShareManager + + + Kindly Reminder + Љубазно подсећамо + + + + Please firstly install samba to continue + Прво инсталирајте самбу за наставак + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + + + + + To protect the files, you cannot share this folder. + Због заштите датотека, не можете делити ову фасциклу. + + + + Sharing failed + Неуспешно дељење + + + + The computer name is too long + Име рачунара је предугачко + + + + You do not have permission to operate file/folder! + Немате дозволу за рад са датотеком/фасциклом! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Унесите лозинку за заштиту дељених датотека + + + + Cancel + button + Откажи + + + + Confirm + button + Потврди + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sv.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sv.ts new file mode 100644 index 0000000..2027601 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_sv.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + Ny mapp + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + Stäng alla + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + Dator + + + + Basic Info + Grundläggande information + + + + Computer Name + Datornamn + + + + Version + Version + + + + Type + Typ + + + + Processor + Processor + + + + Memory + Minne + + + + Disk + Disk + + + + Bit + Bit + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + Sök eller ange adress + + + + DFMAdvanceSearchBar + + + Search: + Sök: + + + + File Type: + Filtyp: + + + + File Size: + Filstorlek: + + + + Time Modified: + Ändrad: + + + + Reset + Återställ + + + + All subdirectories + Alla huvudbibliotek + + + + Current directory + Nuvarande bibliotek + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Idag + + + + Yesterday + Igår + + + + This week + Denna veckan + + + + Last week + Förra veckan + + + + This month + Denna månaden + + + + Last month + Förra månaden + + + + This year + Detta året + + + + Last year + Förra året + + + + DFMTagCrumbController + + + Tag information + + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + Behörighetsfel + + + + The action is denied + Åtgärden nekades + + + + Failed to open the file + Kunde ej öppna filen + + + + Failed to read the file + Kunde ej läsa in filen + + + + Failed to write the file + Kunde ej ändra filen + + + + Failed to create the directory + Kunde ej skapa mappen + + + + Failed to delete the file + Kunde ej radera filen + + + + Failed to move the file + Kunde ej flytta filen + + + + Original file does not exist + Ursprunglig fil existerar ej + + + + Failed, file size must be less than 4GB + Misslyckades, filstorleken får ej överstiga 4GB + + + + Not enough free space on the target disk + + + + + File integrity was damaged + Filintegritet är skadad + + + + The target device is read only + Målenheten är read only + + + + Target folder is inside the source folder + Målmappen är inuti källmappen + + + + copy + Extra name added to new file name when used for file name. + kopiera + + + + Failed to create the directory, cause: %1 + Kunde ej skapa mapp, orsak: %1 + + + + + Failed to open the file, cause: %1 + Kunde ej öppna fil, orsak: %1 + + + + Failed to read the file, cause: %1 + Kunde ej läsa fil, orsak: %1 + + + + Failed to write the file, cause: %1 + Kunde ej ändra fil, orsak: %1 + + + + File integrity was damaged, cause: %1 + Filintegritet skadad, orsak: %1 + + + + Failed to delete the file, cause: %1 + Kunde ej radera fil, orsak: %1 + + + + Fail to create symlink, cause: %1 + Kunde ej skapa symlink, orsak: %1 + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + %1 existerar redan, vill du ersätta den? + + + + Cancel + Avbryt + + + + Replace + Ersätt + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + Namn + + + + + + Time modified + Ändrad + + + + Size + Storlek + + + + Type + Type + + + + Time created + Skapad + + + + + Last access + Senast öppnad + + + + Path + Sökväg + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + + + + + DFileViewHelper + + + Add tag "%1" + + + + + DStatusBar + + + %1 item + %1 objekt + + + + %1 items + %1 objekt + + + + %1 item selected + %1 valt objekt + + + + %1 items selected + %1 valda objekt + + + + %1 folder selected (contains %2) + %1 mapp vald (innehåller %2) + + + + %1 folders selected (contains %2) + %1 mappar valda (innehåller %2) + + + + %1 file selected (%2) + %1 fil vald (%2) + + + + %1 files selected (%2) + %1 filer valda (%2) + + + + %1 folder selected + %1 mapp vald + + + + Filter + Filtrera + + + + Save as: + Spara som: + + + + Loading... + Läser in... + + + + DTaskDialog + + + This action is not supported + Denna åtgärd stöds ej + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + %1 Volym + + + + Data Disk + Data Partition + Data Disk + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + Operation misslyckades! + + + + Target folder is inside the source folder! + Målmappen är inuti källmappen! + + + + + + + + + + + + + OK + OK + + + + Do you want to run %1 or display its content? + Vill du köra %1 eller visa dess innehåll? + + + + It is an executable text file. + Det är en körbar textfil. + + + + + + + + + + + + + + Cancel + Avbryt + + + + + + Run + Kör + + + + + Run in terminal + Kör i terminal + + + + Display + Visa + + + + It is an executable file. + Det är en körbar fil. + + + + This file is not executable, do you want to add the execute permission and run? + Denna filen är ej körbar, vill du göra filen körbar och sedan starta den? + + + + "%1" already exists, please use another name. + "%1" existerar redan, var god välj ett annat namn. + + + + + + + + Confirm + Bekräfta + + + + Are you sure you want to erase all data on the disc? + Är du säker du vill radera all data på skivan? + + + + Erase + Radera + + + + How do you want to use this disc? + Hur vill du använda denna skivan? + + + + Burn image + Bränn avbild + + + + Burn files + Bränn filer + + + + Disc erase failed + Skivradering misslyckades + + + + Burn process failed + Brännprocess misslyckades + + + + %1: %2 + %1: %2 + + + + + Show details + Visa detaljer + + + + Hide details + Göm detaljer + + + + Error + Fel + + + + Permanently delete %1? + Radera %1 permanent? + + + + Permanently delete %1 items? + Radera %1 objekt permanent? + + + + Delete + Radera + + + + Empty + Tom + + + + Sorry, unable to locate your bookmark directory, remove it? + Ledsen, kunde ej hitta ditt bokmärkesbibliotek, ta bort? + + + + Remove + Ta bort + + + + Name: + Namn: + + + + Force unmount + Forcera avmontering + + + + %1 that this shortcut refers to has been changed or moved + %1 som denna genväg refererar till har ändrats eller flyttats + + + + Do you want to delete this shortcut? + Vill du radera denna genväg ? + + + + Failed, file size must be less than 4GB. + Misslyckades, filstorleken måste vara mindre än 4GB. + + + + Fail to create symlink, cause: + Kunde ej skapa symlink, orsak: + + + + The selected files contain system file/directory, and it cannot be deleted + De valda filerna innehåller system filer/mappar, och kan ej raderas + + + + + You do not have permission to operate file/folder! + Du har ej behörighet att bearbeta fil/mapp! + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Ledsen, du har ej behörighet att bearbeta följande %1 filer/mapp(ar)! + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + 2. Bocka av "Slå på snabb uppstart" och "Viloläge" i avstängningsinställningar och starta om + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + Delad mapp kan ej namnges efter nuvarande användarnamn + + + + View + Visa + + + + Do you want to run %1? + Vill du köra %1? + + + + Are you sure you want to empty %1 item? + Är du säker du vill tömma %1 objekt? + + + + Are you sure you want to empty %1 items? + Är du säker du vill tömma %1 objekt? + + + + + This action cannot be undone + Denna åtgärd kan ej ångras + + + + Disk is busy, cannot unmount now + Disken är upptagen, kan ej avmontera nu + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + Montera partition%1 till read-only läge + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + Diskar i Windows kommer inte kunna läsa och skriva normalt om "Slå på snabb uppstart (rekommenderad)" i Avstängnings inställningar + + + + Please restore by the following steps to normally access Windows disk + Gör följande steg för att komma åt Windows disken + + + + 1. Reboot to enter Windows + 1. Starta om för att komma in i Windows + + + 3. Reboot and enter deepin + 3. Starta om och välj deepin + + + + Reboot + Starta om + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + Filnamn + + + + Format + Format + + + + Cancel + Avbryt + + + + Save + Spara + + + + Open + Öppna + + + + Save File + Spara Fil + + + + Open File + Öppna Fil + + + + FileJob + + + copy + kopiera + + + + + Data verification successful. + Data verifiering lyckades. + + + + + Data verification failed. + Data verifiering misslyckades. + + + + + Burn process completed + Brännprocess lyckades + + + + %1 s + %1 s + + + + %1 m %2 s + %1 m %2 s + + + + %1 h %2 m %3 s + %1 h %2 m %3 s + + + + %1 d %2 h %3 m %4 s + %1 d %2 h %3 m %4 s + + + + %1 is a duplicate file. + %1 är en dublett. + + + + Insufficient disc space. + Otillräckligt skivutrymme + + + + Lost connection to drive. + Förlorade kontakt till enhet. + + + + The CD/DVD drive is not ready. Try another disc. + CD/DVD enhet är ej redo. Prova med en annan skiva. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + Okänt fel + + + + GenerateSettingTranslate + + + + + Basic + Grundläggande + + + + + + Open behavior + + + + + + + Always open folder in new window + Öppna alltid mappar i nytt fönster + + + + + + Open file: + Öppna fil: + + + + + + Click + Klick + + + + + + Double click + Dubbelklick + + + + + + New window and tab + Nytt fönster och flik + + + + + + Open from default window: + Öppna från förvalt fönster: + + + + + + + + + Computer + Dator + + + + + + + + + Home + Hem + + + + + + + + + Desktop + Skrivbord + + + + + + + + + Videos + Videos + + + + + + + + + Music + Musik + + + + + + + + + Pictures + Bilder + + + + + + + + + Documents + Dokument + + + + + + + + + Downloads + Hämtningar + + + + + + Open in new tab: + Öppna i ny flik: + + + + + + Current Directory + Nuvarande mapp + + + + + + View + Visa + + + + + + Default size: + Förvald storlek: + + + + + + Extra small + Extra liten + + + + + + Small + Liten + + + + + + Medium + Medium + + + + + + Large + Stor + + + + + + Extra large + Extra stor + + + + + + Default view: + Förvald vy: + + + + + + Icon + Ikon + + + + + + List + Lista + + + + + + Hidden files + Gömda filer + + + + + + Show hidden files + Visa gömda filer + + + + + + Hide file extension when rename + Göm filändelse vid filnamnsbyte + + + + + + Advanced + Avancerat + + + + + + Index + Index + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + + + + + + + Hide system disk + Göm system disk + + + + + + Show hidden files in search results + Visa dolda filer i sökresultat + + + + + + Display recent file entry in left panel + + + + + + + Preview + Förhandsgranska + + + + + Compress file preview + Kompakt förhandsgranskning + + + + + + Text preview + Förhandsgranska text + + + + + + Document preview + Förhandsgranska dokument + + + + + + Image preview + Förhandsgranska bild + + + + + + Video preview + Förhandsgranska film + + + + + + Mount + Montera + + + + + + Auto mount + Auto montera + + + + + + Open after auto mount + Öppna efter automontering + + + + + + Dialog + Dialog + + + Use the file chooser dialog of Deepin File Manager + Använd filväljarens dialog från Deepin filhanteraren + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + Disken är monterad av användare "%1", du kan ej avmontera den. + + + + + + + + Confirm + Bekräfta + + + + + Cannot find the mounting device + Kunde ej hitta den monterade enheten + + + + Cannot unmount the device + Kunde ej avmontera enheten + + + + Cannot eject the device "%1" + Kunde ej mata ut enheten "%1" + + + + MergedDesktopController + + + + Pictures + Bilder + + + + + Music + Musik + + + + + Applications + Program + + + + + Videos + Videos + + + + + Documents + Dokument + + + + + Others + Annat + + + + MimeTypeDisplayManager + + + + Directory + Mappar + + + + + + Application + Program + + + + + + Video + Video + + + + + + Audio + Ljud + + + + + + Image + Bild + + + + + Archive + Arkiv + + + + + + Text + Text + + + + + Executable + Exekverbar + + + + + Backup file + Backupfil + + + + + Unknown + Okänd + + + + MountAskPasswordDialog + + + Cancel + Avbryt + + + + Connect + Anslut + + + + Log in as + Logga in som + + + + Anonymous + Anonym + + + + Registered user + Registrerad användare + + + + Username + Användarnamn + + + + Domain + Domän + + + + Password + Lösenord + + + + Remember password + Kom ihåg lösenord + + + + MountSecretDiskAskPasswordDialog + + + Cancel + Avbryt + + + + Unlock + + + + + Input password to decrypt the disk + Skriv in lösenord för att avkryptera disken + + + + MoveCopyTaskWidget + + Skip + Skippa + + + Keep both + Behåll båda + + + Replace + Ersätt + + + Do not ask again + Fråga inte igen + + + merge + sammanfoga + + + Copying %1 + Kopierar %1 + + + Erasing disc %1, please wait... + Raderar disk %1, var god vänta... + + + Burning disc %1, please wait... + Bränner disk %1, var god vänta... + + + Writing data... + Skriver data... + + + Verifying data... + Verifierar data... + + + Copy to %2 + Kopierar till %2 + + + Moving %1 + Flyttar till %1 + + + Move to %2 + Flytta till %2 + + + Restoring %1 + Återställer %1 + + + Restore to %2 + Återställ till %2 + + + Deleting %1 + Raderar %1 + + + Trashing %1 + Raderar %1 + + + Calculating space, please wait + Beräknar utrymme, var god vänta + + + File named %1 already exists in target folder + Filen %1 existerar redan i målmappen + + + Original path %1 target path %2 + Ursprunglig sökväg %1 målmapp %2 + + + Retry + Försök igen + + + Time modified:%1 + Ändrad:%1 + + + Original folder + Ursprunglig mapp + + + Original file + Ursprunglig fil + + + Target folder + Målmapp + + + Target file + Målfil + + + Contains:%1 + Innehåller:%1 + + + Size:%1 + Storlek:%1 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Är du säker du vill radera %1 permanent? + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + Är du säker du vill radera %1 filer permanent? + + + + Cancel + Avbryt + + + + Delete + Radera + + + + OpenWithDialog + + + Open with + Öppna med + + + + Add other programs + Lägg till andra program + + + + Set as default + Ange som förval + + + + Cancel + Avbryt + + + + Confirm + + + + + Recommended Applications + Rekommenderade Program + + + + Other Applications + Andra Program + + + + PathManager + + + Home + Hem + + + + Desktop + Skrivbord + + + + Videos + Videos + + + + Music + Musik + + + + Pictures + Bilder + + + + Documents + Dokument + + + + Downloads + Hämtningar + + + + + Trash + Papperskorg + + + + + System Disk + System Disk + + + + Computers in LAN + Nätverk + + + + My Shares + Mina delningar + + + + Computer + Dator + + + + Recent + Tidigare + + + + PropertyDialog + + + Basic info + Grundläggande information + + + + Open with + Öppna med + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + %1 (%2) + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + Tillåt att köra som program + + + + QObject + + + + + Size + Storlek + + + + + + Contains + Innehåller + + + + + + Type + Typ + + + + + + + Time modified + Modifierad + + + + Free space + Ledigt utrymme + + + + Total space + Totalt utrymme + + + + Access denied + Åtkomst nekad + + + + + Executable + Körbar + + + + + Write only + Enbart skriv + + + + + Read only + Enbart lös + + + + + Read-write + Läs-skriv + + + + Others + Andra + + + + Owner + Ägare + + + + Device type + + + + + File system + + + + + Group + Grupp + + + + + + Open + Öppna + + + + + Size: %1 + Storlek: %1 + + + + Type: %1 + Typ: %1 + + + + Size: 0 + Storlek: 0 + + + + Items: %1 + Objekt: %1 + + + + + + + + + + + Open in new window + Öppna i nytt fönster + + + + + + + + + + + Open in new tab + Öppna i ny flik + + + + Open with + Öppna med + + + + Compress + Komprimera + + + + Extract + Packa upp + + + + Extract here + Packa upp här + + + + Cut + Klipp ut + + + + Copy + Kopiera + + + + Paste + Klistra in + + + + + + + + + + Rename + Döp om + + + + + + Remove + Ta bort + + + + Create link + Skapa länk + + + + Send to desktop + Skicka till skrivbord + + + + Send to + Skicka till + + + + Add to bookmark + Lägg till bokmärke + + + + + + + Properties + Egenskaper + + + + New folder + Ny mapp + + + + New window + Nytt fönster + + + + Select all + Välj alla + + + + + Clear recent history + Rensa tidigare historik + + + + + + Empty Trash + Töm Papperskorg + + + + Display as + Visa som + + + + Sort by + Sortera efter + + + + New document + Nytt dokument + + + + + Time created + Skapad + + + + Log out and unmount + Logga ut och avmontera + + + + + + Source path + Målsökväg + + + + Share folder + Dela mapp + + + + Cancel sharing + Avbryt delning + + + + Connect to Server + + + + + Set share password + Ange delnings lösenord + + + + Format + Format + + + + Tag information + + + + + Open in new window as admin + Öppna i nytt fönster som admin + + + + Select default program + Ange förvalt program + + + + Open file location + Öppna filens sökväg + + + + Remove bookmark + Radera bokmärke + + + + + + Delete + Radera + + + + Office Text + Office dokument + + + + Spreadsheets + Kalkylblad + + + + Plain Text + Vanlig Text + + + + Open in terminal + Öppna i terminal + + + + Restore + Återställ + + + + Restore all + Återställ alla + + + + File Vault + + + + + Auto mount + Automontera + + + + Open after auto mount + Öppna efter automontering + + + + + Mount + Montera + + + + + Unmount + Avmontera + + + + + + Burn + Bränn + + + + Disc name: + Skivnamn: + + + + + Maximum + Maximal + + + + Allow files to be added later + Tillåt att filer kan läggas till senare + + + + Verify data + Verifera data + + + + Write speed: + Skrivhastighet: + + + + + Eject + Mata ut + + + + Safely Remove + Säker borttagning + + + + + Name + Namn + + + + Settings + Inställningar + + + + Exit + Stäng + + + + Icon + Ikon + + + + List + Lista + + + + Extend + + + + + Set as wallpaper + Ange som bakgrundsbild + + + + + + + Local disk + Lokal disk + + + + + Removable disk + Flyttbar disk + + + + + + Network shared directory + Nätverksmapp + + + + + Android mobile device + Android enhet + + + + + Apple mobile device + Apple enhet + + + + + Camera + Kamera + + + + + DVD + DVD + + + + + Unknown device + Okänd enhet + + + + + + %1 item + %1 objekt + + + + + + %1 items + %1 objekt + + + + Shortcut + Genväg + + + + Create symlink + Skapa länk + + + + Path + Sökväg + + + + + + Time deleted + Borttagen + + + + Loading... + Läser in... + + + + File has been moved or deleted + Filen har flyttats eller tagits bort + + + + + + You do not have permission to access this folder + Du har en behörighet att bearbeta denna mapp + + + + + + + Folder is empty + Mappen är tom + + + + Path + SearchFileInfo + Sökväg + + + + Searching... + Söker... + + + + No results + Inga resultat + + + + Source Path + TrashFileInfo + Målsökväg + + + + Document + Dokument + + + + Spreadsheet + Kalkylblad + + + + + Presentation + Presentation + + + + Text + Text + + + + 1 task in progress + 1 uppgift pågår + + + + %1 tasks in progress + %1 uppgifter pågår + + + + Mode: + Läge: + + + + + Replace Text + Ersätt Text + + + + + Add Text + Lägg till Text + + + + + Custom Text + Anpassad Text + + + + Find: + Hitta: + + + + Replace: + Ersätt: + + + + + Optional + Valfri + + + + Add: + Lägg till: + + + + Location: + Plats: + + + + File name: + Filnamn: + + + + +SN: + +SN: + + + + + + + + + + Required + Krävs + + + + + Before file name + Innan filnamn + + + + + After file name + Efter filnamn + + + + Find + Hitta + + + + Replace + Ersätt + + + + Add + Lägg till + + + + + + Location + Plats + + + + File name + Filnamn + + + + Dimension + + + + + Duration + + + + + +SN + +SN + + + + Tips: Sort by selected file order + + + + + + + Cancel + Avbryt + + + + Rename %1 Files + Döp om %1 Filer + + + + Multiple Files + Multipla Filer + + + + Basic info + Grundläggande information + + + + Total size + Total storlek + + + + Number of files + Antal filer + + + + %1 file(s), %2 folder(s) + %1 fil(er), %2 mapp(ar) + + + + + + Time accessed + + + + + Orange + Orange + + + + Red + Röd + + + + Purple + Lila + + + + Navy-blue + Skeppsblå + + + + Azure + Blå + + + + Green + Grön + + + + Yellow + Gul + + + + Gray + Grå + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + Bokmärken + + + + Erase + Radera + + + + + Copy path + Kopiera sökväg + + + + + Edit address + Ändra adress + + + + Free Space %1 + Ledigt utrymme %1 + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + Dela denna mapp + + + + Share name: + Delningsnamn: + + + + Permission: + Behörighet: + + + + Read and write + Läs och skriv + + + + Read only + Endast läs + + + + Anonymous: + Anonym: + + + + Not allow + Tillåt ej + + + + Allow + Tillåt + + + + Shortcut + + + Item + Objekt + + + + Select to the first item + Välj det första objektet + + + + Shift + Home + Shift + Home + + + + Select to the last item + Välj t.om det sista objektet + + + + Shift + End + Shift + End + + + + Select leftwards + + + + + Shift + Left + Shift + Vänster + + + + Select rightwards + + + + + Shift + Right + Shift + Höger + + + + Select to upper row + + + + + Shift + Up + Shift + Upp + + + + Select to lower row + + + + + Shift + Down + Shift + Ner + + + + Open + Öppna + + + + Ctrl + Down + Ctrl + Ner + + + + To parent directory + Till föregående mapp + + + + Ctrl + Up + Ctrl + Upp + + + + Permanently delete + Radera permanent + + + + Shift + Delete + Shift + Delete + + + + Delete file + Radera fil + + + + Delete + Radera + + + + Select all + Välj alla + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + Kopiera + + + + Cut + Klipp ut + + + + Paste + Klistra in + + + + Rename + Döp om + + + + F2 + F2 + + + + New/Search + Ny/Sök + + + + New window + Nytt fönster + + + + New folder + Ny mapp + + + + + Search + Sök + + + + New tab + Ny flik + + + + View + Visa + + + + Item information + Objekt information + + + + Help + Hjälp + + + + F1 + F1 + + + + Keyboard shortcuts + Tangentbordsgenvägar + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + + + + + Hide item + Göm objekt + + + + Input in address bar + + + + + Switch to icon view + Ändra till ikonvy + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Ändra till listvy + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Annat + + + + Close + Stäng + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Stäng nuvarande flik + + + + Back + Tillbaka + + + + Alt + Left + Alt + Vänster + + + + Alt + Right + Alt + Höger + + + + Switch to next tab + Växla till nästa flik + + + + Ctrl + Tab + + + + + Ctrl + Shift + Tab + + + + + Switch to previous tab + Växla till föregående flik + + + + Next file + Nästa fil + + + + Tab + Tab + + + + Previous file + Föregående fil + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Ändra flik genom att specificera nummer mellan 1 till 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Framåt + + + + TrashPropertyDialog + + + Trash + Papperskorg + + + + item + objekt + + + + items + objekt + + + + Contains %1 %2 + Innehåller %1 %2 + + + + UDiskListener + + + Failed to rename the label + Misslyckades med att ändra etikett + + + + UserShareManager + + + Kindly Reminder + Vänligen kom ihåg + + + + Please firstly install samba to continue + Vänligen installera samba för att fortsätta + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + Avbryt + + + + Confirm + Bekräfta + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ta.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ta.ts new file mode 100644 index 0000000..3704dd9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ta.ts @@ -0,0 +1,3740 @@ + + + AppController + + + New Folder + புதிய கோப்புறை + + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + Mount error: unsupported image format + + + + + Disk is busy, cannot unmount now + + + + + + Disk is busy, cannot eject now + + + + Mount Error + + + + Unsupported image format + + + + + CloseAllDialogIndicator + + + Close all + அனைத்தையும் மூடு + + + + Total size: %1, %2 files + + + + + ComputerModel + + + My Directories + + + + + + + Disks + + + + + ComputerPropertyDialog + + + Computer + கணினி + + + + Basic Info + அடிப்படை தகவல்கள் + + + + Computer Name + கண்ணினியின் பெயர் + + + + Version + பதிப்பு + + + + Type + வகை + + + + Processor + செயலி + + + + Memory + நினைவுத்திறன் + + + + Disk + வட்டு இயக்கி + + + + Bit + பிட் + + + + ConnectToServerDialog + + + Connect to Server + + + + + Cancel + + + + + Connect + + + + + My Favorites: + + + + + Clear History + + + + + DFMAddressBar + + + Search or enter address + தேடு அல்லது முகவரியை உள்ளிடவும் + + + + DFMAdvanceSearchBar + + + Search: + தேடு: + + + + File Type: + கோப்பு வகை: + + + + File Size: + கோப்பின் அளவு: + + + + Time Modified: + மாற்றப்பட்ட நேரம்: + + + + Reset + மீட்டமைக்க + + + + All subdirectories + அனைத்து துணை கோப்பகங்களும் + + + + Current directory + தற்போதைய கோப்பகங்கள் + + + + 0 ~ 100 KB + 0 ~ 100 கே.பி + + + + 100 KB ~ 1 MB + 100 கே.பி ~ 1 எம்பி + + + + 1 MB ~ 10 MB + + + + + 10 MB ~ 100 MB + + + + + 100 MB ~ 1 GB + + + + + > 1 GB + + + + + Today + இன்று + + + + Yesterday + நேற்று + + + + This week + + + + + Last week + + + + + This month + + + + + Last month + + + + + This year + இந்த ஆண்டு + + + + Last year + + + + + DFMTagCrumbController + + + Tag information + + + + + DFMTagWidget + + + Tag + + + + + DFMTaskWidget + + + Keep both + + + + + Skip + + + + + Replace + + + + + Do not ask again + + + + + Retry + + + + + + Time modified: %1 + + + + + + Contains: %1 + + + + + + Size: %1 + + + + Time modified:%1 + + + + + Original folder + + + + Contains:%1 + + + + + Original file + + + + Size:%1 + + + + + Target folder + + + + + Target file + + + + + DFMVaultUnlockPages + + + + Enter the vault password + + + + + Retrieve password + + + + + DFileCopyMoveJob + + + Permission error + + + + + The action is denied + + + + + Failed to open the file + + + + + Failed to read the file + + + + + Failed to write the file + + + + + Failed to create the directory + + + + + Failed to delete the file + + + + + Failed to move the file + + + + + Original file does not exist + + + + + Failed, file size must be less than 4GB + + + + + Not enough free space on the target disk + + + + + File integrity was damaged + + + + + The target device is read only + + + + + Target folder is inside the source folder + + + + + copy + Extra name added to new file name when used for file name. + + + + + Failed to create the directory, cause: %1 + + + + + + Failed to open the file, cause: %1 + + + + + Failed to read the file, cause: %1 + + + + + Failed to write the file, cause: %1 + + + + + File integrity was damaged, cause: %1 + + + + + Failed to delete the file, cause: %1 + + + + + Fail to create symlink, cause: %1 + + + + + DFileDialog + + + + Save + + + + + %1 already exists, do you want to replace it? + + + + + Cancel + + + + + Replace + + + + + Open + + + + + DFileManagerWindow + + + Trash + + + + + Empty + + + + + DFileSystemModel + + + + Name + + + + + + + Time modified + + + + + Size + + + + + Type + + + + + Time created + + + + + + Last access + + + + + Path + + + + + DFileView + + + The disc image was corrupted, cannot mount now, please erase the disc first + + + + + (Reverse) + + + + + DFileViewHelper + + + Add tag "%1" + + + + + DStatusBar + + + %1 item + + + + + %1 items + + + + + %1 item selected + + + + + %1 items selected + + + + + %1 folder selected (contains %2) + + + + + %1 folders selected (contains %2) + + + + + %1 file selected (%2) + + + + + %1 files selected (%2) + + + + + %1 folder selected + + + + + Filter + + + + + Save as: + + + + + Loading... + + + + + DTaskDialog + + + This action is not supported + + + + + Erasing disc %1, please wait... + + + + + Burning disc %1, please wait... + + + + + Writing data... + + + + + Verifying data... + + + + + Copying %1 + + + + + + + to %2 + + + + + %1 already exists in target folder + + + + + Original path %1 Target path %2 + + + + Copy to %2 + + + + + Moving %1 + + + + Move to %2 + + + + + Restoring %1 + + + + Restore to %2 + + + + + Deleting %1 + + + + + Trashing %1 + + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + + Merge + + + + + Replace + + + + + DeepinStorage + + + + + %1 Volume + + + + + Data Disk + Data Partition + + + + + %1 Drive + + + + + Blank %1 Disc + + + + + %1 Encrypted + + + + + DialogManager + + + + + Operation failed! + + + + + Target folder is inside the source folder! + + + + + + + + + + + + + + OK + + + + + Do you want to run %1 or display its content? + + + + + It is an executable text file. + + + + + + + + + + + + + + + Cancel + + + + + + + Run + + + + + + Run in terminal + + + + + Display + + + + + It is an executable file. + + + + + This file is not executable, do you want to add the execute permission and run? + + + + + "%1" already exists, please use another name. + + + + + + + + + Confirm + + + + + Are you sure you want to erase all data on the disc? + + + + + Erase + + + + + How do you want to use this disc? + + + + + Burn image + + + + + Burn files + + + + + Disc erase failed + + + + + Burn process failed + + + + + %1: %2 + + + + + + Show details + + + + + Hide details + + + + + Error + + + + + Permanently delete %1? + + + + + Permanently delete %1 items? + + + + + Delete + + + + + Empty + + + + + Sorry, unable to locate your bookmark directory, remove it? + + + + + Remove + + + + + Name: + + + + + Force unmount + + + + + %1 that this shortcut refers to has been changed or moved + + + + + Do you want to delete this shortcut? + + + + + Failed, file size must be less than 4GB. + + + + + Fail to create symlink, cause: + + + + + The selected files contain system file/directory, and it cannot be deleted + + + + + + You do not have permission to operate file/folder! + + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + + + + + 2. Uncheck "Turn on fast startup" and "Hibernate" in shutdown settings and reboot + + + + + 3. Reboot and enter %1 + + + + + Share folder can't be named after the current username + + + + + View + + + + + Do you want to run %1? + + + + + Are you sure you want to empty %1 item? + + + + + Are you sure you want to empty %1 items? + + + + + + This action cannot be undone + + + + + Disk is busy, cannot unmount now + + + + + Unable to copy. Not enough free space on the target disk. + + + + + Failed to restore %1 file, the target folder is read-only + + + + + Failed to restore %1 files, the target folder is read-only + + + + + Mount partition%1 to be read only + + + + + Disks in Windows will be unable to read and write normally if check "Turn on fast startup (recommended)" in Shutdown settings + + + + + Please restore by the following steps to normally access Windows disk + + + + + 1. Reboot to enter Windows + + + + 3. Reboot and enter deepin + + + + + Reboot + + + + + FileController + + + + + Kindly Reminder + + + + + + + Please install File Roller first and then continue + + + + + FileDialogStatusBar + + + File Name + + + + + Format + + + + + Cancel + + + + + Save + + + + + Open + + + + + Save File + + + + + Open File + + + + + FileJob + + + copy + + + + + + Data verification successful. + + + + + + Data verification failed. + + + + + + Burn process completed + + + + + %1 s + + + + + %1 m %2 s + + + + + %1 h %2 m %3 s + + + + + %1 d %2 h %3 m %4 s + + + + + %1 is a duplicate file. + + + + + Insufficient disc space. + + + + + Lost connection to drive. + + + + + The CD/DVD drive is not ready. Try another disc. + + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + + + + + Unknown error + + + + + GenerateSettingTranslate + + + + + Basic + + + + + + + Open behavior + + + + + + + Always open folder in new window + + + + + + + Open file: + + + + + + + Click + + + + + + + Double click + + + + + + + New window and tab + + + + + + + Open from default window: + + + + + + + + + + Computer + + + + + + + + + + Home + + + + + + + + + + Desktop + + + + + + + + + + Videos + + + + + + + + + + Music + + + + + + + + + + Pictures + + + + + + + + + + Documents + + + + + + + + + + Downloads + + + + + + + Open in new tab: + + + + + + + Current Directory + + + + + + + View + + + + + + + Default size: + + + + + + + Extra small + + + + + + + Small + + + + + + + Medium + + + + + + + Large + + + + + + + Extra large + + + + + + + Default view: + + + + + + + Icon + + + + + + + List + + + + + + + Hidden files + + + + + + + Show hidden files + + + + + + + Hide file extension when rename + + + + + + + Advanced + + + + + + + Index + + + + + + + Auto index internal disk + + + + + + + Index external storage device after connected to computer + + + + + + + Use the file chooser dialog of File Manager + + + + + + + Other + + + + + + + Hide system disk + + + + + + + Show hidden files in search results + + + + + + + Display recent file entry in left panel + + + + + + + Preview + + + + + + Compress file preview + + + + + + + Text preview + + + + + + + Document preview + + + + + + + Image preview + + + + + + + Video preview + + + + + + + Mount + + + + + + + Auto mount + + + + + + + Open after auto mount + + + + + + + Dialog + + + + Use the file chooser dialog of Deepin File Manager + + + + + Compressed file preview + + + + + GvfsMountManager + + + Mounting device error + + + + + The disk is mounted by user "%1", you cannot unmount it. + + + + + + + + + Confirm + + + + + + Cannot find the mounting device + + + + + Cannot unmount the device + + + + + Cannot eject the device "%1" + + + + + MergedDesktopController + + + + Pictures + + + + + + Music + + + + + + Applications + + + + + + Videos + + + + + + Documents + + + + + + Others + + + + + MimeTypeDisplayManager + + + + Directory + + + + + + + Application + + + + + + + Video + + + + + + + Audio + + + + + + + Image + + + + + + Archive + + + + + + + Text + + + + + + Executable + + + + + + Backup file + + + + + + Unknown + + + + + MountAskPasswordDialog + + + Cancel + + + + + Connect + + + + + Log in as + + + + + Anonymous + + + + + Registered user + + + + + Username + + + + + Domain + + + + + Password + + + + + Remember password + + + + + MountSecretDiskAskPasswordDialog + + + Cancel + + + + + Unlock + + + + + Input password to decrypt the disk + + + + + MoveCopyTaskWidget + + Skip + + + + Keep both + + + + Replace + + + + Do not ask again + + + + merge + + + + Copying %1 + + + + Erasing disc %1, please wait... + + + + Burning disc %1, please wait... + + + + Writing data... + + + + Verifying data... + + + + Copy to %2 + + + + Moving %1 + + + + Move to %2 + + + + Restoring %1 + + + + Restore to %2 + + + + Deleting %1 + + + + Trashing %1 + + + + Calculating space, please wait + + + + File named %1 already exists in target folder + + + + Original path %1 target path %2 + + + + Retry + + + + Time modified:%1 + + + + Original folder + + + + Original file + + + + Target folder + + + + Target file + + + + Contains:%1 + + + + Size:%1 + + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + + + + + This file is too big for the trash + + + + + The files are too big for the trash + + + + + Are you sure you want to permanently delete %1 files? + + + + + Cancel + + + + + Delete + + + + + OpenWithDialog + + + Open with + + + + + Add other programs + + + + + Set as default + + + + + Cancel + + + + + Confirm + + + + + Recommended Applications + + + + + Other Applications + + + + + PathManager + + + Home + + + + + Desktop + + + + + Videos + + + + + Music + + + + + Pictures + + + + + Documents + + + + + Downloads + + + + + + Trash + + + + + + System Disk + + + + + Computers in LAN + + + + + My Shares + + + + + Computer + + + + + Recent + + + + + PropertyDialog + + + Basic info + + + + + Open with + + + + + Sharing + + + + + Permissions + + + + + %1 (%2) + + + + + %1 / %2 + + + + + Hide this folder + + + + + Hide this file + + + + + Allow to execute as program + + + + + QObject + + + + + Size + + + + + + + Contains + + + + + + + Type + + + + + + + + Time modified + + + + + Free space + + + + + Total space + + + + + Access denied + + + + + + Executable + + + + + + Write only + + + + + + Read only + + + + + + Read-write + + + + + Others + + + + + Owner + + + + + Device type + + + + + File system + + + + + Group + + + + + + + Open + + + + + + Size: %1 + + + + + Type: %1 + + + + + Size: 0 + + + + + Items: %1 + + + + + + + + + + + + Open in new window + + + + + + + + + + + + Open in new tab + + + + + Open with + + + + + Compress + + + + + Extract + + + + + Extract here + + + + + Cut + + + + + Copy + + + + + Paste + + + + + + + + + + + Rename + + + + + + + Remove + + + + + Create link + + + + + Send to desktop + + + + + Send to + + + + + Add to bookmark + + + + + + + + Properties + + + + + New folder + + + + + New window + + + + + Select all + + + + + + Clear recent history + + + + + + + Empty Trash + + + + + Display as + + + + + Sort by + + + + + New document + + + + + + Time created + + + + + Log out and unmount + + + + + + + Source path + + + + + Share folder + + + + + Cancel sharing + + + + + Connect to Server + + + + + Set share password + + + + + Format + + + + + Tag information + + + + + Open in new window as admin + + + + + Select default program + + + + + Open file location + + + + + Remove bookmark + + + + + + + Delete + + + + + Office Text + + + + + Spreadsheets + + + + + Plain Text + + + + + Open in terminal + + + + + Restore + + + + + Restore all + + + + + File Vault + + + + + Auto mount + + + + + Open after auto mount + + + + + + Mount + + + + + + Unmount + + + + + + + Burn + + + + + Disc name: + + + + + + Maximum + + + + + Allow files to be added later + + + + + Verify data + + + + + Write speed: + + + + + + Eject + + + + + Safely Remove + + + + + + Name + + + + + Settings + + + + + Exit + + + + + Icon + + + + + List + + + + + Extend + + + + + Set as wallpaper + + + + + + + + Local disk + + + + + + Removable disk + + + + + + + Network shared directory + + + + + + Android mobile device + + + + + + Apple mobile device + + + + + + Camera + + + + + + DVD + + + + + + Unknown device + + + + + + + %1 item + + + + + + + %1 items + + + + + Shortcut + + + + + Create symlink + + + + + Path + + + + + + + Time deleted + + + + + Loading... + + + + + File has been moved or deleted + + + + + + + You do not have permission to access this folder + + + + + + + + Folder is empty + + + + + Path + SearchFileInfo + + + + + Searching... + + + + + No results + + + + + Source Path + TrashFileInfo + + + + + Document + + + + + Spreadsheet + + + + + + Presentation + + + + + Text + + + + + 1 task in progress + + + + + %1 tasks in progress + + + + + Mode: + + + + + + Replace Text + + + + + + Add Text + + + + + + Custom Text + + + + + Find: + + + + + Replace: + + + + + + Optional + + + + + Add: + + + + + Location: + + + + + File name: + + + + + +SN: + + + + + + + + + + + Required + + + + + + Before file name + + + + + + After file name + + + + + Find + + + + + Replace + + + + + Add + + + + + + + Location + + + + + File name + + + + + Dimension + + + + + Duration + + + + + +SN + + + + + Tips: Sort by selected file order + + + + + + + Cancel + + + + + Rename %1 Files + + + + + Multiple Files + + + + + Basic info + + + + + Total size + + + + + Number of files + + + + + %1 file(s), %2 folder(s) + + + + + + + Time accessed + + + + + Orange + + + + + Red + + + + + Purple + + + + + Navy-blue + + + + + Azure + + + + + Green + + + + + Yellow + + + + + Gray + + + + + Input tag info, such as work, family. A comma is used between two tags. + + + + + Bookmarks + + + + + Erase + + + + + + Copy path + + + + + + Edit address + + + + + Free Space %1 + + + + + Files are being processed + + + + + %1/%2 + + + + + ShareInfoFrame + + + Share this folder + + + + + Share name: + + + + + Permission: + + + + + Read and write + + + + + Read only + + + + + Anonymous: + + + + + Not allow + + + + + Allow + + + + + Shortcut + + + Item + + + + + Select to the first item + + + + + Shift + Home + + + + + Select to the last item + + + + + Shift + End + + + + + Select leftwards + + + + + Shift + Left + + + + + Select rightwards + + + + + Shift + Right + + + + + Select to upper row + + + + + Shift + Up + + + + + Select to lower row + + + + + Shift + Down + + + + + Open + + + + + Ctrl + Down + + + + + To parent directory + + + + + Ctrl + Up + + + + + Permanently delete + + + + + Shift + Delete + + + + + Delete file + + + + + Delete + + + + + Select all + + + + + Ctrl + A + + + + + Ctrl + C + + + + + Ctrl + X + + + + + Ctrl + V + + + + + Ctrl + N + + + + + Ctrl + Shift + N + + + + + Ctrl + F + + + + + Ctrl + T + + + + + Ctrl + I + + + + + Ctrl + H + + + + + Ctrl + L + + + + + Ctrl + W + + + + + Copy + + + + + Cut + + + + + Paste + + + + + Rename + + + + + F2 + + + + + New/Search + + + + + New window + + + + + New folder + + + + + + Search + + + + + New tab + + + + + View + + + + + Item information + + + + + Help + + + + + F1 + + + + + Keyboard shortcuts + + + + + Ctrl + Shift + / + + + + + Switch display status + + + + + Hide item + + + + + Input in address bar + + + + + Switch to icon view + + + + + Ctrl + 1 + + + + + Switch to list view + + + + + Ctrl + 2 + + + + + Others + + + + + Close + + + + + Alt + F4 + + + + + Close current tab + + + + + Back + + + + + Alt + Left + + + + + Alt + Right + + + + + Switch to next tab + + + + + Ctrl + Tab + + + + + Ctrl + Shift + Tab + + + + + Switch to previous tab + + + + + Next file + + + + + Tab + + + + + Previous file + + + + + Shift + Tab + + + + + Switch tab by specified number between 1 to 8 + + + + + Alt + [1-8] + + + + + Forward + + + + + TrashPropertyDialog + + + Trash + + + + + item + + + + + items + + + + + Contains %1 %2 + + + + + UDiskListener + + + Failed to rename the label + + + + + UserShareManager + + + Kindly Reminder + + + + + Please firstly install samba to continue + + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + + + + + Cancel + + + + + Confirm + + + + + VaultAskCreateKeyPage + + Do you want to export a key file in case that you forgot the password? + + + + Export key + + + + + Do you want to generate a key in case that you forgot the password? + + + + + Generate key + + + + + Skip + + + + + VaultGeneratedKeyPage + + + Find your recovery key below + + + + + Take good care of the recovery key by printing, writing down or saving it to a USB flash drive + + + + + Your recovery key is as important as your password. Do not save the key file on this computer + + + + + Save your vault recovery key + + + + + + File Vault Recovery Key + + + + + File Vault Recovery Key (*.txt) + + + + + To verify that this is the correct recovery key, compare the following key ID with the key ID displayed on your PC. + + + + + Key ID: %1 + + + + + If they are identical, then use the following key to retrieve your vault password. + + + + + Recovery Key: %1 + + + + + If they do not match, then this is not the right key, please try another recovery key. + + + + + Save + + + + + Done + + + + + VaultHeaderView + + + File Vault + + + + + Lock vault + + + + + Generate key + + + + Generate key file + + + + + VaultPasswordPage + + + Here is your vault password + + + + + OK + + + + + VaultSetupSetPasswordPage + + + Next + + + + + Set a password for the vault + + + + + Password + + + + + Repeat password + + + + + VaultSetupWelcomePage + + + Create a new vault + + + + + Import a vault + + + + + File Vault + + + + + Welcome to File Vault + + + + + Create secure private space here + + + + + Advanced encryption technology, safe and secure + + + + + Convenient and easy to use + + + + + VaultVerifyRecoveryKeyPage + + + Compare the following text with the key ID in your recovery key file + + + + + If they are identical, input the recovery key below to retrieve your vault password + + + + + Retrieve password + + + + + VaultVerifyUserPage + + + Enter the vault password + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_tr.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_tr.ts new file mode 100644 index 0000000..31591ed --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_tr.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Yeni Klasör + + + + Mounting device error + Aygıt bağlama hatası + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Disk kalıbı bozulmuş ve şimdi bağlanamıyor, lütfen önce diski silin + + + + Mount error: unsupported image format + Bağlama hatası: desteklenmeyen kalıp biçimi + + + + + The device was not safely removed + Cihaz güvenli bir şekilde kaldırılmadı + + + + + Click "Safely Remove" and then disconnect it next time + Bir daha ki sefer "Güvenle Kaldıra" tıklayın bağlantısını kesin + + + + The device was not ejected + Cihaz çıkarılmadı + + + + Disk is busy, cannot eject now + Disk meşgul, şimdi çıkartılamıyor + + + + Authentication timed out + Kimlik doğrulama zaman aşımı + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Bluetooth Dosya Aktarımı + + + + File Transfer Successful + Dosya Aktarımı Başarılı + + + + File Transfer Failed + Dosya Aktarımı Başarısız + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Dosyalar "<b style="font-weight: 550;">%1</b>" üstüne gönderiliyor + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Dosya gönderilemedi "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + "<b style="font-weight: 550;">%1</b>" üstüne başarıyla gönderildi + + + + Select a Bluetooth device to receive files + Dosyaları almak için bir Bluetooth cihazı seç + + + + Cannot find the connected Bluetooth device + Bağlı Bluetooth cihazı bulunamıyor + + + + Waiting to be received... + Alınmayı bekliyor... + + + + Go to Bluetooth Settings + Bluetooth Ayarlarına Git + + + + %1/%2 Sent + %1/%2 Gönder + + + + Error: the Bluetooth device is disconnected + Hata: Bluetooth cihazının bağlantısı kesildi + + + + Unable to send the file more than 2 GB + Dosya 2 GB'den fazla gönderilemiyor + + + + Unable to send 0 KB files + 0 KB dosya gönderilemiyor + + + + File doesn't exist + Dosya mevcut değil + + + + Next + button + Sonraki + + + + Cancel + button + İptal + + + + Done + button + Bitti + + + + Retry + button + Tekrar dene + + + + OK + button + Tamam + + + + File sending request timed out + Dosya gönderim isteği zaman aşımına uğradı + + + + The service is busy and unable to process the request + Hizmet meşgul ve isteği işleyemiyor + + + + BurnOptDialog + + + Device error + Aygıt hatası + + + + Optical device %1 doesn't exist + Optik cihaz %1 mevcut değil + + + + Advanced settings + Gelişmiş ayarlar + + + + File system: + Dosya sistemi: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Windows İçin) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Unix İçin) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (Windows CD/DVD moduyla uyumlu) + + + + ISO9660 Only + ISO9660 Sadece + + + + CloseAllDialogIndicator + + + Close all + Tümünü kapat + + + + Total size: %1, %2 files + Toplam boyut: %1, %2 dosya + + + + ComputerModel + + + Double click to open it + + + + + My Directories + Dizinlerim + + + + Disks + Diskler + + + + File Vault + Dosya Kasası + + + + Quick Access + + + + + ComputerPropertyDialog + + + Computer + Bilgisayar + + + + Basic Info + Temel Bilgi + + + + + Computer Name + Bilgisayar Adı + + + + + Edition + Yayın + + + + + + Version + Sürüm + + + + + Type + Tür + + + + + + Processor + İşlemci + + + + + + Memory + Bellek + + + + + + + Bit + Bit + + + + + Available + Mevcut + + + + Obtaining... + Alınıyor... + + + + ConnectToServerDialog + + + Connect to Server + Sunucuya Bağlan + + + + Cancel + button + İptal + + + + Connect + button + Bağlan + + + + My Favorites: + Favorilerim: + + + + + Clear History + Geçmişi Temizle + + + + DFMAddressBar + + + Search or enter address + Ara yada adresi gir + + + + DFMAdvanceSearchBar + + + Search: + Ara: + + + + File Type: + Dosya Türü: + + + + File Size: + Dosya Boyutu: + + + + Time Modified: + Düzenlenme Zamanı: + + + + Time Accessed: + Erişim Zamanı: + + + + Time Created: + Oluşturulma Zamanı: + + + + Reset + Sıfırla + + + + All subdirectories + Tüm alt dizinler + + + + Current directory + Mevcut dizin + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + Bugün + + + + Yesterday + Dün + + + + This week + Bu hafta + + + + Last week + Önceki hafta + + + + This month + Bu ay + + + + Last month + Önceki ay + + + + This year + Bu yıl + + + + Last year + Önceki yıl + + + + DFMOpticalMediaWidget + + + + No files to burn + Yazılacak dosya yok + + + + Unable to burn. Not enough free space on the target disk. + Yazılamıyor. Hedef diskte yeterli boş alan yok. + + + + %1 burning is not supported + %1 yazma desteklenmiyor + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. %1 disk değil; +2. Bu dosya sisteminin sürümü henüz dosya eklemeyi desteklemiyor. + + + + DFMTagCrumbController + + + Tag information + Etiket bilgileri + + + + DFMTagWidget + + + Tag + Etiket + + + + DFMTaskWidget + + + Do not ask again + Tekrar sorma + + + + Syncing data + Veri eşitleme + + + + Please wait + Lütfen bekleyin + + + + + Time modified: %1 + Değiştirilme zamanı: %1 + + + + + Contains: %1 + İçerik: %1 + + + + + Size: %1 + Boyut: %1 + + + + Original folder + Özgün klasör + + + + Keep both + button + İkisini de tut + + + + Skip + button + Atla + + + + Replace + button + Değiştir + + + + Retry + button + Tekrar dene + + + + Original file + Özgün dosya + + + + Target folder + Hedef klasör + + + + Target file + Hedef dosya + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Dosya Kasasını Şifrele + + + + Click 'Encrypt' and input the user password. + 'Şifreli'yi tıklayın ve kullanıcı şifresini girin. + + + + Encrypting... + Şifreleniyor... + + + + + + + Encrypt + Şifrele + + + + Failed to create file vault: %1 + Dosya kasası oluşturulamadı: %1 + + + + OK + Tamam + + + + The setup is complete + Kurulum tamamlandı + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + + + + + Keep the key safe to retrieve the vault password later + + + + + Save to default path + + + + + Save to other locations + + + + + No permission, please reselect + + + + + Select a path + + + + + Next + Sonraki + + + + The default path is invisible to other users, and the path information will not be shown. + + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Kurtarma Anahtarı + + + + Generate a recovery key in case that you forgot the password + Parolayı unutmanız durumunda bir kurtarma anahtarı oluşturun + + + + Key + Anahtar + + + + QR code + QR kod + + + + Scan QR code and save the key to another device + QR kodunu tarayın ve anahtarı başka bir cihaza kaydedin + + + + Next + Sonraki + + + + Recovery Key: + Kurtarma Anahtarı: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Kasa Parolasını Ayarla + + + + Method + Yöntem + + + + Manual + El ile + + + + Password + Parola + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 karakter, A-Z, a-z, 0-9 ve sembolleri içerir + + + + Repeat password + Parolayı tekrarla + + + + Input the password again + Parolayı tekrar gir + + + + Password hint + Parola ipucu + + + + Optional + İsteğe bağlı + + + + Next + Sonraki + + + + + Passwords do not match + Parolalar uyuşmuyor + + + + DFMVaultActiveStartView + + + File Vault + Dosya Kasası + + + + Create your secure private space + Güvenli özel alanınızı oluşturun + + + + Advanced encryption technology + Gelişmiş şifreleme teknolojisi + + + + Convenient and easy to use + Rahat ve kullanımı kolay + + + + Create + Oluştur + + + + DFMVaultFileView + + + Cannot open this path + + + + + Hint + İpucu + + + + OK + Tamam + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Anahtarla Kilit Aç + + + + Failed to unlock file vault + Dosya kasasının kilidi açılamadı + + + + OK + Tamam + + + + Input the 32-digit recovery key + 32 basamaklı kurtarma anahtarını gir + + + + Cancel + button + İptal + + + + Unlock + button + Kilidi aç + + + + Wrong recovery key + Yanlış kurtarma anahtarı + + + + DFMVaultRemoveByPasswordView + + + Password + Parola + + + + Password hint: %1 + Parola ipucu: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + 32 basamaklı kurtarma anahtarını gir + + + + DFMVaultRemovePages + + + Delete File Vault + Dosya Kasasını Sil + + + + Once deleted, the files in it will be permanently deleted + Silindikten sonra, içindeki dosyalar kalıcı olarak silinecek + + + + Use Key + Anahtar Kullan + + + + Cancel + button + İptal + + + + Use Key + button + Anahtar Kullan + + + + Delete + button + Sil + + + + + OK + button + Tamam + + + + Use Password + Parola Kullan + + + + Wrong password + Yanlış parola + + + + Wrong recovery key + Yanlış kurtarma anahtarı + + + + Failed to delete file vault + Dosya kasası silinemedi + + + + Deleted successfully + Başarıyla silindi + + + + Failed to delete + Silinemedi + + + + Removing... + Kaldırılıyor... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + + + + + Verification failed + + + + + + Select a path + + + + + + Retrieve Password + + + + + By key in the default path + + + + + By key in the specified path + + + + + Verification Successful + + + + + Keep it safe + + + + + Back + button + Geri + + + + Verify Key + button + + + + + Go to Unlock + button + + + + + Close + button + Kapat + + + + Vault password: %1 + + + + + DFMVaultUnlockPages + + + Unlock File Vault + Dosya Kasasının Kilidini Aç + + + + Forgot password? + + + + + Password hint: %1 + Parola ipucu: %1 + + + + Failed to unlock file vault + Dosya kasasının kilidi açılamadı + + + + Cancel + button + İptal + + + + Password + Parola + + + + Unlock + button + Kilidi aç + + + + Please try again %1 minutes later + + + + + Wrong password, please try again %1 minutes later + + + + + Wrong password, one chance left + + + + + Wrong password, %1 chances left + + + + + Wrong password + Yanlış parola + + + + OK + button + Tamam + + + + DFileCopyMoveJob + + + Permission error + İzin hatası + + + + The action is denied + İşlem reddedildi + + + + Failed to open the file + Dosya açılamadı + + + + Failed to read the file + Dosya okunamadı + + + + Failed to write the file + Dosyaya yazılamadı + + + + Failed to create the directory + Dizin oluşturulamadı + + + + Failed to delete the file + Dosya silinemedi + + + + Failed to move the file + Dosya taşınamadı + + + + Original file does not exist + Özgün dosya bulunamadı + + + + Failed, file size must be less than 4GB + Başarısız, dosya boyutu 4GB'tan küçük olmalıdır + + + + Not enough free space on the target disk + Hedef diskte yeterli boş alan yok + + + + File integrity was damaged + Dosya bütünlüğü zarar gördü + + + + The target device is read only + Hedef aygıt salt okunur + + + + Target folder is inside the source folder + Hedef klasör kaynak klasörün içinde + + + + The action is not supported + İşlem desteklenmiyor + + + + You do not have permission to traverse files in it + İçindeki dosyalar arasında geçiş yapmaya izniniz yok + + + + Failed to position the file pointer! + + + + + copy + Extra name added to new file name when used for file name. + kopyala + + + + Failed to open the directory, cause: file name too long + Dizin açılamadı, nedeni: dosya adı çok uzun + + + + + Failed to open the file, cause: file name too long + Dosya açılamadı, nedeni: dosya adı çok uzun + + + + + Failed to write the file, cause: + Dosyaya şu nedenle yazılamadı: + + + + Failed to position the file pointer, cause: %1 + + + + + Syncing data + Veri eşitleme + + + + Please wait + Lütfen bekleyin + + + + Failed to create the directory, cause: %1 + Klasör şu nedenle oluşturulamadı: %1 + + + + + + + + Failed to open the file, cause: %1 + Dosya şu nedenle açılamadı: %1 + + + + + + + Failed to open the file, cause: Permission denied + Dosya açılamadı, nedeni: İzin reddedildi + + + + + Failed to read the file, cause: %1 + Dosya şu nedenle okunamadı: %1 + + + + + + + Failed to write the file, cause: %1 + Dosyaya şu nedenle yazılamadı: %1 + + + + + File integrity was damaged, cause: %1 + Dosya bütünlüğü şu nedenle zarar gördü: %1 + + + + Failed to open the file, cause: + Dosya şu nedenle açılamadı: + + + + Failed to read the file, cause: + Dosya şu nedenle okunamadı: + + + + Failed to delete the file, cause: %1 + Dosya şu nedenle silinemedi: %1 + + + + Fail to create symlink, cause: %1 + Sembolik bağlantı şu nedenle oluşturulamadı: %1 + + + + DFileDialog + + + + Save + button + Kaydet + + + + + Cancel + button + İptal + + + + Confirm + button + Onayla + + + + %1 already exists, do you want to replace it? + %1 zaten var, değiştirmek ister misiniz? + + + + Replace + button + Değiştir + + + + Open + button + + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Dosya adı bir nokta (.) İle başlıyorsa bu dosya gizlenecektir. Saklamak ister misin + + + + DFileManagerWindow + + + Trash + Çöp kutusu + + + + Empty + Boş + + + + DFileSystemModel + + + + Name + Ad + + + + + + Time modified + Değiştirilme zamanı + + + + Size + Boyut + + + + Type + Tür + + + + Time created + Oluşturulma zamanı + + + + + Last access + Son erişim + + + + + + + Path + Yol + + + + DFileView + + + Disc mount error + Disk bağlama hatası + + + + The disc is in use, please end the running process and remount the disc. + Disk kullanımda, lütfen çalıştırma işlemini sonlandırın ve diski yeniden takın. + + + + Mounting failed + Bağlama başarısız + + + + (Reverse) + (Ters) + + + + DFileViewHelper + + + Add tag "%1" + "%1" Etiketini ekle + + + + DStatusBar + + + %1 item + %1 öge + + + + %1 items + %1 öge + + + + %1 item selected + %1 öge seçildi + + + + %1 items selected + %1 öge seçildi + + + + %1 folder selected (contains %2) + %1 klasör seçildi (%2 öge) + + + + %1 folders selected (contains %2) + %1 klasör seçildi (%2 öge) + + + + %1 file selected (%2) + %1 dosya seçildi (%2) + + + + %1 files selected (%2) + %1 dosya seçildi (%2) + + + + %1 folder selected + %1 klasör seçildi + + + + Filter + Süzgeç + + + + Save as: + Farklı kaydet: + + + + Loading... + Yükleniyor... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Disk siliniyor %1 lütfen bekleyin... + + + + Burning disc %1, please wait... + Disk yazılıyor %1 lütfen bekleyin... + + + + Writing data... + Veri yazılıyor... + + + + Verifying data... + Veri doğrulanıyor... + + + + Copying %1 + %1 kopyalanıyor + + + + + + to %2 + şuraya %2 + + + + %1 already exists in target folder + %1 zaten hedef klasörde var + + + + Original path %1 Target path %2 + Özgün yol %1 Hedef yol %2 + + + + Merge + button + Birleştir + + + + Replace + button + Değiştir + + + + Moving %1 + %1 taşınıyor + + + + Removing file vault, please try later + Dosya kasası kaldırılıyor, lütfen daha sonra deneyin + + + + Restoring %1 + %1 geri yükleniyor + + + + Deleting %1 + %1 siliniyor + + + + Trashing %1 + %1 çöpe atılıyor + + + + Calculating space, please wait + Boş alan hesaplanıyor, lütfen bekleyin + + + + DUMountManager + + + + Authentication timed out + Kimlik doğrulama zaman aşımı + + + + + + Disk is busy, cannot unmount now + Disk meşgul olduğundan şu anda ayrılamıyor + + + + Disk is busy, cannot eject now + Disk meşgul, şimdi çıkartılamıyor + + + + The device is busy, cannot eject now + Aygıt meşgul, şimdi çıkarılamıyor + + + + + + The device is busy, cannot remove now + Aygıt meşgul, şimdi çıkarılamaz + + + + DeepinStorage + + + + + %1 Volume + %1 Birim + + + + Data Disk + Data Partition + Veri Diski + + + + %1 Drive + %1 Sürücü + + + + Blank %1 Disc + Boş %1 Disk + + + + %1 Encrypted + %1 Şifreli + + + + DialogManager + + + + + + Operation failed! + İşlem tamamlanamadı! + + + + Target folder is inside the source folder! + Hedef klasör, kaynak klasörün içinde! + + + + Do you want to run %1 or display its content? + %1 dosyasını çalıştırmayı mı içeriğini görüntülemeyi mi istiyorsunuz? + + + + It is an executable text file. + Çalıştırılabilir bir metin dosyasıdır. + + + + It is an executable file. + Çalıştırılabilir bir dosyadır. + + + + This file is not executable, do you want to add the execute permission and run? + Bu dosyanın çalıştırma izni yok, çalıştırma iznini ekleyip çalıştırmak ister misiniz? + + + + "%1" already exists, please use another name. + "%1" zaten var, lütfen başka bir ad yazın. + + + + The file name must not contain two dots (..) + Dosya adı iki nokta (..) içermemelidir + + + + Device or resource busy + + + + + Are you sure you want to erase all data on the disc? + Diskteki tüm verileri silmek istiyor musunuz? + + + + How do you want to use this disc? + Bu diski nasıl kullanmak istersiniz? + + + + Disc erase failed + Disk silme başarısız + + + + Burn process failed + Yazma işlemi başarısız + + + + %1: %2 + %1: %2 + + + + Show details + Ayrıntıları görüntüle + + + + Hide details + Ayrıntıları gizle + + + + Error + Hata + + + + Permanently delete %1? + %1 kalıcı olarak silinsin mi? + + + + Permanently delete %1 items? + %1 öge kalıcı olarak silinsin mi? + + + + Empty + Boşalt + + + + Do you want to delete %1? + %1'i silmek istiyor musunuz? + + + + Do you want to delete the selected %1 items? + Seçili %1 öğeyi silmek istiyor musunuz? + + + + Sorry, unable to locate your bookmark directory, remove it? + Maalesef, yer imi klasörünüz bulunamadı, kaldırılsın mı? + + + + Name: + Ad: + + + + %1 that this shortcut refers to has been changed or moved + Bu kısayolun gösterdiği %1, değiştirilmiş ya da taşınmış + + + + Do you want to delete this shortcut? + Bu kısayolu silmek ister misiniz? + + + + Failed, file size must be less than 4GB. + Başarısız, dosya boyutu 4GB'tan küçük olmalıdır. + + + + Fail to create symlink, cause: + Sembolik bağlantı şu nedenle oluşturulamadı: + + + + The selected files contain system file/directory, and it cannot be deleted + Seçilmiş dosyalar içinde sistem dosyası ya da klasörü bulunduğundan silinemez + + + + Unable to find the original file + Orijinal dosya bulunamıyor + + + + + You do not have permission to operate file/folder! + Dosya ya da klasör üzerinde çalıştırma izniniz yok! + + + + Failed to restore %1 file, the source file does not exist + %1 dosyası geri yüklenemedi, kaynak dosya mevcut değil + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Maalesef, şu %1 dosya ya da klasörü çalıştırma izniniz yok! + + + + Unable to access %1 + %1 erişilemiyor + + + + + Sending files now, please try later + Dosyaları şimdi gönderiliyor, lütfen daha sonra deneyin + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Cihaz erişmek için önce diski biçimlendirmelisiniz. Şimdi biçimlendirmek istediğinizden emin misiniz? + + + + Scanning the device, stop it? + Cihaz taranıyor, durdurulsun mu? + + + + Share folder can't be named after the current username + Paylaşım klasörüne geçerli kullanıcının adı verilemez + + + + Do you want to run %1? + %1 çalıştırılsın mı? + + + + Burn image + button + Kalıbı yazdır + + + + Burn files + button + Dosyaları yazdır + + + + Are you sure you want to empty %1 item? + %1 ögeyi kalıcı olarak silmek istediğinize emin misiniz? + + + + Are you sure you want to empty %1 items? + %1 ögeyi kalıcı olarak silmek istediğinize emin misiniz? + + + + + This action cannot be undone + Bu işlem geri alınamaz + + + + + + + + + + + + + + OK + button + Tamam + + + + + + + + + + + + + + + Cancel + button + İptal + + + + + + Run + button + Çalıştır + + + + + Run in terminal + button + Uçbirimde çalştır + + + + Display + button + Görüntü + + + + + + + + + + + Confirm + button + Onayla + + + + Erase + button + Sil + + + + Data verification failed + Veri doğrulama başarısız + + + + Show details + button + Ayrıntıları görüntüle + + + + + Delete + button + Sil + + + + Remove + button + Kaldır + + + + Disk is busy, cannot unmount now + Disk meşgul olduğundan şu anda ayrılamıyor + + + + Force unmount + button + Ayırmaya zorla + + + + Unable to copy. Not enough free space on the target disk. + Kopyalanamadı. Hedef diskte yeterli boş alan yok. + + + + Failed to restore %1 file, the target folder is read-only + %1 dosyası geri yüklenemedi, hedef klasör salt okunur + + + + Failed to restore %1 files, the target folder is read-only + %1 dosyaları geri yüklenemedi, hedef klasör salt okunur + + + + Failed to restore %1 files, the source files do not exist + %1 dosya geri yüklenemedi, kaynak dosyalar mevcut değil + + + + Format + button + Biçimlendir + + + + Stop + button + Durdur + + + + FileController + + + + + + Unable to find the original file + Orijinal dosya bulunamıyor + + + + + + Kindly Reminder + Nazikçe Hatırlat + + + + + + Please install File Roller first and then continue + Lütfen File Roller uygulamasını kurun ve sonra devam edin + + + + + Unable to create files here: %1 + Burada dosyalar oluşturulamıyor: %1 + + + + Confirm + button + Onayla + + + + FileDialogStatusBar + + + File Name + Dosya Adı + + + + Format + Biçimlendir + + + + Save + button + Kaydet + + + + Open + button + + + + + Save File + button + Dosyayı Kaydet + + + + Open File + button + Dosya Aç + + + + + + Cancel + button + İptal + + + + FileJob + + + copy + kopyala + + + + + + + Data verification successful. + Veri doğrulama başarılı. + + + + + + Burn process completed + Yazma işlemi tamamlandı + + + + %1 s + %1 sn + + + + %1 m %2 s + %1 dk %2 sn + + + + %1 h %2 m %3 s + %1 sa %2 dk %3 sn + + + + %1 d %2 h %3 m %4 s + %1 g %2 sa %3 dk %4 sn + + + + %1 is a duplicate file. + %1 yinelenen bir dosya. + + + + Insufficient disc space. + Yetersiz disk alanı. + + + + Lost connection to drive. + Sürücü bağlantısı kesildi. + + + + The CD/DVD drive is not ready. Try another disc. + CD/DVD sürücüsü hazır değil. Başka bir disk deneyin. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + CD/DVD sürücüsü meşgul. Sürücüyü kullanarak uygulamadan çıkın ve sürücüyü tekrar takın. + + + + Unknown error + Bilinmeyen hata + + + + Device disconnected + Cihaz bağlantısı kesildi + + + + GenerateSettingTranslate + + + + + Basic + Temel + + + + + + Open behavior + Açma davranışı + + + + + + Always open folder in new window + Klasörü her zaman yeni pencerede aç + + + + + + Open file: + Dosya aç: + + + + + + Click + Tek tık + + + + + + Double click + Çift tık + + + + + + New window and tab + Yeni pencere ve sekme + + + + + + Open from default window: + Varsayılan pencereden aç: + + + + + + + + + Computer + Bilgisayar + + + + + + + + + Home + Ev + + + + + + + + + Desktop + Masaüstü + + + + + + + + + Videos + Videolar + + + + + + + + + Music + Müzikler + + + + + + + + + Pictures + Resimler + + + + + + + + + Documents + Belgeler + + + + + + + + + Downloads + İndirilenler + + + + + + Open in new tab: + Yeni sekmede aç: + + + + + + Current Directory + Mevcut Dizin + + + + + + View + Görünüm + + + + + + Default size: + Varsayılan boyut: + + + + + + Extra small + Çok küçük + + + + + + Small + Küçük + + + + + + Medium + Orta + + + + + + Large + Büyük + + + + + + Extra large + Çok büyük + + + + + + Default view: + Varsayılan görünüm: + + + + + + Icon + Simge + + + + + + List + Liste + + + + + + Hidden files + Gizli dosyalar + + + + + + Show hidden files + Gizli dosyaları görüntüle + + + + + + Hide file extension when rename + Yeniden adlandırırken dosya uzantısını gizle + + + + + + Advanced + Gelişmiş + + + + + + Index + Dizin + + + + + + Auto index internal disk + İç diskin dizini otomatik olarak oluşturulsun + + + + + + Index external storage device after connected to computer + Bağlandıktan sonra harici depolama cihazını dizinle + + + + + + Full-Text search + Tam Metin araması + + + + + + Show item counts and sizes in the path of mounted MTP devices + Takılı MTP cihazlarının yolundaki öğe sayılarını ve boyutlarını göster + + + + + + Keep showing the mounted Samba shares + + + + + + + Use the file chooser dialog of File Manager + Dosya Yöneticisi'nin dosya seçici iletişim kutusunu kullan + + + + + + Ask for my confirmation when deleting files + Dosyaları silerken onayımı sor + + + + + + Other + Diğer + + + + + + Hide system disk + Sistem diskini gizle + + + + + + Show file system on disk icon + Dosya sistemini disk simgesinde göster + + + + + + Show hidden files in search results + Arama sonuçlarında gizli dosyaları göster + + + + + + Display recent file entry in left panel + Son kullanılan dosyaları panelde görüntüle + + + + + + Preview + Önizleme + + + + + Compress file preview + Dosya önizlemesini sıkıştır + + + + + + Text preview + Metin önizlemesi + + + + + + Document preview + Belge önizlemesi + + + + + + Image preview + Görüntü önizlemesi + + + + + + Video preview + Video önizlemesi + + + + + + Mount + Bağla + + + + + + Auto mount + Otomatik bağla + + + + + + Open after auto mount + Otomatik bağlanım sonrası aç + + + + + + Dialog + İletişim + + + + Compressed file preview + Sıkıştırılmış dosya önizlemesi + + + + GvfsMountManager + + + Can’t verify the identity of %1. + %1 kimliği doğrulanamıyor. + + + + This happens when you log in to a computer the first time. + Bu, bir bilgisayarda ilk kez oturum açtığınızda olur. + + + + The identity sent by the remote computer is + Uzak bilgisayar tarafından gönderilen kimlik + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Devam etmenin güvenli olduğundan kesinlikle emin olmak istiyorsanız, sistem yöneticisine başvurun. + + + + + + + + Mounting device error + Aygıt bağlama hatası + + + + + Wrong username or password + Yanlış kullanıcı veya parola + + + + + + + + Confirm + button + Onayla + + + + + Cannot find the mounted device + Takılı aygıt bulunamıyor + + + + No key available to unlock device + Cihazın kilidini açmak için anahtar yok + + + + The disk is mounted by user "%1", you cannot unmount it. + Diski "%1" kullanıcısı bağlamış, siz bu bağı ayıramazsınız. + + + + Cannot unmount the device + Aygıtın bağı ayrılamadı + + + + Cannot eject the device "%1" + "%1" aygıtı çıkartılamadı + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Yazılamıyor. Hedef diskte yeterli boş alan yok. + + + + MergedDesktopController + + + + Pictures + Resimler + + + + + Music + Müzikler + + + + + Applications + Uygulamalar + + + + + Videos + Videolar + + + + + Documents + Belgeler + + + + + Others + Diğerleri + + + + MimeTypeDisplayManager + + + + Directory + Dizin + + + + + + Application + Uygulama + + + + + + Video + Video + + + + + + Audio + Ses + + + + + + Image + Görsel + + + + + Archive + Arşiv + + + + + + Text + Metin + + + + + Executable + Çalıştırılabilir + + + + + Backup file + Yedek dosyası + + + + + Unknown + Bilinmiyor + + + + MountAskPasswordDialog + + + Cancel + button + İptal + + + + Connect + button + Bağlan + + + + Log in as + Farklı oturum aç + + + + Anonymous + Anonim + + + + Registered user + Kayıtlı kullanıcı + + + + Username + Kullanıcı adı + + + + Domain + Alan adı + + + + Password + Parola + + + + Remember password + Parolayı hatırla + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + İptal + + + + Unlock + button + Kilidi aç + + + + Input password to decrypt the disk + Diskin şifresini çözmek için parolayı yazın + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + %1 ögesini kalıcı olarak silmek istediğinize emin misiniz? + + + + This file is too big for the trash + Bu dosya çöp kutusu için çok büyük + + + + The files are too big for the trash + Dosyalar çöp kutusu için çok büyük + + + + Are you sure you want to permanently delete %1 files? + %1 dosyayı kalıcı olarak silmek istediğinize emin misiniz? + + + + Cancel + button + İptal + + + + Delete + button + Sil + + + + OpenWithDialog + + + Open with + Birlikte aç + + + + Add other programs + Diğer programları ekle + + + + Set as default + Varsayılan olarak ayarla + + + + Cancel + button + İptal + + + + Confirm + button + Onayla + + + + Recommended Applications + Önerilen Uygulamalar + + + + Other Applications + Diğer Uygulamalar + + + + PathManager + + + Home + Ev + + + + Desktop + Masaüstü + + + + Videos + Videolar + + + + Music + Müzik + + + + Pictures + Resimler + + + + Documents + Belgeler + + + + Downloads + İndirilenler + + + + + Trash + Çöp Kutusu + + + + + + System Disk + Sistem Diski + + + + Computers in LAN + Yerel Ağdaki Bilgisayarlar + + + + My Shares + Paylaşımlarım + + + + Computer + Bilgisayar + + + + Recent + Son Kullanılanlar + + + + File Vault + Dosya Kasası + + + + PropertyDialog + + + Basic info + Temel bilgi + + + + Open with + Birlikte aç + + + + Sharing + Paylaşım + + + + Permissions + İzinler + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Bu klasörü gizle + + + + Hide this file + Bu dosyayı gizle + + + + Allow to execute as program + Program olarak yürütülebilir + + + + QObject + + + + + + Size + Boyut + + + + + + Contains + İçeriği + + + + + + Type + Tür + + + + + + + + Time modified + Değiştirilme zamanı + + + + Free space + Boş alan + + + + Total space + Toplam alan + + + + + Time locked + Zaman kilitlendi + + + + Access denied + Erişim reddedildi + + + + + Executable + Çalıştırılabilir + + + + + Write only + Salt yazılır + + + + + Read only + Salt okunur + + + + + Read-write + Okunur-yazılır + + + + Others + Diğerleri + + + + Owner + Sahip + + + + Unconnected network shared directory + + + + + Device type + Aygıt türü + + + + File system + Dosya sistemi + + + + Group + Grup + + + + + Open + + + + + Lock + Kilitle + + + + Auto lock + Otomatik kilitle + + + + Never + Asla + + + + 5 minutes + 5 dakika + + + + 10 minutes + 10 dakika + + + + 20 minutes + 20 dakika + + + + Delete File Vault + Dosya Kasasını Sil + + + + Unlock + Kilidi aç + + + + Unlock by key + Anahtarla kilidi aç + + + + Open + button + + + + + + Size: %1 + Boyut: %1 + + + + Type: %1 + Tür: %1 + + + + Size: 0 + Boyut: 0 + + + + Items: %1 + Öge: %1 + + + + + + + + + + Open in new window + Yeni pencerede aç + + + + + + + + + + Open in new tab + Yeni sekmede aç + + + + Open with + Birlikte aç + + + + + Compress + Sıkıştır + + + + Extract + Çıkart + + + + Extract here + Buraya çıkart + + + + Cut + Kes + + + + Copy + Kopyala + + + + Paste + Yapıştır + + + + + + + + Rename + Adlandır + + + + + + + Remove + Kaldır + + + + Create link + Bağ oluştur + + + + Send to desktop + Masaüstüne gönder + + + + Send to + Şuraya gönder + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Yer imlerine ekle + + + + + + + Properties + Özellikler + + + + New folder + Yeni klasör + + + + New window + Yeni pencere + + + + Select all + Tümünü seç + + + + + Clear recent history + Yakın geçmişi temizle + + + + + + Empty Trash + Çöp Kutusunu Boşalt + + + + Display as + Farklı görüntüle + + + + Sort by + Sırala + + + + New document + Yeni belge + + + + + Time created + Oluşturulma tarihi + + + + + + Source path + Kaynak yol + + + + Share folder + Klasörü paylaş + + + + Cancel sharing + Paylaşımı iptal et + + + + Connect to Server + Sunucuya Bağlan + + + + Set share password + Paylaşım parolasını ayarla + + + + Format + Biçimlendir + + + + Tag information + Etiket bilgileri + + + + Open as administrator + Yönetici olarak aç + + + + Select default program + Varsayılan programı seç + + + + Open file location + Dosya konumunu aç + + + + Remove bookmark + Yer imini kaldır + + + + + + Delete + Sil + + + + Office Text + Ofis Belgesi + + + + Spreadsheets + Ofis Tablosu + + + + Plain Text + Düz Metin + + + + Open in terminal + Uçbirimde aç + + + + Restore + Geri al + + + + Restore all + Tümünü geri al + + + + Clear saved password and unmount + + + + + File Vault + Dosya Kasası + + + + Add to disc + Diske ekle + + + + Refresh + + + + + Auto mount + Otomatik bağla + + + + Open after auto mount + Otomatik bağlanım sonrası aç + + + + + Mount + Bağla + + + + + Unmount + Bağı ayır + + + + It does not support burning %1 discs + %1 disk yazmayı desteklemiyor + + + + Burn + Yaz + + + + Disc name: + Disk adı: + + + + + Maximum + En fazla + + + + Allow files to be added later + Sonradan dosyalar eklenebilsin + + + + Verify data + Verileri doğrula + + + + Write speed: + Yazma hızı: + + + + + + + Cancel + button + İptal + + + + Burn + button + Yaz + + + + + Eject + Çıkar + + + + Safely Remove + Güvenli Kaldır + + + + + Name + Ad + + + + Settings + Ayarlar + + + + Exit + Çıkış + + + + Icon + Simge + + + + List + Liste + + + + Extend + Genişlet + + + + Set as wallpaper + Duvar kağıdı olarak ayarla + + + + + + + Local disk + Yerel disk + + + + + Removable disk + Çıkarılabilir disk + + + + + + Network shared directory + Ağ paylaşımlı dizin + + + + + Android mobile device + Android mobil aygıt + + + + + Apple mobile device + Apple mobil aygıt + + + + + Camera + Kamera + + + + + DVD + DVD + + + + + Unknown device + Bilinmeyen aygıt + + + + + + %1 item + %1 öge + + + + + + %1 items + %1 öge + + + + Shortcut + Kısayol + + + + Create symlink + Sembolik bağlantı oluştur + + + + Path + Yol + + + + + + Time deleted + Silinme tarihi + + + + Loading... + Yükleniyor... + + + + File has been moved or deleted + Dosya taşınmış ya da silinmiş + + + + You do not have permission to traverse files in it + İçindeki dosyalar arasında geçiş yapmaya izniniz yok + + + + + + You do not have permission to access this folder + Bu klasöre erişme izniniz yok + + + + + + + + Folder is empty + Klasör boş + + + + Searching... + Aranıyor... + + + + No results + Sonuç yok + + + + Source Path + TrashFileInfo + Kaynak Yol + + + + Document + Belge + + + + Spreadsheet + Tablolar + + + + + Presentation + Sunum + + + + Text + Metin + + + + 1 task in progress + 1 görev devam ediyor + + + + %1 tasks in progress + %1 görev devam diyor + + + + Mode: + Kip: + + + + + Replace Text + Metni Değiştir + + + + + Add Text + Metin Ekle + + + + + Custom Text + Özel Metin + + + + Find: + Bul: + + + + Replace: + Değiştir: + + + + + Optional + İsteğe bağlı + + + + Add: + Ekle: + + + + Location: + Konum: + + + + File name: + Dosya adı: + + + + Start at: + Başla: + + + + + Rename + button + Adlandır + + + + + + + + + + + Required + Zorunlu + + + + + Before file name + Dosya adından önce + + + + + After file name + Dosya adından sonra + + + + Find + Bul + + + + Replace + Değiştir + + + + Add + Ekle + + + + Start at + Başla + + + + + + Location + Konum + + + + File name + Dosya adı + + + + Dimension + Boyut + + + + Duration + Süre + + + + Tips: Sort by selected file order + İpuçları: Seçilmiş dosya sırasına göre sırala + + + + Rename %1 Files + %1 Dosyayı Yeniden Adlandır + + + + Multiple Files + Çoklu Dosyalar + + + + Basic info + Temel bilgi + + + + Total size + Toplam boyut + + + + Number of files + Dosya sayısı + + + + %1 file(s), %2 folder(s) + %1 dosya, %2 klasör + + + + + + Time accessed + Erişim zamanı + + + + Orange + Turuncu + + + + Red + Kırmızı + + + + Purple + Mor + + + + Navy-blue + Lacivert + + + + Azure + Mavi + + + + Green + Yeşil + + + + Yellow + Sarı + + + + Gray + Gri + + + + Input tag info, such as work, family. A comma is used between two tags. + Aile, iş gibi etiket bilgilerini yazın. İki etiketi virgül ile ayırarak yazın. + + + + Bookmarks + Yer imleri + + + + Erase + Sil + + + + Copy path + Yolu kopyala + + + + Edit address + Adresi düzenle + + + + Free Space %1 + Boş Alan %1 + + + + Files are being processed + Dosyalar işleniyor + + + + + Unknown + Bilinmiyor + + + + My Vault + Kasam + + + + + Failed to create file info + Dosya bilgisi oluşturulamadı + + + + Failed to create file handler + Dosya işleyicisi oluşturulamadı + + + + Failed to open the file, cause: %1 + Dosya şu nedenle açılamadı: %1 + + + + Original file does not exist + Özgün dosya bulunamadı + + + + Do you want to delete %1? + %1'i silmek istiyor musunuz? + + + + Confirm + button + Onayla + + + + + + + + %1 are not allowed + %1'e izin verilmiyor + + + + + Failed to start Samba services + + + + + RecentController + + + Cancel + button + İptal + + + + Remove + button + Kaldır + + + + Do you want to remove this item? + + + + + Do yout want to remove %1 items? + + + + + It does not delete the original files + + + + + ShareInfoFrame + + + Share this folder + Bu klasörü paylaş + + + + Share name: + Paylaşım adı: + + + + Permission: + İzin: + + + + Read and write + Okunur ve yazılır + + + + Read only + Salt okunur + + + + Anonymous: + Anonim: + + + + Not allow + İzin verme + + + + Allow + İzin ver + + + + The share name must not be two dots (..) or one dot (.) + Paylaşım adı iki nokta (..) veya bir nokta (.) olmamalıdır + + + + The share name is used by another user. + Paylaşım adı başka bir kullanıcı tarafından kullanılıyor. + + + + OK + button + Tamam + + + + Cancel + button + İptal + + + + Replace + button + Değiştir + + + + The share name already exists. Do you want to replace the shared folder? + Paylaşım adı zaten var. Paylaşılan klasörü değiştirmek istiyor musunuz? + + + + Shortcut + + + Item + Öge + + + + Select to the first item + İlk ögeye kadar seç + + + + Shift + Home + Shift + Home + + + + Select to the last item + Son ögeye kadar seç + + + + Shift + End + Shift + End + + + + Select leftwards + Sola doğru seç + + + + Shift + Left + Shift + Sol + + + + Select rightwards + Sağa doğru seç + + + + Shift + Right + Shift + Sağ + + + + Select to upper row + Üst satıra kadar seç + + + + Shift + Up + Shift + Yukarı + + + + Select to lower row + Alt satıra kadar seç + + + + Shift + Down + Shift + Aşağı + + + + Open + + + + + Ctrl + Down + Ctrl + Aşağı + + + + To parent directory + Üst klasöre geç + + + + Ctrl + Up + Ctrl + Yukarı + + + + Permanently delete + Kalıcı olarak sil + + + + Shift + Delete + Shift + Delete + + + + Delete file + Dosyayı sil + + + + Delete + Sil + + + + Select all + Tümünü seç + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Kopyala + + + + Cut + Kes + + + + Paste + Yapıştır + + + + Rename + Yeniden adlandır + + + + F2 + F2 + + + + New/Search + Yeni/Ara + + + + New window + Yeni pencere + + + + New folder + Yeni klasör + + + + + Search + Ara + + + + New tab + Yeni sekme + + + + View + Görünüm + + + + Item information + Öge bilgisi + + + + Help + Yardım + + + + F1 + F1 + + + + Keyboard shortcuts + Klavye kısayolları + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Ekran durumunu değiştir + + + + Hide item + Ögeyi gizle + + + + Input in address bar + Adres çubuğuna giriş + + + + Switch to icon view + Simge görünümüne geç + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Liste görünümüne geç + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Diğerleri + + + + Close + Kapat + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Mevcut sekmeyi kapat + + + + Back + Geri + + + + Alt + Left + Alt + Sol + + + + Alt + Right + Alt + Sağ + + + + Switch to next tab + Sonraki sekmeye geç + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Önceki sekmeye geç + + + + Next file + Sonraki dosya + + + + Tab + Tab + + + + Previous file + Önceki dosya + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Sekmeyi 1'den 8'e kadar belirtilen sayıya çevir + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + İleri + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Çöp kutusundaki ögeler açılamıyor, lütfen önce geri yükleyin + + + + TrashPropertyDialog + + + Trash + Çöp kutusu + + + + item + öge + + + + items + öge + + + + Contains %1 %2 + %1 %2 içeriyor + + + + UDiskListener + + + Failed to rename the label + Etiket yeniden adlandırılamadı + + + + UnmountWorker + + + + + The device was not safely unmounted + Cihaz güvenli bir şekilde kaldırılmadı + + + + The device was not safely removed + Cihaz güvenli bir şekilde kaldırılmadı + + + + UserShareManager + + + Kindly Reminder + Nazikçe Hatırlat + + + + Please firstly install samba to continue + Lütfen devam etmek için önce samba kurun + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + + + + + To protect the files, you cannot share this folder. + Dosyaları korumak için bu klasörü paylaşamazsınız. + + + + Sharing failed + Paylaşım başarısız oldu + + + + The computer name is too long + Bilgisayar adı çok uzun + + + + You do not have permission to operate file/folder! + Dosya ya da klasör üzerinde çalıştırma izniniz yok! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Paylaşılan klasörleri korumak için bir parola gir + + + + Cancel + button + İptal + + + + Confirm + button + Onayla + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ug.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ug.ts new file mode 100644 index 0000000..6fd2eeb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_ug.ts @@ -0,0 +1,4718 @@ + + + AppController + + + New Folder + مۇندەرىجە قۇرۇش + + + + Mounting device error + قاچىلاش ئۈسكۈنىسىدە خاتالىق كۆرۈلدى + + + + The disc image was corrupted, cannot mount now, please erase the disc first + بۇ دىسكىدىكى رەسىم بۇزۇلغان، قاچىلىغىلى بولمايدۇ، ئۆچۈرۋەتكەندىن كېيىن ئىشلىتىڭ + + + + Mount error: unsupported image format + قاچىلاش خاتا، رەسىم ھۆججەت فورماتىنى قوللىمايدۇ + + + + + The device was not safely removed + ئۈسكۈنە نورمال ئۆچۈرۈلمىدى + + + + + Click "Safely Remove" and then disconnect it next time + «بىخەتەر ئۆچۈرۈش» نى باسقاندىن كېيىن ئۇلىنىشنى ئۈزۈڭ + + + + The device was not ejected + ئۈسكۈنە چىقىرىلمىدى + + + + Disk is busy, cannot eject now + دىسكا ئالدىراش ، ھازىر چىقىرىۋېتەلمەيدۇ + + + + Authentication timed out + دەلىللەش ۋاقتى ئۆتۈپ كەتتى + + + + BluetoothTransDialog + + + Bluetooth File Transfer + كۆكچىش ئارقىلىق ھۆججەت يوللاش + + + + File Transfer Successful + ھۆججەت يوللاش مۇۋەپپەقىيەتلىك بولدى + + + + File Transfer Failed + ھۆججەت يوللاش مەغلۇپ بولدى + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + “<b style="font-weight: 550;">%1</b>”گە ھۆججەت يوللاۋاتىدۇ + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + گە ھۆججەت يوللانمىدى "<b style="font-weight: 550;">%1</b>" + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + “<b style="font-weight: 550;">%1</b>”گە ھۆججەت يوللاندى + + + + Select a Bluetooth device to receive files + بۇ ھۆججەتنى قوبۇل قىلىدىغان كۆكچىش ئۈسكۈنىسىنى تاللاڭ + + + + Cannot find the connected Bluetooth device + ئۇلانغان كۆكچىش ئۈسكۈنىسى يوق + + + + Waiting to be received... + قوبۇللاشنى ساقلاۋاتىدۇ، سەل ساقلاڭ + + + + Go to Bluetooth Settings + كۆكچىش تەڭشىكىگە كىرىش + + + + %1/%2 Sent + %1/%2 يوللاندى + + + + Error: the Bluetooth device is disconnected + سەۋەبى: كۆكچىش ئۈسكۈنىسىنىڭ ئۇلىنىشى ئۈزۈلۈپ قالدى + + + + Unable to send the file more than 2 GB + 2GB دىن چوڭ ھۆججەتنى قوبۇللىيالمايدۇ + + + + Unable to send 0 KB files + 0KB لىق ھۆججەتنى يوللىغىلى بولمايدۇ + + + + File doesn't exist + ھۆججەت مەۋجۇت ئەمەس + + + + Next + button + كىيىنكىسى + + + + Cancel + button + بىكار قىلىش + + + + Done + button + تامام + + + + Retry + button + قايتا سىناڭ + + + + OK + button + ماقۇل + + + + File sending request timed out + ھۆججەت يوللانمىدى + + + + The service is busy and unable to process the request + ئۈسكۈنە ئىنكاس قايتۇرمىدى، تەلىپىڭىزنى ئورۇندىيالمايدۇ + + + + BurnOptDialog + + + Device error + ئۈسكۈنىدە كاشىلا كۆرۈلدى + + + + Optical device %1 doesn't exist + ئوپتىك قوزغاتقۇچ%1 مەۋجۇت ئەمەس + + + + Advanced settings + ئالىي تەڭشەك + + + + File system: + ھۆججەت سىستېمىسى + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (Windows تا ئىشلەيدۇ) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (Unix تا ئىشلەيدۇ) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 فورماتى (Windowsنىڭ سۈكۈتتىكى CD/DVD ئويغۇچىنى قوللايدۇ) + + + + ISO9660 Only + ISO9660 نىلا قوللايدۇ + + + + CloseAllDialogIndicator + + + Close all + ھەممىنى تاقاش + + + + Total size: %1, %2 files + ئومۇمىي سىغىمى% 1 ، ھۆججەتلەرنىڭ ئومۇمىي سانى% 2 + + + + ComputerModel + + + Double click to open it + قوش چېكىپ ئەپنى ئېچىڭ + + + + My Directories + مۇندەرىجەم + + + + Disks + دىسكا + + + + File Vault + بىخەتەرلىك ساندۇقى + + + + Quick Access + تېز زىيارەت قىلىش + + + + ComputerPropertyDialog + + + Computer + كومپيوتېر + + + + Basic Info + ئاساسىي ئۇچۇر + + + + + Computer Name + كومپيوتېر نامى + + + + + Edition + نەشىرى + + + + + + Version + نەشىر + + + + + Type + تىپى + + + + + + Processor + بىر تەرەپ قىلغۇچ + + + + + + Memory + ئىچكى سىغىمى + + + + + + + Bit + بىت + + + + + Available + ئىشلەتكىلى بولىدۇ + + + + Obtaining... + ئېرىشىۋاتىدۇ... + + + + ConnectToServerDialog + + + Connect to Server + مۇلازىمېتىرغا ئۇلاش + + + + Cancel + button + بىكار قىلىش + + + + Connect + button + ئۇلاش + + + + My Favorites: + شەخسىي يىغىش مۇلازىمىتىرى + + + + + Clear History + يېقىندا ئىشلىتىلگەن مۇلازىمېتىرلارنى ئۆچۈرۈش + + + + DFMAddressBar + + + Search or enter address + ئادرېسنى ئىزدەڭ ياكى كىرگۈزۈڭ + + + + DFMAdvanceSearchBar + + + Search: + ئىزدەش دائىرىسى: + + + + File Type: + ھۆججەت تىپى: + + + + File Size: + ھۆججەت چوڭلۇقى: + + + + Time Modified: + ئۆزگەرتىلگەن ۋاقتى: + + + + Time Accessed: + زىيارەت ۋاقتى: + + + + Time Created: + قۇرۇلغان ۋاقتى: + + + + Reset + ئەسلىگە قايتۇرۇش + + + + All subdirectories + بارلىق تارماق ھۆججەتلەر + + + + Current directory + نۆۋەتتىكى ھۆججەت قىسقۇچ + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + 1 GB< + + + + Today + بۈگۈن + + + + Yesterday + تۈنۈگۈن + + + + This week + بۇ ھەپتە + + + + Last week + ئالدىنقى ھەپتە + + + + This month + بۇ ئاي + + + + Last month + ئالدىنقى ئاي + + + + This year + بۇ يىل + + + + Last year + بۇلتۇر + + + + DFMOpticalMediaWidget + + + + No files to burn + ئويىدىغان ھۆججەت يوق + + + + Unable to burn. Not enough free space on the target disk. + نىشان دىسكىنىڭ قالدۇق بوشلۇقى يېتىشمىدى، كۆچۈرگىلى بولمايدۇ! + + + + %1 burning is not supported + بۇ دىسكا %1نى ئويالمايدۇ + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. تىپى %1 ئەمەس؛ +2. نۆۋەتتە ئوپتىك دىسكا ھۆججەت سىستېمىسىنىڭ نەشرى ۋاقتىنچە قوشۇپ ئويۇشنى قوللىمايدۇ. + + + + DFMTagCrumbController + + + Tag information + خەتكۈچ ئۇچۇرى + + + + DFMTagWidget + + + Tag + خەتكۈچ + + + + DFMTaskWidget + + + Do not ask again + قايتا سورىما + + + + Syncing data + سانلىق مەلۇمات ماس قەدەملىنىۋاتىدۇ + + + + Please wait + سەل ساقلاڭ + + + + + Time modified: %1 + ئۆزگەرتىلگەن ۋاقىت: %1 + + + + + Contains: %1 + دانە: %1 + + + + + Size: %1 + چوڭلۇقى: %1 + + + + Original folder + ئەسلى ھۆججەت قىسقۇچ + + + + Keep both + button + تەڭ ساقلاش + + + + Skip + button + ئاتلاش + + + + Replace + button + ئالماشتۇرۇش + + + + Retry + button + قايتا سىناڭ + + + + Original file + ئەسلى ھۆججەت + + + + Target folder + نىشان ھۆججەت قىسقۇچ + + + + Target file + نىشان ھۆججەت + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + بىخەتەرلىك ساندۇقىغا قوشۇش + + + + Click 'Encrypt' and input the user password. + «بىخەتەرلىك ساندۇقىغا قوشۇش» نى باسقاندىن كېيىن، ئىشلەتكۈچى پارولىنى كىرگۈزۈپ تەڭشەكنى تاماملاڭ. + + + + Encrypting... + شىفىرلاشتۇرۇۋاتىدۇ... + + + + + + + Encrypt + بىخەتەرلىك ساندۇقىغا قوشۇش + + + + Failed to create file vault: %1 + بىخەتەرلىك ساندۇقىغا قوشالمىدى: %1 + + + + OK + ماقۇل + + + + The setup is complete + شىفىرلاندى + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + ئاچقۇچلۇق ھۆججەتنى ساقلاش + + + + Keep the key safe to retrieve the vault password later + ئاچقۇچ ھۆججىتى بىخەتەرلىك ساندۇقىنىڭ پارولىنى قايتۇرۇشقا ئىشلىتىلىدۇ،ياخشى ساقلاڭ + + + + Save to default path + كۆڭۈلدىكى يولغا ساقلاش + + + + Save to other locations + باشقا يولغا ساقلاش + + + + No permission, please reselect + ھوقۇقى يەتمىدى،قايتا تاللاڭ + + + + Select a path + ئاچقۇچلۇق ھۆججەتنى ساقلاش يولىنى تاللاڭ + + + + Next + كىيىنكىسى + + + + The default path is invisible to other users, and the path information will not be shown. + كۆڭۈلدىكى يول باشقا ئابونتلارنىڭ ئالاھىدە يولىنى ئاشكارىلىمايدۇ، ھەمدە يول ئۇچۇرىنى ئېنىق كۆرسەتمەيدۇ. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + ھۆججەت بىخەتەرلىك ساندۇقىنىڭ شىفىرلىق ئاچقۇچىنى ئەسلىگە كەلتۈرۈش + + + + Generate a recovery key in case that you forgot the password + ئەگەر پارولنى ئۇنتۇپ قالسىڭىز ، ئاچقۇچنى ئىشلىتىپ زىيارەتنى ئەسلىگە كەلتۈرەلەيسىز + + + + Key + شىفىرلىق ئاچقۇچ + + + + QR code + چىپاركود + + + + Scan QR code and save the key to another device + QR كودىنى سايىلەپ باشقا ئۈسكۈنىلەرگە ساقلاڭ + + + + Next + كىيىنكىسى + + + + Recovery Key: + ھۆججەت بىخەتەرلىك ساندۇقىنى ئەسلىگە كەلتۈرۈش ئاچقۇچى: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + ئېچىش ئۇسۇلىنى تەڭشەڭ + + + + Method + تىپى + + + + Manual + قولدا + + + + Password + پارول + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + كەم دېگەندە 8 خانە بولۇشى، A-Z, a-z, 0-9 لارنى ۋە ھەرپنى ئۆز ئىچىگە ئېلىشى كېرەك + + + + Repeat password + پارولنى قايتا سېلىش + + + + Input the password again + پارولنى قايتا كىرگۈزۈڭ + + + + Password hint + پارول ئەسكەرتىشى + + + + Optional + ئىختىيارى + + + + Next + كىيىنكىسى + + + + + Passwords do not match + پارول بىردەك ئەمەس + + + + DFMVaultActiveStartView + + + File Vault + بىخەتەرلىك ساندۇقى + + + + Create your secure private space + شەخسكە خاس بىخەتەر بوشلۇق + + + + Advanced encryption technology + ئىلغار مەخپىيلەشتۈرۈش تېخنىكىسى قوللىنىلغان، مەخپىيەتلىك ۋە بىخەتەرلىككە كاپالەتلىك قىلىنىدۇ + + + + Convenient and easy to use + ئىشلىتىشكە تېخىمۇ قۇلايلىق، مەشغۇلات قىلىش ئاسان + + + + Create + ئېچىش + + + + DFMVaultFileView + + + Cannot open this path + بۇ يولنى ئاچقىلى بولمىدى + + + + Hint + ئەسكەرتىش + + + + OK + ماقۇل + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + شىفىرلىق ئاچقۇچتا ئېچىشنى ئەسلىگە كۈلتۈرۈش + + + + Failed to unlock file vault + بىخەتەرلىك ساندۇقى ئېچىلمىدى + + + + OK + ماقۇل + + + + Input the 32-digit recovery key + 32 خانىلىق ئەسلىگە كەلتۈرۈش ئاچقۇچىنى كىرگۈزۈڭ + + + + Cancel + button + بىكار قىلىش + + + + Unlock + button + قۇلۇپ ئېچىش + + + + Wrong recovery key + پارول خاتا + + + + DFMVaultRemoveByPasswordView + + + Password + پارول + + + + Password hint: %1 + پارول ئەسكەرتىشى: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + 32 خانىلىق ئەسلىگە كەلتۈرۈش ئاچقۇچىنى كىرگۈزۈڭ + + + + DFMVaultRemovePages + + + Delete File Vault + بىخەتەرلىك ساندۇقىنى ئۆچۈرۈش + + + + Once deleted, the files in it will be permanently deleted + بىخەتەرلىك ساندۇقىنى ئۆچۈرگەندىن كېيىن، ئۇنىڭدىكى بارلىق مەزمۇن مەڭگۈلۈك ئۆچۈرۈلىدۇ + + + + Use Key + شىفىرلىق ئاچقۇچنى دەلىللەش + + + + Cancel + button + بىكار قىلىش + + + + Use Key + button + شىفىرلىق ئاچقۇچنى دەلىللەش + + + + Delete + button + ئۆچۈرۈش + + + + + OK + button + ماقۇل + + + + Use Password + پارول بىلەن دەلىللەش + + + + Wrong password + پارول خاتا + + + + Wrong recovery key + پارول خاتا + + + + Failed to delete file vault + بىخەتەرلىك ساندۇقىنى ئۆچۈرگىلى بولمىدى + + + + Deleted successfully + ئۆچۈرۈلدى + + + + Failed to delete + ئۆچۈرەلمىدى + + + + Removing... + ئۆچۈرۈۋاتىدۇ... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + ئاچقۇچلۇق ھۆججەتكە ئېرىشەلمىدى + + + + Verification failed + ئاچقۇچ دەلىللەش مەغلۇب بولدى + + + + + Select a path + ئاچقۇچلۇق ھۆججەتنى ساقلاش يولىنى تاللاڭ + + + + + Retrieve Password + پارول قايتۇرۇش + + + + By key in the default path + كۆڭۈلدىكى يولدىكى ئاچقۇچلۇق ھۆججەت ئارقىلىق پارول قايتۇرۇش + + + + By key in the specified path + ئاچقۇچ ھۆججەت ئورنىنى كۆرسىتىش ئارقىلىق پارولنى قايتۇرۇش + + + + Verification Successful + ئاچقۇچ دەلىللەندى + + + + Keep it safe + ياخشى ساقلاڭ + + + + Back + button + قايتىش + + + + Verify Key + button + ئاچقۇچ دەلىللەش + + + + Go to Unlock + button + قۇلۇپ يىشىشكە قايتىش + + + + Close + button + تاقاش + + + + Vault password: %1 + بىخەتەرلىك ساندۇقى پارولى: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + بىخەتەرلىك ساندۇقىنى ئېچىش + + + + Forgot password? + پارول قايتۇرىمەن + + + + Password hint: %1 + پارول ئەسكەرتىشى: %1 + + + + Failed to unlock file vault + بىخەتەرلىك ساندۇقى ئېچىلمىدى + + + + Cancel + button + بىكار قىلىش + + + + Password + پارول + + + + Unlock + button + قۇلۇپ ئېچىش + + + + Please try again %1 minutes later + %1 مىنۇتتىن كېيىن سىناڭ + + + + Wrong password, please try again %1 minutes later + پارول خاتا، %1 مىنۇتتىن كېيىن سىناڭ + + + + Wrong password, one chance left + پارول خاتا، يەنە 1 قېتىم سىنىيالايسىز + + + + Wrong password, %1 chances left + پارول خاتا، يەنە %1 قېتىم سىنىيالايسىز + + + + Wrong password + پارول خاتا + + + + OK + button + ماقۇل + + + + DFileCopyMoveJob + + + Permission error + ھۆججەت ئىجازىتى خاتا + + + + The action is denied + ھۆججەت بۇ مەشغۇلاتنى قوللىمايدۇ + + + + Failed to open the file + ھۆججەت ئېچىلمىدى + + + + Failed to read the file + ھۆججەت مەزمۇنىنى ئوقۇيالمىدى + + + + Failed to write the file + ھۆججەت مەزمۇنىنى يېزىش مەغلۇب بولدى + + + + Failed to create the directory + مۇندەرىجە قۇرۇش مەغلۇب بولدى + + + + Failed to delete the file + بۇ ھۆججەتنى ئۆچۈرەلمىدى + + + + Failed to move the file + ھۆججەت يۆتكەش مەغلۇب بولدى + + + + Original file does not exist + مەنبە ھۆججىتى مەۋجۇت ئەمەس + + + + Failed, file size must be less than 4GB + مەشغۇلات مەغلۇپ بولۇپ ، ھۆججەتنىڭ سىغىمى 4GB دىن ئېشىپ كەتتى! + + + + Not enough free space on the target disk + نىشان دىسكىدىكى قالدۇق بوشلۇق يەتمىدى + + + + File integrity was damaged + ھۆججەتنىڭ مۇكەممەللىكىنى تەكشۈرۈش مەغلۇپ بولدى + + + + The target device is read only + نىشان ئۈسكۈنە پەقەت ئوقۇلىدۇ + + + + Target folder is inside the source folder + نىشان ھۆججەت قىسقۇچ مەنبەلىك ھۆججەت قىسقۇچنىڭ ئىچىدە + + + + The action is not supported + بۇ مەشغۇلاتنى قوللىمايدۇ + + + + You do not have permission to traverse files in it + تارماق ھۆججەتلەرنى كۆرۈش ھوقۇقىڭىز يوق + + + + Failed to position the file pointer! + ئورنىنى كۆرسىتىش مەغلۇب بولدى! + + + + copy + Extra name added to new file name when used for file name. + كۆچۈرۈش + + + + Failed to open the directory, cause: file name too long + مۇندەرىجىنى ئېچىش مەغلۇب بولدى ، سەۋەبى: ھۆججەت نامى ئۇزۇن + + + + + Failed to open the file, cause: file name too long + ھۆججەتنى ئېچىش مەغلۇب بولدى ، سەۋەبى: ھۆججەت نامى ئۇزۇن + + + + + Failed to write the file, cause: + ھۆججەت مەزمۇنىنى يېزىش مەغلۇپ بولدى، سەۋەبى: + + + + Failed to position the file pointer, cause: %1 + ئورنىنى كۆرسىتەلمىدى، سەۋەبى :%1 + + + + Syncing data + سانلىق مەلۇمات ماس قەدەملىنىۋاتىدۇ + + + + Please wait + سەل ساقلاڭ + + + + Failed to create the directory, cause: %1 + مۇندەرىجە قۇرۇش مەغلۇب بولدى ، سەۋەبى:% 1 + + + + + + + + Failed to open the file, cause: %1 + ھۆججەت ئېچىش مەغلۇب بولدى ، سەۋەبى:% 1 + + + + + + + Failed to open the file, cause: Permission denied + ھۆججەتنى ئېچىش مەغلۇب بولدى ، سەۋەبى: ھوقۇقىڭىز يەتمەيدۇ + + + + + Failed to read the file, cause: %1 + ھۆججەت مەزمۇنىنى ئوقۇيالمىدى ، سەۋەبى:% 1 + + + + + + + Failed to write the file, cause: %1 + ھۆججەت مەزمۇنىنى يېزىش مەغلۇب بولدى ، سەۋەبى:% 1 + + + + + File integrity was damaged, cause: %1 + ھۆججەتنىڭ مۇكەممەللىكىنى تەكشۈرۈش مەغلۇب بولدى ، سەۋەبى:% 1 + + + + Failed to open the file, cause: + ھۆججەتنى ئېچىش مەغلۇب بولدى ، سەۋەبى:% 1 + + + + Failed to read the file, cause: + ھۆججەت مەزمۇنىنى ئوقۇيالمىدى ، سەۋەبى:% 1 + + + + Failed to delete the file, cause: %1 + ھۆججەت ئۆچۈرۈش مەغلۇب بولدى ، سەۋەبى:% 1 + + + + Fail to create symlink, cause: %1 + %1 سەۋەبلىك ئۇلىنىش قۇرۇش مەغلۇب بولدى + + + + DFileDialog + + + + Save + button + ساقلاش + + + + + Cancel + button + بىكار قىلىش + + + + Confirm + button + جەزملەشتۈرۈش + + + + %1 already exists, do you want to replace it? + «%1» مەۋجۇت، ئالماشتۇرامسىز؟ + + + + Replace + button + ئالماشتۇرۇش + + + + Open + button + ئېچىش + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + “.” بىلەن باشلانسا بۇ ھۆججەت يوشۇرۇلىدۇ، داۋاملاشتۇرامسىز؟ + + + + DFileManagerWindow + + + Trash + يىغىۋېلىش پونكىتى + + + + Empty + قۇرۇقداش + + + + DFileSystemModel + + + + Name + نامى + + + + + + Time modified + ئۆزگەرتىلگەن ۋاقىت + + + + Size + چوڭلۇقى + + + + Type + تىپى + + + + Time created + قۇرۇلغان ۋاقتى + + + + + Last access + ئاخىرقى زىيارەت ۋاقتى + + + + + + + Path + يول + + + + DFileView + + + Disc mount error + دىسكىغا ئورنىتىشتا خاتالىق كۆرۈلدى + + + + The disc is in use, please end the running process and remount the disc. + نۆۋەتتىكى قوزغاتقۇچ ئۈسكۈنىسى ئىشلىتىلىۋاتىدۇ، ئىگىلىۋالغان پىروگراممىلارنى تاقاپ قايتا ئورنىتىڭ + + + + Mounting failed + مەشغۇلات مەغلۇب بولدى + + + + (Reverse) + (تەتۈر تىزىش) + + + + DFileViewHelper + + + Add tag "%1" + خەتكۈچ قوشۇش "% 1" + + + + DStatusBar + + + %1 item + %1تۈر + + + + %1 items + %1تۈر + + + + %1 item selected + %1 تۈرلۈك مەزمۇننى تاللاش + + + + %1 items selected + %1 تۈرلۈك مەزمۇننى تاللاش + + + + %1 folder selected (contains %2) + % 1 ھۆججەت قىسقۇچنى تاللاڭ (% 2 نى ئۆز ئىچىگە ئالىدۇ) + + + + %1 folders selected (contains %2) + % 1 ھۆججەت قىسقۇچنى تاللاڭ (% 2 نى ئۆز ئىچىگە ئالىدۇ) + + + + %1 file selected (%2) + %1 ھۆججەتنى تاللاش (%2) + + + + %1 files selected (%2) + %1 ھۆججەتنى تاللاش (%2) + + + + %1 folder selected + %1 ھۆججەت قىسقۇچنى تاللاش + + + + Filter + سۈزگۈچ + + + + Save as: + ساقلاش: + + + + Loading... + يۈكلەۋاتىدۇ... + + + + DTaskDialog + + + Erasing disc %1, please wait... + %1 دىسكىنى فورماتلاۋاتىدۇ ، سەل ساقلاڭ... + + + + Burning disc %1, please wait... + ئويۇپ %1 غا كەلدى، سەل ساقلاڭ... + + + + Writing data... + سانلىق مەلۇمات يېزىلىۋاتىدۇ... + + + + Verifying data... + سانلىق مەلۇمات تەكشۈرۈلۈۋاتىدۇ... + + + + Copying %1 + كۆپەيتىۋاتىدۇ%1 + + + + + + to %2 + %2 گە كەلدى + + + + %1 already exists in target folder + نىشان ھۆججەت قىسقۇچتا %1 ناملىق ھۆججەت مەۋجۇت + + + + Original path %1 Target path %2 + ئەسلىدىكى ئورۇن %1 نىشان ئورۇن %2 + + + + Merge + button + قوشۇۋېتىش + + + + Replace + button + ئالماشتۇرۇش + + + + Moving %1 + يۆتكىلىۋاتىدۇ%1 + + + + Removing file vault, please try later + بىخەتەرلىك ساندۇقى ئۆچۈرۈلۈۋاتىدۇ، سەل ساقلاڭ... + + + + Restoring %1 + ئەسلىگە قايتۇرۇۋاتىدۇ%1 + + + + Deleting %1 + ئۆچۈرۈۋاتىدۇ%1 + + + + Trashing %1 + يۆتكىلىۋاتىدۇ%1 + + + + Calculating space, please wait + سىغىمى ھېسابلىنىۋاتىدۇ، سەل ساقلاڭ + + + + DUMountManager + + + + Authentication timed out + دەلىللەش ۋاقتى ئۆتۈپ كەتتى + + + + + + Disk is busy, cannot unmount now + دىسكا ھۆججىتى ئىگىلىۋېلىندى ، ئۆچۈرگىلى بولمايدۇ + + + + Disk is busy, cannot eject now + دىسكا ئالدىراش ، ھازىر چىقىرىۋېتەلمەيدۇ + + + + The device is busy, cannot eject now + دىسكا ئالدىراش ، ھازىر چىقىرىۋېتەلمەيدۇ + + + + + + The device is busy, cannot remove now + دىسكا ئالدىراش ، ھازىر بىخەتەر چىقىرىۋېتەلمەيدۇ + + + + DeepinStorage + + + + + %1 Volume + %1 رايۇن + + + + Data Disk + Data Partition + سانلىق مەلۇمات دىسكىسى + + + + %1 Drive + %1 قوزغاتقۇچ + + + + Blank %1 Disc + قۇرۇق %1 دىسكا + + + + %1 Encrypted + % 1 شىفىرلانغان + + + + DialogManager + + + + + + Operation failed! + مەشغۇلات مەغلۇب بولدى + + + + Target folder is inside the source folder! + نىشان ھۆججەت قىسقۇچ مەنبەلىك ھۆججەت قىسقۇچنىڭ ئىچىدە! + + + + Do you want to run %1 or display its content? + “%1” نى ئىجرا قىلماقچىمۇ ياكى ئۇنىڭ مەزمۇنىنى كۆرمەكچىمۇ؟ + + + + It is an executable text file. + بۇ ئىجرا قىلغىلى بولىدىغان تېكىسىت ھۆججىتى. + + + + It is an executable file. + بۇ ئىجرا قىلغىلى بولىدىغان ھۆججەت. + + + + This file is not executable, do you want to add the execute permission and run? + بۇ ھۆججەتنىڭ ئىجرا قىلىشقا بولىدىغان ھوقۇق يوق. ھوقۇق قوشۇپ ئىجرا قىلماقچىمۇ؟ + + + + "%1" already exists, please use another name. + «%1» ھۆججەت نامى مەۋجۇت،باشقا نام قوللىنىڭ + + + + The file name must not contain two dots (..) + ھۆججەت ئىسمىدا ئىككى دانە چىكىت(..) بولسا بولمايدۇ + + + + Device or resource busy + ئۈسكۈنە ياكى مەنبە ئالدىراش + + + + Are you sure you want to erase all data on the disc? + بۇ دىسكىدىكى بارلىق مەزمۇننى ئۆچۈرمەكچىمۇ؟ + + + + How do you want to use this disc? + بۇ دىسكىغا تەسۋىر ئويماقچىمۇ ياكى ھۆججەت ساقلىماقچىمۇ؟ + + + + Disc erase failed + ئۆچۈرەلمىدى + + + + Burn process failed + ئويالمىدى + + + + %1: %2 + %1:%2 + + + + Show details + تەپسىلاتىنى كۆرۈش + + + + Hide details + تەپسىلاتىنى يوشۇرۇش + + + + Error + خاتالىق ئۇچۇرى + + + + Permanently delete %1? + %1 نى راستلا تەلتۆكۈس ئۆچۈرەمسىز؟ + + + + Permanently delete %1 items? + تاللانغان %1 تۈرلۈك مەزمۇننى تەلتۆكۈس ئۆچۈرمەكچىمۇ؟ + + + + Empty + قۇرۇقداش + + + + Do you want to delete %1? + %1نى ئۆچۈرەمسىز؟ + + + + Do you want to delete the selected %1 items? + تاللىغان %1 تۈرلۈك مەزمۇننى ئۆچۈرەمسىز؟ + + + + Sorry, unable to locate your bookmark directory, remove it? + كەچۈرۈڭ، خەتكۈچ مۇندەرىجىسىنى تاپالمىدى، ئۆچۈرەمسىز؟ + + + + Name: + نامى: + + + + %1 that this shortcut refers to has been changed or moved + بۇ تېزلەتمە كۆرسەتكەن “%1” ئۆزگەرتىۋېتىلگەن ياكى يۆتكىۋېتىلگەن + + + + Do you want to delete this shortcut? + بۇ تېزلەتمىنى ئۆچۈرەمسىز؟ + + + + Failed, file size must be less than 4GB. + مەغلۇب بولدى، ھۆججەت سىغىمى 4GBلىق يۇقىرى چەكتىن ئېشىپ كەتتى! + + + + Fail to create symlink, cause: + ئۇلىنىش قۇرالمىدى، سەۋەبى: + + + + The selected files contain system file/directory, and it cannot be deleted + تاللانغان ھۆججەتتە سىستېما مۇندەرىجىسى بار، ئۆچۈرگىلى بولمايدۇ + + + + Unable to find the original file + ئۇلىنىش نىشان ھۆججىتىنى تاپالمىدى + + + + + You do not have permission to operate file/folder! + سىزنىڭ بۇ ھۆججەت/ ھۆججەت قىسقۇچقا مەشغۇلات قىلىدىغان ھوقۇقىڭىز يوق! + + + + Failed to restore %1 file, the source file does not exist + ئەسلى ھۆججەت مەۋجۇت ئەمەس، %1 ھۆججەتنى ئەسلىگە قايتۇرۇش مەغلۇب بولدى + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + كەچۈرۈڭ، تۆۋەندىكى %1 ھۆججەت/ ھۆججەت قىسقۇچقا مەشغۇلات قىلىدىغان ھوقۇقىڭىز يوق + + + + Unable to access %1 + %1نى زىيارەت قىلغىلى بولمىدى + + + + + Sending files now, please try later + ھازىر ھۆججەت ئەۋەتىلىۋاتىدۇ، بىردەمدىن كېيىن قايتا سىناڭ + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + بۇ ئۈسكۈنىنى زىيارەت قىلىش ئۈچۈن دىسكىنى فورماتلاش كېرەك، داۋاملاشتۇرامسىز؟ + + + + Scanning the device, stop it? + ئۈسكۈنە سايىلىنىۋاتىدۇ، سايىلەشنى توختىتامسىز؟ + + + + Share folder can't be named after the current username + ئورتاقلاشقان ھۆججەت قىسقۇچ نامى ھازىرقى ئىشلەتكۈچى ئىسمى بىلەن ئوخشاش بولسا بولمايدۇ + + + + Do you want to run %1? + “%1”نى ئىجرا قىلامسىز؟ + + + + Burn image + button + تەسۋىرنى ئويۇش + + + + Burn files + button + ھۆججەت ساقلايمەن + + + + Are you sure you want to empty %1 item? + ئەخلەت ساندۇقىدىكى %1 مەزمۇننى راستلا قۇرۇقدامسىز؟ + + + + Are you sure you want to empty %1 items? + ئەخلەت ساندۇقىدىكى %1 مەزمۇننى راستلا قۇرۇقدامسىز؟ + + + + + This action cannot be undone + بۇ مەشغۇلاتنى ئەسلىگە قايتۇرغىلى بولمايدۇ + + + + + + + + + + + + + + OK + button + ماقۇل + + + + + + + + + + + + + + + Cancel + button + بىكار قىلىش + + + + + + Run + button + يۈرگۈزۈش + + + + + Run in terminal + button + تېرمىنالدا يۈرگۈزۈش + + + + Display + button + كۆرسىتىش + + + + + + + + + + + Confirm + button + جەزملەشتۈرۈش + + + + Erase + button + ئۆچۈرۈش + + + + Data verification failed + سانلىق مەلۇماتنى تەكشۈرۈش مەغلۇب بولدى + + + + Show details + button + تەپسىلاتىنى كۆرۈش + + + + + Delete + button + ئۆچۈرۈش + + + + Remove + button + چىقىرۋېتىش + + + + Disk is busy, cannot unmount now + دىسكا ھۆججىتى ئىگىلىۋېلىندى ، ئۆچۈرگىلى بولمايدۇ + + + + Force unmount + button + مەجبۇرىي چىقىرۋېتىش + + + + Unable to copy. Not enough free space on the target disk. + نىشان دىسكىنىڭ بوشلۇقى يېتىشمىگەچكە كۆچۈرۈش مەغلۇب بولدى. + + + + Failed to restore %1 file, the target folder is read-only + %1 ھۆججەتنى ئەسلىگە كەلتۈرگىلى بولمىدى، نىشان ھۆججەت قىسقۇچقا يېزىش ھوقۇقىڭىز يوق + + + + Failed to restore %1 files, the target folder is read-only + %1 ھۆججەتنى ئەسلىگە كەلتۈرگىلى بولمىدى، نىشان ھۆججەت قىسقۇچقا يېزىش ھوقۇقىڭىز يوق + + + + Failed to restore %1 files, the source files do not exist + ئەسلى ھۆججەت مەۋجۇت ئەمەس، %1 ھۆججەتنى ئەسلىگە قايتۇرۇش مەغلۇب بولدى + + + + Format + button + فورماتلاش + + + + Stop + button + توختىتىمەن + + + + FileController + + + + + + Unable to find the original file + ئۇلىنىش نىشان ھۆججىتىنى تاپالمىدى + + + + + + Kindly Reminder + سەمىمىي ئەسكەرتىش + + + + + + Please install File Roller first and then continue + داۋاملاشتۇرۇشتىن بۇرۇن ئارخىپ باشقۇرغۇچىنى قاچىلاڭ + + + + + Unable to create files here: %1 + بۇ يەردە ھۆججەت قۇرغىلى بولمايدۇ: %1 + + + + Confirm + button + جەزملەشتۈرۈش + + + + FileDialogStatusBar + + + File Name + ھۆججەت ئىسمى + + + + Format + فورماتلاش + + + + Save + button + ساقلاش + + + + Open + button + ئېچىش + + + + Save File + button + ھۆججەتنى ساقلاڭ + + + + Open File + button + ھۆججەت ئېچىش + + + + + + Cancel + button + بىكار قىلىش + + + + FileJob + + + copy + كۆچۈرۈش + + + + + + + Data verification successful. + سانلىق مەلۇمات تەكشۈرۈلدى + + + + + + Burn process completed + ئويۇش تاماملاندى + + + + %1 s + %1 سېكۇنت + + + + %1 m %2 s + %1 مىنۇت %2 سېكۇنت + + + + %1 h %2 m %3 s + %1 سائەت %2 مىنۇت %3 سېكۇنت + + + + %1 d %2 h %3 m %4 s + %1 كۈن %2 سائەت %3 مىنۇت %4 سېكۇنت + + + + %1 is a duplicate file. + %1 قايتىلانغان ھۆججەت + + + + Insufficient disc space. + دىسكىدىكى بوشلۇق يېتىشمىدى + + + + Lost connection to drive. + ئوپتىك قوزغاتقۇچ بىلەن بولغان ئۇلىنىش ئۈزۈلۈپ قالدى + + + + The CD/DVD drive is not ready. Try another disc. + ئوپتىك قوزغاتقۇچ تەييارلىنىپ بولالمىدى، باشقا دىسكا ئالماشتۇرۇپ سىناپ باقسىڭىز بولىدۇ. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + ئوپتىك قوزغاتقۇچ ئىشلىتىلىۋاتىدۇ، ئوپتىك قوزغاتقۇچتىكى ئىشلىتىۋاتقان پىروگراممىنى تاقىۋەتكەندىن كېيىن قايتا كىرگۈزۈپ سىناپ باقسىڭىز بولىدۇ. + + + + Unknown error + نامەلۇم خاتالىق + + + + Device disconnected + ئوپتىك قوزغاتقۇچ ئۈسكۈنىسى ئۇلانمىغان + + + + GenerateSettingTranslate + + + + + Basic + ئاساسىي تەڭشەك + + + + + + Open behavior + ئېچىش مەشغۇلاتى + + + + + + Always open folder in new window + دائىملا يىڭى كۆزنەكتە ئېچىش + + + + + + Open file: + ھۆججەت ئېچىش: + + + + + + Click + تاق چېكىڭ + + + + + + Double click + قوش چېكىش + + + + + + New window and tab + يېڭى كۆزنەك ۋە يېڭى بەتكۈچ + + + + + + Open from default window: + سۈكۈتتىكى كۆزنەكتە ئېچىش: + + + + + + + + + Computer + كومپيوتېر + + + + + + + + + Home + باش مۇندەرىجە + + + + + + + + + Desktop + ئېكران + + + + + + + + + Videos + سىنلار + + + + + + + + + Music + مۇزىكا + + + + + + + + + Pictures + رەسىملەر + + + + + + + + + Documents + ھۆججەتلەر + + + + + + + + + Downloads + چۈشۈرۈلمىلەر + + + + + + Open in new tab: + يىڭى بەتكۈچتە ئېچىش + + + + + + Current Directory + نۆۋەتتىكى مۇندەرىجە + + + + + + View + كۆرۈنۈش + + + + + + Default size: + سۈكۈتتىكى چوڭلۇقى: + + + + + + Extra small + بەك كىچىك + + + + + + Small + كىچىك + + + + + + Medium + ئوتتۇرا + + + + + + Large + چوڭ + + + + + + Extra large + بەك چوڭ + + + + + + Default view: + سۈكۈتتىكى كۆرۈنۈش: + + + + + + Icon + سىن بەلگە كۆرۈنۈشى + + + + + + List + تىزىملىك + + + + + + Hidden files + ھۆججەت يوشۇرۇش + + + + + + Show hidden files + ھۆججەت كۆرسىتىش، يوشۇرۇش + + + + + + Hide file extension when rename + ئىسىم ئۆزگەرتكەندە كېڭەيتمە نامى كۆرۈنمىسۇن + + + + + + Advanced + تىخىمۇ كۆپ + + + + + + Index + ئىندېكس + + + + + + Auto index internal disk + ئىچكى دىسكىغا ئاپتوماتىك ئىندېكسلاش + + + + + + Index external storage device after connected to computer + كومپيۇتېرغا ئۇلىغاندىن كېيىن سىرتقى ساقلاش ئۈسكۈنىسىگە ئىندېكسلىنىدۇ + + + + + + Full-Text search + پۈتۈن تېكىستتىن ئىزدەش + + + + + + Show item counts and sizes in the path of mounted MTP devices + MTP يۈكلەش مۇندەرىجىسىدىكى ھۆججەت ئىستاتىستىكىسىنىڭ تەپسىلىي ئەھۋالىنى كۆرسىتىش + + + + + + Keep showing the mounted Samba shares + Samba ھەمبەھىرلەش ئېغىزى كىرىش ئېغىزىدا دائىم كۆرۈنسۇن + + + + + + Use the file chooser dialog of File Manager + ھۆججەت باشقۇرغۇچىنىڭ ھۆججەت تاللاش سۆزلىشىش رامكىسىنى ئىشلىتىڭ + + + + + + Ask for my confirmation when deleting files + ئادەتتىكى ئۆچۈرۈش ئەسكەرتمىسىنى ئېچىش + + + + + + Other + باشقا + + + + + + Hide system disk + سىستېما دىسكىسىنى يوشۇرۇش + + + + + + Show file system on disk icon + دىسكا سىنبەلگىسىدە ھۆججەت سىستېمىسى بەلگىسىنى كۆرسەتسۇن + + + + + + Show hidden files in search results + ئىزدەش نەتىجىسىدە يوشۇرۇنغان ھۆججەتلەر كۆرۈنسۇن + + + + + + Display recent file entry in left panel + يېقىندا ئىشلەتكەن ھۆججەت كۆرۈنسۇن + + + + + + Preview + كۆرۈش + + + + + Compress file preview + بولاقنى كۆرۈپ بېقىش + + + + + + Text preview + تېكىستنى كۆرۈپ بېقىش + + + + + + Document preview + ھۆججەتنى كۆرۈپ بېقىش + + + + + + Image preview + سۈرەتنى كۆرۈپ بېقىش + + + + + + Video preview + سىننى كۆرۈپ بېقىش + + + + + + Mount + ئاغدۇرۇلغان + + + + + + Auto mount + ئاپتوماتىك ئاغدۇرۇش + + + + + + Open after auto mount + ئاپتوماتىك ئاغدۇرغاندىن كېيىن ئېچىش + + + + + + Dialog + سۆزلىشىش رامكىسى + + + + Compressed file preview + بولاق ھۆججەتنى كۆرۈپ بېقىش + + + + GvfsMountManager + + + Can’t verify the identity of %1. + %1 نىڭ سالاھىيىتى نامەلۇم + + + + This happens when you log in to a computer the first time. + تۇنجى كىرگەندە بۇ ئەسكەرتىش چىقىدۇ + + + + The identity sent by the remote computer is + يىراق مۇساپىلىك كومپيۇتېر يوللىغان سالاھىيەت ئۇچۇرى + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + مەشغۇلاتنى داۋاملاشتۇرۇشنىڭ بىخەتەر ياكى ئەمەسلىكىنى جەزملەشتۈرمەكچى بولسىڭىز سىستېما باشقۇرغۇچىسى بىلەن ئالاقىلىشىڭ. + + + + + + + + Mounting device error + قاچىلاش ئۈسكۈنىسىدە خاتالىق كۆرۈلدى + + + + + Wrong username or password + ئىشلەتكۈچى نامى ياكى پارول خاتا + + + + + + + + Confirm + button + جەزملەشتۈرۈش + + + + + Cannot find the mounted device + ماس ئاغدۇرۇش ئۈسكۈنىسى تېپىلمىدى + + + + No key available to unlock device + ئۈسكۈنىنى ئاچىدىغان ئاچقۇچ يوق + + + + The disk is mounted by user "%1", you cannot unmount it. + دىسكىغا “%1” ئىشلەتكۈچى ئاغدۇرۇلغان، ئۆچۈرۈش ھوقۇقىڭىز يوق. + + + + Cannot unmount the device + ئۈسكۈنىنى چىقىرالمىدى + + + + Cannot eject the device "%1" + ئۈسكۈنە  "%1" نى چىقارغىلى بولمىدى + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + نىشان دىسكىنىڭ قالدۇق بوشلۇقى يېتىشمىدى، كۆچۈرگىلى بولمايدۇ! + + + + MergedDesktopController + + + + Pictures + رەسىملەر + + + + + Music + مۇزىكا + + + + + Applications + ئەپ + + + + + Videos + سىنلار + + + + + Documents + ھۆججەتلەر + + + + + Others + باشقىلىرى + + + + MimeTypeDisplayManager + + + + Directory + مۇندەرىجە + + + + + + Application + ئەپ + + + + + + Video + سىن + + + + + + Audio + ئۈن + + + + + + Image + رەسىم + + + + + Archive + بولاق + + + + + + Text + ھۆججەت + + + + + Executable + ئىجرا بولىدىغان پىروگرامما + + + + + Backup file + زاپاس ھۆججەت + + + + + Unknown + نامەلۇم + + + + MountAskPasswordDialog + + + Cancel + button + بىكار قىلىش + + + + Connect + button + ئۇلاش + + + + Log in as + ئۇلاش سالاھىيىتى + + + + Anonymous + نامسىز + + + + Registered user + تىزىملاتقان ئىشلەتكۈچى + + + + Username + ئىشلەتكۈچى نامى + + + + Domain + دائىرە + + + + Password + پارول + + + + Remember password + پارول ئەستە ساقلانسۇن + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + بىكار قىلىش + + + + Unlock + button + قۇلۇپ ئېچىش + + + + Input password to decrypt the disk + بۇ دىسكىنى پارول كىرگۈزۈپ ئېچىڭ + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + %1 نى راستلا تەلتۆكۈس ئۆچۈرەمسىز؟ + + + + This file is too big for the trash + بۇ ھۆججەت بەك چوڭ، ئەخلەت ساندۇقىغا قويغىلى بولمايدۇ + + + + The files are too big for the trash + ھۆججەت بەك چوڭ، ئەخلەت ساندۇقىغا قويغىلى بولمايدۇ + + + + Are you sure you want to permanently delete %1 files? + بۇ %1 ھۆججەتنى راستلا تەلتۆكۈس ئۆچۈرەمسىز؟ + + + + Cancel + button + بىكار قىلىش + + + + Delete + button + ئۆچۈرۈش + + + + OpenWithDialog + + + Open with + باشقا پروگراممىلاردا ئېچىش + + + + Add other programs + باشقا پىروگرامما قوشۇش + + + + Set as default + سۈكۈتتىكى قىلىپ بەلگىلەش + + + + Cancel + button + بىكار قىلىش + + + + Confirm + button + جەزملەشتۈرۈش + + + + Recommended Applications + تەۋسىيە ئەپلەر + + + + Other Applications + باشقا پروگراممىلار + + + + PathManager + + + Home + ئاساسلىق مۇندەرىجە + + + + Desktop + ئېكران + + + + Videos + سىنلار + + + + Music + مۇزىكا + + + + Pictures + رەسىملەر + + + + Documents + ھۆججەتلەر + + + + Downloads + چۈشۈرۈلمىلەر + + + + + Trash + ئەخلەت + + + + + + System Disk + سىستېما دىسكىسى + + + + Computers in LAN + توردىكى قوشنىلار + + + + My Shares + ھەمبەھىرلەنمىلىرىم + + + + Computer + كومپيوتېر + + + + Recent + يېقىندا ئىشلەتكەنلىرىم + + + + File Vault + بىخەتەرلىك ساندۇقى + + + + PropertyDialog + + + Basic info + ئاساسى ئۇچۇرى + + + + Open with + باشقا پروگراممىلاردا ئېچىش + + + + Sharing + ھەمبەھىرلىنىشنى باشقۇرۇش + + + + Permissions + ھوقۇق باشقۇرۇش + + + + %1 (%2) + %1 (%2) +  + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + بۇ ھۆججەت قىسقۇچنى يوشۇرۇش + + + + Hide this file + بۇ ھۆججەتنى يوشۇرۇش + + + + Allow to execute as program + پىروگرامما ئارقىلىق ئىجرا قىلىشقا رۇخسەت قىلىش + + + + QObject + + + + + + Size + چوڭلۇقى + + + + + + Contains + ھۆججەت سانى + + + + + + Type + تىپى + + + + + + + + Time modified + ئۆزگەرتىلگەن ۋاقىت + + + + Free space + بىكار بوشلۇق + + + + Total space + ئومومى بوشلۇقى + + + + + Time locked + قۇلۇپلانغان ۋاقىت + + + + Access denied + ئوقۇغىلى، يازغىلى بولمايدۇ + + + + + Executable + ئىجرا بولىدىغان پىروگرامما + + + + + Write only + يازغىلى بولىدۇ، ئوقۇغىلى بولمايدۇ + + + + + Read only + ئوقۇشقىلا بولىدۇ + + + + + Read-write + يېزىش، ئوقۇش + + + + Others + باشقىلىرى + + + + Owner + ئىگىدار + + + + Unconnected network shared directory + ئۇلانمىغان تور ھەمبەھىر مۇندەرىجىسى + + + + Device type + ئۈسكۈنە تىپى + + + + File system + سىستېما ھۆججىتى + + + + Group + توپ + + + + + Open + ئېچىش + + + + Lock + قۇلۇپلاش + + + + Auto lock + ئاپتوماتىك قۇلۇپلاش + + + + Never + ھەرگىز + + + + 5 minutes + 5 مىنۇت + + + + 10 minutes + 10 مىنۇت + + + + 20 minutes + 20 مىنۇت + + + + Delete File Vault + بىخەتەرلىك ساندۇقىنى ئۆچۈرۈش + + + + Unlock + قۇلۇپ ئېچىش + + + + Unlock by key + شىفىرلىق ئاچقۇچتا ئېچىش + + + + Open + button + ئېچىش + + + + + Size: %1 + چوڭلۇقى: %1 + + + + Type: %1 + تىپى: %1 + + + + Size: 0 + سىغىمى: 0 + + + + Items: %1 + ھۆججەت سانى: %1 + + + + + + + + + + Open in new window + يىڭى كۆزنەكتە ئېچىش + + + + + + + + + + Open in new tab + يىڭى بەتتە ئېچىش + + + + Open with + باشقا پروگراممىلاردا ئېچىش + + + + + Compress + پىرىسلاش + + + + Extract + پىرىشتىن يېيىش + + + + Extract here + بۇ يەرگە پىرىستىن يىشىش + + + + Cut + كىسىش + + + + Copy + كۆچۈرۈش + + + + Paste + چاپلاش + + + + + + + + Rename + ئىسم ئۆزگەرتىش + + + + + + + Remove + چىقىرۋېتىش + + + + Create link + ئۇلىنىش قۇرۇش + + + + Send to desktop + ئۈستەليۈزىگە ئەۋەتىش + + + + Send to + ئەۋەتىش + + + + Bluetooth + كۆكچىش + + + + Add to bookmark + خەتكۈچ قوشۇش + + + + + + + Properties + ئىقتىدار + + + + New folder + مۇندەرىجە قۇرۇش + + + + New window + يېڭى كۆزنەك + + + + Select all + ھەممىسىنى تاللاش + + + + + Clear recent history + يېقىنقى زىيارەت خاتىرىسىنى ئۆچۈرۈش + + + + + + Empty Trash + سىۋەتنى قۇرۇقداش + + + + Display as + كۆرۈنمە شەكلى + + + + Sort by + تەرتىپلەش + + + + New document + يېڭى ھۆججەت + + + + + Time created + قۇرۇلغان ۋاقتى + + + + + + Source path + ئەسلى ئورنى + + + + Share folder + مۇندەرىجە ھەمبەھىرلەش + + + + Cancel sharing + ھەمبەھىرلەشنى بىكار قىلىش + + + + Connect to Server + مۇلازىمېتىرغا ئۇلاش + + + + Set share password + ھەمبەھرىلىنىش پارولى تەڭشەش + + + + Format + فورماتلاش + + + + Tag information + ئۇچۇرغا بەلگە قويۇش + + + + Open as administrator + باشقۇرغۇچى سالاھىيىتىدە ئېچىش + + + + Select default program + سۈكۈتتىكى پروگراممىنى تاللاش + + + + Open file location + ھۆججەت ئورنىنى ئېچىش + + + + Remove bookmark + خەتكۈچنى يۆتكەش + + + + + + Delete + ئۆچۈرۈش + + + + Office Text + مەزمۇن ھۆججىتى + + + + Spreadsheets + جەدۋەل + + + + Plain Text + تىكىست ھۆججىتى + + + + Open in terminal + تېرمىنالدا ئېچىش + + + + Restore + ئەسلىگە قايتۇرۇش + + + + Restore all + ھەممىنى ئەسلىگە قايتۇرۇش + + + + Clear saved password and unmount + پارولنى ئەستە ساقلاشنى بىكار قىلىش ھەمدە ئۆچۈرۈش + + + + File Vault + بىخەتەرلىك ساندۇقى + + + + Add to disc + دىسكىغا ئويۇشقا قوشۇش + + + + Refresh + يېڭىلاش + + + + Auto mount + ئاپتوماتىك ئاغدۇرۇش + + + + Open after auto mount + ئاپتوماتىك ئاغدۇرغاندىن كېيىن ئېچىش + + + + + Mount + ئاغدۇرۇلغان + + + + + Unmount + چىقىرۋېتىش + + + + It does not support burning %1 discs + %1 فورماتىنى ئويغىلى بولمايدۇ + + + + Burn + ئويۇش + + + + Disc name: + دىسكا نامى + + + + + Maximum + ئەڭ چوڭ تېزلىك + + + + Allow files to be added later + سانلىق مەلۇمات قوشۇشقا يول قويۇش + + + + Verify data + سانلىق مەلۇماتنى تەكشۈرۈش + + + + Write speed: + يېزىش سۈرئىتى: + + + + + + + Cancel + button + بىكار قىلىش + + + + Burn + button + ئويۇش + + + + + Eject + چىقىرۋېتىش + + + + Safely Remove + بىخەتەر چىقىرىش + + + + + Name + نامى + + + + Settings + تەڭشەكلەر + + + + Exit + چېكىنىش + + + + Icon + سىن بەلگە كۆرۈنۈشى + + + + List + تىزىملىك + + + + Extend + كېڭەيتمە كۆرۈنۈش + + + + Set as wallpaper + تەگلىك تەڭشەش + + + + + + + Local disk + يەرلىك دىسكا + + + + + Removable disk + يۆتكىلىشچان دىسكا + + + + + + Network shared directory + توردىكى ھەمبەھرىلىنىش مۇندەرىجىسى + + + + + Android mobile device + Android كۆچمە ئۈسكۈنە + + + + + Apple mobile device + ئالما كۆچمە ئۈسكۈنە + + + + + Camera + كامېرا + + + + + DVD + DVD + + + + + Unknown device + نامەلۇم ئۈسكۈنە + + + + + + %1 item + %1تۈر + + + + + + %1 items + %1تۈر + + + + Shortcut + تىز كونۇپكا + + + + Create symlink + ئۇلانما قۇرۇش + + + + Path + يول + + + + + + Time deleted + ئۆچۈرۈلگەن ۋاقتى + + + + Loading... + يۈكلەۋاتىدۇ... + + + + File has been moved or deleted + ھۆججەت يۆتكىۋېتىلگەن ياكى ئۆچۈرۈلگەن + + + + You do not have permission to traverse files in it + تارماق ھۆججەتلەرنى كۆرۈش ھوقۇقىڭىز يوق + + + + + + You do not have permission to access this folder + بۇ ھۆججەتنى ئوقۇش ھوقۇقىڭىز يوق + + + + + + + + Folder is empty + ھۆججەت قىسقۇچ قۇرۇق + + + + Searching... + ئىزدەۋاتىدۇ... + + + + No results + نەتىجە تېپىلمىدى + + + + Source Path + TrashFileInfo + ئەسلى ئادېرسى + + + + Document + Word ھۆججەت قۇرۇش + + + + Spreadsheet + جەدۋەل + + + + + Presentation + تامتەسۋىر + + + + Text + ھۆججەت + + + + 1 task in progress + 1 ۋەزىپە ئىجرا بولۇۋاتىدۇ + + + + %1 tasks in progress + %1 ۋەزىپە ئىجرا بولۇۋاتىدۇ + + + + Mode: + ئۇسۇلى: + + + + + Replace Text + تېكىست ئالماشتۇرۇش + + + + + Add Text + تېكىست قوشۇش + + + + + Custom Text + تېكىست بەلگىلەش + + + + Find: + ئىزدەش: + + + + Replace: + ئالماشتۇرۇش: + + + + + Optional + ئىختىيارى + + + + Add: + قوشۇش: + + + + Location: + ئورۇن: + + + + File name: + ھۆججەت نامى: + + + + Start at: + + تەرتىپ نومۇر: + + + + + Rename + button + ئىسم ئۆزگەرتىش + + + + + + + + + + + Required + زۆرۈر تۈر: + + + + + Before file name + نامى ئالدىدا + + + + + After file name + نامى كەينىدە + + + + Find + ئىزدەش + + + + Replace + ئالماشتۇرۇش + + + + Add + قوشۇش + + + + Start at + + تەرتىپ نومۇر + + + + + + Location + ئورۇن + + + + File name + ھۆججەت نامى + + + + Dimension + رازمېرى + + + + Duration + ۋاقتى + + + + Tips: Sort by selected file order + ئەسكەرتىش: تاللانغان ھۆججەتلەرنىڭ تەرتىپى بويىچە تەرتىپلەش + + + + Rename %1 Files + %1 ھۆججەتنىڭ نامىنى ئۆزگەرتىش + + + + Multiple Files + كۆپ ھۆججەت + + + + Basic info + ئاساسى ئۇچۇرى + + + + Total size + ئومومى چوڭلۇقى + + + + Number of files + ھۆججەت سانى + + + + %1 file(s), %2 folder(s) + %1 ھۆججەت، %2 ھۆججەت قىسقۇچ + + + + + + Time accessed + زىيارەت ۋاقتى + + + + Orange + ئاپېلسىن رەڭ + + + + Red + قىزىل + + + + Purple + بىنەپشە رەڭ + + + + Navy-blue + دېڭىز كۆكى + + + + Azure + ئاسمان كۆكى + + + + Green + يېشىل + + + + Yellow + سېرىق + + + + Gray + كۈلرەڭ + + + + Input tag info, such as work, family. A comma is used between two tags. + بەلگە ئۇچۇرىنى كىرگۈزۈڭ، مەسىلەن “خىزمەت”、“ئائىلەم” قاتارلىق. كۆپ بەلگە ئۇچۇرىنى پەش بەلگىسى ئارقىلىق ئايرىيسىز. + + + + Bookmarks + بەتكۈچ + + + + Erase + ئۆچۈرۈش + + + + Copy path + ئادېرىس كۆچۈرۈش + + + + Edit address + ئادرېسنى تەھرىرلەش + + + + Free Space %1 + بىكار بوشلۇق %1 + + + + Files are being processed + ھۆججەتنى بىر تەرەپ قىلىۋاتىدۇ + + + + + Unknown + نامەلۇم + + + + My Vault + بىخەتەرلىك ساندۇقۇم + + + + + Failed to create file info + ھۆججەت ئۇچۇرلىرىنى قۇرالمىدى + + + + Failed to create file handler + ھۆججەت بىر تەرەپ قىلىش پىروگراممىسىنى قۇرالمىدى + + + + Failed to open the file, cause: %1 + ھۆججەت ئېچىش مەغلۇب بولدى ، سەۋەبى:% 1 + + + + Original file does not exist + مەنبە ھۆججىتى مەۋجۇت ئەمەس + + + + Do you want to delete %1? + %1نى ئۆچۈرەمسىز؟ + + + + Confirm + button + جەزملەشتۈرۈش + + + + + + + + %1 are not allowed + %1 لار بولسا بولمايدۇ + + + + + Failed to start Samba services + Sambaمۇلازىمىتىنى قوزغىتالمىدى + + + + RecentController + + + Cancel + button + بىكار قىلىش + + + + Remove + button + چىقىرۋېتىش + + + + Do you want to remove this item? + سىز تاللىغان تۈرلەرنى چىقىرۋىتىشنى جەزىملەشتۈرەمسىز؟ + + + + Do yout want to remove %1 items? + سىز تاللىغان %1 دانە تۈرنى چىقىرۋىتىشنى جەزىملەشتۈرەمسىز؟ + + + + It does not delete the original files + بۇ مەشخۇلات ئەسلى ھۆججەتنى ئۆچۈرمەيدۇ + + + + ShareInfoFrame + + + Share this folder + مۇشۇ مۇندەرىجىنى ھەمبەھىرلەش + + + + Share name: + ھەمبەھىر ئىسمى: + + + + Permission: + ھوقوقى: + + + + Read and write + ئوقۇغىلى، يازغىلى بولىدۇ + + + + Read only + ئوقۇشقىلا بولىدۇ + + + + Anonymous: + نامسىز زىيارەت قىلىش: + + + + Not allow + رەت قىلىش + + + + Allow + روخسەت قىلىش + + + + The share name must not be two dots (..) or one dot (.) + ..ۋە. لارنى ھەمبەھىر نامى قىلىشقا بولمايدۇ + + + + The share name is used by another user. + بۇ ھەمبەھىر نامنى باشقىلار ئىشلىتىپ بولغان + + + + OK + button + ماقۇل + + + + Cancel + button + بىكار قىلىش + + + + Replace + button + ئالماشتۇرۇش + + + + The share name already exists. Do you want to replace the shared folder? + بۇ ھەمبەھىر نام مەۋجۇت، ئەسلىدىكى ھۆججەت قىسقۇچقا ئالماشتۇرامسىز؟ + + + + Shortcut + + + Item + ھۆججەت + + + + Select to the first item + بىرىنچى ھۆججەتكىچە تاللاش + + + + Shift + Home + Shift + Home + + + + Select to the last item + ئاخىرقى ھۆججەتكىچە تاللاش + + + + Shift + End + Shift + End + + + + Select leftwards + ئالدىغا تاللاش + + + + Shift + Left + Shift + Left + + + + Select rightwards + كەينىگە تاللاش + + + + Shift + Right + Shift + Right + + + + Select to upper row + ئالدىنقى قۇرنى تاللاش + + + + Shift + Up + Shift + Up + + + + Select to lower row + كېيىنكى قۇرنى تاللاش + + + + Shift + Down + Shift + Down + + + + Open + ئېچىش + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + ئالدىنقىغا قايتىش + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + تەلتۆكۈس ئۆچۈرۈش + + + + Shift + Delete + Shift + Delete + + + + Delete file + ھۆججەتنى ئۆچۈرۈش + + + + Delete + ئۆچۈرۈش + + + + Select all + ھەممىسىنى تاللاش + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + كۆچۈرۈش + + + + Cut + كىسىش + + + + Paste + چاپلاش + + + + Rename + ئىسم ئۆزگەرتىش + + + + F2 + F2 + + + + New/Search + قۇرۇش/ئىزدەش + + + + New window + يېڭى كۆزنەك + + + + New folder + مۇندەرىجە قۇرۇش + + + + + Search + ئىزدەش + + + + New tab + يىڭى بەت + + + + View + كۆرۈش + + + + Item information + تەپسىلاتى + + + + Help + ياردەم قوللانمىسى + + + + F1 + F1 + + + + Keyboard shortcuts + تىز كونۇپكا + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + كۆرسىتىش ھالىتىنى ئالماشتۇرۇش + + + + Hide item + يوشۇرۇش + + + + Input in address bar + ئادرېس ئىستونىغا كىرگۈزۈش + + + + Switch to icon view + سىنبەلگە كۆرۈنۈشىگە ئالماشتۇرۇش + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + تىزىملىك كۆرۈنۈشىگە ئالماشتۇرۇش + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + باشقىلىرى + + + + Close + تاقاش + + + + Alt + F4 + Alt + F4 + + + + Close current tab + نۆۋەتتىكى بەتكۈچى تاقاش + + + + Back + قايتىش + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + كېيىنكى بەتكۈچكە ئالماشتۇرۇش + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + ئالدىنقى بەتكە ئالمىشىش + + + + Next file + كىيىنكى ھۆججەت + + + + Tab + بەت + + + + Previous file + ئالدىنقى ھۆججەت + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + 1-8 ئارىلىقىدا بەلگىلەنگەن تەرتىپنى تاللاپ بەتكۈچ ئالماشتۇرۇڭ + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + ئالدىغا + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + ئەخلەت ساندۇقىڭىز تۈرنى ئېچىش ئۈچۈن ئاۋۋال ئەسلىگە قايتۇرۇڭ + + + + TrashPropertyDialog + + + Trash + ئەخلەت + + + + item + تۈر + + + + items + تۈر + + + + Contains %1 %2 + %1 دانە %2 نى ئۆز ئىچىگە ئالىدۇ + + + + UDiskListener + + + Failed to rename the label + دىسكا نامىنى ئۆزگەرتىش مەغلۇب بولدى + + + + UnmountWorker + + + + + The device was not safely unmounted + ئۈسكۈنە نورمال چىقىرىلمىدى + + + + The device was not safely removed + ئۈسكۈنە نورمال ئۆچۈرۈلمىدى + + + + UserShareManager + + + Kindly Reminder + سەمىمىي ئەسكەرتىش + + + + Please firstly install samba to continue + sambaنى قاچىلىغاندىن كېيىن ھەمبەھرىلەشكە ئالاقىدار مەشغۇلات قىلىڭ + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + ھەمبەھىرلەش نامىدا بۇلار بولسا بولمايدۇ %<>*?|/\+=;:,", +دىن باشلانسا بولمايدۇ ھەمدە %1 + + + + To protect the files, you cannot share this folder. + ھۆججەت بىخەتەرلىكى ئۈچۈن، بۇ ھۆججەت قىسقۇچنى ھەمبەھرىلەشكە بولمايدۇ. + + + + Sharing failed + ھەمبەھرىلىنەلمىدى + + + + The computer name is too long + كومپيۇتېر نامى بەك ئۇزۇن بولۇپ قالدى + + + + You do not have permission to operate file/folder! + سىزنىڭ بۇ ھۆججەت/ ھۆججەت قىسقۇچقا مەشغۇلات قىلىدىغان ھوقۇقىڭىز يوق! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + بەھرىلەش پارولىنى كىرگۈزۈڭ + + + + Cancel + button + بىكار قىلىش + + + + Confirm + button + جەزملەشتۈرۈش + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_uk.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_uk.ts new file mode 100644 index 0000000..6354907 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_uk.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + Нова тека + + + + Mounting device error + Помилка під час монтування пристрою + + + + The disc image was corrupted, cannot mount now, please erase the disc first + Образ диска був пошкоджений, не може бути змонтований, будь ласка, спочатку зітріть диск + + + + Mount error: unsupported image format + Помилка монтування: непідтримуваний формат образу + + + + + The device was not safely removed + Пристрій не було безпечно вилучено + + + + + Click "Safely Remove" and then disconnect it next time + Наступного разу натисніть кнопку «Вилучити безпечно», а вже потім від'єднуйте пристрій + + + + The device was not ejected + Пристрій не було виштовхнуто + + + + Disk is busy, cannot eject now + Диск зайнятий, зараз його неможливо вийняти + + + + Authentication timed out + Перевищено час очікування на розпізнавання + + + + BluetoothTransDialog + + + Bluetooth File Transfer + Передавання файлів через Bluetooth + + + + File Transfer Successful + Успішне перенесення файлів + + + + File Transfer Failed + Перенесення файлів зазнало невдачі + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + Надсилаємо файли до «<b style="font-weight: 550;">%1</b>» + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + Не вдалося надіслати файли до «<b style="font-weight: 550;">%1</b>» + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + Успішно надіслано до «<b style="font-weight: 550;">%1</b>» + + + + Select a Bluetooth device to receive files + Виберіть пристрій Bluetooth для отримання файлів + + + + Cannot find the connected Bluetooth device + Не вдалося знайти з'єднаний пристрій Bluetooth + + + + Waiting to be received... + Очікуємо на отримання… + + + + Go to Bluetooth Settings + Перейти до параметрів Bluetooth + + + + %1/%2 Sent + Надіслано %1 з %2 + + + + Error: the Bluetooth device is disconnected + Помилка: пристрій Bluetooth від'єднано + + + + Unable to send the file more than 2 GB + Неможливо надсилати файли, розмір яких перевищує 2 ГБ + + + + Unable to send 0 KB files + Не можна надсилати файли, розмір яких дорівнює 0 кБ + + + + File doesn't exist + Файла не існує + + + + Next + button + Наступний + + + + Cancel + button + Скасувати + + + + Done + button + Готово + + + + Retry + button + Повторити + + + + OK + button + Гаразд + + + + File sending request timed out + Перевищено час очікування на завершення виконання запиту щодо надсилання + + + + The service is busy and unable to process the request + Службу зайнято виконанням завдання. Вона не може обробити запит + + + + BurnOptDialog + + + Device error + Помилка пристрою + + + + Optical device %1 doesn't exist + Оптичного пристрою %1 не існує + + + + Advanced settings + Додаткові параметри + + + + File system: + Файлова система: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (для Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (для Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1 (сумісний із режимом CD/DVD Windows) + + + + ISO9660 Only + Лише ISO9660 + + + + CloseAllDialogIndicator + + + Close all + Закрити все + + + + Total size: %1, %2 files + Загальний розмір %1, %2 файли + + + + ComputerModel + + + Double click to open it + Двічі клацніть, щоб відкрити його + + + + My Directories + Мої Директорії + + + + Disks + Диски + + + + File Vault + Файлове сховище + + + + Quick Access + Швидкий доступ + + + + ComputerPropertyDialog + + + Computer + Комп'ютер + + + + Basic Info + Базова інформація + + + + + Computer Name + Назва комп’ютера + + + + + Edition + Редагування + + + + + + Version + Версія + + + + + Type + Тип + + + + + + Processor + Процесор + + + + + + Memory + Памʼять + + + + + + + Bit + Біт + + + + + Available + Доступна + + + + Obtaining... + Отримуємо… + + + + ConnectToServerDialog + + + Connect to Server + Підключення до сервера + + + + Cancel + button + Скасувати + + + + Connect + button + Під'єднатися + + + + My Favorites: + Мої улюблені: + + + + + Clear History + Очистити історію + + + + DFMAddressBar + + + Search or enter address + Знайдіть або введіть адресу + + + + DFMAdvanceSearchBar + + + Search: + Шукати: + + + + File Type: + Тип файла: + + + + File Size: + Розмір файла: + + + + Time Modified: + Внесення змін: + + + + Time Accessed: + Час доступу: + + + + Time Created: + Час створення: + + + + Reset + Скинути + + + + All subdirectories + Усі підкаталоги + + + + Current directory + Поточний каталог + + + + 0 ~ 100 KB + 0 ~ 100 кБ + + + + 100 KB ~ 1 MB + 100 кБ ~ 1 МБ + + + + 1 MB ~ 10 MB + 1 МБ ~ 10 МБ + + + + 10 MB ~ 100 MB + 10 МБ ~ 100 МБ + + + + 100 MB ~ 1 GB + 100 МБ ~ 1 ГБ + + + + > 1 GB + > 1 ГБ + + + + Today + Сьогодні + + + + Yesterday + Вчора + + + + This week + Цього тижня + + + + Last week + Минулого тижня + + + + This month + Цього місяця + + + + Last month + Минулого місяця + + + + This year + Цього року + + + + Last year + Минулого року + + + + DFMOpticalMediaWidget + + + + No files to burn + Немає файлів для записування + + + + Unable to burn. Not enough free space on the target disk. + Не вдалося записати. Недостатньо вільного місця на диску призначення. + + + + %1 burning is not supported + Підтримки запису %1 не передбачено + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. Цей диск не є диском %1. +2. У версії цієї файлової системи поки не передбачено підтримки додавання файлів. + + + + DFMTagCrumbController + + + Tag information + Дані щодо мітки + + + + DFMTagWidget + + + Tag + Тег + + + + DFMTaskWidget + + + Do not ask again + Не запитувати знову + + + + Syncing data + Синхронізація даних + + + + Please wait + Будь ласка, зачекайте + + + + + Time modified: %1 + Час зміни: %1 + + + + + Contains: %1 + Вміщує: %1 + + + + + Size: %1 + Розмір: %1 + + + + Original folder + Початкова тека + + + + Keep both + button + Залишити два + + + + Skip + button + Пропустити + + + + Replace + button + Замінити + + + + Retry + button + Повторити + + + + Original file + Початковий файл + + + + Target folder + Тека призначення + + + + Target file + Файл призначення + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + Зашифрувати сховище файлів + + + + Click 'Encrypt' and input the user password. + Натисніть «Зашифрувати» і введіть пароль користувача. + + + + Encrypting... + Шифрування… + + + + + + + Encrypt + Зашифрувати + + + + Failed to create file vault: %1 + Не вдалося створити сховище файлів: %1 + + + + OK + Гаразд + + + + The setup is complete + Налаштовування завершено + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + Зберегти ключ відновлення + + + + Keep the key safe to retrieve the vault password later + Зберегти ключ у безпеці для отримання пароля до сховища згодом + + + + Save to default path + Зберегти за типовим шляхом + + + + Save to other locations + Зберегти до інших місць + + + + No permission, please reselect + Немає доступу. Будь ласка, змініть вибір + + + + Select a path + Виберіть шлях + + + + Next + Наступний + + + + The default path is invisible to other users, and the path information will not be shown. + Типовий шлях є невидимим для інших користувачів, а дані щодо шляху не буде показано. + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + Ключ відновлення + + + + Generate a recovery key in case that you forgot the password + Створіть ключ відновлення на випадок, якщо ви забудете пароль + + + + Key + Ключ + + + + QR code + QR-код + + + + Scan QR code and save the key to another device + Заскануйте QR-код і збережіть ключ на іншому пристрої + + + + Next + Наступний + + + + Recovery Key: + Ключ відновлення: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + Встановлення пароля сховища + + + + Method + Метод + + + + Manual + Вручну + + + + Password + Пароль + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + ≥ 8 символів, може містити A-Z, a-z, 0-9 та символи пунктуації + + + + Repeat password + Повторити пароль + + + + Input the password again + Введіть ваш пароль ще раз + + + + Password hint + Підказка пароля + + + + Optional + Необов'язково + + + + Next + Наступний + + + + + Passwords do not match + Паролі не збігаються + + + + DFMVaultActiveStartView + + + File Vault + Файлове сховище + + + + Create your secure private space + Створіть ваш безпечний приватний простір + + + + Advanced encryption technology + Додаткові технології шифрування + + + + Convenient and easy to use + Зручний і простий у використанні + + + + Create + Створити + + + + DFMVaultFileView + + + Cannot open this path + Не вдалося відкрити цей шлях + + + + Hint + Підказка + + + + OK + Гаразд + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + Розблокувати ключем + + + + Failed to unlock file vault + Не вдалося розблокувати сховище файлів + + + + OK + Гаразд + + + + Input the 32-digit recovery key + Введіть 32-цифровий ключ відновлення + + + + Cancel + button + Скасувати + + + + Unlock + button + Розблокувати + + + + Wrong recovery key + Помилковий ключ відновлення + + + + DFMVaultRemoveByPasswordView + + + Password + Пароль + + + + Password hint: %1 + Підказка пароля: %1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + Введіть 32-цифровий ключ відновлення + + + + DFMVaultRemovePages + + + Delete File Vault + Вилучити сховище файлів + + + + Once deleted, the files in it will be permanently deleted + У результаті вилучення сховища файли буде остаточно вилучено + + + + Use Key + Використати ключ + + + + Cancel + button + Скасувати + + + + Use Key + button + Використати ключ + + + + Delete + button + Видалити + + + + + OK + button + Гаразд + + + + Use Password + Використовувати пароль + + + + Wrong password + Помилковий пароль + + + + Wrong recovery key + Помилковий ключ відновлення + + + + Failed to delete file vault + Не вдалося вилучити сховище файлів + + + + Deleted successfully + Успішно вилучено + + + + Failed to delete + Не вдалося вилучити + + + + Removing... + Вилучення… + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + Не вдалося отримати файл ключа + + + + Verification failed + Не вдалося пройти перевірку + + + + + Select a path + Виберіть шлях + + + + + Retrieve Password + Отримати пароль + + + + By key in the default path + За ключем за типовим шляхом + + + + By key in the specified path + За ключем за вказаним шляхом + + + + Verification Successful + Перевірку успішно пройдено + + + + Keep it safe + Зберегти у безпеці + + + + Back + button + Назад + + + + Verify Key + button + Перевірити ключ + + + + Go to Unlock + button + Перейти до розблокування + + + + Close + button + Закрити + + + + Vault password: %1 + Пароль до сховища: %1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + Не вдалося розблокувати файлове сховище + + + + Forgot password? + Забули пароль? + + + + Password hint: %1 + Підказка пароля: %1 + + + + Failed to unlock file vault + Не вдалося розблокувати сховище файлів + + + + Cancel + button + Скасувати + + + + Password + Пароль + + + + Unlock + button + Розблокувати + + + + Please try again %1 minutes later + Будь ласка, повторіть спробу за %1 хвилин + + + + Wrong password, please try again %1 minutes later + Помилковий пароль. Будь ласка, повторіть спробу за %1 хвилин + + + + Wrong password, one chance left + Помилковий пароль. Лишилася одна спроба. + + + + Wrong password, %1 chances left + Помилковий пароль. Лишилося %1 спроб. + + + + Wrong password + Помилковий пароль + + + + OK + button + Гаразд + + + + DFileCopyMoveJob + + + Permission error + Помилка прав доступу + + + + The action is denied + Виконання дії заборонено + + + + Failed to open the file + Не вдалося відкрити файл + + + + Failed to read the file + Не вдалося прочитати файл + + + + Failed to write the file + Не вдалося виконати запис до файла + + + + Failed to create the directory + Не вдалося створити каталог + + + + Failed to delete the file + Не вдалося вилучити файл + + + + Failed to move the file + Не вдалося пересунути файл + + + + Original file does not exist + Початкового файла не існує + + + + Failed, file size must be less than 4GB + Помилка, розмір файла не повинен перевищувати 4 ГБ + + + + Not enough free space on the target disk + Не вистачає вільного місця на диску призначення + + + + File integrity was damaged + Файл не є цілісним + + + + The target device is read only + Пристрій призначення використовується лише для читання + + + + Target folder is inside the source folder + Тека призначення перебуває всередині теки походження даних + + + + The action is not supported + Підтримки виконання дії не передбачено + + + + You do not have permission to traverse files in it + Ви не маєте права пересувати тут файли + + + + Failed to position the file pointer! + Не вдалося розташувати вказівник на файл! + + + + copy + Extra name added to new file name when used for file name. + копія + + + + Failed to open the directory, cause: file name too long + Не вдалося відкрити каталог. Причина: надто довга назва файла + + + + + Failed to open the file, cause: file name too long + Не вдалося відкрити файл. Причина: надто довга назва файла + + + + + Failed to write the file, cause: + Не вдалося записати файл. Причина: + + + + Failed to position the file pointer, cause: %1 + Не вдалося розташувати вказівник на файл, причина: %1 + + + + Syncing data + Синхронізація даних + + + + Please wait + Будь ласка, зачекайте + + + + Failed to create the directory, cause: %1 + Не вдалося створити каталог. Причина: %1 + + + + + + + + Failed to open the file, cause: %1 + Не вдалося відкрити файл. Причина: %1 + + + + + + + Failed to open the file, cause: Permission denied + Не вдалося відкрити файл. Причина: доступ заборонено + + + + + Failed to read the file, cause: %1 + Не вдалося прочитати файл. Причина: %1 + + + + + + + Failed to write the file, cause: %1 + Не вдалося виконати запис до файла. Причина: %1 + + + + + File integrity was damaged, cause: %1 + Файл не є цілісним. Причина: %1 + + + + Failed to open the file, cause: + Не вдалося відкрити файл. Причина: + + + + Failed to read the file, cause: + Не вдалося прочитати файл. Причина: + + + + Failed to delete the file, cause: %1 + Не вдалося вилучити файл. Причина: %1 + + + + Fail to create symlink, cause: %1 + Не вдалося створити символічне посилання. Причина: %1 + + + + DFileDialog + + + + Save + button + Зберегти + + + + + Cancel + button + Скасувати + + + + Confirm + button + Підтвердити + + + + %1 already exists, do you want to replace it? + 1% вже існує, ви хочете його перезаписати? + + + + Replace + button + Замінити + + + + Open + button + Відкрити + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + Цей файл буде приховано, якщо його назва починатиметься з крапки («.»). Хочете приховати файл? + + + + DFileManagerWindow + + + Trash + Смітник + + + + Empty + Порожньо + + + + DFileSystemModel + + + + Name + Назва + + + + + + Time modified + Час зміни + + + + Size + Розмір + + + + Type + Тип + + + + Time created + Час створення + + + + + Last access + Останній доступ + + + + + + + Path + Шлях + + + + DFileView + + + Disc mount error + Помилка під час монтування диска + + + + The disc is in use, please end the running process and remount the disc. + Диск використовують інші програми. Будь ласка, завершіть роботу відповідного процесу і повторно змонтуйте диск. + + + + Mounting failed + Не вдалося змонтувати + + + + (Reverse) + (Зворотний) + + + + DFileViewHelper + + + Add tag "%1" + Додати тег "1%" + + + + DStatusBar + + + %1 item + %1 об'єкт + + + + %1 items + %1 об'єктів + + + + %1 item selected + %1 об'єкт вибрано + + + + %1 items selected + %1 об'єктів вибрано + + + + %1 folder selected (contains %2) + %1 тека вибрана (вміщує %2) + + + + %1 folders selected (contains %2) + %1 тек вибрано (вміщує %2) + + + + %1 file selected (%2) + %1 файл вибрано (%2) + + + + %1 files selected (%2) + %1 файлів вибрано (%2) + + + + %1 folder selected + %1 теку вибрано + + + + Filter + Фільтр + + + + Save as: + Зберегти як: + + + + Loading... + Завантаження... + + + + DTaskDialog + + + Erasing disc %1, please wait... + Стирання диска %1, будь ласка, зачекайте... + + + + Burning disc %1, please wait... + Записуємо диск %1. Будь ласка, зачекайте… + + + + Writing data... + Запис даних... + + + + Verifying data... + Перевірка даних... + + + + Copying %1 + Копіювання %1 + + + + + + to %2 + до %2 + + + + %1 already exists in target folder + %1 вже існує в цільовій теці + + + + Original path %1 Target path %2 + Оригінальний шлях %1 цільовий шлях %2 + + + + Merge + button + Об'єднати + + + + Replace + button + Замінити + + + + Moving %1 + Переміщення %1 + + + + Removing file vault, please try later + Вилучаємо сховище файлів. Будь ласка, повторіть спробу пізніше + + + + Restoring %1 + Відновлення %1 + + + + Deleting %1 + Видалення %1 + + + + Trashing %1 + Переміщення до смітнику %1 + + + + Calculating space, please wait + Розрахунок простору, будь ласка, зачекайте + + + + DUMountManager + + + + Authentication timed out + Перевищено час очікування на розпізнавання + + + + + + Disk is busy, cannot unmount now + Диск зайнятий, його неможливо розмонтувати зараз + + + + Disk is busy, cannot eject now + Диск зайнятий, зараз його неможливо вийняти + + + + The device is busy, cannot eject now + Пристрій зайнято, його не можна виштовхнути зараз + + + + + + The device is busy, cannot remove now + Пристрій зайнято, зараз вилучення неможливе + + + + DeepinStorage + + + + + %1 Volume + Том %1 + + + + Data Disk + Data Partition + Диск із даними + + + + %1 Drive + Пристрій %1 + + + + Blank %1 Disc + Порожній диск %1 + + + + %1 Encrypted + %1 Зашифрований + + + + DialogManager + + + + + + Operation failed! + Помилка операції! + + + + Target folder is inside the source folder! + Цільова тека знаходиться всередині вихідної теки! + + + + Do you want to run %1 or display its content? + Чи бажаєте запустити %1 або відобразити цей вміст? + + + + It is an executable text file. + Це є виконуваний текстовий файл + + + + It is an executable file. + Це є виконуваний файл + + + + This file is not executable, do you want to add the execute permission and run? + Цей файл не є виконуваним. Хочете додати права на виконання і запустити його? + + + + "%1" already exists, please use another name. + "%1" вже використовується, будь ласка введіть інше ім'я + + + + The file name must not contain two dots (..) + У назві файла не повинно міститися двох крапок («..») + + + + Device or resource busy + Пристрій або ресурс зайнято + + + + Are you sure you want to erase all data on the disc? + Ви справді хочете витерти усі дані на диску? + + + + How do you want to use this disc? + Як ви хочете скористатися цим диском? + + + + Disc erase failed + Не вдалося витерти диск + + + + Burn process failed + Не вдалося записати диск + + + + %1: %2 + %1: %2 + + + + Show details + Показати подробиці + + + + Hide details + Приховати подробиці + + + + Error + Помилка + + + + Permanently delete %1? + Назавжди видалити %1? + + + + Permanently delete %1 items? + Видалити назавжди %1 об'єктів? + + + + Empty + Очистити + + + + Do you want to delete %1? + Хочете вилучити %1? + + + + Do you want to delete the selected %1 items? + Хочете вилучити позначені %1 записів? + + + + Sorry, unable to locate your bookmark directory, remove it? + Вибачте, неможливо знайти ваш каталог закладок, вилучити її? + + + + Name: + Ім'я: + + + + %1 that this shortcut refers to has been changed or moved + %1 на що цей ярлик посилається, було змінено або переміщено + + + + Do you want to delete this shortcut? + Ви хочете видалити це ярлик? + + + + Failed, file size must be less than 4GB. + Не вдалося, розмір файлу має становити менше 4 ГБ. + + + + Fail to create symlink, cause: + Не вдалося створити символічне посилання, тому що: + + + + The selected files contain system file/directory, and it cannot be deleted + Вибрані файли містять системний файл/директорію, і його не можливо видалити + + + + Unable to find the original file + Не вдалося знайти початковий файл + + + + + You do not have permission to operate file/folder! + Ви не маєте права керувати файлами/теками! + + + + Failed to restore %1 file, the source file does not exist + Не вдалося відновити файл %1 — не існує початкового файла + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + Вибачте, ви не маєте дозволу керувати наступним %1 файлом/текою(и)! + + + + Unable to access %1 + Не вдалося отримати доступ до %1 + + + + + Sending files now, please try later + Надсилаємо файли. Будь ласка, повторіть спробу пізніше + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + Щоб отримати доступ до пристрою, вам слід спочатку виконати форматування диска. Ви справді хочете форматувати диск зараз? + + + + Scanning the device, stop it? + Скануємо пристрій. Припинити? + + + + Share folder can't be named after the current username + Тека загального доступу не може бути названа після поточного імені користувача + + + + Do you want to run %1? + Ви дійсно хочете запустити %1? + + + + Burn image + button + Записати образ + + + + Burn files + button + Записати файли + + + + Are you sure you want to empty %1 item? + Ви впевнені, що бажаєте очистити %1 об'єкт? + + + + Are you sure you want to empty %1 items? + Ви впевнені, що бажаєте очистити %1 об'єкти? + + + + + This action cannot be undone + Цю дію не можна скасувати + + + + + + + + + + + + + + OK + button + Гаразд + + + + + + + + + + + + + + + Cancel + button + Скасувати + + + + + + Run + button + Запустити + + + + + Run in terminal + button + Запустити в терміналі + + + + Display + button + Відобразити + + + + + + + + + + + Confirm + button + Підтвердити + + + + Erase + button + Витерти + + + + Data verification failed + Не вдалося виконати процедуру перевірки + + + + Show details + button + Показати подробиці + + + + + Delete + button + Видалити + + + + Remove + button + Вилучити + + + + Disk is busy, cannot unmount now + Диск зайнятий, його неможливо розмонтувати зараз + + + + Force unmount + button + Примусово розмонтувати + + + + Unable to copy. Not enough free space on the target disk. + Неможливо скопіювати. Не вистачає вільного місця на диску призначення. + + + + Failed to restore %1 file, the target folder is read-only + Не вдалося відновити файл %1, цільова тека доступна лише для читання + + + + Failed to restore %1 files, the target folder is read-only + Не вдалося відновити файли %1, цільова тека доступна лише для читання + + + + Failed to restore %1 files, the source files do not exist + Не вдалося відновити %1 файлів — не існує початкових файлів + + + + Format + button + Форматувати + + + + Stop + button + Припинити + + + + FileController + + + + + + Unable to find the original file + Не вдалося знайти початковий файл + + + + + + Kindly Reminder + Увічливе нагадування + + + + + + Please install File Roller first and then continue + Будь ласка, спочатку встановіть File Roller, а потім продовжуйте + + + + + Unable to create files here: %1 + Не вдалося створити файли тут: %1 + + + + Confirm + button + Підтвердити + + + + FileDialogStatusBar + + + File Name + Ім'я файлу + + + + Format + Формат + + + + Save + button + Зберегти + + + + Open + button + Відкрити + + + + Save File + button + Зберегти файл + + + + Open File + button + Відкрити файл + + + + + + Cancel + button + Скасувати + + + + FileJob + + + copy + копіювати + + + + + + + Data verification successful. + Дані успішно перевірено. + + + + + + Burn process completed + Процедуру запису завершено + + + + %1 s + %1 с + + + + %1 m %2 s + %1 хв %2 с + + + + %1 h %2 m %3 s + %1 г %2 хв %3 с + + + + %1 d %2 h %3 m %4 s + %1 дн %2 г %3 хв %4 с + + + + %1 is a duplicate file. + %1 є файлом-дублікатом. + + + + Insufficient disc space. + Недостатньо місця на диску. + + + + Lost connection to drive. + Втрачено зв'язок із диском. + + + + The CD/DVD drive is not ready. Try another disc. + Пристрій для записування CD/DVD є неготовим. Спробуйте інший диск. + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + Пристрій для записування CD/DVD зайнято. Завершіть роботу програми, яка працює із пристроєм, і повторіть спробу. + + + + Unknown error + Невідома помилка + + + + Device disconnected + Пристрій від'єднано + + + + GenerateSettingTranslate + + + + + Basic + Основний + + + + + + Open behavior + Поведінка відкриття + + + + + + Always open folder in new window + Завжди відкривати теку у новому вікні + + + + + + Open file: + Відкриття файла: + + + + + + Click + Клацання + + + + + + Double click + Подвійне клацання + + + + + + New window and tab + Нове вікно і вкладка + + + + + + Open from default window: + Відкриття з типового вікна: + + + + + + + + + Computer + Комп'ютер + + + + + + + + + Home + Домівка + + + + + + + + + Desktop + Стільниця + + + + + + + + + Videos + Відео + + + + + + + + + Music + Музика + + + + + + + + + Pictures + Зображення + + + + + + + + + Documents + Документи + + + + + + + + + Downloads + Завантаження + + + + + + Open in new tab: + Відкриття у новій вкладці: + + + + + + Current Directory + Поточний каталог + + + + + + View + Перегляд + + + + + + Default size: + Типовий розмір: + + + + + + Extra small + Дуже малий + + + + + + Small + Малий + + + + + + Medium + Середній + + + + + + Large + Великий + + + + + + Extra large + Дуже великий + + + + + + Default view: + Типовий перегляд: + + + + + + Icon + Піктограма + + + + + + List + Список + + + + + + Hidden files + Приховані файли + + + + + + Show hidden files + Показувати приховані файли + + + + + + Hide file extension when rename + Приховувати суфікс назви під час перейменовування + + + + + + Advanced + Додатково + + + + + + Index + Покажчик + + + + + + Auto index internal disk + Автоматично створювати покажчик вбудованого диска + + + + + + Index external storage device after connected to computer + Створювати покажчики зовнішніх дисків після з'єднання із комп'ютером + + + + + + Full-Text search + Повнотекстовий пошук + + + + + + Show item counts and sizes in the path of mounted MTP devices + Показувати кількість записів та розміри у каталозі змонтованих пристроїв MTP + + + + + + Keep showing the mounted Samba shares + Продовжувати показ змонтованих спільних ресурсів Samba + + + + + + Use the file chooser dialog of File Manager + Використовувати вікно вибору файлів Менеджера файлів + + + + + + Ask for my confirmation when deleting files + Просити підтвердження вилучення файлів + + + + + + Other + Інше + + + + + + Hide system disk + Приховати системний диск + + + + + + Show file system on disk icon + Показувати файлову систему на піктограмі диска + + + + + + Show hidden files in search results + Показувати приховані файли у результатах пошуку + + + + + + Display recent file entry in left panel + Показувати запис останнього файла на лівій панелі + + + + + + Preview + Попередній перегляд + + + + + Compress file preview + Перегляд стиснених файлів + + + + + + Text preview + Перегляд тексту + + + + + + Document preview + Перегляд документів + + + + + + Image preview + Перегляд зображень + + + + + + Video preview + Перегляд відео + + + + + + Mount + Монтування + + + + + + Auto mount + Автоматичне монтування + + + + + + Open after auto mount + Відкривати після автоматичного монтування + + + + + + Dialog + Вікно + + + + Compressed file preview + Попередній перегляд стисненого файлу + + + + GvfsMountManager + + + Can’t verify the identity of %1. + Не вдалося переконатися у ідентичності %1. + + + + This happens when you log in to a computer the first time. + Таке трапляється, якщо ви входите до системи уперше. + + + + The identity sent by the remote computer is + Профіль, який надіслано віддаленим комп'ютером, — + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + Якщо ви хочете бути абсолютно певні, що виконання дії є безпечним, проконсультуйтеся в адміністратора вашої системи. + + + + + + + + Mounting device error + Помилка під час монтування пристрою + + + + + Wrong username or password + Помилкове ім'я користувача або пароль + + + + + + + + Confirm + button + Підтвердити + + + + + Cannot find the mounted device + Не вдалося знайти змонтований пристрій + + + + No key available to unlock device + Немає ключа для розблокування пристрою + + + + The disk is mounted by user "%1", you cannot unmount it. + Диск змонтовано користувачем %1, ви не можете розмонтувати його. + + + + Cannot unmount the device + Не вдалося демонтувати пристрій + + + + Cannot eject the device "%1" + Не вдалося виштовхнути носій з пристрою «%1» + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + Не вдалося записати. Недостатньо вільного місця на диску призначення. + + + + MergedDesktopController + + + + Pictures + Зображення + + + + + Music + Музика + + + + + Applications + Програма + + + + + Videos + Відео + + + + + Documents + Документи + + + + + Others + Інші + + + + MimeTypeDisplayManager + + + + Directory + Каталог + + + + + + Application + Програма + + + + + + Video + Відео + + + + + + Audio + Аудіо + + + + + + Image + Зображення + + + + + Archive + Архів + + + + + + Text + Текст + + + + + Executable + Виконуваний + + + + + Backup file + Файл резервної копії + + + + + Unknown + Невідомо + + + + MountAskPasswordDialog + + + Cancel + button + Скасувати + + + + Connect + button + Під'єднатися + + + + Log in as + Увійти як + + + + Anonymous + Анонімно + + + + Registered user + Зареєстрований користувач + + + + Username + Ім'я користувача + + + + Domain + Домен + + + + Password + Пароль + + + + Remember password + Запам'ятати пароль + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + Скасувати + + + + Unlock + button + Розблокувати + + + + Input password to decrypt the disk + Введіть пароль для розшифрування диска + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + Ви впевнені, що хочете остаточно видалити %1? + + + + This file is too big for the trash + Цей файл завеликий для переміщення до смітнику + + + + The files are too big for the trash + Файли завеликий для переміщення до смітнику + + + + Are you sure you want to permanently delete %1 files? + Ви впевнені, що хочете остаточно видалити %1 файли? + + + + Cancel + button + Скасувати + + + + Delete + button + Видалити + + + + OpenWithDialog + + + Open with + Відкрити з + + + + Add other programs + Додати інші програми + + + + Set as default + Встановити за замовчуванням + + + + Cancel + button + Скасувати + + + + Confirm + button + Підтвердити + + + + Recommended Applications + Рекомендовані програми + + + + Other Applications + Інші програми + + + + PathManager + + + Home + Домівка + + + + Desktop + Стільниця + + + + Videos + Відео + + + + Music + Музика + + + + Pictures + Зображення + + + + Documents + Документи + + + + Downloads + Завантаження + + + + + Trash + Смітник + + + + + + System Disk + Системний диск + + + + Computers in LAN + Комп'ютери в локальній мережі + + + + My Shares + Мої спільні + + + + Computer + Комп'ютер + + + + Recent + Нещодавні + + + + File Vault + Файлове сховище + + + + PropertyDialog + + + Basic info + Базова інформація + + + + Open with + Відкрити з + + + + Sharing + Поділитись + + + + Permissions + Дозволи + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + Приховати цю теку + + + + Hide this file + Приховати цей файл + + + + Allow to execute as program + Дозволити виконати як програму + + + + QObject + + + + + + Size + Розмір + + + + + + Contains + Вміщує + + + + + + Type + Тип + + + + + + + + Time modified + Час зміни + + + + Free space + Вільний простір + + + + Total space + Загальний розмір + + + + + Time locked + Час блокування + + + + Access denied + Доступ заборонено + + + + + Executable + Виконуваний + + + + + Write only + Лише для запису + + + + + Read only + Лише для читання + + + + + Read-write + Читання-запис + + + + Others + Інші + + + + Owner + Власник + + + + Unconnected network shared directory + Нез'єднаний мережевий спільний каталог + + + + Device type + Тип пристрою + + + + File system + Файлова система + + + + Group + Група + + + + + Open + Відкрити + + + + Lock + Заблокувати + + + + Auto lock + Автоблокування + + + + Never + Ніколи + + + + 5 minutes + 5 хвилин + + + + 10 minutes + 10 хвилин + + + + 20 minutes + 20 хвилин + + + + Delete File Vault + Вилучити сховище файлів + + + + Unlock + Розблокувати + + + + Unlock by key + Розблокувати ключем + + + + Open + button + Відкрити + + + + + Size: %1 + Розмір: %1 + + + + Type: %1 + Тип: %1 + + + + Size: 0 + Розмір: 0 + + + + Items: %1 + Об'єкти: %1 + + + + + + + + + + Open in new window + Відкрити у новому вікні + + + + + + + + + + Open in new tab + Відкрити у новій вкладці + + + + Open with + Відкрити з + + + + + Compress + Стиснути + + + + Extract + Видобути + + + + Extract here + Видобути сюди + + + + Cut + Вирізати + + + + Copy + Копіювати + + + + Paste + Вставити + + + + + + + + Rename + Перейменувати + + + + + + + Remove + Вилучити + + + + Create link + Створити посилання + + + + Send to desktop + Надіслати на стільницю + + + + Send to + Надіслати до + + + + Bluetooth + Bluetooth + + + + Add to bookmark + Додати до закладок + + + + + + + Properties + Властивості + + + + New folder + Нова тека + + + + New window + Нове вікно + + + + Select all + Вибрати все + + + + + Clear recent history + Очистити нещодавню історію + + + + + + Empty Trash + Спорожнити смітник + + + + Display as + Відобразити як + + + + Sort by + Сортувати за + + + + New document + Новий документ + + + + + Time created + Час створення + + + + + + Source path + Шлях до джерела + + + + Share folder + Поділитися текою + + + + Cancel sharing + Скасувати обмін + + + + Connect to Server + Підключення до сервера + + + + Set share password + Встановити загальний пароль + + + + Format + Форматувати + + + + Tag information + Дані щодо мітки + + + + Open as administrator + Відкрити від імені адміністратора + + + + Select default program + Вибрати програму за замовчуванням + + + + Open file location + Відкрити розташування файлу + + + + Remove bookmark + Вилучити закладку + + + + + + Delete + Видалити + + + + Office Text + Офісний текстовий документ + + + + Spreadsheets + Електронні таблиці + + + + Plain Text + Звичайний текстовий документ + + + + Open in terminal + Відкрити в терміналі + + + + Restore + Відновити + + + + Restore all + Відновити все + + + + Clear saved password and unmount + Вилучити збережений пароль і демонтувати + + + + File Vault + Файлове сховище + + + + Add to disc + Додати на диск + + + + Refresh + Освіжити + + + + Auto mount + Авто-монтування + + + + Open after auto mount + Відкрити після автоматичного монтування + + + + + Mount + Змонтувати + + + + + Unmount + Відмонтувати + + + + It does not support burning %1 discs + Не передбачено підтримки запису дисків %1 + + + + Burn + Записати + + + + Disc name: + Назва диска: + + + + + Maximum + Максимальна + + + + Allow files to be added later + Уможливити наступне додавання файлів + + + + Verify data + Перевірити дані + + + + Write speed: + Швидкість запису: + + + + + + + Cancel + button + Скасувати + + + + Burn + button + Записати + + + + + Eject + Відʼєднати + + + + Safely Remove + Безпечне Вилучення + + + + + Name + Назва + + + + Settings + Налаштування + + + + Exit + Вихід + + + + Icon + Іконка + + + + List + Список + + + + Extend + Продовжити + + + + Set as wallpaper + Встановити як шпалери + + + + + + + Local disk + Локальний накопичувач + + + + + Removable disk + Знімний накопичувач + + + + + + Network shared directory + Мережева спільна директорія + + + + + Android mobile device + Мобільний пристрій Android + + + + + Apple mobile device + Мобільний пристрій Apple + + + + + Camera + Камера + + + + + DVD + DVD + + + + + Unknown device + Невідомий пристрій + + + + + + %1 item + %1 об'єкт + + + + + + %1 items + %1 об'єктів + + + + Shortcut + Ярлик + + + + Create symlink + Створити посилання + + + + Path + Шлях + + + + + + Time deleted + Час видалення + + + + Loading... + Завантаження... + + + + File has been moved or deleted + Файл був переміщений чи видалений + + + + You do not have permission to traverse files in it + Ви не маєте права пересувати тут файли + + + + + + You do not have permission to access this folder + У вас немає дозволу на доступ до цієї теки + + + + + + + + Folder is empty + Порожня тека + + + + Searching... + Пошук... + + + + No results + Немає результатів + + + + Source Path + TrashFileInfo + Шлях до джерела + + + + Document + Документ + + + + Spreadsheet + Електронна таблиця + + + + + Presentation + Презентація + + + + Text + Текст + + + + 1 task in progress + 1 завдання в процесі + + + + %1 tasks in progress + %1 завдань в процесі + + + + Mode: + Режим: + + + + + Replace Text + Замінити текст + + + + + Add Text + Додати текст + + + + + Custom Text + Користувацький текст + + + + Find: + Знайти: + + + + Replace: + Замінити: + + + + + Optional + Необов'язково + + + + Add: + Додати: + + + + Location: + Місцезнаходження: + + + + File name: + Ім'я файлу: + + + + Start at: + Почати з: + + + + + Rename + button + Перейменувати + + + + + + + + + + + Required + Вимагається + + + + + Before file name + Перед ім'ям файлу + + + + + After file name + Після імені файлу + + + + Find + Знайти + + + + Replace + Замінити + + + + Add + Додати + + + + Start at + Почати з + + + + + + Location + Місцезнаходження + + + + File name + Ім'я файлу + + + + Dimension + Розмір + + + + Duration + Тривалість + + + + Tips: Sort by selected file order + Поради: сортувати за вибраним порядком файлів + + + + Rename %1 Files + Перейменувати %1 файли + + + + Multiple Files + Декілька файлів + + + + Basic info + Основна інформація + + + + Total size + Загальний розмір + + + + Number of files + Кількість файлів + + + + %1 file(s), %2 folder(s) + %1 файл(и), %2 тека(и) + + + + + + Time accessed + Час доступу + + + + Orange + Оранжевий + + + + Red + Червоний + + + + Purple + Фіолетовий + + + + Navy-blue + Синій + + + + Azure + Блакитний + + + + Green + Зелений + + + + Yellow + Жовтий + + + + Gray + Сірий + + + + Input tag info, such as work, family. A comma is used between two tags. + Вхідні данні для тегу, наприклад робота, сім'я. Використовуйте кому між двома тегами. + + + + Bookmarks + Закладки + + + + Erase + Витерти + + + + Copy path + Копіювати шлях + + + + Edit address + Редагувати адресу + + + + Free Space %1 + Вільне місце %1 + + + + Files are being processed + Файли обробляються + + + + + Unknown + Невідомо + + + + My Vault + Моє сховище + + + + + Failed to create file info + Не вдалося створити відомості щодо файла + + + + Failed to create file handler + Не вдалося створити обробник файла + + + + Failed to open the file, cause: %1 + Не вдалося відкрити файл. Причина: %1 + + + + Original file does not exist + Початкового файла не існує + + + + Do you want to delete %1? + Хочете вилучити %1? + + + + Confirm + button + Підтвердити + + + + + + + + %1 are not allowed + %1 заборонено + + + + + Failed to start Samba services + Не вдалося запустити служби Samba + + + + RecentController + + + Cancel + button + Скасувати + + + + Remove + button + Вилучити + + + + Do you want to remove this item? + Хочете вилучити цей запис? + + + + Do yout want to remove %1 items? + Хочете вилучити %1 записів? + + + + It does not delete the original files + Початкові файли вилучено не буде + + + + ShareInfoFrame + + + Share this folder + Поділитися цією текою + + + + Share name: + Поділитися ім'ям: + + + + Permission: + Дозвіл: + + + + Read and write + Читання та запис + + + + Read only + Тільки читання + + + + Anonymous: + Анонімно: + + + + Not allow + Не дозволяти + + + + Allow + Дозволити + + + + The share name must not be two dots (..) or one dot (.) + Назвою спільного ресурсу не може дві крапки (..) або одна крапка (.) + + + + The share name is used by another user. + Назву спільного ресурсу вже використано іншим користувачем. + + + + OK + button + Гаразд + + + + Cancel + button + Скасувати + + + + Replace + button + Замінити + + + + The share name already exists. Do you want to replace the shared folder? + Спільний ресурс із такою назвою вже існує. Хочете замінити теку спільного використання? + + + + Shortcut + + + Item + Об'єкт + + + + Select to the first item + Вибрати перший об'єкт + + + + Shift + Home + Shift + Home + + + + Select to the last item + Вибрати останній об'єкт + + + + Shift + End + Shift + End + + + + Select leftwards + Вибрати ліворуч + + + + Shift + Left + Shift + Left + + + + Select rightwards + Вибрати праворуч + + + + Shift + Right + Shift + Right + + + + Select to upper row + Вибрати верхній рядок + + + + Shift + Up + Shift + Up + + + + Select to lower row + Вибрати нижній рядок + + + + Shift + Down + Shift + Down + + + + Open + Відкрити + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + До батьківської директорії + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + Видалити назавжди + + + + Shift + Delete + Shift + Delete + + + + Delete file + Видалити файл + + + + Delete + Видалити + + + + Select all + Вибрати все + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + Копіювати + + + + Cut + Обрізати + + + + Paste + Вставити + + + + Rename + Перейменувати + + + + F2 + F2 + + + + New/Search + Новий/Пошук + + + + New window + Нове вікно + + + + New folder + Нова тека + + + + + Search + Пошук + + + + New tab + Нова вкладка + + + + View + Вид + + + + Item information + Інформація про об'єкт + + + + Help + Довідка + + + + F1 + F1 + + + + Keyboard shortcuts + Гарячі клавіши + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + Стан відображення перемикача + + + + Hide item + Сховати обʼєкт + + + + Input in address bar + Введення в адресний рядок + + + + Switch to icon view + Перемкнутися на перегляд піктограм + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + Перемкнутися не перегляд списку + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + Інші + + + + Close + Закрити + + + + Alt + F4 + Alt + F4 + + + + Close current tab + Закрити поточну вкладку + + + + Back + Назад + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + Переключитися до наступної вкладки + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + Переключитися до попередньої вкладки + + + + Next file + Наступний файл + + + + Tab + Tab + + + + Previous file + Попередній файл + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + Перейдіть на вкладку за вказаним номером від 1 до 8 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + Вперед + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + Не вдалося відкрити записи у смітнику. Будь ласка, спочатку відновіть їх. + + + + TrashPropertyDialog + + + Trash + Смітник + + + + item + об'єкт + + + + items + об'єктів + + + + Contains %1 %2 + Вміщує %1 %2 + + + + UDiskListener + + + Failed to rename the label + Не вдалося перейменувати мітку + + + + UnmountWorker + + + + + The device was not safely unmounted + Пристрій не було безпечно вилучено + + + + The device was not safely removed + Пристрій не було безпечно вилучено + + + + UserShareManager + + + Kindly Reminder + Увічливе нагадування + + + + Please firstly install samba to continue + Будь ласка, спочатку встановіть samba + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + Назва спільного ресурсу не повинна містити %<>*?|/\+=;:," і не повинна починатися з %1 + + + + To protect the files, you cannot share this folder. + Щоб захистити файли, вам заборонено надавати цю теку у спільне користування. + + + + Sharing failed + Невдала спроба оприлюднення + + + + The computer name is too long + Надто довга назва комп'ютера + + + + You do not have permission to operate file/folder! + Ви не маєте права керувати файлами/теками! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + Введіть пароль для захисту спільних тек + + + + Cancel + button + Скасувати + + + + Confirm + button + Підтвердити + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_zh_CN.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_zh_CN.ts new file mode 100644 index 0000000..2e7caf9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_zh_CN.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + 新建文件夹 + + + + Mounting device error + 挂载设备出错 + + + + The disc image was corrupted, cannot mount now, please erase the disc first + 此光盘中的镜像已损坏,无法挂载,请擦除后使用 + + + + Mount error: unsupported image format + 挂载错误,镜像文件格式不支持 + + + + + The device was not safely removed + 设备没有正常移除 + + + + + Click "Safely Remove" and then disconnect it next time + 请点击“安全移除”后,再断开连接 + + + + The device was not ejected + 设备未弹出 + + + + Disk is busy, cannot eject now + 磁盘文件被占用,无法弹出 + + + + Authentication timed out + 认证超时 + + + + BluetoothTransDialog + + + Bluetooth File Transfer + 蓝牙文件传输 + + + + File Transfer Successful + 文件传输成功 + + + + File Transfer Failed + 文件传输失败 + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + 正在向“<b style="font-weight: 550;">%1</b>”传送文件 + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + 向“<b style="font-weight: 550;">%1</b>”传送文件失败 + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + 向“<b style="font-weight: 550;">%1</b>”传送文件成功 + + + + Select a Bluetooth device to receive files + 选择接收此文件的蓝牙设备 + + + + Cannot find the connected Bluetooth device + 未找到已连接的蓝牙设备 + + + + Waiting to be received... + 等待接收,请稍候... + + + + Go to Bluetooth Settings + 前往蓝牙设置 + + + + %1/%2 Sent + 已传送%1/%2 + + + + Error: the Bluetooth device is disconnected + 原因:蓝牙设备连接中断 + + + + Unable to send the file more than 2 GB + 无法发送超过2GB的文件 + + + + Unable to send 0 KB files + 无法发送0KB的文件 + + + + File doesn't exist + 文件不存在 + + + + Next + button + 下一步 + + + + Cancel + button + 取 消 + + + + Done + button + 完 成 + + + + Retry + button + 重 试 + + + + OK + button + 确 定 + + + + File sending request timed out + 文件发送超时 + + + + The service is busy and unable to process the request + 设备超时,无法处理该请求 + + + + BurnOptDialog + + + Device error + 设备故障 + + + + Optical device %1 doesn't exist + 光驱%1不存在 + + + + Advanced settings + 高级设置 + + + + File system: + 文件系统: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (可用于Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (可用于Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1格式(兼容Windows的CD/DVD刻录模式) + + + + ISO9660 Only + 仅ISO9660 + + + + CloseAllDialogIndicator + + + Close all + 关闭全部 + + + + Total size: %1, %2 files + 总容量 %1,总文件数量 %2个 + + + + ComputerModel + + + Double click to open it + 双击打开应用程序 + + + + My Directories + 我的目录 + + + + Disks + 磁盘 + + + + File Vault + 保险箱 + + + + Quick Access + 快速访问 + + + + ComputerPropertyDialog + + + Computer + 计算机 + + + + Basic Info + 基本信息 + + + + + Computer Name + 计算机名 + + + + + Edition + 版本 + + + + + + Version + 版本号 + + + + + Type + 类型 + + + + + + Processor + 处理器 + + + + + + Memory + 内存 + + + + + + + Bit + + + + + + Available + 可用 + + + + Obtaining... + 正在获取中... + + + + ConnectToServerDialog + + + Connect to Server + 连接到服务器 + + + + Cancel + button + 取 消 + + + + Connect + button + 连 接 + + + + My Favorites: + 个人收藏服务器 + + + + + Clear History + 清除最近使用的服务器 + + + + DFMAddressBar + + + Search or enter address + 搜索或输入地址 + + + + DFMAdvanceSearchBar + + + Search: + 搜索范围: + + + + File Type: + 文件类型: + + + + File Size: + 文件大小: + + + + Time Modified: + 修改时间: + + + + Time Accessed: + 访问时间: + + + + Time Created: + 创建时间: + + + + Reset + 重置 + + + + All subdirectories + 所有子文件夹 + + + + Current directory + 当前文件夹 + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + 今天 + + + + Yesterday + 昨天 + + + + This week + 本周 + + + + Last week + 上周 + + + + This month + 本月 + + + + Last month + 上月 + + + + This year + 今年 + + + + Last year + 去年 + + + + DFMOpticalMediaWidget + + + + No files to burn + 没有文件需要刻录 + + + + Unable to burn. Not enough free space on the target disk. + 目标磁盘剩余空间不足,无法进行刻录! + + + + %1 burning is not supported + 当前光盘介质不支持%1刻录 + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. 介质类型不是%1; +2. 当前光盘文件系统版本暂不支持追加刻录。 + + + + DFMTagCrumbController + + + Tag information + 标记信息 + + + + DFMTagWidget + + + Tag + 标记 + + + + DFMTaskWidget + + + Do not ask again + 不再询问 + + + + Syncing data + 数据同步中 + + + + Please wait + 请稍候 + + + + + Time modified: %1 + 修改时间:%1 + + + + + Contains: %1 + 个数:%1 + + + + + Size: %1 + 大小:%1 + + + + Original folder + 原始文件夹 + + + + Keep both + button + 共 存 + + + + Skip + button + 跳 过 + + + + Replace + button + 替 换 + + + + Retry + button + 重 试 + + + + Original file + 原始文件 + + + + Target folder + 目标文件夹 + + + + Target file + 目标文件 + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + 加密保险箱 + + + + Click 'Encrypt' and input the user password. + 点击“加密保险箱”后,输入用户密码完成设置。 + + + + Encrypting... + 正在加密... + + + + + + + Encrypt + 加密保险箱 + + + + Failed to create file vault: %1 + 创建保险箱失败:%1 + + + + OK + 确 定 + + + + The setup is complete + 加密已完成 + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + 保存密钥文件 + + + + Keep the key safe to retrieve the vault password later + 密钥文件可用来找回您设置的保险箱密码,请妥善保管 + + + + Save to default path + 保存至默认路径 + + + + Save to other locations + 保存至其他路径 + + + + No permission, please reselect + 权限不够,请重新选择 + + + + Select a path + 选择密钥文件保存路径 + + + + Next + 下一步 + + + + The default path is invisible to other users, and the path information will not be shown. + 默认路径为不会暴露给其他用户的特殊路径,且不会明文显示路径信息。 + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + 文件保险箱恢复密钥 + + + + Generate a recovery key in case that you forgot the password + 如果忘记密码,可以使用该密钥恢复访问 + + + + Key + 密钥 + + + + QR code + 二维码 + + + + Scan QR code and save the key to another device + 扫描二维码,保存至其它设备 + + + + Next + 下一步 + + + + Recovery Key: + 文件保险箱恢复密钥: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + 设置解锁方式 + + + + Method + 类型 + + + + Manual + 手动 + + + + Password + 密码 + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + 至少8位,包含A-Z, a-z, 0-9和符号 + + + + Repeat password + 重复密码 + + + + Input the password again + 再次输入密码 + + + + Password hint + 密码提示 + + + + Optional + 选填 + + + + Next + 下一步 + + + + + Passwords do not match + 输入密码不一致 + + + + DFMVaultActiveStartView + + + File Vault + 保险箱 + + + + Create your secure private space + 专属于个人的安全空间 + + + + Advanced encryption technology + 先进的加密技术,隐私安全有保障 + + + + Convenient and easy to use + 使用更便捷,操作更简单 + + + + Create + 开启 + + + + DFMVaultFileView + + + Cannot open this path + 无法打开当前路径 + + + + Hint + 提示 + + + + OK + 确 定 + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + 恢复密钥解锁 + + + + Failed to unlock file vault + 解锁保险箱失败 + + + + OK + 确 定 + + + + Input the 32-digit recovery key + 请输入32位恢复密钥 + + + + Cancel + button + 取 消 + + + + Unlock + button + 解 锁 + + + + Wrong recovery key + 密钥错误 + + + + DFMVaultRemoveByPasswordView + + + Password + 密码 + + + + Password hint: %1 + 密码提示:%1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + 请输入32位恢复密钥 + + + + DFMVaultRemovePages + + + Delete File Vault + 删除保险箱 + + + + Once deleted, the files in it will be permanently deleted + 删除保险箱后,其中的所有内容将会被永久删除 + + + + Use Key + 密钥验证 + + + + Cancel + button + 取 消 + + + + Use Key + button + 密钥验证 + + + + Delete + button + 删 除 + + + + + OK + button + 确 定 + + + + Use Password + 密码验证 + + + + Wrong password + 密码错误 + + + + Wrong recovery key + 密钥错误 + + + + Failed to delete file vault + 删除保险箱失败 + + + + Deleted successfully + 删除成功 + + + + Failed to delete + 删除失败 + + + + Removing... + 正在删除... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + 无法获取密钥文件 + + + + Verification failed + 密钥验证失败 + + + + + Select a path + 选择密钥文件保存路径 + + + + + Retrieve Password + 密码找回 + + + + By key in the default path + 通过默认路径密钥文件找回密码 + + + + By key in the specified path + 通过指定路径密钥文件找回密码 + + + + Verification Successful + 密钥验证成功 + + + + Keep it safe + 请妥善保管 + + + + Back + button + 返 回 + + + + Verify Key + button + 验证密钥 + + + + Go to Unlock + button + 返回解锁 + + + + Close + button + 关 闭 + + + + Vault password: %1 + 保险箱密码为:%1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + 解锁保险箱 + + + + Forgot password? + 忘记密码? + + + + Password hint: %1 + 密码提示:%1 + + + + Failed to unlock file vault + 解锁保险箱失败 + + + + Cancel + button + 取 消 + + + + Password + 密码 + + + + Unlock + button + 解 锁 + + + + Please try again %1 minutes later + 请%1分钟后再试 + + + + Wrong password, please try again %1 minutes later + 密码错误,请%1分钟后再试 + + + + Wrong password, one chance left + 密码错误,您还可再输入1次 + + + + Wrong password, %1 chances left + 密码错误,您还可再输入%1次 + + + + Wrong password + 密码错误 + + + + OK + button + 确 定 + + + + DFileCopyMoveJob + + + Permission error + 权限错误 + + + + The action is denied + 文件不支持此操作 + + + + Failed to open the file + 文件打开失败 + + + + Failed to read the file + 文件内容读取失败 + + + + Failed to write the file + 文件内容写入失败 + + + + Failed to create the directory + 目录创建失败 + + + + Failed to delete the file + 文件删除失败 + + + + Failed to move the file + 文件移动失败 + + + + Original file does not exist + 源文件不存在 + + + + Failed, file size must be less than 4GB + 操作失败,文件大小已超出上限值4GB! + + + + Not enough free space on the target disk + 目标磁盘剩余空间不足 + + + + File integrity was damaged + 文件完整性检查失败 + + + + The target device is read only + 目标设备为只读 + + + + Target folder is inside the source folder + 目标文件夹位于源文件夹内 + + + + The action is not supported + 不支持该操作 + + + + You do not have permission to traverse files in it + 您没有权限遍历子文件 + + + + Failed to position the file pointer! + 指针定位失败! + + + + copy + Extra name added to new file name when used for file name. + 副本 + + + + Failed to open the directory, cause: file name too long + 目录打开失败,原因:文件名过长 + + + + + Failed to open the file, cause: file name too long + 文件打开失败,原因:文件名过长 + + + + + Failed to write the file, cause: + 文件内容写入失败,原因: + + + + Failed to position the file pointer, cause: %1 + 指针定位失败,原因:%1 + + + + Syncing data + 数据同步中 + + + + Please wait + 请稍候 + + + + Failed to create the directory, cause: %1 + 目录创建失败,原因:%1 + + + + + + + + Failed to open the file, cause: %1 + 文件打开失败,原因:%1 + + + + + + + Failed to open the file, cause: Permission denied + 文件打开失败,原因:权限不足 + + + + + Failed to read the file, cause: %1 + 文件内容读取失败,原因:%1 + + + + + + + Failed to write the file, cause: %1 + 文件内容写入失败,原因:%1 + + + + + File integrity was damaged, cause: %1 + 文件完整性检查失败,原因:%1 + + + + Failed to open the file, cause: + 文件打开失败,原因: + + + + Failed to read the file, cause: + 文件内容读取失败,原因: + + + + Failed to delete the file, cause: %1 + 文件删除失败,原因:%1 + + + + Fail to create symlink, cause: %1 + 创建链接失败,原因:%1 + + + + DFileDialog + + + + Save + button + 保 存 + + + + + Cancel + button + 取 消 + + + + Confirm + button + 确 定 + + + + %1 already exists, do you want to replace it? + “%1”已存在,您是否要替换? + + + + Replace + button + 替 换 + + + + Open + button + 打 开 + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + 文件名以“.”开始将会隐藏此文件,请确认是否继续? + + + + DFileManagerWindow + + + Trash + 回收站 + + + + Empty + 清空 + + + + DFileSystemModel + + + + Name + 名称 + + + + + + Time modified + 修改时间 + + + + Size + 大小 + + + + Type + 类型 + + + + Time created + 创建时间 + + + + + Last access + 最近访问时间 + + + + + + + Path + 路径 + + + + DFileView + + + Disc mount error + 光盘挂载错误 + + + + The disc is in use, please end the running process and remount the disc. + 当前光驱设备正在占用,请关闭占用进程再重新挂载 + + + + Mounting failed + 挂载失败 + + + + (Reverse) + (反序) + + + + DFileViewHelper + + + Add tag "%1" + 添加标记“%1” + + + + DStatusBar + + + %1 item + %1 项 + + + + %1 items + %1 项 + + + + %1 item selected + 选中 %1 项内容 + + + + %1 items selected + 选中 %1 项内容 + + + + %1 folder selected (contains %2) + 选中%1个文件夹(包含%2) + + + + %1 folders selected (contains %2) + 选中%1个文件夹(包含%2) + + + + %1 file selected (%2) + 选中%1个文件(%2) + + + + %1 files selected (%2) + 选中%1个文件(%2) + + + + %1 folder selected + 选中%1个文件夹 + + + + Filter + 过滤 + + + + Save as: + 保存为: + + + + Loading... + 正在加载...... + + + + DTaskDialog + + + Erasing disc %1, please wait... + 正在擦除%1,请稍候... + + + + Burning disc %1, please wait... + 正在刻录到%1,请稍候... + + + + Writing data... + 正在写入数据... + + + + Verifying data... + 正在校验数据... + + + + Copying %1 + 正在复制%1 + + + + + + to %2 + 到%2 + + + + %1 already exists in target folder + 目标文件夹中已存在名为%1的文件 + + + + Original path %1 Target path %2 + 原路径%1 目标路径%2 + + + + Merge + button + 合 并 + + + + Replace + button + 替 换 + + + + Moving %1 + 正在移动%1 + + + + Removing file vault, please try later + 正在删除保险箱,请稍候... + + + + Restoring %1 + 正在恢复%1 + + + + Deleting %1 + 正在删除%1 + + + + Trashing %1 + 正在移动 %1 + + + + Calculating space, please wait + 正在计算大小,请稍候 + + + + DUMountManager + + + + Authentication timed out + 认证超时 + + + + + + Disk is busy, cannot unmount now + 磁盘文件被占用,无法卸载 + + + + Disk is busy, cannot eject now + 磁盘文件被占用,无法弹出 + + + + The device is busy, cannot eject now + 光驱正忙,无法弹出 + + + + + + The device is busy, cannot remove now + 设备正忙,无法安全移除 + + + + DeepinStorage + + + + + %1 Volume + %1 卷 + + + + Data Disk + Data Partition + 数据盘 + + + + %1 Drive + %1 驱动器 + + + + Blank %1 Disc + 空白%1光盘 + + + + %1 Encrypted + %1 已加密 + + + + DialogManager + + + + + + Operation failed! + 操作失败! + + + + Target folder is inside the source folder! + 目标文件夹位于源文件夹内! + + + + Do you want to run %1 or display its content? + 您是要运行 “%1”,还是显示它的内容? + + + + It is an executable text file. + 它是可执行的文本文件。 + + + + It is an executable file. + 它是一个可执行文件。 + + + + This file is not executable, do you want to add the execute permission and run? + 此文件没有可执行权限,是否添加权限并运行? + + + + "%1" already exists, please use another name. + 文件名 "%1" 已被占用,请使用其他名称。 + + + + The file name must not contain two dots (..) + 文件名不得含有两个点(..) + + + + Device or resource busy + 设备或资源繁忙 + + + + Are you sure you want to erase all data on the disc? + 您确定要擦除此光盘的所有内容吗? + + + + How do you want to use this disc? + 您希望使用此光盘刻录镜像或者是存储文件? + + + + Disc erase failed + 擦除失败 + + + + Burn process failed + 刻录失败 + + + + %1: %2 + %1:%2 + + + + Show details + 显示详情 + + + + Hide details + 隐藏详情 + + + + Error + 错误信息 + + + + Permanently delete %1? + 您确定要彻底删除 %1? + + + + Permanently delete %1 items? + 您确定要彻底删除选中的%1项内容? + + + + Empty + 清空 + + + + Do you want to delete %1? + 是否删除 %1? + + + + Do you want to delete the selected %1 items? + 是否删除选中的%1项内容? + + + + Sorry, unable to locate your bookmark directory, remove it? + 抱歉, 找不到您的书签目录, 是否移除? + + + + Name: + 名称: + + + + %1 that this shortcut refers to has been changed or moved + 此快捷方式所指向的“%1”已被更改或移动 + + + + Do you want to delete this shortcut? + 是否删除此快捷方式? + + + + Failed, file size must be less than 4GB. + 操作失败,文件大小已超出上限值4GB! + + + + Fail to create symlink, cause: + 创建链接失败,原因: + + + + The selected files contain system file/directory, and it cannot be deleted + 选择的文件中包含系统目录,不能被删除 + + + + Unable to find the original file + 无法找到链接目标文件 + + + + + You do not have permission to operate file/folder! + 您没有权限操作文件/文件夹! + + + + Failed to restore %1 file, the source file does not exist + 原文件不存在,%1个文件恢复失败 + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + 抱歉,您没有权限操作以下%1个文件/文件夹 + + + + Unable to access %1 + 访问%1失败 + + + + + Sending files now, please try later + 当前已有发送中的文件,请稍后再试 + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + 需要格式化磁盘才能访问此设备,是否继续? + + + + Scanning the device, stop it? + 正在扫描当前设备,是否终止扫描? + + + + Share folder can't be named after the current username + 共享文件夹不能和当前用户名重名 + + + + Do you want to run %1? + 您是否要运行“%1”? + + + + Burn image + button + 刻录镜像 + + + + Burn files + button + 存储文件 + + + + Are you sure you want to empty %1 item? + 您确定要清空回收站里的 %1 项内容吗? + + + + Are you sure you want to empty %1 items? + 您确定要清空回收站里的 %1 项内容吗? + + + + + This action cannot be undone + 此操作不可以恢复 + + + + + + + + + + + + + + OK + button + 确 定 + + + + + + + + + + + + + + + Cancel + button + 取 消 + + + + + + Run + button + 运 行 + + + + + Run in terminal + button + 在终端中运行 + + + + Display + button + 显 示 + + + + + + + + + + + Confirm + button + 确 定 + + + + Erase + button + 擦 除 + + + + Data verification failed + 数据校验失败 + + + + Show details + button + 显示详情 + + + + + Delete + button + 删 除 + + + + Remove + button + 删 除 + + + + Disk is busy, cannot unmount now + 磁盘文件被占用,无法卸载 + + + + Force unmount + button + 强制卸载 + + + + Unable to copy. Not enough free space on the target disk. + 目标磁盘剩余空间不足,无法进行复制! + + + + Failed to restore %1 file, the target folder is read-only + %1个文件还原失败,目标文件夹不可写 + + + + Failed to restore %1 files, the target folder is read-only + %1个文件还原失败,目标文件夹不可写 + + + + Failed to restore %1 files, the source files do not exist + 原文件不存在,%1个文件恢复失败 + + + + Format + button + 格式化 + + + + Stop + button + 终 止 + + + + FileController + + + + + + Unable to find the original file + 无法找到链接目标文件 + + + + + + Kindly Reminder + 温馨提示 + + + + + + Please install File Roller first and then continue + 请先安装归档管理器然后继续 + + + + + Unable to create files here: %1 + 不能在此创建文件:%1 + + + + Confirm + button + 确 定 + + + + FileDialogStatusBar + + + File Name + 文件名 + + + + Format + 格式 + + + + Save + button + 保 存 + + + + Open + button + 打 开 + + + + Save File + button + 保存文件 + + + + Open File + button + 打开文件 + + + + + + Cancel + button + 取 消 + + + + FileJob + + + copy + 副本 + + + + + + + Data verification successful. + 数据验证成功。 + + + + + + Burn process completed + 刻录完成 + + + + %1 s + %1 秒 + + + + %1 m %2 s + %1 分 %2 秒 + + + + %1 h %2 m %3 s + %1 时 %2 分 %3 秒 + + + + %1 d %2 h %3 m %4 s + %1 天 %2 时 %3 分 %4 秒 + + + + %1 is a duplicate file. + %1为重复文件。 + + + + Insufficient disc space. + 光盘空间不足。 + + + + Lost connection to drive. + 与光驱的连接断开。 + + + + The CD/DVD drive is not ready. Try another disc. + 光驱未准备好,您可以换一张光盘再试。 + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + 光驱被占用,您可以尝试关掉正在使用光驱的程序后重新插入光驱。 + + + + Unknown error + 未知错误 + + + + Device disconnected + 光驱设备未连接 + + + + GenerateSettingTranslate + + + + + Basic + 基础设置 + + + + + + Open behavior + 打开行为 + + + + + + Always open folder in new window + 总是在新窗口打开文件夹 + + + + + + Open file: + 打开文件: + + + + + + Click + 单击 + + + + + + Double click + 双击 + + + + + + New window and tab + 新窗口和新标签 + + + + + + Open from default window: + 从默认窗口打开: + + + + + + + + + Computer + 计算机 + + + + + + + + + Home + 主目录 + + + + + + + + + Desktop + 桌面 + + + + + + + + + Videos + 视频 + + + + + + + + + Music + 音乐 + + + + + + + + + Pictures + 图片 + + + + + + + + + Documents + 文档 + + + + + + + + + Downloads + 下载 + + + + + + Open in new tab: + 从新标签打开: + + + + + + Current Directory + 当前目录 + + + + + + View + 视图 + + + + + + Default size: + 默认大小: + + + + + + Extra small + 特小 + + + + + + Small + + + + + + + Medium + + + + + + + Large + + + + + + + Extra large + 特大 + + + + + + Default view: + 默认视图: + + + + + + Icon + 图标视图 + + + + + + List + 列表视图 + + + + + + Hidden files + 隐藏文件 + + + + + + Show hidden files + 显示隐藏文件 + + + + + + Hide file extension when rename + 重命名时隐藏文件扩展名 + + + + + + Advanced + 高级设置 + + + + + + Index + 索引 + + + + + + Auto index internal disk + 自动索引内置磁盘 + + + + + + Index external storage device after connected to computer + 连接电脑后索引外部存储设备 + + + + + + Full-Text search + 全文搜索 + + + + + + Show item counts and sizes in the path of mounted MTP devices + MTP挂载路径下显示文件统计详情 + + + + + + Keep showing the mounted Samba shares + Samba共享端常驻显示挂载入口 + + + + + + Use the file chooser dialog of File Manager + 使用文件管理器的文件选择对话框 + + + + + + Ask for my confirmation when deleting files + 开启普通删除提示 + + + + + + Other + 其他 + + + + + + Hide system disk + 隐藏系统盘 + + + + + + Show file system on disk icon + 在磁盘图标上显示文件系统标签 + + + + + + Show hidden files in search results + 搜索结果显示隐藏文件 + + + + + + Display recent file entry in left panel + 显示最近使用文件 + + + + + + Preview + 预览 + + + + + Compress file preview + 压缩包预览 + + + + + + Text preview + 文本预览 + + + + + + Document preview + 文档预览 + + + + + + Image preview + 图片预览 + + + + + + Video preview + 视频预览 + + + + + + Mount + 挂载 + + + + + + Auto mount + 自动挂载 + + + + + + Open after auto mount + 自动挂载后打开 + + + + + + Dialog + 对话框 + + + + Compressed file preview + 压缩文件预览 + + + + GvfsMountManager + + + Can’t verify the identity of %1. + 无法确认%1的身份。 + + + + This happens when you log in to a computer the first time. + 当您首次登录时会看到这个提示。 + + + + The identity sent by the remote computer is + 远程电脑发送的身份信息为 + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + 若想确认继续操作是否安全,请联系系统管理员。 + + + + + + + + Mounting device error + 挂载设备出错 + + + + + Wrong username or password + 用户名或密码错误 + + + + + + + + Confirm + button + 确 定 + + + + + Cannot find the mounted device + 找不到对应的挂载设备 + + + + No key available to unlock device + 没有密钥解锁设备 + + + + The disk is mounted by user "%1", you cannot unmount it. + 磁盘由用户“%1”挂载,您没有卸载权限。 + + + + Cannot unmount the device + 无法卸载设备 + + + + Cannot eject the device "%1" + 无法弹出设备 "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + 目标磁盘剩余空间不足,无法进行刻录! + + + + MergedDesktopController + + + + Pictures + 图片 + + + + + Music + 音乐 + + + + + Applications + 应用 + + + + + Videos + 视频 + + + + + Documents + 文档 + + + + + Others + 其他 + + + + MimeTypeDisplayManager + + + + Directory + 目录 + + + + + + Application + 应用程序 + + + + + + Video + 视频 + + + + + + Audio + 音频 + + + + + + Image + 图片 + + + + + Archive + 压缩文件 + + + + + + Text + 文档 + + + + + Executable + 可执行程序 + + + + + Backup file + 备份文件 + + + + + Unknown + 未知 + + + + MountAskPasswordDialog + + + Cancel + button + 取 消 + + + + Connect + button + 连 接 + + + + Log in as + 连接身份 + + + + Anonymous + 匿名 + + + + Registered user + 注册用户 + + + + Username + 用户名 + + + + Domain + + + + + Password + 密码 + + + + Remember password + 记住密码 + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + 取 消 + + + + Unlock + button + 解 锁 + + + + Input password to decrypt the disk + 输入密码来解锁此磁盘 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + 您确定要彻底删除%1吗? + + + + This file is too big for the trash + 该文件太大,无法放入回收站 + + + + The files are too big for the trash + 文件太大,无法放入回收站 + + + + Are you sure you want to permanently delete %1 files? + 您确定要彻底删除这%1个文件吗? + + + + Cancel + button + 取 消 + + + + Delete + button + 删 除 + + + + OpenWithDialog + + + Open with + 打开方式 + + + + Add other programs + 添加其他程序 + + + + Set as default + 设为默认 + + + + Cancel + button + 取 消 + + + + Confirm + button + 确 定 + + + + Recommended Applications + 推荐应用 + + + + Other Applications + 其它应用 + + + + PathManager + + + Home + 主目录 + + + + Desktop + 桌面 + + + + Videos + 视频 + + + + Music + 音乐 + + + + Pictures + 图片 + + + + Documents + 文档 + + + + Downloads + 下载 + + + + + Trash + 回收站 + + + + + + System Disk + 系统盘 + + + + Computers in LAN + 网络邻居 + + + + My Shares + 我的共享 + + + + Computer + 计算机 + + + + Recent + 最近使用 + + + + File Vault + 保险箱 + + + + PropertyDialog + + + Basic info + 基本信息 + + + + Open with + 打开方式 + + + + Sharing + 共享管理 + + + + Permissions + 权限管理 + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + 隐藏此文件夹 + + + + Hide this file + 隐藏此文件 + + + + Allow to execute as program + 允许以程序执行 + + + + QObject + + + + + + Size + 大小 + + + + + + Contains + 文件个数 + + + + + + Type + 类型 + + + + + + + + Time modified + 修改时间 + + + + Free space + 可用空间 + + + + Total space + 总容量 + + + + + Time locked + 上锁时间 + + + + Access denied + 不可读不可写 + + + + + Executable + 可执行 + + + + + Write only + 可写不可读 + + + + + Read only + 只读 + + + + + Read-write + 读写 + + + + Others + 其他 + + + + Owner + 所有者 + + + + Unconnected network shared directory + 未连接的网络共享目录 + + + + Device type + 设备类型 + + + + File system + 文件系统 + + + + Group + 群组 + + + + + Open + 打开 + + + + Lock + 立即上锁 + + + + Auto lock + 自动上锁 + + + + Never + 从不 + + + + 5 minutes + 5分钟 + + + + 10 minutes + 10分钟 + + + + 20 minutes + 20分钟 + + + + Delete File Vault + 删除保险箱 + + + + Unlock + 解锁 + + + + Unlock by key + 密钥解锁 + + + + Open + button + 打 开 + + + + + Size: %1 + 大小:%1 + + + + Type: %1 + 类型:%1 + + + + Size: 0 + 大小:0 + + + + Items: %1 + 文件数量:%1 + + + + + + + + + + Open in new window + 在新窗口打开 + + + + + + + + + + Open in new tab + 在新标签中打开 + + + + Open with + 打开方式 + + + + + Compress + 压缩 + + + + Extract + 解压缩 + + + + Extract here + 解压到当前文件夹 + + + + Cut + 剪切 + + + + Copy + 复制 + + + + Paste + 粘贴 + + + + + + + + Rename + 重命名 + + + + + + + Remove + 移除 + + + + Create link + 创建链接 + + + + Send to desktop + 发送到桌面 + + + + Send to + 发送到 + + + + Bluetooth + 蓝牙 + + + + Add to bookmark + 添加书签 + + + + + + + Properties + 属性 + + + + New folder + 新建文件夹 + + + + New window + 新建窗口 + + + + Select all + 全选 + + + + + Clear recent history + 清除最近访问 + + + + + + Empty Trash + 清空回收站 + + + + Display as + 显示方式 + + + + Sort by + 排序方式 + + + + New document + 新建文档 + + + + + Time created + 创建时间 + + + + + + Source path + 原始路径 + + + + Share folder + 共享文件夹 + + + + Cancel sharing + 取消共享 + + + + Connect to Server + 连接到服务器 + + + + Set share password + 设置共享密码 + + + + Format + 格式化 + + + + Tag information + 标记信息 + + + + Open as administrator + 以管理员身份打开 + + + + Select default program + 选择默认程序 + + + + Open file location + 打开文件所在位置 + + + + Remove bookmark + 移除书签 + + + + + + Delete + 删除 + + + + Office Text + 办公文档 + + + + Spreadsheets + 电子表格 + + + + Plain Text + 文本文档 + + + + Open in terminal + 在终端中打开 + + + + Restore + 还原 + + + + Restore all + 全部还原 + + + + Clear saved password and unmount + 取消记住密码并卸载 + + + + File Vault + 保险箱 + + + + Add to disc + 添加至光盘刻录 + + + + Refresh + 刷新 + + + + Auto mount + 自动挂载 + + + + Open after auto mount + 自动挂载后打开 + + + + + Mount + 挂载 + + + + + Unmount + 卸载 + + + + It does not support burning %1 discs + %1格式暂不支持刻录 + + + + Burn + 刻录 + + + + Disc name: + 光盘名称: + + + + + Maximum + 最大速度 + + + + Allow files to be added later + 允许追加数据 + + + + Verify data + 校验数据 + + + + Write speed: + 写入速度: + + + + + + + Cancel + button + 取 消 + + + + Burn + button + 刻 录 + + + + + Eject + 弹出 + + + + Safely Remove + 安全移除 + + + + + Name + 名称 + + + + Settings + 设置 + + + + Exit + 退出 + + + + Icon + 图标视图 + + + + List + 列表视图 + + + + Extend + 扩展视图 + + + + Set as wallpaper + 设置壁纸 + + + + + + + Local disk + 本地磁盘 + + + + + Removable disk + 可移动磁盘 + + + + + + Network shared directory + 网络共享目录 + + + + + Android mobile device + 安卓移动设备 + + + + + Apple mobile device + 苹果移动设备 + + + + + Camera + 相机 + + + + + DVD + 光驱设备 + + + + + Unknown device + 未知设备 + + + + + + %1 item + %1 项 + + + + + + %1 items + %1 项 + + + + Shortcut + 快捷方式 + + + + Create symlink + 创建链接 + + + + Path + 路径 + + + + + + Time deleted + 删除时间 + + + + Loading... + 正在加载... + + + + File has been moved or deleted + 文件已被移动或删除 + + + + You do not have permission to traverse files in it + 您没有权限遍历子文件 + + + + + + You do not have permission to access this folder + 您没有权限访问该文件夹 + + + + + + + + Folder is empty + 文件夹为空 + + + + Searching... + 正在搜索... + + + + No results + 无搜索结果 + + + + Source Path + TrashFileInfo + 原始路径 + + + + Document + 新建Word文档 + + + + Spreadsheet + 新建Excel文档 + + + + + Presentation + 演示文档 + + + + Text + 新建文本 + + + + 1 task in progress + 有1个任务正在进行 + + + + %1 tasks in progress + 有%1个任务正在进行 + + + + Mode: + 方式: + + + + + Replace Text + 替换文本 + + + + + Add Text + 添加文本 + + + + + Custom Text + 自定义文本 + + + + Find: + 查找: + + + + Replace: + 替换: + + + + + Optional + 选填 + + + + Add: + 添加: + + + + Location: + 位置: + + + + File name: + 文件名: + + + + Start at: + +序列: + + + + + Rename + button + 重命名 + + + + + + + + + + + Required + 必填 + + + + + Before file name + 名称之前 + + + + + After file name + 名称之后 + + + + Find + 查找 + + + + Replace + 替换 + + + + Add + 添加 + + + + Start at + +序列 + + + + + + Location + 位置 + + + + File name + 文件名 + + + + Dimension + 尺寸 + + + + Duration + 时长 + + + + Tips: Sort by selected file order + 提示:根据选择文件的顺序先后排序 + + + + Rename %1 Files + 给%1个文件重命名 + + + + Multiple Files + 多个文件 + + + + Basic info + 基本信息 + + + + Total size + 总大小 + + + + Number of files + 文件数量 + + + + %1 file(s), %2 folder(s) + %1个文件,%2个文件夹 + + + + + + Time accessed + 访问时间 + + + + Orange + 橙色 + + + + Red + 红色 + + + + Purple + 紫色 + + + + Navy-blue + 海蓝 + + + + Azure + 天蓝 + + + + Green + 绿色 + + + + Yellow + 黄色 + + + + Gray + 灰色 + + + + Input tag info, such as work, family. A comma is used between two tags. + 输入标记信息,如“工作”、“家人”等。多个标记信息之间用逗号分隔。 + + + + Bookmarks + 书签 + + + + Erase + 擦除 + + + + Copy path + 复制路径 + + + + Edit address + 编辑地址 + + + + Free Space %1 + 可用空间 %1 + + + + Files are being processed + 正在处理文件 + + + + + Unknown + 未知 + + + + My Vault + 我的保险箱 + + + + + Failed to create file info + 文件信息创建失败 + + + + Failed to create file handler + 文件处理程序创建失败 + + + + Failed to open the file, cause: %1 + 文件打开失败,原因:%1 + + + + Original file does not exist + 源文件不存在 + + + + Do you want to delete %1? + 是否删除 %1? + + + + Confirm + button + 确 定 + + + + + + + + %1 are not allowed + 不得含有%1 + + + + + Failed to start Samba services + Samba服务启动失败 + + + + RecentController + + + Cancel + button + 取 消 + + + + Remove + button + 移 除 + + + + Do you want to remove this item? + 您确定要移除选中的此项内容? + + + + Do yout want to remove %1 items? + 您确定要移除选中的%1项内容? + + + + It does not delete the original files + 此操作不会删除源文件 + + + + ShareInfoFrame + + + Share this folder + 共享此文件夹 + + + + Share name: + 共享名: + + + + Permission: + 权限: + + + + Read and write + 可读写 + + + + Read only + 只读 + + + + Anonymous: + 匿名访问: + + + + Not allow + 不允许 + + + + Allow + 允许 + + + + The share name must not be two dots (..) or one dot (.) + ..和.禁止作为共享名使用 + + + + The share name is used by another user. + 该共享名已被其他用户使用 + + + + OK + button + 确 定 + + + + Cancel + button + 取 消 + + + + Replace + button + 替 换 + + + + The share name already exists. Do you want to replace the shared folder? + 该共享名已存在。是否替换原有共享文件夹? + + + + Shortcut + + + Item + 文件 + + + + Select to the first item + 选择到第一个文件 + + + + Shift + Home + Shift + Home + + + + Select to the last item + 选择到最后一个文件 + + + + Shift + End + Shift + End + + + + Select leftwards + 向前选择 + + + + Shift + Left + Shift + Left + + + + Select rightwards + 向后选择 + + + + Shift + Right + Shift + Right + + + + Select to upper row + 向上一行选择 + + + + Shift + Up + Shift + Up + + + + Select to lower row + 向下一行选择 + + + + Shift + Down + Shift + Down + + + + Open + 打开文件 + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + 返回上一级 + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + 彻底删除 + + + + Shift + Delete + Shift + Delete + + + + Delete file + 删除文件 + + + + Delete + Delete + + + + Select all + 全选文件 + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + 拷贝文件 + + + + Cut + 剪切文件 + + + + Paste + 粘贴文件 + + + + Rename + 重命名 + + + + F2 + F2 + + + + New/Search + 新建/搜索 + + + + New window + 新建窗口 + + + + New folder + 新建文件夹 + + + + + Search + 搜索 + + + + New tab + 新建标签 + + + + View + 查看 + + + + Item information + 文件信息 + + + + Help + 帮助手册 + + + + F1 + F1 + + + + Keyboard shortcuts + 所有快捷键 + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + 切换显示状态 + + + + Hide item + 隐藏文件 + + + + Input in address bar + 地址栏输入 + + + + Switch to icon view + 切换到图标视图 + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + 切换到列表视图 + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + 其他 + + + + Close + 关闭 + + + + Alt + F4 + Alt + F4 + + + + Close current tab + 关闭当前标签 + + + + Back + 后退 + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + 切换到下一个标签 + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + 切换到上一个标签 + + + + Next file + 下一个文件 + + + + Tab + Tab + + + + Previous file + 上一个文件 + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + 在1-8之间切换标签到指定序号 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + 前进 + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + 无法打开回收站中的项目,请先还原 + + + + TrashPropertyDialog + + + Trash + 回收站 + + + + item + 项目 + + + + items + 项目 + + + + Contains %1 %2 + 包含%1个%2 + + + + UDiskListener + + + Failed to rename the label + 重命名卷标失败 + + + + UnmountWorker + + + + + The device was not safely unmounted + 设备没有正常卸载 + + + + The device was not safely removed + 设备没有正常移除 + + + + UserShareManager + + + Kindly Reminder + 温馨提示 + + + + Please firstly install samba to continue + 请您先安装samba后,再进行共享相关操作! + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + 共享名不得包含%<>*?|/\+=;:,",且不能以%1开头 + + + + To protect the files, you cannot share this folder. + 为了文件安全,无法共享此文件夹。 + + + + Sharing failed + 共享失败 + + + + The computer name is too long + 计算机名过长 + + + + You do not have permission to operate file/folder! + 您没有权限操作文件/文件夹! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + 请输入共享密码 + + + + Cancel + button + 取 消 + + + + Confirm + button + 确 定 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_zh_HK.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_zh_HK.ts new file mode 100644 index 0000000..e59d6a9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_zh_HK.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + 新建文件夾 + + + + Mounting device error + 掛載設備出錯 + + + + The disc image was corrupted, cannot mount now, please erase the disc first + 此光盤中的鏡像已損壞,無法掛載,請擦除後使用 + + + + Mount error: unsupported image format + 掛載錯誤,鏡像文件格式不支持 + + + + + The device was not safely removed + 設備沒有正常移除 + + + + + Click "Safely Remove" and then disconnect it next time + 請點擊“安全移除”後,再斷開連接 + + + + The device was not ejected + 設備未彈出 + + + + Disk is busy, cannot eject now + 磁盤文件被佔用,無法彈出 + + + + Authentication timed out + 認證超時 + + + + BluetoothTransDialog + + + Bluetooth File Transfer + 藍牙檔案傳輸 + + + + File Transfer Successful + 檔案傳送成功 + + + + File Transfer Failed + 檔案傳送失敗 + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + 正在向“<b style="font-weight: 550;">%1</b>”傳送文件 + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + 向“<b style="font-weight: 550;">%1</b>”傳送文件失敗 + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + 向“<b style="font-weight: 550;">%1</b>”傳送文件成功 + + + + Select a Bluetooth device to receive files + 選擇接收此文件的藍牙設備 + + + + Cannot find the connected Bluetooth device + 未找到已連接的藍牙設備 + + + + Waiting to be received... + 等待接收,請稍候... + + + + Go to Bluetooth Settings + 轉到藍牙設定 + + + + %1/%2 Sent + 已傳送 %1/%2 + + + + Error: the Bluetooth device is disconnected + 原因:藍牙設備連接中斷 + + + + Unable to send the file more than 2 GB + 無法發送超過2GB的文件 + + + + Unable to send 0 KB files + 無法發送0KB的文件 + + + + File doesn't exist + 文件不存在 + + + + Next + button + 下一步 + + + + Cancel + button + 取 消 + + + + Done + button + 完 成 + + + + Retry + button + 重 試 + + + + OK + button + 確 定 + + + + File sending request timed out + 文件發送超時 + + + + The service is busy and unable to process the request + 設備超時,無法處理該請求 + + + + BurnOptDialog + + + Device error + 設備故障 + + + + Optical device %1 doesn't exist + 光驅%1不存在 + + + + Advanced settings + 高級設置 + + + + File system: + 文件系統: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (可用於Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (可用於Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1格式(兼容Windows的CD/DVD刻錄模式) + + + + ISO9660 Only + 僅ISO9660 + + + + CloseAllDialogIndicator + + + Close all + 關閉全部 + + + + Total size: %1, %2 files + 總容量 %1,總文件數量 %2個 + + + + ComputerModel + + + Double click to open it + 雙擊打開應用程序 + + + + My Directories + 我的目錄 + + + + Disks + 磁盤 + + + + File Vault + 保險箱 + + + + Quick Access + 快速訪問 + + + + ComputerPropertyDialog + + + Computer + 計算機 + + + + Basic Info + 基本訊息 + + + + + Computer Name + 計算機名 + + + + + Edition + 版本 + + + + + + Version + 版本號 + + + + + Type + 類型 + + + + + + Processor + 處理器 + + + + + + Memory + 內存 + + + + + + + Bit + + + + + + Available + 可用 + + + + Obtaining... + 正在獲取中... + + + + ConnectToServerDialog + + + Connect to Server + 連接到伺服器 + + + + Cancel + button + 取 消 + + + + Connect + button + 連 接 + + + + My Favorites: + 個人收藏伺服器 + + + + + Clear History + 清除最近使用的伺服器 + + + + DFMAddressBar + + + Search or enter address + 搜索或輸入地址 + + + + DFMAdvanceSearchBar + + + Search: + 搜索範圍: + + + + File Type: + 文件類型: + + + + File Size: + 文件大小: + + + + Time Modified: + 修改時間: + + + + Time Accessed: + 訪問時間: + + + + Time Created: + 創建時間: + + + + Reset + 重置 + + + + All subdirectories + 所有子文件夾 + + + + Current directory + 當前文件夾 + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + 今天 + + + + Yesterday + 昨天 + + + + This week + 本週 + + + + Last week + 上週 + + + + This month + 本月 + + + + Last month + 上月 + + + + This year + 今年 + + + + Last year + 去年 + + + + DFMOpticalMediaWidget + + + + No files to burn + 沒有文件需要刻錄 + + + + Unable to burn. Not enough free space on the target disk. + 目標磁盤剩餘空間不足,無法進行刻錄! + + + + %1 burning is not supported + 當前光盤介質不支持%1刻錄 + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. 介質類型不是%1; +2. 當前光盤文件系統版本暫不支持追加刻錄。 + + + + DFMTagCrumbController + + + Tag information + 標記訊息 + + + + DFMTagWidget + + + Tag + 標記 + + + + DFMTaskWidget + + + Do not ask again + 不再詢問 + + + + Syncing data + 數據同步中 + + + + Please wait + 請稍候 + + + + + Time modified: %1 + 修改時間:%1 + + + + + Contains: %1 + 個數:%1 + + + + + Size: %1 + 大小:%1 + + + + Original folder + 原始文件夹 + + + + Keep both + button + 共 存 + + + + Skip + button + 跳 過 + + + + Replace + button + 替 換 + + + + Retry + button + 重 試 + + + + Original file + 原始文件 + + + + Target folder + 目標文件夾 + + + + Target file + 目標文件 + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + 加密保險箱 + + + + Click 'Encrypt' and input the user password. + 點擊“加密保險箱”後,輸入用戶密碼完成設置。 + + + + Encrypting... + 正在加密... + + + + + + + Encrypt + 加密保險箱 + + + + Failed to create file vault: %1 + 創建保險箱失敗:%1 + + + + OK + 確 定 + + + + The setup is complete + 加密已完成 + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + 保存密鑰文件 + + + + Keep the key safe to retrieve the vault password later + 密鑰文件可用來找回您設置的保險箱密碼,請妥善保管 + + + + Save to default path + 保存至默認路徑 + + + + Save to other locations + 保存至其他路徑 + + + + No permission, please reselect + 權限不夠,請重新選擇 + + + + Select a path + 選擇密鑰文件保存路徑 + + + + Next + 下一步 + + + + The default path is invisible to other users, and the path information will not be shown. + 默認路徑為不會暴露給其他用戶的特殊路徑,且不會明文顯示路徑訊息。 + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + 文件保險箱恢復密鑰 + + + + Generate a recovery key in case that you forgot the password + 如果忘記密碼,可以使用該密鑰恢復訪問 + + + + Key + 密鑰 + + + + QR code + 二維碼 + + + + Scan QR code and save the key to another device + 掃描二維碼,保存至其他設備 + + + + Next + 下一步 + + + + Recovery Key: + 文件保險箱恢復密鑰: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + 設置解鎖方式 + + + + Method + 類型 + + + + Manual + 手動 + + + + Password + 密碼 + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + 至少8位,包含A-Z, a-z, 0-9和符號 + + + + Repeat password + 重複密碼 + + + + Input the password again + 再次輸入密碼 + + + + Password hint + 密碼提示 + + + + Optional + 選填 + + + + Next + 下一步 + + + + + Passwords do not match + 密碼不符 + + + + DFMVaultActiveStartView + + + File Vault + 保險箱 + + + + Create your secure private space + 專屬於個人的安全空間 + + + + Advanced encryption technology + 先進的加密技術,私隱安全有保障 + + + + Convenient and easy to use + 使用更便捷,操作更簡單 + + + + Create + 建立 + + + + DFMVaultFileView + + + Cannot open this path + 無法打開當前路徑 + + + + Hint + 提示 + + + + OK + 確 定 + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + 恢復密鑰解鎖 + + + + Failed to unlock file vault + 解鎖保險箱失敗 + + + + OK + 確 定 + + + + Input the 32-digit recovery key + 請輸入32位恢復密鑰 + + + + Cancel + button + 取 消 + + + + Unlock + button + 解 鎖 + + + + Wrong recovery key + 密鑰錯誤 + + + + DFMVaultRemoveByPasswordView + + + Password + 密碼 + + + + Password hint: %1 + 密碼提示:%1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + 請輸入32位恢復密鑰 + + + + DFMVaultRemovePages + + + Delete File Vault + 刪除保險箱 + + + + Once deleted, the files in it will be permanently deleted + 刪除保險箱後,其中的所有內容將會被永久刪除 + + + + Use Key + 密鑰驗證 + + + + Cancel + button + 取 消 + + + + Use Key + button + 密鑰驗證 + + + + Delete + button + 刪 除 + + + + + OK + button + 確 定 + + + + Use Password + 使用密碼 + + + + Wrong password + 密碼錯誤 + + + + Wrong recovery key + 密鑰錯誤 + + + + Failed to delete file vault + 刪除保險箱失敗 + + + + Deleted successfully + 刪除成功 + + + + Failed to delete + 刪除失敗 + + + + Removing... + 正在刪除... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + 無法獲取密鑰文件 + + + + Verification failed + 密鑰驗證失敗 + + + + + Select a path + 選擇密鑰文件保存路徑 + + + + + Retrieve Password + 密碼找回 + + + + By key in the default path + 通過默認路徑密鑰文件找回密碼 + + + + By key in the specified path + 通過指定路徑密鑰文件找回密碼 + + + + Verification Successful + 密鑰驗證成功 + + + + Keep it safe + 請妥善保管 + + + + Back + button + 返 回 + + + + Verify Key + button + 驗證密鑰 + + + + Go to Unlock + button + 返回解鎖 + + + + Close + button + 關 閉 + + + + Vault password: %1 + 保險箱密碼為:%1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + 解鎖保險箱 + + + + Forgot password? + 忘記密碼? + + + + Password hint: %1 + 密碼提示:%1 + + + + Failed to unlock file vault + 解鎖保險箱失敗 + + + + Cancel + button + 取 消 + + + + Password + 密碼 + + + + Unlock + button + 解 鎖 + + + + Please try again %1 minutes later + 請%1分鐘後再試 + + + + Wrong password, please try again %1 minutes later + 密碼錯誤,請%1分鐘後再試 + + + + Wrong password, one chance left + 密碼錯誤,您還可再輸入1次 + + + + Wrong password, %1 chances left + 密碼錯誤,您還可再輸入%1次 + + + + Wrong password + 密碼錯誤 + + + + OK + button + 確 定 + + + + DFileCopyMoveJob + + + Permission error + 文件權限錯誤 + + + + The action is denied + 文件不支持此操作 + + + + Failed to open the file + 文件打開失敗 + + + + Failed to read the file + 文件內容讀取失敗 + + + + Failed to write the file + 文件內容寫入失敗 + + + + Failed to create the directory + 目錄創建失敗 + + + + Failed to delete the file + 文件刪除失敗 + + + + Failed to move the file + 文件移動失敗 + + + + Original file does not exist + 源文件不存在 + + + + Failed, file size must be less than 4GB + 操作失敗,文件大小已超出上限值4GB! + + + + Not enough free space on the target disk + 目標磁盤剩餘空間不足 + + + + File integrity was damaged + 文件完整性檢查失敗 + + + + The target device is read only + 目標設備為只讀 + + + + Target folder is inside the source folder + 目標文件夾位於源文件夾內 + + + + The action is not supported + 不支持該操作 + + + + You do not have permission to traverse files in it + 您沒有權限遍歷子文件 + + + + Failed to position the file pointer! + 指針定位失敗! + + + + copy + Extra name added to new file name when used for file name. + 副本 + + + + Failed to open the directory, cause: file name too long + 目錄打開失敗,原因:文件名過長 + + + + + Failed to open the file, cause: file name too long + 文件打開失敗,原因:文件名過長 + + + + + Failed to write the file, cause: + 文件內容寫入失敗,原因: + + + + Failed to position the file pointer, cause: %1 + 指針定位失敗,原因:%1 + + + + Syncing data + 數據同步中 + + + + Please wait + 請稍候 + + + + Failed to create the directory, cause: %1 + 目錄創建失敗,原因:%1 + + + + + + + + Failed to open the file, cause: %1 + 文件打開失敗,原因:%1 + + + + + + + Failed to open the file, cause: Permission denied + 文件打開失敗,原因:權限不足 + + + + + Failed to read the file, cause: %1 + 文件內容讀取失敗,原因:%1 + + + + + + + Failed to write the file, cause: %1 + 文件內容寫入失敗,原因:%1 + + + + + File integrity was damaged, cause: %1 + 文件完整性檢查失敗,原因:%1 + + + + Failed to open the file, cause: + 文件打開失敗,原因: + + + + Failed to read the file, cause: + 文件內容讀取失敗,原因: + + + + Failed to delete the file, cause: %1 + 文件刪除失敗,原因:%1 + + + + Fail to create symlink, cause: %1 + 創建鏈接失敗,原因:%1 + + + + DFileDialog + + + + Save + button + 保 存 + + + + + Cancel + button + 取 消 + + + + Confirm + button + 確 定 + + + + %1 already exists, do you want to replace it? + “%1”已存在,您是否要替換? + + + + Replace + button + 替 換 + + + + Open + button + 打 開 + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + 文件名以“.”開始將會隱藏此文件,請確認是否繼續? + + + + DFileManagerWindow + + + Trash + 回收站 + + + + Empty + 清空 + + + + DFileSystemModel + + + + Name + 名稱 + + + + + + Time modified + 修改時間 + + + + Size + 大小 + + + + Type + 類型 + + + + Time created + 創建時間 + + + + + Last access + 最近訪問時間 + + + + + + + Path + 路徑 + + + + DFileView + + + Disc mount error + 光盤掛載錯誤 + + + + The disc is in use, please end the running process and remount the disc. + 當前光驅設備正在佔用,請關閉佔用進程再重新掛載 + + + + Mounting failed + 掛載失敗 + + + + (Reverse) + (反序) + + + + DFileViewHelper + + + Add tag "%1" + 添加標記“%1” + + + + DStatusBar + + + %1 item + %1 項 + + + + %1 items + %1 項 + + + + %1 item selected + 選中 %1 項內容 + + + + %1 items selected + 選中 %1 項內容 + + + + %1 folder selected (contains %2) + 選中%1個文件夾(包含%2) + + + + %1 folders selected (contains %2) + 選中%1個文件夾(包含%2) + + + + %1 file selected (%2) + 選中%1個文件(%2) + + + + %1 files selected (%2) + 選中%1個文件(%2) + + + + %1 folder selected + 選中%1個文件夾 + + + + Filter + 過濾 + + + + Save as: + 保存為: + + + + Loading... + 正在加載...... + + + + DTaskDialog + + + Erasing disc %1, please wait... + 正在擦除%1,請稍候... + + + + Burning disc %1, please wait... + 正在刻錄到%1,請稍候... + + + + Writing data... + 正在寫入數據... + + + + Verifying data... + 正在校驗數據... + + + + Copying %1 + 正在複製%1 + + + + + + to %2 + 到%2 + + + + %1 already exists in target folder + 目標文件夾中已存在名為%1的文件 + + + + Original path %1 Target path %2 + 原路徑%1 目標路徑%2 + + + + Merge + button + 合 併 + + + + Replace + button + 替 換 + + + + Moving %1 + 正在移動%1 + + + + Removing file vault, please try later + 正在刪除保險箱,請稍候... + + + + Restoring %1 + 正在恢復%1 + + + + Deleting %1 + 正在刪除%1 + + + + Trashing %1 + 正在移動 %1 + + + + Calculating space, please wait + 正在計算大小,請稍候 + + + + DUMountManager + + + + Authentication timed out + 認證超時 + + + + + + Disk is busy, cannot unmount now + 磁盤文件被佔用,無法卸載 + + + + Disk is busy, cannot eject now + 磁盤文件被佔用,無法彈出 + + + + The device is busy, cannot eject now + 光驅正忙,無法彈出 + + + + + + The device is busy, cannot remove now + 設備正忙,無法安全移除 + + + + DeepinStorage + + + + + %1 Volume + %1 卷 + + + + Data Disk + Data Partition + 數據盤 + + + + %1 Drive + %1 驅動器 + + + + Blank %1 Disc + 空白%1光盤 + + + + %1 Encrypted + %1 已加密 + + + + DialogManager + + + + + + Operation failed! + 操作失敗! + + + + Target folder is inside the source folder! + 目標文件夾位於源文件夾內! + + + + Do you want to run %1 or display its content? + 您是要運行 “%1”,還是顯示它的內容? + + + + It is an executable text file. + 它是可執行的文本文件。 + + + + It is an executable file. + 它是一個可執行文件。 + + + + This file is not executable, do you want to add the execute permission and run? + 此文件沒有可執行權限,是否添加權限並運行? + + + + "%1" already exists, please use another name. + 文件名 "%1" 已被佔用,請使用其他名稱。 + + + + The file name must not contain two dots (..) + 文件名不得含有兩個點(..) + + + + Device or resource busy + 設備或資源繁忙 + + + + Are you sure you want to erase all data on the disc? + 您確定要擦除此光盤的所有內容嗎? + + + + How do you want to use this disc? + 您希望使用此光盤刻錄鏡像或者是存儲文件? + + + + Disc erase failed + 擦除失敗 + + + + Burn process failed + 刻錄失敗 + + + + %1: %2 + %1:%2 + + + + Show details + 顯示詳情 + + + + Hide details + 隱藏詳情 + + + + Error + 錯誤訊息 + + + + Permanently delete %1? + 您確定要徹底刪除 %1? + + + + Permanently delete %1 items? + 您確定要徹底刪除選中的%1項內容? + + + + Empty + 清空 + + + + Do you want to delete %1? + 是否刪除 %1? + + + + Do you want to delete the selected %1 items? + 是否刪除選中的%1項內容? + + + + Sorry, unable to locate your bookmark directory, remove it? + 抱歉, 找不到您的書籤目錄, 是否移除? + + + + Name: + 名稱: + + + + %1 that this shortcut refers to has been changed or moved + 此快捷方式所指向的“%1”已被更改或移動 + + + + Do you want to delete this shortcut? + 是否刪除此快捷方式? + + + + Failed, file size must be less than 4GB. + 操作失敗,文件大小已超出上限值4GB! + + + + Fail to create symlink, cause: + 創建鏈接失敗,原因: + + + + The selected files contain system file/directory, and it cannot be deleted + 選擇的文件中包含系統目錄,不能被刪除 + + + + Unable to find the original file + 無法找到鏈接目標文件 + + + + + You do not have permission to operate file/folder! + 您沒有權限操作文件/文件夾! + + + + Failed to restore %1 file, the source file does not exist + 原文件不存在,%1個文件恢復失敗 + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + 抱歉,您沒有權限操作以下%1個文件/文件夾 + + + + Unable to access %1 + 訪問%1失敗 + + + + + Sending files now, please try later + 當前已有發送中的文件,請稍後再試 + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + 需要格式化磁盤才能訪問此設備,是否繼續? + + + + Scanning the device, stop it? + 正在掃描當前設備,是否終止掃描? + + + + Share folder can't be named after the current username + 共享文件夾不能和當前用戶名重名 + + + + Do you want to run %1? + 您是否要運行“%1”? + + + + Burn image + button + 刻錄鏡像 + + + + Burn files + button + 存儲文件 + + + + Are you sure you want to empty %1 item? + 您確定要清空回收站裏的 %1 項內容嗎? + + + + Are you sure you want to empty %1 items? + 您確定要清空回收站裏的 %1 項內容嗎? + + + + + This action cannot be undone + 此操作不可以恢復 + + + + + + + + + + + + + + OK + button + 確 定 + + + + + + + + + + + + + + + Cancel + button + 取 消 + + + + + + Run + button + 運 行 + + + + + Run in terminal + button + 在終端中運行 + + + + Display + button + 顯 示 + + + + + + + + + + + Confirm + button + 確 定 + + + + Erase + button + 擦 除 + + + + Data verification failed + 數據校驗失敗 + + + + Show details + button + 顯示詳情 + + + + + Delete + button + 刪 除 + + + + Remove + button + 刪 除 + + + + Disk is busy, cannot unmount now + 磁盤文件被佔用,無法卸載 + + + + Force unmount + button + 強制卸載 + + + + Unable to copy. Not enough free space on the target disk. + 目標磁盤剩餘空間不足,無法進行複製! + + + + Failed to restore %1 file, the target folder is read-only + %1個文件還原失敗,目標文件夾不可寫 + + + + Failed to restore %1 files, the target folder is read-only + %1個文件還原失敗,目標文件夾不可寫 + + + + Failed to restore %1 files, the source files do not exist + 原文件不存在,%1個文件恢復失敗 + + + + Format + button + 格式化 + + + + Stop + button + 終 止 + + + + FileController + + + + + + Unable to find the original file + 無法找到鏈接目標文件 + + + + + + Kindly Reminder + 溫馨提示 + + + + + + Please install File Roller first and then continue + 請先安裝歸檔管理器然後繼續 + + + + + Unable to create files here: %1 + 不能在此創建文件:%1 + + + + Confirm + button + 確 定 + + + + FileDialogStatusBar + + + File Name + 文件名 + + + + Format + 格式 + + + + Save + button + 保 存 + + + + Open + button + 打 開 + + + + Save File + button + 保存文件 + + + + Open File + button + 打開文件 + + + + + + Cancel + button + 取 消 + + + + FileJob + + + copy + 副本 + + + + + + + Data verification successful. + 數據驗證成功。 + + + + + + Burn process completed + 刻錄完成 + + + + %1 s + %1 秒 + + + + %1 m %2 s + %1 分 %2 秒 + + + + %1 h %2 m %3 s + %1 時 %2 分 %3 秒 + + + + %1 d %2 h %3 m %4 s + %1 天 %2 時 %3 分 %4 秒 + + + + %1 is a duplicate file. + %1為重複文件。 + + + + Insufficient disc space. + 光盤空間不足。 + + + + Lost connection to drive. + 與光驅的連接斷開。 + + + + The CD/DVD drive is not ready. Try another disc. + 光驅未準備好,您可以換一張光盤再試。 + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + 光驅被佔用,您可以嘗試關掉正在使用光驅的程序後重新插入光驅。 + + + + Unknown error + 未知錯誤 + + + + Device disconnected + 光驅設備未連接 + + + + GenerateSettingTranslate + + + + + Basic + 基礎設置 + + + + + + Open behavior + 打開行為 + + + + + + Always open folder in new window + 總是在新窗口打開文件夾 + + + + + + Open file: + 打開文件: + + + + + + Click + 單擊 + + + + + + Double click + 雙擊 + + + + + + New window and tab + 新窗口和新標籤 + + + + + + Open from default window: + 從默認窗口打開: + + + + + + + + + Computer + 計算機 + + + + + + + + + Home + 主目錄 + + + + + + + + + Desktop + 桌面 + + + + + + + + + Videos + 影片 + + + + + + + + + Music + 音樂 + + + + + + + + + Pictures + 圖片 + + + + + + + + + Documents + 文檔 + + + + + + + + + Downloads + 下載 + + + + + + Open in new tab: + 從新標籤打開: + + + + + + Current Directory + 當前目錄 + + + + + + View + 視圖 + + + + + + Default size: + 默認大小: + + + + + + Extra small + 特小 + + + + + + Small + + + + + + + Medium + + + + + + + Large + + + + + + + Extra large + 特大 + + + + + + Default view: + 默認視圖: + + + + + + Icon + 圖標視圖 + + + + + + List + 列表視圖 + + + + + + Hidden files + 隱藏文件 + + + + + + Show hidden files + 顯示隱藏文件 + + + + + + Hide file extension when rename + 重命名時隱藏文件擴展名 + + + + + + Advanced + 高級設置 + + + + + + Index + 索引 + + + + + + Auto index internal disk + 自動索引內置磁盤 + + + + + + Index external storage device after connected to computer + 連接電腦後索引外部存儲設備 + + + + + + Full-Text search + 全文搜索 + + + + + + Show item counts and sizes in the path of mounted MTP devices + MTP掛載路徑下顯示文件統計詳情 + + + + + + Keep showing the mounted Samba shares + Samba共享端常駐顯示掛載入口 + + + + + + Use the file chooser dialog of File Manager + 使用檔案管理員的文件選擇對話框 + + + + + + Ask for my confirmation when deleting files + 開啟普通刪除提示 + + + + + + Other + 其他 + + + + + + Hide system disk + 隱藏系統盤 + + + + + + Show file system on disk icon + 在磁盤圖標上顯示文件系統標籤 + + + + + + Show hidden files in search results + 搜索結果顯示隱藏文件 + + + + + + Display recent file entry in left panel + 顯示最近使用文件 + + + + + + Preview + 預覽 + + + + + Compress file preview + 壓縮包預覽 + + + + + + Text preview + 文本預覽 + + + + + + Document preview + 文檔預覽 + + + + + + Image preview + 圖片預覽 + + + + + + Video preview + 影片預覽 + + + + + + Mount + 掛載 + + + + + + Auto mount + 自動掛載 + + + + + + Open after auto mount + 自動掛載後打開 + + + + + + Dialog + 對話框 + + + + Compressed file preview + 壓縮文件預覽 + + + + GvfsMountManager + + + Can’t verify the identity of %1. + 無法確認%1的身份。 + + + + This happens when you log in to a computer the first time. + 當您首次登錄時會看到這個提示。 + + + + The identity sent by the remote computer is + 遠程電腦發送的身份訊息為 + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + 若想確認繼續操作是否安全,請聯繫系統管理員。 + + + + + + + + Mounting device error + 掛載設備出錯 + + + + + Wrong username or password + 用戶名或密碼錯誤 + + + + + + + + Confirm + button + 確 定 + + + + + Cannot find the mounted device + 找不到對應的掛載設備 + + + + No key available to unlock device + 沒有金鑰解鎖設備 + + + + The disk is mounted by user "%1", you cannot unmount it. + 磁盤由用戶“%1”掛載,您沒有卸載權限。 + + + + Cannot unmount the device + 無法卸載設備 + + + + Cannot eject the device "%1" + 無法彈出設備 "%1" + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + 目標磁盤剩餘空間不足,無法進行刻錄! + + + + MergedDesktopController + + + + Pictures + 圖片 + + + + + Music + 音樂 + + + + + Applications + 應用 + + + + + Videos + 影片 + + + + + Documents + 文檔 + + + + + Others + 其他 + + + + MimeTypeDisplayManager + + + + Directory + 目錄 + + + + + + Application + 應用程序 + + + + + + Video + 影片 + + + + + + Audio + 音頻 + + + + + + Image + 圖片 + + + + + Archive + 壓縮文件 + + + + + + Text + 文檔 + + + + + Executable + 可進程 + + + + + Backup file + 備份文件 + + + + + Unknown + 未知 + + + + MountAskPasswordDialog + + + Cancel + button + 取 消 + + + + Connect + button + 連 接 + + + + Log in as + 連接身份 + + + + Anonymous + 匿名 + + + + Registered user + 註冊用戶 + + + + Username + 用戶名 + + + + Domain + + + + + Password + 密碼 + + + + Remember password + 記住密碼 + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + 取 消 + + + + Unlock + button + 解 鎖 + + + + Input password to decrypt the disk + 輸入密碼來解鎖此磁盤 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + 您確定要徹底刪除%1嗎? + + + + This file is too big for the trash + 該文件太大,無法放入回收站 + + + + The files are too big for the trash + 文件太大,無法放入回收站 + + + + Are you sure you want to permanently delete %1 files? + 您確定要徹底刪除這%1個文件嗎? + + + + Cancel + button + 取 消 + + + + Delete + button + 刪 除 + + + + OpenWithDialog + + + Open with + 打開方式 + + + + Add other programs + 添加其他程序 + + + + Set as default + 設為默認 + + + + Cancel + button + 取 消 + + + + Confirm + button + 確 定 + + + + Recommended Applications + 推薦應用 + + + + Other Applications + 其他應用 + + + + PathManager + + + Home + 主目錄 + + + + Desktop + 桌面 + + + + Videos + 影片 + + + + Music + 音樂 + + + + Pictures + 圖片 + + + + Documents + 文檔 + + + + Downloads + 下載 + + + + + Trash + 回收站 + + + + + + System Disk + 系統盤 + + + + Computers in LAN + 網絡鄰居 + + + + My Shares + 我的共享 + + + + Computer + 計算機 + + + + Recent + 最近使用 + + + + File Vault + 保險箱 + + + + PropertyDialog + + + Basic info + 基本訊息 + + + + Open with + 打開方式 + + + + Sharing + 共享管理 + + + + Permissions + 權限管理 + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + 隱藏此文件夾 + + + + Hide this file + 隱藏此文件 + + + + Allow to execute as program + 允許以程序執行 + + + + QObject + + + + + + Size + 大小 + + + + + + Contains + 文件個數 + + + + + + Type + 類型 + + + + + + + + Time modified + 修改時間 + + + + Free space + 可用空間 + + + + Total space + 總容量 + + + + + Time locked + 上鎖時間 + + + + Access denied + 不可讀不可寫 + + + + + Executable + 可進程 + + + + + Write only + 可寫不可讀 + + + + + Read only + 只讀 + + + + + Read-write + 讀寫 + + + + Others + 其他 + + + + Owner + 所有者 + + + + Unconnected network shared directory + 未連接的網絡共享目錄 + + + + Device type + 設備類型 + + + + File system + 文件系統 + + + + Group + 群組 + + + + + Open + 打開 + + + + Lock + 立即上鎖 + + + + Auto lock + 自動上鎖 + + + + Never + 從不 + + + + 5 minutes + 5分鐘 + + + + 10 minutes + 10分鐘 + + + + 20 minutes + 20分鐘 + + + + Delete File Vault + 刪除保險箱 + + + + Unlock + 解鎖 + + + + Unlock by key + 密鑰解鎖 + + + + Open + button + 打 開 + + + + + Size: %1 + 大小:%1 + + + + Type: %1 + 類型:%1 + + + + Size: 0 + 大小:0 + + + + Items: %1 + 文件數量:%1 + + + + + + + + + + Open in new window + 在新窗口打開 + + + + + + + + + + Open in new tab + 在新標籤中打開 + + + + Open with + 打開方式 + + + + + Compress + 壓縮 + + + + Extract + 解壓縮 + + + + Extract here + 解壓到當前文件夾 + + + + Cut + 剪切 + + + + Copy + 複製 + + + + Paste + 黏貼 + + + + + + + + Rename + 重命名 + + + + + + + Remove + 移除 + + + + Create link + 創建鏈接 + + + + Send to desktop + 發送到桌面 + + + + Send to + 發送到 + + + + Bluetooth + 藍牙 + + + + Add to bookmark + 添加書籤 + + + + + + + Properties + 屬性 + + + + New folder + 新建文件夾 + + + + New window + 新建窗口 + + + + Select all + 全選 + + + + + Clear recent history + 清除最近訪問 + + + + + + Empty Trash + 清空回收站 + + + + Display as + 顯示方式 + + + + Sort by + 排序方式 + + + + New document + 新建文檔 + + + + + Time created + 創建時間 + + + + + + Source path + 原始路徑 + + + + Share folder + 共享文件夾 + + + + Cancel sharing + 取消共享 + + + + Connect to Server + 連接到伺服器 + + + + Set share password + 設置共享密碼 + + + + Format + 格式化 + + + + Tag information + 標記訊息 + + + + Open as administrator + 以管理員身份打開 + + + + Select default program + 選擇默認程序 + + + + Open file location + 打開文件所在位置 + + + + Remove bookmark + 移除書籤 + + + + + + Delete + 刪除 + + + + Office Text + 辦公文檔 + + + + Spreadsheets + 電子表格 + + + + Plain Text + 文本文檔 + + + + Open in terminal + 在終端中打開 + + + + Restore + 還原 + + + + Restore all + 全部還原 + + + + Clear saved password and unmount + 取消記住密碼並卸載 + + + + File Vault + 保險箱 + + + + Add to disc + 添加至光盤刻錄 + + + + Refresh + 刷新 + + + + Auto mount + 自動掛載 + + + + Open after auto mount + 自動掛載後打開 + + + + + Mount + 掛載 + + + + + Unmount + 卸載 + + + + It does not support burning %1 discs + %1格式暫不支持刻錄 + + + + Burn + 刻錄 + + + + Disc name: + 光盤名稱: + + + + + Maximum + 最大速度 + + + + Allow files to be added later + 允許追加數據 + + + + Verify data + 校驗數據 + + + + Write speed: + 寫入速度: + + + + + + + Cancel + button + 取 消 + + + + Burn + button + 刻 錄 + + + + + Eject + 彈出 + + + + Safely Remove + 安全移除 + + + + + Name + 名稱 + + + + Settings + 設置 + + + + Exit + 退出 + + + + Icon + 圖標視圖 + + + + List + 列表視圖 + + + + Extend + 擴展視圖 + + + + Set as wallpaper + 設置壁紙 + + + + + + + Local disk + 本地磁盤 + + + + + Removable disk + 可移動磁盤 + + + + + + Network shared directory + 網絡共享目錄 + + + + + Android mobile device + 安卓移動設備 + + + + + Apple mobile device + 蘋果移動設備 + + + + + Camera + 相機 + + + + + DVD + 光驅設備 + + + + + Unknown device + 未知設備 + + + + + + %1 item + %1 項 + + + + + + %1 items + %1 項 + + + + Shortcut + 快捷方式 + + + + Create symlink + 創建鏈接 + + + + Path + 路徑 + + + + + + Time deleted + 刪除時間 + + + + Loading... + 正在加載...... + + + + File has been moved or deleted + 文件已被移動或刪除 + + + + You do not have permission to traverse files in it + 您沒有權限遍歷子文件 + + + + + + You do not have permission to access this folder + 您沒有權限讀取此文件夾 + + + + + + + + Folder is empty + 文件夾為空 + + + + Searching... + 正在搜索... + + + + No results + 無搜索結果 + + + + Source Path + TrashFileInfo + 原始路徑 + + + + Document + 新建Word文檔 + + + + Spreadsheet + 新建Excel文檔 + + + + + Presentation + 演示文檔 + + + + Text + 文檔 + + + + 1 task in progress + 有1個任務正在進行 + + + + %1 tasks in progress + 有%1個任務正在進行 + + + + Mode: + 方式: + + + + + Replace Text + 替換文本 + + + + + Add Text + 添加文本 + + + + + Custom Text + 自定義文本 + + + + Find: + 查找: + + + + Replace: + 替換: + + + + + Optional + 選填 + + + + Add: + 添加: + + + + Location: + 位置: + + + + File name: + 文件名: + + + + Start at: + +序列: + + + + + Rename + button + 重命名 + + + + + + + + + + + Required + 必填 + + + + + Before file name + 名稱之前 + + + + + After file name + 名稱之後 + + + + Find + 查找 + + + + Replace + 替換 + + + + Add + 添加 + + + + Start at + +序列 + + + + + + Location + 位置 + + + + File name + 文件名 + + + + Dimension + 尺寸 + + + + Duration + 時長 + + + + Tips: Sort by selected file order + 提示:根據選擇文件的順序先後排序 + + + + Rename %1 Files + 給%1個文件重命名 + + + + Multiple Files + 多個文件 + + + + Basic info + 基本訊息 + + + + Total size + 總大小 + + + + Number of files + 文件數量 + + + + %1 file(s), %2 folder(s) + %1個文件,%2個文件夾 + + + + + + Time accessed + 訪問時間 + + + + Orange + 橙色 + + + + Red + 紅色 + + + + Purple + 紫色 + + + + Navy-blue + 海藍 + + + + Azure + 天藍 + + + + Green + 綠色 + + + + Yellow + 黃色 + + + + Gray + 灰色 + + + + Input tag info, such as work, family. A comma is used between two tags. + 輸入標記訊息,如“工作”、“家人”等。多個標記訊息之間用逗號分隔。 + + + + Bookmarks + 書籤 + + + + Erase + 擦除 + + + + Copy path + 複製路徑 + + + + Edit address + 編輯地址 + + + + Free Space %1 + 可用空間 %1 + + + + Files are being processed + 正在處理文件 + + + + + Unknown + 未知 + + + + My Vault + 我的保險箱 + + + + + Failed to create file info + 文件訊息創建失敗 + + + + Failed to create file handler + 文件進程創建失敗 + + + + Failed to open the file, cause: %1 + 文件打開失敗,原因:%1 + + + + Original file does not exist + 源文件不存在 + + + + Do you want to delete %1? + 是否刪除 %1? + + + + Confirm + button + 確 定 + + + + + + + + %1 are not allowed + 不得含有%1 + + + + + Failed to start Samba services + Samba服務啟動失敗 + + + + RecentController + + + Cancel + button + 取 消 + + + + Remove + button + 移 除 + + + + Do you want to remove this item? + 您確定要移除選中的此項內容? + + + + Do yout want to remove %1 items? + 您確定要移除選中的%1項內容? + + + + It does not delete the original files + 此操作不會刪除源文件 + + + + ShareInfoFrame + + + Share this folder + 共享此文件夾 + + + + Share name: + 共享名: + + + + Permission: + 權限: + + + + Read and write + 可讀寫 + + + + Read only + 只讀 + + + + Anonymous: + 匿名訪問: + + + + Not allow + 不允許 + + + + Allow + 允許 + + + + The share name must not be two dots (..) or one dot (.) + ..和.禁止作為共享名使用 + + + + The share name is used by another user. + 該共享名已被其他用戶使用 + + + + OK + button + 確 定 + + + + Cancel + button + 取 消 + + + + Replace + button + 替 換 + + + + The share name already exists. Do you want to replace the shared folder? + 該共享名已存在。是否替換原有共享文件夾? + + + + Shortcut + + + Item + 文件 + + + + Select to the first item + 選擇到第一個文件 + + + + Shift + Home + Shift + Home + + + + Select to the last item + 選擇到最後一個文件 + + + + Shift + End + Shift + End + + + + Select leftwards + 向前選擇 + + + + Shift + Left + Shift + Left + + + + Select rightwards + 向后选择 + + + + Shift + Right + Shift + Right + + + + Select to upper row + 向上一行選擇 + + + + Shift + Up + Shift + Up + + + + Select to lower row + 向下一行選擇 + + + + Shift + Down + Shift + Down + + + + Open + 打開 + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + 返回上一級 + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + 徹底刪除 + + + + Shift + Delete + Shift + Delete + + + + Delete file + 刪除文件 + + + + Delete + Delete + + + + Select all + 全選 + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + 複製文件 + + + + Cut + 剪切文件 + + + + Paste + 黏貼文件 + + + + Rename + 重命名 + + + + F2 + F2 + + + + New/Search + 新建/搜索 + + + + New window + 新建窗口 + + + + New folder + 新建文件夾 + + + + + Search + 搜索 + + + + New tab + 新建標籤 + + + + View + 查看 + + + + Item information + 文件訊息 + + + + Help + 幫助手冊 + + + + F1 + F1 + + + + Keyboard shortcuts + 所有快捷鍵 + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + 切換顯示狀態 + + + + Hide item + 隱藏文件 + + + + Input in address bar + 地址欄輸入 + + + + Switch to icon view + 切換到圖標視圖 + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + 切換到列表視圖 + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + 其他 + + + + Close + 關閉 + + + + Alt + F4 + Alt + F4 + + + + Close current tab + 關閉當前標籤 + + + + Back + 後退 + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + 切換到下一個標籤 + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + 切換到上一個標籤 + + + + Next file + 下一個文件 + + + + Tab + Tab + + + + Previous file + 上一個文件 + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + 在1-8之間切換標籤到指定序號 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + 前進 + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + 無法打開回收站中的項目,請先還原 + + + + TrashPropertyDialog + + + Trash + 回收站 + + + + item + 項目 + + + + items + 項目 + + + + Contains %1 %2 + 包含%1個%2 + + + + UDiskListener + + + Failed to rename the label + 重命名卷標失敗 + + + + UnmountWorker + + + + + The device was not safely unmounted + 設備沒有正常卸載 + + + + The device was not safely removed + 設備沒有正常移除 + + + + UserShareManager + + + Kindly Reminder + 溫馨提示 + + + + Please firstly install samba to continue + 請您先安裝samba後,再進行共享相關操作! + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + 共享名不得包含%<>*?|/\+=;:,",且不能以%1開頭 + + + + To protect the files, you cannot share this folder. + 為了文件安全,無法共享此文件夾。 + + + + Sharing failed + 共享失敗 + + + + The computer name is too long + 計算機名過長 + + + + You do not have permission to operate file/folder! + 您沒有權限操作文件/文件夾! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + 請輸入共享密碼 + + + + Cancel + button + 取 消 + + + + Confirm + button + 確 定 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_zh_TW.ts b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_zh_TW.ts new file mode 100644 index 0000000..8ebfc6f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/translations/dde-file-manager_zh_TW.ts @@ -0,0 +1,4716 @@ + + + AppController + + + New Folder + 建立資料夾 + + + + Mounting device error + 掛載裝置時發生錯誤 + + + + The disc image was corrupted, cannot mount now, please erase the disc first + 此光碟中的鏡像已損壞,無法掛載,請擦除後使用 + + + + Mount error: unsupported image format + 掛載錯誤,鏡像檔案格式不支援 + + + + + The device was not safely removed + 裝置沒有正常移除 + + + + + Click "Safely Remove" and then disconnect it next time + 請點擊「安全移除」後,再斷開連接 + + + + The device was not ejected + 裝置未彈出 + + + + Disk is busy, cannot eject now + 磁碟忙碌,現在無法退出 + + + + Authentication timed out + 認證超時 + + + + BluetoothTransDialog + + + Bluetooth File Transfer + 藍牙文件傳輸 + + + + File Transfer Successful + 文件傳輸成功 + + + + File Transfer Failed + 文件傳輸失敗 + + + + Sending files to "<b style="font-weight: 550;">%1</b>" + 正在向「<b style="font-weight: 550;">%1</b>」傳送文件 + + + + Failed to send files to "<b style="font-weight: 550;">%1</b>" + 向「<b style="font-weight: 550;">%1</b>」傳送文件失敗 + + + + Sent to "<b style="font-weight: 550;">%1</b>" successfully + 向「<b style="font-weight: 550;">%1</b>」傳送文件成功 + + + + Select a Bluetooth device to receive files + 選擇接收此文件的藍牙裝置 + + + + Cannot find the connected Bluetooth device + 未找到已連接的藍牙裝置 + + + + Waiting to be received... + 等待接收,請稍候... + + + + Go to Bluetooth Settings + 前往藍牙設定 + + + + %1/%2 Sent + 已傳送%1/%2 + + + + Error: the Bluetooth device is disconnected + 原因:藍牙裝置連線中斷 + + + + Unable to send the file more than 2 GB + 無法傳送超過2GB的文件 + + + + Unable to send 0 KB files + 無法傳送0KB的文件 + + + + File doesn't exist + 文件不存在 + + + + Next + button + 下一步 + + + + Cancel + button + 取 消 + + + + Done + button + 完 成 + + + + Retry + button + 重 試 + + + + OK + button + 確 定 + + + + File sending request timed out + 文件發送超時 + + + + The service is busy and unable to process the request + 裝置超時,無法處理該請求 + + + + BurnOptDialog + + + Device error + 裝置故障 + + + + Optical device %1 doesn't exist + 光碟機%1不存在 + + + + Advanced settings + 進階設定 + + + + File system: + 文件系統: + + + + ISO9660/Joliet (For Windows) + ISO9660/Joliet (可用於Windows) + + + + ISO9660/Rock Ridge (For Unix) + ISO9660/Rock Ridge (可用於Unix) + + + + %1 (Compatible with Windows CD/DVD mode) + %1格式(相容Windows的CD/DVD燒錄模式) + + + + ISO9660 Only + 僅ISO9660 + + + + CloseAllDialogIndicator + + + Close all + 全部關閉 + + + + Total size: %1, %2 files + 總容量為 %1,包含 %2 個檔案 + + + + ComputerModel + + + Double click to open it + 雙擊打開應用程式 + + + + My Directories + 我的資料夾 + + + + Disks + 磁碟 + + + + File Vault + 保險箱 + + + + Quick Access + 快速訪問 + + + + ComputerPropertyDialog + + + Computer + 電腦 + + + + Basic Info + 基本資訊 + + + + + Computer Name + 電腦名稱 + + + + + Edition + 版本 + + + + + + Version + 版本號 + + + + + Type + 類型 + + + + + + Processor + 處理器 + + + + + + Memory + 記憶體 + + + + + + + Bit + 位元 + + + + + Available + 可用 + + + + Obtaining... + 正在獲取中... + + + + ConnectToServerDialog + + + Connect to Server + 連線到伺服器 + + + + Cancel + button + 取 消 + + + + Connect + button + 連 線 + + + + My Favorites: + 個人收藏伺服器 + + + + + Clear History + 清除最近使用的伺服器 + + + + DFMAddressBar + + + Search or enter address + 搜尋或輸入位址 + + + + DFMAdvanceSearchBar + + + Search: + 搜尋: + + + + File Type: + 檔案類型: + + + + File Size: + 檔案大小: + + + + Time Modified: + 修改時間: + + + + Time Accessed: + 訪問時間: + + + + Time Created: + 建立時間: + + + + Reset + 重設 + + + + All subdirectories + 所有子目錄 + + + + Current directory + 目前目錄 + + + + 0 ~ 100 KB + 0 ~ 100 KB + + + + 100 KB ~ 1 MB + 100 KB ~ 1 MB + + + + 1 MB ~ 10 MB + 1 MB ~ 10 MB + + + + 10 MB ~ 100 MB + 10 MB ~ 100 MB + + + + 100 MB ~ 1 GB + 100 MB ~ 1 GB + + + + > 1 GB + > 1 GB + + + + Today + 今天 + + + + Yesterday + 昨天 + + + + This week + 這週 + + + + Last week + 上週 + + + + This month + 這個月 + + + + Last month + 上個月 + + + + This year + 今年 + + + + Last year + 去年 + + + + DFMOpticalMediaWidget + + + + No files to burn + 沒有文件需要燒錄 + + + + Unable to burn. Not enough free space on the target disk. + 目標磁碟剩餘空間不足,無法進行燒錄! + + + + %1 burning is not supported + 目前光碟介質不支援%1燒錄 + + + + 1. It is not %1 disc; +2. The version of this file system does not support adding files yet. + 1. 介質類型不是%1; +2. 目前光碟文件系統版本暫不支援追加燒錄。 + + + + DFMTagCrumbController + + + Tag information + 標記內容 + + + + DFMTagWidget + + + Tag + 標記 + + + + DFMTaskWidget + + + Do not ask again + 不再詢問 + + + + Syncing data + 資料同步中 + + + + Please wait + 請稍候 + + + + + Time modified: %1 + 修改時間:%1 + + + + + Contains: %1 + 檔案數量:%1 + + + + + Size: %1 + 大小:%1 + + + + Original folder + 原始資料夾 + + + + Keep both + button + 共 存 + + + + Skip + button + 略 過 + + + + Replace + button + 取 代 + + + + Retry + button + 重 試 + + + + Original file + 原始檔案 + + + + Target folder + 目標資料夾 + + + + Target file + 目標檔案 + + + + DFMVaultActiveFinishedView + + + Encrypt File Vault + 加密保險箱 + + + + Click 'Encrypt' and input the user password. + 點擊“加密保險箱”後,輸入使用者密碼完成設定。 + + + + Encrypting... + 正在加密... + + + + + + + Encrypt + 加密保險箱 + + + + Failed to create file vault: %1 + 建立保險箱失敗:%1 + + + + OK + 確 定 + + + + The setup is complete + 加密已完成 + + + + DFMVaultActiveSaveKeyFileView + + + Save Recovery Key + 儲存金鑰文件 + + + + Keep the key safe to retrieve the vault password later + 金鑰文件可用來找回您設置的保險箱密碼,請妥善保管 + + + + Save to default path + 儲存至預設路徑 + + + + Save to other locations + 儲存至其他路徑 + + + + No permission, please reselect + 權限不夠,請重新選擇 + + + + Select a path + 選擇金鑰文件儲存路徑 + + + + Next + 下一步 + + + + The default path is invisible to other users, and the path information will not be shown. + 預設路徑為不會暴露給其他使用者的特殊路徑,且不會明文顯示路徑訊息。 + + + + DFMVaultActiveSaveKeyView + + + Recovery Key + 文件保險箱復原金鑰 + + + + Generate a recovery key in case that you forgot the password + 如果忘記密碼,可以使用該金鑰復原訪問 + + + + Key + 金鑰 + + + + QR code + 二維碼 + + + + Scan QR code and save the key to another device + 掃描二維碼,儲存至其它裝置 + + + + Next + 下一步 + + + + Recovery Key: + 文件保險箱復原金鑰: + + + + DFMVaultActiveSetUnlockMethodView + + + Set Vault Password + 設定解鎖方式 + + + + Method + 類型 + + + + Manual + 手動 + + + + Password + 密碼 + + + + + ≥ 8 chars, contains A-Z, a-z, 0-9, and symbols + 至少8位,包含A-Z, a-z, 0-9和符號 + + + + Repeat password + 重複密碼 + + + + Input the password again + 再次輸入密碼 + + + + Password hint + 密碼提示 + + + + Optional + 選用 + + + + Next + 下一步 + + + + + Passwords do not match + 輸入密碼不一致 + + + + DFMVaultActiveStartView + + + File Vault + 保險箱 + + + + Create your secure private space + 專屬於個人的安全空間 + + + + Advanced encryption technology + 先進的加密技術,隱私安全有保障 + + + + Convenient and easy to use + 使用更便捷,操作更簡單 + + + + Create + 建立 + + + + DFMVaultFileView + + + Cannot open this path + 無法打開目前路徑 + + + + Hint + 提示 + + + + OK + 確 定 + + + + DFMVaultRecoveryKeyPages + + + Unlock by Key + 復原金鑰解鎖 + + + + Failed to unlock file vault + 解鎖保險箱失敗 + + + + OK + 確 定 + + + + Input the 32-digit recovery key + 請輸入32位復原金鑰 + + + + Cancel + button + 取 消 + + + + Unlock + button + 解 鎖 + + + + Wrong recovery key + 金鑰錯誤 + + + + DFMVaultRemoveByPasswordView + + + Password + 密碼 + + + + Password hint: %1 + 密碼提示:%1 + + + + DFMVaultRemoveByRecoverykeyView + + + Input the 32-digit recovery key + 請輸入32位復原金鑰 + + + + DFMVaultRemovePages + + + Delete File Vault + 刪除保險箱 + + + + Once deleted, the files in it will be permanently deleted + 刪除保險箱後,其中的所有內容將會被永久刪除 + + + + Use Key + 金鑰驗證 + + + + Cancel + button + 取 消 + + + + Use Key + button + 金鑰驗證 + + + + Delete + button + 刪 除 + + + + + OK + button + 確 定 + + + + Use Password + 密碼驗證 + + + + Wrong password + 密碼錯誤 + + + + Wrong recovery key + 金鑰錯誤 + + + + Failed to delete file vault + 刪除保險箱失敗 + + + + Deleted successfully + 刪除成功 + + + + Failed to delete + 刪除失敗 + + + + Removing... + 正在刪除... + + + + DFMVaultRetrievePassword + + + + + + + + Unable to get the key file + 無法獲取金鑰文件 + + + + Verification failed + 金鑰驗證失敗 + + + + + Select a path + 選擇金鑰文件儲存路徑 + + + + + Retrieve Password + 密碼找回 + + + + By key in the default path + 透過預設路徑金鑰文件找回密碼 + + + + By key in the specified path + 透過指定路徑金鑰文件找回密碼 + + + + Verification Successful + 金鑰驗證成功 + + + + Keep it safe + 請妥善保管 + + + + Back + button + 返 回 + + + + Verify Key + button + 驗證金鑰 + + + + Go to Unlock + button + 返回解鎖 + + + + Close + button + 關 閉 + + + + Vault password: %1 + 保險箱密碼為:%1 + + + + DFMVaultUnlockPages + + + Unlock File Vault + 解鎖保險箱 + + + + Forgot password? + 忘記密碼? + + + + Password hint: %1 + 密碼提示:%1 + + + + Failed to unlock file vault + 解鎖保險箱失敗 + + + + Cancel + button + 取 消 + + + + Password + 密碼 + + + + Unlock + button + 解 鎖 + + + + Please try again %1 minutes later + 請%1分鐘後再試 + + + + Wrong password, please try again %1 minutes later + 密碼錯誤,請%1分鐘後再試 + + + + Wrong password, one chance left + 密碼錯誤,您還可再輸入1次 + + + + Wrong password, %1 chances left + 密碼錯誤,您還可再輸入%1次 + + + + Wrong password + 密碼錯誤 + + + + OK + button + 確 定 + + + + DFileCopyMoveJob + + + Permission error + 權限錯誤 + + + + The action is denied + 動作被拒 + + + + Failed to open the file + 開啟檔案失敗 + + + + Failed to read the file + 讀取檔案失敗 + + + + Failed to write the file + 寫入檔案失敗 + + + + Failed to create the directory + 建立目錄失敗 + + + + Failed to delete the file + 刪除檔案失敗 + + + + Failed to move the file + 移動檔案失敗 + + + + Original file does not exist + 原始檔案不存在 + + + + Failed, file size must be less than 4GB + 失敗,檔案大小至多只能 4GB + + + + Not enough free space on the target disk + 目標磁碟剩餘空間不足 + + + + File integrity was damaged + 檔案完整性被破壞 + + + + The target device is read only + 目標裝置唯讀 + + + + Target folder is inside the source folder + 目標資料夾在來源資料夾內 + + + + The action is not supported + 不支援該操作 + + + + You do not have permission to traverse files in it + 您沒有權限遍歷子文件 + + + + Failed to position the file pointer! + 指標定位失敗! + + + + copy + Extra name added to new file name when used for file name. + 副本 + + + + Failed to open the directory, cause: file name too long + 目錄打開失敗,原因:檔案名過長 + + + + + Failed to open the file, cause: file name too long + 文件打開失敗,原因:檔案名過長 + + + + + Failed to write the file, cause: + 無法寫入檔案,因為: + + + + Failed to position the file pointer, cause: %1 + 指標定位失敗,原因:%1 + + + + Syncing data + 資料同步中 + + + + Please wait + 請稍候 + + + + Failed to create the directory, cause: %1 + 無法建立目錄,因為:%1 + + + + + + + + Failed to open the file, cause: %1 + 無法開啟檔案,因為:%1 + + + + + + + Failed to open the file, cause: Permission denied + 文件打開失敗,原因:權限不足 + + + + + Failed to read the file, cause: %1 + 無法讀取檔案,因為:%1 + + + + + + + Failed to write the file, cause: %1 + 無法寫入檔案,因為:%1 + + + + + File integrity was damaged, cause: %1 + 檔案完整性被破壞,因為:%1 + + + + Failed to open the file, cause: + 無法開啟檔案,因為: + + + + Failed to read the file, cause: + 無法讀取檔案,因為: + + + + Failed to delete the file, cause: %1 + 刪除檔案失敗,因為:%1 + + + + Fail to create symlink, cause: %1 + 建立符號連結失敗,因為:%1 + + + + DFileDialog + + + + Save + button + 儲 存 + + + + + Cancel + button + 取 消 + + + + Confirm + button + 確 定 + + + + %1 already exists, do you want to replace it? + %1 已存在,請問要取代它嗎? + + + + Replace + button + 取 代 + + + + Open + button + 開 啟 + + + + This file will be hidden if the file name starts with a dot (.). Do you want to hide it? + 檔案名以“.”開始將會隱藏此文件,請確認是否繼續? + + + + DFileManagerWindow + + + Trash + 回收桶 + + + + Empty + 清除 + + + + DFileSystemModel + + + + Name + 名稱 + + + + + + Time modified + 修改時間 + + + + Size + 檔案大小 + + + + Type + 檔案類型 + + + + Time created + 建立時間 + + + + + Last access + 上次存取 + + + + + + + Path + 路徑 + + + + DFileView + + + Disc mount error + 光盤掛載錯誤 + + + + The disc is in use, please end the running process and remount the disc. + 當前光驅設備正在佔用,請關閉佔用進程再重新掛載 + + + + Mounting failed + 掛載失敗 + + + + (Reverse) + (還原) + + + + DFileViewHelper + + + Add tag "%1" + 新增「%1」標記 + + + + DStatusBar + + + %1 item + %1 個項目 + + + + %1 items + %1 個項目 + + + + %1 item selected + 已選取 %1 個項目 + + + + %1 items selected + 已選取 %1 個項目 + + + + %1 folder selected (contains %2) + 已選取 %1 個資料夾(包含 %2 ) + + + + %1 folders selected (contains %2) + 已選取 %1 個資料夾(包含 %2 ) + + + + %1 file selected (%2) + 已選取 %1 個檔案(%2) + + + + %1 files selected (%2) + 已選取 %1 個檔案(%2) + + + + %1 folder selected + 已選取 %1 個資料夾 + + + + Filter + 檔案類型 + + + + Save as: + 另存為: + + + + Loading... + 正在載入… + + + + DTaskDialog + + + Erasing disc %1, please wait... + 正在清除 %1 光碟,請稍候… + + + + Burning disc %1, please wait... + 正在燒錄 %1 光碟,請稍候… + + + + Writing data... + 正在寫入資料… + + + + Verifying data... + 正在驗證資料… + + + + Copying %1 + 正在複製 %1 + + + + + + to %2 + 到 %2 + + + + %1 already exists in target folder + %1 已存在目標資料夾 + + + + Original path %1 Target path %2 + 原始路徑 %1 目標路徑 %2 + + + + Merge + button + 合 併 + + + + Replace + button + 取 代 + + + + Moving %1 + 正在移動 %1 + + + + Removing file vault, please try later + 正在刪除保險箱,請稍候... + + + + Restoring %1 + 正在還原 %1 + + + + Deleting %1 + 正在刪除 %1 + + + + Trashing %1 + 正在移動 %1 + + + + Calculating space, please wait + 正在計算空間,請稍候 + + + + DUMountManager + + + + Authentication timed out + 認證超時 + + + + + + Disk is busy, cannot unmount now + 磁碟忙碌中,現無法卸載 + + + + Disk is busy, cannot eject now + 磁碟忙碌,現在無法退出 + + + + The device is busy, cannot eject now + 光碟機正忙,無法彈出 + + + + + + The device is busy, cannot remove now + 裝置正忙,無法安全移除 + + + + DeepinStorage + + + + + %1 Volume + %1 磁碟區 + + + + Data Disk + Data Partition + 資料硬碟 + + + + %1 Drive + %1 光碟機 + + + + Blank %1 Disc + 空白 %1 光碟 + + + + %1 Encrypted + %1 已加密 + + + + DialogManager + + + + + + Operation failed! + 作業失敗! + + + + Target folder is inside the source folder! + 目標資料夾於來源資料夾中! + + + + Do you want to run %1 or display its content? + 執行 %1 或顯示內容? + + + + It is an executable text file. + 此為文字執行檔案。 + + + + It is an executable file. + 此為執行檔案。 + + + + This file is not executable, do you want to add the execute permission and run? + 此檔案不是可執行檔案,是否要對這檔案增加執行權限並執行? + + + + "%1" already exists, please use another name. + 「%1」已存在,請使用其他檔案名稱。 + + + + The file name must not contain two dots (..) + 檔案名不得含有兩個點(..) + + + + Device or resource busy + 裝置或資源繁忙 + + + + Are you sure you want to erase all data on the disc? + 確定清除光碟上的所有資料? + + + + How do you want to use this disc? + 確定使用此光碟? + + + + Disc erase failed + 清除光碟失敗 + + + + Burn process failed + 燒錄失敗 + + + + %1: %2 + %1:%2 + + + + Show details + 顯示詳細資訊 + + + + Hide details + 隱藏詳細資訊 + + + + Error + 錯誤 + + + + Permanently delete %1? + 完全刪除 %1? + + + + Permanently delete %1 items? + 完全刪除 %1 個項目? + + + + Empty + 清除 + + + + Do you want to delete %1? + 是否刪除 %1? + + + + Do you want to delete the selected %1 items? + 是否刪除選中的%1項內容? + + + + Sorry, unable to locate your bookmark directory, remove it? + 抱歉,找不到書籤位置,是否移除? + + + + Name: + 名稱: + + + + %1 that this shortcut refers to has been changed or moved + %1 捷徑連結的檔案或資料夾已更改或移除 + + + + Do you want to delete this shortcut? + 確定刪除快速鍵? + + + + Failed, file size must be less than 4GB. + 失敗,檔案大小至少要小於 4GB。 + + + + Fail to create symlink, cause: + 建立連結失敗,由於: + + + + The selected files contain system file/directory, and it cannot be deleted + 已選取的檔案中包含系統檔案╱資料夾,無法刪除 + + + + Unable to find the original file + 無法找到連結目標文件 + + + + + You do not have permission to operate file/folder! + 你無權對檔案或資料夾進行操作! + + + + Failed to restore %1 file, the source file does not exist + 原文件不存在,%1個文件復原失敗 + + + + Sorry, you don't have permission to operate the following %1 file/folder(s)! + 抱歉,您無權執行以下 %1 個檔案和資料夾! + + + + Unable to access %1 + 訪問%1失敗 + + + + + Sending files now, please try later + 目前已有傳送中的文件,請稍後再試 + + + + To access the device, you must format the disk first. Are you sure you want to format it now? + 需要格式化磁碟才能訪問此裝置,是否繼續? + + + + Scanning the device, stop it? + 正在掃描目前裝置,是否終止掃描? + + + + Share folder can't be named after the current username + 無法在目前使用者名稱後命名分享資料夾 + + + + Do you want to run %1? + 你要執行 %1? + + + + Burn image + button + 燒錄映像 + + + + Burn files + button + 燒錄檔案 + + + + Are you sure you want to empty %1 item? + 確定清空 %1 個項目? + + + + Are you sure you want to empty %1 items? + 確定清空 %1 個項目? + + + + + This action cannot be undone + 此動作無法復原 + + + + + + + + + + + + + + OK + button + 確 定 + + + + + + + + + + + + + + + Cancel + button + 取 消 + + + + + + Run + button + 執 行 + + + + + Run in terminal + button + 終端機執行 + + + + Display + button + 顯 示 + + + + + + + + + + + Confirm + button + 確 定 + + + + Erase + button + 清 除 + + + + Data verification failed + 資料校驗失敗 + + + + Show details + button + 顯示詳細資訊 + + + + + Delete + button + 刪 除 + + + + Remove + button + 刪 除 + + + + Disk is busy, cannot unmount now + 磁碟忙碌中,現無法卸載 + + + + Force unmount + button + 強制退出 + + + + Unable to copy. Not enough free space on the target disk. + 無法進行複製,目標磁碟剩餘空間不足 + + + + Failed to restore %1 file, the target folder is read-only + %1個文件還原失敗,目標資料夾不可寫 + + + + Failed to restore %1 files, the target folder is read-only + %1個文件還原失敗,目標資料夾不可寫 + + + + Failed to restore %1 files, the source files do not exist + 原文件不存在,%1個文件復原失敗 + + + + Format + button + 格式化 + + + + Stop + button + 終 止 + + + + FileController + + + + + + Unable to find the original file + 無法找到連結目標文件 + + + + + + Kindly Reminder + 提醒 + + + + + + Please install File Roller first and then continue + 請先安裝歸檔管理器然後繼續 + + + + + Unable to create files here: %1 + 不能在此建立文件:%1 + + + + Confirm + button + 確 定 + + + + FileDialogStatusBar + + + File Name + 檔名 + + + + Format + 檔案格式 + + + + Save + button + 儲 存 + + + + Open + button + 開 啟 + + + + Save File + button + 儲存檔案 + + + + Open File + button + 開啟檔案 + + + + + + Cancel + button + 取 消 + + + + FileJob + + + copy + 副本 + + + + + + + Data verification successful. + 資料驗證成功。 + + + + + + Burn process completed + 燒錄完成 + + + + %1 s + 剩餘 %1 秒 + + + + %1 m %2 s + 剩餘 %1 分 %2 秒 + + + + %1 h %2 m %3 s + 剩餘 %1 時 %2 分 %3 秒 + + + + %1 d %2 h %3 m %4 s + 剩餘 %1 天 %2 時 %3 分 %4 秒 + + + + %1 is a duplicate file. + %1 檔案重複。 + + + + Insufficient disc space. + 光碟剩餘空間不足。 + + + + Lost connection to drive. + 光碟機連結被斷開。 + + + + The CD/DVD drive is not ready. Try another disc. + 未準備好 CD/DVD 光碟機。請嘗試另一張光碟。 + + + + The CD/DVD drive is busy. Exit the program using the drive, and insert the drive again. + CD/DVD 光碟機忙碌中。請關閉使用此光碟機的程式,再重新插入光碟機。 + + + + Unknown error + 未知錯誤 + + + + Device disconnected + 光碟機裝置未連接 + + + + GenerateSettingTranslate + + + + + Basic + 基本 + + + + + + Open behavior + 開啟方式 + + + + + + Always open folder in new window + 永遠在新視窗開啟 + + + + + + Open file: + 檔案開啟方式: + + + + + + Click + 滑鼠按一下 + + + + + + Double click + 滑鼠連按兩下 + + + + + + New window and tab + 新視窗與新分頁 + + + + + + Open from default window: + 視窗預設開啟: + + + + + + + + + Computer + 電腦 + + + + + + + + + Home + 主資料夾 + + + + + + + + + Desktop + 桌面 + + + + + + + + + Videos + 影片 + + + + + + + + + Music + 音樂 + + + + + + + + + Pictures + 圖片 + + + + + + + + + Documents + 文件 + + + + + + + + + Downloads + 下載 + + + + + + Open in new tab: + 新建分頁時開啟: + + + + + + Current Directory + 目前目錄 + + + + + + View + 檢視 + + + + + + Default size: + 預設大小: + + + + + + Extra small + 最小 + + + + + + Small + + + + + + + Medium + + + + + + + Large + + + + + + + Extra large + 最大 + + + + + + Default view: + 預設顯示 + + + + + + Icon + 圖示顯示 + + + + + + List + 列表顯示 + + + + + + Hidden files + 隱藏檔案 + + + + + + Show hidden files + 顯示隱藏檔案 + + + + + + Hide file extension when rename + 重新命名時隱藏檔案副檔名 + + + + + + Advanced + 進階 + + + + + + Index + 索引 + + + + + + Auto index internal disk + 自動索引內部硬碟 + + + + + + Index external storage device after connected to computer + 外部裝置連上電腦時索引 + + + + + + Full-Text search + 全文搜尋 + + + + + + Show item counts and sizes in the path of mounted MTP devices + MTP掛載路徑下顯示文件統計詳情 + + + + + + Keep showing the mounted Samba shares + Samba共享端常駐顯示掛載入口 + + + + + + Use the file chooser dialog of File Manager + 使用檔案管理器的選擇檔案對話框 + + + + + + Ask for my confirmation when deleting files + 開啟普通刪除提示 + + + + + + Other + 其他 + + + + + + Hide system disk + 隱藏系統硬碟 + + + + + + Show file system on disk icon + 在磁碟圖標上顯示文件系統標籤 + + + + + + Show hidden files in search results + 搜尋結果顯示隱藏檔案 + + + + + + Display recent file entry in left panel + 在左方面板顯示最近檔案項目 + + + + + + Preview + 預覽 + + + + + Compress file preview + 預覽壓縮檔案 + + + + + + Text preview + 預覽文字檔案 + + + + + + Document preview + 預覽文件檔案 + + + + + + Image preview + 預覽圖片 + + + + + + Video preview + 預覽影片 + + + + + + Mount + 掛載 + + + + + + Auto mount + 自動掛載 + + + + + + Open after auto mount + 自動掛載後開啟 + + + + + + Dialog + 對話框 + + + + Compressed file preview + 壓縮檔案預覽 + + + + GvfsMountManager + + + Can’t verify the identity of %1. + 無法確認%1的身份。 + + + + This happens when you log in to a computer the first time. + 當您首次登入時會看到這個提示。 + + + + The identity sent by the remote computer is + 遠端電腦發送的身份訊息為 + + + + If you want to be absolutely sure it is safe to continue, contact the system administrator. + 若想確認繼續操作是否安全,請聯絡系統管理員。 + + + + + + + + Mounting device error + 掛載裝置時發生錯誤 + + + + + Wrong username or password + 使用者名稱或密碼錯誤 + + + + + + + + Confirm + button + 確 定 + + + + + Cannot find the mounted device + 找不到掛載裝置 + + + + No key available to unlock device + 沒有金鑰解鎖裝置 + + + + The disk is mounted by user "%1", you cannot unmount it. + 此磁碟已被「%1」給掛載,你無法移除它。 + + + + Cannot unmount the device + 無法卸載裝置 + + + + Cannot eject the device "%1" + 無法退出裝置「%1」 + + + + MasteredMediaController + + + Unable to burn. Not enough free space on the target disk. + 目標磁碟剩餘空間不足,無法進行燒錄! + + + + MergedDesktopController + + + + Pictures + 圖片 + + + + + Music + 音樂 + + + + + Applications + 應用程式 + + + + + Videos + 影片 + + + + + Documents + 文件 + + + + + Others + 其他 + + + + MimeTypeDisplayManager + + + + Directory + 目錄 + + + + + + Application + 應用程式 + + + + + + Video + 影片 + + + + + + Audio + 音樂 + + + + + + Image + 影像 + + + + + Archive + 封存檔 + + + + + + Text + 純文字文件 + + + + + Executable + 可執行 + + + + + Backup file + 備份檔 + + + + + Unknown + 未知 + + + + MountAskPasswordDialog + + + Cancel + button + 取 消 + + + + Connect + button + 連 線 + + + + Log in as + 登入身份 + + + + Anonymous + 匿名 + + + + Registered user + 登入使用者 + + + + Username + 使用者名稱 + + + + Domain + 網域 + + + + Password + 密碼 + + + + Remember password + 記住密碼 + + + + MountSecretDiskAskPasswordDialog + + + Cancel + button + 取 消 + + + + Unlock + button + 解 鎖 + + + + Input password to decrypt the disk + 輸入密碼解鎖此磁碟 + + + + MoveToTrashConflictDialog + + + Are you sure you want to permanently delete %1? + 確定永久刪除 %1? + + + + This file is too big for the trash + 檔案過大無法丟到回收桶 + + + + The files are too big for the trash + 檔案過大無法丟到回收桶 + + + + Are you sure you want to permanently delete %1 files? + 確定永久刪除 %1 個檔案? + + + + Cancel + button + 取 消 + + + + Delete + button + 刪 除 + + + + OpenWithDialog + + + Open with + 其他程式開啟 + + + + Add other programs + 加入其他應用程式 + + + + Set as default + 作為預設值 + + + + Cancel + button + 取 消 + + + + Confirm + button + 確 定 + + + + Recommended Applications + 建議的應用程式 + + + + Other Applications + 其他應用程式 + + + + PathManager + + + Home + 主資料夾 + + + + Desktop + 桌面 + + + + Videos + 影片 + + + + Music + 音樂 + + + + Pictures + 圖片 + + + + Documents + 文件 + + + + Downloads + 下載 + + + + + Trash + 回收桶 + + + + + + System Disk + 系統磁碟 + + + + Computers in LAN + 共用的電腦 + + + + My Shares + 我的共用 + + + + Computer + 電腦 + + + + Recent + 最近 + + + + File Vault + 保險箱 + + + + PropertyDialog + + + Basic info + 基本資訊 + + + + Open with + 其他程式開啟 + + + + Sharing + 共享管理 + + + + Permissions + 存取權限 + + + + %1 (%2) + %1 (%2) + + + + %1 + %1 + + + + %1 / %2 + %1 / %2 + + + + Hide this folder + 隱藏此資料夾 + + + + Hide this file + 隱藏此文件 + + + + Allow to execute as program + 允許作為程式執行 + + + + QObject + + + + + + Size + 大小 + + + + + + Contains + 檔案數量 + + + + + + Type + 類型 + + + + + + + + Time modified + 修改時間 + + + + Free space + 剩餘空間 + + + + Total space + 總空間 + + + + + Time locked + 上鎖時間 + + + + Access denied + 不可讀不可寫 + + + + + Executable + 可執行 + + + + + Write only + 僅寫 + + + + + Read only + 唯讀 + + + + + Read-write + 讀寫 + + + + Others + 其他 + + + + Owner + 擁有者 + + + + Unconnected network shared directory + 未連接的網路共享目錄 + + + + Device type + 裝置類型 + + + + File system + 文件系統 + + + + Group + 群組 + + + + + Open + 開啟 + + + + Lock + 立即上鎖 + + + + Auto lock + 自動上鎖 + + + + Never + 永不 + + + + 5 minutes + 5分鐘 + + + + 10 minutes + 10分鐘 + + + + 20 minutes + 20分鐘 + + + + Delete File Vault + 刪除保險箱 + + + + Unlock + 解鎖 + + + + Unlock by key + 金鑰解鎖 + + + + Open + button + 開 啟 + + + + + Size: %1 + 大小:%1 + + + + Type: %1 + 類型:%1 + + + + Size: 0 + 大小:0 + + + + Items: %1 + 項目:%1 + + + + + + + + + + Open in new window + 在新視窗中開啟 + + + + + + + + + + Open in new tab + 在新分頁中開啟 + + + + Open with + 用其他程式開啟 + + + + + Compress + 壓縮 + + + + Extract + 解壓縮 + + + + Extract here + 在此解壓縮 + + + + Cut + 剪下 + + + + Copy + 複製 + + + + Paste + 貼上 + + + + + + + + Rename + 重新命名 + + + + + + + Remove + 移除 + + + + Create link + 建立連結 + + + + Send to desktop + 傳送到桌面 + + + + Send to + 傳送到 + + + + Bluetooth + 藍牙 + + + + Add to bookmark + 加到書籤 + + + + + + + Properties + 屬性 + + + + New folder + 新增資料夾 + + + + New window + 新增視窗 + + + + Select all + 全選 + + + + + Clear recent history + 清除最近使用的位置 + + + + + + Empty Trash + 清除回收桶 + + + + Display as + 顯示方式 + + + + Sort by + 排列順序 + + + + New document + 新增文件 + + + + + Time created + 建立時間 + + + + + + Source path + 原始路徑 + + + + Share folder + 共用資料夾 + + + + Cancel sharing + 取消共用 + + + + Connect to Server + 連線到伺服器 + + + + Set share password + 設定共用密碼 + + + + Format + 格式化 + + + + Tag information + 標記內容 + + + + Open as administrator + 以管理員身份打開 + + + + Select default program + 選擇預設開啟程式 + + + + Open file location + 開啟檔案位置 + + + + Remove bookmark + 移除書籤 + + + + + + Delete + 刪除 + + + + Office Text + 辦公文件 + + + + Spreadsheets + 試算表 + + + + Plain Text + 文字檔案 + + + + Open in terminal + 開啟終端機 + + + + Restore + 還原 + + + + Restore all + 全部還原 + + + + Clear saved password and unmount + 取消記住密碼並移除 + + + + File Vault + 保險箱 + + + + Add to disc + 添加至光碟燒錄 + + + + Refresh + 重新整理 + + + + Auto mount + 自動掛載 + + + + Open after auto mount + 自動掛載後開啟 + + + + + Mount + 掛載 + + + + + Unmount + 卸載 + + + + It does not support burning %1 discs + %1格式暫不支援燒錄 + + + + Burn + 燒錄 + + + + Disc name: + 光碟名稱: + + + + + Maximum + 最快速度 + + + + Allow files to be added later + 允許稍候附加檔案 + + + + Verify data + 驗證資料 + + + + Write speed: + 寫入速度: + + + + + + + Cancel + button + 取 消 + + + + Burn + button + 燒 錄 + + + + + Eject + 退出 + + + + Safely Remove + 安全移除 + + + + + Name + 檔案名稱 + + + + Settings + 設定 + + + + Exit + 退出 + + + + Icon + 圖示顯示 + + + + List + 列表顯示 + + + + Extend + 延伸 + + + + Set as wallpaper + 設定為桌布 + + + + + + + Local disk + 本機磁碟 + + + + + Removable disk + 卸除式磁碟機 + + + + + + Network shared directory + 網路共用資料夾 + + + + + Android mobile device + Android 行動裝置 + + + + + Apple mobile device + Apple 行動裝置 + + + + + Camera + 相機 + + + + + DVD + 光碟機 + + + + + Unknown device + 未知裝置 + + + + + + %1 item + %1 個項目 + + + + + + %1 items + %1 個項目 + + + + Shortcut + 快速鍵 + + + + Create symlink + 建立連結 + + + + Path + 路徑 + + + + + + Time deleted + 刪除時間 + + + + Loading... + 正在載入… + + + + File has been moved or deleted + 檔案已移動或刪除 + + + + You do not have permission to traverse files in it + 您沒有權限遍歷子文件 + + + + + + You do not have permission to access this folder + 無權進入資料夾 + + + + + + + + Folder is empty + 空資料夾 + + + + Searching... + 正在搜尋… + + + + No results + 找不到結果 + + + + Source Path + TrashFileInfo + 來源路徑 + + + + Document + 文件 + + + + Spreadsheet + 試算表 + + + + + Presentation + 簡報 + + + + Text + 純文字文件 + + + + 1 task in progress + 正在進行 1 項作業 + + + + %1 tasks in progress + 正在進行 %1 項作業 + + + + Mode: + 模式: + + + + + Replace Text + 取代文件 + + + + + Add Text + 加入文件 + + + + + Custom Text + 自訂文件 + + + + Find: + 尋找: + + + + Replace: + 取代: + + + + + Optional + 選用 + + + + Add: + 加入: + + + + Location: + 目錄: + + + + File name: + 檔名: + + + + Start at: + +序列: + + + + + Rename + button + 重新命名 + + + + + + + + + + + Required + 必須 + + + + + Before file name + 在檔名前 + + + + + After file name + 在檔名後 + + + + Find + 尋找 + + + + Replace + 取代 + + + + Add + 加入 + + + + Start at + +序列 + + + + + + Location + 目錄 + + + + File name + 檔名 + + + + Dimension + 尺寸 + + + + Duration + 時長 + + + + Tips: Sort by selected file order + 小提示:用選取檔案順序來排序 + + + + Rename %1 Files + 重新命名 %1 個檔案 + + + + Multiple Files + 多個檔案 + + + + Basic info + 基本資訊 + + + + Total size + 總空大小 + + + + Number of files + 檔案數量 + + + + %1 file(s), %2 folder(s) + %1 個檔案,%2 個資料夾 + + + + + + Time accessed + 訪問時間 + + + + Orange + 橘色 + + + + Red + 紅色 + + + + Purple + 紫色 + + + + Navy-blue + 藏青色 + + + + Azure + 天藍色 + + + + Green + 綠色 + + + + Yellow + 黃色 + + + + Gray + 灰色 + + + + Input tag info, such as work, family. A comma is used between two tags. + 輸入標記資訊,例如工作、家庭。兩個標記之間請使用逗號 (,) 分割 + + + + Bookmarks + 書籤 + + + + Erase + 清除 + + + + Copy path + 複製路徑 + + + + Edit address + 編輯位址 + + + + Free Space %1 + 可用空間 %1 + + + + Files are being processed + 正在處理文件 + + + + + Unknown + 未知 + + + + My Vault + 我的保險箱 + + + + + Failed to create file info + 文件訊息建立失敗 + + + + Failed to create file handler + 文件處理程序建立失敗 + + + + Failed to open the file, cause: %1 + 無法開啟檔案,因為:%1 + + + + Original file does not exist + 原始檔案不存在 + + + + Do you want to delete %1? + 是否刪除 %1? + + + + Confirm + button + 確 定 + + + + + + + + %1 are not allowed + 不得含有%1 + + + + + Failed to start Samba services + Samba服務啟動失敗 + + + + RecentController + + + Cancel + button + 取 消 + + + + Remove + button + 移 除 + + + + Do you want to remove this item? + 您確定要移除選中的此項內容? + + + + Do yout want to remove %1 items? + 您確定要移除選中的%1項內容? + + + + It does not delete the original files + 此操作不會刪除來源文件 + + + + ShareInfoFrame + + + Share this folder + 共用資料夾 + + + + Share name: + 共用名稱: + + + + Permission: + 存取權限: + + + + Read and write + 讀寫 + + + + Read only + 唯讀 + + + + Anonymous: + 匿名: + + + + Not allow + 不允許 + + + + Allow + 允許 + + + + The share name must not be two dots (..) or one dot (.) + ..和.禁止作為共享名使用 + + + + The share name is used by another user. + 該共享名已被其他使用者使用 + + + + OK + button + 確 定 + + + + Cancel + button + 取 消 + + + + Replace + button + 取 代 + + + + The share name already exists. Do you want to replace the shared folder? + 該共享名已存在。是否取代原有共享資料夾? + + + + Shortcut + + + Item + 項目 + + + + Select to the first item + 選取到第一個項目 + + + + Shift + Home + Shift + Home + + + + Select to the last item + 選取到最後一個項目 + + + + Shift + End + Shift + End + + + + Select leftwards + 向左選取 + + + + Shift + Left + Shift + Left + + + + Select rightwards + 向右選取 + + + + Shift + Right + Shift + Right + + + + Select to upper row + 向上選取 + + + + Shift + Up + Shift + Up + + + + Select to lower row + 向下選取 + + + + Shift + Down + Shift + Down + + + + Open + 開啟 + + + + Ctrl + Down + Ctrl + Down + + + + To parent directory + 返回上層資料夾 + + + + Ctrl + Up + Ctrl + Up + + + + Permanently delete + 完全刪除 + + + + Shift + Delete + Shift + Delete + + + + Delete file + 刪除檔案 + + + + Delete + 刪除 + + + + Select all + 全選 + + + + Ctrl + A + Ctrl + A + + + + Ctrl + C + Ctrl + C + + + + Ctrl + X + Ctrl + X + + + + Ctrl + V + Ctrl + V + + + + Ctrl + N + Ctrl + N + + + + Ctrl + Shift + N + Ctrl + Shift + N + + + + Ctrl + F + Ctrl + F + + + + Ctrl + T + Ctrl + T + + + + Ctrl + I + Ctrl + I + + + + Ctrl + H + Ctrl + H + + + + Ctrl + L + Ctrl + L + + + + Ctrl + W + Ctrl + W + + + + Copy + 複製文件 + + + + Cut + 剪下文件 + + + + Paste + 貼上文件 + + + + Rename + 重新命名 + + + + F2 + F2 + + + + New/Search + 新增╱搜尋 + + + + New window + 新增視窗 + + + + New folder + 新增資料夾 + + + + + Search + 搜尋 + + + + New tab + 新增分頁 + + + + View + 檢視 + + + + Item information + 項目內容 + + + + Help + 說明 + + + + F1 + F1 + + + + Keyboard shortcuts + 鍵盤快速鍵 + + + + Ctrl + Shift + / + Ctrl + Shift + / + + + + Switch display status + 切換顯示狀態 + + + + Hide item + 隱藏項目 + + + + Input in address bar + 位址列輸入 + + + + Switch to icon view + 切換到圖示檢視 + + + + Ctrl + 1 + Ctrl + 1 + + + + Switch to list view + 切換到列表檢視 + + + + Ctrl + 2 + Ctrl + 2 + + + + Others + 其他 + + + + Close + 關閉視窗 + + + + Alt + F4 + Alt + F4 + + + + Close current tab + 關閉目前分頁 + + + + Back + 上一頁 + + + + Alt + Left + Alt + Left + + + + Alt + Right + Alt + Right + + + + Switch to next tab + 切換到下個分頁 + + + + Ctrl + Tab + Ctrl + Tab + + + + Ctrl + Shift + Tab + Ctrl + Shift + Tab + + + + Switch to previous tab + 切換到上個分頁 + + + + Next file + 下個項目 + + + + Tab + Tab + + + + Previous file + 上個項目 + + + + Shift + Tab + Shift + Tab + + + + Switch tab by specified number between 1 to 8 + 透過數字 1 到 8 切換到指定分頁 + + + + Alt + [1-8] + Alt + [1-8] + + + + Forward + 下一頁 + + + + TrashManager + + + + Unable to open items in the trash, please restore it first + 無法打開回收站中的項目,請先還原 + + + + TrashPropertyDialog + + + Trash + 回收桶 + + + + item + 項目 + + + + items + 項目 + + + + Contains %1 %2 + 包含 %1 %2 + + + + UDiskListener + + + Failed to rename the label + 無法重新命名標籤 + + + + UnmountWorker + + + + + The device was not safely unmounted + 裝置沒有正常移除 + + + + The device was not safely removed + 裝置沒有正常移除 + + + + UserShareManager + + + Kindly Reminder + 提醒 + + + + Please firstly install samba to continue + 請先安裝 Samba 後再繼續 + + + + + The share name must not contain %<>*?|/\+=;:," and should not start with %1 + 共享名不得包含%<>*?|/\+=;:,",且不能以%1開頭 + + + + To protect the files, you cannot share this folder. + 為了文件安全,無法共享此資料夾。 + + + + Sharing failed + 共享失敗 + + + + The computer name is too long + 計算機名過長 + + + + You do not have permission to operate file/folder! + 你無權對檔案或資料夾進行操作! + + + + UserSharePasswordSettingDialog + + + Enter a password to protect shared folders + 請輸入共享密碼 + + + + Cancel + button + 取 消 + + + + Confirm + button + 確 定 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/update_translations.sh b/dde-file-manager-5.5.3/src/dde-file-manager-lib/update_translations.sh new file mode 100755 index 0000000..1ff5582 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/update_translations.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# this file is used to auto update ts file. + +lupdate -ts translations/dde-file-manager.ts -no-obsolete +lupdate -ts translations/dde-file-manager_zh_CN.ts -no-obsolete \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/interfaceactivevault.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/interfaceactivevault.cpp new file mode 100644 index 0000000..44eb8b0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/interfaceactivevault.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "interfaceactivevault.h" +#include "operatorcenter.h" + +InterfaceActiveVault::InterfaceActiveVault(QObject *parent) + : QObject(parent) +{ + +} + +InterfaceActiveVault::~InterfaceActiveVault() +{ + +} + +QString InterfaceActiveVault::getPassword() +{ + return OperatorCenter::getInstance()->getSaltAndPasswordCipher(); +} + +bool InterfaceActiveVault::getPasswordHint(QString &passwordHint) +{ + return OperatorCenter::getInstance()->getPasswordHint(passwordHint); +} + +bool InterfaceActiveVault::checkPassword(const QString &password, QString &cipher) +{ + return OperatorCenter::getInstance()->checkPassword(password, cipher); +} + +bool InterfaceActiveVault::checkUserKey(const QString &userKey, QString &cipher) +{ + return OperatorCenter::getInstance()->checkUserKey(userKey, cipher); +} + +QString InterfaceActiveVault::getEncryptDir() +{ + return OperatorCenter::getInstance()->getEncryptDirPath(); +} + +QString InterfaceActiveVault::getDecryptDir() +{ + return OperatorCenter::getInstance()->getdecryptDirPath(); +} + +QStringList InterfaceActiveVault::getConfigFilePath() +{ + return OperatorCenter::getInstance()->getConfigFilePath(); +} + +EN_VaultState InterfaceActiveVault::vaultState() +{ + return OperatorCenter::getInstance()->vaultState(); +} + +bool InterfaceActiveVault::getRootPassword() +{ + return OperatorCenter::getInstance()->getRootPassword(); +} + +int InterfaceActiveVault::executionShellCommand(const QString &strCmd, QStringList &lstShellOutput) +{ + return OperatorCenter::getInstance()->executionShellCommand(strCmd, lstShellOutput); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/interfaceactivevault.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/interfaceactivevault.h new file mode 100644 index 0000000..5a5c8d0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/interfaceactivevault.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef INTERFACEACTIVEVAULT_H +#define INTERFACEACTIVEVAULT_H + +#include "vaultglobaldefine.h" + +#include + +class InterfaceActiveVault : public QObject +{ + Q_OBJECT +public: + explicit InterfaceActiveVault(QObject *parent = nullptr); + ~InterfaceActiveVault(); + + /** + * @brief getPassword 获取密码 + * @return + */ + static QString getPassword(); + + /** + * @brief getPasswordHint 获得密码提示信息 + * @param passwordHint 返回密码提示 + * @return 是否成功 + */ + static bool getPasswordHint(QString &passwordHint); + + /** + * @brief checkPassword 验证密码是否正确 + * @param password 密码 + * @param cipher 返回密码的密文 + * @return 是否成功 + */ + static bool checkPassword(const QString &password, QString &cipher); + + /** + * @brief checkUserKey 验证密钥是否正确 + * @param userKey 密钥 + * @param cipher 返回密码的密文 + * @return 是否成功 + */ + static bool checkUserKey(const QString &userKey, QString &cipher); + + + /** + * @brief getEncryptedDir 获得加密文件夹路径 + * @return + */ + static QString getEncryptDir(); + + /** + * @brief getDecryptDir 获得解密文件夹路径 + * @return + */ + static QString getDecryptDir(); + + /** + * @brief getConfigFilePath + * @return + */ + static QStringList getConfigFilePath(); + + /** + * @brief vaultState // 获得保险箱状态 + * @return + */ + static EN_VaultState vaultState(); + + /** + * @brief getRootPassword 管理员权限认证 + * @return + */ + static bool getRootPassword(); + + /** + * @brief executionShellCommand 执行shell命令并获得shell命令的返回值 + * @param strCmd 要执行的shell命令 + * @param lstShellOutput shell命令返回的结果 + * @return 返回值为0表示成功,其它都不成功 + */ + static int executionShellCommand(const QString &strCmd, QStringList &lstShellOutput); + +signals: + +public slots: + +private: + +}; + +#endif // INTERFACEACTIVEVAULT_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/openssl-operator/pbkdf2.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/openssl-operator/pbkdf2.cpp new file mode 100644 index 0000000..05139e5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/openssl-operator/pbkdf2.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "pbkdf2.h" + +#include +#include +#include +#include + +char pbkdf2::charToHexadecimalChar(char nibble) +{ + char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + return buf[nibble & 0xF]; +} + +char *pbkdf2::octalToHexadecimal(const char *str, int length) +{ + const char *s = str; + int i = 0; + length *= 2; + + if (length > CIPHER_LENGHT_MAX) + length = CIPHER_LENGHT_MAX - 1; + + char *bit_string = reinterpret_cast(malloc(size_t(length + 1))); + + for (i = 0; i < length; i += 2) { + bit_string[i] = charToHexadecimalChar(*s >> 4); + bit_string[i + 1] = charToHexadecimalChar(*s & 0xF); + s++; + } + bit_string[i] = 0; + + return bit_string; +} + +// 生成随机盐 +QString pbkdf2::createRandomSalt(int byte) + +{ + BIGNUM *rnd = BN_new(); + int bits = byte * 4; + int top = 0, bottom = 0; + BN_rand(rnd, bits, top, bottom); + + char *cstr = BN_bn2hex(rnd); + QString strRandSalt = QString::fromUtf8(QByteArray(cstr)); + BN_free(rnd); + + return strRandSalt; + +} + +QString pbkdf2::pbkdf2EncrypyPassword(const QString &password, const QString &randSalt, int iteration, int cipherByteNum) +{ + if (cipherByteNum < 0 || cipherByteNum % 2 != 0) { + qDebug() << "cipherByteNum can't less than zero and must be even!"; + return ""; + } + // 字节长度 + int nCipherLength = cipherByteNum / 2; + + // 格式化随机盐 + uchar salt_value[SALT_LENGTH_MAX]; + memset(salt_value, 0, SALT_LENGTH_MAX); + int nSaltLength = randSalt.length(); + for (int i = 0; i < nSaltLength; i++) { + salt_value[i] = uchar(randSalt.at(i).toLatin1()); + } + + // 生成密文 + QString strCipherText(""); + uchar *out = reinterpret_cast(malloc(size_t(cipherByteNum / 2 + 1))); + memset(out, 0, size_t(cipherByteNum / 2 + 1)); + // 修复bug-51478 + // 修复bug-60724 + std::string strPassword = password.toStdString(); + const char *pwd = strPassword.c_str(); + if (PKCS5_PBKDF2_HMAC_SHA1(pwd, password.length(), + salt_value, randSalt.length(), + iteration, + nCipherLength, + out) != 0) { + char *pstr = octalToHexadecimal(reinterpret_cast(out), nCipherLength); + // 修复bug-51478 + strCipherText = QString(pstr); + if (pstr) + free(pstr); + } else { + qDebug() << "PKCS5_PBKDF2_HMAC_SHA1 failed"; + } + free(out); + return strCipherText; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/openssl-operator/pbkdf2.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/openssl-operator/pbkdf2.h new file mode 100644 index 0000000..573f8ab --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/openssl-operator/pbkdf2.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef PBKDF2_H +#define PBKDF2_H + +#define SALT_LENGTH_MAX 100 +#define CIPHER_LENGHT_MAX 100 + +class QString; + +class pbkdf2 +{ +public: + /** + * @brief createRandomSalt 创建随机数(十六进制字符串) + * @param byte 字符串的字节数 + * @return 随机字符串 + */ + static QString createRandomSalt(int byte); + + /** + * @brief pbkdf2EncrypyPassword PBKDF2加密密码 + * @param password 密码 + * @param randSalt 随机盐 + * @param iteration 迭代次数 + * @param cipherByteNum 生成密文的字节数 + * @return 加密后的密文 + */ + static QString pbkdf2EncrypyPassword(const QString &password, + + const QString &randSalt, + + int iteration, + + int cipherByteNum); + +private: + static char charToHexadecimalChar(char nibble); + static char *octalToHexadecimal(const char *str, int length); + +}; + + + + +#endif // PBKDF2_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/openssl-operator/rsam.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/openssl-operator/rsam.cpp new file mode 100644 index 0000000..738d506 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/openssl-operator/rsam.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "rsam.h" + +#include + +#include +#include + +bool rsam::createPublicAndPrivateKey(QString &publicKey, QString &privateKey) + +{ + // 创建rsa对象 + RSA *pRsa = RSA_new(); + BIGNUM *pNum = BN_new(); + BN_set_word(pNum, RSA_F4); + int nRet = RSA_generate_key_ex(pRsa, KEY_LENGTH, pNum, nullptr); + if (nRet != 1) { + qDebug() << "RSA_generate_key_ex 失败!"; + return false; + } + + // 创建私钥对象 + BIO *pPrivateBio = BIO_new(BIO_s_mem()); + PEM_write_bio_RSAPrivateKey(pPrivateBio, pRsa, nullptr, nullptr, 0, nullptr, nullptr); + + // 创建公钥对象 + BIO *pPublicBio = BIO_new(BIO_s_mem()); + PEM_write_bio_RSAPublicKey(pPublicBio, pRsa); + + // 获得私钥长度 + int nPrivateKeyLen = BIO_pending(pPrivateBio); + // 获得公钥长度 + int nPublicKeyLen = BIO_pending(pPublicBio); + + // 获得私钥 + char *pPrivateKey = new char[nPrivateKeyLen]; + BIO_read(pPrivateBio, pPrivateKey, nPrivateKeyLen); + // 获得公钥 + char *pPublicKey = new char[nPublicKeyLen]; + BIO_read(pPublicBio, pPublicKey, nPublicKeyLen); + + // 将私钥转化为QByte + privateKey = QByteArray(pPrivateKey, nPrivateKeyLen); + // 将公钥转化成QByte + publicKey = QByteArray(pPublicKey, nPublicKeyLen); + + + // 销毁对象 + RSA_free(pRsa); + BN_free(pNum); + BIO_free_all(pPrivateBio); + BIO_free_all(pPublicBio); + delete[] pPrivateKey; + delete[] pPublicKey; + + return true; +} + +// 私钥加密 +QString rsam::privateKeyEncrypt(const QString &password, const QString &privateKey) +{ + // 转化私钥 + QByteArray privateKeyArry = privateKey.toUtf8(); + uchar *pPrivateKey = reinterpret_cast(privateKeyArry.data()); + BIO *pPrivateKeyBio = BIO_new_mem_buf(pPrivateKey, privateKey.length()); + if (pPrivateKeyBio == nullptr) { + qDebug() << "BIO_new_mem_buf 失败!"; + return ""; + } + + RSA *pRsa = RSA_new(); + pRsa = PEM_read_bio_RSAPrivateKey(pPrivateKeyBio, &pRsa, nullptr, nullptr); + if (pRsa == nullptr) { + BIO_free_all(pPrivateKeyBio); + qDebug() << "PEM_read_bio_RSAPrivateKey 失败!"; + return ""; + } + + int nLength = RSA_size(pRsa); + char *strCiphertext = new char[nLength]; + memset(strCiphertext, 0, size_t(nLength)); + QByteArray passwordArry = password.toUtf8(); + int npasswordLen = passwordArry.length(); + uchar *pPasswordData = reinterpret_cast(passwordArry.data()); + int nSize = RSA_private_encrypt(npasswordLen, + pPasswordData, + reinterpret_cast(strCiphertext), + pRsa, + RSA_PKCS1_PADDING); + + QString qstrCiphertext = ""; + if (nSize >= 0) { + QByteArray arry(strCiphertext, nSize); + qstrCiphertext = arry.toBase64(); + } + + // 销毁对象 + delete[] strCiphertext; + BIO_free_all(pPrivateKeyBio); + RSA_free(pRsa); + + return qstrCiphertext; +} + +// 公钥解密 +QString rsam::publicKeyDecrypt(const QString &ciphertext, const QString &publicKey) +{ + QByteArray publickKeyArry = publicKey.toUtf8(); + uchar *pPublicKey = reinterpret_cast(publickKeyArry.data()); + BIO *pPublicKeyBio = BIO_new_mem_buf(pPublicKey, publicKey.length()); + if (pPublicKeyBio == nullptr) { + qDebug() << "BIO_new_mem_buf 失败!"; + return ""; + } + + RSA *pRsa = RSA_new(); + if (publicKey.contains(KEY_BEGIN)) { + pRsa = PEM_read_bio_RSAPublicKey(pPublicKeyBio, &pRsa, nullptr, nullptr); + } else { + pRsa = PEM_read_bio_RSA_PUBKEY(pPublicKeyBio, &pRsa, nullptr, nullptr); + } + + if (!pRsa) { + qDebug() << "PEM_read_bio_RSAPublicKey 失败!"; + return ""; + } + + int nLen = RSA_size(pRsa); + char *passwordBuf = new char[nLen]; + memset(passwordBuf, 0, size_t(nLen)); + + // 解密 + QByteArray ciphertextArry = ciphertext.toUtf8(); + ciphertextArry = QByteArray::fromBase64(ciphertextArry); + int nCiphertextLen = ciphertextArry.length(); + uchar *pCiphertextData = reinterpret_cast(ciphertextArry.data()); + int nSize = RSA_public_decrypt(nCiphertextLen, + pCiphertextData, + reinterpret_cast(passwordBuf), + pRsa, + RSA_PKCS1_PADDING); + QString qstrPassword = ""; + if (nSize >= 0) { + qstrPassword = QByteArray(passwordBuf, nSize); + } + + // 销毁对象 + delete[] passwordBuf; + BIO_free_all(pPublicKeyBio); + RSA_free(pRsa); + + return qstrPassword; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/openssl-operator/rsam.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/openssl-operator/rsam.h new file mode 100644 index 0000000..b784711 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/openssl-operator/rsam.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef RSAM_H +#define RSAM_H + +#include + +#define KEY_LENGTH 2048 // 密钥的长度 +#define KEY_BEGIN "BEGIN RSA PUBLIC KEY" // 代码生成key + +class rsam +{ +public: + /** + * @brief createPublicAndPrivateKey 生成公钥和私钥对 + * @param publicKey 公钥 + * @param privateKey 私钥 + * @return 是否成功 + */ + static bool createPublicAndPrivateKey(QString &publicKey, QString &privateKey); + + /** + * @brief privateKeyEncrypt 私钥加密密码,生成密文 + * @param password 密码 + * @param privateKey 私钥 + * @return 密文 + */ + static QString privateKeyEncrypt(const QString &password, const QString &privateKey); + + /** + * @brief publicKeyDecrypt 公钥解密密文,获得密码 + * @param ciphertext 密文 + * @param strPubKey 公钥 + * @return 密码 + */ + static QString publicKeyDecrypt(const QString &ciphertext, const QString &publicKey); +}; + + + + +#endif // RSAM_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/operatorcenter.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/operatorcenter.cpp new file mode 100644 index 0000000..f971751 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/operatorcenter.cpp @@ -0,0 +1,636 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "operatorcenter.h" +#include "openssl-operator/pbkdf2.h" +#include "openssl-operator/rsam.h" +#include "qrencode/qrencode.h" +#include "vaultconfig.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +OperatorCenter::OperatorCenter(QObject *parent) + : QObject(parent), m_strCryfsPassword(""), m_strUserKey(""), m_standOutput("") +{ +} + +QString OperatorCenter::makeVaultLocalPath(const QString &before, const QString &behind) +{ + return VAULT_BASE_PATH + // + QDir::separator() + CONFIG_DIR_NAME + + (before.isEmpty() ? QString("") : QDir::separator()) + before + + (behind.isEmpty() ? QString("") : QDir::separator()) + behind; +} + +bool OperatorCenter::runCmd(const QString &cmd) +{ + QProcess process; + int mescs = 10000; + if (cmd.startsWith(ROOT_PROXY)) { + mescs = -1; + } + process.start(cmd); + + bool res = process.waitForFinished(mescs); + m_standOutput = process.readAllStandardOutput(); + int exitCode = process.exitCode(); + if (cmd.startsWith(ROOT_PROXY) && (exitCode == 127 || exitCode == 126)) { + QString strOut = "Run \'" + cmd + "\' fauled: Password Error! " + QString::number(exitCode) + "\n"; + qDebug() << strOut; + return false; + } + + if (res == false) { + QString strOut = "Run \'" + cmd + "\' failed\n"; + qDebug() << strOut; + } + + return res; +} + +bool OperatorCenter::executeProcess(const QString &cmd) +{ + if (false == cmd.startsWith("sudo")) { + return runCmd(cmd); + } + + runCmd("id -un"); + if (m_standOutput.trimmed() == "root") { + return runCmd(cmd); + } + + QString newCmd = QString(ROOT_PROXY) + " \""; + newCmd += cmd; + newCmd += "\""; + newCmd.remove("sudo"); + return runCmd(newCmd); +} + +bool OperatorCenter::secondSaveSaltAndCiphertext(const QString &ciphertext, const QString &salt, const char *vaultVersion) +{ + // 密文 + QString strCiphertext = pbkdf2::pbkdf2EncrypyPassword(ciphertext, salt, ITERATION_TWO, PASSWORD_CIPHER_LENGTH); + if (strCiphertext.isEmpty()) + return false; + // 写入文件 + QString strSaltAndCiphertext = salt + strCiphertext; + VaultConfig config; + config.set(CONFIG_NODE_NAME, CONFIG_KEY_CIPHER, QVariant(strSaltAndCiphertext)); + // 更新保险箱版本信息 + config.set(CONFIG_NODE_NAME, CONFIG_KEY_VERSION, QVariant(vaultVersion)); + + return true; +} + +bool OperatorCenter::createKeyNew(const QString &password) +{ + m_strPubKey.clear(); + QString strPriKey(""); + rsam::createPublicAndPrivateKey(m_strPubKey, strPriKey); + + // 私钥加密 + QString strCipher = rsam::privateKeyEncrypt(password, strPriKey); + + // 验证公钥长度 + if (m_strPubKey.length() < 2 * USER_KEY_INTERCEPT_INDEX + 32) { + qDebug() << "USER_KEY_LENGTH is to long!"; + m_strPubKey.clear(); + return false; + } + + // 保存密文 + QString strCipherFilePath = makeVaultLocalPath(RSA_CIPHERTEXT_FILE_NAME); + QFile cipherFile(strCipherFilePath); + if (!cipherFile.open(QIODevice::Text | QIODevice::WriteOnly | QIODevice::Truncate)) { + qDebug() << "open rsa cipher file failure!"; + return false; + } + QTextStream out2(&cipherFile); + out2 << strCipher; + cipherFile.close(); + + return true; +} + +bool OperatorCenter::saveKey(QString key, QString path) +{ + // 保存部分公钥 + QString publicFilePath = path; + QFile publicFile(publicFilePath); + if (!publicFile.open(QIODevice::Text | QIODevice::WriteOnly | QIODevice::Truncate)) { + qDebug() << "open public key file failure!"; + return false; + } + publicFile.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ReadGroup); + QTextStream out(&publicFile); + out << key; + publicFile.close(); + return true; +} + +QString OperatorCenter::getPubKey() +{ + return m_strPubKey; +} + +bool OperatorCenter::verificationRetrievePassword(const QString keypath, QString &password) +{ + QFile localPubKeyfile(keypath); + if (!localPubKeyfile.open(QIODevice::Text | QIODevice::ReadOnly)) { + qDebug() << "cant't open local public key file!"; + return false; + } + + QString strLocalPubKey(localPubKeyfile.readAll()); + localPubKeyfile.close(); + + // 利用完整公钥解密密文,得到密码 + QString strRSACipherFilePath = makeVaultLocalPath(RSA_CIPHERTEXT_FILE_NAME); + QFile rsaCipherfile(strRSACipherFilePath); + if (!rsaCipherfile.open(QIODevice::Text | QIODevice::ReadOnly)) { + qDebug() << "cant't open rsa cipher file!"; + return false; + } + + QString strRsaCipher(rsaCipherfile.readAll()); + rsaCipherfile.close(); + + password = rsam::publicKeyDecrypt(strRsaCipher, strLocalPubKey); + + // 判断密码的正确性,如果密码正确,则用户密钥正确,否则用户密钥错误 + QString temp = ""; + if (!checkPassword(password, temp)) { + qDebug() << "user key error!"; + return false; + } + + return true; +} + +OperatorCenter *OperatorCenter::getInstance() +{ + static OperatorCenter instance; + return &instance; +} + +OperatorCenter::~OperatorCenter() +{ +} + +bool OperatorCenter::createDirAndFile() +{ + // 创建配置文件目录 + QString strConfigDir = makeVaultLocalPath(); + QDir configDir(strConfigDir); + if (!configDir.exists()) { + bool ok = configDir.mkpath(strConfigDir); + if (!ok) { + qDebug() << "create config dir failure!"; + return false; + } + } + + // 创建配置文件,并设置文件权限 + QString strConfigFilePath = strConfigDir + QDir::separator() + VAULT_CONFIG_FILE_NAME; + QFile configFile(strConfigFilePath); + if (!configFile.exists()) { + // 如果文件不存在,则创建文件,并设置权限 + if (configFile.open(QFileDevice::WriteOnly | QFileDevice::Text)) { + configFile.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ReadGroup); + configFile.close(); + } else { + qInfo() << "保险箱:创建配置文件失败!"; + } + } + + // 创建存放rsa公钥的文件,并设置文件权限 + QString strPriKeyFile = makeVaultLocalPath(RSA_PUB_KEY_FILE_NAME); + QFile prikeyFile(strPriKeyFile); + if (!prikeyFile.open(QIODevice::WriteOnly | QIODevice::Append)) { + qDebug() << "create rsa private key file failure!"; + return false; + } + prikeyFile.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ReadGroup); + prikeyFile.close(); + + // 创建存放rsa公钥加密后密文的文件,并设置文件权限 + QString strRsaCiphertext = makeVaultLocalPath(RSA_CIPHERTEXT_FILE_NAME); + QFile rsaCiphertextFile(strRsaCiphertext); + if (!rsaCiphertextFile.open(QIODevice::WriteOnly | QIODevice::Append)) { + qDebug() << "create rsa ciphertext file failure!"; + return false; + } + rsaCiphertextFile.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ReadGroup); + rsaCiphertextFile.close(); + + // 创建密码提示信息文件,并设置文件权限 + QString strPasswordHintFilePath = makeVaultLocalPath(PASSWORD_HINT_FILE_NAME); + QFile passwordHintFile(strPasswordHintFilePath); + if (!passwordHintFile.open(QIODevice::WriteOnly | QIODevice::Append)) { + qDebug() << "create password hint file failure!"; + return false; + } + passwordHintFile.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ReadGroup); + passwordHintFile.close(); + + return true; +} + +bool OperatorCenter::saveSaltAndCiphertext(const QString &password, const QString &passwordHint) +{ + // 加密密码,并将盐和密文写入密码文件 + // 随机盐 + QString strRandomSalt = pbkdf2::createRandomSalt(RANDOM_SALT_LENGTH); + // 密文 + QString strCiphertext = pbkdf2::pbkdf2EncrypyPassword(password, strRandomSalt, ITERATION, PASSWORD_CIPHER_LENGTH); + // 组合盐值与密文 + QString strSaltAndCiphertext = strRandomSalt + strCiphertext; + + // 保存第二次加密后的密文,并更新保险箱版本信息 + secondSaveSaltAndCiphertext(strSaltAndCiphertext, strRandomSalt, CONFIG_VAULT_VERSION_1050); + + // 保存密码提示信息 + QString strPasswordHintFilePath = makeVaultLocalPath(PASSWORD_HINT_FILE_NAME); + QFile passwordHintFile(strPasswordHintFilePath); + if (!passwordHintFile.open(QIODevice::Text | QIODevice::WriteOnly | QIODevice::Truncate)) { + qDebug() << "write password hint failure"; + return false; + } + QTextStream out2(&passwordHintFile); + out2 << passwordHint; + passwordHintFile.close(); + + // 缓存cryfs密码 + m_strCryfsPassword = strSaltAndCiphertext; + + return true; +} + +bool OperatorCenter::createKey(const QString &password, int bytes) +{ + // 清空上次的用户密钥 + m_strUserKey.clear(); + + // 创建密钥对 + QString strPriKey(""); + QString strPubKey(""); + rsam::createPublicAndPrivateKey(strPubKey, strPriKey); + + // 私钥加密 + QString strCipher = rsam::privateKeyEncrypt(password, strPriKey); + + // 将公钥分成两部分(一部分用于保存到本地,一部分生成二维码,提供给用户) + QString strSaveToLocal(""); + if (strPubKey.length() < 2 * USER_KEY_INTERCEPT_INDEX + bytes) { + qDebug() << "USER_KEY_LENGTH is to long!"; + return false; + } + QString strPart1 = strPubKey.mid(0, USER_KEY_INTERCEPT_INDEX); + QString strPart2 = strPubKey.mid(USER_KEY_INTERCEPT_INDEX, USER_KEY_LENGTH); + QString strPart3 = strPubKey.mid(USER_KEY_INTERCEPT_INDEX + USER_KEY_LENGTH); + m_strUserKey = strPart2; + strSaveToLocal = strPart1 + strPart3; + + // 保存部分公钥 + QString publicFilePath = makeVaultLocalPath(RSA_PUB_KEY_FILE_NAME); + QFile publicFile(publicFilePath); + if (!publicFile.open(QIODevice::Text | QIODevice::WriteOnly | QIODevice::Truncate)) { + qDebug() << "open public key file failure!"; + return false; + } + QTextStream out(&publicFile); + out << strSaveToLocal; + publicFile.close(); + + // 保存密文 + QString strCipherFilePath = makeVaultLocalPath(RSA_CIPHERTEXT_FILE_NAME); + QFile cipherFile(strCipherFilePath); + if (!cipherFile.open(QIODevice::Text | QIODevice::WriteOnly | QIODevice::Truncate)) { + qDebug() << "open rsa cipher file failure!"; + return false; + } + QTextStream out2(&cipherFile); + out2 << strCipher; + cipherFile.close(); + + return true; +} + +bool OperatorCenter::checkPassword(const QString &password, QString &cipher) +{ + // 获得版本信息 + VaultConfig config; + QString strVersion = config.get(CONFIG_NODE_NAME, CONFIG_KEY_VERSION).toString(); + + if ((CONFIG_VAULT_VERSION == strVersion) || (CONFIG_VAULT_VERSION_1050 == strVersion)) { // 如果是新版本,验证第二次加密的结果 + // 获得本地盐及密文 + QString strSaltAndCipher = config.get(CONFIG_NODE_NAME, CONFIG_KEY_CIPHER).toString(); + QString strSalt = strSaltAndCipher.mid(0, RANDOM_SALT_LENGTH); + QString strCipher = strSaltAndCipher.mid(RANDOM_SALT_LENGTH); + // pbkdf2第一次加密密码,获得密文 + QString strNewCipher = pbkdf2::pbkdf2EncrypyPassword(password, strSalt, ITERATION, PASSWORD_CIPHER_LENGTH); + // 组合密文和盐值 + QString strNewSaltAndCipher = strSalt + strNewCipher; + // pbkdf2第二次加密密码,获得密文 + QString strNewCipher2 = pbkdf2::pbkdf2EncrypyPassword(strNewSaltAndCipher, strSalt, ITERATION_TWO, PASSWORD_CIPHER_LENGTH); + + if (strCipher != strNewCipher2) { + qDebug() << "password error!"; + return false; + } + cipher = strNewSaltAndCipher; + } else { // 如果是旧版本,验证第一次加密的结果 + // 获得本地盐及密文 + QString strfilePath = makeVaultLocalPath(PASSWORD_FILE_NAME); + QFile file(strfilePath); + if (!file.open(QIODevice::Text | QIODevice::ReadOnly)) { + qDebug() << "open pbkdf2cipher file failure!"; + return false; + } + QString strSaltAndCipher = QString(file.readAll()); + file.close(); + QString strSalt = strSaltAndCipher.mid(0, RANDOM_SALT_LENGTH); + QString strCipher = strSaltAndCipher.mid(RANDOM_SALT_LENGTH); + + // pbkdf2加密密码,获得密文 + QString strNewCipher = pbkdf2::pbkdf2EncrypyPassword(password, strSalt, ITERATION, PASSWORD_CIPHER_LENGTH); + QString strNewSaltAndCipher = strSalt + strNewCipher; + if (strNewSaltAndCipher != strSaltAndCipher) { + qDebug() << "password error!"; + return false; + } + + cipher = strNewSaltAndCipher; + + // 保存第二次加密后的密文,并更新保险箱版本信息 + if (!secondSaveSaltAndCiphertext(strNewSaltAndCipher, strSalt, CONFIG_VAULT_VERSION)) { + qDebug() << "第二次加密密文失败!"; + return false; + } + + // 删除旧版本遗留的密码文件 + QFile::remove(strfilePath); + } + return true; +} + +bool OperatorCenter::checkUserKey(const QString &userKey, QString &cipher) +{ + if (userKey.length() != USER_KEY_LENGTH) { + qDebug() << "user key length error!"; + return false; + } + + // 结合本地公钥和用户密钥,还原完整公钥 + QString strLocalPubKeyFilePath = makeVaultLocalPath(RSA_PUB_KEY_FILE_NAME); + QFile localPubKeyfile(strLocalPubKeyFilePath); + if (!localPubKeyfile.open(QIODevice::Text | QIODevice::ReadOnly)) { + qDebug() << "cant't open local public key file!"; + return false; + } + QString strLocalPubKey(localPubKeyfile.readAll()); + localPubKeyfile.close(); + + QString strNewPubKey = strLocalPubKey.insert(USER_KEY_INTERCEPT_INDEX, userKey); + + // 利用完整公钥解密密文,得到密码 + QString strRSACipherFilePath = makeVaultLocalPath(RSA_CIPHERTEXT_FILE_NAME); + QFile rsaCipherfile(strRSACipherFilePath); + if (!rsaCipherfile.open(QIODevice::Text | QIODevice::ReadOnly)) { + qDebug() << "cant't open rsa cipher file!"; + return false; + } + QString strRsaCipher(rsaCipherfile.readAll()); + rsaCipherfile.close(); + + QString strNewPassword = rsam::publicKeyDecrypt(strRsaCipher, strNewPubKey); + + // 判断密码的正确性,如果密码正确,则用户密钥正确,否则用户密钥错误 + if (!checkPassword(strNewPassword, cipher)) { + qDebug() << "user key error!"; + return false; + } + + return true; +} + +QString OperatorCenter::getUserKey() +{ + return m_strUserKey; +} + +bool OperatorCenter::getPasswordHint(QString &passwordHint) +{ + QString strPasswordHintFilePath = makeVaultLocalPath(PASSWORD_HINT_FILE_NAME); + QFile passwordHintFile(strPasswordHintFilePath); + if (!passwordHintFile.open(QIODevice::Text | QIODevice::ReadOnly)) { + qDebug() << "open password hint file failure"; + return false; + } + passwordHint = QString(passwordHintFile.readAll()); + passwordHintFile.close(); + + return true; +} + +bool OperatorCenter::createQRCode(const QString &srcStr, int width, int height, QPixmap &pix) +{ + if (width < 1 || height < 1) { + qDebug() << "QR code width or height error"; + return false; + } + + QRcode *qrcode = QRcode_encodeString(srcStr.toStdString().c_str(), 2, QR_ECLEVEL_Q, QR_MODE_8, 1); + // 二维码图片大小 + qint32 temp_width = width; + qint32 temp_height = height; + + // 二维码的宽度(也是高度,正方向) + qint32 qrcode_width = qrcode->width > 0 ? qrcode->width : 1; + + // 二维码图片的缩放比例 + double scale_x = double(temp_width) / double(qrcode_width); + double scale_y = double(temp_height) / double(qrcode_width); + + // 生成二维码图片 + QImage mainimg = QImage(temp_width, temp_height, QImage::Format_ARGB32); + QPainter painter(&mainimg); + + QColor background(Qt::white); + painter.setBrush(background); + painter.setPen(Qt::NoPen); + painter.drawRect(0, 0, temp_width, temp_height); + + QColor foreground(Qt::black); + painter.setBrush(foreground); + for (qint32 y = 0; y < qrcode_width; y++) { + for (qint32 x = 0; x < qrcode_width; x++) { + unsigned char b = qrcode->data[y * qrcode_width + x]; + if (b & 0x01) { + QRectF r(x * scale_x, y * scale_y, scale_x, scale_y); + painter.drawRects(&r, 1); + } + } + } + + pix = QPixmap::fromImage(mainimg); + + if (qrcode) + QRcode_free(qrcode); + return true; +} + +EN_VaultState OperatorCenter::vaultState() +{ + QString cryfsBinary = QStandardPaths::findExecutable("cryfs"); + if (cryfsBinary.isEmpty()) { + return NotAvailable; + } + + if (QFile::exists(makeVaultLocalPath(VAULT_ENCRYPY_DIR_NAME, CRYFS_CONFIG_FILE_NAME))) { + QStorageInfo info(makeVaultLocalPath(VAULT_DECRYPT_DIR_NAME)); + if (info.isValid() && info.fileSystemType() == "fuse.cryfs") { + return Unlocked; + } + return Encrypted; + } else { + return NotExisted; + } +} + +QString OperatorCenter::getSaltAndPasswordCipher() +{ + return m_strCryfsPassword; +} + +void OperatorCenter::clearSaltAndPasswordCipher() +{ + m_strCryfsPassword.clear(); +} + +QString OperatorCenter::getEncryptDirPath() +{ + return makeVaultLocalPath(VAULT_ENCRYPY_DIR_NAME); +} + +QString OperatorCenter::getdecryptDirPath() +{ + return makeVaultLocalPath(VAULT_DECRYPT_DIR_NAME); +} + +QStringList OperatorCenter::getConfigFilePath() +{ + QStringList lstPath; + + lstPath << makeVaultLocalPath(PASSWORD_FILE_NAME); + lstPath << makeVaultLocalPath(RSA_PUB_KEY_FILE_NAME); + lstPath << makeVaultLocalPath(RSA_CIPHERTEXT_FILE_NAME); + lstPath << makeVaultLocalPath(PASSWORD_HINT_FILE_NAME); + + return lstPath; +} + +QString OperatorCenter::autoGeneratePassword(int length) +{ + if (length < 3) return ""; + qsrand(uint(QTime(0, 0, 0).secsTo(QTime::currentTime()))); + + QString strPassword(""); + + QString strNum("0123456789"); + strPassword += strNum.at(qrand() % 10); + + QString strSpecialChar("`~!@#$%^&*"); + strPassword += strSpecialChar.at(qrand() % 10); + + QString strABC("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + strPassword += strABC.at(qrand() % 10); + + QString strAllChar = strNum + strSpecialChar + strABC; + int nCount = length - 3; + for (int i = 0; i < nCount; ++i) { + strPassword += strAllChar.at(qrand() % 52); + } + return strPassword; +} + +bool OperatorCenter::getRootPassword() +{ + // 判断当前是否是管理员登陆 + bool res = runCmd("id -un"); // file path is fixed. So write cmd direct + if (res && m_standOutput.trimmed() == "root") { + return true; + } + + if (false == executeProcess("sudo whoami")) { + return false; + } + + return true; +} + +int OperatorCenter::executionShellCommand(const QString &strCmd, QStringList &lstShellOutput) +{ + FILE *fp; + + std::string sCmd = strCmd.toStdString(); + const char *cmd = sCmd.c_str(); + + // 命令为空 + if (strCmd.isEmpty()) { + qDebug() << "cmd is empty!"; + return -1; + } + + if ((fp = popen(cmd, "r")) == nullptr) { + perror("popen"); + qDebug() << QString("popen error: %s").arg(strerror(errno)); + return -1; + } else { + char buf[MAXLINE] = { '\0' }; + while (fgets(buf, sizeof(buf), fp)) { // 获得每行输出 + QString strLineOutput(buf); + if (strLineOutput.endsWith('\n')) + strLineOutput.chop(1); + lstShellOutput.push_back(strLineOutput); + } + + int res; + if ((res = pclose(fp)) == -1) { + qDebug() << "close popen file pointer fp error!"; + return res; + } else if (res == 0) { + return res; + } else { + qDebug() << QString("popen res is : %1").arg(res); + return res; + } + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/operatorcenter.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/operatorcenter.h new file mode 100644 index 0000000..3f95e61 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/operatorcenter.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef OPERATORCENTER_H +#define OPERATORCENTER_H + +#include "vaultglobaldefine.h" + +#include + +#include + +class OperatorCenter : public QObject +{ + Q_OBJECT +public: + static OperatorCenter *getInstance(); + ~OperatorCenter(); + + /** + * @brief createDirAndFile 创建保险箱目录及密钥文件 + * @return 是否成功 + */ + bool createDirAndFile(); + + /** + * @brief saveSaltAndCiphertext pbkdf2加密密码,并将盐和密文写入密码文件 + * @param password 密码 + * @param passwordHint 密码提示 + * @return 是否成功 + */ + bool saveSaltAndCiphertext(const QString &password, const QString &passwordHint); + + /** + * @brief createKey rsa生成密钥对,私钥加密密码,将密文写入文件,将一部分公钥写入文件(另一部分公钥提供给用户) + * @param password 密码 + * @param bytes 提供给用户的那部分公钥的长度 + * @return 是否成功 + */ + bool createKey(const QString &password, int bytes); + + /** + * @brief checkPassword 验证密码是否正确 + * @param password 密码 + * @param cipher 如果密码正确,返回加密后的密文,用于解锁保险箱 + * @return 是否正确 + */ + bool checkPassword(const QString &password, QString &cipher); + + /** + * @brief checkUserKey 验证用户密钥是否正确 + * @param userKey 用户密钥 + * @param cipher 如果密钥正确,返回加密后的密文,用于解锁保险箱 + * @return 是否正确 + */ + bool checkUserKey(const QString &userKey, QString &cipher); + + /** + * @brief getUserKey 获得用户密钥 + * @return 用户密钥 + */ + QString getUserKey(); + + /** + * @brief getPasswordHint 获取密码提示信息 + * @param passwordHint 返回提示信息 + * @return 是否成功 + */ + bool getPasswordHint(QString &passwordHint); + + /** + * @brief createQRCode 生成二维码 + * @param srcStr 数据源 + * @param width 二维码图片宽度 + * @param height 二维码图片高度 + * @param pix 返回二维码图片 + * @return 是否成功 + */ + bool createQRCode(const QString &srcStr, int width, int height, QPixmap &pix); + + //! 获取保险箱状态 + EN_VaultState vaultState(); + + //! 获取盐值及密码密文 + QString getSaltAndPasswordCipher(); + + //! 清除盐值及密码密文的缓存 + void clearSaltAndPasswordCipher(); + + //! 获得加密文件夹路径 + QString getEncryptDirPath(); + //! 获得解密文件夹路径 + QString getdecryptDirPath(); + + //! 获得配置文件路径 + QStringList getConfigFilePath(); + + //! 随即生成密码 + QString autoGeneratePassword(int minLength); + + //! 管理员权限认证 + bool getRootPassword(); + + //! 执行shell命令并获得shell命令的返回值 + int executionShellCommand(const QString &strCmd, QStringList &lstShellOutput); + +private: + explicit OperatorCenter(QObject *parent = nullptr); + // 组织保险箱本地文件路径 + QString makeVaultLocalPath(const QString &before = "", const QString &behind = ""); + bool runCmd(const QString &cmd); + bool executeProcess(const QString &cmd); + // 保存第二次加密后的密文,并更新保险箱版本信息 + bool secondSaveSaltAndCiphertext(const QString &ciphertext, const QString &salt, const char *vaultVersion); + +public: + /** + * @brief createKeyNew rsa生成密钥对,私钥加密密码,将密文写入文件 + * @param in password 密码 + * @return 是否成功 + */ + bool createKeyNew(const QString &password); + + /** + * @brief saveKey 保存公钥 + * @param key 公钥 + * @param path 保存路径 + * @return + */ + bool saveKey(QString key, QString path); + + /** + * @brief getPubKey 获得密码公钥 + * @return 密码公钥 + */ + QString getPubKey(); + + /** + * @brief verificationRetrievePassword 验证用户密钥是否正确 + * @param1 in keypath 密钥文件 + * @param2 out password 密码 + * @return 是否正确 + */ + bool verificationRetrievePassword(const QString keypath, QString &password); + +private: + Dtk::Core::DSecureString m_strCryfsPassword; // cryfs密码 + QString m_strUserKey; + QString m_standOutput; + QString m_strPubKey; +}; + +#endif // OPERATORCENTER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/src.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/src.qrc new file mode 100644 index 0000000..4d8ed66 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/src.qrc @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vault.pri b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vault.pri new file mode 100644 index 0000000..39900bf --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vault.pri @@ -0,0 +1,50 @@ +DEFINES += HAVE_CONFIG_H + +3rd_srcdir = $$PWD/../../../3rdparty + +SOURCES += \ + $$3rd_srcdir/qrencode/bitstream.c \ + $$3rd_srcdir/qrencode/mask.c \ + $$3rd_srcdir/qrencode/mmask.c \ + $$3rd_srcdir/qrencode/mqrspec.c \ + $$3rd_srcdir/qrencode/qrencode.c \ + $$3rd_srcdir/qrencode/qrinput.c \ + $$3rd_srcdir/qrencode/rscode.c \ + $$3rd_srcdir/qrencode/split.c \ + $$3rd_srcdir/qrencode/qrspec.c \ + $$PWD/openssl-operator/pbkdf2.cpp \ + $$PWD/openssl-operator/rsam.cpp \ + $$PWD/interfaceactivevault.cpp \ + $$PWD/operatorcenter.cpp \ + $$PWD/vaultlockmanager.cpp \ + $$PWD/vaulthelper.cpp \ + $$PWD/vaultconfig.cpp + +HEADERS += \ + $$3rd_srcdir/qrencode/bitstream.h \ + $$3rd_srcdir/qrencode/config.h \ + $$3rd_srcdir/qrencode/mask.h \ + $$3rd_srcdir/qrencode/mmask.h \ + $$3rd_srcdir/qrencode/mqrspec.h \ + $$3rd_srcdir/qrencode/qrencode_inner.h \ + $$3rd_srcdir/qrencode/qrencode.h \ + $$3rd_srcdir/qrencode/qrinput.h \ + $$3rd_srcdir/qrencode/rscode.h \ + $$3rd_srcdir/qrencode/split.h \ + $$3rd_srcdir/qrencode/qrspec.h \ + $$PWD/openssl-operator/pbkdf2.h \ + $$PWD/openssl-operator/rsam.h \ + $$PWD/interfaceactivevault.h \ + $$PWD/operatorcenter.h \ + $$PWD/vaultglobaldefine.h \ + $$PWD/vaultlockmanager.h \ + $$PWD/vaulthelper.h \ + $$PWD/vaultconfig.h + +PKGCONFIG += libcrypto + +RESOURCES += + +INCLUDEPATH += $$PWD \ + $$3rd_srcdir + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultconfig.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultconfig.cpp new file mode 100644 index 0000000..ab55a24 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultconfig.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "vaultconfig.h" +#include "vaultglobaldefine.h" + +#include +#include + +VaultConfig::VaultConfig(const QString &filePath) + : m_filePath(filePath) +{ + if (filePath.isEmpty()) { + m_filePath = VAULT_BASE_PATH + QDir::separator() + VAULT_CONFIG_FILE_NAME; + } + m_pSetting = new QSettings(m_filePath, QSettings::IniFormat); +} + +VaultConfig::~VaultConfig() +{ + if (m_pSetting) + delete m_pSetting; + m_pSetting = nullptr; +} + +void VaultConfig::set(const QString &nodeName, const QString &keyName, QVariant value) +{ + m_pSetting->setValue(QString("/%1/%2").arg(nodeName).arg(keyName), value); +} + +QVariant VaultConfig::get(const QString &nodeName, const QString &keyName) +{ + QVariant var = m_pSetting->value(QString("/%1/%2").arg(nodeName).arg(keyName)); + return var; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultconfig.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultconfig.h new file mode 100644 index 0000000..e3c648a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultconfig.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef VAULTCONFIG_H +#define VAULTCONFIG_H + +#define CONFIG_NODE_NAME "INFO" +#define CONFIG_KEY_CIPHER "pbkgcipher" +#define CONFIG_KEY_VERSION "version" +#define CONFIG_VAULT_VERSION "new" +#define CONFIG_VAULT_VERSION_1050 "1050" + +#include + +QT_BEGIN_NAMESPACE +class QSettings; +QT_END_NAMESPACE + +class VaultConfig +{ +public: + explicit VaultConfig(const QString &filePath = ""); + ~VaultConfig(); + void set(const QString &nodeName, const QString &keyName, QVariant value); + QVariant get(const QString &nodeName, const QString &keyName); + +private: + QString m_filePath; + QSettings *m_pSetting; +}; + +#endif // VAULTCONFIG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultglobaldefine.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultglobaldefine.h new file mode 100644 index 0000000..48eb54d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultglobaldefine.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef VAULTGLOBALDEFINE_H +#define VAULTGLOBALDEFINE_H + +#include + +#define CONFIG_DIR_NAME "vault" +#define VAULT_DECRYPT_DIR_NAME "vault_unlocked" +#define VAULT_ENCRYPY_DIR_NAME "vault_encrypted" + +#define CRYFS_CONFIG_FILE_NAME "cryfs.config" + +#define PASSWORD_FILE_NAME "pbkdf2clipher" +#define RSA_PUB_KEY_FILE_NAME "rsapubkey" +#define RSA_CIPHERTEXT_FILE_NAME "rsaclipher" +#define PASSWORD_HINT_FILE_NAME "passwordHint" +#define VAULT_CONFIG_FILE_NAME "vaultConfig.ini" + + +#define RANDOM_SALT_LENGTH 10 // 随机盐的字节数 +#define ITERATION 1024 // pbkdf2迭代次数 +#define ITERATION_TWO 10000 // pbkdf2迭代次数 +#define PASSWORD_CIPHER_LENGTH 50 // 密码密文长度 +#define USER_KEY_LENGTH 32 // 用户密钥长度 +#define USER_KEY_INTERCEPT_INDEX 50 // 用户密钥从公钥中截取的起始点索引 + +#define ROOT_PROXY "pkexec deepin-vault-authenticateProxy" + +#define MAXLINE 1024 // shell命令输出每行最大的字符个数 + +#define VAULT_BASE_PATH (QDir::homePath() + QString("/.config/Vault")) //! 获取保险箱创建的目录地址 + +#define VAULT_BASE_PATH_OLD (QDir::homePath() + QString("/.local/share/applications")) //! 获取保险箱创建的旧目录地址 + +#define GET_COMPRESSOR_PID_SHELL(x) QString("ps -xo pid,cmd | grep /usr/bin/deepin-compressor | grep ")+x+QString(" | grep -v grep | awk '{print $1}'") + +//! 保险箱时间配置文件 +#define VAULT_TIME_CONFIG_FILE QString("/../dde-file-manager/vaultTimeConfig.json") + +enum EN_VaultState { + NotExisted = 0, + Encrypted, + Unlocked, + UnderProcess, + Broken, + NotAvailable +}; + +//! 保险箱当前页面标记 +enum VaultPageMark { + UNKNOWN, + CREATEVAULTPAGE, + CREATEVAULTPAGE1, + UNLOCKVAULTPAGE, + RETRIEVEPASSWORDPAGE, + DELETEFILEPAGE, + DELETEVAULTPAGE, + COPYFILEPAGE, + CLIPBOARDPAGE, + VAULTPAGE +}; + +#endif // VAULTGLOBALDEFINE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaulthelper.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaulthelper.cpp new file mode 100644 index 0000000..6c73cd0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaulthelper.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "singleton.h" +#include "app/define.h" +#include "vault/interfaceactivevault.h" +#include "vaulthelper.h" +#include "dialogs/dialogmanager.h" +#include "dialogs/dtaskdialog.h" +#include "controllers/vaultcontroller.h" + +#include +#include +#include + +DFM_BEGIN_NAMESPACE + +using namespace Dtk::Core; + +// 初始化静态变量 +bool VaultHelper::isModel = false; + +VaultHelper::VaultHelper(QObject *parent) : QObject(parent) +{ + +} + +bool VaultHelper::topVaultTasks() +{ + // 如果正在有保险箱的移动、粘贴、删除操作,置顶弹出任务框 + DTaskDialog *pTaskDlg = dialogManager->taskDialog(); + if (pTaskDlg) { + if (pTaskDlg->haveNotCompletedVaultTask()) { + // Flashing alert + pTaskDlg->hide(); + pTaskDlg->showDialogOnTop(); + return true; + } + } + // 如果当前有保险箱的压缩或解压缩任务,激活任务对话框进程 + QString strCmd = GET_COMPRESSOR_PID_SHELL(VAULT_BASE_PATH); + QStringList lstShellOutput; + // 执行shell命令,获得压缩进程PID + int res = InterfaceActiveVault::executionShellCommand(strCmd, lstShellOutput); + if (res == 0) { // shell命令执行成功 + QStringList::const_iterator itr = lstShellOutput.begin(); + QSet setResult; + for (; itr != lstShellOutput.end(); ++itr) { + setResult.insert(*itr); + } + if (setResult.count() > 0) { // 有压缩任务 + // 遍历桌面窗口 + bool bFlag = false; + for (auto window : DWindowManagerHelper::instance()->currentWorkspaceWindows()) { + QString strWid = QString("%1").arg(window->pid()); + // 如果当前窗口的进程PID属于压缩进程,则将窗口置顶 + if (setResult.contains(strWid)) { + window->raise(); + bFlag = true; + } + } + if (bFlag) { + return true; + } + } + } else { + qDebug() << "Failed to execute PID search command!"; + } + + //! 如果正在有保险箱的移动、粘贴到桌面的任务,通知桌面进程置顶任务对话框 + QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.FileManager1", + "/org/freedesktop/FileManager1", + "org.freedesktop.FileManager1", + "topTaskDialog"); + // 修复BUG-44055 设置超时等待为1000毫米,提高用户操作流畅度 + QDBusMessage response = QDBusConnection::sessionBus().call(message, QDBus::Block, 1000); + if (response.type() == QDBusMessage::ReplyMessage) { + bool bValue = response.arguments().takeFirst().toBool(); + if (bValue) { + return true; + } + } + + return false; +} + +bool VaultHelper::killVaultTasks() +{ + //! 如果正在有保险箱的移动、粘贴、删除操作,强行结束任务 + DTaskDialog *pTaskDlg = dialogManager->taskDialog(); + if (pTaskDlg) { + if (pTaskDlg->haveNotCompletedVaultTask()) { + pTaskDlg->stopVaultTask(); + } + } + + //! 如果当前有保险箱的压缩或解压缩任务,杀死任务对话框进程 + QString strCmd = GET_COMPRESSOR_PID_SHELL(VAULT_BASE_PATH); + QStringList lstShellOutput; + int res = InterfaceActiveVault::executionShellCommand(strCmd, lstShellOutput); + if (res == 0) { //! shell命令执行成功 + QStringList::const_iterator itr = lstShellOutput.begin(); + for (; itr != lstShellOutput.end(); ++itr) { + QString strCmd2 = QString("kill -9 %1").arg(*itr); + QStringList lstShellOutput2; + int res2 = InterfaceActiveVault::executionShellCommand(strCmd2, lstShellOutput2); + if (res2 == 0) + qDebug() << QString("杀死进程PID: %1 成功").arg(*itr); + } + } else { + qDebug() << "执行查找进程PID命令失败!"; + } + + //! 如果正在有保险箱的移动、粘贴到桌面的任务,通知桌面进程置结束当前保险箱的任务 + QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.FileManager1", + "/org/freedesktop/FileManager1", + "org.freedesktop.FileManager1", + "closeTask"); + // 设置超时等待为1000毫秒 + QDBusMessage response = QDBusConnection::sessionBus().call(message, QDBus::Block, 1000); + if (response.type() != QDBusMessage::ReplyMessage) { + qDebug() << "close vault task failed!"; + return false; + } + + return true; +} + +bool VaultHelper::isVaultEnabled() +{ + if (!DSysInfo::isCommunityEdition()) { // 如果不是社区版 + DSysInfo::DeepinType deepinType = DSysInfo::deepinType(); + // 如果是专业版 + if (DSysInfo::DeepinType::DeepinProfessional == deepinType && VaultController::ins()->isVaultVisiable()) { + return true ; + } + } + return false; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaulthelper.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaulthelper.h new file mode 100644 index 0000000..f7f5f4d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaulthelper.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + + +#ifndef VAULTHELPER_H +#define VAULTHELPER_H + +#include "dfmglobal.h" +#include + +DFM_BEGIN_NAMESPACE +class VaultHelper : public QObject +{ + Q_OBJECT +public: + explicit VaultHelper(QObject *parent = nullptr); + + /** + * @brief topVaultTasks Is there a vault task, top it if exist. + * @return bool + */ + static bool topVaultTasks(); + + /** + * @brief killVaultTasks Kill all vault tasks. + * @return bool + */ + static bool killVaultTasks(); + + /** + * @brief isVaultEnabled + * @return + */ + static bool isVaultEnabled(); + + // 定义静态变量,记录当前保险箱是否处于模态弹窗状态 + static bool isModel; + +signals: + +public slots: +}; + +DFM_END_NAMESPACE + +#endif // VAULTHELPER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultlockmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultlockmanager.cpp new file mode 100644 index 0000000..2ee25c2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultlockmanager.cpp @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "vaultlockmanager.h" +#include "dfileservices.h" +#include "dfmsettings.h" +#include "dfmapplication.h" +#include "controllers/vaultcontroller.h" +#include "controllers/vaulterrorcode.h" +#include "../app/define.h" +#include "dialogs/dialogmanager.h" +#include "dialogs/dtaskdialog.h" +#include "interfaceactivevault.h" +#include "vault/vaulthelper.h" +#include "dbusinterface/vault_interface.h" +#include "vault/vaulthelper.h" + +#include + +#define VAULT_AUTOLOCK_KEY "AutoLock" +#define VAULT_GROUP "Vault/AutoLock" + +/** + * @brief The VaultLockManagerPrivate class + */ +class VaultLockManagerPrivate +{ +public: + explicit VaultLockManagerPrivate(VaultLockManager *qq); + + VaultInterface *m_vaultInterface = nullptr; // dbus interface + VaultLockManager::AutoLockState m_autoLockState; // auto lock state + QTimer m_alarmClock; // auto lock clock + bool m_isCacheTimeReloaded; + + VaultLockManager *q_ptr; + + Q_DECLARE_PUBLIC(VaultLockManager) +}; + +VaultLockManagerPrivate::VaultLockManagerPrivate(VaultLockManager *qq) + : m_autoLockState(VaultLockManager::Never) + , m_isCacheTimeReloaded(false) + , q_ptr(qq) +{ +} + +VaultLockManager &VaultLockManager::getInstance() +{ + static VaultLockManager instance; + return instance; +} + +VaultLockManager::VaultLockManager(QObject *parent) + : QObject(parent) + , d_ptr(new VaultLockManagerPrivate(this)) +{ + Q_D(VaultLockManager); + + d->m_vaultInterface = new VaultInterface("com.deepin.filemanager.daemon", + "/com/deepin/filemanager/daemon/VaultManager", + QDBusConnection::systemBus(), + this); + + if (!isValid()) { + qDebug() << d->m_vaultInterface->lastError().message(); + return; + } + + //! 自动锁计时处理 + connect(&d->m_alarmClock, &QTimer::timeout, this, &VaultLockManager::processAutoLock); + d->m_alarmClock.setInterval(1000); + + connect(VaultController::ins(), &VaultController::signalLockVault, this, &VaultLockManager::slotLockVault); + connect(VaultController::ins(), &VaultController::signalUnlockVault, this, &VaultLockManager::slotUnlockVault); + + loadConfig(); + + // monitor screen lock event. + QDBusConnection::sessionBus().connect( + "org.freedesktop.FileManager1", + "/org/freedesktop/FileManager1", + "org.freedesktop.FileManager1", + "lockEventTriggered", + this, + SLOT(slotLockEvent(QString))); +} + +void VaultLockManager::loadConfig() +{ + VaultLockManager::AutoLockState state = VaultLockManager::Never; + QVariant var = DFMApplication::genericSetting()->value(VAULT_GROUP, VAULT_AUTOLOCK_KEY); + if (var.isValid()) { + state = static_cast(var.toInt()); + } + autoLock(state); +} + +void VaultLockManager::resetConfig() +{ + autoLock(VaultLockManager::Never); +} + +VaultLockManager::AutoLockState VaultLockManager::autoLockState() const +{ + D_DC(VaultLockManager); + + return d->m_autoLockState; +} + +bool VaultLockManager::autoLock(VaultLockManager::AutoLockState lockState) +{ + Q_D(VaultLockManager); + + d->m_autoLockState = lockState; + + if (d->m_autoLockState == Never) { + d->m_alarmClock.stop(); + } else { + if (d->m_isCacheTimeReloaded) { + refreshAccessTime(); + } + + d->m_alarmClock.start(); + } + d->m_isCacheTimeReloaded = true; + + DFMApplication::genericSetting()->setValue(VAULT_GROUP, VAULT_AUTOLOCK_KEY, lockState); + + return true; +} + +void VaultLockManager::refreshAccessTime() +{ + if (isValid()) { + quint64 curTime = dbusGetSelfTime(); + dbusSetRefreshTime(static_cast(curTime)); + } +} + +bool VaultLockManager::checkAuthentication(QString type) +{ + Q_D(VaultLockManager); + + bool res = false; + if (d->m_vaultInterface->isValid()) { + QDBusPendingReply reply = d->m_vaultInterface->checkAuthentication(type); + reply.waitForFinished(); + if (reply.isError()) { + qDebug() << reply.error().message(); + } else { + res = reply.value(); + } + } + return res; +} + +void VaultLockManager::processAutoLock() +{ + Q_D(VaultLockManager); + + VaultController *controller = VaultController::ins(); + if (controller->state() != VaultController::Unlocked + || d->m_autoLockState == Never) { + + return; + } + + quint64 lastAccessTime = dbusGetLastestTime(); + + quint64 curTime = dbusGetSelfTime(); + + quint64 interval = curTime - lastAccessTime; + quint32 threshold = d->m_autoLockState * 60; + +#ifdef AUTOLOCK_TEST + qDebug() << "vault autolock countdown > " << interval; +#endif + + if (interval > threshold) { + qDebug() << "-----------enter interval > threshold-------------"; + VaultHelper::killVaultTasks(); + qDebug() << "---------------begin lockVault---------------"; + controller->lockVault(); + qDebug() << "---------------leave lockVault---------------"; + } +} + +void VaultLockManager::slotLockVault(int msg) +{ + Q_D(VaultLockManager); + + if (static_cast(msg) == ErrorCode::Success) { + d->m_alarmClock.stop(); + } else { + qDebug() << "vault cannot lock"; + } +} + +void VaultLockManager::slotUnlockVault(int msg) +{ + Q_D(VaultLockManager); + + if (static_cast(msg) == ErrorCode::Success) { + autoLock(d->m_autoLockState); + } +} + +void VaultLockManager::processLockEvent() +{ + // lock vault. + VaultHelper::killVaultTasks(); + VaultController::ins()->lockVault(); +} + +void VaultLockManager::slotLockEvent(const QString &user) +{ + char *loginUser = getlogin(); + if (user == loginUser) { + processLockEvent(); + } +} + +bool VaultLockManager::isValid() const +{ + D_DC(VaultLockManager); + + bool bValid = false; + + if (d->m_vaultInterface->isValid()) { + QDBusPendingReply reply = d->m_vaultInterface->getLastestTime(); + reply.waitForFinished(); + bValid = !reply.isError(); + } + return bValid; +} + +void VaultLockManager::dbusSetRefreshTime(quint64 time) +{ + Q_D(VaultLockManager); + + if (d->m_vaultInterface->isValid()) { + QDBusPendingReply<> reply = d->m_vaultInterface->setRefreshTime(time); + reply.waitForFinished(); + if (reply.isError()) { + qDebug() << reply.error().message(); + } + } +} + +quint64 VaultLockManager::dbusGetLastestTime() const +{ + D_DC(VaultLockManager); + + quint64 latestTime = 0; + if (d->m_vaultInterface->isValid()) { + QDBusPendingReply reply = d->m_vaultInterface->getLastestTime(); + reply.waitForFinished(); + if (reply.isError()) { + qDebug() << reply.error().message(); + } else { + latestTime = reply.value(); + } + } + return latestTime; +} + +quint64 VaultLockManager::dbusGetSelfTime() const +{ + D_DC(VaultLockManager); + + quint64 selfTime = 0; + if (d->m_vaultInterface->isValid()) { + QDBusPendingReply reply = d->m_vaultInterface->getSelfTime(); + reply.waitForFinished(); + if (reply.isError()) { + qDebug() << reply.error().message(); + } else { + selfTime = reply.value(); + } + } + return selfTime; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultlockmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultlockmanager.h new file mode 100644 index 0000000..13355f3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/vault/vaultlockmanager.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef VAULTLOCKMANAGER_H +#define VAULTLOCKMANAGER_H + +#include "dabstractfilecontroller.h" + +#include "dfmglobal.h" + +//#define AUTOLOCK_TEST +class VaultInterface; +class VaultLockManagerPrivate; +class VaultLockManager : public QObject +{ + Q_OBJECT + +public: + enum AutoLockState { + Never = 0, + FiveMinutes = 5, + TenMinutes = 10, + TwentyMinutes = 20 + }; + + static VaultLockManager &getInstance(); + + /** + * @brief autoLockState 自动上锁状态 + * @return 返回状态值 + */ + AutoLockState autoLockState() const; + + /** + * @brief autoLock 设置自动锁状态 + * @param lockState 状态值 + * @return + */ + bool autoLock(AutoLockState lockState); + + /** + * @brief isValid 保险箱服务是否开启 + * @return + */ + bool isValid() const; + + /** + * @brief refreshAccessTime 刷新保险箱访问时间 + */ + void refreshAccessTime(); + + /** + * @brief checkAuthentication 保险箱权限认证 + */ + bool checkAuthentication(QString type); + + /** + * @brief resetConfig 重置保险箱配置 + */ + void resetConfig(); + +protected slots: + /** + * @brief processAutoLock 处理自动加锁 + */ + void processAutoLock(); + + /** + * @brief slotLockVault 加锁状态槽函数 + */ + void slotLockVault(int msg); + + /** + * @brief slotUnlockVault 解锁状态槽函数 + */ + void slotUnlockVault(int msg); + + /** + * @brief processLockEvent 处理加锁事件 + */ + void processLockEvent(); + + /** + * @brief slotLockEvent 上锁事件 + * @param user + */ + void slotLockEvent(const QString &user); + +protected: + /** + * @brief loadConfig 加载配置文件 + */ + void loadConfig(); + + /** + * @brief setRefreshTime 刷新保险柜最新计时 + * @param time 时间 + * @return + */ + void dbusSetRefreshTime(quint64 time); + + /** + * @brief getLastestTime 获取最新计时 + * @return + */ + quint64 dbusGetLastestTime() const; + + /** + * @brief dbusGetSelfTime 获取自定义时间 + * @return + */ + quint64 dbusGetSelfTime() const; + +private: + explicit VaultLockManager(QObject *parent = nullptr); + QSharedPointer d_ptr; + + Q_DECLARE_PRIVATE(VaultLockManager) +}; + +#endif // VAULTLOCKMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/computerview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/computerview.cpp new file mode 100644 index 0000000..924c381 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/computerview.cpp @@ -0,0 +1,472 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "computerview.h" +#include "dfilemenu.h" +#include "dfilemenumanager.h" +#include "windowmanager.h" +#include "dfmevent.h" +#include "dfmeventdispatcher.h" +#include "dfmapplication.h" +#include "dfmsettings.h" + +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "dfileservices.h" +#include "controllers/pathmanager.h" +#include "controllers/appcontroller.h" +#include "deviceinfo/udisklistener.h" +#include "dabstractfileinfo.h" +#include "interfaces/dfmstandardpaths.h" +#include "gvfs/gvfsmountmanager.h" +#include "singleton.h" +#include "dabstractfilewatcher.h" +#include "models/dfmrootfileinfo.h" +#include "models/computermodel.h" +#include "computerviewitemdelegate.h" +#include "views/dfmopticalmediawidget.h" +#include "models/deviceinfoparser.h" +#include "controllers/vaultcontroller.h" +#include "accessibility/ac-lib-file-manager.h" +#include "../shutil/fileutils.h" +#include "views/dtoolbar.h" +#include "drootfilemanager.h" +#include "utils.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +const QList ComputerView::iconsizes = {48, 64, 96, 128, 256}; + +class ViewReturnEater : public QObject +{ + Q_OBJECT +public: + explicit ViewReturnEater(QListView *parent) : QObject(parent) {} + +protected: + bool eventFilter(QObject *, QEvent *e) + { + if (e->type() == QEvent::Type::KeyPress) { + QKeyEvent *ke = static_cast(e); + if (ke->key() == Qt::Key::Key_Return || ke->key() == Qt::Key::Key_Enter) { + QListView *v = qobject_cast(parent()); + if (v) { + auto model = v->model(); + const QModelIndex &curIdx = v->selectionModel()->currentIndex(); + if (!curIdx.isValid()) { + return true; + } + // when device is editing name, ignore enter event. + if (model->data(curIdx, ComputerModel::DataRoles::IsEditingRole).toBool()) { + return false; + } + Q_EMIT entered(curIdx); + return true; + } + } + } + return false; + } + +Q_SIGNALS: + void entered(const QModelIndex &idx); +}; + +ComputerView::ComputerView(QWidget *parent) : QWidget(parent) +{ + AC_SET_OBJECT_NAME(this, AC_COMPUTER_VIEW); + AC_SET_ACCESSIBLE_NAME(this, AC_COMPUTER_VIEW); + + m_view = new ComputerListView(this); + m_statusbar = new DStatusBar(this); + m_statusbar->scalingSlider()->setMaximum(iconsizes.count() - 1); + m_statusbar->scalingSlider()->setMinimum(0); + m_statusbar->scalingSlider()->setTickInterval(1); + m_statusbar->scalingSlider()->setPageStep(1); + m_statusbar->scalingSlider()->hide(); + m_statusbar->setMaximumHeight(22); + + setLayout(new QVBoxLayout); + layout()->addWidget(m_view); + layout()->addWidget(m_statusbar); + layout()->setMargin(0); + + m_model = new ComputerModel(this); + m_view->setModel(m_model); + m_view->setItemDelegate(new ComputerViewItemDelegate(this)); + m_view->setWrapping(true); + m_view->setSpacing(10); + m_view->setFlow(QListView::Flow::LeftToRight); + m_view->setResizeMode(QListView::ResizeMode::Adjust); + m_view->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); + m_view->setEditTriggers(QListView::EditKeyPressed | QListView::SelectedClicked); + m_view->setIconSize(QSize(iconsizes[m_statusbar->scalingSlider()->value()], iconsizes[m_statusbar->scalingSlider()->value()])); + m_view->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); + m_view->setFrameShape(QFrame::Shape::NoFrame); + m_view->installEventFilter(this); + m_view->viewport()->installEventFilter(this); + m_view->viewport()->setAutoFillBackground(false); + + DFMEvent event(this); + event.setWindowId(window()->internalWinId()); + m_statusbar->itemCounted(event, m_model->itemCount()); + + connect(m_model, &ComputerModel::itemCountChanged, this, [this](int count) { + DFMEvent dfmevent(this); + dfmevent.setWindowId(this->window()->internalWinId()); + if (this->m_view->selectionModel()->currentIndex().isValid()) { + return; + } + this->m_statusbar->itemCounted(dfmevent, count); + }); + connect(m_view->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this] { + DFMEvent dfmevent(this); + dfmevent.setWindowId(this->window()->internalWinId()); + if (this->m_view->selectionModel()->hasSelection()) + { + QModelIndex curidx(this->m_view->selectionModel()->currentIndex()); + DAbstractFileInfoPointer fi = fileService->createFileInfo(this, curidx.data(ComputerModel::DataRoles::DFMRootUrlRole).value()); + if (fi && fi->suffix() == SUFFIX_USRDIR) { + DUrlList urlList{curidx.data(ComputerModel::DataRoles::OpenUrlRole).value()}; + dfmevent.setData(urlList); + } + this->m_statusbar->itemSelected(dfmevent, 1); + return; + } + this->m_statusbar->itemCounted(dfmevent, this->m_model->itemCount()); + }); + + connect(m_view, &QWidget::customContextMenuRequested, this, &ComputerView::contextMenu); + auto enterfunc = [this](const QModelIndex & idx, int triggermatch) { + + DUrl url = idx.data(ComputerModel::DataRoles::DFMRootUrlRole).value(); + if (!url.isValid()) + return; + + //! 在点击计算机页面中的图标时,判断是否是保险箱以及保险箱是否解锁,如果解锁发送信号触发计算保险箱大小的线程 + if(VaultController::Unlocked == VaultController::ins()->state() && url.isVaultFile()) { + emit VaultController::ins()->sigFinishedCopyFile(); + } + + if (~triggermatch) { + if (DFMApplication::instance()->appAttribute(DFMApplication::AA_OpenFileMode).toInt() != triggermatch) { + return; + } + } + + // searchBarTextEntered also invoke "checkGvfsMountFileBusy", forbit invoke twice + if (url.path().endsWith(SUFFIX_STASHED_REMOTE)) { + DFileManagerWindow *window = qobject_cast(this->window()); + if (window) { + auto path = RemoteMountsStashManager::normalizeConnUrl(url.path()); + window->getToolBar()->searchBarTextEntered(path); + return; + } + } + + //判断网络文件是否可以到达 + // fix bug 63803 这里是鼠标事件进入后,checkGvfsMountfileBusy需要很长时间,所以鼠标事件没有结束 + // 切换到其他界面,就析构了自己,当这个checkGvfsMountfileBusy退出,qt处理鼠标事件就崩溃了。 + m_eventProcessing = true; + if (DFileService::instance()->checkGvfsMountfileBusy(url,true)) { + m_eventProcessing = false; + if (m_needRelease.load()) + DFMBaseView::deleteLater(); + return; + } + m_eventProcessing = false; + if (m_needRelease.load()) { + DFMBaseView::deleteLater(); + return; + } + if (url.path().endsWith(SUFFIX_USRDIR)) { + appController->actionOpen(dMakeEventPointer(this, DUrlList() << idx.data(ComputerModel::DataRoles::OpenUrlRole).value())); + } else if (url.scheme() == DFMVAULT_SCHEME) { + appController->actionOpen(dMakeEventPointer(this, DUrlList() << idx.data(ComputerModel::DataRoles::OpenUrlRole).value())); + } else { + appController->actionOpenDisk(dMakeEventPointer(this, url)); + } + }; + + QAction *newTabAction = new QAction(m_view); + m_view->addAction(newTabAction); + newTabAction->setShortcut(QKeySequence(Qt::Key::Key_T | Qt::Modifier::CTRL)); + connect(newTabAction, &QAction::triggered, [this] { + if (m_view->selectionModel()->hasSelection()) + { + const QModelIndex &idx = m_view->selectionModel()->currentIndex(); + DUrl url = idx.data(ComputerModel::DataRoles::DFMRootUrlRole).value(); + if (url.path().endsWith(SUFFIX_USRDIR)) { + appController->actionOpenInNewTab(dMakeEventPointer(this, idx.data(ComputerModel::DataRoles::OpenUrlRole).value())); + } else { + appController->actionOpenDiskInNewTab(dMakeEventPointer(this, url)); + } + } else + { + appController->actionOpenInNewTab(dMakeEventPointer(this, rootUrl())); + } + }); + + QAction *newWindowAction = new QAction(m_view); + m_view->addAction(newWindowAction); + newWindowAction->setShortcut(QKeySequence(Qt::Key::Key_N | Qt::Modifier::CTRL)); + connect(newWindowAction, &QAction::triggered, [this] { + if (m_view->selectionModel()->hasSelection()) + { + const QModelIndex &idx = m_view->selectionModel()->currentIndex(); + DUrl url = idx.data(ComputerModel::DataRoles::DFMRootUrlRole).value(); + if (url.path().endsWith(SUFFIX_USRDIR)) { + appController->actionOpenInNewWindow(dMakeEventPointer(this, DUrlList() << idx.data(ComputerModel::DataRoles::OpenUrlRole).value())); + } else { + appController->actionOpenDiskInNewWindow(dMakeEventPointer(this, url)); + } + } else + { + appController->actionOpenInNewWindow(dMakeEventPointer(this, DUrlList() << rootUrl())); + } + }); + + QAction *propAction = new QAction(m_view); + m_view->addAction(propAction); + propAction->setShortcut(QKeySequence(Qt::Key::Key_I | Qt::Modifier::CTRL)); + connect(propAction, &QAction::triggered, [this] { + if (m_view->selectionModel()->hasSelection()) + { + const QModelIndex &idx = m_view->selectionModel()->currentIndex(); + DUrl url = idx.data(ComputerModel::DataRoles::DFMRootUrlRole).value(); + if (url.path().endsWith(SUFFIX_USRDIR)) { + appController->actionProperty(dMakeEventPointer(this, DUrlList() << idx.data(ComputerModel::DataRoles::OpenUrlRole).value())); + } else { + appController->actionProperty(dMakeEventPointer(this, DUrlList() << url)); + } + } + }); + + ViewReturnEater *re = new ViewReturnEater(m_view); + m_view->installEventFilter(re); + connect(m_view, &QAbstractItemView::doubleClicked, std::bind(enterfunc, std::placeholders::_1, 1)); + connect(m_view, &QAbstractItemView::clicked, std::bind(enterfunc, std::placeholders::_1, 0)); + connect(re, &ViewReturnEater::entered, std::bind(enterfunc, std::placeholders::_1, -1)); + connect(m_statusbar->scalingSlider(), &QSlider::valueChanged, this, [this] {m_view->setIconSize(QSize(iconsizes[m_statusbar->scalingSlider()->value()], iconsizes[m_statusbar->scalingSlider()->value()]));}); + connect(fileSignalManager, &FileSignalManager::requestRename, this, &ComputerView::onRenameRequested); + + connect(&DeviceInfoParser::Instance(), SIGNAL(loadFinished()), this, SLOT(repaint())); + connect(fileSignalManager, &FileSignalManager::requestUpdateComputerView, this, static_cast(&ComputerView::update)); +} + +ComputerView::~ComputerView() +{ + ComputerModel *m = static_cast(m_view->model()); + m_view->setModel(nullptr); + delete m; +} + +QWidget *ComputerView::widget() const +{ + return const_cast(this); +} + +DUrl ComputerView::rootUrl() const +{ + return DUrl(COMPUTER_ROOT); +} + +bool ComputerView::setRootUrl(const DUrl &url) +{ + return url == DUrl(COMPUTER_ROOT); +} + +QListView *ComputerView::view() +{ + return m_view; +} + +bool ComputerView::isEventProcessing() const +{ + return m_eventProcessing.load(); +} + +void ComputerView::setNeedRelease() +{ + m_needRelease.store(true); +} + +void ComputerView::contextMenu(const QPoint &pos) +{ + const QModelIndex &idx = m_view->indexAt(pos); + if (!idx.isValid()) { + return; + } + + m_view->closeEditingEditor(); + const QVector &av = idx.data(ComputerModel::DataRoles::ActionVectorRole).value>(); + + QSet disabled; + if (!WindowManager::tabAddableByWinId(WindowManager::getWindowId(this))) { + disabled.insert(MenuAction::OpenInNewTab); + disabled.insert(MenuAction::OpenDiskInNewTab); + } + + const QString &strVolTag = idx.data(ComputerModel::DataRoles::VolumeTagRole).value(); + if (strVolTag.startsWith("sr") // fix bug#25921 仅针对光驱设备实行禁用操作 + && idx.data(ComputerModel::DataRoles::DiscUUIDRole).value().isEmpty() + && !idx.data(ComputerModel::DataRoles::DiscOpticalRole).value() + && (!idx.data(ComputerModel::DataRoles::OpenUrlRole).value().isValid() + || idx.data(ComputerModel::DataRoles::SizeTotalRole).value() == 0)) { + //fix:光驱还没有加载成功前,右键点击光驱“挂载”,光驱自动弹出。 + disabled.insert(MenuAction::OpenDiskInNewWindow); + disabled.insert(MenuAction::OpenDiskInNewTab); + disabled.insert(MenuAction::Mount); + //fix:不插光盘,打开文件管理器,光盘的弹出按钮不能置灰 + //disabled.insert(MenuAction::Eject); + disabled.insert(MenuAction::SafelyRemoveDrive); + + disabled.insert(MenuAction::Property); + } + if (strVolTag.startsWith("sr") && DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].bBurningOrErasing) { // 如果当前光驱设备正在执行擦除/刻录,则禁用所有右键菜单选项 + for (MenuAction act : av) + disabled.insert(act); + } + + DFileMenu *menu = nullptr; + //! create vault menu. + if (idx.data(ComputerModel::DataRoles::SchemeRole) == DFMVAULT_SCHEME) { + quint64 wndId = WindowManager::getWindowId(this); + menu = DFileMenuManager::createVaultMenu(WindowManager::getWindowById(wndId)); + } else { + menu = DFileMenuManager::genereteMenuByKeys(av, disabled); + } + + menu->setEventData(DUrl(), {idx.data(ComputerModel::DataRoles::DFMRootUrlRole).value()}, WindowManager::getWindowId(this), this); + //fix bug 33305 在用右键菜单复制大量文件时,在复制过程中,关闭窗口这时this释放了,在关闭拷贝menu的exec退出,menu的deleteLater崩溃 + QPointer me = this; + if (!menu->actions().isEmpty()) + menu->exec(this->mapToGlobal(pos)); + menu->deleteLater(me); +} + +void ComputerView::onRenameRequested(const DFMUrlBaseEvent &event) +{ + if (event.sender() != this) { + return; + } + const QModelIndex &idx = m_model->findIndex(event.url()); + if (idx.model() && idx.isValid()) { + m_view->edit(idx); + } +} + +void ComputerView::resizeEvent(QResizeEvent *event) +{ + for (int i = 0; i < m_view->model()->rowCount(); ++i) { + if (m_view->model()->index(i, 0).data(ComputerModel::DataRoles::ICategoryRole) == ComputerModelItemData::Category::cat_splitter) + emit m_view->itemDelegate()->sizeHintChanged(m_view->model()->index(i, 0)); + } + QWidget::resizeEvent(event); +} + +bool ComputerView::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::MouseButtonRelease && obj == m_view->viewport()) { + QMouseEvent *e = static_cast(event); + const QModelIndex &idx = m_view->indexAt(e->pos()); + if (e->button() == Qt::MouseButton::LeftButton && (!idx.isValid() || !(idx.flags() & Qt::ItemFlag::ItemIsEnabled))) { + m_view->selectionModel()->clearSelection(); + } + return false; + } else if (event->type() == QEvent::KeyPress && obj == m_view) { + QKeyEvent *ke = static_cast(event); + if (ke->modifiers() == Qt::Modifier::ALT) { + this->event(event); + return true; + } + return false; + } else { + return QObject::eventFilter(obj, event); + } +} + +ComputerListView::ComputerListView(QWidget *parent) + : QListView(parent) +{ + AC_SET_OBJECT_NAME(this, AC_COMPUTER_LIST_VIEW); + AC_SET_ACCESSIBLE_NAME(this, AC_COMPUTER_LIST_VIEW); + setMouseTracking(true); +} + +void ComputerListView::closeEditingEditor() +{ + auto delegate = qobject_cast(itemDelegate()); + if (!delegate) + return; + + delegate->closeEditingEditor(this); +} + +void ComputerListView::mouseMoveEvent(QMouseEvent *event) +{ + QListView::mouseMoveEvent(event); + const QModelIndex &idx = indexAt(event->pos()); + const QString &volTag = idx.data(ComputerModel::VolumeTagRole).toString(); + if (volTag.startsWith("sr") && DFMOpticalMediaWidget::g_mapCdStatusInfo.contains(volTag) + && DFMOpticalMediaWidget::g_mapCdStatusInfo[volTag].bLoading) { + DFileService::instance()->setCursorBusyState(true); + } else { + DFileService::instance()->setCursorBusyState(false); + } +} + +void ComputerListView::showEvent(QShowEvent *event) +{ + //! 显示计算机页面时,判断保险箱是否解锁,如果解锁发送信号触发计算保险箱大小的线程 + if(VaultController::Unlocked == VaultController::ins()->state()) { + emit VaultController::ins()->sigFinishedCopyFile(); + } + QListView::showEvent(event); +} + +#include "computerview.moc" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/computerview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/computerview.h new file mode 100644 index 0000000..9ed1624 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/computerview.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef COMPUTERVIEW_H +#define COMPUTERVIEW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dstyleditemdelegate.h" +#include "dfileview.h" + +#include "fileitem.h" +#include "durl.h" +#include "dabstractfileinfo.h" +#include "ddiskmanager.h" +#include "dblockdevice.h" +#include "dstatusbar.h" +#include "dfmbaseview.h" + +DFM_USE_NAMESPACE + +class ComputerListView; +class ComputerModel; +class DFMUrlBaseEvent; +class ComputerView : public QWidget, public DFMBaseView +{ + Q_OBJECT +public: + explicit ComputerView(QWidget *parent = nullptr); + ~ComputerView() override; + + QWidget* widget() const override; + DUrl rootUrl() const override; + bool setRootUrl(const DUrl &url) override; + QListView *view(); + // 当前view是否在忙碌中 + bool isEventProcessing() const; + // 设置当前需要析构 + void setNeedRelease(); + +public Q_SLOTS: + void contextMenu(const QPoint &pos); + void onRenameRequested(const DFMUrlBaseEvent &event); + +protected: + void resizeEvent(QResizeEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; + +private: + ComputerListView *m_view; + ComputerModel *m_model; + DStatusBar *m_statusbar; + //是否是在事件处理中 + QAtomicInteger m_eventProcessing = false; + QAtomicInteger m_needRelease = false; + static const QList iconsizes; +}; + +// sp3 feature 35 光盘加载时光标移动到光驱图标上,光标变成繁忙状态,其余时候为正常指针 +// 原来的 view 直接使用的 QListView,因此这里继承重写其中的 mouseMoveEvent 函数 +class ComputerListView : public QListView +{ + Q_OBJECT +public: + explicit ComputerListView(QWidget *parent = nullptr); + void closeEditingEditor(); + +protected: + void mouseMoveEvent(QMouseEvent *event) override; + + void showEvent(QShowEvent *event) override; +}; + +#endif // COMPUTERVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/computerviewitemdelegate.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/computerviewitemdelegate.cpp new file mode 100644 index 0000000..5e5f5a2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/computerviewitemdelegate.cpp @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2019 ~ 2019 Deepin Technology Co., Ltd. + * 2019 ~ 2019 Chris Xiong + * + * Author: Chris Xiong + * + * 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 + * 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 . + */ + +#include +#include +#include +#include +#include + +#include "models/computermodel.h" +#include "shutil/fileutils.h" +#include "computerviewitemdelegate.h" +#include "dfmapplication.h" + +//LABEL间的间隔 +#define LABEL_TOTAL_SPACING 6 +#define TOTAL_PROBAR_SPACING 4 +#define ICON_LABEL_SPACING 10 + +//上下左右间隔 +#define ICON_TOP_MARGIN 20 +#define ICON_BOTTOM_MARGIN 20 +#define ICON_LEFT_MARGIN 10 +#define LABEL_RIGHT_MARGIN 20 + +//! +//! \brief 一些特殊的字体和 CESI_*_GB* 的字体在计算机页面重命名时,显示位置偏上 +//! 因此针对这些字体使用 top-margin 调整,确保文字垂直居中 +//! \return top-margin of lineeditor +//! +static int editorMarginTop(const QString &family) +{ + int margin = 0; + if (dfm_util::isContains(family, QString("Unifont"), QString("WenQuanYi Micro Hei"))) + margin = 4; + else if (family.startsWith("CESI")) { + if (family.endsWith("GB2312") || family.endsWith("GB13000")|| family.endsWith("GB18030")) + margin = 4; + } + return margin; +} + +ComputerViewItemDelegate::ComputerViewItemDelegate(QObject *parent) : QStyledItemDelegate(parent) +{ + par = qobject_cast(parent); +} + +ComputerViewItemDelegate::~ComputerViewItemDelegate() +{ +} + +void ComputerViewItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + painter->setRenderHint(QPainter::RenderHint::Antialiasing); + + ComputerModelItemData::Category cat = ComputerModelItemData::Category(index.data(ComputerModel::DataRoles::ICategoryRole).toInt()); + if (cat == ComputerModelItemData::Category::cat_splitter) { + QFont fnt(par->font()); + fnt.setPixelSize(30); + painter->setFont(fnt); + painter->setPen(qApp->palette().color(QPalette::ColorRole::Text)); + painter->drawText(option.rect, 0, index.data(Qt::ItemDataRole::DisplayRole).toString()); + return; + } + + if (cat == ComputerModelItemData::Category::cat_widget) { + return; + } + + DPalette pl(DApplicationHelper::instance()->palette(option.widget)); + QColor c = pl.color(DPalette::ColorGroup::Active, DPalette::ColorType::ItemBackground); + QColor base_color = c; + if (option.widget) { + DPalette pa = DApplicationHelper::instance()->palette(option.widget); + base_color = option.widget->palette().base().color(); + DGuiApplicationHelper::ColorType ct = DGuiApplicationHelper::toColorType(base_color); + if (ct == DGuiApplicationHelper::DarkType) { + base_color = DGuiApplicationHelper::adjustColor(base_color, 0, 0, +5, 0, 0, 0, 0); + } + } + + if (option.state & QStyle::StateFlag::State_Selected) { + // c = pl.color(DPalette::ColorGroup::Active, QPalette::ColorRole::Highlight); + c.setAlpha(c.alpha() + 30); + } else if (option.state & QStyle::StateFlag::State_MouseOver) { + DGuiApplicationHelper::ColorType ct = DGuiApplicationHelper::toColorType(base_color); + if (ct == DGuiApplicationHelper::DarkType) { + base_color = DGuiApplicationHelper::adjustColor(base_color, 0, 0, +5, 0, 0, 0, 0); + c = base_color; + } + else + c = c.lighter(); + } else { + c = base_color; + } + painter->setPen(c); + painter->setBrush(c); + + painter->drawRoundedRect(option.rect.adjusted(1, 1, -1, -1), 18, 18); + + const QIcon icon = index.data(Qt::ItemDataRole::DecorationRole).value(); + + //目录绘制 + if (cat == ComputerModelItemData::Category::cat_user_directory) { + const int iconsize = par->view()->iconSize().width() * 4 / 3; + const int topmargin = iconsize / 8 + 3; + const int text_max_width = option.rect.width() - 24; + const QString elided_text = option.fontMetrics.elidedText(index.data(Qt::DisplayRole).toString(), Qt::ElideMiddle, text_max_width); + const int fstw = par->fontMetrics().width(elided_text); + const int leftmargin = iconsize / 4 + 12; + const int text_topmargin = iconsize / 4; + painter->drawPixmap(option.rect.x() + leftmargin, option.rect.y() + topmargin, icon.pixmap(iconsize)); + + painter->setFont(par->font()); + painter->setPen(qApp->palette().color((option.state & QStyle::StateFlag::State_Selected) ? QPalette::ColorRole::HighlightedText : QPalette::ColorRole::Text)); + painter->drawText(option.rect.x() + (option.rect.width() - fstw) / 2, option.rect.y() + topmargin + iconsize + text_topmargin, elided_text); + return; + } + + //设备绘制 + QRect nameLabelRect = option.rect; + const int iconsize = par->view()->iconSize().width(); + + const int text_max_width = sizeHint(option,index).width() + - ICON_LEFT_MARGIN + - iconsize + - ICON_LABEL_SPACING + - LABEL_RIGHT_MARGIN; + + const int fontpixelsize = par->fontInfo().pixelSize(); + nameLabelRect.setLeft(option.rect.left() + ICON_LEFT_MARGIN + iconsize + ICON_LABEL_SPACING); + nameLabelRect.setTop(option.rect.top() + ICON_TOP_MARGIN); + nameLabelRect.setHeight(par->fontMetrics().height()); + QFont font = par->font(); + font.setWeight(66); + painter->setFont(font); + painter->setPen(qApp->palette().color(QPalette::ColorRole::Text)); + + QString fileSysType = index.data(ComputerModel::DataRoles::FileSystemRole).toString(); + int fstw = par->fontMetrics().width(fileSysType); + QString text; + if (!fileSysType.isEmpty()) { + text = option.fontMetrics.elidedText(index.data(Qt::DisplayRole).toString(), Qt::ElideMiddle, text_max_width - fstw - 7); + } else { + text = option.fontMetrics.elidedText(index.data(Qt::DisplayRole).toString(), Qt::ElideMiddle, text_max_width - 5); + } + + QRect nameTextDarwRect; //此处真实的字符绘制Rect非labelRect + painter->drawText(nameLabelRect, Qt::TextWrapAnywhere, text, &nameTextDarwRect); + + // 添加对文件系统格式的显示 + if (DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowFileSystemTagOnDiskIcon).toBool() && !fileSysType.isEmpty()) { + + // 使用细线进行绘制 + font.setWeight(12); + painter->setFont(font); + QRect fsTypeLabelrect = nameTextDarwRect; + + fsTypeLabelrect.setWidth(fstw); + fsTypeLabelrect.setHeight(fontpixelsize + 4); + //与真实字符绘制Rect保持左侧12的间距 + fsTypeLabelrect.moveLeft(nameTextDarwRect.right() + 12); + //与真实字符绘制Rect保持 居中 + fsTypeLabelrect.moveBottom(nameTextDarwRect.bottom() - (nameTextDarwRect.height() - fsTypeLabelrect.height())/2); + //微调类型绘制范围 + fsTypeLabelrect.adjust(-5, 0, 5, 0); + + QColor brushColor(0xD2D2D2); + QColor penColor(0x5D5D5D); + QColor borderColor(0xA5A5A5); + + if (fileSysType == "EXT2" + || fileSysType == "EXT3" + || fileSysType == "EXT4" + || fileSysType == "VFAT") { + + brushColor = QColor(0xA1E4FF); + penColor = QColor(0x0081B2); + borderColor = QColor(0x73C7EE); + + } else if (fileSysType == "NTFS" + || fileSysType == "FAT16" + || fileSysType == "FAT32" + || fileSysType == "EXFAT") { + + brushColor = QColor(0xFFDDA1); + penColor = QColor(0x502504); + borderColor = QColor(0xEEB273); + } + + painter->setBrush(brushColor); + painter->setPen(borderColor); + painter->drawRoundedRect(fsTypeLabelrect, 7.5, 7.5); + painter->setPen(penColor); + painter->drawText(fsTypeLabelrect, Qt::AlignCenter, fileSysType); + } + + QFont smallf(par->font()); + smallf.setPixelSize(int(fontpixelsize * 0.85)); + painter->setFont(smallf); + + QRect totalLabelRect = nameLabelRect; + + // 修复bug-63543 控制中心修改字体为unifont后,item的格式标签会覆盖住盘符大小标签 + totalLabelRect.setTop(nameTextDarwRect.bottom() + LABEL_TOTAL_SPACING); //添加与真实绘制的盘符名称间隔 + totalLabelRect.setHeight(QFontMetrics(smallf).height()); //字符高度 + + quint64 sizeinuse = index.data(ComputerModel::DataRoles::SizeInUseRole).toULongLong(); + quint64 sizetotal = index.data(ComputerModel::DataRoles::SizeTotalRole).toULongLong(); + QString strVolTag = index.data(ComputerModel::DataRoles::VolumeTagRole).toString(); + painter->setPen(pl.color(DPalette::TextTips)); + + // Paint size. + bool bSizeVisible = index.data(ComputerModel::DataRoles::SizeRole).toBool(); + QString scheme = index.data(ComputerModel::DataRoles::SchemeRole).toString(); + if (bSizeVisible) { + if (scheme == DFMVAULT_SCHEME) { + // vault only show size. + painter->drawText(totalLabelRect, Qt::AlignLeft, FileUtils::formatSize(static_cast(sizeinuse))); + } else { + painter->drawText(totalLabelRect, Qt::AlignLeft, FileUtils::diskUsageString(sizeinuse, sizetotal, strVolTag)); + } + } + + // for app entry description + if (scheme == APPENTRY_SCHEME) { + auto commentRect = totalLabelRect; + commentRect.setWidth(text_max_width); + auto fullComment = index.data(ComputerModel::DataRoles::AppEntryDescription).toString(); + QFontMetrics fm(smallf); + auto firstLine = fm.elidedText(fullComment, Qt::ElideRight, text_max_width); + if (firstLine.endsWith("…")) { + firstLine.chop(1); + painter->drawText(commentRect, Qt::AlignLeft, firstLine); + // draw second line + auto secondLine = fullComment.remove(0, firstLine.length()); + secondLine = fm.elidedText(secondLine, Qt::ElideRight, text_max_width); + commentRect.moveTo(commentRect.x(), commentRect.y() + commentRect.height()); + painter->drawText(commentRect, Qt::AlignLeft, secondLine); + } else { + painter->drawText(commentRect, Qt::AlignLeft, firstLine); + } + } + + QRect usgplrect(QPoint(totalLabelRect.x(), + totalLabelRect.bottom() + TOTAL_PROBAR_SPACING), + QSize(text_max_width, 6)); + QStyle *sty = option.widget && option.widget->style() ? option.widget->style() : qApp->style(); + QStyleOptionProgressBar plopt; + plopt.textVisible = false; + plopt.rect = usgplrect; + plopt.minimum = 0; + plopt.maximum = 10000; + plopt.progress = sizetotal && ~sizeinuse ? int(10000. * sizeinuse / sizetotal) : 0; + if (plopt.progress > plopt.maximum) { + plopt.progress = plopt.maximum; + } + QColor plcolor; + if (plopt.progress < 7000) { + plcolor = QColor(0xFF0081FF); + } else if (plopt.progress < 9000) { + plcolor = QColor(0xFFF8AE2C); + } else { + plcolor = QColor(0xFFFF6170); + } + plopt.palette = option.widget ? option.widget->palette() : qApp->palette(); + plopt.palette.setColor(QPalette::ColorRole::Highlight, plcolor); + painter->setPen(Qt::PenStyle::NoPen); + + // Paint progress + bool bProgressVisible = index.data(ComputerModel::DataRoles::ProgressRole).toBool(); + + if (bProgressVisible) { + sty->drawControl(QStyle::ControlElement::CE_ProgressBarGroove, &plopt, painter, option.widget); + sty->drawControl(QStyle::ControlElement::CE_ProgressBarContents, &plopt, painter, option.widget); + } + + //设备盘符图标高度居中 + int deviceIconAligmentY = option.rect.y() + (sizeHint(option,index).height() - iconsize)/2; + painter->drawPixmap(option.rect.x() + ICON_LEFT_MARGIN, deviceIconAligmentY, icon.pixmap(iconsize)); +} + +QSize ComputerViewItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + ComputerModelItemData::Category cat = ComputerModelItemData::Category(index.data(ComputerModel::DataRoles::ICategoryRole).toInt()); + if (cat == ComputerModelItemData::Category::cat_widget) { + return static_cast(index.internalPointer())->widget->size(); + } else if (cat == ComputerModelItemData::Category::cat_splitter) { + return QSize(par->width() - 12, 45); + } else if (cat == ComputerModelItemData::Category::cat_user_directory) { + int sz = par->view()->iconSize().width() * 2 + 24; + return QSize(sz, sz); + } + + const int iconSize = par->view()->iconSize().width(); + const int textMaxWidth = int(iconSize * 3.75); + + //右侧真实大小 + int processBarHeight = 6; + QFont smallf(par->font()); + smallf.setPixelSize(int(par->fontInfo().pixelSize() * 0.85)); + int capacityLabelHeight = QFontMetrics(smallf).height(); + int nameTextLabelHeight = QFontMetrics(option.fontMetrics).height(); + + int colLabelsHeight = processBarHeight + + capacityLabelHeight + + nameTextLabelHeight + + LABEL_TOTAL_SPACING + + TOTAL_PROBAR_SPACING + + ICON_TOP_MARGIN + + ICON_BOTTOM_MARGIN; + + return QSize(ICON_LEFT_MARGIN + iconSize + ICON_LABEL_SPACING + textMaxWidth + LABEL_RIGHT_MARGIN, + qMax(ICON_TOP_MARGIN + iconSize + ICON_BOTTOM_MARGIN, colLabelsHeight)); +} + +QWidget *ComputerViewItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index) + editingIndex = index; + QLineEdit *le = new QLineEdit(parent); + editingEditor = le; + int topMargin = editorMarginTop(option.font.family()); + le->setFrame(false); + le->setTextMargins(0, topMargin, 0, 0); + //消除编辑框背后多余的填充色 +// le->setAutoFillBackground(true); + le->setAlignment(Qt::AlignTop | Qt::AlignLeft); + QRegExp regx("^[^\\.\\\\/\':\\*\\?\"<>|%&][^\\\\/\':\\*\\?\"<>|%&]*"); //屏蔽特殊字符 + QValidator *validator = new QRegExpValidator(regx, le); + le->setValidator(validator); + + int maxLenInBytes = index.data(ComputerModel::EditorLengthRole).toInt(); + connect(le, &QLineEdit::textChanged, this, [le, maxLenInBytes](const QString &txt) { + if (!le) + return; + if (txt.toUtf8().length() > maxLenInBytes) { + const QSignalBlocker blocker(le); + QString newLabel = txt; + newLabel.chop(1); + le->setText(newLabel); + } + }); + + connect(le, &QLineEdit::destroyed, this, [this, le] { + if (editingEditor == le) + editingIndex = QModelIndex(); + }); + + return le; +} + +void ComputerViewItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + QLineEdit *le = qobject_cast(editor); + le->setText(index.data(Qt::DisplayRole).toString()); // TODO: implement EditRole + this->par->view()->model()->setData(index, true, ComputerModel::DataRoles::IsEditingRole); +} + +void ComputerViewItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + QLineEdit *le = qobject_cast(editor); + model->setData(index, le->text()); + model->setData(index, false, ComputerModel::DataRoles::IsEditingRole); +} + +void ComputerViewItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index); + if (index.model() && index.data(ComputerModel::DataRoles::ICategoryRole) == ComputerModelItemData::Category::cat_widget) { + editor->setGeometry(option.rect); + return; + } + QRect textrect = option.rect; + const int iconsize = par->view()->iconSize().width(); + const int text_max_width = int(iconsize * 3.75); + textrect.setLeft(option.rect.left() + ICON_LEFT_MARGIN + iconsize + ICON_LABEL_SPACING + 1); + textrect.setWidth(text_max_width); + textrect.setTop(option.rect.top() + ICON_TOP_MARGIN - 2); + textrect.setHeight(par->fontInfo().pixelSize() * 2); + editor->setGeometry(textrect); +} + +void ComputerViewItemDelegate::closeEditingEditor(ComputerListView *view) +{ + if (!view || !editingIndex.isValid()) + return; + + QWidget *editor = view->indexWidget(editingIndex); + if (!editor) + return; + + QMetaObject::invokeMethod(this, "_q_commitDataAndCloseEditor", + Qt::DirectConnection, Q_ARG(QWidget *, editor)); +} + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/computerviewitemdelegate.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/computerviewitemdelegate.h new file mode 100644 index 0000000..fd97a56 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/computerviewitemdelegate.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2019 ~ 2019 Deepin Technology Co., Ltd. + * 2019 ~ 2019 Chris Xiong + * + * Author: Chris Xiong + * + * 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 + * 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 . + */ + +#ifndef COMPUTERVIEWITEMDELEGATE_H +#define COMPUTERVIEWITEMDELEGATE_H + +#include + +#include "computerview.h" + +class ComputerViewItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit ComputerViewItemDelegate(QObject *parent = nullptr); + ~ComputerViewItemDelegate(); + + void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void setEditorData(QWidget *editor, const QModelIndex &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + + void closeEditingEditor(ComputerListView *view); + +private: + ComputerView *par; + mutable QLineEdit *editingEditor {nullptr}; + mutable QModelIndex editingIndex; +}; + + +#endif // COMPUTERVIEWITEMDELEGATE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dcompleterlistview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dcompleterlistview.cpp new file mode 100644 index 0000000..1b2b5a2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dcompleterlistview.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ +#include "dcompleterlistview.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include + +#include + +#include +#include + + +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE + +DCompleterListView::DCompleterListView(QWidget *parent) + : QListView(parent) +{ + AC_SET_OBJECT_NAME(this, AC_COMPUTER_COMPLETER_LIST_VIEW); + AC_SET_ACCESSIBLE_NAME(this, AC_COMPUTER_COMPLETER_LIST_VIEW); + + overrideWindowFlags(Qt::Tool /*| Qt::WindowDoesNotAcceptFocus*/); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + setViewportMargins(0, 0, -verticalScrollBar()->sizeHint().width(), 0); + setMouseTracking(true); +} +//解决bug19609文件管理器中,文件夹搜索功能中输入法在输入过程中忽然失效然后恢复 +void DCompleterListView::keyPressEvent(QKeyEvent *e) +{ + return QListView::keyPressEvent(e); +} + +void DCompleterListView::showMe() +{ + QListView::show(); +} +//隐藏、停止计时器、释放鼠标 +void DCompleterListView::hideMe() +{ + QListView::hide(); +} + +void DCompleterListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + Q_UNUSED(previous); + emit listCurrentChanged(current); + QListView::currentChanged(current, previous); +} + +void DCompleterListView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) +{ + Q_UNUSED(deselected); + emit listSelectionChanged(selected); + QListView::selectionChanged(selected, deselected); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dcompleterlistview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dcompleterlistview.h new file mode 100644 index 0000000..6b958b3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dcompleterlistview.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ +#ifndef DCOMPLETERLISTVIEW_H +#define DCOMPLETERLISTVIEW_H + +#include +#include + +#include "dfmglobal.h" + +DFM_BEGIN_NAMESPACE + +class DCompleterListView : public QListView +{ + Q_OBJECT + +public: + explicit DCompleterListView(QWidget *parent = nullptr); + void keyPressEvent(QKeyEvent *e) override; + + void showMe(); +public slots: + void hideMe(); +protected: + void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) override; + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override; + +signals: + void listCurrentChanged(const QModelIndex ¤t); + void listSelectionChanged(const QItemSelection &selected); + +}; + +DFM_END_NAMESPACE + +#endif // DCOMPLETERLISTVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/ddetailview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/ddetailview.cpp new file mode 100644 index 0000000..a3809c2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/ddetailview.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "ddetailview.h" + +DDetailView::DDetailView(QWidget *parent) : QFrame(parent) +{ + +} + +DDetailView::~DDetailView() +{ + +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/ddetailview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/ddetailview.h new file mode 100644 index 0000000..202595b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/ddetailview.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DDETAILVIEW_H +#define DDETAILVIEW_H + +#include + +class DDetailView : public QFrame +{ + Q_OBJECT +public: + explicit DDetailView(QWidget *parent = 0); + ~DDetailView(); + +signals: + +public slots: +}; + +#endif // DDETAILVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfiledialog.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfiledialog.cpp new file mode 100644 index 0000000..f7aa08a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfiledialog.cpp @@ -0,0 +1,1511 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "private/dfiledialog_p.h" +#include "dfiledialog.h" +#include "dfilesystemmodel.h" +#include "dfileservices.h" +#include "dfmevent.h" +#include "dfmeventdispatcher.h" +#include "dfmsidebar.h" +#include "dfmaddressbar.h" +#include "models/masteredmediafileinfo.h" +#include "views/dstatusbar.h" +#include "views/filedialogstatusbar.h" +#include "controllers/vaultcontroller.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +QList DFileDialogPrivate::orderedSelectedUrls() const +{ + if (!view || !view->model()) { + return QList(); + } + + QModelIndex rootIndex = view->rootIndex(); + DUrlList list; + + QModelIndexList seclist = view->selectedIndexes(); + if (seclist.size() < orderedSelectedList.size()) { + auto it = orderedSelectedList.begin(); + while (it != orderedSelectedList.end()) { + if (seclist.contains(*it)) { + ++it; + } else { + it = orderedSelectedList.erase(it); + } + } + } else if (seclist.size() > orderedSelectedList.size()) { + qWarning() << "oops, something was wrong..."; + // the reset may not be ordered + QSet resetSet = seclist.toSet() - orderedSelectedList.toSet(); + for (QModelIndex idx : resetSet) { + orderedSelectedList.append(idx); + } + } + + for (const QModelIndex &index : orderedSelectedList) { + if (index.parent() != rootIndex) + continue; + + list << view->model()->getUrlByIndex(index); + } + + return list; +} + +bool DFileDialogPrivate::checkFileSuffix(const QString &fileName, const int &filterIndex, QString &suffix) const +{ + bool suffixCheck = false; //后缀名检测 + for (QString nameFilterList : nameFilters) { + for (QString nameFilter : QPlatformFileDialogHelper::cleanFilterList(nameFilterList)) { //清理掉多余的信息 + QRegExp re(nameFilter, Qt::CaseInsensitive, QRegExp::Wildcard); + if (re.exactMatch(fileName)) { + suffixCheck = true; + break; + }; + } + if (suffixCheck) { + break; + } + } + + //需要补充扩展名,查找匹配扩展名 + if (!suffixCheck && !nameFilters.isEmpty()) { //文件名、扩展名匹配? + QMimeDatabase mdb; + QString filter = nameFilters[filterIndex]; //当前设置扩展名 + QStringList newNameFilters = QPlatformFileDialogHelper::cleanFilterList(filter); + if (!newNameFilters.isEmpty()) { + for (const QString &newFilter : newNameFilters) { + suffix = mdb.suffixForFileName(newFilter); + if (suffix.isEmpty()) { //未查询到扩展名用正则表达式再查一次,新加部分,解决WPS保存文件去掉扩展名后没有补上扩展名的问题 + QRegExp regExp(newFilter.mid(2), Qt::CaseInsensitive, QRegExp::Wildcard); + mdb.allMimeTypes().first().suffixes().first(); + for (QMimeType m : mdb.allMimeTypes()) { + for (QString suffixe : m.suffixes()) { + if (regExp.exactMatch(suffixe)) { + suffix = suffixe; + return true; //查询到后跳出循环 + } + } + } + } else { + return true; + } + } + } + } + + return false; +} + +DFileDialog::DFileDialog(QWidget *parent) + : DFileManagerWindow(parent) + , d_ptr(new DFileDialogPrivate()) + , m_acceptCanOpenOnSave(false) +{ + d_ptr->view = qobject_cast(DFileManagerWindow::getFileView()->widget()); + // 文件对话框只能在本窗口打开新目录 + if (d_ptr->view) { + d_ptr->view->setAlwaysOpenInCurrentWindow(true); + } + + setWindowFlags(Qt::WindowCloseButtonHint | Qt::WindowTitleHint | Qt::Dialog); + + if (titlebar()) { + titlebar()->setDisableFlags(Qt::WindowSystemMenuHint); + titlebar()->setMenuVisible(false); + } + + d_ptr->statusBar = new FileDialogStatusBar(this); + AC_SET_OBJECT_NAME(d_ptr->statusBar, AC_FD_STATUS_BAR_INTEL); + AC_SET_ACCESSIBLE_NAME(d_ptr->statusBar, AC_FD_STATUS_BAR_INTEL); + centralWidget()->layout()->addWidget(d_ptr->statusBar); + + setAcceptMode(QFileDialog::AcceptOpen); + handleNewView(DFileManagerWindow::getFileView()); + + getLeftSideBar()->setDisableUrlSchemes(QSet() << "trash" << "network"); + getLeftSideBar()->setContextMenuEnabled(false); + getLeftSideBar()->setAcceptDrops(false); + + DFMEventDispatcher::instance()->installEventFilter(this); + + connect(statusBar()->acceptButton(), &QPushButton::clicked, this, &DFileDialog::onAcceptButtonClicked); + connect(statusBar()->rejectButton(), &QPushButton::clicked, this, &DFileDialog::onRejectButtonClicked); + connect(getFileView(), &DFileView::fileDialogRename, this, &DFileDialog::disableOpenBtn); + connect(statusBar()->comboBox(), + static_cast(&QComboBox::activated), + this, &DFileDialog::selectNameFilter); + connect(statusBar()->comboBox(), + static_cast(&QComboBox::activated), + this, &DFileDialog::selectedNameFilterChanged); + + statusBar()->lineEdit()->setMaxLength(MAX_FILE_NAME_CHAR_COUNT); + + // 修复bug-45176 + // 如果是wanyland平台,将弹出的文件框居中 + if(DFMGlobal::isWayLand()) { + Dtk::Widget::moveToCenter(this); + } +} + +DFileDialog::~DFileDialog() +{ + +} + +void DFileDialog::setDirectory(const QString &directory) +{ + setDirectoryUrl(DUrl::fromLocalFile(directory)); +} + +void DFileDialog::setDirectory(const QDir &directory) +{ + setDirectoryUrl(DUrl::fromLocalFile(directory.absolutePath())); +} + +QDir DFileDialog::directory() const +{ + return QDir(directoryUrl().toLocalFile()); +} + +void DFileDialog::setDirectoryUrl(const DUrl &directory) +{ + if (!getFileView()) { + return; + } + // 修复BUG-44160 + DUrl url(directory); + if (VaultController::isVaultFile(directory.path())) { // 判断是否是保险箱路径 + if (VaultController::Encrypted == VaultController::ins()->state()) { // 判断保险箱当前状态,如果处于加密状态 + url.setPath(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first()); + } + } + getFileView()->cd(url); +} + +QUrl DFileDialog::directoryUrl() const +{ + if (!getFileView()) { + return QUrl(); + } + + // 保险箱QUrl->转换为文件QUrl + DUrl url = getFileView()->rootUrl(); + QString strPath = url.path(); + QString strScheme = url.scheme(); + if (strScheme == DFMVAULT_SCHEME) { + QUrl urlVault; + urlVault.setScheme(FILE_SCHEME); + urlVault.setPath(strPath); + return urlVault; + } + else if (strScheme == BURN_SCHEME) { // 光盘转文件QUrl + MasteredMediaFileInfo mediafileInfo(url); + QUrl urlBurn(mediafileInfo.toLocalFile()); + urlBurn.setScheme(FILE_SCHEME); + return urlBurn; + } + return url; +} + +void DFileDialog::selectFile(const QString &filename) +{ + DUrl url = currentUrl(); + QDir dir(url.path()); + + url.setPath(dir.absoluteFilePath(filename)); + + selectUrl(url); +} + +QStringList DFileDialog::selectedFiles() const +{ + QStringList list; + + for (const QUrl &url : selectedUrls()) { + DUrl fileUrl(url); + list << fileUrl.toLocalFile(); + } + + return list; +} + +void DFileDialog::selectUrl(const QUrl &url) +{ + if (!getFileView()) { + return; + } + getFileView()->select(DUrlList() << DUrl(url)); + + const DAbstractFileInfoPointer &fileInfo = getFileView()->model()->fileInfo(DUrl(url)); + + if (fileInfo && fileInfo->exists()) { + return; + } + + setCurrentInputName(QFileInfo(url.path()).fileName()); +} + +QList DFileDialog::selectedUrls() const +{ + D_DC(DFileDialog); + + if (!getFileView()) { + return QList(); + } + DUrlList list = d->orderedSelectedUrls();//getFileView()->selectedUrls(); + + DUrlList::iterator begin = list.begin(); + + while (begin != list.end()) { + const DAbstractFileInfoPointer &fileInfo = getFileView()->model()->fileInfo(*begin); + + if (fileInfo && !fileInfo->toLocalFile().isEmpty()) { + DUrl newUrl = DUrl::fromLocalFile(fileInfo->toLocalFile()); + + if (newUrl.isValid()) { + *begin = newUrl; + } + } + + ++begin; + } + + if (d->acceptMode == QFileDialog::AcceptSave) { + DUrl fileUrl = list.isEmpty() ? getFileView()->rootUrl() : list.first(); + const DAbstractFileInfoPointer &fileInfo = getFileView()->model()->fileInfo(fileUrl); + + if (fileInfo) { + if (list.isEmpty()) { + fileUrl = fileInfo->getUrlByChildFileName(statusBar()->lineEdit()->text()); + } else { + fileUrl = fileInfo->getUrlByNewFileName(statusBar()->lineEdit()->text()); + } + } + + return QList() << fileUrl; + } + + if (list.isEmpty() && (d->fileMode == QFileDialog::Directory + || d->fileMode == QFileDialog::DirectoryOnly)) { + if (directoryUrl().isLocalFile()) + list << DUrl(directoryUrl()); + } + + return DUrl::toQUrlList(list); +} + +void DFileDialog::addDisableUrlScheme(const QString &scheme) +{ + QSet schemes = getLeftSideBar()->disableUrlSchemes(); + + schemes << scheme; + + getLeftSideBar()->setDisableUrlSchemes(schemes); +} + +/* + Strip the filters by removing the details, e.g. (*.*). +*/ +QStringList qt_strip_filters(const QStringList &filters) +{ + QStringList strippedFilters; + QRegExp r(QString::fromLatin1("^(.*)\\(([^()]*)\\)$")); + const int numFilters = filters.count(); + strippedFilters.reserve(numFilters); + for (int i = 0; i < numFilters; ++i) { + QString filterName = filters[i]; + int index = r.indexIn(filterName); + if (index >= 0) { + filterName = r.cap(1); + } + strippedFilters.append(filterName.simplified()); + } + return strippedFilters; +} + +void DFileDialog::setNameFilters(const QStringList &filters) +{ + D_D(DFileDialog); + + d->nameFilters = filters; + + if (testOption(QFileDialog::HideNameFilterDetails)) { + statusBar()->setComBoxItems(qt_strip_filters(filters)); + } else { + statusBar()->setComBoxItems(filters); + } + + if (modelCurrentNameFilter().isEmpty()) { + selectNameFilter(filters.isEmpty() ? QString() : filters.first()); + } +} + +QStringList DFileDialog::nameFilters() const +{ + D_DC(DFileDialog); + + return d->nameFilters; +} + +void DFileDialog::selectNameFilter(const QString &filter) +{ + QString key; + + if (testOption(QFileDialog::HideNameFilterDetails)) { + key = qt_strip_filters(QStringList(filter)).first(); + } else { + key = filter; + } + + int index = statusBar()->comboBox()->findText(key); + + selectNameFilterByIndex(index); +} + +QString DFileDialog::modelCurrentNameFilter() const +{ + if (!getFileView()) { + return ""; + } + const QStringList &filters = getFileView()->nameFilters(); + + if (filters.isEmpty()) { + return QString(); + } + + return filters.first(); +} + +QString DFileDialog::selectedNameFilter() const +{ + Q_D(const DFileDialog); + + const QComboBox *box = statusBar()->comboBox(); + + return box ? d->nameFilters.value(box->currentIndex()) : QString(); +} + +void DFileDialog::selectNameFilterByIndex(int index) +{ + D_D(DFileDialog); + if (index < 0 || index >= statusBar()->comboBox()->count() || !getFileView()) { + return; + } + + statusBar()->comboBox()->setCurrentIndex(index); + + QStringList nameFilters = d->nameFilters; + + if (index == nameFilters.size()) { + QAbstractItemModel *comboModel = statusBar()->comboBox()->model(); + nameFilters.append(comboModel->index(comboModel->rowCount() - 1, 0).data().toString()); + setNameFilters(nameFilters); + } + + QString nameFilter = nameFilters.at(index); + QStringList newNameFilters = QPlatformFileDialogHelper::cleanFilterList(nameFilter); + if (d->acceptMode == QFileDialog::AcceptSave && !newNameFilters.isEmpty()) { + QString newNameFilterExtension; + QMimeDatabase db; + QString fileName = statusBar()->lineEdit()->text(); + const QString fileNameExtension = db.suffixForFileName(fileName); + + for (const QString &filter : newNameFilters) { //从扩展名列表中轮询,目前发现的应用程序传入扩展名列表均只有一个 + newNameFilterExtension = db.suffixForFileName(filter); //在QMimeDataBase里面查询扩展名是否存在(不能查询正则表达式) + if (newNameFilterExtension.isEmpty()) { //未查询到扩展名用正则表达式再查一次,新加部分,解决WPS保存文件去掉扩展名后没有补上扩展名的问题 + QRegExp regExp(filter.mid(2), Qt::CaseInsensitive, QRegExp::Wildcard); + qDebug() << "未通过QMimeDataBase::suffixForFileName查询到匹配的扩展名,尝试使用正则表达式" << filter; + for (QMimeType m : db.allMimeTypes()) { + for (QString suffixe : m.suffixes()) { + if (regExp.exactMatch(suffixe)) { + newNameFilterExtension = suffixe; + qDebug() << "正则表达式查询到扩展名" << suffixe; + break; //查询到后跳出循环 + } + } + if (!newNameFilterExtension.isEmpty()) { + break; //查询到后跳出循环 + } + } + } + + if (newNameFilterExtension.isEmpty()) { + qDebug() << "未查询到扩展名"; + } + + QRegExp re(newNameFilterExtension, Qt::CaseInsensitive, QRegExp::Wildcard); + + if (re.exactMatch(fileNameExtension)) { //原扩展名与新扩展名不匹配? + qDebug() << "设置新的过滤规则" << newNameFilters; + return getFileView()->setNameFilters(newNameFilters); //这里传递回去的有可能是一个正则表达式,它决定哪些文件不被置灰 + } + } +// 下面这部分内容似乎没有必要,因为上面已经查询到了第一个符合QMimeDataBase记录的扩展名 +// newNameFilterExtension = db.suffixForFileName(newNameFilters.at(0)); + + if (!fileNameExtension.isEmpty() && !newNameFilterExtension.isEmpty()) { + const int fileNameExtensionLength = fileNameExtension.count(); + fileName.replace(fileName.count() - fileNameExtensionLength, + fileNameExtensionLength, newNameFilterExtension); + setCurrentInputName(fileName); + } else if (fileNameExtension.isEmpty() && !fileName.isEmpty() && !newNameFilterExtension.isEmpty()) { + fileName.append('.' + newNameFilterExtension); + setCurrentInputName(fileName); + } + } + + // when d->fileMode == QFileDialog::DirectoryOnly or d->fileMode == QFileDialog::Directory + // we use setNameFilters("/") to filter files (can't select file, select dir is ok) + if ((d->fileMode == QFileDialog::DirectoryOnly || + d->fileMode == QFileDialog::Directory) && QStringList("/") != newNameFilters) { + newNameFilters = QStringList("/"); + } + + getFileView()->setNameFilters(newNameFilters); +} + +int DFileDialog::selectedNameFilterIndex() const +{ + const QComboBox *box = statusBar()->comboBox(); + + return box ? box->currentIndex() : -1; +} + +QDir::Filters DFileDialog::filter() const +{ + return getFileView() ? getFileView()->filters() : QDir::Filters(); +} + +void DFileDialog::setFilter(QDir::Filters filters) +{ + if (getFileView()) { + getFileView()->setFilters(filters); + } +} + +void DFileDialog::setViewMode(DFileView::ViewMode mode) +{ + if (getFileView()) { + getFileView()->setViewMode(mode); + } +} + +DFileView::ViewMode DFileDialog::viewMode() const +{ + return getFileView() ? getFileView()->viewMode() : DFileView::ViewMode::ListMode ; +} + +void DFileDialog::setFileMode(QFileDialog::FileMode mode) +{ + if (!getFileView()) { + return; + } + + D_D(DFileDialog); + + if (d->fileMode == QFileDialog::DirectoryOnly + || d->fileMode == QFileDialog::Directory) { + // 清理只显示目录时对文件名添加的过滤条件 + getFileView()->setNameFilters(QStringList()); + } + + d->fileMode = mode; + updateAcceptButtonState(); + + switch (static_cast(mode)) { + case QFileDialog::ExistingFiles: + getFileView()->setEnabledSelectionModes(QSet() << QAbstractItemView::ExtendedSelection); + break; + case QFileDialog::DirectoryOnly: + case QFileDialog::Directory: + // 文件名中不可能包含 '/', 此处目的是过滤掉所有文件 + getFileView()->setNameFilters(QStringList("/")); + getLeftSideBar()->setDisableUrlSchemes({"recent"}); // 打开目录时禁用recent + // fall through + default: + getFileView()->setEnabledSelectionModes(QSet() << QAbstractItemView::SingleSelection); + break; + } +} + +void DFileDialog::setAllowMixedSelection(bool on) +{ + D_D(DFileDialog); + + d->allowMixedSelection = on; +} + +void DFileDialog::setAcceptMode(QFileDialog::AcceptMode mode) +{ + if (!getFileView()) { + return; + } + + D_D(DFileDialog); + + d->acceptMode = mode; + updateAcceptButtonState(); + + if (mode == QFileDialog::AcceptOpen) { + statusBar()->setMode(FileDialogStatusBar::Open); + setFileMode(d->fileMode); + + disconnect(statusBar()->lineEdit(), &QLineEdit::textChanged, + this, &DFileDialog::onCurrentInputNameChanged); + } else { + statusBar()->setMode(FileDialogStatusBar::Save); + getFileView()->setSelectionMode(QAbstractItemView::SingleSelection); + getLeftSideBar()->setDisableUrlSchemes({"recent"}); // save mode disable recent + setFileMode(QFileDialog::DirectoryOnly); + + connect(statusBar()->lineEdit(), &QLineEdit::textChanged, + this, &DFileDialog::onCurrentInputNameChanged); + } +} + +QFileDialog::AcceptMode DFileDialog::acceptMode() const +{ + D_DC(DFileDialog); + + return d->acceptMode; +} + +void DFileDialog::setLabelText(QFileDialog::DialogLabel label, const QString &text) +{ + switch (static_cast(label)) { + case QFileDialog::Accept: + statusBar()->acceptButton()->setText(text); + break; + case QFileDialog::Reject: + statusBar()->rejectButton()->setText(text); + break; + default: + break; + } +} + +QString DFileDialog::labelText(QFileDialog::DialogLabel label) const +{ + switch (static_cast(label)) { + case QFileDialog::Accept: + return statusBar()->acceptButton()->text(); + case QFileDialog::Reject: + return statusBar()->rejectButton()->text(); + default: + break; + } + + return QString(); +} + +void DFileDialog::setOptions(QFileDialog::Options options) +{ + if (!getFileView()) { + return; + } + + Q_D(DFileDialog); + + // (此处修改比较特殊,临时方案)与产品沟通后,使用uos文管保存框保存文件时,如果当前目录下有同名文件, + // 必须要弹出提示框 “是否覆盖重名文件”。 + // 所以options中的QFileDialog::DontConfirmOverwrite标志位将失去意义, + // 所以此处直接将该标志位赋值为0。 + options &= ~QFileDialog::DontConfirmOverwrite; + + d->options = options; + + getFileView()->model()->setReadOnly(options.testFlag(QFileDialog::ReadOnly)); + + if (options.testFlag(QFileDialog::ShowDirsOnly)) { + getFileView()->setFilters(getFileView()->filters() & ~QDir::Files & ~QDir::Drives); + } +} + +void DFileDialog::setOption(QFileDialog::Option option, bool on) +{ + Q_D(DFileDialog); + + QFileDialog::Options options = d->options; + + if (on) { + options |= option; + } else { + options &= ~option; + } + + setOptions(options); +} + +bool DFileDialog::testOption(QFileDialog::Option option) const +{ + Q_D(const DFileDialog); + + return d->options.testFlag(option); +} + +QFileDialog::Options DFileDialog::options() const +{ + Q_D(const DFileDialog); + + return d->options; +} + +void DFileDialog::setCurrentInputName(const QString &name) +{ + if (!statusBar()->lineEdit()) { + return; + } + + statusBar()->lineEdit()->setText(name); + + QMimeDatabase db; + + const QString &suffix = db.suffixForFileName(name); + + if (suffix.isEmpty()) { + statusBar()->lineEdit()->selectAll(); + } else { + statusBar()->lineEdit()->setSelection(0, name.length() - suffix.length() - 1); + } +} + +void DFileDialog::addCustomWidget(CustomWidgetType type, const QString &data) +{ + const QJsonDocument &json = QJsonDocument::fromJson(data.toUtf8()); + const QJsonObject &object = json.object(); + + if (type == LineEditType) { + int maxLength = object["maxLength"].toInt(); + QLineEdit::EchoMode echoMode = static_cast(object["echoMode"].toInt()); + QString inputMask = object["inputMask"].toString(); + QLabel *label = new QLabel(object["text"].toString()); + QLineEdit *edit = new QLineEdit(object["defaultValue"].toString()); + + if (maxLength > 0) { + edit->setMaxLength(maxLength); + } + + if (!inputMask.isEmpty()) { + edit->setInputMask(inputMask); + } + + edit->setEchoMode(echoMode); + edit->setPlaceholderText(object["placeholderText"].toString()); + edit->setFixedHeight(24); + statusBar()->addLineEdit(label, edit); + } else { + QStringList data; + + for (const QVariant &v : object["data"].toArray().toVariantList()) { + data << v.toString(); + } + + QString defaultValue = object["defaultValue"].toString(); + + QLabel *label = new QLabel(object["text"].toString()); + QComboBox *comboBox = new QComboBox(); + + comboBox->setEditable(object["editable"].toBool()); + comboBox->addItems(data); + + if (!defaultValue.isEmpty()) { + comboBox->setCurrentText(defaultValue); + } + + statusBar()->addComboBox(label, comboBox); + } +} + +void DFileDialog::beginAddCustomWidget() +{ + statusBar()->beginAddCustomWidget(); +} + +void DFileDialog::endAddCustomWidget() +{ + statusBar()->endAddCustomWidget(); +} + +QVariant DFileDialog::getCustomWidgetValue(DFileDialog::CustomWidgetType type, const QString &text) const +{ + if (type == LineEditType) { + return statusBar()->getLineEditValue(text); + } else if (type == ComboBoxType) { + return statusBar()->getComboBoxValue(text); + } + + return QVariant(); +} + +QVariantMap DFileDialog::allCustomWidgetsValue(DFileDialog::CustomWidgetType type) const +{ + if (type == LineEditType) { + return statusBar()->allLineEditsValue(); + } else if (type == ComboBoxType) { + return statusBar()->allComboBoxsValue(); + } + + return QVariantMap(); +} + +void DFileDialog::setHideOnAccept(bool enable) +{ + D_D(DFileDialog); + + d->hideOnAccept = enable; +} + +bool DFileDialog::hideOnAccept() const +{ + D_DC(DFileDialog); + + return d->hideOnAccept; +} + +DFileView *DFileDialog::getFileView() const +{ + Q_D(const DFileDialog); + + return d->view; +} + +void DFileDialog::accept() +{ + done(QDialog::Accepted); +} + +void DFileDialog::done(int r) +{ + D_D(DFileDialog); + + if (d->eventLoop) { + d->eventLoop->exit(r); + } + + if (r != QDialog::Accepted || d->hideOnAccept) + hide(); + + emit finished(r); + if (r == QDialog::Accepted) { + emit accepted(); + } else if (r == QDialog::Rejected) { + emit rejected(); + } +} + +int DFileDialog::exec() +{ + D_D(DFileDialog); + + if (d->eventLoop) { + qWarning("DFileDialog::exec: Recursive call detected"); + return -1; + } + + bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose); + setAttribute(Qt::WA_DeleteOnClose, false); + + bool wasShowModal = testAttribute(Qt::WA_ShowModal); + setAttribute(Qt::WA_ShowModal, true); + + show(); + + QPointer guard = this; + QEventLoop eventLoop; + d->eventLoop = &eventLoop; + int res = eventLoop.exec(QEventLoop::DialogExec); + if (guard.isNull()) { + return QDialog::Rejected; + } + d->eventLoop = nullptr; + + setAttribute(Qt::WA_ShowModal, wasShowModal); + + if (deleteOnClose) { + delete this; + } + return res; +} + +void DFileDialog::open() +{ + show(); +} + +void DFileDialog::reject() +{ + done(QDialog::Rejected); +} + +void DFileDialog::disableOpenBtn() +{ + statusBar()->acceptButton()->setEnabled(false); +} + +void DFileDialog::showEvent(QShowEvent *event) +{ + if (!event->spontaneous() && !testAttribute(Qt::WA_Moved)) { + Qt::WindowStates state = windowState(); + adjustPosition(parentWidget()); + setAttribute(Qt::WA_Moved, false); // not really an explicit position + if (state != windowState()) { + setWindowState(state); + } + } + + activateWindow(); + + windowHandle()->installEventFilter(this); + + if (windowFlags().testFlag(Qt::WindowSystemMenuHint)) { + overrideWindowFlags(windowFlags() & ~Qt::WindowSystemMenuHint); + } + + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, currentUrl()); + if (info) { + setWindowTitle(info->fileDisplayName()); + } + + return DFileManagerWindow::showEvent(event); +} + +void DFileDialog::closeEvent(QCloseEvent *event) +{ +#ifndef QT_NO_WHATSTHIS + if (isModal() && QWhatsThis::inWhatsThisMode()) { + QWhatsThis::leaveWhatsThisMode(); + } +#endif + if (isVisible()) { + QPointer that = this; + reject(); + if (that && isVisible()) { + event->ignore(); + } + } else { + event->accept(); + } + + return DFileManagerWindow::closeEvent(event); +} + +bool DFileDialog::eventFilter(QObject *watched, QEvent *event) +{ + Q_D(DFileDialog); + if (watched == windowHandle() && event->type() == QEvent::KeyPress) { + QKeyEvent *e = static_cast(event); + + if (e->modifiers() == Qt::ControlModifier + && (e->key() == Qt::Key_T + || e->key() == Qt::Key_W)) { + return true; + } else if (e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier) { + if (e == QKeySequence::Cancel) { + DFileView *fileView = d->view; + if (fileView) { + if (fileView->state() == 3) { + fileView->closePersistentEditor(fileView->currentIndex()); + return true; + } + } + close(); + } else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) { + handleEnterPressed(); + } + } + } + + return DFileManagerWindow::eventFilter(watched, event); +} + +void DFileDialog::adjustPosition(QWidget *w) +{ + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) + if (theme->themeHint(QPlatformTheme::WindowAutoPlacement).toBool()) { + return; + } + QPoint p(0, 0); + int extraw = 0, extrah = 0, scrn = 0; + if (w) { + w = w->window(); + } + QRect desk; + if (w) { + scrn = QApplication::desktop()->screenNumber(w); + } else if (QApplication::desktop()->isVirtualDesktop()) { + scrn = QApplication::desktop()->screenNumber(QCursor::pos()); + } else { + scrn = QApplication::desktop()->screenNumber(this); + } + desk = QApplication::desktop()->availableGeometry(scrn); + + QWidgetList list = QApplication::topLevelWidgets(); + for (int i = 0; (extraw == 0 || extrah == 0) && i < list.size(); ++i) { + QWidget *current = list.at(i); + if (current->isVisible()) { + int framew = current->geometry().x() - current->x(); + int frameh = current->geometry().y() - current->y(); + + extraw = qMax(extraw, framew); + extrah = qMax(extrah, frameh); + } + } + + // sanity check for decoration frames. With embedding, we + // might get extraordinary values + if (extraw == 0 || extrah == 0 || extraw >= 10 || extrah >= 40) { + extrah = 40; + extraw = 10; + } + + + if (w && (w->windowFlags() | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint) != w->windowFlags()) { + // Use pos() if the widget is embedded into a native window + QPoint pp; + if (w->windowHandle() && w->windowHandle()->property("_q_embedded_native_parent_handle").value()) { + pp = w->pos(); + } else { + pp = w->mapToGlobal(QPoint(0, 0)); + } + p = QPoint(pp.x() + w->width() / 2, + pp.y() + w->height() / 2); + } else { + // p = middle of the desktop + p = QPoint(desk.x() + desk.width() / 2, desk.y() + desk.height() / 2); + } + + // p = origin of this + p = QPoint(p.x() - width() / 2 - extraw, + p.y() - height() / 2 - extrah); + + + if (p.x() + extraw + width() > desk.x() + desk.width()) { + p.setX(desk.x() + desk.width() - width() - extraw); + } + if (p.x() < desk.x()) { + p.setX(desk.x()); + } + + if (p.y() + extrah + height() > desk.y() + desk.height()) { + p.setY(desk.y() + desk.height() - height() - extrah); + } + if (p.y() < desk.y()) { + p.setY(desk.y()); + } + + move(p); +} + +bool DFileDialog::fmEventFilter(const QSharedPointer &event, DFMAbstractEventHandler *target, QVariant *resultData) +{ + Q_UNUSED(target) + Q_UNUSED(resultData) + + if (!isActiveWindow()) { + return false; + } + + if (event->type() == DFMEvent::OpenFile) { + onAcceptButtonClicked(); + return true; + } + //当打开多文件时要吞噬按键消息(解决字体安装器,选择多个文件的时候,文件管理器的对话框未关闭) + if (event->type() == DFMEvent::OpenFiles) { + onAcceptButtonClicked(); + return true; + } + + switch (event->type()) { + case DFMEvent::OpenFile: + case DFMEvent::OpenFiles: + case DFMEvent::OpenFileByApp: + case DFMEvent::CompressFiles: + case DFMEvent::DecompressFile: + case DFMEvent::DecompressFileHere: +// case DFMEvent::DeleteFiles: +// case DFMEvent::RestoreFromTrash: + case DFMEvent::OpenFileLocation: + case DFMEvent::CreateSymlink: + case DFMEvent::FileShare: + case DFMEvent::CancelFileShare: + case DFMEvent::OpenInTerminal: + return true; + default: + break; + } + + return false; +} + +void DFileDialog::handleNewView(DFMBaseView *view) +{ + Q_D(DFileDialog); + + DFileView *fileView = qobject_cast(view->widget()); + + statusBar()->acceptButton()->setDisabled(!fileView); + + if (!fileView) { + // sava data + d->currentNameFilterIndex = selectedNameFilterIndex(); + d->filters = filter(); + d->currentInputName = statusBar()->lineEdit()->text(); + + d->view = nullptr; // switch to computerview + d->orderedSelectedList.clear(); + return; + } + + d->view = fileView; + + QSet whitelist; + + whitelist << DFMGlobal::NewFolder << DFMGlobal::NewDocument << DFMGlobal::DisplayAs + << DFMGlobal::SortBy << DFMGlobal::Open << DFMGlobal::Rename << DFMGlobal::Delete + << DFMGlobal::ListView << DFMGlobal::IconView << DFMGlobal::ExtendView << DFMGlobal::NewWord + << DFMGlobal::NewExcel << DFMGlobal::NewPowerpoint << DFMGlobal::NewText << DFMGlobal::Name + << DFMGlobal::Size << DFMGlobal::Type << DFMGlobal::CreatedDate << DFMGlobal::LastModifiedDate + << DFMGlobal::DeletionDate << DFMGlobal::SourcePath << DFMGlobal::AbsolutePath << DFMGlobal::Copy + << DFMGlobal::Paste << DFMGlobal::Cut; + + fileView->setMenuActionWhitelist(whitelist); + fileView->setDragEnabled(false); + fileView->setDragDropMode(QAbstractItemView::NoDragDrop); + + connect(fileView->selectionModel(), &QItemSelectionModel::selectionChanged, + this, &DFileDialog::selectionFilesChanged); + + connect(fileView, &DFileView::rootUrlChanged, + this, &DFileDialog::currentUrlChanged); + + connect(fileView, &DFileView::rootUrlChanged, this, &DFileDialog::updateAcceptButtonState); + connect(this, &DFileDialog::selectionFilesChanged, &DFileDialog::updateAcceptButtonState); + + connect(fileView, static_cast(&DFileView::currentChanged), + this, [this, fileView] { + Q_D(const DFileDialog); + + if (d->acceptMode != QFileDialog::AcceptSave) + { + return; + } + + const QModelIndex &index = fileView->currentIndex(); + + const DAbstractFileInfoPointer &fileInfo = fileView->model()->fileInfo(index); + + if (!fileInfo) + return; + + if (fileInfo->isFile()) + setCurrentInputName(fileInfo->fileName()); + }); + + connect(fileView, &DFileView::rootUrlChanged, this, [this]() { + Q_D(const DFileDialog); + + if (d->acceptMode == QFileDialog::AcceptSave) { + setLabelText(QFileDialog::Accept, tr("Save","button")); + m_acceptCanOpenOnSave = false; + onCurrentInputNameChanged(); + } + }); + + connect(fileView->selectionModel(), &QItemSelectionModel::selectionChanged, fileView, + [d](const QItemSelection & selected, const QItemSelection & deselected) { + + //qDebug() << "----selectionChanged" << "selected----"; + for (auto range : selected) { + for (QModelIndex idx : range.indexes()) { + if (!d->orderedSelectedList.contains(idx)) + d->orderedSelectedList.append(idx); + } + } + //qDebug() << "----unselected----"; + for (auto range : deselected) { + QModelIndexList removeList = range.indexes(); + if (removeList.size() == 0 || d->orderedSelectedList.size() == 0) { + return; + } + + for (QModelIndex idx : removeList) { + d->orderedSelectedList.removeOne(idx); + } + } + //qDebug() << "----selectionChanged----"; + }); + + + if (!d->nameFilters.isEmpty()) { + setNameFilters(d->nameFilters); + } + + if (d->filters != 0) { + setFilter(d->filters); + } + + if (d->currentNameFilterIndex >= 0) { + selectNameFilterByIndex(d->currentNameFilterIndex); + } + + if (!d->currentInputName.isEmpty()) { + setCurrentInputName(d->currentInputName); + } + + // fix switch computerview --> fileview fileMode miss + setFileMode(d->fileMode); +} + +FileDialogStatusBar *DFileDialog::statusBar() const +{ + D_DC(DFileDialog); + + return d->statusBar; +} + +#if DTK_VERSION > DTK_VERSION_CHECK(2, 0, 5, 0) +static bool pwPluginVersionGreaterThen(const QString &v) +{ + const QStringList &version_list = DPlatformWindowHandle::pluginVersion().split("."); + const QStringList &v_v_list = v.split("."); + + for (int i = 0; i < version_list.count(); ++i) { + if (v.count() <= i) + return true; + + if (version_list[i].toInt() > v_v_list[i].toInt()) + return true; + } + + return false; +} +#endif + +void DFileDialog::onAcceptButtonClicked() +{ + D_DC(DFileDialog); + if (!getFileView()) { + return; + } + + if (selectedUrls().isEmpty()) + return; + + if (d->acceptMode == QFileDialog::AcceptSave) { + if (m_acceptCanOpenOnSave) { + getFileView()->cd(getFileView()->selectedUrls().first()); + return; + } + + if (!directoryUrl().isLocalFile()) { + return; + } + + if (!directory().exists()) { + return; + } + + QString file_name = statusBar()->lineEdit()->text(); //文件名 + QString suffix = ""; + //检查是否要补充后缀 + if (d->checkFileSuffix(file_name, statusBar()->comboBox()->currentIndex(), suffix)) { + file_name.append('.' + suffix); + setCurrentInputName(file_name); + } + + if (!file_name.isEmpty()) { + if (file_name.startsWith(".")) { + //文件名以点开头的文件会被视为隐藏文件,需要确认 + DDialog dialog(this); + + dialog.setIcon(QIcon::fromTheme("dialog-warning")); + dialog.setTitle(tr("This file will be hidden if the file name starts with a dot (.). Do you want to hide it?")); + dialog.addButton(tr("Cancel","button"), true); + dialog.addButton(tr("Confirm","button"), false, DDialog::ButtonWarning); + + if (dialog.exec() != DDialog::Accepted) { + return; + } + } + + //linux文件名长度不能超过255 + //转到输入时对文本长度进行校验 +// int nameLength = file_name.toLocal8Bit().length(); +// if (nameLength > 255) +// { +// DDialog dialog(this); + +// dialog.setIcon(QIcon::fromTheme("dialog-warning")); +// dialog.setTitle(tr("The file name length is too long!")); +// dialog.addButton(tr("Confirm","button"), true); + +// dialog.exec(); + +// return; +// } + + if (!d->options.testFlag(QFileDialog::DontConfirmOverwrite)) { + QFileInfo info(directory().absoluteFilePath(file_name)); + + if (info.exists() || info.isSymLink()) { + DDialog dialog(this); + + // NOTE(zccrs): dxcb bug + if ((!DFMGlobal::isWayLand() && !DPlatformWindowHandle::isEnabledDXcb(this)) +#if DTK_VERSION > DTK_VERSION_CHECK(2, 0, 5, 0) + || pwPluginVersionGreaterThen("1.1.8.3") +#endif + ) { + dialog.setWindowModality(Qt::WindowModal); + } + + dialog.setIcon(QIcon::fromTheme("dialog-warning")); + + QLabel *titleLabel = dialog.findChild("TitleLabel"); + if (titleLabel) + file_name = titleLabel->fontMetrics().elidedText(file_name, Qt::ElideMiddle, 380); + + QString title = tr("%1 already exists, do you want to replace it?").arg(file_name); + dialog.setTitle(title); + dialog.addButton(tr("Cancel","button"), true); + dialog.addButton(tr("Replace","button"), false, DDialog::ButtonWarning); + + if (dialog.exec() != DDialog::Accepted) { + return; + } + + + } + } + + accept(); + } + + return; + } + + const DUrlList &urls = getFileView()->selectedUrls(); + + switch (d->fileMode) { + case QFileDialog::AnyFile: + case QFileDialog::ExistingFile: + if (urls.count() == 1) { + const DAbstractFileInfoPointer &fileInfo = getFileView()->model()->fileInfo(urls.first()); + + if (fileInfo->isDir()) { + getFileView()->cd(urls.first()); + } else { + accept(); + } + } + break; + case QFileDialog::ExistingFiles: { + + bool doCdWhenPossible = urls.count() == 1; + + for (const DUrl &url : urls) { + const DAbstractFileInfoPointer &fileInfo = getFileView()->model()->fileInfo(url); + if (!fileInfo) {continue;} + if (!fileInfo->isFile() && !d->allowMixedSelection) { + if (doCdWhenPossible && fileInfo->isDir()) { + // blumia: it's possible to select more than one file/dirs, we only do cd when select a single directory. + getFileView()->cd(urls.first()); + } + return; + } + } + + if (!urls.isEmpty()) { + accept(); + } + break; + } + default: { + //if(urls.isEmpty()) return; + + for (const DUrl &url : urls) { + const DAbstractFileInfoPointer &fileInfo = getFileView()->model()->fileInfo(url); + + if (!fileInfo->isDir()) { + return; + } + } + accept(); + break; + } + } +} + +void DFileDialog::onRejectButtonClicked() +{ + reject(); +} + +void DFileDialog::onCurrentInputNameChanged() +{ + if (!getFileView()) { + return; + } + Q_D(DFileDialog); + + QString fileName = statusBar()->lineEdit()->text(); //文件名 + QString suffix = ""; + int addSuffixLength = 0; + if (d->checkFileSuffix(fileName, statusBar()->comboBox()->currentIndex(), suffix)) + addSuffixLength = QString('.' + suffix).toLocal8Bit().length(); + + //文件名超长处理 + int cursorPos = statusBar()->lineEdit()->cursorPosition(); + //截取新增字符的左右字符段 + QString leftStr = statusBar()->lineEdit()->text().left(cursorPos); + QString rightStr = statusBar()->lineEdit()->text().mid(cursorPos); + int removeCount = 0; + //计算需要回退的字符个数 + while (QString(leftStr.chopped(removeCount) + rightStr).toLocal8Bit().length() > (MAX_FILE_NAME_CHAR_COUNT - addSuffixLength)) + ++removeCount; + + if (removeCount > 0) { + //拼合为输入前的字符串,并调整光标位置 + statusBar()->lineEdit()->setText(leftStr.chopped(removeCount) + rightStr); + statusBar()->lineEdit()->setCursorPosition(cursorPos - removeCount); + } + + // fix bug 65861 + // 输入框中禁止输入某些特殊字符 + QString srcText = statusBar()->lineEdit()->text(); + QString dstText = DFMGlobal::preprocessingFileName(srcText); + //如果存在非法字符且更改了当前的文本文件 + if (srcText != dstText) { + //之前的光标Pos + int srcCursorPos = statusBar()->lineEdit()->cursorPosition(); + statusBar()->lineEdit()->setText(dstText); + int endPos = srcCursorPos + (dstText.length() - srcText.length()); + //调整光标位置 + statusBar()->lineEdit()->setCursorPosition(endPos); + } + + d->currentInputName = statusBar()->lineEdit()->text(); + //statusBar()->acceptButton()->setDisabled(d->currentInputName.isEmpty()); + updateAcceptButtonState(); + + DFileSystemModel *model = getFileView()->model(); + if (model && !model->sortedUrls().isEmpty()) { + + const DAbstractFileInfoPointer &fileInfo = model->fileInfo(model->sortedUrls().first()); + if (fileInfo) { + DUrl fileUrl = fileInfo->getUrlByNewFileName(statusBar()->lineEdit()->text()); + + DUrlList urlList; + if (model->sortedUrls().contains(fileUrl) && + model->fileInfo(fileUrl)->isDir()) { + urlList << fileUrl; + setLabelText(QFileDialog::Accept, tr("Open","button")); + m_acceptCanOpenOnSave = true; + } else { + setLabelText(QFileDialog::Accept, tr("Save","button")); + m_acceptCanOpenOnSave = false; + } + + getFileView()->select(urlList); + } + } +} + +void DFileDialog::handleEnterPressed() +{ + if (!statusBar()->acceptButton()->isEnabled() || !getFileView()) { + return; + } + + if (!qobject_cast(qApp->focusWidget())) { + for (const QModelIndex &index : getFileView()->selectedIndexes()) { + const DAbstractFileInfoPointer &info = getFileView()->model()->fileInfo(index); + if (info->isDir()) { + return; + } + } + statusBar()->acceptButton()->animateClick(); + } +} + +void DFileDialog::updateAcceptButtonState() +{ + if (!getFileView()) { + return; + } + + DUrl url = getFileView()->rootUrl(); + const DAbstractFileInfoPointer &fileInfo = getFileView()->model()->fileInfo(url); + if (!fileInfo) { + return; + } + + Q_D(const DFileDialog); + qDebug() << "file mode:" << d->fileMode << "\r\naccept mode:" << d->acceptMode; + qDebug() << fileInfo->fileUrl() << "isVirtualEntry:" << fileInfo->isVirtualEntry(); + + bool isDirMode = d->fileMode == QFileDialog::Directory || d->fileMode == QFileDialog::DirectoryOnly; + bool dialogShowMode = d->acceptMode; + if (dialogShowMode == QFileDialog::AcceptOpen) { + bool isSelectFiles = getFileView()->selectedIndexes().size() > 0; + // 1.打开目录(非虚拟目录) 2.打开文件(选中文件) + statusBar()->acceptButton()->setDisabled((isDirMode && fileInfo->isVirtualEntry()) || + (!isDirMode && !isSelectFiles)); + return; + } + + if (dialogShowMode == QFileDialog::AcceptSave) { + statusBar()->acceptButton()->setDisabled(fileInfo->isVirtualEntry()|| statusBar()->lineEdit()->text().trimmed().isEmpty()); + + //fix 63653 在此插入目录路径的button管控,相关BUG可直接在此逻辑增加if判断 + if(url.scheme() == TRASH_SCHEME) { + statusBar()->acceptButton()->setDisabled(true); + } + + return; + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfiledialog.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfiledialog.h new file mode 100644 index 0000000..ff11e58 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfiledialog.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef DFILEDIALOG_H +#define DFILEDIALOG_H + +#include "dfilemanagerwindow.h" +#include "dfileview.h" +#include "dfmabstracteventhandler.h" + +#include + +DFM_USE_NAMESPACE + +class DFileDialogPrivate; +class FileDialogStatusBar; +class DFileDialog : public DFileManagerWindow +{ + Q_OBJECT + +public: + enum CustomWidgetType { + LineEditType = 0, + ComboBoxType = 1 + }; + + explicit DFileDialog(QWidget *parent = nullptr); + ~DFileDialog() override; + + void setDirectory(const QString &directory); + void setDirectory(const QDir &directory); + QDir directory() const; + + void setDirectoryUrl(const DUrl &directory); + QUrl directoryUrl() const; + + void selectFile(const QString &filename); + QStringList selectedFiles() const; + + void selectUrl(const QUrl &url); + QList selectedUrls() const; + + void addDisableUrlScheme(const QString &scheme); + + void setNameFilters(const QStringList &filters); + QStringList nameFilters() const; + void selectNameFilter(const QString &filter); + QString modelCurrentNameFilter() const; + QString selectedNameFilter() const; + void selectNameFilterByIndex(int index); + int selectedNameFilterIndex() const; + + QDir::Filters filter() const; + void setFilter(QDir::Filters filters); + + void setViewMode(DFileView::ViewMode mode); + DFileView::ViewMode viewMode() const; + + void setFileMode(QFileDialog::FileMode mode); + + void setAllowMixedSelection(bool on); + + void setAcceptMode(QFileDialog::AcceptMode mode); + QFileDialog::AcceptMode acceptMode() const; + + void setLabelText(QFileDialog::DialogLabel label, const QString &text); + QString labelText(QFileDialog::DialogLabel label) const; + + void setOptions(QFileDialog::Options options); + void setOption(QFileDialog::Option option, bool on = true); + bool testOption(QFileDialog::Option option) const; + QFileDialog::Options options() const; + + void setCurrentInputName(const QString &name); + void addCustomWidget(CustomWidgetType type, const QString &data); + void beginAddCustomWidget(); + void endAddCustomWidget(); + QVariant getCustomWidgetValue(CustomWidgetType type, const QString &text) const; + QVariantMap allCustomWidgetsValue(CustomWidgetType type) const; + + void setHideOnAccept(bool enable); + bool hideOnAccept() const; + + DFileView *getFileView() const; + +Q_SIGNALS: + void finished(int result); + void accepted(); + void rejected(); + void selectionFilesChanged(); + void currentUrlChanged(); + void selectedNameFilterChanged(); + +public Q_SLOTS: + void accept(); + void done(int r); + int exec(); + void open(); + void reject(); + + /** + * @brief disableOpenBtn + * 设置打开按钮的是否可用 bug 63430 + */ + void disableOpenBtn(); + +protected: + void showEvent(QShowEvent *event) override; + void closeEvent(QCloseEvent *event) override; + bool eventFilter(QObject *watched, QEvent *event) override; + void adjustPosition(QWidget *w); + + bool fmEventFilter(const QSharedPointer &event, DFMAbstractEventHandler *target = 0, QVariant *resultData = 0) override; + +private: + void handleNewView(DFMBaseView *view) override; + FileDialogStatusBar *statusBar() const; + + void onAcceptButtonClicked(); + void onRejectButtonClicked(); + void onCurrentInputNameChanged(); + void handleEnterPressed(); + void updateAcceptButtonState(); + + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), DFileDialog) + + bool m_acceptCanOpenOnSave; +}; + +#endif // DFILEDIALOG_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfilemanagerwindow.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfilemanagerwindow.cpp new file mode 100644 index 0000000..6e1a1d9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfilemanagerwindow.cpp @@ -0,0 +1,1779 @@ +/* +* Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. +* 2016 ~ 2018 dragondjf +* +* Author: dragondjf +* +* Maintainer: dragondjf +* zccrs +* Tangtong +* +* 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 +* 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 . +*/ + +#include "dfilemanagerwindow_p.h" +#include "dfilemanagerwindow.h" +#include "dtoolbar.h" +#include "dfileview.h" +#include "fileviewhelper.h" +#include "ddetailview.h" +#include "dfilemenu.h" +#include "extendview.h" +#include "dstatusbar.h" +#include "dfilemenumanager.h" +#include "computerview.h" +#include "dtabbar.h" +#include "windowmanager.h" +#include "dfileservices.h" +#include "dfilesystemmodel.h" +#include "dfmviewmanager.h" +#include "dfmsidebar.h" +#include "dfmaddressbar.h" +#include "dfmsettings.h" +#include "dfmapplication.h" +#include "dfmstandardpaths.h" +#include "dfmopticalmediawidget.h" +#include "dfmevent.h" +#include "xutil.h" +#include "utils.h" +#include "dfmadvancesearchbar.h" +#include "dtagactionwidget.h" +#include "droundbutton.h" +#include "dfmrightdetailview.h" +#include "drenamebar.h" +#include "singleton.h" +#include "dfileservices.h" +#include "dfmsplitter.h" + +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "deviceinfo/udisklistener.h" +#include "usershare/usersharemanager.h" +#include "controllers/pathmanager.h" +#include "shutil/fileutils.h" +#include "gvfs/networkmanager.h" +#include "dde-file-manager/singleapplication.h" +#include "dialogs/dialogmanager.h" +#include "controllers/appcontroller.h" +#include "view/viewinterface.h" +#include "plugins/pluginmanager.h" +#include "controllers/trashmanager.h" +#include "controllers/filecontroller.h" +#include "models/dfmrootfileinfo.h" +#include "controllers/vaultcontroller.h" +#include "views/dfmvaultactiveview.h" +#include "vault/vaultglobaldefine.h" +#include "dde-file-manager-daemon/dbusservice/dbusinterface/usershare_interface.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +std::unique_ptr DFileManagerWindow::renameBarState{ nullptr }; +std::atomic DFileManagerWindow::flagForNewWindowFromTab{ false }; +bool vaultMoveState = true; + +void DFileManagerWindowPrivate::setCurrentView(DFMBaseView *view) +{ + Q_Q(DFileManagerWindow); + + if (currentView && currentView->widget()) { + currentView->widget()->removeEventFilter(q); + } + + currentView = view; + + if (currentView && currentView->widget()) { + currentView->widget()->installEventFilter(q); + if (sideBar && sideBar->sidebarView()) { + QWidget::setTabOrder(currentView->widget(), sideBar->sidebarView()); + } + } + + if (!view) { + return; + } + + toolbar->setCustomActionList(view->toolBarActionList()); + + if (!tabBar->currentTab()) { + toolbar->addHistoryStack(); + tabBar->createTab(view); + } else { + tabBar->currentTab()->setFileView(view); + } + + //! 检测保险箱是否上锁,是否是已经移动保险箱了 + if (vaultMoveState && VaultController::Unlocked != VaultController::ins()->state()) { + vaultRemove flg = moveVaultPath(); + if(vaultRemove::SUCCESS == flg) { + qInfo() << "移动到新存储位置成功"; + } + else if (vaultRemove::NOTEXIST == flg){ + qInfo() << "文件不存在"; + } + else { + qInfo() << "移动到新存储位置失败"; + } + vaultMoveState = false; + } +} + +bool DFileManagerWindowPrivate::processKeyPressEvent(QKeyEvent *event) +{ + Q_Q(DFileManagerWindow); + + switch (event->modifiers()) { + case Qt::NoModifier: { + switch (event->key()) { + case Qt::Key_F5: + if (currentView) { + currentView->refresh(); + } + return true; + } + break; + } + case Qt::ControlModifier: { + switch (event->key()) { + case Qt::Key_Tab: + tabBar->activateNextTab(); + return true; + case Qt::Key_Backtab: + tabBar->activatePreviousTab(); + return true; + case Qt::Key_F: + appController->actionctrlF(q->windowId()); + return true; + case Qt::Key_L: + appController->actionctrlL(q->windowId()); + return true; + case Qt::Key_Left: + appController->actionBack(q->windowId()); + return true; + case Qt::Key_Right: + appController->actionForward(q->windowId()); + return true; + case Qt::Key_W: + emit fileSignalManager->requestCloseCurrentTab(q->windowId()); + return true; + case Qt::Key_1: + case Qt::Key_2: + case Qt::Key_3: + case Qt::Key_4: + case Qt::Key_5: + case Qt::Key_6: + case Qt::Key_7: + case Qt::Key_8: + case Qt::Key_9: + toolbar->triggerActionByIndex(event->key() - Qt::Key_1); + return true; + } + break; + } + case Qt::AltModifier: + case Qt::AltModifier | Qt::KeypadModifier: + if (event->key() >= Qt::Key_1 && event->key() <= Qt::Key_8) { + tabBar->setCurrentIndex(event->key() - Qt::Key_1); + return true; + } + + switch (event->key()) { + case Qt::Key_Left: + appController->actionBack(q->windowId()); + return true; + case Qt::Key_Right: + appController->actionForward(q->windowId()); + return true; + } + + break; + case Qt::ControlModifier | Qt::ShiftModifier: + if (event->key() == Qt::Key_Question) { + appController->actionShowHotkeyHelp(q->windowId()); + return true; + } else if (event->key() == Qt::Key_Backtab) { + tabBar->activatePreviousTab(); + return true; + } + break; + } + + return false; +} + +bool DFileManagerWindowPrivate::processTitleBarEvent(QMouseEvent *event) +{ + // tmp: 删除和恢复文件走的主线程,不能拖动窗口,后面修改回复和删除文件的方式后去除以下代码 + if (TrashManager::isWorking()) { + if (!event) + return false; + + Q_Q(DFileManagerWindow); + + if (event->type() == QEvent::MouseButtonPress) { + auto mouseEvent = static_cast(event); + if (mouseEvent->button() == Qt::LeftButton) { + move = true; + /*记录鼠标的全局坐标.*/ + startPoint = mouseEvent->globalPos(); + /*记录窗体的全局坐标.*/ + windowPoint = q->frameGeometry().topLeft(); + return true; + } + return false; + } + + if (event->type() == QEvent::MouseButtonRelease) { + auto mouseEvent = static_cast(event); + /*改变移动状态.*/ + if (mouseEvent->buttons() & Qt::LeftButton) { + move = false; + return true; + } + return false; + } + + if (event->type() == QEvent::MouseButtonDblClick) { + move = false; + return false; + } + + if (event->type() == QEvent::MouseMove) { + if (move) { + auto mouseEvent = static_cast(event); + /*移动中的鼠标位置相对于初始位置的相对位置.*/ + QPoint relativePos = mouseEvent->globalPos() - startPoint; + /*然后移动窗体即可.*/ + if (event->buttons() == Qt::LeftButton) { + q->move(windowPoint + relativePos); + } + } + return false; + } + + move = false; + return false; + } + + return false; +} + +bool DFileManagerWindowPrivate::cdForTab(Tab *tab, const DUrl &fileUrl) +{ + Q_Q(DFileManagerWindow); + qInfo() << " cd to " << fileUrl; + DFMBaseView *current_view = tab->fileView(); + + const QString &scheme = fileUrl.scheme(); + + // fix 6942 取消判断先后请求地址差异判断 + // fix 28857 高频进入光驱会死锁 + if (current_view && current_view->rootUrl() == fileUrl && scheme == BURN_ROOT) { + return false; + } + + bool fileSamba = false; + { + const auto &decodeUrl = QUrl::fromEncoded(fileUrl.toString().toLocal8Bit()).toString(); + QRegularExpression rx(R"(.*/run/user/.*gvfs/smb-share:server=\d+.\d+.\d+.\d+.*)"); + QRegularExpressionMatch match = rx.match(decodeUrl); + fileSamba = match.hasMatch(); + } + + if (scheme == BURN_SCHEME) { + // 如果当前设备正在执行刻录或擦除,激活进度窗口,拒绝跳转至文件列表页面 + QString strVolTag = DFMOpticalMediaWidget::getVolTag(fileUrl); + if (!strVolTag.isEmpty() && DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].bBurningOrErasing) { + emit fileSignalManager->activeTaskDlg(); + return false; + } + } else if (scheme == DFMROOT_SCHEME) { + DAbstractFileInfoPointer fi = DFileService::instance()->createFileInfo(q_ptr, fileUrl); + if (fi->suffix() == SUFFIX_USRDIR) { + return cdForTab(tab, fi->redirectedFileUrl()); + } else if (fi->suffix() == SUFFIX_UDISKS) { + QString blkDevicePath = fi->extraProperties()["udisksblk"].toString(); + QScopedPointer blk(DDiskManager::createBlockDevice(blkDevicePath)); + if (blk->mountPoints().empty()) { + qDebug() << "mount the device{" << blkDevicePath << " } at:" << blk->mount({}); + } + } + } else if (scheme == SMB_SCHEME || (fileUrl.toString().contains("/run/user") && fileUrl.toString().contains("smb-share"))) { + // 需求 88316,smb 可能已经关闭 这里需求尝试启动 + + // 首先判断smb地址是否是自己ip + // 获取url里面的ip + QString urlIp; + QRegularExpression rx(R"((\d+.\d+.\d+.\d+))"); + QRegularExpressionMatch match = rx.match(fileUrl.toString()); + if (match.hasMatch()) + urlIp = match.captured(); + + // 获取本机ip + bool selfIp = false; + const auto &allAddresses = QNetworkInterface::allAddresses(); + qDebug() << allAddresses; + for (const auto &address : allAddresses) { + if (address.protocol() == QAbstractSocket::IPv4Protocol) { + const QString &ipAddr = address.toString(); + if (ipAddr == urlIp) { + selfIp = true; + break; + } + } + } + if (selfIp) { // 自己ip再判断smb状态 + if (!FileUtils::isSambaServiceRunning()) { + // 异步调启动smb窗口 + q_ptr->startSambaServiceAsync(tab, fileUrl); + return false; + } + } + } + + if (scheme == DFMVAULT_SCHEME || + VaultController::isVaultFile(fileUrl.fragment())) { + if (VaultController::Unlocked != VaultController::ins()->state() + || fileUrl.host() == "delete") { + + DUrl realUrl = fileUrl.isTaggedFile() ? DUrl::fromLocalFile(fileUrl.fragment()) : fileUrl; + + //! set scheme to get vault file info. + realUrl.setScheme(DFMVAULT_SCHEME); + + DFMBaseView *view = DFMViewManager::instance()->createViewByUrl(realUrl); + view->widget()->setParent(q); + bool ret = view->setRootUrl(realUrl); + delete view; + view = nullptr; + return ret; + } + } + + if (!current_view || !DFMViewManager::instance()->isSuited(fileUrl, current_view)) { + DFMBaseView *view = DFMViewManager::instance()->createViewByUrl(fileUrl); + if (view) { + viewStackLayout->addWidget(view->widget()); + + if (tab == tabBar->currentTab()) + viewStackLayout->setCurrentWidget(view->widget()); + + q_ptr->handleNewView(view); + } else { + qWarning() << "Not support url: " << fileUrl; + + //###(zccrs): + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(q_ptr, fileUrl); + if (fileInfo) { + /* Call fileInfo->exists() twice. First result is false and the second one is true; + Maybe this is a bug of fuse when smb://10.0.10.30/people is mounted and cd to mounted folder immediately. + */ + qDebug() << fileInfo->exists() << fileUrl; + qDebug() << fileInfo->exists() << fileUrl; + } + + if (!fileInfo || !fileInfo->exists()) { + DUrl searchUrl = current_view ? current_view->rootUrl() : DUrl::fromLocalFile(QDir::homePath()); + + if (searchUrl.isComputerFile()) { + searchUrl = DUrl::fromLocalFile("/"); + } + + if (searchUrl.isSearchFile()) { + searchUrl = searchUrl.searchTargetUrl(); + } + + if (!q_ptr->isCurrentUrlSupportSearch(searchUrl)) { + return false; + } + + const DUrl &newUrl = DUrl::fromSearchFile(searchUrl, fileUrl.toString()); + const DAbstractFileInfoPointer &file_info = DFileService::instance()->createFileInfo(q_ptr, newUrl); + + if (!file_info || !file_info->exists()) { + return false; + } + + qWarning() << "SearchFile url : " << newUrl; + + return cdForTab(tab, newUrl); + } + + return false; + } + if (current_view) { + // fix bug 63803 + ComputerView *computerView = dynamic_cast(current_view); + if (computerView && computerView->isEventProcessing()) + computerView->setNeedRelease(); + else + current_view->deleteLater(); + } + tab->setFileView(view); + if (tab == tabBar->currentTab()) + setCurrentView(view); + + current_view = view; + } + + bool ok = false; + if (current_view) { + // 为了解决 bug 34363: [4K屏]下且[缩放],[ICON视图]下[浏览大量文件],同时[疯狂滚动 scrollbar] 导致的崩溃问题 + auto fileView = dynamic_cast(current_view); + if (fileView && fileView->isIconViewMode()) { + auto model = fileView->model(); + if (model) { + auto state = model->state(); + // busy 状态说明文件太多,还没加载完 + if (state == DFileSystemModel::Busy) { + // 目前系统缩放区间为 [1.0, 2.75], ratio > 1.0 则为缩放, 目前 1.0 没有出现崩溃 + qreal ratio = qApp->primaryScreen()->devicePixelRatio(); + if (ratio > 1.0) { + // 如果疯狂滚动,那么Qt可能会由于绘制的原因崩溃,因此在切换前选中第一个item + // 这样界面就不会处于一个疯狂刷新绘制的状态,即不会调用绘制的函数,因此避免了绘制崩溃的问题 + fileView->setCurrentIndex(model->index(0, 0)); + } + } + } + } + ok = current_view->setRootUrl(fileUrl); + + if (ok) { + tab->onFileRootUrlChanged(fileUrl); + if (tab == tabBar->currentTab()) { + emit q_ptr->currentUrlChanged(); + } + } + } + + return ok; +} + +void DFileManagerWindowPrivate::initAdvanceSearchBar() +{ + if (advanceSearchBar) return; + + Q_Q(DFileManagerWindow); + + // blumia: we add the DFMAdvanceSearchBar widget to layout so actually we shouldn't give it a parent here, + // but we need to apply the currect stylesheet to it so set a parent will do this job. + // feel free to replace it with a better way to apply stylesheet. + advanceSearchBar = new DFMAdvanceSearchBar(q); + + initRenameBar(); // ensure we can use renameBar. + + Q_CHECK_PTR(rightViewLayout); + + int renameWidgetIndex = rightViewLayout->indexOf(renameBar); + int advanceSearchBarInsertTo = renameWidgetIndex == -1 ? 0 : renameWidgetIndex + 1; + + // fix bug 59215 挤压导致界面异常,使用QScrollArea处理 + advanceSearchArea = new QScrollArea(q); + advanceSearchArea->setWidget(advanceSearchBar); + advanceSearchArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//隐藏横向滚动条 + advanceSearchArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//隐藏竖向滚动条 + rightViewLayout->insertWidget(advanceSearchBarInsertTo, advanceSearchArea); + + QObject::connect(advanceSearchBar, &DFMAdvanceSearchBar::optionChanged, q, [ = ](const QMap &formData, bool updateView) { + if (currentView) { + DFileView *fv = dynamic_cast(currentView); + if (fv) { + fv->setAdvanceSearchFilter(formData, true, updateView); + } + } + }); +} + +bool DFileManagerWindowPrivate::isAdvanceSearchBarVisible() const +{ + return advanceSearchArea ? advanceSearchArea->isVisible() : false; +} + +void DFileManagerWindowPrivate::setAdvanceSearchBarVisible(bool visible) +{ + if (!advanceSearchBar) { + if (!visible) return; + initAdvanceSearchBar(); + } + + advanceSearchArea->setVisible(visible); +} + +void DFileManagerWindowPrivate::initRenameBar() +{ + if (renameBar) return; + + Q_Q(DFileManagerWindow); + + // see the comment in initAdvanceSearchBar() + renameBar = new DRenameBar(q); + + rightViewLayout->insertWidget(rightViewLayout->indexOf(emptyTrashHolder) + 1, renameBar); + + QObject::connect(renameBar, &DRenameBar::clickCancelButton, q, &DFileManagerWindow::hideRenameBar); +} + +bool DFileManagerWindowPrivate::isRenameBarVisible() const +{ + return renameBar ? renameBar->isVisible() : false; +} + +void DFileManagerWindowPrivate::setRenameBarVisible(bool visible) +{ + if (!renameBar) { + if (!visible) return; + initRenameBar(); + } + + renameBar->setVisible(visible); +} + +void DFileManagerWindowPrivate::resetRenameBar() +{ + if (!renameBar) return; + + renameBar->resetRenameBar(); +} + +DFileManagerWindowPrivate::vaultRemove DFileManagerWindowPrivate::moveVaultPath() +{ + QStringList vaultfilelist; + vaultfilelist << VAULT_BASE_PATH_OLD + "/" + VAULT_ENCRYPY_DIR_NAME + << VAULT_BASE_PATH_OLD + "/" + VAULT_DECRYPT_DIR_NAME + << VAULT_BASE_PATH_OLD + "/" + PASSWORD_FILE_NAME + << VAULT_BASE_PATH_OLD + "/" + RSA_PUB_KEY_FILE_NAME + << VAULT_BASE_PATH_OLD + "/" + RSA_CIPHERTEXT_FILE_NAME + << VAULT_BASE_PATH_OLD + "/" + PASSWORD_HINT_FILE_NAME + << VAULT_BASE_PATH_OLD + "/" + VAULT_CONFIG_FILE_NAME; + + QString mvBinary = QStandardPaths::findExecutable("mv"); + if (mvBinary.isEmpty()) return NOTEXIST; + QString vaultNewPath = VAULT_BASE_PATH; + QDir dir; + if(!dir.exists(vaultNewPath)) { + dir.mkdir(vaultNewPath); + } + + DFileManagerWindowPrivate::vaultRemove flg = NOTEXIST; + + for (QString & filepath : vaultfilelist) { + QFile file(filepath); + if(file.exists()) { + QStringList argments; + argments << filepath << vaultNewPath; + QProcess process; + process.start(mvBinary, argments); + process.waitForStarted(); + process.waitForFinished(); + process.terminate(); + + if(process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0) { + flg = SUCCESS; + } + else { + flg = FAILED; + } + } + } + + return flg; +} + +void DFileManagerWindowPrivate::storeUrlListToRenameBar(const QList &list) noexcept +{ + if (!renameBar) initRenameBar(); + + renameBar->storeUrlList(list); +} + +void DFileManagerWindowPrivate::updateSelectUrl() +{ + DFileView *fv = dynamic_cast(currentView); + if (detailView && fv) { + detailView->setUrl(fv->selectedUrls().value(0, fv->rootUrl())); + if (fv->selectedIndexCount() == 0) + detailView->setTagWidgetVisible(false); + } +} + +void DFileManagerWindowPrivate::createRightDetailViewHolder() +{ + rightDetailViewHolder = new QFrame; + rightDetailViewHolder->setObjectName("rightviewHolder"); + AC_SET_ACCESSIBLE_NAME(rightDetailViewHolder, AC_DM_RIGHT_VIEW_HOLDER); + rightDetailViewHolder->setAutoFillBackground(true); + rightDetailViewHolder->setBackgroundRole(QPalette::ColorRole::Base); + rightDetailViewHolder->setFixedWidth(320); + QHBoxLayout *rvLayout = new QHBoxLayout(rightDetailViewHolder); + rvLayout->setMargin(0); + + detailView = new DFMRightDetailView(currentView ? currentView->rootUrl() : DUrl()); + QFrame *rightDetailVLine = new QFrame; + AC_SET_OBJECT_NAME(rightDetailVLine, AC_DM_RIGHT_VIEW_DETAIL_VLINE); + AC_SET_ACCESSIBLE_NAME(rightDetailVLine, AC_DM_RIGHT_VIEW_DETAIL_VLINE); + rightDetailVLine->setFrameShape(QFrame::VLine); + rvLayout->addWidget(rightDetailVLine); + rvLayout->addWidget(detailView, 1); + midLayout->addWidget(rightDetailViewHolder, 1); + rightDetailViewHolder->setVisible(false); //不显示先 +} + +DFileManagerWindow::DFileManagerWindow(QWidget *parent) + : DFileManagerWindow(DUrl(), parent) +{ + AC_SET_OBJECT_NAME(this, AC_COMPUTER_MIAN_WINDOW); + AC_SET_ACCESSIBLE_NAME(this, AC_COMPUTER_MIAN_WINDOW); +} + +QPair winId_mtx; //异步初始化win插件 +DFileManagerWindow::DFileManagerWindow(const DUrl &fileUrl, QWidget *parent) + : DMainWindow(parent) + , d_ptr(new DFileManagerWindowPrivate(this)) +{ + AC_SET_OBJECT_NAME(this, AC_COMPUTER_MIAN_WINDOW); + AC_SET_ACCESSIBLE_NAME(this, AC_COMPUTER_MIAN_WINDOW); + /// init global AppController + setWindowIcon(QIcon::fromTheme("dde-file-manager")); + if (!winId_mtx.first) { + //等待异步加载完成 + winId_mtx.second.lock(); + winId_mtx.first = true; + winId_mtx.second.unlock(); + } + winId(); + initData(); + initUI(); + initConnect(); + + //202007010032【文件管理器】【5.1.2.10-1】【sp2】(.doc,ppt,xls)文件拖拽到桌面上的文件管理器图标上,被识别为文件夹打开, + // 判断出入的url是否是一个目录,不是就取parentUrl + DUrl newurl = fileUrl; + //排除u盘自动挂载,并且自动打开,拖拽的文件都是FILE_SCHEME + if (newurl.scheme() == FILE_SCHEME || newurl.scheme() == DFMVAULT_SCHEME) { + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(nullptr, fileUrl); + + if (fileInfo && !fileInfo->isDir()) { + newurl = fileUrl.parentUrl(); + } + } + + openNewTab(newurl); +} + +DFileManagerWindow::~DFileManagerWindow() +{ + m_currentTab = nullptr; + auto menu = titlebar()->menu(); + if (menu) { + delete menu; + menu = nullptr; + } +} + +void DFileManagerWindow::onRequestCloseTab(const int index, const bool &remainState) +{ + D_D(DFileManagerWindow); + + Tab *tab = d->tabBar->tabAt(index); + + if (!tab) { + return; + } + + DFMBaseView *view = tab->fileView(); + + d->viewStackLayout->removeWidget(view->widget()); + view->deleteLater(); + + // delete 之后某些逻辑任然被误触发, 设置标志让 view 自己能判断这种情况 + // 若 QObject 更直接的方式判断, 可以直接修改 + DFileView *dfileview = dynamic_cast(view); + if (dfileview) { + dfileview->setDestroyFlag(true); + } + + d->toolbar->removeNavStackAt(index); + d->tabBar->removeTab(index, remainState); +} + +void DFileManagerWindow::closeCurrentTab(quint64 winId) +{ + D_D(DFileManagerWindow); + + if (winId != this->winId()) { + return; + } + + if (d->tabBar->count() == 1) { + close(); + return; + } + + emit d->tabBar->tabCloseRequested(d->tabBar->currentIndex()); +} + +// 关闭当前窗口的所有保险箱的标签 +void DFileManagerWindow::closeAllTabOfVault(quint64 winId) +{ + D_D(DFileManagerWindow); + + // 传入的窗口ID不是当前活动窗口ID + if (winId != this->winId()) { + return; + } + + // 当前只有一个标签,不用关闭 + int nCount = d->tabBar->count(); + if (nCount < 2) { + return; + } + + // 记录是否有除保险箱之外的标签 + bool bOtherTab = false; + for (int i = nCount - 1; i > -1; --i) { + Tab *tab = d->tabBar->tabAt(i); + if (!tab) { + return; + } + + DUrl url = tab->currentUrl(); + if (VaultController::isVaultFile(url.toString())) { + if (i == 0) { // 当判断到最后一个标签时,如何没有其它标签,则保留该标签 + if (!bOtherTab) { + return; + } + } + // 删除编号对应的标签 + emit d->tabBar->tabCloseRequested(i); + } else { + bOtherTab = true; + } + } +} + +void DFileManagerWindow::showNewTabButton() +{ + D_D(DFileManagerWindow); + d->newTabButton->show(); + d->tabTopLine->show(); + d->tabBottomLine->show(); +} + +void DFileManagerWindow::hideNewTabButton() +{ + D_D(DFileManagerWindow); + d->newTabButton->hide(); + d->tabTopLine->hide(); + d->tabBottomLine->hide(); +} + +void DFileManagerWindow::showEmptyTrashButton() +{ + Q_D(DFileManagerWindow); + d->emptyTrashHolder->show(); + d->emptyTrashSplitLine->show(); +} + +void DFileManagerWindow::hideEmptyTrashButton() +{ + Q_D(DFileManagerWindow); + d->emptyTrashHolder->hide(); + d->emptyTrashSplitLine->hide(); +} + +void DFileManagerWindow::onNewTabButtonClicked() +{ + DUrl url = DFMApplication::instance()->appUrlAttribute(DFMApplication::AA_UrlOfNewTab); + + if (!url.isValid()) { + url = currentUrl(); + } + + openNewTab(url); +} + +void DFileManagerWindow::requestEmptyTrashFiles() +{ + DFMGlobal::clearTrash(); +} + +void DFileManagerWindow::onTrashStateChanged() +{ + if (currentUrl() == DUrl::fromTrashFile("/") && !TrashManager::isEmpty()) { + showEmptyTrashButton(); + } else { + hideEmptyTrashButton(); + } +} + +void DFileManagerWindow::onTabAddableChanged(bool addable) +{ + D_D(DFileManagerWindow); + + d->newTabButton->setEnabled(addable); +} + +void DFileManagerWindow::onCurrentTabChanged(int tabIndex) +{ + D_D(DFileManagerWindow); + + Tab *tab = d->tabBar->tabAt(tabIndex); + + if (tab) { + d->toolbar->switchHistoryStack(tabIndex); + + if (!tab->fileView()) { + return; + } + + switchToView(tab->fileView()); + // bug 32988 进入标签先刷新一次,解决保险箱重命名文件夹,在标签目录下出现重复文件夹 + tab->fileView()->refresh(); + +// if (currentUrl().isSearchFile()) { +// if (!d->toolbar->getSearchBar()->isVisible()) { +// d->toolbar->searchBarActivated(); +// d->toolbar->getSearchBar()->setText(tab->fileView()->rootUrl().searchKeyword()); +// } +// } else { +// if (d->toolbar->getSearchBar()->isVisible()) { +// d->toolbar->searchBarDeactivated(); +// } +// } + } +} + +DUrl DFileManagerWindow::currentUrl() const +{ + D_DC(DFileManagerWindow); + + return d->currentView ? d->currentView->rootUrl() : DUrl(); +} + +DFMBaseView::ViewState DFileManagerWindow::currentViewState() const +{ + D_DC(DFileManagerWindow); + + return d->currentView ? d->currentView->viewState() : DFMBaseView::ViewIdle; +} + +bool DFileManagerWindow::isCurrentUrlSupportSearch(const DUrl ¤tUrl) +{ + const DAbstractFileInfoPointer ¤tFileInfo = DFileService::instance()->createFileInfo(this, currentUrl); + + if (!currentFileInfo || !currentFileInfo->canIteratorDir()) { + return false; + } + return true; +} + +DToolBar *DFileManagerWindow::getToolBar() const +{ + D_DC(DFileManagerWindow); + + return d->toolbar; +} + +DFMBaseView *DFileManagerWindow::getFileView() const +{ + D_DC(DFileManagerWindow); + + return d->currentView; +} + +DFMSideBar *DFileManagerWindow::getLeftSideBar() const +{ + D_DC(DFileManagerWindow); + + return d->sideBar; +} + +int DFileManagerWindow::getSplitterPosition() const +{ + D_DC(DFileManagerWindow); + + return d->splitter ? d->splitter->sizes().at(0) : DFMSideBar::maximumWidth; +} + +void DFileManagerWindow::setSplitterPosition(int pos) +{ + Q_D(DFileManagerWindow); + + if (d->splitter) { + d->splitter->setSizes({pos, d->splitter->width() - pos - d->splitter->handleWidth()}); + } +} + +quint64 DFileManagerWindow::windowId() +{ + return WindowManager::getWindowId(this); +} + +bool DFileManagerWindow::tabAddable() const +{ + D_DC(DFileManagerWindow); + return d->tabBar->tabAddable(); +} + +bool DFileManagerWindow::cd(const DUrl &fileUrl) +{ + D_D(DFileManagerWindow); + + if (!d->tabBar->currentTab()) { + d->toolbar->addHistoryStack(); + d->tabBar->createTab(nullptr); + } + // fix bug 99023 smb挂载成功后所有的标签页是访问smb网络地址的都需要切换到挂载点 + DUrl tmpUrl; + if (fileUrl.scheme().contains(NETWORK_REDIRECT_SCHEME_EX)) { + tmpUrl.setScheme(fileUrl.scheme().replace(NETWORK_REDIRECT_SCHEME_EX, "")); + DUrl newworkUrl = DUrl(fileUrl.query()); + tmpUrl.setPath(fileUrl.path()); + for (int i = 0; i < d->tabBar->count(); ++i) { + if (i == d->tabBar->currentIndex()) + continue; + if (d->tabBar->tabAt(i)->currentUrl() == newworkUrl) + d->cdForTab(d->tabBar->tabAt(i), tmpUrl); + } + } else { + tmpUrl = fileUrl; + } + + if (!d->cdForTab(d->tabBar->currentTab(), tmpUrl)) { + return false; + } + + this->hideRenameBar(); + + return true; +} + +bool DFileManagerWindow::cdForTab(int tabIndex, const DUrl &fileUrl) +{ + Q_D(DFileManagerWindow); + + return d->cdForTab(d->tabBar->tabAt(tabIndex), fileUrl); +} + +bool DFileManagerWindow::cdForTabByView(DFMBaseView *view, const DUrl &fileUrl) +{ + Q_D(DFileManagerWindow); + + for (int i = 0; i < d->tabBar->count(); ++i) { + Tab *tab = d->tabBar->tabAt(i); + + if (tab->fileView() == view) { + return d->cdForTab(tab, fileUrl); + } + } + + return false; +} + +bool DFileManagerWindow::openNewTab(DUrl fileUrl) +{ + D_D(DFileManagerWindow); + + if (!d->tabBar->tabAddable()) { + return false; + } + + if (fileUrl.isEmpty()) { + fileUrl = DUrl::fromLocalFile(QDir::homePath()); + } + + d->toolbar->addHistoryStack(); + d->setCurrentView(nullptr); + d->tabBar->createTab(nullptr); + + return cd(fileUrl); +} + +void DFileManagerWindow::switchToView(DFMBaseView *view) +{ + D_D(DFileManagerWindow); + + if (d->currentView == view) { + return; + } + + const DUrl &old_url = currentUrl(); + + DFMBaseView::ViewState old_view_state = currentViewState(); + + d->setCurrentView(view); + d->viewStackLayout->setCurrentWidget(view->widget()); + + if (old_view_state != view->viewState()) + emit currentViewStateChanged(); + + if (view && view->rootUrl() == old_url) { + return; + } + + emit currentUrlChanged(); +} + +void DFileManagerWindow::moveCenter(const QPoint &cp) +{ + QRect qr = frameGeometry(); + + qr.moveCenter(cp); + move(qr.topLeft()); +} + +void DFileManagerWindow::moveTopRight() +{ + QRect pRect; + pRect = qApp->desktop()->availableGeometry(); + int x = pRect.width() - width(); + move(QPoint(x, 0)); +} + +void DFileManagerWindow::moveTopRightByRect(QRect rect) +{ + int x = rect.x() + rect.width() - width(); + move(QPoint(x, 0)); +} + +void DFileManagerWindow::closeEvent(QCloseEvent *event) +{ + Q_D(DFileManagerWindow); + + // fix bug 59239 drag事件的接受者的drop事件和发起drag事件的发起者的mousemove事件处理完成才能 + // 析构本窗口 + DFileView *fv = dynamic_cast(d->currentView); + if (fv) + connect(fv,&DFileView::requestWindowDestruct,this,&DFileManagerWindow::onRequestDestruct); + emit aboutToClose(); + d->m_isNeedClosed.store(true); + + DMainWindow::closeEvent(event); +} + +void DFileManagerWindow::hideEvent(QHideEvent *event) +{ + QVariantMap state; + state["sidebar"] = getSplitterPosition(); + DFMApplication::appObtuselySetting()->setValue("WindowManager", "SplitterState", state); + + return DMainWindow::hideEvent(event); +} + +void DFileManagerWindow::mouseDoubleClickEvent(QMouseEvent *event) +{ + D_DC(DFileManagerWindow); + + if (event->y() <= d->titleFrame->height()) { + if (isMaximized()) { + showNormal(); + } else { + showMaximized(); + } + } else { + DMainWindow::mouseDoubleClickEvent(event); + } +} + +void DFileManagerWindow::moveEvent(QMoveEvent *event) +{ + DMainWindow::moveEvent(event); + + emit positionChanged(event->pos()); +} + +void DFileManagerWindow::keyPressEvent(QKeyEvent *event) +{ + Q_D(DFileManagerWindow); + + if (!d->processKeyPressEvent(event)) { + return DMainWindow::keyPressEvent(event); + } +} + +bool DFileManagerWindow::eventFilter(QObject *watched, QEvent *event) +{ + Q_D(DFileManagerWindow); + + if (watched == titlebar()) { + return d->processTitleBarEvent(static_cast(event)); + } + + if (!getFileView() || watched != getFileView()->widget()) { + return false; + } + + if (event->type() != QEvent::KeyPress) { + return false; + } + + return d->processKeyPressEvent(static_cast(event)); +} + +void DFileManagerWindow::resizeEvent(QResizeEvent *event) +{ + DMainWindow::resizeEvent(event); +} + +bool DFileManagerWindow::fmEvent(const QSharedPointer &event, QVariant *resultData) +{ + Q_UNUSED(resultData) + Q_D(DFileManagerWindow); + + switch (event->type()) { + case DFMEvent::Back: + d->toolbar->back(); + return true; + case DFMEvent::Forward: + d->toolbar->forward(); + return true; + case DFMEvent::OpenNewTab: { + if (event->windowId() != this->internalWinId()) { + return false; + } + + openNewTab(event.staticCast()->url()); + + return true; + } + default: + break; + } + + return false; +} + +QObject *DFileManagerWindow::object() const +{ + return const_cast(this); +} + +void DFileManagerWindow::handleNewView(DFMBaseView *view) +{ + Q_UNUSED(view) +} + +void DFileManagerWindow::initData() +{ + +} + +void DFileManagerWindow::initUI() +{ + D_DC(DFileManagerWindow); + + resize(DEFAULT_WINDOWS_WIDTH, DEFAULT_WINDOWS_HEIGHT); + setMinimumSize(760, 420); + initTitleBar(); + initCentralWidget(); + setCentralWidget(d->centralWidget); +} + +void DFileManagerWindow::initTitleFrame() +{ + D_D(DFileManagerWindow); + + initToolBar(); + titlebar()->setIcon(QIcon::fromTheme("dde-file-manager", QIcon::fromTheme("system-file-manager"))); + d->titleFrame = new QFrame; + d->titleFrame->setObjectName("TitleBar"); + AC_SET_OBJECT_NAME(d->titleFrame, AC_COMPUTER_CUSTOM_TITLE_BAR); + AC_SET_ACCESSIBLE_NAME(d->titleFrame, AC_COMPUTER_CUSTOM_TITLE_BAR); + QHBoxLayout *titleLayout = new QHBoxLayout; + titleLayout->setMargin(0); + titleLayout->setSpacing(0); + + titleLayout->addWidget(d->toolbar); + titleLayout->setSpacing(0); + titleLayout->setContentsMargins(0, 7, 0, 7); + d->titleFrame->setLayout(titleLayout); + d->titleFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); +} + +void DFileManagerWindow::initTitleBar() +{ + D_D(DFileManagerWindow); + + initTitleFrame(); + + DFileMenu *menu = fileMenuManger->createToolBarSettingsMenu(); + + menu->setProperty("DFileManagerWindow", (quintptr)this); + menu->setProperty("ToolBarSettingsMenu", true); + menu->setEventData(DUrl(), DUrlList() << DUrl(), winId(), this); + + titlebar()->setMenu(menu); + titlebar()->setContentsMargins(0, 0, 0, 0); + titlebar()->setCustomWidget(d->titleFrame, false); + + // fix: titlebar的move事件在自定义的耗时异步事件时会失效,因此自行处理titlebar的事件 + titlebar()->installEventFilter(this); +} + +void DFileManagerWindow::initSplitter() +{ + D_D(DFileManagerWindow); + + initLeftSideBar(); + initRightView(); + + d->splitter = new DFMSplitter(Qt::Horizontal, this); + d->splitter->addWidget(d->sideBar); + d->splitter->addWidget(d->rightView); + d->splitter->setChildrenCollapsible(false); +} + +void DFileManagerWindow::initLeftSideBar() +{ + D_D(DFileManagerWindow); + + d->sideBar = new DFMSideBar(this); + d->sideBar->setContentsMargins(0, 0, 0, 0); + + d->sideBar->setObjectName("DFMSideBar"); + d->sideBar->setMaximumWidth(DFMSideBar::maximumWidth); + d->sideBar->setMinimumWidth(DFMSideBar::minimumWidth); + + // connections + connect(this, &DFileManagerWindow::currentUrlChanged, this, [this, d]() { + d->sideBar->setCurrentUrl(currentUrl()); + }); +} + +void DFileManagerWindow::initRightView() +{ + D_D(DFileManagerWindow); + + initTabBar(); + initViewLayout(); + d->rightView = new QFrame; + AC_SET_OBJECT_NAME(d->rightView, AC_DM_RIGHT_VIEW); + AC_SET_ACCESSIBLE_NAME(d->rightView, AC_DM_RIGHT_VIEW); + + QSizePolicy sp = d->rightView->sizePolicy(); + + //NOTE(zccrs): 保证窗口宽度改变时只会调整right view的宽度,侧边栏保持不变 + // QSplitter是使用QLayout的策略对widgets进行布局,所以此处 + // 设置size policy可以生效 + sp.setHorizontalStretch(1); + d->rightView->setSizePolicy(sp); + + this->initRenameBarState(); + + d->emptyTrashHolder = new QFrame(this); + d->emptyTrashHolder->setFrameShape(QFrame::NoFrame); + AC_SET_OBJECT_NAME(d->emptyTrashHolder, AC_DM_RIGHT_VIEW_TRASH_HOLDER); + AC_SET_ACCESSIBLE_NAME(d->emptyTrashHolder, AC_DM_RIGHT_VIEW_TRASH_HOLDER); + + QHBoxLayout *emptyTrashLayout = new QHBoxLayout(d->emptyTrashHolder); + QLabel *trashLabel = new QLabel(this); + AC_SET_OBJECT_NAME(trashLabel, AC_DM_RIGHT_VIEW_TRASH_LABEL); + AC_SET_ACCESSIBLE_NAME(trashLabel, AC_DM_RIGHT_VIEW_TRASH_LABEL); + trashLabel->setText(tr("Trash")); + QFont f = trashLabel->font(); + f.setPixelSize(17); + f.setBold(true); + trashLabel->setFont(f); + QPushButton *emptyTrashButton = new QPushButton{ this }; + emptyTrashButton->setContentsMargins(0, 0, 0, 0); + emptyTrashButton->setObjectName("EmptyTrashButton"); + AC_SET_ACCESSIBLE_NAME(emptyTrashButton, AC_DM_RIGHT_VIEW_EMPTY_TRASH_BUTTON); + emptyTrashButton->setText(tr("Empty")); + emptyTrashButton->setToolTip(QObject::tr("Empty Trash")); + emptyTrashButton->setFixedSize({86, 36}); + DPalette pal = DApplicationHelper::instance()->palette(this); + QPalette buttonPalette = emptyTrashButton->palette(); + buttonPalette.setColor(QPalette::ButtonText, pal.color(DPalette::Active, DPalette::TextWarning)); + emptyTrashButton->setPalette(buttonPalette); + QObject::connect(emptyTrashButton, &QPushButton::clicked, + this, &DFileManagerWindow::requestEmptyTrashFiles, Qt::QueuedConnection); + QPalette pa = emptyTrashButton->palette(); + pa.setColor(QPalette::ColorRole::Text, QColor("#FF5736")); + emptyTrashButton->setPalette(pa); + emptyTrashLayout->addWidget(trashLabel, 0, Qt::AlignLeft); + emptyTrashLayout->addWidget(emptyTrashButton, 0, Qt::AlignRight); + + d->emptyTrashSplitLine = new DHorizontalLine(this); + AC_SET_OBJECT_NAME(d->emptyTrashSplitLine, AC_DM_RIGHT_VIEW_TRASH_SPLIT_LINE); + AC_SET_ACCESSIBLE_NAME(d->emptyTrashSplitLine, AC_DM_RIGHT_VIEW_TRASH_SPLIT_LINE); + + QHBoxLayout *tabBarLayout = new QHBoxLayout; + tabBarLayout->setMargin(0); + tabBarLayout->setSpacing(0); + tabBarLayout->addWidget(d->tabBar); + tabBarLayout->addWidget(d->newTabButton); + + d->tabTopLine->setFixedHeight(1); + d->tabBottomLine->setFixedHeight(1); + + d->rightViewLayout = new QVBoxLayout; + d->rightViewLayout->addWidget(d->tabTopLine); + d->rightViewLayout->addLayout(tabBarLayout); + d->rightViewLayout->addWidget(d->tabBottomLine); + d->rightViewLayout->addWidget(d->emptyTrashHolder); + d->rightViewLayout->addWidget(d->emptyTrashSplitLine); + d->rightViewLayout->addLayout(d->viewStackLayout, 1); + d->rightViewLayout->setSpacing(0); + d->rightViewLayout->setContentsMargins(0, 0, 0, 0); + d->rightView->setLayout(d->rightViewLayout); + d->emptyTrashHolder->hide(); + d->emptyTrashSplitLine->hide(); +} + +void DFileManagerWindow::initToolBar() +{ + D_D(DFileManagerWindow); + + d->toolbar = new DToolBar(this); + d->toolbar->setObjectName("ToolBar"); + + AC_SET_ACCESSIBLE_NAME(d->toolbar, AC_DM_TOOLBAR); +} + +void DFileManagerWindow::initTabBar() +{ + D_D(DFileManagerWindow); + + d->tabBar = new TabBar(this); + d->tabBar->setFixedHeight(36); + + d->newTabButton = new DIconButton(this); + d->newTabButton->setObjectName("NewTabButton"); + AC_SET_ACCESSIBLE_NAME(d->newTabButton, AC_VIEW_TAB_BAR_NEW_BUTTON); + d->newTabButton->setFixedSize(36, 36); + d->newTabButton->setIconSize({24, 24}); + d->newTabButton->setIcon(QIcon::fromTheme("dfm_tab_new")); + d->newTabButton->setFlat(true); + d->newTabButton->hide(); + + d->tabTopLine = new DHorizontalLine(this); + AC_SET_OBJECT_NAME(d->tabTopLine, AC_VIEW_TAB_BAR_TOP_LINE); + AC_SET_ACCESSIBLE_NAME(d->tabTopLine, AC_VIEW_TAB_BAR_TOP_LINE); + + d->tabBottomLine = new DHorizontalLine(this); + AC_SET_OBJECT_NAME(d->tabBottomLine, AC_VIEW_TAB_BAR_BOTTOM_LINE); + AC_SET_ACCESSIBLE_NAME(d->tabBottomLine, AC_VIEW_TAB_BAR_BOTTOM_LINE); + + d->tabTopLine->hide(); + d->tabBottomLine->hide(); +} + +void DFileManagerWindow::initViewLayout() +{ + D_D(DFileManagerWindow); + + d->viewStackLayout = new QStackedLayout; + d->viewStackLayout->setSpacing(0); + d->viewStackLayout->setContentsMargins(0, 0, 0, 0); +} + +void DFileManagerWindow::initCentralWidget() +{ + D_D(DFileManagerWindow); + initSplitter(); + + d->centralWidget = new QFrame(this); + d->centralWidget->setObjectName("CentralWidget"); + AC_SET_ACCESSIBLE_NAME(d->centralWidget, AC_COMPUTER_CENTRAL_WIDGET); + QVBoxLayout *mainLayout = new QVBoxLayout; + + QWidget *midWidget = new QWidget; + d->midLayout = new QHBoxLayout; + AC_SET_OBJECT_NAME(midWidget, AC_VIEW_MID_WIDGET); + AC_SET_ACCESSIBLE_NAME(midWidget, AC_VIEW_MID_WIDGET); + + midWidget->setLayout(d->midLayout); + //! lixiang start 设置后显示空间会大些 + d->midLayout->setContentsMargins(0, 0, 0, 0); + //! lixiang end + d->midLayout->addWidget(d->splitter); + + mainLayout->addWidget(midWidget); + mainLayout->setSpacing(0); + mainLayout->setContentsMargins(0, 0, 0, 0); + + AC_SET_OBJECT_NAME(d->centralWidget, AC_COMPUTER_CENTRAL_WIDGET); + AC_SET_ACCESSIBLE_NAME(d->centralWidget, AC_COMPUTER_CENTRAL_WIDGET); + d->centralWidget->setLayout(mainLayout); +} + +void DFileManagerWindow::initConnect() +{ + D_D(DFileManagerWindow); + + if (titlebar()) { + QObject::connect(titlebar(), SIGNAL(minimumClicked()), parentWidget(), SLOT(showMinimized())); + QObject::connect(titlebar(), SIGNAL(maximumClicked()), parentWidget(), SLOT(showMaximized())); + QObject::connect(titlebar(), SIGNAL(restoreClicked()), parentWidget(), SLOT(showNormal())); + QObject::connect(titlebar(), SIGNAL(closeClicked()), parentWidget(), SLOT(close())); + } + + QObject::connect(fileSignalManager, &FileSignalManager::requestCloseCurrentTab, this, &DFileManagerWindow::closeCurrentTab); + + // 请求关闭窗口所有保险箱的标签 + QObject::connect(fileSignalManager, &FileSignalManager::requestCloseAllTabOfVault, + this, &DFileManagerWindow::closeAllTabOfVault); + + QObject::connect(d->tabBar, &TabBar::tabMoved, d->toolbar, &DToolBar::moveNavStacks); + QObject::connect(d->tabBar, &TabBar::currentChanged, this, &DFileManagerWindow::onCurrentTabChanged); + QObject::connect(d->tabBar, &TabBar::tabCloseRequested, this, &DFileManagerWindow::onRequestCloseTab); + QObject::connect(d->tabBar, &TabBar::tabAddableChanged, this, &DFileManagerWindow::onTabAddableChanged); + + QObject::connect(d->tabBar, &TabBar::tabBarShown, this, &DFileManagerWindow::showNewTabButton); + QObject::connect(d->tabBar, &TabBar::tabBarHidden, this, &DFileManagerWindow::hideNewTabButton); + QObject::connect(d->newTabButton, &QPushButton::clicked, this, &DFileManagerWindow::onNewTabButtonClicked); + + QObject::connect(fileSignalManager, &FileSignalManager::trashStateChanged, this, &DFileManagerWindow::onTrashStateChanged); + QObject::connect(d->tabBar, &TabBar::currentChanged, this, &DFileManagerWindow::onTrashStateChanged); + + QObject::connect(this, &DFileManagerWindow::currentUrlChanged, this, [this, d] { + DUrl url = currentUrl(); + + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, url); + + if (VaultController::isVaultFile(url.toString())) + { + // 如果是快捷方式,则赋值为快捷方式的源文件路径,便于正常显示快捷方式的路径 + if (info->isSymLink()) { + url = info->symLinkTarget(); + url = VaultController::localUrlToVault(url); + } + } + d->tabBar->onCurrentUrlChanged(DFMUrlBaseEvent(this, url)); + d->toolbar->currentUrlChanged(DFMUrlBaseEvent(this, url)); + this->onTrashStateChanged(); + + if (info) + { + setWindowTitle(info->fileDisplayName()); + } else if (url.isComputerFile()) + { + setWindowTitle(systemPathManager->getSystemPathDisplayName("Computer")); + } + }); + + QObject::connect(fileSignalManager, &FileSignalManager::requestMultiFilesRename, this, &DFileManagerWindow::onShowRenameBar); + QObject::connect(d->tabBar, &TabBar::currentChanged, this, &DFileManagerWindow::onTabBarCurrentIndexChange); + QObject::connect(d->toolbar, &DToolBar::detailButtonClicked, this, [this, d]() { + if (!d->rightDetailViewHolder) { + d->createRightDetailViewHolder(); + } + + if (d->rightDetailViewHolder) { + d->rightDetailViewHolder->setVisible(!d->rightDetailViewHolder->isVisible()); + //! 触发resize事件,避免文件列表未自适应宽度 + if (d->currentView && d->currentView->widget()) { + QSize variable(1, 1); + d->currentView->widget()->resize(d->currentView->widget()->size() - variable); + d->currentView->widget()->resize(d->currentView->widget()->size() + variable); + } + qDebug() << "File information window on the right"; + } + + // 这里需要更新 selectUrlChanged + d->updateSelectUrl(); + }); + + QObject::connect(this, &DFileManagerWindow::selectUrlChanged, this, [d](/*const QList &urlList*/) { + d->updateSelectUrl(); + }); + + //! redirect when tab root url changed. + QObject::connect(fileSignalManager, &FileSignalManager::requestRedirectTabUrl, this, &DFileManagerWindow::onRequestRedirectUrl); + QObject::connect(fileSignalManager, &FileSignalManager::requestCloseTab, this, &DFileManagerWindow::onRequestCloseTabByUrl); + QObject::connect(fileSignalManager, &FileSignalManager::cdFolder, this, &DFileManagerWindow::cd); +} + +void DFileManagerWindow::startSambaServiceAsync(Tab *tab, const DUrl &fileUrl) +{ + QDBusInterface interface("org.freedesktop.systemd1", + "/org/freedesktop/systemd1/unit/smbd_2eservice", + "org.freedesktop.systemd1.Unit", + QDBusConnection::systemBus()); + + QDBusPendingCall pcall = interface.asyncCall(QLatin1String("Start"), QString("replace")); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); + + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &DFileManagerWindow::callFinishedSlot); + + m_currentTab = tab; + m_currentUrl = fileUrl; +} + +void DFileManagerWindow::callFinishedSlot(QDBusPendingCallWatcher *watcher) +{ + QObject::disconnect(watcher, &QDBusPendingCallWatcher::finished, this, &DFileManagerWindow::callFinishedSlot); + + QDBusPendingReply<> reply = *watcher; + watcher->deleteLater(); + if (reply.isValid()) { + const QString &errorMsg = reply.reply().errorMessage(); + if (errorMsg.isEmpty()) { + qDebug() << "smbd service start success"; + + // 自启动 + // 这里创建链接文件 以便下次开机自启 + UserShareInterface userShareInterface("com.deepin.filemanager.daemon", + "/com/deepin/filemanager/daemon/UserShareManager", + QDBusConnection::systemBus(), + this); + QDBusReply reply = userShareInterface.createShareLinkFile(); + if (reply.isValid()) { + qDebug() << "set usershare password:" << reply.value(); + if(reply.value()) { + Q_D(DFileManagerWindow); + d->cdForTab(m_currentTab, m_currentUrl); + } + } else { + qDebug() << "set usershare password:" << reply.error(); + } + } + } else { + dialogManager->showErrorDialog(QString(), QObject::tr("Failed to start Samba services")); + } +} + +void DFileManagerWindow::moveCenterByRect(QRect rect) +{ + QRect qr = frameGeometry(); + qr.moveCenter(rect.center()); + move(qr.topLeft()); +} + + +void DFileManagerWindow::onShowRenameBar(const DFMUrlListBaseEvent &event) noexcept +{ + DFileManagerWindowPrivate *const d { d_func() }; + + if (event.windowId() == this->windowId()) { + d->storeUrlListToRenameBar(event.urlList()); //### get the urls of selection. + + m_currentTab = d->tabBar->currentTab(); + d->setRenameBarVisible(true); + } +} + +void DFileManagerWindow::onTabBarCurrentIndexChange(const int &index)noexcept +{ + DFileManagerWindowPrivate *const d{ d_func() }; + + if (m_currentTab != d->tabBar->tabAt(index)) { + + if (d->isRenameBarVisible() == true) { + this->onReuqestCacheRenameBarState();//###: invoke this function before setVisible. + + hideRenameBar(); + } + } +} + +void DFileManagerWindow::hideRenameBar() noexcept //###: Hide renamebar and then clear history. +{ + DFileManagerWindowPrivate *const d{ d_func() }; + + d->setRenameBarVisible(false); + d->resetRenameBar(); +} + + +void DFileManagerWindow::onReuqestCacheRenameBarState()const +{ + const DFileManagerWindowPrivate *const d{ d_func() }; + DFileManagerWindow::renameBarState = d->renameBar->getCurrentState();//###: record current state, when a new window is created from a already has tab. +} + +void DFileManagerWindow::onRequestRedirectUrl(const DUrl &tabRootUrl, const DUrl &newUrl) +{ + D_D(DFileManagerWindow); + + int curIndex = d->tabBar->currentIndex(); + int tabCount = d->tabBar->count(); + if (tabCount > 1) { + for (int i = 0; i < tabCount; i++) { + Tab *tab = d->tabBar->tabAt(i); + if (tabRootUrl == tab->fileView()->rootUrl()) { + onRequestCloseTab(i, false); + openNewTab(newUrl); + d->tabBar->setCurrentIndex(curIndex); + } + } + } +} + +void DFileManagerWindow::onRequestCloseTabByUrl(const DUrl &rootUrl) +{ + D_D(DFileManagerWindow); + if (rootUrl.toString() == TRASH_ROOT) { + return; + } + TabBar *tabBar = d->tabBar; + if (tabBar->count() <= 1) { + return; + } + int originIndex = tabBar->currentIndex(); + for (int i = tabBar->count() - 1; i >= 0 && tabBar->count() > 1; i--) { + Tab *tab = tabBar->tabAt(i); + if (tab->fileView()) { + DUrl tabUrl = tab->fileView()->rootUrl(); + if (FileUtils::isAncestorUrl(rootUrl, tabUrl)) { + onRequestCloseTab(i, false); + } + } + } + int curIndex = tabBar->currentIndex(); + if (curIndex != originIndex) { + if (originIndex < tabBar->count()) { + tabBar->setCurrentIndex(originIndex); + } + } +} + +void DFileManagerWindow::onRequestDestruct() +{ + Q_D(DFileManagerWindow); + if (d->m_isNeedClosed) + deleteLater(); +} + +void DFileManagerWindow::showEvent(QShowEvent *event) +{ + DMainWindow::showEvent(event); + + const QVariantMap &state = DFMApplication::appObtuselySetting()->value("WindowManager", "SplitterState").toMap(); + int splitterPos = state.value("sidebar", DFMSideBar::maximumWidth).toInt(); + setSplitterPosition(splitterPos); +} + +void DFileManagerWindow::initRenameBarState() +{ + DFileManagerWindowPrivate *const d{ d_func() }; + + bool expected{ true }; + ///###: CAS, when we draged a tab to leave TabBar for creating a new window. + if (DFileManagerWindow::flagForNewWindowFromTab.compare_exchange_strong(expected, false, std::memory_order_seq_cst)) { + + if (static_cast(DFileManagerWindow::renameBarState) == true) { //###: when we drag a tab to create a new window, but the RenameBar is showing in last window. + //多标签情况下,renamebar可能存在隐藏的情况,在新窗口中打开目录会出现renamebar指针失效的问题 + //这种情况下需要跳过loadState + if (!d->renameBar || !d->renameBar->isVisible()) + return; + d->renameBar->loadState(DFileManagerWindow::renameBarState); + + } else { //###: when we drag a tab to create a new window, but the RenameBar is hiding. + d->setRenameBarVisible(false); + } + + } else { //###: when open a new window from right click menu. + d->setRenameBarVisible(false); + } +} + + +void DFileManagerWindow::requestToSelectUrls() +{ + DFileManagerWindowPrivate *const d{ d_func() }; + + //多标签情况下,renamebar可能存在隐藏的情况,在新窗口中打开目录会出现renamebar指针失效的问题 + //这种情况下需要跳过loadState + if (!d->renameBar || !d->renameBar->isVisible()) + return; + + if (static_cast(DFileManagerWindow::renameBarState) == true) { + d->renameBar->loadState(DFileManagerWindow::renameBarState); + + QList selectedUrls{ DFileManagerWindow::renameBarState->getSelectedUrl() }; + quint64 winId{ this->windowId() }; + DFMUrlListBaseEvent event{ nullptr, selectedUrls}; + event.setWindowId(winId); + + QTimer::singleShot(100, [ = ] { emit fileSignalManager->requestSelectFile(event); }); + + DFileManagerWindow::renameBarState.reset(nullptr); + } +} + +bool DFileManagerWindow::isAdvanceSearchBarVisible() +{ + Q_D(DFileManagerWindow); + + return d->isAdvanceSearchBarVisible(); +} + +void DFileManagerWindow::updateAdvanceSearchBarValue(const FileFilter *filter) +{ + Q_D(DFileManagerWindow); + + if (d->advanceSearchBar && isAdvanceSearchBarVisible()) + d->advanceSearchBar->updateFilterValue(filter); +} + +void DFileManagerWindow::toggleAdvanceSearchBar(bool visible, bool resetForm) +{ + Q_D(DFileManagerWindow); + + if (!d->currentView) return; + + if (d->isAdvanceSearchBarVisible() != visible) { + d->setAdvanceSearchBarVisible(visible); + } + + if (d->advanceSearchBar && resetForm) { + // fix bug 64066 + // 隐藏高级搜索时,更新view + d->advanceSearchBar->resetForm(!visible); + } +} + +void DFileManagerWindow::showFilterButton() +{ + Q_D(DFileManagerWindow); + + d->toolbar->setSearchButtonVisible(true); +} + +bool DFileManagerWindow::getCanDestruct() const +{ + Q_D(const DFileManagerWindow); + DFileView *fv = dynamic_cast(d->currentView); + if (fv) + return fv->getCanDestruct(); + return true; +} + +void DFileManagerWindow::clearActions() +{ + if (fileMenuManger) + fileMenuManger->clearActions(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfilemanagerwindow.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfilemanagerwindow.h new file mode 100644 index 0000000..5aa8a00 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfilemanagerwindow.h @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DFILEMANAGERWINDOW_H +#define DFILEMANAGERWINDOW_H + +#include "durl.h" +#include "dfmglobal.h" +#include "dfmabstracteventhandler.h" +#include "shutil/filebatchprocess.h" + + +#include + +#include + +#include +#include +#include + +#define DEFAULT_WINDOWS_WIDTH 960 +#define DEFAULT_WINDOWS_HEIGHT 540 + +class DTitleBar; +class DToolBar; +class DDetailView; +class QStatusBar; +class QFrame; +class QHBoxLayout; +class QVBoxLayout; +class QResizeEvent; + +class ExtendView; +class QStackedLayout; +class QPushButton; + +class DStatusBar; +class DFMEvent; +class DFMUrlBaseEvent; +class TabBar; +class Tab; +class RecordRenameBarState; + + +class DFMUrlListBaseEvent; +typedef struct fileFilter FileFilter; + +DFM_BEGIN_NAMESPACE +class DFMSideBar; +class DFMAddressBar; +DFM_END_NAMESPACE + +DWIDGET_USE_NAMESPACE +DFM_USE_NAMESPACE + +extern QPair winId_mtx; + +class DFileManagerWindowPrivate; +class DFileManagerWindow : public DMainWindow, public DFMAbstractEventHandler +{ + Q_OBJECT +public: + explicit DFileManagerWindow(QWidget *parent = nullptr); + explicit DFileManagerWindow(const DUrl &fileUrl, QWidget *parent = nullptr); + virtual ~DFileManagerWindow() override; + + DUrl currentUrl() const; + DFMBaseView::ViewState currentViewState() const; + bool isCurrentUrlSupportSearch(const DUrl ¤tUrl); + + DToolBar *getToolBar() const; + DFMBaseView *getFileView() const; + DFMSideBar *getLeftSideBar() const; + int getSplitterPosition() const; + + void setSplitterPosition(int pos); + + quint64 windowId(); + + bool tabAddable() const; + void hideRenameBar() noexcept; + void requestToSelectUrls(); + bool isAdvanceSearchBarVisible(); + void updateAdvanceSearchBarValue(const FileFilter *filter); + void toggleAdvanceSearchBar(bool visible = true, bool resetForm = true); + void showFilterButton(); + //获取能否析构 + bool getCanDestruct() const; + /** + * @brief 主动释放静态action + * @param + * @return + */ + void clearActions(); + +signals: + void aboutToClose(); + void positionChanged(const QPoint &pos); + void currentUrlChanged(); + void currentViewStateChanged(); + void selectUrlChanged(const QList &urlList); + +public slots: + void moveCenter(const QPoint &cp); + void moveTopRight(); + void moveCenterByRect(QRect rect); + void moveTopRightByRect(QRect rect); + + bool cd(const DUrl &fileUrl); + bool cdForTab(int tabIndex, const DUrl &fileUrl); + bool cdForTabByView(DFMBaseView *view, const DUrl &fileUrl); + + bool openNewTab(DUrl fileUrl); + void switchToView(DFMBaseView *view); + void onTabAddableChanged(bool addable); + void onCurrentTabChanged(int tabIndex); + void onRequestCloseTab(const int index, const bool &remainState); + void closeCurrentTab(quint64 winId); + // 关闭当前窗口的所有保险箱的标签 + void closeAllTabOfVault(quint64 winId); + void showNewTabButton(); + void hideNewTabButton(); + void showEmptyTrashButton(); + void hideEmptyTrashButton(); + void onNewTabButtonClicked(); + void requestEmptyTrashFiles(); + void onTrashStateChanged(); + + void onShowRenameBar(const DFMUrlListBaseEvent &event)noexcept; + void onTabBarCurrentIndexChange(const int &index)noexcept; + void onReuqestCacheRenameBarState() const; + //! re-direct url when root directory renamed. + void onRequestRedirectUrl(const DUrl &tabRootUrl, const DUrl &newUrl); + //! close tab when root directory deleted. + void onRequestCloseTabByUrl(const DUrl &rootUrl); + //! destruct current windows + void onRequestDestruct(); + +protected: + void showEvent(QShowEvent *event) override; + void closeEvent(QCloseEvent *event) override; + void hideEvent(QHideEvent *event) override; + void mouseDoubleClickEvent(QMouseEvent *event) override; + void moveEvent(QMoveEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + bool eventFilter(QObject *watched, QEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + bool fmEvent(const QSharedPointer &event, QVariant *resultData = nullptr) override; + QObject *object() const override; + + virtual void handleNewView(DFMBaseView *view); + + void initData(); + void initUI(); + + void initTitleFrame(); + void initTitleBar(); + void initSplitter(); + + void initLeftSideBar(); + + void initRightView(); + + void initRenameBarState(); + + void initToolBar(); + void initTabBar(); + void initViewLayout(); + + void initCentralWidget(); + void initConnect(); + +private: + void startSambaServiceAsync(Tab *tab, const DUrl &fileUrl); +private slots: + void callFinishedSlot(QDBusPendingCallWatcher *watcher); + +private: + Tab *m_currentTab{ nullptr }; + DUrl m_currentUrl; + std::atomic m_tabBarIndexChangeFlag{ false };//###: when the index of tabbar changed hide RenameBar through the value. + + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), DFileManagerWindow) + +public: + static std::unique_ptr renameBarState;//###: record pattern of RenameBar and the string of QLineEdit's content. + static std::atomic flagForNewWindowFromTab; //###: open a new window form a already has tab, this will be true. + //and after opening new window this will be back to false. +}; + +#endif // DFILEMANAGERWINDOW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfilemanagerwindow_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfilemanagerwindow_p.h new file mode 100644 index 0000000..0bf59e3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfilemanagerwindow_p.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DFILEMANAGERWINDOWPRIVATE_H +#define DFILEMANAGERWINDOWPRIVATE_H + +#include "dfmglobal.h" +#include "dfmbaseview.h" +#include "dtabbar.h" +#include "dfmsidebar.h" +#include "dfmrightdetailview.h" +#include "dtoolbar.h" +#include "diconbutton.h" +#include "dfmsplitter.h" +#include "DHorizontalLine" +#include "drenamebar.h" +#include "dfmadvancesearchbar.h" + +#include +#include + +DFM_USE_NAMESPACE + +class DFileManagerWindow; +class DFileManagerWindowPrivate +{ +public: + enum vaultRemove{ + SUCCESS, //! 移动成功 + FAILED, //! 移动失败 + NOTEXIST //! 文件不存在 + }; + + explicit DFileManagerWindowPrivate(DFileManagerWindow *qq) + : q_ptr(qq) {} + + void setCurrentView(DFMBaseView *view); + bool processKeyPressEvent(QKeyEvent *event); + bool processTitleBarEvent(QMouseEvent *event); + bool cdForTab(Tab *tab, const DUrl &fileUrl); + void initAdvanceSearchBar(); + bool isAdvanceSearchBarVisible() const; + void setAdvanceSearchBarVisible(bool visible); + void initRenameBar(); + bool isRenameBarVisible() const; + void setRenameBarVisible(bool visible); + void resetRenameBar(); + void storeUrlListToRenameBar(const QList &list) noexcept; + void updateSelectUrl(); + void createRightDetailViewHolder(); + /** + * @brief moveVaultPath 移动保险箱存储路径 + * @return 返回REMOVEOK移动成功,REMOVENO失败,EXIST文件不存在 + */ + DFileManagerWindowPrivate::vaultRemove moveVaultPath(); + + QFrame *centralWidget{ nullptr };//中央区域(所有的除顶部区域) + DFMSideBar *sideBar{ nullptr }; + QFrame *rightView { nullptr }; + DFMRightDetailView *detailView { nullptr }; + QFrame *rightDetailViewHolder { nullptr }; + QHBoxLayout *midLayout { nullptr }; + QVBoxLayout *rightViewLayout { nullptr }; + DToolBar *toolbar{ nullptr }; + TabBar *tabBar { nullptr }; + DIconButton *newTabButton { nullptr }; + QFrame *tabTopLine { nullptr }; + QFrame *tabBottomLine { nullptr }; + DFMBaseView *currentView { nullptr }; + DStatusBar *statusBar { nullptr }; + QVBoxLayout *mainLayout { nullptr }; + DFMSplitter *splitter { nullptr }; + QFrame *titleFrame { nullptr }; + QStackedLayout *viewStackLayout { nullptr };//右边文件显示的布局 + QFrame *emptyTrashHolder { nullptr }; + DHorizontalLine *emptyTrashSplitLine { nullptr }; + DRenameBar *renameBar{ nullptr }; + DFMAdvanceSearchBar *advanceSearchBar = nullptr; + QScrollArea *advanceSearchArea = nullptr; + + QMap views; + + bool move = false; + QPoint startPoint; + QPoint windowPoint; + //是否需要关闭 + QAtomicInteger m_isNeedClosed = false; + + DFileManagerWindow *q_ptr{ nullptr }; + + D_DECLARE_PUBLIC(DFileManagerWindow) +}; + +#endif // DFILEMANAGERWINDOWPRIVATE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfileview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfileview.cpp new file mode 100644 index 0000000..aab0f73 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfileview.cpp @@ -0,0 +1,4030 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "dfileview_p.h" +#include "dfileview.h" +#include "fileitem.h" +#include "dfilemenumanager.h" +#include "dfilemenu.h" +#include "windowmanager.h" +#include "dstatusbar.h" +#include "fileviewhelper.h" +#include "dfilemanagerwindow.h" +#include "dtoolbar.h" +#include "dabstractfilewatcher.h" +#include "dfmheaderview.h" +#include "dfmeventdispatcher.h" +#include "dfmsettings.h" +#include "dblockdevice.h" +#include "ddiskdevice.h" +#include "ddiskmanager.h" +#include "disomaster.h" +#include "dfmopticalmediawidget.h" +#include "io/dstorageinfo.h" +#include "app/define.h" +#include "app/filesignalmanager.h" + +#include "interfaces/dfmglobal.h" +#include "interfaces/diconitemdelegate.h" +#include "interfaces/dlistitemdelegate.h" +#include "dfmapplication.h" +#include "interfaces/dfmcrumbbar.h" +#include "dialogs/dialogmanager.h" + +#include "controllers/appcontroller.h" +#include "dfileservices.h" +#include "controllers/pathmanager.h" +#include "controllers/vaultcontroller.h" + +#include "models/dfileselectionmodel.h" +#include "dfilesystemmodel.h" + +#include "shutil/fileutils.h" +#include "shutil/mimesappsmanager.h" +#include "fileoperations/filejob.h" +#include "deviceinfo/udisklistener.h" + +#include "singleton.h" +#include "interfaces/dfilemenumanager.h" +#include "models/desktopfileinfo.h" +#include "dfmstandardpaths.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +#define ICON_VIEW_SPACING 5 +#define LIST_VIEW_SPACING 0 +#define LIST_VIEW_MINIMUM_WIDTH 80 + +#define DEFAULT_HEADER_SECTION_WIDTH 140 + +#define LOOPNUM 10 // 判断文件是否存在的循环次数 +#define WAITTIME 10 // 判断没有文件是否存在的间隔时间 + +#define ICON_X_OFFSET 10 +#define ICON_Y_OFFSET 10 +#define ICON_WIDTH_OFFSET -20 +#define ICON_HEIGHT_OFFSET -20 + +#define DRAGICON_SIZE 128 //拖拽聚合默认icon边长 +#define DRAGICON_OUTLINE 30 //增加外圈范围,防止旋转后部分图片的角绘制不到 +#define DRAGICON_MAX 4 //拖拽聚合最多绘制icon数量 +#define DRAGICON_ROTATE 10.0 //拖拽聚合旋转角度 +#define DRAGICON_OPACITY 0.1 //拖拽聚合透明度梯度 +#define DRAGICON_MAX_COUNT 99 //最大显示计数 + +SelectWork::SelectWork(QObject *parent) + : QThread(parent), m_pModel(nullptr), m_bStop(false) +{ +} + +void SelectWork::setInitData(QList lst, DFileSystemModel *model) +{ + // 修复bug-51429 bug-51039 bug-51503 + // 解决拷贝/剪贴文件到保险箱,文件没有选中问题 + QList::iterator itr = lst.begin(); + for (; itr != lst.end(); ++itr) { + QString path = (*itr).toLocalFile(); + if (VaultController::isVaultFile(path)) { + DUrl url(VaultController::localToVault(path)); + *itr = url; + } + } + m_lstNoValid = lst; + m_pModel = model; +} + +void SelectWork::startWork() +{ + m_bStop = false; + start(); +} + +void SelectWork::stopWork() +{ + m_bStop = true; +} + +void SelectWork::run() +{ + msleep(WAITTIME); + // 判断当前是否存在未处理的文件 + if (!m_lstNoValid.isEmpty()) { + QList::iterator itr = m_lstNoValid.begin(); + int loopNum = 0; + while (itr != m_lstNoValid.end()) { + msleep(WAITTIME); + // 修复bug-51429 bug-51039 bug-51503 + // 增加一个结束判断,当重复判断一个文件LOOPNUM次都不存在后,不在选中该文件 + if (loopNum > LOOPNUM) { + itr = m_lstNoValid.erase(itr); + continue; + } + if (m_bStop) + break; + if (!m_pModel) + break; + const QModelIndex &index = m_pModel->index(*itr); + if (index.isValid()) { + // 发送信号选中该文件 + emit sigSetSelect(*itr); + itr = m_lstNoValid.erase(itr); + loopNum = 0; + } else { + ++loopNum; + } + } + } + if (m_pModel) { + // 刷新模型 + m_pModel->update(); + } +} + +DFileView::DFileView(QWidget *parent) + : DListView(parent), d_ptr(new DFileViewPrivate(this)), m_currentTargetUrl(DUrl()) +{ + D_D(DFileView); + + d_ptr->enabledSelectionModes << NoSelection << SingleSelection + << MultiSelection << ExtendedSelection + << ContiguousSelection; + + d_ptr->defaultViewMode = static_cast(DFMApplication::instance()->appAttribute(DFMApplication::AA_ViewMode).toInt()); + +#if QT_VERSION < QT_VERSION_CHECK(5, 9, 0) + d_ptr->touchTapDistance = 15; +#else + d_ptr->touchTapDistance = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::TouchDoubleTapDistance).toInt(); +#endif + + AC_SET_OBJECT_NAME(this, AC_FILE_VIEW); + AC_SET_ACCESSIBLE_NAME(this, AC_FILE_VIEW); + + initUI(); + initModel(); + initDelegate(); + initConnects(); + + // 修复wayland TASK-37638 + // 初始化子线程 + m_pSelectWork = new SelectWork(); + connect(m_pSelectWork, &SelectWork::sigSetSelect, + this, &DFileView::slotSetSelect); + + setIconSizeBySizeIndex(DFMApplication::instance()->appAttribute(DFMApplication::AA_IconSizeLevel).toInt()); + d->updateStatusBarTimer = new QTimer(this); + d->updateStatusBarTimer->setInterval(100); + d->updateStatusBarTimer->setSingleShot(true); + connect(d->updateStatusBarTimer, &QTimer::timeout, this, &DFileView::updateStatusBar); + + d->diskmgr = new DDiskManager(this); + connect(d->diskmgr, &DDiskManager::opticalChanged, this, &DFileView::onDriveOpticalChanged); + d->diskmgr->setWatchChanges(true); +} + +DFileView::~DFileView() +{ + disconnect(this, &DFileView::rowCountChanged, this, &DFileView::onRowCountChanged); + disconnect(selectionModel(), &QItemSelectionModel::selectionChanged, this, &DFileView::delayUpdateStatusBar); + + if (m_pSelectWork) { + m_pSelectWork->stopWork(); + m_pSelectWork->wait(); + m_pSelectWork->deleteLater(); + m_pSelectWork = nullptr; + } + + //所有的槽函数必须跑完才能析构 + QMutexLocker lkUpdateStatusBar(&d_ptr->m_mutexUpdateStatusBar); +} + +DFileSystemModel *DFileView::model() const +{ + return qobject_cast(DListView::model()); +} + +DFMStyledItemDelegate *DFileView::itemDelegate() const +{ + return qobject_cast(DListView::itemDelegate()); +} + +void DFileView::setItemDelegate(DFMStyledItemDelegate *delegate) +{ + D_D(DFileView); + + QAbstractItemDelegate *dg = DListView::itemDelegate(); + + if (dg) + dg->deleteLater(); + + DListView::setItemDelegate(delegate); + + connect(d->statusBar->scalingSlider(), &QSlider::valueChanged, delegate, &DFMStyledItemDelegate::setIconSizeByIconSizeLevel); + + if (isIconViewMode()) { + d->statusBar->scalingSlider()->setMinimum(delegate->minimumIconSizeLevel()); + d->statusBar->scalingSlider()->setMaximum(delegate->maximumIconSizeLevel()); + } +} + +DStatusBar *DFileView::statusBar() const +{ + D_DC(DFileView); + + return d->statusBar; +} + +FileViewHelper *DFileView::fileViewHelper() const +{ + D_DC(DFileView); + + return d->fileViewHelper; +} + +DUrl DFileView::rootUrl() const +{ + return model()->rootUrl(); +} + +DFMBaseView::ViewState DFileView::viewState() const +{ + return model()->state() == DFileSystemModel::Busy ? ViewBusy : ViewIdle; +} + +QList DFileView::selectedUrls() const +{ + QModelIndex rootIndex = this->rootIndex(); + DUrlList list; + + for (const QModelIndex &index : selectedIndexes()) { + if (index.parent() != rootIndex) + continue; + + list << model()->getUrlByIndex(index); + } + + return list; +} + +bool DFileView::isIconViewMode() const +{ + D_DC(DFileView); + + return d->currentViewMode == IconMode; +} + +int DFileView::columnWidth(int column) const +{ + D_DC(DFileView); + + if (d->headerView) { + int logicalIndex = d->headerView->logicalIndex(column); + return d->headerView->sectionSize(logicalIndex); + } + + return 100; +} + +int DFileView::headerViewHeight() const +{ + D_DC(DFileView); + + return d->headerView ? d->headerView->height() : 0; +} + +void DFileView::setColumnWidth(int column, int width) +{ + D_D(DFileView); + + if (!d->headerView) + return; + + d->headerView->resizeSection(column, width); +} + +int DFileView::columnCount() const +{ + D_DC(DFileView); + + return d->headerView ? d->headerView->count() : 1; +} + +int DFileView::rowCount() const +{ + int count = this->count(); + int itemCountForRow = this->itemCountForRow(); + + return count / itemCountForRow + int(count % itemCountForRow > 0); +} + +int DFileView::itemCountForRow() const +{ + Q_D(const DFileView); + + if (!isIconViewMode()) + return 1; + + return d->iconModeColumnCount(); +} + +QList DFileView::columnRoleList() const +{ + D_DC(DFileView); + + return d->columnRoles; +} + +quint64 DFileView::windowId() const +{ + return WindowManager::getWindowId(this); +} + +void DFileView::setIconSize(const QSize &size) +{ + DListView::setIconSize(size); + + updateHorizontalOffset(); + updateGeometries(); +} + +DFileView::ViewMode DFileView::getDefaultViewMode() const +{ + D_DC(DFileView); + + return d->defaultViewMode; +} + +DFileView::ViewMode DFileView::viewMode() const +{ + D_DC(DFileView); + + return d->currentViewMode; +} + +bool DFileView::testViewMode(ViewModes modes, DFileView::ViewMode mode) const +{ + return (modes | mode) == modes; +} + +int DFileView::horizontalOffset() const +{ + D_DC(DFileView); + + return d->horizontalOffset; +} + +bool DFileView::isSelected(const QModelIndex &index) const +{ +#ifndef CLASSICAL_SECTION + return static_cast(selectionModel())->isSelected(index); +#else + return selectionModel()->isSelected(index); +#endif +} + +int DFileView::selectedIndexCount() const +{ +#ifndef CLASSICAL_SECTION + return static_cast(selectionModel())->selectedCount(); +#else + return selectionModel()->selectedIndexes().count(); +#endif +} + +QModelIndexList DFileView::selectedIndexes() const +{ +#ifndef CLASSICAL_SECTION + return static_cast(selectionModel())->selectedIndexes(); +#else + return selectionModel()->selectedIndexes(); +#endif +} + +QModelIndex DFileView::indexAt(const QPoint &point) const +{ + Q_D(const DFileView); + + if (isIconViewMode()) { + for (QModelIndex &index : itemDelegate()->hasWidgetIndexs()) { + if (index == itemDelegate()->editingIndex()) + continue; + + QWidget *widget = indexWidget(index); + + if (widget && widget->isVisible() && widget->geometry().contains(point)) { + return index; + } + } + } + + QPoint pos = QPoint(point.x() + horizontalOffset(), point.y() + verticalOffset()); + QSize item_size = itemSizeHint(); + + if (pos.y() % (item_size.height() + spacing() * 2) < spacing()) + return QModelIndex(); + + int index = -1; + + if (item_size.width() == -1) { + int item_height = item_size.height() + LIST_VIEW_SPACING * 2; + + index = pos.y() / item_height; + } else { + int item_width = item_size.width() + ICON_VIEW_SPACING * 2; + + if (pos.x() % item_width <= ICON_VIEW_SPACING) + return QModelIndex(); + + int row_index = pos.y() / (item_size.height() + ICON_VIEW_SPACING * 2); + int column_count = d->iconModeColumnCount(item_width); + int column_index = pos.x() / item_width; + + if (column_index >= column_count) + return QModelIndex(); + + index = row_index * column_count + column_index; + + const QModelIndex &tmp_index = rootIndex().child(index, 0); + QStyleOptionViewItem option = viewOptions(); + + option.rect = QRect(QPoint(column_index * item_width + ICON_VIEW_SPACING, + row_index * (item_size.height() + ICON_VIEW_SPACING * 2) + ICON_VIEW_SPACING), + item_size); + + const QList &list = itemDelegate()->paintGeomertys(option, tmp_index); + + auto ret = std::any_of(list.begin(), list.end(), [pos](const QRect &rect) { + return rect.contains(pos); + }); + if (ret) + return tmp_index; + + return QModelIndex(); + } + + return rootIndex().child(index, 0); +} + +QRect DFileView::visualRect(const QModelIndex &index) const +{ + Q_D(const DFileView); + + QRect rect; + + if (index.column() != 0) + return rect; + + QSize item_size = itemSizeHint(); + + if (item_size.width() == -1) { + rect.setLeft(LIST_VIEW_SPACING - horizontalScrollBar()->value()); + rect.setRight(viewport()->width() - LIST_VIEW_SPACING - 1); + rect.setTop(index.row() * (item_size.height() + LIST_VIEW_SPACING * 2) + LIST_VIEW_SPACING); + rect.setHeight(item_size.height()); + + if (d->allowedAdjustColumnSize) { + rect.setWidth(d->headerView->length()); + } + } else { + int item_width = item_size.width() + ICON_VIEW_SPACING * 2; + int column_count = d->iconModeColumnCount(item_width); + + if (column_count == 0) + return rect; + + int column_index = index.row() % column_count; + int row_index = index.row() / column_count; + + rect.setTop(row_index * (item_size.height() + ICON_VIEW_SPACING * 2) + ICON_VIEW_SPACING); + rect.setLeft(column_index * item_width + ICON_VIEW_SPACING); + rect.setSize(item_size); + } + + rect.moveLeft(rect.left() - horizontalOffset()); + rect.moveTop(rect.top() - verticalOffset()); + + return rect; +} + +DFileView::RandeIndexList DFileView::visibleIndexes(QRect rect) const +{ + Q_D(const DFileView); + + RandeIndexList list; + + QSize item_size = itemSizeHint(); + QSize icon_size = iconSize(); + + int count = this->count(); + int spacing = this->spacing(); + int item_width = item_size.width() + spacing * 2; + int item_height = item_size.height() + spacing * 2; + + if (item_size.width() == -1) { + list << RandeIndex(qMax((rect.top() + spacing) / item_height, 0), + qMin((rect.bottom() - spacing) / item_height, count - 1)); + } else { + rect -= QMargins(spacing, spacing, spacing, spacing); + + int column_count = d->iconModeColumnCount(item_width); + + if (column_count <= 0) + return list; + + int begin_row_index = rect.top() / item_height; + int end_row_index = rect.bottom() / item_height; + int begin_column_index = rect.left() / item_width; + int end_column_index = rect.right() / item_width; + + if (rect.top() % item_height > icon_size.height()) + ++begin_row_index; + + int icon_margin = (item_width - icon_size.width()) / 2; + + if (rect.left() % item_width > item_width - icon_margin) + ++begin_column_index; + + if (rect.right() % item_width < icon_margin) + --end_column_index; + + begin_row_index = qMax(begin_row_index, 0); + begin_column_index = qMax(begin_column_index, 0); + end_row_index = qMin(end_row_index, count / column_count); + end_column_index = qMin(end_column_index, column_count - 1); + + if (begin_row_index > end_row_index || begin_column_index > end_column_index) + return list; + + int begin_index = begin_row_index * column_count; + + if (end_column_index - begin_column_index + 1 == column_count) { + list << RandeIndex(qMax(begin_index, 0), qMin((end_row_index + 1) * column_count - 1, count - 1)); + + return list; + } + + for (int i = begin_row_index; i <= end_row_index; ++i) { + if (begin_index + begin_column_index >= count) + break; + + list << RandeIndex(qMax(begin_index + begin_column_index, 0), + qMin(begin_index + end_column_index, count - 1)); + + begin_index += column_count; + } + } + + return list; +} + +QSize DFileView::itemSizeHint() const +{ + + return itemDelegate()->sizeHint(viewOptions(), rootIndex()); +} + +bool DFileView::isDropTarget(const QModelIndex &index) const +{ + D_DC(DFileView); + + return d->dragMoveHoverIndex == index; +} + +bool DFileView::cd(const DUrl &url) +{ + DFileManagerWindow *w = qobject_cast(WindowManager::getWindowById(windowId())); + + return w && w->cd(url); +} + +bool DFileView::cdUp() +{ + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(rootIndex()); + + const DUrl &oldCurrentUrl = rootUrl(); + const DUrl &parentUrl = fileInfo ? fileInfo->parentUrl() : DUrl::parentUrl(oldCurrentUrl); + + if (parentUrl.isValid() && !parentUrl.isRecentFile()) + return cd(parentUrl); + return cd(DUrl::fromComputerFile("/")); +} + +bool DFileView::edit(const QModelIndex &index, QAbstractItemView::EditTrigger trigger, QEvent *event) +{ + DUrl fileUrl = model()->getUrlByIndex(index); + + if (fileUrl.isEmpty() || selectedIndexCount() > 1 || (trigger == SelectedClicked && DFMGlobal::keyShiftIsPressed())) + return false; +#ifdef SW_LABEL + bool isCheckRenameAction = false; +#endif + if (trigger == SelectedClicked && !isIconViewMode()) { + QStyleOptionViewItem option = viewOptions(); + + option.rect = visualRect(index); + ; + + const QRect &file_name_rect = itemDelegate()->fileNameRect(option, index); + + if (!file_name_rect.contains(static_cast(event)->pos())) { + return false; + } else { +#ifdef SW_LABEL + isCheckRenameAction = true; +#endif + } + } +#ifdef SW_LABEL + if (trigger == EditKeyPressed) { + isCheckRenameAction = true; + } + + if (isCheckRenameAction) { + bool isCanRename = checkRenamePrivilege_sw(fileUrl); + if (!isCanRename) + return false; + } +#endif + if (trigger == EditKeyPressed || trigger == AllEditTriggers) { + emit fileDialogRename(); + } + + return DListView::edit(index, trigger, event); +} + +void DFileView::select(const QList &list) +{ + QModelIndex firstIndex; + QModelIndex lastIndex; + const QModelIndex &root = rootIndex(); + clearSelection(); + for (DUrl url : list) { + // 保险箱路径特殊处理 + if (VaultController::isVaultFile(url.toString())) + url = VaultController::localUrlToVault(url); + const QModelIndex &index = model()->index(url); + + if (!index.isValid() || index == root) { + continue; + } + + selectionModel()->select(index, QItemSelectionModel::Select); + + if (!firstIndex.isValid()) + firstIndex = index; + + lastIndex = index; + } + + if (lastIndex.isValid()) + selectionModel()->setCurrentIndex(lastIndex, QItemSelectionModel::Select); + + if (firstIndex.isValid()) + scrollTo(firstIndex, PositionAtTop); +} + +void DFileView::selectAllAfterCutOrCopy(const QList &list) +{ + QModelIndex firstIndex; + QModelIndex lastIndex; + const QModelIndex &root = rootIndex(); + clearSelection(); + + // 修复wayland TASK-37638 缓存为选中的拷贝或剪贴文件 + QList lstNoValid; + + for (DUrl url : list) { + // 保险箱路径特殊处理 + if (VaultController::isVaultFile(url.toString())) + url = VaultController::localUrlToVault(url); + const QModelIndex &index = model()->index(url); + + // 缓存没有刷新的文件对象 + if (!index.isValid()) { + lstNoValid.push_back(url); + continue; + } + + if (index == root) { + continue; + } + + // 将文件对象设置成选中状态 + selectionModel()->select(index, QItemSelectionModel::Select); + + if (!firstIndex.isValid()) + firstIndex = index; + + lastIndex = index; + } + + if (lastIndex.isValid()) + selectionModel()->setCurrentIndex(lastIndex, QItemSelectionModel::Select); + + if (firstIndex.isValid()) + scrollTo(firstIndex, PositionAtTop); + + // 修复wayland TASK-37638 启动子线程,选中为选中的拷贝或剪贴的文件 + if (!lstNoValid.isEmpty() && m_pSelectWork) { + if (m_pSelectWork->isRunning()) { + m_pSelectWork->stopWork(); + m_pSelectWork->wait(); + } + // 启动子线程 + m_pSelectWork->setInitData(lstNoValid, model()); + m_pSelectWork->startWork(); + } +} + +void DFileView::slotSetSelect(DUrl url) +{ + const QModelIndex &index = model()->index(url); + if (index.isValid()) + selectionModel()->select(index, QItemSelectionModel::Select); +} + +void DFileView::setDefaultViewMode(DFileView::ViewMode mode) +{ + Q_D(DFileView); + d->defaultViewMode = mode; + + const DUrl &root_url = rootUrl(); + + //fix task wayland 21328 当切换到列表显示时自动适应列宽度 + if (d->allowedAdjustColumnSize) { + setResizeMode(QListView::Adjust); + } + + if (!root_url.isValid()) + return; + + if (d->fileViewStateValue(root_url, "viewMode", QVariant()).isValid()) + return; + + DAbstractFileInfoPointer info = model()->fileInfo(rootIndex()); + + if (!info) + return; + + ViewModes modes = static_cast(info->supportViewMode()); + + //view mode support handler + if (modes & mode) { + switchViewMode(mode); + } +} + +void DFileView::setViewMode(DFileView::ViewMode mode) +{ + switchViewMode(mode); + emit viewStateChanged(); +} + +void DFileView::sortByRole(int role, Qt::SortOrder order) +{ + D_D(DFileView); + + model()->setSortRole(role, order); + + d->oldSelectedUrls = this->selectedUrls(); + + if (!d->oldSelectedUrls.isEmpty()) + d->oldCurrentUrl = model()->getUrlByIndex(currentIndex()); + + clearSelection(); + model()->sort(); + + if (d->headerView) { + QSignalBlocker blocker(d->headerView); + Q_UNUSED(blocker) + d->headerView->setSortIndicator(model()->sortColumn(), model()->sortOrder()); + } +} + +QStringList DFileView::nameFilters() const +{ + return model()->nameFilters(); +} + +void DFileView::setNameFilters(const QStringList &nameFilters) +{ + model()->setNameFilters(nameFilters); +} + +QDir::Filters DFileView::filters() const +{ + return model()->filters(); +} + +void DFileView::setEnabledSelectionModes(const QSet &list) +{ + Q_D(DFileView); + + d->enabledSelectionModes = list; + + if (!list.contains(selectionMode())) { + const DAbstractFileInfoPointer &info = model()->fileInfo(rootIndex()); + + if (!info) + return; + + const QList &supportSelectionModes = info->supportSelectionModes(); + + for (DAbstractFileInfo::SelectionMode mode : supportSelectionModes) { + if (list.contains(static_cast(mode))) { + setSelectionMode(static_cast(mode)); + break; + } + } + } +} + +QSet DFileView::enabledSelectionModes() const +{ + Q_D(const DFileView); + + return d->enabledSelectionModes; +} + +QWidget *DFileView::widget() const +{ + return const_cast(this); +} + +QList DFileView::toolBarActionList() const +{ + Q_D(const DFileView); + + return d->toolbarActionGroup->actions(); +} + +void DFileView::setDestroyFlag(bool flag) +{ + m_destroyFlag = flag; +} + +void DFileView::setAlwaysOpenInCurrentWindow(bool openInCurrentWindow) +{ + Q_D(DFileView); + + d->isAlwaysOpenInCurrentWindow = openInCurrentWindow; +} + +void DFileView::setFilters(QDir::Filters filters) +{ + model()->setFilters(filters); +} + +void DFileView::setAdvanceSearchFilter(const QMap &formData, bool turnOn, bool avoidUpdateView) +{ + // Q_UNUSED(avoidUpdateView); + model()->setAdvanceSearchFilter(formData, turnOn, avoidUpdateView); +} + +void DFileView::dislpayAsActionTriggered(QAction *action) +{ + QAction *dAction = static_cast(action); + dAction->setChecked(true); + MenuAction type = static_cast(dAction->data().toInt()); + + switch (type) { + case MenuAction::IconView: + setViewModeToIcon(); + break; + case MenuAction::ListView: + setViewModeToList(); + break; + case MenuAction::ExtendView: + break; + default: + break; + } +} + +void DFileView::sortByActionTriggered(QAction *action) +{ + Q_D(DFileView); + + QAction *dAction = static_cast(action); + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(rootIndex()); + + if (!fileInfo) + return; + + int action_index = d->sortByActionGroup->actions().indexOf(dAction); + + if (action_index < 0) + return; + + int sort_role = fileInfo->sortSubMenuActionUserColumnRoles().at(action_index); + + Qt::SortOrder order = (model()->sortRole() == sort_role && model()->sortOrder() == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder; + + sortByRole(sort_role, order); + + const DUrl &root_url = rootUrl(); + + d->setFileViewStateValue(root_url, "sortRole", model()->sortRole()); + d->setFileViewStateValue(root_url, "sortOrder", static_cast(order)); +} + +void DFileView::openWithActionTriggered(QAction *action) +{ + QAction *dAction = static_cast(action); + QString app = dAction->property("app").toString(); + DUrl fileUrl(dAction->property("url").toUrl()); + fileService->openFileByApp(this, app, fileUrl); +} + +void DFileView::onRowCountChanged() +{ + //所有的槽函数必须跑完才能析构 + QPointer me = this; + if (me.isNull()) { + return; + } + +#ifndef CLASSICAL_SECTION + static_cast(selectionModel())->m_selectedList.clear(); +#endif + + delayUpdateStatusBar(); + if (me.isNull()) { + return; + } + updateContentLabel(); + if (me.isNull()) { + return; + } + updateModelActiveIndex(); + if (me.isNull()) { + return; + } +} + +void DFileView::wheelEvent(QWheelEvent *event) +{ + // 左键按下则不响应滚轮事件,解决87504Bug,完善框选未定义行为 + if (event->buttons().testFlag(Qt::LeftButton)) { + return; + } + + if (isIconViewMode()) { + if (DFMGlobal::keyCtrlIsPressed()) { + if (event->angleDelta().y() > 0) { + increaseIcon(); + } else { + decreaseIcon(); + } + emit viewStateChanged(); + event->accept(); + } else { + verticalScrollBar()->setSliderPosition(verticalScrollBar()->sliderPosition() - event->angleDelta().y()); + } + } else if (event->modifiers() == Qt::AltModifier) { + horizontalScrollBar()->setSliderPosition(horizontalScrollBar()->sliderPosition() - event->angleDelta().x()); + } else { + verticalScrollBar()->setSliderPosition(verticalScrollBar()->sliderPosition() - event->angleDelta().y()); + } +} + +void DFileView::keyPressEvent(QKeyEvent *event) +{ + D_D(DFileView); + + const DUrlList &urls = selectedUrls(); + + switch (event->modifiers()) { + case Qt::NoModifier: + if (event->key() == Qt::Key_Space) { + emit fileSignalManager->requestShowFilePreviewDialog(selectedUrls(), model()->sortedUrls()); + return; + } else if (normalKeyPressEvent(event)) { + return; + } + break; + case Qt::KeypadModifier: + if (normalKeyPressEvent(event)) { + return; + } + break; + case Qt::ControlModifier: + switch (event->key()) { + case Qt::Key_N: { + DUrlList list; + + for (const DUrl &url : urls) { + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, url); + + if (info && info->canFetch()) + list << url; + } + + appController->actionNewWindow(dMakeEventPointer(this, list.isEmpty() ? DUrlList() << DUrl() : list)); + return; + } + case Qt::Key_H: + d->preSelectionUrls = urls; + + itemDelegate()->hideAllIIndexWidget(); + clearSelection(); + model()->toggleHiddenFiles(rootUrl()); + + return; + case Qt::Key_I: + if (rootUrl().isNetWorkFile()) + return; + + appController->actionProperty(dMakeEventPointer(this, urls)); + + return; + case Qt::Key_Up: + cdUp(); + + return; + case Qt::Key_Down: + appController->actionOpen(dMakeEventPointer(this, urls)); + + return; + case Qt::Key_T: { + //do not handle key press event of autoRepeat type + if (event->isAutoRepeat()) + return; + + DUrl url; + bool selectionvalid = false; + + if (selectedIndexCount() == 1) { + const DAbstractFileInfoPointer &fileInfoPointer = model()->fileInfo(selectedIndexes().first()); + if (fileInfoPointer->canFetch()) { + selectionvalid = true; + url = fileInfoPointer->fileUrl(); + if (FileUtils::isArchive(fileInfoPointer->absoluteFilePath())) { + url.setScheme(AVFS_SCHEME); + } + } + } + if (!selectionvalid) { + url = DFMApplication::instance()->appUrlAttribute(DFMApplication::AA_UrlOfNewTab); + if (!url.isValid()) + url = rootUrl(); + } + DFMEventDispatcher::instance()->processEvent(this, url); + return; + } + default: + break; + } + + break; + case Qt::ShiftModifier: + if (event->key() == Qt::Key_Delete) { + if (urls.isEmpty()) + return; + + // 只支持回收站根目录下的文件执行删除 + if (rootUrl().isTrashFile() && rootUrl() != DUrl::fromTrashFile("/")) + return; + + //! 共享文件夹不用弹出彻底删除对话框 + //! 网络邻居目录不用弹出彻底删除对话框 + //! 最近使用目录不用弹出彻底删除对话框 + bool bSlient = false; + if (urls.size() > 0 && (urls.first().isUserShareFile() || urls.first().isSMBFile() || urls.first().isRecentFile())) + bSlient = true; + + fileService->deleteFiles(this, urls, true, bSlient); + + return; + } else if (event->key() == Qt::Key_T) { + appController->actionOpenInTerminal(dMakeEventPointer(this, urls)); + + return; + } + + break; + case Qt::ControlModifier | Qt::ShiftModifier: + if (event->key() == Qt::Key_N) { + if (itemDelegate()->editingIndex().isValid()) + return; + + clearSelection(); + appController->actionNewFolder(dMakeEventPointer(this, rootUrl())); + + return; + } + break; + + case Qt::AltModifier: + case Qt::AltModifier | Qt::KeypadModifier: + switch (event->key()) { + case Qt::Key_Up: + cdUp(); + + return; + case Qt::Key_Down: + appController->actionOpen(dMakeEventPointer(this, urls)); + + return; + case Qt::Key_Home: + cd(DUrl::fromLocalFile(QDir::homePath())); + + return; + } + break; + + default: + break; + } + + DListView::keyPressEvent(event); +} + +void DFileView::showEvent(QShowEvent *event) +{ + DListView::showEvent(event); + + Q_D(DFileView); + + /// set menu actions filter + DFileMenuManager::setActionWhitelist(d->menuWhitelist); + DFileMenuManager::setActionBlacklist(d->menuBlacklist); + + d->showCount++; + setFocus(); +} + +void DFileView::mousePressEvent(QMouseEvent *event) +{ + D_D(DFileView); + + //获取已按下的鼠标是否存在左侧按键 + if (event->buttons().testFlag(Qt::LeftButton)) { + d->m_isMouseLeftPress = true; + } else { + d->m_isMouseLeftPress = false; + } + + switch (event->button()) { + case Qt::BackButton: { + DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(this), qobject_cast(window())); + break; + } + case Qt::ForwardButton: { + DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(this), qobject_cast(window())); + break; + } + case Qt::LeftButton: { + // 当事件source为MouseEventSynthesizedByQt,认为此事件为TouchBegin转换而来 + // if (event->source() == Qt::MouseEventSynthesizedByQt) { + // d->lastTouchBeginPos = event->pos(); + + // // 清空触屏滚动操作,因为在鼠标按下时还不知道即将进行的是触屏滚动还是文件框选 + // if (QScroller::hasScroller(this)) { + // // 不可使用 ungrab,会导致应用崩溃,或许是Qt的bug + // QScroller::scroller(this)->deleteLater(); + // } + + // if (d->updateEnableSelectionByMouseTimer) { + // d->updateEnableSelectionByMouseTimer->stop(); + // } else { + // d->updateEnableSelectionByMouseTimer = new QTimer(this); + // d->updateEnableSelectionByMouseTimer->setSingleShot(true); + + // static QObject *theme_settings = reinterpret_cast(qvariant_cast(qApp->property("_d_theme_settings_object"))); + // QVariant touchFlickBeginMoveDelay; + + // if (theme_settings) { + // touchFlickBeginMoveDelay = theme_settings->property("touchFlickBeginMoveDelay"); + // } + + // d->updateEnableSelectionByMouseTimer->setInterval(touchFlickBeginMoveDelay.isValid() ? touchFlickBeginMoveDelay.toInt() : 300); + + // connect(d->updateEnableSelectionByMouseTimer, &QTimer::timeout, d->updateEnableSelectionByMouseTimer, &QTimer::deleteLater); + // } + + // d->updateEnableSelectionByMouseTimer->start(); + // } + + bool isEmptyArea = d->fileViewHelper->isEmptyArea(event->pos()); + + if (dragDropMode() != NoDragDrop) { + setDragDropMode(DragDrop); + } + + const QModelIndex &index = indexAt(event->pos()); + + d->m_currentPressedIndex = isEmptyArea ? QModelIndex() : index; + + itemDelegate()->commitDataAndCloseActiveEditor(); + + if (isEmptyArea) { + d->currentSelection = selectionModel()->selection(); + if (!DFMGlobal::keyCtrlIsPressed()) { + itemDelegate()->hideNotEditingIndexWidget(); + + if (dragDropMode() != NoDragDrop) { + setDragDropMode(DropOnly); + } + + // 避免通过触屏拖动视图时当前选中被清除 + // if (event->source() != Qt::MouseEventSynthesizedByQt) { + // clearSelection(); + // update(); + // } + } + } else if (DFMGlobal::keyCtrlIsPressed()) { + //const QModelIndex &index = indexAt(event->pos()); + + if (selectionModel()->isSelected(index)) { + d->mouseLastPressedIndex = index; + + DListView::mousePressEvent(event); + + selectionModel()->select(index, QItemSelectionModel::Select); + + return; + } + } else if (DFMGlobal::keyShiftIsPressed()) { // 如果按住shit键,鼠标左键点击某项 + if (!selectionModel()->isSelected(index)) { // 如果该项没有被选择 + DListView::mousePressEvent(event); // 选择该项 + } + } + + d->mouseLastPressedIndex = QModelIndex(); + + DListView::mousePressEvent(event); + break; + } + case Qt::RightButton: { + // 47203 创建链接后,先打开桌面文件菜单,会将创建链接弹窗内的菜单改变 + // 弹出文件选择框后,左键选择文件之前右键选择其中的文件无法触发focusInEvent事件,这里手动设置焦点 + if (qApp->activeWindow() != this->window()) + setFocus(Qt::ActiveWindowFocusReason); + if (d->m_isMouseLeftPress) //右键互斥默认执行上层逻辑 + DListView::mousePressEvent(event); + break; + } + default: + break; + } +} + +void DFileView::mouseMoveEvent(QMouseEvent *event) +{ + // Q_D(const DFileView); + + // source为此类型时认为是触屏事件 + // if (event->source() == Qt::MouseEventSynthesizedByQt) { + // if (QScroller::hasScroller(this)) + // return; + + // // 在定时器期间收到鼠标move事件且距离大于一定值则认为触发视图滚动 + // if (d->updateEnableSelectionByMouseTimer + // && d->updateEnableSelectionByMouseTimer->isActive()) { + // const QPoint difference_pos = event->pos() - d->lastTouchBeginPos; + + // if (qAbs(difference_pos.x()) > d->touchTapDistance + // || qAbs(difference_pos.y()) > d->touchTapDistance) { + // QScroller::grabGesture(this); + // QScroller *scroller = QScroller::scroller(this); + + // scroller->handleInput(QScroller::InputPress, event->localPos(), static_cast(event->timestamp())); + // scroller->handleInput(QScroller::InputMove, event->localPos(), static_cast(event->timestamp())); + // } + + // return; + // } + // } + Q_D(DFileView); + //fix bug 59239 drag事件的发起者是在mouseMoveEvent中,所以等待mouseMoveEvent结束才能析构窗口 + d->m_isMouseMoveing.store(true); + DListView::mouseMoveEvent(event); + d->m_isMouseMoveing.store(false); + if (!d->m_isDragging.load()) + emit requestWindowDestruct(); +} + +void DFileView::mouseReleaseEvent(QMouseEvent *event) +{ + D_D(DFileView); + + d->dragMoveHoverIndex = QModelIndex(); + d->currentSelection = QItemSelection(); + + if (d->mouseLastPressedIndex.isValid() && DFMGlobal::keyCtrlIsPressed()) { + if (d->mouseLastPressedIndex == indexAt(event->pos())) + selectionModel()->select(d->mouseLastPressedIndex, QItemSelectionModel::Deselect); + } + + // 避免滚动视图导致文件选中状态被取消 + if (!QScroller::hasScroller(this)) + return DListView::mouseReleaseEvent(event); +} + +void DFileView::updateModelActiveIndex() +{ + if (m_isRemovingCase) // bug202007010004:正在删除的时候,fileInfo->makeToActive() 第二次调用会 crash + return; + + Q_D(DFileView); + + const RandeIndexList randeList = visibleIndexes(QRect(QPoint(0, verticalScrollBar()->value()), QSize(size()))); + + if (randeList.isEmpty()) { + m_isRemovingCase = false; + return; + } + + const RandeIndex &rande = randeList.first(); + DAbstractFileWatcher *fileWatcher = model()->fileWatcher(); + + for (int i = d->visibleIndexRande.first; i < rande.first; ++i) { + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(model()->index(i, 0)); + + if (fileInfo) { + fileInfo->makeToInactive(); + + if (fileWatcher) + fileWatcher->setEnabledSubfileWatcher(fileInfo->fileUrl(), false); + } + } + + for (int i = rande.second; i < d->visibleIndexRande.second; ++i) { + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(model()->index(i, 0)); + + if (fileInfo) { + fileInfo->makeToInactive(); + if (fileWatcher) + fileWatcher->setEnabledSubfileWatcher(fileInfo->fileUrl(), false); + } + } + + d->visibleIndexRande = rande; + for (int i = rande.first; i <= rande.second; ++i) { + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(model()->index(i, 0)); + + if (fileInfo) { + fileInfo->makeToActive(); + + if (!fileInfo->exists()) { + m_isRemovingCase = true; + model()->removeRow(i, rootIndex()); + } else if (fileWatcher) { + fileWatcher->setEnabledSubfileWatcher(fileInfo->fileUrl()); + } + } + } + m_isRemovingCase = false; +} + +void DFileView::handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) +{ + DListView::dataChanged(topLeft, bottomRight, roles); + + for (int i = topLeft.row(); i <= bottomRight.row(); ++i) { + update(model()->index(i, 0)); + } +} + +void DFileView::delayUpdateStatusBar() +{ + Q_D(DFileView); + + // when QItemSelectionModel::selectionChanged emit we get selectedUrls() were old selecturls + // so we wait... + // fix bug 63925 在挂载网络文件后,选中一个文件或者文件夹,卸载挂载的目录,在处理rooturl切换时, + // 获取的还是以前的url,所以这里在切换url没有结束就不执行。 + if (m_destroyFlag || d->m_isSetRootUrl) { + return; + } + + //判断网络文件是否可以到达 + if (DFileService::instance()->checkGvfsMountfileBusy(rootUrl())) { + d->updateStatusBarTimer->stop(); + return; + } + d->updateStatusBarTimer->start(); +} + +void DFileView::updateStatusBar() +{ + Q_D(DFileView); + + //智能指针和枷锁处理等待判断当前对象是否被析构 + QPointer me = this; + QMutexLocker lkUpdateStatusBar(&d_ptr->m_mutexUpdateStatusBar); + if (!me) { + return; + } + if (model()->state() != DFileSystemModel::Idle) + return; + + //若处于触摸滑动中,延时该更新,因为当前版本QT加速回弹动画会被子节点setText打断 + if (QScroller::hasScroller(this)) { + d_ptr->updateStatusBarTimer->stop(); + d_ptr->updateStatusBarTimer->start(); + return; + } + + DFMEvent event(this); + event.setWindowId(windowId()); + //来自搜索目录的url需要处理转换为localfile,否则statusBar上的展示会不正确 + QList sourceUrls = selectedUrls(); + QList corectUrls; + for (DUrl srcUrl : sourceUrls) { + if (srcUrl.scheme() == SEARCH_SCHEME) { + corectUrls << srcUrl.searchedFileUrl(); + } else { + corectUrls << srcUrl; + } + } + event.setData(corectUrls); + int count = selectedIndexCount(); + //判断网络文件是否可以到达 + if (DFileService::instance()->checkGvfsMountfileBusy(rootUrl())) { + return; + } + + // fix bug 67301 + if (rootUrl().isSearchFile() && !corectUrls.isEmpty()) { + if (DFileService::instance()->checkGvfsMountfileBusy(corectUrls.first())) + return; + } + + if (!me) { + qDebug() << "DFileView is null,so exit"; + return; + } + notifySelectUrlChanged(corectUrls); + if (count == 0) { + d->statusBar->itemCounted(event, this->count()); + } else { + d->statusBar->itemSelected(event, count); + } +} + +void DFileView::openIndexByOpenAction(const int &action, const QModelIndex &index) +{ + if (action == DFMApplication::instance()->appAttribute(DFMApplication::AA_OpenFileMode).toInt()) { + //在dfiledialog中单击打开文件时 需要判断文件是否处于enable的状态 否则会引起dialog崩溃 + if (action == 0) { + Qt::ItemFlags flags = model()->flags(index); + if (!flags.testFlag(Qt::ItemIsEnabled)) + return; + } + + if (!DFMGlobal::keyCtrlIsPressed() && !DFMGlobal::keyShiftIsPressed()) + openIndex(index); + } +} + +void DFileView::setIconSizeBySizeIndex(const int &sizeIndex) +{ + QSignalBlocker blocker(statusBar()->scalingSlider()); + Q_UNUSED(blocker) + statusBar()->scalingSlider()->setValue(sizeIndex); + itemDelegate()->setIconSizeByIconSizeLevel(sizeIndex); +} + +#ifdef SW_LABEL +bool DFileView::checkRenamePrivilege_sw(DUrl fileUrl) +{ + QString srcFileName = fileUrl.toLocalFile(); + if (FileJob::isLabelFile(srcFileName)) { + int nRet = FileJob::checkRenamePrivilege(srcFileName); + if (nRet != 0) { + emit fileSignalManager->jobFailed(nRet, "rename", srcFileName); + return false; + } + } + return true; +} +#endif + +void DFileView::onRootUrlDeleted(const DUrl &rootUrl) +{ + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(this, rootUrl); + DUrl new_url = fileInfo ? fileInfo->goToUrlWhenDeleted() : DUrl::fromLocalFile(QDir::homePath()); + + requestCdTo(new_url); +} + +void DFileView::freshView() +{ + model()->refresh(rootUrl()); +} + +void DFileView::loadViewState(const DUrl &url) +{ + Q_D(DFileView); + + QVariant defIconSize = DFMApplication::instance()->appAttribute(DFMApplication::AA_IconSizeLevel).toInt(); + int iconSize = d->fileViewStateValue(url, "iconSizeLevel", defIconSize).toInt(); + setIconSizeBySizeIndex(iconSize); + int savedViewMode = d->fileViewStateValue(url, "viewMode", -1).toInt(); + ViewMode viewMode = getDefaultViewMode(); + if (savedViewMode == -1) { + if (DFMApplication::appObtuselySetting()->value("ApplicationAttribute", "UseParentViewMode", false).toBool()) { + DAbstractFileInfoPointer info = fileService->createFileInfo(nullptr, url); + DUrlList urlList = info->parentUrlList(); + for (const DUrl &url : urlList) { + int checkViewMode = d->fileViewStateValue(url, "viewMode", -1).toInt(); + if (checkViewMode != -1) { + viewMode = static_cast(checkViewMode); + break; + } + } + } + } else { + viewMode = static_cast(savedViewMode); + } + + switchViewMode(viewMode); +} + +void DFileView::saveViewState() +{ + //filter url that we are not interesting on + const DUrl &url = rootUrl(); + + if (url.isSearchFile() || !url.isValid() || url.isComputerFile()) { + return; + } + + Q_D(DFileView); + + d->setFileViewStateValue(url, "iconSizeLevel", statusBar()->scalingSlider()->value()); + d->setFileViewStateValue(url, "viewMode", static_cast(viewMode())); +} + +void DFileView::onSortIndicatorChanged(int logicalIndex, Qt::SortOrder order) +{ + Q_D(DFileView); + + model()->setSortColumn(logicalIndex, order); + + d->oldSelectedUrls = this->selectedUrls(); + + if (!d->oldSelectedUrls.isEmpty()) + d->oldCurrentUrl = model()->getUrlByIndex(currentIndex()); + + clearSelection(); + model()->sort(); + + const DUrl &root_url = rootUrl(); + + d->setFileViewStateValue(root_url, "sortRole", model()->sortRole()); + d->setFileViewStateValue(root_url, "sortOrder", static_cast(order)); +} + +void DFileView::onDriveOpticalChanged(const QString &path) +{ + Q_D(DFileView); + + for (auto i : d->diskmgr->blockDevices({})) { + QScopedPointer blkdev(DDiskManager::createBlockDevice(i)); + if (path == blkdev->drive()) { + qDebug() << QString(blkdev->device()); + ISOMaster->nullifyDevicePropertyCache(QString(blkdev->device())); + } + } +} + +void DFileView::reset() +{ + DListView::reset(); +} + +void DFileView::setRootIndex(const QModelIndex &index) +{ + DListView::setRootIndex(index); +} + +void DFileView::onHeaderSectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex) +{ + Q_D(DFileView); + Q_UNUSED(logicalIndex) + Q_UNUSED(oldVisualIndex) + Q_UNUSED(newVisualIndex) + + //更新本地的设置数据 + QVariantList logicalIndexList; + for (int i = 0; i < d->headerView->count(); ++i) { + int logicalIndex = d->headerView->logicalIndex(i); + logicalIndexList << model()->columnToRole(logicalIndex); + } + + DUrl root_url = rootUrl(); + //所有搜索目录统一类目顺序,存入"search:"配置项中 + if (root_url.isSearchFile()) { + root_url = DUrl(); + root_url.setScheme(SEARCH_SCHEME); + } + d->setFileViewStateValue(root_url, "headerList", logicalIndexList); + //及时同步到本地配置文件中 + DFMApplication::appObtuselySetting()->sync(); + + //刷新界面 + updateListHeaderViewProperty(); + update(); +} + +void DFileView::focusInEvent(QFocusEvent *event) +{ + Q_D(const DFileView); + + // 为了避免QAbstractItemView::focusInEvent会自动设置currentIndex + QAbstractScrollArea::focusInEvent(event); + itemDelegate()->commitDataAndCloseActiveEditor(); + + /// set menu actions filter + DFileMenuManager::setActionWhitelist(d->menuWhitelist); + DFileMenuManager::setActionBlacklist(d->menuBlacklist); +} + +void DFileView::resizeEvent(QResizeEvent *event) +{ + Q_D(DFileView); + + DListView::resizeEvent(event); + + if (d->statusBar && d->statusBar->width() != width()) { + d->statusBar->setFixedWidth(width()); + } + + updateHorizontalOffset(); + + if (itemDelegate()->editingIndex().isValid()) + doItemsLayout(); + + updateModelActiveIndex(); +} + +void DFileView::contextMenuEvent(QContextMenuEvent *event) +{ + D_DC(DFileView); + + if (!canShowContextMenu(event)) + return; + + const QModelIndex &index = indexAt(event->pos()); + bool clickedSelected = isSelected(index); + bool isEmptyArea = d->fileViewHelper->isEmptyArea(event->pos()); + Qt::ItemFlags flags = index.flags(); + + //顶层目录没有开启item flags列表,任何菜单都将不会展示 + if (isEmptyArea && !model()->flags(rootIndex()).testFlag(Qt::ItemIsEnabled)) { + return; + } + + if (clickedSelected) { //选中逻辑 + //当前选中的index未使能 + if (!flags.testFlag(Qt::ItemIsEnabled)) { + return showEmptyAreaMenu(rootIndex().flags()); //show root Index flags + } else { + return showNormalMenu(index, flags); // show opration menu + } + } else { //非选中逻辑 + itemDelegate()->hideNotEditingIndexWidget(); //提交所有的编辑框edit数据 + clearSelection(); //清除选中的indexs + + if (!index.isValid()) { //index不存在 + return showEmptyAreaMenu(rootIndex().flags()); //show root Index flags + + } else if (!isIconViewMode() && isEmptyArea) { //listview 下判断 isEmptyArea + return showEmptyAreaMenu(rootIndex().flags()); //show root Index flags + + } else { //index 存在 + selectionModel()->select(index, QItemSelectionModel::SelectionFlag::Select); + //当前选中的index未使能 + if (!flags.testFlag(Qt::ItemIsEnabled)) { + //show root Index flags + return showEmptyAreaMenu(rootIndex().flags()); + } else { + return showNormalMenu(index, flags); + } + + } //else end + } +} + +bool DFileView::canShowContextMenu(QContextMenuEvent *event) +{ + Q_D(DFileView); + + //左键按下则不触发右键菜单 + if (d->m_isMouseLeftPress) { + return false; + } + + //检查当前路径是否可访问辨别smb目录 + if (DFileService::instance()->checkGvfsMountfileBusy(rootUrl())) + return false; + + //搜索路径下存在不可访问(访问不可达)的文件 + if (rootUrl().isSearchFile()) { + //搜索结果有效点击了index + if (indexAt(event->pos()).isValid()) { + DUrl fileUrl = model()->getUrlByIndex(indexAt(event->pos())).searchedFileUrl(); + if (DFileService::instance()->checkGvfsMountfileBusy(fileUrl)) + return false; + } else { //搜索结果界面点击了空白区域 + DUrl fileUrl = rootUrl().searchTargetUrl(); + if (DFileService::instance()->checkGvfsMountfileBusy(fileUrl)) + return false; + } + } + + return true; +} + +void DFileView::dragEnterEvent(QDragEnterEvent *event) +{ + Q_D(DFileView); + // 修复bug-65773 拖拽事件进入前,需要将当前拖拽缓存清空, + // 使得程序执行DFileDragClient::setTargetUrl(data, url); + // 方便压缩软件获得目的地址,这种方案会导致“系统关闭窗口特效时,拖拽压缩软件中的文件 + // 反复进出文管时,产生残影”(此方案为临时修复方案) + m_currentTargetUrl.clear(); + if (DFileDragClient::checkMimeData(event->mimeData())) { + event->acceptProposedAction(); + setTargetUrlToApp(event->mimeData(), rootUrl()); + return; + } + + //由于普通用户无法访问root用户的共享内存,跨用户的情况使用从mimedata中取url的方式 + bool sameUser = DFMGlobal::isMimeDatafromCurrentUser(event->mimeData()); + if (sameUser) { + if (!fetchDragEventUrlsFromSharedMemory()) + return; + } else { + m_urlsForDragEvent = event->mimeData()->urls(); + } + const DAbstractFileInfoPointer &rootFileInfo = DFileService::instance()->createFileInfo(this, rootUrl()); + + DUrl rootItemUrl = rootUrl(); + if (rootFileInfo && rootItemUrl.isTaggedFile() && rootFileInfo->canRedirectionFileUrl()) + rootItemUrl = rootFileInfo->redirectedFileUrl(); + for (const auto &url : m_urlsForDragEvent) { + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(this, DUrl(url)); + if (!fileInfo) { + event->ignore(); + return; + } + if (!rootUrl().isTaggedFile() || (rootUrl().isTaggedFile() && rootFileInfo && rootFileInfo->canRedirectionFileUrl())) { + bool isInSameDevice = DStorageInfo::inSameDevice(fileInfo->fileUrl(), rootItemUrl); + if ((!isInSameDevice && !fileInfo->isReadable()) || (!DFMGlobal::keyCtrlIsPressed() && isInSameDevice && !fileInfo->canRename())) { + event->ignore(); + return; + } + } + + //部分文件不能复制或剪切,需要在拖拽时忽略 + if (!fileInfo || !fileInfo->canMoveOrCopy()) { + event->ignore(); + return; + } + + //防止不可添加tag的文件被拖进tag目录从而获取tag属性 + if (model()->rootUrl().isTaggedFile() && !fileInfo->canTag()) { + event->ignore(); + return; + } + } + + d->fileViewHelper->preproccessDropEvent(event, m_urlsForDragEvent); + + if (event->mimeData()->hasFormat("XdndDirectSave0")) { + event->setDropAction(Qt::CopyAction); + event->acceptProposedAction(); + + return; + } + + DListView::dragEnterEvent(event); +} + +void DFileView::dragMoveEvent(QDragMoveEvent *event) +{ + D_D(DFileView); + + if (isIconViewMode()) { + d->dragMoveHoverIndex = d->fileViewHelper->isEmptyArea(event->pos()) ? rootIndex() : indexAt(event->pos()); + } else { // fix 88616 在列表模式下,拖拽文件到文件夹的名称后面空出,无法拖拽文件到文件夹中 + d->dragMoveHoverIndex = indexAt(event->pos()); + //保持index为空时,rootIndex判断 + if (!d->dragMoveHoverIndex.isValid()) { + d->dragMoveHoverIndex = rootIndex(); + } + } + + if (d->dragMoveHoverIndex.isValid()) { + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(d->dragMoveHoverIndex); + + if (fileInfo) { + d->fileViewHelper->preproccessDropEvent(event, m_urlsForDragEvent); + if (!fileInfo->canDrop() + || !fileInfo->supportedDropActions().testFlag(event->dropAction()) + || (fileInfo->isDir() && !fileInfo->isWritable())) { + d->dragMoveHoverIndex = QModelIndex(); + update(); + + return event->ignore(); + } + if (fileInfo->isDir() && ((!fileInfo->fileUrl().isTaggedFile()) || (fileInfo->fileUrl().isTaggedFile() && fileInfo->canRedirectionFileUrl()))) { + DUrl dragMoveHoverIndexUrl = fileInfo->fileUrl().isTaggedFile() ? fileInfo->redirectedFileUrl() : fileInfo->fileUrl(); + for (const auto &url : m_urlsForDragEvent) { + const DAbstractFileInfoPointer &dragFileInfo = DFileService::instance()->createFileInfo(this, DUrl(url)); + if (!dragFileInfo) { + event->ignore(); + return; + } + + bool isInSameDevice = DStorageInfo::inSameDevice(dragFileInfo->fileUrl(), dragMoveHoverIndexUrl); + if ((!isInSameDevice && !dragFileInfo->isReadable()) || (!DFMGlobal::keyCtrlIsPressed() && isInSameDevice && !dragFileInfo->canRename())) { + event->ignore(); + return; + } + } + } + // 如果是回收站里面搜索,不让拖拽 + const DUrl &toUrl = model()->getUrlByIndex(d->dragMoveHoverIndex); + if (toUrl.isSearchFile() && toUrl.fragment().startsWith(TRASH_ROOT)) { + d->dragMoveHoverIndex = QModelIndex(); + update(); + + return event->ignore(); + } + + // fix bug 64049 + // 文件不可在同目录下进行拖拽操作 + const DAbstractFileInfoPointer &srcInfo = model()->fileInfo(selectionModel()->currentIndex()); + if (event->dropAction() == Qt::MoveAction && srcInfo) { + const DUrl &parent = srcInfo->parentUrl(); + if (parent == fileInfo->fileUrl() && event->source() == d->fileViewHelper->parent()) { + d->dragMoveHoverIndex = QModelIndex(); + update(); + + return event->ignore(); + } + } + + if (DFileDragClient::checkMimeData(event->mimeData())) { + event->acceptProposedAction(); + setTargetUrlToApp(event->mimeData(), fileInfo->fileUrl()); + } else { + event->accept(); + } + + // 判断是否是压缩文件,是否只读,设置事件状态 + if (fileInfo->canDrop() && fileInfo->canDragCompress()) { + // 设置当拖拽gvfs文件时,不支持追加压缩 + if (!m_urlsForDragEvent.isEmpty()) { + const DAbstractFileInfoPointer &dragfileInfo = DFileService::instance()->createFileInfo(this, DUrl(m_urlsForDragEvent.first())); + if (dragfileInfo->isGvfsMountFile()) { + event->setDropAction(Qt::MoveAction); + return event->ignore(); + } + } + + // 搜索界面中,除去回收站和最近使用的搜索界面,其余支持拖拽压缩 + const DUrl &toUrl = model()->getUrlByIndex(d->dragMoveHoverIndex); + if (toUrl.isSearchFile()) { + // 判断搜索出来的文件的父目录是否可读 + if (!fileInfo->canRename()) { + return event->ignore(); + } + // 判断是否是拖拽到最近使用或回收站的搜索目录 + if (!(toUrl.fragment().startsWith(RECENT_ROOT) || toUrl.fragment().startsWith(TRASH_ROOT))) { + return event->setDropAction(Qt::CopyAction); + } + } + + // 父目录为只读文件时,不支持追加压缩 + const DAbstractFileInfoPointer &parentInfo = model()->fileInfo(d->dragMoveHoverIndex.parent()); + if (parentInfo && parentInfo->isWritable()) { + return event->setDropAction(Qt::CopyAction); + } + return event->ignore(); + } + } + } + + update(); + // update()没有使draging时delegate重绘(why?), 再调用viewport()->update()一次 + viewport()->update(); + + if (dragDropMode() == InternalMove + && (event->source() != this || !(event->possibleActions() & Qt::MoveAction))) + QAbstractItemView::dragMoveEvent(event); +} + +void DFileView::dragLeaveEvent(QDragLeaveEvent *event) +{ + D_D(DFileView); + + d->dragMoveHoverIndex = QModelIndex(); + + DListView::dragLeaveEvent(event); +} + +void DFileView::dropEvent(QDropEvent *event) +{ + D_D(DFileView); + d->dragMoveHoverIndex = QModelIndex(); + // clean old index area + update(); + + d->fileViewHelper->preproccessDropEvent(event); + + if (event->mimeData()->property("IsDirectSaveMode").toBool()) { + event->setDropAction(Qt::CopyAction); + + const QModelIndex &index = indexAt(event->pos()); + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(index.isValid() ? index : rootIndex()); + + if (fileInfo && fileInfo->fileUrl().isLocalFile()) { + if (fileInfo->isDir()) { + const_cast(event->mimeData())->setProperty("DirectSaveUrl", fileInfo->fileUrl()); + } else { + const_cast(event->mimeData())->setProperty("DirectSaveUrl", fileInfo->parentUrl()); + } + } + + event->accept(); // yeah! we've done with XDS so stop Qt from further event propagation. + } else { + + QModelIndex index; + if (isIconViewMode()) { + index = d->fileViewHelper->isEmptyArea(event->pos()) ? QModelIndex() : indexAt(event->pos()); + } else { // fix 88616 在列表模式下,拖拽文件到文件夹的名称后面空出,无法拖拽文件到文件夹中 + index = indexAt(event->pos()); + } + + if (!index.isValid()) + index = rootIndex(); + + if (!index.isValid()) + return; + + // 防止把目录拖动到自己里边 + if (isSelected(index) && event->source() == this) + return; + + if (model()->supportedDropActions() & event->dropAction() && model()->flags(index) & Qt::ItemIsDropEnabled) { + const Qt::DropAction action = dragDropMode() == InternalMove ? Qt::MoveAction : event->dropAction(); + //fix bug 59239 drag事件的接受者要在dropMimeData处理完才能去析构本窗口 + d->m_isDragging.store(true); + if (model()->dropMimeData(event->mimeData(), action, index.row(), index.column(), index)) { + if (action != event->dropAction()) { + event->setDropAction(action); + event->accept(); + } else { + event->acceptProposedAction(); + } + } + } + //还原鼠标状态 + DFileService::instance()->setCursorBusyState(false); + stopAutoScroll(); + setState(NoState); + viewport()->update(); + } + + if (DFileDragClient::checkMimeData(event->mimeData())) { + + QModelIndex index; + if (isIconViewMode()) { + index = d->fileViewHelper->isEmptyArea(event->pos()) ? QModelIndex() : indexAt(event->pos()); + } else { // fix 88616 在列表模式下,拖拽文件到文件夹的名称后面空出,无法拖拽文件到文件夹中 + index = indexAt(event->pos()); + } + + if (!index.isValid()) + index = rootIndex(); + + if (!index.isValid()) { + //fix bug 59239 drag事件的接受者要在dropMimeData处理完才能去析构本窗口 + d->m_isDragging.store(false); + if (!d->m_isMouseMoveing.load()) + emit requestWindowDestruct(); + return; + } + + event->acceptProposedAction(); + setTargetUrlToApp(event->mimeData(), model()->getUrlByIndex(index)); + + // DFileDragClient deletelater() will be called after connection destroyed + DFileDragClient *c = new DFileDragClient(event->mimeData()); + DUrlList urlList = DUrl::fromQUrlList(event->mimeData()->urls()); + connect(c, &DFileDragClient::stateChanged, this, [this, urlList](DFileDragState state) { + if (state == Finished) { + select(urlList); + } + }); + } + //fix bug 59239 drag事件的接受者要在dropMimeData处理完才能去析构本窗口 + d->m_isDragging.store(false); + if (!d->m_isMouseMoveing.load()) + emit requestWindowDestruct(); +} + +void DFileView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags) +{ + D_D(DFileView); + if (DFMGlobal::keyShiftIsPressed()) { + //鼠标从空白区域开始框选,追加框选的item + if (!d->m_currentPressedIndex.isValid()) { + QItemSelection oldSelection = d->currentSelection; + + if (isIconViewMode()) { //图标模式 + DFileSystemModel *pModel = model(); + if (pModel) { + // ListView中的文件摆放逻辑是一列多行,所以行的数量就是文件的数量 + int nRowNum = pModel->rowCount(); + + QPoint offset(-horizontalOffset() + ICON_X_OFFSET, ICON_Y_OFFSET); + // 判断文件是否在鼠标框选区域内(注意:rect只是view的框选位置,并不是画布的框选位置,所以加上滚动偏移) + QRect actualRect(MIN(rect.left(), rect.right()), MIN(rect.top(), rect.bottom()) + verticalOffset(), abs(rect.width()), abs(rect.height())); + // 用来存放鼠标框选中的文件项 + QVector selectItems; + for (int i = 0; i < nRowNum; ++i) { + const QModelIndex &index = pModel->index(i, 0); + const QRect &itemRect = rectForIndex(index); + QRect realItemRect((itemRect.topLeft() + offset), itemRect.bottomRight() + offset + QPoint(ICON_HEIGHT_OFFSET, ICON_WIDTH_OFFSET)); + if (!(actualRect.left() > realItemRect.right() - 3 + || actualRect.top() > realItemRect.bottom() - 3 + || realItemRect.left() + 3 > actualRect.right() + || realItemRect.top() + 3 > actualRect.bottom())) { + if (!oldSelection.contains(index)) { + QItemSelectionRange selectionRange(index); + oldSelection.push_back(selectionRange); + } + } + } + selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect); + return; + } + } else { //列表模式 + QRect tmp_rect = rect; + //修改远程时,文件选择框内容选中后被取消问题 + if (tmp_rect.width() < 5 && tmp_rect.width() > -5 && tmp_rect.height() < 5 && tmp_rect.height() > -5) + return; + + tmp_rect.translate(horizontalOffset(), verticalOffset()); + tmp_rect.setCoords(qMin(tmp_rect.left(), tmp_rect.right()), qMin(tmp_rect.top(), tmp_rect.bottom()), + qMax(tmp_rect.left(), tmp_rect.right()), qMax(tmp_rect.top(), tmp_rect.bottom())); + + const RandeIndexList &list = visibleIndexes(tmp_rect); + + for (const RandeIndex &index : list) { + oldSelection.append(QItemSelectionRange(rootIndex().child(index.first, 0), rootIndex().child(index.second, 0))); + } + + return selectionModel()->select(oldSelection, flags); + } + } + + const QModelIndex &index = indexAt(rect.bottomRight()); + + if (!index.isValid()) + return; + + const QModelIndex &lastSelectedIndex = indexAt(rect.topLeft()); + + if (!lastSelectedIndex.isValid()) + return; + + selectionModel()->select(QItemSelection(lastSelectedIndex, index), QItemSelectionModel::ClearAndSelect); + + return; + } + + if (flags == (QItemSelectionModel::Current | QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect)) { + QRect tmp_rect = rect; + //修改远程时,文件选择框内容选中后被取消问题 + if (tmp_rect.width() < 5 && tmp_rect.width() > -5 && tmp_rect.height() < 5 && tmp_rect.height() > -5) + return; + + // sp4-task:文管框选内容不正确问题 + // 判断是否是图标模式 + if (isIconViewMode()) { + DFileSystemModel *pModel = model(); + if (pModel) { + // ListView中的文件摆放逻辑是一列多行,所以行的数量就是文件的数量 + int nRowNum = pModel->rowCount(); + + QPoint offset(-horizontalOffset() + ICON_X_OFFSET, ICON_Y_OFFSET); + // 判断文件是否在鼠标框选区域内(注意:rect只是view的框选位置,并不是画布的框选位置,所以加上滚动偏移) + QRect actualRect(MIN(rect.left(), rect.right()), MIN(rect.top(), rect.bottom()) + verticalOffset(), abs(rect.width()), abs(rect.height())); + // 用来存放鼠标框选中的文件项 + QVector selectItems; + for (int i = 0; i < nRowNum; ++i) { + const QModelIndex &index = pModel->index(i, 0); + const QRect &itemRect = rectForIndex(index); + QRect realItemRect((itemRect.topLeft() + offset), itemRect.bottomRight() + offset + QPoint(ICON_HEIGHT_OFFSET, ICON_WIDTH_OFFSET)); + if (!(actualRect.left() > realItemRect.right() - 3 + || actualRect.top() > realItemRect.bottom() - 3 + || realItemRect.left() + 3 > actualRect.right() + || realItemRect.top() + 3 > actualRect.bottom())) + selectItems.push_back(index); + } + // 取消上一次选中项的选中状态 + clearSelection(); + // 将当前选中项设置成选中状态 + QVector::const_iterator itr = selectItems.begin(); + for (; itr != selectItems.end(); ++itr) { + // 将文件设置选中状态 + selectionModel()->select(*itr, QItemSelectionModel::Select); + } + } + return; + } + + tmp_rect.translate(horizontalOffset(), verticalOffset()); + tmp_rect.setCoords(qMin(tmp_rect.left(), tmp_rect.right()), qMin(tmp_rect.top(), tmp_rect.bottom()), + qMax(tmp_rect.left(), tmp_rect.right()), qMax(tmp_rect.top(), tmp_rect.bottom())); + + const RandeIndexList &list = visibleIndexes(tmp_rect); + + if (list.isEmpty()) { + clearSelection(); + + return; + } + +#ifndef CLASSICAL_SECTION + return selectionModel()->select(QItemSelection(rootIndex().child(list.first().first, 0), + rootIndex().child(list.last().second, 0)), + flags); +#else + QItemSelection selection; + + for (const RandeIndex &index : list) { + selection.append(QItemSelectionRange(rootIndex().child(index.first, 0), rootIndex().child(index.second, 0))); + } + + return selectionModel()->select(selection, flags); +#endif + } + DListView::setSelection(rect, flags); +} + +QModelIndex DFileView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers) +{ + D_D(DFileView); + + QModelIndex current = currentIndex(); + + if (!current.isValid()) { + d->lastCursorIndex = DListView::moveCursor(cursorAction, modifiers); + + return d->lastCursorIndex; + } + + if (rectForIndex(current).isEmpty()) { + d->lastCursorIndex = model()->index(0, 0, rootIndex()); + + return d->lastCursorIndex; + } + + QModelIndex index; + + switch (cursorAction) { + case MoveLeft: + if (DFMGlobal::keyShiftIsPressed()) { + index = DListView::moveCursor(cursorAction, modifiers); + + if (index == d->lastCursorIndex) { + index = index.sibling(index.row() - 1, index.column()); + } + } else { + index = current.sibling(current.row() - 1, current.column()); + } + + // rekols: Loop to find the next file item that can be selected. + while (index.model() && !(index.flags() & Qt::ItemIsSelectable) && index.isValid()) { + index = index.sibling(index.row() - 1, index.column()); + } + + break; + + case MoveRight: + if (DFMGlobal::keyShiftIsPressed()) { + index = DListView::moveCursor(cursorAction, modifiers); + + if (index == d->lastCursorIndex) { + index = index.sibling(index.row() + 1, index.column()); + } + } else { + index = current.sibling(current.row() + 1, current.column()); + } + + while (index.model() && !(index.flags() & Qt::ItemIsSelectable) && index.isValid()) { + index = index.sibling(index.row() + 1, index.column()); + } + + break; + + default: + index = DListView::moveCursor(cursorAction, modifiers); + break; + } + + if (index.isValid()) { + if (viewMode() == IconMode) { + bool last_row = indexOfRow(index) == rowCount() - 1; + + if (!last_row + && current == index + && (cursorAction == MoveDown + || cursorAction == MovePageDown + || cursorAction == MoveNext)) { + // 当下一个位置没有元素时,QListView不会自动换一列选择,应该直接选中最后一个 + index = model()->index(count() - 1, 0); + last_row = true; + } + + if (last_row) { + // call later + //QTimer::singleShot(0, this, [this, index, d] {//this index unused,改成如下 + QTimer::singleShot(0, this, [d] { + // scroll to end + d->verticalScrollBar->setValue(d->verticalScrollBar->maximum()); + }); + } + } + + d->lastCursorIndex = index; + + return index; + } + + d->lastCursorIndex = current; + + return current; +} + +void DFileView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +{ + QModelIndex currentIdx = currentIndex(); + for (const QModelIndex &index : selectedIndexes()) { + if (index.parent() != parent) + continue; + + if (index.row() >= start && index.row() <= end) { + selectionModel()->select(index, QItemSelectionModel::Clear); + if (index == currentIdx) { + clearSelection(); + } + } + } + + Q_D(DFileView); + + if (start < d->visibleIndexRande.second) { + if (end <= d->visibleIndexRande.first) { + d->visibleIndexRande.first -= (end - start + 1); + d->visibleIndexRande.second -= (end - start + 1); + } else if (end <= d->visibleIndexRande.second) { + d->visibleIndexRande.first = start; + d->visibleIndexRande.second -= (end - start + 1); + } else { + d->visibleIndexRande.first = d->visibleIndexRande.second = -1; + } + } + + DListView::rowsAboutToBeRemoved(parent, start, end); +} + +void DFileView::rowsInserted(const QModelIndex &parent, int start, int end) +{ + DListView::rowsInserted(parent, start, end); +} + +void DFileView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) +{ + D_D(DFileView); + + DListView::dataChanged(topLeft, bottomRight, roles); + + if (d->oldCurrentUrl.isValid()) + setCurrentIndex(model()->index(d->oldCurrentUrl)); + + for (const DUrl &url : d->oldSelectedUrls) { + selectionModel()->select(model()->index(url), QItemSelectionModel::Select); + } + + /// Clean + d->oldCurrentUrl = DUrl(); + d->oldSelectedUrls.clear(); +} + +bool DFileView::event(QEvent *e) +{ + Q_D(DFileView); + switch (e->type()) { + case QEvent::KeyPress: { + QKeyEvent *keyEvent = static_cast(e); + if (keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Backtab) { + if (keyEvent->modifiers() == Qt::ControlModifier || keyEvent->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) + return DListView::event(e); + e->accept(); + + if (keyEvent->modifiers() == Qt::ShiftModifier) { + QKeyEvent nkeyEvent(keyEvent->type(), Qt::Key_Left, Qt::NoModifier); + keyPressEvent(&nkeyEvent); + } else { + QKeyEvent nkeyEvent(keyEvent->type(), Qt::Key_Right, Qt::NoModifier); + keyPressEvent(&nkeyEvent); + } + + return true; + } + } break; + case QEvent::Resize: + d->pureResizeEvent(static_cast(e)); + break; + case QEvent::ParentChange: + window()->installEventFilter(this); + break; + case QEvent::FontChange: + // blumia: to trigger DIconItemDelegate::updateItemSizeHint() to update its `d->itemSizeHint` ... + emit iconSizeChanged(iconSize()); + default: + break; + } + + return DListView::event(e); +} + +void DFileView::updateGeometries() +{ + Q_D(DFileView); + + if (!d->headerView || !d->allowedAdjustColumnSize) { + return DListView::updateGeometries(); + } + + resizeContents(d->headerView->length(), contentsSize().height()); + + DListView::updateGeometries(); +} + +bool DFileView::eventFilter(QObject *obj, QEvent *event) +{ + Q_D(DFileView); + + switch (event->type()) { + case QEvent::Move: + if (obj != horizontalScrollBar()->parentWidget()) + return DListView::eventFilter(obj, event); + d->updateHorizontalScrollBarPosition(); + break; + case QEvent::WindowStateChange: + if (d->headerView) { + d->toggleHeaderViewSnap(true); + d->doFileNameColResize(); + } + break; + // blumia: 这里通过给横向滚动条加事件过滤器并监听其显示隐藏时间来判断是否应当进入吸附状态。 + // 不过其实可以通过 Resize 事件的 size 和 oldSize 判断是否由于窗口调整大小而进入了吸附状态。 + // 鉴于已经实现完了,如果当前的实现方式实际发现了较多问题,则应当调整为使用 Resize 事件来标记吸附状态的策略。 + case QEvent::ShowToParent: + case QEvent::HideToParent: + if (d->headerView && d->cachedViewWidth != this->width()) { + d->cachedViewWidth = this->width(); + d->toggleHeaderViewSnap(true); + } + break; + default: + break; + } + + return DListView::eventFilter(obj, event); +} + +#if QT_CONFIG(draganddrop) +void DFileView::startDrag(Qt::DropActions supportedActions) +{ + Q_D(DFileView); + QModelIndexList indexes = d->selectedDraggableIndexes(); + if (!indexes.isEmpty()) { + if (indexes.count() == 1) { + DListView::startDrag(supportedActions); + return; + } + + QMimeData *data = model()->mimeData(indexes); + if (!data) + return; + + QPixmap pixmap = d->renderToPixmap(indexes); + QDrag *drag = new QDrag(this); + drag->setPixmap(pixmap); + drag->setMimeData(data); + drag->setHotSpot(QPoint(static_cast(pixmap.size().width() / (2 * pixmap.devicePixelRatio())), + static_cast(pixmap.size().height() / (2 * pixmap.devicePixelRatio())))); + Qt::DropAction dropAction = Qt::IgnoreAction; + Qt::DropAction defaultDropAction = QAbstractItemView::defaultDropAction(); + if (defaultDropAction != Qt::IgnoreAction && (supportedActions & defaultDropAction)) + dropAction = defaultDropAction; + else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove) + dropAction = Qt::CopyAction; + + drag->exec(supportedActions, dropAction); + } +} +#endif // QT_CONFIG(draganddrop) + +void DFileView::onShowHiddenFileChanged() +{ + QDir::Filters filters; + + if (DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowedHiddenFiles).toBool()) + filters = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::System | QDir::Hidden; + else + filters = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::System; + + model()->setFilters(filters); +} + +void DFileView::initDelegate() +{ + D_D(DFileView); + + setItemDelegate(new DIconItemDelegate(d->fileViewHelper)); + setIconSizeBySizeIndex(itemDelegate()->iconSizeLevel()); +} + +void DFileView::initUI() +{ + D_D(DFileView); + + setSpacing(ICON_VIEW_SPACING); + setResizeMode(QListView::Adjust); + setOrientation(QListView::LeftToRight, true); + setTextElideMode(Qt::ElideMiddle); + setDragDropMode(QAbstractItemView::DragDrop); + setDropIndicatorShown(false); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setSelectionBehavior(QAbstractItemView::SelectRows); + setEditTriggers(QListView::EditKeyPressed | QListView::SelectedClicked); + // setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + setDefaultDropAction(Qt::CopyAction); + + // disable auto remove item when drop of MoveAction finished + setDragDropOverwriteMode(true); + + DListView::setSelectionRectVisible(true); + + d->displayAsActionGroup = new QActionGroup(this); + d->sortByActionGroup = new QActionGroup(this); + d->openWithActionGroup = new QActionGroup(this); + d->fileViewHelper = new FileViewHelper(this); + + d->statusBar = new DStatusBar(this); + d->statusBar->scalingSlider()->setPageStep(1); + d->statusBar->scalingSlider()->setTickInterval(1); + + addFooterWidget(d->statusBar); + + d->headerOpticalDisc = new DFMOpticalMediaWidget(this); + addHeaderWidget(d->headerOpticalDisc); + d->headerOpticalDisc->hide(); + + d->verticalScrollBar = verticalScrollBar(); + //d->verticalScrollBar->setParent(this); // this will make verticalScrollBar always visible + + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + + if (d->allowedAdjustColumnSize) { + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + } + + d->toolbarActionGroup = new QActionGroup(this); + + updateToolBarActions(this); + + // context width adjustable: + d->allowedAdjustColumnSize = DFMApplication::instance()->appAttribute(DFMApplication::AA_ViewSizeAdjustable).toBool(); +} + +void DFileView::initModel() +{ + D_D(DFileView); + + setModel(new DFileSystemModel(d->fileViewHelper)); +#ifndef CLASSICAL_SECTION + setSelectionModel(new DFileSelectionModel(model(), this)); +#endif +} + +void DFileView::initConnects() +{ + D_D(DFileView); + + connect(this, &DFileView::clicked, [=](const QModelIndex &index) { + openIndexByOpenAction(0, index); + }); + + connect(this, &DFileView::doubleClicked, [=](const QModelIndex &index) { + openIndexByOpenAction(1, index); + }); + + connect(this, &DFileView::rowCountChanged, this, &DFileView::onRowCountChanged, Qt::QueuedConnection); + + connect(d->displayAsActionGroup, &QActionGroup::triggered, this, &DFileView::dislpayAsActionTriggered); + connect(d->sortByActionGroup, &QActionGroup::triggered, this, &DFileView::sortByActionTriggered); + connect(d->openWithActionGroup, &QActionGroup::triggered, this, &DFileView::openWithActionTriggered); + + connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, &DFileView::delayUpdateStatusBar); + connect(model(), &DFileSystemModel::dataChanged, this, &DFileView::handleDataChanged); + connect(model(), &DFileSystemModel::stateChanged, this, &DFileView::onModelStateChanged); + connect(model(), &DFileSystemModel::sortFinished, this, &DFileView::delayUpdateStatusBar); + connect(model(), &DFileSystemModel::rootUrlDeleted, this, &DFileView::onRootUrlDeleted); + + connect(this, &DFileView::iconSizeChanged, this, &DFileView::updateHorizontalOffset, Qt::QueuedConnection); + connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &DFileView::updateModelActiveIndex); + + connect(DFMApplication::instance(), &DFMApplication::iconSizeLevelChanged, this, &DFileView::setIconSizeBySizeIndex); + connect(DFMApplication::instance(), &DFMApplication::showedHiddenFilesChanged, this, &DFileView::onShowHiddenFileChanged); + connect(fileSignalManager, &FileSignalManager::requestFreshAllFileView, this, &DFileView::freshView, Qt::QueuedConnection); + connect(DFMApplication::instance(), &DFMApplication::viewModeChanged, this, [this](const int &viewMode) { + setDefaultViewMode(static_cast(viewMode)); + }); + connect(DFMApplication::instance(), &DFMApplication::previewAttributeChanged, this, [this] { + model()->refresh(); + }); + + connect(d->statusBar->scalingSlider(), &QSlider::valueChanged, this, &DFileView::viewStateChanged); + connect(this, &DFileView::rootUrlChanged, this, &DFileView::loadViewState); + connect(this, &DFileView::viewStateChanged, this, &DFileView::saveViewState); + + connect(d->toolbarActionGroup, &QActionGroup::triggered, this, [this] { + Q_D(const DFileView); + + if (d->toolbarActionGroup->actions().first()->isChecked()) + setViewModeToIcon(); + else + setViewModeToList(); + }); + + // fix bug#44171 有搜索结果时才展示高级筛选面板 + connect(model(), &DFileSystemModel::showFilterButton, this, [this]() { + DFileManagerWindow *w = qobject_cast(WindowManager::getWindowById(windowId())); + if (w) { + w->showFilterButton(); + } + }); + + // fix bug 63938 + // 切换标签时,更新高级选项中的过滤项 + connect(model(), &DFileSystemModel::updateFilterRule, this, [this](const FileFilter *filter) { + DFileManagerWindow *w = qobject_cast(WindowManager::getWindowById(windowId())); + if (w) + w->updateAdvanceSearchBarValue(filter); + }); +} + +void DFileView::increaseIcon() +{ + int iconSizeLevel = itemDelegate()->increaseIcon(); + + if (iconSizeLevel >= 0) { + setIconSizeBySizeIndex(iconSizeLevel); + } +} + +void DFileView::decreaseIcon() +{ + int iconSizeLevel = itemDelegate()->decreaseIcon(); + + if (iconSizeLevel >= 0) { + setIconSizeBySizeIndex(iconSizeLevel); + } +} + +void DFileView::openIndex(const QModelIndex &index) +{ + Q_D(DFileView); + + const DUrl &url = model()->getUrlByIndex(index); + //判断网络文件是否可以到达 + if (DFileService::instance()->checkGvfsMountfileBusy(url)) { + return; + } + + DFMOpenUrlEvent::DirOpenMode mode; + if (d->isAlwaysOpenInCurrentWindow) { + mode = DFMOpenUrlEvent::OpenInCurrentWindow; + } else { + mode = DFMApplication::instance()->appAttribute(DFMApplication::AA_AllwayOpenOnNewWindow).toBool() + ? DFMOpenUrlEvent::ForceOpenNewWindow + : DFMOpenUrlEvent::OpenInCurrentWindow; + } + + if (mode == DFMOpenUrlEvent::OpenInCurrentWindow) + DFMEventDispatcher::instance()->processEventAsync(this, DUrlList() << url, mode); + else + DFMEventDispatcher::instance()->processEvent(this, DUrlList() << url, mode); +} + +void DFileView::keyboardSearch(const QString &search) +{ + D_D(DFileView); + + if (search.isEmpty()) + return; + + d->fileViewHelper->keyboardSearch(search.toLocal8Bit().at(0)); +} + +bool DFileView::setRootUrl(const DUrl &url) +{ + D_D(DFileView); + d->m_isSetRootUrl = true; + if (url.isEmpty()) { + d->m_isSetRootUrl = false; + return false; + } + + itemDelegate()->hideAllIIndexWidget(); + clearSelection(); + if (!url.isSearchFile()) { + setFocus(); + } + DUrl fileUrl = url; + //! 快捷方式打开路径需要转换,把真是路径转换成虚拟路径 + // if(url.toLocalFile().contains(VaultController::makeVaultLocalPath())) + // { + // fileUrl = VaultController::localUrlToVault(url); + // } + + DAbstractFileInfoPointer info = DFileService::instance()->createFileInfo(this, fileUrl); + + while (info && info->canRedirectionFileUrl()) { + const DUrl old_url = fileUrl; + + fileUrl = info->redirectedFileUrl(); + + if (old_url == fileUrl) + break; + //判断网络文件是否可以到达 + if (!DFileService::instance()->checkGvfsMountfileBusy(fileUrl)) { + info = DFileService::instance()->createFileInfo(this, fileUrl); + } else { + info = nullptr; + } + + qDebug() << "url redirected, from:" << old_url << "to:" << fileUrl; + } + + //! 书签方式打开路径需要转换,把真是路径转换成虚拟路径 + // if(fileUrl.toLocalFile().contains(VaultController::makeVaultLocalPath())) + // { + // fileUrl = VaultController::localUrlToVault(fileUrl); + // } + + if (!info) { + qDebug() << "This scheme isn't support, url" << fileUrl; + d->m_isSetRootUrl = false; + return false; + } + // TODO: drop this special case when we switch away from UDiskListener::addSubscriber in AppController. + if (fileUrl.scheme() == BURN_SCHEME) { + Q_ASSERT(fileUrl.burnDestDevice().length() > 0); + + QString strVolTag = DFMOpticalMediaWidget::getVolTag(fileUrl); + + QString devpath = fileUrl.burnDestDevice(); + QStringList rootDeviceNode = DDiskManager::resolveDeviceNode(devpath, {}); + if (rootDeviceNode.isEmpty()) { + d->m_isSetRootUrl = false; + return false; + } + QString udiskspath = rootDeviceNode.first(); + //getOpticalDriveMutex()->lock();// 主线程不能加锁,否则导致界面僵死:bug 31318:切换用户,打开文件管理器,多次点击左侧光驱栏目,右键,关闭一个授权弹窗,文件管理器卡死 + DISOMasterNS::DeviceProperty dp = ISOMaster->getDevicePropertyCached(devpath); + //getOpticalDriveMutex()->unlock(); + QSharedPointer blkdev(DDiskManager::createBlockDevice(udiskspath)); + CdStatusInfo *pCdStatusInfo = &DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag]; // bug fix 31427:挂载光驱,切换多个用户,文件管理器卡死:多用户情况下 授权框是 串行资源,必须做执行才能继续后续操作,不能神操作,否则就卡,这是 linux 的安全策略 + + if (!dp.devid.length()) { + //QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + DFileService::instance()->setCursorBusyState(true); + if (DFMOpticalMediaWidget::g_mapCdStatusInfo.contains(strVolTag)) + DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].bLoading = true; + + QSharedPointer> fw(new QFutureWatcher); + connect(fw.data(), &QFutureWatcher::finished, this, [=] { + //QGuiApplication::restoreOverrideCursor(); + if (!pCdStatusInfo->bProcessLocked) { + DFileService::instance()->setCursorBusyState(false); + //QGuiApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); // bug 31318, 应该直接使用ArrowCursor,否则多个弹窗的情况下,鼠标要出问题 + } + + if (fw->result()) { + cd(fileUrl); + } + }); + fw->setFuture(QtConcurrent::run([=] { + if (pCdStatusInfo->bProcessLocked) + return false; + QMutexLocker locker(getOpticalDriveMutex()); + blkdev->unmount({}); + + pCdStatusInfo->bProcessLocked = false; // 过了unmount 流程,系统就不会有卡点了,下面流程会平滑过度 + + // fix bug 27211 用户操作其他用户挂载的设备的时候,需要先卸载,卸载得提权,如果用户直接关闭了对话框,会返回错误代码 QDbusError::Other + // 需要对错误进行处理,出错的时候就不再执行后续操作了。 + QDBusError err = blkdev->lastError(); + if (err.isValid() && !err.name().toLower().contains("notmounted")) // 如果未挂载,Error 返回 Other,错误信息 org.freedesktop.UDisks2.Error.NotMounted + { + qDebug() << "disc mount error: " << err.message() << err.name() << err.type(); + DThreadUtil::runInMainThread([] { + dialogManager->showErrorDialog(tr("Disc mount error"), tr("The disc is in use, please end the running process and remount the disc.")); + }); + return false; + } + if (!ISOMaster->acquireDevice(devpath)) { + ISOMaster->releaseDevice(); + blkdev->unmount({}); + QThread::msleep(1000); + QScopedPointer diskdev(DDiskManager::createDiskDevice(blkdev->drive())); + diskdev->eject({}); + qDebug() << "setRootUrl failed:" << blkdev->drive(); + if (diskdev->optical()) { + emit fileSignalManager->cdFolder(DUrl(COMPUTER_ROOT)); // 失败的时候跳转到计算机界面 + QMetaObject::invokeMethod(dialogManager, std::bind(&DialogManager::showErrorDialog, dialogManager, tr("Mounting failed"), QString()), Qt::ConnectionType::QueuedConnection); + } + return false; + } + ISOMaster->getDeviceProperty(); + ISOMaster->releaseDevice(); + blkdev->mount({}); + + return true; + })); + d->m_isSetRootUrl = false; + return false; + } else { + d->headerOpticalDisc->updateDiscInfo(fileUrl.burnDestDevice()); + d->headerOpticalDisc->show(); + auto points = blkdev->mountPoints(); + if (points.empty()) { + blkdev->mount({}); + // 挂载后更新缓存的挂载点 + points = blkdev->mountPoints(); + } + if (!blkdev->mountPoints().empty()) { + d->headerOpticalDisc->setDiscMountPoint(blkdev->mountPoints()[0]); + } else { + d->headerOpticalDisc->setDiscMountPoint(""); + } + d->headerOpticalDisc->setDefaultDiscName(blkdev->idLabel()); + } + } else { + d->headerOpticalDisc->hide(); + } + + const DUrl &rootUrl = this->rootUrl(); + + qDebug() << "cd: current url:" << rootUrl << "to url:" << fileUrl; + + // if (rootUrl == fileUrl) + // return true; + // 对于相同路径也要走同样的流程 + + // fix bug 63275 + // 默认情况下,QUrlQuery使用等号("=")来分隔key和value,符号("&")分割彼此的key-value对 + // 因此当传递过来的文件名中带有&符号,就会导致获取selectUrl失败 + // 对query字段内容进行编码处理,解析的时候再进行解码 + QUrlQuery urlQuery; + QByteArray encode = QUrl::toPercentEncoding(fileUrl.query(QUrl::FullyEncoded), "="); + urlQuery.setQuery(encode); + const DUrl &defaultSelectUrl = DUrl(urlQuery.queryItemValue("selectUrl", QUrl::FullyDecoded)); + + if (defaultSelectUrl.isValid()) { + d->preSelectionUrls << defaultSelectUrl; + + urlQuery.removeQueryItem("selectUrl"); + fileUrl.setQuery(urlQuery); + } else { + //判断网络文件是否可以到达 + if (!DFileService::instance()->checkGvfsMountfileBusy(rootUrl, false)) { + QList ancestors; + if (const DAbstractFileInfoPointer ¤t_file_info = DFileService::instance()->createFileInfo(this, rootUrl)) { + if (current_file_info->isAncestorsUrl(fileUrl, &ancestors)) + d->preSelectionUrls << (ancestors.count() > 1 ? ancestors.at(ancestors.count() - 2) : rootUrl); + } + } + } + + QModelIndex index = model()->setRootUrl(fileUrl); + d->m_isSetRootUrl = false; + setRootIndex(index); + + if (!model()->canFetchMore(index)) { + updateContentLabel(); + } + + model()->setSortRole(d->fileViewStateValue(fileUrl, "sortRole", DFileSystemModel::FileDisplayNameRole).toInt(), + static_cast(d->fileViewStateValue(fileUrl, "sortOrder", Qt::AscendingOrder).toInt())); + + if (d->headerView) { + updateListHeaderViewProperty(); + // update header view sort indicator + QSignalBlocker blocker(d->headerView); + Q_UNUSED(blocker) + d->headerView->setSortIndicator(model()->sortColumn(), model()->sortOrder()); + } + + if (info) { + ViewModes modes = static_cast(info->supportViewMode()); + + //view mode support handler + toolBarActionList().first()->setVisible(testViewMode(modes, IconMode)); + toolBarActionList().at(1)->setVisible(testViewMode(modes, ListMode)); + } + + emit rootUrlChanged(fileUrl); + + if (fileUrl.isSearchFile()) { + setViewMode(ListMode); + } + + // NOTE(zccrs): 视图模式切换失败后,被选中的action是一个错误的。此时切换目录,应该在目录改变后再根据当前视图模式重设action的选中状态。 + if (viewMode() == IconMode) { + toolBarActionList().first()->setChecked(true); + } else { + toolBarActionList().at(1)->setChecked(true); + } + + const QList &supportSelectionModes = info->supportSelectionModes(); + + for (DAbstractFileInfo::SelectionMode mode : supportSelectionModes) { + if (d->enabledSelectionModes.contains(static_cast(mode))) { + setSelectionMode(static_cast(mode)); + break; + } + } + + return true; +} + +bool DFileView::getCanDestruct() const +{ + Q_D(const DFileView); + return !(d->m_isDragging.load() || d->m_isMouseMoveing.load()); +} + +void DFileView::clearHeardView() +{ + D_D(DFileView); + + if (d->headerView) { + removeHeaderWidget(1); + + d->headerView->disconnect(); + d->headerView = nullptr; + d->headerViewHolder = nullptr; + } +} + +void DFileView::clearSelection() +{ + QListView::clearSelection(); + setCurrentIndex(QModelIndex()); +} + +void DFileView::setContentLabel(const QString &text) +{ + D_D(DFileView); + + if (!d->contentLabel) { + d->contentLabel = new QLabel(this); + // font-family: SourceHanSansSC-Light; + // font-size: 20px; + // color: #bdbdbd; #D0D0D0; + QPalette palette = d->contentLabel->palette(); + QStyleOption opt; + opt.initFrom(d->contentLabel); + QColor color = opt.palette.color(QPalette::Inactive, QPalette::Text); + palette.setColor(QPalette::Text, color); + d->contentLabel->setPalette(palette); + auto font = d->contentLabel->font(); + font.setFamily("SourceHanSansSC-Light"); + font.setPixelSize(20); + d->contentLabel->setFont(font); + + d->contentLabel.setCenterIn(this); + d->contentLabel->setObjectName("contentLabel"); + d->contentLabel->setStyleSheet(this->styleSheet()); + d->contentLabel->setAttribute(Qt::WA_TransparentForMouseEvents); + d->contentLabel->show(); + } + + d->contentLabel->setText(text); + d->contentLabel->adjustSize(); +} + +void DFileView::setMenuActionWhitelist(const QSet &actionList) +{ + Q_D(DFileView); + + d->menuWhitelist = actionList; + + if (focusWidget() == this) { + DFileMenuManager::setActionWhitelist(d->menuWhitelist); + } +} + +void DFileView::setMenuActionBlacklist(const QSet &actionList) +{ + Q_D(DFileView); + + d->menuBlacklist = actionList; + + if (focusWidget() == this) { + DFileMenuManager::setActionBlacklist(d->menuBlacklist); + } +} + +void DFileView::updateHorizontalOffset() +{ + D_D(DFileView); + + if (isIconViewMode()) { + int contentWidth = maximumViewportSize().width(); + int itemWidth = itemSizeHint().width() + spacing() * 2; + int itemColumn = d->iconModeColumnCount(itemWidth); + + d->horizontalOffset = -(contentWidth - itemWidth * itemColumn) / 2; + } else { + d->horizontalOffset = 0; + } +} + +void DFileView::switchViewMode(DFileView::ViewMode mode) +{ + D_D(DFileView); + + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(rootUrl()); + + if (fileInfo) { + const auto modes = fileInfo->supportViewMode(); + if (!(modes & mode)) { + if (modes & DFileView::ListMode) { + mode = DFileView::ListMode; + } else if (modes & DFileView::IconMode) { + mode = DFileView::IconMode; + } else { + return; + } + } + } + + if (d->currentViewMode == mode) { + return; + } + + d->currentViewMode = mode; + + itemDelegate()->hideAllIIndexWidget(); + + horizontalScrollBar()->parentWidget()->removeEventFilter(this); + + switch (mode) { + case IconMode: { + clearHeardView(); + d->columnRoles.clear(); + setOrientation(QListView::LeftToRight, true); + setSpacing(ICON_VIEW_SPACING); + setItemDelegate(new DIconItemDelegate(d->fileViewHelper)); + setUniformItemSizes(false); + setResizeMode(Adjust); + setAlternatingRowColors(false); + + d->statusBar->scalingSlider()->show(); + itemDelegate()->setIconSizeByIconSizeLevel(d->statusBar->scalingSlider()->value()); + d->toolbarActionGroup->actions().first()->setChecked(true); + + break; + } + case ListMode: { + setItemDelegate(new DListItemDelegate(d->fileViewHelper)); + setUniformItemSizes(true); + setResizeMode(Fixed); + setAlternatingRowColors(false); + + if (!d->headerView) { + if (d->allowedAdjustColumnSize) { + d->headerViewHolder = new QWidget(this); + d->headerView = new DFMHeaderView(Qt::Horizontal, d->headerViewHolder); + + connect(d->headerView, &DFMHeaderView::viewResized, this, [d] { + d->headerViewHolder->setFixedHeight(d->headerView->height()); + }); + connect(d->headerView, &DFMHeaderView::sectionResized, d->headerView, &DFMHeaderView::adjustSize); + connect(d->headerView, SIGNAL(sectionHandleDoubleClicked(int)), this, SLOT(_q_onSectionHandleDoubleClicked(int))); + } else { + d->headerView = new DFMHeaderView(Qt::Horizontal, this); + d->headerViewHolder = d->headerView; + } + + updateListHeaderViewProperty(); + + d->headerView->setHighlightSections(false); + d->headerView->setSectionsClickable(true); + d->headerView->setSortIndicatorShown(true); + d->headerView->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); + d->headerView->setContextMenuPolicy(Qt::CustomContextMenu); + + if (selectionModel()) { + d->headerView->setSelectionModel(selectionModel()); + } + + connect(d->headerView, &QHeaderView::sectionResized, + this, static_cast(&DFileView::update)); + connect(d->headerView, &QHeaderView::sortIndicatorChanged, + this, &DFileView::onSortIndicatorChanged); + connect(d->headerView, &QHeaderView::customContextMenuRequested, + this, &DFileView::popupHeaderViewContextMenu); + connect(d->headerView, &DFMHeaderView::mouseReleased, this, [=] { + //仅当修改了宽度使headerview和view的宽度不一致时才取消自适应宽度 + if (d->headerView->width() != width()) + d->toggleHeaderViewSnap(false); + QList roleList = columnRoleList(); + QVariantMap state; + for (const int role : roleList) { + int colWidth = columnWidth(model()->roleToColumn(role)); + + if (colWidth > 0) + state[QString::number(role)] = colWidth; + } + DFMApplication::appObtuselySetting()->setValue("WindowManager", "ViewColumnState", state); + }); + connect(horizontalScrollBar(), &QScrollBar::valueChanged, d->headerView, + [d](int value) { + if (d->headerView) { + d->headerView->move(-value, d->headerView->y()); + } + }); + + connect(d->headerView, &DFMHeaderView::sectionMoved, this, &DFileView::onHeaderSectionMoved); + + if (d->allowedAdjustColumnSize) { + connect(d->headerView, &QHeaderView::sectionResized, + this, &DFileView::updateGeometries); + } + + d->headerView->setAttribute(Qt::WA_TransparentForMouseEvents, model()->state() == DFileSystemModel::Busy); + } + + addHeaderWidget(d->headerViewHolder); + + setOrientation(QListView::TopToBottom, false); + setSpacing(LIST_VIEW_SPACING); + d->statusBar->scalingSlider()->hide(); + d->toolbarActionGroup->actions().at(1)->setChecked(true); + + if (d->allowedAdjustColumnSize) { + horizontalScrollBar()->parentWidget()->installEventFilter(this); + // 初始化列宽调整 + d->cachedViewWidth = this->width(); + //fix task wayland 21328 当切换到列表显示时自动适应列宽度 + d->adjustFileNameCol = true; //fix 31609 无论如何在切换显示模式时都去调整列表宽度 + updateListHeaderViewProperty(); + } + + break; + } + case ExtendMode: { + break; + } + default: + break; + } + + setFocus(); + + emit viewModeChanged(mode); +} + +void DFileView::showEmptyAreaMenu(const Qt::ItemFlags &indexFlags) +{ + Q_UNUSED(indexFlags) + D_D(DFileView); + + const QModelIndex &index = rootIndex(); + const DAbstractFileInfoPointer &info = model()->fileInfo(index); + QVector actions = info->menuActionList(DAbstractFileInfo::SpaceArea); + + // 右键刷新,根据开关移除 + { + static const DGioSettings menuSwitch("com.deepin.dde.filemanager.contextmenu", + "/com/deepin/dde/filemanager/contextmenu/"); + auto showRefreh = menuSwitch.value("Refresh"); + if (!showRefreh.isValid() || !showRefreh.toBool()) + actions.removeAll(MenuAction::RefreshView); + } + + if (actions.isEmpty()) + return; + // sp3 feature: root用户, 服务器版本用户, 非开发者模式均不需要以管理员身份打开的功能 + if (DFMGlobal::isRootUser() || DFMGlobal::isServerSys() || !DFMGlobal::isDeveloperMode()) { + actions.removeAll(MenuAction::OpenAsAdmin); + } + + const QMap> &subActions = info->subMenuActionList(DAbstractFileInfo::SpaceArea); + + QSet disableList = DFileMenuManager::getDisableActionList(model()->getUrlByIndex(index)); + + if (model()->state() != DFileSystemModel::Idle) { + disableList << MenuAction::SortBy; + } + + // if (!indexFlags.testFlag(Qt::ItemIsEditable)) + // disableList << MenuAction::NewDocument << MenuAction::NewFolder << MenuAction::Paste; + + const bool &tabAddable = WindowManager::tabAddableByWinId(windowId()); + if (!tabAddable) + disableList << MenuAction::OpenInNewTab; + + if (!count()) + disableList << MenuAction::SelectAll; + + DFileMenu *menu = DFileMenuManager::genereteMenuByKeys(actions, disableList, true, subActions); + if (!menu) { + return; + } + + QAction *tmp_action = menu->actionAt(fileMenuManger->getActionString(MenuAction::DisplayAs)); + DFileMenu *displayAsSubMenu = static_cast(tmp_action ? tmp_action->menu() : Q_NULLPTR); + tmp_action = menu->actionAt(fileMenuManger->getActionString(MenuAction::SortBy)); + DFileMenu *sortBySubMenu = static_cast(tmp_action ? tmp_action->menu() : Q_NULLPTR); + + for (QAction *action : d->displayAsActionGroup->actions()) { + d->displayAsActionGroup->removeAction(action); + } + + if (displayAsSubMenu) { + foreach (QAction *action, displayAsSubMenu->actions()) { + action->setActionGroup(d->displayAsActionGroup); + action->setCheckable(true); + action->setChecked(false); + } + + QAction *currentViewModeAction = nullptr; + + if (d->currentViewMode == IconMode) { + currentViewModeAction = displayAsSubMenu->actionAt(fileMenuManger->getActionString(MenuAction::IconView)); + } else if (d->currentViewMode == ListMode) { + currentViewModeAction = displayAsSubMenu->actionAt(fileMenuManger->getActionString(MenuAction::ListView)); + } else if (d->currentViewMode == ExtendMode) { + currentViewModeAction = displayAsSubMenu->actionAt(fileMenuManger->getActionString(MenuAction::ExtendView)); + } + + if (currentViewModeAction) + currentViewModeAction->setChecked(true); + } + + for (QAction *action : d->sortByActionGroup->actions()) { + d->sortByActionGroup->removeAction(action); + } + + if (sortBySubMenu) { + foreach (QAction *action, sortBySubMenu->actions()) { + action->setActionGroup(d->sortByActionGroup); + action->setCheckable(true); + action->setChecked(false); + } + + QAction *action = sortBySubMenu->actionAt(info->sortSubMenuActionUserColumnRoles().indexOf(model()->sortRole())); + + if (action) + action->setChecked(true); + } + + DFileMenuManager::loadEmptyAreaPluginMenu(menu, rootUrl(), false); + + //扩展菜单 + if (DFileMenuManager::isCustomMenuSupported(rootUrl())) + DFileMenuManager::extendCustomMenu(menu, false, rootUrl(), {}, {}); + + menu->setEventData(rootUrl(), selectedUrls(), windowId(), this); + + fileViewHelper()->handleMenu(menu); + //fix bug 33305 在用右键菜单复制大量文件时,在复制过程中,关闭窗口这时this释放了,在关闭拷贝menu的exec退出,menu的deleteLater崩溃 + QPointer me = this; + menu->exec(); + menu->deleteLater(me); +} + +void DFileView::showNormalMenu(const QModelIndex &index, const Qt::ItemFlags &indexFlags) +{ + if (!index.isValid()) + return; + DUrlList list = selectedUrls(); + + DFileMenu *menu; + +#ifdef SW_LABEL + DAbstractFileInfoPointer info = model()->fileInfo(index); + info->updateLabelMenuItems(); +#else + const DAbstractFileInfoPointer &info = model()->fileInfo(index); +#endif + + if (!info || !info->exists()) { + qDebug() << "info is null or not exists,so exit"; + return; + } + + QSet disableList; + QSet unusedList; + + // blumia: when touching this part, do the same change in canvasgridview.cpp + if (list.size() == 1) { + + if (!info->isWritable() && !info->isFile() && !info->isSymLink()) { + disableList << MenuAction::Delete; + } + + if (!indexFlags.testFlag(Qt::ItemIsEditable)) { + disableList << MenuAction::Rename; + } + } + + // 在上一个菜单没有结束前,拒绝下一个菜单 + static bool lock = false; + qint64 curTime = QDateTime::currentMSecsSinceEpoch(); + static qint64 lastTime = QDateTime::currentMSecsSinceEpoch(); + + // 两次右键菜单的间隔时间, < 500 毫秒说明点击过于频繁, 进行限制 + // 目的是为了防止右键菜单产生新的模态对话框, exec() 函数无法结束, lock状态无法重置 + // 相关bug: 47478 + qint64 intervalime = curTime - lastTime; + if (lock && (intervalime < 500)) { + qDebug() << "reject show menu"; + return; + } + + if (VaultController::isRootDirectory(info->fileUrl().fragment())) { + //! create vault menu. + menu = DFileMenuManager::createVaultMenu(this->topLevelWidget()); + } else { + if (DFileService::instance()->checkGvfsMountfileBusy(info->fileUrl())) + return; + menu = DFileMenuManager::createNormalMenu(info->fileUrl(), list, disableList, unusedList, static_cast(windowId()), false); + menu->setAccessibleInfo(AC_FILE_MENU_FILEVIEW); + } + lock = true; + + if (!menu) { + lock = false; + return; + } + + //扩展菜单 + { + //是否显示自定义菜单 + const DUrl &viewRootUrl = rootUrl(); + bool customMenu = DFileMenuManager::isCustomMenuSupported(viewRootUrl); + if (customMenu && (viewRootUrl == DUrl::fromLocalFile(DFMStandardPaths::location(DFMStandardPaths::DesktopPath)))) { + //判断计算机 回收站 主目录 + const DUrl &computerDesktopFile = DesktopFileInfo::computerDesktopFileUrl(); + const DUrl &trashDesktopFile = DesktopFileInfo::trashDesktopFileUrl(); + const DUrl &homeDesktopFile = DesktopFileInfo::homeDesktopFileUrl(); + + //多选文件中包含以下文件时 则不展示扩展菜单项 + for (const DUrl &url : list) { + if (url == computerDesktopFile + || url == trashDesktopFile + || url == homeDesktopFile) { + customMenu = false; + break; + } + } + } + + if (customMenu) + DFileMenuManager::extendCustomMenu(menu, true, viewRootUrl, info->fileUrl(), list); + } + + menu->setEventData(rootUrl(), selectedUrls(), windowId(), this, index); + + fileViewHelper()->handleMenu(menu); + // 若此处使用this,那么当切换到其台view时,当前view释放,会造成野指针引起崩溃 + // 因此使用当前的 activewindow,确保当前窗口下工作时切换到其他view不受影响 + //fix bug 33305 在用右键菜单复制大量文件时,在复制过程中,关闭窗口这时this释放了, + //在关闭拷贝menu的exec退出,menu的deleteLater崩溃 + QPointer window = qApp->activeWindow(); + lastTime = QDateTime::currentMSecsSinceEpoch(); + menu->exec(); + menu->deleteLater(window); + lock = false; +} + +void DFileView::updateListHeaderViewProperty() +{ + D_D(DFileView); + + if (!d->headerView) + return; + + d->headerView->setModel(Q_NULLPTR); + d->headerView->setModel(model()); + + d->headerView->setDefaultSectionSize(DEFAULT_HEADER_SECTION_WIDTH); + + if (d->allowedAdjustColumnSize) { + d->headerView->setSectionResizeMode(QHeaderView::Interactive); + d->headerView->setMinimumSectionSize(LIST_VIEW_MINIMUM_WIDTH); + } else { + d->headerView->setSectionResizeMode(QHeaderView::Fixed); + d->headerView->setMinimumSectionSize(DEFAULT_HEADER_SECTION_WIDTH); + } + + d->headerView->setSortIndicator(model()->sortColumn(), model()->sortOrder()); + d->columnRoles.clear(); + + // set value from config file. + const QVariantMap &state = DFMApplication::appObtuselySetting()->value("WindowManager", "ViewColumnState").toMap(); + + for (int i = 0; i < d->headerView->count(); ++i) { + int logicalIndex = d->headerView->logicalIndex(i); + d->columnRoles << model()->columnToRole(i); + + if (d->allowedAdjustColumnSize) { + int colWidth = state.value(QString::number(d->columnRoles.last()), -1).toInt(); + if (colWidth > 0) { + d->headerView->resizeSection(model()->roleToColumn(d->columnRoles.last()), colWidth); + } + } else { + int column_width = model()->columnWidth(i); + if (column_width >= 0) { + d->headerView->resizeSection(logicalIndex, column_width + COLUMU_PADDING * 2); + } else { + d->headerView->setSectionResizeMode(logicalIndex, QHeaderView::Stretch); + } + } + + const QString &column_name = model()->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); + + if (!d->columnForRoleHiddenMap.contains(column_name)) { + d->headerView->setSectionHidden(logicalIndex, !model()->columnDefaultVisibleForRole(model()->columnToRole(i))); + } else { + d->headerView->setSectionHidden(logicalIndex, d->columnForRoleHiddenMap.value(column_name)); + } + } + + if (d->adjustFileNameCol) { + d->doFileNameColResize(); + } + + updateColumnWidth(); +} + +void DFileView::updateExtendHeaderViewProperty() +{ + D_D(DFileView); + + if (!d->headerView) + return; + + d->headerView->setModel(Q_NULLPTR); + d->headerView->setModel(model()); + d->headerView->setDefaultSectionSize(DEFAULT_HEADER_SECTION_WIDTH); + + if (!d->allowedAdjustColumnSize) { + d->headerView->setSectionResizeMode(QHeaderView::Fixed); + d->headerView->setSectionResizeMode(0, QHeaderView::Stretch); + d->headerView->setMinimumSectionSize(DEFAULT_HEADER_SECTION_WIDTH); + } + + d->columnRoles.clear(); + d->columnRoles << model()->columnToRole(0); +} + +void DFileView::updateColumnWidth() +{ + D_D(DFileView); + + if (!d->allowedAdjustColumnSize) { + int column_count = d->headerView->count(); + int i = 0; + int j = column_count - 1; + + for (; i < column_count; ++i) { + int logicalIndex = d->headerView->logicalIndex(i); + if (d->headerView->isSectionHidden(logicalIndex)) + continue; + + d->headerView->resizeSection(logicalIndex, model()->columnWidth(i) + LEFT_PADDING + LIST_MODE_LEFT_MARGIN + 2 * COLUMU_PADDING); + break; + } + + for (; j > 0; --j) { + int logicalIndex = d->headerView->logicalIndex(j); + if (d->headerView->isSectionHidden(logicalIndex)) + continue; + + d->headerView->resizeSection(logicalIndex, model()->columnWidth(j) + RIGHT_PADDING + LIST_MODE_RIGHT_MARGIN + 2 * COLUMU_PADDING); + break; + } + + if (d->firstVisibleColumn != i) { + if (d->firstVisibleColumn > 0) + d->headerView->resizeSection(d->headerView->logicalIndex(d->firstVisibleColumn), model()->columnWidth(d->firstVisibleColumn) + 2 * COLUMU_PADDING); + + d->firstVisibleColumn = i; + } + + if (d->lastVisibleColumn != j) { + if (d->lastVisibleColumn > 0) + d->headerView->resizeSection(d->headerView->logicalIndex(d->lastVisibleColumn), model()->columnWidth(d->lastVisibleColumn) + 2 * COLUMU_PADDING); + + d->lastVisibleColumn = j; + } + } +} + +void DFileView::popupHeaderViewContextMenu(const QPoint &pos) +{ + D_D(DFileView); + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(rootIndex()); + DFileMenu *menu = new DFileMenu(); + + if (fileInfo && fileInfo->columnIsCompact()) { + /*contextmenu of headview for sort function*/ + int column = d->headerView->logicalIndexAt(pos.x()); + + const QList &childRoles = fileInfo->userColumnChildRoles(column); + + if (childRoles.isEmpty()) { + //fix bug 33305 在用右键菜单复制大量文件时,在复制过程中,关闭窗口这时this释放了, + //在关闭拷贝menu的exec退出,menu的deleteLater崩溃 + QPointer me = this; + menu->deleteLater(me); + + return; + } + + for (int i = 0; i < childRoles.count() * 2; ++i) { + int childRole = childRoles.at(i / 2); + QAction *action = new QAction(menu); + + if (i % 2 == 0) { + action->setText(fileInfo->userColumnDisplayName(childRole).toString()); + } else if (i % 2 == 1) { + action->setText(fileInfo->userColumnDisplayName(childRole).toString() + tr("(Reverse)")); + } + + action->setCheckable(true); + + if (!d->headerView->isSectionHidden(d->headerView->sortIndicatorSection()) + && model()->sortRole() == childRole) { + if (i % 2 == 1 && model()->sortOrder() == Qt::DescendingOrder) { + action->setChecked(true); + } + if (i % 2 == 0 && model()->sortOrder() == Qt::AscendingOrder) { + action->setChecked(true); + } + } + + connect(action, &QAction::triggered, this, [this, i, childRoles] { + if (i % 2 == 0) { + sortByRole(childRoles.at(i / 2), Qt::AscendingOrder); + } else if (i % 2 == 1) { + sortByRole(childRoles.at(i / 2), Qt::DescendingOrder); + } + }); + + menu->addAction(action); + } + } else { + for (int i = 0; i < d->headerView->count(); ++i) { + //名称列不能被隐藏 + if (model()->columnToRole(i) == DFileSystemModel::FileNameRole || model()->columnToRole(i) == DFileSystemModel::FileDisplayNameRole) + continue; + + QAction *action = new QAction(menu); + + action->setText(model()->columnNameByRole(model()->columnToRole(i)).toString()); + action->setCheckable(true); + action->setChecked(!d->headerView->isSectionHidden(i)); + + connect(action, &QAction::triggered, this, [this, action, i, d] { + action->setChecked(!action->isChecked()); + d->columnForRoleHiddenMap[action->text()] = action->isChecked(); + + d->headerView->setSectionHidden(i, action->isChecked()); + + // fix bug#36610 增加或减少排序方式分类列表未自适应 + if (d->allowedAdjustColumnSize) { + updateListHeaderViewProperty(); + } else { + updateColumnWidth(); + } + }); + + menu->addAction(action); + } + } + //fix bug 33305 在用右键菜单复制大量文件时,在复制过程中,关闭窗口这时this释放了, + //在关闭拷贝menu的exec退出,menu的deleteLater崩溃 + QPointer me = this; + menu->exec(QCursor::pos()); + menu->deleteLater(me); +} + +void DFileView::onModelStateChanged(int state) +{ + D_D(DFileView); + + DFMEvent event(this); + + event.setWindowId(windowId()); + event.setData(rootUrl()); + + if (state == DFileSystemModel::Busy) { + QString tipText; + + if (const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(rootIndex())) { + tipText = fileInfo->loadingTip(); + } + + d->statusBar->setLoadingIncatorVisible(state == DFileSystemModel::Busy, tipText); + + setContentLabel(QString()); + + if (d->headerView) { + d->headerView->setAttribute(Qt::WA_TransparentForMouseEvents); + } + } else if (state == DFileSystemModel::Idle) { + d->statusBar->setLoadingIncatorVisible(state == DFileSystemModel::Busy); + + if (!d->preSelectionUrls.isEmpty()) { + const QModelIndex &index = model()->index(d->preSelectionUrls.first()); + + setCurrentIndex(index); + scrollTo(index, PositionAtTop); + } + + for (const DUrl &url : d->preSelectionUrls) { + selectionModel()->select(model()->index(url), QItemSelectionModel::Select); + } + + d->preSelectionUrls.clear(); + + delayUpdateStatusBar(); + updateContentLabel(); + + if (d->headerView) { + d->headerView->setAttribute(Qt::WA_TransparentForMouseEvents, false); + } + } + + // 通知对应的主窗口 + notifyStateChanged(); +} + +void DFileView::updateContentLabel() +{ + if (model()->state() != DFileSystemModel::Idle + || model()->canFetchMore(rootIndex())) { + setContentLabel(QString()); + + return; + } + + int count = this->count(); + + if (count <= 0) { + const DAbstractFileInfoPointer &fileInfo = model()->fileInfo(rootIndex()); + + if (fileInfo) { + setContentLabel(fileInfo->subtitleForEmptyFloder()); + return; + } + } + + setContentLabel(QString()); +} + +void DFileView::updateToolBarActions(QWidget *widget, QString theme) +{ + Q_UNUSED(theme) + D_D(DFileView); + if (widget == this) { + QAction *icon_view_mode_action; + QAction *list_view_mode_action; + const QList actions = d->toolbarActionGroup->actions(); + + if (actions.count() > 1) { + icon_view_mode_action = actions.first(); + list_view_mode_action = actions.at(1); + } else { + icon_view_mode_action = new QAction(this); + list_view_mode_action = new QAction(this); + + icon_view_mode_action->setCheckable(true); + icon_view_mode_action->setChecked(true); + + list_view_mode_action->setCheckable(true); + + d->toolbarActionGroup->addAction(icon_view_mode_action); + d->toolbarActionGroup->addAction(list_view_mode_action); + } + + icon_view_mode_action->setIcon(QIcon::fromTheme("dfm_viewlist_icons")); + list_view_mode_action->setIcon(QIcon::fromTheme("dfm_viewlist_details")); + } +} + +bool DFileView::normalKeyPressEvent(const QKeyEvent *event) +{ + D_D(DFileView); + + const DUrlList urls = selectedUrls(); + switch (event->key()) { + case Qt::Key_Return: + case Qt::Key_Enter: + if (!itemDelegate()->editingIndex().isValid()) { + appController->actionOpen(dMakeEventPointer(this, urls), true); + return true; + } + break; + case Qt::Key_Backspace: { + // blmark: revert commit vbfdf8e575447249ba284402bfac8a512bae2d10e + cdUp(); + return true; + } + case Qt::Key_Delete: { + QString rootPath = rootUrl().toLocalFile(); + if (FileUtils::isGvfsMountFile(rootPath) || deviceListener->isInRemovableDeviceFolder(rootPath) || VaultController::isVaultFile(rootPath)) { + appController->actionCompleteDeletion(dMakeEventPointer(this, urls)); + } else { + //! refresh after vault file deleted. + if (urls.size() > 0) { + QString filepath = urls.front().toLocalFile(); + if (VaultController::isVaultFile(filepath) && !d->isVaultDelSigConnected) { + d->isVaultDelSigConnected = true; + } + } + + // 只支持回收站根目录下的文件执行删除 + if (rootUrl().isTrashFile() && rootUrl() != DUrl::fromTrashFile("/")) + break; + + appController->actionDelete(dMakeEventPointer(this, urls)); + } + break; + } + case Qt::Key_End: + if (urls.isEmpty()) { + setCurrentIndex(model()->index(count() - 1, 0)); + return true; + } + default: + break; + } + + return false; +} + +void DFileView::refresh() +{ + model()->refresh(); +} + +bool DFileView::fetchDragEventUrlsFromSharedMemory() +{ + QSharedMemory sm; + sm.setKey(DRAG_EVENT_URLS); + + if (!sm.isAttached()) { + if (!sm.attach()) { + qDebug() << "FQSharedMemory detach failed."; + return false; + } + } + + QBuffer buffer; + QDataStream in(&buffer); + QList urls; + + sm.lock(); + //用缓冲区得到共享内存关联后得到的数据和数据大小 + buffer.setData(static_cast(const_cast(sm.constData())), sm.size()); + buffer.open(QBuffer::ReadOnly); //设置读取模式 + in >> m_urlsForDragEvent; //使用数据流从缓冲区获得共享内存的数据,然后输出到字符串中 + qInfo() << "drop file urls = " << m_urlsForDragEvent << "to current url = " << rootUrl(); + sm.unlock(); //解锁 + sm.detach(); //与共享内存空间分离 + + return true; +} + +void DFileView::setTargetUrlToApp(const QMimeData *data, const DUrl &url) +{ + //仅当target改变的时候才调用DFileDragClient::setTargetUrl + if (!m_currentTargetUrl.isValid() || m_currentTargetUrl.path() != url.path()) { + m_currentTargetUrl = url; + DFileDragClient::setTargetUrl(data, url); + } +} + +int DFileViewPrivate::iconModeColumnCount(int itemWidth) const +{ + Q_Q(const DFileView); + + // int frameAroundContents = 0; + // if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents)) + // frameAroundContents = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2; + + int horizontalMargin = /*q->verticalScrollBarPolicy()==Qt::ScrollBarAsNeeded + ? q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, q->verticalScrollBar()) + frameAroundContents + : */ + 0; + + int contentWidth = q->maximumViewportSize().width(); + + if (itemWidth <= 0) + itemWidth = q->itemSizeHint().width() + q->spacing() * 2; + + return qMax((contentWidth - horizontalMargin - 1) / itemWidth, 1); +} + +QVariant DFileViewPrivate::fileViewStateValue(const DUrl &url, const QString &key, const QVariant &defalutValue) +{ + return DFMApplication::appObtuselySetting()->value("FileViewState", url).toMap().value(key, defalutValue); +} + +void DFileViewPrivate::setFileViewStateValue(const DUrl &url, const QString &key, const QVariant &value) +{ + QVariantMap map = DFMApplication::appObtuselySetting()->value("FileViewState", url).toMap(); + + map[key] = value; + + DFMApplication::appObtuselySetting()->setValue("FileViewState", url, map); +} + +void DFileViewPrivate::updateHorizontalScrollBarPosition() +{ + Q_Q(DFileView); + + QWidget *widget = static_cast(q->horizontalScrollBar()->parentWidget()); + + // 更新横向滚动条的位置,将它显示在状态栏上面(此处没有加防止陷入死循环的处理) + widget->move(widget->x(), q->height() - statusBar->height() - widget->height()); +} + +void DFileViewPrivate::pureResizeEvent(QResizeEvent *event) +{ + Q_Q(DFileView); + + if (currentViewMode == DFileView::ListMode) { //修复分非列表模式启动崩溃 + if (showCount == 1) { //fix 任务25717 文件管理器窗口默认以列表视图显示时,开启文件管理器窗口,列表视图未适配窗口大小。 + adjustFileNameCol = q->width() >= headerView->width(); + showCount++; //次数比实际次数多一次,跳过1 + } + } + + if (!allowedAdjustColumnSize) { + // auto switch list mode + if (currentViewMode == DFileView::ListMode + && DFMApplication::instance()->appAttribute(DFMApplication::AA_ViewAutoCompace).toBool()) { + if (q->model()->setColumnCompact(event->size().width() < 600)) { + q->updateListHeaderViewProperty(); + q->doItemsLayout(); + } + } + } else { + doFileNameColResize(); + } +} + +void DFileViewPrivate::doFileNameColResize() +{ + Q_Q(DFileView); + + if (allowedAdjustColumnSize && headerView && adjustFileNameCol) { + int fileNameColRole = q->model()->roleToColumn(DFileSystemModel::FileDisplayNameRole); + int columnCount = headerView->count(); + int columnWidthSumOmitFileName = 0; + for (int i = 0; i < columnCount; ++i) { + if (i == fileNameColRole || headerView->isSectionHidden(i)) + continue; + columnWidthSumOmitFileName += q->columnWidth(i); + } + + int targetWidth = q->width() - columnWidthSumOmitFileName; + if (targetWidth >= headerView->minimumSectionSize()) { + headerView->resizeSection(fileNameColRole, q->width() - columnWidthSumOmitFileName); + } else { + // fix bug#39026 文件管理器列表视图的窗口拖至最窄,点击最大化,点击还原,文管窗口未自适应大小 + // 当文管窗口拖至最窄时,targetWidth的值小于headerView->minimumSectionSize()(80), + // 所以不会走上面的if,导致还原时显示的还是最大化时候的值 + headerView->resizeSection(fileNameColRole, headerView->minimumSectionSize()); + } + } +} + +void DFileViewPrivate::toggleHeaderViewSnap(bool on) +{ + adjustFileNameCol = on; + // DFMApplication::appObtuselySetting()->setValue("WindowManager", "HeaderViewSnapped", on); +} + +void DFileViewPrivate::_q_onSectionHandleDoubleClicked(int logicalIndex) +{ + Q_Q(DFileView); + + if (q->model()->state() != DFileSystemModel::Idle) + return; + + int row_count = q->model()->rowCount(); + + if (row_count < 1) { + return; + } + + QStyleOptionViewItem option = q->viewOptions(); + + option.rect.setWidth(QWIDGETSIZE_MAX); + option.rect.setHeight(q->itemSizeHint().height()); + + int column_max_width = 0; + + for (int i = 0; i < row_count; ++i) { + const QModelIndex &index = q->model()->index(i, 0); + const QList &list = q->itemDelegate()->paintGeomertys(option, index, true); + + // 第0列为文件名列,此列比较特殊,因为前面还有文件图标占用了一部分空间 + int width = 0; + + if (logicalIndex == 0) { + width = list.at(1).right() + COLUMU_PADDING / 2; + } else { + width = list.at(logicalIndex + 1).width() + COLUMU_PADDING * 2; + } + + if (width > column_max_width) { + column_max_width = width; + } + } + + for (int i = headerView->count() - 1; i >= 0; --i) { + if (headerView->isSectionHidden(i)) + continue; + + // 最后一列要多加上视图的右margin + if (i == logicalIndex) + column_max_width += LIST_MODE_RIGHT_MARGIN; + + break; + } + + headerView->resizeSection(logicalIndex, column_max_width); +} + +QModelIndexList DFileViewPrivate::selectedDraggableIndexes() const +{ + Q_Q(const DFileView); + + QModelIndexList indexes = q->selectedIndexes(); + auto isNotDragEnabled = [=](const QModelIndex &index) { + return !(q->model()->flags(index) & Qt::ItemIsDragEnabled); + }; + + indexes.erase(std::remove_if(indexes.begin(), indexes.end(), isNotDragEnabled), + indexes.end()); + + return indexes; +} + +QPixmap DFileViewPrivate::renderToPixmap(const QModelIndexList &indexes) const +{ + Q_Q(const DFileView); + + qreal scale = 1; + QWidget *window = q->window(); + if (window) { + QWindow *windowHandle = window->windowHandle(); + if (windowHandle) + scale = windowHandle->devicePixelRatio(); + } + + //将当前按住的index剔除 + QModelIndexList indexesWithoutPressed = indexes; + auto needRemove = [=](const QModelIndex &index) { + return index.row() == m_currentPressedIndex.row(); + }; + indexesWithoutPressed.erase(std::remove_if(indexesWithoutPressed.begin(), indexesWithoutPressed.end(), needRemove), + indexesWithoutPressed.end()); + + QRect pixRect(0, 0, DRAGICON_SIZE + DRAGICON_OUTLINE * 2, DRAGICON_SIZE + DRAGICON_OUTLINE * 2); + QPixmap pixmap(pixRect.size() * scale); + pixmap.setDevicePixelRatio(scale); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + QStyleOptionViewItem option = q->viewOptions(); + option.state |= QStyle::State_Selected; + option.rect = option.rect.translated(DRAGICON_OUTLINE, DRAGICON_OUTLINE); + + qreal offsetX = pixRect.width() / 2; + qreal offsetY = pixRect.height() / 2; + for (int i = qMin(DRAGICON_MAX - 1, indexesWithoutPressed.length() - 1); i >= 0; --i) { + //计算旋转角度 + qreal rotate = DRAGICON_ROTATE * (ceil((i + 1.0) / 2.0) / 2.0 + 1.0) * (i % 2 == 1 ? -1 : 1); + //设置透明度 + painter.setOpacity(1.0 - (i + 5) * DRAGICON_OPACITY); + + //旋转 + painter.translate(offsetX, offsetY); //让图片的中心作为旋转的中心 + painter.rotate(rotate); + painter.translate(-offsetX, -offsetY); //使原点复原 + + //绘制icon + q->itemDelegate()->paintDragIcon(&painter, option, indexesWithoutPressed.at(i), QSize(DRAGICON_SIZE, DRAGICON_SIZE)); + + //旋转回原角度 + painter.translate(offsetX, offsetY); + painter.rotate(-rotate); + painter.translate(-offsetX, -offsetY); + } + + //绘制当前按住的icon + painter.setOpacity(0.8); + q->itemDelegate()->paintDragIcon(&painter, option, m_currentPressedIndex, QSize(DRAGICON_SIZE, DRAGICON_SIZE)); + QSize iconSize = q->itemDelegate()->getIndexIconSize(option, m_currentPressedIndex, QSize(DRAGICON_SIZE, DRAGICON_SIZE)); + + //绘制数量提示原点,大于99个文件显示为99+ + int length = indexes.length() > DRAGICON_MAX_COUNT ? 28 : 24; //原点直径:1到2个字符直径为24,3个字符直径为28 + int x = DRAGICON_OUTLINE + (DRAGICON_SIZE + iconSize.width() - length) / 2; + int y = DRAGICON_OUTLINE + (DRAGICON_SIZE + iconSize.height() - length) / 2; + + QColor pointColor(244, 74, 74); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setOpacity(1); + painter.setPen(pointColor); + painter.setBrush(pointColor); + painter.drawEllipse(x, y, length, length); + + painter.setPen(Qt::white); + //按照设计的要求设置字体:Arial,12大小,粗体 + QFont ft("Arial"); + ft.setPixelSize(12); + ft.setBold(true); + painter.setFont(ft); + QString countStr = indexes.length() > DRAGICON_MAX_COUNT ? QString::number(DRAGICON_MAX_COUNT).append("+") : QString::number(indexes.length()); + painter.drawText(QRect(x, y, length, length), Qt::AlignCenter, countStr); + + return pixmap; +} + +#include "moc_dfileview.cpp" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfileview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfileview.h new file mode 100644 index 0000000..ab19f14 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfileview.h @@ -0,0 +1,348 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILEVIEW_H +#define DFILEVIEW_H + +#include "dfmglobal.h" +#include "durl.h" +#include "dfmbaseview.h" +#include "dfmstyleditemdelegate.h" + +#include + +#include + +class DFileSystemModel; + +QT_BEGIN_NAMESPACE +class QHeaderView; +class QTimer; +QT_END_NAMESPACE + +DWIDGET_USE_NAMESPACE +DFM_USE_NAMESPACE + +class FileController; +class DFileMenuManager; +class DFileSystemModel; +class DAbstractFileInfo; +class DStatusBar; +class FileViewHelper; +class DFileViewPrivate; + +// 修复wayland TASK-37638 添加子线程,完成“选择当前拷贝或剪贴过来的文件” +class SelectWork : public QThread +{ + Q_OBJECT +public: + explicit SelectWork(QObject *parent = nullptr); + // 设置初始数据,(未处理的文件 文件模型) + void setInitData(QList lst, DFileSystemModel *model); + // 开始线程 + void startWork(); + // 结束线程 + void stopWork(); + +signals: + // 发送该信号,选择文件模型 + void sigSetSelect(DUrl url); + +protected: + void run() override; + +private: + QList m_lstNoValid; + DFileSystemModel *m_pModel; + bool m_bStop; +}; + +class DFileView : public DListView, public DFMBaseView +{ + Q_OBJECT +public: + enum ViewMode { + IconMode = 0x01, + ListMode = 0x02, + ExtendMode = 0x04, + AllViewMode = IconMode | ListMode | ExtendMode + }; + Q_ENUM(ViewMode) + + Q_DECLARE_FLAGS(ViewModes, ViewMode) + + explicit DFileView(QWidget *parent = nullptr); + ~DFileView() override; + + DFileSystemModel *model() const; + DFMStyledItemDelegate *itemDelegate() const; + void setItemDelegate(DFMStyledItemDelegate *delegate); + DStatusBar *statusBar() const; + FileViewHelper *fileViewHelper() const; + + DUrl rootUrl() const override; + ViewState viewState() const override; + QList selectedUrls() const; + + bool isIconViewMode() const; + + int columnWidth(int column) const; + int headerViewHeight() const; + void setColumnWidth(int column, int width); + int columnCount() const; + + int rowCount() const; + + /// icon view row index count + int itemCountForRow() const; + inline int indexOfRow(const QModelIndex &index) const + { return index.row() / itemCountForRow();} + + QList columnRoleList() const; + + quint64 windowId() const; + + using DListView::edit; + + void setIconSize(const QSize &size); + + ViewMode getDefaultViewMode() const; + ViewMode viewMode() const; + + bool testViewMode(ViewModes modes, ViewMode mode) const; + + int horizontalOffset() const override; + + bool isSelected(const QModelIndex &index) const; + int selectedIndexCount() const; + QModelIndexList selectedIndexes() const override; + + QModelIndex indexAt(const QPoint &point) const override; + QRect visualRect(const QModelIndex &index) const override; + + typedef QPair RandeIndex; + typedef QList RandeIndexList; + RandeIndexList visibleIndexes(QRect rect) const; + + QSize itemSizeHint() const; + + using DListView::viewportMargins; + using DListView::updateGeometries; + + bool isDropTarget(const QModelIndex &index) const; + + QStringList nameFilters() const; + QDir::Filters filters() const; + + void setEnabledSelectionModes(const QSet &list); + QSet enabledSelectionModes() const; + + QWidget *widget() const override; + QList toolBarActionList() const override; + + // 设置已被销毁标志 + void setDestroyFlag(bool flag); + + // 设置总是在当前窗口打开子目录 + void setAlwaysOpenInCurrentWindow(bool openInCurrentWindow); + +public slots: + bool cd(const DUrl &url); + bool cdUp(); + bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event) override; + void select(const QList &list); + // 修复wayland BUG-38453 重新添加一个函数,当拷贝和剪贴过后,调用该函数选择全部文件对象 + void selectAllAfterCutOrCopy(const QList &list); + // 修复wayland TASK-37638 添加槽函数,选中文件 + void slotSetSelect(DUrl url); + inline void setViewModeToList() + { setViewMode(ListMode);} + inline void setViewModeToIcon() + { setViewMode(IconMode);} + inline void setViewModeToExtend() + { setViewMode(ExtendMode);} + void setDefaultViewMode(ViewMode mode); + void setViewMode(ViewMode mode); + void sortByRole(int role, Qt::SortOrder order); + + void setNameFilters(const QStringList &nameFilters); + void setFilters(QDir::Filters filters); + void setAdvanceSearchFilter(const QMap &formData, bool turnOn = true, bool avoidUpdateView = false); + + void clearHeardView(); + void clearSelection(); + + void setContentLabel(const QString &text); + + void setMenuActionWhitelist(const QSet &actionList); + void setMenuActionBlacklist(const QSet &actionList); + + void delayUpdateStatusBar(); + void updateStatusBar(); + void openIndexByOpenAction(const int &action, const QModelIndex &index); + + void setIconSizeBySizeIndex(const int &sizeIndex); + + bool setRootUrl(const DUrl &url) override; + //获取当前是否可以析构,判断当前是否是在draging中和mousemove中 + bool getCanDestruct() const; + +#ifdef SW_LABEL + bool checkRenamePrivilege_sw(DUrl fileUrl); +#endif + +signals: + void rootUrlChanged(const DUrl &url); + void viewModeChanged(ViewMode viewMode); + void viewStateChanged(); + //drop或者mousemove结束请求关闭当前窗口 + void requestWindowDestruct(); + + /** + * @brief fileDialogRename + * 在弹出对话框中修改重名时发送次信号 bug 63430 + */ + void fileDialogRename(); + +private slots: + void dislpayAsActionTriggered(QAction *action); + void sortByActionTriggered(QAction *action); + void openWithActionTriggered(QAction *action); + void onRowCountChanged(); + void updateModelActiveIndex(); + void handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector()); + void freshView(); + void loadViewState(const DUrl &url); + void saveViewState(); + void onSortIndicatorChanged(int logicalIndex, Qt::SortOrder order); + void onDriveOpticalChanged(const QString &path); + void reset() override; + void setRootIndex(const QModelIndex &index) override; + void onHeaderSectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex); + +protected slots: + virtual void onRootUrlDeleted(const DUrl &rootUrl); + +protected: + void wheelEvent(QWheelEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void showEvent(QShowEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void focusInEvent(QFocusEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void contextMenuEvent(QContextMenuEvent *event) override; + void dragEnterEvent(QDragEnterEvent *event) override; + void dragMoveEvent(QDragMoveEvent *event) override; + void dragLeaveEvent(QDragLeaveEvent *event) override; + void dropEvent(QDropEvent *event) override; + void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags) override; + QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override; + void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) override; + void rowsInserted(const QModelIndex &parent, int start, int end) override; + void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, + const QVector &roles = QVector()) override; + bool event(QEvent *e) override; + void updateGeometries() override; + bool eventFilter(QObject *obj, QEvent *event) override; + +#if QT_CONFIG(draganddrop) + void startDrag(Qt::DropActions supportedActions) override; +#endif + + void onShowHiddenFileChanged(); + + void initDelegate(); + void initUI(); + void initModel(); + void initConnects(); + + /** + * @brief contextMenuEventShowCheck contextMenuEvent之前执行的检查函数 + * 显示右键菜单之前执行的事件之前所执行的检查函数。 + * 该函数可以做一些特殊处理,其返回结果将用作是否执行contextMenuEvent后续执行的判断条件。 + * 可继承dfileview重载实现该函数。 + * ctrl and show url context menu process method. + * @param event 上下文菜单事件 + * @return bool + * 如果返回true,则执行contextMenuEvent事件, + * 返回false,将不会执行contextMenuEvent事件。 + * if return true, can show menu and execute contextMenuEvent method, + * return false ,can't execute contextMenuEvent method. + */ + virtual bool canShowContextMenu(QContextMenuEvent *event); + +private: + void increaseIcon(); + void decreaseIcon(); + void openIndex(const QModelIndex &index); + void keyboardSearch(const QString &search) override; + void updateHorizontalOffset(); + void switchViewMode(ViewMode mode); + void showEmptyAreaMenu(const Qt::ItemFlags &indexFlags); + void showNormalMenu(const QModelIndex &index, const Qt::ItemFlags &indexFlags); + void updateListHeaderViewProperty(); + void updateExtendHeaderViewProperty(); + void updateColumnWidth(); + void popupHeaderViewContextMenu(const QPoint &pos); + void onModelStateChanged(int state); + void updateContentLabel(); + void updateToolBarActions(QWidget *widget = nullptr, QString theme = ""); + /** + * @brief normalKeyPressEvent 一般键盘事件 + * 只允许被keyPressEvent调用,用于消除noMotify与keypadMotify之间无break时会产生警告的问题 + * @param event 键盘时间 + * @return 在keyPressEvent是否需要return + */ + bool normalKeyPressEvent(const QKeyEvent *event); + + using DListView::setOrientation; + + void refresh() override; + bool fetchDragEventUrlsFromSharedMemory(); + + /** + * @brief setTargetUrlToApp 为其他应用设置目标Url + * 仅当被拖拽行为是DFileDrag时会被调用 + * @param data mimeData + * @param url 目标Url + */ + void setTargetUrlToApp(const QMimeData *data, const DUrl &url); + + bool m_isRemovingCase = false; + QScopedPointer d_ptr; + QList m_urlsForDragEvent; + DUrl m_currentTargetUrl; //缓存当前目标Url + + // 处理选择文件的子线程对象 + SelectWork *m_pSelectWork{nullptr}; + bool m_destroyFlag = false; + + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), DFileView) + Q_PRIVATE_SLOT(d_ptr, void _q_onSectionHandleDoubleClicked(int)) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(DFileView::ViewModes) + +#endif // DFILEVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfileview_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfileview_p.h new file mode 100644 index 0000000..5812e54 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfileview_p.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef DFILEVIEWPRIVATE_H +#define DFILEVIEWPRIVATE_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "dfileview.h" +#include "interfaces/dabstractfileinfo.h" +#include "dfilesystemmodel.h" +#include "dfmheaderview.h" + +class DFMOpticalMediaWidget; +class DDiskManager; + +class DFileViewPrivate +{ +public: + explicit DFileViewPrivate(DFileView *qq) + : q_ptr(qq) {} + + int iconModeColumnCount(int itemWidth = 0) const; + QVariant fileViewStateValue(const DUrl &url, const QString &key, const QVariant &defalutValue); + void setFileViewStateValue(const DUrl &url, const QString &key, const QVariant &value); + void updateHorizontalScrollBarPosition(); + void pureResizeEvent(QResizeEvent *event); + void doFileNameColResize(); + void toggleHeaderViewSnap(bool on); + void _q_onSectionHandleDoubleClicked(int logicalIndex); + QModelIndexList selectedDraggableIndexes() const; + QPixmap renderToPixmap(const QModelIndexList &indexes) const; + void paintDragIcon(QPainter *painter, const QIcon &icon, const QRectF &rect, Qt::Alignment alignment = Qt::AlignCenter, + QIcon::Mode mode = QIcon::Normal, QIcon::State state = QIcon::Off) const; + +public: + DFileView *q_ptr; + + DFileMenuManager *fileMenuManager = nullptr; + DFMHeaderView *headerView = nullptr; + QWidget *headerViewHolder = nullptr; + DFMOpticalMediaWidget *headerOpticalDisc = nullptr; + DStatusBar *statusBar = nullptr; + + QActionGroup *displayAsActionGroup = nullptr; + QActionGroup *sortByActionGroup = nullptr; + QActionGroup *openWithActionGroup = nullptr; + + FileViewHelper *fileViewHelper = nullptr; + + QTimer *updateStatusBarTimer = nullptr; + + QScrollBar *verticalScrollBar = nullptr; + + DDiskManager *diskmgr = nullptr; + + QActionGroup *toolbarActionGroup = nullptr; + + + // 用于实现触屏滚动视图和框选文件不冲突,手指在屏幕上按下短时间内就开始移动 + // 会被认为触发滚动视图,否则为触发文件选择(时间默认为300毫秒) + QPointer updateEnableSelectionByMouseTimer; + + // 记录触摸按下事件,在mouse move事件中使用,用于判断手指移动的距离,当大于 + // QPlatformTheme::TouchDoubleTapDistance 的值时认为触发触屏滚动 + QPoint lastTouchBeginPos; + + QList columnRoles; + + DFileView::ViewMode defaultViewMode = DFileView::IconMode; + DFileView::ViewMode currentViewMode = DFileView::IconMode; + /// move cursor later selecte index when pressed key shift + QModelIndex lastCursorIndex; + + QModelIndex mouseLastPressedIndex; + + //记录当前mousePressEvent中按下的Index + QModelIndex m_currentPressedIndex; + + QItemSelection currentSelection; + + /// drag drop + QModelIndex dragMoveHoverIndex; + //析构锁,当更新updatestatusbar正在处理时,不要析构 + QMutex m_mutexUpdateStatusBar; + + /// list mode column visible + QMap columnForRoleHiddenMap; + + DUrlList preSelectionUrls; + + /// Saved before sorting + DUrlList oldSelectedUrls; + + DAnchors contentLabel = nullptr; + + DUrl oldCurrentUrl; + + /// menu actions filter + QSet menuWhitelist; + + QSet menuBlacklist; + + QSet enabledSelectionModes; + + int horizontalOffset = 0; + int firstVisibleColumn = -1; + int lastVisibleColumn = -1; + int cachedViewWidth = -1; + int touchTapDistance = -1; + int showCount = 0; //记录showEvent次数,为了在第一次时去调整列表模式的表头宽度 + DFileView::RandeIndex visibleIndexRande; + + bool allowedAdjustColumnSize = true; + bool adjustFileNameCol = false; // mac finder style half-auto col size adjustment flag. + + char justAvoidWaringOfAlignmentBoundary[2] = {0};//只是为了避免边界对其问题警告,其他地方未使用。//若有更好的办法可以替换之 + + bool isVaultDelSigConnected = false; //is vault delete signal connected. + + bool isAlwaysOpenInCurrentWindow = false; + QAtomicInteger m_isDragging = false; + QAtomicInteger m_isMouseMoveing = false; + //正在设置当前的rooturl + QAtomicInteger m_isSetRootUrl = false; + QAtomicInteger m_isMouseLeftPress = false; + Q_DECLARE_PUBLIC(DFileView) +}; + +#endif // DFILEVIEWPRIVATE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmactionbutton.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmactionbutton.cpp new file mode 100644 index 0000000..009b022 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmactionbutton.cpp @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2017 Deepin Technology Co., Ltd. + * + * 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. + **/ +#include "dfmactionbutton.h" + +#include +#include + +DFMActionButton::DFMActionButton(QWidget *parent) + : QToolButton(parent) +{ + setMouseTracking(true); +} + +void DFMActionButton::setAction(QAction *action) +{ + auto onActionChanged = [this, action] { + setVisible(action->isVisible()); + setEnabled(action->isEnabled()); + setCheckable(action->isCheckable()); + setChecked(action->isChecked()); + setIcon(action->icon()); + }; + + onActionChanged(); + connect(action, &QAction::changed, this, onActionChanged); + connect(this, &DFMActionButton::clicked, action, &QAction::trigger); + connect(action, &QAction::triggered, this, &DFMActionButton::setChecked); + + setDefaultAction(action); +} + +QAction *DFMActionButton::action() const +{ + return actions().value(0); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmactionbutton.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmactionbutton.h new file mode 100644 index 0000000..c851787 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmactionbutton.h @@ -0,0 +1,26 @@ +/** + * Copyright (C) 2017 Deepin Technology Co., Ltd. + * + * 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. + **/ +#ifndef DFMACTIONBUTTON_H +#define DFMACTIONBUTTON_H + +#include + + +class DFMActionButton : public QToolButton +{ + Q_OBJECT + +public: + explicit DFMActionButton(QWidget *parent = nullptr); + + void setAction(QAction *action); + QAction *action() const; +}; + +#endif // DFMACTIONBUTTON_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmaddressbar.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmaddressbar.cpp new file mode 100644 index 0000000..cac880c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmaddressbar.cpp @@ -0,0 +1,777 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ +#include "dfmaddressbar.h" +#include "dfmcrumbmanager.h" +#include "dfmcrumbfactory.h" +#include "dfmcrumbbar.h" + +#include "views/dcompleterlistview.h" +#include "interfaces/dfmcrumbinterface.h" +#include "controllers/searchhistroymanager.h" +#include "controllers/vaultcontroller.h" +#include "accessibility/ac-lib-file-manager.h" + +#include "singleton.h" +#include "dfileservices.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE + +DCompleterStyledItemDelegate::DCompleterStyledItemDelegate(QObject *parent) + : QStyledItemDelegate(parent) +{ + +} + +void DCompleterStyledItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + // prepare + QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) + ? QPalette::Normal : QPalette::Disabled; + if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) { + cg = QPalette::Inactive; + } + + // draw background + if (option.showDecorationSelected && (option.state & (QStyle::State_Selected | QStyle::State_MouseOver))) { + painter->fillRect(option.rect, option.palette.brush(cg, QPalette::Highlight)); + } + + // draw text + if (option.state & (QStyle::State_Selected | QStyle::State_MouseOver)) { + painter->setPen(option.palette.color(cg, QPalette::HighlightedText)); + } else { + painter->setPen(option.palette.color(cg, QPalette::Text)); + } + + painter->setFont(option.font); + painter->drawText(option.rect.adjusted(31, 0, 0, 0), Qt::AlignVCenter, index.data(Qt::DisplayRole).toString()); +} + +QSize DCompleterStyledItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QSize s = QStyledItemDelegate::sizeHint(option, index); + s.setHeight(24); + + return s; +} + +/*! + * \class DFMAddressBar + * \inmodule dde-file-manager-lib + * + * \brief DFMAddressBar is the address bar of the file manager + * + * The address bar is also the search bar, it can also handle search job. The address + * bar is managed by the crumb bar. + * + * \sa DFMCrumbBar, DFMCrumbInterface + */ + +DFMAddressBar::DFMAddressBar(DFMCrumbBar *parent) + : QLineEdit(parent) +{ + setObjectName(AC_COMPUTER_TITLE_BAR_ADRESS); + setObjectName(AC_COMPUTER_TITLE_BAR_ADRESS); + + initUI(); + initConnections(); + initData(); +} + +QCompleter *DFMAddressBar::completer() const +{ + return urlCompleter; +} + +QString DFMAddressBar::placeholderText() const +{ + return m_placeholderText; +} + +/*! + * \brief Set current url \a path + * + * \param path Current url + */ +void DFMAddressBar::setCurrentUrl(const DUrl &path) +{ + QString text = path.isLocalFile() ? path.toLocalFile() : path.toString(); + + currentUrl = path; + //m_disableCompletion = true; + this->setText(text); + this->setSelection(0, text.length()); +} + +void DFMAddressBar::setCompleter(QCompleter *c) +{ + if (urlCompleter) { + urlCompleter->disconnect(); + } + + urlCompleter = c; + + if (!urlCompleter) { + return; + } + + urlCompleter->setModel(&completerModel); + urlCompleter->setPopup(completerView); + urlCompleter->setCompletionMode(QCompleter::PopupCompletion); + urlCompleter->setCaseSensitivity(Qt::CaseSensitive); + urlCompleter->setMaxVisibleItems(10); + connect(urlCompleter, SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString))); + connect(urlCompleter, SIGNAL(highlighted(QString)), this, SLOT(onCompletionHighlighted(QString))); + connect(urlCompleter->completionModel(), &QAbstractItemModel::modelReset, + this, &DFMAddressBar::onCompletionModelCountChanged); + + completerView->setItemDelegate(&styledItemDelegate); + //解决bug19609文件管理器中,文件夹搜索功能中输入法在输入过程中忽然失效然后恢复,设置这个属性listview就可以拥有地址兰的输入法 + completerView->setAttribute(Qt::WA_InputMethodEnabled); + +} + +void DFMAddressBar::setPlaceholderText(const QString &text) +{ + // Since the placeholder text provided by QLineEdit can not have separate alignment + // alone with the user entered edit text. + m_placeholderText = text; +} + +void DFMAddressBar::playAnimation() +{ + if (animationSpinner) + return; + + // Right animation widget + animationSpinner = new DSpinner(this); + animationSpinner->setAttribute(Qt::WA_TransparentForMouseEvents); + animationSpinner->setFocusPolicy(Qt::NoFocus); + animationSpinner->setFixedSize(height() - 8, height() - 8); + + DAnchorsBase::setAnchor(animationSpinner, Qt::AnchorVerticalCenter, this, Qt::AnchorVerticalCenter); + DAnchorsBase::setAnchor(animationSpinner, Qt::AnchorRight, this, Qt::AnchorRight); + DAnchorsBase::getAnchorBaseByWidget(animationSpinner)->setRightMargin(height() + 8); + + animationSpinner->show(); + animationSpinner->start(); +} + +void DFMAddressBar::stopAnimation() +{ + pauseButton->setVisible(false); + if (!animationSpinner) + return; + + //fix 64394 输入框状态组件没有stop会一直start + animationSpinner->stop(); + animationSpinner->close(); + update(); + animationSpinner->deleteLater(); + animationSpinner = nullptr; +} + +void DFMAddressBar::hide() +{ + QLineEdit::hide(); + completerView->hideMe(); + // fix bug 69679 + stopAnimation(); +} + +void DFMAddressBar::focusInEvent(QFocusEvent *e) +{ + if (urlCompleter) { + urlCompleter->setWidget(this); + } + + return QLineEdit::focusInEvent(e); +} + +void DFMAddressBar::focusOutEvent(QFocusEvent *e) +{ + // blumia: Sometimes completion will trigger weird Qt::ActiveWindowFocusReason event, + // right click context menu will trigger Qt::PopupFocusReason event. It will + // cause focusOutEvent. So we simply ignore it here. + // blumia: 2019/12/01: seems now based on current 5.11.3.2+c1-1+deepin version of Qt, + // completion will no longer trigger Qt::ActiveWindowFocusReason reason focus + // out event, so we comment out this case for now and see if it still happens. + // fix bug#38455 文管启动后第一次点击搜索,再点击筛选按钮,会导致搜索框隐藏 + // 第一次点击筛选按钮,会发出Qt::OtherFocusReason信号导致搜索框隐藏,所以将其屏蔽 + if (/*e->reason() == Qt::ActiveWindowFocusReason || */ e->reason() == Qt::PopupFocusReason || e->reason() == Qt::OtherFocusReason) { + e->accept(); + setFocus(); + return; + } + completerView->hideMe(); + emit lostFocus(); + + return QLineEdit::focusOutEvent(e); +} + +void DFMAddressBar::keyPressEvent(QKeyEvent *e) +{ + isKeyPressed = true; + QTimer::singleShot(100, this, [ = ]() { //设定100ms,若有问题可视情况改变 + isKeyPressed = false; + }); + lastPreviousKey = lastPressedKey; + lastPressedKey = e->key(); + switch (e->key()) { + case Qt::Key_Escape: + emit escKeyPressed(); + completerView->hideMe(); + e->accept(); + return; + default: + break; + } + + if (urlCompleter && urlCompleter->popup()->isVisible()) { + if (isHistoryInCompleterModel && e->modifiers() == Qt::ShiftModifier && e->key() == Qt::Key_Delete) { + QString completeResult = completerView->currentIndex().data().toString(); + bool ret = Singleton::instance()->removeSearchHistory(completeResult); + if (ret) { + historyList.clear(); + historyList.append(Singleton::instance()->toStringList()); + completerModel.setStringList(historyList); + } + } + // The following keys are forwarded by the completer to the widget + switch (e->key()) { + case Qt::Key_Backtab: + e->ignore(); + return; + case Qt::Key_Enter: + case Qt::Key_Return: + e->accept(); + completerView->hideMe(); + emit returnPressed(); + return; + case Qt::Key_Tab: + if (completer()->completionCount() > 0) { + if (selectedText().isEmpty()) { + QString completeResult = urlCompleter->completionModel()->index(0, 0).data().toString(); + insertCompletion(completeResult); + } + if (DUrl::fromUserInput(text()).isLocalFile()) { + setText(text() + '/'); + emit textEdited(text()); + } + } + e->accept(); + return; + //解决bug19609文件管理器中,文件夹搜索功能中输入法在输入过程中忽然失效然后恢复 + case Qt::Key_Up: + case Qt::Key_Down: + completerView->keyPressEvent(e); + break; + default: + break; + } + setFocus(); + } else { + // If no compiler + switch (e->key()) { + case Qt::Key_Tab: + e->accept(); + return; + case Qt::Key_Enter: + case Qt::Key_Return: + emit returnPressed(); + e->accept(); + return; + default: + break; + } + } + + return QLineEdit::keyPressEvent(e); +} + +void DFMAddressBar::paintEvent(QPaintEvent *e) +{ + QLineEdit::paintEvent(e); + + // addressbar animation + QPainter painter(this); + + // check if we should draw placeholder text + if (text().isEmpty()) { + QPen oldpen = painter.pen(); + QColor phColor = palette().text().color(); + const Qt::Alignment alignPhText = QStyle::visualAlignment(Qt::LeftToRight, QFlag(Qt::AlignCenter)); + + phColor.setAlpha(128); + painter.setPen(phColor); + + painter.drawText(rect(), alignPhText, placeholderText()); + + painter.setPen(oldpen); + } + + // Draw growing animation + if (animation && animation->state() != QAbstractAnimation::Stopped) { + + QIcon icon = QIcon::fromTheme("dfm_addressbar_glowing"); + if (icon.availableSizes().isEmpty()) + return; + const QSize size = icon.availableSizes().first(); + QPixmap glowingImg = icon.pixmap(size); + float curValue = animation->currentValue().toFloat(); + float xPos = (this->width() + glowingImg.width()) * curValue - glowingImg.width(); + + painter.drawPixmap(xPos, 0, glowingImg); + } +} + +void DFMAddressBar::showEvent(QShowEvent *event) +{ + timer.start(); + updateIndicatorIcon(); + + return QLineEdit::showEvent(event); +} +//解决bug19609文件管理器中,文件夹搜索功能中输入法在输入过程中忽然失效然后恢复 +void DFMAddressBar::inputMethodEvent(QInputMethodEvent *e) +{ + if (hasSelectedText()) { + // fix bug#31692 搜索框输入中文后,全选已输入的,再次输入未覆盖之前的内容 + int pos = selectPosStart; + setText(lastEditedString.remove(selectPosStart, selectLength)); + // 设置光标到修改处 + setCursorPosition(pos); + } + QLineEdit::inputMethodEvent(e); +} + +void DFMAddressBar::enterEvent(QEvent *e) +{ + if (indicatorType == Search && animationSpinner && animationSpinner->isPlaying()) { + animationSpinner->hide(); + pauseButton->setVisible(true); + } + + QLineEdit::enterEvent(e); +} + +void DFMAddressBar::leaveEvent(QEvent *e) +{ + if (indicatorType == Search && animationSpinner && animationSpinner->isPlaying()) { + pauseButton->setVisible(false); + animationSpinner->show(); + } + + QLineEdit::leaveEvent(e); +} + +void DFMAddressBar::initUI() +{ + // pause button + pauseButton = new DIconButton(this); + pauseButton->setIcon(QIcon::fromTheme("dfm_search_pause")); + pauseButton->setFocusPolicy(Qt::NoFocus); + pauseButton->setCursor({Qt::ArrowCursor}); + pauseButton->setFixedSize(24, 24); + pauseButton->setIconSize({24, 24}); + pauseButton->setFlat(true); + pauseButton->setVisible(false); + + DAnchorsBase::setAnchor(pauseButton, Qt::AnchorVerticalCenter, this, Qt::AnchorVerticalCenter); + DAnchorsBase::setAnchor(pauseButton, Qt::AnchorRight, this, Qt::AnchorRight); + DAnchorsBase::getAnchorBaseByWidget(pauseButton)->setRightMargin(height() + 15); + + // Left indicator (clickable! did u know that?) + indicator = new QAction(this); + addAction(indicator, QLineEdit::LeadingPosition); + + // Clear text button + setClearButtonEnabled(true); + + // Completer List + completerView = new DCompleterListView(this); + + // Animation + timer.setInterval(200); // animation delay + timer.setSingleShot(true); + animation = new QVariantAnimation(this); + animation->setDuration(616); + animation->setEasingCurve(QEasingCurve::OutQuad); + animation->setStartValue(QVariant(1.0f)); + animation->setEndValue(QVariant(0.0f)); + + connect(animation, &QVariantAnimation::valueChanged, + this, static_cast(&DFMAddressBar::update)); + + // Other misc.. + //setFixedHeight(24); + setObjectName("DSearchBar"); + setMinimumWidth(1); + setAlignment(Qt::AlignHCenter); + setAlignment(Qt::AlignLeft); + setPlaceholderText(QCoreApplication::translate("DFMAddressBar", "Search or enter address")); + + setFocusPolicy(Qt::ClickFocus); +} + +void DFMAddressBar::initConnections() +{ + connect(indicator, &QAction::triggered, this, [this]() { + emit returnPressed(); + }); + connect(this, &DFMAddressBar::returnPressed, this, [this]() { + if (text().isEmpty()) { + return; + } + + //! 如果为保险箱路径则进行路径转换 + QString str = VaultController::toInternalPath(text()); + + if (!DUrl::fromUserInput(str).isLocalFile()) { + if (!historyList.contains(str)) { + historyList.append(str); + Singleton::instance()->writeIntoSearchHistory(str); + } + } + }); + connect(this, &DFMAddressBar::textEdited, this, &DFMAddressBar::onTextEdited); + + QAction *clear_action = findChild("_q_qlineeditclearaction"); + + if (clear_action) { + connect(clear_action, &QAction::triggered, this, &DFMAddressBar::clearButtonPressed); + } + + // animation delay timer + connect(&timer, &QTimer::timeout, animation, [this]() { + animation->start(); + }); + + // fix bug#31692 搜索框输入中文后,全选已输入的,再次输入未覆盖之前的内容 + // 选中内容时,记录光标开始位置以及选中的长度 + connect(this, &DFMAddressBar::selectionChanged, this, [this] { + int posStart = selectionStart(); + int posEnd = selectionEnd(); + selectPosStart = posStart < posEnd ? posStart : posEnd; + selectLength = selectionLength(); + }); + + connect(pauseButton, &DIconButton::clicked, this, &DFMAddressBar::pauseButtonClicked); +} + +void DFMAddressBar::initData() +{ + // Completer + urlCompleter = new QCompleter(this); + this->setCompleter(urlCompleter); + + // History + historyList.clear(); + historyList.append(Singleton::instance()->toStringList()); +} + +/*! + * \brief Set the indicator type of address bar. + * \param type Indicator type + * + * This will also update the indicator icon's pixmap. + * \sa updateIndicatorIcon + */ +void DFMAddressBar::setIndicator(DFMAddressBar::IndicatorType type) +{ + if (indicatorType != type) { + clearCompleterModel(); + } + indicatorType = type; + updateIndicatorIcon(); +} + +/*! + * \brief Update the indicator icon via the indicatorType value. + * + * \sa setIndicator + */ +void DFMAddressBar::updateIndicatorIcon() +{ + QIcon indicatorIcon; + QString scope = indicatorType == IndicatorType::Search ? "search" : "go-right"; + indicatorIcon = QIcon::fromTheme(scope); + indicator->setIcon(indicatorIcon); +} + +/*! + * \brief Do complete by calling QCompleter::complete() + * + * Fake inline completion means auto select the only matched completion when + * there are only one matched item avaliable. + */ +void DFMAddressBar::doComplete() +{ + if (completerView->isHidden()) { + completer()->complete(rect().adjusted(0, 5, 0, 5)); + } else { + urlCompleter->metaObject()->invokeMethod(urlCompleter, "_q_autoResizePopup"); + } + if (completer()->completionCount() == 1 + && lastPressedKey != Qt::Key_Backspace + && lastPressedKey != Qt::Key_Delete + && isKeyPressed //判断是否按键按下,时间设定的时100ms + && !(lastPressedKey == Qt::Key_X && lastPreviousKey == Qt::Key_Control) //键盘剪切事件 + && cursorPosition() == text().length()) { + completerView->setCurrentIndex(urlCompleter->completionModel()->index(0, 0)); + } + completerView->showMe(); + completerView->activateWindow(); + + return; +} + +void DFMAddressBar::clearCompleterModel() +{ + isHistoryInCompleterModel = false; + completerModel.setStringList(QStringList()); +} + +/*! + * \brief Update completion prefix and start completion transmission. + * \param text User entered text in the address bar. + * + * Will analysis and set the completion prefix, + * Will also start a new completion when we should. + */ +void DFMAddressBar::updateCompletionState(const QString &text) +{ + int slashIndex = text.lastIndexOf('/'); + bool hasSlash = (slashIndex != -1); + // 修复bug-62112 对保险箱虚拟路径特殊判断,将保险箱虚拟路径转化为本地路径 + QString strLocalPath(text); + if (strLocalPath.startsWith(DFMVAULT_ROOT)) { + strLocalPath = VaultController::virtualPathToLocalPath(hasSlash ? strLocalPath.left(slashIndex + 1) : strLocalPath); + } else { + strLocalPath = hasSlash ? strLocalPath.left(slashIndex + 1) : strLocalPath; + } + const DUrl &url = DUrl::fromUserInput(strLocalPath, false); + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, url); + + // Check if the entered text is a string to search or a url to complete. + if (hasSlash && url.isValid() && !url.scheme().isEmpty()) { + // Update Icon + setIndicator(IndicatorType::JumpTo); + + // Check if (now is parent) url exist. + if (url.isValid() && info && !info->exists()) { + return; + } + + // Check if we should start a new completion transmission. + if (!isHistoryInCompleterModel && (this->completerBaseString == text.left(slashIndex + 1) + || DUrl::fromUserInput(this->completerBaseString) == DUrl::fromUserInput(text.left(slashIndex + 1)))) { + urlCompleter->setCompletionPrefix(text.mid(slashIndex + 1)); // set completion prefix first + onCompletionModelCountChanged(); // will call complete() + return; + } + + // Set Base String + this->completerBaseString = text.left(slashIndex + 1); + + // 修复bug-62110 修复bug-62112 设置成保险箱路径虚拟路径根目录 + if (this->completerBaseString == (DFMVAULT_SCHEME + QString(":/"))) + this->completerBaseString = DFMVAULT_ROOT; + + // start request + // 由于下方urlCompleter->setCompletionPrefix会触发onCompletionModelCountChanged接口 + // 因此在这之前需要将completerModel清空,否则会使用上一次model中的数据 + clearCompleterModel(); + + // set completion prefix. + urlCompleter->setCompletionPrefix(text.mid(slashIndex + 1)); + + // URL completion. + if (!crumbController || !crumbController->supportedUrl(url)) { + if (crumbController) { + crumbController->cancelCompletionListTransmission(); + crumbController->disconnect(); + crumbController->deleteLater(); + } + DFMCrumbBar *crumbBar = qobject_cast(this->parent()); + Q_CHECK_PTR(crumbBar); + crumbController = DFMCrumbManager::instance()->createControllerByUrl(url, crumbBar); + // Still not found? Then nothing here... + if (!crumbController) { + clearCompleterModel(); + qDebug() << "Unsupported url / scheme for completion: " << url; + return; + } + crumbController->setParent(this); + // connections + connect(crumbController, &DFMCrumbInterface::completionFound, this, [this](const QStringList & list) { + // append list to completion list. + appendToCompleterModel(list); + }); + connect(crumbController, &DFMCrumbInterface::completionListTransmissionCompleted, this, [this]() { + if (urlCompleter->completionCount() > 0) { + if (urlCompleter->popup()->isHidden()) + doComplete(); + } else { + completerView->hideMe(); + setFocus(); // Hide will cause lost focus (weird..), so setFocus() here. + } + }); + } + + //fix 33750 在匹配到smb:/,就创建url地址smb:///,去拉取url的目录,目前不知道什么原因造成gio mount smb:///失败就会出现提示框 + if (text.endsWith("smb:/")) { + return; + } + crumbController->requestCompletionList(url); + } else { + // set completion prefix. + urlCompleter->setCompletionPrefix(text); + + // Update Icon + setIndicator(IndicatorType::Search); + + // Check if we already loaded history list in model + if (isHistoryInCompleterModel) { + return; + } + + // Set Base String + this->completerBaseString = ""; + + // History completion. + isHistoryInCompleterModel = true; + // 修复bug-62117 搜索补全中不显示保险箱全路径 + QStringList::iterator itr = historyList.begin(); + while (itr != historyList.end()) { + if (VaultController::isVaultFile(*itr)) { + (*itr) = VaultController::toExternalPath(*itr); + if (VaultController::isVaultFile(*itr)) { + itr = historyList.erase(itr); + continue; + } + } + ++itr; + } + completerModel.setStringList(historyList); + } + + return; +} + +void DFMAddressBar::appendToCompleterModel(const QStringList &stringList) +{ + for (const QString &str : stringList) { + //防止出现空的补全提示 + if (str.isEmpty()) + continue; + + if (completerModel.insertRow(completerModel.rowCount())) { + QModelIndex index = completerModel.index(completerModel.rowCount() - 1, 0); + completerModel.setData(index, str); + } else { + qWarning("Failed to append some data to completerModel."); + } + } +} + +void DFMAddressBar::insertCompletion(const QString &completion) +{ + if (urlCompleter->widget() != this) { + return; + } + + this->setText(completerBaseString + completion); +} + +void DFMAddressBar::onCompletionHighlighted(const QString &highlightedCompletion) +{ + int completionPrefixLen = urlCompleter->completionPrefix().length(); + int selectBeginPos = highlightedCompletion.length() - completionPrefixLen; + setText(completerBaseString + highlightedCompletion); + setSelection(text().length() - selectBeginPos, text().length()); +} + +void DFMAddressBar::onCompletionModelCountChanged() +{ + if (completer()->completionCount() <= 0) { + completerView->hideMe(); + setFocus(); + return; + } + + doComplete(); +} + +void DFMAddressBar::onTextEdited(const QString &text) +{ + lastEditedString = text; + if (text.isEmpty()) { + urlCompleter->popup()->hide(); + completerBaseString = ""; + setIndicator(IndicatorType::Search); + return; + } + + // Stop the animation if user start editing text + if (timer.isActive()) { + timer.stop(); + } + + // blumia: Assume address is: /aa/bbbb/cc , completion prefix should be "cc", + // completerBaseString should be "/aa/bbbb/" + updateCompletionState(text); +} + +bool DFMAddressBar::event(QEvent *e) +{ + // blumia: When window lost focus and then get activated, we should hide + // addressbar if it's visiable. + if (e->type() == QEvent::WindowActivate) { + if (!hasFocus() && isVisible()) { + Q_EMIT lostFocus(); + } + } + + if (e->type() == QEvent::KeyPress) { + keyPressEvent(static_cast(e)); + return true; + } + + return QLineEdit::event(e); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmaddressbar.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmaddressbar.h new file mode 100644 index 0000000..c28cb18 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmaddressbar.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ +#ifndef DFMADDRESSBAR_H +#define DFMADDRESSBAR_H + +#include "dfmglobal.h" + +#include +#include +#include +#include +#include +#include + +#include + +DWIDGET_BEGIN_NAMESPACE +class DSpinner; +class DIconButton; +DWIDGET_END_NAMESPACE + +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE + +class DCompleterStyledItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit DCompleterStyledItemDelegate(QObject *parent = nullptr); + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; +}; + +class DFMCrumbBar; +class DFMCrumbInterface; +class DCompleterListView; +class DFMAddressBar : public QLineEdit +{ + Q_OBJECT +public: + enum IndicatorType { + Search, + JumpTo + }; + + explicit DFMAddressBar(DFMCrumbBar *parent = nullptr); + + QCompleter *completer() const; + QString placeholderText() const; + + void setCurrentUrl(const DUrl &path); + void setCompleter(QCompleter *c); + void setPlaceholderText(const QString &text); + + void playAnimation(); + void stopAnimation(); + +public slots: + void hide(); + +signals: + void lostFocus(); + void clearButtonPressed(); + void escKeyPressed(); + void pauseButtonClicked(); + +protected: + void focusInEvent(QFocusEvent *e) override; + void focusOutEvent(QFocusEvent *e) override; + void keyPressEvent(QKeyEvent *e) override; + void paintEvent(QPaintEvent *e) override; + void showEvent(QShowEvent *event) override; + void inputMethodEvent(QInputMethodEvent *e) override; + void enterEvent(QEvent *e) override; + void leaveEvent(QEvent *e) override; + +private: + void initUI(); + void initConnections(); + void initData(); + void setIndicator(enum IndicatorType type); + void updateIndicatorIcon(); + void doComplete(); + void clearCompleterModel(); + void updateCompletionState(const QString &text); + void appendToCompleterModel(const QStringList &stringList); + + int lastPressedKey = Qt::Key_D; // just an init value + int lastPreviousKey = Qt::Key_Control; //记录上前一个按钮 + bool isHistoryInCompleterModel = false; + QTimer timer; + DUrl currentUrl = DUrl(); + QString m_placeholderText = QString(); + QString completerBaseString = QString(); + QString lastEditedString = QString(); + // inputMethodEvent中获取不到选中的内容,故缓存光标开始位置以及选中长度 + int selectPosStart = 0; + int selectLength = 0; + QStringListModel completerModel; + DCompleterListView *completerView; + QStringList historyList; + QAction *indicator = nullptr; + QCompleter *urlCompleter = nullptr; + QVariantAnimation *animation = nullptr; + DFMCrumbInterface *crumbController = nullptr; // Scheme completion support + DCompleterStyledItemDelegate styledItemDelegate; + enum IndicatorType indicatorType = IndicatorType::Search; + + DSpinner *animationSpinner = nullptr; + bool isKeyPressed = false; + + DIconButton *pauseButton = nullptr; + +private slots: + void insertCompletion(const QString &completion); + void onCompletionHighlighted(const QString &highlightedCompletion); + void onCompletionModelCountChanged(); + void onTextEdited(const QString &text); + + bool event(QEvent *e) override; +}; + +DFM_END_NAMESPACE + +#endif // DFMADDRESSBAR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmadvancesearchbar.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmadvancesearchbar.cpp new file mode 100644 index 0000000..139af35 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmadvancesearchbar.cpp @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ + +#include "dfmadvancesearchbar.h" +#include "dfilesystemmodel.h" + +#include +#include +#include +#include +#include +#include + +#include + +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE + +DFMAdvanceSearchBar::DFMAdvanceSearchBar(QWidget *parent) + : DBoxWidget(QBoxLayout::LeftToRight, parent) +{ + initUI(); + initConnection(); +} + +void DFMAdvanceSearchBar::resetForm(bool updateView) +{ + allowUpdateView = updateView; + for (int i = 0; i < LABEL_COUNT; i++) { + asbCombos[i]->setCurrentIndex(0); + } + allowUpdateView = true; +} + +void DFMAdvanceSearchBar::updateFilterValue(const FileFilter *filter) +{ + // 防止触发信号 + blockSignals(true); + if (filter) { + // 搜索范围 + const auto &searchRange = filter->filterRule[SEARCH_RANGE]; + asbCombos[SEARCH_RANGE]->setCurrentIndex(searchRange.toBool() ? 0 : 1); + + // 文件类型 + const auto &fileType = filter->filterRule[FILE_TYPE]; + if (fileType.isValid()) { + asbCombos[FILE_TYPE]->setCurrentText(fileType.toString()); + } else { + asbCombos[FILE_TYPE]->setCurrentIndex(0); + } + + // 文件大小 + const auto &sizeRange = filter->filterRule[SIZE_RANGE]; + if (sizeRange.isValid() && filter->f_comboValid[SIZE_RANGE]) { + asbCombos[SIZE_RANGE]->setCurrentIndex(sizeRangeMap[filter->f_sizeRange]); + } else { + asbCombos[SIZE_RANGE]->setCurrentIndex(0); + } + + // 修改时间 + const auto &dateRange = filter->filterRule[DATE_RANGE]; + if (dateRange.isValid()) { + asbCombos[DATE_RANGE]->setCurrentIndex(dateRangeMap[dateRange]); + } else { + asbCombos[DATE_RANGE]->setCurrentIndex(0); + } + + // 访问时间 + const auto &accessDateRange = filter->filterRule[ACCESS_DATE_RANGE]; + if (accessDateRange.isValid()) { + asbCombos[ACCESS_DATE_RANGE]->setCurrentIndex(dateRangeMap[accessDateRange]); + } else { + asbCombos[ACCESS_DATE_RANGE]->setCurrentIndex(0); + } + + // 创建时间 + const auto &createDateRange = filter->filterRule[CREATE_DATE_RANGE]; + if (createDateRange.isValid()) { + asbCombos[CREATE_DATE_RANGE]->setCurrentIndex(dateRangeMap[createDateRange]); + } else { + asbCombos[CREATE_DATE_RANGE]->setCurrentIndex(0); + } + + } else { + resetForm(); + } + blockSignals(false); +} + +void DFMAdvanceSearchBar::onOptionChanged() +{ + QMap formData; + + bool searchRangeChanged = formData[SEARCH_RANGE] != asbCombos[SEARCH_RANGE]->currentData(); + + formData[SEARCH_RANGE] = asbCombos[SEARCH_RANGE]->currentData(); + formData[FILE_TYPE] = asbCombos[FILE_TYPE]->currentData(); + formData[SIZE_RANGE] = asbCombos[SIZE_RANGE]->currentData(); + formData[DATE_RANGE] = asbCombos[DATE_RANGE]->currentData(); + formData[ACCESS_DATE_RANGE] = asbCombos[ACCESS_DATE_RANGE]->currentData(); + formData[CREATE_DATE_RANGE] = asbCombos[CREATE_DATE_RANGE]->currentData(); + + bool triggerSearch = false; + + if (needSearchAgain) { + needSearchAgain = false; + triggerSearch = true; + } + + if (searchRangeChanged) { + triggerSearch = true; + } + + formData[TRIGGER_SEARCH] = QVariant::fromValue(triggerSearch); + + emit optionChanged(formData, allowUpdateView); +} + +void DFMAdvanceSearchBar::onResetButtonPressed() +{ + resetForm(); +} + +void DFMAdvanceSearchBar::hideEvent(QHideEvent *) +{ + needSearchAgain = true; +} + +void DFMAdvanceSearchBar::initUI() +{ + mainLayout = this->layout(); + + const int LEFT_COMBO_MIN_WIDTH = 140; + const int RIGHT_COMBO_MIN_WIDTH = 100; + + QGridLayout *formLayout = new QGridLayout; + + auto createLabelCombo = [ = ](int index, const QString & labelText) { + asbLabels[index] = new QLabel(labelText); + asbCombos[index] = new QComboBox(this); +#ifndef __arm__ + /*针对ARM部分机器上搜索高级选项下拉框不能使用做特殊处理*/ + asbCombos[index]->setFocusPolicy(Qt::NoFocus); +#endif + asbLabels[index]->setBuddy(asbCombos[index]); + }; + + createLabelCombo(SEARCH_RANGE, qApp->translate("DFMAdvanceSearchBar", "Search:")); + createLabelCombo(FILE_TYPE, qApp->translate("DFMAdvanceSearchBar", "File Type:")); + createLabelCombo(SIZE_RANGE, qApp->translate("DFMAdvanceSearchBar", "File Size:")); + createLabelCombo(DATE_RANGE, qApp->translate("DFMAdvanceSearchBar", "Time Modified:")); + createLabelCombo(ACCESS_DATE_RANGE, qApp->translate("DFMAdvanceSearchBar", "Time Accessed:")); + createLabelCombo(CREATE_DATE_RANGE, qApp->translate("DFMAdvanceSearchBar", "Time Created:")); + + resetBtn = new DCommandLinkButton(qApp->translate("DFMAdvanceSearchBar", "Reset"), this); +#ifndef __arm__ + /*针对ARM部分机器上搜索高级选项下拉框不能使用做特殊处理*/ + resetBtn->setFocusPolicy(Qt::NoFocus); +#endif + + int leftLebelWidth = 80; // qMin(asbLabels[SEARCH_RANGE]->width(), asbLabels[SIZE_RANGE]->width()) + int rightLebelWidth = 90; + asbLabels[SEARCH_RANGE]->setMinimumWidth(leftLebelWidth); + asbCombos[SEARCH_RANGE]->setMinimumWidth(LEFT_COMBO_MIN_WIDTH); + asbLabels[SIZE_RANGE]->setMinimumWidth(leftLebelWidth); + asbCombos[SIZE_RANGE]->setMinimumWidth(LEFT_COMBO_MIN_WIDTH); + asbLabels[FILE_TYPE]->setMinimumWidth(rightLebelWidth); + asbCombos[FILE_TYPE]->setMinimumWidth(RIGHT_COMBO_MIN_WIDTH); + asbLabels[DATE_RANGE]->setMinimumWidth(rightLebelWidth); + asbCombos[DATE_RANGE]->setMinimumWidth(RIGHT_COMBO_MIN_WIDTH); + asbCombos[ACCESS_DATE_RANGE]->setMinimumWidth(RIGHT_COMBO_MIN_WIDTH); + asbCombos[CREATE_DATE_RANGE]->setMinimumWidth(RIGHT_COMBO_MIN_WIDTH); + + asbCombos[SEARCH_RANGE]->addItem(qApp->translate("DFMAdvanceSearchBar", "All subdirectories"), QVariant::fromValue(true)); + asbCombos[SEARCH_RANGE]->addItem(qApp->translate("DFMAdvanceSearchBar", "Current directory"), QVariant::fromValue(false)); + + auto addItemToFileTypeCombo = [this](const QString & typeStr) { + asbCombos[FILE_TYPE]->addItem(typeStr, QVariant::fromValue(typeStr)); + }; + + asbCombos[FILE_TYPE]->addItem("--", QVariant()); + addItemToFileTypeCombo(qApp->translate("MimeTypeDisplayManager", "Application")); + addItemToFileTypeCombo(qApp->translate("MimeTypeDisplayManager", "Video")); + addItemToFileTypeCombo(qApp->translate("MimeTypeDisplayManager", "Audio")); + addItemToFileTypeCombo(qApp->translate("MimeTypeDisplayManager", "Image")); + addItemToFileTypeCombo(qApp->translate("MimeTypeDisplayManager", "Archive")); + addItemToFileTypeCombo(qApp->translate("MimeTypeDisplayManager", "Text")); + addItemToFileTypeCombo(qApp->translate("MimeTypeDisplayManager", "Executable")); + addItemToFileTypeCombo(qApp->translate("MimeTypeDisplayManager", "Backup file")); + + sizeRangeMap[QPair(0, 100)] = 1; + sizeRangeMap[QPair(100, 1024)] = 2; + sizeRangeMap[QPair(1024, 10 * 1024)] = 3; + sizeRangeMap[QPair(10 * 1024, 100 * 1024)] = 4; + sizeRangeMap[QPair(100 * 1024, 1 << 20)] = 5; + sizeRangeMap[QPair(1 << 20, 1 << 30)] = 6; + + asbCombos[SIZE_RANGE]->addItem("--", QVariant()); + asbCombos[SIZE_RANGE]->addItem(qApp->translate("DFMAdvanceSearchBar", "0 ~ 100 KB"), QVariant::fromValue(QPair(0, 100))); + asbCombos[SIZE_RANGE]->addItem(qApp->translate("DFMAdvanceSearchBar", "100 KB ~ 1 MB"), QVariant::fromValue(QPair(100, 1024))); + asbCombos[SIZE_RANGE]->addItem(qApp->translate("DFMAdvanceSearchBar", "1 MB ~ 10 MB"), QVariant::fromValue(QPair(1024, 10 * 1024))); + asbCombos[SIZE_RANGE]->addItem(qApp->translate("DFMAdvanceSearchBar", "10 MB ~ 100 MB"), QVariant::fromValue(QPair(10 * 1024, 100 * 1024))); + asbCombos[SIZE_RANGE]->addItem(qApp->translate("DFMAdvanceSearchBar", "100 MB ~ 1 GB"), QVariant::fromValue(QPair(100 * 1024, 1 << 20))); + asbCombos[SIZE_RANGE]->addItem(qApp->translate("DFMAdvanceSearchBar", "> 1 GB"), QVariant::fromValue(QPair(1 << 20, 1 << 30))); // here to 1T + + dateRangeMap[QVariant::fromValue(1)] = 1; + dateRangeMap[QVariant::fromValue(2)] = 2; + dateRangeMap[QVariant::fromValue(7)] = 3; + dateRangeMap[QVariant::fromValue(14)] = 4; + dateRangeMap[QVariant::fromValue(30)] = 5; + dateRangeMap[QVariant::fromValue(60)] = 6; + dateRangeMap[QVariant::fromValue(365)] = 7; + dateRangeMap[QVariant::fromValue(730)] = 8; + + auto createDateCombos = [ = ](const LabelIndex index) { + asbCombos[index]->addItem("--", QVariant()); + asbCombos[index]->addItem(qApp->translate("DFMAdvanceSearchBar", "Today"), QVariant::fromValue(1)); + asbCombos[index]->addItem(qApp->translate("DFMAdvanceSearchBar", "Yesterday"), QVariant::fromValue(2)); + asbCombos[index]->addItem(qApp->translate("DFMAdvanceSearchBar", "This week"), QVariant::fromValue(7)); + asbCombos[index]->addItem(qApp->translate("DFMAdvanceSearchBar", "Last week"), QVariant::fromValue(14)); + asbCombos[index]->addItem(qApp->translate("DFMAdvanceSearchBar", "This month"), QVariant::fromValue(30)); + asbCombos[index]->addItem(qApp->translate("DFMAdvanceSearchBar", "Last month"), QVariant::fromValue(60)); + asbCombos[index]->addItem(qApp->translate("DFMAdvanceSearchBar", "This year"), QVariant::fromValue(365)); + asbCombos[index]->addItem(qApp->translate("DFMAdvanceSearchBar", "Last year"), QVariant::fromValue(730)); + }; + createDateCombos(DATE_RANGE); + createDateCombos(ACCESS_DATE_RANGE); + createDateCombos(CREATE_DATE_RANGE); + + +// QTimer::singleShot(1000, this, [this] { +// qDebug() << asbCombos[0]->sizeHint() << asbCombos[0]->size() << asbCombos[0]->minimumSizeHint(); +// }); + + formLayout->addWidget(asbLabels[SEARCH_RANGE], 0, 0); + formLayout->addWidget(asbCombos[SEARCH_RANGE], 0, 1); + formLayout->addItem(new QSpacerItem(14, 1), 0, 2); + formLayout->addWidget(asbLabels[FILE_TYPE], 0, 3); + formLayout->addWidget(asbCombos[FILE_TYPE], 0, 4); + formLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding), 0, 7); + formLayout->addWidget(resetBtn, 0, 8); + + formLayout->addWidget(asbLabels[SIZE_RANGE], 1, 0); + formLayout->addWidget(asbCombos[SIZE_RANGE], 1, 1); + formLayout->addWidget(asbLabels[DATE_RANGE], 1, 3); + formLayout->addWidget(asbCombos[DATE_RANGE], 1, 4); + formLayout->addWidget(asbLabels[ACCESS_DATE_RANGE], 0, 5); + formLayout->addWidget(asbCombos[ACCESS_DATE_RANGE], 0, 6); + formLayout->addWidget(asbLabels[CREATE_DATE_RANGE], 1, 5); + formLayout->addWidget(asbCombos[CREATE_DATE_RANGE], 1, 6); + + + formLayout->setSpacing(6); + formLayout->setMargin(6); +// formLayout->setRowMinimumHeight(0, 36); +// formLayout->setRowMinimumHeight(1, 36); + + mainLayout->addSpacing(20); + mainLayout->addLayout(formLayout); + mainLayout->addSpacing(20); +} + +void DFMAdvanceSearchBar::initConnection() +{ + connect(resetBtn, &QCommandLinkButton::pressed, this, &DFMAdvanceSearchBar::onResetButtonPressed); + + for (int i = 0; i < LABEL_COUNT; i++) { + connect(asbCombos[i], static_cast(&QComboBox::currentIndexChanged), this, &DFMAdvanceSearchBar::onOptionChanged); + } +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmadvancesearchbar.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmadvancesearchbar.h new file mode 100644 index 0000000..79f460e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmadvancesearchbar.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ + +#ifndef DFMADVANCESEARCHBAR_H +#define DFMADVANCESEARCHBAR_H + +#include + +#include +#include +#include +#include +#include +#include + +typedef struct fileFilter FileFilter; +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE + +class DFMAdvanceSearchBar : public DBoxWidget +{ + Q_OBJECT +public: + explicit DFMAdvanceSearchBar(QWidget *parent = nullptr); + + void resetForm(bool updateView = true); + + void updateFilterValue(const FileFilter *filter); + +signals: + void optionChanged(QMap formData, bool updateView); + +private slots: + void onOptionChanged(); + void onResetButtonPressed(); + +protected slots: + void hideEvent(QHideEvent *) override; + +private: + void initUI(); + void initConnection(); + + enum LabelIndex { + SEARCH_RANGE, FILE_TYPE, SIZE_RANGE, DATE_RANGE, ACCESS_DATE_RANGE, CREATE_DATE_RANGE, LABEL_COUNT, + TRIGGER_SEARCH = 114514 + }; + + QBoxLayout *mainLayout; + QLabel *asbLabels[LABEL_COUNT]; + QComboBox *asbCombos[LABEL_COUNT]; + DCommandLinkButton *resetBtn; + bool needSearchAgain = true; + bool allowUpdateView = true; + + // 记录下拉框选项信息,用于更新下拉框选项 + QMap, int> sizeRangeMap; + QMap dateRangeMap; +}; + +DFM_END_NAMESPACE + +#endif // DFMADVANCESEARCHBAR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmfilebasicinfowidget.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmfilebasicinfowidget.cpp new file mode 100644 index 0000000..86044a9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmfilebasicinfowidget.cpp @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Mike Chen + * + * Maintainer: Mike Chen + * + * 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 + * 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 . + */ +#include "dfmfilebasicinfowidget.h" +#include "dfmeventdispatcher.h" +#include "dfileinfo.h" +#include "dfileservices.h" +#include "models/trashfileinfo.h" +#include "dfilestatisticsjob.h" +#include "shutil/fileutils.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "singleton.h" +#include "shutil/mimetypedisplaymanager.h" +#include "controllers/vaultcontroller.h" +#include "dfmsettings.h" +#include "vaultglobaldefine.h" + +#include +#include +#include +#include +#include +#include + +#include + +DFM_BEGIN_NAMESPACE + +SectionKeyLabel::SectionKeyLabel(const QString &text, QWidget *parent, Qt::WindowFlags f): + QLabel(text, parent, f) +{ + setObjectName("SectionKeyLabel"); + setFixedWidth(100); + QFont font = this->font(); + font.setWeight(QFont::Bold - 8); + font.setPixelSize(13); + setFont(font); + setAlignment(Qt::AlignVCenter | Qt::AlignLeft); +} + + +SectionValueLabel::SectionValueLabel(const QString &text, QWidget *parent, Qt::WindowFlags f): + QLabel(text, parent, f) +{ + setObjectName("SectionValueLabel"); + setFixedWidth(150); + setAlignment(Qt::AlignVCenter | Qt::AlignLeft); +} + +bool SectionValueLabel::event(QEvent *e) +{ + if (e->type() == QEvent::FontChange) { + //! 根据字体大小来设置label的宽度 + setFixedWidth(this->fontMetrics().horizontalAdvance(this->text())); + } + return QLabel::event(e); +} + +void SectionValueLabel::showEvent(QShowEvent *e) +{ + QString txt = this->text(); + if (!txt.isEmpty()) { + //! 根据字体大小来设置label的宽度 + setFixedWidth(this->fontMetrics().horizontalAdvance(txt)); + } + QLabel::showEvent(e); +} + +LinkSectionValueLabel::LinkSectionValueLabel(const QString &text, QWidget *parent, Qt::WindowFlags f): + SectionValueLabel(text, parent, f) +{ + +} + +void LinkSectionValueLabel::mouseReleaseEvent(QMouseEvent *event) +{ + DFMEventDispatcher::instance()->processEvent(Q_NULLPTR, linkTargetUrl()); + SectionValueLabel::mouseReleaseEvent(event); +} + +DUrl LinkSectionValueLabel::linkTargetUrl() const +{ + return m_linkTargetUrl; +} + +void LinkSectionValueLabel::setLinkTargetUrl(const DUrl &linkTargetUrl) +{ + m_linkTargetUrl = linkTargetUrl; +} + +class DFMFileBasicInfoWidgetPrivate +{ +public: + explicit DFMFileBasicInfoWidgetPrivate(DFMFileBasicInfoWidget *qq); + ~DFMFileBasicInfoWidgetPrivate(); + + void setUrl(const DUrl &url); +protected: + void initUI(); + void startCalcFolderSize(); + void update(); + +private: + DUrl m_url; + QLabel *m_folderSizeLabel{ nullptr }; + QLabel *m_containSizeLabel{ nullptr }; + bool m_showFileName{ false }; + bool m_showMediaInfo{ false }; + bool m_showSummaryOnly{ false }; + + DFM_NAMESPACE::DFileStatisticsJob *m_sizeWorker{ nullptr }; + + DFMFileBasicInfoWidget *q_ptr; + Q_DECLARE_PUBLIC(DFMFileBasicInfoWidget) +}; + +DFMFileBasicInfoWidgetPrivate::DFMFileBasicInfoWidgetPrivate(DFMFileBasicInfoWidget *qq) + : q_ptr(qq) +{ + initUI(); +} + +DFMFileBasicInfoWidgetPrivate::~DFMFileBasicInfoWidgetPrivate() +{ + if (m_sizeWorker) + m_sizeWorker->stop(); +} + +void DFMFileBasicInfoWidgetPrivate::startCalcFolderSize() +{ + Q_Q(DFMFileBasicInfoWidget); + if (m_showSummaryOnly) + return; + + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(q, m_url); + if (!info) + return; + DUrl validUrl = m_url; + if (info->isSymLink()) { + validUrl = info->redirectedFileUrl(); + } else { + validUrl = DUrl::fromLocalFile(info->toLocalFile()); + } + + if (validUrl.isUserShareFile()) { + validUrl.setScheme(FILE_SCHEME); + } + + DUrlList urls; + urls << validUrl; + + if (!m_sizeWorker) { + m_sizeWorker = new DFileStatisticsJob(q); + QObject::connect(m_sizeWorker, &DFileStatisticsJob::dataNotify, q, &DFMFileBasicInfoWidget::updateSizeText); + } + + m_sizeWorker->start(urls); +} + +void DFMFileBasicInfoWidgetPrivate::initUI() +{ + Q_Q(DFMFileBasicInfoWidget); + q->setLayout(new QStackedLayout); + +} +void DFMFileBasicInfoWidgetPrivate::setUrl(const DUrl &url) +{ + if (m_url == url) { + return; + } + + m_url = url; + Q_Q(DFMFileBasicInfoWidget); + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(q, m_url); + if (!info) + return; + + QStackedLayout *stackedLayout = qobject_cast(q->layout()); + if (!stackedLayout) + return; + + if (stackedLayout->currentWidget()) { + if (m_sizeWorker) + m_sizeWorker->stop(); + delete stackedLayout->currentWidget(); + } + + QWidget *layoutWidget = new QWidget; + QFormLayout *layout = new QFormLayout(layoutWidget); + layout->setHorizontalSpacing(5); + layout->setVerticalSpacing(16); + layout->setLabelAlignment(Qt::AlignRight | Qt::AlignTop); + stackedLayout->addWidget(layoutWidget); + stackedLayout->setCurrentWidget(layoutWidget); + + if (m_showFileName) { + QLabel *fileNameKeyLabel = new SectionKeyLabel(QObject::tr("Name")); + QLabel *fileNameLabel = new SectionValueLabel(info->fileDisplayName()); + QString text = info->fileDisplayName(); + fileNameLabel->setText(fileNameLabel->fontMetrics().elidedText(text, Qt::ElideMiddle, fileNameLabel->width())); + fileNameLabel->setToolTip(text); + + layout->addRow(fileNameKeyLabel, fileNameLabel); + } + + m_folderSizeLabel = new SectionValueLabel("", layoutWidget); + SectionValueLabel *typeLabel = new SectionValueLabel(info->mimeTypeDisplayName().split(" (")[0]); + + if (info->isDir()) { + if (!m_showSummaryOnly) { + m_containSizeLabel = new SectionValueLabel(info->sizeDisplayName()); + SectionKeyLabel *sizeSectionLabel = new SectionKeyLabel(QObject::tr("Size")); + SectionKeyLabel *fileAmountSectionLabel = new SectionKeyLabel(QObject::tr("Contains")); + layout->addRow(sizeSectionLabel, m_folderSizeLabel); + layout->addRow(fileAmountSectionLabel, m_containSizeLabel); + } + } else { + SectionKeyLabel *sizeSectionLabel = new SectionKeyLabel(QObject::tr("Size")); + layout->addRow(sizeSectionLabel, m_folderSizeLabel); + } + + if (m_showMediaInfo) { + DAbstractFileInfo::FileType fileType = mimeTypeDisplayManager->displayNameToEnum(info->mimeTypeName()); + + DFMMediaInfo::MeidiaType mediaType = DFMMediaInfo::Other; + switch (fileType) { + case DAbstractFileInfo::Videos: + mediaType = DFMMediaInfo::Video; + break; + case DAbstractFileInfo::Audios: + mediaType = DFMMediaInfo::Audio; + break; + case DAbstractFileInfo::Images: + mediaType = DFMMediaInfo::Image; + break; + default: + + break; + } + + if (mediaType != DFMMediaInfo::Other) { + const QString &filePath = info->filePath(); + DFMMediaInfo *mediaInfo = nullptr; + // iphone 中读media文件很慢,因此特殊处理 + if (filePath.contains(IPHONE_STAGING) && filePath.startsWith(MOBILE_ROOT_PATH)) { + mediaInfo = new DFMMediaInfo(filePath, nullptr); + // startReadInfo 可能会很慢,因此延时1秒后,待后面的代码执行完后再执行 + QTimer::singleShot(1000, [mediaInfo]() { + mediaInfo->startReadInfo(); + // 立即析构会导致读取media的任务无法完成,因此延时析构,5s是实验后比较稳定的值 + QTimer::singleShot(5000, [mediaInfo]() { + mediaInfo->deleteLater(); + }); + }); + } else { + mediaInfo = new DFMMediaInfo(filePath, layoutWidget); + mediaInfo->startReadInfo(); + } + QPointer ptrMediaInfo = mediaInfo; + QObject::connect(fileSignalManager, &FileSignalManager::requestCloseMediaInfo, layout, [ptrMediaInfo, this](const QString path){ + if (m_url.path() == path && ptrMediaInfo) { + ptrMediaInfo->stopReadInfo(); + } + }, Qt::DirectConnection); + + QObject::connect(mediaInfo, &DFMMediaInfo::Finished, layout, [ = ]() { + int frame_height = q->height(); + QString duration = mediaInfo->Value("Duration", mediaType); + if (duration.isEmpty()) { + duration = mediaInfo->Value("Duration", DFMMediaInfo::General); + } + // mkv duration may be float ? like '666.000', toInt() will failed + bool ok = false; + int ms = duration.toInt(&ok); + if (!ok) + ms = static_cast(duration.toFloat(&ok)); + + int row = 2; + if (ok) { + QTime t(0, 0); + t = t.addMSecs(ms); + QLabel *pixelKeyLabel = new SectionKeyLabel(QObject::tr("Duration")); + QLabel *pixelLabel = new SectionValueLabel; + pixelLabel->setText(t.toString("hh:mm:ss")); + layout->insertRow(row++, pixelKeyLabel, pixelLabel); + frame_height += 30; + } + + bool okw = false, okh = false; + int width = mediaInfo->Value("Width", mediaType).toInt(&okw); + int height = mediaInfo->Value("Height", mediaType).toInt(&okh); + if (okw && okh) { + QString text = QString("%1x%2").arg(width).arg(height); + QLabel *pixelKeyLabel = new SectionKeyLabel(QObject::tr("Dimension")); + QLabel *pixelLabel = new SectionValueLabel; + pixelLabel->setText(text); + layout->insertRow(row++, pixelKeyLabel, pixelLabel); + frame_height += 30; + } + + if (ok || (okw && okh)) { + q->setFixedHeight(frame_height); + } + }); + } + } + + /*if (!info->isVirtualEntry())*/ { + SectionKeyLabel *typeSectionLabel = new SectionKeyLabel(QObject::tr("Type")); + layout->addRow(typeSectionLabel, typeLabel); + } + + if (info->isSymLink()) { + SectionKeyLabel *linkPathSectionLabel = new SectionKeyLabel(QObject::tr("Location")); + + LinkSectionValueLabel *linkPathLabel = new LinkSectionValueLabel(info->symlinkTargetPath()); + linkPathLabel->setToolTip(info->symlinkTargetPath()); + linkPathLabel->setLinkTargetUrl(info->redirectedFileUrl()); + linkPathLabel->setOpenExternalLinks(true); + linkPathLabel->setWordWrap(false); + QString t = linkPathLabel->fontMetrics().elidedText(info->symlinkTargetPath(), Qt::ElideMiddle, 150); + linkPathLabel->setText(t); + layout->addRow(linkPathSectionLabel, linkPathLabel); + } + + if (!info->isVirtualEntry()) { + SectionKeyLabel *TimeCreatedSectionLabel = new SectionKeyLabel(QObject::tr("Time accessed")); + SectionValueLabel *timeCreatedLabel = nullptr; + SectionKeyLabel *TimeModifiedSectionLabel = nullptr; + SectionValueLabel *timeModifiedLabel = nullptr; + if (VaultController::isRootDirectory(info->fileUrl().toLocalFile())) { + TimeModifiedSectionLabel = new SectionKeyLabel(QObject::tr("Time locked")); + //! 保险箱根目录创建、访问、修改时间的读取 + DFM_NAMESPACE::DFMSettings setting(VAULT_TIME_CONFIG_FILE); + timeCreatedLabel = new SectionValueLabel(setting.value(QString("VaultTime"), QString("InterviewTime")).toString()); + if (setting.value(QString("VaultTime"), QString("LockTime")).toString().isEmpty()) + timeModifiedLabel = new SectionValueLabel(setting.value(QString("VaultTime"), QString("InterviewTime")).toString()); + else + timeModifiedLabel = new SectionValueLabel(setting.value(QString("VaultTime"), QString("LockTime")).toString()); + }else { + TimeModifiedSectionLabel = new SectionKeyLabel(QObject::tr("Time modified")); + timeCreatedLabel = new SectionValueLabel(info->lastReadDisplayName()); + timeModifiedLabel = new SectionValueLabel(info->lastModifiedDisplayName()); + } + DFMGlobal::setToolTip(TimeCreatedSectionLabel); + DFMGlobal::setToolTip(TimeModifiedSectionLabel); + + layout->addRow(TimeCreatedSectionLabel, timeCreatedLabel); + layout->addRow(TimeModifiedSectionLabel, timeModifiedLabel); + } + + if (info->fileUrl().isTrashFile() && info->fileUrl() != DUrl(TRASH_ROOT)) { + QString pathStr = static_cast(info.constData())->sourceFilePath(); + SectionValueLabel *sourcePathLabel = new SectionValueLabel(pathStr); + QString elidedStr = sourcePathLabel->fontMetrics().elidedText(pathStr, Qt::ElideMiddle, 150); + sourcePathLabel->setToolTip(pathStr); + sourcePathLabel->setWordWrap(false); + sourcePathLabel->setText(elidedStr); + SectionKeyLabel *sourcePathSectionLabel = new SectionKeyLabel(QObject::tr("Source path")); + layout->addRow(sourcePathSectionLabel, sourcePathLabel); + } + + //layout->setContentsMargins(0, 0, 40, 0); + //! lixiang change + layoutWidget->update(); + //! lixiang change +} + +DFMFileBasicInfoWidget::DFMFileBasicInfoWidget(QWidget *parent) + : QFrame(parent) + , d_private(new DFMFileBasicInfoWidgetPrivate(this)) +{ + +} + +DFMFileBasicInfoWidget::~DFMFileBasicInfoWidget() +{ + +} + +void DFMFileBasicInfoWidget::setUrl(const DUrl &url) +{ + Q_D(DFMFileBasicInfoWidget); + d->setUrl(url); +} + +bool DFMFileBasicInfoWidget::showFileName() +{ + Q_D(DFMFileBasicInfoWidget); + return d->m_showFileName; +} + +void DFMFileBasicInfoWidget::setShowFileName(bool visible) +{ + Q_D(DFMFileBasicInfoWidget); + d->m_showFileName = visible; +} + +bool DFMFileBasicInfoWidget::showMediaInfo() +{ + Q_D(DFMFileBasicInfoWidget); + return d->m_showMediaInfo; +} + +void DFMFileBasicInfoWidget::setShowMediaInfo(bool visible) +{ + Q_D(DFMFileBasicInfoWidget); + d->m_showMediaInfo = visible; +} + +bool DFMFileBasicInfoWidget::showSummary() +{ + Q_D(DFMFileBasicInfoWidget); + return d->m_showSummaryOnly; +} + +void DFMFileBasicInfoWidget::setShowSummary(bool enable) +{ + Q_D(DFMFileBasicInfoWidget); + d->m_showSummaryOnly = enable; +} + +void DFMFileBasicInfoWidget::updateSizeText(qint64 size, int filesCount, int directoryCount) +{ + Q_D(DFMFileBasicInfoWidget); + + if (d->m_folderSizeLabel) + d->m_folderSizeLabel->setText(FileUtils::formatSize(size)); + if (d->m_containSizeLabel) + d->m_containSizeLabel->setText(QString::number(filesCount + directoryCount)); +} + +void DFMFileBasicInfoWidget::showEvent(QShowEvent *event) +{ + Q_D(DFMFileBasicInfoWidget); + if (d->m_folderSizeLabel && d->m_folderSizeLabel->text().isEmpty()) { + d->startCalcFolderSize(); + } + + return QFrame::showEvent(event); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmfilebasicinfowidget.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmfilebasicinfowidget.h new file mode 100644 index 0000000..d71a9a2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmfilebasicinfowidget.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Mike Chen + * + * Maintainer: Mike Chen + * + * 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 + * 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 . + */ +#ifndef DFMFILEBASICINFOWIDGET_H +#define DFMFILEBASICINFOWIDGET_H + +#include +#include +#include +#include "durl.h" + +DFM_BEGIN_NAMESPACE + + +class SectionKeyLabel: public QLabel +{ + Q_OBJECT + +public: + explicit SectionKeyLabel(const QString &text = "", QWidget *parent = nullptr, Qt::WindowFlags f = {}); +}; + +class SectionValueLabel: public QLabel +{ + Q_OBJECT + +public: + explicit SectionValueLabel(const QString &text = "", QWidget *parent = nullptr, Qt::WindowFlags f = {}); + +protected: + //! Set the width of the label after the font is changed + virtual bool event(QEvent *e) override; + //! Set the width of the label after the selected file changes + virtual void showEvent(QShowEvent *e) override; +}; + +class LinkSectionValueLabel: public SectionValueLabel +{ + Q_OBJECT + +public: + explicit LinkSectionValueLabel(const QString &text = "", QWidget *parent = nullptr, Qt::WindowFlags f = {}); + + DUrl linkTargetUrl() const; + void setLinkTargetUrl(const DUrl &linkTargetUrl); + +protected: + void mouseReleaseEvent(QMouseEvent *event) override; + +private: + DUrl m_linkTargetUrl; +}; + + +class DFMFileBasicInfoWidgetPrivate; +class DFMFileBasicInfoWidget : public QFrame +{ + Q_OBJECT +public: + explicit DFMFileBasicInfoWidget(QWidget *parent = nullptr); + virtual ~DFMFileBasicInfoWidget(); + + void setUrl(const DUrl &url); + + bool showFileName(); + void setShowFileName(bool visible); + + bool showMediaInfo(); + void setShowMediaInfo(bool visible); + bool showSummary(); // 目录只显示概要, 包含几个文件等。 + void setShowSummary(bool enable); + +protected: + void updateSizeText(qint64 size, int filesCount, int directoryCount); + virtual void showEvent(QShowEvent *event); +private: + QScopedPointer d_private; + Q_DECLARE_PRIVATE_D(d_private, DFMFileBasicInfoWidget) +}; + +DFM_END_NAMESPACE + +#endif // DFMFILEBASICINFOWIDGET_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmheaderview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmheaderview.cpp new file mode 100644 index 0000000..3039c09 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmheaderview.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ +#include "dfmheaderview.h" + +DFMHeaderView::DFMHeaderView(Qt::Orientation orientation, QWidget *parent) + : QHeaderView(orientation, parent) +{ + setSectionsMovable(true); + setFirstSectionMovable(false); +} + +QSize DFMHeaderView::sizeHint() const +{ + QSize size = QHeaderView::sizeHint(); + + size.setWidth(length()); + + return size; +} + +void DFMHeaderView::mouseReleaseEvent(QMouseEvent *e) +{ + emit mouseReleased(); + + return QHeaderView::mouseReleaseEvent(e); +} + +void DFMHeaderView::resizeEvent(QResizeEvent *e) +{ + emit viewResized(); + + return QHeaderView::resizeEvent(e); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmheaderview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmheaderview.h new file mode 100644 index 0000000..ee87b8c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmheaderview.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ +#ifndef DFMHEADERVIEW_H +#define DFMHEADERVIEW_H + +#include + +class DFMHeaderView : public QHeaderView +{ + Q_OBJECT +public: + explicit DFMHeaderView(Qt::Orientation orientation, QWidget *parent = nullptr); + + QSize sizeHint() const override; + + using QHeaderView::updateGeometries; + +protected: + void mouseReleaseEvent(QMouseEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + +signals: + void mouseReleased(); + void viewResized(); +}; + +#endif // DFMHEADERVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmopticalmediawidget.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmopticalmediawidget.cpp new file mode 100644 index 0000000..be2f177 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmopticalmediawidget.cpp @@ -0,0 +1,419 @@ +//fix: 设置光盘容量属性 +#include "interfaces/dfmstandardpaths.h" + +#include "dfmopticalmediawidget.h" +#include "disomaster.h" +#include "shutil/fileutils.h" +#include "dialogs/burnoptdialog.h" +#include "dialogs/dialogmanager.h" +#include "dfilestatisticsjob.h" +#include "dfileview.h" +#include "dfilesystemmodel.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "singleton.h" +#include "models/dfmrootfileinfo.h" +#include "dfmapplication.h" +#include "dfmsettings.h" + +#include +#include + +#include +#include +//fix: 根据光盘选择文件状态实时更新状态 +#include +//fix: 设置光盘容量属性 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +using namespace DISOMasterNS; + +//fixed:CD display size error +QMap DFMOpticalMediaWidget::g_mapCdStatusInfo; +//fix: 动态获取刻录选中文件的字节大小 +qint64 DFMOpticalMediaWidget::g_selectBurnFilesSize = 0; +qint64 DFMOpticalMediaWidget::g_selectBurnDirFileCount = 0; + +class DFMOpticalMediaWidgetPrivate +{ +public: + explicit DFMOpticalMediaWidgetPrivate(DFMOpticalMediaWidget *q); + ~DFMOpticalMediaWidgetPrivate(); + void setupUi(); + void setDeviceProperty(DeviceProperty dp); + void setCurrentDevice(const QString &dev); + void setCurrentFSByDev(const QString &dev); + QString getCurrentDevice() const; + QString getVolTag(); + + //fix: 根据光盘选择文件状态实时更新状态 + QTimer *updateBurnStatusTimer = nullptr; + +private: + //fix: 根据光盘选择文件状态实时更新状态 + qint64 m_selectBurnFilesSize = 0; + qint64 m_selectBurnDirCount = 0; + + QLabel *lb_mediatype = nullptr; + QLabel *lb_available = nullptr; + QLabel *lb_udsupport = nullptr; + DPushButton *pb_burn = nullptr; + QSvgWidget *icon_caution = nullptr; + + QHBoxLayout *layout = nullptr; + DFMOpticalMediaWidget *q_ptr; + QString curFS; + QString curFSVersion; + QString curdev; + QString strMntPath; + QString defaultDiscName; + Q_DECLARE_PUBLIC(DFMOpticalMediaWidget) +}; + +DFMOpticalMediaWidget::DFMOpticalMediaWidget(QWidget *parent) : + QWidget(parent), + d_ptr(new DFMOpticalMediaWidgetPrivate(this)) +{ + Q_D(DFMOpticalMediaWidget); + d->setupUi(); + + m_pStatisticWorker = new DFileStatisticsJob(this); + //fix: 根据光盘选择文件状态实时更新状态 + DFMOpticalMediaWidget::g_selectBurnFilesSize = 0; + DFMOpticalMediaWidget::g_selectBurnDirFileCount = 0; + + connect(d->pb_burn, &DPushButton::clicked, this, [ = ] { + if (m_pStatisticWorker->isRunning()) + return; + + QString volTag = d->getVolTag(); + CdStatusInfo &statusInfo = DFMOpticalMediaWidget::g_mapCdStatusInfo[volTag]; + statusInfo.bReadyToBurn = true; + + QDir::Filters filter = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::System | QDir::Hidden; + + DUrl urlOfStage = DUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/" + qApp->organizationName() + + "/" DISCBURN_STAGING "/" + d->getCurrentDevice().replace('/', '_') + "/"); + // 1、获取暂存区内文件列表信息,去除与当前光盘中有交集的部分(当前 isomaster 库不提供覆盖写入的选项,后或可优化) + QDir dirMnt(d->strMntPath); + if (!dirMnt.exists()) + { + statusInfo.bReadyToBurn = false; + qWarning() << "Mount points doesn't exist: " << d->strMntPath; + return; + } + // 如果放入空盘是没有挂载点的,此时给QDir传入空的path将导致QDir获取到的是程序运行目录的Dir,之后的去重会产生不正常的结果 + QFileInfoList lstFilesOnDisc = d->strMntPath.isEmpty() ? QFileInfoList() : dirMnt.entryInfoList(filter); + + QDir dirStage(urlOfStage.path()); + if (!dirStage.exists()) + { + statusInfo.bReadyToBurn = false; + return; + } + QFileInfoList lstFilesInStage = dirStage.entryInfoList(filter); + if (lstFilesInStage.count() == 0) + { + statusInfo.bReadyToBurn = false; + dialogManager->showMessageDialog(DialogManager::msgWarn, tr("No files to burn")); + return; + } + + bool bDeletedValidFile = false; // 在点击进入光驱中文件夹时,因解决bug#27870时,在暂存区中手动创建了本不存在的目录 + // 如果光盘挂载根目录与暂存区根目录中有同名文件或文件夹,则移除暂存区中的相关文件或文件夹; + for (QFileInfo fOn : lstFilesOnDisc) + { + for (QFileInfo fStage : lstFilesInStage) { + if (fStage.fileName() != fOn.fileName()) + continue; + + if (fStage.isFile() || fStage.isSymLink()) + dirStage.remove(fStage.fileName()); + else { + if (!bDeletedValidFile) + bDeletedValidFile = hasFileInDir(fStage.absoluteFilePath()); // 这里判断是否有移除掉非文件夹类文件 + QDir(fStage.absoluteFilePath()).removeRecursively(); + } + } + } + + lstFilesInStage = dirStage.entryInfoList(filter); + if (lstFilesInStage.count() == 0) + { + QString errTitle(tr("No files to burn")); + dialogManager->showMessageDialog(DialogManager::msgWarn, errTitle); + statusInfo.bReadyToBurn = false; + return; + } + + // 2、启动worker线程计算缓存区文件大小 + m_pStatisticWorker->start({urlOfStage}); + }); + + connect(m_pStatisticWorker, &DFileStatisticsJob::finished, this, [ = ] { + + QString volTag = d->getVolTag(); + CdStatusInfo &statusInfo = DFMOpticalMediaWidget::g_mapCdStatusInfo[volTag]; + + DeviceProperty dp = ISOMaster->getDevicePropertyCached(d->getCurrentDevice()); + + if (dp.avail == 0 || static_cast(m_pStatisticWorker->totalSize()) > dp.avail) // 可用空间为0时也禁止刻录 + { + //fix: 光盘容量小于刻录项目,对话框提示:目标磁盘剩余空间不足,无法进行刻录! + qDebug() << d->m_selectBurnFilesSize / 1024 / 1024 << "MB" << dp.avail / 1024 / 1024 << "MB"; + dialogManager->showMessageDialog(DialogManager::msgWarn, tr("Unable to burn. Not enough free space on the target disk.")); + statusInfo.bReadyToBurn = false; + return; + } + + QScopedPointer bd(new BurnOptDialog(d->getCurrentDevice(), this)); + bd->setJobWindowId(static_cast(this->window()->winId())); + bd->setDefaultVolName(d->defaultDiscName); + bd->setDiscAndFsInfo(dp.media, d->curFS, d->curFSVersion); + bd->exec(); + statusInfo.bReadyToBurn = false; + }); +} + +DFMOpticalMediaWidget::~DFMOpticalMediaWidget() +{ + Q_D(DFMOpticalMediaWidget); +// d->updateBurnStatusTimer->stop(); + DFMOpticalMediaWidget::g_selectBurnFilesSize = 0; + DFMOpticalMediaWidget::g_selectBurnDirFileCount = 0; + d->m_selectBurnFilesSize = 0; + d->m_selectBurnDirCount = 0; +} + +//fix: 设置光盘容量属性 +// TODO(zhangs): 此函数的逻辑不应该在此类中,重构后需要移除,将此逻辑改为服务进程中,通过 dbus 接口调用 +void DFMOpticalMediaWidget::setBurnCapacity(int status, QString strVolTag) +{ + QMap capacityInfo; + double burnTotalSize = DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].nTotal; + double burnUsedSize = DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].nUsage; + + capacityInfo[BURN_CAPACITY_TOTAL_SIZE] = burnTotalSize; + capacityInfo[BURN_CAPACITY_USED_SIZE] = burnUsedSize; + capacityInfo[BURN_CAPACITY_STATUS] = status; + + DFMApplication::genericSetting()->setValue(BURN_CAPACITY_ATTRIBUTE, strVolTag, capacityInfo); +} + +void DFMOpticalMediaWidget::updateDiscInfo(QString dev) +{ + Q_D(DFMOpticalMediaWidget); + d->setCurrentFSByDev(dev); + d->setCurrentDevice(dev); + //fix: 设置光盘容量属性 + DFMOpticalMediaWidget::setBurnCapacity(BCSA_BurnCapacityStatusAddMount, d->getVolTag()); +} + +void DFMOpticalMediaWidget::setDiscMountPoint(const QString &strMntPath) +{ + Q_D(DFMOpticalMediaWidget); + d->strMntPath = strMntPath; +} + +void DFMOpticalMediaWidget::setDefaultDiscName(const QString &name) +{ + Q_D(DFMOpticalMediaWidget); + d->defaultDiscName = name; +} + +bool DFMOpticalMediaWidget::hasFileInDir(QDir dir) +{ + QFileInfoList lstFiles = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::System); + foreach (QFileInfo f, lstFiles) { + if (f.isFile()) + return true; + return hasFileInDir(QDir(f.absoluteFilePath())); + } + return false; +} + +QString DFMOpticalMediaWidget::getDiscMountPoint() +{ + Q_D(DFMOpticalMediaWidget); + return d->strMntPath; +} + +//fix: 根据光盘选择文件状态实时更新状态 +void DFMOpticalMediaWidget::selectBurnFilesOptionUpdate() +{ + Q_D(DFMOpticalMediaWidget); + d->m_selectBurnDirCount = DFMOpticalMediaWidget::g_selectBurnDirFileCount; + d->m_selectBurnFilesSize = DFMOpticalMediaWidget::g_selectBurnFilesSize; + if ((d->m_selectBurnFilesSize > 0) || (d->m_selectBurnDirCount > 0)) { + d->pb_burn->setEnabled(true); + } else { + d->pb_burn->setEnabled(false); + } +} + +QString DFMOpticalMediaWidget::getVolTag(const DUrl &fileUrl) +{ + QString strVolTag = fileUrl.path().split("/", QString::SkipEmptyParts).count() >= 2 + ? fileUrl.path().split("/", QString::SkipEmptyParts).at(1) + : ""; + return strVolTag; +} + +bool DFMOpticalMediaWidget::hasVolProcessBusy() +{ + QMap::iterator ite = g_mapCdStatusInfo.begin(); + + for (; ite != g_mapCdStatusInfo.end(); ++ite) { + if (ite.value().bProcessLocked) + return true; + } + return false; +} + +CdStatusInfo *DFMOpticalMediaWidget::getCdStatusInfo(const QString &dev) +{ + QMap::iterator ite = g_mapCdStatusInfo.find(dev); + if (ite != g_mapCdStatusInfo.end()) { + return &(ite.value()); + } + return nullptr; +} + +DFMOpticalMediaWidgetPrivate::DFMOpticalMediaWidgetPrivate(DFMOpticalMediaWidget *q) : + q_ptr(q) +{ +} + +DFMOpticalMediaWidgetPrivate::~DFMOpticalMediaWidgetPrivate() +{ +} + +void DFMOpticalMediaWidgetPrivate::setupUi() +{ + Q_Q(DFMOpticalMediaWidget); + layout = new QHBoxLayout(q); + q->setLayout(layout); + layout->addWidget(lb_mediatype = new QLabel("")); + layout->addWidget(lb_available = new QLabel("")); + layout->addWidget(lb_udsupport = new QLabel(QObject::tr("It does not support burning %1 discs").arg(QString("U/D/F").remove("/")))); + layout->addWidget(pb_burn = new DPushButton()); + layout->addWidget(icon_caution = new QSvgWidget()); + pb_burn->setText(QObject::tr("Burn")); + lb_udsupport->setVisible(false); + icon_caution->setVisible(false); + + + pb_burn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + lb_available->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + lb_mediatype->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + lb_available->setAlignment(Qt::AlignCenter); +} + +void DFMOpticalMediaWidgetPrivate::setDeviceProperty(DeviceProperty dp) +{ + const static QHash rtypemap = { + {MediaType::CD_ROM, "CD-ROM"}, + {MediaType::CD_R, "CD-R"}, + {MediaType::CD_RW, "CD-RW"}, + {MediaType::DVD_ROM, "DVD-ROM"}, + {MediaType::DVD_R, "DVD-R"}, + {MediaType::DVD_RW, "DVD-RW"}, + {MediaType::DVD_PLUS_R, "DVD+R"}, + {MediaType::DVD_PLUS_R_DL, "DVD+R/DL"}, + {MediaType::DVD_RAM, "DVD-RAM"}, + {MediaType::DVD_PLUS_RW, "DVD+RW"}, + {MediaType::BD_ROM, "BD-ROM"}, + {MediaType::BD_R, "BD-R"}, + {MediaType::BD_RE, "BD-RE"} + }; + + lb_available->setText(QObject::tr("Free Space %1").arg(FileUtils::formatSize(dp.avail))); + lb_mediatype->setText(rtypemap[dp.media]); + + auto isSupportedUD = [this, &dp]{ + if (!DFMGlobal::isProfessional()) + return false; + if (!BurnOptDialog::isSupportedUDVersion(curFSVersion)) + return false; + if (BurnOptDialog::isSupportedUDMedium(dp.media)) + return true; + return false; + }; + if (curFS == QString("u/d/f").remove("/") && !isSupportedUD()) { + if (DFMGlobal::isProfessional()) { // for other version, show normal unsupported writtings + lb_udsupport->setText(DFMOpticalMediaWidget::tr("%1 burning is not supported").arg("U/D/F").remove("/")); + icon_caution->setVisible(true); + icon_caution->load(QString(":/dark/icons/caution.svg")); + icon_caution->setFixedSize(14, 14); + icon_caution->setToolTip(DFMOpticalMediaWidget::tr("1. It is not %1 disc;\n2. The version of this file system does not support adding files yet.") + .arg("DVD+R, DVD-R, CD-R, CD-RW")); + } + lb_udsupport->setVisible(true); + pb_burn->setEnabled(false); + } else { + lb_udsupport->setVisible(false); + icon_caution->setVisible(false); + pb_burn->setEnabled(true); + } + + if (dp.avail == 0) { + lb_udsupport->setVisible(false); + icon_caution->setVisible(false); + } +} + +void DFMOpticalMediaWidgetPrivate::setCurrentDevice(const QString &dev) +{ + curdev = dev; + DeviceProperty dp = ISOMaster->getDevicePropertyCached(dev); + setDeviceProperty(dp); + + QString strKey = getVolTag(); + //fixed:CD display size error + if (dp.avail != 0 || DFMOpticalMediaWidget::g_mapCdStatusInfo[strKey].nTotal == 0) { + DFMOpticalMediaWidget::g_mapCdStatusInfo[strKey].nTotal = dp.data + dp.avail; + DFMOpticalMediaWidget::g_mapCdStatusInfo[strKey].nUsage = dp.data; + } + if (dp.avail == 0) // fix while available is zero, the button is still enable + pb_burn->setEnabled(false); + + QString tempMediaAddr = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); + + QString cachePath = tempMediaAddr + DISCBURN_CACHE_MID_PATH + strKey; + DFMOpticalMediaWidget::g_mapCdStatusInfo[strKey].cachePath = cachePath; + DFMOpticalMediaWidget::g_mapCdStatusInfo[strKey].bLoading = false; + + qDebug() << "get " << strKey << " catch path:" << cachePath; +} + +void DFMOpticalMediaWidgetPrivate::setCurrentFSByDev(const QString &dev) +{ + DAbstractFileInfoPointer fi(new DFMRootFileInfo(DUrl(DFMROOT_ROOT + dev.mid(QString("/dev/").length()) + "." SUFFIX_UDISKS))); + curFS = fi->extraProperties()["fsType"].toString().toLower(); + curFSVersion = fi->extraProperties()["fsVersion"].toString().toLower(); +} + +QString DFMOpticalMediaWidgetPrivate::getCurrentDevice() const +{ + return curdev; +} + +QString DFMOpticalMediaWidgetPrivate::getVolTag() +{ + QString strKey; + QStringList lst = curdev.split("/", QString::SkipEmptyParts); // /dev/sr0 -> { dev, sr0 } + if (lst.count() >= 2) + strKey = lst[1]; // strKey = + return strKey; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmopticalmediawidget.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmopticalmediawidget.h new file mode 100644 index 0000000..f32d842 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmopticalmediawidget.h @@ -0,0 +1,82 @@ +#ifndef DFMOPTICALMEDIAWIDGET_H +#define DFMOPTICALMEDIAWIDGET_H + +#include "app/define.h" +#include "dfileservices.h" + +#include + +DFM_BEGIN_NAMESPACE +class DFileStatisticsJob; +DFM_END_NAMESPACE +DFM_USE_NAMESPACE + +#define BURN_CAPACITY_ATTRIBUTE "BurnCapacityAttribute" // 光盘容量属性信息 + +#define BURN_CAPACITY_TOTAL_SIZE "BurnCapacityTotalSize" // 光盘容量总大小字节 +#define BURN_CAPACITY_USED_SIZE "BurnCapacityUsedSize" // 光盘容量已使用大小字节 +#define BURN_CAPACITY_STATUS "BurnCapacityStatus" // 光盘容量状态(DFMOpticalMediaWidget::BurnCapacityStatusAttribute) + +struct CdStatusInfo { + bool bVolFlag = false; + bool bMntFlag = false; + quint64 nUsage = 0; + quint64 nTotal = 0; + bool bReadyToBurn = false; + bool bBurningOrErasing = false; + bool bProcessLocked = false; + QString cachePath=""; // bug202007010027:添加文件缓存区,进行统一管理 + bool bLoading = false; // sp3 feature 35,光盘加载时显示光标为繁忙状态 +}; + +/** + * todo : 此类作为一个视图类,包含了太多职责/临时方案代码,应该拆分重构 + */ + +class DFMOpticalMediaWidgetPrivate; +class DFMOpticalMediaWidget : public QWidget +{ + Q_OBJECT +public: + //fix: 光盘容量属性: 光盘容量状态 + enum BurnCapacityStatusAttribute { + BCSA_BurnCapacityStatusEjct = 0, //光盘容量状态:0,光驱弹出状态 + BCSA_BurnCapacityStatusAdd, //光盘容量状态:1,光驱弹入处于添加未挂载状态 + BCSA_BurnCapacityStatusAddMount //光盘容量状态:2,光驱弹入处于添加后并挂载的状态 + }; + + //fixed:CD display size error + static QMap g_mapCdStatusInfo; + //fix: 动态获取刻录选中文件的字节大小 + static qint64 g_selectBurnFilesSize; + static qint64 g_selectBurnDirFileCount; + + explicit DFMOpticalMediaWidget(QWidget *parent); + ~DFMOpticalMediaWidget(); + + void updateDiscInfo(QString dev); + void setDiscMountPoint(const QString &strMntPath); + void setDefaultDiscName(const QString &name); + bool hasFileInDir(QDir dir); + QString getDiscMountPoint(); + //fix: 设置光盘容量属性 + static void setBurnCapacity(int status, QString strVolTag = ""); + + //根据url 获取光驱标签 + static QString getVolTag(const DUrl &fileUrl); + + //判断当前磁盘是否正忙碌 + static bool hasVolProcessBusy(); + + static CdStatusInfo* getCdStatusInfo(const QString& dev); + //fix: 动态更新光驱磁盘状态 +private slots: + void selectBurnFilesOptionUpdate(); + +private: + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(DFMOpticalMediaWidget) + DFileStatisticsJob *m_pStatisticWorker = nullptr; +}; + +#endif // DFMOPTICALMEDIAWIDGET_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmrightdetailview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmrightdetailview.cpp new file mode 100644 index 0000000..0bd0a2c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmrightdetailview.cpp @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Mike Chen + * + * Maintainer: Mike Chen + * + * 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 + * 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 . + */ +#include "dfmrightdetailview.h" +#include "dtagactionwidget.h" +#include "dfileservices.h" +#include "views/dfmfilebasicinfowidget.h" +#include "app/define.h" +#include "dfmtagwidget.h" +#include "singleton.h" +#include "controllers/pathmanager.h" +#include "controllers/vaultcontroller.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class DFMRightDetailViewPrivate +{ +public: + explicit DFMRightDetailViewPrivate(DFMRightDetailView *qq, const DUrl &url); + virtual ~DFMRightDetailViewPrivate(); + + DUrl m_url; + QVBoxLayout *mainLayout = nullptr; + QLabel *iconLabel = nullptr; + QFrame *baseInfoWidget = nullptr; + QFrame *separatorLine1 = nullptr; + QFrame *separatorLine2 = nullptr; + DFMTagWidget *tagInfoWidget = nullptr; + + QScrollArea *scrollArea = nullptr; + + DFMRightDetailView *q_ptr = nullptr; + D_DECLARE_PUBLIC(DFMRightDetailView) +}; + +DFMRightDetailViewPrivate::DFMRightDetailViewPrivate(DFMRightDetailView *qq, const DUrl &url) + : m_url(url), q_ptr(qq) +{ +} + +DFMRightDetailViewPrivate::~DFMRightDetailViewPrivate() +{ +} + +DFMRightDetailView::DFMRightDetailView(const DUrl &fileUrl, QWidget *parent) + : QFrame(parent), d_private(new DFMRightDetailViewPrivate(this, fileUrl)) +{ + AC_SET_OBJECT_NAME(this, AC_DM_RIGHT_VIEW_DETAIL_VIEW); + AC_SET_ACCESSIBLE_NAME(this, AC_DM_RIGHT_VIEW_DETAIL_VIEW); + + initUI(); + setUrl(fileUrl); +} + +DFMRightDetailView::~DFMRightDetailView() +{ +} + +static QFrame *createLine() +{ + DHorizontalLine *line = new DHorizontalLine(); + AC_SET_OBJECT_NAME(line, AC_DM_RIGHT_VIEW_MAIN_FRAME_LINE); + AC_SET_ACCESSIBLE_NAME(line, AC_DM_RIGHT_VIEW_MAIN_FRAME_LINE); + line->setFixedHeight(1); + line->setWindowFlags(Qt::WindowTransparentForInput); + return line; +} + +void DFMRightDetailView::initUI() +{ + Q_D(DFMRightDetailView); + d->scrollArea = new QScrollArea(this); + d->scrollArea->setObjectName("DFMRightDetailView-QScrollArea"); + AC_SET_ACCESSIBLE_NAME(d->scrollArea, AC_DM_RIGHT_VIEW_MAIN_FRAME_SCROLLAREA); + d->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff); + d->scrollArea->setAlignment(Qt::AlignTop); + d->scrollArea->setFrameShape(Shape::NoFrame); + + QVBoxLayout *layout = new QVBoxLayout; + layout->setAlignment(Qt::AlignCenter); + layout->addWidget(d->scrollArea); + layout->setContentsMargins(0, 0, 0, 0); + + setLayout(layout); + + d->mainLayout = new QVBoxLayout; + d->mainLayout->setAlignment(Qt::AlignCenter | Qt::AlignTop); + d->mainLayout->setSpacing(5); + + QFrame *mainFrame = new QFrame; + AC_SET_OBJECT_NAME(mainFrame, AC_DM_RIGHT_VIEW_MAIN_FRAME); + AC_SET_ACCESSIBLE_NAME(mainFrame, AC_DM_RIGHT_VIEW_MAIN_FRAME); + mainFrame->setLayout(d->mainLayout); + + d->iconLabel = new QLabel(this); + AC_SET_OBJECT_NAME(d->iconLabel, AC_DM_RIGHT_VIEW_MAIN_FRAME_ICON_LABEL); + AC_SET_ACCESSIBLE_NAME(d->iconLabel, AC_DM_RIGHT_VIEW_MAIN_FRAME_ICON_LABEL); + + d->iconLabel->setFixedSize(160, 160); + d->mainLayout->addWidget(d->iconLabel, 1, Qt::AlignHCenter); + + d->mainLayout->addWidget(d->separatorLine1 = createLine()); + d->mainLayout->addWidget(d->separatorLine2 = createLine()); + d->separatorLine1->setVisible(false); + d->separatorLine2->setVisible(false); + + initTagWidget(); + + // 默认值在此场景下无效 + d->mainLayout->addStretch(9999); + + mainFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + d->scrollArea->setWidget(mainFrame); + d->scrollArea->setWidgetResizable(true); +} + +void DFMRightDetailView::initTagWidget() +{ + Q_D(DFMRightDetailView); + d->tagInfoWidget = new DFMTagWidget(d->m_url, this); + d->tagInfoWidget->tagTitle()->setHidden(true); + d->tagInfoWidget->tagLeftTitle()->setHidden(false); + d->tagInfoWidget->setMaximumHeight(100); + d->mainLayout->addWidget(d->tagInfoWidget); + d->tagInfoWidget->setVisible(false); +} + +void DFMRightDetailView::setUrl(const DUrl &url) +{ + Q_D(DFMRightDetailView); + + if (!url.isValid()) + return; + + d->m_url = url; + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(this, d->m_url); + if (d->scrollArea) + d->scrollArea->setVisible(fileInfo); + if (d->separatorLine1) + d->separatorLine1->setVisible(fileInfo); + if (!fileInfo) + return; + bool shouldShowTags = fileInfo->canTag(); + setTagWidgetVisible(shouldShowTags); + if (d->tagInfoWidget) { + d->tagInfoWidget->loadTags(d->m_url); + } + if (d->iconLabel) { + QString iconName; + if (url == DUrl(RECENT_ROOT)) { + iconName = systemPathManager->getSystemPathIconName("Recent"); + } else if (url == DUrl(TRASH_ROOT)) { + iconName = systemPathManager->getSystemPathIconName("Trash"); + } else if (url.isNetWorkFile() || url.isSMBFile()) { + iconName = systemPathManager->getSystemPathIconName("Network"); + } else if (url.isUserShareFile()) { + iconName = systemPathManager->getSystemPathIconName("UserShare"); + } else if (VaultController::isRootDirectory(url.path())) { + iconName = systemPathManager->getSystemPathIconName("Vault"); + } + QIcon fileIcon = iconName.isEmpty() ? fileInfo->fileIcon() : QIcon::fromTheme(iconName); + QList iconSizeList = fileIcon.availableSizes(); + //缩放处理的图标,系统图标都是成队出现 + if (iconSizeList.size() == 1 + && iconSizeList.first().width() != iconSizeList.first().height()) { + QSize avaliSize = iconSizeList.first(); + QSize targetSize = avaliSize.scaled(d->iconLabel->height(), + d->iconLabel->height(), + Qt::KeepAspectRatio); + d->iconLabel->setPixmap(fileIcon.pixmap(targetSize)); + //自适应layout居中 + d->iconLabel->setFixedWidth(targetSize.width()); + } else { + d->iconLabel->setFixedSize(d->iconLabel->height(), d->iconLabel->height()); + d->iconLabel->setPixmap(fileIcon.pixmap(d->iconLabel->size())); + } + } + + if (d->baseInfoWidget) { + d->mainLayout->removeWidget(d->baseInfoWidget); + d->baseInfoWidget->setHidden(true); + d->baseInfoWidget->deleteLater(); + } + + DFMFileBasicInfoWidget *basicInfoWidget = new DFMFileBasicInfoWidget(this); + d->baseInfoWidget = basicInfoWidget; + basicInfoWidget->setShowFileName(true); + basicInfoWidget->setShowMediaInfo(true); + basicInfoWidget->setShowSummary(fileInfo->isDir()); + basicInfoWidget->setUrl(d->m_url); + d->mainLayout->insertWidget(2, d->baseInfoWidget); +} + +void DFMRightDetailView::setTagWidgetVisible(bool visible) +{ + Q_D(DFMRightDetailView); + if (d->tagInfoWidget) { + d->tagInfoWidget->setVisible(visible); + } + + if (d->separatorLine2) { + d->separatorLine2->setVisible(visible); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmrightdetailview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmrightdetailview.h new file mode 100644 index 0000000..510c7d5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmrightdetailview.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Mike Chen + * + * Maintainer: Mike Chen + * + * 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 + * 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 . + */ +#ifndef DFMRIGHTDETAILVIEW_H +#define DFMRIGHTDETAILVIEW_H + +#include +#include + +class DFMRightDetailViewPrivate; +class DFMRightDetailView : public QFrame{ + Q_OBJECT +public: + explicit DFMRightDetailView(const DUrl &fileUrl, QWidget *parent = nullptr); + virtual ~DFMRightDetailView(); + + void setUrl(const DUrl &url); + void setTagWidgetVisible(bool visible); +protected: + void initUI(); + void initTagWidget(); + void LoadFileTags(); + +private: + QScopedPointer d_private; + Q_DECLARE_PRIVATE_D(d_private, DFMRightDetailView) + +}; + + +#endif // DFMRIGHTDETAILVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebar.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebar.cpp new file mode 100644 index 0000000..fc2c181 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebar.cpp @@ -0,0 +1,1098 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ +#include "dfmsidebar.h" + +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "dabstractfilewatcher.h" +#include "dfilemanagerwindow.h" +#include "dfileservices.h" +#include "singleton.h" +#include "app/define.h" +#include "drootfilemanager.h" +#include "dtoolbar.h" +#include "utils.h" +#include "dfmsidebarmanager.h" +#include "dfmsidebaritemdelegate.h" +#include "dfmsidebaritem.h" +#include "dfmopticalmediawidget.h" + +#include "interfaces/dfmsidebariteminterface.h" +#include "views/dfmsidebarview.h" +#include "models/dfmsidebarmodel.h" +#include "models/dfmrootfileinfo.h" +#include "controllers/dfmsidebardefaultitemhandler.h" +#include "controllers/dfmsidebarbookmarkitemhandler.h" +#include "controllers/dfmsidebardeviceitemhandler.h" +#include "controllers/dfmsidebartagitemhandler.h" +#include "controllers/dfmsidebarvaultitemhandler.h" // 保险柜 +#include "controllers/vaultcontroller.h" +#include "controllers/pathmanager.h" +#include "app/filesignalmanager.h" +#include "vault/vaulthelper.h" +#include "interfaces/dfilemenu.h" +#include "accessibility/ac-lib-file-manager.h" +#include "deviceinfo/udisklistener.h" +#include "shutil/fileutils.h" +#include "dtoolbar.h" +#include "utils.h" +#include "controllers/bookmarkmanager.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "plugins/schemepluginmanager.h" + +#define SIDEBAR_ITEMORDER_KEY "SideBar/ItemOrder" + +DFM_BEGIN_NAMESPACE + +DFMSideBar::DFMSideBar(QWidget *parent) + : QWidget(parent), + m_sidebarView(new DFMSideBarView(this)), + m_sidebarModel(new DFMSideBarModel(this)) +{ + AC_SET_OBJECT_NAME(this, AC_DM_SIDE_BAR); + AC_SET_ACCESSIBLE_NAME(this, AC_DM_SIDE_BAR); + + // init view. + m_sidebarView->setModel(m_sidebarModel); + m_sidebarView->setItemDelegate(new DFMSideBarItemDelegate(m_sidebarView)); + m_sidebarView->setViewportMargins(10, 0, m_sidebarView->verticalScrollBar()->sizeHint().width(), 0); + m_sidebarView->setContextMenuPolicy(Qt::CustomContextMenu); + m_sidebarView->setFrameShape(QFrame::Shape::NoFrame); + m_sidebarView->setAutoFillBackground(true); + + initUI(); + initModelData(); + initConnection(); + initUserShareItem(); + initRecentItem(); + + // DFMSideBarManager::instance(); + //NOTE [XIAO] 从Plugin中导入SideBarItem + initItemFromPlugin(); +} + +DFMSideBar::~DFMSideBar() +{ +#ifdef ENABLE_ASYNCINIT + m_initDevThread.first = true; + m_initDevThread.second.waitForFinished(); +#endif +} + +QWidget *DFMSideBar::sidebarView() +{ + return m_sidebarView; +} + +QRect DFMSideBar::groupGeometry(const QString &groupName) +{ + return m_sidebarView->visualRect(groupModelIndex(groupName)); +} + +void DFMSideBar::scrollToGroup(const QString &groupName) +{ + m_sidebarView->scrollTo(groupModelIndex(groupName)); +} + +void DFMSideBar::setCurrentUrl(const DUrl &url, bool changeUrl) +{ + QMutexLocker lk(&m_currentUrlMutex); + m_currentUrl = changeUrl ? url : m_currentUrl; + int index = findItem(m_currentUrl, true); + if (index != -1) { + m_sidebarView->setCurrentIndex(m_sidebarModel->index(index, 0)); + m_sidebarView->updateItemUniqueKey(m_sidebarView->currentIndex()); + } else { + m_sidebarView->clearSelection(); + } +} + +int DFMSideBar::addItem(DFMSideBarItem *item, const QString &group) +{ + if (!item) { + return 0; + } + int lastAtGroup = findLastItem(group, false); + lastAtGroup++; // append after the last item + this->insertItem(lastAtGroup, item, group); + + return lastAtGroup; +} + +bool DFMSideBar::removeItem(const DUrl &url, const QString &group) +{ + int index = findItem(url, group); + bool succ = false; + if (index >= 0) { + succ = m_sidebarModel->removeRow(index); + } + + return succ; +} + +int DFMSideBar::findItem(const DFMSideBarItem *item) const +{ + return m_sidebarModel->indexFromItem(item).row(); +} + +int DFMSideBar::findItem(const DUrl &url, const QString &group) const +{ + for (int i = 0, nEnd = m_sidebarModel->rowCount(); i < nEnd; ++i) { + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(i); + const auto &itemType = item->itemType(); + const auto &itemGroupName = item->groupName(); + if (itemType == DFMSideBarItem::SidebarItem && itemGroupName == group) { + const auto &itemUrl = item->url(); + if (itemUrl == url) { + return i; + } + } + } + + return -1; +} + +/*! + * \brief Find the index of the first item match the given \a url + * + * \return the index of the item we can found, or -1 if not found. + */ +int DFMSideBar::findItem(const DUrl &url, bool fuzzy/* = false*/) const +{ + for (int i = 0; i < m_sidebarModel->rowCount(); i++) { + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(i); + if (item->itemType() == DFMSideBarItem::SidebarItem) { + if (item->url() == url) + return i; + + if (!fuzzy) + continue; + + DUrl itemUrl = item->url(); + if (itemUrl.isBookMarkFile() && DUrl(itemUrl.path()) == url) { + return i; + } else if (itemUrl.scheme() == DFMROOT_SCHEME) { + DAbstractFileInfoPointer pointer = DFileService::instance()->createFileInfo(nullptr, itemUrl); + if (!pointer) + continue; + if (pointer->redirectedFileUrl() == url) + return i; + } + } + } + + return -1; +} + +int DFMSideBar::findItem(std::function cb) const +{ + for (int i = 0; i < m_sidebarModel->rowCount(); i++) { + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(i); + if (cb(item)) { + return i; + } + } + + return -1; +} + +int DFMSideBar::findLastItem(const QString &group, bool sidebarItemOnly) const +{ + int index = -1; + for (int i = 0; i < m_sidebarModel->rowCount(); i++) { + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(i); + if (item->groupName() == group && (item->itemType() == DFMSideBarItem::SidebarItem || !sidebarItemOnly)) { + index = i; + } else if (item->groupName() != group && index != -1) { + // already found the group and already leaved the group + break; + } + } + + return index; +} + +void DFMSideBar::openItemEditor(int index) const +{ + m_sidebarView->edit(m_sidebarModel->index(index, 0)); +} + +QSet DFMSideBar::disableUrlSchemes() const +{ + return m_disableUrlSchemes; +} + +void DFMSideBar::setContextMenuEnabled(bool enabled) +{ + m_contextMenuEnabled = enabled; +} + +void DFMSideBar::setDisableUrlSchemes(const QSet &schemes) +{ + m_disableUrlSchemes += schemes; + for (QString scheme : m_disableUrlSchemes) { + forever { + int index = findItem([&](const DFMSideBarItem * item) -> bool { + return item->url().scheme() == scheme; + }); + + if (index >= 0) { + m_sidebarModel->removeRow(index); + } else { + break; + } + } + } + + emit disableUrlSchemesChanged(); +} + +DUrlList DFMSideBar::savedItemOrder(const QString &groupName) const +{ + DUrlList list; + + QStringList savedList = DFMApplication::genericSetting()->value(SIDEBAR_ITEMORDER_KEY, groupName).toStringList(); + for (const QString &item : savedList) { + list << DUrl(item); + } + + return list; +} + +void DFMSideBar::saveItemOrder(const QString &groupName) const +{ + QVariantList list; + + for (int i = 0; i < m_sidebarModel->rowCount(); i++) { + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(m_sidebarModel->index(i, 0)); + if (item->itemType() == DFMSideBarItem::SidebarItem && item->groupName() == groupName) { + list << QVariant(item->url()); + } + } + + DFMApplication::genericSetting()->setValue(SIDEBAR_ITEMORDER_KEY, groupName, list); +} + +QString DFMSideBar::groupName(DFMSideBar::GroupName group) +{ + Q_ASSERT(group != Unknow); + + switch (group) { + case Common: + return "common"; + case Device: + return "device"; + case Bookmark: + return "bookmark"; + case Network: + return "network"; + case Tag: + return "tag"; + case Other: // deliberate + default: + break; + } + + return QString(); +} + +DFMSideBar::GroupName DFMSideBar::groupFromName(const QString &name) +{ + if (name.isEmpty()) { + return Other; + } + + switch (name.toLatin1().at(0)) { + case 'c': + if (name == QStringLiteral("common")) { + return Common; + } + + break; + case 'd': + if (name == QStringLiteral("device")) { + return Device; + } + + break; + case 'b': + if (name == QStringLiteral("bookmark")) { + return Bookmark; + } + + break; + case 'n': + if (name == QStringLiteral("network")) { + return Network; + } + + break; + case 't': + if (name == QStringLiteral("tag")) { + return Tag; + } + + break; + default: + break; + } + + return Unknow; +} + +void DFMSideBar::rootFileResult() +{ + QList filist = rootFileManager->getRootFile(); + qDebug() << "DFileService::instance()->getRootFile() filist:" << filist.size(); + if (filist.isEmpty()) + return; + + for (const DAbstractFileInfoPointer &fi : filist) { +#ifdef ENABLE_ASYNCINIT + if (m_initDevThread.first){ + qDebug() << "thrad cancled" << this; + return; + } +#endif + if (static_cast(fi->fileType()) != DFMRootFileInfo::ItemType::UserDirectory) { + if (devitems.contains(fi->fileUrl())) { + continue; + } + if (Singleton::instance()->isVisiblePartitionPath(fi)) { + // 这里需要根据url进行排序 + const auto &url = fi->fileUrl(); + auto r = std::upper_bound(devitems.begin(), devitems.end(), url, + [](const DUrl & a, const DUrl & b) { + DAbstractFileInfoPointer fia = fileService->createFileInfo(nullptr, a); + DAbstractFileInfoPointer fib = fileService->createFileInfo(nullptr, b); + return DFMRootFileInfo::typeCompare(fia, fib); + }); + if (r == devitems.end()) { + this->addItem(DFMSideBarDeviceItemHandler::createItem(url), this->groupName(Device)); + devitems.append(url); + } else { + this->insertItem(this->findLastItem(this->groupName(Device)) - (devitems.end() - r) + 1, DFMSideBarDeviceItemHandler::createItem(url), this->groupName(Device)); + devitems.insert(r, url); + } + } + } + } +} + +void DFMSideBar::onItemActivated(const QModelIndex &index) +{ + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(index); + QString identifierStr = item->registeredHandler(SIDEBAR_ID_INTERNAL_FALLBACK); + + if (m_lastToggleTime.isValid() && m_lastToggleTime.addMSecs(500) > QDateTime::currentDateTime() + && m_pLastToggleItem == item) { + m_lastToggleTime = QDateTime::currentDateTime(); + return; + } + m_lastToggleTime = QDateTime::currentDateTime(); + m_pLastToggleItem = item; + + QScopedPointer interface(DFMSideBarManager::instance()->createByIdentifier(identifierStr)); + if (interface) { + // searchBarTextEntered also invoke "checkGvfsMountFileBusy", forbit invoke twice + if (item->url().path().endsWith(SUFFIX_STASHED_REMOTE)) { + DFileManagerWindow *window = qobject_cast(this->window()); + if (window) { + auto path = RemoteMountsStashManager::normalizeConnUrl(item->url().path()); + window->getToolBar()->searchBarTextEntered(path); + return; + } + } + + + //判断网络文件是否可以到达 + if (DFileService::instance()->checkGvfsMountfileBusy(item->url())) { + return; + } + DFileService::instance()->setCursorBusyState(true); + interface->cdAction(this, item); + + DFileService::instance()->setCursorBusyState(DFMOpticalMediaWidget::hasVolProcessBusy()); + } +} + +void DFMSideBar::onContextMenuRequested(const QPoint &pos) +{ + // block signals to avoid function reentrant. + const QSignalBlocker blocker(this); + + if (!m_contextMenuEnabled) return; + + + QModelIndex modelIndex = m_sidebarView->indexAt(pos); + if (!modelIndex.isValid()) { + return; + } + + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(modelIndex); + if (!item || item->itemType() == DFMSideBarItem::Separator) { + return ; // separator should not show menu + } + QString identifierStr = item->registeredHandler(SIDEBAR_ID_INTERNAL_FALLBACK); + DFileService::instance()->setCursorBusyState(true); + QScopedPointer interface(DFMSideBarManager::instance()->createByIdentifier(identifierStr)); + QMenu *menu = nullptr; + if (interface) { + menu = interface->contextMenu(this, item); + if (menu) { + // 如果光驱正在执行刻录/擦除操作,禁用光驱的右键菜单 + QString strVolTag = item->url().path().remove("/").remove(".localdisk"); // /sr0.localdisk 去头去尾 + if (strVolTag.startsWith("sr") && DFMOpticalMediaWidget::g_mapCdStatusInfo[strVolTag].bBurningOrErasing) { + for (QAction *act : menu->actions()) + act->setEnabled(false); + } + DFileMenu *fmenu = qobject_cast(menu); + DFileService::instance()->setCursorBusyState(false); + if (fmenu) { + //fix bug 33305 在用右键菜单复制大量文件时,在复制过程中,关闭窗口这时this释放了, + //在关闭拷贝menu的exec退出,menu的deleteLater崩溃 + QPointer me = this; + fmenu->exec(this->mapToGlobal(pos)); + fmenu->deleteLater(me); + } else { + menu->exec(this->mapToGlobal(pos)); + menu->deleteLater(); + } + } + DFileService::instance()->setCursorBusyState(false); + } + DFileService::instance()->setCursorBusyState(false); +} + +void DFMSideBar::onRename(const QModelIndex &index, QString newName) const +{ + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(index); + QString identifierStr = item->registeredHandler(SIDEBAR_ID_INTERNAL_FALLBACK); + + QScopedPointer interface(DFMSideBarManager::instance()->createByIdentifier(identifierStr)); + if (interface && !newName.isEmpty() && item->text() != newName) { + interface->rename(item, newName); + } + if(m_sidebarView) + m_sidebarView->update(); +} + +void DFMSideBar::initUI() +{ + // init layout. + QVBoxLayout *layout = new QVBoxLayout(this); + layout->addWidget(m_sidebarView); + + layout->setMargin(0); + layout->setSpacing(0); + + this->setMaximumWidth(200); + this->setFocusProxy(m_sidebarView); + + applySidebarColor(); +} + +void DFMSideBar::initModelData() +{ + // register meta type for DUrl, since we use it in item view DnD operation. + qRegisterMetaTypeStreamOperators("DUrl"); + + static QList groups = { + //NOTE [REN] 添加Plugin类型,实现插件组的分割线 + + GroupName::Common, GroupName::Device, GroupName::Bookmark, GroupName::Network, GroupName::Tag, GroupName::Plugin + }; + + //bool hasSeparator = false; + foreach (const DFMSideBar::GroupName &groupType, groups) { +#ifdef DISABLE_TAG_SUPPORT + if (groupType == DFMSideBar::GroupName::Tag) continue; +#endif // DISABLE_TAG_SUPPORT + + m_sidebarModel->appendRow(DFMSideBarItem::createSeparatorItem(groupName(groupType))); + + addGroupItems(groupType); + } + + // init done, then we should update the separator visible state. + updateSeparatorVisibleState(); +} + +void DFMSideBar::initConnection() +{ + connect(DFMApplication::instance(), &DFMApplication::reloadComputerModel, this, [this]{ + bool vaultEnable = VaultHelper::isVaultEnabled(); + if (vaultEnable) { + // if vault is enabled, check if it is exist in sidebar + int index = findItem([&](const DFMSideBarItem *item) {return item->url().scheme() == DFMVAULT_SCHEME;}); + if (index > 0) + return; + + // otherwise insert it just below computer item + index = findItem([&](const DFMSideBarItem *item) {return item->url().scheme() == COMPUTER_SCHEME;}); + if (index > 0) + this->insertItem(index+1, DFMSideBarVaultItemHandler::createItem("Vault"), groupName(GroupName::Device)); + } else { + // check if vault item is in sidebar + int index = findItem([&](const DFMSideBarItem *item) {return item->url().scheme() == DFMVAULT_SCHEME;}); + if (index < 0) + return; + this->m_sidebarModel->removeRow(index); + } + }); + + // drag to delete bookmark or tag + connect(m_sidebarView, &DFMSideBarView::requestRemoveItem, this, [this]() { + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(m_sidebarView->currentIndex()); + if (item && item->flags().testFlag(Qt::ItemIsEnabled) && item->flags().testFlag(Qt::ItemIsDragEnabled)) { + DFileService::instance()->deleteFiles(nullptr, DUrlList{item->url()}, false); + } + }); + // do `cd` work + connect(m_sidebarView, &QListView::activated, this, &DFMSideBar::onItemActivated); + + // we need single click also trigger activated() + connect(m_sidebarView, &QListView::clicked, this, &DFMSideBar::onItemActivated); + + // context menu + connect(m_sidebarView, &QListView::customContextMenuRequested, this, &DFMSideBar::onContextMenuRequested); + + // so no extra separator if a group is empty. + // since we do this, ensure we do initConnection() after initModelData(). + connect(m_sidebarModel, &QStandardItemModel::rowsInserted, this, &DFMSideBar::updateSeparatorVisibleState); + connect(m_sidebarModel, &QStandardItemModel::rowsRemoved, this, &DFMSideBar::updateSeparatorVisibleState); + connect(m_sidebarModel, &QStandardItemModel::rowsMoved, this, &DFMSideBar::updateSeparatorVisibleState); + // drag to move item will emit rowsInserted and rowsMoved.. + connect(m_sidebarModel, &QStandardItemModel::rowsRemoved, this, + [this](const QModelIndex & parent, int first, int last) { + Q_UNUSED(parent); + Q_UNUSED(last); + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(first); + if (!item) { + item = m_sidebarModel->itemFromIndex(first - 1); + } + + // only bookmark and tag item are DragEnabled + if (item && item->flags().testFlag(Qt::ItemIsEnabled) && item->flags().testFlag(Qt::ItemIsDragEnabled)) { + saveItemOrder(item->groupName()); + } + }); + DFMSideBarItemDelegate *idelegate = dynamic_cast(m_sidebarView->itemDelegate()); + if (idelegate) { + connect(idelegate, &DFMSideBarItemDelegate::rename, this, &DFMSideBar::onRename); + } + + connect(fileSignalManager, &FileSignalManager::requestRename, this, [this](const DFMUrlBaseEvent & event) { + if (event.sender() == this) { + this->openItemEditor(this->findItem(event.url())); + } + }); + + initBookmarkConnection(); +#ifdef ENABLE_ASYNCINIT + m_initDevThread.first = false; + m_initDevThread.second = QtConcurrent::run([this](){initDeviceConnection();}); +#else + initDeviceConnection(); +#endif + + initTagsConnection(); +} + +void DFMSideBar::initUserShareItem() +{ + int count = DFileService::instance()->getChildren(nullptr, DUrl::fromUserShareFile("/"), + QStringList(), QDir::AllEntries).count(); + if (count) { + addItem(DFMSideBarDefaultItemHandler::createItem("UserShare"), groupName(Network)); + } + + DAbstractFileWatcher *userShareFileWatcher = DFileService::instance()->createFileWatcher(this, DUrl::fromUserShareFile("/"), this); + Q_CHECK_PTR(userShareFileWatcher); + userShareFileWatcher->startWatcher(); + + auto deleteUserShareLambda = [ = ](const DUrl & url) { + Q_UNUSED(url) + int cnt = DFileService::instance()->getChildren(nullptr, DUrl::fromUserShareFile("/"), + QStringList(), QDir::AllEntries).count(); + int index = findItem(DUrl::fromUserShareFile("/")); + m_sidebarView->setRowHidden(index, cnt == 0); + }; + + auto addUserShareLambda = [ = ](const DUrl & url) { + Q_UNUSED(url) + int cnt = DFileService::instance()->getChildren(nullptr, DUrl::fromUserShareFile("/"), + QStringList(), QDir::AllEntries).count(); + int index = findItem(DUrl::fromUserShareFile("/")); + if (index == -1) { + if (cnt > 0) { + addItem(DFMSideBarDefaultItemHandler::createItem("UserShare"), groupName(Network)); + } + } else { + // DFileService::instance()->changeRootFile(url,false); + m_sidebarView->setRowHidden(index, false); + } + emit addUserShareItemFinished(url); + }; + + connect(userShareFileWatcher, &DAbstractFileWatcher::fileDeleted, this, deleteUserShareLambda); + connect(userShareFileWatcher, &DAbstractFileWatcher::subfileCreated, this, addUserShareLambda); +} + +void DFMSideBar::initRecentItem() +{ + auto recentLambda = [ = ](bool enable) { + int index = findItem(DUrl(RECENT_ROOT), groupName(Common)); + if (index) { + m_sidebarView->setRowHidden(index, !enable); + if (!enable) { + // jump out of recent:/// + DAbstractFileWatcher::ghostSignal(DUrl(RECENT_ROOT), &DAbstractFileWatcher::fileDeleted, DUrl(RECENT_ROOT)); + } + } + }; + + recentLambda(DFMApplication::instance()->genericAttribute(DFMApplication::GA_ShowRecentFileEntry).toBool()); + connect(DFMApplication::instance(), &DFMApplication::recentDisplayChanged, this, recentLambda); +} + +void DFMSideBar::initBookmarkConnection() +{ + DAbstractFileWatcher *bookmarkWatcher = DFileService::instance()->createFileWatcher(this, DUrl(BOOKMARK_ROOT), this); + if (!bookmarkWatcher) return; + + bookmarkWatcher->startWatcher(); + + connect(bookmarkWatcher, &DAbstractFileWatcher::subfileCreated, this, + [this](const DUrl & url) { + // DFileService::instance()->changeRootFile(url); + const QString &groupNameStr = groupName(Bookmark); + this->addItem(DFMSideBarBookmarkItemHandler::createItem(url), groupNameStr); + this->saveItemOrder(groupNameStr); + }); + + connect(bookmarkWatcher, &DAbstractFileWatcher::fileDeleted, this, + [this](const DUrl & url) { + qDebug() << url; + int index = findItem(url, groupName(Bookmark)); + if (index >= 0) { + // DFileService::instance()->changeRootFile(url,false); + m_sidebarModel->removeRow(index); + this->saveItemOrder(groupName(Bookmark)); + } + }); + + connect(bookmarkWatcher, &DAbstractFileWatcher::fileMoved, this, + [this](const DUrl & source, const DUrl & target) { + int index = findItem(source, groupName(Bookmark)); + if (index > 0) { + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(index); + if (item) { + item->setText(target.bookmarkName()); + item->setUrl(target); + this->saveItemOrder(groupName(Bookmark)); + } + } + }); + + bookmarkManager->refreshBookmark(); +} + +void DFMSideBar::initDeviceConnection() +{ + // 获取遍历结果进行显示 + connect(DRootFileManager::instance(),&DRootFileManager::queryRootFileFinsh,this,[this](){ + rootFileResult(); + },Qt::QueuedConnection); + + connect(DRootFileManager::instance(),&DRootFileManager::serviceHideSystemPartition,this,[this](){ + QList removelist; + for (auto itemurl : devitems) { + if (!DRootFileManager::instance()->isRootFileContain(itemurl)) { + removelist.push_back(itemurl); + } + } + for (auto removeurl : removelist) { + devitems.removeOne(removeurl); + removeItem(removeurl, groupName(Device)); + } + rootFileResult(); + },Qt::QueuedConnection); + + // 已经初始化了就直接拿结果 + if (DRootFileManager::instance()->isRootFileInited()) { + rootFileResult(); + } + // 开启遍历线程,刷新一次root,修复分区问题 + DRootFileManager::instance()->startQuryRootFile(); + + DAbstractFileWatcher *devicesWatcher = rootFileManager->rootFileWather(); + connect(devicesWatcher, &DAbstractFileWatcher::subfileCreated, this, [this](const DUrl &url) { + auto fi = fileService->createFileInfo(nullptr, url); + if (!fi->exists()) { + return; + } + + if (!Singleton::instance()->isVisiblePartitionPath(fi)) { + return; + } + + if (this->findItem(url) == -1) { + auto r = std::upper_bound(devitems.begin(), devitems.end(), url, + [](const DUrl & a, const DUrl & b) { + DAbstractFileInfoPointer fia = fileService->createFileInfo(nullptr, a); + DAbstractFileInfoPointer fib = fileService->createFileInfo(nullptr, b); + return DFMRootFileInfo::typeCompare(fia, fib); + }); + if (r == devitems.end()) { + //DFileService::instance()->changeRootFile(url); //性能优化,注释 + this->addItem(DFMSideBarDeviceItemHandler::createItem(url), this->groupName(Device)); + devitems.append(url); + } else { + //DFileService::instance()->changeRootFile(url); //性能优化,注释 + this->insertItem(this->findLastItem(this->groupName(Device)) - (devitems.end() - r) + 1, DFMSideBarDeviceItemHandler::createItem(url), this->groupName(Device)); + devitems.insert(r, url); + } + //还原url + if (m_currentUrl == fi->redirectedFileUrl()) + setCurrentUrl(m_currentUrl, false); + } + }); + connect(devicesWatcher, &DAbstractFileWatcher::fileDeleted, this, [this](const DUrl & url) { + bool curUrlCanAccess = true; // 初始化为true 避免影响原有逻辑 + auto fi = fileService->createFileInfo(nullptr, m_currentUrl); + if (fi) + curUrlCanAccess = fi->exists(); + int index = findItem(url, groupName(Device)); + int curIndex = m_sidebarView->currentIndex().row(); + if ((curIndex == index && index != -1) + || (!curUrlCanAccess)) { + + DUrl urlSkip; + const QString &absFilePath = url.toAbsolutePathUrl().path(); + QString localFilePath = QUrl::fromPercentEncoding(url.path().toLocal8Bit()); + localFilePath = localFilePath.startsWith("//") ? localFilePath.mid(1) : localFilePath; + + const auto &allDevice = deviceListener->getAllDeviceInfos(); + bool blockDevice = false; + for (const auto &dev : allDevice.keys()) { + if (dev.contains(absFilePath.left(absFilePath.indexOf(".localdisk")))) { + blockDevice = true; + break; + } + } + + // 判断删除的路径是否是外设路径,外设路径需要跳转到computer页面 + bool turnToComputer = false; + if (deviceListener->isInDeviceFolder(absFilePath) + || localFilePath.startsWith("/run/user") + || localFilePath.startsWith("/media/") + || blockDevice // like u disk + || FileUtils::isGvfsMountFile(localFilePath) + ) { + urlSkip = DUrl(COMPUTER_ROOT); + turnToComputer = true; + } else { + urlSkip = DUrl::fromLocalFile(QDir::homePath()); + } + + index = findItem(urlSkip, groupName(turnToComputer ? Device : Common)); + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(index); + if (item) { + QString identifierStr = item->registeredHandler(SIDEBAR_ID_INTERNAL_FALLBACK); + QScopedPointer interface(DFMSideBarManager::instance()->createByIdentifier(identifierStr)); + if (interface) { + interface->cdAction(this, item); + } + } + } + //DFileService::instance()->changeRootFile(url,false); //性能优化,注释 + this->removeItem(url, this->groupName(Device)); + devitems.removeAll(url); + }); + connect(devicesWatcher, &DAbstractFileWatcher::fileAttributeChanged, this, [this](const DUrl & url) { + int index = findItem(url, groupName(Device)); + DAbstractFileInfoPointer fi = DFileService::instance()->createFileInfo(nullptr, url); + + if (!~index || !fi) { + return; + } + + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(index); + DViewItemActionList actionList = item->actionList(Qt::RightEdge); + auto list = fi->menuActionList(); + if (!actionList.isEmpty()) { + actionList.front()->setVisible(list.contains(MenuAction::Eject) || + list.contains(MenuAction::Unmount) || + list.contains(MenuAction::SafelyRemoveDrive)); + } + + item->setText(fi->fileDisplayName()); + + Qt::ItemFlags flags = item->flags() & (~Qt::ItemFlag::ItemIsEditable); + if (fi->menuActionList().contains(MenuAction::Rename)) { + flags |= Qt::ItemFlag::ItemIsEditable; + } + item->setFlags(flags); + }); +} + +void DFMSideBar::initTagsConnection() +{ +#ifdef DISABLE_TAG_SUPPORT + return; +#endif + + DAbstractFileWatcher *tagsWatcher = DFileService::instance()->createFileWatcher(this, DUrl(TAG_ROOT), this); + Q_CHECK_PTR(tagsWatcher); + tagsWatcher->startWatcher(); + + QString groupNameStr(groupName(Tag)); + + // New tag added. + connect(tagsWatcher, &DAbstractFileWatcher::subfileCreated, this, [this, groupNameStr](const DUrl & url) { + // DFileService::instance()->changeRootFile(url); + this->addItem(DFMSideBarTagItemHandler::createItem(url), groupNameStr); + this->saveItemOrder(groupNameStr); + }); + + // Tag get removed. + connect(tagsWatcher, &DAbstractFileWatcher::fileDeleted, this, [this, groupNameStr](const DUrl & url) { + // DFileService::instance()->changeRootFile(url,false); + this->removeItem(url, groupNameStr); + this->saveItemOrder(groupNameStr); + }); + + // Tag got rename + connect(tagsWatcher, &DAbstractFileWatcher::fileMoved, this, + [this, groupNameStr](const DUrl & source, const DUrl & target) { + int index = findItem(source, groupNameStr); + if (index >= 0) { + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(index); + item->setText(target.tagName()); + item->setUrl(target); + this->saveItemOrder(groupNameStr); + } + }); + + // // Tag changed color + // q->connect(tagsWatcher, &DAbstractFileWatcher::fileAttributeChanged, group, [group](const DUrl & url) { + // DFMSideBarItem *item = group->findItem(url); + // item->setIconFromThemeConfig("BookmarkItem." + TagManager::instance()->getTagColorName(url.tagName())); + // }); +} + +//NOTE [XIAO] 从Plugin中导入SideBarItem +void DFMSideBar::initItemFromPlugin() +{ + // tab标签页不会显示“我的手机”,因为路径初始化的时候还没有开始加载插件 + // 在这里插件已经加载过所以调用initPaths再加载一下插件的路径 add by CL + Singleton::instance()->initPaths(); + qWarning() << "[PLUGIN]" << "try to load plugin of sidebar item"; + auto plugins = SchemePluginManager::instance()->schemePlugins(); + for (auto plugin : plugins) { + qWarning() << "[PLUGIN]" << "load sidebar item from plugin:" << plugin.first; + DFMSideBarItem *item = plugin.second->createSideBarItem(); + // NOTE [XIAO] 插件中的GroupName与文管版本中一致。 + //this->addItem(item, item->groupName()); + this->appendItem(item, item->groupName()); + } +} + +void DFMSideBar::applySidebarColor() +{ + m_sidebarView->setBackgroundType(DStyledItemDelegate::BackgroundType(DStyledItemDelegate::RoundedBackground | DStyledItemDelegate::NoNormalState)); + m_sidebarView->setItemSpacing(0); +} + +void DFMSideBar::updateSeparatorVisibleState() +{ + QString lastGroupName = "__not_existed_group"; + int lastGroupItemCount = 0; + int lastSeparatorIndex = -1; + + for (int i = 0; i < m_sidebarModel->rowCount(); i++) { + DFMSideBarItem *item = m_sidebarModel->itemFromIndex(i); + if (item->groupName() != lastGroupName) { + if (item->itemType() == DFMSideBarItem::Separator) { + m_sidebarView->setRowHidden(i, lastGroupItemCount == 0); + lastSeparatorIndex = i; + lastGroupItemCount = 0; + lastGroupName = item->groupName(); + } + } else { + if (item->itemType() == DFMSideBarItem::SidebarItem) { + lastGroupItemCount++; + } + } + } + + // hide the last one if last group is empty + if (lastGroupItemCount == 0) { + m_sidebarView->setRowHidden(lastSeparatorIndex, true); + } +} + +void DFMSideBar::addGroupItems(DFMSideBar::GroupName groupType) +{ + const QString &groupNameStr = groupName(groupType); + switch (groupType) { + case GroupName::Common: + if (!m_disableUrlSchemes.contains(RECENT_SCHEME)) { + appendItem(DFMSideBarDefaultItemHandler::createItem("Recent"), groupNameStr); + } + appendItem(DFMSideBarDefaultItemHandler::createItem("Home"), groupNameStr); + appendItem(DFMSideBarDefaultItemHandler::createItem("Desktop"), groupNameStr); + appendItem(DFMSideBarDefaultItemHandler::createItem("Videos"), groupNameStr); + appendItem(DFMSideBarDefaultItemHandler::createItem("Music"), groupNameStr); + appendItem(DFMSideBarDefaultItemHandler::createItem("Pictures"), groupNameStr); + appendItem(DFMSideBarDefaultItemHandler::createItem("Documents"), groupNameStr); + appendItem(DFMSideBarDefaultItemHandler::createItem("Downloads"), groupNameStr); + if (!m_disableUrlSchemes.contains(TRASH_SCHEME)) { + appendItem(DFMSideBarDefaultItemHandler::createItem("Trash"), groupNameStr); + } + break; + case GroupName::Device: { + if (!m_disableUrlSchemes.contains(COMPUTER_SCHEME)) { + appendItem(DFMSideBarDefaultItemHandler::createItem("Computer"), groupNameStr); + } + // 判断系统类型,决定是否启用保险箱 + if (VaultHelper::isVaultEnabled()) { + if (!m_disableUrlSchemes.contains(DFMVAULT_SCHEME)) { + appendItem(DFMSideBarVaultItemHandler::createItem("Vault"), groupNameStr); + } + } + break; + } + case GroupName::Bookmark: { + if (m_disableUrlSchemes.contains(BOOKMARK_SCHEME)) { + break; + } + + const DUrlList urlList = bookmarkManager->getBookmarkUrls(); + QList unsortedList; + for (const DUrl &url : urlList) { + unsortedList << DFMSideBarBookmarkItemHandler::createItem(url); + } + appendItemWithOrder(unsortedList, savedItemOrder(groupNameStr), groupNameStr); + break; + } + case GroupName::Network: + if (m_disableUrlSchemes.contains(NETWORK_SCHEME)) { + break; + } + appendItem(DFMSideBarDefaultItemHandler::createItem("Network"), groupNameStr); + break; + case GroupName::Tag: { + if (m_disableUrlSchemes.contains(TAG_SCHEME)) { + break; + } + + auto tag_infos = DFileService::instance()->getChildren(this, DUrl(TAG_ROOT), + QStringList(), QDir::AllEntries); + QList unsortedList; + for (const DAbstractFileInfoPointer &info : tag_infos) { + unsortedList << DFMSideBarTagItemHandler::createItem(info->fileUrl()); + } + appendItemWithOrder(unsortedList, savedItemOrder(groupNameStr), groupNameStr); + break; + } + default: + break; + } +} + +void DFMSideBar::insertItem(int index, DFMSideBarItem *item, const QString &groupName) +{ + if (!item) { + return; + } + item->setGroupName(groupName); + m_sidebarModel->insertRow(index, item); +} + +/*! + * \brief append an \a item to the sidebar item model, with the given \a groupName + * + * Warning! Item is directly append to the model, will NOT try to find the group + * location by the given group name. For that (find group location and append item) + * purpose, use addItem() instead. + */ +void DFMSideBar::appendItem(DFMSideBarItem *item, const QString &groupName) +{ + item->setGroupName(groupName); + m_sidebarModel->appendRow(item); +} + +void DFMSideBar::appendItemWithOrder(QList &list, const DUrlList &order, const QString &groupName) +{ + DUrlList urlList; + + for (const DFMSideBarItem *item : list) { + urlList << item->url(); + } + + for (const DUrl &url : order) { + int idx = urlList.indexOf(url); + if (idx >= 0) { + urlList.removeAt(idx); + this->appendItem(list.takeAt(idx), groupName); + } + } + + for (DFMSideBarItem *item : list) { + this->appendItem(item, groupName); + } +} + +/*! + * \brief Find the model-index of the groupNname + * + * \return the the model-index of the groupNname we can found, or invalid-model-index if not found. + */ +QModelIndex DFMSideBar::groupModelIndex(const QString &groupName) +{ + return m_sidebarModel->index(findLastItem(groupName), 0, m_sidebarView->rootIndex()); +} + +void DFMSideBar::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::PaletteChange) { + applySidebarColor(); + } + + return QWidget::changeEvent(event); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebar.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebar.h new file mode 100644 index 0000000..ead3895 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebar.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ +#pragma once + +#include +#include +#include +#include + +#include "durl.h" +#include "dfmglobal.h" +#include "interfaces/dabstractfileinfo.h" +#include + +DFM_BEGIN_NAMESPACE + +class DFMSideBarView; +class DFMSideBarModel; +class DFMSideBarItem; +class DFMSideBar : public QWidget +{ + Q_OBJECT +public: + enum GroupName { + Common, + Device, + Bookmark, + Network, + Tag, + Other, + Plugin,//NOTE [ren] Add new group + Unknow + }; + + explicit DFMSideBar(QWidget *parent = nullptr); + ~DFMSideBar(); + QWidget *sidebarView(); // return m_sidebarView + + QRect groupGeometry(const QString &groupName); + void scrollToGroup(const QString &groupName); + + void setCurrentUrl(const DUrl &url, bool changeUrl = true); + + int addItem(DFMSideBarItem *item, const QString &group); + bool removeItem(const DUrl &url, const QString &group); + int findItem(const DFMSideBarItem *item) const; + int findItem(const DUrl &url, const QString &group) const; + int findItem(const DUrl &url, bool fuzzy = false) const; + int findItem(std::function cb) const; // cb return true to get the index + int findLastItem(const QString &group, bool sidebarItemOnly = true) const; + void openItemEditor(int index) const; + QSet disableUrlSchemes() const; + + void setContextMenuEnabled(bool enabled); + void setDisableUrlSchemes(const QSet &schemes); + + DUrlList savedItemOrder(const QString &groupName) const; + void saveItemOrder(const QString &groupName) const; + + static QString groupName(GroupName group); + static GroupName groupFromName(const QString &name); + + static const int minimumWidth = 120; + static const int maximumWidth = 200; + void rootFileResult(); + +signals: + void disableUrlSchemesChanged(); + // 侧边栏添加共享item信号,url为共享文件夹的路径 + void addUserShareItemFinished(const DUrl &url); + +private slots: + void onItemActivated(const QModelIndex &index); + void onContextMenuRequested(const QPoint &pos); + void onRename(const QModelIndex &index, QString newName) const ; + +private: + void initUI(); + void initModelData(); + void initConnection(); + void initUserShareItem(); + void initRecentItem(); + void initBookmarkConnection(); + void initDeviceConnection(); + void initTagsConnection(); + //NOTE [XIAO] 从Plugin中导入SideBarItem + void initItemFromPlugin(); + void applySidebarColor(); + void updateSeparatorVisibleState(); + void addGroupItems(GroupName groupType); + void insertItem(int index, DFMSideBarItem *item, const QString &groupName); + void appendItem(DFMSideBarItem *item, const QString &groupName); + void appendItemWithOrder(QList &list, const DUrlList &order, const QString &groupName); + + QModelIndex groupModelIndex(const QString &groupName); + + void changeEvent(QEvent *event) override; + + DFMSideBarView *m_sidebarView; + DFMSideBarModel *m_sidebarModel; + QScopedPointer m_udisks2DiskManager; + bool m_contextMenuEnabled = true; + QList devitems; + QSet m_disableUrlSchemes; + + QDateTime m_lastToggleTime; + DFMSideBarItem *m_pLastToggleItem = nullptr; + DUrl m_currentUrl; + QMutex m_currentUrlMutex; + +#ifdef ENABLE_ASYNCINIT + QPair> m_initDevThread; //初始化initDeviceConnection线程,first为是否强制结束线程 +#endif +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebaritemdelegate.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebaritemdelegate.cpp new file mode 100644 index 0000000..4c40c04 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebaritemdelegate.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ +#include "dfmsidebaritemdelegate.h" + +#include "interfaces/dfmsidebaritem.h" +/*********************************************************/ +//bug 26937 书签目标目录不存在情况下还可以重命名问题。相关头文件添加 +#include "interfaces/dfileservices.h" +#include "dfmsidebarview.h" +#include "models/dfmsidebarmodel.h" +/*********************************************************/ +#include +#include +#include +#include +#include +#include + +QT_USE_NAMESPACE +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE + +DFMSideBarItemDelegate::DFMSideBarItemDelegate(QAbstractItemView *parent) + : DStyledItemDelegate(parent) +{ + +} + +void DFMSideBarItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QVariant v = index.data(DFMSideBarItem::ItemTypeRole); + if (v.isValid() && v.toInt() == DFMSideBarItem::Separator) { + return paintSeparator(painter, option); + } + + return DStyledItemDelegate::paint(painter, option, index); +} + +QSize DFMSideBarItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QVariant v = index.data(DFMSideBarItem::ItemTypeRole); + if (v.isValid() && v.toInt() == DFMSideBarItem::Separator) { + return sizeHintForType(DFMSideBarItem::Separator); + } else { + return DStyledItemDelegate::sizeHint(option, index); + } +} + +void DFMSideBarItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + Q_UNUSED(model); + QByteArray n = editor->metaObject()->userProperty().name(); + if (!n.isEmpty()) { + emit rename(index, editor->property(n).toString()); + } + + return; +} + +QWidget *DFMSideBarItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + /***************************************************************************************************************/ + //此部分判断主要是为了解决书签目标目录不存在情况下仍可以对书签进行重命名并且重命名后可打开失效目录问题 + //目前在标签对应目标路径不存在的情况下,右键重命名是失效的,所以也不应允许双击修改。故此处做规避 + //有用过QFileInfo::exists直接path路径有问题所以改成了DAbstractFileInfoPointer + DFMSideBarView *sidebarView = dynamic_cast(this->parent()); + DFMSideBarModel *sidebarModel = dynamic_cast(sidebarView->model()); + DFMSideBarItem *tgItem = sidebarModel->itemFromIndex(index); + + const DAbstractFileInfoPointer &sourceInfo = DFileService::instance()->createFileInfo(nullptr, tgItem->url()); + if(!sourceInfo->exists()) + return nullptr; + /***************************************************************************************************************/ + QWidget *editor = DStyledItemDelegate::createEditor(parent, option, index); + QLineEdit *qle = nullptr; + if ((qle = dynamic_cast(editor))) { + QRegExp regx("^[^\\.\\\\/\':\\*\\?\"<>|%&][^\\\\/\':\\*\\?\"<>|%&]*"); //屏蔽特殊字符 + QValidator *validator = new QRegExpValidator(regx, qle); + qle->setValidator(validator); + const QString &fs = sourceInfo->extraProperties()["fsType"].toString(); + // 普通文件系统限制最长输入字符为 40, vfat exfat 由于文件系统的原因,只能输入 11 个字符 + int maxLenInBytes = fs.toLower().endsWith("fat") ? 11 : 40; + connect(qle, &QLineEdit::textChanged, this, [qle, maxLenInBytes](const QString &txt) { + if (!qle) + return; + if (txt.toUtf8().length() > maxLenInBytes) { + const QSignalBlocker blocker(qle); + QString newLabel = txt; + newLabel.chop(1); + qle->setText(newLabel); + } + }); + } + + return editor; +} + +void DFMSideBarItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index); + DStyledItemDelegate::updateEditorGeometry(editor, option, index); + + //DTK在计算editor宽度的时候没有考虑icon的宽度,导致editor超出view的范围,超出部分看不到了,这里需要调整editor的宽度。 + DFMSideBarView *sidebarView = dynamic_cast(this->parent()); + editor->setFixedWidth(sidebarView->width() - 59); +} + +void DFMSideBarItemDelegate::paintSeparator(QPainter *painter, const QStyleOptionViewItem &option) const +{ + painter->save(); + + int yPoint = option.rect.top() + option.rect.height() / 2; + qDrawShadeLine(painter, 0, yPoint, option.rect.width(), yPoint, option.palette); + + painter->restore(); +} + +QSize DFMSideBarItemDelegate::sizeHintForType(int type) const +{ + switch (type) { + case DFMSideBarItem::Separator: + return QSize(200, 5); + } + + return QSize(0, 0); +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebaritemdelegate.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebaritemdelegate.h new file mode 100644 index 0000000..2e25e04 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebaritemdelegate.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Gary Wang + * + * Maintainer: Gary Wang + * + * 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 + * 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 . + */ +#pragma once + +#include "dfmglobal.h" +#include + +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE + +class DFMSideBarItemDelegate : public DStyledItemDelegate +{ + Q_OBJECT +public: + explicit DFMSideBarItemDelegate(QAbstractItemView *parent = nullptr); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const override; + QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + void updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex &index) const override; +signals: + void rename(const QModelIndex &index, QString newName) const; +private: + void paintSeparator(QPainter *painter, const QStyleOptionViewItem &option) const; + QSize sizeHintForType(int type) const; +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebarview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebarview.cpp new file mode 100644 index 0000000..ceecdfb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebarview.cpp @@ -0,0 +1,578 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "dfmsidebarview.h" +#include "dfmsidebaritem.h" +#include "dfileservices.h" +#include "app/define.h" +#include "dfmopticalmediawidget.h" +#include "controllers/vaultcontroller.h" +#include "accessibility/ac-lib-file-manager.h" +#include "plugins/schemepluginmanager.h" + +#include +#include +#include +#include +#include +#include + +#include + +//#define DRAG_EVENT_URLS "UrlsInDragEvent" +#define DRAG_EVENT_URLS ((getuid() == 0) ? (QString(getlogin()) + "_RootUrlsInDragEvent") : (QString(getlogin()) + "_UrlsInDragEvent")) + +DFM_BEGIN_NAMESPACE + +DFMSideBarView::DFMSideBarView(QWidget *parent) + : DListView(parent) +{ + AC_SET_OBJECT_NAME(this, AC_DM_SIDE_BAR_VIEW); + AC_SET_ACCESSIBLE_NAME(this, AC_DM_SIDE_BAR_VIEW); + + setVerticalScrollMode(ScrollPerPixel); + setIconSize(QSize(16, 16)); + // setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + setMouseTracking(true); // sp3 feature 35,解除注释以便鼠标在移动时就能触发 mousemoveevent + + setDragDropMode(QAbstractItemView::InternalMove); + setDragDropOverwriteMode(false); + //QListView拖拽时会先插入后删除,于是可以通过rowCountChanged()信号来判断拖拽操作是否结束 + connect(this, &DFMSideBarView::rowCountChanged, this, &DFMSideBarView::onRowCountChanged); //Qt5风格 + connect(this, static_cast(&DListView::currentChanged), this, &DFMSideBarView::currentChanged); + + m_lastOpTime = 0; +} + +void DFMSideBarView::mousePressEvent(QMouseEvent *event) +{ + //频繁点击操作与网络或挂载设备的加载效率低两个因素的共同作用下 会导致侧边栏可能出现显示错误 + //暂时抛去部分频繁点击来规避这个问题 + if (!checkOpTime()) + return; + + // 鼠标按下时记录当前点击item的唯一key + updateItemUniqueKey(indexAt(event->pos())); + + if (event->button() == Qt::RightButton) { +#if 1 //fix bug#33502 鼠标挪动到侧边栏底部右键,滚动条滑动,不能定位到选中的栏目上 + event->accept(); + return; +#else + if (m_current != indexAt(event->pos())) { + DListView::mousePressEvent(event); + return setCurrentIndex(m_previous); + } +#endif + } + DListView::mousePressEvent(event); +} + +void DFMSideBarView::mouseMoveEvent(QMouseEvent *event) +{ + DListView::mouseMoveEvent(event); + // sp3 feature 35,光标悬浮到光驱item上如果正在加载,需要显示为繁忙光标。添加判定避免额外操作 + if (event->button() == Qt::NoButton) { + const QModelIndex &idx = indexAt(event->pos()); + QString voltag = idx.data(DFMSideBarItem::ItemVolTagRole).toString(); + if (!voltag.isEmpty() && voltag.startsWith("sr") + && DFMOpticalMediaWidget::g_mapCdStatusInfo.contains(voltag) + && DFMOpticalMediaWidget::g_mapCdStatusInfo[voltag].bLoading) { + // 设置光标为繁忙状态 + DFileService::instance()->setCursorBusyState(true); + } else { + DFileService::instance()->setCursorBusyState(false); + } + } else { +#if QT_CONFIG(draganddrop) + if (state() == DraggingState) { + startDrag(Qt::MoveAction); + setState(NoState); // the startDrag will return when the dnd operation is done + stopAutoScroll(); + QPoint pt = mapFromGlobal(QCursor::pos()); + QRect rc = geometry(); + if (!rc.contains(pt)) { + emit requestRemoveItem(); //model()->removeRow(currentIndex().row()); + } + } +#endif // QT_CONFIG(draganddrop) + } +} + +void DFMSideBarView::dragEnterEvent(QDragEnterEvent *event) +{ + previousRowCount = model()->rowCount(); + //从view本身拖拽的item不需要从共享内存取url数据 + if (event->source() == this) { + //防止误判之前的url数据,这里清空缓存 + m_urlsForDragEvent.clear(); + } else { + bool sameUser = DFMGlobal::isMimeDatafromCurrentUser(event->mimeData()); + if (sameUser) { + fetchDragEventUrlsFromSharedMemory(); + } else { + m_urlsForDragEvent = event->mimeData()->urls(); + } + } + + if (isAccepteDragEvent(event)) { + return; + } + + DListView::dragEnterEvent(event); + + if (event->source() != this) { + event->setDropAction(Qt::IgnoreAction); + event->accept(); + } +} + +void DFMSideBarView::dragMoveEvent(QDragMoveEvent *event) +{ + if (isAccepteDragEvent(event)) { + return; + } + + DListView::dragMoveEvent(event); + + if (event->source() != this) { + event->ignore(); + } +} + +void DFMSideBarView::dropEvent(QDropEvent *event) +{ + dropPos = event->pos(); + DFMSideBarItem *item = itemAt(event->pos()); + if (!item) { + return DListView::dropEvent(event); + } + + qDebug() << "source: " << event->mimeData()->urls(); + qDebug() << "target item: " << item->groupName() << "|" << item->text() << "|" << item->url(); + + //wayland环境下QCursor::pos()在此场景中不能获取正确的光标当前位置,代替方案为直接使用QDropEvent::pos() + //QDropEvent::pos() 实际上就是drop发生时光标在该widget坐标系中的position (mapFromGlobal(QCursor::pos())) + //但rc本来就是由event->pos()计算item得出的Rect,这样判断似乎就没有意义了(虽然原来的逻辑感觉也没什么意义) + QPoint pt = event->pos(); //mapFromGlobal(QCursor::pos()); + QRect rc = visualRect(indexAt(event->pos())); + if (!rc.contains(pt)) { + qDebug() << "mouse not in my area"; + return DListView::dropEvent(event); + } + + // bug case 24499, 这里需要区分哪些是可读的文件 或文件夹,因为其权限是不一样的,所以需要对不同权限的文件进行区分处理 + // 主要有4种场景:1.都是可读写的场景; 2.文件夹是只读属性,子集是可读写的; 3.文件夹或文件是可读写的; 4.拖动的包含 可读写的和只读的 + DUrlList urls, copyUrls; + for (const QUrl &url : event->mimeData()->urls()) { + if (DUrl(url).parentUrl() == item->url() && !DFMGlobal::keyCtrlIsPressed()) { + qDebug() << "skip the same dir file..." << url; + } else { + QString folderPath = DUrl(url).parentUrl().path(); + QString filePath = url.path(); + + bool isFolderWritable = false; + bool isFileWritable = false; + + if (VaultController::isVaultFile(folderPath) + || VaultController::isVaultFile(filePath)) { + //! vault file get permissions separatly + isFolderWritable = VaultController::getPermissions(folderPath) & QFileDevice::WriteUser; + isFileWritable = VaultController::getPermissions(filePath) & QFileDevice::WriteUser; + } else { + QFileInfo folderinfo(folderPath); // 判断上层文件是否是只读,有可能上层是只读,而里面子文件或文件夾又是可以写 + QFileInfo fileinfo(filePath); + + isFileWritable = fileinfo.isWritable(); + isFolderWritable = folderinfo.isWritable(); + + //fix 89245 选择Root权限的链接文件,拖拽到侧边栏回收站中,无法拖拽文件到回收站 + if (isFolderWritable && fileinfo.isSymLink() && item->url().toString() == TRASH_ROOT) { + urls << DUrl(url); + continue; + } + } + + if (!isFolderWritable) { + copyUrls << DUrl(url); + qDebug() << "this is a unwriteable case:" << url; + } else { + urls << DUrl(url); + } + } + } + + bool isActionDone = false; + if (!urls.isEmpty()) { + Qt::DropAction action = canDropMimeData(item, event->mimeData(), Qt::MoveAction); + if (action == Qt::IgnoreAction) { + action = canDropMimeData(item, event->mimeData(), event->possibleActions()); + } + + if (item->url().scheme() == PLUGIN_SCHEME) { // 对我的手机目录执行的单独拖拽动作,拖拽目录固定 add by CL + for (auto plugin : SchemePluginManager::instance()->schemePlugins()) { + if ((item->url().host() == plugin.first) && plugin.second->isSideBarItemSupportedDrop()) { + if (urls.size() > 0 && plugin.second->dropFileToPlugin(urls, item->url())) { + event->setDropAction(action); + isActionDone = true; + } + break; + } + } + } + + if (urls.size() > 0 && onDropData(urls, item->url(), action)) { + event->setDropAction(action); + isActionDone = true; + } + } + if (!copyUrls.isEmpty()) { + if (item->url().scheme() == PLUGIN_SCHEME) { // 对我的手机目录执行的单独拖拽动作,拖拽目录固定 add by CL + for (auto plugin : SchemePluginManager::instance()->schemePlugins()) { + if ((item->url().host() == plugin.first) && plugin.second->isSideBarItemSupportedDrop()) { + if (urls.size() > 0 && plugin.second->dropFileToPlugin(urls, item->url())) { + event->setDropAction(Qt::CopyAction); + isActionDone = true; + } + + break; + } + } + } + + if (onDropData(copyUrls, item->url(), Qt::CopyAction)) { // 对于只读权限的,只能进行 copy动作 + event->setDropAction(Qt::CopyAction); + isActionDone = true; + } + } + + if (isActionDone) { + //fix bug 24478,在drop事件完成时,设置当前窗口为激活窗口,crtl+z就能找到正确的回退 + QWidget *parentptr = parentWidget(); + QWidget *curwindow = nullptr; + while (parentptr) { + curwindow = parentptr; + parentptr = parentptr->parentWidget(); + } + if (curwindow) { + qApp->setActiveWindow(curwindow); + } + + event->accept(); + } else { + DListView::dropEvent(event); + } +} + +QModelIndex DFMSideBarView::indexAt(const QPoint &p) const +{ + QModelIndex index = QListView::indexAt(p); + if (index.data(DFMSideBarItem::ItemTypeRole) == DFMSideBarItem::Separator) { + return QModelIndex(); + } + + return index; +} + +QModelIndex DFMSideBarView::getPreviousIndex() const +{ + return m_previous; +} + +QModelIndex DFMSideBarView::getCurrentIndex() const +{ + return m_current; +} + +void DFMSideBarView::currentChanged(const QModelIndex &previous) +{ + m_current = currentIndex(); + m_previous = previous; +} + +bool DFMSideBarView::onDropData(DUrlList srcUrls, DUrl dstUrl, Qt::DropAction action) const +{ + const DAbstractFileInfoPointer &dstInfo = fileService->createFileInfo(this, dstUrl); + if (!dstInfo) { + return false; + } + + for (DUrl &u : srcUrls) { + // we only do redirection for burn:// urls for the fear of screwing everything up again + if (u.scheme() == BURN_SCHEME) { + DAbstractFileInfoPointer fi = fileService->createFileInfo(nullptr, u); + while (fi && fi->canRedirectionFileUrl()) { + u = fi->redirectedFileUrl(); + fi = fileService->createFileInfo(nullptr, u); + } + } + } + + // convert destnation url to real path if it's a symbol link. + if (dstInfo->isSymLink()) { + dstUrl = dstInfo->rootSymLinkTarget(); + } + + //这里不能全redirected例如ftp内的书签会有问题 + if (dstInfo->canRedirectionFileUrl()) { + DUrl url = dstInfo->redirectedFileUrl(); + if (url.burnIsOnDisc()) { + dstUrl = url; + } + } + + switch (action) { + case Qt::CopyAction: + // blumia: should run in another thread or user won't do another DnD opreation unless the copy action done. + QtConcurrent::run([=]() { + fileService->pasteFile(this, DFMGlobal::CopyAction, dstUrl, srcUrls); + }); + + break; + case Qt::LinkAction: + break; + case Qt::MoveAction: + // fix bug 81143 ,开启普通文件删除提示功能后,打开最近使用和回收站两个窗口,拖拽最近使用到回收站,在还没有 + // 弹出对话框的时候,快速框选最近访问窗口。这时弹窗出现(使用的runinMainThread)使用的exec就会开启一个本地事件循环,将框选事件加入本地循环 + // 执行,框选事件又在等待drag事件结束(mousemove事件结束),本地事件又阻塞drag事件,相互等待。使用线程去执行 + // 业务逻辑,让drop事件快速返回。 + if (dstUrl.isTrashFile()) { + QtConcurrent::run([=]() { + fileService->moveToTrash(this, srcUrls); + }); + } else + fileService->pasteFile(this, DFMGlobal::CutAction, dstUrl, srcUrls); + break; + default: + return false; + } + + return true; +} + +DFMSideBarItem *DFMSideBarView::itemAt(const QPoint &pt) +{ + DFMSideBarItem *item = nullptr; + QModelIndex index = indexAt(pt); + if (!index.isValid()) { + return item; + } + + DFMSideBarModel *mod = dynamic_cast(model()); + Q_ASSERT(mod); + item = mod->itemFromIndex(index); + Q_ASSERT(item); + + return item; +} + +void DFMSideBarView::updateItemUniqueKey(const QModelIndex &index) +{ + if (model() && index.isValid()) + m_strItemUniqueKey = model()->data(index, DFMSideBarItem::ItemUniqueKeyRole).toString(); +} + +Qt::DropAction DFMSideBarView::canDropMimeData(DFMSideBarItem *item, const QMimeData *data, Qt::DropActions actions) const +{ + Q_UNUSED(data) + // Got a copy of urls so whatever data was changed, it won't affact the following code. + QList urls = m_urlsForDragEvent; + + if (urls.empty()) { + return Qt::IgnoreAction; + } + const DAbstractFileInfoPointer &info = fileService->createFileInfo(this, item->url()); + DUrl itemUrl = item->url(); + if (itemUrl.isBookMarkFile() && info && info->canRedirectionFileUrl()) + itemUrl = info->redirectedFileUrl(); + + for (const QUrl &url : urls) { + const DAbstractFileInfoPointer &fileInfo = fileService->createFileInfo(this, DUrl(url)); + if (!fileInfo || !info) + return Qt::IgnoreAction; + + if (!itemUrl.isTaggedFile()) { + bool isInSameDevice = DStorageInfo::inSameDevice(fileInfo->fileUrl(), itemUrl); + if ((!isInSameDevice && !fileInfo->isReadable()) || (!DFMGlobal::keyCtrlIsPressed() && isInSameDevice && !fileInfo->canRename())) + return Qt::IgnoreAction; + } + + //部分文件不能复制或剪切,需要在拖拽时忽略 + if (!fileInfo->canMoveOrCopy()) { + return Qt::IgnoreAction; + } + //防止不可添加tag的文件被拖进tag目录从而获取tag属性 + if (item->url().isTaggedFile() && !fileInfo->canTag()) { + return Qt::IgnoreAction; + } + } + + if (!info || !info->canDrop()) { + for (auto plugin : SchemePluginManager::instance()->schemePlugins()) { + // 对我的手机item做临时处理,连接成功时允许向item拖拽 + if ((item->url().scheme() == PLUGIN_SCHEME) && (item->url().host() == plugin.first) && plugin.second->isSideBarItemSupportedDrop()) { + return Qt::CopyAction; + } + } + + return Qt::IgnoreAction; + } + + Qt::DropAction action = Qt::CopyAction; + const Qt::DropActions support_actions = info->supportedDropActions() & actions; + const DUrl from = DUrl(urls.first()); + DUrl to = info->fileUrl(); + + //fix bug#23703勾选自动整理,拖拽其他目录文件到桌面做得是复制操作 + //因为自动整理的路径被DStorageInfo::inSameDevice判断为false,这里做转化 + if (to.scheme() == BOOKMARK_SCHEME) { + if (info->canRedirectionFileUrl()) + to = info->redirectedFileUrl(); + } + //end + + if (qApp->keyboardModifiers() == Qt::AltModifier) { + action = Qt::MoveAction; + } else if (!DFMGlobal::keyCtrlIsPressed()) { + // 如果文件和目标路径在同一个分区下,默认为移动文件,否则默认为复制文件 + if (DStorageInfo::inSameDevice(from, to)) { + action = Qt::MoveAction; + } + } + + //任意来源为回收站的drop操作均为move(统一回收站拖拽标准) + bool isFromTrash = from.url().contains(".local/share/Trash/"); + bool isToTrash = to.isTrashFile(); + + if (isFromTrash || isToTrash) { + if (!isFromTrash || !isToTrash) { + action = Qt::MoveAction; + } else { + return Qt::IgnoreAction; + } + } + + // 保险箱时,修改DropAction为Qt::CopyAction + if ((VaultController::isVaultFile(from.url()) + || VaultController::isVaultFile(to.toString())) + && !isToTrash) { + action = Qt::CopyAction; + } + + //跨用户的操作不允许修改原文件 + if (!DFMGlobal::isMimeDatafromCurrentUser(data) && action == Qt::MoveAction) + action = Qt::CopyAction; + + // 最近使用目录下的文件,只有拖拽到回收站为剪切,其他都为拷贝 + if (from.isRecentFile()) + action = isToTrash ? Qt::MoveAction : Qt::CopyAction; + + if (support_actions.testFlag(action)) { + return action; + } + + return Qt::IgnoreAction; +} + +bool DFMSideBarView::isAccepteDragEvent(DFMDragEvent *event) +{ + DFMSideBarItem *item = itemAt(event->pos()); + if (!item) { + return false; + } + + bool accept = false; + + Qt::DropAction action = canDropMimeData(item, event->mimeData(), event->proposedAction()); + if (action == Qt::IgnoreAction) { + action = canDropMimeData(item, event->mimeData(), event->possibleActions()); + } + + if (action != Qt::IgnoreAction) { + event->setDropAction(action); + event->accept(); + accept = true; + } + + return accept; +} + +//添加此函数为解决拖拽后不选中拖拽项目问题 +void DFMSideBarView::onRowCountChanged() +{ + // 重写该函数,之前的实现方式会导致在频繁添加、移除书签或是进行其他影响侧边栏item数量的操作时,左侧item的高亮选项错误跳动 + if (m_strItemUniqueKey.isEmpty()) + return; + DFMSideBarModel *pModel = dynamic_cast(model()); + if (!pModel) + return; + for (int i = 0; i < pModel->rowCount(); i++) { + QModelIndex currIdx = pModel->index(i, 0); + if (pModel->data(currIdx, DFMSideBarItem::ItemUniqueKeyRole).toString() == m_strItemUniqueKey) { + setCurrentIndex(currIdx); + QTimer::singleShot(50, this, [this] { m_strItemUniqueKey.clear(); }); // 发生拖拽排序的时候该函数会在短时间内触发两次,第二次才是准确数据,触发间隔时间 << 50ms,因此这里设置50ms后清空记录的key + return; + } + } +} + +bool DFMSideBarView::fetchDragEventUrlsFromSharedMemory() +{ + QSharedMemory sm; + sm.setKey(DRAG_EVENT_URLS); + + if (!sm.isAttached()) { + if (!sm.attach()) { + qDebug() << "FQSharedMemory detach failed."; + return false; + } + } + + QBuffer buffer; + QDataStream in(&buffer); + QList urls; + + sm.lock(); + //用缓冲区得到共享内存关联后得到的数据和数据大小 + buffer.setData((char *)sm.constData(), sm.size()); + buffer.open(QBuffer::ReadOnly); //设置读取模式 + in >> m_urlsForDragEvent; //使用数据流从缓冲区获得共享内存的数据,然后输出到字符串中 + sm.unlock(); //解锁 + sm.detach(); //与共享内存空间分离 + + return true; +} + +bool DFMSideBarView::checkOpTime() +{ + //如果两次操作时间间隔足够长,则返回true + if (QDateTime::currentDateTime().toMSecsSinceEpoch() - m_lastOpTime > 200) { + m_lastOpTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + return true; + } + + return false; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebarview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebarview.h new file mode 100644 index 0000000..c581b47 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsidebarview.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#pragma once + +#include "dfmglobal.h" +#include + +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE +class DFMSideBarItem; +typedef QDropEvent DFMDragEvent; +class DFMSideBarView : public DListView +{ + Q_OBJECT +public: + explicit DFMSideBarView(QWidget *parent = nullptr); + void mousePressEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void dragEnterEvent(QDragEnterEvent *event) override; + void dragMoveEvent(QDragMoveEvent *event) override; + void dropEvent(QDropEvent *event) override; + QModelIndex indexAt(const QPoint &p) const override; + QModelIndex getPreviousIndex() const; + QModelIndex getCurrentIndex() const; + void currentChanged(const QModelIndex &previous); + DFMSideBarItem *itemAt(const QPoint &pt); + void updateItemUniqueKey(const QModelIndex &index); + +protected: + bool onDropData(DUrlList srcUrls, DUrl dstUrl, Qt::DropAction action) const; + Qt::DropAction canDropMimeData(DFMSideBarItem *item, const QMimeData *data, Qt::DropActions actions) const; + bool isAccepteDragEvent(DFMDragEvent *event); +signals: + void requestRemoveItem(); + +private slots: + void onRowCountChanged(); + +private: + bool fetchDragEventUrlsFromSharedMemory(); + //检查当前操作与上次操作的时间间隔 + bool checkOpTime(); + int previousRowCount; + QPoint dropPos; + QString dragItemName; + int dragRow; + QModelIndex m_previous; + QModelIndex m_current; + QString m_strItemUniqueKey; + + QList m_urlsForDragEvent; + + //上次操作的时间(ms) + qint64 m_lastOpTime; +}; + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsplitter.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsplitter.cpp new file mode 100644 index 0000000..51b0c14 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsplitter.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2017 ~ 2020 Deepin Technology Co., Ltd. + * + * Author: liuyang + * + * Maintainer: liuyang + * + * 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 + * 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 . + */ + +#include "dfmsplitter.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include +#include + +DFMSplitterHandle::DFMSplitterHandle(Qt::Orientation orientation, QSplitter *parent): + QSplitterHandle(orientation, parent) +{ + +} + +void DFMSplitterHandle::enterEvent(QEvent *) +{ + QGuiApplication::setOverrideCursor(orientation() == Qt::Horizontal ? Qt::SizeHorCursor : Qt::SizeVerCursor); +} + +void DFMSplitterHandle::leaveEvent(QEvent *) +{ + QGuiApplication::restoreOverrideCursor(); +} + +// ---------- Item Get Border Line ---------- + +DFMSplitter::DFMSplitter(Qt::Orientation orientation, QWidget *parent) + :QSplitter(orientation, parent) +{ + AC_SET_OBJECT_NAME(this, AC_DM_SPLITTER); + AC_SET_ACCESSIBLE_NAME(this, AC_DM_SPLITTER); +} + +void DFMSplitter::moveSplitter(int pos, int index) +{ + return QSplitter::moveSplitter(pos, index); +} + +QSplitterHandle *DFMSplitter::createHandle() +{ + return new DFMSplitterHandle(orientation(), this); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsplitter.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsplitter.h new file mode 100644 index 0000000..c3fc5d0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmsplitter.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2017 ~ 2020 Deepin Technology Co., Ltd. + * + * Author: liuyang + * + * Maintainer: liuyang + * + * 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 + * 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 . + */ + +#ifndef DFMSPLITTER_H +#define DFMSPLITTER_H + + +#include +#include + +class DFMSplitterHandle: public QSplitterHandle +{ + Q_OBJECT + +public: + explicit DFMSplitterHandle(Qt::Orientation orientation, QSplitter* parent); + +protected: + void enterEvent(QEvent*) override; + void leaveEvent(QEvent*) override; +}; + +// ---------- Item Get Border Line ---------- + +class DFMSplitter : public QSplitter +{ + Q_OBJECT + +public: + explicit DFMSplitter(Qt::Orientation orientation, QWidget *parent = nullptr); + void moveSplitter(int pos, int index); + +protected: + QSplitterHandle* createHandle() override; +}; + +#endif // DFMSPLITTER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmtagwidget.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmtagwidget.cpp new file mode 100644 index 0000000..11a2848 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmtagwidget.cpp @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Mike Chen + * + * Maintainer: Mike Chen + * + * 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 + * 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 . + */ +#include "dfmtagwidget.h" +#include "dfileservices.h" +#include "app/define.h" +#include "controllers/pathmanager.h" +#include "controllers/vaultcontroller.h" +#include "accessibility/ac-lib-file-manager.h" +#include "singleton.h" +#include +#include +#include +#include +#include +#include +#include +#include +DFM_BEGIN_NAMESPACE + +class DFMCrumbEdit : public DCrumbEdit +{ +public: + explicit DFMCrumbEdit(QWidget *parent = nullptr): DCrumbEdit(parent) + { + auto doc = QTextEdit::document(); + doc->setDocumentMargin(doc->documentMargin() + 5); + } + + bool isEditing() + { + return m_isEditByDoubleClick; + } +protected: + void mouseDoubleClickEvent(QMouseEvent *event) override + { + m_isEditByDoubleClick = true; + DCrumbEdit::mouseDoubleClickEvent(event); + m_isEditByDoubleClick = false; + } + +private: + bool m_isEditByDoubleClick{false}; +}; + +class DFMTagWidgetPrivate : public QSharedData +{ +public: + explicit DFMTagWidgetPrivate(DFMTagWidget *qq, const DUrl &url); + virtual ~DFMTagWidgetPrivate(); + +protected: + DUrl redirectUrl(const DUrl &url); + +private: + DUrl m_url; + QLabel *m_tagLable{nullptr}; + QLabel *m_tagLeftLable{nullptr}; + QVBoxLayout *m_mainLayout{nullptr}; + DFMCrumbEdit *m_tagCrumbEdit{ nullptr }; + DTagActionWidget *m_tagActionWidget{ nullptr }; + DAbstractFileWatcher *m_devicesWatcher{ nullptr }; + + QMap currentTagWithColorMap; + + DFMTagWidget *q_ptr{ nullptr }; + Q_DECLARE_PUBLIC(DFMTagWidget) +}; + + +DUrl DFMTagWidgetPrivate::redirectUrl(const DUrl &url) +{ + DUrl durl = url; + if (url.isTaggedFile()) { + durl = DUrl::fromLocalFile(url.fragment(QUrl::FullyDecoded)); + } else if (url.isSearchFile()) { + durl = url.searchedFileUrl(); + } else if (url.isVaultFile()) { + durl = VaultController::vaultToLocalUrl(url); + } else { /* if (url.isRecentFile()) */ + durl = DUrl::fromLocalFile(url.path()); + } + + return durl; +} + +DFMTagWidgetPrivate::DFMTagWidgetPrivate(DFMTagWidget *qq, const DUrl &url) + : m_url(redirectUrl(url)) + , q_ptr(qq) +{ + +} + +DFMTagWidgetPrivate::~DFMTagWidgetPrivate() +{ + +} + +DFMTagWidget::DFMTagWidget(DUrl url, QWidget *parent/*=nullptr*/) + : QFrame(parent) + , d_private(new DFMTagWidgetPrivate(this, url)) +{ + AC_SET_OBJECT_NAME(this, AC_TAG_WIDGET); + AC_SET_ACCESSIBLE_NAME(this, AC_TAG_WIDGET); + initUi(); + initConnection(); +} + +DFMTagWidget::~DFMTagWidget() +{ + +} + +void DFMTagWidget::initUi() +{ + Q_D(DFMTagWidget); + d->m_mainLayout = new QVBoxLayout; + setLayout(d->m_mainLayout); + + //tr("Tag"); // dde_file_manager::DFMTagWidget not found in .ts + QString name = qApp->translate("DFMTagWidget", "Tag"); + d->m_tagLable = new QLabel(name, this); + d->m_tagLable->setObjectName(name); + AC_SET_ACCESSIBLE_NAME(d->m_tagLable, AC_TAG_LABLE); + + d->m_mainLayout->addWidget(d->m_tagLable); + d->m_tagLeftLable = new QLabel(name, this); + d->m_tagLeftLable->setObjectName(name); + AC_SET_ACCESSIBLE_NAME(d->m_tagLeftLable, AC_TAG_LEFT_LABLE); + + d->m_tagActionWidget = new DTagActionWidget(this); + d->m_tagActionWidget->setMaximumHeight(20); + d->m_tagActionWidget->setObjectName("tagActionWidget"); + AC_SET_ACCESSIBLE_NAME(d->m_tagActionWidget, AC_TAG_ACTION_WIDGET); + QHBoxLayout *tagActionLayout = new QHBoxLayout; + tagActionLayout->addWidget(d->m_tagLeftLable); + tagActionLayout->addWidget(d->m_tagActionWidget); + d->m_mainLayout->addLayout(tagActionLayout); + d->m_tagLeftLable->setHidden(true); + + d->m_tagCrumbEdit = new DFMCrumbEdit(this); + d->m_tagCrumbEdit->setObjectName("tagCrumbEdit"); + AC_SET_ACCESSIBLE_NAME(d->m_tagCrumbEdit, AC_TAG_CRUMB_EDIT); + d->m_tagCrumbEdit->setFrameShape(QFrame::Shape::NoFrame); + d->m_tagCrumbEdit->viewport()->setBackgroundRole(QPalette::NoRole); + d->m_mainLayout->addWidget(d->m_tagCrumbEdit); + + // 修复bug-47113 UI显示问题 +// d->m_mainLayout->addStretch(); + d->m_mainLayout->setContentsMargins(10, 10, 10, 10); + + loadTags(d->m_url); +} + +void DFMTagWidget::initConnection() +{ + Q_D(DFMTagWidget); + if (!d->m_tagCrumbEdit || !d->m_tagActionWidget) + return; + + QObject::connect(d->m_tagCrumbEdit, &DCrumbEdit::crumbListChanged, d->m_tagCrumbEdit, [ = ]() { + if (!d->m_tagCrumbEdit->isEditing() && !d->m_tagCrumbEdit->property("LoadFileTags").toBool()) { + bool ret = DFileService::instance()->makeTagsOfFiles(nullptr, {d->m_url}, d->m_tagCrumbEdit->crumbList()); + + if (!ret) { + loadTags(d->m_url); + return; + } + } + }); + + QObject::connect(d->m_tagActionWidget, &DTagActionWidget::checkedColorChanged, d->m_tagActionWidget, [ = ](const QColor & color) { + Q_UNUSED(color) + const QStringList tagNameList = TagManager::instance()->getTagsThroughFiles({d->m_url}); + QMap nameColors = TagManager::instance()->getTagColor({tagNameList}); + DUrlList urlList{d->m_url}; + QList checkedColors{ d->m_tagActionWidget->checkedColorList() }; + QSet defaultNames = TagManager::instance()->allTagOfDefaultColors(); + + QStringList newTagNames; + for (const QColor &color : checkedColors) { + QString tagName = TagManager::instance()->getTagNameThroughColor(color); + if (tagName.isEmpty()) { + continue; + } + newTagNames << tagName; + } + + for (auto it = nameColors.begin(); it != nameColors.end(); ++it) { + if (!defaultNames.contains(it.key())) { + newTagNames << it.key(); + } + } + + DFileService::instance()->makeTagsOfFiles(nullptr, urlList, newTagNames); + loadTags(d->m_url); + }); +} + +void DFMTagWidget::loadTags(const DUrl &durl) +{ + Q_D(DFMTagWidget); + DUrl url = d->redirectUrl(durl); + if (!d->m_tagCrumbEdit || !d->m_tagActionWidget || !shouldShow(url)) + return; + const QStringList tag_name_list = TagManager::instance()->getTagsThroughFiles({url}); + QMap nameColors = TagManager::instance()->getTagColor({tag_name_list}); + QSet defaultColors = TagManager::instance()->allTagOfDefaultColors(); + QList selectColors; + + //避免重复刷新edit,防止出现因刷新导致输入文本丢失的情况 + if (d->m_url == url && tag_name_list.length() == d->currentTagWithColorMap.count()) { + bool needRefreshEdit = false; + for (const QString &tag : tag_name_list) { + QString colorName = TagManager::instance()->getColorByDisplayName(tag); + if (!d->currentTagWithColorMap.contains(tag) || + d->currentTagWithColorMap.value(tag) != colorName) { + needRefreshEdit = true; + break; + } + } + + if (!needRefreshEdit) + return; + } + + d->m_tagCrumbEdit->setProperty("LoadFileTags", true); + d->m_tagCrumbEdit->clear(); + d->currentTagWithColorMap.clear(); + for (auto it = nameColors.begin(); it != nameColors.end(); ++it) { + DCrumbTextFormat format = d->m_tagCrumbEdit->makeTextFormat(); + format.setText(it.key()); + // 默认名字的颜色才勾选 checkbox + QString colorName = TagManager::instance()->getColorByDisplayName(it.key()); + if (!colorName.isEmpty()) { + QColor defaultColor = TagManager::instance()->getColorByColorName(colorName); + if (defaultColors.contains(it.key()) && it.value() == defaultColor) { + selectColors << it.value(); + } + } + format.setBackground(QBrush(it.value())); + format.setBackgroundRadius(5); + d->m_tagCrumbEdit->insertCrumb(format, 0); + d->currentTagWithColorMap.insert(it.key(), colorName); + } + d->m_tagCrumbEdit->setProperty("LoadFileTags", false); + + d->m_tagActionWidget->setCheckedColorList(selectColors); + if (!d->m_devicesWatcher || d->m_url != url) { + d->m_url = url; + + if (d->m_devicesWatcher) { + d->m_devicesWatcher->stopWatcher(); + d->m_devicesWatcher->deleteLater(); + } + d->m_devicesWatcher = DFileService::instance()->createFileWatcher(this, d->m_url, this); + if (d->m_devicesWatcher) { + d->m_devicesWatcher->startWatcher(); + + connect(d->m_devicesWatcher, &DAbstractFileWatcher::fileAttributeChanged, this, [ = ](const DUrl & url) { + if (url == d->m_url) { + loadTags(d->m_url); + } + }); + //当文件被删除时需要在这里把watcher移除,否则可能导致再创建同名文件无法正确添加watcher + connect(d->m_devicesWatcher, &DAbstractFileWatcher::fileDeleted, this, [ = ] { + if (d->m_devicesWatcher) + { + d->m_devicesWatcher->stopWatcher(); + d->m_devicesWatcher->deleteLater(); + d->m_devicesWatcher = nullptr; + } + }); + } + } +} + +QWidget *DFMTagWidget::tagTitle() +{ + Q_D(DFMTagWidget); + return d->m_tagLable; +} + +QWidget *DFMTagWidget::tagLeftTitle() +{ + Q_D(DFMTagWidget); + return d->m_tagLeftLable; +} + +DTagActionWidget *DFMTagWidget::tagActionWidget() +{ + Q_D(DFMTagWidget); + return d->m_tagActionWidget; +} + +DCrumbEdit *DFMTagWidget::tagCrumbEdit() +{ + Q_D(DFMTagWidget); + return d->m_tagCrumbEdit; +} + +bool DFMTagWidget::shouldShow(const DUrl &url) +{ + if (DFileService::instance()->checkGvfsMountfileBusy(url,false)) + return false; + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(nullptr, url); + //如果是网络挂载(gvfs)文件就返回 + if (!fileInfo || fileInfo->isVirtualEntry() || fileInfo->isGvfsMountFile() || DStorageInfo::isLowSpeedDevice(url.toAbsolutePathUrl().path())) + return false; + bool isComputerOrTrash = false; + DUrl realTargetUrl = fileInfo->fileUrl(); + if (fileInfo && fileInfo->isSymLink()) { + realTargetUrl = fileInfo->rootSymLinkTarget(); + } + + if (realTargetUrl.toLocalFile().endsWith(QString(".") + "desktop")) { + DesktopFile df(realTargetUrl.toLocalFile()); + isComputerOrTrash = (df.getDeepinId() == "dde-trash" || df.getDeepinId() == "dde-computer"); + } + + bool showTags = !systemPathManager->isSystemPath(url.path()) && + !isComputerOrTrash && DFileMenuManager::whetherShowTagActions({url}); + return showTags; +} + +DFM_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmtagwidget.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmtagwidget.h new file mode 100644 index 0000000..f988304 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmtagwidget.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 Deepin Technology Co., Ltd. + * + * Author: Mike Chen + * + * Maintainer: Mike Chen + * + * 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 + * 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 . + */ +#ifndef DFMTAGWIDGET_H +#define DFMTAGWIDGET_H +#include "dfmglobal.h" +#include "dtagactionwidget.h" + +#include +#include +#include +#include +DWIDGET_USE_NAMESPACE + +DFM_BEGIN_NAMESPACE + +class DFMTagWidgetPrivate; +class DFMTagWidget : public QFrame +{ + Q_OBJECT +public: + DFMTagWidget(DUrl url, QWidget *parent = nullptr); + ~DFMTagWidget(); + + void loadTags(const DUrl &durl); + QWidget *tagTitle(); + QWidget *tagLeftTitle(); + DTagActionWidget *tagActionWidget(); + DCrumbEdit *tagCrumbEdit(); + + static bool shouldShow(const DUrl &url); + +protected: + void initUi(); + void initConnection(); +private: + QScopedPointer d_private; + Q_DECLARE_PRIVATE_D(d_private, DFMTagWidget) +}; + +DFM_END_NAMESPACE + +#endif // DFMTAGWIDGET_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivefinishedview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivefinishedview.cpp new file mode 100644 index 0000000..a6e423a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivefinishedview.cpp @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmvaultactivefinishedview.h" +#include "operatorcenter.h" +#include "../../controllers/vaultcontroller.h" +#include "vault/vaultlockmanager.h" +#include "app/define.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace PolkitQt1; + +DFMVaultActiveFinishedView::DFMVaultActiveFinishedView(QWidget *parent) + : QWidget(parent) + , m_pTips(nullptr) + , m_pEncryptFinishedImage(nullptr) + , m_pTips4(nullptr) + , m_pFinishedBtn(nullptr) +{ + AC_SET_ACCESSIBLE_NAME(this, AC_VAULT_ACTIVE_ENCRYPT_WIDGET); + + // 标题 + QLabel *pLabelTitle = new QLabel(tr("Encrypt File Vault"), this); + AC_SET_ACCESSIBLE_NAME(pLabelTitle, AC_VAULT_ACTIVE_ENCRYPT_TITLE); + QFont font = pLabelTitle->font(); + font.setPixelSize(18); + pLabelTitle->setFont(font); + pLabelTitle->setAlignment(Qt::AlignHCenter); + + // 加密提示 + m_pTips = new DLabel(tr("Click 'Encrypt' and input the user password."), this); + AC_SET_ACCESSIBLE_NAME(m_pTips, AC_VAULT_ACTIVE_ENCRYPT_CONTENT); + m_pTips->setAlignment(Qt::AlignHCenter); + + // 加密保险箱图片 + m_pEncryVaultImage = new DLabel(this); + AC_SET_ACCESSIBLE_NAME(m_pEncryVaultImage, AC_VAULT_ACTIVE_ENCRYPT_IMAGE); + m_pEncryVaultImage->setPixmap(QIcon::fromTheme("dfm_vault_active_encrypt").pixmap(98, 88)); + m_pEncryVaultImage->setAlignment(Qt::AlignHCenter); + + // 进度条 + m_pWaterProgress = new DWaterProgress(this); + AC_SET_ACCESSIBLE_NAME(m_pWaterProgress, AC_VAULT_ACTIVE_ENCRYPT_PROGRESS); + m_pWaterProgress->setValue(1); + m_pWaterProgress->setFixedSize(98, 98); + // 进度条提示 + m_pTips3 = new DLabel(tr("Encrypting..."), this); + AC_SET_ACCESSIBLE_NAME(m_pTips3, AC_VAULT_ACTIVE_ENCRYPT_PROGRESS_HINT); + m_pTips3->setAlignment(Qt::AlignHCenter); + + // 加密完成完成图片 + m_pEncryptFinishedImage = new DLabel(this); + AC_SET_ACCESSIBLE_NAME(m_pEncryptFinishedImage, AC_VAULT_ACTIVE_ENCRYPT_FINISH_IMAGE); + m_pEncryptFinishedImage->setPixmap(QIcon::fromTheme("dfm_vault_active_finish").pixmap(128, 128)); + m_pEncryptFinishedImage->setAlignment(Qt::AlignHCenter); + // 加密完成提示 + m_pTips4 = new DLabel(tr("The setup is complete"), this); + AC_SET_ACCESSIBLE_NAME(m_pTips4, AC_VAULT_ACTIVE_ENCRYPT_FINISH_HINT); + m_pTips4->setAlignment(Qt::AlignHCenter); + + // 加密保险箱按钮 + m_pFinishedBtn = new QPushButton(tr("Encrypt"), this); + AC_SET_ACCESSIBLE_NAME(m_pFinishedBtn, AC_VAULT_ACTIVE_ENCRYPT_BUTTON); + connect(m_pFinishedBtn, &QPushButton::clicked, + this, &DFMVaultActiveFinishedView::slotEncryptVault); + + // 布局 + m_pWidget1 = new QWidget(this); + QVBoxLayout *play1 = new QVBoxLayout(m_pWidget1); + play1->setMargin(0); + play1->addWidget(m_pTips); + play1->addSpacing(22); + play1->addWidget(m_pEncryVaultImage); + + m_pWidget2 = new QWidget(this); + QVBoxLayout *play2 = new QVBoxLayout(m_pWidget2); + play2->setContentsMargins(0, 22, 0, 0); + play2->addWidget(m_pWaterProgress, 0, Qt::AlignCenter); + play2->addSpacing(22); + play2->addWidget(m_pTips3, 0, Qt::AlignCenter); + + m_pWidget3 = new QWidget(this); + QVBoxLayout *play3 = new QVBoxLayout(m_pWidget3); + play3->setContentsMargins(0, 15, 0, 0); + play3->addWidget(m_pEncryptFinishedImage); + play3->addSpacing(10); + play3->addWidget(m_pTips4); + + QVBoxLayout *m_pLay = new QVBoxLayout(this); + m_pLay->setMargin(0); + m_pLay->addWidget(pLabelTitle); + m_pLay->addSpacing(10); + m_pLay->addWidget(m_pWidget1); + m_pLay->addWidget(m_pWidget2, 0, Qt::AlignHCenter); + m_pLay->addWidget(m_pWidget3); + m_pLay->addStretch(); + m_pLay->addWidget(m_pFinishedBtn); + + m_pWidget2->setVisible(false); + m_pWidget3->setVisible(false); + + // cryfs对象 + VaultController *pcryfs = VaultController::ins(); + connect(pcryfs, &VaultController::signalCreateVault, + this, &DFMVaultActiveFinishedView::slotEncryptComplete); + + // 初始化定时器 + m_pTimer = new QTimer(this); + connect(m_pTimer, &QTimer::timeout, + this, &DFMVaultActiveFinishedView::slotTimeout); +} + +void DFMVaultActiveFinishedView::setFinishedBtnEnabled(bool b) +{ + m_pFinishedBtn->setEnabled(b); + m_pFinishedBtn->setText(tr("Encrypt")); + m_pWidget1->setVisible(true); + m_pWidget2->setVisible(false); + m_pWidget3->setVisible(false); +} + +void DFMVaultActiveFinishedView::slotEncryptComplete(int nState) +{ + if (nState == 0) { // 创建保险箱成功 + m_pWaterProgress->setValue(100); + m_pWaterProgress->stop(); + repaint(); + m_pTimer->setSingleShot(true); + m_pTimer->start(500); + + // Reset autolock time config. + VaultLockManager::getInstance().resetConfig(); + + // 保险箱初始化操作 + VaultController::ins()->restoreLeftoverErrorInputTimes(); + VaultController::ins()->restoreNeedWaitMinutes(); + } else { + QMessageBox::warning(this, QString(), QString(tr("Failed to create file vault: %1").arg(nState))); + } +} + +void DFMVaultActiveFinishedView::slotEncryptVault() +{ + if (m_pFinishedBtn->text() == tr("Encrypt")) { + // 异步授权 + auto ins = Authority::instance(); + ins->checkAuthorization(VAULT_CREATE, + UnixProcessSubject(getpid()), + Authority::AllowUserInteraction); + connect(ins, &Authority::checkAuthorizationFinished, + this, &DFMVaultActiveFinishedView::slotCheckAuthorizationFinished); + // 灰化按钮,避免异步时用户再次点击按钮 + m_pFinishedBtn->setEnabled(false); + } else { + // 切换到保险箱主页面 + emit sigAccepted(); + } +} + +void DFMVaultActiveFinishedView::slotCheckAuthorizationFinished(PolkitQt1::Authority::Result result) +{ + disconnect(Authority::instance(), &Authority::checkAuthorizationFinished, + this, &DFMVaultActiveFinishedView::slotCheckAuthorizationFinished); + if (isVisible()) { + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::CREATEVAULTPAGE1); + if (result == Authority::Yes) { + if (m_pFinishedBtn->text() == tr("Encrypt")) { + // 完成按钮灰化 + m_pFinishedBtn->setEnabled(false); + // 隐藏右上角关闭按钮 + if (parentWidget()) { + DDialog *pParent = qobject_cast(parentWidget()->parentWidget()); + if (pParent) { + pParent->setCloseButtonVisible(false); + } + } + + // 进度条 + m_pWaterProgress->start(); + m_pWidget1->setVisible(false); + m_pWidget2->setVisible(true); + m_pWidget3->setVisible(false); + + std::thread t([]() { + // 调用创建保险箱接口 + // 拿到密码 + QString strPassword = OperatorCenter::getInstance()->getSaltAndPasswordCipher(); + if (!strPassword.isEmpty()) { + VaultController::ins()->createVault(strPassword); + OperatorCenter::getInstance()->clearSaltAndPasswordCipher(); + } else + qDebug() << "获取cryfs密码为空,创建保险箱失败!"; + }); + t.detach(); + } + } + else { + m_pFinishedBtn->setEnabled(true); + } + } +} + +void DFMVaultActiveFinishedView::showEvent(QShowEvent *event) +{ + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::CREATEVAULTPAGE1); + QWidget::showEvent(event); +} + +void DFMVaultActiveFinishedView::slotTimeout() +{ + m_pWidget1->setVisible(false); + m_pWidget2->setVisible(false); + m_pWidget3->setVisible(true); + m_pFinishedBtn->setText(tr("OK")); + m_pFinishedBtn->setEnabled(true); + // 显示右上角关闭按钮 + if (parentWidget()) { + DDialog *pParent = qobject_cast(parentWidget()->parentWidget()); + if (pParent) { + pParent->setCloseButtonVisible(true); + } + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivefinishedview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivefinishedview.h new file mode 100644 index 0000000..6508ade --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivefinishedview.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMVAULTACTIVEFINISHEDVIEW_H +#define DFMVAULTACTIVEFINISHEDVIEW_H + +#include + +#include + +#include + +QT_BEGIN_NAMESPACE +class QLabel; +class QPushButton; +class QGridLayout; +class QVBoxLayout; +QT_END_NAMESPACE + +DWIDGET_BEGIN_NAMESPACE +class DIconButton; +class DWaterProgress; +class DLabel; +DWIDGET_END_NAMESPACE + +DWIDGET_USE_NAMESPACE + +class DFMVaultActiveFinishedView : public QWidget +{ + Q_OBJECT +public: + explicit DFMVaultActiveFinishedView(QWidget *parent = nullptr); + + void setFinishedBtnEnabled(bool b); + +signals: + void sigAccepted(); + +public slots: + // 连接创建保险箱返回信号 + void slotEncryptComplete(int nState); + +private slots: + void slotEncryptVault(); + void slotTimeout(); + // 异步授权时,此函数接收授权完成的结果 + void slotCheckAuthorizationFinished(PolkitQt1::Authority::Result result); + +protected: + void showEvent(QShowEvent *event) override; + +private: + QWidget *m_pWidget1; + DLabel *m_pTips; + DLabel *m_pEncryVaultImage; + + QWidget *m_pWidget2; + DWaterProgress *m_pWaterProgress; + DLabel *m_pTips3; + + QWidget *m_pWidget3; + DLabel *m_pEncryptFinishedImage; + DLabel *m_pTips4; + + QPushButton *m_pFinishedBtn; + + QVBoxLayout *m_pLay; + + // 辅助进度条,实现加密过程效果 + QTimer *m_pTimer; +}; + +#endif // DFMVAULTACTIVEFINISHEDVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesavekeyfileview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesavekeyfileview.cpp new file mode 100644 index 0000000..5495be4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesavekeyfileview.cpp @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "dfmvaultactivesavekeyfileview.h" +#include "accessibility/ac-lib-file-manager.h" +#include "vaultglobaldefine.h" +#include "operatorcenter.h" +#include "dguiapplicationhelper.h" +#include "controllers/vaultcontroller.h" + +#include +#include + +#include +#include +#include +#include +#include + +DGUI_USE_NAMESPACE + +DFMVaultActiveSaveKeyFileView::DFMVaultActiveSaveKeyFileView(QWidget *parent) + : QWidget(parent) +{ + initUI(); +} + +void DFMVaultActiveSaveKeyFileView::initUI() +{ + m_title = new DLabel(this); + DFontSizeManager::instance()->bind(m_title, DFontSizeManager::T7, QFont::Medium); + m_title->setForegroundRole(DPalette::TextTitle); + m_title->setAlignment(Qt::AlignCenter); + m_title->setText(tr("Save Recovery Key")); + + m_hintMsg = new DLabel(this); + DFontSizeManager::instance()->bind(m_hintMsg, DFontSizeManager::T7, QFont::Normal); + m_hintMsg->setForegroundRole(DPalette::TextTips); + m_hintMsg->setWordWrap(true); + m_hintMsg->setAlignment(Qt::AlignCenter); + m_hintMsg->setText(tr("Keep the key safe to retrieve the vault password later")); + + m_defaultPathRadioBtn = new QRadioButton(this); + DFontSizeManager::instance()->bind(m_defaultPathRadioBtn, DFontSizeManager::T7, QFont::Medium); + m_defaultPathRadioBtn->setForegroundRole(DPalette::ButtonText); + AC_SET_ACCESSIBLE_NAME(m_defaultPathRadioBtn, AC_VAULT_DEFAULT_PATH_RADIOBTN); + m_defaultPathRadioBtn->setChecked(true); + m_defaultPathRadioBtn->setText(tr("Save to default path")); + + m_otherPathRadioBtn = new QRadioButton(this); + DFontSizeManager::instance()->bind(m_otherPathRadioBtn, DFontSizeManager::T7, QFont::Medium); + m_otherPathRadioBtn->setForegroundRole(DPalette::ButtonText); + AC_SET_ACCESSIBLE_NAME(m_otherPathRadioBtn, AC_VAULT_OTHER_PATH_RADIOBTN); + m_otherPathRadioBtn->setText(tr("Save to other locations")); + + m_otherRadioBtnHitMsg = new DLabel(tr("No permission, please reselect"), this); + m_otherRadioBtnHitMsg->hide(); + DFontSizeManager::instance()->bind(m_otherRadioBtnHitMsg, DFontSizeManager::T9, QFont::Normal); + m_otherRadioBtnHitMsg->setForegroundRole(DPalette::TextWarning); + + m_SelectfileSavePathEdit = new DFileChooserEdit(this); + DFontSizeManager::instance()->bind(m_otherPathRadioBtn, DFontSizeManager::T8, QFont::Medium); + AC_SET_ACCESSIBLE_NAME(m_SelectfileSavePathEdit, AC_VAULT_SELECT_FILE_SAVE_PATH_EDIT); + m_SelectfileSavePathEdit->lineEdit()->setReadOnly(true); + m_SelectfileSavePathEdit->lineEdit()->setPlaceholderText(tr("Select a path")); + QFileDialog *filedialog = new QFileDialog(m_SelectfileSavePathEdit, QDir::homePath(), QString("pubKey.key")); + filedialog->setAcceptMode(QFileDialog::AcceptMode::AcceptSave); + filedialog->setNameFilter("KEY file(*.key)"); + filedialog->setDefaultSuffix(QString("key")); + m_SelectfileSavePathEdit->setFileDialog(filedialog); + m_SelectfileSavePathEdit->setDirectoryUrl(QDir::homePath()); + m_SelectfileSavePathEdit->setEnabled(false); + m_SelectfileSavePathEdit->setFileMode(QFileDialog::Directory); + + QButtonGroup *group = new QButtonGroup(this); + group->addButton(m_defaultPathRadioBtn, 1); + group->addButton(m_otherPathRadioBtn, 2); + + connect(group, SIGNAL(buttonClicked(QAbstractButton *)), this, SLOT(slotSelectRadioBtn(QAbstractButton *))); + connect(m_SelectfileSavePathEdit, &DFileChooserEdit::fileChoosed, this, &DFMVaultActiveSaveKeyFileView::slotChangeEdit); + connect(filedialog, &QFileDialog::fileSelected, this, &DFMVaultActiveSaveKeyFileView::slotSelectCurrentFile); + + // 下一步按钮 + m_pNext = new QPushButton(tr("Next"), this); + AC_SET_ACCESSIBLE_NAME(m_pNext, AC_VAULT_ACTIVE_KEY_NEXT_BUTTON); + connect(m_pNext, &QPushButton::clicked, + this, &DFMVaultActiveSaveKeyFileView::slotNextBtnClicked); + + RadioFrame *frame = new RadioFrame; + + DLabel *checkBoxLabel = new DLabel(frame); + DFontSizeManager::instance()->bind(checkBoxLabel, DFontSizeManager::T10, QFont::Normal); + checkBoxLabel->setForegroundRole(DPalette::TextTips); + checkBoxLabel->setWordWrap(true); + checkBoxLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + checkBoxLabel->setText(tr("The default path is invisible to other users, and the path information will not be shown.")); + + QHBoxLayout *layout = new QHBoxLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(m_defaultPathRadioBtn); + + QHBoxLayout *layout1 = new QHBoxLayout(); + layout1->setContentsMargins(30, 0, 0, 0); + layout1->addWidget(checkBoxLabel); + + QVBoxLayout *layout2 = new QVBoxLayout(frame); + layout2->setContentsMargins(8, 5, 8, 5); + layout2->setSpacing(0); + layout2->addLayout(layout); + layout2->addLayout(layout1); + layout2->addStretch(2); + + RadioFrame *frame1 = new RadioFrame; + + QFrame *line = new QFrame(this); + line->setObjectName(QString("line")); + line->setFixedHeight(1); + line->installEventFilter(this); + + QHBoxLayout *layout3 = new QHBoxLayout(); + layout3->setContentsMargins(0, 0, 0, 0); + layout3->addWidget(m_otherPathRadioBtn); + layout3->addWidget(m_otherRadioBtnHitMsg); + layout3->addStretch(1); + + QHBoxLayout *layout4 = new QHBoxLayout; + layout4->setContentsMargins(8, 5, 8, 5); + layout4->addLayout(layout3); + + QHBoxLayout *layout5 = new QHBoxLayout; + layout5->setContentsMargins(10, 10, 10, 10); + layout5->addWidget(m_SelectfileSavePathEdit); + + QVBoxLayout *vlayout5 = new QVBoxLayout(frame1); + vlayout5->setMargin(0); + vlayout5->setSpacing(0); + vlayout5->addLayout(layout4); + vlayout5->addWidget(line); + vlayout5->addLayout(layout5); + + QVBoxLayout *vlayout3 = new QVBoxLayout; + vlayout3->setContentsMargins(20, 0, 20, 0); + vlayout3->addWidget(frame, 1); + vlayout3->addSpacing(3); + vlayout3->addWidget(frame1, 1); + + QVBoxLayout *vlayout1 = new QVBoxLayout; + vlayout1->setContentsMargins(0, 0, 0, 0); + vlayout1->addWidget(m_title); + vlayout1->addWidget(m_hintMsg); + vlayout1->addStretch(2); + vlayout1->addLayout(vlayout3); + vlayout1->addStretch(2); + vlayout1->addWidget(m_pNext); + + setLayout(vlayout1); +} + +void DFMVaultActiveSaveKeyFileView::slotNextBtnClicked() +{ + //! 获取密钥字符串 + QString pubKey = OperatorCenter::getInstance()->getPubKey(); + if (pubKey.isEmpty()) { + return; + } + + bool flg = false; + if (m_defaultPathRadioBtn->isChecked()) { + //! 密钥保存默认路径 + QString path = VAULT_BASE_PATH + QString("/") + (RSA_PUB_KEY_FILE_NAME) + QString(".key"); + flg = OperatorCenter::getInstance()->saveKey(pubKey, path); + } else if (m_otherPathRadioBtn->isChecked()) { + //! 密钥保存用户指定路径 + QString path = m_SelectfileSavePathEdit->text(); + flg = OperatorCenter::getInstance()->saveKey(pubKey, path); + } + + if (flg) { + emit sigAccepted(); + } +} + +void DFMVaultActiveSaveKeyFileView::slotSelectRadioBtn(QAbstractButton *btn) +{ + if (btn == m_defaultPathRadioBtn) { + m_SelectfileSavePathEdit->setEnabled(false); + m_pNext->setEnabled(true); + } else if (btn == m_otherPathRadioBtn) { + m_SelectfileSavePathEdit->setEnabled(true); + if (m_SelectfileSavePathEdit->text().isEmpty()) + m_pNext->setEnabled(false); + } +} + +void DFMVaultActiveSaveKeyFileView::slotChangeEdit(const QString &fileName) +{ + QDir dir(fileName); + dir.cdUp(); + QString path = dir.absolutePath(); + QFile file(path); + QFileDevice::Permissions ps = file.permissions(); + auto temp = ps & QFileDevice::WriteUser; + if (temp != QFileDevice::WriteUser) { + m_pNext->setEnabled(false); + m_otherRadioBtnHitMsg->show(); + } else if (!fileName.isEmpty()) { + m_otherRadioBtnHitMsg->hide(); + m_pNext->setEnabled(true); + } +} + +void DFMVaultActiveSaveKeyFileView::slotSelectCurrentFile(const QString &file) +{ + QFileInfo fileInfo(file); + if (fileInfo.isDir()) { + m_SelectfileSavePathEdit->fileDialog()->selectFile(QString("pubKey.key")); + } else if (!file.endsWith(QString(".key"))) { + m_SelectfileSavePathEdit->fileDialog()->selectFile(file + QString(".key")); + } +} + +void DFMVaultActiveSaveKeyFileView::showEvent(QShowEvent *event) +{ + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::CREATEVAULTPAGE); + m_defaultPathRadioBtn->setChecked(true); + m_SelectfileSavePathEdit->clear(); + m_otherRadioBtnHitMsg->hide(); + QWidget::showEvent(event); +} + +bool DFMVaultActiveSaveKeyFileView::eventFilter(QObject *watched, QEvent *event) +{ + if(watched->objectName() == QString("line") && event->type() == QEvent::Paint) { + QFrame *frame = static_cast(watched); + QPainter painter(frame); + QPalette palette = this->palette(); + painter.setBrush(palette.background()); + + painter.setPen(Qt::transparent); + QRect rect = this->rect(); + rect.setWidth(rect.width() - 1); + rect.setHeight(rect.height() - 1); + painter.drawRoundedRect(rect, 0, 0); + { + QPainterPath painterPath; + painterPath.addRoundedRect(rect, 0, 0); + painter.drawPath(painterPath); + } + } + + return QWidget::eventFilter(watched, event); +} + +RadioFrame::RadioFrame(QFrame *parent) + : QFrame(parent) +{ + DPalette pal; + QColor color; + color.setRgbF(0.9, 0.9, 0.9, 0.03); + pal.setColor(DPalette::Light, color); + this->setPalette(pal); +} + +void RadioFrame::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); // 反锯齿; + if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType) { + painter.setBrush(QBrush(QColor("#4c252525"))); + } else if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) { + QColor color; + color.setRgbF(0.0, 0.0, 0.0, 0.03); + painter.setBrush(QBrush(color)); + } + + painter.setPen(Qt::transparent); + QRect rect = this->rect(); + rect.setWidth(rect.width() - 1); + rect.setHeight(rect.height() - 1); + painter.drawRoundedRect(rect, 8, 8); + //也可用QPainterPath 绘制代替 painter.drawRoundedRect(rect, 8, 8); + { + QPainterPath painterPath; + painterPath.addRoundedRect(rect, 8, 8); + painter.drawPath(painterPath); + } + QFrame::paintEvent(event); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesavekeyfileview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesavekeyfileview.h new file mode 100644 index 0000000..665dbe8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesavekeyfileview.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef DFMVAULTACTIVESAVEKEYFILEVIEW_H +#define DFMVAULTACTIVESAVEKEYFILEVIEW_H + +#include +#include + +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class RadioFrame : public QFrame +{ + Q_OBJECT +public: + explicit RadioFrame(QFrame *parent = nullptr); + +protected: + void paintEvent(QPaintEvent *event) override; +}; + +class DFMVaultActiveSaveKeyFileView : public QWidget +{ + Q_OBJECT +public: + explicit DFMVaultActiveSaveKeyFileView(QWidget *parent = nullptr); + + void initUI(); + +signals: + /** + * @brief sigAccepted 下一步的信号 + */ + void sigAccepted(); + +public slots: + /** + * @brief slotNextBtnClicked 保存密钥文件 + */ + void slotNextBtnClicked(); + + /** + * @brief slotSelectRadioBtn 单选框选中槽函数 + * @param btn 选中的单选框按钮 + */ + void slotSelectRadioBtn(QAbstractButton *btn); + + /** + * @brief slotChangeEdit 处理保存密钥路径权限问题,并在UI上进行提示 + * @param fileName 选择保存密钥的路径 + */ + void slotChangeEdit(const QString &fileName); + + void slotSelectCurrentFile(const QString &file); + +protected: + void showEvent(QShowEvent *event) override; + + virtual bool eventFilter(QObject *watched, QEvent *event) override; + +private: + //! 保存密钥文件页面标题 + DLabel *m_title = nullptr; + //! 密钥文件安全提示 + DLabel *m_hintMsg = nullptr; + //! 默认保存单选框按钮 + QRadioButton *m_defaultPathRadioBtn = nullptr; + //! 用户自定义保存单选框按钮 + QRadioButton *m_otherPathRadioBtn = nullptr; + //! 用户自定义保存路径编辑框 + DFileChooserEdit *m_SelectfileSavePathEdit = nullptr; + //! 保存密钥文件并进行下一步操作的按钮 + QPushButton *m_pNext = nullptr; + //! 保存密钥权限提示 + DLabel *m_otherRadioBtnHitMsg = nullptr; +}; + +#endif // DFMVAULTACTIVESAVEKEYFILEVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesavekeyview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesavekeyview.cpp new file mode 100644 index 0000000..a927ee4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesavekeyview.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmvaultactivesavekeyview.h" +#include "operatorcenter.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +DFMVaultActiveSaveKeyView::DFMVaultActiveSaveKeyView(QWidget *parent) + : QWidget(parent) + , m_pTipsLabel(nullptr) + , m_pQRCodeImage(nullptr) + , m_pNext(nullptr) +{ + AC_SET_ACCESSIBLE_NAME(this, AC_VAULT_ACTIVE_KEY_WIDGET); + + // 标题名 + QLabel *pLabelTitle = new QLabel(tr("Recovery Key"), this); + AC_SET_ACCESSIBLE_NAME(pLabelTitle, AC_VAULT_ACTIVE_KEY_TITLE); + QFont font = pLabelTitle->font(); + font.setPixelSize(18); + pLabelTitle->setFont(font); + pLabelTitle->setAlignment(Qt::AlignHCenter); + + // 提示标签 + m_pTipsLabel = new DLabel(tr("Generate a recovery key in case that you forgot the password"), this); + AC_SET_ACCESSIBLE_NAME(m_pTipsLabel, AC_VAULT_ACTIVE_KEY_CONTENT); + + DButtonBox *m_pButtonBox = new DButtonBox(this); + + // 密钥 + m_pKeyBtn = new DButtonBoxButton(tr("Key"), this); + AC_SET_ACCESSIBLE_NAME(m_pKeyBtn, AC_VAULT_ACTIVE_KEY_KEY_BUTTON); + m_pKeyBtn->setCheckable(true); + m_pKeyBtn->setChecked(true); + connect(m_pKeyBtn, &DButtonBoxButton::clicked, + this, &DFMVaultActiveSaveKeyView::slotKeyBtnClicked); + m_pKeyText = new QPlainTextEdit(this); + AC_SET_ACCESSIBLE_NAME(m_pKeyText, AC_VAULT_ACTIVE_KEY_KEY_EDIT); + m_pKeyText->setReadOnly(true); + m_pKeyText->setFixedSize(452, 134); + + // 二维码 + m_pQRCodeBtn = new DButtonBoxButton(tr("QR code"), this); + AC_SET_ACCESSIBLE_NAME(m_pQRCodeBtn, AC_VAULT_ACTIVE_KEY_QRCODE_BUTTON); + m_pQRCodeBtn->setCheckable(true); + connect(m_pQRCodeBtn, &DButtonBoxButton::clicked, + this, &DFMVaultActiveSaveKeyView::slotQRCodeBtnClicked); + m_pQRCodeImage = new DLabel(this); + AC_SET_ACCESSIBLE_NAME(m_pQRCodeImage, AC_VAULT_ACTIVE_KEY_QRCODE_IMAGE); + m_pQRCodeImage->setFixedSize(120, 120); + m_pQRCodeImage->setVisible(false); + + QList lstBtn; + lstBtn.push_back(m_pKeyBtn); + lstBtn.push_back(m_pQRCodeBtn); + m_pButtonBox->setButtonList(lstBtn, true); + + // 扫描提示 + m_pScanTipsLabel = new DLabel(tr("Scan QR code and save the key to another device"), this); + AC_SET_ACCESSIBLE_NAME(m_pScanTipsLabel, AC_VAULT_ACTIVE_KEY_QRCODE_HINT); + QFont font2 = m_pScanTipsLabel->font(); + font2.setPixelSize(12); + m_pScanTipsLabel->setFont(font2); + m_pScanTipsLabel->setVisible(false); + + // 下一步按钮 + m_pNext = new QPushButton(tr("Next"), this); + AC_SET_ACCESSIBLE_NAME(m_pNext, AC_VAULT_ACTIVE_KEY_NEXT_BUTTON); + connect(m_pNext, &QPushButton::clicked, + this, &DFMVaultActiveSaveKeyView::slotNextBtnClicked); + + // 布局 + play1 = new QGridLayout(); + play1->setMargin(0); + play1->addWidget(m_pTipsLabel, 0, 0, 1, 4, Qt::AlignCenter); + play1->addWidget(m_pButtonBox, 1, 0, 1, 4, Qt::AlignHCenter); + play1->addWidget(m_pKeyText, 2, 0, 2, 4, Qt::AlignCenter); + + + QVBoxLayout *play = new QVBoxLayout(this); + play->setMargin(0); + play->addWidget(pLabelTitle); + play->addLayout(play1); + play->addStretch(); + play->addWidget(m_pNext); +} + +void DFMVaultActiveSaveKeyView::showEvent(QShowEvent *event) +{ + QString strUserKey = OperatorCenter::getInstance()->getUserKey(); + qDebug() << "user key: " << strUserKey; + + QString strKeyShow = strUserKey; + strKeyShow.insert(28, '-'); + strKeyShow.insert(24, '-'); + strKeyShow.insert(20, '-'); + strKeyShow.insert(16, '-'); + strKeyShow.insert(12, '-'); + strKeyShow.insert(8, '-'); + strKeyShow.insert(4, '-'); + QString strContent = QString(tr("Recovery Key:")) + strKeyShow; + QPixmap QRCodePix; + if (OperatorCenter::getInstance()->createQRCode(strContent, m_pQRCodeImage->width(), m_pQRCodeImage->height(), QRCodePix)) + m_pQRCodeImage->setPixmap(QRCodePix); + m_pKeyText->setPlainText(strKeyShow); + + QWidget::showEvent(event); +} + +void DFMVaultActiveSaveKeyView::slotNextBtnClicked() +{ + emit sigAccepted(); +} + +void DFMVaultActiveSaveKeyView::slotKeyBtnClicked() +{ + play1->removeWidget(m_pQRCodeImage); + m_pQRCodeImage->setVisible(false); + play1->removeWidget(m_pScanTipsLabel); + m_pScanTipsLabel->setVisible(false); + + play1->addWidget(m_pKeyText, 2, 0, 2, 4, Qt::AlignCenter); + m_pKeyText->setVisible(true); +} + +void DFMVaultActiveSaveKeyView::slotQRCodeBtnClicked() +{ + m_pKeyText->setVisible(false); + play1->removeWidget(m_pKeyText); + + play1->addWidget(m_pQRCodeImage, 2, 0, 1, 4, Qt::AlignHCenter); + m_pQRCodeImage->setVisible(true); + play1->addWidget(m_pScanTipsLabel, 3, 0, 1, 4, Qt::AlignHCenter); + m_pScanTipsLabel->setVisible(true); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesavekeyview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesavekeyview.h new file mode 100644 index 0000000..8672859 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesavekeyview.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMVAULTACTIVESAVEKEYVIEW_H +#define DFMVAULTACTIVESAVEKEYVIEW_H + +#include + +#include + +QT_BEGIN_NAMESPACE +class QLabel; +class QPushButton; +class QLineEdit; +class QTextEdit; +class QGridLayout; +class QPlainTextEdit; +QT_END_NAMESPACE + +DWIDGET_BEGIN_NAMESPACE +class DButtonBoxButton; +class DLabel; +DWIDGET_END_NAMESPACE +DWIDGET_USE_NAMESPACE + +/** + * @brief The DFMVaultActiveSaveKeyView class 由于新需求UI界面改动很大,所以此类弃用 + */ +class DFMVaultActiveSaveKeyView : public QWidget +{ + Q_OBJECT +public: + explicit DFMVaultActiveSaveKeyView(QWidget *parent = nullptr); + +protected: + void showEvent(QShowEvent *event) override; + +public slots: + +private slots: + void slotNextBtnClicked(); + void slotKeyBtnClicked(); + void slotQRCodeBtnClicked(); + +signals: + void sigAccepted(); + +private: + +private: + DLabel *m_pTipsLabel; + DButtonBoxButton *m_pKeyBtn; + QPlainTextEdit *m_pKeyText; + DButtonBoxButton *m_pQRCodeBtn; + DLabel *m_pQRCodeImage; + DLabel *m_pScanTipsLabel; + QPushButton *m_pNext; + QGridLayout *play1; +}; + +#endif // DFMVAULTACTIVESAVEKEYVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesetunlockmethodview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesetunlockmethodview.cpp new file mode 100644 index 0000000..b8ec7cb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesetunlockmethodview.cpp @@ -0,0 +1,440 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmvaultactivesetunlockmethodview.h" +#include "operatorcenter.h" +#include "accessibility/ac-lib-file-manager.h" +#include "controllers/vaultcontroller.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DFMVaultActiveSetUnlockMethodView::DFMVaultActiveSetUnlockMethodView(QWidget *parent) + : QWidget(parent) + , m_pTypeCombo(nullptr) + , m_pPassword(nullptr) + , m_pRepeatPassword(nullptr) + , m_pPasswordHintLabel(nullptr) + , m_pTips(nullptr) +// , m_pOtherMethod(nullptr) + , m_pNext(nullptr) +{ + AC_SET_ACCESSIBLE_NAME(this, AC_VAULT_ACTIVE_SET_PASSWORD_WIDGET); + + // 设置开锁方式标签 + QLabel *pLabel = new QLabel(tr("Set Vault Password"), this); + AC_SET_ACCESSIBLE_NAME(pLabel, AC_VAULT_ACTIVE_SET_PASSWORD_TITLE); + QFont font = pLabel->font(); + font.setPixelSize(18); + pLabel->setFont(font); + pLabel->setAlignment(Qt::AlignHCenter); + + // 类型 + DLabel *pTypeLabel = new DLabel(tr("Method"), this); + AC_SET_ACCESSIBLE_NAME(pTypeLabel, AC_VAULT_ACTIVE_SET_PASSWORD_TYPE_LABEL); + m_pTypeCombo = new QComboBox(this); + AC_SET_ACCESSIBLE_NAME(m_pTypeCombo, AC_VAULT_ACTIVE_SET_PASSWORD_TYPE_COMBOX); + QStringList lstItems; + lstItems << tr("Manual")/* << tr("Random")*/; + m_pTypeCombo->addItems(lstItems); + connect(m_pTypeCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(slotTypeChanged(int))); + + // 设置只能输入大小写字母、数字和部分符号的正则表达式 + QRegExp regx("[A-Za-z0-9,.;?@/=()<>_+*&^%$#!`~\'\"|]+"); + // 创建验证器 + QValidator *validator = new QRegExpValidator(regx, this); + + // 设置密码 + m_pPasswordLabel = new DLabel(tr("Password"), this); + AC_SET_ACCESSIBLE_NAME(m_pPasswordLabel, AC_VAULT_ACTIVE_SET_PASSWORD_PASSWORD_LABEL); + m_pPassword = new DPasswordEdit(this); + AC_SET_ACCESSIBLE_NAME(m_pPassword, AC_VAULT_ACTIVE_SET_PASSWORD_PASSWORD_EDIT); + m_pPassword->lineEdit()->setValidator(validator); // 设置验证器 + m_pPassword->lineEdit()->setPlaceholderText(tr("≥ 8 chars, contains A-Z, a-z, 0-9, and symbols")); + m_pPassword->lineEdit()->setAttribute(Qt::WA_InputMethodEnabled, false); + connect(m_pPassword, &DPasswordEdit::textEdited, + this, &DFMVaultActiveSetUnlockMethodView::slotLimiPasswordLength); + connect(m_pPassword, &DPasswordEdit::editingFinished, + this, &DFMVaultActiveSetUnlockMethodView::slotPasswordEditFinished); + connect(m_pPassword, &DPasswordEdit::textChanged, + this, &DFMVaultActiveSetUnlockMethodView::slotPasswordEditing); + connect(m_pPassword, &DPasswordEdit::focusChanged, + this, &DFMVaultActiveSetUnlockMethodView::slotPasswordEditFocusChanged); + + + // 重复密码 + m_pRepeatPasswordLabel = new DLabel(tr("Repeat password"), this); + AC_SET_ACCESSIBLE_NAME(m_pRepeatPasswordLabel, AC_VAULT_ACTIVE_SET_PASSWORD_REPASSWORD_LABEL); + m_pRepeatPassword = new DPasswordEdit(this); + AC_SET_ACCESSIBLE_NAME(m_pRepeatPassword, AC_VAULT_ACTIVE_SET_PASSWORD_REPASSWORD_EDIT); + m_pRepeatPassword->lineEdit()->setValidator(validator); // 设置验证器 + m_pRepeatPassword->lineEdit()->setPlaceholderText(tr("Input the password again")); + m_pRepeatPassword->lineEdit()->setAttribute(Qt::WA_InputMethodEnabled, false); + connect(m_pRepeatPassword, &DPasswordEdit::textEdited, + this, &DFMVaultActiveSetUnlockMethodView::slotLimiPasswordLength); + connect(m_pRepeatPassword, &DPasswordEdit::editingFinished, + this, &DFMVaultActiveSetUnlockMethodView::slotRepeatPasswordEditFinished); + connect(m_pRepeatPassword, &DPasswordEdit::textChanged, + this, &DFMVaultActiveSetUnlockMethodView::slotRepeatPasswordEditing); + connect(m_pRepeatPassword, &DPasswordEdit::focusChanged, + this, &DFMVaultActiveSetUnlockMethodView::slotRepeatPasswordEditFocusChanged); + + // 提示信息 + m_pPasswordHintLabel = new DLabel(tr("Password hint"), this); + AC_SET_ACCESSIBLE_NAME(m_pPasswordHintLabel, AC_VAULT_ACTIVE_SET_PASSWORD_HINT_LABEL); + m_pTips = new QLineEdit(this); + AC_SET_ACCESSIBLE_NAME(m_pTips, AC_VAULT_ACTIVE_SET_PASSWORD_HINT_EDIT); + m_pTips->setMaxLength(14); + m_pTips->setPlaceholderText(tr("Optional")); + + + + // 下一步按钮 + m_pNext = new QPushButton(tr("Next"), this); + AC_SET_ACCESSIBLE_NAME(m_pNext, AC_VAULT_ACTIVE_SET_PASSWORD_NEXT_BUTTON); + m_pNext->setEnabled(false); + connect(m_pNext, &QPushButton::clicked, + this, &DFMVaultActiveSetUnlockMethodView::slotNextBtnClicked); + + // 其他解锁方式 +// m_pOtherMethod = new QCheckBox(tr("Fingerprint"), this); +// m_pOtherMethod->setVisible(false); + // 长度 +// m_pLengthLabel = new QLabel(tr("Length"), this); +// m_pLengthSlider = new QSlider(this); +// m_pLengthSlider->setOrientation(Qt::Horizontal); +// m_pLengthSlider->setRange(8, 24); +// connect(m_pLengthSlider, &QSlider::valueChanged, +// this, &DFMVaultActiveSetUnlockMethodView::slotLengthChanged); +// m_pLengthEdit = new QLineEdit(this); +// m_pLengthEdit->setMaximumWidth(60); +// m_pLengthEdit->setReadOnly(true); +// m_pLengthEdit->setText(tr("8Bit")); +// m_pStrengthLabel = new QLabel(tr("Week"), this); +// m_pStrengthLabel->setStyleSheet("color: #FF4500"); +// m_pStrengthLabel->setMaximumWidth(50); +// m_pLengthLabel->setVisible(false); +// m_pLengthSlider->setVisible(false); +// m_pLengthEdit->setVisible(false); +// m_pStrengthLabel->setVisible(false); + + // 结果 +// m_pResultLabel = new QLabel(tr("Result"), this); +// m_pResultEdit = new QLineEdit(tr(""), this); +// connect(m_pResultEdit, &QLineEdit::textChanged, +// this, &DFMVaultActiveSetUnlockMethodView::slotGenerateEditChanged); +// m_pResultLabel->setVisible(false); +// m_pResultEdit->setVisible(false); + + // 生成随即密码按钮 +// m_pGenerateBtn = new QPushButton(tr("Generate"), this); +// connect(m_pGenerateBtn, &QPushButton::clicked, +// this, &DFMVaultActiveSetUnlockMethodView::slotGeneratePasswordBtnClicked); +// m_pGenerateBtn->setVisible(false); + + // 布局 + play1 = new QGridLayout(); + play1->setMargin(0); + + play1->addWidget(pTypeLabel, 0, 0, 1, 1, Qt::AlignLeft); + play1->addWidget(m_pTypeCombo, 0, 1, 1, 5); + + play1->addWidget(m_pPasswordLabel, 1, 0, 1, 1, Qt::AlignLeft); + play1->addWidget(m_pPassword, 1, 1, 1, 5); + + play1->addWidget(m_pRepeatPasswordLabel, 2, 0, 1, 1, Qt::AlignLeft); + play1->addWidget(m_pRepeatPassword, 2, 1, 1, 5); + + play1->addWidget(m_pPasswordHintLabel, 3, 0, 1, 1, Qt::AlignLeft); + play1->addWidget(m_pTips, 3, 1, 1, 5); + + QVBoxLayout *play = new QVBoxLayout(this); + play->setMargin(0); + play->addWidget(pLabel); + play->addSpacing(15); + play->addLayout(play1); + play->addStretch(); + play->addWidget(m_pNext); + + // 创建文件夹与目录 + if (!OperatorCenter::getInstance()->createDirAndFile()) return; +} + +void DFMVaultActiveSetUnlockMethodView::clearText() +{ + m_pPassword->clear(); + m_pPassword->hideAlertMessage(); + // 修复BUG-51508 取消密码框警告状态 + m_pPassword->setAlert(false); + m_pRepeatPassword->clear(); + m_pRepeatPassword->hideAlertMessage(); + // 修复BUG-51508 取消密码框警告状态 + m_pRepeatPassword->setAlert(false); + m_pTips->clear(); +} + +void DFMVaultActiveSetUnlockMethodView::slotPasswordEditing() +{ + bool ok = checkPassword(m_pPassword->text()); + if (ok) { + if (checkInputInfo()) { + m_pNext->setEnabled(true); + } + } + m_pNext->setEnabled(false); +} + +void DFMVaultActiveSetUnlockMethodView::slotPasswordEditFinished() +{ + bool ok = checkPassword(m_pPassword->text()); + if (!ok) { + m_pNext->setEnabled(false); + // 修复BUG-51508 激活密码框警告状态 + m_pPassword->setAlert(true); + m_pPassword->showAlertMessage(tr("≥ 8 chars, contains A-Z, a-z, 0-9, and symbols"), TIPS_TIME); + } else { + if (checkInputInfo()) { + m_pNext->setEnabled(true); + } + } +} + +void DFMVaultActiveSetUnlockMethodView::slotPasswordEditFocusChanged(bool bFocus) +{ + if (bFocus) { + // 修复BUG-51508 取消密码框警告状态 + m_pPassword->setAlert(false); + m_pPassword->hideAlertMessage(); + } +} + +void DFMVaultActiveSetUnlockMethodView::slotRepeatPasswordEditFinished() +{ + bool ok = checkRepeatPassword(); + if (!ok) { + // 修复BUG-51508 激活密码框警告状态 + m_pRepeatPassword->setAlert(true); + m_pRepeatPassword->showAlertMessage(tr("Passwords do not match"), TIPS_TIME); + } +} + +void DFMVaultActiveSetUnlockMethodView::slotRepeatPasswordEditing() +{ + const QString &strRepeatPassword = m_pRepeatPassword->text(); + const QString &strPassword = m_pPassword->text(); + + bool bSizeMatch = strRepeatPassword.size() == strPassword.size(); + if (bSizeMatch) { + if (checkPassword(m_pPassword->text())) { + if (checkRepeatPassword()) { + m_pNext->setEnabled(true); + return; + } else { + m_pRepeatPassword->showAlertMessage(tr("Passwords do not match")); + } + } + } + m_pNext->setEnabled(false); +} + +void DFMVaultActiveSetUnlockMethodView::slotRepeatPasswordEditFocusChanged(bool bFocus) +{ + if (bFocus) { + // 修复BUG-51508 取消密码框警告状态 + m_pRepeatPassword->setAlert(false); + m_pRepeatPassword->hideAlertMessage(); + } +} + +void DFMVaultActiveSetUnlockMethodView::slotGenerateEditChanged(const QString &str) +{ + if (!checkPassword(str)) { + m_pNext->setEnabled(false); + } else { + m_pNext->setEnabled(true); + } +} + +void DFMVaultActiveSetUnlockMethodView::slotNextBtnClicked() +{ + QString strPassword = m_pPassword->text(); + QString strPasswordHint = m_pTips->text(); + if (OperatorCenter::getInstance()->saveSaltAndCiphertext(strPassword, strPasswordHint) + && OperatorCenter::getInstance()->createKeyNew(strPassword)) + emit sigAccepted(); +} + +void DFMVaultActiveSetUnlockMethodView::slotTypeChanged(int index) +{ + if (index) { // 随机 + + play1->removeWidget(m_pPasswordLabel); + play1->removeWidget(m_pPassword); + play1->removeWidget(m_pRepeatPasswordLabel); + play1->removeWidget(m_pRepeatPassword); +// play1->removeWidget(m_pOtherMethod); + + m_pPasswordLabel->setVisible(false); + m_pPassword->setVisible(false); + m_pRepeatPasswordLabel->setVisible(false); + m_pRepeatPassword->setVisible(false); +// m_pOtherMethod->setVisible(false); + +// play1->addWidget(m_pLengthLabel, 2, 0, 1, 1, Qt::AlignLeft); +// play1->addWidget(m_pLengthSlider, 2, 1, 1, 3); +// play1->addWidget(m_pLengthEdit, 2, 4, 1, 1); +// play1->addWidget(m_pStrengthLabel, 2, 5, 1, 1); +// play1->addWidget(m_pResultLabel, 3, 0, 1, 1, Qt::AlignLeft); +// play1->addWidget(m_pResultEdit, 3, 1, 1, 5); +// play1->addWidget(m_pGenerateBtn, 5, 2, 1, 2, Qt::AlignHCenter); + +// m_pLengthLabel->setVisible(true); +// m_pLengthSlider->setVisible(true); +// m_pLengthEdit->setVisible(true); +// m_pStrengthLabel->setVisible(true); +// m_pResultLabel->setVisible(true); +// m_pResultEdit->setVisible(true); +// m_pGenerateBtn->setVisible(true); + + // 检测密码的正确性 +// slotGenerateEditChanged(m_pResultEdit->text()); + + } else { // 手动 + + play1->addWidget(m_pPasswordLabel, 2, 0, 1, 1, Qt::AlignLeft); + play1->addWidget(m_pPassword, 2, 1, 1, 5); + play1->addWidget(m_pRepeatPasswordLabel, 3, 0, 1, 1, Qt::AlignLeft); + play1->addWidget(m_pRepeatPassword, 3, 1, 1, 5); +// play1->addWidget(m_pOtherMethod, 5, 2, 1, 2, Qt::AlignHCenter); + + m_pPasswordLabel->setVisible(true); + m_pPassword->setVisible(true); + m_pRepeatPasswordLabel->setVisible(true); + m_pRepeatPassword->setVisible(true); +// m_pOtherMethod->setVisible(true); + +// play1->removeWidget(m_pLengthLabel); +// play1->removeWidget(m_pLengthSlider); +// play1->removeWidget(m_pLengthEdit); +// play1->removeWidget(m_pStrengthLabel); +// play1->removeWidget(m_pResultLabel); +// play1->removeWidget(m_pResultEdit); +// play1->removeWidget(m_pGenerateBtn); + +// m_pLengthLabel->setVisible(false); +// m_pLengthSlider->setVisible(false); +// m_pLengthEdit->setVisible(false); +// m_pStrengthLabel->setVisible(false); +// m_pResultLabel->setVisible(false); +// m_pResultEdit->setVisible(false); +// m_pGenerateBtn->setVisible(false); + + // 检测密码正确性 + slotRepeatPasswordEditFinished(); + } +} + +//void DFMVaultActiveSetUnlockMethodView::slotLengthChanged(int length) +//{ +// m_pLengthEdit->setText(QString("%1%2").arg(length).arg(tr("Bit"))); +// if(length > 7 && length < 12){ +// m_pStrengthLabel->setText(tr("Week")); +// m_pStrengthLabel->setStyleSheet("color: #FF4500"); +// }else if(length >= 12 && length < 19){ +// m_pStrengthLabel->setText(tr("Medium")); +// m_pStrengthLabel->setStyleSheet("color: #EEC900"); +// }else if(length >= 19 && length < 25){ +// m_pStrengthLabel->setText(tr("Strong")); +// m_pStrengthLabel->setStyleSheet("color: #32CD32"); +// } +//} + +void DFMVaultActiveSetUnlockMethodView::slotLimiPasswordLength(const QString &password) +{ + DPasswordEdit *pPasswordEdit = qobject_cast(sender()); + if (password.length() > PASSWORD_LENGHT_MAX) { + pPasswordEdit->setText(password.mid(0, PASSWORD_LENGHT_MAX)); + } +} + +//void DFMVaultActiveSetUnlockMethodView::slotGeneratePasswordBtnClicked() +//{ +// QString strPassword = OperatorCenter::getInstance().autoGeneratePassword(m_pLengthSlider->value()); +// m_pResultEdit->setText(strPassword); +//} + +bool DFMVaultActiveSetUnlockMethodView::checkPassword(const QString &password) +{ + QString strPassword = password; + + QRegExp rx("^(?![^a-z]+$)(?![^A-Z]+$)(?!\\D+$)(?![a-zA-Z0-9]+$).{8,}$"); + QRegExpValidator v(rx); + int pos = 0; + QValidator::State res; + res = v.validate(strPassword, pos); + if (QValidator::Acceptable != res) { + return false; + + } else { + return true; + } +} + +bool DFMVaultActiveSetUnlockMethodView::checkRepeatPassword() +{ + const QString &strRepeatPassword = m_pRepeatPassword->text(); + const QString &strPassword = m_pPassword->text(); + if (strRepeatPassword != strPassword) { + return false; + } else { + return true; + } +} + +bool DFMVaultActiveSetUnlockMethodView::checkInputInfo() +{ + if (checkPassword(m_pPassword->text()) && checkRepeatPassword()) { + return true; + } else { + return false; + } +} + +void DFMVaultActiveSetUnlockMethodView::showEvent(QShowEvent *event) +{ + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::CREATEVAULTPAGE); + QWidget::showEvent(event); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesetunlockmethodview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesetunlockmethodview.h new file mode 100644 index 0000000..1fe9797 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivesetunlockmethodview.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMVAULTSETUNLOCKMETHODVIEW_H +#define DFMVAULTSETUNLOCKMETHODVIEW_H + +#include + +#include + +#define PASSWORD_LENGHT_MAX 24 +#define TIPS_TIME 3600000 + +QT_BEGIN_NAMESPACE +class QLineEdit; +class QPushButton; +class QCheckBox; +class QLabel; +class OperatorCenter; +class QSlider; +class QComboBox; +class QGridLayout; +QT_END_NAMESPACE + +DWIDGET_BEGIN_NAMESPACE +class DPasswordEdit; +class DLabel; +DWIDGET_END_NAMESPACE + +DWIDGET_USE_NAMESPACE + +class DFMVaultActiveSetUnlockMethodView : public QWidget +{ + Q_OBJECT +public: + explicit DFMVaultActiveSetUnlockMethodView(QWidget *parent = nullptr); + void clearText(); + +signals: + void sigAccepted(); + // 抛出二维码显示的内容 + void qrcodeContant(const QString &qrcode); + +public slots: + +private slots: + void slotPasswordEditing(); + void slotPasswordEditFinished(); + void slotPasswordEditFocusChanged(bool bFocus); + void slotRepeatPasswordEditFinished(); + void slotRepeatPasswordEditing(); + void slotRepeatPasswordEditFocusChanged(bool bFocus); + void slotGenerateEditChanged(const QString &str); + // 下一步按钮点击 + void slotNextBtnClicked(); + // 类型切换 + void slotTypeChanged(int index); + // 随即密码长度改变 +// void slotLengthChanged(int length); + // 限制密码的长度 + void slotLimiPasswordLength(const QString &password); + // 随即生成密码按钮点击 +// void slotGeneratePasswordBtnClicked(); + +private: + // 校验密码是否符合规则 + bool checkPassword(const QString &password); + // 校验重复密码框是否符合规则 + bool checkRepeatPassword(); + // 校验界面输入信息是否符合规则 + bool checkInputInfo(); + + void showEvent(QShowEvent *event) override; + +private: + QComboBox *m_pTypeCombo; + + DLabel *m_pPasswordLabel; + DPasswordEdit *m_pPassword; + + DLabel *m_pRepeatPasswordLabel; + DPasswordEdit *m_pRepeatPassword; + + DLabel *m_pPasswordHintLabel; + QLineEdit *m_pTips; + + QPushButton *m_pNext; + + QGridLayout *play1; + +// QLabel *m_pLengthLabel; +// QSlider *m_pLengthSlider; +// QLineEdit *m_pLengthEdit; +// QLabel *m_pStrengthLabel; +// QLabel *m_pResultLabel; +// QLineEdit *m_pResultEdit; +// QCheckBox *m_pOtherMethod; +// QPushButton *m_pGenerateBtn; +}; + +#endif // DFMVAULTSETUNLOCKMETHODVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivestartview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivestartview.cpp new file mode 100644 index 0000000..846a475 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivestartview.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmvaultactivestartview.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include + +#include +#include +#include +#include + + +DWIDGET_USE_NAMESPACE + +DFMVaultActiveStartView::DFMVaultActiveStartView(QWidget *parent) + : QWidget(parent) + , m_pStartBtn(nullptr) +{ + AC_SET_ACCESSIBLE_NAME(this, AC_VAULT_ACTIVE_START_WIDGET); + + // 标题 + DLabel *pLabel1 = new DLabel(tr("File Vault"), this); + AC_SET_ACCESSIBLE_NAME(pLabel1, AC_VAULT_ACTIVE_START_TITLE_LABEL); + QFont font = pLabel1->font(); + font.setPixelSize(18); + pLabel1->setFont(font); + pLabel1->setAlignment(Qt::AlignHCenter); + + DLabel *pLabel2 = new DLabel(tr("Create your secure private space") + '\n' + + tr("Advanced encryption technology") + '\n' + + tr("Convenient and easy to use"), this); + AC_SET_ACCESSIBLE_NAME(pLabel2, AC_VAULT_ACTIVE_START_CONTENT_LABEL); + pLabel2->setAlignment(Qt::AlignHCenter); + + DLabel *pLabel3 = new DLabel(); + AC_SET_ACCESSIBLE_NAME(pLabel3, AC_VAULT_ACTIVE_START_PICTURE); + pLabel3->setPixmap(QIcon::fromTheme("dfm_vault_active_start").pixmap(88, 100)); + pLabel3->setAlignment(Qt::AlignHCenter); + + m_pStartBtn = new QPushButton(tr("Create"), this); + AC_SET_ACCESSIBLE_NAME(m_pStartBtn, AC_VAULT_ACTIVE_START_BUTTON); + connect(m_pStartBtn, &QPushButton::clicked, + this, &DFMVaultActiveStartView::slotStartBtnClicked); + + // 布局 + QVBoxLayout *play = new QVBoxLayout(this); + play->setMargin(0); + play->addWidget(pLabel1); + play->addSpacing(5); + play->addWidget(pLabel2); + play->addSpacing(15); + play->addWidget(pLabel3); + play->addStretch(); + play->addWidget(m_pStartBtn); +} + +void DFMVaultActiveStartView::slotStartBtnClicked() +{ + emit sigAccepted(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivestartview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivestartview.h new file mode 100644 index 0000000..91a074f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactivestartview.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMVAULTACTIVESTARTVIEW_H +#define DFMVAULTACTIVESTARTVIEW_H + +#include + +#include + +QT_BEGIN_NAMESPACE +class QPushButton; +QT_END_NAMESPACE + +class DFMVaultActiveStartView : public QWidget +{ + Q_OBJECT +public: + explicit DFMVaultActiveStartView(QWidget *parent = nullptr); + +signals: + void sigAccepted(); + +private slots: + void slotStartBtnClicked(); + +public slots: + +private: + QPushButton *m_pStartBtn; // 开启包厢按钮 +}; + +#endif // DFMVAULTACTIVESTARTVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactiveview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactiveview.cpp new file mode 100644 index 0000000..c436432 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactiveview.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmvaultactiveview.h" +#include "dfmvaultactivestartview.h" +#include "dfmvaultactivesetunlockmethodview.h" +#include "dfmvaultactivesavekeyfileview.h" +#include "dfmvaultactivefinishedview.h" +#include "accessibility/ac-lib-file-manager.h" +#include "controllers/vaultcontroller.h" + +#include +#include +#include +#include +#include +#include +#include + +DFMVaultActiveView::DFMVaultActiveView(QWidget *parent) + : DFMVaultPageBase(parent), + m_pStackedWidget(nullptr), + m_pStartVaultWidget(nullptr), + m_pSetUnclockMethodWidget(nullptr), + m_SaveKeyWidget(nullptr), + m_ActiveVaultFinishedWidget(nullptr), + m_SaveKeyFileWidget(nullptr) +{ + AC_SET_ACCESSIBLE_NAME(this, AC_VAULT_ACTIVE_WIDGET); + this->setIcon(QIcon::fromTheme("dfm_vault")); + + // 初始化试图容器 + m_pStackedWidget = new QStackedWidget(this); + AC_SET_ACCESSIBLE_NAME(m_pStackedWidget, AC_VAULT_ACTIVE_STACK); + + // 初始化内部窗体 + m_pStartVaultWidget = new DFMVaultActiveStartView(this); + connect(m_pStartVaultWidget, &DFMVaultActiveStartView::sigAccepted, + this, &DFMVaultActiveView::slotNextWidget); + m_pSetUnclockMethodWidget = new DFMVaultActiveSetUnlockMethodView(this); + connect(m_pSetUnclockMethodWidget, &DFMVaultActiveSetUnlockMethodView::sigAccepted, + this, &DFMVaultActiveView::slotNextWidget); + m_SaveKeyFileWidget = new DFMVaultActiveSaveKeyFileView(this); + connect(m_SaveKeyFileWidget, &DFMVaultActiveSaveKeyFileView::sigAccepted, + this, &DFMVaultActiveView::slotNextWidget); + m_ActiveVaultFinishedWidget = new DFMVaultActiveFinishedView(this); + connect(m_ActiveVaultFinishedWidget, &DFMVaultActiveFinishedView::sigAccepted, + this, &DFMVaultActiveView::slotNextWidget); + + m_pStackedWidget->addWidget(m_pStartVaultWidget); + m_pStackedWidget->addWidget(m_pSetUnclockMethodWidget); + m_pStackedWidget->addWidget(m_SaveKeyFileWidget); + m_pStackedWidget->addWidget(m_ActiveVaultFinishedWidget); + m_pStackedWidget->layout()->setMargin(0); + + this->addContent(m_pStackedWidget); + setMinimumSize(472, 346); + + connect(this, &DFMVaultPageBase::accepted, this, &DFMVaultPageBase::enterVaultDir); + + connect(VaultController::ins(), &VaultController::sigCloseWindow, this, &DFMVaultActiveView::close); +} + +void DFMVaultActiveView::setBeginingState() +{ + m_pStackedWidget->setCurrentIndex(0); + m_pSetUnclockMethodWidget->clearText(); + m_ActiveVaultFinishedWidget->setFinishedBtnEnabled(true); + this->setCloseButtonVisible(true); +} + +void DFMVaultActiveView::closeEvent(QCloseEvent *event) +{ + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::UNKNOWN); + setBeginingState(); + // 响应基类关闭事件 + DFMVaultPageBase::closeEvent(event); +} + +void DFMVaultActiveView::showEvent(QShowEvent *event) +{ + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::CREATEVAULTPAGE); + DFMVaultPageBase::showEvent(event); +} + +void DFMVaultActiveView::slotNextWidget() +{ + if (m_pStackedWidget) { + int nIndex = m_pStackedWidget->currentIndex(); + int nCount = m_pStackedWidget->count(); + if (nIndex < nCount - 1) { + int nNextIndex = nIndex + 1; + m_pStackedWidget->setCurrentIndex(nNextIndex); + } else { + setBeginingState(); // 控件文本恢复初值 + emit accept(); + } + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactiveview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactiveview.h new file mode 100644 index 0000000..439856d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultactiveview.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMVAULTACTIVEVIEW_H +#define DFMVAULTACTIVEVIEW_H + +#include "dfmvaultpagebase.h" + +QT_BEGIN_NAMESPACE +class QStackedWidget; +class QMouseEvent; +QT_END_NAMESPACE + +class DFMVaultActiveStartView; +class DFMVaultActiveSetUnlockMethodView; +class DFMVaultActiveSaveKeyView; +class DFMVaultActiveFinishedView; +class DFMVaultActiveSaveKeyFileView; + +DWIDGET_USE_NAMESPACE + +class DFMVaultActiveView : public DFMVaultPageBase +{ +public: + static DFMVaultActiveView *getInstance() + { + static DFMVaultActiveView dlg; + return &dlg; + } + +protected: + // 重写基类关闭事件 + void closeEvent(QCloseEvent *event) override; + + void showEvent(QShowEvent *event) override; + +private slots: + void slotNextWidget(); + +private: + explicit DFMVaultActiveView(QWidget *parent = nullptr); + + // 复原操作 + void setBeginingState(); + +private: + // 窗口容器 + QStackedWidget *m_pStackedWidget; + + DFMVaultActiveStartView *m_pStartVaultWidget; + DFMVaultActiveSetUnlockMethodView *m_pSetUnclockMethodWidget; + DFMVaultActiveSaveKeyView *m_SaveKeyWidget; //! 弃用 + DFMVaultActiveFinishedView *m_ActiveVaultFinishedWidget; + DFMVaultActiveSaveKeyFileView *m_SaveKeyFileWidget; +}; + +#endif // DFMVAULTACTIVEVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultfileview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultfileview.cpp new file mode 100644 index 0000000..8c1eafa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultfileview.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "dfmvaultfileview.h" +#include "controllers/vaultcontroller.h" +#include "vault/vaultlockmanager.h" +#include "dfmsettings.h" +#include "views/dfmvaultunlockpages.h" +#include "views/dfmvaultrecoverykeypages.h" +#include "views/dfmvaultremovepages.h" +#include "views/dfmvaultactiveview.h" +#include "views/dfilemanagerwindow.h" +#include "dfilesystemmodel.h" +#include "vaultglobaldefine.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "singleton.h" + +#include + +DFMVaultFileView::DFMVaultFileView(QWidget *parent) + : DFileView(parent) +{ + connect(VaultController::ins(), &VaultController::signalLockVault, this, &DFMVaultFileView::onLeaveVault); + connect(fileSignalManager, &FileSignalManager::requestIgnoreDragEvent, this, &DFMVaultFileView::IgnoreDragEvent); +} + +bool DFMVaultFileView::setRootUrl(const DUrl &url) +{ + if(!VaultController::ins()->isVaultVisiable()) { + DDialog dialog(tr("Hint"), tr("Cannot open this path"), this); + dialog.addButton(tr("OK")); + dialog.exec(); + return false; + } + + VaultController::VaultState enState = VaultController::ins()->state(); + + QWidget *wndPtr = widget()->topLevelWidget(); + DFMVaultPageBase *page = nullptr; + if (enState != VaultController::Unlocked) { + switch (enState) { + case VaultController::NotAvailable: { + qDebug() << "cryfs not installed!"; + break; + } + case VaultController::NotExisted: { + page = DFMVaultActiveView::getInstance(); + break; + } + case VaultController::Encrypted: { + if (url.host() == "certificate") { + page = DFMVaultRecoveryKeyPages::instance(); + } else { + page = DFMVaultUnlockPages::instance(); + } + break; + } + default: + ; + } + } else { + if (url.host() == "delete") { + page = DFMVaultRemovePages::instance(); + } + + //! 记录访问保险箱时间 + if (VaultController::isRootDirectory(url.toLocalFile())) { + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::VAULTPAGE); + DFM_NAMESPACE::DFMSettings setting(VAULT_TIME_CONFIG_FILE); + setting.setValue(QString("VaultTime"), QString("InterviewTime"), QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); + } + } + + if (page) { + page->setWndPtr(wndPtr); + page->showTop(); + return false; + } + + if (DFMVaultRemovePages::instance()->isVisible()) { + DFMVaultRemovePages::instance()->raise(); + } + + return DFileView::setRootUrl(url); +} + +void DFMVaultFileView::onLeaveVault(int state) +{ + if (state == 0) { + this->cd(DUrl(COMPUTER_ROOT)); + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::UNKNOWN); + } +} + +void DFMVaultFileView::IgnoreDragEvent() +{ + QDrag::cancel(); +} + +bool DFMVaultFileView::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::HoverMove + || event->type() == QEvent::MouseButtonPress + || event->type() == QEvent::KeyRelease) { + + VaultLockManager::getInstance().refreshAccessTime(); +#ifdef AUTOLOCK_TEST + qDebug() << "type == " << event->type(); +#endif + } + + return DFileView::eventFilter(obj, event); +} + +void DFMVaultFileView::onRootUrlDeleted(const DUrl &rootUrl) +{ + // 修复bug-77747 保险箱上锁情况下会跳转到计算机页面,所以这里不用执行跳转 + if (VaultController::ins()->state() == VaultController::Encrypted) + return; + + DFileView::onRootUrlDeleted(rootUrl); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultfileview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultfileview.h new file mode 100644 index 0000000..d51c01d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultfileview.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#pragma once + +#include "dfileview.h" +#include "interfaces/dfilemenu.h" + +/** + * @brief The DFMVaultFileView class + * The class is vault main view, list files in vault directory. + * It will open pages or dialog according to current encrypted + * state when setRootUrl invoked. + */ +class DFMVaultFileView : public DFileView +{ + Q_OBJECT +public: + explicit DFMVaultFileView(QWidget *parent = nullptr); + + /** + * @brief setRootUrl 设置根目录地址 + * @param url 根目录地址 + * @return 是否设置成功,如果是page相关的地址,返回false + */ + bool setRootUrl(const DUrl &url) override; + +public slots: + /** + * @brief onLeaveVault 离开保险箱,当上锁/删除保险箱时调用 + */ + void onLeaveVault(int state); + + /** + * @brief IgnoreDragEvent 忽略拖拽事件 + */ + void IgnoreDragEvent(); + +protected: + /** + * @brief eventFilter 事件过滤器,用于获取保险箱操作事件 + * @param obj + * @param event 事件指针 + * @return + */ + bool eventFilter(QObject *obj, QEvent *event) override; + +protected slots: + // 保险箱单独实现父目录删除后,目录跳转方法 + void onRootUrlDeleted(const DUrl &rootUrl) override; +}; diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultpagebase.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultpagebase.cpp new file mode 100644 index 0000000..c761ee3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultpagebase.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "dfmvaultpagebase.h" +#include "vault/vaulthelper.h" +#include "controllers/vaultcontroller.h" +#include "dfilemanagerwindow.h" + +#include + +DFMVaultPageBase::DFMVaultPageBase(QWidget *parent) + : DDialog(parent) +{ + if(DFMGlobal::isWayLand()) + { + //设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + //this->windowHandle()->setProperty("_d_dwayland_window-type", "wallpaper"); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + this->moveToCenter(); + } + // 修复BUG-45226 设置该弹窗为模态弹窗 + this->setModal(true); +} + +void DFMVaultPageBase::enterVaultDir() +{ + //! bug 38585 这样修改可以减少一次文管是否设置双击文件始终在新窗口中打开 + DUrl vaultUrl = VaultController::makeVaultUrl(VaultController::makeVaultLocalPath()); + DFileManagerWindow *wnd = dynamic_cast(m_wndptr); + AppController::instance()->actionOpen(dMakeEventPointer(wnd, DUrlList() << vaultUrl)); +} + +void DFMVaultPageBase::closeEvent(QCloseEvent *event) +{ + // 记录当前退出模态对话框状态 + VaultHelper::isModel = false; + DDialog::closeEvent(event); +} + +void DFMVaultPageBase::setWndPtr(QWidget *wnd) +{ + m_wndptr = wnd; +} + +QWidget *DFMVaultPageBase::getWndPtr() const +{ + return m_wndptr; +} + +void DFMVaultPageBase::showTop() +{ + this->activateWindow(); + this->showNormal(); + this->raise(); + // 记录当前处于模态弹窗状态 + VaultHelper::isModel = true; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultpagebase.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultpagebase.h new file mode 100644 index 0000000..418bd02 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultpagebase.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#pragma once + +#include +#include + +DWIDGET_USE_NAMESPACE + +class DFMVaultPageBase : public DDialog +{ + Q_OBJECT +public: + explicit DFMVaultPageBase(QWidget *parent = nullptr); + + void setWndPtr(QWidget *wnd); + QWidget *getWndPtr() const; + + virtual void showTop(); + +public slots: + void enterVaultDir(); + +protected: + // 重载基类关闭事件 + void closeEvent(QCloseEvent *event) override; + +protected: + QWidget *m_wndptr = nullptr; //! current window pointer. +}; diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultrecoverykeypages.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultrecoverykeypages.cpp new file mode 100644 index 0000000..4ecc1db --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultrecoverykeypages.cpp @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmvaultrecoverykeypages.h" +#include "vault/interfaceactivevault.h" +#include "controllers/vaultcontroller.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include + +#include +#include +#include +#include + +// 密钥最大长度 +#define MAX_KEY_LENGTH (32) +DWIDGET_USE_NAMESPACE +class DFMVaultRecoveryKeyPagesPrivate +{ +public: + ~DFMVaultRecoveryKeyPagesPrivate() + { + if (tooltip) { + tooltip->deleteLater(); + } + } + + DToolTip *tooltip {nullptr}; + DFloatingWidget *frame {nullptr}; +}; + +DFMVaultRecoveryKeyPages::DFMVaultRecoveryKeyPages(QWidget *parent) + : DFMVaultPageBase(parent) + , d_ptr(new DFMVaultRecoveryKeyPagesPrivate()) +{ + AC_SET_ACCESSIBLE_NAME(this, AC_VAULT_KEY_UNLOCK_WIDGET); + + this->setIcon(QIcon::fromTheme("dfm_vault")); + this->setFixedSize(396, 218); + + // 标题 + QLabel *pTitle = new QLabel(tr("Unlock by Key"), this); + AC_SET_ACCESSIBLE_NAME(pTitle, AC_VAULT_KEY_UNLOCK_TITLE); + QFont font = pTitle->font(); + font.setPixelSize(16); + pTitle->setFont(font); + pTitle->setAlignment(Qt::AlignHCenter); + + // 密钥编辑框 + m_recoveryKeyEdit = new QPlainTextEdit(this); + AC_SET_ACCESSIBLE_NAME(m_recoveryKeyEdit, AC_VAULT_KEY_UNLOCK_EDIT); + m_recoveryKeyEdit->setPlaceholderText(tr("Input the 32-digit recovery key")); + m_recoveryKeyEdit->setMaximumBlockCount(MAX_KEY_LENGTH + 3); + m_recoveryKeyEdit->installEventFilter(this); + + // 主视图 + QFrame *mainFrame = new QFrame(this); + // 布局 + QVBoxLayout *mainLayout = new QVBoxLayout(mainFrame); + mainLayout->setMargin(0); + mainLayout->addWidget(pTitle); + mainLayout->addWidget(m_recoveryKeyEdit); + + mainFrame->setLayout(mainLayout); + addContent(mainFrame); + + QStringList btnList({tr("Cancel","button"), tr("Unlock","button")}); + addButton(btnList[0], false); + addButton(btnList[1], true, ButtonType::ButtonRecommend); + getButton(1)->setEnabled(false); + + AC_SET_ACCESSIBLE_NAME(getButton(0), AC_VAULT_KEY_UNLOCK_CANCEL_BUTTON); + AC_SET_ACCESSIBLE_NAME(getButton(1), AC_VAULT_KEY_UNLOCK_OK_BUTTON); + + // 防止点击按钮后界面隐藏 + setOnButtonClickedClose(false); + + connect(this, &DFMVaultRecoveryKeyPages::buttonClicked, this, &DFMVaultRecoveryKeyPages::onButtonClicked); + connect(m_recoveryKeyEdit, &QPlainTextEdit::textChanged, this, &DFMVaultRecoveryKeyPages::recoveryKeyChanged); + connect(VaultController::ins(), &VaultController::signalUnlockVault, this, &DFMVaultRecoveryKeyPages::onUnlockVault); + connect(this, &DFMVaultPageBase::accepted, this, &DFMVaultPageBase::enterVaultDir); +} + +DFMVaultRecoveryKeyPages::~DFMVaultRecoveryKeyPages() +{ + +} + +DFMVaultRecoveryKeyPages *DFMVaultRecoveryKeyPages::instance() +{ + static DFMVaultRecoveryKeyPages s_instance; + return &s_instance; +} + +void DFMVaultRecoveryKeyPages::showAlertMessage(const QString &text, int duration) +{ + Q_D(DFMVaultRecoveryKeyPages); + + if (!d->tooltip) { + d->tooltip = new DToolTip(text); + d->tooltip->setObjectName("AlertTooltip"); + d->tooltip->setForegroundRole(DPalette::TextWarning); + d->tooltip->setWordWrap(true); + + d->frame = new DFloatingWidget; + d->frame->setFramRadius(DStyle::pixelMetric(style(), DStyle::PM_FrameRadius)); + d->frame->setStyleSheet("background-color: rgba(247, 247, 247, 0.6);"); + d->frame->setWidget(d->tooltip); + } + + d->frame->setParent(m_recoveryKeyEdit); + + d->tooltip->setText(text); + if (d->frame->parent()) { + d->frame->setGeometry(0, 25, 68, 26); + d->frame->show(); + d->frame->adjustSize(); + d->frame->raise(); + } + + if (duration < 0) { + return; + } + + QTimer::singleShot(duration, d->frame, [d] { + d->frame->close(); + }); +} + +void DFMVaultRecoveryKeyPages::onButtonClicked(const int &index) +{ + if (index == 1) { + // 点击解锁后,灰化解锁按钮 + getButton(1)->setEnabled(false); + + QString strKey = m_recoveryKeyEdit->toPlainText(); + strKey.replace("-", ""); + + QString strCipher(""); + if (InterfaceActiveVault::checkUserKey(strKey, strCipher)) { + m_bUnlockByKey = true; + VaultController::ins()->unlockVault(strCipher); + } else { + showAlertMessage(tr("Wrong recovery key")); + } + + return; + } + + close(); +} + +int DFMVaultRecoveryKeyPages::afterRecoveryKeyChanged(QString &str) +{ + if (str.isEmpty()) { + return -1; + } + + int location = m_recoveryKeyEdit->textCursor().position(); // 计算当前光标位置 + int srcLength = str.length(); // 用于计算原有字符串中的“-”数量 + //清除所有的“-” + str.replace("-", ""); + int minusNumber = srcLength - str.length(); // 原有字符串中的“-”数量 + + int index = 4; + int minusNum = 0; + + int length = str.length(); + while (index < length) { + if (index % 4 == 0) { + str.insert(index + minusNum, "-"); + minusNum++; + } + index++; + } + + //计算添加“-”后,重新计算下光标的位置, + if (minusNum > minusNumber) { + location += minusNum - minusNumber; + } + + if (location > str.length()) { + location = str.length(); + } else if (location < 0) { + location = 0; + } + + return location; +} + +void DFMVaultRecoveryKeyPages::showEvent(QShowEvent *event) +{ + m_recoveryKeyEdit->clear(); + m_bUnlockByKey = false; + event->accept(); +} + +void DFMVaultRecoveryKeyPages::recoveryKeyChanged() +{ + QString key = m_recoveryKeyEdit->toPlainText(); + int length = key.length(); + int maxLength = MAX_KEY_LENGTH + 7; + + if (key.isEmpty()) { + getButton(1)->setEnabled(false); + } else { + getButton(1)->setEnabled(true); + } + + // 限制密钥输入框只能输入数字、字母、以及+/- + QRegExp rx("[a-zA-Z0-9-+/]+"); + QString res(""); + int pos = 0; + while ((pos = rx.indexIn(key, pos)) != -1) { + res += rx.cap(0); + pos += rx.matchedLength(); + } + key = res; + + m_recoveryKeyEdit->blockSignals(true); + // 限制输入的最大长度 + if (length > maxLength) { + int position = m_recoveryKeyEdit->textCursor().position(); + QTextCursor textCursor = m_recoveryKeyEdit->textCursor(); + key.remove(position - (length - maxLength), length - maxLength); + m_recoveryKeyEdit->setPlainText(key); + textCursor.setPosition(position - (length - maxLength)); + m_recoveryKeyEdit->setTextCursor(textCursor); + + m_recoveryKeyEdit->blockSignals(false); + return; + } + + int position = afterRecoveryKeyChanged(key); + m_recoveryKeyEdit->setPlainText(key); + + QTextCursor textCursor = m_recoveryKeyEdit->textCursor(); + textCursor.setPosition(position); + m_recoveryKeyEdit->setTextCursor(textCursor); + + m_recoveryKeyEdit->blockSignals(false); +} + +void DFMVaultRecoveryKeyPages::onUnlockVault(int state) +{ + if (m_bUnlockByKey) { + if (state == 0) { + // success + emit accepted(); + close(); + } else { + // others + QString errMsg = tr("Failed to unlock file vault"); + DDialog dialog(this); + dialog.setIcon(QIcon::fromTheme("dialog-warning")); + dialog.setTitle(errMsg); + dialog.addButton(tr("OK"), true, DDialog::ButtonRecommend); + dialog.exec(); + } + m_bUnlockByKey = false; + } +} + +bool DFMVaultRecoveryKeyPages::eventFilter(QObject *watched, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) { + QPlainTextEdit *edit = qobject_cast(watched); + if (edit == m_recoveryKeyEdit) { + QKeyEvent *keyEvent = dynamic_cast(event); + + switch (keyEvent->key()) { + case Qt::Key_Minus: + case Qt::Key_Enter: + case Qt::Key_Return: // 过滤"-"以及换行操作 + return true; + default: + break; + } + } + } + + return DDialog::eventFilter(watched, event); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultrecoverykeypages.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultrecoverykeypages.h new file mode 100644 index 0000000..f6e87bd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultrecoverykeypages.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#pragma once + +#include "dfmvaultpagebase.h" + +#include + +QT_BEGIN_NAMESPACE +class QPlainTextEdit; +QT_END_NAMESPACE + +DWIDGET_USE_NAMESPACE + +class DFMVaultRecoveryKeyPagesPrivate; +class DFMVaultRecoveryKeyPages : public DFMVaultPageBase +{ + Q_OBJECT +public: + static DFMVaultRecoveryKeyPages *instance(); + + void showAlertMessage(const QString &text, int duration = 3000); +private slots: + void onButtonClicked(const int &index); + + void recoveryKeyChanged(); + + void onUnlockVault(int state); +private: + explicit DFMVaultRecoveryKeyPages(QWidget *parent = nullptr); + ~DFMVaultRecoveryKeyPages() override; + + bool eventFilter(QObject *watched, QEvent *event) override; + + int afterRecoveryKeyChanged(QString &str); + + void showEvent(QShowEvent *event) override; +private: + QPlainTextEdit *m_recoveryKeyEdit {nullptr}; + bool m_bUnlockByKey = false; + + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE(DFMVaultRecoveryKeyPages) +}; diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovebypasswordview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovebypasswordview.cpp new file mode 100644 index 0000000..87c1eaa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovebypasswordview.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "dfmvaultremovebypasswordview.h" +#include "interfaceactivevault.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include +#include + +#include +#include +#include + +DFMVaultRemoveByPasswordView::DFMVaultRemoveByPasswordView(QWidget *parent) + : QWidget(parent) +{ + //密码输入框 + m_pwdEdit = new DPasswordEdit(this); + AC_SET_ACCESSIBLE_NAME(m_pwdEdit, AC_VAULT_DELETE_PASSWORD_EDIT); + m_pwdEdit->lineEdit()->setPlaceholderText(tr("Password")); + m_pwdEdit->lineEdit()->setAttribute(Qt::WA_InputMethodEnabled, false); + + // 提示按钮 + m_tipsBtn = new QPushButton(this); + AC_SET_ACCESSIBLE_NAME(m_tipsBtn, AC_VAULT_DELETE_HINT_BUTTON); + m_tipsBtn->setIcon(QIcon(":/icons/images/icons/light_32px.svg")); + + QHBoxLayout *layout = new QHBoxLayout(); + layout->addWidget(m_pwdEdit); + layout->addWidget(m_tipsBtn); + layout->setContentsMargins(0, 15, 0, 0); + this->setLayout(layout); + + connect(m_pwdEdit->lineEdit(), &QLineEdit::textChanged, this, &DFMVaultRemoveByPasswordView::onPasswordChanged); + connect(m_tipsBtn, &QPushButton::clicked, this, [this] { + QString strPwdHint(""); + if (InterfaceActiveVault::getPasswordHint(strPwdHint)) + { + QString hint = tr("Password hint: %1").arg(strPwdHint); + showToolTip(hint, 3000, EN_ToolTip::Information); + } + }); +} + +DFMVaultRemoveByPasswordView::~DFMVaultRemoveByPasswordView() +{ + +} + +QString DFMVaultRemoveByPasswordView::getPassword() +{ + return m_pwdEdit->text(); +} + +void DFMVaultRemoveByPasswordView::clear() +{ + // 重置状态 + m_pwdEdit->clear(); + QLineEdit edit; + QPalette palette = edit.palette(); + m_pwdEdit->lineEdit()->setPalette(palette); + m_pwdEdit->setEchoMode(QLineEdit::Password); +} + +void DFMVaultRemoveByPasswordView::showAlertMessage(const QString &text, int duration) +{ + // 修复bug-51508 激活密码框的警告状态 + m_pwdEdit->setAlert(true); + m_pwdEdit->showAlertMessage(text, duration); +} + +void DFMVaultRemoveByPasswordView::showToolTip(const QString &text, int duration, DFMVaultRemoveByPasswordView::EN_ToolTip enType) +{ + if (!m_tooltip) { + m_tooltip = new DToolTip(text); + m_tooltip->setObjectName("AlertTooltip"); + m_tooltip->setWordWrap(true); + + m_frame = new DFloatingWidget; + m_frame->setFramRadius(DStyle::pixelMetric(style(), DStyle::PM_FrameRadius)); + m_frame->setStyleSheet("background-color: rgba(247, 247, 247, 0.6);"); + m_frame->setWidget(m_tooltip); + } + if (EN_ToolTip::Warning == enType) { + // 修复bug-51508 激活密码框的警告状态 + m_pwdEdit->setAlert(true); + m_tooltip->setForegroundRole(DPalette::TextWarning); + } else { + m_tooltip->setForegroundRole(DPalette::TextTitle); + } + + if (parentWidget() && parentWidget()->parentWidget() && parentWidget()->parentWidget()->parentWidget()) { + m_frame->setParent(parentWidget()->parentWidget()->parentWidget()); + } + + m_tooltip->setText(text); + if (m_frame->parent()) { + // 优化调整 调整悬浮框的显示位置 + QWidget *pWidget = static_cast(m_frame->parent()); + if (pWidget) { + m_frame->setGeometry(6, pWidget->height() - 78, 68, 26); + } + m_frame->show(); + m_frame->adjustSize(); + m_frame->raise(); + } + + if (duration < 0) { + return; + } + + QTimer::singleShot(duration, this, [ = ] { + m_frame->close(); + }); +} + +void DFMVaultRemoveByPasswordView::setTipsButtonVisible(bool visible) +{ + m_tipsBtn->setVisible(visible); +} + +void DFMVaultRemoveByPasswordView::onPasswordChanged(const QString &password) +{ + if (!password.isEmpty()) { + // 修复bug-51508 取消密码框的警告状态 + m_pwdEdit->setAlert(false); + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovebypasswordview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovebypasswordview.h new file mode 100644 index 0000000..b287de2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovebypasswordview.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef DFMVAULTREMOVEBYPASSWORDVIEW_H +#define DFMVAULTREMOVEBYPASSWORDVIEW_H + +#include + +#include + +class QLineEdit; +class QPushButton; + +DWIDGET_BEGIN_NAMESPACE +class DPasswordEdit; +class DToolTip; +class DFloatingWidget; +DWIDGET_END_NAMESPACE + +DWIDGET_USE_NAMESPACE + +class DFMVaultRemoveByPasswordView : public QWidget +{ + Q_OBJECT +public: + explicit DFMVaultRemoveByPasswordView(QWidget *parent = nullptr); + ~DFMVaultRemoveByPasswordView() override; + enum EN_ToolTip { + Warning = 0, + Information + }; + + /** + * @brief 获取密码 + */ + QString getPassword(); + + /** + * @brief 清空密码 + */ + void clear(); + + /** + * @brief showAlertMessage 显示密码输入框提示信息 + * @param text 信息内容 + * @param duration 显示时长 + */ + void showAlertMessage(const QString &text, int duration = 3000); + void showToolTip(const QString &text, int duration, EN_ToolTip enType); + + /** + * @brief setTipsButtonVisible 设置提示按钮是否可见 + * @param visible + */ + void setTipsButtonVisible(bool visible); +public slots: + void onPasswordChanged(const QString &password); + +private: + DPasswordEdit *m_pwdEdit {nullptr}; + QPushButton *m_tipsBtn {nullptr}; + + DToolTip *m_tooltip {nullptr}; + DFloatingWidget *m_frame {nullptr}; +}; + +#endif // DFMVAULTREMOVEBYPASSWORDVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovebyrecoverykeyview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovebyrecoverykeyview.cpp new file mode 100644 index 0000000..ff63aef --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovebyrecoverykeyview.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "dfmvaultremovebyrecoverykeyview.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include +#include +#include + +#include +#include +#include + + +#define MAX_KEY_LENGTH (32) //凭证最大值,4的倍数 +DWIDGET_USE_NAMESPACE +class DFMVaultRemoveByRecoverykeyViewPrivate +{ +public: + explicit DFMVaultRemoveByRecoverykeyViewPrivate(DFMVaultRemoveByRecoverykeyView *qq) + : q_ptr(qq) {} + ~DFMVaultRemoveByRecoverykeyViewPrivate() + { + if (tooltip) { + tooltip->deleteLater(); + } + } + + DToolTip *tooltip {nullptr}; + DFloatingWidget *frame {nullptr}; + + DFMVaultRemoveByRecoverykeyView *q_ptr; + Q_DECLARE_PUBLIC(DFMVaultRemoveByRecoverykeyView) +}; + +DFMVaultRemoveByRecoverykeyView::DFMVaultRemoveByRecoverykeyView(QWidget *parent) + : QWidget(parent) + , d_ptr(new DFMVaultRemoveByRecoverykeyViewPrivate(this)) +{ + m_keyEdit = new QPlainTextEdit(this); + AC_SET_ACCESSIBLE_NAME(m_keyEdit, AC_VAULT_DELETE_KEY_EDIT); + m_keyEdit->setPlaceholderText(tr("Input the 32-digit recovery key")); + m_keyEdit->installEventFilter(this); + + QVBoxLayout *layout = new QVBoxLayout(); + layout->addWidget(m_keyEdit); + layout->setMargin(0); + this->setLayout(layout); + + connect(m_keyEdit, &QPlainTextEdit::textChanged, this, &DFMVaultRemoveByRecoverykeyView::onRecoveryKeyChanged); +} + +DFMVaultRemoveByRecoverykeyView::~DFMVaultRemoveByRecoverykeyView() +{ + +} + +QString DFMVaultRemoveByRecoverykeyView::getRecoverykey() +{ + QString strKey = m_keyEdit->toPlainText(); + + return strKey.replace("-", ""); +} + +void DFMVaultRemoveByRecoverykeyView::clear() +{ + m_keyEdit->clear(); +} + +void DFMVaultRemoveByRecoverykeyView::showAlertMessage(const QString &text, int duration) +{ + Q_D(DFMVaultRemoveByRecoverykeyView); + + if (!d->tooltip) { + d->tooltip = new DToolTip(text); + d->tooltip->setObjectName("AlertTooltip"); + d->tooltip->setForegroundRole(DPalette::TextWarning); + d->tooltip->setWordWrap(true); + + d->frame = new DFloatingWidget; + d->frame->setFramRadius(DStyle::pixelMetric(style(), DStyle::PM_FrameRadius)); + d->frame->setBackgroundRole(QPalette::ToolTipBase); + d->frame->setWidget(d->tooltip); + } + + d->frame->setParent(parentWidget()); + + d->tooltip->setText(text); + if (d->frame->parent()) { + d->frame->setGeometry(0, 25, 68, 26); + d->frame->show(); + d->frame->adjustSize(); + d->frame->raise(); + } + + if (duration < 0) { + return; + } + + QTimer::singleShot(duration, d->frame, [d] { + d->frame->close(); + }); +} + +void DFMVaultRemoveByRecoverykeyView::onRecoveryKeyChanged() +{ + QString key = m_keyEdit->toPlainText(); + int length = key.length(); + int maxLength = MAX_KEY_LENGTH + 7; + + // 限制密钥输入框只能输入数字、字母、以及+/- + QRegExp rx("[a-zA-Z0-9-+/]+"); + QString res(""); + int pos = 0; + while ((pos = rx.indexIn(key, pos)) != -1) { + res += rx.cap(0); + pos += rx.matchedLength(); + } + key = res; + + m_keyEdit->blockSignals(true); + // 限制输入的最大长度 + if (length > maxLength) { + int position = m_keyEdit->textCursor().position(); + QTextCursor textCursor = m_keyEdit->textCursor(); + key.remove(position - (length - maxLength), length - maxLength); + m_keyEdit->setPlainText(key); + textCursor.setPosition(position - (length - maxLength)); + m_keyEdit->setTextCursor(textCursor); + + m_keyEdit->blockSignals(false); + return; + } + + int position = afterRecoveryKeyChanged(key); + m_keyEdit->setPlainText(key); + + QTextCursor textCursor = m_keyEdit->textCursor(); + textCursor.setPosition(position); + m_keyEdit->setTextCursor(textCursor); + m_keyEdit->blockSignals(false); +} + +int DFMVaultRemoveByRecoverykeyView::afterRecoveryKeyChanged(QString &str) +{ + if (str.isEmpty()) { + return -1; + } + + int location = m_keyEdit->textCursor().position(); // 计算当前光标位置 + int srcLength = str.length(); // 用于计算原有字符串中的“-”数量 + //清除所有的“-” + str.replace("-", ""); + int minusNumber = srcLength - str.length(); // 原有字符串中的“-”数量 + + int index = 4; + int minusNum = 0; + + int length = str.length(); + while (index < length) { + if (index % 4 == 0) { + str.insert(index + minusNum, "-"); + minusNum++; + } + index++; + } + + //计算添加“-”后,重新计算下光标的位置, + if (minusNum > minusNumber) { + location += minusNum - minusNumber; + } + + if (location > str.length()) { + location = str.length(); + } else if (location < 0) { + location = 0; + } + + return location; +} + +bool DFMVaultRemoveByRecoverykeyView::eventFilter(QObject *watched, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) { + QPlainTextEdit *edit = qobject_cast(watched); + if (edit == m_keyEdit) { + QKeyEvent *keyEvent = dynamic_cast(event); + + // 过滤换行操作以及“-” + if (keyEvent->key() == Qt::Key_Enter + || keyEvent->key() == Qt::Key_Return + || keyEvent->key() == Qt::Key_Minus) { + return true; + } + } + } + + return QWidget::eventFilter(watched, event); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovebyrecoverykeyview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovebyrecoverykeyview.h new file mode 100644 index 0000000..35161cf --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovebyrecoverykeyview.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef DFMVAULTREMOVEBYRECOVERYKEYVIEW_H +#define DFMVAULTREMOVEBYRECOVERYKEYVIEW_H + +#include +#include + +class QPlainTextEdit; + +class DFMVaultRemoveByRecoverykeyViewPrivate; +class DFMVaultRemoveByRecoverykeyView : public QWidget +{ + Q_OBJECT +public: + explicit DFMVaultRemoveByRecoverykeyView(QWidget *parent = nullptr); + ~DFMVaultRemoveByRecoverykeyView() override; + + /** + * @brief 获取凭证 + */ + QString getRecoverykey(); + + /** + * @brief 清空凭证 + */ + void clear(); + + void showAlertMessage(const QString &text, int duration = 3000); +public slots: + void onRecoveryKeyChanged(); + +private: + // 输入凭证后,对凭证添加“-” + int afterRecoveryKeyChanged(QString &str); + + bool eventFilter(QObject *watched, QEvent *event) override; +private: + QPlainTextEdit *m_keyEdit {nullptr}; + + QScopedPointer d_ptr; + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), DFMVaultRemoveByRecoverykeyView) +}; + +#endif // DFMVAULTREMOVEBYRECOVERYKEYVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovepages.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovepages.cpp new file mode 100644 index 0000000..56eee74 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovepages.cpp @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + + +#include "dfmvaultremovepages.h" +#include "vault/interfaceactivevault.h" +#include "vault/vaultlockmanager.h" +#include "vault/vaulthelper.h" +#include "controllers/vaultcontroller.h" +#include "app/define.h" +#include "dfmvaultremoveprogressview.h" +#include "dfmvaultremovebypasswordview.h" +#include "dfmvaultremovebyrecoverykeyview.h" +#include "accessibility/ac-lib-file-manager.h" +#include "vaulthelper.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace PolkitQt1; + +DWIDGET_USE_NAMESPACE + +DFMVaultRemovePages::DFMVaultRemovePages(QWidget *parent) + : DFMVaultPageBase(parent) + , m_passwordView(new DFMVaultRemoveByPasswordView(this)) + , m_recoverykeyView(new DFMVaultRemoveByRecoverykeyView(this)) + , m_progressView(new DFMVaultRemoveProgressView(this)) + , m_stackedWidget(new QStackedWidget(this)) +{ + AC_SET_ACCESSIBLE_NAME(this, AC_VAULT_DELETE_WIDGET); + + setIcon(QIcon(":/icons/deepin/builtin/icons/dfm_vault_32px.svg")); + // 修复bug-41001 提示信息显示不全 + this->setFixedWidth(396); + + // 标题 + DLabel *pTitle = new DLabel(tr("Delete File Vault"), this); + AC_SET_ACCESSIBLE_NAME(pTitle, AC_VAULT_DELETE_TITLE); + // 文本水平并垂直居中 + pTitle->setAlignment(Qt::AlignCenter); + + // 信息 + m_pInfo = new QLabel(this); + AC_SET_ACCESSIBLE_NAME(m_pInfo, AC_VAULT_DELETE_CONTENT); + // 文本水平并垂直居中 + m_pInfo->setAlignment(Qt::AlignCenter); + // 修复bug-41001 提示信息显示不全 + m_pInfo->setWordWrap(true); + + // 主界面 + QFrame *mainFrame = new QFrame(this); + + // 修复bug-41001 提示信息显示不全 + m_stackedWidget->setFixedHeight(95); + m_stackedWidget->addWidget(m_passwordView); + m_stackedWidget->addWidget(m_recoverykeyView); + m_stackedWidget->addWidget(m_progressView); + + // 布局 + QVBoxLayout *mainLayout = new QVBoxLayout(mainFrame); + mainLayout->setMargin(0); + mainLayout->addWidget(pTitle); + mainLayout->addWidget(m_pInfo); + mainLayout->addWidget(m_stackedWidget); + + mainFrame->setLayout(mainLayout); + addContent(mainFrame); + + showVerifyWidget(); + + // 防止点击按钮隐藏界面 + setOnButtonClickedClose(false); + + initConnect(); +} + +void DFMVaultRemovePages::initConnect() +{ + connect(this, &DFMVaultRemovePages::buttonClicked, this, &DFMVaultRemovePages::onButtonClicked); + connect(VaultController::ins(), &VaultController::signalLockVault, this, &DFMVaultRemovePages::onLockVault); + connect(m_progressView, &DFMVaultRemoveProgressView::removeFinished, this, &DFMVaultRemovePages::onVualtRemoveFinish); +} + +void DFMVaultRemovePages::showVerifyWidget() +{ + setInfo(tr("Once deleted, the files in it will be permanently deleted")); + + setCloseButtonVisible(true); + clearButtons(); + QStringList buttonTexts({tr("Cancel","button"), tr("Use Key","button"), tr("Delete","button")}); + addButton(buttonTexts[0], false); + //! 1050及以上版本无密钥验证 + if(!VaultController::getVaultVersion()) + addButton(buttonTexts[1], false); + addButton(buttonTexts[2], true, DDialog::ButtonWarning); + if(!VaultController::getVaultVersion()) + setDefaultButton(2); + else + setDefaultButton(1); + m_stackedWidget->setCurrentIndex(0); + + AC_SET_ACCESSIBLE_NAME(getButton(0), AC_VAULT_DELETE_CANCEL_BUTTON); + AC_SET_ACCESSIBLE_NAME(getButton(1), AC_VAULT_DELETE_CHANGE_BUTTON); + if(!VaultController::getVaultVersion()) + AC_SET_ACCESSIBLE_NAME(getButton(2), AC_VAULT_DELETE_DELETE_BUTTON); + + // 如果密码提示信息为空,则隐藏提示按钮 + QString strPwdHint(""); + if (InterfaceActiveVault::getPasswordHint(strPwdHint)) { + if (strPwdHint.isEmpty()) { + m_passwordView->setTipsButtonVisible(false); + } else { + m_passwordView->setTipsButtonVisible(true); + } + } +} + +void DFMVaultRemovePages::showRemoveWidget() +{ + setInfo(tr("Removing...")); + + setCloseButtonVisible(false); + clearButtons(); + addButton(tr("OK","button"), true, ButtonType::ButtonRecommend); + getButton(0)->setEnabled(false); + m_stackedWidget->setCurrentIndex(2); +} + +void DFMVaultRemovePages::setInfo(const QString &info) +{ + m_pInfo->setText(info); +} + +void DFMVaultRemovePages::closeEvent(QCloseEvent *event) +{ + // 重置界面状态 + m_passwordView->clear(); + m_recoverykeyView->clear(); + m_progressView->clear(); + m_bRemoveVault = false; + + // 调用基类关闭事件 + DFMVaultPageBase::closeEvent(event); +} + +DFMVaultRemovePages *DFMVaultRemovePages::instance() +{ + static DFMVaultRemovePages s_instance; + return &s_instance; +} + +void DFMVaultRemovePages::showTop() +{ + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::DELETEVAULTPAGE); + showVerifyWidget(); + activateWindow(); + show(); + raise(); + // 设置当前保险箱处于模态弹窗状态 + DFM_NAMESPACE::VaultHelper::isModel = true; +} + +void DFMVaultRemovePages::onButtonClicked(int index) +{ + switch (index) { + case 0: //点击取消按钮 + close(); + break; + case 1: + //! 1050及以上版本无密钥验证 + if(!VaultController::getVaultVersion()){ + { // 切换验证方式 + if (m_stackedWidget->currentIndex() == 0) { + getButton(1)->setText(tr("Use Password")); + m_stackedWidget->setCurrentIndex(1); + } else { + getButton(1)->setText(tr("Use Key")); + m_stackedWidget->setCurrentIndex(0); + } + } + break; + } + case 2: { // 删除 + if (m_stackedWidget->currentIndex() == 0) { + // 密码验证 + QString strPwd = m_passwordView->getPassword(); + QString strCipher(""); + + if (!InterfaceActiveVault::checkPassword(strPwd, strCipher)) { + m_passwordView->showToolTip(tr("Wrong password"), 3000, DFMVaultRemoveByPasswordView::EN_ToolTip::Warning); + return; + } + } else { + // 密钥验证 + QString strKey = m_recoverykeyView->getRecoverykey(); + strKey.replace("-", ""); + QString strCipher(""); + + if (!InterfaceActiveVault::checkUserKey(strKey, strCipher)) { + m_recoverykeyView->showAlertMessage(tr("Wrong recovery key")); + return; + } + } + + // 用户权限认证(异步授权) + auto ins = Authority::instance(); + ins->checkAuthorization(VAULT_REMOVE, + UnixProcessSubject(getpid()), + Authority::AllowUserInteraction); + connect(ins, &Authority::checkAuthorizationFinished, + this, &DFMVaultRemovePages::slotCheckAuthorizationFinished); + + QAbstractButton * btn; + //! 1050及以上版本无密钥验证 + if(!VaultController::getVaultVersion()) { + btn = getButton(2); + }else { + btn = getButton(1); + } + + // 按钮置灰,防止用户胡乱操作 + if (btn) + btn->setEnabled(false); + } + break; + default: + break; + } +} + +void DFMVaultRemovePages::slotCheckAuthorizationFinished(Authority::Result result) +{ + disconnect(Authority::instance(), &Authority::checkAuthorizationFinished, + this, &DFMVaultRemovePages::slotCheckAuthorizationFinished); + if (isVisible()) { + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::DELETEVAULTPAGE); + if (result == Authority::Yes) { + m_bRemoveVault = true; + // 删除前,先置顶保险箱内拷贝、剪贴、压缩任务 + if (DFM_NAMESPACE::VaultHelper::topVaultTasks()) { + qDebug() << "当前保险箱内是否有拷贝、剪贴、压缩任务,不能删除保险箱!"; + } else { + // 验证成功,先对保险箱进行上锁 + VaultController::ins()->lockVault(); + } + } + + QAbstractButton * btn; + //! 1050及以上版本无密钥验证 + if(!VaultController::getVaultVersion()) { + btn = getButton(2); + }else { + btn = getButton(1); + } + + // 按钮置灰,防止用户胡乱操作 + if (btn) + btn->setEnabled(false); + } + +} + +void DFMVaultRemovePages::onLockVault(int state) +{ + if (m_bRemoveVault) { + if (state == 0) { + // 切换至删除界面 + showRemoveWidget(); + emit accepted(); + + QString vaultLockPath = VaultController::ins()->vaultLockPath(); + QString vaultUnlockPath = VaultController::ins()->vaultUnlockPath(); + m_progressView->removeVault(vaultLockPath, vaultUnlockPath); + } else { + // error tips + QString errMsg = tr("Failed to delete file vault"); + DDialog dialog(this); + dialog.setIcon(QIcon::fromTheme("dialog-warning")); + dialog.setTitle(errMsg); + dialog.addButton(tr("OK","button"), true, DDialog::ButtonRecommend); + dialog.exec(); + } + m_bRemoveVault = false; + } +} + +void DFMVaultRemovePages::onVualtRemoveFinish(bool result) +{ + if (result) { + setInfo(tr("Deleted successfully")); + } else { + setInfo(tr("Failed to delete")); + } + + this->getButton(0)->setEnabled(true); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovepages.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovepages.h new file mode 100644 index 0000000..cf9aa73 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremovepages.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef DFMVAULTREMOVEPAGES_H +#define DFMVAULTREMOVEPAGES_H + +#include "dfmvaultpagebase.h" + +#include + +class QStackedWidget; + +class DFMVaultRemoveProgressView; +class DFMVaultRemoveByRecoverykeyView; +class DFMVaultRemoveByPasswordView; +DWIDGET_BEGIN_NAMESPACE + +class DLabel; +DWIDGET_END_NAMESPACE +DWIDGET_USE_NAMESPACE + +class DFMVaultRemovePages : public DFMVaultPageBase +{ + Q_OBJECT +public: + static DFMVaultRemovePages *instance(); + + void showTop() override; + +public slots: + void onButtonClicked(int index); + + void onLockVault(int state); + + void onVualtRemoveFinish(bool result); + +private slots: + // 异步授权时,此函数接收授权完成的结果 + void slotCheckAuthorizationFinished(PolkitQt1::Authority::Result result); + +private: + explicit DFMVaultRemovePages(QWidget *parent = nullptr); + ~DFMVaultRemovePages() override {} + + void initConnect(); + + void showVerifyWidget(); + + void showRemoveWidget(); + void setInfo(const QString &info); + + void closeEvent(QCloseEvent *event) override; + + +private: + DFMVaultRemoveByPasswordView *m_passwordView {nullptr}; + DFMVaultRemoveByRecoverykeyView *m_recoverykeyView {nullptr}; + DFMVaultRemoveProgressView *m_progressView {nullptr}; + + QStackedWidget *m_stackedWidget {nullptr}; //用于页面切换 + bool m_bRemoveVault = false; + + QLabel *m_pInfo; +}; + +#endif // DFMVAULTREMOVEPAGES_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremoveprogressview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremoveprogressview.cpp new file mode 100644 index 0000000..3188b90 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremoveprogressview.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#include "dfmvaultremoveprogressview.h" +#include "dfmsettings.h" +#include "accessibility/ac-lib-file-manager.h" +#include "vault/vaultglobaldefine.h" + +#include + +#include +#include +#include +#include +#include + +#include + +DFMVaultRemoveProgressView::DFMVaultRemoveProgressView(QWidget *parent) + : QWidget(parent) + , m_vaultRmProgressBar(new DWaterProgress(this)) +{ + m_vaultRmProgressBar->setFixedSize(80, 80); + AC_SET_ACCESSIBLE_NAME(m_vaultRmProgressBar, AC_VAULT_DELETE_PROGRESS); + QHBoxLayout *layout = new QHBoxLayout(); + layout->setMargin(0); + layout->addWidget(m_vaultRmProgressBar, 1, Qt::AlignCenter); + + this->setLayout(layout); + connect(this, &DFMVaultRemoveProgressView::fileRemoved, this, &DFMVaultRemoveProgressView::onFileRemove); +} + +DFMVaultRemoveProgressView::~DFMVaultRemoveProgressView() +{ + m_vaultRmProgressBar->setValue(0); + m_vaultRmProgressBar->stop(); + m_iFiles = 0; + m_iRmFiles = 0; + m_iRmDir = 0; +} + +void DFMVaultRemoveProgressView::removeVault(const QString &vaultLockPath, const QString &vaultUnlockPath) +{ + if (vaultLockPath.isEmpty() || vaultUnlockPath.isEmpty()) + return; + m_vaultRmProgressBar->start(); + // 开启线程进行文件删除 + std::thread thread( + [ = ]() { + try { + if (statisticsFiles(vaultLockPath)) { + removeFileInDir(vaultLockPath); + QDir dir; + dir.rmdir(vaultUnlockPath); + QFile::remove(VAULT_BASE_PATH + QDir::separator() + RSA_PUB_KEY_FILE_NAME); + QFile::remove(VAULT_BASE_PATH + QDir::separator() + RSA_CIPHERTEXT_FILE_NAME); + QFile::remove(VAULT_BASE_PATH + QDir::separator() + PASSWORD_HINT_FILE_NAME); + QFile::remove(VAULT_BASE_PATH + QDir::separator() + VAULT_CONFIG_FILE_NAME); + QFile::remove(VAULT_BASE_PATH + QDir::separator() + PASSWORD_FILE_NAME); + QFile::remove(VAULT_BASE_PATH + QDir::separator() + RSA_PUB_KEY_FILE_NAME + QString(".key")); + + emit removeFinished(true); + //! 清除保险箱所有时间 + DFM_NAMESPACE::DFMSettings setting(VAULT_TIME_CONFIG_FILE); + setting.removeGroup(QString("VaultTime")); + } else { + emit removeFinished(false); + } + } catch (...) { + emit removeFinished(false); + } + }); + + thread.detach(); +} + +void DFMVaultRemoveProgressView::clear() +{ + m_vaultRmProgressBar->setValue(0); + m_vaultRmProgressBar->stop(); + m_iFiles = 0; + m_iRmFiles = 0; + m_iRmDir = 0; +} + +bool DFMVaultRemoveProgressView::statisticsFiles(const QString &vaultPath) +{ + QDir dir(vaultPath); + if (!dir.exists()) + return false; + + dir.setFilter(QDir::Dirs | QDir::Files); + dir.setSorting(QDir::DirsFirst); + QFileInfoList list = dir.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::NoSymLinks | QDir::AllDirs); + int i = 0; + while (i < list.size()) { + QFileInfo fileInfo = list.at(i); + + bool bisDir = fileInfo.isDir(); + if (bisDir) { + m_iFiles++; + //递归 + statisticsFiles(fileInfo.filePath()); + } else { + m_iFiles++; + } + + i++; + } + + return true; +} + +void DFMVaultRemoveProgressView::removeFileInDir(const QString &vaultPath) +{ + QDir dir(vaultPath); + QFileInfoList infoList = dir.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::NoSymLinks | QDir::AllDirs); + + if (dir.exists()) { + dir.setFilter(QDir::Files | QDir::NoSymLinks); + QFileInfoList list = dir.entryInfoList(); + } + + //遍历文件信息列表,进行文件删除 + foreach (const QFileInfo &fileInfo, infoList) { + if (fileInfo.isDir()) { + //递归 + removeFileInDir(fileInfo.absoluteFilePath()); + } else if (fileInfo.isFile()) { + QFile file(fileInfo.absoluteFilePath()); + + //删除文件 + file.remove(); + m_iRmFiles++; + if (m_iFiles > 0) { + int value = 100 * (m_iRmFiles + m_iRmDir - 1) / m_iFiles; + emit fileRemoved(value); + } + } + } + + QDir temp_dir; + //删除文件夹 + temp_dir.rmdir(vaultPath); + m_iRmDir++; + if (m_iFiles > 0) { + int value = 100 * (m_iRmFiles + m_iRmDir - 1) / m_iFiles; + emit fileRemoved(value); + } +} + +void DFMVaultRemoveProgressView::onFileRemove(int value) +{ + if (m_vaultRmProgressBar->value() != 100) + m_vaultRmProgressBar->setValue(value); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremoveprogressview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremoveprogressview.h new file mode 100644 index 0000000..b103b31 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultremoveprogressview.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#ifndef DFMVAULTREMOVEPROGRESSVIEW_H +#define DFMVAULTREMOVEPROGRESSVIEW_H + +#include +#include + +DWIDGET_BEGIN_NAMESPACE +class DWaterProgress; +DWIDGET_END_NAMESPACE + +DWIDGET_USE_NAMESPACE +class DFMVaultRemoveProgressView : public QWidget +{ + Q_OBJECT +public: + explicit DFMVaultRemoveProgressView(QWidget *parent = nullptr); + ~DFMVaultRemoveProgressView(); + + /** + * @brief removeVault 删除保险箱 + * @param vaultPath 保险箱全路径 + */ + void removeVault(const QString &vaultLockPath, const QString &vaultUnlockPath); + + void clear(); + +private: + /** + * @brief statisticsFiles 统计指定目录下的文件数量 + * @param vaultPath 保险箱全路径 + * @return + */ + bool statisticsFiles(const QString &vaultPath); + + /** + * @brief removeFileInDir 递归删除指定文件夹下的文件 + * @param vaultPath 保险箱全路径 + */ + void removeFileInDir(const QString &vaultPath); + +signals: + void fileRemoved(int value); + + void removeFinished(bool result); + +private slots: + void onFileRemove(int value); + +private: + DWaterProgress *m_vaultRmProgressBar {nullptr}; + + int m_iFiles = 0; //文件、文件夹数量 + int m_iRmFiles = 0; //删除文件数量 + int m_iRmDir = 0; //删除文件夹数量 +}; + +#endif // DFMVAULTREMOVEPROGRESSVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultretrievepassword.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultretrievepassword.cpp new file mode 100644 index 0000000..3b6447b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultretrievepassword.cpp @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "dfmvaultretrievepassword.h" +#include "accessibility/ac-lib-file-manager.h" +#include "vault/operatorcenter.h" +#include "durl.h" +#include "controllers/vaultcontroller.h" +#include "dfmvaultunlockpages.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace PolkitQt1; + +DWIDGET_USE_NAMESPACE + +const QString defaultKeyPath = VAULT_BASE_PATH + QString("/") + RSA_PUB_KEY_FILE_NAME + QString(".key"); +const QString PolicyKitRetrievePasswordActionId = "com.deepin.filemanager.vault.VerifyKey.RetrievePassword"; + +DFMVaultRetrievePassword *DFMVaultRetrievePassword::instance() +{ + static DFMVaultRetrievePassword s_instance; + return &s_instance; +} + +void DFMVaultRetrievePassword::verificationKey() +{ + QString password; + QString keyPath; + switch (m_savePathTypeComboBox->currentIndex()) { + case 0: { + if (QFile::exists(defaultKeyPath)) { + m_defaultFilePathEdit->setText(QString(DFMVAULT_ROOT) + RSA_PUB_KEY_FILE_NAME + QString(".key")); + getButton(1)->setEnabled(true); + keyPath = defaultKeyPath; + } else { + m_defaultFilePathEdit->setPlaceholderText(tr("Unable to get the key file")); + m_defaultFilePathEdit->setText(""); + getButton(1)->setEnabled(false); + } + break; + } + case 1: + keyPath = m_filePathEdit->text(); + if (!QFile::exists(keyPath)) { + m_filePathEdit->lineEdit()->setPlaceholderText(tr("Unable to get the key file")); + m_filePathEdit->setText(""); + getButton(1)->setEnabled(false); + } else { + getButton(1)->setEnabled(true); + } + break; + } + + if (OperatorCenter::getInstance()->verificationRetrievePassword(keyPath, password)) { + setResultsPage(password); + } else { + m_verificationPrompt->setText(tr("Verification failed")); + } +} + +QString DFMVaultRetrievePassword::getUserName() +{ + QString userPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); + QString userName = userPath.section("/", -1, -1); + return userName; +} + +void DFMVaultRetrievePassword::onButtonClicked(int index, const QString &text) +{ + switch (index) { + case 0: + emit signalReturn(); + break; + case 1: + if (text == btnList[3]) { + setOnButtonClickedClose(true); //! 按钮1关闭窗口能力打开 + } else { + setOnButtonClickedClose(false); //! 按钮1关闭窗口能力关闭 + // 用户权限认证(异步授权) + auto ins = Authority::instance(); + ins->checkAuthorization(PolicyKitRetrievePasswordActionId, + UnixProcessSubject(getpid()), + Authority::AllowUserInteraction); + connect(ins, &Authority::checkAuthorizationFinished, + this, &DFMVaultRetrievePassword::slotCheckAuthorizationFinished); + } + break; + } +} + +void DFMVaultRetrievePassword::onComboBoxIndex(int index) +{ + switch (index) { + case 0: { + m_defaultFilePathEdit->show(); + m_filePathEdit->hide(); + if (QFile::exists(defaultKeyPath)) { + m_defaultFilePathEdit->setText(QString(DFMVAULT_ROOT) + RSA_PUB_KEY_FILE_NAME + QString(".key")); + getButton(1)->setEnabled(true); + } else { + m_defaultFilePathEdit->setPlaceholderText(tr("Unable to get the key file")); + m_defaultFilePathEdit->setText(""); + getButton(1)->setEnabled(false); + } + m_verificationPrompt->setText(""); + } break; + case 1: + m_defaultFilePathEdit->hide(); + m_filePathEdit->show(); + if (QFile::exists(m_filePathEdit->text())) + getButton(1)->setEnabled(true); + else if (!m_filePathEdit->text().isEmpty() && m_filePathEdit->lineEdit()->placeholderText() != QString(tr("Unable to get the key file"))) { + m_filePathEdit->lineEdit()->setPlaceholderText(tr("Unable to get the key file")); + m_filePathEdit->setText(""); + getButton(1)->setEnabled(false); + } else { + m_filePathEdit->lineEdit()->setPlaceholderText(tr("Select a path")); + getButton(1)->setEnabled(false); + } + m_verificationPrompt->setText(""); + break; + } +} + +void DFMVaultRetrievePassword::onBtnSelectFilePath(const QString &path) +{ + m_filePathEdit->setText(path); + if (!path.isEmpty()) + getButton(1)->setEnabled(true); +} + +void DFMVaultRetrievePassword::slotCheckAuthorizationFinished(PolkitQt1::Authority::Result result) +{ + disconnect(Authority::instance(), &Authority::checkAuthorizationFinished, + this, &DFMVaultRetrievePassword::slotCheckAuthorizationFinished); + if (isVisible()) { + if (result == Authority::Yes) { + verificationKey(); + } + } +} + +DFMVaultRetrievePassword::DFMVaultRetrievePassword(QWidget *parent) + : DFMVaultPageBase(parent) +{ + setIcon(QIcon::fromTheme("dfm_vault")); + setFixedWidth(396); + setMinimumHeight(270); + + setTitle(tr("Retrieve Password")); + QLabel *title = this->findChild("TitleLabel"); + if (title) + DFontSizeManager::instance()->bind(title, DFontSizeManager::T7, QFont::Medium); + + m_savePathTypeComboBox = new QComboBox(this); + AC_SET_ACCESSIBLE_NAME(m_savePathTypeComboBox, AC_VAULT_SAVE_PATH_TYPE_COMBOBOX); + m_savePathTypeComboBox->addItem(tr("By key in the default path")); + m_savePathTypeComboBox->addItem(tr("By key in the specified path")); + + m_filePathEdit = new DFileChooserEdit(this); + AC_SET_ACCESSIBLE_NAME(m_filePathEdit, AC_VAULT_SAVE_PUBKEY_FILE_EDIT); + m_filePathEdit->lineEdit()->setPlaceholderText(tr("Select a path")); + QFileDialog *fileDialog = new QFileDialog(this, QDir::homePath()); + fileDialog->setDirectoryUrl(QDir::homePath()); + fileDialog->setNameFilter(QString("KEY file(*.key)")); + m_filePathEdit->setFileDialog(fileDialog); + m_filePathEdit->lineEdit()->setReadOnly(true); + m_filePathEdit->hide(); + + m_defaultFilePathEdit = new QLineEdit(this); + m_defaultFilePathEdit->setReadOnly(true); + + m_verificationPrompt = new DLabel(this); + m_verificationPrompt->setForegroundRole(DPalette::TextWarning); + m_verificationPrompt->setAlignment(Qt::AlignHCenter); + DFontSizeManager::instance()->bind(m_verificationPrompt, DFontSizeManager::T7, QFont::Medium); + + m_PasswordRecoveryPage = new QFrame(this); + + m_passwordMsg = new DLabel(m_PasswordRecoveryPage); + m_passwordMsg->setAlignment(Qt::AlignCenter); + + m_hintMsg = new DLabel(m_PasswordRecoveryPage); + m_hintMsg->setAlignment(Qt::AlignCenter); + m_hintMsg->setText(tr("Keep it safe")); + + QVBoxLayout *vlayout = new QVBoxLayout(m_PasswordRecoveryPage); + vlayout->setContentsMargins(0, 0, 0, 0); + vlayout->setAlignment(Qt::AlignTop); + vlayout->addWidget(m_passwordMsg); + vlayout->addWidget(m_hintMsg); + vlayout->addStretch(1); + m_PasswordRecoveryPage->hide(); + + // 主视图 + m_selectKeyPage = new QFrame(this); + + // 布局 + QVBoxLayout *funLayout = new QVBoxLayout(); + funLayout->addWidget(m_savePathTypeComboBox); + funLayout->addSpacing(4); + funLayout->addWidget(m_filePathEdit); + funLayout->addWidget(m_defaultFilePathEdit); + + QVBoxLayout *mainLayout = new QVBoxLayout(m_selectKeyPage); + mainLayout->setContentsMargins(25, 10, 25, 0); + mainLayout->addStretch(1); + mainLayout->addLayout(funLayout); + mainLayout->addWidget(m_verificationPrompt); + + m_selectKeyPage->setLayout(mainLayout); + addContent(m_selectKeyPage, Qt::AlignVCenter); + + // 防止点击按钮后界面隐藏 + setOnButtonClickedClose(false); + + btnList = QStringList({ tr("Back", "button"), tr("Verify Key", "button"), tr("Go to Unlock", "button"), tr("Close", "button") }); + addButton(btnList[0], false); + addButton(btnList[1], true, ButtonType::ButtonRecommend); + + AC_SET_ACCESSIBLE_NAME(getButton(0), AC_VAULT_RETURN_UNLOCK_PAGE_BTN); + AC_SET_ACCESSIBLE_NAME(getButton(1), AC_VAULT_VERIFY_PUKEY_FILE_BTN); + + connect(this, &DFMVaultRetrievePassword::buttonClicked, this, &DFMVaultRetrievePassword::onButtonClicked); + + connect(m_savePathTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onComboBoxIndex(int))); + + connect(m_filePathEdit, &DFileChooserEdit::fileChoosed, this, &DFMVaultRetrievePassword::onBtnSelectFilePath); + + connect(VaultController::ins(), &VaultController::sigCloseWindow, this, &DFMVaultRetrievePassword::close); +} + +void DFMVaultRetrievePassword::setVerificationPage() +{ + m_savePathTypeComboBox->setCurrentIndex(0); + if (getContent(0) == m_PasswordRecoveryPage) { + removeContent(m_PasswordRecoveryPage, false); + setTitle(tr("Retrieve Password")); + m_PasswordRecoveryPage->hide(); + addContent(m_selectKeyPage); + m_selectKeyPage->show(); + m_filePathEdit->setText(QString("")); + } + m_verificationPrompt->setText(""); + setButtonText(0, btnList[0]); + setButtonText(1, btnList[1]); +} + +void DFMVaultRetrievePassword::setResultsPage(QString password) +{ + m_passwordMsg->setText(tr("Vault password: %1").arg(password)); + m_selectKeyPage->hide(); + + setTitle(tr("Verification Successful")); + removeContent(m_selectKeyPage, false); + addContent(m_PasswordRecoveryPage); + m_PasswordRecoveryPage->show(); + setButtonText(0, btnList[2]); + setButtonText(1, btnList[3]); + AC_SET_ACCESSIBLE_NAME(getButton(1), AC_VAULT_VERIFY_PUKEY_FILE_BTN); +} + +void DFMVaultRetrievePassword::showEvent(QShowEvent *event) +{ + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::RETRIEVEPASSWORDPAGE); + if (QFile::exists(defaultKeyPath)) { + m_defaultFilePathEdit->setText(QString(DFMVAULT_ROOT) + RSA_PUB_KEY_FILE_NAME + QString(".key")); + getButton(1)->setEnabled(true); + } else { + m_defaultFilePathEdit->setPlaceholderText(tr("Unable to get the key file")); + getButton(1)->setEnabled(false); + } + m_filePathEdit->setText(""); + setVerificationPage(); + + //! 保持和解锁界面对齐 + QPoint pt = DFMVaultUnlockPages::instance()->pos(); + move(pt.x(), pt.y()); + + event->accept(); +} + +void DFMVaultRetrievePassword::closeEvent(QCloseEvent *event) +{ + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::UNKNOWN); + DFMVaultPageBase::closeEvent(event); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultretrievepassword.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultretrievepassword.h new file mode 100644 index 0000000..a00975b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultretrievepassword.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef DFMVAULTRETRIEVEPASSWORD_H +#define DFMVAULTRETRIEVEPASSWORD_H + +#include "dfmvaultpagebase.h" + +#include +#include + +#include + +#include + + + +DWIDGET_USE_NAMESPACE + +class DFMVaultRetrievePassword : public DFMVaultPageBase +{ + Q_OBJECT +public: + static DFMVaultRetrievePassword *instance(); + + /** + * @brief verificationKey 验证密钥 + */ + void verificationKey(); + + /** + * @brief getUserName 获取用户名 + * @return 返回当前用户的用户名 + */ + QString getUserName(); + +signals: + /** + * @brief signalReturn 返回解锁页面 + */ + void signalReturn(); + +public slots: + /** + * @brief onButtonClicked 返回解锁页面与验证密钥按钮 + * @param index 按钮编号 + * @param text 按钮文本 + */ + void onButtonClicked(int index, const QString &text); + + /** + * @brief onComboBoxIndex 选择密钥文件的方式 + * @param index 0默认路径选择,1用户自己选择 + */ + void onComboBoxIndex(int index); + + /** + * @brief onBtnSelectFilePath 设置用户选择的密钥文件路径 + * @param path 选择的密钥文件路径 + */ + void onBtnSelectFilePath(const QString &path); + +private slots: + /** + * @brief slotCheckAuthorizationFinished 异步授权时,此函数接收授权完成的结果 + * @param result 授权结果 成功或失败 + */ + void slotCheckAuthorizationFinished(PolkitQt1::Authority::Result result); + +private: + explicit DFMVaultRetrievePassword(QWidget *parent = nullptr); + + /** + * @brief setVerificationPage 设置密钥验证页面 + */ + void setVerificationPage(); + + /** + * @brief setResultsPage 设置找回密码后的页面 + * @param password 密码 + */ + void setResultsPage(QString password); + +protected: + void showEvent(QShowEvent *event) override; + + void closeEvent(QCloseEvent *event) override; + +private: + //! 找回密码页面标题 + DLabel *m_title = nullptr; + + //! 选择要验证的密钥路径 + QComboBox *m_savePathTypeComboBox = nullptr; + + //! 用户自选密钥文件路径编辑框 + DFileChooserEdit *m_filePathEdit = nullptr; + + //! 默认密钥文件路径编辑框 + QLineEdit *m_defaultFilePathEdit = nullptr; + + //! 密钥验证失败提示标签 + DLabel *m_verificationPrompt = nullptr; + + //! 选择密钥页面 + QFrame *m_selectKeyPage = nullptr; + + //! 显示找回的密码页面 + QFrame *m_PasswordRecoveryPage = nullptr; + + //! 密钥验证成页面标题 + DLabel *m_title1 = nullptr; + //! 找回的密码信息 + DLabel *m_passwordMsg = nullptr; + //! 安全提示 + DLabel *m_hintMsg = nullptr; + + //! 4个按钮的文本 + QStringList btnList; +}; + +#endif // DFMVAULTRETRIEVEPASSWORD_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultunlockpages.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultunlockpages.cpp new file mode 100644 index 0000000..890ca2e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultunlockpages.cpp @@ -0,0 +1,389 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#define TOOLTIP_SHOW_DURATION 3000 + +#include "dfmvaultunlockpages.h" +#include "vault/interfaceactivevault.h" +#include "controllers/vaultcontroller.h" +#include "dfilemanagerwindow.h" +#include "accessibility/ac-lib-file-manager.h" +#include "dfmvaultretrievepassword.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +DFMVaultUnlockPages *DFMVaultUnlockPages::m_instance = nullptr; + +DFMVaultUnlockPages::DFMVaultUnlockPages(QWidget *parent) + : DFMVaultPageBase(parent) +{ + pTooltipTimer = new QTimer(this); + connect(pTooltipTimer, &QTimer::timeout, + this, &DFMVaultUnlockPages::slotTooltipTimerTimeout); + + AC_SET_ACCESSIBLE_NAME(this, AC_VAULT_PASSWORD_UNLOCK_WIDGET); + + setIcon(QIcon::fromTheme("dfm_vault")); + setMinimumSize(396, 244); + + // 标题 + DLabel *pTitle = new DLabel(tr("Unlock File Vault"), this); + AC_SET_ACCESSIBLE_NAME(pTitle, AC_VAULT_PASSWORD_UNLOCK_TITLE); + + pTitle->setAlignment(Qt::AlignHCenter); + pTitle->setMargin(0); + // Set font. + DFontSizeManager::instance()->bind(pTitle, DFontSizeManager::T7, QFont::Medium); + pTitle->setForegroundRole(DPalette::TextTitle); + + m_forgetPassword = new DLabel(tr("Forgot password?")); + AC_SET_ACCESSIBLE_NAME(m_forgetPassword, AC_VAULT_PASSWORD_UNLOCK_FORGETPASSWORD_BUTTON); + QFont font = pTitle->font(); + font.setPixelSize(12); + m_forgetPassword->setFont(font); + m_forgetPassword->installEventFilter(this); + m_forgetPassword->setForegroundRole(DPalette::ColorType::LightLively); + if (VaultController::getVaultVersion()) + m_forgetPassword->show(); + else { + m_forgetPassword->hide(); + } + + // 密码编辑框 + m_passwordEdit = new DPasswordEdit(this); + AC_SET_ACCESSIBLE_NAME(m_passwordEdit, AC_VAULT_PASSWORD_UNLOCK_EDIT); + m_passwordEdit->lineEdit()->setPlaceholderText(tr("Password")); + m_passwordEdit->lineEdit()->installEventFilter(this); + m_passwordEdit->lineEdit()->setAttribute(Qt::WA_InputMethodEnabled, false); + + + // 提示按钮 + m_tipsButton = new QPushButton(this); + AC_SET_ACCESSIBLE_NAME(m_tipsButton, AC_VAULT_PASSWORD_UNLOCK_HINT_BUTTON); + m_tipsButton->setIcon(QIcon(":/icons/images/icons/light_32px.svg")); + + //! 找回密码页面 + m_retrievePage = DFMVaultRetrievePassword::instance(); + + // 主视图 + QFrame *mainFrame = new QFrame(this); + + // 布局 + QHBoxLayout *play1 = new QHBoxLayout(); + play1->setMargin(0); + play1->addWidget(m_passwordEdit); + play1->addWidget(m_tipsButton); + + QHBoxLayout *play2 = new QHBoxLayout(); + play2->setMargin(0); + play2->addStretch(1); + play2->addWidget(m_forgetPassword); + m_forgetPassword->setAlignment(Qt::AlignRight); + + QVBoxLayout *mainLayout = new QVBoxLayout(mainFrame); + mainLayout->setMargin(0); + mainLayout->addWidget(pTitle); + mainLayout->addStretch(); + mainLayout->addLayout(play1); + mainLayout->addLayout(play2); + mainLayout->addStretch(); + + mainFrame->setLayout(mainLayout); + addContent(mainFrame); + setSpacing(0); + // 防止点击按钮后界面隐藏 + setOnButtonClickedClose(false); + + QStringList btnList({tr("Cancel", "button"), tr("Unlock", "button")}); + addButton(btnList[0], false); + addButton(btnList[1], true, ButtonType::ButtonRecommend); + getButton(1)->setEnabled(false); + + AC_SET_ACCESSIBLE_NAME(getButton(0), AC_VAULT_PASSWORD_UNLOCK_CANCEL_BUTTON); + AC_SET_ACCESSIBLE_NAME(getButton(1), AC_VAULT_PASSWORD_UNLOCK_OK_BUTTON); + + connect(this, &DFMVaultUnlockPages::buttonClicked, this, &DFMVaultUnlockPages::onButtonClicked); + connect(m_passwordEdit, &DPasswordEdit::textChanged, this, &DFMVaultUnlockPages::onPasswordChanged); + connect(VaultController::ins(), &VaultController::signalUnlockVault, this, &DFMVaultUnlockPages::onVaultUlocked); + connect(m_tipsButton, &QPushButton::clicked, this, [this] { + QString strPwdHint(""); + if (InterfaceActiveVault::getPasswordHint(strPwdHint)) + { + QString hint = tr("Password hint: %1").arg(strPwdHint); + showToolTip(hint, TOOLTIP_SHOW_DURATION, EN_ToolTip::Information); + } + }); + connect(this, &DFMVaultPageBase::accepted, this, &DFMVaultPageBase::enterVaultDir); + + connect(static_cast(m_retrievePage), &DFMVaultRetrievePassword::signalReturn, this, &DFMVaultUnlockPages::onReturnUnlockedPage); +} + +void DFMVaultUnlockPages::showEvent(QShowEvent *event) +{ + if(m_extraLockVault) { + //! 预防由于其他外部因素导致保险箱之前上锁未能全部完成,所以额外在解锁页面显示时主动调用lockVault函数进行强行卸载保险箱挂载点 + QDir dir(VAULT_BASE_PATH); + QFileInfoList filelist = dir.entryInfoList(QStringList() << VAULT_DECRYPT_DIR_NAME, QDir::Dirs); + for(QFileInfo & info : filelist) { + if(info.absoluteFilePath() + QDir::separator() == VaultController::makeVaultLocalPath()) { + if(!QFile::exists(VaultController::makeVaultLocalPath())) { + emit VaultController::ins()->sigLockVault(info.absoluteFilePath()); + break; + } + } + } + m_extraLockVault = false; + } + + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::UNLOCKVAULTPAGE); + // 重置所有控件状态 + m_passwordEdit->lineEdit()->clear(); + QLineEdit edit; + QPalette palette = edit.palette(); + m_passwordEdit->lineEdit()->setPalette(palette); + m_passwordEdit->setEchoMode(QLineEdit::Password); + m_bUnlockByPwd = false; + + // 如果密码提示信息为空,则隐藏提示按钮 + QString strPwdHint(""); + if (InterfaceActiveVault::getPasswordHint(strPwdHint)) { + if (strPwdHint.isEmpty()) { + m_tipsButton->hide(); + } else { + m_tipsButton->show(); + } + } + + //! 根据保险箱版本判断是否在解锁页面显示忘记密码控件 + if (VaultController::getVaultVersion()) + m_forgetPassword->show(); + else { + m_forgetPassword->hide(); + } + event->accept(); +} + +void DFMVaultUnlockPages::closeEvent(QCloseEvent *event) +{ + m_extraLockVault = true; + VaultController::ins()->setVauleCurrentPageMark(VaultPageMark::UNKNOWN); + + DFMVaultPageBase::closeEvent(event); +} + +void DFMVaultUnlockPages::showToolTip(const QString &text, int duration, DFMVaultUnlockPages::EN_ToolTip enType) +{ + if (!m_tooltip) { + m_tooltip = new DToolTip(text); + m_tooltip->setObjectName("AlertTooltip"); + m_tooltip->setWordWrap(true); + + m_frame = new DFloatingWidget; + m_frame->setFramRadius(DStyle::pixelMetric(style(), DStyle::PM_FrameRadius)); + m_frame->setStyleSheet("background-color: rgba(247, 247, 247, 0.6);"); + m_frame->setWidget(m_tooltip); + } + if (EN_ToolTip::Warning == enType) + m_tooltip->setForegroundRole(DPalette::TextWarning); + else + m_tooltip->setForegroundRole(DPalette::TextTitle); + + m_frame->setParent(this); + + m_tooltip->setText(text); + if (m_frame->parent()) { + m_frame->setGeometry(8, 154, 68, 26); + m_frame->show(); + m_frame->adjustSize(); + m_frame->raise(); + } + + if (duration < 0) { + return; + } + + // 重新启动定时器,定时隐藏tooltip + if (pTooltipTimer) { + if (pTooltipTimer->isActive()) + pTooltipTimer->stop(); + pTooltipTimer->start(duration); + } +} + +DFMVaultUnlockPages *DFMVaultUnlockPages::instance() +{ + if (!m_instance) + m_instance = new DFMVaultUnlockPages(); + return m_instance; +} + +void DFMVaultUnlockPages::hideEvent(QHideEvent *event) +{ + if (m_frame) + m_frame->close(); + DFMVaultPageBase::hideEvent(event); +} + +void DFMVaultUnlockPages::onButtonClicked(const int &index) +{ + if (index == 1) { + // 点击解锁后,灰化解锁按钮 + getButton(1)->setEnabled(false); + + // 判断保险箱剩余错误输入次数 + VaultController *pVaultController = VaultController::ins(); + int nLeftoverErrorTimes = pVaultController->getLeftoverErrorInputTimes(); + if (nLeftoverErrorTimes < 1) { + int nNeedWaitMinutes = pVaultController->getNeedWaitMinutes(); + m_passwordEdit->showAlertMessage(tr("Please try again %1 minutes later").arg(nNeedWaitMinutes)); + return; + } + + QString strPwd = m_passwordEdit->text(); + + QString strCipher(""); + if (InterfaceActiveVault::checkPassword(strPwd, strCipher)) { + m_bUnlockByPwd = true; + pVaultController->unlockVault(strCipher); + // 密码输入正确后,剩余输入次数还原,需要等待的分钟数还原 + pVaultController->restoreLeftoverErrorInputTimes(); + pVaultController->restoreNeedWaitMinutes(); + } else { + // 设置密码输入框颜色 + // 修复bug-51508 激活密码框警告状态 + m_passwordEdit->setAlert(true); + + // 保险箱剩余错误密码输入次数减1 + pVaultController->leftoverErrorInputTimesMinusOne(); + // 显示错误输入提示 + nLeftoverErrorTimes = pVaultController->getLeftoverErrorInputTimes(); + if (nLeftoverErrorTimes < 1) { + // 计时10分钟后,恢复密码编辑框 + pVaultController->startTimerOfRestorePasswordInput(); + // 错误输入次数超过了限制 + int nNeedWaitMinutes = pVaultController->getNeedWaitMinutes(); + m_passwordEdit->showAlertMessage(tr("Wrong password, please try again %1 minutes later").arg(nNeedWaitMinutes)); + } else { + if (nLeftoverErrorTimes == 1) + m_passwordEdit->showAlertMessage(tr("Wrong password, one chance left")); + else + m_passwordEdit->showAlertMessage(tr("Wrong password, %1 chances left").arg(nLeftoverErrorTimes)); + } + } + return; + } + + close(); +} + +void DFMVaultUnlockPages::onPasswordChanged(const QString &pwd) +{ + if (!pwd.isEmpty()) { + getButton(1)->setEnabled(true); + // 修复bug-51508 取消密码框警告状态 + m_passwordEdit->setAlert(false); + } else { + getButton(1)->setEnabled(false); + } +} + +void DFMVaultUnlockPages::onVaultUlocked(int state) +{ + if (m_bUnlockByPwd) { + if (state == 0) { + emit accepted(); + close(); + } else if (state == 1) { // cryfs没有成功卸载挂载目录 + // 解决sp3bug-38885:注销系统时,cryfs卸载挂载目录会概率性失败 + // 卸载挂载目录 + QProcess process; + QString fusermountBinary = QStandardPaths::findExecutable("fusermount"); + process.start(fusermountBinary, {"-zu", QString(VAULT_BASE_PATH) + QDir::separator() + QString(VAULT_DECRYPT_DIR_NAME)}); + process.waitForStarted(); + process.waitForFinished(); + process.terminate(); + if (process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0) { + QString strPwd = m_passwordEdit->text(); + QString strCipher(""); + // 判断密码是否正确 + if (InterfaceActiveVault::checkPassword(strPwd, strCipher)) { + VaultController::ins()->unlockVault(strCipher); + return; + } else { // 密码不正确 + // 设置密码输入框颜色,并弹出tooltip + m_passwordEdit->lineEdit()->setStyleSheet("background-color:rgba(241, 57, 50, 0.15)"); + m_passwordEdit->showAlertMessage(tr("Wrong password")); + } + } + } else { + // error tips + QString errMsg = tr("Failed to unlock file vault"); + DDialog dialog(this); + dialog.setIcon(QIcon::fromTheme("dialog-warning")); + dialog.setTitle(errMsg); + dialog.addButton(tr("OK", "button"), true, DDialog::ButtonRecommend); + dialog.exec(); + } + + m_bUnlockByPwd = false; + } +} + +void DFMVaultUnlockPages::onReturnUnlockedPage() +{ + m_retrievePage->hide(); + this->show(); +} + +bool DFMVaultUnlockPages::eventFilter(QObject *obj, QEvent *evt) +{ + if (obj == m_forgetPassword) { + if (evt->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(evt); + if (mouseEvent->button() == Qt::LeftButton) { + this->hide(); + m_retrievePage->show(); + } + } + } + return DDialog::eventFilter(obj, evt); +} + +void DFMVaultUnlockPages::slotTooltipTimerTimeout() +{ + m_frame->close(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultunlockpages.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultunlockpages.h new file mode 100644 index 0000000..c533dff --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dfmvaultunlockpages.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 . +*/ + +#pragma once + +#include "dfmvaultpagebase.h" + +DWIDGET_BEGIN_NAMESPACE +class DPasswordEdit; +class DToolTip; +class DFloatingWidget; +class DLabel; +DWIDGET_END_NAMESPACE + +DWIDGET_USE_NAMESPACE + +class DFMVaultUnlockPages : public DFMVaultPageBase +{ + Q_OBJECT +public: + static DFMVaultUnlockPages *instance(); + + enum EN_ToolTip { + Warning = 0, + Information + }; + +protected: + // 重写视图隐藏事件,用于隐藏tooltip + void hideEvent(QHideEvent *event) override; + +public slots: + void onButtonClicked(const int &index); + + void onPasswordChanged(const QString &pwd); + + void onVaultUlocked(int state); + + /** + * @brief onReturnUnlockedPage 返回界面页面 + */ + void onReturnUnlockedPage(); + +protected: + bool eventFilter(QObject *obj, QEvent *evt); //! m_forgetPassword 点击事件过滤处理 + +private slots: + // 超时函数,定时隐藏tooltip显示 + void slotTooltipTimerTimeout(); + +private: + explicit DFMVaultUnlockPages(QWidget *parent = nullptr); + ~DFMVaultUnlockPages() override {} + + void showEvent(QShowEvent *event) override; + + void closeEvent(QCloseEvent *event) override; + + void showToolTip(const QString &text, int duration, EN_ToolTip enType); + +private: + static DFMVaultUnlockPages *m_instance; + DPasswordEdit *m_passwordEdit {nullptr}; + QPushButton *m_tipsButton {nullptr}; + bool m_bUnlockByPwd = false; + + DToolTip *m_tooltip {nullptr}; + DFloatingWidget *m_frame {nullptr}; + // 定时器,用于定时隐藏tooltip + QTimer *pTooltipTimer {nullptr}; + DLabel *m_forgetPassword {nullptr}; //! 忘记密码提示与找回入口 + DFMVaultPageBase *m_retrievePage {nullptr}; //! 找回密码验证页面 + bool m_extraLockVault = true; +}; diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/drenamebar.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/drenamebar.cpp new file mode 100644 index 0000000..2070b02 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/drenamebar.cpp @@ -0,0 +1,781 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "drenamebar.h" +#include "windowmanager.h" +#include "controllers/appcontroller.h" +#include "views/dfilemanagerwindow.h" +#include "interfaces/dfileservices.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace Dtk::Widget; + + +template +RecordRenameBarState::RecordRenameBarState(Type &&arg, Types &&... args) +{ + static_assert(sizeof...(args) == 6, "Must be 6 parameters!"); + auto tuple = std::make_tuple(std::forward(args)...); + + m_patternFirst = std::forward(arg); + + m_patternSecond.first = std::get<0>(tuple).first; + m_patternSecond.second = std::get<0>(tuple).second; + + + m_patternThird.first = std::get<1>(tuple).first; + m_patternThird.second = std::get<1>(tuple).second; + + m_buttonStateInThreePattern = std::get<2>(tuple); + m_currentPattern = std::get<3>(tuple); + + m_selectedUrls = std::get<4>(tuple); + m_visible.store(std::get<5>(tuple), std::memory_order_seq_cst); +} + + +RecordRenameBarState::RecordRenameBarState(const RecordRenameBarState &other) + : m_patternFirst{ other.m_patternFirst }, + m_patternSecond{ other.m_patternSecond }, + m_patternThird{ other.m_patternThird }, + m_buttonStateInThreePattern{ other.m_buttonStateInThreePattern }, + m_currentPattern{ other.m_currentPattern }, + m_selectedUrls{ other.m_selectedUrls } +{ + m_visible.store(other.m_visible.load(std::memory_order_seq_cst), std::memory_order_seq_cst); +} + + +RecordRenameBarState::RecordRenameBarState(RecordRenameBarState &&other) + : m_patternFirst{ std::move(other.m_patternFirst) }, + m_patternSecond{ std::move(other.m_patternSecond) }, + m_patternThird{ std::move(other.m_patternThird) }, + m_buttonStateInThreePattern{ std::move(other.m_buttonStateInThreePattern) }, + m_currentPattern{ std::move(other.m_currentPattern) }, + m_selectedUrls{ std::move(other.m_selectedUrls) } +{ + m_visible.store(other.m_visible.load(std::memory_order_seq_cst), std::memory_order_seq_cst); +} + + + +RecordRenameBarState &RecordRenameBarState::operator=(const RecordRenameBarState &other) +{ + m_patternFirst = other.m_patternFirst; + m_patternSecond = other.m_patternSecond; + m_patternThird = other.m_patternThird; + m_buttonStateInThreePattern = other.m_buttonStateInThreePattern; + m_currentPattern = other.m_currentPattern; + m_selectedUrls = other.m_selectedUrls; + m_visible.store(other.m_visible.load(std::memory_order_seq_cst), std::memory_order_seq_cst); + + return *this; +} + + + + +RecordRenameBarState &RecordRenameBarState::operator=(RecordRenameBarState &&other) +{ + m_patternFirst = std::move(other.m_patternFirst); + m_patternSecond = std::move(other.m_patternSecond); + m_patternThird = std::move(other.m_patternThird); + m_buttonStateInThreePattern = std::move(other.m_buttonStateInThreePattern); + m_currentPattern = std::move(other.m_currentPattern); + m_selectedUrls = std::move(other.m_selectedUrls); + m_visible.store(other.m_visible.load(std::memory_order_seq_cst), std::memory_order_seq_cst); + + return *this; +} + +void RecordRenameBarState::clear() +{ + m_patternFirst.first.clear(); + m_patternFirst.second.clear(); + m_patternSecond.first.clear(); + m_patternSecond.second = DFileService::AddTextFlags::Before; + m_patternThird.first.clear(); + m_patternThird.second.clear(); + m_buttonStateInThreePattern = std::array {false, false, false}; + m_currentPattern = 0; + m_selectedUrls.clear(); + m_visible.store(false, std::memory_order_seq_cst); +} + + + +class DRenameBarPrivate +{ +private: + template + using QTuple = std::tuple; + + template + using QArray = std::array; + + +public: + explicit DRenameBarPrivate(DRenameBar *const qPtr); + ~DRenameBarPrivate() = default; + + ///###: in fact, you can not also std::move too. + DRenameBarPrivate(const DRenameBarPrivate &) = delete; + DRenameBarPrivate &operator=(DRenameBarPrivate &&) = delete; + + + void initUi(); + void setUiParameters(); + void layoutItems()noexcept; + void setRenameBtnStatus(const bool &value)noexcept; + + QString filteringText(const QString &text); //bug 26533 + void updateLineEditText(QLineEdit *lineEdit, const QString &defaultValue = "");//bug 26533 + + + DRenameBar *q_ptr{ nullptr }; + QHBoxLayout *m_mainLayout{ nullptr }; + QComboBox *m_comboBox{ nullptr }; + QStackedWidget *m_stackWidget{ nullptr }; + QArray<3> m_renameButtonStates{{false}}; //###: this is a array for recording the state of rename button in current pattern. + std::size_t m_currentPattern{0}; //###: this number record current pattern. + QList m_urlList{}; //###: this list stores the url of file which is waiting to be modified! + DFileService::AddTextFlags m_flag{ DFileService::AddTextFlags::Before }; //###: the loacation of text should be added. + + QTuple m_replaceOperatorItems{}; + QPair m_frameForLayoutReplaceArea{}; + + QTuple m_addOperatorItems{}; + QPair m_frameForLayoutAddArea{}; + + + QTuple m_customOPeratorItems{}; + QPair m_frameForLayoutCustomArea{}; + QRegExpValidator *m_validator{ nullptr }; + + + QTuple m_buttonsArea{}; + + + +public slots: + void onRenamePatternChanged(const int &index)noexcept; +}; + + +DRenameBarPrivate::DRenameBarPrivate(DRenameBar *const qPtr) + : q_ptr{ qPtr } +{ + this->initUi(); + this->setUiParameters(); + this->layoutItems(); +} + +void DRenameBarPrivate::initUi() +{ + m_mainLayout = new QHBoxLayout(q_ptr); + m_comboBox = new QComboBox; + m_stackWidget = new QStackedWidget; + + AC_SET_OBJECT_NAME(m_comboBox, AC_COMPUTER_RENAME_BAR_SELECT_TYPE); + AC_SET_ACCESSIBLE_NAME(m_comboBox, AC_COMPUTER_RENAME_BAR_SELECT_TYPE); + AC_SET_OBJECT_NAME(m_stackWidget, AC_COMPUTER_RENAME_BAR_STACK_WIDGET); + AC_SET_ACCESSIBLE_NAME(m_stackWidget, AC_COMPUTER_RENAME_BAR_STACK_WIDGET); + + m_replaceOperatorItems = std::make_tuple(new QLabel, new QLineEdit, new QLabel, new QLineEdit); + m_frameForLayoutReplaceArea = QPair { new QHBoxLayout, new QFrame }; + + m_addOperatorItems = std::make_tuple(new QLabel, new QLineEdit, new QLabel, new QComboBox); + m_frameForLayoutAddArea = QPair { new QHBoxLayout, new QFrame }; + + m_customOPeratorItems = std::make_tuple(new QLabel, new QLineEdit, new QLabel, new QLineEdit, new QLabel); + m_frameForLayoutCustomArea = QPair { new QHBoxLayout, new QFrame }; + + m_buttonsArea = std::make_tuple(new QPushButton, new QPushButton, new QHBoxLayout, new QFrame); +} + + +void DRenameBarPrivate::setUiParameters() +{ + m_comboBox->addItems(QList { QObject::tr("Replace Text"), QObject::tr("Add Text"), QObject::tr("Custom Text") }); + + QComboBox *comboBox{ nullptr }; + QLabel *label{ std::get<0>(m_replaceOperatorItems) }; + QLineEdit *lineEdit{ std::get<1>(m_replaceOperatorItems) }; + + label->setText(QObject::tr("Find")); + label->setObjectName(QString{"DRenameBarLabel"}); + lineEdit->setPlaceholderText(QObject::tr("Required")); + label->setBuddy(lineEdit); + + label = std::get<2>(m_replaceOperatorItems); + label->setObjectName(QString{"DRenameBarLabel"}); + lineEdit = std::get<3>(m_replaceOperatorItems); + label->setText(QObject::tr("Replace")); + lineEdit->setPlaceholderText(QObject::tr("Optional")); + label->setBuddy(lineEdit); + + label = std::get<0>(m_addOperatorItems); + label->setObjectName(QString{"DRenameBarLabel"}); + lineEdit = std::get<1>(m_addOperatorItems); + label->setText(QObject::tr("Add")); + lineEdit->setPlaceholderText(QObject::tr("Required")); + label->setBuddy(lineEdit); + + label = std::get<2>(m_addOperatorItems); + label->setObjectName(QString{"DRenameBarLabel"}); + comboBox = std::get<3>(m_addOperatorItems); + label->setText(QObject::tr("Location")); + comboBox->addItems(QList { QObject::tr("Before file name"), QObject::tr("After file name") }); + label->setBuddy(comboBox); + + label = std::get<0>(m_customOPeratorItems); + label->setObjectName(QString{"DRenameBarLabel"}); + lineEdit = std::get<1>(m_customOPeratorItems); + label->setText(QObject::tr("File name")); + lineEdit->setPlaceholderText(QObject::tr("Required")); + label->setBuddy(lineEdit); + + label = std::get<2>(m_customOPeratorItems); + label->setObjectName(QString{"DRenameBarLabel"}); + lineEdit = std::get<3>(m_customOPeratorItems); + label->setText(QObject::tr("Start at")); + lineEdit->setPlaceholderText(QObject::tr("Required")); + lineEdit->setText(QString{"1"}); + + QRegExp regStr{ QString{"[0-9]+"} }; + m_validator = new QRegExpValidator{ regStr, lineEdit }; + + lineEdit->setValidator(m_validator); + label->setBuddy(lineEdit); + label = std::get<4>(m_customOPeratorItems); + label->setObjectName(QString{"DRenameBarLabel"}); + label->setText(QObject::tr("Tips: Sort by selected file order")); + + QPushButton *button{ std::get<0>(m_buttonsArea) }; + button->setText(QObject::tr("Cancel","button")); + button = std::get<1>(m_buttonsArea); + button->setText(QObject::tr("Rename","button")); + + button->setEnabled(false); +} + +void DRenameBarPrivate::layoutItems()noexcept +{ + QHBoxLayout *hBoxLayout{ nullptr }; + QFrame *frame{ nullptr }; + + hBoxLayout = m_frameForLayoutReplaceArea.first; + frame = m_frameForLayoutReplaceArea.second; + hBoxLayout->setSpacing(0); + hBoxLayout->setMargin(0); + hBoxLayout->addWidget(std::get<0>(m_replaceOperatorItems)); + hBoxLayout->setSpacing(5); + hBoxLayout->addWidget(std::get<1>(m_replaceOperatorItems)); + hBoxLayout->addSpacing(32); + hBoxLayout->addWidget(std::get<2>(m_replaceOperatorItems)); + hBoxLayout->setSpacing(13); + hBoxLayout->addWidget(std::get<3>(m_replaceOperatorItems)); + hBoxLayout->addStretch(0); + frame->setLayout(hBoxLayout); + m_stackWidget->addWidget(frame); + + + hBoxLayout = m_frameForLayoutAddArea.first; + frame = m_frameForLayoutAddArea.second; + hBoxLayout->setSpacing(0); + hBoxLayout->setMargin(0); + hBoxLayout->addWidget(std::get<0>(m_addOperatorItems)); + hBoxLayout->setSpacing(5); + hBoxLayout->addWidget(std::get<1>(m_addOperatorItems)); + hBoxLayout->addSpacing(32); + hBoxLayout->addWidget(std::get<2>(m_addOperatorItems)); + hBoxLayout->setSpacing(5); + hBoxLayout->addWidget(std::get<3>(m_addOperatorItems)); + hBoxLayout->addStretch(); + frame->setLayout(hBoxLayout); + m_stackWidget->addWidget(frame); + + + hBoxLayout = m_frameForLayoutCustomArea.first; + frame = m_frameForLayoutCustomArea.second; + hBoxLayout->setSpacing(0); + hBoxLayout->setMargin(0); + hBoxLayout->addWidget(std::get<0>(m_customOPeratorItems)); + hBoxLayout->setSpacing(5); + hBoxLayout->addWidget(std::get<1>(m_customOPeratorItems)); + hBoxLayout->addSpacing(32); + hBoxLayout->addWidget(std::get<2>(m_customOPeratorItems)); + hBoxLayout->setSpacing(5); + hBoxLayout->addWidget(std::get<3>(m_customOPeratorItems)); + hBoxLayout->setSpacing(5); + hBoxLayout->addWidget(std::get<4>(m_customOPeratorItems)); + hBoxLayout->addStretch(0); + frame->setLayout(hBoxLayout); + m_stackWidget->addWidget(frame); + + + hBoxLayout = std::get<2>(m_buttonsArea); + hBoxLayout->setSpacing(0); + hBoxLayout->setMargin(0); + frame = std::get<3>(m_buttonsArea); //###: !!! + hBoxLayout->addWidget(std::get<0>(m_buttonsArea)); + hBoxLayout->addSpacing(10); + hBoxLayout->addWidget(std::get<1>(m_buttonsArea)); + hBoxLayout->setContentsMargins(0, 0, 0, 0); + frame->setLayout(hBoxLayout); + + + m_mainLayout->addWidget(m_comboBox); + m_mainLayout->addSpacing(32); + m_mainLayout->addWidget(m_stackWidget); + m_mainLayout->addStretch(0); + m_mainLayout->addWidget(frame);//###: !!! +// m_mainLayout->setContentsMargins(0,0,0,0); //do not open this. +// m_mainLayout->setSpacing(0); + m_stackWidget->setCurrentIndex(0); + + q_ptr->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum)); + q_ptr->setLayout(m_mainLayout); +} + + +void DRenameBarPrivate::setRenameBtnStatus(const bool &value)noexcept +{ + QPushButton *button{ std::get<1>(m_buttonsArea) }; + + button->setEnabled(value); +} + +QString DRenameBarPrivate::filteringText(const QString &text) +{ + if (text.isEmpty()) + return text; + + QString readyText = text; + return readyText.remove(QRegExp("[\\\\/:\\*\\?\"<>|%&]")); +} + +void DRenameBarPrivate::updateLineEditText(QLineEdit *lineEdit, const QString &defaultValue) +{ + QString olderText = lineEdit->text(); + QString text = filteringText(olderText); + if (olderText != text) { + lineEdit->setText(text); + } + if (text.isEmpty()) { + lineEdit->setText(defaultValue); + } +} + +DRenameBar::DRenameBar(QWidget *parent) + : QFrame{parent}, + d_ptr{ new DRenameBarPrivate{this} } +{ + this->initConnect(); + this->hide(); + this->setObjectName(QString{"DRenameBar"}); + AC_SET_ACCESSIBLE_NAME(this, AC_COMPUTER_RENAME_BAR); +} + + +void DRenameBar::onRenamePatternChanged(const int &index)noexcept +{ + DRenameBarPrivate *const d{ d_func() }; + + d->m_currentPattern = static_cast(index); + + bool state{ d->m_renameButtonStates[static_cast(index)] }; //###: we get the value of state of button in current mode. + d->m_stackWidget->setCurrentIndex(index); + std::get<1>(d->m_buttonsArea)->setEnabled(state); + + ///###: here, call a slot, this function will set focus of QLineEdit in current mode. + this->onVisibleChanged(true); +} + + +void DRenameBar::onReplaceOperatorFileNameChanged(const QString &text)noexcept +{ + DRenameBarPrivate *const d{ d_func() }; + + QLineEdit *lineEdit{ std::get<1>(d->m_replaceOperatorItems) }; + d->updateLineEditText(lineEdit); + + if (text.isEmpty() == true) { + d->m_renameButtonStates[0] = false; //###: record the states of rename button + + d->setRenameBtnStatus(false); + return; + } + + d->m_renameButtonStates[0] = true; //###: record the states of rename button + + d->setRenameBtnStatus(true); + return; +} + +void DRenameBar::onReplaceOperatorDestNameChanged(const QString &textChanged)noexcept +{ + Q_UNUSED(textChanged); + DRenameBarPrivate *const d{ d_func() }; + + QLineEdit *lineEdit{ std::get<3>(d->m_replaceOperatorItems) }; + d->updateLineEditText(lineEdit); +} + +void DRenameBar::onAddOperatorAddedContentChanged(const QString &text)noexcept +{ + DRenameBarPrivate *const d{ d_func() }; + + QLineEdit *lineEdit{ std::get<1>(d->m_addOperatorItems)}; + d->updateLineEditText(lineEdit); + + if (text.isEmpty() == true) { + d->m_renameButtonStates[1] = false; + + d->setRenameBtnStatus(false); + return; + } + + d->m_renameButtonStates[1] = true; + + d->setRenameBtnStatus(true); + return; +} + + +void DRenameBar::eventDispatcher() +{ + DRenameBarPrivate *const d { d_func() }; + + bool value{ false }; + + if (d->m_currentPattern == 0) { //###: replace + QString forFindingStr{ std::get<1>(d->m_replaceOperatorItems)->text() }; + QString forReplaceStr{ std::get<3>(d->m_replaceOperatorItems)->text() }; + + QPair pair{forFindingStr, forReplaceStr}; + + value = DFileService::instance()->multiFilesReplaceName(d->m_urlList, pair); + + } else if (d->m_currentPattern == 1) { //###: add + QString forAddingStr{ std::get<1>(d->m_addOperatorItems)->text() }; + + QPair pair{ forAddingStr, d->m_flag }; + + value = DFileService::instance()->multiFilesAddStrToName(d->m_urlList, pair); + + } else if (d->m_currentPattern == 2) { //###: custom + QString forCustomStr{ std::get<1>(d->m_customOPeratorItems)->text() }; + QString numberStr{ std::get<3>(d->m_customOPeratorItems)->text() }; + + QPair pair{ forCustomStr, numberStr}; + + value = DFileService::instance()->multiFilesCustomName(d->m_urlList, pair); + } + + if (value == true) { + if (QWidget *const parent = dynamic_cast(this->parent())) { + quint64 windowId{ WindowManager::getWindowId(parent) }; + AppController::multiSelectionFilesCache.second = windowId; + } + } + + this->setVisible(false); + this->resetRenameBar(); +} + +void DRenameBar::onAddTextPatternChanged(const int &index)noexcept +{ + DRenameBarPrivate *const d{ d_func() }; + + if (index == 0) { //###: add text to the front of filename. + d->m_flag = DFileService::AddTextFlags::Before; + } else { //###: add text to the back of filename. + d->m_flag = DFileService::AddTextFlags::After; + } + + ///###: here, call a slot, this function will set focus of QLineEdit in current mode. + this->onVisibleChanged(true); +} + + +void DRenameBar::onCustomOperatorFileNameChanged()noexcept +{ + DRenameBarPrivate *const d{ d_func() }; + + QLineEdit *lineEditForFileName{ std::get<1>(d->m_customOPeratorItems) }; + + d->updateLineEditText(lineEditForFileName); + + if (lineEditForFileName->text().isEmpty() == true) { //###: must be input filename. + d->m_renameButtonStates[2] = false; + d->setRenameBtnStatus(false); + + } else { + + QLineEdit *lineEditForSNNumber{ std::get<3>(d->m_customOPeratorItems) }; + + if (lineEditForSNNumber->text().isEmpty() == true) { + d->m_renameButtonStates[2] = false; + d->setRenameBtnStatus(false); + + } else { + d->m_renameButtonStates[2] = true; + d->setRenameBtnStatus(true); + + } + + } +} + +void DRenameBar::onCustomOperatorSNNumberChanged() +{ + DRenameBarPrivate *const d{ d_func() }; + + QLineEdit *lineEditForSNNumber{ std::get<3>(d->m_customOPeratorItems) }; + if (lineEditForSNNumber->text().isEmpty() == true) { //###: must be input filename. + d->m_renameButtonStates[2] = false; + d->setRenameBtnStatus(false); + + } else { + + QLineEdit *lineEditForFileName{ std::get<3>(d->m_customOPeratorItems) }; + + if (lineEditForFileName->text().isEmpty() == true) { + d->m_renameButtonStates[2] = false; + d->setRenameBtnStatus(false); + + } else { + d->m_renameButtonStates[2] = true; + d->setRenameBtnStatus(true); + + } + + ///###: renew from exception. + std::string content{ lineEditForSNNumber->text().toStdString() }; + try { + Q_UNUSED(std::stoull(content)); + } catch (const std::out_of_range &err) { + (void)err; + lineEditForSNNumber->setText(QString{"1"}); + + } catch (...) { + lineEditForSNNumber->setText(QString{"1"}); + } + + } + + +} + + + +void DRenameBar::storeUrlList(const QList &list)noexcept +{ + DRenameBarPrivate *const d{ d_func() }; + d->m_urlList = list; +} + +void DRenameBar::initConnect() +{ + DRenameBarPrivate *const d{ d_func() }; + using funcType = void (QComboBox::*)(int index); + + + QObject::connect(d->m_comboBox, static_cast(&QComboBox::activated), this, &DRenameBar::onRenamePatternChanged); + + QObject::connect(std::get<0>(d->m_buttonsArea), &QPushButton::clicked, this, &DRenameBar::clickCancelButton); + QObject::connect(std::get<1>(d->m_replaceOperatorItems), &QLineEdit::textChanged, this, &DRenameBar::onReplaceOperatorFileNameChanged); + QObject::connect(std::get<3>(d->m_replaceOperatorItems), &QLineEdit::textChanged, this, &DRenameBar::onReplaceOperatorDestNameChanged); + QObject::connect(std::get<1>(d->m_addOperatorItems), &QLineEdit::textChanged, this, &DRenameBar::onAddOperatorAddedContentChanged); + + QObject::connect(std::get<1>(d->m_buttonsArea), &QPushButton::clicked, this, &DRenameBar::eventDispatcher); + QObject::connect(std::get<3>(d->m_addOperatorItems), static_cast(&QComboBox::currentIndexChanged), this, &DRenameBar::onAddTextPatternChanged); + + + QObject::connect(std::get<1>(d->m_customOPeratorItems), &QLineEdit::textChanged, this, &DRenameBar::onCustomOperatorFileNameChanged); + QObject::connect(std::get<3>(d->m_customOPeratorItems), &QLineEdit::textChanged, this, &DRenameBar::onCustomOperatorSNNumberChanged); + + QObject::connect(this, &DRenameBar::visibleChanged, this, &DRenameBar::onVisibleChanged); + QObject::connect(this, &DRenameBar::clickRenameButton, this, &DRenameBar::eventDispatcher); +} + + +void DRenameBar::resetRenameBar()noexcept +{ + DRenameBarPrivate *const d{ d_func() }; + + ///replace + QLineEdit *lineEdit{ std::get<1>(d->m_replaceOperatorItems) }; + lineEdit->clear(); + lineEdit = std::get<3>(d->m_replaceOperatorItems); + lineEdit->clear(); + + ///add + lineEdit = std::get<1>(d->m_addOperatorItems); + lineEdit->clear(); + + ///custom + lineEdit = std::get<1>(d->m_customOPeratorItems); + lineEdit->clear(); + lineEdit = std::get<3>(d->m_customOPeratorItems); + lineEdit->setText(QString{"1"}); + + d->m_flag = DFileService::AddTextFlags::Before; + d->m_currentPattern = 0; + d->m_renameButtonStates = std::array {false, false, false}; + + d->m_comboBox->setCurrentIndex(0); + d->m_stackWidget->setCurrentIndex(0); + std::get<3>(d->m_addOperatorItems)->setCurrentIndex(0); +} + +std::unique_ptr DRenameBar::getCurrentState()const +{ + const DRenameBarPrivate *const d{ d_func() }; + QPair patternOneContent{ std::get<1>(d->m_replaceOperatorItems)->text(), + std::get<3>(d->m_replaceOperatorItems)->text() + }; + QPair patternTwoContent{ std::get<1>(d->m_addOperatorItems)->text(), + d->m_flag }; + QPair patternThreeContent{ std::get<1>(d->m_customOPeratorItems)->text(), + std::get<3>(d->m_customOPeratorItems)->text() + }; + + std::array buttonsState{ d->m_renameButtonStates }; + std::size_t currentPattern{ d->m_currentPattern }; + QList selectedUrls{ d->m_urlList }; + + bool visibleValue{ this->isVisible() }; + + std::unique_ptr state{ + new RecordRenameBarState{ + patternOneContent, patternTwoContent, patternThreeContent, + buttonsState, currentPattern, selectedUrls, visibleValue } + }; + return state; +} + +void DRenameBar::loadState(std::unique_ptr &state) +{ + DRenameBarPrivate *const d{ d_func() }; + + if (static_cast(state) == true) { + + QPair patternOneContent{ state->getPatternFirstItemContent() }; + std::get<1>(d->m_replaceOperatorItems)->setText(patternOneContent.first); + std::get<3>(d->m_replaceOperatorItems)->setText(patternOneContent.second); + + QPair patternTwoContent{ state->getPatternSecondItemContent() }; + std::get<1>(d->m_addOperatorItems)->setText(patternTwoContent.first); + d->m_flag = patternTwoContent.second; + std::get<3>(d->m_addOperatorItems)->setCurrentIndex(static_cast(patternTwoContent.second)); + + QPair patternThreeContent{ state->getPatternThirdItemContent() }; + std::get<1>(d->m_customOPeratorItems)->setText(patternThreeContent.first); + std::get<3>(d->m_customOPeratorItems)->setText(patternThreeContent.second); + + d->m_renameButtonStates = state->getbuttonStateInThreePattern(); + d->m_currentPattern = state->getCurrentPattern(); + d->m_stackWidget->setCurrentIndex(static_cast(state->getCurrentPattern())); + std::get<1>(d->m_buttonsArea)->setEnabled(d->m_renameButtonStates[d->m_currentPattern]); + + d->m_urlList = state->getSelectedUrl(); + this->setVisible(state->getVisibleValue()); + } +} + +void DRenameBar::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Return: + case Qt::Key_Enter: { + emit this->clickRenameButton(); + break; + } + case Qt::Key_Escape: { + emit this->clickCancelButton(); + break; + } + default: + break; + } +} + +void DRenameBar::setVisible(bool value) +{ + this->QFrame::setVisible(value); + emit visibleChanged(value); +} + +void DRenameBar::onVisibleChanged(bool value)noexcept +{ + DRenameBarPrivate *const d{ d_func() }; + + if (value == true) { + + switch (d->m_currentPattern) { + case 0: { + QLineEdit *lineEdit{ std::get<1>(d->m_replaceOperatorItems) }; + lineEdit->setFocus(); + break; + } + case 1: { + QLineEdit *lineEdit{ std::get<1>(d->m_addOperatorItems) }; + lineEdit->setFocus(); + break; + } + case 2: { + QLineEdit *lineEdit{ std::get<1>(d->m_customOPeratorItems) }; + lineEdit->setFocus(); + break; + } + default: { + break; + } + } + } else { + //还原焦点 + if (parentWidget()) { + parentWidget()->setFocus(); + } + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/drenamebar.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/drenamebar.h new file mode 100644 index 0000000..45f3b09 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/drenamebar.h @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DRENAMEBAR_H +#define DRENAMEBAR_H + + +#include +#include +#include + + +#include "shutil/filebatchprocess.h" + + +class DRenameBarPrivate; + + +///###: This structure record DRenameBar's state, content. +class RecordRenameBarState +{ +private: + QPair m_patternFirst{}; + QPair m_patternSecond{}; + QPair m_patternThird{}; + std::array m_buttonStateInThreePattern{{false}}; + std::size_t m_currentPattern{ 0 }; + QList m_selectedUrls{}; + std::atomic m_visible{ false }; + + + +public: + RecordRenameBarState() = default; + ~RecordRenameBarState() = default; + + + ///###: copy! + RecordRenameBarState(const RecordRenameBarState &other); + RecordRenameBarState(RecordRenameBarState &&other); + + ///###: move! + RecordRenameBarState &operator=(const RecordRenameBarState &other); + RecordRenameBarState &operator=(RecordRenameBarState &&other); + + ///###: clear! + void clear(); + + ///###: set! + template + RecordRenameBarState(Type &&arg, Types &&... args); + + inline void setPatternFirstItemContent(const QPair &patternOneItemsContent) + { + m_patternFirst = patternOneItemsContent; + } + + inline void setPatternSecondItemContent(const QPair &patternTwoItemsContent) + { + m_patternSecond = patternTwoItemsContent; + } + + inline void setPatternThirdItemContent(const QPair &patternThreeItemsContent) + { + m_patternThird = patternThreeItemsContent; + } + + inline void setbuttonStateInThreePattern(const std::array &buttonsState) + { + m_buttonStateInThreePattern = buttonsState; + } + + inline void setCurrentPattern(const std::size_t ¤tPattern) + { + m_currentPattern = currentPattern; + } + + inline void setSelectedUrls(const QList &urlList) + { + m_selectedUrls = urlList; + } + + inline void setStoredValueOfVisible(const bool &value) + { + m_visible.store(value, std::memory_order_seq_cst); + } + + + ///###: get! + inline const QPair &getPatternFirstItemContent()const noexcept + { + return m_patternFirst; + } + inline const QPair &getPatternSecondItemContent()const noexcept + { + return m_patternSecond; + } + inline const QPair &getPatternThirdItemContent()const noexcept + { + return m_patternThird; + } + inline const std::array &getbuttonStateInThreePattern()const noexcept + { + return m_buttonStateInThreePattern; + } + inline const std::size_t &getCurrentPattern()const noexcept + { + return m_currentPattern; + } + inline const QList &getSelectedUrl()const noexcept + { + return m_selectedUrls; + } + inline bool getVisibleValue()const noexcept + { + return m_visible.load(std::memory_order_seq_cst); + } +}; + + + +class DRenameBar : public QFrame +{ + Q_OBJECT +public: + explicit DRenameBar(QWidget *parent = nullptr);//###: init widgets and layout widgets when constructing DRenameBarPrivate. + virtual ~DRenameBar() override = default; + + DRenameBar(const DRenameBar &) = delete; + DRenameBar &operator=(const DRenameBar &) = delete; + + + void storeUrlList(const QList &list)noexcept; + void resetRenameBar()noexcept; //###: do not delete item! just clear content + std::unique_ptr getCurrentState()const;// return state and parameters by this function. + void loadState(std::unique_ptr &state); + + virtual void setVisible(bool value) override; + +protected: + virtual void keyPressEvent(QKeyEvent *event)override; + +signals: + void requestReplaceOperator(); + void clickCancelButton(); + void clickRenameButton(); + + void visibleChanged(bool value); + + +private slots: + void onVisibleChanged(bool value)noexcept; + void onRenamePatternChanged(const int &index)noexcept; + + void onReplaceOperatorFileNameChanged(const QString &text)noexcept; + void onReplaceOperatorDestNameChanged(const QString &textChanged)noexcept; + void onAddOperatorAddedContentChanged(const QString &text)noexcept; + void onAddTextPatternChanged(const int &index)noexcept; + void onCustomOperatorFileNameChanged()noexcept; + void onCustomOperatorSNNumberChanged(); + void eventDispatcher(); + + +private: + ///###: just connect signals and slots(through d pointer). + void initConnect(); + + QSharedPointer d_ptr{ nullptr }; + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), DRenameBar) +}; + +#endif // DRENAMEBAR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/droundbutton.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/droundbutton.cpp new file mode 100644 index 0000000..2431298 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/droundbutton.cpp @@ -0,0 +1,213 @@ + + +#include + +#include "droundbutton.h" + + +static constexpr QMarginsF MARGINS{ 1.0, 1.0, 1.0, 1.0}; + + +DRoundButton::DRoundButton(const std::initializer_list>& colors, QWidget* const parent) + :QFrame{ parent }, + m_allStatusColors{ colors } +{ +} + +void DRoundButton::setRadiusF(const double& radius)noexcept +{ + this->m_radius.first = radius; + this->setFixedSize(static_cast(radius), static_cast(radius)); +} + +void DRoundButton::setRadius(const std::size_t& radius)noexcept +{ + this->m_radius.second = radius; + this->setFixedSize(static_cast(radius), static_cast(radius)); +} + +void DRoundButton::setCheckable(bool checkable)noexcept +{ + m_checkable = checkable; +} + +void DRoundButton::setChecked(bool checked) +{ + if (!m_checkable) + return; + + if (checked) { + if (m_paintStatus == PaintStatus::checked) + return; + + setPaintStatus(PaintStatus::checked); + } else if (m_paintStatus == PaintStatus::checked) { + setPaintStatus(PaintStatus::normal); + } else { + return; + } + + emit checkedChanged(); +} + +bool DRoundButton::isChecked() const +{ + return m_paintStatus == PaintStatus::checked; +} + +bool DRoundButton::isHovered() const +{ + return testAttribute(Qt::WA_UnderMouse); +} + +QColor DRoundButton::color() const +{ + return m_allStatusColors.first().second; +} + +void DRoundButton::enterEvent(QEvent* event) +{ + if (!isChecked()) { + setPaintStatus(PaintStatus::hover); + } + + event->accept(); + + emit enter(); +} + +void DRoundButton::leaveEvent(QEvent* event) +{ + if (!isChecked()) { + setPaintStatus(PaintStatus::normal); + } + + event->accept(); + + emit leave(); +} + +void DRoundButton::mousePressEvent(QMouseEvent* event) +{ + if (!isChecked()) { + setPaintStatus(PaintStatus::pressed); + } + + QFrame::mousePressEvent(event); +} + +void DRoundButton::mouseReleaseEvent(QMouseEvent* event) +{ + setChecked(!isChecked()); + + emit click(m_allStatusColors[0].second); + QFrame::mouseReleaseEvent(event); +} + + + +void DRoundButton::paintEvent(QPaintEvent* paintEvent) +{ + (void)paintEvent; + + QPainter painter{ this }; + double theRadius{ static_cast( m_radius.first > m_radius.second ? + m_radius.first : m_radius.second ) }; + + QPen pen{ Qt::SolidLine }; + + pen.setWidthF(1.0); + pen.setJoinStyle(Qt::RoundJoin); + painter.setRenderHint(QPainter::Antialiasing, true); + + switch(m_paintStatus) + { + case PaintStatus::normal: + { + QRectF rectF{ 4, 4, theRadius-8, theRadius-8 }; + QBrush brush{ m_allStatusColors[0].second }; + + pen.setColor( m_allStatusColors[0].first ); + painter.setPen(pen); + painter.setBrush(brush); + painter.drawEllipse(rectF.marginsRemoved(MARGINS)); + + break; + } + case PaintStatus::hover: + { + QRectF rectF{ 0, 0, theRadius, theRadius }; + + pen.setColor( m_allStatusColors[1].first ); + painter.setPen(pen); + painter.drawEllipse(rectF.marginsRemoved(MARGINS)); + + QBrush brush{ m_allStatusColors[0].second }; + rectF = QRectF{ 4, 4, theRadius-8, theRadius-8 }; + pen.setColor( m_allStatusColors[0].first ); + painter.setPen(pen); + painter.setBrush(brush); + painter.drawEllipse(rectF.marginsRemoved(MARGINS)); + + break; + } + case PaintStatus::pressed: + { + QRectF rectF{ 0, 0, theRadius, theRadius }; + QBrush brush{ m_allStatusColors[1].second }; + + pen.setColor( m_allStatusColors[1].first ); + painter.setPen(pen); + painter.setBrush(brush); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.drawEllipse(rectF.marginsRemoved(MARGINS)); + + + rectF = QRectF{ 4, 4, theRadius-8, theRadius-8 }; + pen.setColor( m_allStatusColors[0].first ); + brush.setColor( m_allStatusColors[0].second ); + painter.setPen(pen); + painter.setBrush(brush); + painter.drawEllipse(rectF.marginsRemoved(MARGINS)); + + break; + } + case PaintStatus::checked: + { + QRectF rectF{ 0, 0, theRadius, theRadius }; + QBrush brush{ m_allStatusColors[1].second }; + + pen.setColor( m_allStatusColors[1].first ); + painter.setPen(pen); + painter.setBrush(brush); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.drawEllipse(rectF.marginsRemoved(MARGINS)); + + + rectF = QRectF{ 4, 4, theRadius-8, theRadius-8 }; + pen.setColor( m_allStatusColors[0].first ); + brush.setColor( m_allStatusColors[0].second ); + painter.setPen(pen); + painter.setBrush(brush); + painter.drawEllipse(rectF.marginsRemoved(MARGINS)); + + break; + } + default: + { + break; + } + } + +} + +void DRoundButton::setPaintStatus(DRoundButton::PaintStatus status) +{ + if (m_paintStatus == status) + return; + + m_paintStatus = status; + + update(); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/droundbutton.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/droundbutton.h new file mode 100644 index 0000000..ca461e4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/droundbutton.h @@ -0,0 +1,82 @@ +#ifndef DROUNDRECTBUTTON_H +#define DROUNDRECTBUTTON_H + + +#include +#include + +#include +#include +#include +#include +#include + +class DRoundButton final : public QFrame +{ + Q_OBJECT + +private: + enum class PaintStatus{ normal, hover, pressed, checked }; + +public: + + DRoundButton(const std::initializer_list>& colors, + QWidget* const parent = nullptr); + + + + DRoundButton(const DRoundButton& other)=delete; + DRoundButton& operator=(const DRoundButton& other)=delete; + + void setRadiusF(const double& radius)noexcept; + void setRadiusF(const double &radius)const noexcept= delete; + void setRadius(const std::size_t& radius) noexcept; + void setRadius(const std::size_t& radius)const noexcept = delete; + + void setBackGroundColor(const QColor& color)noexcept; + void setBackGroundColor(const QColor &color)const noexcept = delete; + + + void setCheckable(bool checkable)noexcept; + void setChecked(bool checked); + bool isChecked() const; + bool isHovered() const; + + QColor color() const; + +signals: + void click(QColor color); + void enter(); + void leave(); + void checkedChanged(); + +protected: + virtual void enterEvent(QEvent* event)override; + virtual void leaveEvent(QEvent* event)override; + virtual void mousePressEvent(QMouseEvent* event)override; + virtual void mouseReleaseEvent(QMouseEvent* event)override; + + virtual void paintEvent(QPaintEvent* paintEvent)override; + + + +private: + using QFrame::setFixedHeight; + using QFrame::setFixedWidth; + using QFrame::setFixedSize; + using QFrame::setBaseSize; + + + void setParameters(); + void setPaintStatus(PaintStatus status); + + bool m_checkable{ true }; + + QColor m_selectedColor{}; + QPair m_radius{0.0, 0}; + QList> m_allStatusColors{}; + PaintStatus m_paintStatus{ PaintStatus::normal }; +}; + + +#endif // DROUNDRECTBUTTON_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dstatusbar.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dstatusbar.cpp new file mode 100644 index 0000000..9f2adc3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dstatusbar.cpp @@ -0,0 +1,728 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +//fix: 动态获取刻录选中文件的字节大小 +#include "dfmopticalmediawidget.h" + +#include "dstatusbar.h" +#include "windowmanager.h" +#include "dfmapplication.h" + +#include "dfmevent.h" +#include "app/filesignalmanager.h" +#include "app/define.h" +#include "controllers/vaultcontroller.h" +#include "shutil/fileutils.h" + +#include "dfileservices.h" +#include "dfilestatisticsjob.h" +#include +#include "accessibility/ac-lib-file-manager.h" + +#include "singleton.h" +#include +#include +#include +#include + +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +#define STATUSBAR_WIDGET_DEFAULT_HEIGHT 24 + +DStatusBar::DStatusBar(QWidget *parent) + : QFrame(parent) +{ + setObjectName("DStatusBar"); + AC_SET_ACCESSIBLE_NAME(this, AC_COMPUTER_STATUS_BAR); + + initUI(); + initConnect(); + setMode(Normal); +} + +void DStatusBar::initUI() +{ + m_OnlyOneItemCounted = tr("%1 item"); + m_counted = tr("%1 items"); + m_OnlyOneItemSelected = tr("%1 item selected"); + m_selected = tr("%1 items selected"); + m_selectOnlyOneFolder = tr("%1 folder selected (contains %2)"); + m_selectFolders = tr("%1 folders selected (contains %2)"); + m_selectOnlyOneFile = tr("%1 file selected (%2)"); + m_selectFiles = tr("%1 files selected (%2)"); + m_selectedNetworkOnlyOneFolder = tr("%1 folder selected"); + m_layout = new QHBoxLayout(this); + + m_loadingIndicator = new DPictureSequenceView(this); + m_loadingIndicator->setFixedSize(18, 18); + AC_SET_OBJECT_NAME(m_loadingIndicator, AC_COMPUTER_STATUS_BAR_LOADING_INDICATOR); + AC_SET_ACCESSIBLE_NAME(m_loadingIndicator, AC_COMPUTER_STATUS_BAR_LOADING_INDICATOR); +#if 0 //性能优化,放到 setLoadingIncatorVisible函数处理 + { + QStringList seq; + for (int i(1); i != 91; ++i) + seq.append(QString(":/images/images/Spinner/Spinner%1.png").arg(i, 2, 10, QChar('0'))); + m_loadingIndicator->setPictureSequence(seq, true); + } +#endif + m_loadingIndicator->setSpeed(20); + m_loadingIndicator->hide(); + + m_scaleSlider = new QSlider(this); + AC_SET_OBJECT_NAME(m_scaleSlider, AC_COMPUTER_STATUS_BAR_SCALE_SLIDER); + AC_SET_ACCESSIBLE_NAME(m_scaleSlider, AC_COMPUTER_STATUS_BAR_SCALE_SLIDER); + m_scaleSlider->setOrientation(Qt::Horizontal); + m_scaleSlider->adjustSize(); + m_scaleSlider->setFixedWidth(120); + + setBackgroundRole(QPalette::Window); + + setFocusPolicy(Qt::NoFocus); + setLayout(m_layout); +} + +void DStatusBar::initConnect() +{ +// connect(fileSignalManager, &FileSignalManager::statusBarItemsSelected, this, &DStatusBar::itemSelected); +// connect(fileSignalManager, &FileSignalManager::statusBarItemsCounted, this, &DStatusBar::itemCounted); + // connect(fileSignalManager, &FileSignalManager::loadingIndicatorShowed, this, &DStatusBar::setLoadingIncatorVisible); +} + +DStatusBar::Mode DStatusBar::mode() const +{ + return m_mode; +} + +void DStatusBar::setMode(DStatusBar::Mode mode) +{ + m_mode = mode; + + if (mode == Normal) { + if (m_label) + return; + + if (m_acceptButton) { + m_acceptButton->hide(); + m_acceptButton->deleteLater(); + m_acceptButton = Q_NULLPTR; + } + if (m_rejectButton) { + m_rejectButton->hide(); + m_rejectButton->deleteLater(); + m_rejectButton = Q_NULLPTR; + } + if (m_lineEdit) { + m_lineEdit->hide(); + m_lineEdit->deleteLater(); + m_lineEdit = Q_NULLPTR; + } + if (m_comboBox) { + m_comboBox->hide(); + m_comboBox->deleteLater(); + m_comboBox = Q_NULLPTR; + } + + m_label = new DFMElidLabel(m_counted.arg("0"), this); + m_label->setAlignment(Qt::AlignCenter); + m_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + clearLayoutAndAnchors(); + m_layout->addWidget(m_loadingIndicator); + m_layout->addWidget(m_label); + m_layout->addWidget(m_scaleSlider, 0, Qt::AlignRight); + m_layout->setSpacing(14); + m_layout->setContentsMargins(0, 0, 4, 0); + + return; + } + + if (m_comboBox || m_lineEdit) { + m_lineEdit->setVisible(mode == DialogSave); + m_lineEditLabel->setVisible(m_lineEdit->isVisible()); + return; + } + + m_comboBox = new QComboBox(this); + m_comboBox->setMaximumWidth(200); + m_comboBox->setFixedHeight(STATUSBAR_WIDGET_DEFAULT_HEIGHT); + m_comboBox->hide(); + m_comboBoxLabel = new QLabel(this); + m_comboBoxLabel->setObjectName("comboBoxLabel"); + m_comboBoxLabel->setText(tr("Filter")); + m_comboBoxLabel->hide(); + + m_lineEdit = new QLineEdit(this); + AC_SET_OBJECT_NAME(m_lineEdit, AC_COMPUTER_STATUS_BAR_LINE_EDIT); + AC_SET_ACCESSIBLE_NAME(m_lineEdit, AC_COMPUTER_STATUS_BAR_LINE_EDIT); + m_lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_lineEdit->setFixedHeight(STATUSBAR_WIDGET_DEFAULT_HEIGHT); + m_lineEdit->setVisible(mode == DialogSave); + m_lineEdit->installEventFilter(this); + m_lineEditLabel = new QLabel(this); + m_lineEditLabel->setObjectName("lineEditLabel"); + AC_SET_OBJECT_NAME(m_lineEditLabel, AC_COMPUTER_STATUS_BAR_LINE_EDIT); + AC_SET_ACCESSIBLE_NAME(m_lineEditLabel, AC_COMPUTER_STATUS_BAR_LINE_EDIT); + m_lineEditLabel->setText(tr("Save as:")); + m_lineEditLabel->hide(); + + if (m_label) { + m_label->hide(); + m_label->deleteLater(); + m_label = Q_NULLPTR; + } + if (!m_acceptButton) { + m_acceptButton = new QPushButton(QString(), this); + AC_SET_OBJECT_NAME(m_acceptButton, AC_COMPUTER_STATUS_BAR_ACCEPT_BUTTON); + AC_SET_ACCESSIBLE_NAME(m_acceptButton, AC_COMPUTER_STATUS_BAR_ACCEPT_BUTTON); + m_acceptButton->setFixedHeight(STATUSBAR_WIDGET_DEFAULT_HEIGHT); + m_acceptButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + } + if (!m_rejectButton) { + m_rejectButton = new QPushButton(QString(), this); + AC_SET_OBJECT_NAME(m_rejectButton, AC_COMPUTER_STATUS_BAR_REJECT_BUTTON); + AC_SET_ACCESSIBLE_NAME(m_rejectButton, AC_COMPUTER_STATUS_BAR_REJECT_BUTTON); + m_rejectButton->setFixedHeight(STATUSBAR_WIDGET_DEFAULT_HEIGHT); + m_rejectButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + } + + clearLayoutAndAnchors(); + m_scaleSlider->move(0, 0); + m_layout->addWidget(m_scaleSlider); + m_layout->addWidget(m_comboBoxLabel); + m_layout->addWidget(m_comboBox); + m_layout->addWidget(m_lineEditLabel); + m_layout->addWidget(m_lineEdit, 1); + m_layout->addStretch(); + m_layout->addWidget(m_loadingIndicator, 0, Qt::AlignRight); + m_layout->addWidget(m_rejectButton, 0, Qt::AlignRight); + m_layout->addWidget(m_acceptButton, 0, Qt::AlignRight); + m_layout->setSpacing(10); + m_layout->setContentsMargins(10, 10, 10, 10); + + emit modeChanged(); +} + +void DStatusBar::setComBoxItems(const QStringList &filters) +{ + if (!m_comboBox) + return; + + m_comboBox->clear(); + m_comboBox->addItems(filters); + m_comboBox->setVisible(!filters.isEmpty()); + m_comboBoxLabel->setVisible(m_comboBox->isVisible()); +} + +QSlider *DStatusBar::scalingSlider() const +{ + return m_scaleSlider; +} + +QPushButton *DStatusBar::acceptButton() const +{ + return m_acceptButton; +} + +QPushButton *DStatusBar::rejectButton() const +{ + return m_rejectButton; +} + +QLineEdit *DStatusBar::lineEdit() const +{ + return m_lineEdit; +} + +QComboBox *DStatusBar::comboBox() const +{ + return m_comboBox; +} + +QSize DStatusBar::sizeHint() const +{ + QSize size = QFrame::sizeHint(); + + size.setHeight(qMax(25, size.height())); + + return size; +} + +qint64 DStatusBar::computerSize(const DUrlList &urllist) +{ + qint64 fileSize = 0; + foreach (DUrl url, urllist) { + const DAbstractFileInfoPointer &fileInfo = fileService->createFileInfo(this, url); + if (fileInfo->isFile()) { + fileSize += fileInfo->size(); + } + } + return fileSize; +} + +int DStatusBar::computerFolderContains(const DUrlList &urllist) +{ + int folderContains = 0; + foreach (DUrl url, urllist) { + const DAbstractFileInfoPointer &fileInfo = fileService->createFileInfo(this, url); + if (fileInfo->isDir()) { + folderContains += fileInfo->filesCount(); + } + } + return folderContains; +} + +QVariantList DStatusBar::calcFolderAndFile(const DUrlList &urllist) +{ + int folderCount(0); + int folderContains(0); + int fileCount(0); + qint64 fileSize(0); + foreach (const DUrl &url, urllist) { + const DAbstractFileInfoPointer &fileInfo = fileService->createFileInfo(this, url); + if (fileInfo->isDir()) { + // 统计目录个数及目录内的文件个数 + folderCount++; + folderContains += fileInfo->filesCount(); + } else { + // 统计文件个数及文件的大小 + fileCount++; + fileSize += fileInfo->size(); + } + } + return QVariantList{folderCount, folderContains, fileCount, fileSize}; +} + +void DStatusBar::initJobConnection() +{ + if (!m_fileStatisticsJob) { + return; + } + + auto onFoundFile = [this] { + if (!sender()) + return; + + ++m_folderContains; + updateStatusMessage(); + }; + + connect(m_fileStatisticsJob, &DFileStatisticsJob::finished, this, + [this] { + m_folderContains = m_fileStatisticsJob->filesCount() + m_fileStatisticsJob->directorysCount(); + updateStatusMessage(); + } + ); + connect(m_fileStatisticsJob, &DFileStatisticsJob::fileFound, this, onFoundFile); + connect(m_fileStatisticsJob, &DFileStatisticsJob::directoryFound, this, onFoundFile); +} + +void DStatusBar::showMtpStatus(const DFMEvent &event, int number) +{ + // 重置统计状态 + m_fileCount = 0; + m_fileSize = 0; + m_folderCount = 0; + m_folderContains = 0; + + // number 大于 1 时, 显示不一样, 需要拼接文本 + if (number > 1) { + DUrl fileUrl; + if (event.fileUrlList().count() > 0) { + fileUrl = event.fileUrlList().first(); + } else { + fileUrl = event.fileUrl(); + } + foreach (const DUrl &url, event.fileUrlList()) { + struct stat statInfo; + int fileStat = stat(url.path().toStdString().c_str(), &statInfo); + if (0 != fileStat) { + continue; + } + if (S_ISDIR(statInfo.st_mode)) { + m_folderCount += 1; // 文件夹数量 + } else { + m_fileCount += 1; // 文件数量 + } + } + QString selectItems; + + if (m_folderCount > 0 && m_fileCount > 0) // 同时有文件夹和文件时, 统一显示成项 + selectItems = m_OnlyOneItemSelected.arg(QString::number(m_folderCount+m_fileCount)); + else if (m_folderCount > 0) + selectItems = m_selectedNetworkOnlyOneFolder.arg(QString::number(m_folderCount)); + else if (m_fileCount > 0) + selectItems = m_OnlyOneItemSelected.arg(QString::number(m_fileCount)); + else + selectItems = ""; + + m_label->setText(QString("%1").arg(selectItems)); + } else { + if (number == 1) { // 选中数量为1, 要么是文件夹, 要么是文件 + if (event.fileUrlList().count() == 1) { + DUrl durl = event.fileUrlList().first(); + const DAbstractFileInfoPointer &info = fileService->createFileInfo(this, durl); + //check network folder at first + QStringList networkSchemeList = {SMB_SCHEME, FTP_SCHEME, SFTP_SCHEME, MTP_SCHEME, DAV_SCHEME}; + if (networkSchemeList.contains(event.fileUrlList().first().scheme())) { + m_label->setText(m_selectedNetworkOnlyOneFolder.arg(QString::number(number))); + } else if (info) { + if (info->isDir()) { + m_folderCount = 1; + m_label->setText(m_selectedNetworkOnlyOneFolder.arg(QString::number(number))); + } else { + m_fileCount = 1; + m_label->setText(m_OnlyOneItemSelected.arg(QString::number(1))); + } + } + } else { + m_label->setText(m_OnlyOneItemSelected.arg(QString::number(1))); + } + } + } +} + +void DStatusBar::itemSelected(const DFMEvent &event, int number) +{ + if (!m_label || event.windowId() != WindowManager::getWindowId(this)) + return; + + { // mtp挂载时 暂时不显示下方状态栏数据 能大幅提升访问性能 + // 首先判断配置 + const bool showInfo = DFMApplication::genericAttribute(DFMApplication::GA_MTPShowBottomInfo).toBool(); + if (!showInfo) { // mtp 不显示底部状态的设置下 再进行 mtp 判断 + static const QString &mtpType = "gvfs/mtp:host"; + const QString &path = event.fileUrlList().count() > 0 ? event.fileUrlList().first().toLocalFile() + : event.fileUrl().toLocalFile(); + if (path.contains(mtpType)) { + showMtpStatus(event, number); + return; + } + } + } + + /* remark 190412: + * This function is triggered by multiple different events when + * using keyboard navigation, causing DFileStatisticsJob to be + * started more than once. + * A fix better than the current one should eventually be applied. + */ + if (!m_fileStatisticsJob) { + m_fileStatisticsJob = new DFileStatisticsJob(this); + m_fileStatisticsJob->setFileHints(DFileStatisticsJob::ExcludeSourceFile | DFileStatisticsJob::SingleDepth); + } else if (m_fileStatisticsJob->isRunning()) { + m_fileStatisticsJob->stop(); + m_fileStatisticsJob->wait(); + } + if (m_isjobDisconnect) { + m_isjobDisconnect = false; + initJobConnection(); + } + m_fileCount = 0; + m_fileSize = 0; + m_folderCount = 0; + m_folderContains = 0; + + //fix: 动态获取刻录选中文件的字节大小 + DFMOpticalMediaWidget::g_selectBurnFilesSize = 0; + DFMOpticalMediaWidget::g_selectBurnDirFileCount = 0; + if (number > 1) { + DUrl fileUrl; + if (event.fileUrlList().count() > 0) { + fileUrl = event.fileUrlList().first(); + } else { + fileUrl = event.fileUrl(); + } + bool isInGVFs = FileUtils::isGvfsMountFile(fileUrl.toLocalFile()); + DUrlList folderList; + if (isInGVFs) { + foreach (const DUrl &url, event.fileUrlList()) { + struct stat statInfo; + int fileStat = stat(url.path().toStdString().c_str(), &statInfo); + if (0 != fileStat) { + continue; + } + if (S_ISDIR(statInfo.st_mode)) { + m_folderCount += 1; + folderList << url; + } else { + m_fileCount += 1; + } + } + } else { + // 保险箱内,全选文件达到2000个时,文管会很卡顿,以下修改优化该问题 + if (VaultController::isVaultFile(fileUrl.toLocalFile())) { + // 将文件个数及大小的计算过程放入异步线程中 + QFutureWatcher *fileWatcher = new QFutureWatcher(); + connect(fileWatcher, &QFutureWatcher::finished, this, &DStatusBar::handleCalcFolderAndFileFinished); + QFuture fileFuture = QtConcurrent::run(this, &DStatusBar::calcFolderAndFile, event.fileUrlList()); + fileWatcher->setFuture(fileFuture); + } else { + foreach (const DUrl &url, event.fileUrlList()) { + const DAbstractFileInfoPointer &info = fileService->createFileInfo(this, url); + if (info->isDir()) { + m_folderCount += 1; + folderList << url; + } else { + if (!isInGVFs) { + m_fileSize += info->size(); + } + m_fileCount += 1; + } + } + } + } + + if (isInGVFs) { + QFutureWatcher *fileWatcher = new QFutureWatcher(); + connect(fileWatcher, SIGNAL(finished()), this, SLOT(handdleComputerFileSizeFinished())); + // Start the computation. + QFuture fileFuture = QtConcurrent::run(this, &DStatusBar::computerSize, event.fileUrlList()); + fileWatcher->setFuture(fileFuture); + + QFutureWatcher *folderWatcher = new QFutureWatcher(); + connect(folderWatcher, SIGNAL(finished()), this, SLOT(handdleComputerFolderContainsFinished())); + // Start the computation. + QFuture folderFuture = QtConcurrent::run(this, &DStatusBar::computerFolderContains, event.fileUrlList()); + folderWatcher->setFuture(folderFuture); + } else { + m_fileStatisticsJob->start(folderList); + } + updateStatusMessage(); + } else { + if (number == 1) { + if (event.fileUrlList().count() == 1) { + DUrl durl = event.fileUrlList().first(); + const DAbstractFileInfoPointer &info = fileService->createFileInfo(this, durl); + + //check network folder at first + QStringList networkSchemeList = {SMB_SCHEME, FTP_SCHEME, SFTP_SCHEME, MTP_SCHEME, DAV_SCHEME}; + if (networkSchemeList.contains(event.fileUrlList().first().scheme())) { + m_label->setText(m_selectedNetworkOnlyOneFolder.arg(QString::number(number))); + } else if (info) { + if (info->isDir()) { + m_folderCount = 1; + m_label->setText(m_selectOnlyOneFolder.arg(number).arg(m_counted.arg(0))); + m_fileStatisticsJob->start(event.fileUrlList()); + + + } else { /*if (fileInfo->isFile())*/ + m_fileCount = 1; + m_label->setText(m_selectOnlyOneFile.arg(QString::number(number), FileUtils::formatSize(info->size()))); + + //fix: 动态获取刻录选中文件的字节大小 + DFMOpticalMediaWidget::g_selectBurnFilesSize = info->size(); + } + } + } else { + m_label->setText(m_OnlyOneItemSelected.arg(QString::number(1))); + } + } + } + //fix: 动态获取刻录选中文件夹的个数 + DFMOpticalMediaWidget::g_selectBurnDirFileCount = m_folderCount; +} + +void DStatusBar::updateStatusMessage() +{ + QString selectedFolders; + + if (m_folderCount == 1 && m_folderContains == 1) { + selectedFolders = m_selectOnlyOneFolder.arg(QString::number(m_folderCount), m_OnlyOneItemCounted.arg(m_folderContains)); + } else if (m_folderCount == 1 && m_folderContains != 1) { + selectedFolders = m_selectOnlyOneFolder.arg(QString::number(m_folderCount), m_counted.arg(m_folderContains)); + } else if (m_folderCount > 1 && m_folderContains == 1) { + selectedFolders = m_selectFolders.arg(QString::number(m_folderCount), m_OnlyOneItemCounted.arg(m_folderContains)); + } else if (m_folderCount > 1 && m_folderContains != 1) { + selectedFolders = m_selectFolders.arg(QString::number(m_folderCount), m_counted.arg(m_folderContains)); + } else { + selectedFolders = ""; + } + + QString selectedFiles; + + if (m_fileCount == 1) { + selectedFiles = m_selectOnlyOneFile.arg(QString::number(m_fileCount), FileUtils::formatSize(m_fileSize)); + //fix: 动态获取刻录选中文件的字节大小 + DFMOpticalMediaWidget::g_selectBurnFilesSize = m_fileSize; + } else if (m_fileCount > 1) { + selectedFiles = m_selectFiles.arg(QString::number(m_fileCount), FileUtils::formatSize(m_fileSize)); + //fix: 动态获取刻录选中文件的字节大小 + DFMOpticalMediaWidget::g_selectBurnFilesSize = m_fileSize; + } else { + selectedFiles = ""; + } + + if (selectedFolders.isEmpty()) { + m_label->setText(QString("%1").arg(selectedFiles)); + } else if (selectedFiles.isEmpty()) { + m_label->setText(QString("%1").arg(selectedFolders)); + } else { + m_label->setText(QString("%1,%2").arg(selectedFolders, selectedFiles)); + } +} + +void DStatusBar::handdleComputerFolderContainsFinished() +{ + QFutureWatcher *watcher = static_cast*>(sender()); + int result = watcher->future().result(); + m_folderContains = result; + updateStatusMessage(); + watcher->deleteLater(); +} + +void DStatusBar::handleCalcFolderAndFileFinished() +{ + QFutureWatcher *watcher = dynamic_cast *>(sender()); + if (watcher) { + QVariantList result = watcher->future().result(); + if (result.size() == 4) { + // 设置目录和文件的个数及大小 + m_folderCount = result[0].toInt(); + m_folderContains = result[1].toInt(); + m_fileCount = result[2].toInt(); + m_fileSize = result[3].toLongLong(); + // 状态栏显示目录和文件的个数及大小 + updateStatusMessage(); + } + watcher->deleteLater(); + } +} + +void DStatusBar::handdleComputerFileSizeFinished() +{ + QFutureWatcher *watcher = static_cast*>(sender()); + qint64 result = watcher->future().result(); + m_fileSize = result; + updateStatusMessage(); + watcher->deleteLater(); +} + +void DStatusBar::itemCounted(const DFMEvent &event, int number) +{ + if (m_fileStatisticsJob) { + if (m_fileStatisticsJob->isRunning()) { + m_fileStatisticsJob->stop(); + m_fileStatisticsJob->wait(); + if (m_fileStatisticsJob->disconnect()) { + m_isjobDisconnect = true; + } + } + } + + if (!m_label || event.windowId() != WindowManager::getWindowId(this)) + return; + + if (number != 1) { + m_label->setText(m_counted.arg(QString::number(number))); + } else { + m_label->setText(m_OnlyOneItemCounted.arg(QString::number(number))); + } + + //fix: 动态获取刻录选中文件的字节大小 + DFMOpticalMediaWidget::g_selectBurnFilesSize = 0; + DFMOpticalMediaWidget::g_selectBurnDirFileCount = 0; +} + +void DStatusBar::setLoadingIncatorVisible(bool visible, const QString &tipText) +{ + m_loadingIndicator->setVisible(visible); + + if (visible) { + if (!m_loadingIndicatorInited) { + QStringList seq; + for (int i(1); i != 91; ++i) + seq.append(QString(":/images/images/Spinner/Spinner%1.png").arg(i, 2, 10, QChar('0'))); + m_loadingIndicator->setPictureSequence(seq, true); + m_loadingIndicatorInited = true; + } + + m_loadingIndicator->play(); + } + + if (!m_label) + return; + + if (visible) { + m_label->setText(tipText.isEmpty() ? tr("Loading...") : tipText); + } else { + m_label->setText(QString()); + } +} + +bool DStatusBar::eventFilter(QObject *watched, QEvent *event) +{ + if (watched != m_lineEdit) + return false; + + if (event->type() == QEvent::FocusIn) { + TIMER_SINGLESHOT_OBJECT(this, 10, { + QMimeDatabase db; + const QString &name = m_lineEdit->text(); + const QString &suffix = db.suffixForFileName(name); + + if (suffix.isEmpty()) + m_lineEdit->selectAll(); + else + m_lineEdit->setSelection(0, name.length() - suffix.length() - 1); + }, this) + } else if (event->type() == QEvent::Show) { + TIMER_SINGLESHOT_OBJECT(this, 10, m_lineEdit->setFocus(), this); + } + + return false; +} + +void DStatusBar::clearLayoutAndAnchors() +{ + while (m_layout->count() > 0) + delete m_layout->takeAt(0); + + DAnchorsBase::clearAnchors(this); + DAnchorsBase::clearAnchors(m_scaleSlider); +} + +void DFMElidLabel::setText(const QString &text) +{ + m_text = text; + setElidText(text); +} + +void DFMElidLabel::setElidText(const QString &text) +{ + QFont font = this->font(); + QFontMetrics fm(font); + QString str = fm.elidedText(text, Qt::ElideRight, width()); + setToolTip(m_text); + QLabel::setText(str); +} + +void DFMElidLabel::resizeEvent(QResizeEvent *event) +{ + QLabel::resizeEvent(event); + setElidText(m_text); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dstatusbar.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dstatusbar.h new file mode 100644 index 0000000..858d7a9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dstatusbar.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DSTATUSBAR_H +#define DSTATUSBAR_H + +#include +#include + +#include +#include +#include +#include +#include + +#include "durl.h" +#include "dfmglobal.h" + +DWIDGET_USE_NAMESPACE + +QT_BEGIN_NAMESPACE +class QPushButton; +class QLineEdit; +class QComboBox; +QT_END_NAMESPACE + +class DFMEvent; + +DFM_BEGIN_NAMESPACE +class DFileStatisticsJob; +DFM_END_NAMESPACE + +DFM_USE_NAMESPACE + + +class DFMElidLabel : public QLabel +{ +public: + explicit DFMElidLabel(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()) + : QLabel(parent, f) + { + } + explicit DFMElidLabel(const QString &text, QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()) + : QLabel(text, parent, f) + { + + } + ~DFMElidLabel() {} + + void setText(const QString &text); +protected: + void setElidText(const QString &text); + void resizeEvent(QResizeEvent *event) override ; + +private: + QString m_text; +}; + +class DStatusBar : public QFrame +{ + Q_OBJECT + + Q_PROPERTY(Mode mode READ mode WRITE setMode NOTIFY modeChanged) + +public: + enum Mode { + Normal, + DialogOpen, + DialogSave + }; + + explicit DStatusBar(QWidget *parent = nullptr); + + void initUI(); + void initConnect(); + + Mode mode() const; + void setMode(Mode mode); + void setComBoxItems(const QStringList &filters); + + QSlider *scalingSlider() const; + QPushButton *acceptButton() const; + QPushButton *rejectButton() const; + QLineEdit *lineEdit() const; + QComboBox *comboBox() const; + + QSize sizeHint() const override; + + qint64 computerSize(const DUrlList &urllist); + int computerFolderContains(const DUrlList &urllist); + // 计算目录和文件的个数及大小 + QVariantList calcFolderAndFile(const DUrlList &urllist); + +signals: + void modeChanged(); + +public slots: + void itemSelected(const DFMEvent &event, int number); + void updateStatusMessage(); + void handdleComputerFileSizeFinished(); + void handdleComputerFolderContainsFinished(); + // 更新目录和文件的个数及大小,并显示于状态栏 + void handleCalcFolderAndFileFinished(); + void itemCounted(const DFMEvent &event, int number); + void setLoadingIncatorVisible(bool visible, const QString &tipText = QString()); + +protected: + bool eventFilter(QObject *watched, QEvent *event) override; + +private: + void clearLayoutAndAnchors(); + void initJobConnection(); + /** + * @brief mtp挂载时, 更新底部统计信息显示 + * @param DFMEvent int + * @return void + */ + void showMtpStatus(const DFMEvent &event, int number); + + QString m_OnlyOneItemCounted; + QString m_counted; + QString m_OnlyOneItemSelected; + QString m_selected; + + QString m_selectFolders; + QString m_selectOnlyOneFolder; + QString m_selectFiles; + QString m_selectOnlyOneFile; + QString m_selectedNetworkOnlyOneFolder; + + int m_fileCount = 0; + qint64 m_fileSize = 0; + int m_folderCount = 0; + int m_folderContains = 0; + + QHBoxLayout *m_layout; + DFMElidLabel *m_label = Q_NULLPTR; + DPictureSequenceView *m_loadingIndicator; + bool m_loadingIndicatorInited = false; + + QSlider *m_scaleSlider; + + QPushButton *m_acceptButton = Q_NULLPTR; + QPushButton *m_rejectButton = Q_NULLPTR; + QLineEdit *m_lineEdit = Q_NULLPTR; + QComboBox *m_comboBox = Q_NULLPTR; + QLabel *m_lineEditLabel = Q_NULLPTR; + QLabel *m_comboBoxLabel = Q_NULLPTR; + DFileStatisticsJob *m_fileStatisticsJob = nullptr; + bool m_isjobDisconnect = true; + + Mode m_mode = Normal; +}; + +#endif // DSTATUSBAR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtabbar.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtabbar.cpp new file mode 100644 index 0000000..30782da --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtabbar.cpp @@ -0,0 +1,970 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "dtabbar.h" +#include "windowmanager.h" + +#include "app/define.h" +#include "dfmevent.h" +#include "controllers/appcontroller.h" + +#include + +#include +#include +#include +#include +#include + +#include "app/define.h" +#include "dfmevent.h" +#include "app/filesignalmanager.h" +#include "deviceinfo/udisklistener.h" +#include "usershare/usersharemanager.h" +#include "controllers/pathmanager.h" +#include "interfaces/dfileservices.h" +#include "plugins/pluginmanager.h" +#include "view/viewinterface.h" +#include "interfaces/dfmstandardpaths.h" +#include "views/dfilemanagerwindow.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +Tab::Tab(QGraphicsObject *parent, DFMBaseView *view): + QGraphicsObject(parent) +{ + m_fileView = view; + + if (view) + setCurrentUrl(view->rootUrl()); + + initConnect(); + setAcceptHoverEvents(true); + setFlags(ItemIsSelectable); + setAcceptedMouseButtons(Qt::LeftButton); +} + +Tab::~Tab() +{ +} + +void Tab::initConnect() +{ + +} + +void Tab::setTabText(QString text) +{ + m_tabText = text; + update(); +} + +QString Tab::tabText() +{ + return m_tabText; +} + +DFMBaseView *Tab::fileView() +{ + return m_fileView; +} + +void Tab::setFileView(DFMBaseView *view) +{ + if (m_fileView == view) + return; + + m_fileView = view; + + if (view) { + setCurrentUrl(view->rootUrl()); + } +} + +DUrl Tab::currentUrl() const +{ + return m_url; +} + +void Tab::setCurrentUrl(const DUrl &url) +{ + m_url = url; + setTabText(getDisplayNameByUrl(url)); +} + +void Tab::setFixedSize(QSize size) +{ + prepareGeometryChange(); + m_width = size.width(); + m_height = size.height(); +} + +void Tab::setGeometry(QRect rect) +{ + prepareGeometryChange(); + setX(rect.x()); + setY(rect.y()); + m_width = rect.width(); + m_height = rect.height(); +} + +QRect Tab::geometry() +{ + return QRect(static_cast(x()), static_cast(y()), m_width, m_height); +} + +int Tab::width() +{ + return m_width; +} + +int Tab::height() +{ + return m_height; +} + +bool Tab::isDragging() +{ + return m_isDragging; +} + +void Tab::setHovered(bool hovered) +{ + m_hovered = hovered; +} + +bool Tab::isDragOutSide() +{ + return m_dragOutSide; +} + +QPixmap Tab::toPixmap(bool drawBorder) +{ + QImage img(300, m_height, QImage::Format_ARGB32); + img.fill(Qt::white); + QPainter painter(&img); + QPen pen; + QColor color(Qt::yellow); + pen.setStyle(Qt::SolidLine); + pen.setWidth(1); + + //draw text + QFont font; + font.setPixelSize(12); + painter.setFont(font); + QFontMetrics fm(font); + QString str = fm.elidedText(m_tabText, Qt::ElideRight, 300 - 10); + + //draw backgound + color.setNamedColor("#FFFFFF"); + painter.fillRect(boundingRect(), color); + color.setNamedColor("#303030"); + pen.setColor(color); + painter.setPen(pen); + painter.drawText((300 - fm.width(str)) / 2, (m_height - fm.height()) / 2, + fm.width(str), fm.height(), 0, str); + + if (drawBorder) { + QPainterPath path; + path.addRect(0, 0, 300 - 1, m_height - 1); + color.setRgb(0, 0, 0, static_cast(0.1 * 255)); + pen.setColor(color); + painter.setPen(pen); + painter.drawPath(path); + } + + return QPixmap::fromImage(img); +} + +bool Tab::isChecked() const +{ + return m_checked; +} + +void Tab::setChecked(const bool check) +{ + m_checked = check; + update(); +} + +bool Tab::borderLeft() const +{ + return m_borderLeft; +} + +void Tab::setBorderLeft(const bool flag) +{ + m_borderLeft = flag; +} + +QString Tab::getDisplayNameByUrl(const DUrl &url) const +{ + QString urlDisplayName; + if (url.isComputerFile()) { + if (systemPathManager->isSystemPath(url.toString())) + urlDisplayName = systemPathManager->getSystemPathDisplayNameByPath(url.toString()); + } //NOTE [REN] 这儿获取plugin插件的tab名 + else if (url.isPluginFile()) { + if (systemPathManager->isSystemPath(url.toString())) { + urlDisplayName = systemPathManager->getSystemPathDisplayNameByPath(url.toString()); + } else { + //NOTE [REN] plugin插件的非根目录的url也是存在plugin的,格式是plugin://***/***,也走这个判断流程 + QString path = url.path(); + if (path.contains("/")) { + QStringList listvalue = path.split("/"); + urlDisplayName = listvalue.at(listvalue.size() - 1); + } + } + } else if (url == DUrl::fromTrashFile("/")) { + urlDisplayName = systemPathManager->getSystemPathDisplayName("Trash"); + } else if (PluginManager::instance()->getViewInterfacesMap().keys().contains(url.scheme())) { + urlDisplayName = PluginManager::instance()->getViewInterfaceByScheme(url.scheme())->bookMarkText(); + } else if (url == DUrl(RECENT_ROOT)) { + urlDisplayName = systemPathManager->getSystemPathDisplayName("Recent"); + } else { + const DAbstractFileInfoPointer &fileInfo = fileService->createFileInfo(this, url); + + if (fileInfo) + urlDisplayName = fileInfo->fileDisplayName(); + } + return urlDisplayName; +} + +QRectF Tab::boundingRect() const +{ + return QRectF(0, 0, m_width, m_height); +} + +QPainterPath Tab::shape() const +{ + QPainterPath path; + path.addRect(boundingRect()); + return path; +} + +void Tab::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget) + Q_UNUSED(option) + + if (m_dragOutSide) + return; + QPen pen = painter->pen(); + pen.setWidth(1); + + //draw text + QFont font; + font.setPixelSize(12); + + if (isChecked()) { + font.setWeight(QFont::Normal + 10); + } else { + font.setWeight(QFont::Normal); + } + + painter->setFont(font); + QFontMetrics fm(font); + QString str = fm.elidedText(m_tabText, Qt::ElideRight, m_width - 10); + + DPalette pal = DApplicationHelper::instance()->palette(widget); + QColor color; + + //draw backgound + if (isChecked()) { + color = pal.color(QPalette::Active, QPalette::Base); + color = DGuiApplicationHelper::adjustColor(color, 0, 0, 0, 0, 0, 0, +51); + painter->fillRect(boundingRect(), color); + + color = pal.color(QPalette::Active, QPalette::Highlight); + QPen tPen = painter->pen(); + tPen.setColor(color); + painter->setPen(tPen); + painter->drawText((m_width - fm.width(str)) / 2, (m_height - fm.height()) / 2, + fm.width(str), fm.height(), 0, str); + } else if (m_hovered || (m_hovered && !isChecked())) { + color = pal.color(QPalette::Active, QPalette::Light); + color = DGuiApplicationHelper::adjustColor(color, 0, 0, 0, +2, +2, +2, +51); + painter->fillRect(boundingRect(), color); + painter->drawText((m_width - fm.width(str)) / 2, (m_height - fm.height()) / 2, + fm.width(str), fm.height(), 0, str); + } else { + if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) + color = QColor(235, 235, 235, 204); + else + color = QColor(30, 30, 30, 204); + painter->fillRect(boundingRect(), color); + painter->drawText((m_width - fm.width(str)) / 2, (m_height - fm.height()) / 2, + fm.width(str), fm.height(), 0, str); + } + + // draw line + pen.setColor(pal.color(QPalette::Inactive, QPalette::Shadow)); + painter->setPen(pen); + int y = static_cast(boundingRect().height()); + int x = static_cast(boundingRect().width()); + qDrawShadeLine(painter, QPoint(x, 0), QPoint(x, y), pal); + QPalette::ColorGroup cp = isChecked() || m_hovered ? QPalette::Active : QPalette::Inactive; + pen.setColor(pal.color(cp, QPalette::Foreground)); + painter->setPen(pen); +} + +void Tab::onFileRootUrlChanged(const DUrl &url) +{ + setCurrentUrl(url); +} + +void Tab::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + m_pressed = true; + m_originPos = pos(); + setZValue(3); +// m_isDragging = true; + } + QGraphicsObject::mousePressEvent(event); +} + +void Tab::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if (m_isDragging && !m_borderLeft) { + m_borderLeft = true; + update(); + } + + if (event->pos().y() < -m_height || event->pos().y() > m_height * 2) { + + if (!m_dragOutSide) { + m_dragOutSide = true; + update(); + emit aboutToNewWindow(this); + emit draggingFinished(); + m_dragObject = new QDrag(this); + QMimeData *mimeData = new QMimeData; + int radius = 20; + + const QPixmap &pixmap = toPixmap(true); + QImage image = Dtk::Widget::dropShadow(pixmap, radius, QColor(0, 0, 0, static_cast(0.2 * 255))); + QPainter pa(&image); + + pa.drawPixmap(radius, radius, pixmap); + + m_dragObject->setPixmap(QPixmap::fromImage(image)); + m_dragObject->setMimeData(mimeData); + m_dragObject->setHotSpot(QPoint(150 + radius, 12 + radius)); + m_dragObject->exec(); + m_dragObject->deleteLater(); + m_pressed = false; + + DFileManagerWindow::flagForNewWindowFromTab.store(true, std::memory_order_seq_cst); + emit requestNewWindow(currentUrl()); + } + } + + if (m_dragOutSide) { + QGraphicsObject::mouseMoveEvent(event); + return; + } + + if (pos().x() == 0 && pos().x() == scene()->width() - m_width) { + QGraphicsObject::mouseMoveEvent(event); + return; + } + setPos(x() + event->pos().x() - event->lastPos().x(), 0); + draggingStarted(); + m_isDragging = true; + if (pos().x() < 0) + setX(0); + else if (pos().x() > scene()->width() - m_width) + setX(scene()->width() - m_width); + + if (pos().x() > m_originPos.x() + m_width / 2) { + emit moveNext(this); + m_originPos.setX(m_originPos.x() + m_width); + } else if (pos().x() < m_originPos.x() - m_width / 2) { + emit movePrevius(this); + m_originPos.setX(m_originPos.x() - m_width); + } + + QGraphicsObject::mouseMoveEvent(event); +} + +void Tab::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if (m_dragOutSide) { + m_pressed = false; + setZValue(1); + QGraphicsObject::mouseReleaseEvent(event); + + m_dragOutSide = false; + m_isDragging = false; + return; + } + + emit clicked(); + m_pressed = false; + setZValue(1); + m_isDragging = false; + m_borderLeft = false; + update(); + emit draggingFinished(); + QGraphicsObject::mouseReleaseEvent(event); +} + +void Tab::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + m_hovered = true; + QGraphicsObject::hoverEnterEvent(event); +} + +void Tab::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + m_hovered = false; + m_pressed = false; + QGraphicsObject::hoverLeaveEvent(event); +} + +TabCloseButton::TabCloseButton(QGraphicsItem *parent): + QGraphicsObject(parent) +{ + setFlag(QGraphicsItem::ItemIsSelectable); + setAcceptHoverEvents(true); +} + +QRectF TabCloseButton::boundingRect() const +{ + return QRectF(0, 0, 24, 24); + +} + +void TabCloseButton::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + QIcon closeIcon = QIcon::fromTheme("window-close_round"); + + QIcon::Mode md = QIcon::Mode::Disabled; + if (m_mousePressed) { + md = QIcon::Mode::Selected; + } + if (m_mouseHovered) { + md = QIcon::Mode::Active; + } + + QRect rc = boundingRect().toRect(); + closeIcon.paint(painter, rc, Qt::AlignCenter, md); +} + +int TabCloseButton::closingIndex() +{ + return m_closingIndex; +} + +void TabCloseButton::setClosingIndex(int index) +{ + m_closingIndex = index; +} + +void TabCloseButton::setActiveWidthTab(bool active) +{ + m_activeWidthTab = active; + update(); +} + +void TabCloseButton::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); + + m_mousePressed = true; + if (m_mouseHovered) + m_mouseHovered = false; + update(); +} + +void TabCloseButton::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); + + m_mousePressed = false; + emit clicked(); + update(); +} + +void TabCloseButton::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +{ + event->ignore(); + if (!m_mouseHovered) + m_mouseHovered = true; + update(); +} + +void TabCloseButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + emit unHovered(closingIndex()); + event->ignore(); + m_mouseHovered = false; + update(); +} + +void TabCloseButton::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + event->ignore(); + m_mouseHovered = true; + emit hovered(closingIndex()); + update(); +} + +TabBar::TabBar(QWidget *parent): QGraphicsView(parent) +{ + setObjectName("TabBar"); + m_scene = new QGraphicsScene(this); + m_scene->setSceneRect(0, 0, width(), height()); + setContentsMargins(0, 0, 0, 0); + AC_SET_OBJECT_NAME( this, AC_VIEW_TAB_BAR); + AC_SET_ACCESSIBLE_NAME( this, AC_VIEW_TAB_BAR); + setScene(m_scene); + m_scene->installEventFilter(this); + + m_TabCloseButton = new TabCloseButton; + m_TabCloseButton->setZValue(4); + m_TabCloseButton->hide(); + m_scene->addItem(m_TabCloseButton); + + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + setMouseTracking(true); + setFrameShape(QFrame::NoFrame); + + initConnections(); + hide(); +} + +void TabBar::initConnections() +{ + QObject::connect(m_TabCloseButton, &TabCloseButton::hovered, this, &TabBar::onTabCloseButtonHovered); + QObject::connect(m_TabCloseButton, &TabCloseButton::unHovered, this, &TabBar::onTabCloseButtonUnHovered); + QObject::connect(m_TabCloseButton, &TabCloseButton::clicked, this, [ = ] { + int closingIndex = m_TabCloseButton->closingIndex(); + + //effect handler + if (closingIndex == count() - 1) + { + m_historyWidth = count() * m_tabs.at(0)->width(); + } else + { + m_historyWidth = (count() - 1) * m_tabs.at(0)->width(); + } + emit tabCloseRequested(closingIndex, true); + + //redirect tab close button's closingIndex + if (closingIndex >= count()) + m_TabCloseButton->setClosingIndex(--closingIndex); + }); +} + +int TabBar::createTab(DFMBaseView *view) +{ + Tab *tab = new Tab(nullptr, view); + m_tabs.append(tab); + m_scene->addItem(tab); + + if (isHidden() && count() >= 2) { + show(); + emit tabBarShown(); + } + + int index = count() - 1; + + QObject::connect(tab, &Tab::clicked, this, &TabBar::onTabClicked); + QObject::connect(tab, &Tab::moveNext, this, &TabBar::onMoveNext); + QObject::connect(tab, &Tab::movePrevius, this, &TabBar::onMovePrevius); + QObject::connect(tab, &Tab::requestNewWindow, this, &TabBar::onRequestNewWindow); + QObject::connect(tab, &Tab::aboutToNewWindow, this, &TabBar::onAboutToNewWindow); + QObject::connect(tab, &Tab::draggingFinished, this, &TabBar::onTabDragFinished); + QObject::connect(tab, &Tab::draggingStarted, this, &TabBar::onTabDragStarted); + QObject::connect(tab, &Tab::requestActiveNextTab, this, &TabBar::activateNextTab); + QObject::connect(tab, &Tab::requestActivePreviousTab, this, &TabBar::activatePreviousTab); + +// QObject::connect(tab, &Tab::draggingFinished, this, &TabBar::requestCacheRenameBarState);//###: forward the signal Tab::requestNewWindow; + + m_lastAddTabState = true; + setCurrentIndex(index); + m_lastAddTabState = false; + + tabAddableChanged(count() < TAB_MAX_COUNT); + + return index; +} + +void TabBar::removeTab(const int index, const bool &remainState) +{ + Tab *tab = m_tabs.at(index); + + m_tabs.removeAt(index); + tab->deleteLater(); + + if (m_TabCloseButton->closingIndex() <= count() - 1 && + m_TabCloseButton->closingIndex() >= 0) { + m_lastDeleteState = remainState; + } else { + m_lastAddTabState = false; + // handle tab close button display position + if (remainState) { + QMouseEvent *event = new QMouseEvent(QMouseEvent::MouseMove, + mapFromGlobal(QCursor::pos()), + Qt::NoButton, + Qt::NoButton, + Qt::NoModifier); + mouseMoveEvent(event); + } + } + + if (index < count()) + setCurrentIndex(index); + else + setCurrentIndex(count() - 1); + emit tabAddableChanged(count() < TAB_MAX_COUNT); + + if (count() < 2) { + m_lastDeleteState = false; + hide(); + emit tabBarHidden(); + } +} + +void TabBar::setCurrentIndex(const int index) +{ + if (index < 0 || index >= m_tabs.count()) + return; + + m_currentIndex = index; + + int counter = 0; + for (auto tab : m_tabs) { + if (counter == index) { + tab->setChecked(true); + } else { + tab->setChecked(false); + } + counter ++; + } + + emit currentChanged(index); + updateScreen(); +} + +void TabBar::setTabText(const int &index, const QString &text) +{ + if (index > 0 && index < count()) { + m_tabs.at(index)->setTabText(text); + } +} + +int TabBar::count() const +{ + return m_tabs.count(); +} + +int TabBar::currentIndex() const +{ + return m_currentIndex; +} + +bool TabBar::tabAddable() const +{ + return count() < TAB_MAX_COUNT; +} + +Tab *TabBar::currentTab() +{ + if (m_currentIndex >= 0 && m_currentIndex < count()) + return m_tabs.at(currentIndex()); + return nullptr; +} + +Tab *TabBar::tabAt(const int &index) +{ + if (index >= 0 && index < count()) + return m_tabs.at(index); + return nullptr; +} + +void TabBar::onMoveNext(Tab *who) +{ + if (m_tabs.indexOf(who) >= count() - 1) + return; + m_tabs.swap(m_tabs.indexOf(who), m_tabs.indexOf(who) + 1); + emit tabMoved(m_tabs.indexOf(who) - 1, m_tabs.indexOf(who)); + setCurrentIndex(m_tabs.indexOf(who)); +} + +void TabBar::onMovePrevius(Tab *who) +{ + if (m_tabs.indexOf(who) <= 0) + return; + m_tabs.swap(m_tabs.indexOf(who), m_tabs.indexOf(who) - 1); + emit tabMoved(m_tabs.indexOf(who) + 1, m_tabs.indexOf(who)); + setCurrentIndex(m_tabs.indexOf(who)); +} + +void TabBar::onRequestNewWindow(const DUrl url) +{ + appController->actionNewWindow(dMakeEventPointer(this, DUrlList() << url)); +} + +void TabBar::onAboutToNewWindow(Tab *who) +{ + emit tabCloseRequested(m_tabs.indexOf(who)); +} + +void TabBar::onTabClicked() +{ + Tab *tab = qobject_cast(sender()); + if (!tab) + return; + setCurrentIndex(m_tabs.indexOf(tab)); + m_TabCloseButton->setActiveWidthTab(true); +} + +void TabBar::onTabDragFinished() +{ + Tab *tab = qobject_cast(sender()); + if (!tab) + return; + m_TabCloseButton->setZValue(2); + if (tab->isDragOutSide()) + m_TabCloseButton->hide(); + m_lastDeleteState = false; + updateScreen(); + + //hide border left line + for (auto it : m_tabs) + if (it->borderLeft()) + it->setBorderLeft(false); +} + +void TabBar::onTabDragStarted() +{ + m_TabCloseButton->setZValue(0); + + Tab *tab = qobject_cast(sender()); + if (!tab) + return; + + int pairIndex = m_tabs.indexOf(tab) + 1; + int counter = 0; + for (auto it : m_tabs) { + if (counter == m_tabs.indexOf(tab) || counter == pairIndex) + it->setBorderLeft(true); + else + it->setBorderLeft(false); + counter ++; + } +} + +void TabBar::activateNextTab() +{ + if (m_currentIndex == count() - 1) + setCurrentIndex(0); + else + setCurrentIndex(currentIndex() + 1); + +} + +void TabBar::activatePreviousTab() +{ + if (m_currentIndex == 0) + setCurrentIndex(count() - 1); + else + setCurrentIndex(currentIndex() - 1); +} + +void TabBar::onCurrentUrlChanged(const DFMUrlBaseEvent &event) +{ + currentTab()->onFileRootUrlChanged(event.url()); +} + +void TabBar::onTabCloseButtonUnHovered(int closingIndex) +{ + if (closingIndex < 0 || closingIndex >= count()) + return; + Tab *tab = m_tabs.at(closingIndex); + tab->setHovered(false); + tab->update(); +} + +void TabBar::onTabCloseButtonHovered(int closingIndex) +{ + if (closingIndex < 0 || closingIndex >= count()) + return; + Tab *tab = m_tabs.at(closingIndex); + if (!tab) + return; + tab->setHovered(true); + tab->update(); +} +void TabBar::resizeEvent(QResizeEvent *event) +{ + m_scene->setSceneRect(0, 0, width(), height()); + m_historyWidth = width(); + updateScreen(); + QGraphicsView::resizeEvent(event); +} + +bool TabBar::event(QEvent *event) +{ + if (event->type() == event->Leave) { + m_TabCloseButton->hide(); + m_lastDeleteState = false; + m_historyWidth = width(); + updateScreen(); + } + return QGraphicsView::event(event); +} + +void TabBar::mouseMoveEvent(QMouseEvent *event) +{ + if (!m_TabCloseButton->isVisible()) + m_TabCloseButton->show(); + + int closingIndex = -1; + for (int i = 0; i < m_tabs.count(); i++) { + Tab *tab = m_tabs.at(i); + if (tab->sceneBoundingRect().contains(event->pos())) + closingIndex = i; + else { + tab->setHovered(false); + tab->update(); + } + } + + if (closingIndex < count() && closingIndex >= 0) { + Tab *tab = m_tabs.at(closingIndex); + m_TabCloseButton->setClosingIndex(closingIndex); + m_TabCloseButton->setPos(tab->x() + tab->width() - 30, 6); + + if (closingIndex == currentIndex()) + m_TabCloseButton->setActiveWidthTab(true); + else + m_TabCloseButton->setActiveWidthTab(false); + + } else { + if (m_lastDeleteState) { + m_lastDeleteState = false; + updateScreen(); + } + + } + + QGraphicsView::mouseMoveEvent(event); +} + +bool TabBar::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::GraphicsSceneMouseRelease) { + QGraphicsSceneMouseEvent *e = static_cast(event); + if (e->button() == Qt::MiddleButton) { + if (QGraphicsItem *item = itemAt(mapFromGlobal(QCursor::pos()))) { + Tab *t = static_cast(item); + if (m_tabs.contains(t)) { + qDebug() << m_tabs.indexOf(t); + emit tabCloseRequested(m_tabs.indexOf(t)); + } + } else { + qDebug("You didn't click on an item."); + } + } + } + return QGraphicsView::eventFilter(obj, event); +} + +void TabBar::wheelEvent(QWheelEvent *event) +{ + if (event->angleDelta().y() > 0) { + activateNextTab(); + } else { + activatePreviousTab(); + } + + QGraphicsView::wheelEvent(event); +} + + +QSize TabBar::tabSizeHint(const int &index) +{ + + if (m_lastDeleteState) + return QSize(m_tabs.at(0)->width(), m_tabs.at(0)->height()); + + int averageWidth = m_historyWidth / count(); + + if (index == count() - 1) + return (QSize(m_historyWidth - averageWidth * (count() - 1), 36)); + else + return (QSize(averageWidth, 36)); +} + +void TabBar::updateScreen() +{ + int counter = 0; + int lastX = 0; + for (Tab *tab : m_tabs) { + QRect rect(lastX, 0, tabSizeHint(counter).width(), tabSizeHint(counter).height()); + lastX = rect.x() + rect.width(); + if (tab->isDragging()) { + counter ++ ; + continue; + } + if (!m_lastAddTabState) { + QPropertyAnimation *animation = new QPropertyAnimation(tab, "geometry"); + animation->setDuration(100); + animation->setStartValue(tab->geometry()); + animation->setEndValue(rect); + animation->start(QAbstractAnimation::DeleteWhenStopped); + + connect(animation, &QPropertyAnimation::finished, tab, [ = ] { + if (m_TabCloseButton->closingIndex() == counter) + { + m_TabCloseButton->setPos(tab->x() + tab->width() - 30, 6); + } + if ((m_TabCloseButton->closingIndex() >= count() || m_TabCloseButton->closingIndex() < 0) && m_lastDeleteState) + { + m_lastDeleteState = false; + } + }); + } else { + tab->setGeometry(rect); + } + + counter++; + } + + updateSceneRect(m_scene->sceneRect()); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtabbar.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtabbar.h new file mode 100644 index 0000000..1b94077 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtabbar.h @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DTABBAR_H +#define DTABBAR_H + +#include "singleton.h" +#include "durl.h" +#include +#include "singleton.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dfileview.h" +#include "dfmevent.h" + +#define TAB_CLOSE_BUTTON_WIDTH 18 +#define TAB_CLOSE_BUTTON_HEIGHT 24 +#define TAB_MAX_COUNT 8 + +class Tab: public QGraphicsObject +{ + Q_OBJECT + Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry) + +public: + explicit Tab(QGraphicsObject *parent = nullptr, DFMBaseView *view = nullptr); + ~Tab() override; + void initConnect(); + void setTabText(QString text); + QString tabText(); + DFMBaseView *fileView(); + void setFileView(DFMBaseView *view); + DUrl currentUrl() const; + void setCurrentUrl(const DUrl &url); + + void setFixedSize(QSize size); + void setGeometry(QRect rect); + QRect geometry(); + int width(); + int height(); + bool isDragging(); + void setHovered(bool hovered); + bool isDragOutSide(); + QPixmap toPixmap(bool drawBorder = true); + bool isChecked() const; + void setChecked(const bool check); + bool borderLeft() const; + void setBorderLeft(const bool flag); + QString getDisplayNameByUrl(const DUrl &url) const; + + QRectF boundingRect() const override; + QPainterPath shape() const override; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; + +public slots: + void onFileRootUrlChanged(const DUrl &url); + +protected: + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; + void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; + void mousePressEvent(QGraphicsSceneMouseEvent *event) override; + + void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override; +signals: + void clicked(); + void moveNext(Tab *who); + void movePrevius(Tab *who); + void requestNewWindow(const DUrl url); + void aboutToNewWindow(Tab *who); + void draggingFinished(); + void draggingStarted(); + void requestActiveNextTab(); + void requestActivePreviousTab(); + +private: + int m_tabIndex; + QVariant m_tabData; + QString m_tabText; + + bool m_hovered{ false }; + bool m_pressed{ false }; + int m_width{ 0 }; + int m_height{ 0 }; + bool m_isDragging{ false }; + QPointF m_originPos; + bool m_dragOutSide{ false }; + QDrag *m_dragObject{ nullptr }; + bool m_checked{ false }; + bool m_borderLeft{ false }; + DFMBaseView *m_fileView{ nullptr }; + DUrl m_url{}; +}; + +class TabCloseButton: public QGraphicsObject +{ + Q_OBJECT +public: + explicit TabCloseButton(QGraphicsItem *parent = 0); + QRectF boundingRect() const override; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override; + int closingIndex(); + void setClosingIndex(int index); + void setActiveWidthTab(bool active); +signals: + void clicked(); + void hovered(int index); + void unHovered(int index); + +protected: + void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override; + void mousePressEvent(QGraphicsSceneMouseEvent *event) override; + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; + void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override; + +private: + bool m_mouseHovered{ false }; + bool m_mousePressed{ false }; + int m_closingIndex{ 0 }; + bool m_activeWidthTab{ false }; + QIcon m_active_normalIcon; + QIcon m_active_hoverIcon; + QIcon m_active_pressIcon; + QIcon m_normalIcon; + QIcon m_hoverIcon; + QIcon m_pressIcon; +}; + +class TabBar: public QGraphicsView +{ + + Q_OBJECT +public: + explicit TabBar(QWidget *parent = 0); + void initConnections(); + int createTab(DFMBaseView *view); + void removeTab(const int index, const bool &remainState = false); + void setTabText(const int &index, const QString &text); + int count() const; + int currentIndex() const; + bool tabAddable() const; + Tab *currentTab(); + Tab *tabAt(const int &index); + +signals: + void currentChanged(const int &index); + void tabCloseRequested(const int &index, const bool &remainState = false); + void tabAddableChanged(const bool &tabAddable); + void tabMoved(const int &from, const int &to); + void tabBarShown(); + void tabBarHidden(); + void requestNewWindow(const DUrl &url);//###: this signal will connect to Tab::requestNewWindow; + +// void requestCacheRenameBarState(); + +public slots: + void setCurrentIndex(const int index); + void onTabCloseButtonHovered(int closingIndex); + void onTabCloseButtonUnHovered(int closingIndex); + void onMoveNext(Tab *who); + void onMovePrevius(Tab *who); + void onRequestNewWindow(const DUrl url); + void onAboutToNewWindow(Tab *who); + void onTabClicked(); + void onTabDragFinished(); + void onTabDragStarted(); + void activateNextTab(); + void activatePreviousTab(); + void onCurrentUrlChanged(const DFMUrlBaseEvent &event); + +protected: + void resizeEvent(QResizeEvent *event) override; + bool event(QEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; + void wheelEvent(QWheelEvent *event) override; +private: + QGraphicsScene *m_scene{ nullptr }; + int m_currentIndex{ -1 }; + QList m_tabs{}; + bool m_barHovered{ false }; + bool m_lastStateOndelete{ false }; + int m_lastDeletedAverageWidth{ 0 }; + QPoint m_tabLastMouseDragPos{}; + bool m_tabDragging{ false }; + TabCloseButton *m_TabCloseButton{ nullptr }; + int m_trackingIndex{ 0 }; + bool m_lastDeleteState{ false }; + bool m_lastAddTabState{ false }; + int m_historyWidth{ 0 }; + + QSize tabSizeHint(const int &index); + void updateScreen(); +}; + + + + +#endif // DTABBAR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtagactionwidget.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtagactionwidget.cpp new file mode 100644 index 0000000..ca22730 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtagactionwidget.cpp @@ -0,0 +1,223 @@ + +#include + +#include "dfileview.h" +#include "darrowrectangle.h" +#include "dtagactionwidget.h" +#include "views/droundbutton.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class DTagActionWidgetPrivate +{ +public: + explicit DTagActionWidgetPrivate(DTagActionWidget *const qPtr); + + + void setParameters()noexcept; + void initUiElement(); + + + std::array m_roundButtons{ {nullptr} }; + QVBoxLayout *mainLayout{ nullptr }; + QHBoxLayout *m_HBoxLayout{ nullptr }; + DTagActionWidget *q_ptr{ nullptr }; + QStringList checkedColorList; + QLabel *toolTip{ nullptr }; + bool exclusive = false; +}; + + + +DTagActionWidgetPrivate::DTagActionWidgetPrivate(DTagActionWidget *const qPtr) + : q_ptr{ qPtr } +{ + this->initUiElement(); +} + +void DTagActionWidgetPrivate::setParameters()noexcept +{ + q_ptr->setFocusPolicy(Qt::StrongFocus); +} + +void DTagActionWidgetPrivate::initUiElement() +{ + m_roundButtons[0] = new DRoundButton{ + { QColor{"#ff9311"}, QColor{"#ffa503"} }, + { QColor{"#d8d8d8"}, QColor{"#cecece"} } + }; + + m_roundButtons[1] = new DRoundButton{ + { QColor{"#ec1640"}, QColor{"#ff1c49"} }, + { QColor{"#d8d8d8"}, QColor{"#cecece"} } + }; + + m_roundButtons[2] = new DRoundButton{ + { QColor{"#8e08de"}, QColor{"#9023fc"} }, + { QColor{"#d8d8d8"}, QColor{"#cecece"} } + }; + + m_roundButtons[3] = new DRoundButton{ + { QColor{"#0956e7"}, QColor{"#3468ff"} }, + { QColor{"#d8d8d8"}, QColor{"#cecece"} } + }; + + m_roundButtons[4] = new DRoundButton{ + { QColor{"#00c7e1"}, QColor{"#00b5ff"} }, + { QColor{"#d8d8d8"}, QColor{"#cecece"} } + }; + + m_roundButtons[5] = new DRoundButton{ + { QColor{"#60cb00"}, QColor{"#58df0a"} }, + { QColor{"#d8d8d8"}, QColor{"#cecece"} } + }; + + m_roundButtons[6] = new DRoundButton{ + { QColor{"#f4e710"}, QColor{"#fef144"} }, + { QColor{"#d8d8d8"}, QColor{"#cecece"} } + }; + + m_roundButtons[7] = new DRoundButton{ + { QColor{"#ababab"}, QColor{"#cccccc"} }, + { QColor{"#d8d8d8"}, QColor{"#cecece"} } + }; + + + m_HBoxLayout = new QHBoxLayout; + + m_HBoxLayout->addSpacing(21); + for (std::size_t index = 0; index != 8; ++index) { + m_roundButtons[index]->setContentsMargins(0, 0, 0, 0); + m_roundButtons[index]->setRadius(20); + + QString objMark = QString("Color%1").arg(index + 1); + m_roundButtons[index]->setObjectName(objMark); + AC_SET_ACCESSIBLE_NAME( m_roundButtons[index], objMark); + + m_HBoxLayout->addWidget(m_roundButtons[index], Qt::AlignCenter); + } + + m_HBoxLayout->addSpacing(21); + m_HBoxLayout->setMargin(0); + m_HBoxLayout->setSpacing(0); + + mainLayout = new QVBoxLayout(); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + mainLayout->addLayout(m_HBoxLayout); + + toolTip = new QLabel(); + toolTip->setText(QStringLiteral(" ")); + toolTip->setStyleSheet("color: #707070; font-size: 10px"); + toolTip->setObjectName("tool_tip"); + AC_SET_ACCESSIBLE_NAME( toolTip, AC_TAG_ACTION_WIDGET_TOOL_TIP); + + mainLayout->addWidget(toolTip, 0, Qt::AlignHCenter); +} + + + +DTagActionWidget::DTagActionWidget(QWidget *const parent) + : QFrame{ parent }, + d_ptr{ new DTagActionWidgetPrivate{ this } } +{ + this->setObjectName("tagActionWidget"); + AC_SET_ACCESSIBLE_NAME( this, AC_TAG_ACTION_WIDGET); + this->setCentralLayout(); + this->initConnect(); +} + +QList DTagActionWidget::checkedColorList() const +{ + Q_D(const DTagActionWidget); + + QList list; + + for (const DRoundButton *button : d->m_roundButtons) { + if (button->isChecked()) + list << button->color(); + } + + return list; +} + +void DTagActionWidget::setCheckedColorList(const QList &colorNames) +{ + Q_D(DTagActionWidget); + + for (DRoundButton *button : d->m_roundButtons) { + button->setChecked(colorNames.contains(button->color())); + } +} + +bool DTagActionWidget::exclusive() const +{ + Q_D(const DTagActionWidget); + + return d->exclusive; +} + +void DTagActionWidget::setExclusive(bool exclusive) +{ + Q_D(DTagActionWidget); + + d->exclusive = exclusive; +} + +void DTagActionWidget::setToolTipVisible(bool visible) +{ + Q_D(DTagActionWidget); + + d->toolTip->setVisible(visible); +} + +void DTagActionWidget::setToolTipText(const QString &text) +{ + Q_D(DTagActionWidget); + + d->toolTip->setText(text); +} + +void DTagActionWidget::clearToolTipText() +{ + setToolTipText(QStringLiteral(" ")); +} + +void DTagActionWidget::setCentralLayout()noexcept +{ + DTagActionWidgetPrivate *const d{ d_func() }; + this->setLayout(d->mainLayout); +} + +void DTagActionWidget::initConnect() +{ + Q_D(const DTagActionWidget); + + for (DRoundButton *button : d->m_roundButtons) { + connect(button, &DRoundButton::enter, this, [this, button] { + emit hoverColorChanged(button->color()); + }); + connect(button, &DRoundButton::leave, this, [this] { + emit hoverColorChanged(QColor()); + }); + connect(button, &DRoundButton::checkedChanged, this, [this, button, d] { + if (button->isChecked() && exclusive()) + { + for (DRoundButton *b : d->m_roundButtons) { + if (b != button) + b->setChecked(false); + } + } + }); + connect(button, &DRoundButton::click, this, [this](QColor color) { + emit checkedColorChanged(color); + }); + + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtagactionwidget.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtagactionwidget.h new file mode 100644 index 0000000..3b68428 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtagactionwidget.h @@ -0,0 +1,49 @@ +#ifndef DTAGACTIONWIDGET_H +#define DTAGACTIONWIDGET_H + + +#include +#include +#include +#include +#include + + +class DTagActionWidgetPrivate; +class DTagActionWidget final : public QFrame +{ + Q_OBJECT + + Q_PROPERTY(QList checkedColorList READ checkedColorList WRITE setCheckedColorList) + Q_PROPERTY(bool exclusive READ exclusive WRITE setExclusive) + +public: + explicit DTagActionWidget(QWidget* const parent = nullptr); + virtual ~DTagActionWidget()=default; + + DTagActionWidget(const DTagActionWidget& other)=delete; + DTagActionWidget& operator=(const DTagActionWidget &other)=delete; + + QList checkedColorList() const; + void setCheckedColorList(const QList &colorNames); + + bool exclusive() const; + void setExclusive(bool exclusive); + + void setToolTipVisible(bool visible); + void setToolTipText(const QString &text); + void clearToolTipText(); + +signals: + void hoverColorChanged(const QColor &color); + void checkedColorChanged(const QColor &color); + +private: + void setCentralLayout()noexcept; + void initConnect(); + + QSharedPointer d_ptr{ nullptr }; + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), DTagActionWidget) +}; + +#endif // DTAGACTIONWIDGET_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtagedit.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtagedit.cpp new file mode 100644 index 0000000..c428ef4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtagedit.cpp @@ -0,0 +1,153 @@ + +#include "dtagedit.h" +#include "../app/define.h" +#include "../tag/tagmanager.h" +#include "../utils/singleton.h" +#include "../app/filesignalmanager.h" +#include "../controllers/appcontroller.h" +#include "../interfaces/dfmeventdispatcher.h" + +#include "dfileservices.h" + +#include +#include +#include + +DTagEdit::DTagEdit(QWidget *const parent) + : DArrowRectangle{ DArrowRectangle::ArrowTop, parent } +{ + this->initializeWidgets(); + this->initializeParameters(); + this->initializeLayout(); + this->initializeConnect(); + + this->installEventFilter(this); + + // wayland协议下,使用Qt::Tool仍然附带窗口边框,此时采用Qt::FramelessWindowHint消除边框 + if (DFMGlobal::isWayLand()) + setWindowFlags(windowFlags() | Qt::Popup | Qt::FramelessWindowHint); + else + setWindowFlags(Qt::Tool); +} + +void DTagEdit::setFocusOutSelfClosing(bool value)noexcept +{ + ///###: CAS! + bool excepted{ !value }; + m_flagForShown.compare_exchange_strong(excepted, value, std::memory_order_release); +} + +void DTagEdit::setFilesForTagging(const QList &files) +{ + m_files = files; +} + +void DTagEdit::setDefaultCrumbs(const QStringList &list) +{ + m_isSettingDefault = true; + + for (const QString &crumb : list) + m_crumbEdit->appendCrumb(crumb); + + m_isSettingDefault = false; +} + +void DTagEdit::onFocusOut() +{ + if (m_flagForShown.load(std::memory_order_acquire)) { + this->processTags(); + this->close(); + } +} + +void DTagEdit::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Escape: { + this->processTags(); + event->accept(); + this->close(); + break; + } + case Qt::Key_Enter: + case Qt::Key_Return: { + QObject::disconnect(this, &DTagEdit::windowDeactivate, this, &DTagEdit::onFocusOut); + this->processTags(); + event->accept(); + this->close(); + break; + } + default: + break; + } + + DArrowRectangle::keyPressEvent(event); +} + +void DTagEdit::mouseMoveEvent(QMouseEvent *event) +{ + Q_UNUSED(event); +} + +void DTagEdit::initializeWidgets() +{ + m_crumbEdit = new DCrumbEdit; + m_promptLabel = new QLabel{ + QObject::tr("Input tag info, such as work, family. A comma is used between two tags.") + }; + m_totalLayout = new QVBoxLayout; + m_BGFrame = new QFrame; +} + +void DTagEdit::initializeParameters() +{ + m_crumbEdit->setFixedSize(140, 40); + m_crumbEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_crumbEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_crumbEdit->setCrumbReadOnly(true); + m_crumbEdit->setCrumbRadius(2); + + m_promptLabel->setFixedWidth(140); + m_promptLabel->setWordWrap(true); + m_BGFrame->setContentsMargins(QMargins{0, 0, 0, 0}); + + this->setMargin(0); + this->setFixedWidth(140); + this->setFocusPolicy(Qt::StrongFocus); + this->setBorderColor(QColor{"#ffffff"}); + this->setBackgroundColor(QColor{"#ffffff"}); + this->setWindowFlags(Qt::FramelessWindowHint); +} + +void DTagEdit::initializeLayout() +{ + m_totalLayout->addStretch(1); + m_totalLayout->addWidget(m_crumbEdit); + m_totalLayout->addSpacing(8); + m_totalLayout->addWidget(m_promptLabel); + m_totalLayout->addStretch(1); + + m_BGFrame->setLayout(m_totalLayout); + this->setContent(m_BGFrame); +} + +void DTagEdit::initializeConnect() +{ + QObject::connect(this, &DTagEdit::windowDeactivate, this, &DTagEdit::onFocusOut); + + QObject::connect(m_crumbEdit, &DCrumbEdit::crumbListChanged, this, [=]{ + //初始化设置默认tag值的时候不需要执行tag变更逻辑 + if (!m_isSettingDefault) { + processTags(); + } + }); +} + +void DTagEdit::processTags() +{ + QList tagList{ m_crumbEdit->crumbList() }; + //防止DTagEdit对象被析构后m_files无法访问 + QList files = m_files; + + DFileService::instance()->onTagEditorChanged(tagList, files); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtagedit.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtagedit.h new file mode 100644 index 0000000..159d56a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtagedit.h @@ -0,0 +1,68 @@ +#ifndef DTAGEDIT_H +#define DTAGEDIT_H + +#include + +#include "durl.h" +#include "dcrumbedit.h" +#include "darrowrectangle.h" + + +#include +#include +#include +#include +#include +#include +#include + +using namespace Dtk::Widget; + + +class DTagEdit final : public DArrowRectangle +{ + Q_OBJECT + +public: + explicit DTagEdit(QWidget *const parent = nullptr); + virtual ~DTagEdit() override = default; + DTagEdit(const DTagEdit &other) = delete; + DTagEdit &operator=(const DTagEdit &other) = delete; + + void setFocusOutSelfClosing(bool value) noexcept; + void setFilesForTagging(const QList &files); + void setDefaultCrumbs(const QStringList &list); + +public slots: + void onFocusOut(); + +protected: + void keyPressEvent(QKeyEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + +private: + void initializeWidgets(); + void initializeParameters(); + void initializeLayout(); + void initializeConnect(); + + void processTags(); + + void onPressESC() noexcept; + + DCrumbEdit *m_crumbEdit{ nullptr }; + QLabel *m_promptLabel{ nullptr }; + QVBoxLayout *m_totalLayout{ nullptr }; + QFrame *m_BGFrame{ nullptr }; + + QList m_files{}; + + std::atomic m_flagForShown{ false }; + + bool m_isSettingDefault = false; + QTimer m_waitForMoreCrumbChanged; //用于等待短时间内的多次CrumbChanged +}; + + + +#endif // DTAGEDIT_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtoolbar.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtoolbar.cpp new file mode 100644 index 0000000..9792959 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtoolbar.cpp @@ -0,0 +1,556 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "dtoolbar.h" +#include "dfmcrumbbar.h" +#include "historystack.h" +#include "historystack.h" +#include "windowmanager.h" +#include "dfileservices.h" +#include "dfmeventdispatcher.h" +#include "dfmaddressbar.h" + +#include "dfmevent.h" +#include "app/define.h" +#include "app/filesignalmanager.h" + +#include "dfilemenumanager.h" + +#include "singleton.h" +#include "views/dfileview.h" +#include "views/dfilemanagerwindow.h" +#include "views/dfmactionbutton.h" +#include "models/networkfileinfo.h" +#include "gvfs/gvfsmountmanager.h" +#include "accessibility/ac-lib-file-manager.h" + +#include + +#include +#include +#include +#include +#include +#include + +const int DToolBar::ButtonWidth = 36; +const int DToolBar::ButtonHeight = 36; +static const QSize iconSize(16, 16); + +/*! + * \class DToolBar + * + * \brief DToolBar is the toolbar (topbar) of the file manager + * + * This widget is the container of the navigation arrows, switching view buttons, menu button, + * search button and the crumb bar (and also the address bar). + * + * \sa DFMCrumbBar, DFMAddressBar + */ + +DToolBar::DToolBar(QWidget *parent) : QFrame(parent) +{ + AC_SET_OBJECT_NAME( this, AC_COMPUTER_TITLE_BAR); + AC_SET_ACCESSIBLE_NAME( this, AC_COMPUTER_TITLE_BAR); + + initData(); + initUI(); + initConnect(); +} + +DToolBar::~DToolBar() +{ +// delete m_navStack; +} + +void DToolBar::initData() +{ +// m_navStack = new HistoryStack(65536); +} + +void DToolBar::initUI() +{ + setFocusPolicy(Qt::NoFocus); + initAddressToolBar(); + initContollerToolBar(); + + m_detailButton = new QToolButton(this); + m_detailButton->setFixedWidth(ButtonWidth); + m_detailButton->setFixedHeight(ButtonHeight); + m_detailButton->setObjectName("detailButton"); + AC_SET_ACCESSIBLE_NAME( m_detailButton, AC_COMPUTER_TITLE_BAR_DETAIL_BTN); + m_detailButton->setCheckable(true); + m_detailButton->setFocusPolicy(Qt::NoFocus); + m_detailButton->setIcon(QIcon::fromTheme("dfm_rightview_detail")); + m_detailButton->setIconSize(iconSize); + m_detailButton->setFixedSize(36, 36); + + QHBoxLayout *mainLayout = new QHBoxLayout; + mainLayout->addWidget(m_addressToolBar); + // mainLayout->addSpacing(22); + mainLayout->addWidget(m_contollerToolBar); + + // mainLayout->addSpacing(22); + mainLayout->addWidget(m_detailButton); + + mainLayout->addSpacing(0); + mainLayout->setContentsMargins(14, 0, 4, 0); + setLayout(mainLayout); +} + +void DToolBar::initAddressToolBar() +{ + m_addressToolBar = new QFrame; + m_addressToolBar->setObjectName("AddressToolBar"); + AC_SET_OBJECT_NAME( m_addressToolBar, AC_COMPUTER_TITLE_BAR_ADRESS); + //m_addressToolBar->setFixedHeight(40); + + QHBoxLayout *backForwardLayout = new QHBoxLayout; + + m_backButton = new DButtonBoxButton(QStyle::SP_ArrowBack); + AC_SET_OBJECT_NAME( m_backButton, AC_COMPUTER_TITLE_BAR_BACK_BTN); + AC_SET_ACCESSIBLE_NAME( m_backButton, AC_COMPUTER_TITLE_BAR_BACK_BTN); + m_backButton->setDisabled(true); + m_backButton->setFixedWidth(36); + + m_forwardButton = new DButtonBoxButton(QStyle::SP_ArrowForward); + AC_SET_OBJECT_NAME( m_forwardButton, AC_COMPUTER_TITLE_BAR_FORWARD_BTN); + AC_SET_ACCESSIBLE_NAME( m_forwardButton, AC_COMPUTER_TITLE_BAR_FORWARD_BTN); + m_forwardButton->setDisabled(true); + m_forwardButton->setFixedWidth(36); + + QList buttonList; + buttonList << m_backButton << m_forwardButton; + + DButtonBox *buttonBox = new DButtonBox(this); + AC_SET_OBJECT_NAME( buttonBox, AC_COMPUTER_TITLE_BAR_BTN_BOX); + AC_SET_ACCESSIBLE_NAME( buttonBox, AC_COMPUTER_TITLE_BAR_BTN_BOX); + buttonBox->setButtonList(buttonList, false); + buttonBox->setFocusPolicy(Qt::NoFocus); + + m_searchButton = new QPushButton(this); + m_searchButton->setObjectName("searchButton"); + AC_SET_ACCESSIBLE_NAME( m_searchButton, AC_COMPUTER_TITLE_BAR_SERACH_BTN); + m_searchButton->setFixedSize(ButtonWidth, ButtonHeight); + m_searchButton->setFocusPolicy(Qt::NoFocus); + m_searchButton->setFlat(true); + m_searchButton->setIcon(QIcon::fromTheme("search")); + m_searchButton->setIconSize(iconSize); + + + backForwardLayout->addWidget(buttonBox); + backForwardLayout->setSpacing(0); + backForwardLayout->setContentsMargins(0, 0, 0, 0); + + + QFrame *crumbAndSearch = new QFrame; + m_crumbWidget = new DFMCrumbBar(this); + crumbAndSearch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + AC_SET_OBJECT_NAME( crumbAndSearch, AC_COMPUTER_TITLE_BAR_CRUMB_SERACH_FRAME); + AC_SET_ACCESSIBLE_NAME( crumbAndSearch, AC_COMPUTER_TITLE_BAR_CRUMB_SERACH_FRAME); + + QHBoxLayout *comboLayout = new QHBoxLayout; + comboLayout->addWidget(m_crumbWidget); + comboLayout->addWidget(m_searchButton); + // comboLayout->setSpacing(10); + comboLayout->setContentsMargins(0, 0, 0, 0); + + + crumbAndSearch->setLayout(comboLayout); + + QHBoxLayout *mainLayout = new QHBoxLayout; + mainLayout->addLayout(backForwardLayout); + mainLayout->addWidget(crumbAndSearch); + mainLayout->setContentsMargins(0, 0, 0, 0); + // mainLayout->setSpacing(10); + m_addressToolBar->setLayout(mainLayout); + +} + +void DToolBar::initContollerToolBar() +{ + m_contollerToolBar = new QFrame; + m_contollerToolBar->setObjectName("ContollerToolBar"); + AC_SET_ACCESSIBLE_NAME( m_contollerToolBar, AC_COMPUTER_TITLE_BAR_CONTOLLER_TOOL_BAR); + m_contollerToolBar->setFrameShape(QFrame::NoFrame); + m_contollerToolBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_contollerToolBarContentLayout = new QHBoxLayout(m_contollerToolBar); + m_contollerToolBarContentLayout->setContentsMargins(14, 1, 14, 1); + m_contollerToolBarContentLayout->setSpacing(20); +} + +void DToolBar::initConnect() +{ + connect(m_detailButton, &QAbstractButton::clicked, this, &DToolBar::detailButtonClicked); + connect(m_backButton, &DButtonBoxButton::clicked, this, &DToolBar::onBackButtonClicked); + connect(m_forwardButton, &DButtonBoxButton::clicked, this, &DToolBar::onForwardButtonClicked); + connect(m_crumbWidget, &DFMCrumbBar::addressBarContentEntered, this, &DToolBar::searchBarTextEntered); + connect(m_crumbWidget, &DFMCrumbBar::crumbListItemSelected, this, [this](const DUrl & url) { + //判断网络文件是否可以到达 + if (DFileService::instance()->checkGvfsMountfileBusy(url)) { + return; + } + DFMEventDispatcher::instance()->processEvent(m_crumbWidget, url, window()); + }); + connect(m_crumbWidget, &DFMCrumbBar::addressBarShown, this, &DToolBar::searchBarActivated); + connect(m_crumbWidget, &DFMCrumbBar::addressBarHidden, this, &DToolBar::searchBarDeactivated); + connect(m_searchButton, &QPushButton::clicked, this, &DToolBar::onSearchButtonClicked); + connect(fileSignalManager, &FileSignalManager::requestSearchCtrlF, this, &DToolBar::handleHotkeyCtrlF); + connect(fileSignalManager, &FileSignalManager::requestSearchCtrlL, this, &DToolBar::handleHotkeyCtrlL); + connect(this, &DToolBar::toolbarUrlChanged, m_crumbWidget, &DFMCrumbBar::updateCurrentUrl); + connect(gvfsMountManager, &GvfsMountManager::mount_removed, this, [this](const QDiskInfo& diskInfo) { + Q_UNUSED(diskInfo) + this->updateBackForwardButtonsState(); + }); + + DFileManagerWindow *window = qobject_cast(parent()); + + if (window) { + connect(window, &DFileManagerWindow::currentViewStateChanged, this, [this, window] { + // fix bug 87535 搜索栏只有搜索状态才显示加载动画 + if (window->currentUrl().isSearchFile()) { + if (window->currentViewState() == DFMBaseView::ViewBusy) + m_crumbWidget->playAddressBarAnimation(); + else + m_crumbWidget->stopAddressBarAnimation(); + } + }); + } +} + +DFMCrumbBar *DToolBar::getCrumbWidget() +{ + return m_crumbWidget; +} + +void DToolBar::searchBarActivated() +{ + toggleSearchButtonState(true); +} + +void DToolBar::searchBarDeactivated() +{ + toggleSearchButtonState(false); +} + +/** + * \brief DToolBar::searchBarTextEntered + * + * Set the tab bar when return press is detected + * on search bar. + */ +void DToolBar::searchBarTextEntered(const QString textEntered) +{ + QString text = textEntered; + + if (text.isEmpty()) { + //m_searchBar->clearText(); + return; + } + + const QString ¤tDir = QDir::currentPath(); + DUrl currentUrl; + if (auto fmWindow = qobject_cast(topLevelWidget())) + currentUrl = fmWindow->currentUrl(); + else + qCritical() << "DFileManagerWindow is null"; + //判断网络文件是否可以到达 + if (DFileService::instance()->checkGvfsMountfileBusy(currentUrl, true)) + return; + + if (currentUrl.isLocalFile()) { + QDir::setCurrent(currentUrl.toLocalFile()); + } + + setEnterText(text); + + DUrl inputUrl = DUrl::fromUserInput(text, false); ///###: here, judge whether the text is a local file path. + + QDir::setCurrent(currentDir); + + //fix bug 32652 当连接了同一台机器的smb共享时,就缓存了它,第二次再去连接smb访问时,使用了缓存 + NetworkManager::NetworkNodes.remove(inputUrl); + + DFMEventDispatcher::instance()->processEvent(this, inputUrl, window()); +} + +void DToolBar::onSearchButtonClicked() +{ + if (!m_searchButtonAsbState) { + m_crumbWidget->showAddressBar(""); + } else { + // toggle asb visible + if (DFileManagerWindow *dfmWindow = qobject_cast(window())) { + bool oldState = dfmWindow->isAdvanceSearchBarVisible(); + dfmWindow->toggleAdvanceSearchBar(!oldState); + m_searchButton->setDown(!oldState); + } + else { + qCritical() << "DFileManagerWindow is null"; + } + } +} + +void DToolBar::currentUrlChanged(const DFMEvent &event) +{ + if (event.windowId() != WindowManager::getWindowId(this)) { + return; + } + + if (event.sender() == m_crumbWidget) { + pushUrlToHistoryStack(event.fileUrl()); + return; + } + + emit toolbarUrlChanged(event.fileUrl()); + + if (event.sender() == this) { + return; + } + + pushUrlToHistoryStack(event.fileUrl()); +} + +void DToolBar::back() +{ + DUrl url = m_navStack->back(); + //判断网络文件是否可以到达 + if (DFileService::instance()->checkGvfsMountfileBusy(url)) { + return; + } + if (!url.isEmpty()) { + updateBackForwardButtonsState(); + DFMEventDispatcher::instance()->processEvent(this, url, window()); + } +} + +void DToolBar::forward() +{ + DUrl url = m_navStack->forward(); + //判断网络文件是否可以到达 + if (DFileService::instance()->checkGvfsMountfileBusy(url)) { + return; + } + if (!url.isEmpty()) { + updateBackForwardButtonsState(); + DFMEventDispatcher::instance()->processEvent(this, url, window()); + } +} + +void DToolBar::handleHotkeyCtrlF(quint64 winId) +{ + // fix bug 65436 + // 仅当搜索/过滤按钮可见时才响应Ctrl+F + if (winId == WindowManager::getWindowId(this) && m_searchButton->isVisible()) { + onSearchButtonClicked(); + } +} + +void DToolBar::handleHotkeyCtrlL(quint64 winId) +{ + if (winId == WindowManager::getWindowId(this)) { + m_crumbWidget->showAddressBar(qobject_cast(topLevelWidget())->currentUrl()); + } +} + +void DToolBar::pushUrlToHistoryStack(DUrl url) +{ + if (!m_navStack) { + return; + } + + m_navStack->append(url); + updateBackForwardButtonsState(); +} + +void DToolBar::addHistoryStack() +{ + m_navStacks.append(std::shared_ptr(new HistoryStack(65536))); +} + +void DToolBar::switchHistoryStack(const int index) +{ + m_navStack = m_navStacks.at(index); + if (!m_navStack) + return; + updateBackForwardButtonsState(); +} + +/*! + * \brief Switch Search Button State + * + * \param asb Make search button control Advance Search Bar + */ +void DToolBar::toggleSearchButtonState(bool asb) +{ + if (asb) { + m_searchButton->setHidden(true); + m_searchButton->setObjectName("filterButton"); + m_searchButton->setIcon(QIcon::fromTheme("dfm_view_filter")); + m_searchButton->style()->unpolish(m_searchButton); + m_searchButton->style()->polish(m_searchButton); + m_searchButton->setFlat(true); + m_searchButtonAsbState = true; + } else { + m_searchButton->setHidden(false); + m_searchButton->style()->unpolish(m_searchButton); + m_searchButton->style()->polish(m_searchButton); + m_searchButton->setIcon(QIcon::fromTheme("search")); + m_searchButton->setDown(false); + m_searchButtonAsbState = false; + if (DFileManagerWindow *dfmWindow = qobject_cast(window())) { + dfmWindow->toggleAdvanceSearchBar(false); + } + else { + qCritical() << "window() is null or faile to cast to DFileManagerWindow."; + } + } +} + +void DToolBar::removeNavStackAt(int index) +{ + m_navStacks.removeAt(index); + + if (index < m_navStacks.count()) + m_navStack = m_navStacks.at(index); + else + m_navStack = m_navStacks.at(m_navStacks.count() - 1); + + if (!m_navStack) + return; + if (m_navStack->size() > 1) + m_backButton->setEnabled(true); + else + m_backButton->setEnabled(false); + + if (m_navStack->isLast()) + m_forwardButton->setEnabled(false); + else + m_forwardButton->setEnabled(true); +} + +void DToolBar::moveNavStacks(int from, int to) +{ + m_navStacks.move(from, to); +} + +int DToolBar::navStackCount() const +{ + return m_navStacks.count(); +} + +void DToolBar::updateBackForwardButtonsState() +{ + if (!m_navStack || m_navStack->size() <= 1) { + m_backButton->setEnabled(false); + m_forwardButton->setEnabled(false); + } else { + //前目录不存在时(外设被拔出、网络目录被卸载),回退按钮需要置灰 + if (m_navStack->isFirst() || !m_navStack->backIsExist()) { + m_backButton->setEnabled(false); + } else { + m_backButton->setEnabled(true); + } + + //后目录不存在时(外设被拔出、网络目录被卸载),向前按钮需要置灰 + if (m_navStack->isLast() || !m_navStack->forwardIsExist()) { + m_forwardButton->setEnabled(false); + } else { + m_forwardButton->setEnabled(true); + } + } +} + +void DToolBar::setCustomActionList(const QList &list) +{ + m_actionList = list; + + for (DFMActionButton *button : m_contollerToolBar->findChildren()) { + m_contollerToolBarContentLayout->removeWidget(button); + button->deleteLater(); + } + + for (int i = 0; i < list.count(); ++i) { + DFMActionButton *button = new DFMActionButton(this); + button->setFixedSize(36, 36); + button->setFocusPolicy(Qt::NoFocus); + button->setAction(list.at(i)); + button->setIconSize(iconSize); + + QString acMark = QString("action_botton_%1").arg(i+1); + AC_SET_OBJECT_NAME( button, acMark); + AC_SET_ACCESSIBLE_NAME( button, acMark); + + m_contollerToolBarContentLayout->addWidget(button); + + if (list.at(i)->isVisible()) { + button->show(); + } + } + + m_contollerToolBar->setHidden(list.isEmpty()); + + if (m_detailButton) { + m_detailButton->setHidden(list.isEmpty()); + if (m_detailButton->isChecked() && list.isEmpty()) + m_detailButton->click(); + } +} + +void DToolBar::triggerActionByIndex(int index) +{ + if (QAction *action = m_actionList.value(index)) { + if (action->isVisible()) { + action->trigger(); + } + } +} + +void DToolBar::setSearchButtonVisible(bool visble) +{ + if (m_searchButton->isVisible() != visble) + m_searchButton->setVisible(visble); +} + +void DToolBar::onBackButtonClicked() +{ + DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(this), qobject_cast(window())); +} + +void DToolBar::onForwardButtonClicked() +{ + DFMEventDispatcher::instance()->processEvent(dMakeEventPointer(this), qobject_cast(window())); +} + +void DToolBar::setEnterText(QString &text) +{ + //【recent:】后无斜杠、单斜杠、双斜杠、三斜杠均响应跳转只最近使用页面,无视其后输入的文件名是否存在 + if (text.startsWith("recent:")) { + text = "recent:///"; + } else if (text.startsWith("usershare:")) { + text = "usershare:///"; + } else if (text.startsWith("computer:")) { + text = "computer:///"; + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtoolbar.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtoolbar.h new file mode 100644 index 0000000..4b4377b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/dtoolbar.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef DTOOLBAR_H +#define DTOOLBAR_H + +#include +#include + +#include "dfileview.h" + +class DFMEvent; +class HistoryStack; + +QT_BEGIN_NAMESPACE +class QPushButton; +class QHBoxLayout; +class QToolButton; +QT_END_NAMESPACE + +DWIDGET_BEGIN_NAMESPACE +class DButtonBoxButton; +DWIDGET_END_NAMESPACE + +DFM_BEGIN_NAMESPACE +class DFMCrumbBar; +class DFMAddressBar; +class DFMIconButton; +DFM_END_NAMESPACE + +DFM_USE_NAMESPACE + +class DToolBar : public QFrame +{ + Q_OBJECT +public: + explicit DToolBar(QWidget *parent = nullptr); + ~DToolBar(); + static const int ButtonWidth; + static const int ButtonHeight; + void initData(); + void initUI(); + void initAddressToolBar(); + void initContollerToolBar(); + void initConnect(); + DFMCrumbBar *getCrumbWidget(); + void addHistoryStack(); + + int navStackCount() const; + void updateBackForwardButtonsState(); + + void setCustomActionList(const QList &list); + void triggerActionByIndex(int index); + void setSearchButtonVisible(bool visble); + +signals: + void refreshButtonClicked(); + void toolbarUrlChanged(const DUrl &url); + void detailButtonClicked(); + +public slots: + void searchBarActivated(); + void searchBarDeactivated(); + void searchBarTextEntered(const QString textEntered); + void onSearchButtonClicked(); + void currentUrlChanged(const DFMEvent &event); + + void back(); + void forward(); + + void handleHotkeyCtrlF(quint64 winId); + void handleHotkeyCtrlL(quint64 winId); + + void moveNavStacks(int from, int to); + void removeNavStackAt(int index); + void switchHistoryStack(const int index ); + +private: + void toggleSearchButtonState(bool asb = true); + void pushUrlToHistoryStack(DUrl url); + void onBackButtonClicked(); + void onForwardButtonClicked(); + void setEnterText(QString &text); + + QFrame *m_addressToolBar; + DButtonBoxButton *m_backButton = nullptr; + DButtonBoxButton *m_forwardButton = nullptr; + QPushButton *m_searchButton = nullptr; + QToolButton *m_detailButton = nullptr; + QFrame *m_contollerToolBar; + QHBoxLayout *m_contollerToolBarContentLayout; + QList m_actionList; + + bool m_switchState = false; + bool m_searchButtonAsbState = false; + DFMCrumbBar *m_crumbWidget = nullptr; + std::shared_ptr m_navStack = nullptr; + QList> m_navStacks; +}; + +#endif // DTOOLBAR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/extendview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/extendview.cpp new file mode 100644 index 0000000..297f2df --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/extendview.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "extendview.h" +#include +#include +#include +#include +#include "ddetailview.h" +#include "dfileview.h" + + +ExtendView::ExtendView(QWidget *parent) : QFrame(parent) +{ + initUI(); + initConnect(); +} + +ExtendView::~ExtendView() +{ + +} + +void ExtendView::initUI() +{ + m_extendListView = new QListWidget; + m_extendListView->setFlow(QListWidget::LeftToRight); + m_detailView = new DDetailView; + m_detailView->setFixedWidth(200); + QHBoxLayout *mainLayout = new QHBoxLayout; + mainLayout->addWidget(m_extendListView); + mainLayout->addWidget(m_detailView); + mainLayout->setSpacing(0); + mainLayout->setContentsMargins(0, 0, 0, 0); + setLayout(mainLayout); +} + +void ExtendView::initConnect() +{ + +} + +void ExtendView::setStartUrl(const DUrl &url) +{ + if (url == m_currentUrl) { + return; + } +// m_extendListView->clear(); +// DUrlList urls = m_startUrl.childrenList(url); + +// foreach (DUrl url, urls) { +// qDebug()<< url; +// QListWidgetItem* item = new QListWidgetItem; +// item->setSizeHint(QSize(200, 10)); +// m_extendListView->addItem(item); + +// DFileView* view = new DFileView; +// view->setViewModeToExtend(); +// view->setFixedWidth(200); +// view->setCurrentUrl(url); +// m_extendListView->setItemWidget(item, view); +// } + + m_currentUrl = url; +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/extendview.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/extendview.h new file mode 100644 index 0000000..6d0ce16 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/extendview.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef EXTENDVIEW_H +#define EXTENDVIEW_H + +#include +#include "durl.h" +class QListWidget; +class DDetailView; + + +class ExtendView : public QFrame +{ + Q_OBJECT +public: + explicit ExtendView(QWidget *parent = nullptr); + ~ExtendView(); + +signals: + +public slots: + void setStartUrl(const DUrl &url); + +private: + void initUI(); + void initConnect(); + +private: + QListWidget *m_extendListView = nullptr; + DDetailView *m_detailView = nullptr; + DUrl m_startUrl; + DUrl m_currentUrl; +}; + +#endif // EXTENDVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/filedialogstatusbar.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/filedialogstatusbar.cpp new file mode 100644 index 0000000..d87ae2e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/filedialogstatusbar.cpp @@ -0,0 +1,400 @@ +/** + * Copyright (C) 2017 Deepin Technology Co., Ltd. + * + * 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. + **/ +#include "filedialogstatusbar.h" +#include "dfmglobal.h" +#include "accessibility/ac-lib-file-manager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +FileDialogStatusBar::FileDialogStatusBar(QWidget *parent) + : QFrame(parent) +{ + AC_SET_OBJECT_NAME(this, AC_FD_STATUS_BAR); + AC_SET_ACCESSIBLE_NAME(this, AC_FD_STATUS_BAR); + + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + setFrameShape(QFrame::NoFrame); + + m_titleLabel = new QLabel(this); + AC_SET_OBJECT_NAME(m_titleLabel, AC_FD_STATUS_BAR_TITLE_LABEL); + AC_SET_ACCESSIBLE_NAME(m_titleLabel, AC_FD_STATUS_BAR_TITLE_LABEL); + + QString labelName = tr("File Name"); + QString labelFilters = tr("Format"); + m_fileNameLabel = new QLabel(labelName, this); + m_filtersLabel = new QLabel(labelFilters, this); + + m_fileNameLabel->setObjectName(labelName); + AC_SET_ACCESSIBLE_NAME(m_fileNameLabel, labelName); + m_filtersLabel->setObjectName(labelFilters); + AC_SET_ACCESSIBLE_NAME(m_filtersLabel, labelFilters); + + m_fileNameEdit = new QLineEdit(this); + m_filtersComboBox = new QComboBox(this); + + AC_SET_OBJECT_NAME(m_fileNameEdit, AC_FD_STATUS_BAR_FILE_NAME_EDIT); + AC_SET_ACCESSIBLE_NAME(m_fileNameEdit, AC_FD_STATUS_BAR_FILE_NAME_EDIT); + AC_SET_OBJECT_NAME(m_filtersComboBox, AC_FD_STATUS_BAR_FILTERS); + AC_SET_ACCESSIBLE_NAME(m_filtersComboBox, AC_FD_STATUS_BAR_FILTERS); + + m_fileNameEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_fileNameEdit->installEventFilter(this); + m_filtersComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + m_acceptButton = new QPushButton(this); + m_rejectButton = new QPushButton(tr("Cancel","button"), this); + + m_rejectButton->setObjectName(tr("Cancel","button")); + AC_SET_ACCESSIBLE_NAME(m_rejectButton, tr("Cancel","button")); + + m_acceptButton->setMinimumWidth(130); + m_rejectButton->setMinimumWidth(130); + + m_acceptButton->setObjectName("FileDialogStatusBarAcceptButton"); + + m_contentLayout = new QHBoxLayout(); + + QVBoxLayout *mainLayout = new QVBoxLayout(this); + + mainLayout->addWidget(m_titleLabel, 0, Qt::AlignHCenter); + mainLayout->addLayout(m_contentLayout); +} + +void FileDialogStatusBar::setMode(FileDialogStatusBar::Mode mode) +{ + if (m_mode == mode) + return; + + m_mode = mode; + + QString acButton = mode == Save ? tr("Save","button") : tr("Open","button"); + m_acceptButton->setText(acButton); + m_acceptButton->setObjectName(acButton); + AC_SET_ACCESSIBLE_NAME(m_acceptButton, acButton); + + updateLayout(); + + if (m_titleLabel->text().isEmpty()) { + QString titleLabel = mode == Save ? tr("Save File","button") : tr("Open File","button"); + m_titleLabel->setText(titleLabel); + + m_titleLabel->setObjectName(titleLabel); + AC_SET_ACCESSIBLE_NAME(m_titleLabel, titleLabel); + } +} + +void FileDialogStatusBar::setComBoxItems(const QStringList &list) +{ + bool visible = m_filtersComboBox->isVisible(); + + m_filtersComboBox->clear(); + m_filtersComboBox->addItems(list); + + if (m_mode == Open) { + m_filtersComboBox->setHidden(list.isEmpty()); + m_filtersLabel->setHidden(list.isEmpty()); + } else { + if (visible == list.isEmpty()) { + updateLayout(); + } + } +} + +QComboBox *FileDialogStatusBar::comboBox() const +{ + return m_filtersComboBox; +} + +QLineEdit *FileDialogStatusBar::lineEdit() const +{ + return m_fileNameEdit; +} + +QPushButton *FileDialogStatusBar::acceptButton() const +{ + return m_acceptButton; +} + +QPushButton *FileDialogStatusBar::rejectButton() const +{ + return m_rejectButton; +} + +void FileDialogStatusBar::addLineEdit(QLabel *label, QLineEdit *edit) +{ + AC_SET_OBJECT_NAME(label, AC_FD_STATUS_BAR_TITLE_CONTENT_LABEL); + AC_SET_ACCESSIBLE_NAME(label, AC_FD_STATUS_BAR_TITLE_CONTENT_LABEL); + AC_SET_OBJECT_NAME(edit, AC_FD_STATUS_BAR_TITLE_CONTENT_EDIT); + AC_SET_ACCESSIBLE_NAME(edit, AC_FD_STATUS_BAR_TITLE_CONTENT_EDIT); + m_customLineEditList << qMakePair(label, edit); +} + +QString FileDialogStatusBar::getLineEditValue(const QString &text) const +{ + auto iter = std::find_if(m_customLineEditList.begin(), m_customLineEditList.end(), + [text](const QPair &i) { + return i.first->text() == text; + }); + + if (iter != m_customLineEditList.end()) { + return iter->second->text(); + } + + return QString(); +} + +QVariantMap FileDialogStatusBar::allLineEditsValue() const +{ + QVariantMap map; + + for (auto i : m_customLineEditList) + map[i.first->text()] = i.second->text(); + + return map; +} + +void FileDialogStatusBar::addComboBox(QLabel *label, QComboBox *box) +{ + AC_SET_OBJECT_NAME(label, AC_FD_STATUS_BAR_TITLE_CONTENT_LABEL); + AC_SET_ACCESSIBLE_NAME(label, AC_FD_STATUS_BAR_TITLE_CONTENT_LABEL); + AC_SET_OBJECT_NAME(box, AC_FD_STATUS_BAR_TITLE_CONTENT_BOX); + AC_SET_ACCESSIBLE_NAME(box, AC_FD_STATUS_BAR_TITLE_CONTENT_BOX); + + m_customComboBoxList << qMakePair(label, box); +} + +QString FileDialogStatusBar::getComboBoxValue(const QString &text) const +{ + auto iter = std::find_if(m_customComboBoxList.begin(), m_customComboBoxList.end(), + [text](const QPair &i) { + return i.first->text() == text; + }); + + if (iter != m_customComboBoxList.end()) { + return iter->second->currentText(); + } + + return QString(); +} + +QVariantMap FileDialogStatusBar::allComboBoxsValue() const +{ + QVariantMap map; + + for (auto i : m_customComboBoxList) + map[i.first->text()] = i.second->currentText(); + + return map; +} + +void FileDialogStatusBar::beginAddCustomWidget() +{ + for (auto i : m_customLineEditList) { + i.first->deleteLater(); + i.second->deleteLater(); + } + + for (auto i : m_customLineEditList) { + i.first->deleteLater(); + i.second->deleteLater(); + } + + m_customComboBoxList.clear(); + m_customLineEditList.clear(); +} + +void FileDialogStatusBar::endAddCustomWidget() +{ + updateLayout(); +} + +void FileDialogStatusBar::showEvent(QShowEvent *event) +{ + const QString &title = window()->windowTitle(); + + if (!title.isEmpty()) { + m_titleLabel->setText(title); + + m_titleLabel->setObjectName(title); + AC_SET_ACCESSIBLE_NAME(m_titleLabel, title); + } + connect(window(), &QWidget::windowTitleChanged, this, &FileDialogStatusBar::onWindowTitleChanged); + + if (m_fileNameEdit->isVisible()) + m_fileNameEdit->setFocus(); + + return QFrame::showEvent(event); +} + +void FileDialogStatusBar::hideEvent(QHideEvent *event) +{ + disconnect(window(), &QWidget::windowTitleChanged, this, &FileDialogStatusBar::onWindowTitleChanged); + + return QFrame::hideEvent(event); +} + +bool FileDialogStatusBar::eventFilter(QObject *watched, QEvent *event) +{ + if (watched != m_fileNameEdit) + return false; + + if (event->type() == QEvent::FocusIn) { + TIMER_SINGLESHOT_OBJECT(this, 10, { + QMimeDatabase db; + const QString &name = m_fileNameEdit->text(); + const QString &suffix = db.suffixForFileName(name); + + if (suffix.isEmpty()) + m_fileNameEdit->selectAll(); + else + m_fileNameEdit->setSelection(0, name.length() - suffix.length() - 1); + }, this) + } else if (event->type() == QEvent::Show) { + TIMER_SINGLESHOT_OBJECT(this, 500, m_fileNameEdit->setFocus(), this); + } + + return false; +} + +void FileDialogStatusBar::updateLayout() +{ + if (m_mode == Unknow) + return; + + while (m_contentLayout->count() > 0) + delete m_contentLayout->takeAt(0); + + m_fileNameLabel->hide(); + m_filtersLabel->hide(); + + m_fileNameEdit->hide(); + m_filtersComboBox->hide(); + + m_contentLayout->addSpacing(10); + + int widget_count = m_customComboBoxList.count() + m_customLineEditList.count(); + + if (m_mode == Save) { + ++widget_count; + } + + if (m_filtersComboBox->count() > 0) + ++widget_count; + + if (widget_count <= 1) { + int added_widget_count = 1; + + if (!m_customLineEditList.isEmpty()) { + m_contentLayout->addWidget(m_customLineEditList.first().first); + m_contentLayout->addSpacing(10); + m_contentLayout->addWidget(m_customLineEditList.first().second, 1); + } else if (!m_customComboBoxList.isEmpty()) { + m_contentLayout->addWidget(m_customComboBoxList.first().first); + m_contentLayout->addSpacing(10); + m_contentLayout->addWidget(m_customComboBoxList.first().second, 1); + } else { + added_widget_count = 0; + } + + if (m_mode == Open) { + if (added_widget_count == 0) { + m_contentLayout->addWidget(m_filtersLabel); + m_contentLayout->addSpacing(10); + m_contentLayout->addWidget(m_filtersComboBox, 1); + } + + m_contentLayout->addSpacing(10); + m_contentLayout->addStretch(); + m_contentLayout->addWidget(m_rejectButton); + m_contentLayout->addWidget(m_acceptButton); + + if (m_filtersComboBox->count() > 0) { + m_filtersLabel->show(); + m_filtersComboBox->show(); + } + + return; + } + + if (m_filtersComboBox->count() <= 0) { + if (added_widget_count == 0) { + m_contentLayout->addWidget(m_fileNameLabel); + m_contentLayout->addSpacing(10); + m_contentLayout->addWidget(m_fileNameEdit); + } + + m_contentLayout->addSpacing(10); + m_contentLayout->addWidget(m_rejectButton); + m_contentLayout->addWidget(m_acceptButton); + + m_fileNameLabel->show(); + m_fileNameEdit->show(); + + return; + } + } + + QVBoxLayout *label_layout = new QVBoxLayout(); + QVBoxLayout *center_layout = new QVBoxLayout(); + + if (m_mode == Save) { + label_layout->addWidget(m_fileNameLabel); + center_layout->addWidget(m_fileNameEdit); + m_fileNameLabel->show(); + m_fileNameEdit->show(); + } + + for (auto i : m_customLineEditList) { + label_layout->addWidget(i.first); + center_layout->addWidget(i.second); + } + + if (m_filtersComboBox->count() > 0) { + label_layout->addWidget(m_filtersLabel); + center_layout->addWidget(m_filtersComboBox); + m_filtersLabel->show(); + m_filtersComboBox->show(); + } + + for (auto i : m_customComboBoxList) { + label_layout->addWidget(i.first); + center_layout->addWidget(i.second); + } + + QVBoxLayout *button_layout = new QVBoxLayout(); + + button_layout->addStretch(); + button_layout->addWidget(m_rejectButton, 0, Qt::AlignRight | Qt::AlignVCenter); + button_layout->addWidget(m_acceptButton, 0, Qt::AlignRight | Qt::AlignVCenter); + + m_contentLayout->addLayout(label_layout); + m_contentLayout->addSpacing(10); + m_contentLayout->addLayout(center_layout); + m_contentLayout->addSpacing(10); + m_contentLayout->addLayout(button_layout); +} + +void FileDialogStatusBar::onWindowTitleChanged(const QString &title) +{ + if (title.isEmpty()) + return; + + m_titleLabel->setText(title); + + m_titleLabel->setObjectName(title); + AC_SET_ACCESSIBLE_NAME(m_titleLabel, title); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/filedialogstatusbar.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/filedialogstatusbar.h new file mode 100644 index 0000000..d428f32 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/filedialogstatusbar.h @@ -0,0 +1,81 @@ +/** + * Copyright (C) 2017 Deepin Technology Co., Ltd. + * + * 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. + **/ +#ifndef FILEDIALOGSTATUSBAR_H +#define FILEDIALOGSTATUSBAR_H + +#include + +QT_BEGIN_NAMESPACE +class QHBoxLayout; +class QLabel; +class QLineEdit; +class QComboBox; +class QPushButton; +QT_END_NAMESPACE + +class FileDialogStatusBar : public QFrame +{ + Q_OBJECT +public: + enum Mode { + Unknow, + Open, + Save + }; + + explicit FileDialogStatusBar(QWidget *parent = 0); + + void setMode(Mode mode); + + void setComBoxItems(const QStringList &list); + QComboBox *comboBox() const; + + QLineEdit *lineEdit() const; + + QPushButton *acceptButton() const; + QPushButton *rejectButton() const; + + void addLineEdit(QLabel *label, QLineEdit *edit); + QString getLineEditValue(const QString &text) const; + QVariantMap allLineEditsValue() const; + void addComboBox(QLabel *label, QComboBox *box); + QString getComboBoxValue(const QString &text) const; + QVariantMap allComboBoxsValue() const; + void beginAddCustomWidget(); + void endAddCustomWidget(); + +private: + void showEvent(QShowEvent *event) override; + void hideEvent(QHideEvent *event) override; + bool eventFilter(QObject *watched, QEvent *event) override; + + void updateLayout(); + void onWindowTitleChanged(const QString &title); + + Mode m_mode = Unknow; + + QHBoxLayout *m_contentLayout; + + QLabel *m_titleLabel; + QLabel *m_fileNameLabel; + QLabel *m_filtersLabel; + + QLineEdit *m_fileNameEdit; + QComboBox *m_filtersComboBox; + + QPushButton *m_acceptButton; + QPushButton *m_rejectButton; + + QList> m_customLineEditList; + QList> m_customComboBoxList; + + friend class DFileDialog; +}; + +#endif // FILEDIALOGSTATUSBAR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/fileitem.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/fileitem.cpp new file mode 100644 index 0000000..3ff8799 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/fileitem.cpp @@ -0,0 +1,453 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "fileitem.h" +#include "dfmglobal.h" +#include "app/define.h" +#include + +DWIDGET_USE_NAMESPACE + +class CanSetDragTextEdit : public DTextEdit +{ +public: + explicit CanSetDragTextEdit(QWidget *parent = nullptr); + explicit CanSetDragTextEdit(const QString& text, QWidget* parent = nullptr); + //set QTextEdit can drag + void setDragEnabled(const bool &bdrag); +}; + +class FileIconItemPrivate{ +public: + FileIconItemPrivate(){} + ~FileIconItemPrivate() + { + if (tooltip){ + tooltip->deleteLater(); + } + } + + DArrowRectangle *tooltip {nullptr}; + QString validText; +}; + +FileIconItem::FileIconItem(QWidget *parent) : + QFrame(parent) + , d_ptr(new FileIconItemPrivate()) +{ + icon = new QLabel(this); + edit = new CanSetDragTextEdit(this); + + icon->setAlignment(Qt::AlignCenter); + icon->setFrameShape(QFrame::NoFrame); + icon->installEventFilter(this); + + edit->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + edit->setAlignment(Qt::AlignHCenter); + edit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + edit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + edit->setFrameShape(QFrame::NoFrame); + edit->installEventFilter(this); + edit->setAcceptRichText(false); + edit->setContextMenuPolicy(Qt::CustomContextMenu); + edit->setAcceptDrops(false); + static_cast(edit)->setDragEnabled(false); + + auto vlayout = new QVBoxLayout; + vlayout->setContentsMargins(0, 0, 0, 0); + vlayout->setSpacing(0); + setLayout(vlayout); + + vlayout->addWidget(icon, 0, Qt::AlignTop | Qt::AlignHCenter); + vlayout->addSpacing(ICON_MODE_ICON_SPACING); + vlayout->addWidget(edit, 0, Qt::AlignTop | Qt::AlignHCenter); + + setFrameShape(QFrame::NoFrame); + setFocusProxy(edit); + + connect(edit, &QTextEdit::customContextMenuRequested, this, &FileIconItem::popupEditContentMenu); +} + +FileIconItem::~FileIconItem() +{ + +} + +qreal FileIconItem::opacity() const +{ + if (opacityEffect) + return opacityEffect->opacity(); + + return 1; +} + +void FileIconItem::setOpacity(qreal opacity) +{ + if (opacity - 1.0 >= 0) { + if (opacityEffect) { + opacityEffect->deleteLater(); + opacityEffect = Q_NULLPTR; + } + + return; + } else if (!opacityEffect) { + opacityEffect = new QGraphicsOpacityEffect(this); + setGraphicsEffect(opacityEffect); + } + + opacityEffect->setOpacity(opacity); +} + +void FileIconItem::setMaxCharSize(int maxSize) +{ + m_maxCharSize = maxSize; +} + +int FileIconItem::maxCharSize() +{ + return m_maxCharSize; +} + +QSize FileIconItem::sizeHint() const +{ + return QSize(width(), icon->height() + edit->height()); +} + +void FileIconItem::popupEditContentMenu() +{ + QMenu *menu = edit->createStandardContextMenu(); + + if (!menu || edit->isReadOnly()) { + return; + } + + QAction *undo_action = menu->findChild(QStringLiteral("edit-undo")); + QAction *redo_action = menu->findChild(QStringLiteral("edit-redo")); + + if (undo_action) { + undo_action->setEnabled(editTextStackCurrentIndex > 0); + disconnect(undo_action, SIGNAL(triggered(bool))); + connect(undo_action, &QAction::triggered, this, &FileIconItem::editUndo); + } + if (redo_action) { + redo_action->setEnabled(editTextStackCurrentIndex < editTextStack.count() - 1); + disconnect(redo_action, SIGNAL(triggered(bool))); + connect(redo_action, &QAction::triggered, this, &FileIconItem::editRedo); + } + + menu->exec(QCursor::pos()); + menu->deleteLater(); +} + +void FileIconItem::editUndo() +{ + disableEditTextStack = true; + QTextCursor cursor = edit->textCursor(); + edit->setPlainText(editTextStackBack()); + edit->setTextCursor(cursor); +} + +void FileIconItem::editRedo() +{ + disableEditTextStack = true; + QTextCursor cursor = edit->textCursor(); + edit->setPlainText(editTextStackAdvance()); + edit->setTextCursor(cursor); +} + +void FileIconItem::doLineEditTextChanged() +{ + QSignalBlocker blocker(edit); + Q_UNUSED(blocker) + + const QString srcText = edit->toPlainText(); + QString dstText = DFMGlobal::preprocessingFileName(srcText); + + if (srcText != dstText){ + // 修改文件的命名规则 + showAlertMessage(tr("%1 are not allowed").arg("|[/\\*:\"']?<>")); + edit->setPlainText(dstText); + } else { + return; + } + + QVector list = dstText.toUcs4(); + int cursor_pos = edit->textCursor().position() - srcText.length() + dstText.length(); + + while (dstText.toLocal8Bit().size() > m_maxCharSize) { + list.removeAt(--cursor_pos); + + dstText = QString::fromUcs4(list.data(), list.size()); + } + + while (dstText.toLocal8Bit().size() > m_maxCharSize) { + dstText.chop(1); + } + + if (editTextStackCurrentItem() != dstText) { + pushItemToEditTextStack(dstText); + } + + QTextCursor cursor = edit->textCursor(); + + cursor.movePosition(QTextCursor::Start); + + do { + QTextBlockFormat format = cursor.blockFormat(); + + format.setLineHeight(fontMetrics().height(), QTextBlockFormat::FixedHeight); + cursor.setBlockFormat(format); + } while (cursor.movePosition(QTextCursor::NextBlock)); + + cursor.setPosition(cursor_pos); + + edit->setTextCursor(cursor); + edit->setAlignment(Qt::AlignHCenter); + + if (edit->isVisible()) { + updateEditorGeometry(); + } +} + +//提供外部调用的槽函数 +void FileIconItem::resizeFromEditTextChanged() +{ + //根据字符串的长度调整大小调整(之前的逻辑) + updateEditorGeometry(); + //调整大小后,重新设置水平居中,否则会左对齐。 + if (edit) { + edit->setAlignment(Qt::AlignHCenter); + } +} + +void FileIconItem::showAlertMessage(const QString &text, int duration) +{ + Q_D(FileIconItem); + + if (!d->tooltip){ + d->tooltip = new DArrowRectangle(DArrowRectangle::ArrowTop, this); + d->tooltip->setObjectName("AlertTooltip"); + + QLabel *label = new QLabel(d->tooltip); + + label->setWordWrap(true); + label->setMaximumWidth(500); + d->tooltip->setContent(label); + d->tooltip->setBackgroundColor(palette().color(backgroundRole())); + d->tooltip->setArrowX(15); + d->tooltip->setArrowHeight(5); + + QTimer::singleShot(duration, d->tooltip, [d] { + d->tooltip->deleteLater(); + d->tooltip = Q_NULLPTR; + }); + } + + QLabel *label = qobject_cast(d->tooltip->getContent()); + + if (!label) { + return; + } + + label->setText(text); + label->adjustSize(); + + const QPoint &pos = edit->mapToGlobal(QPoint(edit->width()/2, edit->height())); + + d->tooltip->show(pos.x(), pos.y()); +} + +bool FileIconItem::event(QEvent *ee) +{ + if (ee->type() == QEvent::DeferredDelete) { + if (!canDeferredDelete) { + ee->accept(); + + return true; + } + } else if (ee->type() == QEvent::Resize) { + updateEditorGeometry(); + int marginsHeight = contentsMargins().top(); + resize(width(), icon->height() + edit->height() + ICON_MODE_ICON_SPACING + marginsHeight); + } else if (ee->type() == QEvent::FontChange) { + edit->setFont(font()); + } + + return QFrame::event(ee); +} + +bool FileIconItem::eventFilter(QObject *obj, QEvent *ee) +{ + switch (ee->type()) { + case QEvent::Resize: + if (obj == icon || obj == edit) { + int marginsHeight = contentsMargins().top(); + //计算高度时需加上marginsHeight,否则文字会显示不全 + resize(width(), icon->height() + edit->height() + ICON_MODE_ICON_SPACING + marginsHeight); + } + + break; + case QEvent::KeyPress: { + if (obj != edit) { + return QFrame::eventFilter(obj, ee); + } + + QKeyEvent *event = static_cast(ee); + + if (event->key() != Qt::Key_Enter && event->key() != Qt::Key_Return && event->key() != Qt::Key_Tab) { + if (event == QKeySequence::Undo) { + editUndo(); + } else if (event == QKeySequence::Redo) { + editRedo(); + } else { + return QFrame::eventFilter(obj, ee); + } + + disableEditTextStack = false; + ee->accept(); + + return true; + } + + if (!(event->modifiers() & Qt::ShiftModifier)) { + ee->accept(); + parentWidget()->setFocus(); + + return true; + } else { + event->accept(); + return false; + } + + break; + } + case QEvent::FocusOut: + if (obj == edit && qApp->focusWidget() != edit) { + emit inputFocusOut(); + } + + break; + case QEvent::Show: + updateEditorGeometry(); + + break; + default: + break; + } + + return QFrame::eventFilter(obj, ee); +} + +void FileIconItem::updateEditorGeometry() +{ + edit->setFixedWidth(width()); + int text_height = static_cast(edit->document()->size().height()); + + if (edit->isReadOnly()) { + if (edit->isVisible()) { + edit->setFixedHeight(text_height); + } + } else { + edit->setFixedHeight(qMin(fontMetrics().height() * 3 + TEXT_PADDING * 2, text_height)); + } +} + +void FileIconItem::updateStyleSheet() +{ + QString base = "FileIconItem[showBackground=true] QTextEdit {background: %1; color: %2;}"; + + base.append("FileIconItem QTextEdit {color: %3}"); + base = base.arg(palette().color(QPalette::Background).name(QColor::HexArgb)) + .arg(palette().color(QPalette::BrightText).name(QColor::HexArgb)) + .arg(palette().color(QPalette::Text).name(QColor::HexArgb)); + + // WARNING: setStyleSheet will clean margins!!!!!! + auto saveContent = contentsMargins(); + setStyleSheet(base); + setContentsMargins(saveContent); +} + +QString FileIconItem::editTextStackCurrentItem() const +{ + return editTextStack.value(editTextStackCurrentIndex); +} + +QString FileIconItem::editTextStackBack() +{ + editTextStackCurrentIndex = qMax(0, editTextStackCurrentIndex - 1); + const QString &text = editTextStackCurrentItem(); + + return text; +} + +QString FileIconItem::editTextStackAdvance() +{ + editTextStackCurrentIndex = qMin(editTextStack.count() - 1, editTextStackCurrentIndex + 1); + const QString &text = editTextStackCurrentItem(); + + return text; +} + +void FileIconItem::pushItemToEditTextStack(const QString &item) +{ + if (disableEditTextStack) { + return; + } + + editTextStack.remove(editTextStackCurrentIndex + 1, editTextStack.count() - editTextStackCurrentIndex - 1); + editTextStack.push(item); + ++editTextStackCurrentIndex; +} + +CanSetDragTextEdit::CanSetDragTextEdit(QWidget *parent) : + DTextEdit (parent) +{ + +} + +CanSetDragTextEdit::CanSetDragTextEdit(const QString &text, QWidget *parent) : + DTextEdit (text, parent) +{ + +} + +void CanSetDragTextEdit::setDragEnabled(const bool &bdrag) +{ + QTextEditPrivate *dd = reinterpret_cast(qGetPtrHelper(d_ptr)); + dd->control->setDragEnabled(bdrag); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/fileitem.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/fileitem.h new file mode 100644 index 0000000..2069092 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/fileitem.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef FILEITEM_H +#define FILEITEM_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QTextEdit; +class QGraphicsOpacityEffect; +QT_END_NAMESPACE + +class FileIconItemEdit; +class FileIconItemPrivate; +class FileIconItem : public QFrame +{ + Q_OBJECT + + Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) + +public: + explicit FileIconItem(QWidget *parent = nullptr); + ~FileIconItem() override; + + qreal opacity() const; + void setOpacity(qreal opacity); + void setMaxCharSize(int maxSize); + int maxCharSize(); + + QSize sizeHint() const override; + + inline QLabel *getIconLabel() const + { return icon; } + inline QTextEdit *getTextEdit() const + { return edit; } + + +public slots: + /** + * @brief showAlertMessage 显示提示信息 + * @param text 提示内容 + * @param duration 显示时间,默认3秒 + */ + void showAlertMessage(const QString &text, int duration = 3000); + +signals: + void inputFocusOut(); + +private slots: + void popupEditContentMenu(); + void editUndo(); + void editRedo(); + void doLineEditTextChanged(); + void resizeFromEditTextChanged(); + +protected: + void updateEditorGeometry(); + bool event(QEvent *ee) override; + bool eventFilter(QObject *obj, QEvent *ee) override; + +private: + void updateStyleSheet(); + + QString editTextStackCurrentItem() const; + QString editTextStackBack(); + QString editTextStackAdvance(); + void pushItemToEditTextStack(const QString &item); + + bool canDeferredDelete = true; + QLabel *icon; + QTextEdit *edit; + int editTextStackCurrentIndex = -1; + bool disableEditTextStack = false; + QStack editTextStack; + QGraphicsOpacityEffect *opacityEffect = Q_NULLPTR; + int m_maxCharSize = INT_MAX; + + friend class DIconItemDelegate; + friend class DFileView; + friend class DFileViewHelper; + + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(FileIconItem) + Q_DISABLE_COPY(FileIconItem) +}; + +#endif // FILEITEM_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/fileviewhelper.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/fileviewhelper.cpp new file mode 100644 index 0000000..731a51e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/fileviewhelper.cpp @@ -0,0 +1,196 @@ +/** + * Copyright (C) 2016 Deepin Technology Co., Ltd. + * + * 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. + **/ + +#include "fileviewhelper.h" +#include "dfileview.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "controllers/appcontroller.h" +#include "dfilesystemmodel.h" +#include "singleton.h" +#include "usershare/usersharemanager.h" + +FileViewHelper::FileViewHelper(DFileView *parent) + : DFileViewHelper(parent) + , lastEvent(this, DUrl()) +{ + connect(parent, &DFileView::triggerEdit, this, &DFileViewHelper::triggerEdit); + + connect(fileSignalManager, &FileSignalManager::requestViewSelectAll, + this, &FileViewHelper::selectAll); + connect(fileSignalManager, &FileSignalManager::requestSelectFile, + this, &FileViewHelper::handleSelectEvent); + connect(fileSignalManager, &FileSignalManager::requestFoucsOnFileView, + this, &FileViewHelper::setFoucsOnFileView); + connect(fileSignalManager, &FileSignalManager::requestFreshFileView, + this, &FileViewHelper::refreshFileView); +} + +DFileView *FileViewHelper::parent() const +{ + return qobject_cast(DFileViewHelper::parent()); +} + +quint64 FileViewHelper::windowId() const +{ + return parent()->windowId(); +} + +bool FileViewHelper::isSelected(const QModelIndex &index) const +{ + return parent()->isSelected(index); +} + +bool FileViewHelper::isDropTarget(const QModelIndex &index) const +{ + return parent()->isDropTarget(index); +} + +int FileViewHelper::selectedIndexsCount() const +{ + return parent()->selectedIndexCount(); +} + +int FileViewHelper::rowCount() const +{ + return parent()->rowCount(); +} + +int FileViewHelper::indexOfRow(const QModelIndex &index) const +{ + return parent()->indexOfRow(index); +} + +const DAbstractFileInfoPointer FileViewHelper::fileInfo(const QModelIndex &index) const +{ + return parent()->model()->fileInfo(index); +} + +DFMStyledItemDelegate *FileViewHelper::itemDelegate() const +{ + return parent()->itemDelegate(); +} + +DFileSystemModel *FileViewHelper::model() const +{ + return parent()->model(); +} + +const DUrlList FileViewHelper::selectedUrls() const +{ + return parent()->selectedUrls(); +} + +DUrl FileViewHelper::currentUrl() const +{ + return parent()->rootUrl(); +} + +QList FileViewHelper::columnRoleList() const +{ + return parent()->columnRoleList(); +} + +int FileViewHelper::columnWidth(int columnIndex) const +{ + return parent()->columnWidth(columnIndex); +} + +void FileViewHelper::select(const QList &list) +{ + if(DFMGlobal::isWayLand()) { + // 修复wayland BUG-38453 拷贝或剪贴过后,调用该函数选择全部对象 + parent()->selectAllAfterCutOrCopy(list); + } else { + if (list.count() < FILE_SELECT_THRESHOLD) { + parent()->select(list); + } else { // 当选择文件过多时,可能出现文件未被选中,启动线程的方式去选中未被选中的文件 + parent()->selectAllAfterCutOrCopy(list); + } + } + +} + +void FileViewHelper::viewFlicker() +{ + refreshFileView(windowId()); +} + +void FileViewHelper::preHandleCd(const DFMUrlBaseEvent &event) +{ + if (event.windowId() != windowId()) + return; + + if (event.fileUrl().isNetWorkFile()) { + emit fileSignalManager->requestFetchNetworks(event); + return; + } else if (event.fileUrl().isSMBFile()) { + emit fileSignalManager->requestFetchNetworks(event); + return; + } + + lastEvent = event; + parent()->cd(event.fileUrl()); + lastEvent = DFMUrlBaseEvent(this, DUrl()); +} + +void FileViewHelper::cd(const DFMUrlBaseEvent &event) +{ + if (event.windowId() != windowId()) + return; + + lastEvent = event; + parent()->cd(event.fileUrl()); + lastEvent = DFMUrlBaseEvent(this, DUrl()); +} + +void FileViewHelper::cdUp(const DFMUrlBaseEvent &event) +{ + if (event.windowId() != windowId()) + return; + + lastEvent = event; + parent()->cdUp(); + lastEvent = DFMUrlBaseEvent(this, DUrl()); +} + +void FileViewHelper::handleSelectEvent(const DFMUrlListBaseEvent &event) +{ + // TODO: should check fileSignalManager->requestSelectFile() and ensure sender correct. + if (event.sender() != this->parent() + && event.sender() != this->model()) { + return; + } + + select(event.urlList()); +} + +void FileViewHelper::selectAll(quint64 windowId) +{ + if(windowId != this->windowId()) + return; + + parent()->selectAll(); +} + +void FileViewHelper::setFoucsOnFileView(quint64 winId) +{ + if (winId == windowId()) { + parent()->setFocus(); + } +} + +void FileViewHelper::refreshFileView(quint64 winId) +{ + if (winId != windowId()) { + return; + } + + model()->refresh(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/fileviewhelper.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/fileviewhelper.h new file mode 100644 index 0000000..57470da --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/fileviewhelper.h @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2016 Deepin Technology Co., Ltd. + * + * 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. + **/ + +#ifndef FILEVIEWHELPER_H +#define FILEVIEWHELPER_H + +#include "dfmevent.h" +#include "interfaces/dfileviewhelper.h" + +#include + +#define FILE_SELECT_THRESHOLD 6 // 是否启用线程选择文件的阈值 + +class DFileView; +class FileViewHelper : public DFileViewHelper +{ + Q_OBJECT + +public: + explicit FileViewHelper(DFileView *parent); + + DFileView *parent() const; + + quint64 windowId() const override; + bool isSelected(const QModelIndex &index) const override; + bool isDropTarget(const QModelIndex &index) const override; + int selectedIndexsCount() const override; + int rowCount() const override; + int indexOfRow(const QModelIndex &index) const override; + const DAbstractFileInfoPointer fileInfo(const QModelIndex &index) const override; + DFMStyledItemDelegate *itemDelegate() const override; + DFileSystemModel *model() const override; + const DUrlList selectedUrls() const override; + DUrl currentUrl() const override; + QList columnRoleList() const override; + int columnWidth(int columnIndex) const override; + void select(const QList &list) override; + virtual void viewFlicker() override; +public slots: + // helper fm event + void preHandleCd(const DFMUrlBaseEvent &event); + void cd(const DFMUrlBaseEvent &event); + void cdUp(const DFMUrlBaseEvent &event); + void handleSelectEvent(const DFMUrlListBaseEvent &event); + void selectAll(quint64 windowId); + void setFoucsOnFileView(quint64 winId); + void refreshFileView(quint64 winId); + +private: + DFMUrlBaseEvent lastEvent; +}; + +#endif // FILEVIEWHELPER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/historystack.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/historystack.cpp new file mode 100644 index 0000000..1eb892c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/historystack.cpp @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "historystack.h" + +#include "dfileservices.h" +#include "plugins/pluginmanager.h" +#include "drootfilemanager.h" + +#include +#include + +HistoryStack::HistoryStack(int threshold) +{ + m_threshold = threshold; + m_index = -1; +} + +void HistoryStack::append(DUrl url) +{ + if ((m_index < m_list.count()) && (m_index >= 0)) { + if(m_list.at(m_index) == url) + return; + } + + if (m_index < m_threshold) { + ++m_index; + + if (m_index != m_list.size()) { + m_list = m_list.mid(0, m_index); + } + + m_list.append(url); + } else { + m_list.takeFirst(); + m_list.append(url); + } +} + +DUrl HistoryStack::back() +{ + const DUrl ¤tUrl = m_list.value(m_index); + DUrl url; + + if (m_index <= 0) + return url; + + while (--m_index >= 0) { + if (m_index >= m_list.count()) + continue; + + url = m_list.at(m_index); + + if(url.isComputerFile()) + break; + + //TODO [XIAO] 此处可以用插件的方式写 + //如果是我的手机界面返回,为了我的手机界面前进,回退功能 + if (url.isPluginFile()) + break; + + if (url.isUserShareFile()) + break; + + if (PluginManager::instance()->getViewInterfacesMap().keys().contains(url.scheme())) + break; + //判断网络文件是否可以到达 + if (DFileService::instance()->checkGvfsMountfileBusy(url,false)) { + if (currentUrl == url) { + removeAt(m_index); + url = m_list.at(m_index); + } + else { + break; + } + } + else { + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, url); + + if (!fileInfo || !fileInfo->exists() || currentUrl == url) { + removeAt(m_index); + url = m_list.at(m_index); + } else { + break; + } + } + } + + return url; +} + +DUrl HistoryStack::forward() +{ + const DUrl ¤tUrl = m_list.value(m_index); + DUrl url; + + if (m_index >= m_list.count() - 1) + return url; + + while (++m_index < m_list.count()) { + url = m_list.at(m_index); + + if(url.isComputerFile()) + break; + + //TODO [XIAO] 此处可以用插件的方式写 + //如果是我的手机界面返回,为了我的手机界面前进,回退功能 + if (url.isPluginFile()) + break; + + if (url.isUserShareFile()) + break; + + if (PluginManager::instance()->getViewInterfacesMap().keys().contains(url.scheme())) + break; + //判断网络文件是否可以到达 + if (DFileService::instance()->checkGvfsMountfileBusy(url,false)) { + if (currentUrl == url) { + removeAt(m_index); + --m_index; + url = m_list.at(m_index); + } + else { + break; + } + } + else { + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, url); + + if (!fileInfo || !fileInfo->exists() || currentUrl == url) { + removeAt(m_index); + --m_index; + url = m_list.at(m_index); + } else { + break; + } + } + } + + return url; +} + +void HistoryStack::setThreshold(int threshold) +{ + m_threshold = threshold; +} + +bool HistoryStack::isFirst() +{ + if(m_index < 0){ + m_index = 0; + } + return m_index == 0; +} + +bool HistoryStack::isLast() +{ + if(m_index > m_list.size() - 1){ + m_index = m_list.size() - 1; + } + return m_index == m_list.size() - 1; +} + +int HistoryStack::size() +{ + return m_list.size(); +} + +void HistoryStack::removeAt(int i) +{ + m_list.removeAt(i); +} + +int HistoryStack::currentIndex() +{ + return m_index; +} + +bool HistoryStack::backIsExist() +{ + if (m_index <= 0) + return false; + + DUrl backUrl = m_list.at(m_index - 1); + + if (!needCheckExist(backUrl)) + return true; + + //为了避免获取目录的info对象,采用了test命令,只测试计算机中是否包含该目录 + //避免获取info对象是因为若目录为网络目录,且该网络已不可达,会导致获取info等待时间不可控 + return checkPathIsExist(backUrl); +} + +bool HistoryStack::forwardIsExist() +{ + if (m_index >= m_list.size() - 1) + return false; + + DUrl forwardUrl = m_list.at(m_index + 1); + + if (!needCheckExist(forwardUrl)) + return true; + + //为了避免获取目录的info对象,采用了test命令,只测试计算机中是否包含该目录 + //避免获取info对象是因为若目录为网络目录,且该网络已不可达,会导致获取info等待时间不可控 + return checkPathIsExist(forwardUrl); +} + +bool HistoryStack::needCheckExist(const DUrl &url) +{ + if (url.isComputerFile() || url.isUserShareFile()) + return false; + + if (PluginManager::instance()->getViewInterfacesMap().keys().contains(url.scheme())) + return false; + + return true; +} + +bool HistoryStack::checkPathIsExist(const DUrl &url) +{ + //判断是否是协议设备的挂载路径 + static QRegularExpression regExp(GVFS_MATCH_EX, + QRegularExpression::DotMatchesEverythingOption + | QRegularExpression::DontCaptureOption + | QRegularExpression::OptimizeOnFirstUsageOption); + + QString urlPath = url.path(); + if (regExp.match(urlPath, 0, QRegularExpression::NormalMatch, QRegularExpression::DontCheckSubjectStringMatchOption).hasMatch()) { + //协议设备需要考虑断网问题,通过查询挂载点是否存在来判断是否存在 + DUrl rootUrl; + QString rootFileName; + int qi = 0; + QStringList urlPathList = urlPath.split(QRegularExpression(GVFS_MATCH)); + QString urlStr; + QString urlLast; + if (urlPathList.size() >= 2) { + urlLast = urlPathList[1]; + urlStr = urlPath.left(urlPath.indexOf(urlLast)); + } + + qi = urlLast.indexOf("/"); + QString path; + if (0 >= qi) { + path = urlPath; + QStringList rootStrList = path.split(QRegularExpression(GVFS_MATCH)); + if (rootStrList.size() >= 2) { + rootFileName = rootStrList.at(1); + rootFileName = rootFileName.replace(QString(".") + QString(SUFFIX_GVFSMP), ""); + } + } else { + rootFileName = urlLast.left(qi); + path = urlStr + urlLast.left(qi); + } + if (path.isNull() || path.isEmpty() || + !(rootFileName.startsWith(SMB_SCHEME) || rootFileName.startsWith(FTP_SCHEME) + || rootFileName.startsWith(SFTP_SCHEME) || rootFileName.startsWith(MTP_SCHEME) + || rootFileName.startsWith(GPHOTO2_SCHEME) || rootFileName.startsWith(AFC_SCHEME))) { + return false; + } + rootUrl.setScheme(DFMROOT_SCHEME); + rootUrl.setPath("/" + QUrl::toPercentEncoding(path) + "." SUFFIX_GVFSMP); + + return DRootFileManager::instance()->isRootFileContain(rootUrl); + } else { + // 对我的手机目录进行单独处理,直接返回true,否则涉及我的手机相关目录前进后退会失效 add by CL + if (url.scheme() == PLUGIN_SCHEME) { + return true; + } + //非协议设备挂载不用考虑断网问题,可以直接取fileinfo来判断是否存在 + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, url); + if (fileInfo) + return fileInfo->exists(); + } + + return false; +} + +QT_BEGIN_NAMESPACE +QDebug operator<<(QDebug beg, const HistoryStack &stack) +{ + beg << "history list:" << stack.m_list << "current pos:" << stack.m_index; + + return beg; +} +QT_END_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/historystack.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/historystack.h new file mode 100644 index 0000000..0825bbd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/historystack.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef HISTORYSTACK_H +#define HISTORYSTACK_H + +#include + +#include "durl.h" + +class HistoryStack +{ +public: + explicit HistoryStack(int threshold); + void append(DUrl url); + DUrl back(); + DUrl forward(); + void setThreshold(int threshold); + bool isFirst(); + bool isLast(); + int size(); + void removeAt(int i); + int currentIndex(); + + /** + * @brief backIsExist back目录是否存在 + * 该函数只测试计算机中是否包含back目录 + * @return + */ + bool backIsExist(); + /** + * @brief forwardIsExist forward目录是否存在 + * 该函数只测试计算机中是否包含forward目录 + * @return + */ + bool forwardIsExist(); + + +private: + QList m_list; + int m_threshold; + int m_index; + + friend QDebug operator<<(QDebug beg, const HistoryStack &stack); + + bool needCheckExist(const DUrl &url); + bool checkPathIsExist(const DUrl &url); +}; + +QT_BEGIN_NAMESPACE +QDebug operator<<(QDebug beg, const HistoryStack &stack); +QT_END_NAMESPACE + +#endif // HISTORYSTACK_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/private/dfiledialog_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/private/dfiledialog_p.h new file mode 100644 index 0000000..c4c7340 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/private/dfiledialog_p.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 ~ 2016 Uniontech Software Technology Co., Ltd. + * + * Author: luzhen + * + * Maintainer: zhengyouge + * luzhen + * + * 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 + * 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 +*/ + +#ifndef DFILEDIALOGPRIVATE_P_H +#define DFILEDIALOGPRIVATE_P_H + +#include +#include +#include + +class QEventLoop; +class DFileView; +class FileDialogStatusBar; + +class DFileDialogPrivate +{ +public: + int result = 0; + bool hideOnAccept = true; + bool allowMixedSelection = false; + + QFileDialog::FileMode fileMode = QFileDialog::AnyFile; + QFileDialog::AcceptMode acceptMode = QFileDialog::AcceptOpen; + QFileDialog::Options options; + QEventLoop *eventLoop = Q_NULLPTR; + QStringList nameFilters; + + DFileView *view = Q_NULLPTR; + int currentNameFilterIndex = -1; + QDir::Filters filters = nullptr; + QString currentInputName; + mutable QModelIndexList orderedSelectedList; + FileDialogStatusBar *statusBar; + +public: + QList orderedSelectedUrls() const; + bool checkFileSuffix(const QString &fileName, const int &filterIndex, QString &suffix) const; +}; + +#endif // DFILEDIALOGPRIVATE_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/windowmanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/windowmanager.cpp new file mode 100644 index 0000000..967b87b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/windowmanager.cpp @@ -0,0 +1,433 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "windowmanager.h" +#include "dfilemanagerwindow.h" +#include "dabstractfilewatcher.h" +#include "dabstractfileinfo.h" +#include "dfileservices.h" +#include "dfmapplication.h" +#include "dfmsettings.h" +#include "drootfilemanager.h" +#include "app/define.h" +#include "app/filesignalmanager.h" + +#include "fileoperations/filejob.h" + +#include "dialogs/dialogmanager.h" + +#include "qobjecthelper.h" + +#include "singleton.h" +#include "vault/vaulthelper.h" +#include "shutil/fileutils.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +DTK_USE_NAMESPACE + +DFM_USE_NAMESPACE + +enum NetWmState { + NetWmStateAbove = 0x1, + NetWmStateBelow = 0x2, + NetWmStateFullScreen = 0x4, + NetWmStateMaximizedHorz = 0x8, + NetWmStateMaximizedVert = 0x10, + NetWmStateModal = 0x20, + NetWmStateStaysOnTop = 0x40, + NetWmStateDemandsAttention = 0x80 +}; + +Q_DECLARE_FLAGS(NetWmStates, NetWmState) + +QHash WindowManager::m_windows; +int WindowManager::m_count = 0; + +WindowManager::WindowManager(QObject *parent) : QObject(parent) +{ +#ifdef AUTO_RESTART_DEAMON + m_restartProcessTimer = new QTimer(this); + m_restartProcessTimer->setInterval(1000 * 60 * 5); +#endif + initConnect(); +} + +class WindowManager_ : public WindowManager {}; +Q_GLOBAL_STATIC(WindowManager_, wmGlobal) + +WindowManager *WindowManager::instance() +{ + return wmGlobal; +} + +WindowManager::~WindowManager() +{ + +} + +void WindowManager::initConnect() +{ + connect(fileSignalManager, &FileSignalManager::requestOpenNewWindowByUrl, this, &WindowManager::showNewWindow); + connect(fileSignalManager, &FileSignalManager::aboutToCloseLastActivedWindow, this, &WindowManager::onLastActivedWindowClosed); + connect(qApp, &QApplication::aboutToQuit, this, [ = ]() { + fileSignalManager->requestCloseListen(); + DFMGlobal::setAppQuiting(); + qInfo() << "app quiting !"; + }); + connect(fileSignalManager, &FileSignalManager::requestShowNewWindows, this, &WindowManager::onShowNewWindow, + Qt::QueuedConnection); + connect(DRootFileManager::instance(), &DRootFileManager::queryRootFileFinsh, this, &WindowManager::onShowNewWindow, + Qt::QueuedConnection); + connect(fileSignalManager, &FileSignalManager::requestRemoveSmbUrl, this, &WindowManager::onRemoveNeedShowSmbUrl); + +#ifdef AUTO_RESTART_DEAMON + connect(m_restartProcessTimer, &QTimer::timeout, this, &WindowManager::reastartAppProcess); +#endif +} + +void WindowManager::loadWindowState(DFileManagerWindow *window) +{ + const QVariantMap &state = DFMApplication::appObtuselySetting()->value("WindowManager", "WindowState").toMap(); + + int width = state.value("width").toInt(); + int height = state.value("height").toInt(); + NetWmStates windowState = static_cast(state.value("state").toInt()); + // fix bug 30932,获取全屏属性,必须是width全屏和height全屏熟悉都满足,才判断是全屏 + if ((m_windows.size() == 0) && ((windowState & NetWmStateMaximizedHorz) != 0 && (windowState & NetWmStateMaximizedVert) != 0)) { + window->showMaximized(); + } else { + window->resize(width, height); + } +} + + +void WindowManager::saveWindowState(DFileManagerWindow *window) +{ + /// The power by dxcb platform plugin + NetWmStates states = static_cast(window->window()->windowHandle()->property("_d_netWmStates").toInt()); + QVariantMap state; + // fix bug 30932,获取全屏属性,必须是width全屏和height全屏熟悉都满足,才判断是全屏 + if ((states & NetWmStateMaximizedHorz) == 0 || (states & NetWmStateMaximizedVert) == 0) { + state["width"] = window->size().width(); + state["height"] = window->size().height(); + } else { + const QVariantMap &state1 = DFMApplication::appObtuselySetting()->value("WindowManager", "WindowState").toMap(); + state["width"] = state1.value("width").toInt(); + state["height"] = state1.value("height").toInt(); + state["state"] = static_cast(states); + } + DFMApplication::appObtuselySetting()->setValue("WindowManager", "WindowState", state); +} + +DUrl WindowManager::getUrlByWindowId(quint64 windowId) +{ + if (getWindowById(windowId)) { + DFileManagerWindow *window = qobject_cast(getWindowById(windowId)); + return window->currentUrl(); + } + return DUrl::fromLocalFile(QDir::homePath()); +} + +bool WindowManager::tabAddableByWinId(const quint64 &winId) +{ + DFileManagerWindow *window = qobject_cast(getWindowById(winId)); + if (window) + return window->tabAddable(); + return false; + +} + +bool WindowManager::enableAutoQuit() const +{ +#ifdef AUTO_RESTART_DEAMON + return m_enableAutoQuit; +#else + return false; +#endif +} + +void WindowManager::clearWindowActions() +{ + for (auto win : m_windows.keys()) { + QWidget *window = const_cast(win); + DFileManagerWindow *fmWin = qobject_cast(window); + if (fmWin) + fmWin->clearActions(); + } +} + +void WindowManager::showNewWindow(const DUrl &url, const bool &isNewWindow) +{ + if (!DFMGlobal::isInitAppOver() || DFMGlobal::isAppQuiting()) { + qInfo() << "window app not init over or app quit! " << isNewWindow << url; + return; + } + bool tempNewWindow = isNewWindow; + if (url.scheme() == SMB_SCHEME && !url.host().isEmpty() && !url.path().isEmpty()) + tempNewWindow = true; + if (!tempNewWindow) { + for (int i = 0; i < m_windows.count(); i++) { + QWidget *window = const_cast(m_windows.keys().at(i)); + DUrl currentUrl = static_cast(window)->currentUrl(); + if (currentUrl == url) { + DFileManagerWindow *wd = static_cast(window); + qDebug() << currentUrl << wd; + if (wd->isMinimized()) { + wd->setWindowState(wd->windowState() & ~Qt::WindowMinimized); + } + qApp->setActiveWindow(wd); + return; + } + } + } + // 处理同一个smb在挂载时,第二个窗口不要启动,等待这个一个smb挂载结束了在启动窗口 + if (url.scheme() == SMB_SCHEME && !url.host().isEmpty() && !url.path().isEmpty()) { + DUrl smbUrl(url); + QString smbShareName = url.path().mid(1); + smbShareName = smbShareName.mid(0, smbShareName.indexOf("/")); + smbUrl.setPath("/" + smbShareName); + if (!DRootFileManager::instance()->isRootFileInited() || + !DRootFileManager::instance()->isRootFileContainSmb(url)) { + QMutexLocker lk(&m_smbPointUrlMutex); + if (m_smbPointUrl.keys().contains(smbUrl)) { + m_smbPointUrl.insert(smbUrl, url); + return; + } else { + m_smbPointUrl.insert(smbUrl, DUrl()); + } + } + } + QX11Info::setAppTime(QX11Info::appUserTime()); + DFileManagerWindow *window = new DFileManagerWindow(url.isEmpty() ? DFMApplication::instance()->appUrlAttribute(DFMApplication::AA_UrlOfNewWindow) : url); + loadWindowState(window); + // fix bug 59239 drag事件的接受者的drop事件和发起drag事件的发起者的mousemove事件处理完成才能 + // 析构本窗口,所以去掉属性Qt::WA_DeleteOnClose + + qInfo() << "new window" << window->winId() << url; + + connect(window, &DFileManagerWindow::aboutToClose, + this, &WindowManager::onWindowClosed); + + m_windows.insert(window, window->winId()); + window->requestToSelectUrls(); //###: here, when selected files and then drag a tab to create a new window. + // will select these files again in new window. + + if (m_windows.count() == 1) { + QPoint pos = QCursor::pos(); + QRect currentScreenGeometry; + + for (QScreen *screen : qApp->screens()) { + if (screen->geometry().contains(pos)) { + currentScreenGeometry = screen->geometry(); + } + } + + if (currentScreenGeometry.isEmpty()) { + currentScreenGeometry = qApp->primaryScreen()->geometry(); + } + + window->moveCenter(currentScreenGeometry.center()); + } + + //fix bug71721 先移动到对应位置再show防止出现卡其他位置画面的问题 + window->show(); + + // 修复bug-45226 文管弹出一个模态窗后,再次弹出文管框, + // 该模态框将失去焦点,无法正常显示 + if (!VaultHelper::isModel) + qApp->setActiveWindow(window); +} + + +quint64 WindowManager::getWindowId(const QWidget *window) +{ + int winId = static_cast(m_windows.value(window->topLevelWidget(), 0)); + + if (winId != 0) + return static_cast(winId); + + const QWidget *newW = window; + + while (newW) { + if (newW->inherits("DFileManagerWindow")) { + return newW->winId(); + } + + newW = newW->parentWidget(); + } + + return window->window()->internalWinId(); +} + +QWidget *WindowManager::getWindowById(quint64 winId) +{ + if (winId <= 0) + return Q_NULLPTR; + + const QWidget *widget = m_windows.key(winId); + + if (widget) + return const_cast(widget); + + for (QWidget *top_level_widget : qApp->topLevelWidgets()) { + if (top_level_widget->internalWinId() == winId) + return top_level_widget; + } + + return Q_NULLPTR; +} + +void WindowManager::reastartAppProcess() +{ + if (m_windows.count() == 0) { + if (dialogManager->isTaskDialogEmpty()) { + // 当没有顶级窗口时才允许应用自动退出 + if (qApp->topLevelWindows().isEmpty()) { + qApp->quit(); + } + } + } +} + +void WindowManager::setEnableAutoQuit(bool enableAutoQuit) +{ +#ifdef AUTO_RESTART_DEAMON + if (m_enableAutoQuit == enableAutoQuit) + return; + + m_enableAutoQuit = enableAutoQuit; + + if (m_enableAutoQuit) { + m_restartProcessTimer->start(); + } else { + m_restartProcessTimer->stop(); + } +#else + Q_UNUSED(enableAutoQuit) +#endif +} + +void WindowManager::onWindowClosed() +{ + if (m_windows.count() <= 0) + return; + DFileManagerWindow *window = qobject_cast(sender()); + if (m_windows.count() == 1) { + if (window && window->getCanDestruct()) { + if (!m_lastWindow && window != m_lastWindow) + m_lastWindow->deleteLater(); + m_lastWindow = window; + } + saveWindowState(window); + dialogManager->closeAllPropertyDialog(); + } else if (window && window->getCanDestruct()) { + // fix bug 59239 drag事件的接受者的drop事件和发起drag事件的发起者的mousemove事件处理完成才能 + // 析构本窗口,检查当前窗口是否可以析构 + QPointer pwindow = window; + QTimer::singleShot(1000, this, [ = ]() { + if (pwindow) + pwindow->deleteLater(); + }); + qInfo() << "window deletelater !"; + } + m_windows.remove(static_cast(sender())); + + if (window && window->currentUrl().scheme() == PLUGIN_SCHEME) { + qInfo() << "delete plugin view:" << window->currentUrl().host(); + // NOTE [REN] 防止插件窗口关闭后,后台将信号发送到该窗口导致崩溃 + window->getFileView()->deleteLater(); + } +} + +void WindowManager::onLastActivedWindowClosed(quint64 winId) +{ + QList winIds = m_windows.values(); + foreach (quint64 id, winIds) { + if (id != winId) { + getWindowById(id)->close(); + } + } + + if (QWidget *window = getWindowById(winId)) + window->close(); + //fix bug 32774 在复制大量文件时,用菜单的退出按钮,会造成这里qApp退出(等待拷贝线程),dfilesystemmodel中的addfile中qApp->processEvents + //上的while循环等待,卡死主进程,所以复制进度条也卡死 +// qApp->quit(); +} + + +/*! + * \brief onShowNewWindow 同一个smb共享下的url正在挂载时或者启动没有获取挂载目录结束阻塞不显示, + * + * 当挂载这个smb或者获取挂载目录结束后,在创建相应的window并显示 + */ +void WindowManager::onShowNewWindow() +{ + if (!DRootFileManager::instance()->isRootFileInited()) + return; + QMutexLocker lk(&m_smbPointUrlMutex); + QList smbUrlKey = m_smbPointUrl.keys(); + QList::Iterator it = smbUrlKey.begin(); + while (it != smbUrlKey.end()) { + if (DRootFileManager::instance()->isRootFileContainSmb(*it)) { + QList showUrls = m_smbPointUrl.values(*it); + m_smbPointUrl.remove(*it); + for (auto showUrl : showUrls) { + if (showUrl.isValid()) + showNewWindow(showUrl, true); + } + } + ++it; + } +} +/*! + * \brief onRemoveNeedShowSmbUrl 同一个smb共享下的url正在挂载时或者启动没有获取挂载目录结束阻塞不显示, + * + * 当挂载失败后,清理掉要显示的窗口 + * + * \param url 挂载失败的smb的url + */ +void WindowManager::onRemoveNeedShowSmbUrl(const DUrl &url) +{ + if (url.scheme() != SMB_SCHEME || url.host().isEmpty() || url.path().isNull()) { + qWarning() << "url is not a valid smb url, url = " << url; + return; + } + DUrl smbUrl(url); + QString shareName = url.path(); + shareName = shareName.mid(1); + shareName = shareName.mid(0, shareName.indexOf("/")); + smbUrl.setPath("/" + shareName); + QMutexLocker lk(&m_smbPointUrlMutex); + m_smbPointUrl.remove(smbUrl); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/windowmanager.h b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/windowmanager.h new file mode 100644 index 0000000..3bd3a9c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-lib/views/windowmanager.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef WINDOWMANAGER_H +#define WINDOWMANAGER_H + +#include +#include +#include + +class DFileManagerWindow; +class DUrl; +class DFMEvent; +class QTimer; + + +class WindowManager : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool enableAutoQuit READ enableAutoQuit WRITE setEnableAutoQuit) + +public: + static WindowManager *instance(); + + ~WindowManager(); + void initConnect(); + + void loadWindowState(DFileManagerWindow* window); + void saveWindowState(DFileManagerWindow* window); + inline QHash getWindows(){return m_windows;} + + static DUrl getUrlByWindowId(quint64 windowId); + + static bool tabAddableByWinId(const quint64& winId); + + bool enableAutoQuit() const; + + void clearWindowActions(); + +signals: + void start(const QString &src); + +public slots: + void showNewWindow(const DUrl &url, const bool &isNewWindow=false); + static quint64 getWindowId(const QWidget *window); + static QWidget* getWindowById(quint64 winId); + void reastartAppProcess(); + + void setEnableAutoQuit(bool enableAutoQuit); + +private slots: + void onWindowClosed(); + void onLastActivedWindowClosed(quint64 winId); + void onShowNewWindow(); + void onRemoveNeedShowSmbUrl(const DUrl &url); + +protected: + explicit WindowManager(QObject *parent = nullptr); + +private: + static QHash m_windows; + static int m_count; + DFileManagerWindow *m_lastWindow = nullptr; + QMultiHash m_smbPointUrl; + QMutex m_smbPointUrlMutex; + +#ifdef AUTO_RESTART_DEAMON + QTimer* m_restartProcessTimer = NULL; + bool m_enableAutoQuit = false; +#endif +}; + +#endif // WINDOWMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/ImageMenuPlugin.json b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/ImageMenuPlugin.json new file mode 100644 index 0000000..1e81138 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/ImageMenuPlugin.json @@ -0,0 +1,3 @@ +{ + "Keys" : [ ] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/ImageMenuPlugin.pro b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/ImageMenuPlugin.pro new file mode 100644 index 0000000..6307f6f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/ImageMenuPlugin.pro @@ -0,0 +1,30 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2016-11-29T11:20:23 +# +#------------------------------------------------- + +QT += core gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ImageMenuPlugin +TEMPLATE = lib +CONFIG += plugin c++11 + +include(../../common/common.pri) +include(../plugininterfaces/plugininterfaces.pri) + +SOURCES += imagemenuplugin.cpp + +HEADERS += imagemenuplugin.h +DISTFILES += ImageMenuPlugin.json + +DESTDIR = ../menu + +unix { + target.path = $$PLUGINDIR/menu + INSTALLS += target +} + +RESOURCES += \ + pluginicons.qrc diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/imagemenuplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/imagemenuplugin.cpp new file mode 100644 index 0000000..31cbbbc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/imagemenuplugin.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "imagemenuplugin.h" +#include "interfaces/dfilemenu.h" +#include +#include +#include +#include + + +ImageMenuPlugin::ImageMenuPlugin(QObject *parent) : + QObject(parent) +{ + +} + +QList ImageMenuPlugin::additionalIcons(const QString &file) +{ + QList icons; + QIcon icon(":/images/phone.svg"); +// icons << icon; + return icons; +} + +QList ImageMenuPlugin::additionalMenu(const QStringList &files, const QString& currentDir) +{ + QList actions; + QAction* formatAction = new QAction(tr("Format convert"), this); + QAction* testAction = new QAction(tr("Format test"), this); + QAction* sublAction = new QAction(tr("SubMenu"), this); + + actions << formatAction << testAction << sublAction; + + + DFileMenu* subsubmenu = new DFileMenu; + QList subsublActions; + for (int i=0; i <10; i++) { + QAction* action = new QAction(QString::number(i), this); + connect(action, &QAction::triggered, [](){ + qDebug() << "=======12345======="; + }); + subsublActions.append(action); + } + subsubmenu->addActions(subsublActions); + + + DFileMenu* menu = new DFileMenu; + QList sublActions; + for (int i=0; i <10; i++) { + QAction* action = new QAction(QString::number(i), this); + connect(action, &QAction::triggered, [=](){ + qDebug() << "======dsd========"; + }); + sublActions.append(action); + + if (i % 2 == 0){ + action->setMenu(subsubmenu); + } + } + menu->addActions(sublActions); + sublAction->setMenu(menu); + + connect(formatAction, &QAction::triggered, this, &ImageMenuPlugin::handleFormat); + connect(testAction, &QAction::triggered, this, &ImageMenuPlugin::handleTest); + + return actions; +} + +QList ImageMenuPlugin::additionalEmptyMenu(const QString ¤tDir) +{ + QList actions; + QAction* formatAction = new QAction(tr("dssdds"), this); + QAction* testAction = new QAction(tr("sdsdds"), this); + QAction* sublAction = new QAction(tr("sdds"), this); + + actions << formatAction << testAction << sublAction; + + return actions; +} + +void ImageMenuPlugin::handleFormat() +{ + qDebug() << "1111111111111111"; +} + +void ImageMenuPlugin::handleTest() +{ + qDebug() << "2222222222222222"; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/imagemenuplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/imagemenuplugin.h new file mode 100644 index 0000000..1089d5b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/imagemenuplugin.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef IMAGEMENUPLUGIN_H +#define IMAGEMENUPLUGIN_H + +#include +#include "../plugininterfaces/menu/menuinterface.h" + + +class ImageMenuPlugin : public QObject, public MenuInterface +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID MenuInterface_iid FILE "ImageMenuPlugin.json") + Q_INTERFACES(MenuInterface) + +public: + ImageMenuPlugin(QObject *parent = 0); + + QList additionalIcons(const QString &file); + QList additionalMenu(const QStringList &files, const QString& currentDir); + QList additionalEmptyMenu(const QString& currentDir); + +public: + void handleFormat(); + void handleTest(); +}; + +#endif // IMAGEMENUPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/images/phone.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/images/phone.svg new file mode 100644 index 0000000..3a544da --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/images/phone.svg @@ -0,0 +1,16 @@ + + + + Android_phone_normal_16px + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/pluginicons.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/pluginicons.qrc new file mode 100644 index 0000000..0ef4d94 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/ImageMenuPlugin/pluginicons.qrc @@ -0,0 +1,5 @@ + + + images/phone.svg + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/dde-file-manager-plugins.pro b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/dde-file-manager-plugins.pro new file mode 100644 index 0000000..d9d5f7d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/dde-file-manager-plugins.pro @@ -0,0 +1,34 @@ +TEMPLATE = subdirs + +include(../common/common.pri) + +IS_TEST_VIEW_PLUGIN = False + +isEqual(ARCH, mips64) | isEqual(ARCH, mips32) | isEqual(ARCH, loongarch64) { +# SUBDIRS += \ +# showfile +} + +isEqual(IS_TEST_VIEW_PLUGIN, True){ + SUBDIRS += \ + pluginView +} + +SUBDIRS += \ + pluginPreview + +TRANSLATIONS += $$PWD/translations/$${TARGET}.ts \ + $$PWD/translations/$${TARGET}_zh_CN.ts + +CONFIG(release, debug|release) { + !system($$PWD/generate_translations.sh): error("Failed to generate translation") + !system($$PWD/update_translations.sh): error("Failed to generate translation") +} + +unix { + target.path = $$PLUGIN_INSTALL_DIR + + translations.path = $${PREFIX}/share/dde-file-manager/translations + translations.files = $$PWD/translations/*.qm + INSTALLS += target translations +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/generate_translations.sh b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/generate_translations.sh new file mode 100755 index 0000000..c908092 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/generate_translations.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# this file is used to auto-generate .qm file from .ts file. +# author: shibowen at linuxdeepin.com + +ts_list=(`ls translations/*.ts`) + +for ts in "${ts_list[@]}" +do + printf "\nprocess ${ts}\n" + lrelease "${ts}" +done diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/dde-image-preview-plugin.json b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/dde-image-preview-plugin.json new file mode 100644 index 0000000..63dabfd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/dde-image-preview-plugin.json @@ -0,0 +1,3 @@ +{ + "Keys" : ["image/*"] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/dde-image-preview-plugin.pri b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/dde-image-preview-plugin.pri new file mode 100644 index 0000000..1648793 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/dde-image-preview-plugin.pri @@ -0,0 +1,9 @@ +SOURCES += \ + imageview.cpp \ + imagepreview.cpp \ + $$PWD/imagepreviewplugin.cpp + +HEADERS += \ + imageview.h \ + imagepreview.h \ + $$PWD/imagepreviewplugin.h diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/dde-image-preview-plugin.pro b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/dde-image-preview-plugin.pro new file mode 100644 index 0000000..9e6ebcd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/dde-image-preview-plugin.pro @@ -0,0 +1,34 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-03-31T16:00:06 +# +#------------------------------------------------- + +QT += widgets + +TARGET = dde-image-preview-plugin +TEMPLATE = lib + +CONFIG += plugin c++11 link_pkgconfig +PKGCONFIG += dtkwidget dtkgui + +include(../../../common/common.pri) +include(dde-image-preview-plugin.pri) + +DISTFILES += dde-image-preview-plugin.json + +PLUGIN_INSTALL_DIR = $$PLUGINDIR/previews + +DESTDIR = $$top_srcdir/plugins/previews + +unix { + target.path = $$PLUGIN_INSTALL_DIR + INSTALLS += target +} + +#安全加固 +QMAKE_CXXFLAGS += -fstack-protector-all +QMAKE_LFLAGS += -z now -fPIC +isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + QMAKE_LFLAGS += -z noexecstack -z relro +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/icon.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/icon.qrc new file mode 100644 index 0000000..2af2f35 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/icon.qrc @@ -0,0 +1,3 @@ + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/icons.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/icons.qrc new file mode 100644 index 0000000..bf380c1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/icons.qrc @@ -0,0 +1,7 @@ + + + icons/close_round_press.png + icons/close_round_normal.png + icons/close_round_hover.png + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imagepreview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imagepreview.cpp new file mode 100644 index 0000000..9002ad6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imagepreview.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "imagepreview.h" +#include "dabstractfileinfo.h" +#include "dfileservices.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "imageview.h" + +DWIDGET_USE_NAMESPACE + +DFM_USE_NAMESPACE + +ImagePreview::ImagePreview(QObject *parent) + : DFMFilePreview(parent) +{ +} + +ImagePreview::~ImagePreview() +{ + if (m_imageView) + m_imageView->deleteLater(); + + if (m_messageStatusBar) + m_messageStatusBar->deleteLater(); +} + +bool ImagePreview::canPreview(const QUrl &url, QByteArray *format) const +{ + QByteArray f = QImageReader::imageFormat(url.toLocalFile()); + + if (f.isEmpty()) { + QMimeDatabase mimeDatabase; + + const QMimeType &mt = mimeDatabase.mimeTypeForFile(url.toLocalFile(), QMimeDatabase::MatchContent); + + f = mt.preferredSuffix().toLatin1(); + + if (f.isEmpty()) { + if (format) { + *format = f; + } + + return false; + } + } + + if (format) { + *format = f; + } + + return QImageReader::supportedImageFormats().contains(f); +} + +void ImagePreview::initialize(QWidget *window, QWidget *statusBar) +{ + Q_UNUSED(window) + + m_messageStatusBar = new QLabel(statusBar); + m_messageStatusBar->setStyleSheet("QLabel{font-family: Helvetica;\ + font-size: 12px;\ + font-weight: 300;}"); + + DAnchorsBase(m_messageStatusBar).setCenterIn(statusBar); +} + +bool ImagePreview::setFileUrl(const DUrl &url) +{ + if (m_url == url) + return true; + + DUrl tmpUrl = url; + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, url); + + if (!info) + return false; + + if (info->canRedirectionFileUrl()) { + tmpUrl = info->redirectedFileUrl(); + } + + if (!tmpUrl.isLocalFile()) + return false; + + QByteArray format; + + if (!canPreview(tmpUrl, &format)) + return false; + + m_url = tmpUrl; + + if (!m_imageView) + m_imageView = new ImageView(tmpUrl.toLocalFile(), format); + else + m_imageView->setFile(tmpUrl.toLocalFile(), format); + + const QSize &image_size = m_imageView->sourceSize(); + + m_messageStatusBar->setText(QString("%1x%2").arg(image_size.width()).arg(image_size.height())); + m_messageStatusBar->adjustSize(); + + m_title = QFileInfo(tmpUrl.toLocalFile()).fileName(); + + Q_EMIT titleChanged(); + + return true; +} + +DUrl ImagePreview::fileUrl() const +{ + return m_url; +} + +QWidget *ImagePreview::contentWidget() const +{ + return m_imageView; +} + +QString ImagePreview::title() const +{ + return m_title; +} + +void ImagePreview::copyFile() const +{ + QMimeData *data = new QMimeData(); + QImage image(m_url.toLocalFile()); + + if (!image.isNull()) + data->setImageData(image); + + DFMGlobal::setUrlsToClipboard({m_url}, DFMGlobal::CopyAction, data); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imagepreview.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imagepreview.h new file mode 100644 index 0000000..20b4eab --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imagepreview.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef IMAGEPREVIEW_H +#define IMAGEPREVIEW_H + +#include +#include +#include + +#include "dfmfilepreview.h" +#include "durl.h" + +class QLabel; + +class ImageView; + +class ImagePreview : public DFM_NAMESPACE::DFMFilePreview +{ + Q_PLUGIN_METADATA(IID PreviewInterface_iid FILE "dde-image-preview-plugin.json") + Q_INTERFACES(PreviewInterface) +public: + explicit ImagePreview(QObject *parent = nullptr); + ~ImagePreview() override; + + bool canPreview(const QUrl &url, QByteArray *format = nullptr) const; + + void initialize(QWidget *window, QWidget *statusBar) override; + + bool setFileUrl(const DUrl &url) override; + DUrl fileUrl() const override; + + QWidget *contentWidget() const override; + + QString title() const override; + + void copyFile() const override; + +private: + DUrl m_url; + QPointer m_messageStatusBar; + QPointer m_imageView; + QString m_title; +}; + +#endif // IMAGEPREVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imagepreviewplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imagepreviewplugin.cpp new file mode 100644 index 0000000..041d09c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imagepreviewplugin.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "imagepreviewplugin.h" + +DFM_USE_NAMESPACE + +DFMFilePreview *ImagePreviewPlugin::create(const QString &key) +{ + Q_UNUSED(key) + + return new ImagePreview(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imagepreviewplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imagepreviewplugin.h new file mode 100644 index 0000000..3942be2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imagepreviewplugin.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef IMAGEPREVIEWPLUGIN_H +#define IMAGEPREVIEWPLUGIN_H + + +#include "dfmfilepreviewplugin.h" +#include "imagepreview.h" + +class ImagePreviewPlugin : public DFM_NAMESPACE::DFMFilePreviewPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DFMFilePreviewFactoryInterface_iid FILE "dde-image-preview-plugin.json") + +public slots: + DFM_NAMESPACE::DFMFilePreview *create(const QString &key) Q_DECL_OVERRIDE; +}; + +#endif // IMAGEPREVIEWPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imageview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imageview.cpp new file mode 100644 index 0000000..3d87ba9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imageview.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "imageview.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN_SIZE QSize(400, 300) + +ImageView::ImageView(const QString &fileName, const QByteArray &format, QWidget *parent) + : QLabel(parent) +{ + setFile(fileName, format); + setMinimumSize(MIN_SIZE); + setAlignment(Qt::AlignCenter); +} + +void ImageView::setFile(const QString &fileName, const QByteArray &format) +{ + if (format == QByteArrayLiteral("gif")) { + if (movie) { + movie->stop(); // blumia: we need to stop it first before we load a new file + movie->setFileName(fileName); + } else { + movie = new QMovie(fileName, format, this); + } + + setMovie(movie); + movie->start(); + m_sourceSize = movie->frameRect().size(); + + return; + } else { + setMovie(nullptr); + } + + if (movie) { + QMovie * tmpMovie = movie; + movie = nullptr; + tmpMovie->stop(); + tmpMovie->disconnect(); + tmpMovie->deleteLater(); + } + + QImageReader reader(fileName, format); + + m_sourceSize = reader.size(); + + const QSize &dsize = qApp->desktop()->size(); + qreal device_pixel_ratio = this->devicePixelRatioF(); + + QPixmap pixmap = QPixmap::fromImageReader(&reader).scaled(QSize(qMin(static_cast(dsize.width() * 0.7 * device_pixel_ratio), m_sourceSize.width()), + qMin(static_cast(dsize.height() * 0.8 * device_pixel_ratio), m_sourceSize.height())), + Qt::KeepAspectRatio, Qt::SmoothTransformation); + + pixmap.setDevicePixelRatio(device_pixel_ratio); + + setPixmap(pixmap); +} + +QSize ImageView::sourceSize() const +{ + return m_sourceSize; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imageview.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imageview.h new file mode 100644 index 0000000..e61243f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/imageview.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef IMAGEVIEW_H +#define IMAGEVIEW_H + +#include + +class ImageView : public QLabel +{ + Q_OBJECT +public: + explicit ImageView(const QString &fileName, const QByteArray &format, QWidget *parent = nullptr); + + void setFile(const QString &fileName, const QByteArray &format); + QSize sourceSize() const; + +private: + QSize m_sourceSize; + QMovie *movie = nullptr; +}; + +#endif // IMAGEVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/main.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/main.cpp new file mode 100644 index 0000000..b67784f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/main.cpp @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2017 Deepin Technology Co., Ltd. + * + * 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. + **/ + +#include "dfmfilepreviewplugin.h" + +#include "imagepreview.h" + +DFM_BEGIN_NAMESPACE + +class ImagePreviewPlugin : public DFMFilePreviewPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DFMFilePreviewFactoryInterface_iid FILE "dde-image-preview-plugin.json") + +public: + DFMFilePreview *create(const QString &key) Q_DECL_OVERRIDE + { + Q_UNUSED(key) + + return new ImagePreview(); + } +}; + +DFM_END_NAMESPACE + +#include "main.moc" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/theme.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/theme.qrc new file mode 100644 index 0000000..7646d2b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-image-preview-plugin/theme.qrc @@ -0,0 +1 @@ + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin.ts b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin.ts new file mode 100644 index 0000000..92ab682 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin.ts @@ -0,0 +1,17 @@ + + + + + MusicMessageView + + + Artist: + + + + + Album: + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/dde-music-preview-plugin.json b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/dde-music-preview-plugin.json new file mode 100644 index 0000000..26a0901 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/dde-music-preview-plugin.json @@ -0,0 +1,3 @@ +{ + "Keys" : ["audio/*"] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/dde-music-preview-plugin.pri b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/dde-music-preview-plugin.pri new file mode 100644 index 0000000..7698023 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/dde-music-preview-plugin.pri @@ -0,0 +1,15 @@ +SOURCES += \ + toolbarframe.cpp \ + musicpreview.cpp \ + musicmessageview.cpp \ + $$PWD/musicpreviewplugin.cpp + +HEADERS += \ + toolbarframe.h \ + musicmessageview.h \ + musicpreview.h \ + $$PWD/musicpreviewplugin.h + +RESOURCES += \ + dde-music-preview-plugin.qrc + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/dde-music-preview-plugin.pro b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/dde-music-preview-plugin.pro new file mode 100644 index 0000000..0a97962 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/dde-music-preview-plugin.pro @@ -0,0 +1,35 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-04-20T15:40:08 +# +#------------------------------------------------- + +QT += core gui widgets multimedia + +TARGET = dde-music-preview-plugin +TEMPLATE = lib + +PKGCONFIG += taglib + +CONFIG += c++11 plugin link_pkgconfig + +include(../../../common/common.pri) +include(dde-music-preview-plugin.pri) + +DISTFILES += dde-music-preview-plugin.json + +PLUGIN_INSTALL_DIR = $$PLUGINDIR/previews + +DESTDIR = $$top_srcdir/plugins/previews + +unix { + target.path = $$PLUGIN_INSTALL_DIR + INSTALLS += target +} + +#安全加固 +QMAKE_CXXFLAGS += -fstack-protector-all +QMAKE_LFLAGS += -z now -fPIC +isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + QMAKE_LFLAGS += -z noexecstack -z relro +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/dde-music-preview-plugin.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/dde-music-preview-plugin.qrc new file mode 100644 index 0000000..708996f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/dde-music-preview-plugin.qrc @@ -0,0 +1,11 @@ + + + icons/start_pressed.png + icons/start_normal.png + icons/start_hover.png + icons/pause_pressed.png + icons/pause_normal.png + icons/pause_hover.png + icons/default_music_cover.png + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/default_music_cover.png b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/default_music_cover.png new file mode 100644 index 0000000..1ed3bcc Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/default_music_cover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/pause_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/pause_hover.png new file mode 100644 index 0000000..3ddfea2 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/pause_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/pause_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/pause_normal.png new file mode 100644 index 0000000..33113b8 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/pause_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/pause_pressed.png b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/pause_pressed.png new file mode 100644 index 0000000..e98e3ed Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/pause_pressed.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/start_hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/start_hover.png new file mode 100644 index 0000000..8ec935c Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/start_hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/start_normal.png b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/start_normal.png new file mode 100644 index 0000000..9e0fad0 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/start_normal.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/start_pressed.png b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/start_pressed.png new file mode 100644 index 0000000..8bb3243 Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/icons/start_pressed.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/main.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/main.cpp new file mode 100644 index 0000000..e5a5286 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/main.cpp @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2017 Deepin Technology Co., Ltd. + * + * 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. + **/ + +#include "dfmfilepreviewplugin.h" +#include "musicpreview.h" + +DFM_BEGIN_NAMESPACE + +class MusicPreviewPlugin : public DFMFilePreviewPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DFMFilePreviewFactoryInterface_iid FILE "dde-music-preview-plugin.json") + +public: + DFMFilePreview *create(const QString &key) Q_DECL_OVERRIDE + { + Q_UNUSED(key) + + return new MusicPreview(); + } +}; + +DFM_END_NAMESPACE + +#include "main.moc" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicmessageview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicmessageview.cpp new file mode 100644 index 0000000..c5b0f55 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicmessageview.cpp @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "musicmessageview.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +MusicMessageView::MusicMessageView(const QString &uri, QWidget *parent) : + QFrame(parent), + m_uri(uri) +{ + initUI(); + localeCodes.insert("zh_CN", "GB18030"); +} + +void MusicMessageView::initUI() +{ + setFixedSize(600, 300); + + m_titleLabel = new QLabel(this); + m_titleLabel->setObjectName("Title"); + + m_artistLabel = new QLabel(this); + m_artistLabel->setObjectName("Artist"); + m_artistLabel->setText(tr("Artist:")); + m_artistValue = new QLabel(this); + m_artistValue->setObjectName("artistValue"); + + m_albumLabel = new QLabel(this); + m_albumLabel->setObjectName("Album"); + m_albumLabel->setText(tr("Album:")); + m_albumValue = new QLabel(this); + m_albumValue->setObjectName("albumValue"); + + m_imgLabel = new QLabel(this); + m_imgLabel->setFixedSize(QSize(240, 240)); + + m_player = new QMediaPlayer(this); + connect(m_player, &QMediaPlayer::mediaStatusChanged, this, &MusicMessageView::mediaStatusChanged); + + m_player->setMedia(QUrl::fromUserInput(m_uri)); + + QHBoxLayout *artistLayout = new QHBoxLayout; + artistLayout->addWidget(m_artistLabel); + artistLayout->addSpacing(5); + artistLayout->addWidget(m_artistValue, 1); + + QHBoxLayout *albumLayout = new QHBoxLayout; + albumLayout->addWidget(m_albumLabel); + albumLayout->addSpacing(5); + albumLayout->addWidget(m_albumValue, 1); + + QVBoxLayout *messageLayout = new QVBoxLayout; + messageLayout->setSpacing(0); + messageLayout->addWidget(m_titleLabel); + messageLayout->addSpacing(10); + messageLayout->addLayout(artistLayout); + messageLayout->addSpacing(3); + messageLayout->addLayout(albumLayout); + messageLayout->addStretch(); + + QHBoxLayout *mainLayout = new QHBoxLayout; + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->addWidget(m_imgLabel, 0, Qt::AlignTop); + mainLayout->addSpacing(15); + mainLayout->addLayout(messageLayout); + mainLayout->addStretch(); + + setLayout(mainLayout); + + setStyleSheet("QLabel#Title{" + "font-size: 18px;" + "font:demibold;" + "}" + "QLabel#Artist{" + "color: #5b5b5b;" + "font-size: 12px;" + "}" + "QLabel#Album{" + "color: #5b5b5b;" + "font-size: 12px;" + "}" + "QLabel#artistValue{" + "color: #5b5b5b;" + "font-size: 12px;" + "}" + "QLabel#albumValue{" + "color: #5b5b5b;" + "font-size: 12px;" + "}"); + +} + +void MusicMessageView::updateElidedText() +{ + QFont font; + font.setPixelSize(16); + QFontMetrics fm(font); + m_titleLabel->setText(fm.elidedText(m_title, Qt::ElideRight, width() - m_imgLabel->width() - 40 - m_margins)); + + font.setPixelSize(12); + fm = QFontMetrics(font); + m_artistValue->setText(fm.elidedText(m_artist, Qt::ElideRight, width() - m_imgLabel->width() - 40 - m_margins)); + m_albumValue->setText(fm.elidedText(m_album, Qt::ElideRight, width() - m_imgLabel->width() - 40 - m_margins)); +} + +void MusicMessageView::mediaStatusChanged(QMediaPlayer::MediaStatus status) +{ + if (status == QMediaPlayer::BufferedMedia || status == QMediaPlayer::LoadedMedia) { + MediaMeta meta = tagOpenMusicFile(m_uri); + m_title = meta.title; + if (m_title.isEmpty()) { + QFileInfo file(m_uri); + QString fileName = file.baseName(); + m_title = fileName; + } + m_artist = meta.artist; + if (m_artist.isEmpty()) + m_artist = QString(tr("unknown artist")); + + m_album = meta.album; + if (m_album.isEmpty()) + m_album = QString(tr("unknown album")); + + QImage img = m_player->metaData(QMediaMetaData::CoverArtImage).value(); + if (img.isNull()) { + img = QImage(":/icons/icons/default_music_cover.png"); + } + m_imgLabel->setPixmap(QPixmap::fromImage(img).scaled(m_imgLabel->size(), Qt::KeepAspectRatio)); + + m_player->deleteLater(); + + updateElidedText(); + } +} + +void MusicMessageView::resizeEvent(QResizeEvent *event) +{ + QFrame::resizeEvent(event); + m_margins = (event->size().height() - m_imgLabel->height()) / 2; + if ((event->size().width() - m_margins - 250) < m_imgLabel->width()) { + m_margins = event->size().width() - 250 - m_imgLabel->width(); + } + setContentsMargins(m_margins, m_margins, 0, m_margins); + updateElidedText(); +} + +QList MusicMessageView::detectEncodings(const QByteArray &rawData) +{ + QList charsets; + QByteArray charset = QTextCodec::codecForLocale()->name(); + charsets << charset; + + const char *data = rawData.data(); + int32_t len = rawData.size(); + + UCharsetDetector *csd; + const UCharsetMatch **csm; + int32_t matchCount = 0; + + UErrorCode status = U_ZERO_ERROR; + + csd = ucsdet_open(&status); + if (status != U_ZERO_ERROR) { + ucsdet_close(csd); + return charsets; + } + + ucsdet_setText(csd, data, len, &status); + if (status != U_ZERO_ERROR) { + ucsdet_close(csd); + return charsets; + } + + csm = ucsdet_detectAll(csd, &matchCount, &status); + if (status != U_ZERO_ERROR) { + ucsdet_close(csd); + return charsets; + } + + if (matchCount > 0) { + charsets.clear(); + } + + for (int32_t match = 0; match < matchCount; match += 1) { + const char *name = ucsdet_getName(csm[match], &status); + const char *lang = ucsdet_getLanguage(csm[match], &status); + if (lang == nullptr || strlen(lang) == 0) { + lang = "**"; + } + charsets << name; + } + + ucsdet_close(csd); + return charsets; +} + +bool MusicMessageView::isChinese(const QChar &c) +{ + return c.unicode() <= 0x9FBF && c.unicode() >= 0x4E00; +} + +MediaMeta MusicMessageView::tagOpenMusicFile(const QString &path) +{ + QUrl url(path); + TagLib::FileRef f(url.toLocalFile().toLocal8Bit()); + + TagLib::Tag *tag = f.tag(); + + if (!f.file()) { + qCritical() << "TagLib: open file failed:" << path << f.file(); + } + + if (!tag) { + qWarning() << "TagLib: no tag for media file" << path; + return MediaMeta(); + } + + MediaMeta meta; + characterEncodingTransform(meta, static_cast(tag)); + return meta; +} + +void MusicMessageView::characterEncodingTransform(MediaMeta &meta, void *obj) +{ + TagLib::Tag *tag = static_cast(obj); + bool encode = true; + encode &= tag->title().isNull() ? true : tag->title().isLatin1(); + encode &= tag->artist().isNull() ? true : tag->artist().isLatin1(); + encode &= tag->album().isNull() ? true : tag->album().isLatin1(); + + QByteArray detectByte; + QByteArray detectCodec; + if (encode) { + if (detectCodec.isEmpty()) { + detectByte += tag->title().toCString(); + detectByte += tag->artist().toCString(); + detectByte += tag->album().toCString(); + auto allDetectCodecs = detectEncodings(detectByte); + auto localeCode = localeCodes.value(QLocale::system().name()); + + auto iter = std::find_if(allDetectCodecs.begin(), allDetectCodecs.end(), + [localeCode](const QByteArray & curDetext) { + return (curDetext == "Big5" || curDetext == localeCode); + }); + + if (iter != allDetectCodecs.end()) { + detectCodec = *iter; + } + + if (detectCodec.isEmpty()) + detectCodec = allDetectCodecs.value(0); + + QString curStr = QString::fromLocal8Bit(tag->title().toCString()); + if (curStr.isEmpty()) + curStr = QString::fromLocal8Bit(tag->artist().toCString()); + if (curStr.isEmpty()) + curStr = QString::fromLocal8Bit(tag->album().toCString()); + + auto ret = std::any_of(curStr.begin(), curStr.end(), [this](const QChar & ch) { + return isChinese(ch); + }); + + if (ret) { + detectCodec = "GB18030"; + } + } + + QString detectCodecStr(detectCodec); + if (detectCodecStr.compare("utf-8", Qt::CaseInsensitive) == 0) { + meta.album = TStringToQString(tag->album()); + meta.artist = TStringToQString(tag->artist()); + meta.title = TStringToQString(tag->title()); + meta.codec = "UTF-8"; //info codec + } else { + QTextCodec *codec = QTextCodec::codecForName(detectCodec); + if (codec == nullptr) { + meta.album = TStringToQString(tag->album()); + meta.artist = TStringToQString(tag->artist()); + meta.title = TStringToQString(tag->title()); + } else { + meta.album = codec->toUnicode(tag->album().toCString()); + meta.artist = codec->toUnicode(tag->artist().toCString()); + meta.title = codec->toUnicode(tag->title().toCString()); + } + meta.codec = detectCodec; + } + } else { + meta.album = TStringToQString(tag->album()); + meta.artist = TStringToQString(tag->artist()); + meta.title = TStringToQString(tag->title()); + meta.codec = "UTF-8"; + } + + //empty str + meta.album = meta.album.simplified(); + meta.artist = meta.artist.simplified(); + meta.title = meta.title.simplified(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicmessageview.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicmessageview.h new file mode 100644 index 0000000..099ecc5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicmessageview.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef MUSICMESSAGEVIEW_H +#define MUSICMESSAGEVIEW_H + +#include +#include +class QLabel; + +/** + * @brief MediaMeta 音频文件信息结构体 + */ +struct MediaMeta { + QString title; + QString artist; + QString album; + QString codec; +}; + +class MusicMessageView : public QFrame +{ + Q_OBJECT +public: + explicit MusicMessageView(const QString &uri = "", QWidget *parent = nullptr); + void initUI(); + void updateElidedText(); + +signals: + +public slots: + void mediaStatusChanged(QMediaPlayer::MediaStatus status); + +protected: + void resizeEvent(QResizeEvent *event) override; + +private: + /** + * @brief detectEncodings 检测字符串字符编码 + * @param rawData 需要检测的字符串 + * @return 返回检测到的字符编码列表 + */ + QList detectEncodings(const QByteArray &rawData); + + /** + * @brief isChinese 检测字符是否是中文 + * @param c 需要检测的字符 + * @return true 为中文字符,反之亦然 + */ + bool isChinese(const QChar &c); + + /** + * @brief tagOpenMusicFile 使用taglib打开音频文件获取信息 + * @param path 音频文件路径 + * @return 音频文件信息 + */ + MediaMeta tagOpenMusicFile(const QString &path); + + /** + * @brief characterEncodingTransform 对音频文件信息字符数据进行转码 + * @param meta 音频文件信息对象,输出参数 + * @param obj taglib打开的文件对象 + */ + void characterEncodingTransform(MediaMeta &meta, void *obj); + +private: + QString m_uri; + QLabel *m_titleLabel; + QLabel *m_artistLabel; + QLabel *m_albumLabel; + QLabel *m_imgLabel; + QLabel *m_artistValue; + QLabel *m_albumValue; + + + QMediaPlayer *m_player; + + QString m_title; + QString m_artist; + QString m_album; + int m_margins; + QMap localeCodes; //! 区域与编码 +}; + +#endif // MUSICMESSAGEVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicpreview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicpreview.cpp new file mode 100644 index 0000000..4fda698 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicpreview.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "musicpreview.h" + +#include "dfileservices.h" +#include "dabstractfileinfo.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "toolbarframe.h" +#include "musicmessageview.h" + +#include "taglib/taglib.h" +#include "taglib/tag.h" +#include "taglib/tpropertymap.h" +#include "taglib/fileref.h" +#include "taglib/id3v2header.h" +#include "taglib/attachedpictureframe.h" + +#include "taglib/mp4file.h" +#include "taglib/mp4item.h" +#include "taglib/mp4coverart.h" +#include "taglib/mp4properties.h" + +MusicPreview::MusicPreview(QObject *parent) + : DFMFilePreview(parent) +{ + +} + +MusicPreview::~MusicPreview() +{ + if (m_musicView) + m_musicView->deleteLater(); + + if (m_statusBarFrame) + m_statusBarFrame->deleteLater(); +} + +bool MusicPreview::setFileUrl(const DUrl &url) +{ + if (m_url == url) + return true; + + if (!url.isLocalFile()) + return false; + + if (m_musicView || m_statusBarFrame) + return false; + + if (!canPreview(url)) + return false; + + m_url = url; + + m_musicView = new MusicMessageView(url.toString()); + m_statusBarFrame = new ToolBarFrame(url.toString()); + + m_musicView->setFixedSize(600, 336); + m_statusBarFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + return true; +} + +DUrl MusicPreview::fileUrl() const +{ + return m_url; +} + +QWidget *MusicPreview::contentWidget() const +{ + return m_musicView; +} + +QWidget *MusicPreview::statusBarWidget() const +{ + return m_statusBarFrame; +} + +Qt::Alignment MusicPreview::statusBarWidgetAlignment() const +{ + return Qt::Alignment(); +} + +void MusicPreview::play() +{ + m_statusBarFrame->play(); +} + +void MusicPreview::pause() +{ + m_statusBarFrame->pause(); +} + +void MusicPreview::stop() +{ + m_statusBarFrame->stop(); +} + +bool MusicPreview::canPreview(const DUrl &url) const +{ + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, url); + + if (!info) + return false; + + return QMediaPlayer::hasSupport(info->mimeTypeName(QMimeDatabase::MatchContent)) != QMultimedia::NotSupported; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicpreview.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicpreview.h new file mode 100644 index 0000000..9e748c9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicpreview.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef MUSICPREVIEW_H +#define MUSICPREVIEW_H + +#include "dfmfilepreview.h" +#include "durl.h" + +#include + +class MusicMessageView; +class ToolBarFrame; + +class MusicPreview : public DFM_NAMESPACE::DFMFilePreview +{ + Q_OBJECT + +public: + explicit MusicPreview(QObject *parent = nullptr); + ~MusicPreview() override; + + bool setFileUrl(const DUrl &url) override; + DUrl fileUrl() const override; + + QWidget *contentWidget() const override; + QWidget *statusBarWidget() const override; + Qt::Alignment statusBarWidgetAlignment() const override; + + void play() override; + void pause() override; + void stop() override; + + bool canPreview(const DUrl &url) const; + +private: + DUrl m_url; + + QPointer m_musicView; + QPointer m_statusBarFrame; +}; + +#endif // MUSICPREVIEWPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicpreviewplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicpreviewplugin.cpp new file mode 100644 index 0000000..53cee48 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicpreviewplugin.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "musicpreviewplugin.h" + +DFM_USE_NAMESPACE + +DFMFilePreview *MusicPreviewPlugin::create(const QString &key) +{ + Q_UNUSED(key) + + return new MusicPreview(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicpreviewplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicpreviewplugin.h new file mode 100644 index 0000000..19b0f62 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/musicpreviewplugin.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef MUSICPREVIEWPLUGIN_H +#define MUSICPREVIEWPLUGIN_H + +#include "dfmfilepreviewplugin.h" +#include "musicpreview.h" + +class MusicPreviewPlugin : public DFM_NAMESPACE::DFMFilePreviewPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DFMFilePreviewFactoryInterface_iid FILE "dde-music-preview-plugin.json") + +public: + DFM_NAMESPACE::DFMFilePreview *create(const QString &key) Q_DECL_OVERRIDE; +}; + +#endif // MUSICPREVIEWPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/toolbarframe.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/toolbarframe.cpp new file mode 100644 index 0000000..8c25b3d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/toolbarframe.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "toolbarframe.h" + +#include +#include +#include +#include +#include +#include +#include + +ToolBarFrame::ToolBarFrame(const QString &uri, QWidget *parent) : + QFrame(parent) +{ + m_player = new QMediaPlayer(this); + + m_updateProgressTimer = new QTimer(this); + m_updateProgressTimer->setInterval(1000); + + initUI(); + initConnections(); + + m_player->setMedia(QUrl::fromUserInput(uri)); +} + +void ToolBarFrame::initUI() +{ + m_playControlButton = new QPushButton(this); + m_playControlButton->setFixedSize(24, 24); + m_playControlButton->setStyleSheet("QPushButton{" + "border: none;" + "image: url(:/icons/icons/start_normal.png);" + "}" + "QPushButton::pressed{" + "image: url(:/icons/icons/start_pressed.png);" + "}" + "QPushButton::hover{" + "image: url(:/icons/icons/start_hover.png);" + "}" + ); + + m_progressSlider = new QSlider(this); + m_progressSlider->setOrientation(Qt::Horizontal); + m_progressSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + m_durationLabel = new QLabel(this); + + QHBoxLayout *layout = new QHBoxLayout; + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(m_playControlButton, 0, Qt::AlignVCenter); + layout->addWidget(m_progressSlider, 0, Qt::AlignVCenter); + layout->addWidget(m_durationLabel, 0, Qt::AlignVCenter); + + setLayout(layout); +} + +void ToolBarFrame::initConnections() +{ + connect(m_player, &QMediaPlayer::stateChanged, this, &ToolBarFrame::onPlayStateChanged); + connect(m_player, &QMediaPlayer::mediaStatusChanged, this, &ToolBarFrame::onPlayStatusChanged); + connect(m_player, &QMediaPlayer::durationChanged, this, &ToolBarFrame::onPlayDurationChanged); + connect(m_playControlButton, &QPushButton::clicked, this, &ToolBarFrame::onPlayControlButtonClicked); + connect(m_updateProgressTimer, &QTimer::timeout, this, &ToolBarFrame::updateProgress); + connect(m_progressSlider, &QSlider::valueChanged, this, &ToolBarFrame::seekPosition); +} + +void ToolBarFrame::onPlayDurationChanged(qint64 duration) +{ + durationToLabel(duration); +} + +void ToolBarFrame::onPlayStateChanged(const QMediaPlayer::State &state) +{ + if (state == QMediaPlayer::StoppedState) { + stop(); + } + + QString iconName; + if (state == QMediaPlayer::StoppedState || state == QMediaPlayer::PausedState) { + iconName = "start"; + } else { + iconName = "pause"; + } + + m_playControlButton->setStyleSheet("QPushButton{" + "border: none;" + "image: url(:/icons/icons/" + iconName + "_normal.png);" + "}" + "QPushButton::pressed{" + "image: url(:/icons/icons/" + iconName + "_pressed.png);" + "}" + "QPushButton::hover{" + "image: url(:/icons/icons/" + iconName + "_hover.png);" + "}" + ); +} + +void ToolBarFrame::onPlayStatusChanged(const QMediaPlayer::MediaStatus &status) +{ + if (status == QMediaPlayer::LoadedMedia || status == QMediaPlayer::BufferedMedia) { + durationToLabel(m_player->duration()); + } +} + +void ToolBarFrame::onPlayControlButtonClicked() +{ + if (m_player->state() == QMediaPlayer::PlayingState) { + pause(); + } else if (m_player->state() == QMediaPlayer::StoppedState) { + m_progressSlider->setValue(0); + play(); + } else { + play(); + } +} + +void ToolBarFrame::updateProgress() +{ + m_progressSlider->setValue(static_cast(m_player->position())); +} + +void ToolBarFrame::seekPosition(const int &pos) +{ + if (qAbs(pos - m_player->position()) > 3) { + m_player->setPosition(pos); + } +} + +void ToolBarFrame::play() +{ + m_player->play(); + m_updateProgressTimer->start(); +} + +void ToolBarFrame::pause() +{ + m_player->pause(); + m_updateProgressTimer->stop(); +} + +void ToolBarFrame::stop() +{ + m_progressSlider->setValue(0); + m_player->stop(); + m_updateProgressTimer->stop(); +} + +void ToolBarFrame::durationToLabel(qint64 duration) +{ + qlonglong msDuration = duration; + qlonglong sDurations = msDuration / 1000; + int minutes = static_cast(sDurations) / 60; + int seconds = sDurations % 60; + QString minutesStr; + QString secondsStr; + if (minutes < 10) { + minutesStr = "0" + QString::number(minutes); + } else { + minutesStr = QString::number(minutes); + } + if (seconds < 10) { + secondsStr = "0" + QString::number(seconds); + } else { + secondsStr = QString::number(seconds); + } + + m_durationLabel->setText(QString("%1: %2").arg(minutesStr, secondsStr)); + + m_progressSlider->setMinimum(0); + m_progressSlider->setMaximum(static_cast(duration)); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/toolbarframe.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/toolbarframe.h new file mode 100644 index 0000000..f57a37b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-music-preview-plugin/toolbarframe.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef TOOLBARFRAME_H +#define TOOLBARFRAME_H + +#include +#include + + +class QPushButton; +class QSlider; +class QLabel; +class QMediaPlayer; +class QTimer; +class ToolBarFrame : public QFrame +{ + Q_OBJECT +public: + explicit ToolBarFrame(const QString &uri, QWidget *parent = nullptr); + +private: + void initUI(); + void initConnections(); + +signals: + +public slots: + void onPlayStateChanged(const QMediaPlayer::State &state); + void onPlayStatusChanged(const QMediaPlayer::MediaStatus &status); + void onPlayDurationChanged(qint64 duration); + void onPlayControlButtonClicked(); + void updateProgress(); + void seekPosition(const int &pos); + void play(); + void pause(); + void stop(); + +private: + void durationToLabel(qint64 duration); + +private: + QMediaPlayer *m_player; + QPushButton *m_playControlButton; + QSlider *m_progressSlider; + QLabel *m_durationLabel; + QTimer *m_updateProgressTimer; +}; + +#endif // TOOLBARFRAME_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/dde-pdf-preview-plugin.json b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/dde-pdf-preview-plugin.json new file mode 100644 index 0000000..3291fa6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/dde-pdf-preview-plugin.json @@ -0,0 +1,3 @@ +{ + "Keys" : ["application/pdf", "application/x-bzpdf", "application/x-gzpdf", "application/x-lzpdf", "application/x-xzpdf"] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/dde-pdf-preview-plugin.pri b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/dde-pdf-preview-plugin.pri new file mode 100644 index 0000000..4832980 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/dde-pdf-preview-plugin.pri @@ -0,0 +1,14 @@ +SOURCES += \ + pdfwidget.cpp \ + pdfpreview.cpp \ + $$PWD/pdfpreviewplugin.cpp + +HEADERS += \ + pdfwidget.h \ + pdfpreview.h \ + $$PWD/pdfwidget_p.h \ + $$PWD/pdfpreviewplugin.h + +RESOURCES += \ + theme.qrc + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/dde-pdf-preview-plugin.pro b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/dde-pdf-preview-plugin.pro new file mode 100644 index 0000000..fe27db5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/dde-pdf-preview-plugin.pro @@ -0,0 +1,35 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-04-12T09:08:50 +# +#------------------------------------------------- + +QT += core gui widgets concurrent + +TARGET = dde-pdf-preview-plugin +TEMPLATE = lib + +PKGCONFIG += poppler-cpp + +CONFIG += c++11 plugin link_pkgconfig + +include(../../../common/common.pri) +include(dde-pdf-preview-plugin.pri) + +DISTFILES += dde-pdf-preview-plugin.json + +PLUGIN_INSTALL_DIR = $$PLUGINDIR/previews + +DESTDIR = $$top_srcdir/plugins/previews + +unix { + target.path = $$PLUGIN_INSTALL_DIR + INSTALLS += target +} + +#安全加固 +QMAKE_CXXFLAGS += -fstack-protector-all +QMAKE_LFLAGS += -z now -fPIC +isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + QMAKE_LFLAGS += -z noexecstack -z relro +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/dde-pdf-preview.theme b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/dde-pdf-preview.theme new file mode 100644 index 0000000..6abaff7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/dde-pdf-preview.theme @@ -0,0 +1,8 @@ +QListWidget#Thumbnail{ + border: none; + background: white; + border-right: 1px solid rgba(0, 0, 0, 0.1); +}" +QListWidget#Thumbnail::item{ + border: none; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/main.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/main.cpp new file mode 100644 index 0000000..fec1955 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/main.cpp @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2017 Deepin Technology Co., Ltd. + * + * 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. + **/ + +#include "dfmfilepreviewplugin.h" + +#include "pdfpreview.h" + +DFM_BEGIN_NAMESPACE + +class PDFPreviewPlugin : public DFMFilePreviewPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DFMFilePreviewFactoryInterface_iid FILE "dde-pdf-preview-plugin.json") + +public: + DFMFilePreview *create(const QString &key) Q_DECL_OVERRIDE + { + Q_UNUSED(key) + + return new PDFPreview(); + } +}; + +DFM_END_NAMESPACE + +#include "main.moc" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfpreview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfpreview.cpp new file mode 100644 index 0000000..48365e3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfpreview.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "pdfpreview.h" + +#include +#include +#include +#include + +#include "pdfwidget.h" + +DFM_USE_NAMESPACE + +PDFPreview::PDFPreview(QObject *parent) + : DFMFilePreview(parent) +{ + +} + +PDFPreview::~PDFPreview() +{ + if (m_pdfWidget) { + m_pdfWidget->setNeedRelease(true); + if (m_pdfWidget->getCanRelease()) + m_pdfWidget->deleteLater(); + } + +} + +bool PDFPreview::setFileUrl(const DUrl &url) +{ + if (m_url == url) + return true; + + if (!url.isLocalFile()) + return false; + + if (m_pdfWidget) + return false; + + m_pdfWidget = new PdfWidget(url.toLocalFile()); + m_pdfWidget->setFixedSize(800, 500); + + m_title = QFileInfo(url.toLocalFile()).fileName(); + + Q_EMIT titleChanged(); + + return true; +} + +DUrl PDFPreview::fileUrl() const +{ + return m_url; +} + +QWidget *PDFPreview::contentWidget() const +{ + return m_pdfWidget; +} + +QString PDFPreview::title() const +{ + return m_title; +} + +bool PDFPreview::showStatusBarSeparator() const +{ + return true; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfpreview.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfpreview.h new file mode 100644 index 0000000..c4d9260 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfpreview.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef PDFPREVIEW_H +#define PDFPREVIEW_H + +#include +#include + +#include "dfmfilepreview.h" +#include "durl.h" + +class PdfWidget; + +class PDFPreview : public DFM_NAMESPACE::DFMFilePreview +{ + Q_OBJECT + +public: + explicit PDFPreview(QObject *parent = nullptr); + ~PDFPreview() override; + + bool setFileUrl(const DUrl &url) override; + DUrl fileUrl() const override; + + QWidget *contentWidget() const override; + + QString title() const override; + bool showStatusBarSeparator() const override; + +private: + DUrl m_url; + QString m_title; + + QPointer m_pdfWidget; +}; + +#endif // PDFPREVIEWPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfpreviewplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfpreviewplugin.cpp new file mode 100644 index 0000000..27a7521 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfpreviewplugin.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "pdfpreviewplugin.h" + +DFM_USE_NAMESPACE +DFMFilePreview *PDFPreviewPlugin::create(const QString &key) +{ + Q_UNUSED(key) + + return new PDFPreview(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfpreviewplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfpreviewplugin.h new file mode 100644 index 0000000..b4f6b07 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfpreviewplugin.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef PDFPREVIEWPLUGIN_H +#define PDFPREVIEWPLUGIN_H +#include "dfmfilepreviewplugin.h" + +#include "pdfpreview.h" + +class PDFPreviewPlugin : public DFM_NAMESPACE::DFMFilePreviewPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DFMFilePreviewFactoryInterface_iid FILE "dde-pdf-preview-plugin.json") + +public: + DFM_NAMESPACE::DFMFilePreview *create(const QString &key) Q_DECL_OVERRIDE; +}; + +#endif // PDFPREVIEWPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfwidget.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfwidget.cpp new file mode 100644 index 0000000..59e15be --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfwidget.cpp @@ -0,0 +1,654 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "pdfwidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pdfwidget_p.h" + +PdfWidget::PdfWidget(const QString &file, QWidget *parent) : + QWidget(parent), + d_ptr(new PdfWidgetPrivate(this)) +{ + Q_D(PdfWidget); + + d->pageWorkTimer = new QTimer(this); + d->pageWorkTimer->setSingleShot(true); + d->pageWorkTimer->setInterval(50); + d->thumbWorkTimer = new QTimer(this); + d->thumbWorkTimer->setSingleShot(true); + d->thumbWorkTimer->setInterval(100); + + d->thumbButtonGroup = new QButtonGroup(this); + + + initDoc(file); + initUI(); + + if(d->isBadDoc){ + return; + } + + initConnections(); +} + +PdfWidget::~PdfWidget() +{ + Q_D(PdfWidget); + + disconnect(d->pdfInitWorker, &PdfInitWorker::thumbAdded, this, &PdfWidget::onThumbAdded); + disconnect(d->pdfInitWorker, &PdfInitWorker::pageAdded, this, &PdfWidget::onpageAdded); + this->hide(); + + d->pdfInitWorker->deleteLater(); +} + +void PdfWidget::initDoc(const QString& file) +{ + Q_D(PdfWidget); + d->doc = QSharedPointer(poppler::document::load_from_file(file.toStdString())); + + if (!d->doc || d->doc->is_locked()) { + qDebug () << "Cannot read this pdf file: " << file; + d->isBadDoc = true; + } + + d->pdfInitWorker = new PdfInitWorker(d->doc); +} + +void PdfWidget::initUI() +{ + Q_D(PdfWidget); + + if(d->isBadDoc){ + showBadPage(); + return; + } + + setContentsMargins(0, 0, 0, 0); + setFixedSize(qMin(DEFAULT_VIEW_SIZE.width(), static_cast(qApp->desktop()->width() * 0.8)), + qMin(DEFAULT_VIEW_SIZE.height(), static_cast(qApp->desktop()->height() * 0.8))); + + d->thumbListWidget = new DListWidget(this); + d->thumbListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + d->thumbListWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + d->thumbScrollBar = d->thumbListWidget->verticalScrollBar(); + d->thumbScrollBar->setParent(this); + d->thumbListWidget->setFixedWidth(96); + d->thumbListWidget->setVerticalScrollMode(QListWidget::ScrollPerPixel); + d->thumbListWidget->setAttribute(Qt::WA_MouseTracking); + d->thumbListWidget->setStyleSheet("QListWidget{" + "border: none;" + "background: white;" + "border-right: 1px solid rgba(0, 0, 0, 0.1);" + "}" + "QListWidget::item{" + "border: none;" + "}"); + + d->thumbListWidget->setSpacing(18); + + d->pageListWidget = new DListWidget(this); + d->pageListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + d->pageListWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + d->pageListWidget->setVerticalScrollMode(QListWidget::ScrollPerPixel); + d->pageListWidget->setStyleSheet("QListWidget::item:selected{" + "background: white;" + "}"); + d->pageScrollBar = d->pageListWidget->verticalScrollBar(); + d->pageScrollBar->setParent(this); + + d->mainLayout = new QHBoxLayout; + d->mainLayout->setContentsMargins(0, 0, 0, 0); + d->mainLayout->setSpacing(0); + d->mainLayout->addWidget(d->thumbListWidget); + d->mainLayout->addWidget(d->pageListWidget); + + setLayout(d->mainLayout); + + initEmptyPages(); + + loadThumbSync(0); + loadPageSync(0); +} + +void PdfWidget::initConnections() +{ + Q_D(PdfWidget); + + connect(d->pdfInitWorker, &PdfInitWorker::thumbAdded, this, &PdfWidget::onThumbAdded); + connect(d->pdfInitWorker, &PdfInitWorker::pageAdded, this, &PdfWidget::onpageAdded); + + connect(d->thumbScrollBar, &QScrollBar::valueChanged, this, &PdfWidget::onThumbScrollBarValueChanged); + connect(d->pageScrollBar, &QScrollBar::valueChanged, this, &PdfWidget::onPageScrollBarvalueChanged); + + connect(d->pageWorkTimer, &QTimer::timeout, this, &PdfWidget::startLoadCurrentPages); + connect(d->thumbWorkTimer, &QTimer::timeout, this, &PdfWidget::startLoadCurrentThumbs); +} + +void PdfWidget::showBadPage() +{ + QVBoxLayout* layout = new QVBoxLayout(); + layout->setParent(this); + QLabel* badLabel = new QLabel(this); + badLabel->setStyleSheet("QLabel{" + "font-size: 20px;" + "}"); + badLabel->setText(tr("Cannot preview this file!")); + + layout->addStretch(); + layout->addWidget(badLabel, 0, Qt::AlignHCenter); + layout->addStretch(); + setLayout(layout); +} + +bool PdfWidget::getCanRelease() +{ + Q_D(PdfWidget); + + return d->m_threadRunningCount <= 0; +} + +void PdfWidget::setNeedRelease(const bool &need) +{ + Q_D(PdfWidget); + + d->m_needRelease = need; +} + +void PdfWidget::onThumbAdded(int index, QImage img) +{ + Q_D(PdfWidget); + QListWidgetItem* item = d->thumbListWidget->item(index); + QWidget* w = d->thumbListWidget->itemWidget(item); + + if(!w){ + QPushButton* bnt = new QPushButton(this); + d->thumbButtonGroup->addButton(bnt); + bnt->setIcon(QIcon(QPixmap::fromImage(img))); + bnt->setFixedSize(img.size()); + bnt->setIconSize(QSize(img.width() - 4, img.height())); + bnt->setCheckable(true); + bnt->setStyleSheet("QPushButton{" + "border: 1px solid rgba(0, 0, 0, 0.2);" + "}" + "QPushButton:checked{" + "border: 2px solid #2ca7f8;" + "}"); + + if(index == 0){ + bnt->setChecked(true); + } + + connect(bnt, &QPushButton::clicked, [=]{ + bnt->setChecked(true); + int row = d->thumbListWidget->row(item); + d->pageListWidget->setCurrentRow(row); + + }); + + d->thumbListWidget->setItemWidget(item, bnt); + item->setSizeHint(img.size()); + } + + if(d->thumbScrollBar->maximum() == 0){ + d->thumbScrollBar->hide(); + } else { + d->thumbScrollBar->show(); + } +} + +void PdfWidget::onpageAdded(int index, QImage img) +{ + Q_D(PdfWidget); + + d->pageMap.insert(index, img); + + QListWidgetItem* item = d->pageListWidget->item(index); + QWidget* w = d->pageListWidget->itemWidget(item); + + if(!w){ + img = img.scaled(d->pageListWidget->width(), img.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + QImage page(d->pageListWidget->width(), img.height() + 4, QImage::Format_ARGB32_Premultiplied); + page.fill(Qt::white); + QPainter p(&page); + p.drawImage((page.width() - img.width())/2, 2, img); + if(index < (d->doc->pages() - 1)){ + QPen pen(QColor(0, 0, 0 , 20)); + p.setPen(pen); + p.drawLine(0, page.height() - 1, page.width(), page.height() - 1); + } + + QLabel* pageLabel = new QLabel(this); + pageLabel->setPixmap(QPixmap::fromImage(page)); + + d->pageListWidget->setItemWidget(item, pageLabel); + item->setSizeHint(page.size()); + } + + if(d->pageScrollBar->maximum() == 0){ + d->pageScrollBar->hide(); + } else { + d->pageScrollBar->show(); + } + +} + +void PdfWidget::onThumbScrollBarValueChanged(const int &val) +{ + Q_UNUSED(val) + Q_D(const PdfWidget); + + d->thumbWorkTimer->stop(); + d->thumbWorkTimer->start(); +} + +void PdfWidget::onPageScrollBarvalueChanged(const int &val) +{ + Q_UNUSED(val) + Q_D(const PdfWidget); + + d->pageWorkTimer->stop(); + d->pageWorkTimer->start(); + + resizeCurrentPage(); + + QListWidgetItem* item = d->pageListWidget->itemAt(d->pageListWidget->width() /2 , 20); + if(!item) { + return; + } + + int row = d->pageListWidget->row(item); + d->thumbListWidget->setCurrentRow(row); + QListWidgetItem* thumbItem = d->thumbListWidget->item(row); + if(!thumbItem){ + return; + } + + QWidget* w = d->thumbListWidget->itemWidget(thumbItem); + if(!w){ + return; + } + + QPushButton* bnt = qobject_cast(w); + bnt->setChecked(true); +} + +void PdfWidget::startLoadCurrentPages() +{ + Q_D(const PdfWidget); + QListWidgetItem* item = d->pageListWidget->itemAt(d->pageListWidget->width() / 2, 0); + if(!item){ + item = d->pageListWidget->itemAt(d->pageListWidget->width() / 2, d->pageListWidget->spacing() * 2 + 1); + } + if(item) + { + int row = d->pageListWidget->row(item); + loadPageSync(row); + } +} + +void PdfWidget::startLoadCurrentThumbs() +{ + Q_D(const PdfWidget); + QListWidgetItem* item = d->thumbListWidget->itemAt(d->thumbListWidget->width() / 2, 0); + //To prevent this point is int empty area, we get another point again with next pixcel that lager than it spacing + if(!item){ + item = d->thumbListWidget->itemAt(d->thumbListWidget->width() / 2, d->thumbListWidget->spacing() * 2 + 1); + } + + if(item) + { + int row = d->thumbListWidget->row(item); + loadThumbSync(row); + } +} + +void PdfWidget::resizeEvent(QResizeEvent *event) +{ + Q_D(PdfWidget); + + QWidget::resizeEvent(event); + + if(d->isBadDoc){ + return; + } + + if(d->pageScrollBar->maximum() == 0){ + d->pageScrollBar->hide(); + } else { + d->pageScrollBar->show(); + } + + if(d->thumbScrollBar->maximum() == 0){ + d->thumbScrollBar->hide(); + } else { + d->thumbScrollBar->show(); + } + + d->thumbScrollBar->setFixedSize(d->thumbScrollBar->sizeHint().width(), event->size().height() - 10); + d->thumbScrollBar->move(d->thumbListWidget->width() - d->thumbScrollBar->width(), 10); + + d->pageScrollBar->setFixedSize(d->pageScrollBar->sizeHint().width(), event->size().height() - 30); + d->pageScrollBar->move(event->size().width() - d->pageScrollBar->width(), 30); + d->pageListWidget->setFixedWidth(width() - d->thumbListWidget->width()); + + resizeCurrentPage(); +} + +void PdfWidget::renderBorder(QImage &img) +{ + QColor color(0, 0, 0, 30); + + QPainter painter(&img); + QPen pen; + pen.setColor(color); + pen.setWidth(1); + painter.setPen(pen); + + painter.drawRect(0, 0, img.width() - 1, img.height() -1); +} + +void PdfWidget::emptyBorder(QImage &img) +{ + QColor color(255, 255, 255); + + QPainter painter(&img); + QPen pen; + pen.setColor(color); + pen.setWidth(2); + painter.setPen(pen); + + painter.drawRect(0, 0, img.width() - 2, img.height() - 2); +} + +void PdfWidget::loadPageSync(const int &index) +{ + Q_D(PdfWidget); + + QPointer mePtr = this; + + QtConcurrent::run([=]{ + if (mePtr.isNull() || d->m_needRelease) + return; + d->m_threadRunningCount++; + d->pdfInitWorker->startGetPageImage(index); + d->m_threadRunningCount--; + if (d->m_needRelease && d->m_threadRunningCount <= 0) + this->deleteLater(); + }); +} + +void PdfWidget::loadThumbSync(const int &index) +{ + Q_D(PdfWidget); + + QPointer mePtr = this; + + QtConcurrent::run([=]{ + if (mePtr.isNull() || d->m_needRelease) + return; + d->m_threadRunningCount++; + d->pdfInitWorker->startGetPageThumb(index); + d->m_threadRunningCount--; + if (d->m_needRelease && d->m_threadRunningCount <= 0) + this->deleteLater(); + }); +} + +void PdfWidget::initEmptyPages() +{ + Q_D(PdfWidget); + + for(int i = 0; i < d->doc->pages(); i ++ ){ + QListWidgetItem* pageItem = new QListWidgetItem; + pageItem->setSizeHint(DEFAULT_PAGE_SIZE); + + QListWidgetItem* thumbItem = new QListWidgetItem; + thumbItem->setSizeHint(DEFAULT_THUMB_SIZE); + + d->pageListWidget->addItem(pageItem); + d->thumbListWidget->addItem(thumbItem); + } +} + +void PdfWidget::resizeCurrentPage() +{ + Q_D(PdfWidget); + + QListWidgetItem* currentItem = d->pageListWidget->itemAt(d->pageListWidget->width() / 2, d->pageListWidget->height() / 2); + + if(!currentItem) + return; + + int currentRow = d->pageListWidget->row(currentItem); + int index = currentRow - DISPLAT_PAGE_NUM/2; + if(index < 0){ + index = 0; + } + int counter = 0; + while(counter < DISPLAT_PAGE_NUM){ + counter ++; + + if(d->pageMap.contains(index)){ + + QListWidgetItem* item = d->pageListWidget->item(index); + if(!item){ + continue; + } + + QWidget* w = d->pageListWidget->itemWidget(item); + if(!w){ + continue; + } + + QLabel* label = qobject_cast(w); + + QImage img = d->pageMap.value(index); + img = img.scaled(d->pageListWidget->width(), img.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + QImage page(d->pageListWidget->width(), img.height() + 4, QImage::Format_ARGB32_Premultiplied); + page.fill(Qt::white); + + QPainter p(&page); + p.drawImage((page.width() - img.width()) / 2, 2, img); + + if(index < (d->doc->pages() - 1)){ + QPen pen(QColor(0, 0, 0 , 20)); + p.setPen(pen); + p.drawLine(0, page.height() - 1, page.width(), page.height() - 1); + } + + label->setPixmap(QPixmap::fromImage(page)); + item->setSizeHint(page.size()); + + index ++; + } else { + index ++; + continue; + } + } +} + +PdfInitWorker::PdfInitWorker(QSharedPointer doc, QObject *parent): + QObject(parent), + m_doc(doc) +{ + +} + +void PdfInitWorker::startGetPageThumb(int index) +{ + int counter = 0; + while(counter < DISPLAY_THUMB_NUM){ + counter++; + + //Skip for indexed thumb we got + if(m_gotThumbIndexes.contains(index)){ + index ++; + continue; + } + + QImage img = getRenderedPageImage(index); + + if(img.isNull()){ + break; + } else{ + QImage thumb = getPageThumb(img); + emit thumbAdded(index, thumb); + m_gotThumbIndexes << index; + index ++; + } + + } +} + +void PdfInitWorker::startGetPageImage(int index) +{ + int counter = 0; + while(counter < DISPLAT_PAGE_NUM){ + counter++; + + //Skip for indexed page we got + if(m_gotPageIndexes.contains(index)){ + index ++; + continue; + } + + QImage img = getRenderedPageImage(index); + + if(img.isNull()){ + break; + } else { + emit pageAdded(index, img); + m_gotPageIndexes << index; + index ++; + } + } +} + +QImage PdfInitWorker::getPageThumb(const QImage &img) const +{ + QImage newImg = img; + return newImg.scaled(DEFAULT_THUMB_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation); +} + +QImage PdfInitWorker::getRenderedPageImage(const int &index) const +{ + QImage img; + + QSharedPointer page = QSharedPointer(m_doc->create_page(index)); + + if (!page) { + return img; + } + + poppler::page_renderer pr; + pr.set_render_hint(poppler::page_renderer::antialiasing, true); + pr.set_render_hint(poppler::page_renderer::text_antialiasing, true); + + if(!pr.can_render()){ + qDebug () << "Cannot render page"; + return img; + } + + if(page->page_rect().width() * page->page_rect().height() > 1920 * 1080 * 3){ + qDebug () << "This pdf page is tool large, ignore..."; + return img; + } + + poppler::image imageData = pr.render_page(page.data()); + + if (!imageData.is_valid()) { + qDebug () << "Render error"; + return img; + } + + poppler::image::format_enum format = imageData.format(); + + switch (format) { + case poppler::image::format_invalid: + qDebug () << "Image format is invalid"; + return img; + case poppler::image::format_mono: + img = QImage((uchar*)imageData.data(), imageData.width(), imageData.height(), QImage::Format_Mono); + break; + case poppler::image::format_rgb24: + img = QImage((uchar*)imageData.data(),imageData.width(),imageData.height(),QImage::Format_ARGB6666_Premultiplied); + break; + case poppler::image::format_argb32: + { + //Note that this format has problem that QImage cannot parse it normally + img = QImage(imageData.width(), imageData.height(), QImage::Format_ARGB32_Premultiplied); + img.fill(Qt::white); + int w = imageData.width(); + int h = imageData.height(); + int offset = imageData.bytes_per_row() / imageData.width(); + + char* pdata = imageData.data(); + + for(int y = 0; y < h; y ++){ + for(int x = 0; x < w; x++){ + uchar b = static_cast (pdata[(x * offset) + (y * w * offset)]); + uchar g = static_cast (pdata[(x * offset) + (y * w * offset) + 1]); + uchar r = static_cast (pdata[(x * offset) + (y * w * offset) + 2]); + uchar a = static_cast (pdata[(x * offset) + (y * w * offset) + 3]); + + img.setPixelColor(x, y, QColor((int)r, (int)g, (int)b, (int)a)); + } + } + break; + } + default: + break; + } + + return img; +} + +DListWidget::DListWidget(QWidget *parent): + QListWidget(parent) +{ + +} + +void DListWidget::mouseMoveEvent(QMouseEvent *e) +{ + QWidget::mouseMoveEvent(e); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfwidget.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfwidget.h new file mode 100644 index 0000000..9db19e3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfwidget.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef PDFWIDGET_H +#define PDFWIDGET_H + +#include +#include +#include +#include +#include + +#include "poppler-document.h" +#include "poppler-page.h" +#include "poppler-page-renderer.h" + +#define DEFAULT_VIEW_SIZE QSize(700, 800) +#define DEFAULT_THUMB_SIZE QSize(55, 74) +#define DEFAULT_PAGE_SIZE QSize(800, 1200) +#define DISPLAY_THUMB_NUM 10 +#define DISPLAT_PAGE_NUM 5 + +class PdfWidgetPrivate; +class PdfInitWorker; +class PdfWidget : public QWidget +{ + Q_OBJECT +public: + explicit PdfWidget(const QString &file, QWidget *parent = nullptr); + ~PdfWidget() override; + + void initDoc(const QString &file); + + void initUI(); + void initConnections(); + + void showBadPage(); + + /** + * @brief getCanRelease 对象是否可以被删除 + * @return 如果返回true对象可删除,反之亦然 + */ + bool getCanRelease(); + + /** + * @brief setNeedRelease 设置对象是否要被删除 + * @param need true对象要被删除,反之亦然 + */ + void setNeedRelease(const bool & need); + +public slots: + void onThumbAdded(int index, QImage img); + void onpageAdded(int index, QImage img); + void onThumbScrollBarValueChanged(const int &val); + void onPageScrollBarvalueChanged(const int &val); + void startLoadCurrentPages(); + void startLoadCurrentThumbs(); + +protected: + void resizeEvent(QResizeEvent *event) override; + +private: + + void renderBorder(QImage &img); + void emptyBorder(QImage &img); + + void loadPageSync(const int &index); + void loadThumbSync(const int &index); + void initEmptyPages(); + + void resizeCurrentPage(); + + QSharedPointer d_ptr; + Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), PdfWidget) +}; + +class PdfInitWorker: public QObject +{ + Q_OBJECT +public: + explicit PdfInitWorker(QSharedPointer doc, QObject *parent = nullptr); + + void startGetPageThumb(int index); + void startGetPageImage(int index); + +signals: + void pageAdded(const int &index, const QImage &img); + void thumbAdded(const int &index, const QImage &img); + +private: + QImage getPageThumb(const QImage &img) const; + QImage getRenderedPageImage(const int &index) const; + + QList m_gotThumbIndexes; + QList m_gotPageIndexes; + + QSharedPointer m_doc; +}; + +class DListWidget: public QListWidget +{ + Q_OBJECT +public: + explicit DListWidget(QWidget *parent = nullptr); +protected: + void mouseMoveEvent(QMouseEvent *e) override; +}; + + +#endif // PDFWIDGET_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfwidget_p.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfwidget_p.h new file mode 100644 index 0000000..c41fd97 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/pdfwidget_p.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef PDFWIDGET_P_H +#define PDFWIDGET_P_H + +#include +#include + +#include "pdfwidget.h" + +class PdfWidgetPrivate{ +public: + explicit PdfWidgetPrivate(PdfWidget* qq): + q_ptr(qq){} + + DListWidget* thumbListWidget = nullptr; + DListWidget* pageListWidget = nullptr; + QHBoxLayout* mainLayout = nullptr; + QScrollBar* thumbScrollBar = nullptr; + QScrollBar* pageScrollBar = nullptr; + QButtonGroup* thumbButtonGroup = nullptr; + + QTimer* pageWorkTimer = nullptr; + QTimer* thumbWorkTimer = nullptr; + bool isBadDoc = false; + + QSharedPointer doc; + + PdfInitWorker* pdfInitWorker = nullptr; + QMap pageMap; + //! 正在执行的线程数量 + QAtomicInt m_threadRunningCount = 0; + //! 对象是否要被删除 + QAtomicInteger m_needRelease = false; + + PdfWidget* q_ptr = nullptr; + Q_DECLARE_PUBLIC(PdfWidget) +}; + +#endif // PDFWIDGET_P_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/theme.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/theme.qrc new file mode 100644 index 0000000..5464f14 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-pdf-preview-plugin/theme.qrc @@ -0,0 +1,5 @@ + + + dde-pdf-preview.theme + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/dde-text-preview-plugin.json b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/dde-text-preview-plugin.json new file mode 100644 index 0000000..5a9476d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/dde-text-preview-plugin.json @@ -0,0 +1,3 @@ +{ + "Keys" : ["text/*"] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/dde-text-preview-plugin.pri b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/dde-text-preview-plugin.pri new file mode 100644 index 0000000..ac1a9d9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/dde-text-preview-plugin.pri @@ -0,0 +1,9 @@ +SOURCES += \ + textpreview.cpp \ + $$PWD/textpreviewplugin.cpp + +HEADERS += \ + textpreview.h \ + $$PWD/textpreviewplugin.h + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/dde-text-preview-plugin.pro b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/dde-text-preview-plugin.pro new file mode 100644 index 0000000..16064fe --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/dde-text-preview-plugin.pro @@ -0,0 +1,33 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-04-17T11:02:31 +# +#------------------------------------------------- + +QT += core gui widgets + +TARGET = dde-text-preview-plugin +TEMPLATE = lib +CONFIG += c++11 plugin + +include(../../../common/common.pri) +include(dde-text-preview-plugin.pri) + +DISTFILES += \ + dde-text-preview-plugin.json + +PLUGIN_INSTALL_DIR = $$PLUGINDIR/previews + +DESTDIR = $$top_srcdir/plugins/previews + +unix { + target.path = $$PLUGIN_INSTALL_DIR + INSTALLS += target +} + +#安全加固 +QMAKE_CXXFLAGS += -fstack-protector-all +QMAKE_LFLAGS += -z now -fPIC +isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + QMAKE_LFLAGS += -z noexecstack -z relro +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/main.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/main.cpp new file mode 100644 index 0000000..e0f1861 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/main.cpp @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2017 Deepin Technology Co., Ltd. + * + * 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. + **/ +#include "dfmfilepreviewplugin.h" + +#include "textpreview.h" + +DFM_BEGIN_NAMESPACE + +class TextPreviewPlugin : public DFMFilePreviewPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DFMFilePreviewFactoryInterface_iid FILE "dde-text-preview-plugin.json") + +public: + DFMFilePreview *create(const QString &key) Q_DECL_OVERRIDE + { + Q_UNUSED(key) + + return new TextPreview(); + } +}; + +DFM_END_NAMESPACE + +#include "main.moc" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/textpreview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/textpreview.cpp new file mode 100644 index 0000000..3ef682a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/textpreview.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "textpreview.h" +#include "dabstractfileinfo.h" +#include "dfileservices.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +DFM_USE_NAMESPACE + +TextPreview::TextPreview(QObject *parent): + DFMFilePreview(parent) +{ + +} + +TextPreview::~TextPreview() +{ + if (m_textBrowser) + m_textBrowser->deleteLater(); + if (m_device) + m_device->deleteLater(); +} + +bool TextPreview::setFileUrl(const DUrl &url) +{ + if (m_url == url) + return true; + + m_url = url; + + m_flg = true; //! 预览新文件时对其设置初始值 + + //! 关闭并回收上个文件使用的m_device文件操作对象 + if (m_device) { + m_device->close(); + delete m_device; + m_device = nullptr; + } + + QByteArray text; + + { + const DAbstractFileInfoPointer &info = DFileService::instance()->createFileInfo(this, url); + + if (!info) + return false; + + m_device = info->createIODevice(); + + if (!m_device) { + if (url.isLocalFile()) { + m_device = new QFile(url.toLocalFile()); + } + } + + if (!m_device) + return false; + + if (!m_device->open(QIODevice::ReadOnly)) { + return false; + } + + //fix 如果文件不可读行,之后读行会导致文管假死或中断 + //文本如果不可读行就不显示预览 + if (!m_device->canReadLine()) { + return false; + } + } + + if (!m_textBrowser) { + m_textBrowser = new QPlainTextEdit(); + + m_textBrowser->setReadOnly(true); + m_textBrowser->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); + m_textBrowser->setWordWrapMode(QTextOption::NoWrap); + m_textBrowser->setFixedSize(800, 500); + m_textBrowser->setFocusPolicy(Qt::NoFocus); + m_textBrowser->setContextMenuPolicy(Qt::NoContextMenu); + + //! 滚动条值改变的信号与曹的连接,用以处理分段加载数据的问题 + connect(m_textBrowser->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int))); + } + + //! 每次预览文本时,预先加载49行数据提供显示 + for (int i = 0; i < 49; ++i) { + text.append(m_device->readLine()); + } + QString convertedStr{ DFMGlobal::toUnicode(text, url.toLocalFile()) }; + m_textBrowser->setPlainText(convertedStr); + + m_title = QFileInfo(url.toLocalFile()).fileName(); + + Q_EMIT titleChanged(); + + return true; +} + +DUrl TextPreview::fileUrl() const +{ + return m_url; +} + +QWidget *TextPreview::contentWidget() const +{ + return m_textBrowser; +} + +QString TextPreview::title() const +{ + return m_title; +} + +bool TextPreview::showStatusBarSeparator() const +{ + return true; +} + +void TextPreview::valueChanged(int index) +{ + if (index >= m_textBrowser->verticalScrollBar()->maximum() && m_flg) { + if (!m_device) + return ; + + m_flg = false; //! 等待这次文本数据加载完成后重新设置为true,以免在设置数据时重复执行以下代码 + + //! 每次分段加载数据36行 + QByteArray text; + for (int i = 0; i < 36; ++i) { + text.append(m_device->readLine()); //! 读取文本一行数据,并追加到text中 + } + QString convertedStr{ DFMGlobal::toUnicode(text, m_url.toLocalFile()) }; //! 字符编码转换 + + m_textBrowser->appendPlainText(convertedStr); + m_textBrowser->verticalScrollBar()->setValue(index); //! 设置垂直滚动条停留的位置 + + m_flg = true; //! 设置为true使得下次需要分段加载数据能够被执行 + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/textpreview.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/textpreview.h new file mode 100644 index 0000000..5bda93e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/textpreview.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef TEXTPREVIEW_H +#define TEXTPREVIEW_H + +#include +#include +#include + +#include "dfmfilepreview.h" +#include "durl.h" + +QT_BEGIN_NAMESPACE +class QPlainTextEdit; +QT_END_NAMESPACE + +class TextPreview : public DFM_NAMESPACE::DFMFilePreview +{ + Q_OBJECT + +public: + explicit TextPreview(QObject *parent = nullptr); + ~TextPreview() override; + + bool setFileUrl(const DUrl &url) override; + DUrl fileUrl() const override; + + QWidget *contentWidget() const override; + + QString title() const override; + bool showStatusBarSeparator() const override; + + QWidget *previewWidget(); + +public slots: + /** + * @brief valueChanged 用于文本内容分段加载使用 + * @param index 当前滚动条的值,这里使用的是垂直滚动条 + */ + void valueChanged(int index); + +private: + DUrl m_url; + QString m_title; + + QPointer m_textBrowser; + + //! 操作文件的对象 + QPointer m_device; + + //! 用来控制m_textBrowser中使用appendPlainText追加数据后会发送valueChanged信号导致在 + //! 重复调用曹函数valueChange导致程序崩溃,所以m_flg为true时valueChanged曹函数中的逻辑 + //! 可以执行,否则不执行 + bool m_flg = false; +}; + +#endif // TEXTPREVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/textpreviewplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/textpreviewplugin.cpp new file mode 100644 index 0000000..3ea183f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/textpreviewplugin.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "textpreviewplugin.h" + +DFM_USE_NAMESPACE +DFMFilePreview *TextPreviewPlugin::create(const QString &key) +{ + Q_UNUSED(key) + + return new TextPreview(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/textpreviewplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/textpreviewplugin.h new file mode 100644 index 0000000..320af30 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-text-preview-plugin/textpreviewplugin.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef TEXTPREVIEWPLUGIN_H +#define TEXTPREVIEWPLUGIN_H + +#include "dfmfilepreviewplugin.h" + +#include "textpreview.h" + +class TextPreviewPlugin : public DFM_NAMESPACE::DFMFilePreviewPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DFMFilePreviewFactoryInterface_iid FILE "dde-text-preview-plugin.json") + +public: + DFM_NAMESPACE::DFMFilePreview *create(const QString &key) Q_DECL_OVERRIDE; +}; + +#endif // TEXTPREVIEWPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/dde-video-preview-plugin.json b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/dde-video-preview-plugin.json new file mode 100644 index 0000000..a26abe3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/dde-video-preview-plugin.json @@ -0,0 +1,3 @@ +{ + "Keys" : ["video/*", "application/vnd.adobe.flash.movie"] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/dde-video-preview-plugin.pri b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/dde-video-preview-plugin.pri new file mode 100644 index 0000000..f0d1d3c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/dde-video-preview-plugin.pri @@ -0,0 +1,15 @@ +SOURCES += \ + videopreview.cpp \ + $$PWD/videowidget.cpp \ + $$PWD/videostatusbar.cpp \ + $$PWD/videopreviewplugin.cpp + +HEADERS += \ + videopreview.h \ + $$PWD/videowidget.h \ + $$PWD/videostatusbar.h \ + $$PWD/videopreviewplugin.h + +RESOURCES += \ + dde-video-preview-plugin.qrc + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/dde-video-preview-plugin.pro b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/dde-video-preview-plugin.pro new file mode 100644 index 0000000..7b0a9a2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/dde-video-preview-plugin.pro @@ -0,0 +1,46 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-04-24T16:11:22 +# +#------------------------------------------------- + +QT += core gui widgets + +TARGET = dde-video-preview-plugin +TEMPLATE = lib + +PKGCONFIG += libdmr dtkgui +CONFIG += plugin link_pkgconfig c++11 + +include(../../../common/common.pri) +include(dde-video-preview-plugin.pri) + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +DISTFILES += \ + dde-video-preview-plugin.json + +PLUGIN_INSTALL_DIR = $$PLUGINDIR/previews + +DESTDIR = $$top_srcdir/plugins/previews + +unix { + target.path = $$PLUGIN_INSTALL_DIR + INSTALLS += target +} + +#安全加固 +QMAKE_CXXFLAGS += -fstack-protector-all +QMAKE_LFLAGS += -z now -fPIC +isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + QMAKE_LFLAGS += -z noexecstack -z relro +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/dde-video-preview-plugin.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/dde-video-preview-plugin.qrc new file mode 100644 index 0000000..701cbe1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/dde-video-preview-plugin.qrc @@ -0,0 +1,6 @@ + + + icons/deepin/builtin/actions/dfm_pause_16px.svg + icons/deepin/builtin/actions/dfm_start_16px.svg + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/icons/deepin/builtin/actions/dfm_pause_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/icons/deepin/builtin/actions/dfm_pause_16px.svg new file mode 100644 index 0000000..25602b6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/icons/deepin/builtin/actions/dfm_pause_16px.svg @@ -0,0 +1,13 @@ + + + icon_暂停 + + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/icons/deepin/builtin/actions/dfm_start_16px.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/icons/deepin/builtin/actions/dfm_start_16px.svg new file mode 100644 index 0000000..715c7e9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/icons/deepin/builtin/actions/dfm_start_16px.svg @@ -0,0 +1,12 @@ + + + icon_播放 + + + + + + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/main.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/main.cpp new file mode 100644 index 0000000..b08a707 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/main.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. + * + * Author: zccrs + * + * Maintainer: zccrs + * + * 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 + * 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 . + */ +#include "dfmfilepreviewplugin.h" +#include "videopreview.h" +#include "libdmr/player_widget.h" + +DFM_BEGIN_NAMESPACE + +class VideoPreviewPlugin : public DFMFilePreviewPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DFMFilePreviewFactoryInterface_iid FILE "dde-video-preview-plugin.json") + +public slots: + DFMFilePreview *create(const QString &key) override + { + Q_UNUSED(key) + + return new VideoPreview(); + } +}; + +DFM_END_NAMESPACE + +#include "main.moc" diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videopreview.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videopreview.cpp new file mode 100644 index 0000000..2e12fe2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videopreview.cpp @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "videopreview.h" + +#include +#include +#include + +#include +#include + +//DWIDGET_USE_NAMESPACE + +//DFM_USE_NAMESPACE + +//class VideoWidget : public dmr::PlayerWidget +//{ +//public: +// VideoWidget(VideoPreview *preview) +// : dmr::PlayerWidget(nullptr) +// , p(preview) +// , title(new QLabel(this)) +// { +// setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + +// QPalette pa; +// pa.setColor(QPalette::Foreground, Qt::white); + +// title->setPalette(pa); + +// DAnchorsBase::setAnchor(title, Qt::AnchorHorizontalCenter, this, Qt::AnchorHorizontalCenter); + +// engine().setBackendProperty("keep-open", "yes"); +// } + +// QSize sizeHint() const override +// { +// QSize screen_size; + +// if (window()->windowHandle()) { +// screen_size = window()->windowHandle()->screen()->availableSize(); +// } else { +// screen_size = qApp->desktop()->size(); +// } + +// return QSize(p->info.width, p->info.height).scaled(qMin(p->info.width, int(screen_size.width() * 0.5)), +// qMin(p->info.height, int(screen_size.height() * 0.5)), Qt::KeepAspectRatio); +// } + +// void mouseReleaseEvent(QMouseEvent *event) override +// { +// p->pause(); + +// dmr::PlayerWidget::mouseReleaseEvent(event); +// } + +// VideoPreview *p; +// QLabel *title; +//}; + +//class VideoStatusBar : public QWidget +//{ +//public: +// explicit VideoStatusBar(VideoPreview *preview) +// : QWidget(nullptr) +// , p(preview) +// , slider(new QSlider(this)) +// , timeLabel(new QLabel(this)) +// { +// setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + +// DImageButton *control_button = new DImageButton(this); +//// QWidget *button_mask = new QWidget(control_button); + +// control_button->setNormalPic(":/icons/icons/start_normal.png"); +// control_button->setPressPic(":/icons/icons/start_pressed.png"); +// control_button->setHoverPic(":/icons/icons/start_hover.png"); +//// button_mask->setAutoFillBackground(true); + +//// DAnchorsBase(button_mask).setFill(control_button); + +// QPalette pa_label; + +// pa_label.setColor(QPalette::Foreground, QColor("#303030")); +// timeLabel->setPalette(pa_label); + +// slider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); +// slider->setMinimum(0); +// slider->setOrientation(Qt::Horizontal); + +// QHBoxLayout *layout = new QHBoxLayout(this); + +// layout->setContentsMargins(0, 0, 20, 0); +// layout->addWidget(control_button); +// layout->addWidget(slider); +// layout->addWidget(timeLabel); + +// connect(control_button, &DImageButton::clicked, this, [this] { +// // 由于调用了setBackendProperty("keep-open", "yes") +// // 导致视频播放状态不对(要暂停到最后一帧,所以视频播放完毕后状态还是暂停) +// // 如果是暂停状态,调用pause一定会播放,之后再调用play也没有影响 +// // 反之,如果是停止状态,调用pause无反应,之后再调用play肯定会播放 +// p->pause(); +// p->playerWidget->engine().play(); + +//// button_mask->show(); +// }); +// connect(&p->playerWidget->engine(), &dmr::PlayerEngine::stateChanged, this, [this, control_button] { +// if (p->playerWidget->engine().state() == dmr::PlayerEngine::Playing) +// { +//// button_mask->show(); +// control_button->setNormalPic(":/icons/icons/pause_normal.png"); +// control_button->setPressPic(":/icons/icons/pause_pressed.png"); +// control_button->setHoverPic(":/icons/icons/pause_hover.png"); +// } else +// { +// control_button->setNormalPic(":/icons/icons/start_normal.png"); +// control_button->setPressPic(":/icons/icons/start_pressed.png"); +// control_button->setHoverPic(":/icons/icons/start_hover.png"); +//// button_mask->hide(); +// } +// }); +// connect(slider, &QSlider::valueChanged, this, [this] { +// p->playerWidget->engine().seekAbsolute(slider->value()); +// }); +// connect(slider, &QSlider::sliderPressed, this, [this] { +// sliderIsPressed = true; +// }); +// connect(slider, &QSlider::sliderReleased, this, [this] { +// sliderIsPressed = false; +// }); +// connect(&p->playerWidget->engine(), &dmr::PlayerEngine::elapsedChanged, this, [this] { +// if (!sliderIsPressed) +// { +// QSignalBlocker blocker(slider); +// Q_UNUSED(blocker) +// slider->setValue(static_cast(p->playerWidget->engine().elapsed())); +// } +// timeLabel->setText(dmr::utils::Time2str(p->playerWidget->engine().elapsed())); +// }); +// } + +// VideoPreview *p; +// QSlider *slider; +// QLabel *timeLabel; +// bool sliderIsPressed = false; +//}; + +VideoPreview::VideoPreview(QObject *parent) + : DFMFilePreview(parent) +{ + setlocale(LC_NUMERIC, "C"); + + // 强制不使用嵌入mpv窗口的模式 + // 经确认,该函数已废弃,屏蔽后不影响使用 + // dmr::CompositingManager::get().overrideCompositeMode(true); + + playerWidget = new VideoWidget(this); + statusBar = new VideoStatusBar(this); +} + +VideoPreview::~VideoPreview() +{ + if (playerWidget) { + playerWidget->hide(); + delete playerWidget.data(); + } + + if (statusBar) { + statusBar->hide(); + statusBar->deleteLater(); + } +} + +bool VideoPreview::setFileUrl(const DUrl &url) +{ + if (!playerWidget->engine().isPlayableFile(url)) + return false; + + bool ok = false; + info = dmr::MovieInfo::parseFromFile(QFileInfo(url.toLocalFile()), &ok); + + if (!ok) { + return false; + } + + playerWidget->title->setText(info.title); + playerWidget->title->adjustSize(); + statusBar->slider->setMaximum(static_cast(info.duration)); + videoUrl = QUrl(url.toLocalFile()); + + return true; +} + +DUrl VideoPreview::fileUrl() const +{ + return DUrl(videoUrl); +} + +QWidget *VideoPreview::contentWidget() const +{ + return playerWidget.data(); +} + +QWidget *VideoPreview::statusBarWidget() const +{ + return statusBar.data(); +} + +bool VideoPreview::showStatusBarSeparator() const +{ + return false; +} + +Qt::Alignment VideoPreview::statusBarWidgetAlignment() const +{ + return Qt::Alignment(); +} + +void VideoPreview::DoneCurrent() +{ + //非wayland平台请注释掉这段代码 +#ifdef __armWayland__ + playerWidget->DoneCurrent(); +#endif +} + +void VideoPreview::play() +{ + if (playerWidget) { + playerWidget->play(videoUrl); + } +} + +void VideoPreview::pause() +{ + playerWidget->engine().pauseResume(); +} + +void VideoPreview::stop() +{ + playerWidget->engine().stop(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videopreview.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videopreview.h new file mode 100644 index 0000000..d7b99d5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videopreview.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef VIDEOPREVIEW_H +#define VIDEOPREVIEW_H + +#include "dfmfilepreview.h" +#include "durl.h" +#include "videowidget.h" +#include "videostatusbar.h" + +#include + +#include +#include + +class VideoPreview : public DFM_NAMESPACE::DFMFilePreview +{ + Q_OBJECT + +public: + explicit VideoPreview(QObject *parent = nullptr); + ~VideoPreview() override; + + bool setFileUrl(const DUrl &url) override; + DUrl fileUrl() const override; + + QWidget *contentWidget() const override; + QWidget *statusBarWidget() const override; + + bool showStatusBarSeparator() const override; + Qt::Alignment statusBarWidgetAlignment() const override; + + virtual void DoneCurrent() override; + + void play() override; + void pause() override; + void stop() override; + +private: + QUrl videoUrl; + QPointer playerWidget; + dmr::MovieInfo info; + QPointer statusBar; + + friend class VideoWidget; + friend class VideoStatusBar; +}; + +#endif // VIDEOPREVIEW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videopreviewplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videopreviewplugin.cpp new file mode 100644 index 0000000..327a30f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videopreviewplugin.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "videopreviewplugin.h" + +DFM_USE_NAMESPACE + +DFMFilePreview *VideoPreviewPlugin::create(const QString &key) +{ + Q_UNUSED(key) + + return new VideoPreview(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videopreviewplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videopreviewplugin.h new file mode 100644 index 0000000..cca18df --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videopreviewplugin.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef VIDEOPREVIEWPLUGIN_H +#define VIDEOPREVIEWPLUGIN_H + +#include "dfmfilepreviewplugin.h" +#include "videopreview.h" +#include "libdmr/player_widget.h" + +class VideoPreviewPlugin : public DFM_NAMESPACE::DFMFilePreviewPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DFMFilePreviewFactoryInterface_iid FILE "dde-video-preview-plugin.json") + +public slots: + DFM_NAMESPACE::DFMFilePreview *create(const QString &key) override; +}; + +#endif // VIDEOPREVIEWPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videostatusbar.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videostatusbar.cpp new file mode 100644 index 0000000..f318bff --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videostatusbar.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "videostatusbar.h" +#include "videopreview.h" + +#include + +DWIDGET_USE_NAMESPACE +DFM_USE_NAMESPACE +VideoStatusBar::VideoStatusBar(VideoPreview *preview) + : QWidget(nullptr) + , p(preview) + , slider(new QSlider(this)) + , timeLabel(new QLabel(this)) + , sliderIsPressed(false) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + DIconButton *control_button = new DIconButton(this); + control_button->setFlat(true); + control_button->setIconSize({24, 24}); + + control_button->setIcon(QIcon::fromTheme("dfm_pause")); + + QPalette pa_label; + + pa_label.setColor(QPalette::Foreground, QColor("#303030")); + timeLabel->setPalette(pa_label); + + slider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + slider->setMinimum(0); + slider->setOrientation(Qt::Horizontal); + + QHBoxLayout *layout = new QHBoxLayout(this); + + layout->setContentsMargins(0, 0, 20, 0); + layout->addWidget(control_button); + layout->addWidget(slider); + layout->addWidget(timeLabel); + + connect(control_button, &DIconButton::clicked, this, [this] { + // 由于调用了setBackendProperty("keep-open", "yes") + // 导致视频播放状态不对(要暂停到最后一帧,所以视频播放完毕后状态还是暂停) + // 如果是暂停状态,调用pause一定会播放,之后再调用play也没有影响 + // 反之,如果是停止状态,调用pause无反应,之后再调用play肯定会播放 + p->pause(); + p->playerWidget->engine().play(); + }); + connect(&p->playerWidget->engine(), &dmr::PlayerEngine::stateChanged, this, [this, control_button] { + if (p->playerWidget->engine().state() == dmr::PlayerEngine::Playing) { + control_button->setIcon(QIcon::fromTheme("dfm_pause")); + } else { + control_button->setIcon(QIcon::fromTheme("dfm_start")); + } + }); + connect(slider, &QSlider::valueChanged, this, [this] { + p->playerWidget->engine().seekAbsolute(slider->value()); + }); + connect(slider, &QSlider::sliderPressed, this, [this] { + sliderIsPressed = true; + }); + connect(slider, &QSlider::sliderReleased, this, [this] { + sliderIsPressed = false; + }); + connect(&p->playerWidget->engine(), &dmr::PlayerEngine::elapsedChanged, this, [this] { + if (!sliderIsPressed) { + QSignalBlocker blocker(slider); + Q_UNUSED(blocker) + slider->setValue(static_cast(p->playerWidget->engine().elapsed())); + } + timeLabel->setText(dmr::utils::Time2str(p->playerWidget->engine().elapsed())); + }); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videostatusbar.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videostatusbar.h new file mode 100644 index 0000000..74b5c8d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videostatusbar.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef VIDEOSTATUSBAR_H +#define VIDEOSTATUSBAR_H + +#include +#include +#include + +#include + +class VideoPreview; + +class VideoStatusBar : public QWidget +{ +public: + explicit VideoStatusBar(VideoPreview *preview); + + VideoPreview *p; + QSlider *slider; + QLabel *timeLabel; + bool sliderIsPressed; +}; + +#endif // VIDEOSTATUSBAR_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videowidget.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videowidget.cpp new file mode 100644 index 0000000..47fdbaf --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videowidget.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "videowidget.h" +#include "videopreview.h" + +#include + +DWIDGET_USE_NAMESPACE +VideoWidget::VideoWidget(VideoPreview *preview) + : dmr::PlayerWidget(nullptr) + , p(preview) + , title(new QLabel(this)) +{ + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + QPalette pa; + pa.setColor(QPalette::Foreground, Qt::white); + + title->setPalette(pa); + + DAnchorsBase::setAnchor(title, Qt::AnchorHorizontalCenter, this, Qt::AnchorHorizontalCenter); + + engine().setBackendProperty("keep-open", "yes"); +} + +QSize VideoWidget::sizeHint() const +{ + QSize screen_size; + + if (window()->windowHandle()) { + screen_size = window()->windowHandle()->screen()->availableSize(); + } else { + screen_size = qApp->desktop()->size(); + } + + return QSize(p->info.width, p->info.height).scaled(qMin(p->info.width, int(screen_size.width() * 0.5)), + qMin(p->info.height, int(screen_size.height() * 0.5)), Qt::KeepAspectRatio); +} + +void VideoWidget::mouseReleaseEvent(QMouseEvent *event) +{ + p->pause(); + + dmr::PlayerWidget::mouseReleaseEvent(event); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videowidget.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videowidget.h new file mode 100644 index 0000000..12f541b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/dde-video-preview-plugin/videowidget.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef PLAYERWIDGET_H +#define PLAYERWIDGET_H + +#include +#include +#include + +#include + +class VideoPreview; + +class VideoWidget : public dmr::PlayerWidget +{ +public: + explicit VideoWidget(VideoPreview *preview); + + QSize sizeHint() const override; + + void mouseReleaseEvent(QMouseEvent *event) override; + + VideoPreview *p; + QLabel *title; +}; + +#endif // PLAYERWIDGET_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/pluginPreview.pro b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/pluginPreview.pro new file mode 100644 index 0000000..51eb1b6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginPreview/pluginPreview.pro @@ -0,0 +1,15 @@ +TEMPLATE = subdirs + +SUBDIRS += \ + dde-image-preview-plugin \ + dde-pdf-preview-plugin \ + dde-text-preview-plugin \ + dde-music-preview-plugin + +ARCH = $$QMAKE_HOST.arch + +!CONFIG(DISABLE_FFMPEG):!isEqual(BUILD_MINIMUM, YES) { + !isEqual(ARCH, sw_64):!isEqual(ARCH, mips64):!isEqual(ARCH, mips32):!isEqual(ARCH, loongarch64) { + SUBDIRS += dde-video-preview-plugin + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/images/checked.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/images/checked.svg new file mode 100644 index 0000000..46dced4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/images/checked.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/images/hover.png b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/images/hover.png new file mode 100644 index 0000000..0f588aa Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/images/hover.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/images/pressed.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/images/pressed.svg new file mode 100644 index 0000000..b4b7ddb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/images/pressed.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/images/release.png b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/images/release.png new file mode 100644 index 0000000..6666f0a Binary files /dev/null and b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/images/release.png differ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/pluginView.json b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/pluginView.json new file mode 100644 index 0000000..1e81138 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/pluginView.json @@ -0,0 +1,3 @@ +{ + "Keys" : [ ] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/pluginView.pri b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/pluginView.pri new file mode 100644 index 0000000..34512f2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/pluginView.pri @@ -0,0 +1,5 @@ +SOURCES += \ + viewplugin.cpp + +HEADERS += \ + viewplugin.h diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/pluginView.pro b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/pluginView.pro new file mode 100644 index 0000000..8c9f987 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/pluginView.pro @@ -0,0 +1,39 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2016-12-21T13:15:17 +# +#------------------------------------------------- + +QT += core gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = pluginView +TEMPLATE = lib +CONFIG += c++11 plugin + +include(../../common/common.pri) +include(../plugininterfaces/plugininterfaces.pri) + +#安全加固 +QMAKE_CXXFLAGS += -fstack-protector-all +QMAKE_LFLAGS += -z now -fPIC +isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + QMAKE_LFLAGS += -z noexecstack -z relro +} + +DESTDIR = ../view + +SOURCES += \ + viewplugin.cpp + +HEADERS += \ + viewplugin.h +DISTFILES += pluginView.json + +unix { + target.path = $$PLUGINDIR/view + INSTALLS += target +} + +RESOURCES += \ + pluginview.qrc diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/pluginview.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/pluginview.qrc new file mode 100644 index 0000000..521618f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/pluginview.qrc @@ -0,0 +1,8 @@ + + + images/checked.svg + images/hover.png + images/pressed.svg + images/release.png + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/viewplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/viewplugin.cpp new file mode 100644 index 0000000..3f7601e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/viewplugin.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#include "viewplugin.h" +#include + +ViewPlugin::ViewPlugin(QObject *parent) : + ViewInterface(parent) +{ + Q_INIT_RESOURCE(pluginview); +} + +QString ViewPlugin::bookMarkText() +{ + return "view"; +} + +QIcon ViewPlugin::bookMarkNormalIcon() +{ + return QIcon(":/images/release.png"); +} + +QIcon ViewPlugin::bookMarkHoverIcon() +{ + return QIcon(":/images/hover.png"); +} + +QIcon ViewPlugin::bookMarkPressedIcon() +{ + return QIcon(":/images/pressed.svg"); +} + +QIcon ViewPlugin::bookMarkCheckedIcon() +{ + return QIcon(":/images/checked.svg"); +} + +QString ViewPlugin::crumbText() +{ + return "view"; +} + +QIcon ViewPlugin::crumbNormalIcon() +{ + return QIcon(":/images/release.png"); +} + +QIcon ViewPlugin::crumbHoverIcon() +{ + return QIcon(":/images/hover.png"); +} + +QIcon ViewPlugin::crumbPressedIcon() +{ + return QIcon(":/images/hover.png"); +} + +QIcon ViewPlugin::crumbCheckedIcon() +{ + return QIcon(":/images/checked.svg"); +} + +bool ViewPlugin::isAddSeparator() +{ + return true; +} + +QString ViewPlugin::scheme() +{ + return "view"; +} + +QWidget *ViewPlugin::createView() +{ + QLabel* label = new QLabel; + label->setText("view"); + label->setAlignment(Qt::AlignCenter); +// label->setStyleSheet("background-color: green; margins:0"); + return label; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/viewplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/viewplugin.h new file mode 100644 index 0000000..66e3a4d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/pluginView/viewplugin.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef VIEWPLUGIN_H +#define VIEWPLUGIN_H + +#include "../plugininterfaces/view/viewinterface.h" + + +class ViewPlugin : /*public QObject, */public ViewInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ViewInterface_iid FILE "pluginView.json") + Q_INTERFACES(ViewInterface) +public: + explicit ViewPlugin(QObject *parent = nullptr); + + QString bookMarkText() override; + QIcon bookMarkNormalIcon() override; + QIcon bookMarkHoverIcon() override; + QIcon bookMarkPressedIcon() override; + QIcon bookMarkCheckedIcon() override; + QString crumbText() override; + QIcon crumbNormalIcon() override; + QIcon crumbHoverIcon() override; + QIcon crumbPressedIcon() override; + QIcon crumbCheckedIcon() override; + bool isAddSeparator() override; + QString scheme() override; + QWidget* createView() override; +}; + +#endif // VIEWPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/plugininterfaces/menu/menuinterface.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/plugininterfaces/menu/menuinterface.h new file mode 100644 index 0000000..dc98aad --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/plugininterfaces/menu/menuinterface.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef MENUINTERFACE +#define MENUINTERFACE + +#include +#include +#include +#include +#include +#include +#include + +/* + * The menu interface of dde-file-manager + * 文件管理器的右键菜单插件接口 +*/ +class MenuInterface : public QObject +{ +public: + explicit MenuInterface(QObject *parent = nullptr) + : QObject(parent) {} + + virtual ~MenuInterface() {} + + /*! + * \brief additionalMenu + * \param files: selected files list + * \param currentDir : the current dir of menu which will be showed + * \return QList: QAction pointer list + */ + /*! + * \brief additionalMenu 选中文件菜单接口 + * \param files: 选中的文件路径列表 + * \param currentDir:右键所在的文件目录 + * \return QList:返回一组QAction指针列表,每个action对应菜单的一个菜单项 + */ + virtual QList additionalMenu(const QStringList &files, const QString& currentDir){ + Q_UNUSED(files) + Q_UNUSED(currentDir) + QList actions; + return actions; + } + + /*! + * \brief additionalEmptyMenu + * \param currentDir: the current dir of empty area menu which will be showed + * \param onDesktop: menu got triggered on desktop (dde-desktop) or not + * \return QList: QAction pointer list + */ + /*! + * \brief additionalEmptyMenu 空白菜单接口 + * \param currentDir: 空白菜单所在的文件目录 + * \param onDesktop: 空白菜单是否为在桌面上触发的 + * \return QList:返回一组QAction指针列表,每个action对应菜单的一个菜单项 + */ + virtual QList additionalEmptyMenu(const QString ¤tDir, bool onDesktop = false){ + Q_UNUSED(currentDir) + Q_UNUSED(onDesktop) + QList actions; + return actions; + } +}; + + +/* + * The property dialog expand info interface of dde-file-manager + * 文件管理器的属性对话框插件接口 +*/ +class PropertyDialogExpandInfoInterface : public QObject +{ +public: + explicit PropertyDialogExpandInfoInterface(QObject *parent = nullptr) + : QObject(parent) {} + + virtual ~PropertyDialogExpandInfoInterface() {} + + /*! + * \brief expandWidget + * \param file: the file path + * \return QWidget*: the widget which will be showed in property dialog + */ + /*! + * \brief expandWidget 属性子控件接口 + * \param file:需要扩展属性显示的文件路径 + * \return QWidget*:返回对应的属性控件指针 + */ + virtual QWidget* expandWidget(const QString& file) { + Q_UNUSED(file) + return new QWidget(); + } + + /*! + * \brief expandWidgetTitle + * \return QString: the title of the QWidget which will be showed in property dialog + */ + /*! + * \brief expandWidgetTitle 属性子控件对应的标题即可 + * \return QString: 返回对应扩展属性控件的标题 + */ + virtual QString expandWidgetTitle(const QString& file){ + return file; + } + +}; + + +#define MenuInterface_iid "com.deepin.dde-file-manager.MenuInterface.V1" + +Q_DECLARE_INTERFACE(MenuInterface, MenuInterface_iid) + +#define PropertyDialogExpandInfoInterface_iid "com.deepin.dde-file-manager.PropertyDialogExpandInfoInterface" +Q_DECLARE_INTERFACE(PropertyDialogExpandInfoInterface, PropertyDialogExpandInfoInterface_iid) + +#endif // MENUINTERFACE + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/plugininterfaces/plugininterfaces.pri b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/plugininterfaces/plugininterfaces.pri new file mode 100644 index 0000000..07641fd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/plugininterfaces/plugininterfaces.pri @@ -0,0 +1,4 @@ +HEADERS += \ + $$PWD/menu/menuinterface.h \ + $$PWD/view/viewinterface.h \ + $$PWD/preview/previewinterface.h diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/plugininterfaces/preview/previewinterface.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/plugininterfaces/preview/previewinterface.h new file mode 100644 index 0000000..c8a070b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/plugininterfaces/preview/previewinterface.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef PREVIEWINTERFACE_H +#define PREVIEWINTERFACE_H + +#include +#include +#include + +#define DEFALT_PREVIEW_MIN_SIZE QSize(600, 300) + +class PreviewInterface : public QObject +{ +public: + explicit PreviewInterface(QObject *parent = 0) + : QObject(parent) {} + + virtual void init(const QString& uri){ + Q_UNUSED(uri) + } + + virtual QWidget* previewWidget(){ + return NULL; + } + + virtual QSize previewWidgetMinSize() const { + return DEFALT_PREVIEW_MIN_SIZE; + } + + virtual bool canPreview() const{ + return false; + } + + virtual QWidget* toolBarItem(){ + return NULL; + } + + virtual QString pluginName() const{ + return ""; + } + + virtual QIcon pluginLogo() const{ + return QIcon(); + } + + virtual QString pluginDescription() const{ + return ""; + } +}; + +#define PreviewInterface_iid "com.deepin.dde-file-manager.PreviewInterface" + +Q_DECLARE_INTERFACE(PreviewInterface, PreviewInterface_iid) + +#endif // PREVIEWINTERFACE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/plugininterfaces/view/viewinterface.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/plugininterfaces/view/viewinterface.h new file mode 100644 index 0000000..82b8441 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/plugininterfaces/view/viewinterface.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: lixiang + * + * Maintainer: zhengyouge + * lixiang + * + * 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 + * 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 . +*/ + +#ifndef VIEWINTERFACE_H +#define VIEWINTERFACE_H + +#include +#include +#include +/* + * The view interface of dde-file-manager + * 文件管理器的视图插件接口 +*/ +class ViewInterface : public QObject +{ +public: + explicit ViewInterface(QObject *parent = 0) + : QObject(parent) {} + + virtual ~ViewInterface() {} + + /*! + * \brief bookMarkText + * \return QString: the text of leftbar bookmark which should be 16X16 size + */ + /*! + * \brief bookMarkText + * \return QString: 侧边栏书签文本内容 + */\ + virtual QString bookMarkText(){ + return ""; + } + + /*! + * \brief bookMarkNormalIcon + * \return QIcon: the release icon of leftbar bookmark which should be 16X16 size + */ + /*! + * \brief bookMarkNormalIcon + * \return QIcon: release状态-侧边栏书签Icon + */ + virtual QIcon bookMarkNormalIcon(){ + return QIcon(); + } + + /*! + * \brief bookMarkHoverIcon + * \return QIcon: the hover icon of leftbar bookmark which should be 16X16 size + */ + /*! + * \brief bookMarkHoverIcon + * \return QIcon: hover状态-侧边栏书签Icon + */ + virtual QIcon bookMarkHoverIcon(){ + return QIcon(); + } + + /*! + * \brief bookMarkPressedIcon + * \return QIcon: the pressed hover icon of leftbar bookmark which should be 16X16 size + */ + /*! + * \brief bookMarkPressedIcon + * \return QIcon: pressed状态-侧边栏书签Icon + */ + virtual QIcon bookMarkPressedIcon(){ + return QIcon(); + } + + /*! + * \brief bookMarkCheckedIcon + * \return QIcon: the checked icon of leftbar bookmark which should be 16X16 size + */ + /*! + * \brief bookMarkCheckedIcon + * \return QIcon: checked状态-侧边栏书签Icon + */ + virtual QIcon bookMarkCheckedIcon(){ + return QIcon(); + } + + /*! + * \brief crumbText + * \return QString: text of first crumbButton in titlebar + */ + /*! + * \brief crumbText + * \return QString: 第一个面包屑的显示文本 + */ + virtual QString crumbText(){ + return ""; + } + + /*! + * \brief crumbNormalIcon + * \return QIcon: the normal icon of first crumbButton in titlebar + */ + /*! + * \brief crumbNormalIcon + * \return QIcon: 第一个面包屑的normal状态图标 + */ + virtual QIcon crumbNormalIcon(){ + return QIcon(); + } + + /*! + * \brief crumbHoverIcon + * \return QIcon: the hover icon of first crumbButton in titlebar + */ + /*! + * \brief crumbHoverIcon + * \return QIcon: 第一个面包屑的normal状态图标 + */ + virtual QIcon crumbHoverIcon(){ + return QIcon(); + } + + /*! + * \brief crumbPressedIcon + * \return QIcon: the pressed icon of first crumbButton in titlebar + */ + /*! + * \brief crumbHoverIcon + * \return QIcon: 第一个面包屑的pressed状态图标 + */ + virtual QIcon crumbPressedIcon(){ + return QIcon(); + } + + /*! + * \brief crumbCheckedIcon + * \return QIcon: the checked icon of first crumbButton in titlebar + */ + /*! + * \brief crumbHoverIcon + * \return QIcon: 第一个面包屑的checked状态图标 + */ + virtual QIcon crumbCheckedIcon(){ + return QIcon(); + } + + + /*! + * \brief isAddSeparator + * \return bool: addSeparator whether or not + */ + /*! + * \brief isAddSeparator + * \return bool:是否添加书签分隔符 + */ + virtual bool isAddSeparator(){ + return false; + } + + /*! + * \brief scheme + * \return QString: scheme of view which should by like computer 、trash、 usershare and so on + */ + /*! + * \brief scheme + * \return QString: 视图view对应的协议头,譬如computer 、trash、 usershare等 + */ + virtual QString scheme(){ + return ""; + } + + /*! + * \brief createView + * \return QWidget* : the view will be registered into dde-file-manager view + */ + /*! + * \brief createView + * \return QWidget*: 注册到文件管理器视图区域的视图控件 + */ + virtual QWidget* createView(){ + return NULL; + } +}; + +#define ViewInterface_iid "com.deepin.dde-file-manager.ViewInterface" + +Q_DECLARE_INTERFACE(ViewInterface,ViewInterface_iid) + +#endif // VIEWINTERFACE_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images.qrc b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images.qrc new file mode 100644 index 0000000..c6b988a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images.qrc @@ -0,0 +1,14 @@ + + + images/b-s0.svg + images/b-s1.svg + images/b-s2.svg + images/b-s3.svg + images/b-s4.svg + images/a-s0.svg + images/a-s1.svg + images/a-s2.svg + images/a-s3.svg + images/a-s4.svg + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s0.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s0.svg new file mode 100644 index 0000000..d2ca485 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s0.svg @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s1.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s1.svg new file mode 100644 index 0000000..d80dea8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s1.svg @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s2.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s2.svg new file mode 100644 index 0000000..f1538c3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s2.svg @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s3.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s3.svg new file mode 100644 index 0000000..2310e65 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s3.svg @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s4.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s4.svg new file mode 100644 index 0000000..b6edada --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/a-s4.svg @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s0.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s0.svg new file mode 100644 index 0000000..ddcc9b4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s0.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s1.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s1.svg new file mode 100644 index 0000000..5786ee5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s1.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s2.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s2.svg new file mode 100644 index 0000000..8fe42ca --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s2.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s3.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s3.svg new file mode 100644 index 0000000..c2d26f4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s3.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s4.svg b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s4.svg new file mode 100644 index 0000000..9cef4d0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/images/b-s4.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/showfile.json b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/showfile.json new file mode 100644 index 0000000..1e81138 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/showfile.json @@ -0,0 +1,3 @@ +{ + "Keys" : [ ] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/showfile.pro b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/showfile.pro new file mode 100644 index 0000000..1661021 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/showfile.pro @@ -0,0 +1,28 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2016-12-01T16:21:23 +# +#------------------------------------------------- + +QT += core gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = showfile +TEMPLATE = lib +CONFIG += c++11 plugin + +include(../../common/common.pri) +include(../plugininterfaces/plugininterfaces.pri) + +DESTDIR = ../menu + +SOURCES += showfileplugin.cpp + +HEADERS += showfileplugin.h +DISTFILES += showfile.json +RESOURCES += images.qrc + +unix { + target.path = $$PLUGINDIR/menu + INSTALLS += target +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/showfileplugin.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/showfileplugin.cpp new file mode 100644 index 0000000..9b89541 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/showfileplugin.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "showfileplugin.h" +#include "interfaces/dfilemenu.h" +#include +#include +#include +#include +#include +#include +#include +#include + +ShowFilePlugin::ShowFilePlugin(QObject *parent) : + QObject(parent) +{ + + aIcon[0] = QIcon(":/images/a-s0.svg"); + aIcon[1] = QIcon(":/images/a-s1.svg"); + aIcon[2] = QIcon(":/images/a-s2.svg"); + aIcon[3] = QIcon(":/images/a-s3.svg"); + aIcon[4] = QIcon(":/images/a-s4.svg"); + + + bIcon[0] = QIcon(":/images/b-s0.svg"); + bIcon[1] = QIcon(":/images/b-s1.svg"); + bIcon[2] = QIcon(":/images/b-s2.svg"); + bIcon[3] = QIcon(":/images/b-s3.svg"); + bIcon[4] = QIcon(":/images/b-s4.svg"); + + + //测试菜单, 一共是 6个 + // 一级菜单:测试4及测试,其中 测试有二级菜单 + // 二级菜单: 测试 下面有:测试0-测试3 + cmdTab << "测试" // 有子菜单 + << "测试0" + << "测试1" + << "测试2" + << "测试3" + << "测试4"; // 一级菜单 +} + +QList ShowFilePlugin::additionalIcons(const QString &file) +{ + // 取回 自己格式中的a, b + int a; + int b; + int ret = analyzeFile(QUrl(file).path(), a, b ); + if( ret ){ + return QIconList(); + } + + QIconList icons; + icons << aIcon[ a ]; + icons << bIcon[ b ]; + + return icons; +} + +QList ShowFilePlugin::additionalMenu(const QStringList &files, const QString ¤tDir) +{ + if(files.count() >= 2) + return QActionList(); + + QString filename = QUrl(files.first()).path(); + + int a = 4; + int b; + + int ret = analyzeFile( filename, a, b ); + if( ret ) + { + return QActionList(); + } + if( a == 4 ) //只显示 测试4 + { + QAction* action = new QAction(cmdTab[ 5 ],this); + action->setData(QUrl(files.first()).path()); + connect(action, &QAction::triggered, this, &ShowFilePlugin::onActionTriggered); + return QActionList() << action; + + } + else // 要 显示二级菜单的第一级菜单 + { + QAction* action = new QAction(cmdTab[ 0 ],this); + action->setData(QUrl(files.first()).path()); + + if( a == 4 ) //只显示 测试0-测试3 + { + return QActionList(); + } + // 显示二级菜单 + DFileMenu* subMenu = new DFileMenu; + QActionList subActions; + for( int i = 0; i <= a; i++ ) + { + QAction* subAction = new QAction(cmdTab[ i+1 ], this); + subAction->setData(filename); + subActions << subAction; + connect(subAction, &QAction::triggered, this, &ShowFilePlugin::onActionTriggered); + } + + subMenu->addActions(subActions); + action->setMenu(subMenu); + + return QActionList() << action; + } + + return QActionList(); +} + +QList ShowFilePlugin::additionalEmptyMenu(const QString ¤tDir) +{ + return QActionList(); +} + +QWidget *ShowFilePlugin::expandWidget(const QString &file) +{ + + int a; + int b; + int ret = analyzeFile(QUrl(file).path(), a, b ); + if( ret ) + { + return NULL; + } + + QWidget*w = new QWidget(); + QVBoxLayout* layout = new QVBoxLayout; + QTextBrowser* tb = new QTextBrowser(w); + tb->setText(QString("Property extend info test:%1 \n%2 \n%3 \n%4") + .arg(file) + .arg("bbbbb") + .arg("ccccccccccc") + .arg("ccccccccc") + .arg("ddddddddddddd")); + layout->addWidget(tb); + w->setLayout(layout); + w->setFixedSize(320,150); + tb->setFixedSize(w->size()); + return w; +} + +QString ShowFilePlugin::expandWidgetTitle(const QString &file) +{ + int a; + int b; + int ret = analyzeFile(QUrl(file).path(), a, b ); + if( ret ) + { + return ""; + } + return "title 1"; +} + +void ShowFilePlugin::onActionTriggered() +{ + QAction* action = qobject_cast(sender()); + if(!action) + return; + + QString actionName = action->text(); + QString file = action->data().toString(); + QStringList args; + + args << actionName << file; + + QProcess::startDetached("/opt/test/testprog", args); +} + +int ShowFilePlugin::analyzeFile(const QString &filename, int &a, int &b) +{ + //测试文件格式为,首行 test[01]开始的,数字0为0-4, 并将这2个位数字分别放在 a, b中 + QFileInfo info( filename ); + if(!info.isFile()) // 为目录 + { + return 2; + } + + QFile file(filename); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + return 2; + } + + QTextStream in(&file); + while (!in.atEnd()) + { + QString line = in.readLine(); //只处理第一行 + bool ok; + QString str = line.mid( 5, 2 ); + ushort dec = str.toUShort(&ok); + if( ok ) + { + a = dec/10; + b = dec%10; + if( a > 4 || a < 0 ) + { + return 1; + } + if( b > 4 || b < 0 ) + { + return 1; + } + str = QString("test[%1%2]").arg( a ).arg( b ); + int posi = line.indexOf( str ); + if( posi == 0 ) + { + return 0; + } + else + { + return 1; + } + } + + break; + } + return 1; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/showfileplugin.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/showfileplugin.h new file mode 100644 index 0000000..833597b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/showfileplugin.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef SHOWFILEPLUGIN_H +#define SHOWFILEPLUGIN_H + +#include +#include "../plugininterfaces/menu/menuinterface.h" + +class QIcon; +class QAction; + +#define MAXICON 5 + +struct cmdMenuStr +{ + int argv; //!< 自定义参数值 + QString str; //!< 命令值对应 的 右键的菜单的字符串 +}; + + +class ShowFilePlugin : public QObject, public MenuInterface , public PropertyDialogExpandInfoInterface +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID MenuInterface_iid FILE "showfile.json") + Q_INTERFACES(MenuInterface PropertyDialogExpandInfoInterface) +public: + ShowFilePlugin(QObject *parent = 0); + QList additionalIcons(const QString &file); + QList additionalMenu(const QStringList &files, const QString& currentDir); + QList additionalEmptyMenu(const QString& currentDir); + + QWidget* expandWidget(const QString &file); + QString expandWidgetTitle(const QString& file); + +public slots: + void onActionTriggered(); + +private: + int analyzeFile(const QString &filename, int &a, int &b ); + QIcon aIcon[ MAXICON ]; //!< 自定义格式文件中a对应的图标 + QIcon bIcon[ MAXICON ]; //!< 自定义格式文件中a对应的图标 + QStringList cmdTab; //!< 每一个菜单的显示内容及键值,自定义值 +}; + +typedef QList QIconList; +typedef QList QActionList; + +#endif // SHOWFILEPLUGIN_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a0.txt b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a0.txt new file mode 100644 index 0000000..cf8181c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a0.txt @@ -0,0 +1 @@ +test[04] diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a1.txt b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a1.txt new file mode 100644 index 0000000..681e160 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a1.txt @@ -0,0 +1 @@ +test[13] diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a2.txt b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a2.txt new file mode 100644 index 0000000..39ddcc8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a2.txt @@ -0,0 +1 @@ +test[22] diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a3.txt b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a3.txt new file mode 100644 index 0000000..17fd4e3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a3.txt @@ -0,0 +1 @@ +test[31] diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a4.txt b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a4.txt new file mode 100644 index 0000000..3cfd8a4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/a4.txt @@ -0,0 +1 @@ +test[40] diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b.txt b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b.txt new file mode 100644 index 0000000..76c9b0e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b.txt @@ -0,0 +1 @@ +test[00] diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b0.txt b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b0.txt new file mode 100644 index 0000000..76c9b0e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b0.txt @@ -0,0 +1 @@ +test[00] diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b1.txt b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b1.txt new file mode 100644 index 0000000..63017cb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b1.txt @@ -0,0 +1 @@ +test[11] diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b2.txt b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b2.txt new file mode 100644 index 0000000..39ddcc8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b2.txt @@ -0,0 +1 @@ +test[22] diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b3.txt b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b3.txt new file mode 100644 index 0000000..a1eb1c1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b3.txt @@ -0,0 +1 @@ +test[33] diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b4.txt b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b4.txt new file mode 100644 index 0000000..67c47d4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testFiles/b4.txt @@ -0,0 +1 @@ +test[44] diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/.moc/moc_echowindow.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/.moc/moc_echowindow.cpp new file mode 100644 index 0000000..76a4fbb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/.moc/moc_echowindow.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "../echowindow.h" +#include +#include +#if !defined(Q_MOC_OUTPUT_REVISION) +#error "The header file 'echowindow.h' doesn't include ." +#elif Q_MOC_OUTPUT_REVISION != 67 +#error "This file was generated using the moc from 5.5.1. It" +#error "cannot be used with the include files from this version of Qt." +#error "(The moc has changed too much.)" +#endif + +QT_BEGIN_MOC_NAMESPACE +struct qt_meta_stringdata_EchoWindow_t { + QByteArrayData data[3]; + char stringdata0[21]; +}; +#define QT_MOC_LITERAL(idx, ofs, len) \ + Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ + qptrdiff(offsetof(qt_meta_stringdata_EchoWindow_t, stringdata0) + ofs \ + - idx * sizeof(QByteArrayData)) \ + ) +static const qt_meta_stringdata_EchoWindow_t qt_meta_stringdata_EchoWindow = { + { +QT_MOC_LITERAL(0, 0, 10), // "EchoWindow" +QT_MOC_LITERAL(1, 11, 8), // "sendEcho" +QT_MOC_LITERAL(2, 20, 0) // "" + + }, + "EchoWindow\0sendEcho\0" +}; +#undef QT_MOC_LITERAL + +static const uint qt_meta_data_EchoWindow[] = { + + // content: + 7, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: name, argc, parameters, tag, flags + 1, 0, 19, 2, 0x08 /* Private */, + + // slots: parameters + QMetaType::Void, + + 0 // eod +}; + +void EchoWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + EchoWindow *_t = static_cast(_o); + Q_UNUSED(_t) + switch (_id) { + case 0: _t->sendEcho(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObject EchoWindow::staticMetaObject = { + { &QWidget::staticMetaObject, qt_meta_stringdata_EchoWindow.data, + qt_meta_data_EchoWindow, qt_static_metacall, Q_NULLPTR, Q_NULLPTR} +}; + + +const QMetaObject *EchoWindow::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject; +} + +void *EchoWindow::qt_metacast(const char *_clname) +{ + if (!_clname) return Q_NULLPTR; + if (!strcmp(_clname, qt_meta_stringdata_EchoWindow.stringdata0)) + return static_cast(const_cast< EchoWindow*>(this)); + return QWidget::qt_metacast(_clname); +} + +int EchoWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QWidget::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 1) + qt_static_metacall(this, _c, _id, _a); + _id -= 1; + } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { + if (_id < 1) + *reinterpret_cast(_a[0]) = -1; + _id -= 1; + } + return _id; +} +QT_END_MOC_NAMESPACE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/main.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/main.cpp new file mode 100644 index 0000000..3ecfc0e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/main.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "mainwindow.h" +#include + +int main(int argc, char *argv[]) +{ + if(argc != 3) + { + return 0; + } + QApplication a(argc, argv); + QString eventname = a.arguments().at(1); + QString filepath = a.arguments().at(2); + MainWindow w(eventname,filepath); + w.show(); + w.move ((1333 - w.width())/2,(800 - w.height())/2); + return a.exec(); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/mainwindow.cpp b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/mainwindow.cpp new file mode 100644 index 0000000..eb35625 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/mainwindow.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#include "mainwindow.h" +#include "ui_testprog.h" + +MainWindow::MainWindow(QString &eventname,QString &filepath,QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); + ui->event->setText( eventname ); + ui->filename->setText( filepath ); +} + +MainWindow::~MainWindow() +{ + delete ui; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/mainwindow.h b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/mainwindow.h new file mode 100644 index 0000000..26c0516 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/mainwindow.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. + * 2016 ~ 2018 dragondjf + * + * Author: dragondjf + * + * Maintainer: dragondjf + * zccrs + * Tangtong + * + * 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 + * 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 . + */ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QString &eventname,QString &filepath, QWidget *parent = 0); + ~MainWindow(); + +private: + Ui::MainWindow *ui; +}; + +#endif // MAINWINDOW_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/testprog.pro b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/testprog.pro new file mode 100644 index 0000000..e33f1ec --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/testprog.pro @@ -0,0 +1,23 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2016-10-09T09:08:48 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = testprog +TEMPLATE = app + + +SOURCES += main.cpp\ + mainwindow.cpp + +HEADERS += mainwindow.h + +FORMS += testprog.ui +target.path = /opt/test/ +INSTALLS += target + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/testprog.ui b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/testprog.ui new file mode 100644 index 0000000..a9e2323 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/showfile/testprog/testprog.ui @@ -0,0 +1,100 @@ + + + MainWindow + + + + 0 + 0 + 341 + 175 + + + + 菜单测试 + + + + + 10 + 10 + 321 + 151 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 10 + 57 + 37 + 23 + + + + 菜单: + + + + + + 64 + 57 + 181 + 23 + + + + 测试 + + + + + + 80 + 20 + 67 + 23 + + + + 点击事件: + + + + + + 10 + 95 + 37 + 23 + + + + 文件: + + + + + + 62 + 95 + 241 + 23 + + + + TextLabel + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/translations/dde-file-manager-plugins.ts b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/translations/dde-file-manager-plugins.ts new file mode 100644 index 0000000..81b3274 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/translations/dde-file-manager-plugins.ts @@ -0,0 +1,35 @@ + + + + + MusicMessageView + + + Artist: + + + + + Album: + + + + + unknown artist + + + + + unknown album + + + + + PdfWidget + + + Cannot preview this file! + + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/translations/dde-file-manager-plugins_zh_CN.ts b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/translations/dde-file-manager-plugins_zh_CN.ts new file mode 100644 index 0000000..1cc03d5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/translations/dde-file-manager-plugins_zh_CN.ts @@ -0,0 +1,35 @@ + + + + + MusicMessageView + + + Artist: + 歌手: + + + + Album: + 专辑: + + + + unknown artist + 未知歌手 + + + + unknown album + 未知专辑 + + + + PdfWidget + + + Cannot preview this file! + 不能预览这个文件! + + + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager-plugins/update_translations.sh b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/update_translations.sh new file mode 100755 index 0000000..40a9114 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager-plugins/update_translations.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# this file is used to auto update ts file. + +lupdate -ts translations/dde-file-manager-plugins.ts -no-obsolete +lupdate -ts translations/dde-file-manager-plugins_zh_CN.ts -no-obsolete diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/accessible/accessiblelist.h b/dde-file-manager-5.5.3/src/dde-file-manager/accessible/accessiblelist.h new file mode 100644 index 0000000..5acf7fa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/accessible/accessiblelist.h @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2020 UOS Technology Co., Ltd. + * + * to mark the desktop UI + **/ + +#ifndef DDE_FILE_MANAGER_ACCESSIBLE_LIST_H +#define DDE_FILE_MANAGER_ACCESSIBLE_LIST_H + +#include "acframefunctions.h" + +#include + + +// 添加accessible +SET_FORM_ACCESSIBLE(QWidget,m_w->accessibleName()) + +QAccessibleInterface *accessibleFactory(const QString &classname, QObject *object) +{ + QAccessibleInterface *interface = nullptr; + + USE_ACCESSIBLE(classname, QWidget); + + return interface; +} + +#endif // DDE_FILE_MANAGER_ACCESSIBLE_LIST_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/commandlinemanager.cpp b/dde-file-manager-5.5.3/src/dde-file-manager/commandlinemanager.cpp new file mode 100644 index 0000000..bd12072 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/commandlinemanager.cpp @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "commandlinemanager.h" +#include "dfmeventdispatcher.h" +#include "filemanagerapp.h" +#include "dabstractfileinfo.h" +#include "dfileservices.h" +#include "dfmapplication.h" +#include "dfmstandardpaths.h" +#include "controllers/vaultcontroller.h" + +#include +#include +#include +#include + +DFM_USE_NAMESPACE + +CommandLineManager::CommandLineManager() + : m_commandParser(new QCommandLineParser) +{ + m_commandParser->setApplicationDescription(QString("%1 helper").arg(QCoreApplication::applicationName())); + initOptions(); + m_commandParser->addHelpOption(); + m_commandParser->addVersionOption(); +} + +void CommandLineManager::process() +{ + return process(qApp->arguments()); +} + +void CommandLineManager::process(const QStringList &arguments) +{ + m_commandParser->process(arguments); +} + +void CommandLineManager::initOptions() +{ + QCommandLineOption newWindowOption(QStringList() << "n" << "new-window", "show new window"); + QCommandLineOption backendOption(QStringList() << "d" << "none-window-process", "start dde-file-manager in no window mode"); + QCommandLineOption openPropertyDialogOption(QStringList() << "p" << "property", "show property dialog"); + QCommandLineOption rootOption(QStringList() << "r" << "root", "exec dde-file-manager in root mode"); + QCommandLineOption showFileItem(QStringList() << "show-item", "show a file item in a new window"); + QCommandLineOption raw(QStringList() << "R" << "raw", "process file item url as raw QUrl,will not encode special characters(e.g. '#' '&' '@' '!' '?')"); + QCommandLineOption event(QStringList() << "e" << "event", "process the event by json data"); + + QCommandLineOption get_monitor_files(QStringList() << "get-monitor-files", "Get all the files that have been monitored"); + // blumia: about -w and -r: -r will exec `dde-file-manager-pkexec` (it use `pkexec` command) which won't pass the currect + // working dir, so we need to manually set the working dir via -w. that's why we add a -w arg. + QCommandLineOption workingDirOption(QStringList() << "w" << "working-dir", + "set the file manager working directory (won't work with -r argument)", + "directory"); + QCommandLineOption openWithDialog(QStringList() << "o" << "open", "open with dialog"); + QCommandLineOption openHomeOption(QStringList() << "O" << "open-home", "open home"); + + addOption(newWindowOption); + addOption(backendOption); + addOption(openPropertyDialogOption); + addOption(rootOption); + addOption(showFileItem); + addOption(raw); + addOption(event); + addOption(get_monitor_files); + addOption(workingDirOption); + addOption(openWithDialog); + addOption(openHomeOption); +} + +void CommandLineManager::addOption(const QCommandLineOption &option) +{ + m_commandParser->addOption(option); +} + +void CommandLineManager::addOptions(const QList &options) +{ + foreach (QCommandLineOption option, options) { + addOption(option); + } +} + +QStringList CommandLineManager::positionalArguments() const +{ + return m_commandParser->positionalArguments(); +} + +QStringList CommandLineManager::unknownOptionNames() const +{ + return m_commandParser->unknownOptionNames(); +} + +void CommandLineManager::processCommand() +{ + if (isSet("e")) { + // init + Q_UNUSED(FileManagerApp::instance()); + const QSharedPointer &event = DFMEvent::fromJson(QJsonDocument::fromJson(positionalArguments().first().toLocal8Bit().constData()).object()); + + if (event) + DFMEventDispatcher::instance()->processEvent(event); + + return; + } + + if (isSet("p")) { + QStringList paths = positionalArguments(); + FileManagerApp::instance()->showPropertyDialog(paths); + + return; + } + + if (isSet("o")) { + QStringList files = positionalArguments(); + FileManagerApp::instance()->openWithDialog(files); + + return; + } + + if (isSet("O")) { + DUrlList argumentUrls; + QString homePath = DFMStandardPaths::location(DFMStandardPaths::StandardLocation::HomePath); + DUrl url = DUrl::fromUserInput(homePath); + argumentUrls.append(url); + DFMEventDispatcher::instance()->processEvent(Q_NULLPTR, argumentUrls, isSet("n")); + return; + } + + DUrlList argumentUrls; + + foreach (QString path, positionalArguments()) { + if (!CommandLineManager::instance()->isSet("raw")) { + //路径字符串在DUrl::fromUserInput中会处理编码,这里不处理 + if (!QDir().exists(path) && !path.startsWith("./") && + !path.startsWith("../") && !path.startsWith("/")) + { + // 路径中包含特殊字符的全部uri编码 + QRegExp regexp("[#&@\\!\\?]"); + if (path.contains(regexp)) { + QString left, right, encode; + int idx = path.indexOf(regexp); + while (idx != -1) { + left = path.left(idx); + right = path.mid(idx + 1); + encode = QUrl::toPercentEncoding(path.mid(idx, 1)); + path = left + encode + right; + idx = path.indexOf(regexp); + } + } + } + } + + DUrl url = DUrl::fromUserInput(path); + + //! 如果为保险箱路径,则进行转换,确保可以在保险箱中打开 + if (VaultController::isVaultFile(url.toString())) { + url = VaultController::localUrlToVault(url); + } + + // fix bug 67294 + QString filePath = url.path(); + QString trashFilesPath = DFMStandardPaths::location(DFMStandardPaths::TrashFilesPath); + if (filePath.startsWith(trashFilesPath)) { + if (filePath == trashFilesPath) + filePath += "/"; + url = filePath.replace(trashFilesPath + "/", TRASH_ROOT); + } + + if (CommandLineManager::instance()->isSet("show-item")) { + const DAbstractFileInfoPointer &fileInfo = DFileService::instance()->createFileInfo(Q_NULLPTR, url); + if (!fileInfo) + continue; + + DUrl newUrl = fileInfo->parentUrl(); + + newUrl.setQuery("selectUrl=" + url.toString()); + url = newUrl; + } + + argumentUrls.append(url); + } + if (argumentUrls.isEmpty()) + argumentUrls.append(DFMApplication::instance()->appUrlAttribute(DFMApplication::AA_UrlOfNewWindow)); + + DFMEventDispatcher::instance()->processEvent(Q_NULLPTR, argumentUrls, isSet("n")); +} + +CommandLineManager *CommandLineManager::instance() +{ + static CommandLineManager instance; + + return &instance; +} + +bool CommandLineManager::isSet(const QString &name) const +{ + return m_commandParser->isSet(name); +} + +QString CommandLineManager::value(const QString &name) const +{ + return m_commandParser->value(name); +} + +CommandLineManager::~CommandLineManager() +{ + +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/commandlinemanager.h b/dde-file-manager-5.5.3/src/dde-file-manager/commandlinemanager.h new file mode 100644 index 0000000..8c7afb0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/commandlinemanager.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef COMMANDLINEMANAGER_H +#define COMMANDLINEMANAGER_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QCommandLineParser; +class QCoreApplication; +QT_END_NAMESPACE + +class DUrl; + +class CommandLineManager +{ +public: + static CommandLineManager *instance(); + + bool isSet(const QString &name) const; + QString value(const QString &name) const; + + void process(); + void process(const QStringList &arguments); + + void addOption(const QCommandLineOption &option); + void addOptions(const QList &options); + QStringList positionalArguments() const; + QStringList unknownOptionNames() const; + + void processCommand(); + +private: + explicit CommandLineManager(); + CommandLineManager(CommandLineManager &) = delete; + CommandLineManager &operator=(CommandLineManager &) = delete; + void initOptions(); + + ~CommandLineManager(); + QCommandLineParser *m_commandParser; +}; + +#endif // COMMANDLINEMANAGER_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/dde-file-manager.desktop b/dde-file-manager-5.5.3/src/dde-file-manager/dde-file-manager.desktop new file mode 100644 index 0000000..04c2cde --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/dde-file-manager.desktop @@ -0,0 +1,259 @@ +[Desktop Entry] +Actions=new-window; +Categories=Utility; +Comment=Browse the file system +Exec=/usr/bin/dde-file-manager -n %u +GenericName=File Manager +Icon=dde-file-manager +MimeType=inode/directory; +Name=Deepin File Manager +StartupNotify=true +Terminal=false +Type=Application +Version=1.0 +X-Deepin-DEComponent=true +X-Deepin-Vendor=deepin + +# Translations: +# Do not manually modify! +Comment[am_ET]=የ ፋይል ስርአት መቃኛ +Comment[ar]=تصفح ملف النظام +Comment[ast]=Restola sistemes de ficheros +Comment[az]=Fayl sisteminə baxış +Comment[bg]=Преглед на файловата система +Comment[bn]=ফাইল সিস্টেম ব্রাউজ করুন +Comment[bo]=ཡིག་ཆའི་རྒྱུད་ཁོངས་ལ་རགས་ཙམ་ལྟ་བ། +Comment[ca]=Navegueu pel sistema de fitxers +Comment[cs]=Procházet souborový systém +Comment[da]=Gennemse filsystemet +Comment[de]=Dateisystem durchsuchen +Comment[el]=Περιηγηθείτε στο αρχείο συστήματος +Comment[en_AU]=Browse the file system +Comment[en_GB]=Browse the file system +Comment[es]=Examinar el sistema de archivos +Comment[et]=Sirvi failisüsteemi +Comment[eu]=Arakatu fitxategi sistema +Comment[fa]=سیستم فایل را مرور کنید +Comment[fi]=Selaa tiedostoja +Comment[fr]=Parcourir le système de fichiers +Comment[gl]=Examinar o sistema de ficheiros +Comment[gl_ES]=Examina o sistema de ficheiros +Comment[he]=עיון במערכת הקבצים +Comment[hr]=Pregledavaj datotečni sustav +Comment[hu]=A fájlrendszer böngészése +Comment[id]=Ramban sistem berkas +Comment[is]=Flakka í skráakerfinu +Comment[it]=Apri il File System +Comment[ja]=ファイル システムを参照します +Comment[kab]=Snirem anagraw n yifuyla +Comment[kk]=Файлдық жүйені шолу +Comment[ko]=파일 시스템 찾아보기 +Comment[lt]=Naršyti failų sistemą +Comment[mn]=Файл системийг ажиглах +Comment[ms]=Layar sistem fail +Comment[nb]=Bla gjennom filsystemet +Comment[ne]=फाईल प्रणाली ब्राउज गर्नुहोस् +Comment[nl]=Verken het bestandssysteem +Comment[nn]=Bla gjennom filsystemet +Comment[oc]=Percórrer lo sistèma de fichièrs +Comment[pa]=ਫਾਇਲ ਸਿਸਟਮ ਬਰਾਊਜ਼ ਕਰੋ +Comment[pl]=Przeglądaj system plików +Comment[pt]=Explorar o sistema de ficheiros +Comment[pt_BR]=Navegar pelos arquivos do sistema +Comment[ro]=Gestionați fișierele din sistem +Comment[ru]=Просмотр файловой системы +Comment[sk]=Prehľadávanie systému súborov +Comment[sl]=Brskaj po datotečnem sistemu +Comment[sq]=Shfletoni sistemin e kartelave +Comment[sr]=Прегледај систем датотека +Comment[sv]=Bläddra i filsystemet +Comment[ta]=கோப்பு முறைமை உலாவுக +Comment[te]=దస్త్ర వ్యవస్థను విహరించు +Comment[th]=ท่องดูระบบแฟ้ม +Comment[tr]=Dosya sistemine gözat +Comment[ug]=ھۆججەت سىستېمىسىنى كۆرىدۇ +Comment[uk]=Перегляд файлової системи +Comment[vi]=Duyệt hệ thống tệp tin +Comment[zh_CN]=浏览文件系统 +Comment[zh_HK]=瀏覽檔案系統 +Comment[zh_TW]=瀏覽與管理檔案系統 +GenericName[am_ET]=የ ፋይል አስተዳዳሪ +GenericName[ar]=مدير الملفات +GenericName[ast]=Xestor de ficheros +GenericName[az]=Fayl Meneceri +GenericName[bg]=Файлов мениджър +GenericName[bo]=ཡིག་ཆ་དོ་དམ་བྱེད་ཆས། +GenericName[ca]=Gestor de fitxers +GenericName[cs]=Správce souborů +GenericName[da]=Filhåndtering +GenericName[de]=Dateimanager +GenericName[el]=Διαχειριστής αρχείων +GenericName[en_AU]=File Manager +GenericName[es]=Administrador de archivos +GenericName[et]=Failihaldur +GenericName[fa]=مدیر فایل +GenericName[fi]=Tiedostohallinta +GenericName[fr]=Gestionnaire de fichiers +GenericName[gl_ES]=Xestor de ficheiros +GenericName[hr]=Upravitelj datotekama +GenericName[hu]=Fájlkezelő +GenericName[id]=Manajer Berkas +GenericName[it]=File Manager +GenericName[ja]=ファイル マネージャー +GenericName[kab]=Amsefrek n ifuyla +GenericName[ko]=파일 관리자 +GenericName[lt]=Failų tvarkytuvė +GenericName[ml]=ഫയൽ മാനേജർ +GenericName[mn]=Файл менежер +GenericName[ms]=Pengurus Fail +GenericName[nb]=Filutforsker +GenericName[ne]=फाइल प्रबन्धक +GenericName[nl]=Bestandsbeheer +GenericName[pl]=Menedżer plików +GenericName[pt]=Gestor de Ficheiros +GenericName[pt_BR]=Gerenciador de Arquivos +GenericName[ro]=Manager de fișiere +GenericName[ru]=Файловый Менеджер +GenericName[sk]=Správca súborov +GenericName[sl]=Upravitelj datotek +GenericName[sq]=Përgjegjës Kartelash +GenericName[sr]=Управник Података +GenericName[sv]=Filhanterare +GenericName[ta]=கோப்பு மேலாளர் +GenericName[tr]=Dosya Yöneticisi +GenericName[ug]=ھۆججەت باشقۇرغۇچ +GenericName[uk]=Файловий менеджер +GenericName[zh_CN]=文件管理器 +GenericName[zh_HK]=檔案管理員 +GenericName[zh_TW]=檔案管理器 +Name[am_ET]=ዲፕኢን የ ፋይል አስተዳዳሪ +Name[ar]=مدير ملفات ديبين +Name[ast]=Deepin File Manager +Name[az]=Deepin Fayl Meneceri +Name[bg]=Файлов мениджър +Name[bn]=ফাইল ম্যানেজার +Name[bo]=གཏིང་ཚད་ཡིག་ཆ་དོ་དམ་བྱེད་ཆས། +Name[ca]=Gestor de fitxers del Deepin +Name[cs]=Deepin správce souborů +Name[da]=Deepin filhåndtering +Name[de]=Deepin Dateimanager +Name[el]=Διαχειριστής αρχείων +Name[en_AU]=Deepin File Manager +Name[en_GB]=Deepin File Manager +Name[es]=Administrador de archivos +Name[et]=Deepin failihaldur +Name[eu]=Fitxategi kudeatzailea +Name[fa]=مدیر فایل دیپین +Name[fi]=Deepin tiedostohallinta +Name[fr]=Gestionnaire de fichiers Deepin +Name[gl]=Xestor de ficheiros +Name[gl_ES]=Xestor de ficheiros +Name[he]=מנהל קבצים +Name[hr]=Deepin upravltelj datotekama +Name[hu]=Deepin® Fájlkezelő +Name[id]=Manajer Berkas +Name[is]=Skráastjóri +Name[it]=Deepin File Manager +Name[ja]=Deepin ファイル マネージャー +Name[kab]=Amsefrak n yifuyla n Deepin +Name[kk]=Файлдар басқарушысы +Name[ko]=Deepin 파일 관리자 +Name[lt]=Deepin failų tvarkytuvė +Name[lv]=Faila pārvaldnieks +Name[ml]=ഡീപിൻ ഫയൽ മാനേജർ +Name[mn]=Диипин файл менежер +Name[ms]=Pengurus Fail Deepin +Name[nb]=Filbehandler +Name[ne]=डीपिन फाइल प्रबन्धक +Name[nl]=Deepin Bestandsbeheer +Name[nn]=Filhandsamar +Name[oc]=Gestionari de fichièrs +Name[pa]=ਡੀਪਿਨ ਫਾਇਲ ਮੈਨੇਜਰ +Name[pl]=Menedżer plików Deepin +Name[pt]=Gestor de Ficheiros Deepin +Name[pt_BR]=deepin Gerenciador de Arquivos +Name[ro]=Manager de fișiere Deepin +Name[ru]=Файловый Менеджер Deepin +Name[sk]=Deepin Správca súborov +Name[sl]=Upravitelj datotek Deepin +Name[sq]=Përgjegjës Kartelash Deepin +Name[sr]=Дипин Управник Података +Name[sv]=Filhanterare +Name[ta]=டீபைன் கோப்பு மேலாளர் +Name[te]=దస్త్ర నిర్వాహకం +Name[th]=โปรแกรมจัดการแฟ้ม +Name[tr]=Deepin Dosya Yöneticisi +Name[ug]=ھۆججەت باشقۇرغۇچ +Name[uk]=Файловий менеджер Deepin +Name[vi]=Trình quản lý tệp tin +Name[zh_CN]=深度文件管理器 +Name[zh_HK]=深度檔案管理員 +Name[zh_TW]=Deepin 檔案管理器 + +[Desktop Action new-window] +Exec=dde-file-manager --new-window +Name=New Window +Name[sr@latin]=Novi prozor + +# Translations: +# Do not manually modify! +Name[am_ET]=አዲስ መስኮት +Name[ar]=نافذة جديدة +Name[ast]=Ventana nueva +Name[az]=Yeni Pəncərə +Name[bg]=Нов прозорец +Name[bn]=নতুন উইন্ডো +Name[bo]=སྒེའུ་ཁུང་གསར་འཛུགས། +Name[ca]=Finestra nova +Name[cs]=Nové okno +Name[da]=Nyt vindue +Name[de]=Neues Fenster +Name[el]=Νέο παράθυρο +Name[en_AU]=New Window +Name[es]=Nueva ventana +Name[et]=Uus aken +Name[eu]=Leiho berria +Name[fa]=پنجره نو +Name[fi]=Uusi ikkuna +Name[fr]=Nouvelle fenêtre +Name[fur]=Gnûf barcon +Name[gd]=Uinneag ùr +Name[gl]=Nova xanela +Name[gl_ES]=Nova xanela +Name[he]=חלון חדש +Name[hr]=Novi prozor +Name[hu]=Új ablak +Name[id]=Jendela Baru +Name[it]=Nuova finestra +Name[ja]=新規ウィンドウ +Name[kab]=Asfaylu amaynut +Name[kk]=Жаңа терезе +Name[ko]=새 창 +Name[lt]=Naujas langas +Name[lv]=Jauns logs +Name[mn]=Шинэ цонх +Name[ms]=Tetinkap Baharu +Name[nb]=Nytt vindu +Name[ne]=नयाँ विन्डो +Name[nl]=Nieuw venster +Name[oc]=Fenèstra novèla +Name[pa]=ਨਵੀਂ ਵਿੰਡੋ +Name[pl]=Nowe okno +Name[pt]=Nova Janela +Name[pt_BR]=Nova Janela +Name[ro]=Fereastră nouă +Name[ru]=Новое Окно +Name[sk]=Nové okno +Name[sl]=Novo okno +Name[sq]=Dritare e Re +Name[sr]=Нови прозор +Name[sv]=Nytt fönster +Name[ta]=புதிய திரை +Name[th]=หน้าต่างใหม่ +Name[tr]=Yeni Pencere +Name[ug]=يېڭى كۆزنەك +Name[uk]=Нове вікно +Name[zh_CN]=新建窗口 +Name[zh_HK]=新建窗口 +Name[zh_TW]=新增視窗 + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/dde-file-manager.pro b/dde-file-manager-5.5.3/src/dde-file-manager/dde-file-manager.pro new file mode 100644 index 0000000..6f9b9eb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/dde-file-manager.pro @@ -0,0 +1,152 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-06-24T09:14:17 +# +#------------------------------------------------- + +include(../common/common.pri) + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +QT += network concurrent multimedia + +isEmpty(TARGET) { + TARGET = $$ProjectName +} + +TEMPLATE = app +CONFIG += c++11 link_pkgconfig +PKGCONFIG += gio-unix-2.0 +CONFIG(release, release|debug) { + PKGCONFIG += dtkwidget +} else { + PKGCONFIG += dtkwidget +} + +DEFINES += QMAKE_TARGET=\\\"$$TARGET\\\" QMAKE_VERSION=\\\"$$VERSION\\\" + +DEFINES += QT_MESSAGELOGCONTEXT + +# 获取标签系统设置,具体环境变量还需要等集成测试统一安排 +AC_FUNC_ENABLE = true +#AC_FUNC_ENABLE = $$(ENABLE_AC_FUNC) +# 检查集成测试标签 +equals( AC_FUNC_ENABLE, true ){ + DEFINES += ENABLE_ACCESSIBILITY + message("dde-file-manager enabled accessibility function with set: " $$AC_FUNC_ENABLE) +} + +isEmpty(QMAKE_ORGANIZATION_NAME) { + DEFINES += QMAKE_ORGANIZATION_NAME=\\\"deepin\\\" +} + +CONFIG(release, debug|release) { + !system($$PWD/translate_ts2desktop.sh): error("Failed to generate translation") +} + +CONFIG(debug, debug|release) { +# LIBS += -lprofiler +# DEFINES += ENABLE_PPROF +} + +# 集成测试标签 +include($$PWD/../../3rdparty/accessibility/accessibility-suite.pri) + +SOURCES += \ + main.cpp \ + filemanagerapp.cpp \ + logutil.cpp \ + singleapplication.cpp \ + commandlinemanager.cpp \ + desktopinfo.cpp + +INCLUDEPATH += $$PWD/../dde-file-manager-lib $$PWD/.. \ + $$PWD/../utils \ + $$PWD/../dde-file-manager-lib/interfaces + +BINDIR = $$PREFIX/bin +DEFINES += APPSHAREDIR=\\\"$$PREFIX/share/$$TARGET\\\" + +target.path = $$BINDIR + +desktop.path = $${PREFIX}/share/applications/ +isEqual(ARCH, sw_64) | isEqual(ARCH, mips64) | isEqual(ARCH, mips32) | isEqual(ARCH, aarch64) | isEqual(ARCH, loongarch64) | isEqual(ARCH, riscv64) { + desktop.files = $$PWD/mips/$${TARGET}.desktop \ + dde-open.desktop +}else{ + desktop.files = $${TARGET}.desktop \ + dde-open.desktop +} + +policy.path = $${PREFIX}/share/polkit-1/actions/ +policy.files = pkexec/com.deepin.pkexec.dde-file-manager.policy + +pkexec.path = /usr/bin/ +pkexec.files = pkexec/dde-file-manager-pkexec + +propertyDialogShell.path = /usr/bin/ +propertyDialogShell.files = dde-property-dialog + +manual.files = $$PWD/../../assets/dde-file-manager +manual.path = /usr/share/deepin-manual/manual-assets/application + +INSTALLS += target desktop policy pkexec propertyDialogShell manual + +isEqual(ARCH, sw_64) | isEqual(ARCH, mips64) | isEqual(ARCH, mips32) | isEqual(ARCH, aarch64) | isEqual(ARCH, loongarch64) | isEqual(ARCH, riscv64) { + dde-mips-shs.path = $$BINDIR + dde-mips-shs.files = $$PWD/mips/dde-computer.sh \ + $$PWD/mips/dde-trash.sh \ + $$PWD/mips/file-manager.sh + + dde-file-manager-autostart.path = /etc/xdg/autostart + dde-file-manager-autostart.files = $$PWD/mips/dde-file-manager-autostart.desktop dde-file-manager-dialog-autostart.desktop + INSTALLS += dde-mips-shs dde-file-manager-autostart +}else{ + autostart.path = /etc/xdg/autostart + autostart.files = dde-file-manager-xdg-autostart.desktop dde-file-manager-dialog-autostart.desktop + INSTALLS += autostart +} + +win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../dde-file-manager-lib/release -ldde-file-manager +else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../dde-file-manager-lib/debug -ldde-file-manager +else:unix: LIBS += -L$$OUT_PWD/../dde-file-manager-lib -ldde-file-manager -lKF5Codecs + +CONFIG(debug, debug|release) { + DEPENDPATH += $$PWD/../dde-file-manager-lib + unix:QMAKE_RPATHDIR += $$OUT_PWD/../dde-file-manager-lib +} + +#安全加固 +QMAKE_CXXFLAGS += -fstack-protector-all +QMAKE_LFLAGS += -z now -pie -fPIE +isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + QMAKE_LFLAGS += -z noexecstack -z relro +} + +HEADERS += \ + filemanagerapp.h \ + logutil.h \ + singleapplication.h \ + commandlinemanager.h \ + desktopinfo.h \ + accessible/accessiblelist.h + +DISTFILES += \ + mips/dde-file-manager-autostart.desktop \ + mips/dde-file-manager.desktop \ + mips/dde-computer.sh \ + mips/dde-trash.sh \ + mips/file-manager.sh \ + generate_translations.sh \ + dde-open.desktop + +TRANSLATIONS += $$PWD/translations/$${TARGET}-app.ts \ + $$PWD/translations/$${TARGET}-app_zh_CN.ts + +translations.path = $$APPSHAREDIR/translations +translations.files = translations/*.qm + +INSTALLS += translations + +CONFIG(release, debug|release) { + !system($$PWD/generate_translations.sh): error("Failed to generate translation") +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/dde-open.desktop b/dde-file-manager-5.5.3/src/dde-file-manager/dde-open.desktop new file mode 100644 index 0000000..994267e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/dde-open.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Categories=Utility; +Comment=Open file with dialog +Exec=/usr/bin/dde-file-manager -o %u +GenericName=Open Dialog +Icon=dde-file-manager +NoDisplay=true +StartupNotify=true +Name=DDE Open Dialog +Terminal=false +Type=Application diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/dde-property-dialog b/dde-file-manager-5.5.3/src/dde-file-manager/dde-property-dialog new file mode 100755 index 0000000..e3c67d2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/dde-property-dialog @@ -0,0 +1,38 @@ +#!/bin/bash +#shell name: dde-property-dialog.sh +#description: reuqest show files's or folders's property dialog. +#usage: just use it in bash like dde-property-dialog path1 path2 ... + +#!/bin/bash +process=`ps ax -o 'cmd' |grep 'dde-file-manager$'`; +processd=`ps ax -o 'cmd' |grep 'dde-file-manager -d$'`; +data="ZGRlLWZpbGUtbWFuYWdlcg==" + +if [[ "$process" == ""&&"$processd" == "" ]]; then + dde-file-manager -p "$@"; +else + option="-p" + option_base64=`echo -n $option|base64 -w 0` + data=$data" "$option_base64 + + for path in "$@"; + do + path_base64=`echo -n $path|base64 -w 0` + data=$data" "$path_base64 + done + + target=$XDG_RUNTIME_DIR/dde-file-manager + if [ ! -S $target ];then + target=/tmp/dde-file-manager + if [ ! -S $target ];then + dde-file-manager -p "$@" + exit "$?" + fi + fi + + echo $data | socat - $target + + if [ $? != 0 ]; then + dde-file-manager -p "$@" + fi +fi diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/desktopinfo.cpp b/dde-file-manager-5.5.3/src/dde-file-manager/desktopinfo.cpp new file mode 100644 index 0000000..0acfeba --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/desktopinfo.cpp @@ -0,0 +1,34 @@ +#include "desktopinfo.h" + +#include +#include + +DesktopInfo::DesktopInfo() +{ + auto e = QProcessEnvironment::systemEnvironment(); + XDG_CURRENT_DESKTOP = e.value(QStringLiteral("XDG_CURRENT_DESKTOP")); + XDG_SESSION_TYPE = e.value(QStringLiteral("XDG_SESSION_TYPE")); + WAYLAND_DISPLAY = e.value(QStringLiteral("WAYLAND_DISPLAY")); + KDE_FULL_SESSION = e.value(QStringLiteral("KDE_FULL_SESSION")); + GNOME_DESKTOP_SESSION_ID = e.value(QStringLiteral("GNOME_DESKTOP_SESSION_ID")); + DESKTOP_SESSION = e.value(QStringLiteral("DESKTOP_SESSION")); +} + +bool DesktopInfo::waylandDectected() +{ + //! 该函数只能在QApplication之后调用才能返回有效的值,在此之前会返回空值 + Q_ASSERT(qApp); + return QApplication::platformName() == "wayland"; +} + +DesktopInfo::WM DesktopInfo::windowManager() +{ + DesktopInfo::WM res = DesktopInfo::OTHER; + if (XDG_CURRENT_DESKTOP.contains(QLatin1String("GNOME"), Qt::CaseInsensitive) || + !GNOME_DESKTOP_SESSION_ID.isEmpty()) { + res = DesktopInfo::GNOME; + } else if (!KDE_FULL_SESSION.isEmpty() || DESKTOP_SESSION == QLatin1String("kde-plasma")) { + res = DesktopInfo::KDE; + } + return res; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/desktopinfo.h b/dde-file-manager-5.5.3/src/dde-file-manager/desktopinfo.h new file mode 100644 index 0000000..6fe7b23 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/desktopinfo.h @@ -0,0 +1,30 @@ +#ifndef DESKTOPINFO_H +#define DESKTOPINFO_H + +#include + +class DesktopInfo +{ +public: + DesktopInfo(); + + enum WM { + GNOME, + KDE, + OTHER + }; + + bool waylandDectected(); + WM windowManager(); + +private: + QString XDG_CURRENT_DESKTOP; + QString XDG_SESSION_TYPE; + QString WAYLAND_DISPLAY; + QString KDE_FULL_SESSION; + QString GNOME_DESKTOP_SESSION_ID; + QString GDMSESSION; + QString DESKTOP_SESSION; +}; + +#endif // DESKTOPINFO_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/filemanagerapp.cpp b/dde-file-manager-5.5.3/src/dde-file-manager/filemanagerapp.cpp new file mode 100644 index 0000000..c49c401 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/filemanagerapp.cpp @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "filemanagerapp.h" +#include "dfmglobal.h" +#include "dfmapplication.h" + +#include "views/windowmanager.h" +#include "views/dfilemanagerwindow.h" + +#include "controllers/appcontroller.h" +#include "controllers/pathmanager.h" +#include "app/define.h" +#include "app/filesignalmanager.h" + +#include "dialogs/dialogmanager.h" + +#include "shutil/mimesappsmanager.h" +#include "interfaces/dfmstandardpaths.h" +#include "gvfs/gvfsmountmanager.h" +#include "interfaces/dfileinfo.h" + +#include "singleton.h" +#include "commandlinemanager.h" +#include "interfaces/durl.h" +#include "plugins/pluginmanager.h" +#include "interfaces/dfmstandardpaths.h" +#include "models/desktopfileinfo.h" +#include "interfaces/dfileservices.h" +#include "shutil/fileutils.h" +#include "utils/utils.h" +#include "app/filesignalmanager.h" + +#include "tag/tagmanager.h" + +#include +#include +#include +#include +#include +#include + +class FileManagerAppGlobal : public FileManagerApp {}; +Q_GLOBAL_STATIC(FileManagerAppGlobal, fmaGlobal) + +FileManagerApp::FileManagerApp(QObject *parent) : QObject(parent) +{ + initApp(); + initView(); + lazyRunInitServiceTask(); + initSysPathWatcher(); + initConnect(); +} + +FileManagerApp *FileManagerApp::instance() +{ + return fmaGlobal; +} + +FileManagerApp::~FileManagerApp() +{ + +} + +void FileManagerApp::initApp() +{ + qDebug() << FileUtils::getKernelParameters(); + + /*add plugin path*/ + DFMGlobal::autoLoadDefaultPlugins(); + + /*init plugin manager */ + DFMGlobal::initPluginManager(); + + /*init searchHistoryManager */ + DFMGlobal::initSearchHistoryManager(); + + /*init bookmarkManager */ + DFMGlobal::initBookmarkManager(); + + /*init fileMenuManager */ + DFMGlobal::initFileMenuManager(); + + /*init fileSignalManger */ + DFMGlobal::initFileSiganlManager(); + + /* init dialog manager */ + DFMGlobal::initDialogManager(); + + /*init appController */ + DFMGlobal::initAppcontroller(); + + /*init fileService */ + DFMGlobal::initFileService(); + + /*init deviceListener */ + DFMGlobal::initDeviceListener(); + + /*init mimeAppsManager*/ + DFMGlobal::initMimesAppsManager(); + + /*init systemPathMnager */ + DFMGlobal::initSystemPathManager(); + + /*init mimeTypeDisplayManager */ + DFMGlobal::initMimeTypeDisplayManager(); + + /*init networkManager */ + DFMGlobal::initNetworkManager(); + + /*init gvfsMountManager */ + DFMGlobal::initGvfsMountManager(); + + /*init secretManger */ + DFMGlobal::initSecretManager(); + + /*init userShareManager */ + DFMGlobal::initUserShareManager(); + + /*init controllers for different scheme*/ + fileService->initHandlersByCreators(); + + /*init operator revocation*/ + DFMGlobal::initOperatorRevocation(); + + DFMGlobal::initTagManagerConnect(); + + /*init thumbnail connection*/ + DFMGlobal::initThumbnailConnection(); + + /*init bluetooth manager*/ + DFMGlobal::initBluetoothManager(); + + /*init rootfile manager*/ + DFMGlobal::initRootFileManager(); + + QThreadPool::globalInstance()->setMaxThreadCount(MAX_THREAD_COUNT); +} + +void FileManagerApp::initView() +{ + m_windowManager = WindowManager::instance(); + m_windowManager->setEnableAutoQuit(true); +} + +void FileManagerApp::initManager() +{ + +} + +void FileManagerApp::initTranslation() +{ + +} + +void FileManagerApp::lazyRunInitServiceTask() +{ + QTimer::singleShot(1500, initService); +} + +void FileManagerApp::initSysPathWatcher() +{ + m_sysPathWatcher = new QFileSystemWatcher(this); + m_sysPathWatcher->addPath(QDir::homePath()); +} + +void FileManagerApp::initConnect() +{ + connect(m_sysPathWatcher, &QFileSystemWatcher::directoryChanged, systemPathManager, &PathManager::loadSystemPaths); + connect(DFMApplication::instance(), &DFMApplication::previewCompressFileChanged, this, [] (bool enable) { + if (enable) + FileUtils::mountAVFS(); + else + FileUtils::umountAVFS(); + }); +} + +void FileManagerApp::initService() +{ + if (DFMApplication::instance()->genericAttribute(DFMApplication::GA_PreviewCompressFile).toBool()) { + FileUtils::mountAVFS(); + } +} + +void FileManagerApp::show(const DUrl &url) +{ + m_windowManager->showNewWindow(url); +} + +void FileManagerApp::showPropertyDialog(const QStringList paths) +{ + DUrlList urlList; + foreach (QString path, paths) { + DUrl url = DUrl::fromUserInput(path); + QString uPath = url.path(); + if(uPath.endsWith(QDir::separator()) && uPath.size() > 1) + uPath.chop(1); + url.setPath(uPath); + + //symlink , desktop files filters + const DAbstractFileInfoPointer& info = fileService->createFileInfo(this, url); + DUrl realTargetUrl = url; + if(info && info->isSymLink()){ + realTargetUrl = info->rootSymLinkTarget(); + } + + if(realTargetUrl.toLocalFile().endsWith(".desktop")){ + DesktopFile df(realTargetUrl.toLocalFile()); + if(df.getDeepinId() == "dde-trash"){ + DFMEvent event(this); + event.setData(DUrl::fromTrashFile("/")); + dialogManager->showTrashPropertyDialog(event); + continue; + } else if(df.getDeepinId() == "dde-computer"){ + dialogManager->showComputerPropertyDialog(); + continue; + } + } + + //trash:/// and computer:/// + if(url == DUrl::fromComputerFile("/")){ + dialogManager->showComputerPropertyDialog(); + continue; + } + if(url == DUrl::fromTrashFile("/")){ + DFMEvent event(this); + event.setData(DUrl::fromTrashFile("/")); + dialogManager->showTrashPropertyDialog(event); + continue; + } + if (!url.scheme().isEmpty()){ + if(url.scheme() == FILE_SCHEME && !QFile::exists(url.path())) + continue; + if(url == DUrl::fromTrashFile("/") || + url == DesktopFileInfo::trashDesktopFileUrl()){ + DFMEvent event(this); + DUrlList urls; + urls << url; + event.setData(urls); + emit fileSignalManager->requestShowTrashPropertyDialog(event); + continue; + } + }else{ + if(!QFile::exists(DUrl::fromLocalFile(path).path())) + continue; + } + + if(urlList.contains(url)) + continue; + urlList << url; + } + if(urlList.isEmpty()) + return; + + emit fileSignalManager->requestShowPropertyDialog(DFMUrlListBaseEvent(this, urlList)); +} + +void FileManagerApp::openWithDialog(const QStringList files) +{ + DUrlList urlList; + foreach (QString path, files) { + DUrl url = DUrl::fromUserInput(path); + QString uPath = url.path(); + if(uPath.endsWith(QDir::separator()) && uPath.size() > 1) + uPath.chop(1); + url.setPath(uPath); + + //symlink , desktop files filters + const DAbstractFileInfoPointer& info = fileService->createFileInfo(this, url); + DUrl realTargetUrl = url; + if(info && info->isSymLink()){ + realTargetUrl = info->rootSymLinkTarget(); + } + + if(realTargetUrl.toLocalFile().endsWith(".desktop")){ + DesktopFile df(realTargetUrl.toLocalFile()); + if(df.getDeepinId() == "dde-trash"){ + DFMEvent event(this); + event.setData(DUrl::fromTrashFile("/")); + dialogManager->showTrashPropertyDialog(event); + continue; + } else if(df.getDeepinId() == "dde-computer"){ + dialogManager->showComputerPropertyDialog(); + continue; + } + } + + //trash:/// and computer:/// + if(url == DUrl::fromComputerFile("/")){ + dialogManager->showComputerPropertyDialog(); + continue; + } + if(url == DUrl::fromTrashFile("/")){ + DFMEvent event(this); + event.setData(DUrl::fromTrashFile("/")); + dialogManager->showTrashPropertyDialog(event); + continue; + } + if (!url.scheme().isEmpty()){ + if(url.scheme() == FILE_SCHEME && !QFile::exists(url.path())) + continue; + if(url == DUrl::fromTrashFile("/") || + url == DesktopFileInfo::trashDesktopFileUrl()){ + DFMEvent event(this); + DUrlList urls; + urls << url; + event.setData(urls); + emit fileSignalManager->requestShowTrashPropertyDialog(event); + continue; + } + }else{ + if(!QFile::exists(DUrl::fromLocalFile(path).path())) + continue; + } + + if(urlList.contains(url)) + continue; + urlList << url; + } + if(urlList.isEmpty()) + return; + + emit fileSignalManager->requestShowOpenFilesWithDialog(DFMUrlListBaseEvent(this, urlList)); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/filemanagerapp.h b/dde-file-manager-5.5.3/src/dde-file-manager/filemanagerapp.h new file mode 100644 index 0000000..6bb0882 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/filemanagerapp.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef FILEMANAGERAPP_H +#define FILEMANAGERAPP_H + +#include + +class WindowManager; +class AppController; +class DUrl; +class QFileSystemWatcher; + +QT_BEGIN_NAMESPACE +class QLocalServer; +QT_END_NAMESPACE + +class FileManagerApp : public QObject +{ + Q_OBJECT + +public: + static FileManagerApp *instance(); + + ~FileManagerApp(); + + void initManager(); + void initTranslation(); + static void initService(); + +private: + void initApp(); + void initView(); + void lazyRunInitServiceTask(); + void initSysPathWatcher(); + void initConnect(); + +// QString getFileJobConfigPath(); + +public slots: + void show(const DUrl &url); + void showPropertyDialog(const QStringList paths); + void openWithDialog(const QStringList files); + +protected: + explicit FileManagerApp(QObject *parent = nullptr); + +private: + WindowManager *m_windowManager = nullptr; + QFileSystemWatcher *m_sysPathWatcher; +}; + +#endif // FILEMANAGERAPP_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/generate_translations.sh b/dde-file-manager-5.5.3/src/dde-file-manager/generate_translations.sh new file mode 100755 index 0000000..c908092 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/generate_translations.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# this file is used to auto-generate .qm file from .ts file. +# author: shibowen at linuxdeepin.com + +ts_list=(`ls translations/*.ts`) + +for ts in "${ts_list[@]}" +do + printf "\nprocess ${ts}\n" + lrelease "${ts}" +done diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/logutil.cpp b/dde-file-manager-5.5.3/src/dde-file-manager/logutil.cpp new file mode 100644 index 0000000..9807ea7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/logutil.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "logutil.h" +#include "log/dfmLogManager.h" +#include "log/filterAppender.h" + +DFM_USE_NAMESPACE +LogUtil::LogUtil() +{ + +} + +LogUtil::~LogUtil() +{ + +} + +void LogUtil::registerLogger() +{ + DFMLogManager::registerConsoleAppender(); + DFMLogManager::registerFileAppender(); + + DFMLogManager::getLogger()->logToGlobalInstance("file.job", true); +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/logutil.h b/dde-file-manager-5.5.3/src/dde-file-manager/logutil.h new file mode 100644 index 0000000..ff229da --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/logutil.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef LOGUTIL_H +#define LOGUTIL_H + + +class LogUtil +{ +public: + LogUtil(); + ~LogUtil(); + + static void registerLogger(); +}; + +#endif // LOGUTIL_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/main.cpp b/dde-file-manager-5.5.3/src/dde-file-manager/main.cpp new file mode 100644 index 0000000..9293035 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/main.cpp @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include + +#include "durl.h" +#include "dfmglobal.h" +#include "dabstractfileinfo.h" +#include "dfileservices.h" +#include "dfmeventdispatcher.h" +#include "desktopinfo.h" + +#include "filemanagerapp.h" +#include "logutil.h" +#include "singleapplication.h" + +#include "app/define.h" +#include "app/filesignalmanager.h" + +#include "commandlinemanager.h" + +#include "dialogs/dialogmanager.h" +#include "shutil/fileutils.h" +#include "shutil/mimesappsmanager.h" +#include "dialogs/openwithdialog.h" +#include "controllers/appcontroller.h" +#include "singleton.h" +#include "gvfs/gvfsmountmanager.h" +#include "drootfilemanager.h" +#include "accessible/accessiblelist.h" +#include "dfmapplication.h" +#include "views/dfilemanagerwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef ENABLE_JEMALLOC +#include +#endif + +#ifdef ENABLE_PPROF +#include +#endif + +#define fileManagerApp FileManagerApp::instance() + +// blumia: DDE not yet got fully support about session management, so when logout or shutdown, +// the config file won't save. On mips64el, sw, arm, there will be a "warm-up" process +// running in the background (dde-file-manager -d) and the file manager instance will +// not got exit when all visible DFM window got closed, so that means the file manager +// config file will never got saved. +// blumia: Handling SIGTERM is a workaround way to fix that issue, but we still need to add +// session management support to DDE. + +void handleSIGTERM(int sig) +{ + qCritical() << "break with !SIGTERM! " << sig; + + if (qApp) { + qApp->quit(); + } +} + +void handleSIGPIPE(int sig) +{ + qCritical() << "ignore !SIGPIPE! " << sig; +} + +// Within an SSH session, I can use gvfs-mount provided that +// dbus-daemon is launched first and the environment variable DBUS_SESSION_BUS_ADDRESS is set. + +// gvfs-mount and other GVFS utilities must all talk to the same D-Bus session. Hence, +// if you use multiple SSH sessions or otherwise use mounts across login sessions, you must: +// - start D-Bus the first time it is needed, at the latest; +// - take care not to let D-Bus end with the session, as long as there are mounted GVFS filesystems; +// - reuse the existing D-Bus session at login time if there is one. +// see https://unix.stackexchange.com/questions/44317/reuse-d-bus-sessions-across-login-sessions for that. +void handleEnvOfOpenAsAdmin() +{ + QProcess p; + p.start("bash", QStringList() << "-c" + << "echo $(dbus-launch)"); + p.waitForFinished(); + QString envName("DBUS_SESSION_BUS_ADDRESS"); + QString output(p.readAllStandardOutput()); + QStringList group(output.split(" ")); + for (const QString &vals : group) { + const QStringList &envGroup = vals.split(","); + for (const QString &env : envGroup) { + int mid = env.indexOf("="); + if (env.startsWith(envName) && mid >= envName.size()) { + QString v(env.mid(mid + 1)); + QByteArray nameBytes(envName.toLocal8Bit()); + QByteArray vBytes(v.toLocal8Bit()); + int ret = setenv(nameBytes.data(), vBytes.data(), 1); + qDebug() << "set " << env << "=" << v << "ret=" << ret; + return; + } + } + } +} + +DWIDGET_USE_NAMESPACE + +int main(int argc, char *argv[]) +{ +#ifdef ENABLE_JEMALLOC + // fix bug 89285 + // 设置background_thread=true,让jemalloc后台回收脏数据 + bool oldp = false; + bool newp = true; + size_t len = sizeof(bool); + mallctl("background_thread", &oldp, &len, &newp, len); +#endif + + //for qt5platform-plugins load DPlatformIntegration or DPlatformIntegrationParent + if (qEnvironmentVariableIsEmpty("XDG_CURRENT_DESKTOP")){ + qputenv("XDG_CURRENT_DESKTOP", "Deepin"); + } + + winId_mtx.first = false; +#ifdef ENABLE_PPROF + ProfilerStart("pprof.prof"); +#endif + // Fixed the locale codec to utf-8 + QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8")); + + if (qEnvironmentVariableIsSet("PKEXEC_UID")) { + const quint32 pkexecUID = qgetenv("PKEXEC_UID").toUInt(); + DApplication::customQtThemeConfigPathByUserHome(getpwuid(pkexecUID)->pw_dir); + } + + // fix "Error mounting location: volume doesn't implement mount” when ope as admin (bug-42653) + if (DFMGlobal::isRootUser()) { + handleEnvOfOpenAsAdmin(); + } + + SingleApplication::initSources(); + SingleApplication app(argc, argv); + + if (DFMGlobal::isWayLand()) { + //以下代码用于视频预览使用 + setenv("PULSE_PROP_media.role", "video", 1); + QSurfaceFormat format; + format.setRenderableType(QSurfaceFormat::OpenGLES); + format.setDefaultFormat(format); + } + + app.setOrganizationName(QMAKE_ORGANIZATION_NAME); + app.setApplicationName(QMAKE_TARGET); + app.loadTranslator(); + app.setApplicationDisplayName(app.translate("Application", "File Manager")); + app.setApplicationVersion(DApplication::buildVersion((QMAKE_VERSION))); + app.setProductIcon(QIcon::fromTheme("dde-file-manager")); + app.setApplicationAcknowledgementPage("https://www.deepin.org/acknowledgments/" + qApp->applicationName()); + app.setApplicationDescription(app.translate("Application", "File Manager is a powerful and " + "easy-to-use file management tool, " + "featured with searching, copying, " + "trash, compression/decompression, file property " + "and other useful functions.")); + app.setAttribute(Qt::AA_UseHighDpiPixmaps); + + // 集成测试标签 +#ifdef ENABLE_ACCESSIBILITY + QAccessible::installFactory(accessibleFactory); + QAccessible::setActive(true); +#else + QAccessible::setActive(false); +#endif + + DApplicationSettings setting; + + DFMGlobal::installTranslator(); + + LogUtil::registerLogger(); + CommandLineManager::instance()->process(); + + //使用异步加载win相关的插件 + auto windPluginLoader = QtConcurrent::run([]() { + if (CommandLineManager::instance()->isSet("h") || CommandLineManager::instance()->isSet("v")) + return; + winId_mtx.second.lock(); + if (winId_mtx.first) { + winId_mtx.second.unlock(); + /* 针对bug47144音乐预览加载缓慢的问题,在初始化的时候调用QMediaPlayer::hasSupport,下次调用就快很多*/ + QMediaPlayer::hasSupport("application/octet-stream"); + return; + } + QWidget *w = new QWidget; + w->setWindowIcon(QIcon::fromTheme("dde-file-manager")); + w->winId(); + delete w; + winId_mtx.second.unlock(); + /* 针对bug47144音乐预览加载缓慢的问题,在初始化的时候调用QMediaPlayer::hasSupport,下次调用就快很多*/ + QMediaPlayer::hasSupport("application/octet-stream"); + }); + // init application object + DFMApplication fmApp; + Q_UNUSED(fmApp) + + // init pixmap cache size limit, 20MB * devicePixelRatio + QPixmapCache::setCacheLimit(static_cast(20 * 1024 * app.devicePixelRatio())); + + // working dir + if (CommandLineManager::instance()->isSet("w")) { + QDir::setCurrent(CommandLineManager::instance()->value("w")); + } + + // open as root + if (CommandLineManager::instance()->isSet("r")) { + if (DFMGlobal::isWayLand()) { + QString cmd = "xhost"; + QStringList args; + args << "+"; + QProcess p; + p.start(cmd, args); + p.waitForFinished(); + } + + QStringList args = app.arguments().mid(1); + args.removeAll(QStringLiteral("-r")); + args.removeAll(QStringLiteral("--root")); + args.removeAll(QStringLiteral("-w")); + args.removeAll(QStringLiteral("--working-dir")); + QProcess::startDetached("dde-file-manager-pkexec", args, QDir::currentPath()); + + windPluginLoader.waitForFinished(); + return 0; + } + + if (CommandLineManager::instance()->isSet("h") || CommandLineManager::instance()->isSet("v")) { + return app.exec(); + } + + QString uniqueKey = app.applicationName(); + + bool isSingleInstance = true; + // cannot open the filemanager when multiple users as an administrator + // to open the filemanager(bug-42832). therefore, we have to give up single application mode. + if (DFMGlobal::isOpenAsAdmin()) { + qDebug() << "oepn as admin"; + isSingleInstance = true; + } else { + isSingleInstance = app.setSingleInstance(uniqueKey); + } + + if (isSingleInstance) { + // init app + Q_UNUSED(FileManagerApp::instance()) + + DFMGlobal::setInitAppOver(); + //!开始扫描文件,提升启动速度. + DRootFileManager::instance()->startQuryRootFile(); + + if (CommandLineManager::instance()->isSet("d")) { + fileManagerApp; + app.setQuitOnLastWindowClosed(false); + } else { + CommandLineManager::instance()->processCommand(); + } + + signal(SIGTERM, handleSIGTERM); + signal(SIGPIPE, handleSIGPIPE); // SIGPIPE 引起程序挂死 + +#ifdef ENABLE_PPROF + int request = app.exec(); + + ProfilerStop(); + + return request; +#else + int ret = app.exec(); +#ifdef ENABLE_DAEMON + if (!DFMGlobal::isOpenAsAdmin()) { + app.closeServer(); + QProcess::startDetached(QString("%1 -d").arg(QString(argv[0]))); + } +#endif + return ret; +#endif + } else { + QByteArray data; + bool is_set_get_monitor_files = false; + + for (const QString &arg : app.arguments()) { + if (arg == "--get-monitor-files") + is_set_get_monitor_files = true; + + if (!arg.startsWith("-") && QFile::exists(arg)) + data.append(QDir(arg).absolutePath().toLocal8Bit().toBase64()); + else + data.append(arg.toLocal8Bit().toBase64()); + + data.append(' '); + } + + if (!data.isEmpty()) + data.chop(1); + + QLocalSocket *socket = SingleApplication::newClientProcess(uniqueKey, data); + if (is_set_get_monitor_files && socket->error() == QLocalSocket::UnknownSocketError) { + socket->waitForReadyRead(); + + for (const QByteArray &i : socket->readAll().split(' ')) + qDebug() << QString::fromLocal8Bit(QByteArray::fromBase64(i)); + } + windPluginLoader.waitForFinished(); + return 0; + } +} diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/mips/dde-computer.sh b/dde-file-manager-5.5.3/src/dde-file-manager/mips/dde-computer.sh new file mode 100755 index 0000000..88a4aea --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/mips/dde-computer.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +process=`ps ax -o 'cmd' |grep 'dde-file-manager$'`; +processd=`ps ax -o 'cmd' |grep 'dde-file-manager -d$'`; + +if [[ "$process" == ""&&"$processd" == "" ]]; then + dde-file-manager computer:/// +else + file-manager.sh computer:/// +fi diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/mips/dde-file-manager-autostart.desktop b/dde-file-manager-5.5.3/src/dde-file-manager/mips/dde-file-manager-autostart.desktop new file mode 100644 index 0000000..ecf62fe --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/mips/dde-file-manager-autostart.desktop @@ -0,0 +1,5 @@ +[Desktop Entry] +Type=Application +Name=file-manager-daemon auto +Exec=env GIO_LAUNCHED_DESKTOP_FILE=/usr/share/applications/dde-file-manager.desktop /usr/bin/dde-file-manager -d +NoShowIn=GNOME;Unity;Deepin diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/mips/dde-file-manager.desktop b/dde-file-manager-5.5.3/src/dde-file-manager/mips/dde-file-manager.desktop new file mode 100644 index 0000000..259d50e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/mips/dde-file-manager.desktop @@ -0,0 +1,260 @@ +[Desktop Entry] +Actions=new-window; +Categories=Utility; +Comment=Browse the file system +Exec=/usr/bin/file-manager.sh -n %u +GenericName=File Manager +Icon=dde-file-manager +MimeType=inode/directory; +Name=Deepin File Manager +OnlyShowIn=Deepin; +StartupNotify=false +Terminal=false +Type=Application +Version=1.0 +X-Deepin-Vendor=deepin +X-GNOME-Autostart-Delay=20; + +# Translations: +# Do not manually modify! +Comment[am_ET]=የ ፋይል ስርአት መቃኛ +Comment[ar]=تصفح ملف النظام +Comment[ast]=Restola sistemes de ficheros +Comment[az]=Fayl sisteminə baxış +Comment[bg]=Преглед на файловата система +Comment[bn]=ফাইল সিস্টেম ব্রাউজ করুন +Comment[bo]=ཡིག་ཆའི་རྒྱུད་ཁོངས་ལ་རགས་ཙམ་ལྟ་བ། +Comment[ca]=Navegueu pel sistema de fitxers +Comment[cs]=Procházet souborový systém +Comment[da]=Gennemse filsystemet +Comment[de]=Dateisystem durchsuchen +Comment[el]=Περιηγηθείτε στο αρχείο συστήματος +Comment[en_AU]=Browse the file system +Comment[en_GB]=Browse the file system +Comment[es]=Examinar el sistema de archivos +Comment[et]=Sirvi failisüsteemi +Comment[eu]=Arakatu fitxategi sistema +Comment[fa]=سیستم فایل را مرور کنید +Comment[fi]=Selaa tiedostoja +Comment[fr]=Parcourir le système de fichiers +Comment[gl]=Examinar o sistema de ficheiros +Comment[gl_ES]=Examina o sistema de ficheiros +Comment[he]=עיון במערכת הקבצים +Comment[hr]=Pregledavaj datotečni sustav +Comment[hu]=A fájlrendszer böngészése +Comment[id]=Ramban sistem berkas +Comment[is]=Flakka í skráakerfinu +Comment[it]=Apri il File System +Comment[ja]=ファイル システムを参照します +Comment[kab]=Snirem anagraw n yifuyla +Comment[kk]=Файлдық жүйені шолу +Comment[ko]=파일 시스템 찾아보기 +Comment[lt]=Naršyti failų sistemą +Comment[mn]=Файл системийг ажиглах +Comment[ms]=Layar sistem fail +Comment[nb]=Bla gjennom filsystemet +Comment[ne]=फाईल प्रणाली ब्राउज गर्नुहोस् +Comment[nl]=Verken het bestandssysteem +Comment[nn]=Bla gjennom filsystemet +Comment[oc]=Percórrer lo sistèma de fichièrs +Comment[pa]=ਫਾਇਲ ਸਿਸਟਮ ਬਰਾਊਜ਼ ਕਰੋ +Comment[pl]=Przeglądaj system plików +Comment[pt]=Explorar o sistema de ficheiros +Comment[pt_BR]=Navegar pelos arquivos do sistema +Comment[ro]=Gestionați fișierele din sistem +Comment[ru]=Просмотр файловой системы +Comment[sk]=Prehľadávanie systému súborov +Comment[sl]=Brskaj po datotečnem sistemu +Comment[sq]=Shfletoni sistemin e kartelave +Comment[sr]=Прегледај систем датотека +Comment[sv]=Bläddra i filsystemet +Comment[ta]=கோப்பு முறைமை உலாவுக +Comment[te]=దస్త్ర వ్యవస్థను విహరించు +Comment[th]=ท่องดูระบบแฟ้ม +Comment[tr]=Dosya sistemine gözat +Comment[ug]=ھۆججەت سىستېمىسىنى كۆرىدۇ +Comment[uk]=Перегляд файлової системи +Comment[vi]=Duyệt hệ thống tệp tin +Comment[zh_CN]=浏览文件系统 +Comment[zh_HK]=瀏覽檔案系統 +Comment[zh_TW]=瀏覽與管理檔案系統 +GenericName[am_ET]=የ ፋይል አስተዳዳሪ +GenericName[ar]=مدير الملفات +GenericName[ast]=Xestor de ficheros +GenericName[az]=Fayl Meneceri +GenericName[bg]=Файлов мениджър +GenericName[bo]=ཡིག་ཆ་དོ་དམ་བྱེད་ཆས། +GenericName[ca]=Gestor de fitxers +GenericName[cs]=Správce souborů +GenericName[da]=Filhåndtering +GenericName[de]=Dateimanager +GenericName[el]=Διαχειριστής αρχείων +GenericName[en_AU]=File Manager +GenericName[es]=Administrador de archivos +GenericName[et]=Failihaldur +GenericName[fa]=مدیر فایل +GenericName[fi]=Tiedostohallinta +GenericName[fr]=Gestionnaire de fichiers +GenericName[gl_ES]=Xestor de ficheiros +GenericName[hr]=Upravitelj datotekama +GenericName[hu]=Fájlkezelő +GenericName[id]=Manajer Berkas +GenericName[it]=File Manager +GenericName[ja]=ファイル マネージャー +GenericName[kab]=Amsefrek n ifuyla +GenericName[ko]=파일 관리자 +GenericName[lt]=Failų tvarkytuvė +GenericName[ml]=ഫയൽ മാനേജർ +GenericName[mn]=Файл менежер +GenericName[ms]=Pengurus Fail +GenericName[nb]=Filutforsker +GenericName[ne]=फाइल प्रबन्धक +GenericName[nl]=Bestandsbeheer +GenericName[pl]=Zarządzanie plikami +GenericName[pt]=Gestor de Ficheiros +GenericName[pt_BR]=Gerenciador de Arquivos +GenericName[ro]=Manager de fișiere +GenericName[ru]=Файловый Менеджер +GenericName[sk]=Správca súborov +GenericName[sl]=Upravitelj datotek +GenericName[sq]=Përgjegjës Kartelash +GenericName[sr]=Управник Података +GenericName[sv]=Filhanterare +GenericName[ta]=கோப்பு மேலாளர் +GenericName[tr]=Dosya Yöneticisi +GenericName[ug]=ھۆججەت باشقۇرغۇچ +GenericName[uk]=Файловий менеджер +GenericName[zh_CN]=文件管理器 +GenericName[zh_HK]=檔案管理員 +GenericName[zh_TW]=檔案管理器 +Name[am_ET]=ዲፕኢን የ ፋይል አስተዳዳሪ +Name[ar]=مدير ملفات ديبين +Name[ast]=Deepin File Manager +Name[az]=Deepin Fayl Meneceri +Name[bg]=Файлов мениджър +Name[bn]=ফাইল ম্যানেজার +Name[bo]=གཏིང་ཚད་ཡིག་ཆ་དོ་དམ་བྱེད་ཆས། +Name[ca]=Gestor de fitxers del Deepin +Name[cs]=Deepin správce souborů +Name[da]=Deepin filhåndtering +Name[de]=Deepin Dateimanager +Name[el]=Διαχειριστής αρχείων +Name[en_AU]=Deepin File Manager +Name[en_GB]=Deepin File Manager +Name[es]=Administrador de archivos +Name[et]=Deepin failihaldur +Name[eu]=Fitxategi kudeatzailea +Name[fa]=مدیر فایل دیپین +Name[fi]=Deepin tiedostohallinta +Name[fr]=Gestionnaire de fichiers Deepin +Name[gl]=Xestor de ficheiros +Name[gl_ES]=Xestor de ficheiros +Name[he]=מנהל קבצים +Name[hr]=Deepin upravltelj datotekama +Name[hu]=Deepin® Fájlkezelő +Name[id]=Manajer Berkas +Name[is]=Skráastjóri +Name[it]=Deepin File Manager +Name[ja]=Deepin ファイル マネージャー +Name[kab]=Amsefrak n yifuyla n Deepin +Name[kk]=Файлдар басқарушысы +Name[ko]=Deepin 파일 관리자 +Name[lt]=Deepin failų tvarkytuvė +Name[lv]=Faila pārvaldnieks +Name[ml]=ഡീപിൻ ഫയൽ മാനേജർ +Name[mn]=Диипин файл менежер +Name[ms]=Pengurus Fail Deepin +Name[nb]=Filbehandler +Name[ne]=डीपिन फाइल प्रबन्धक +Name[nl]=Deepin Bestandsbeheer +Name[nn]=Filhandsamar +Name[oc]=Gestionari de fichièrs +Name[pa]=ਡੀਪਿਨ ਫਾਇਲ ਮੈਨੇਜਰ +Name[pl]=Zarządzanie plikami Deepin +Name[pt]=Gestor de Ficheiros Deepin +Name[pt_BR]=deepin Gerenciador de Arquivos +Name[ro]=Manager de fișiere Deepin +Name[ru]=Файловый Менеджер Deepin +Name[sk]=Deepin Správca súborov +Name[sl]=Upravitelj datotek Deepin +Name[sq]=Përgjegjës Kartelash Deepin +Name[sr]=Дипин Управник Података +Name[sv]=Filhanterare +Name[ta]=டீபைன் கோப்பு மேலாளர் +Name[te]=దస్త్ర నిర్వాహకం +Name[th]=โปรแกรมจัดการแฟ้ม +Name[tr]=Deepin Dosya Yöneticisi +Name[ug]=ھۆججەت باشقۇرغۇچ +Name[uk]=Файловий менеджер Deepin +Name[vi]=Trình quản lý tệp tin +Name[zh_CN]=深度文件管理器 +Name[zh_HK]=深度檔案管理員 +Name[zh_TW]=Deepin 檔案管理器 + +[Desktop Action new-window] +Exec=/usr/bin/file-manager.sh --new-window +Name=New Window +Name[sr@latin]=Novi prozor + +# Translations: +# Do not manually modify! +Name[am_ET]=አዲስ መስኮት +Name[ar]=نافذة جديدة +Name[ast]=Ventana nueva +Name[az]=Yeni Pəncərə +Name[bg]=Нов прозорец +Name[bn]=নতুন উইন্ডো +Name[bo]=སྒེའུ་ཁུང་གསར་འཛུགས། +Name[ca]=Finestra nova +Name[cs]=Nové okno +Name[da]=Nyt vindue +Name[de]=Neues Fenster +Name[el]=Νέο παράθυρο +Name[en_AU]=New Window +Name[es]=Nueva ventana +Name[et]=Uus aken +Name[eu]=Leiho berria +Name[fa]=پنجره نو +Name[fi]=Uusi ikkuna +Name[fr]=Nouvelle fenêtre +Name[fur]=Gnûf barcon +Name[gd]=Uinneag ùr +Name[gl]=Nova xanela +Name[gl_ES]=Nova xanela +Name[he]=חלון חדש +Name[hr]=Novi prozor +Name[hu]=Új ablak +Name[id]=Jendela Baru +Name[it]=Nuova finestra +Name[ja]=新規ウィンドウ +Name[kab]=Asfaylu amaynut +Name[kk]=Жаңа терезе +Name[ko]=새 창 +Name[lt]=Naujas langas +Name[lv]=Jauns logs +Name[mn]=Шинэ цонх +Name[ms]=Tetinkap Baharu +Name[nb]=Nytt vindu +Name[ne]=नयाँ विन्डो +Name[nl]=Nieuw venster +Name[oc]=Fenèstra novèla +Name[pa]=ਨਵੀਂ ਵਿੰਡੋ +Name[pl]=Nowe okno +Name[pt]=Nova Janela +Name[pt_BR]=Nova Janela +Name[ro]=Fereastră nouă +Name[ru]=Новое Окно +Name[sk]=Nové okno +Name[sl]=Novo okno +Name[sq]=Dritare e Re +Name[sr]=Нови прозор +Name[sv]=Nytt fönster +Name[ta]=புதிய திரை +Name[th]=หน้าต่างใหม่ +Name[tr]=Yeni Pencere +Name[ug]=يېڭى كۆزنەك +Name[uk]=Нове вікно +Name[zh_CN]=新建窗口 +Name[zh_HK]=新建窗口 +Name[zh_TW]=新增視窗 + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/mips/dde-trash.sh b/dde-file-manager-5.5.3/src/dde-file-manager/mips/dde-trash.sh new file mode 100755 index 0000000..df78738 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/mips/dde-trash.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +process=`ps ax -o 'cmd' |grep 'dde-file-manager$'`; +processd=`ps ax -o 'cmd' |grep 'dde-file-manager -d$'`; + +if [[ "$process" == ""&&"$processd" == "" ]]; then + dde-file-manager trash:/// +else + file-manager.sh trash:/// +fi diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/mips/file-manager.sh b/dde-file-manager-5.5.3/src/dde-file-manager/mips/file-manager.sh new file mode 100755 index 0000000..cc63465 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/mips/file-manager.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +#dde-file-manager +data="ZGRlLWZpbGUtbWFuYWdlcg==" + +for i in "$@" +do + arg_base64=`echo -n "$i"|base64 -w 0` + data=$data" "$arg_base64 +done + +target=$XDG_RUNTIME_DIR/dde-file-manager + +if [ ! -S $target ];then + target=/tmp/dde-file-manager + if [ ! -S $target ];then + dde-file-manager "$@" + exit "$?" + fi +fi + +echo $data | socat - $target + +if [ $? != 0 ]; then + dde-file-manager "$@" +fi diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/pkexec/com.deepin.pkexec.dde-file-manager.policy b/dde-file-manager-5.5.3/src/dde-file-manager/pkexec/com.deepin.pkexec.dde-file-manager.policy new file mode 100644 index 0000000..8ac0bdc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/pkexec/com.deepin.pkexec.dde-file-manager.policy @@ -0,0 +1,21 @@ + + + + LinuxDeepin + https://www.deepin.com/ + + Authentication is required to run the Deepin File Manager + 查看文件夹需要输入密码 + folder + + no + no + auth_admin_keep + + /usr/bin/dde-file-manager + true + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/pkexec/dde-file-manager-pkexec b/dde-file-manager-5.5.3/src/dde-file-manager/pkexec/dde-file-manager-pkexec new file mode 100755 index 0000000..a78ce66 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/pkexec/dde-file-manager-pkexec @@ -0,0 +1,39 @@ +#!/bin/bash + +function run_pkexec() { + xhost +SI:localuser:root + echo "run in pkexec: $@" + pkexec --disable-internal-agent "$@" `id -u` + xhost -SI:localuser:root + xhost +} + +function run_app() { + echo "param in run_app: $@" + uid=$2 + echo "runner uid: $uid" + export XDG_RUNTIME_DIR=/run/user/$uid + export WAYLAND_DISPLAY=wayland-0 + export DISPLAY=:0 + export QT_WAYLAND_SHELL_INTEGRATION=kwayland-shell + export XDG_SESSION_TYPE=wayland + export QT_QPA_PLATFORM= + export GDK_BACKEND=x11 + export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus + + dde-file-manager $1 -w `pwd` +} + +echo "run dde-file-manager in $XDG_SESSION_TYPE" +if [ "$XDG_SESSION_TYPE" == "x11" ];then + pkexec dde-file-manager "$@" -w `pwd` +else + echo "current file: $0" + if [ x`id -u` != "x0" ];then + run_pkexec $0 $@ + exit 0 + fi + + echo "run app: $@" + run_app $@ +fi diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/singleapplication.cpp b/dde-file-manager-5.5.3/src/dde-file-manager/singleapplication.cpp new file mode 100644 index 0000000..a25a269 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/singleapplication.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#include "singleapplication.h" +#include "app/define.h" +#include "app/filesignalmanager.h" +#include "durl.h" +#include "dfmeventdispatcher.h" +#include "dfilewatcher.h" + +#include "commandlinemanager.h" +#include "singleton.h" +#include "filemanagerapp.h" +#include "dfmevent.h" +#include "interfaces/dfileservices.h" + +#include +#include +#include +#include +#include +#include + +#define fileManagerApp FileManagerApp::instance() + +QString SingleApplication::UserID = "1000"; + +SingleApplication::SingleApplication(int &argc, char **argv, int): DApplication(argc, argv) +{ + m_localServer = new QLocalServer; + initConnect(); +} + +SingleApplication::~SingleApplication() +{ + closeServer(); +} + +void SingleApplication::initConnect() +{ + connect(m_localServer, &QLocalServer::newConnection, this, &SingleApplication::handleConnection); + connect(fileSignalManager, &FileSignalManager::requestCloseListen, this, &SingleApplication::closeServer); +} + +void SingleApplication::initSources() +{ + Q_INIT_RESOURCE(icons); +// Q_INIT_RESOURCE(dui_theme_dark); +// Q_INIT_RESOURCE(dui_theme_light); +} + +QLocalSocket *SingleApplication::newClientProcess(const QString &key, const QByteArray &message) +{ + QLocalSocket *localSocket = new QLocalSocket; + localSocket->connectToServer(userServerName(key)); + if (localSocket->waitForConnected(1000)){ + if (localSocket->state() == QLocalSocket::ConnectedState){ + if (localSocket->isValid()) { + localSocket->write(message); + localSocket->flush(); + } + } + }else{ + qDebug() << localSocket->errorString(); + } + + return localSocket; +} + +QString SingleApplication::userServerName(const QString &key) +{ + QString userKey = QString("%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation), key); + if (userKey.isEmpty()) { + userKey = QString("%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::TempLocation), key); + } + return userKey; +} + +QString SingleApplication::userId() +{ + return UserID; +} + +bool SingleApplication::loadTranslator(QList localeFallback) +{ + DApplication::loadTranslator(localeFallback); + + QStringList translateDirs; + + const QStringList &dataDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); + + for (QString path : dataDirs) { + translateDirs << path.append("/").append(applicationName()).append("/translations"); + } + + const QString name = QStringLiteral("dde-file-manager-app"); + + for (const QLocale &locale : localeFallback) { + QString translateFilename = QString("%1_%2").arg(name).arg(locale.name()); + for (QString path : translateDirs) { + const QString &translatePath = path.append("/").append(translateFilename); + if (QFile::exists(translatePath + ".qm")) { + qDebug() << "load translate" << translatePath; + QTranslator *translator = new QTranslator(this); + translator->load(translatePath); + installTranslator(translator); + return true; + } + } + + QStringList parseLocalNameList = locale.name().split("_", QString::SkipEmptyParts); + if (parseLocalNameList.length() > 0) { + translateFilename = QString("%1_%2").arg(name) + .arg(parseLocalNameList.at(0)); + for (QString path : translateDirs) { + const QString &translatePath = path.append("/").append(translateFilename); + if (QFile::exists(translatePath + ".qm")) { + qDebug() << "translatePath after feedback:" << translatePath; + QTranslator *translator = new QTranslator(this); + translator->load(translatePath); + installTranslator(translator); + return true; + } + } + } + } + + return false; +} + +QString SingleApplication::getUserID() +{ + return QString::number(DFMGlobal::getUserId()); +} + +bool SingleApplication::setSingleInstance(const QString &key) +{ + QString userKey = userServerName(key); + + QLocalSocket localSocket; + localSocket.connectToServer(userKey); + + // if connect success, another instance is running. + bool result = localSocket.waitForConnected(1000); + + if (result) + return false; + + m_localServer->removeServer(userKey); + + bool f = m_localServer->listen(userKey); + + return f; +} + +void SingleApplication::handleConnection() +{ + qDebug() << "new connection is coming"; + QLocalSocket* nextPendingConnection = m_localServer->nextPendingConnection(); + connect(nextPendingConnection, SIGNAL(readyRead()), this, SLOT(readData())); +} + +void SingleApplication::readData() +{ + QLocalSocket *socket = qobject_cast(sender()); + + if (!socket) + return; + + QStringList arguments; + //socket->read(1024)中的1024会导致在文件夹名字达到最大长度时获取不完全,临时改为2048 + for (const QByteArray &arg_base64 : socket->read(2048).split(' ')) { + const QByteArray &arg = QByteArray::fromBase64(arg_base64.simplified()); + + if (arg.isEmpty()) + continue; + + arguments << QString::fromLocal8Bit(arg); + } + + CommandLineManager::instance()->process(arguments); + + if (CommandLineManager::instance()->isSet("get-monitor-files")) { + const QStringList &list = DFileWatcher::getMonitorFiles(); + QByteArray data; + + for (const QString &i : list) + data.append(i.toLocal8Bit().toBase64()).append(' '); + + socket->write(data); + socket->flush(); + return; + } + + CommandLineManager::instance()->processCommand(); +} + +void SingleApplication::closeServer() +{ + if (m_localServer){ + m_localServer->removeServer(m_localServer->serverName()); + m_localServer->close(); + delete m_localServer; + m_localServer = nullptr; + } +} + +void SingleApplication::handleQuitAction() +{ + fileSignalManager->aboutToCloseLastActivedWindow(0); +} + diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/singleapplication.h b/dde-file-manager-5.5.3/src/dde-file-manager/singleapplication.h new file mode 100644 index 0000000..b381128 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/singleapplication.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: yanghao + * + * Maintainer: zhengyouge + * yanghao + * hujianzhong + * + * 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 + * 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 . + */ + +#ifndef SINGLEAPPLICATION_H +#define SINGLEAPPLICATION_H + +#include + +#include +#include + +QT_BEGIN_NAMESPACE +class QLocalServer; +class QLocalSocket; +QT_END_NAMESPACE + +DWIDGET_USE_NAMESPACE + +class SingleApplication : public DApplication +{ + Q_OBJECT +public: + explicit SingleApplication(int &argc, char **argv, int = ApplicationFlags); + ~SingleApplication() override; + void initConnect(); + + static void initSources(); + static QLocalSocket *newClientProcess(const QString &key, const QByteArray &message); + static QString userServerName(const QString &key); + static QString userId(); + + bool loadTranslator(QList localeFallback = QList() << QLocale::system()); + +signals: + void screenDevicePixelRatioChanged(QScreen *s); + +public slots: + bool setSingleInstance(const QString &key); + void handleConnection(); + void readData(); + void closeServer(); + +private: + void handleQuitAction() override; + + static QString getUserID(); + + static QString UserID; + QLocalServer *m_localServer; +}; + +#endif // SINGLEAPPLICATION_H diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translate_desktop2ts.sh b/dde-file-manager-5.5.3/src/dde-file-manager/translate_desktop2ts.sh new file mode 100755 index 0000000..12c679b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translate_desktop2ts.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +DESKTOP_SOURCE_FILE=dde-file-manager.desktop +DESKTOP_TS_DIR=translations/dde-file-manager-desktop/ + +/usr/bin/deepin-desktop-ts-convert desktop2ts $DESKTOP_SOURCE_FILE $DESKTOP_TS_DIR \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translate_ts2desktop.sh b/dde-file-manager-5.5.3/src/dde-file-manager/translate_ts2desktop.sh new file mode 100755 index 0000000..2872be4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translate_ts2desktop.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +DESKTOP_TEMP_FILE=dde-file-manager.desktop.tmp +DESKTOP_SOURCE_FILE=dde-file-manager.desktop + +DESKTOP_MIPS_TEMP_FILE=mips/dde-file-manager.desktop.tmp +DESKTOP_MIPS_SOURCE_FILE=mips/dde-file-manager.desktop + +DESKTOP_TS_DIR=translations/dde-file-manager-desktop/ + +/usr/bin/deepin-desktop-ts-convert ts2desktop $DESKTOP_SOURCE_FILE $DESKTOP_TS_DIR $DESKTOP_TEMP_FILE +mv $DESKTOP_TEMP_FILE $DESKTOP_SOURCE_FILE + +/usr/bin/deepin-desktop-ts-convert ts2desktop $DESKTOP_MIPS_SOURCE_FILE $DESKTOP_TS_DIR $DESKTOP_MIPS_TEMP_FILE +mv $DESKTOP_MIPS_TEMP_FILE $DESKTOP_MIPS_SOURCE_FILE diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app.ts new file mode 100644 index 0000000..770855b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + File Manager + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_am_ET.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_am_ET.ts new file mode 100644 index 0000000..b2dff12 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_am_ET.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + የ ዲፕኢን ፋይል አስተዳዳሪ + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + ፋይል አስተዳዳሪ በ ዲፕኢን ውስጥ የ ፋይል አስተዳዳሪ ነው: የ ፋይል አስተዳዳሪ ለፋይል መፈለጊያ: ኮፒ: ማመቂያ/ማራገፊያ: የ ፋይል ባህሪዎች እና ሌሎች አገልግሎቶች የሚሰጥ ነው + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ar.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ar.ts new file mode 100644 index 0000000..3f99fd4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ar.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + مدير الملفات + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + مدير الملفات هو أداة سهلة وقوية لإدارة الملفات، وتتميز بالقدرة على البحث، النسخ، حذف الملفات، الضغط وفك الضغط، عرض خصائص الملفات، وغيرها من الوظائف المفيدة. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ast.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ast.ts new file mode 100644 index 0000000..1b3df56 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ast.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + Deepin File Manager + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + Deepin File Manager ye una ferramienta desendolcada de mou independiente por Deepin Technology. Tien como carauterístiques la gueta, copia, des/compresión y l'unviu a la papelera de ficheros amás d'otres funciones. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_az.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_az.ts new file mode 100644 index 0000000..527dc12 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_az.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Fayl Meneceri + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Fayl Meneceri, axtarmaq, kopyalamaq, zibil qutusu, sıxmaq/aşmaq, fayl xüsusiyyətləri və digər faydalı funksiyaları ilə hazırlanmış, faylları rahat idarə etmək üçün güclü vasitədir. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_bg.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_bg.ts new file mode 100644 index 0000000..8ebe710 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_bg.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + Deepin файлов мениджър + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + Файловият мениджър е инструмент за управление на файлове разработен самостоятелно от Deepin Technology с възможност за търсене, копиране, кошче, компресиране / декомпресиране, свойства на файла и други функции за управление на файлове. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_bn.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_bn.ts new file mode 100644 index 0000000..850c800 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_bn.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + ডিপিন ফাইল ম্যানেজার + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_bo.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_bo.ts new file mode 100644 index 0000000..0b6a05b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_bo.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + ཡིག་ཆ་དོ་དམ་བྱེད་ཆས། + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + ཡིག་ཆ་དོ་དམ་བྱེད་ཆས་ནི་རྩོལ་ནུས་སྟོབས་ཆེན་ཡོད་པའི་དོ་དམ་ཡོ་བྱད་ཅིག་ཡིན། དེར་བཤེར་འཚོལ་དང་། པར་སློག སྙིགས་སྣོད། སྡུད་སྒྲིལ། བསྡུས་འགྲོལ། ཡིག་ཆའི་ངོ་བོ་སོགས་ཚུད་པའི་དོ་དམ་རྩོལ་ནུས་ལྡན་ཡོད། + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ca.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ca.ts new file mode 100644 index 0000000..d263713 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ca.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Gestor de fitxers + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + El Gestor de fitxers és una eina de gestió de fitxers potent i fàcil d'usar que permet cercar, copiar, eliminar, comprimir i descomprimir fitxers, canviar-ne les propietats i altres funcions útils. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_cs.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_cs.ts new file mode 100644 index 0000000..9066e9c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_cs.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Správce souborů + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Správce souborů je mocný, přesto snadno se používající nástroj pro správu souborů. Má funkce jako je vyhledávání, kopírování, mazání, komprimace/rozbalování archivů, zobrazování vlastností souborů a další užitečné funkce. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_da.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_da.ts new file mode 100644 index 0000000..58912cb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_da.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Filhåndtering + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Filhåndtering er et kraftfuldt filhåndteringsværktøj som er let at bruge, med søgning, kopiering, papirkurv, komprimering/udpakning, filegenskab og andre nyttige funktioner. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_de.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_de.ts new file mode 100644 index 0000000..cae53b4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_de.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Dateimanager + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Dateimanager ist ein leistungsstarkes und einfach zu bedienendes Dateiverwaltungswerkzeug, das mit Suchen, Kopieren, Papierkorb, Komprimieren/Dekomprimieren, Dateieigenschaften und anderen nützlichen Funktionen ausgestattet ist. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_el.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_el.ts new file mode 100644 index 0000000..b186b1a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_el.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + Διαχειριστής Αρχείων Deepin + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + Ο Διαχειριστής Αρχείων είναι ένα εργαλείο διαχείρισης αρχείων που αναπτύχθηκε ανεξάρτητα από την Deepin Technology, με χαρακτηριστικά όπως αναζήτηση, αντιγραφή, κάδο, συμπίεση/αποσυμπίεση, ιδιότητες αρχείου και άλλες λειτουργίες διαχείρισης αρχείων. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_en_AU.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_en_AU.ts new file mode 100644 index 0000000..90111af --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_en_AU.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + Deepin File Manager + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_es.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_es.ts new file mode 100644 index 0000000..beb5a68 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_es.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Administrador de archivos + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Administrador de archivos de Deepin es una herramienta de gestión de archivos potente y fácil de usar, incluye funciones de búsqueda, copia, papelera, compresión, descompresión, mostrar propiedades y otras características muy útiles. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_fa.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_fa.ts new file mode 100644 index 0000000..9123426 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_fa.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + مدیر فایل دیپین + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + مدیر فایل ابزاری برای مدیریت فایل است که بطور مستقل توسط دیپین تکنولوژی ساخته شده است ، که با جستجو ، کپی کردن ، حذف ، سطل زباله ، فشرده سازی /استخراج ، خاصیت فایل و دیگر عملکردهای مدیریت فایل ارائه شده است. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_fi.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_fi.ts new file mode 100644 index 0000000..59702ab --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_fi.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Tiedostohallinta + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Tiedostohallinta on tehokas ja helppokäyttöinen tiedostojen hallintatyökalu, joka sisältää etsinnän, kopioinnin, roskakorin, pakkaamisen/purkamisen, tiedosto-ominaisuudet ja muut hyödylliset toiminnot. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_fr.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_fr.ts new file mode 100644 index 0000000..1a775f8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_fr.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Gestionnaire de fichiers + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Le gestionnaire de fichiers est un outil de gestion de fichiers puissant et facile à utiliser, doté de fonctions de recherche, copie, suppression, compression/décompression, propriétés de fichier et autres fonctions utiles. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_gl_ES.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_gl_ES.ts new file mode 100644 index 0000000..f7c89ac --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_gl_ES.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Xestor do ficheiro + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Xestor de ficheiros é unha ferramenta de xestión de ficheiros poderosa e fácil de usar, que inclúe busca, copia, lixo, compresión / descompresión, propiedade de ficheiros e outras funcións útiles. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_he.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_he.ts new file mode 100644 index 0000000..a5ed0fe --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_he.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + מנהל קבצים + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_hi_IN.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_hi_IN.ts new file mode 100644 index 0000000..636fb69 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_hi_IN.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + डीपिन फ़ाइल प्रबंधक + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_hr.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_hr.ts new file mode 100644 index 0000000..7efcd6f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_hr.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + Deepin upravitelj datoteka + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + Upravitelj datotekama je alat za upravljanje datotekama koji je nezavisno razvio Deepin Technology, koji sadrži traženja, smeće, kompresija/dekompresija, svojstva datoteka i ostale funkcije upravljanja datotekama. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_hu.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_hu.ts new file mode 100644 index 0000000..85b5107 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_hu.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Fájlkezelő + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + A Fájlkezelő egy hatékony és könnyen használható fájlkezelő eszköz, amely kereséssel, másolással, kukával, tömörítéssel / kicsomagolással, fájl tulajdonságokkal és egyéb hasznos funkciókkal rendelkezik. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_id.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_id.ts new file mode 100644 index 0000000..b577e99 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_id.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Manajer Berkas + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Manajer Berkas merupakan perkakas manajemen berkas yang mudah digunakan, meliputi fungsi pencarian, penyalinan, sampah, kompresi/dekompresi, properti berkas dan fungsi berguna lainnya. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_it.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_it.ts new file mode 100644 index 0000000..02ba247 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_it.ts @@ -0,0 +1,16 @@ + + + Application + + + File Manager + Gestore File + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Gestore File di Deepin è uno strumento di gestione file con funzionalità di ricerca, copia, compressione/decompressione, dettagli dei file ed altre funzionalità. +Localizzazione italiana a cura di Massimo A. Carofano. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ja.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ja.ts new file mode 100644 index 0000000..0cb4cf7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ja.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + ファイル マネージャー + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + ファイル マネージャーは、検索やコピー、ゴミ箱、圧縮/伸張、ファイルプロパティ、その他の便利な機能を備えた、強力で使いやすいファイル管理ツールです。 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_kab.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_kab.ts new file mode 100644 index 0000000..aff1b1d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_kab.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Amsefrek n ifuyla + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Amsefrak n yifuyla d afecku n usefrek n yifuyla yelhan i isehlen i useqdec, deg-s unadi, anɣal, iḍumman, askussem/asefruri, taɣara n ufaylu akked tmahilin-nniḍen. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ko.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ko.ts new file mode 100644 index 0000000..199d8a6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ko.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + 파일 관리자 + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + 파일 관리자는 검색, 복사, 휴지통, 압축/압축해제, 파일 속성 및 기타 유용한 기능을 갖춘 강력하고 사용하기 쉬운 파일 관리 도구입니다. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_lt.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_lt.ts new file mode 100644 index 0000000..318fefc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_lt.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Failų tvarkytuvė + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Failų tvarkytuvė yra galingas ir lengvas naudoti failų tvarkymo įrankis, kurio ypatybės yra paieška, kopijavimas, šiukšlinė, glaudinimas/išglaudinimas, failų savybės bei kitos naudingos funkcijos. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ml.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ml.ts new file mode 100644 index 0000000..1ea2c0d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ml.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + ഡീപിൻ ഫയൽ മാനേജർ + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_mn.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_mn.ts new file mode 100644 index 0000000..9dea9a9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_mn.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + Дийпин файл менежер + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + Файл менежер нь Дийпин Технологийн хөгжүүлсэн файл зохицуулалтын бие даасан хэрэгсэл, хайлт хийх, хуулах, устгах, шахах, шахсан файл задлах, файлын төлөв байдал болон бусад файлын удирдлагын функц боломжуудтай. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ms.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ms.ts new file mode 100644 index 0000000..ed5046b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ms.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Pengurus Fail + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Pengurus Fail merupakan alat pengurusan fail yang mudah digunakan dan hebat, difiturkan dengan fungsi menggelintar, menyalin, tong sampah, pemampatan/penyahmampatan, sifat fail dan lain-lain fungsi berguna. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_nb.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_nb.ts new file mode 100644 index 0000000..79736d9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_nb.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + Filbehandler + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ne.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ne.ts new file mode 100644 index 0000000..fdfe47c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ne.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + डीपिन फाइल प्रबन्धक + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + फाइल प्रबन्धक एक फाईल प्रबन्धन उपकरण हो जुन स्वतन्त्र रूपमा डीपिन टेक्नोलोजीद्वारा विकसित गरिएको हो, खोजी, प्रतिलिपि, रद्दीटोकरी, कम्प्रेशन / डिकम्प्रेशन, फाइल सम्पत्ती र अन्य फाइल प्रबन्धन कार्यहरू सहितको रूपमा चित्रित छ। + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_nl.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_nl.ts new file mode 100644 index 0000000..78c8463 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_nl.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Bestandsbeheerder + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Bestandsbeheer is een programma voor het beheren van bestanden en beschikt over vele mogelijkheden, zoals zoeken, kopiëren, verwijderen, (de)compressie en andere handige functies. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_pa.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_pa.ts new file mode 100644 index 0000000..ee411ec --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_pa.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + ਡੀਪਿਨ ਫਾਇਲ ਮੈਨੇਜਰ + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + ਫਾਇਲ ਮੈਨੇਜਰ ਫਾਇਲਾਂ ਦਾ ਬੰਦੋਬਸਤ ਕਰਨ ਵਾਲਾ ਸੰਦ ਹੈ, ਜਿਸ ਨੂੰ ਡੀਪਿਨ ਟਕਨਾਲੋਜੀ ਵਲੋਂ ਖੋਜ ਕਰਨ, ਕਾਪੀ ਕਰਨ, ਰੱਦੀ ਵਿੱਚ ਪਾਓ, ਨਪੀੜ/ਖਿਲਾਰਨ, ਫਾਇਲ ਗੁਣ ਅਤੇ ਹੋਰ ਫਾਇਲ ਬੰਦੋਬਸਤ ਫੰਕਸ਼ਨਾਂ ਨਾਲ ਤਿਆਰ ਕੀਤਾ ਗਿਆ ਹੈ। + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_pl.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_pl.ts new file mode 100644 index 0000000..2a8313c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_pl.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Menedżer plików + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Menedżer plików to potężne i łatwe w użyciu narzędzie do zarządzania plikami, wyposażone w wyszukiwanie, kopiowanie, kosz, kompresję/dekompresję, właściwość pliku i inne przydatne funkcje. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_pt.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_pt.ts new file mode 100644 index 0000000..3a7d34d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_pt.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Gestor de Ficheiros + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + O Gestor de Ficheiros é uma ferramenta de gestão de ficheiros poderosa e fácil de usar, que inclui pesquisar, copiar, eliminar, comprimir/extrair, consultar propriedades dos ficheiros e outras funções úteis. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_pt_BR.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_pt_BR.ts new file mode 100644 index 0000000..c58170c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_pt_BR.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Gerenciador de Arquivos + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + O Gerenciador de Arquivos é uma ferramenta poderosa e fácil de usar para manusear os arquivos. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ro.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ro.ts new file mode 100644 index 0000000..31bc4cf --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ro.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + Manager de fișiere + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + Managerul de fișiere este un instrument de gestionare a fișierelor dezvoltat independent de Deepin Technology, dotat cu căutare, copiere, coș de gunoi, compresie / decompresie, proprietate de fișiere și alte funcții de gestionare a fișierelor. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ru.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ru.ts new file mode 100644 index 0000000..6a97e97 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ru.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Файловый Менеджер + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Диспетчер Файлов - это мощный и простой в использовании инструмент управления файлами, включающий поиск, копирование, удаление, сжатие / распаковку, свойства файла и другие полезные функции. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sk.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sk.ts new file mode 100644 index 0000000..47bd1e5 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sk.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Správca súborov + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Správca súborov je výkonný a ľahko použiteľný nástroj na správu súborov vybavený funkciami vyhľadávania, kopírovania, koša, kompresie/dekompresie, vlastností súboru a ďalších užitočných funkcií. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sl.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sl.ts new file mode 100644 index 0000000..464587c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sl.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Upravitelj datotek + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Upravitelj datotek je zmogljivo in enostavno orodje za upravljanje datotek, s funkcijami iskanja, kopiranja, košem, stiskanjem/ razširjanjem, lastnostmi datotek in drugimi uporabnimi zadevami. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sq.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sq.ts new file mode 100644 index 0000000..963fd5e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sq.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Përgjegjës Kartelash + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Përgjegjësi i Kartelave është një mjet i fuqishëm dhe i kollajtë për t’u përdorur për administrim kartelash, që përmban kërkim, kopjim, shpënie te hedhurinat, ngjeshje/çhngjeshje, veti kartelash dhe funksione të tjera të dobishme. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sr.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sr.ts new file mode 100644 index 0000000..7311bef --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sr.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Управник Података + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Управник Података је моћан алат за управљање датотекама који је лак за коришћење. Поседује претрагу, копирање, смеће, запакивање, распакивање, својства датотека и многе друге корисне функције. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sv.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sv.ts new file mode 100644 index 0000000..ce5f68e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_sv.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + Filhanterare + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ta.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ta.ts new file mode 100644 index 0000000..335e974 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ta.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + டீபைன் கோப்பு மேலாளர் + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + கோப்பு மேலாளர் என்பது டீபைன் டெக்னாலஜி சுயாதீனமாக உருவாக்கிய ஒரு கோப்பு நிர்வாக கருவி ஆகும், இது தேடல், நகல், குப்பை, சுருக்க / டிகம்பரஷன், கோப்பு விவரங்கள் மற்றும் பிற கோப்பு மேலாண்மை செயல்பாடுகளை கொண்டுள்ளது. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_th.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_th.ts new file mode 100644 index 0000000..dd1e29d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_th.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + โปรแกรมจัดการแฟ้ม + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_tr.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_tr.ts new file mode 100644 index 0000000..c408fa2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_tr.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Dosya Yöneticisi + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Dosya Yöneticisi, arama, kopyalama, çöp kutusu, sıkıştırma/açma, dosya özelliği ve diğer kullanışlı işlevler içeren güçlü ve kullanımı kolay bir dosya yönetim aracıdır. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ug.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ug.ts new file mode 100644 index 0000000..ee68309 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_ug.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + ھۆججەت باشقۇرغۇچ + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + ھۆججەت باشقۇرغۇچ بولسا كۈچلۈك ۋە ئىشلىتىشكە قۇلايلىق بولغان ھۆججەت باشقۇرۇش قورالى بولۇپ ، ئىزدەش ، كۆپەيتىش ، ئەخلەت ساندۇقى ، پىرىسلاش / يېشىش ، ھۆججەت خاسلىقى ۋە باشقا پايدىلىق ئىقتىدارلار بىلەن ئىپادىلىنىدۇ. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_uk.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_uk.ts new file mode 100644 index 0000000..591a055 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_uk.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + Файловий менеджер + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + Менеджер файлів - це потужний і простий у використанні інструмент керування файлами з функціями пошуку, копіювання, видалення, стиснення/розпакування, зміни властивостей файлу та іншими корисними функціями. + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_vi.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_vi.ts new file mode 100644 index 0000000..1dbb39a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_vi.ts @@ -0,0 +1,23 @@ + + + Application + + Deepin File Manager + Trình quản lý tệp tin + + + + File Manager + + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + + + + File Manager is a file management tool independently developed by Deepin Technology, featured with searching, copying, trash, compression/decompression, file property and other file management functions. + + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_zh_CN.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_zh_CN.ts new file mode 100644 index 0000000..8a7624f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_zh_CN.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + 文件管理器 + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + 文件管理器是一款功能强大的文件管理工具, 它包括搜索、复制、回收站、压缩/解压缩, 文件属性等管理功能。 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_zh_HK.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_zh_HK.ts new file mode 100644 index 0000000..56e38d1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_zh_HK.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + 檔案管理員 + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + 檔案管理員是一款功能強大的文件管理工具, 它包括搜索、複製、回收站、壓縮/解壓縮, 文件屬性等管理功能。 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_zh_TW.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_zh_TW.ts new file mode 100644 index 0000000..da2bc9d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-app_zh_TW.ts @@ -0,0 +1,15 @@ + + + Application + + + File Manager + 檔案管理器 + + + + File Manager is a powerful and easy-to-use file management tool, featured with searching, copying, trash, compression/decompression, file property and other useful functions. + 《檔案管理器》是個強大且易用的檔案管理工具,有搜尋、複製、垃圾桶功能、壓縮/解壓縮、檔案屬性等實用功能。 + + + \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop.ts new file mode 100644 index 0000000..aac396d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop.ts @@ -0,0 +1 @@ +desktopBrowse the file systemBrowse the file systemDeepin File ManagerDeepin File ManagerFile ManagerFile ManagerNew WindowNew Window \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_am_ET.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_am_ET.ts new file mode 100644 index 0000000..d237729 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_am_ET.ts @@ -0,0 +1 @@ +desktopBrowse the file systemየ ፋይል ስርአት መቃኛDeepin File Managerዲፕኢን የ ፋይል አስተዳዳሪFile Managerየ ፋይል አስተዳዳሪNew Windowአዲስ መስኮት \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ar.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ar.ts new file mode 100644 index 0000000..eccece7 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ar.ts @@ -0,0 +1 @@ +desktopBrowse the file systemتصفح ملف النظامDeepin File Managerمدير ملفات ديبينFile Managerمدير الملفاتNew Windowنافذة جديدة \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ast.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ast.ts new file mode 100644 index 0000000..cd1de70 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ast.ts @@ -0,0 +1 @@ +desktopBrowse the file systemRestola sistemes de ficherosDeepin File ManagerDeepin File ManagerFile ManagerXestor de ficherosNew WindowVentana nueva \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_az.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_az.ts new file mode 100644 index 0000000..0dd039f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_az.ts @@ -0,0 +1 @@ +desktopBrowse the file systemFayl sisteminə baxışDeepin File ManagerDeepin Fayl MeneceriFile ManagerFayl MeneceriNew WindowYeni Pəncərə \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_bg.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_bg.ts new file mode 100644 index 0000000..d3c9b6c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_bg.ts @@ -0,0 +1 @@ +desktopBrowse the file systemПреглед на файловата системаDeepin File ManagerФайлов мениджърFile ManagerФайлов мениджърNew WindowНов прозорец \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_bn.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_bn.ts new file mode 100644 index 0000000..acc9cd4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_bn.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemফাইল সিস্টেম ব্রাউজ করুনDeepin File Managerফাইল ম্যানেজারFile ManagerNew Windowনতুন উইন্ডো diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_bo.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_bo.ts new file mode 100644 index 0000000..a07ed78 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_bo.ts @@ -0,0 +1 @@ +desktopBrowse the file systemཡིག་ཆའི་རྒྱུད་ཁོངས་ལ་རགས་ཙམ་ལྟ་བ།Deepin File Managerགཏིང་ཚད་ཡིག་ཆ་དོ་དམ་བྱེད་ཆས།File Managerཡིག་ཆ་དོ་དམ་བྱེད་ཆས།New Windowསྒེའུ་ཁུང་གསར་འཛུགས། \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ca.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ca.ts new file mode 100644 index 0000000..7941435 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ca.ts @@ -0,0 +1 @@ +desktopBrowse the file systemNavegueu pel sistema de fitxersDeepin File ManagerGestor de fitxers del DeepinFile ManagerGestor de fitxersNew WindowFinestra nova \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_cs.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_cs.ts new file mode 100644 index 0000000..f801114 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_cs.ts @@ -0,0 +1 @@ +desktopBrowse the file systemProcházet souborový systémDeepin File ManagerDeepin správce souborůFile ManagerSprávce souborůNew WindowNové okno \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_da.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_da.ts new file mode 100644 index 0000000..b6742e1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_da.ts @@ -0,0 +1 @@ +desktopBrowse the file systemGennemse filsystemetDeepin File ManagerDeepin filhåndteringFile ManagerFilhåndteringNew WindowNyt vindue \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_de.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_de.ts new file mode 100644 index 0000000..b69a240 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_de.ts @@ -0,0 +1 @@ +desktopBrowse the file systemDateisystem durchsuchenDeepin File ManagerDeepin DateimanagerFile ManagerDateimanagerNew WindowNeues Fenster \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_el.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_el.ts new file mode 100644 index 0000000..9b3b9f3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_el.ts @@ -0,0 +1 @@ +desktopBrowse the file systemΠεριηγηθείτε στο αρχείο συστήματοςDeepin File ManagerΔιαχειριστής αρχείωνFile ManagerΔιαχειριστής αρχείωνNew WindowΝέο παράθυρο \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_en_AU.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_en_AU.ts new file mode 100644 index 0000000..703230c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_en_AU.ts @@ -0,0 +1 @@ +desktopBrowse the file systemBrowse the file systemDeepin File ManagerDeepin File ManagerFile ManagerFile ManagerNew WindowNew Window \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_en_GB.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_en_GB.ts new file mode 100644 index 0000000..c0e7dc4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_en_GB.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemBrowse the file systemDeepin File ManagerDeepin File ManagerFile ManagerNew Window diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_es.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_es.ts new file mode 100644 index 0000000..d42f186 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_es.ts @@ -0,0 +1 @@ +desktopBrowse the file systemExaminar el sistema de archivosDeepin File ManagerAdministrador de archivosFile ManagerAdministrador de archivosNew WindowNueva ventana \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_et.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_et.ts new file mode 100644 index 0000000..56a0f4c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_et.ts @@ -0,0 +1 @@ +desktopBrowse the file systemSirvi failisüsteemiDeepin File ManagerDeepin failihaldurFile ManagerFailihaldurNew WindowUus aken \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_eu.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_eu.ts new file mode 100644 index 0000000..c1f16de --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_eu.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemArakatu fitxategi sistemaDeepin File ManagerFitxategi kudeatzaileaFile ManagerNew WindowLeiho berria diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_fa.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_fa.ts new file mode 100644 index 0000000..7b87d5f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_fa.ts @@ -0,0 +1 @@ +desktopBrowse the file systemسیستم فایل را مرور کنیدDeepin File Managerمدیر فایل دیپینFile Managerمدیر فایلNew Windowپنجره نو \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_fi.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_fi.ts new file mode 100644 index 0000000..18e3f7e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_fi.ts @@ -0,0 +1 @@ +desktopBrowse the file systemSelaa tiedostojaDeepin File ManagerDeepin tiedostohallintaFile ManagerTiedostohallintaNew WindowUusi ikkuna \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_fr.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_fr.ts new file mode 100644 index 0000000..b162cf8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_fr.ts @@ -0,0 +1 @@ +desktopBrowse the file systemParcourir le système de fichiersDeepin File ManagerGestionnaire de fichiers DeepinFile ManagerGestionnaire de fichiersNew WindowNouvelle fenêtre \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_fur.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_fur.ts new file mode 100644 index 0000000..676f86e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_fur.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemDeepin File ManagerFile ManagerNew WindowGnûf barcon diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_gd.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_gd.ts new file mode 100644 index 0000000..c938881 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_gd.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemDeepin File ManagerFile ManagerNew WindowUinneag ùr diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_gl.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_gl.ts new file mode 100644 index 0000000..e033d32 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_gl.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemExaminar o sistema de ficheirosDeepin File ManagerXestor de ficheirosFile ManagerNew WindowNova xanela diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_gl_ES.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_gl_ES.ts new file mode 100644 index 0000000..3d01c0d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_gl_ES.ts @@ -0,0 +1 @@ +desktopBrowse the file systemExamina o sistema de ficheirosDeepin File ManagerXestor de ficheirosFile ManagerXestor de ficheirosNew WindowNova xanela \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_he.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_he.ts new file mode 100644 index 0000000..6330699 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_he.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemעיון במערכת הקבציםDeepin File Managerמנהל קבציםFile ManagerNew Windowחלון חדש diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_hr.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_hr.ts new file mode 100644 index 0000000..bc7e7aa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_hr.ts @@ -0,0 +1 @@ +desktopBrowse the file systemPregledavaj datotečni sustavDeepin File ManagerDeepin upravltelj datotekamaFile ManagerUpravitelj datotekamaNew WindowNovi prozor \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_hu.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_hu.ts new file mode 100644 index 0000000..00f6eda --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_hu.ts @@ -0,0 +1 @@ +desktopBrowse the file systemA fájlrendszer böngészéseDeepin File ManagerDeepin® FájlkezelőFile ManagerFájlkezelőNew WindowÚj ablak \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_id.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_id.ts new file mode 100644 index 0000000..2959d3b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_id.ts @@ -0,0 +1 @@ +desktopBrowse the file systemRamban sistem berkasDeepin File ManagerManajer BerkasFile ManagerManajer BerkasNew WindowJendela Baru \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_is.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_is.ts new file mode 100644 index 0000000..3f010de --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_is.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemFlakka í skráakerfinuDeepin File ManagerSkráastjóriFile ManagerNew Window diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_it.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_it.ts new file mode 100644 index 0000000..e61d64a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_it.ts @@ -0,0 +1 @@ +desktopBrowse the file systemApri il File SystemDeepin File ManagerDeepin File ManagerFile ManagerFile ManagerNew WindowNuova finestra \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ja.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ja.ts new file mode 100644 index 0000000..bc49918 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ja.ts @@ -0,0 +1 @@ +desktopBrowse the file systemファイル システムを参照しますDeepin File ManagerDeepin ファイル マネージャーFile Managerファイル マネージャーNew Window新規ウィンドウ \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_kab.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_kab.ts new file mode 100644 index 0000000..378acad --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_kab.ts @@ -0,0 +1 @@ +desktopBrowse the file systemSnirem anagraw n yifuylaDeepin File ManagerAmsefrak n yifuyla n DeepinFile ManagerAmsefrek n ifuylaNew WindowAsfaylu amaynut \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_kk.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_kk.ts new file mode 100644 index 0000000..c28ce0d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_kk.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemФайлдық жүйені шолуDeepin File ManagerФайлдар басқарушысыFile ManagerNew WindowЖаңа терезе diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ko.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ko.ts new file mode 100644 index 0000000..22131bb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ko.ts @@ -0,0 +1 @@ +desktopBrowse the file system파일 시스템 찾아보기Deepin File ManagerDeepin 파일 관리자File Manager파일 관리자New Window새 창 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_lt.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_lt.ts new file mode 100644 index 0000000..f94f2c6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_lt.ts @@ -0,0 +1 @@ +desktopBrowse the file systemNaršyti failų sistemąDeepin File ManagerDeepin failų tvarkytuvėFile ManagerFailų tvarkytuvėNew WindowNaujas langas \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_lv.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_lv.ts new file mode 100644 index 0000000..29d4701 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_lv.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemDeepin File ManagerFaila pārvaldnieksFile ManagerNew WindowJauns logs diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ml.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ml.ts new file mode 100644 index 0000000..be94b6d --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ml.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemDeepin File Managerഡീപിൻ ഫയൽ മാനേജർFile Managerഫയൽ മാനേജർNew Window diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_mn.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_mn.ts new file mode 100644 index 0000000..e96237b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_mn.ts @@ -0,0 +1 @@ +desktopBrowse the file systemФайл системийг ажиглахDeepin File ManagerДиипин файл менежерFile ManagerФайл менежерNew WindowШинэ цонх \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ms.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ms.ts new file mode 100644 index 0000000..37b54a0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ms.ts @@ -0,0 +1 @@ +desktopBrowse the file systemLayar sistem failDeepin File ManagerPengurus Fail DeepinFile ManagerPengurus FailNew WindowTetinkap Baharu \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_nb.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_nb.ts new file mode 100644 index 0000000..50fedfd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_nb.ts @@ -0,0 +1 @@ +desktopBrowse the file systemBla gjennom filsystemetDeepin File ManagerFilbehandlerFile ManagerFilutforskerNew WindowNytt vindu \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ne.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ne.ts new file mode 100644 index 0000000..f851b1b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ne.ts @@ -0,0 +1 @@ +desktopBrowse the file systemफाईल प्रणाली ब्राउज गर्नुहोस्Deepin File Managerडीपिन फाइल प्रबन्धकFile Managerफाइल प्रबन्धकNew Windowनयाँ विन्डो \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_nl.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_nl.ts new file mode 100644 index 0000000..1756f8e --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_nl.ts @@ -0,0 +1 @@ +desktopBrowse the file systemVerken het bestandssysteemDeepin File ManagerDeepin BestandsbeheerFile ManagerBestandsbeheerNew WindowNieuw venster \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_nn.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_nn.ts new file mode 100644 index 0000000..229546c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_nn.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemBla gjennom filsystemetDeepin File ManagerFilhandsamarFile ManagerNew Window diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_oc.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_oc.ts new file mode 100644 index 0000000..2a6ce50 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_oc.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemPercórrer lo sistèma de fichièrsDeepin File ManagerGestionari de fichièrsFile ManagerNew WindowFenèstra novèla diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_pa.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_pa.ts new file mode 100644 index 0000000..f5b5ed1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_pa.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemਫਾਇਲ ਸਿਸਟਮ ਬਰਾਊਜ਼ ਕਰੋDeepin File Managerਡੀਪਿਨ ਫਾਇਲ ਮੈਨੇਜਰFile ManagerNew Windowਨਵੀਂ ਵਿੰਡੋ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_pl.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_pl.ts new file mode 100644 index 0000000..800f125 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_pl.ts @@ -0,0 +1 @@ +desktopBrowse the file systemPrzeglądaj system plikówDeepin File ManagerMenedżer plików DeepinFile ManagerMenedżer plikówNew WindowNowe okno \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_pt.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_pt.ts new file mode 100644 index 0000000..081a160 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_pt.ts @@ -0,0 +1 @@ +desktopBrowse the file systemExplorar o sistema de ficheirosDeepin File ManagerGestor de Ficheiros DeepinFile ManagerGestor de FicheirosNew WindowNova Janela \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_pt_BR.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_pt_BR.ts new file mode 100644 index 0000000..92a0248 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_pt_BR.ts @@ -0,0 +1 @@ +desktopBrowse the file systemNavegar pelos arquivos do sistemaDeepin File Managerdeepin Gerenciador de ArquivosFile ManagerGerenciador de ArquivosNew WindowNova Janela \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ro.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ro.ts new file mode 100644 index 0000000..419f0b9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ro.ts @@ -0,0 +1 @@ +desktopBrowse the file systemGestionați fișierele din sistemDeepin File ManagerManager de fișiere DeepinFile ManagerManager de fișiereNew WindowFereastră nouă \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ru.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ru.ts new file mode 100644 index 0000000..452fc76 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ru.ts @@ -0,0 +1 @@ +desktopBrowse the file systemПросмотр файловой системыDeepin File ManagerФайловый Менеджер DeepinFile ManagerФайловый МенеджерNew WindowНовое Окно \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sk.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sk.ts new file mode 100644 index 0000000..52ba487 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sk.ts @@ -0,0 +1 @@ +desktopBrowse the file systemPrehľadávanie systému súborovDeepin File ManagerDeepin Správca súborovFile ManagerSprávca súborovNew WindowNové okno \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sl.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sl.ts new file mode 100644 index 0000000..067c2e4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sl.ts @@ -0,0 +1 @@ +desktopBrowse the file systemBrskaj po datotečnem sistemuDeepin File ManagerUpravitelj datotek DeepinFile ManagerUpravitelj datotekNew WindowNovo okno \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sq.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sq.ts new file mode 100644 index 0000000..28e6afc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sq.ts @@ -0,0 +1 @@ +desktopBrowse the file systemShfletoni sistemin e kartelaveDeepin File ManagerPërgjegjës Kartelash DeepinFile ManagerPërgjegjës KartelashNew WindowDritare e Re \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sr.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sr.ts new file mode 100644 index 0000000..7ce2383 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sr.ts @@ -0,0 +1 @@ +desktopBrowse the file systemПрегледај систем датотекаDeepin File ManagerДипин Управник ПодатакаFile ManagerУправник ПодатакаNew WindowНови прозор \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sv.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sv.ts new file mode 100644 index 0000000..f9a5cb8 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_sv.ts @@ -0,0 +1 @@ +desktopBrowse the file systemBläddra i filsystemetDeepin File ManagerFilhanterareFile ManagerFilhanterareNew WindowNytt fönster \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ta.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ta.ts new file mode 100644 index 0000000..738c0d3 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ta.ts @@ -0,0 +1 @@ +desktopBrowse the file systemகோப்பு முறைமை உலாவுகDeepin File Managerடீபைன் கோப்பு மேலாளர்File Managerகோப்பு மேலாளர்New Windowபுதிய திரை \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_te.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_te.ts new file mode 100644 index 0000000..7575bf2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_te.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemదస్త్ర వ్యవస్థను విహరించుDeepin File Managerదస్త్ర నిర్వాహకంFile ManagerNew Window diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_th.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_th.ts new file mode 100644 index 0000000..8992ecc --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_th.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemท่องดูระบบแฟ้มDeepin File Managerโปรแกรมจัดการแฟ้มFile ManagerNew Windowหน้าต่างใหม่ diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_tr.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_tr.ts new file mode 100644 index 0000000..2a79c45 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_tr.ts @@ -0,0 +1 @@ +desktopBrowse the file systemDosya sistemine gözatDeepin File ManagerDeepin Dosya YöneticisiFile ManagerDosya YöneticisiNew WindowYeni Pencere \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ug.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ug.ts new file mode 100644 index 0000000..865a9e9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_ug.ts @@ -0,0 +1 @@ +desktopBrowse the file systemھۆججەت سىستېمىسىنى كۆرىدۇDeepin File Managerھۆججەت باشقۇرغۇچFile Managerھۆججەت باشقۇرغۇچNew Windowيېڭى كۆزنەك \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_uk.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_uk.ts new file mode 100644 index 0000000..4899484 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_uk.ts @@ -0,0 +1 @@ +desktopBrowse the file systemПерегляд файлової системиDeepin File ManagerФайловий менеджер DeepinFile ManagerФайловий менеджерNew WindowНове вікно \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_vi.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_vi.ts new file mode 100644 index 0000000..af7483c --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_vi.ts @@ -0,0 +1,3 @@ + + +desktopBrowse the file systemDuyệt hệ thống tệp tinDeepin File ManagerTrình quản lý tệp tinFile ManagerNew Window diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_zh_CN.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_zh_CN.ts new file mode 100644 index 0000000..ec5ba43 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_zh_CN.ts @@ -0,0 +1 @@ +desktopBrowse the file system浏览文件系统Deepin File Manager深度文件管理器File Manager文件管理器New Window新建窗口 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_zh_HK.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_zh_HK.ts new file mode 100644 index 0000000..3274e02 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_zh_HK.ts @@ -0,0 +1 @@ +desktopBrowse the file system瀏覽檔案系統Deepin File Manager深度檔案管理員File Manager檔案管理員New Window新建窗口 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_zh_TW.ts b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_zh_TW.ts new file mode 100644 index 0000000..e7d1523 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-manager/translations/dde-file-manager-desktop/desktop_zh_TW.ts @@ -0,0 +1 @@ +desktopBrowse the file system瀏覽與管理檔案系統Deepin File ManagerDeepin 檔案管理器File Manager檔案管理器New Window新增視窗 \ No newline at end of file diff --git a/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/common.pri b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/common.pri new file mode 100644 index 0000000..b14d6a0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/common.pri @@ -0,0 +1,21 @@ +isEmpty(LIB_INSTALL_DIR) { + TOOLDIR = $$[QT_INSTALL_LIBS]/dde-file-manager/tools/thumbnail +} else { + TOOLDIR = $$LIB_INSTALL_DIR/dde-file-manager/tools/thumbnail +} + +top_dir = $$PWD/.. + +DESTDIR = $$top_dir/tools/thumbnail + +target.path = $$TOOLDIR +json.files += $$_PRO_FILE_PWD_/$${TARGET}.json +json.path = $${target.path} + +INSTALLS += target json +OTHER_FILES += $$json.files + +CONFIG(debug, debug|release) { + mkpath($$DESTDIR) + system(ln -s $$json.files $$DESTDIR) +} diff --git a/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/dde-file-thumbnail-tool.pro b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/dde-file-thumbnail-tool.pro new file mode 100644 index 0000000..ae7a80f --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/dde-file-thumbnail-tool.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs + +!CONFIG(DISABLE_FFMPEG):!isEqual(BUILD_MINIMUM, YES) { + SUBDIRS += video +} diff --git a/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/funcwrapper.cpp b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/funcwrapper.cpp new file mode 100644 index 0000000..18d432b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/funcwrapper.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "funcwrapper.h" + +#include +#include +#include + +char *toBase64(const unsigned char *data, int size, int options) +{ + const char alphabet_base64[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef" + "ghijklmn" "opqrstuv" "wxyz0123" "456789+/"; + const char alphabet_base64url[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef" + "ghijklmn" "opqrstuv" "wxyz0123" "456789-_"; + const char *const alphabet = (options & Base64UrlEncoding) ? alphabet_base64url : alphabet_base64; + const char padchar = '='; + int padlen = 0; + + int tmp_size = (size + 2) / 3 * 4; + char *tmp = new char[static_cast(tmp_size) + 1]; + tmp[tmp_size] = '\0'; + + int i = 0; + char *out = tmp; + while (i < size) { + // encode 3 bytes at a time + int chunk = 0; + chunk |= int((data[i++])) << 16; + if (i == size) { + padlen = 2; + } else { + chunk |= int((data[i++])) << 8; + if (i == size) + padlen = 1; + else + chunk |= int((data[i++])); + } + + int j = (chunk & 0x00fc0000) >> 18; + int k = (chunk & 0x0003f000) >> 12; + int l = (chunk & 0x00000fc0) >> 6; + int m = (chunk & 0x0000003f); + *out++ = alphabet[j]; + *out++ = alphabet[k]; + + if (padlen > 1) { + if ((options & OmitTrailingEquals) == 0) + *out++ = padchar; + } else { + *out++ = alphabet[l]; + } + if (padlen > 0) { + if ((options & OmitTrailingEquals) == 0) + *out++ = padchar; + } else { + *out++ = alphabet[m]; + } + } + + if (!((options & OmitTrailingEquals) || (out == tmp_size + tmp))) { + std::abort(); + } + + if (options & OmitTrailingEquals) { + int new_size = static_cast(out - tmp); + char *new_tmp = new char[static_cast(new_size) + 1]; + + memcpy(new_tmp, tmp, static_cast(new_size)); + delete[] tmp; + + tmp = new_tmp; + } + + return tmp; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/funcwrapper.h b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/funcwrapper.h new file mode 100644 index 0000000..d9ce4f9 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/funcwrapper.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#ifndef FUNCWRAPPER_H +#define FUNCWRAPPER_H + +enum Base64Option { + Base64Encoding = 0, + Base64UrlEncoding = 1, + + KeepTrailingEquals = 0, + OmitTrailingEquals = 2 +}; + +char *toBase64(const unsigned char *data, int size, int options); + +#endif // FUNCWRAPPER_H + diff --git a/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/main.cpp b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/main.cpp new file mode 100644 index 0000000..eddba3b --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/main.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: gongheng + * + * Maintainer: zhengyouge + * gongheng + * + * 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 + * 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 . +*/ + +#include "funcwrapper.h" + +#include + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc != 3) { + return -1; + } + + try { + std::vector imageData; + std::stringstream stream(argv[1]); + std::string path(argv[2]); + + int size; + + stream >> size; + + ffmpegthumbnailer::VideoThumbnailer vt(size, false, true, 20, false); + vt.generateThumbnail(path, ThumbnailerImageTypeEnum::Png, imageData); + + char *base64_data = toBase64(imageData.data(), static_cast(imageData.size()), Base64Encoding); + + printf("%s", base64_data); + fflush(stdout); + } catch (std::logic_error &e) { + std::cerr << e.what(); + return -1; + } + + return 0; +} diff --git a/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/video.json b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/video.json new file mode 100644 index 0000000..33ea638 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/video.json @@ -0,0 +1,3 @@ +{ + "Keys" : ["video/*", "application/vnd.rn-realmedia"] +} diff --git a/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/video.pro b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/video.pro new file mode 100644 index 0000000..c23bea1 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-file-thumbnail-tool/video/video.pro @@ -0,0 +1,22 @@ +TEMPLATE = app +CONFIG -= qt + +include(../common.pri) + +#安全加固 +QMAKE_CXXFLAGS += -fstack-protector-all +QMAKE_LFLAGS += -z now -pie -fPIE +isEqual(ARCH, mips64) | isEqual(ARCH, mips32){ + QMAKE_LFLAGS += -z noexecstack -z relro +} + +SOURCES += \ + main.cpp \ + funcwrapper.cpp + +!CONFIG(DISABLE_FFMPEG):!isEqual(BUILD_MINIMUM, YES) { + LIBS += -lffmpegthumbnailer +} + +HEADERS += \ + funcwrapper.h diff --git a/dde-file-manager-5.5.3/src/dde-select-dialog-wayland/com.deepin.filemanager.filedialog_wayland.service b/dde-file-manager-5.5.3/src/dde-select-dialog-wayland/com.deepin.filemanager.filedialog_wayland.service new file mode 100755 index 0000000..d449358 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-select-dialog-wayland/com.deepin.filemanager.filedialog_wayland.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=com.deepin.filemanager.filedialog_wayland +Exec=/usr/bin/dde-select-dialog-wayland diff --git a/dde-file-manager-5.5.3/src/dde-select-dialog-wayland/dde-select-dialog-wayland.pro b/dde-file-manager-5.5.3/src/dde-select-dialog-wayland/dde-select-dialog-wayland.pro new file mode 100755 index 0000000..1b0ff5a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-select-dialog-wayland/dde-select-dialog-wayland.pro @@ -0,0 +1,43 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2021-08-09T13:53:34 +# +#------------------------------------------------- + +QT += core gui dbus + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = dde-select-dialog-wayland +TEMPLATE = app + +CONFIG += c++11 link_pkgconfig +PKGCONFIG += dtkwidget dtkgui dtkcore + +include($$PWD/../dde-desktop/dbus/filedialog/filedialog.pri) + +INCLUDEPATH += $$PWD/../dde-file-manager-lib \ + $$PWD/../dde-file-manager-lib/interfaces \ + $$PWD/../utils \ + +win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../dde-file-manager-lib/release -ldde-file-manager +else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../dde-file-manager-lib/debug -ldde-file-manager +else:unix: LIBS += -L$$OUT_PWD/../dde-file-manager-lib -ldde-file-manager + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +SOURCES += \ + main.cpp + +HEADERS += \ + +target.path = /usr/bin + +filedialog_service_wayland.path = /usr/share/dbus-1/services +filedialog_service_wayland.files = $$PWD/com.deepin.filemanager.filedialog_wayland.service + +INSTALLS += target filedialog_service_wayland diff --git a/dde-file-manager-5.5.3/src/dde-select-dialog-wayland/main.cpp b/dde-file-manager-5.5.3/src/dde-select-dialog-wayland/main.cpp new file mode 100755 index 0000000..14efaf4 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-select-dialog-wayland/main.cpp @@ -0,0 +1,61 @@ +#include "dbusfiledialogmanager.h" +#include "filedialogmanager_adaptor.h" +#include "log/dfmLogManager.h" + +#include + +#include + +DFM_USE_NAMESPACE +using namespace Dtk::Core; +using namespace Dtk::Widget; + +static bool registerDialogDBus() +{ + if (!QDBusConnection::sessionBus().isConnected()) { + qWarning("Cannot connect to the D-Bus session bus.\n" + "Please check your system settings and try again.\n"); + return false; + } + + // add our D-Bus interface and connect to D-Bus + if (!QDBusConnection::sessionBus().registerService("com.deepin.filemanager.filedialog_wayland")) { + qWarning("Cannot register the \"com.deepin.filemanager.filedialog_wayland\" service.\n"); + return false; + } + + DBusFileDialogManager *manager = new DBusFileDialogManager(); + Q_UNUSED(new FiledialogmanagerAdaptor(manager)); + + if (!QDBusConnection::sessionBus().registerObject("/com/deepin/filemanager/filedialogmanager_wayland", manager)) { + qWarning("Cannot register to the D-Bus object: \"/com/deepin/filemanager/filedialogmanager_wayland\"\n"); + manager->deleteLater(); + return false; + } + + return true; +} + +int main(int argc, char *argv[]) +{ + // 设置环境变量xcb + qputenv("QT_QPA_PLATFORM", "wayland"); + + DApplication a(argc, argv); + a.setOrganizationName("deepin"); + // 加载翻译文件 + DFMGlobal::installTranslator(); + // 设置该进程不要因为没有窗口了就退出 + a.setQuitOnLastWindowClosed(false); + // 初始化日志系统 + DFMLogManager::registerFileAppender(); + // 打印平台信息 + qInfo() << "平台信息:" << QApplication::platformName(); + // ability to show file selection dialog + if (!registerDialogDBus()) { + qWarning() << "Register dialog dbus failed."; + return -1; + } + + return a.exec(); +} diff --git a/dde-file-manager-5.5.3/src/dde-select-dialog-x11/com.deepin.filemanager.filedialog_x11.service b/dde-file-manager-5.5.3/src/dde-select-dialog-x11/com.deepin.filemanager.filedialog_x11.service new file mode 100755 index 0000000..f050f94 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-select-dialog-x11/com.deepin.filemanager.filedialog_x11.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=com.deepin.filemanager.filedialog_x11 +Exec=/usr/bin/dde-select-dialog-x11 diff --git a/dde-file-manager-5.5.3/src/dde-select-dialog-x11/dde-select-dialog-x11.pro b/dde-file-manager-5.5.3/src/dde-select-dialog-x11/dde-select-dialog-x11.pro new file mode 100755 index 0000000..aaf1cb0 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-select-dialog-x11/dde-select-dialog-x11.pro @@ -0,0 +1,43 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2021-08-09T13:53:34 +# +#------------------------------------------------- + +QT += core gui dbus + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = dde-select-dialog-x11 +TEMPLATE = app + +CONFIG += c++11 link_pkgconfig +PKGCONFIG += dtkwidget dtkgui dtkcore + +include($$PWD/../dde-desktop/dbus/filedialog/filedialog.pri) + +INCLUDEPATH += $$PWD/../dde-file-manager-lib \ + $$PWD/../dde-file-manager-lib/interfaces \ + $$PWD/../utils \ + +win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../dde-file-manager-lib/release -ldde-file-manager +else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../dde-file-manager-lib/debug -ldde-file-manager +else:unix: LIBS += -L$$OUT_PWD/../dde-file-manager-lib -ldde-file-manager + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +SOURCES += \ + main.cpp + +HEADERS += \ + +target.path = /usr/bin + +filedialog_service_x11.path = /usr/share/dbus-1/services +filedialog_service_x11.files = $$PWD/com.deepin.filemanager.filedialog_x11.service + +INSTALLS += target filedialog_service_x11 diff --git a/dde-file-manager-5.5.3/src/dde-select-dialog-x11/main.cpp b/dde-file-manager-5.5.3/src/dde-select-dialog-x11/main.cpp new file mode 100755 index 0000000..1b65ffd --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-select-dialog-x11/main.cpp @@ -0,0 +1,61 @@ +#include "dbusfiledialogmanager.h" +#include "filedialogmanager_adaptor.h" +#include "log/dfmLogManager.h" + +#include + +#include + +DFM_USE_NAMESPACE +using namespace Dtk::Core; +using namespace Dtk::Widget; + +static bool registerDialogDBus() +{ + if (!QDBusConnection::sessionBus().isConnected()) { + qWarning("Cannot connect to the D-Bus session bus.\n" + "Please check your system settings and try again.\n"); + return false; + } + + // add our D-Bus interface and connect to D-Bus + if (!QDBusConnection::sessionBus().registerService("com.deepin.filemanager.filedialog_x11")) { + qWarning("Cannot register the \"com.deepin.filemanager.filedialog_x11\" service.\n"); + return false; + } + + DBusFileDialogManager *manager = new DBusFileDialogManager(); + Q_UNUSED(new FiledialogmanagerAdaptor(manager)); + + if (!QDBusConnection::sessionBus().registerObject("/com/deepin/filemanager/filedialogmanager_x11", manager)) { + qWarning("Cannot register to the D-Bus object: \"/com/deepin/filemanager/filedialogmanager_x11\"\n"); + manager->deleteLater(); + return false; + } + + return true; +} + +int main(int argc, char *argv[]) +{ + // 设置环境变量xcb + qputenv("QT_QPA_PLATFORM", "xcb"); + + DApplication a(argc, argv); + a.setOrganizationName("deepin"); + // 加载翻译文件 + DFMGlobal::installTranslator(); + // 设置该进程不要因为没有窗口了就退出 + a.setQuitOnLastWindowClosed(false); + // 初始化日志系统 + DFMLogManager::registerFileAppender(); + // 打印平台信息 + qInfo() << "平台信息:" << QApplication::platformName(); + // ability to show file selection dialog + if (!registerDialogDBus()) { + qWarning() << "Register dialog dbus failed."; + return -1; + } + + return a.exec(); +} diff --git a/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/button.cpp b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/button.cpp new file mode 100644 index 0000000..92bf515 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/button.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: wangchunlin + * + * Maintainer: wangchunlin + * xinglinkun + * + * 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 + * 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 . +*/ +#include "button.h" +#include + +Button::Button(QWidget * parent) : + QPushButton(parent) +{ + //setFlat(true); +} + +Button::~Button() +{ + +} + +void Button::setAttract(bool attract) +{ + Q_UNUSED(attract); +// if (attract) { +// setStyleSheet(ATTRACT_STYLE); +// } else { +// setStyleSheet(NO_ATTRACT_STYLE); +// } +} + +void Button::keyPressEvent(QKeyEvent *event) +{ + switch(event->key()) + { + //按下空格、换行、回车按钮皆发送点击信号 + case Qt::Key_Space: + case Qt::Key_Enter: + case Qt::Key_Return: + emit clicked(); + break; +// case Qt::Key_Up: //bug#30790屏蔽上下键 +// case Qt::Key_Down: +// return; + default: + //保持按键事件传递 + event->ignore(); + break; + } + //QPushButton::keyPressEvent(event); +} diff --git a/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/button.h b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/button.h new file mode 100644 index 0000000..c59c728 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/button.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: wangchunlin + * + * Maintainer: wangchunlin + * xinglinkun + * + * 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 + * 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 . +*/ + +#ifndef BUTTON_H +#define BUTTON_H + +#include + +class Button : public QPushButton +{ + Q_OBJECT +public: + explicit Button(QWidget * parent = nullptr); + ~Button(); + + void setAttract(bool); + +protected: + void keyPressEvent(QKeyEvent *event); +}; + +#endif // BUTTON_H diff --git a/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/checkbox.cpp b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/checkbox.cpp new file mode 100644 index 0000000..e7b092a --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/checkbox.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: wangchunlin + * + * Maintainer: wangchunlin + * xinglinkun + * + * 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 + * 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 . +*/ +#include "checkbox.h" + +#include + +CheckBox::CheckBox(QWidget *parent) + : QCheckBox (parent) +{ + +} + +CheckBox::CheckBox(const QString &text, QWidget *parent) + : QCheckBox (parent) +{ + this->setText(text); +} + +void CheckBox::keyPressEvent(QKeyEvent *event) +{ + // 不要加event->key() == Qt::Key_Space,QCheckBox默认就是空格勾选 + if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return /*|| event->key() == Qt::Key_Space*/){ + if (this->isChecked()){ + this->setChecked(false); + emit clicked(false); + }else { + this->setChecked(true); + emit clicked(true); + } + } + + QCheckBox::keyPressEvent(event); +} diff --git a/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/checkbox.h b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/checkbox.h new file mode 100644 index 0000000..de58de6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/checkbox.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: wangchunlin + * + * Maintainer: wangchunlin + * xinglinkun + * + * 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 + * 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 . +*/ +#ifndef CHECKBOX_H +#define CHECKBOX_H + +#include + +class CheckBox : public QCheckBox +{ + Q_OBJECT +public: + explicit CheckBox(QWidget *parent = nullptr); + explicit CheckBox(const QString &text, QWidget *parent = nullptr); + ~CheckBox() override {} + + /** + * @brief keyPressEvent 重写,实现回车勾选操作 + * @param event 键盘事件 + */ + void keyPressEvent(QKeyEvent *event) override; +}; + +#endif // CHECKBOX_H diff --git a/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/constants.h b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/constants.h new file mode 100644 index 0000000..9853356 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/constants.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: wangchunlin + * + * Maintainer: wangchunlin + * xinglinkun + * + * 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 + * 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 . +*/ + +#ifndef CONSTANTS_H +#define CONSTANTS_H + +static const int FrameHeight = 130; +static const int ListHeight = 100; +static const int HeaderSwitcherHeight = 45; + +static const int ItemCellWidth = 172; +static const int ItemCellHeight = ListHeight; +static const int ItemWidth = ItemCellWidth; +static const int ItemHeight = ListHeight; + +static const QString AppearanceServ = "com.deepin.daemon.Appearance"; +static const QString AppearancePath = "/com/deepin/daemon/Appearance"; + +static const QString DeepinWMServ = "com.deepin.wm"; +static const QString DeepinWMPath = "/com/deepin/wm"; + +static const QString MouseAreaServ = "com.deepin.api.XMouseArea"; +static const QString MouseAreaPath = "/com/deepin/api/XMouseArea"; + +static const QByteArray WallpaperSchemaId = "com.deepin.wrap.gnome.desktop.background"; +static const QByteArray WallpaperPath = "/com/deepin/wrap/gnome/desktop/background/"; +static const QString WallpaperKey = "pictureUri"; + +#endif // CONSTANTS_H diff --git a/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/com.deepin.ScreenSaver.xml b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/com.deepin.ScreenSaver.xml new file mode 100644 index 0000000..d7c52fa --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/com.deepin.ScreenSaver.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/com.deepin.daemon.Appearance.xml b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/com.deepin.daemon.Appearance.xml new file mode 100644 index 0000000..50f5768 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/com.deepin.daemon.Appearance.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/com.deepin.wm.xml b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/com.deepin.wm.xml new file mode 100644 index 0000000..73b34eb --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/com.deepin.wm.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/deepin_wm.cpp b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/deepin_wm.cpp new file mode 100644 index 0000000..193f8f6 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/deepin_wm.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: wangchunlin + * + * Maintainer: wangchunlin + * xinglinkun + * + * 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 + * 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 . +*/ +#include "deepin_wm.h" + +/* + * Implementation of interface class DeepinWM + */ + +DeepinWM::DeepinWM(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ + QDBusConnection::sessionBus().connect(this->service(), this->path(), "org.freedesktop.DBus.Properties", "PropertiesChanged","sa{sv}as", this, SLOT(__propertyChanged__(QDBusMessage))); +} + +DeepinWM::~DeepinWM() +{ + QDBusConnection::sessionBus().disconnect(service(), path(), "org.freedesktop.DBus.Properties", "PropertiesChanged", "sa{sv}as", this, SLOT(propertyChanged(QDBusMessage))); +} + diff --git a/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/deepin_wm.h b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/deepin_wm.h new file mode 100644 index 0000000..d9b3cc2 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dbus/deepin_wm.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: wangchunlin + * + * Maintainer: wangchunlin + * xinglinkun + * + * 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 + * 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 . +*/ + +#ifndef DEEPIN_WM_H_1458115332 +#define DEEPIN_WM_H_1458115332 + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface com.deepin.wm + */ +class DeepinWM: public QDBusAbstractInterface +{ + Q_OBJECT + + Q_SLOT void __propertyChanged__(const QDBusMessage& msg) + { + QList arguments = msg.arguments(); + if (3 != arguments.count()) + return; + QString interfaceName = msg.arguments().at(0).toString(); + if (interfaceName !="com.deepin.wm") + return; + QVariantMap changedProps = qdbus_cast(arguments.at(1).value()); + QStringList keys = changedProps.keys(); + foreach(const QString &prop, keys) { + const QMetaObject* self = metaObject(); + for (int i=self->propertyOffset(); i < self->propertyCount(); ++i) { + QMetaProperty p = self->property(i); + if (p.name() == prop) { + Q_EMIT p.notifySignal().invoke(this); + } + } + } + } +public: + static inline const char *staticInterfaceName() + { return "com.deepin.wm"; } + +public: + DeepinWM(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~DeepinWM(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> CancelHideWindows() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("CancelHideWindows"), argumentList); + } + + inline QDBusPendingReply<> PerformAction(int type) + { + QList argumentList; + argumentList << QVariant::fromValue(type); + return asyncCallWithArgumentList(QStringLiteral("PerformAction"), argumentList); + } + + inline QDBusPendingReply<> RequestHideWindows() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("RequestHideWindows"), argumentList); + } + + inline QDBusPendingReply<> ToggleDebug() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("ToggleDebug"), argumentList); + } + + inline QDBusPendingReply<> SetTransientBackground(const QString &uri) + { + QList argumentList; + argumentList << QVariant::fromValue(uri); + return asyncCallWithArgumentList(QStringLiteral("SetTransientBackground"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void BackgroundChanged(); +// begin property changed signals +}; + +#endif diff --git a/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dde-wallpaper-chooser.pri b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dde-wallpaper-chooser.pri new file mode 100644 index 0000000..2da8dda --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/dde-wallpaper-chooser.pri @@ -0,0 +1,38 @@ +SOURCES += $$PWD/frame.cpp \ + $$PWD/wallpaperlist.cpp \ + $$PWD/wallpaperitem.cpp \ + $$PWD/thumbnailmanager.cpp \ + $$PWD/button.cpp \ + $$PWD/dbus/deepin_wm.cpp \ + $$PWD/checkbox.cpp \ + $$PWD/screensavercontrol.cpp \ + $$PWD/waititem.cpp \ + $$PWD/utils/autoactivatewindow.cpp + +HEADERS += $$PWD/frame.h \ + $$PWD/wallpaperlist.h \ + $$PWD/wallpaperitem.h \ + $$PWD/constants.h \ + $$PWD/thumbnailmanager.h \ + $$PWD/button.h \ + $$PWD/dbus/deepin_wm.h \ + $$PWD/checkbox.h \ + $$PWD/screensavercontrol.h \ + $$PWD/waititem.h \ + $$PWD/utils/autoactivatewindow.h \ + $$PWD/utils/autoactivatewindow_p.h + +INCLUDEPATH += $$_PRO_FILE_PWD_/view + +RESOURCES += \ + $$PWD/images.qrc + +isEmpty(DISABLE_SCREENSAVER) { + dbus_screensaver.files = $$PWD/dbus/com.deepin.ScreenSaver.xml + DBUS_INTERFACES += dbus_screensaver +} + +isEmpty(DISABLE_WALLPAPER_CAROUSEL) { + dbus_appearance.files = $$PWD/dbus/com.deepin.daemon.Appearance.xml + DBUS_INTERFACES += dbus_appearance +} diff --git a/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/frame.cpp b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/frame.cpp new file mode 100644 index 0000000..b2bf455 --- /dev/null +++ b/dde-file-manager-5.5.3/src/dde-wallpaper-chooser/frame.cpp @@ -0,0 +1,1283 @@ +/* + * Copyright (C) 2020 ~ 2021 Uniontech Software Technology Co., Ltd. + * + * Author: wangchunlin + * + * Maintainer: wangchunlin + * xinglinkun + * + * 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 + * 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 . +*/ +#include "frame.h" +#include "checkbox.h" +#include "constants.h" +#include "wallpaperlist.h" +#include "wallpaperitem.h" +#include "dbus/deepin_wm.h" +#include "thumbnailmanager.h" +#include "appearance_interface.h" +#include "screen/screenhelper.h" +#include "dbusinterface/introspectable_interface.h" +#include "screensavercontrol.h" +#include "button.h" +#include "dfileservices.h" +#include "desktopinfo.h" +#include "waititem.h" +#ifndef DISABLE_SCREENSAVER +#include "screensaver_interface.h" +#endif +#include "dfileservices.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DESKTOP_BUTTON_ID "desktop" +#define LOCK_SCREEN_BUTTON_ID "lock-screen" +#define DESKTOP_AND_LOCKSCREEN_BUTTON_ID "desktop-lockscreen" +#define SCREENSAVER_BUTTON_ID "screensaver" +#define SessionManagerService "com.deepin.SessionManager" +#define SessionManagerPath "/com/deepin/SessionManager" + + +#define BUTTON_NARROW_WIDTH 79 +#define BUTTON_WIDE_WIDTH 164 + +DWIDGET_USE_NAMESPACE +DGUI_USE_NAMESPACE +DCORE_USE_NAMESPACE +DFM_USE_NAMESPACE +using namespace com::deepin; +static bool previewBackground() +{ + if (DWindowManagerHelper::instance()->windowManagerName() == DWindowManagerHelper::DeepinWM) + return false; + + return DWindowManagerHelper::instance()->windowManagerName() == DWindowManagerHelper::KWinWM + || !DWindowManagerHelper::instance()->hasBlurWindow(); +} + +//自动更换壁纸时间 +static const QByteArrayList array_policy {"30", "60", "300", "600", "900", "1800", "3600", "login", "wakeup"}; + +Frame::Frame(QString screenName, Mode mode, QWidget *parent) + : DBlurEffectWidget(parent) + , m_sessionManagerInter(new SessionManager(SessionManagerService, + SessionManagerPath, + QDBusConnection::sessionBus(),this)) + , m_mode(mode) + , m_wallpaperList(new WallpaperList(this)) + , m_closeButton(new DIconButton(this)) + , m_dbusWmInter (new WMInter("com.deepin.wm", "/com/deepin/wm", QDBusConnection::sessionBus(), this)) + , m_dbusAppearance(new ComDeepinDaemonAppearanceInterface(AppearanceServ, + AppearancePath, + QDBusConnection::sessionBus(), + this)) + , m_mouseArea(new DRegionMonitor(this)) + , m_screenName(screenName) +{ + m_mouseArea->setCoordinateType(DRegionMonitor::Original); + + setFocusPolicy(Qt::NoFocus); + setWindowFlags(Qt::BypassWindowManagerHint | Qt::WindowStaysOnTopHint); + setAttribute(Qt::WA_TranslucentBackground); + if (DesktopInfo().waylandDectected()){ + winId(); + auto win = windowHandle(); + if (win){ + qDebug() << "set wayland role override"; + win->setProperty("_d_dwayland_window-type","wallpaper-set"); + }else { + qCritical() << "wayland role error,windowHandle is nullptr!"; + } + } + setBlendMode(DBlurEffectWidget::BehindWindowBlend); + initUI(); + initSize(); + + connect(m_mouseArea, &DRegionMonitor::buttonPress, this, [this](const QPoint & p, const int button) { + if (button == 4) { + m_wallpaperList->prevPage(); + } else if (button == 5) { + m_wallpaperList->nextPage(); + } else { + qreal scale = devicePixelRatioF(); + if(!ScreenHelper::screenManager()->screen(m_screenName)){ + qCritical() << "lost screen " << m_screenName << "closed"; + return ; + } + const QRect sRect = ScreenHelper::screenManager()->screen(m_screenName)->geometry(); + QRect nativeRect = geometry(); + + // 获取窗口真实的geometry + nativeRect.moveTopLeft((nativeRect.topLeft() - sRect.topLeft()) * scale + sRect.topLeft()); + nativeRect.setSize(nativeRect.size() * scale); + + if (!nativeRect.contains(p)) { + qDebug() << "button pressed on blank area quit."; + hide(); + } + + activateWindow(); + } + }); + + connect(ScreenMrg, &AbstractScreenManager::sigScreenGeometryChanged,this,[this](){ + initSize(); + if (!isHidden()) + m_wallpaperList->updateItemThumb(); + + qDebug() << "reset geometry" << this->isVisible() << this->geometry(); + this->activateWindow(); + }); + + m_closeButton->hide(); + connect(m_wallpaperList, &WallpaperList::mouseOverItemChanged, + this, &Frame::handleNeedCloseButton); + connect(m_wallpaperList, &WallpaperList::itemPressed, + this, &Frame::onItemPressed); + connect(m_sessionManagerInter, &SessionManager::LockedChanged, this, [this](bool locked){ + this->setVisible(!locked); + }); + + loading(); + m_loadTimer.setSingleShot(true); + connect(&m_loadTimer,&QTimer::timeout,this,[this](){ + this->refreshList(); + }); +} + +Frame::~Frame() +{ + QStringList list = m_needDeleteList; + QTimer::singleShot(1000, [list]() { + ComDeepinDaemonAppearanceInterface dbusAppearance(AppearanceServ, + AppearancePath, + QDBusConnection::sessionBus(), + nullptr); + + for (const QString &path : list) { + dbusAppearance.Delete("background", path); + qDebug() << "delete background" << path; + } + }); + + disconnect(ScreenMrg, nullptr,this,nullptr); + //释放资源 + if (m_itemwait) { + delete m_itemwait; + m_itemwait = nullptr; + } + + if (m_toolLayout) { + delete m_toolLayout; + m_toolLayout = nullptr; + } + + if (m_wallpaperCarouselLayout) { + delete m_wallpaperCarouselLayout; + m_wallpaperCarouselLayout = nullptr; + } +} + +void Frame::show() +{ + if (previewBackground()) { + if (m_dbusDeepinWM) { + // 销毁不需要的资源 + m_dbusDeepinWM->deleteLater(); + m_dbusDeepinWM = nullptr; + } + + if (!m_backgroundManager) { + m_backgroundManager = new BackgroundManager(true, this); + + connect(m_backgroundManager, SIGNAL(sigBackgroundBuilded(int)),this,SLOT(onRest())); + } + } else if (!m_dbusDeepinWM) { + if (m_backgroundManager) { + // 销毁不需要的资源 + m_backgroundManager->deleteLater(); + m_backgroundManager = nullptr; + } + + m_dbusDeepinWM = new DeepinWM(DeepinWMServ, + DeepinWMPath, + QDBusConnection::sessionBus(), + this); + } + + if (m_dbusDeepinWM) + m_dbusDeepinWM->RequestHideWindows(); + + m_mouseArea->registerRegion(); + + DBlurEffectWidget::show(); +} + +void Frame::hide() +{ + DBlurEffectWidget::hide(); +} + +void Frame::setMode(Frame::Mode mode) +{ + if (m_mode == mode) + return; + + if (m_mode == ScreenSaverMode) { + if (m_backgroundManager) { + m_backgroundManager->setVisible(true); + } +#ifndef DISABLE_SCREENSAVER + m_dbusScreenSaver->Stop(); +#endif + } + +#ifndef DISABLE_SCREENSAVER + m_mode = mode; + reLayoutTools(); +#endif + refreshList(); +} + +QPair Frame::desktopBackground() const +{ + return QPair(m_screenName, m_cureentWallpaper); +} + +void Frame::handleNeedCloseButton(QString path, QPoint pos) +{ + if (!path.isEmpty()) { + m_closeButton->adjustSize(); + m_closeButton->move(pos.x() - 10, pos.y() - 10); + m_closeButton->show(); + m_closeButton->disconnect(); + + connect(m_closeButton, &DIconButton::clicked, this, [this, path] { + m_dbusAppearance->Delete("background", path); // 当前自定义壁纸不一定能删成功 + m_needDeleteList << path; + m_wallpaperList->removeWallpaper(path); + m_closeButton->hide(); + }, Qt::UniqueConnection); + } else { + m_closeButton->hide(); + } +} + +void Frame::onRest() +{ + ScreenPointer screen = ScreenMrg->screen(m_screenName); + if (m_backgroundManager){ + BackgroundWidgetPointer bwp = m_backgroundManager->backgroundWidget(screen); + if (bwp){ + m_screenName = screen->name(); + bwp->lower(); + initSize(); + if (!isHidden()) + m_wallpaperList->updateItemThumb(); + raise(); + qDebug() << "onRest frame" << this->isVisible() << this->geometry(); + this->activateWindow(); + return; + } + } + + qDebug() << m_screenName << "lost exit!"; + close(); +} + +void Frame::showEvent(QShowEvent *event) +{ +#ifndef DISABLE_SCREENSAVER + m_switchModeControl->adjustSize(); +#endif + + activateWindow(); + + QTimer::singleShot(1, this, &Frame::refreshList); + + DBlurEffectWidget::showEvent(event); +} + +void Frame::hideEvent(QHideEvent *event) +{ + DBlurEffectWidget::hideEvent(event); + + if (m_dbusDeepinWM) + m_dbusDeepinWM->CancelHideWindows(); + m_mouseArea->unregisterRegion(); + + if (m_mode == WallpaperMode) { + if (!m_cureentWallpaper.isEmpty() && m_dbusDeepinWM) + m_dbusDeepinWM->SetTransientBackground(""); + + if (ThumbnailManager *manager = ThumbnailManager::instance(devicePixelRatioF())) + manager->stop(); + } +#ifndef DISABLE_SCREENSAVER + else if (m_mode == ScreenSaverMode) { + m_dbusScreenSaver->Stop(); + } +#endif + + // 销毁资源 + if (m_dbusDeepinWM) { + m_dbusDeepinWM->deleteLater(); + m_dbusDeepinWM = nullptr; + } + + if (m_backgroundManager) { + m_backgroundManager->setVisible(false); + m_backgroundManager->deleteLater(); + m_backgroundManager = nullptr; + } + + emit done(); +} + +void Frame::keyPressEvent(QKeyEvent *event) +{ + QWidgetList widgetList; //记录页面上可选中控件 + //设置壁纸模式 + if (m_mode == Mode::WallpaperMode) { + widgetList << m_wallpaperCarouselCheckBox; //自动更换壁纸按钮 + //更换周期按钮组 + if (m_wallpaperCarouselControl->isVisible()){ + for (QAbstractButton *button: m_wallpaperCarouselControl->buttonList()) { + widgetList << qobject_cast(button); + } + } + } + //设置屏保模式 +#ifndef DISABLE_SCREENSAVER + else { + //闲置时间按钮组 + for (QAbstractButton *button: m_waitControl->buttonList()) { + widgetList << qobject_cast(button); + } + //是否需要密码按钮 + widgetList << m_lockScreenBox; + } +#endif + + if (!widgetList.contains(focusWidget())) { + widgetList.clear(); + + //模式切换按钮组 +#ifndef DISABLE_SCREENSAVER + for (QAbstractButton *button: m_switchModeControl->buttonList()) { + widgetList << qobject_cast(button); + } +#endif + } + + switch(event->key()) + { + case Qt::Key_Escape: + hide(); + qDebug() << "escape key pressed, quit."; + break; + case Qt::Key_Right: + qDebug() << "Right"; + //选中列表下一控件 + if(widgetList.indexOf(focusWidget(),0) < widgetList.count()-1) { + widgetList.at(widgetList.indexOf(focusWidget(),0)+1)->setFocus(); + } + break; + case Qt::Key_Left: + qDebug() << "Left"; + //选中列表上一控件 + if (widgetList.indexOf(focusWidget(),0) > 0) { + widgetList.at(widgetList.indexOf(focusWidget(),0)-1)->setFocus(); + } + break; + default: + DBlurEffectWidget::keyPressEvent(event); + break; + } +} + +void Frame::paintEvent(QPaintEvent *event) +{ + DBlurEffectWidget::paintEvent(event); + + QPainter pa(this); + + pa.setCompositionMode(QPainter::CompositionMode_SourceOut); + pa.setPen(QPen(QColor(255, 255, 255, 20), 1)); + pa.drawLine(QPoint(0, 0), QPoint(width(), 0)); +} + +bool Frame::event(QEvent *event) +{ +#ifndef DISABLE_SCREENSAVER + if (event->type() == QEvent::LayoutRequest + || event->type() == QEvent::Resize) { + adjustModeSwitcherPoint(); + } +#endif + return DBlurEffectWidget::event(event); +} + +bool Frame::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) { + QKeyEvent *key = static_cast(event); + qDebug() << "keyPress"; + if(!key) { + qDebug()<<"key is null."; + return false; + } + + if (key->key() == Qt::Key_Tab) { + qDebug() << "Tab"; +#ifndef DISABLE_SCREENSAVER + //第一个区域发出tab信号,则跳转到第二个区域的第一个控件上 + if (object == m_wallpaperCarouselCheckBox + || m_wallpaperCarouselControl->buttonList().contains(qobject_cast(object)) + || object == m_lockScreenBox + || m_waitControl->buttonList().contains(qobject_cast(object))) { + m_switchModeControl->buttonList().first()->setFocus(); + return true; + } + //第二个区域tab跳转到第三个区域的当前选项(WallpaperItem)的第一个控件(Button)上 + if (m_switchModeControl->buttonList().contains(qobject_cast(object))) { + if (nullptr == m_wallpaperList->getCurrentItem()) { + return false; + } + QList